Plex and Jellyfin widget (#713)

This commit is contained in:
Manuel
2023-02-15 22:12:49 +01:00
committed by GitHub
parent ca50cffe82
commit d157e986a1
20 changed files with 1129 additions and 236 deletions

View File

@@ -1,5 +0,0 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
yarn-path ".yarn/releases/yarn-1.22.19.cjs"

View File

@@ -29,6 +29,7 @@
"@ctrl/transmission": "^4.1.1",
"@emotion/react": "^11.10.5",
"@emotion/server": "^11.10.0",
"@jellyfin/sdk": "^0.7.0",
"@mantine/core": "^5.9.3",
"@mantine/dates": "^5.9.3",
"@mantine/dropzone": "^5.9.3",
@@ -62,6 +63,7 @@
"rss-parser": "^3.12.0",
"sabnzbd-api": "^1.5.0",
"uuid": "^8.3.2",
"xml-js": "^1.6.11",
"yarn": "^1.22.19",
"zustand": "^4.1.4"
},

View File

@@ -0,0 +1,24 @@
{
"descriptor": {
"name": "Media Server",
"description": "Interact with your Jellyfin or Plex media server",
"settings": {
"title": "Settings for media server widget"
}
},
"card": {
"table": {
"header": {
"session": "Session",
"user": "User",
"currentlyPlaying": "Currently playing"
}
},
"errors": {
"general": {
"title": "Unable to load content",
"text": "Unable to retrieve information from the server. Please check the logs for more details"
}
}
}
}

View File

@@ -0,0 +1,26 @@
import { Avatar, DefaultMantineColor, useMantineTheme } from '@mantine/core';
export const AppAvatar = ({
iconUrl,
color,
}: {
iconUrl: string;
color?: DefaultMantineColor | undefined;
}) => {
const { colors, colorScheme } = useMantineTheme();
return (
<Avatar
src={iconUrl}
bg={colorScheme === 'dark' ? colors.gray[8] : colors.gray[2]}
size="sm"
radius="xl"
p={4}
styles={{
root: {
borderColor: color !== undefined ? colors[color] : undefined,
},
}}
/>
);
};

View File

@@ -75,6 +75,16 @@ export const IntegrationSelector = ({ form }: IntegrationSelectorProps) => {
image: 'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/readarr.png',
label: 'Readarr',
},
{
value: 'jellyfin',
image: 'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/jellyfin.png',
label: 'Jellyfin',
},
{
value: 'plex',
image: 'https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/plex.png',
label: 'Plex',
},
].filter((x) => Object.keys(integrationFieldProperties).includes(x.value));
const getNewProperties = (value: string | null): AppIntegrationPropertyType[] => {

View File

@@ -0,0 +1,17 @@
import { useQuery } from '@tanstack/react-query';
import { MediaServersResponseType } from '../../../types/api/media-server/response';
interface GetMediaServersParams {
enabled: boolean;
}
export const useGetMediaServers = ({ enabled }: GetMediaServersParams) =>
useQuery({
queryKey: ['media-servers'],
queryFn: async (): Promise<MediaServersResponseType> => {
const response = await fetch('/api/modules/media-server');
return response.json();
},
enabled,
refetchInterval: 10 * 1000,
});

View File

@@ -0,0 +1,227 @@
import { Jellyfin } from '@jellyfin/sdk';
import { getSessionApi } from '@jellyfin/sdk/lib/utils/api/session-api';
import { getSystemApi } from '@jellyfin/sdk/lib/utils/api/system-api';
import Consola from 'consola';
import { getCookie } from 'cookies-next';
import { NextApiRequest, NextApiResponse } from 'next';
import { BaseItemKind, ProgramAudio } from '@jellyfin/sdk/lib/generated-client/models';
import { getConfig } from '../../../../tools/config/getConfig';
import { PlexClient } from '../../../../tools/server/sdk/plex/plexClient';
import { GenericMediaServer } from '../../../../types/api/media-server/media-server';
import { MediaServersResponseType } from '../../../../types/api/media-server/response';
import {
GenericCurrentlyPlaying,
GenericSessionInfo,
} from '../../../../types/api/media-server/session-info';
import { ConfigAppType } from '../../../../types/app';
const jellyfin = new Jellyfin({
clientInfo: {
name: 'Homarr',
version: '0.0.1',
},
deviceInfo: {
name: 'Homarr Jellyfin Widget',
id: 'homarr-jellyfin-widget',
},
});
const Get = async (request: NextApiRequest, response: NextApiResponse) => {
const configName = getCookie('config-name', { req: request });
const config = getConfig(configName?.toString() ?? 'default');
const apps = config.apps.filter((app) =>
['jellyfin', 'plex'].includes(app.integration?.type ?? '')
);
const servers = await Promise.all(
apps.map(async (app): Promise<GenericMediaServer | undefined> => {
try {
return await handleServer(app);
} catch (error) {
Consola.error(
`failed to communicate with media server '${app.name}' (${app.id}): ${error}`
);
return {
serverAddress: app.url,
sessions: [],
success: false,
version: undefined,
type: undefined,
appId: app.id,
};
}
})
);
return response.status(200).json({
servers: servers.filter((server) => server !== undefined),
} as MediaServersResponseType);
};
const handleServer = async (app: ConfigAppType): Promise<GenericMediaServer | undefined> => {
switch (app.integration?.type) {
case 'jellyfin': {
const username = app.integration.properties.find((x) => x.field === 'username');
if (!username || !username.value) {
return {
appId: app.id,
serverAddress: app.url,
sessions: [],
type: 'jellyfin',
version: undefined,
success: false,
};
}
const password = app.integration.properties.find((x) => x.field === 'password');
if (!password || !password.value) {
return {
appId: app.id,
serverAddress: app.url,
sessions: [],
type: 'jellyfin',
version: undefined,
success: false,
};
}
const api = jellyfin.createApi(app.url);
const infoApi = await getSystemApi(api).getPublicSystemInfo();
await api.authenticateUserByName(username.value, password.value);
const sessionApi = await getSessionApi(api);
const sessions = await sessionApi.getSessions();
return {
type: 'jellyfin',
appId: app.id,
serverAddress: app.url,
version: infoApi.data.Version ?? undefined,
sessions: sessions.data.map(
(session): GenericSessionInfo => ({
id: session.Id ?? '?',
username: session.UserName ?? undefined,
sessionName: `${session.Client} (${session.DeviceName})`,
supportsMediaControl: session.SupportsMediaControl ?? false,
currentlyPlaying: session.NowPlayingItem
? {
name: session.NowPlayingItem.Name as string,
seasonName: session.NowPlayingItem.SeasonName as string,
albumName: session.NowPlayingItem.Album as string,
episodeCount: session.NowPlayingItem.EpisodeCount ?? undefined,
metadata: {
video:
session.NowPlayingItem &&
session.NowPlayingItem.Width &&
session.NowPlayingItem.Height
? {
videoCodec: undefined,
width: session.NowPlayingItem.Width ?? undefined,
height: session.NowPlayingItem.Height ?? undefined,
bitrate: undefined,
videoFrameRate: session.TranscodingInfo?.Framerate
? String(session.TranscodingInfo?.Framerate)
: undefined,
}
: undefined,
audio: session.TranscodingInfo
? {
audioChannels: session.TranscodingInfo.AudioChannels ?? undefined,
audioCodec: session.TranscodingInfo.AudioCodec ?? undefined,
}
: undefined,
transcoding: session.TranscodingInfo
? {
audioChannels: session.TranscodingInfo.AudioChannels ?? -1,
audioCodec: session.TranscodingInfo.AudioCodec ?? undefined,
container: session.TranscodingInfo.Container ?? undefined,
width: session.TranscodingInfo.Width ?? undefined,
height: session.TranscodingInfo.Height ?? undefined,
videoCodec: session.TranscodingInfo?.VideoCodec ?? undefined,
audioDecision: undefined,
context: undefined,
duration: undefined,
error: undefined,
sourceAudioCodec: undefined,
sourceVideoCodec: undefined,
timeStamp: undefined,
transcodeHwRequested: undefined,
videoDecision: undefined,
}
: undefined,
},
type: convertJellyfinType(session.NowPlayingItem.Type),
}
: undefined,
userProfilePicture: undefined,
})
),
success: true,
};
}
case 'plex': {
const apiKey = app.integration.properties.find((x) => x.field === 'apiKey');
if (!apiKey || !apiKey.value) {
return {
serverAddress: app.url,
sessions: [],
type: 'plex',
appId: app.id,
version: undefined,
success: false,
};
}
const plexClient = new PlexClient(app.url, apiKey.value);
const sessions = await plexClient.getSessions();
return {
serverAddress: app.url,
sessions,
type: 'plex',
version: undefined,
appId: app.id,
success: true,
};
}
default: {
Consola.warn(
`media-server api entered a fallback case. This should normally not happen and must be reported. Cause: '${app.name}' (${app.id})`
);
return undefined;
}
}
};
const convertJellyfinType = (kind: BaseItemKind | undefined): GenericCurrentlyPlaying['type'] => {
switch (kind) {
case BaseItemKind.Audio:
case BaseItemKind.MusicVideo:
return 'audio';
case BaseItemKind.Episode:
case BaseItemKind.Video:
return 'video';
case BaseItemKind.Movie:
return 'movie';
case BaseItemKind.TvChannel:
case BaseItemKind.TvProgram:
case BaseItemKind.LiveTvChannel:
case BaseItemKind.LiveTvProgram:
return 'tv';
default:
return undefined;
}
};
export default async (request: NextApiRequest, response: NextApiResponse) => {
if (request.method === 'GET') {
return Get(request, response);
}
return response.status(405);
};

View File

@@ -0,0 +1,108 @@
import { Element, xml2js } from 'xml-js';
import {
GenericCurrentlyPlaying,
GenericSessionInfo,
} from '../../../../types/api/media-server/session-info';
export class PlexClient {
constructor(private readonly apiAddress: string, private readonly token: string) {}
async getSessions(): Promise<GenericSessionInfo[]> {
const response = await fetch(`${this.apiAddress}/status/sessions?X-Plex-Token=${this.token}`);
const body = await response.text();
// convert xml response to objects, as there is no JSON api
const data = xml2js(body);
// TODO: Investigate when there are no media containers
const mediaContainer = data.elements[0] as Element;
// no sessions are open or available
if (!mediaContainer.elements?.some((_) => true)) {
return [];
}
const videoElements = mediaContainer.elements as Element[];
const videos = videoElements
.map((videoElement): GenericSessionInfo | undefined => {
// extract the elements from the children
const userElement = this.findElement('User', videoElement.elements);
const playerElement = this.findElement('Player', videoElement.elements);
const mediaElement = this.findElement('Media', videoElement.elements);
const sessionElement = this.findElement('Session', videoElement.elements);
if (!userElement || !playerElement || !mediaElement || !sessionElement) {
return undefined;
}
const { videoCodec, videoFrameRate, audioCodec, audioChannels, height, width, bitrate } =
mediaElement;
const transcodingElement = this.findElement('TranscodeSession', videoElement.elements);
return {
id: sessionElement.id as string,
username: userElement.title as string,
userProfilePicture: userElement.thumb as string,
sessionName: `${playerElement.product} (${playerElement.title})`,
currentlyPlaying: {
name: videoElement.attributes?.title as string,
type: this.getCurrentlyPlayingType(videoElement.attributes?.type as string),
metadata: {
video: {
bitrate,
height,
videoCodec,
videoFrameRate,
width,
},
audio: {
audioChannels,
audioCodec,
},
transcoding:
transcodingElement === undefined
? undefined
: {
audioChannels: transcodingElement.audioChannels,
audioCodec: transcodingElement.audioCodec,
audioDecision: transcodingElement.audioDecision,
container: transcodingElement.container,
context: transcodingElement.context,
duration: transcodingElement.duration,
error: transcodingElement.error === 1,
height: transcodingElement.height,
sourceAudioCodec: transcodingElement.sourceAudioCodec,
sourceVideoCodec: transcodingElement.sourceVideoCodec,
timeStamp: transcodingElement.timeStamp,
transcodeHwRequested: transcodingElement.transcodeHwRequested === 1,
videoCodec: transcodingElement.videoCodec,
videoDecision: transcodingElement.videoDecision,
width: transcodingElement.width,
},
},
},
} as GenericSessionInfo;
})
.filter((x) => x !== undefined) as GenericSessionInfo[];
return videos;
}
private findElement(name: string, elements: Element[] | undefined) {
return elements?.find((x) => x.name === name)?.attributes;
}
private getCurrentlyPlayingType(type: string): GenericCurrentlyPlaying['type'] {
switch (type) {
case 'movie':
return 'movie';
case 'episode':
return 'video';
default:
return undefined;
}
}
}

View File

@@ -33,6 +33,7 @@ export const dashboardNamespaces = [
'modules/docker',
'modules/dashdot',
'modules/overseerr',
'modules/media-server',
'modules/common-media-cards',
'modules/video-stream',
];

View File

@@ -0,0 +1,34 @@
import { GenericSessionInfo } from './session-info';
export type GenericMediaServer = {
/**
* The type of the media server.
* Undefined indicates, that the type is either unsupported or recognizing went wrong
*/
type: 'jellyfin' | 'plex' | undefined;
/**
* The address of the server
*/
serverAddress: string;
/**
* The current version of the server
*/
version: string | undefined;
/**
* The active sessions on the server
*/
sessions: GenericSessionInfo[];
/**
* The app id of the used app
*/
appId: string;
/**
* Indicates, wether the communication was successfull or not
*/
success: boolean;
};

View File

@@ -0,0 +1,5 @@
import { GenericMediaServer } from './media-server';
export type MediaServersResponseType = {
servers: GenericMediaServer[];
};

View File

@@ -0,0 +1,46 @@
export type GenericSessionInfo = {
supportsMediaControl: boolean;
username: string | undefined;
id: string;
sessionName: string;
userProfilePicture: string | undefined;
currentlyPlaying: GenericCurrentlyPlaying | undefined;
};
export type GenericCurrentlyPlaying = {
name: string;
seasonName: string | undefined;
albumName: string | undefined;
episodeCount: number | undefined;
type: 'audio' | 'video' | 'tv' | 'movie' | undefined;
metadata: {
video: {
videoCodec: string | undefined;
videoFrameRate: string | undefined;
height: number | undefined;
width: number | undefined;
bitrate: number | undefined;
} | undefined;
audio: {
audioCodec: string | undefined;
audioChannels: number | undefined;
} | undefined;
transcoding: {
context: string | undefined;
sourceVideoCodec: string | undefined;
sourceAudioCodec: string | undefined;
videoDecision: string | undefined;
audioDecision: string | undefined;
container: string | undefined;
videoCodec: string | undefined;
audioCodec: string | undefined;
error: boolean | undefined;
duration: number | undefined;
audioChannels: number | undefined;
width: number | undefined;
height: number | undefined;
transcodeHwRequested: boolean | undefined;
timeStamp: number | undefined;
} | undefined;
};
};

View File

@@ -41,6 +41,8 @@ export type IntegrationType =
| 'deluge'
| 'qBittorrent'
| 'transmission'
| 'plex'
| 'jellyfin'
| 'nzbGet';
export type AppIntegrationType = {
@@ -79,6 +81,8 @@ export const integrationFieldProperties: {
nzbGet: ['username', 'password'],
qBittorrent: ['username', 'password'],
transmission: ['username', 'password'],
jellyfin: ['username', 'password'],
plex: ['apiKey'],
};
export type IntegrationFieldDefinitionType = {

View File

@@ -15,6 +15,7 @@ import { Serie, Datum, ResponsiveLine } from '@nivo/line';
import { IconDownload, IconUpload } from '@tabler/icons';
import { useTranslation } from 'next-i18next';
import { useEffect } from 'react';
import { AppAvatar } from '../../components/AppAvatar';
import { useConfigContext } from '../../config/provider';
import { useGetDownloadClientsQueue } from '../../hooks/widgets/download-speed/useGetNetworkSpeed';
import { useColorTheme } from '../../tools/color';
@@ -258,17 +259,3 @@ export default function TorrentNetworkTrafficTile({ widget }: TorrentNetworkTraf
</Stack>
);
}
const AppAvatar = ({ iconUrl }: { iconUrl: string }) => {
const { colors, colorScheme } = useMantineTheme();
return (
<Avatar
src={iconUrl}
bg={colorScheme === 'dark' ? colors.gray[8] : colors.gray[2]}
size="sm"
radius="xl"
p={4}
/>
);
};

View File

@@ -2,6 +2,7 @@ import calendar from './calendar/CalendarTile';
import dashdot from './dashDot/DashDotTile';
import date from './date/DateTile';
import torrentNetworkTraffic from './download-speed/TorrentNetworkTrafficTile';
import mediaServer from './media-server/MediaServerTile';
import rss from './rss/RssWidgetTile';
import torrent from './torrent/TorrentTile';
import usenet from './useNet/UseNetTile';
@@ -18,4 +19,5 @@ export default {
date,
rss,
'video-stream': videoStream,
'media-server': mediaServer,
};

View File

@@ -0,0 +1,128 @@
import { Card, Divider, Flex, Grid, Group, Text } from '@mantine/core';
import { IconDeviceMobile, IconId } from '@tabler/icons';
import { GenericSessionInfo } from '../../types/api/media-server/session-info';
export const DetailCollapseable = ({ session }: { session: GenericSessionInfo }) => {
let details: { title: string; metrics: { name: string; value: string | undefined }[] }[] = [];
if (session.currentlyPlaying) {
if (session.currentlyPlaying.metadata.video) {
details = [
...details,
{
title: 'Video',
metrics: [
{
name: 'Resolution',
value: `${session.currentlyPlaying.metadata.video.width}x${session.currentlyPlaying.metadata.video.height}`,
},
{
name: 'Framerate',
value: session.currentlyPlaying.metadata.video.videoFrameRate,
},
{
name: 'Codec',
value: session.currentlyPlaying.metadata.video.videoCodec,
},
{
name: 'Bitrate',
value: session.currentlyPlaying.metadata.video.bitrate
? String(session.currentlyPlaying.metadata.video.bitrate)
: undefined,
},
],
},
];
}
if (session.currentlyPlaying.metadata.audio) {
details = [
...details,
{
title: 'Audio',
metrics: [
{
name: 'Audio channels',
value: `${session.currentlyPlaying.metadata.audio.audioChannels}`,
},
{
name: 'Audio codec',
value: session.currentlyPlaying.metadata.audio.audioCodec,
},
],
},
];
}
if (session.currentlyPlaying.metadata.transcoding) {
details = [
...details,
{
title: 'Transcoding',
metrics: [
{
name: 'Resolution',
value: `${session.currentlyPlaying.metadata.transcoding.width}x${session.currentlyPlaying.metadata.transcoding.height}`,
},
{
name: 'Context',
value: session.currentlyPlaying.metadata.transcoding.context,
},
{
name: 'Hardware encoding requested',
value: session.currentlyPlaying.metadata.transcoding.transcodeHwRequested
? 'yes'
: 'no',
},
{
name: 'Source codec',
value:
session.currentlyPlaying.metadata.transcoding.sourceAudioCodec ||
session.currentlyPlaying.metadata.transcoding.sourceVideoCodec
? `${session.currentlyPlaying.metadata.transcoding.sourceVideoCodec} ${session.currentlyPlaying.metadata.transcoding.sourceAudioCodec}`
: undefined,
},
{
name: 'Target codec',
value: `${session.currentlyPlaying.metadata.transcoding.videoCodec} ${session.currentlyPlaying.metadata.transcoding.audioCodec}`,
},
],
},
];
}
}
return (
<Card>
<Flex justify="space-between" mb="xs">
<Group>
<IconId size={16} />
<Text>ID</Text>
</Group>
<Text>{session.id}</Text>
</Flex>
<Flex justify="space-between" mb="md">
<Group>
<IconDeviceMobile size={16} />
<Text>Device</Text>
</Group>
<Text>{session.sessionName}</Text>
</Flex>
{details.length > 0 && <Divider label="Stats for nerds" labelPosition="center" mt="lg" mb="sm" />}
<Grid>
{details.map((detail, index) => (
<Grid.Col xs={12} sm={6} key={index}>
<Text weight="bold">{detail.title}</Text>
{detail.metrics
.filter((x) => x.value !== undefined)
.map((metric, index2) => (
<Group position="apart" key={index2}>
<Text>{metric.name}</Text>
<Text>{metric.value}</Text>
</Group>
))}
</Grid.Col>
))}
</Grid>
</Card>
);
};

View File

@@ -0,0 +1,110 @@
import {
Avatar,
Center,
Group,
Loader,
ScrollArea,
Stack,
Table,
Text,
Title,
} from '@mantine/core';
import { IconAlertTriangle, IconMovie } from '@tabler/icons';
import { useTranslation } from 'next-i18next';
import { AppAvatar } from '../../components/AppAvatar';
import { useConfigContext } from '../../config/provider';
import { useGetMediaServers } from '../../hooks/widgets/media-servers/useGetMediaServers';
import { defineWidget } from '../helper';
import { IWidget } from '../widgets';
import { TableRow } from './TableRow';
const definition = defineWidget({
id: 'media-server',
icon: IconMovie,
options: {},
component: MediaServerTile,
gridstack: {
minWidth: 3,
minHeight: 2,
maxWidth: 12,
maxHeight: 12,
},
});
export type MediaServerWidget = IWidget<(typeof definition)['id'], typeof definition>;
interface MediaServerWidgetProps {
widget: MediaServerWidget;
}
function MediaServerTile({ widget }: MediaServerWidgetProps) {
const { t } = useTranslation('modules/media-server');
const { config } = useConfigContext();
const { data, isError } = useGetMediaServers({
enabled: config !== undefined,
});
if (isError) {
return (
<Center>
<Stack align="center">
<IconAlertTriangle />
<Title order={6}>{t('card.errors.general.title')}</Title>
<Text>{t('card.errors.general.text')}</Text>
</Stack>
</Center>
);
}
if (!data) {
<Center h="100%">
<Loader />
</Center>;
}
return (
<Stack h="100%">
<ScrollArea offsetScrollbars>
<Table highlightOnHover striped>
<thead>
<tr>
<th>{t('card.table.header.session')}</th>
<th>{t('card.table.header.user')}</th>
<th>{t('card.table.header.currentlyPlaying')}</th>
</tr>
</thead>
<tbody>
{data?.servers.map((server) => {
const app = config?.apps.find((x) => x.id === server.appId);
return server.sessions.map((session, index) => (
<TableRow session={session} app={app} key={index} />
));
})}
</tbody>
</Table>
</ScrollArea>
<Group position="right" mt="auto">
<Avatar.Group>
{data?.servers.map((server) => {
const app = config?.apps.find((x) => x.id === server.appId);
if (!app) {
return null;
}
return (
<AppAvatar
iconUrl={app.appearance.iconUrl}
color={server.success === true ? undefined : 'red'}
/>
);
})}
</Avatar.Group>
</Group>
</Stack>
);
}
export default definition;

View File

@@ -0,0 +1,50 @@
import { Flex, Group, Stack, Text } from '@mantine/core';
import {
IconDeviceTv,
IconHeadphones,
IconQuestionMark,
IconVideo,
TablerIcon,
} from '@tabler/icons';
import { useTranslation } from 'next-i18next';
import { GenericSessionInfo } from '../../types/api/media-server/session-info';
export const NowPlayingDisplay = ({ session }: { session: GenericSessionInfo }) => {
const { t } = useTranslation();
if (!session.currentlyPlaying) {
return null;
}
const Icon = (): TablerIcon => {
switch (session.currentlyPlaying?.type) {
case 'audio':
return IconHeadphones;
case 'tv':
return IconDeviceTv;
case 'video':
return IconVideo;
default:
return IconQuestionMark;
}
};
const Test = Icon();
return (
<Flex wrap="nowrap" gap="sm" align="center">
<Test size={16} />
<Stack spacing={0}>
<Text lineClamp={1}>{session.currentlyPlaying.name}</Text>
{session.currentlyPlaying.albumName ? (
<Text lineClamp={1} color="dimmed" size="xs">{session.currentlyPlaying.albumName}</Text>
) : (
session.currentlyPlaying.seasonName && (
<Text lineClamp={1} color="dimmed" size="xs">{session.currentlyPlaying.seasonName}</Text>
)
)}
</Stack>
</Flex>
);
};

View File

@@ -0,0 +1,73 @@
import {
Avatar,
Card,
Collapse,
createStyles,
Flex,
Grid,
Group,
Stack,
Text,
Title,
} from '@mantine/core';
import { useState } from 'react';
import { AppAvatar } from '../../components/AppAvatar';
import { GenericSessionInfo } from '../../types/api/media-server/session-info';
import { AppType } from '../../types/app';
import { DetailCollapseable } from './DetailCollapseable';
import { NowPlayingDisplay } from './NowPlayingDisplay';
interface TableRowProps {
session: GenericSessionInfo;
app: AppType | undefined;
}
export const TableRow = ({ session, app }: TableRowProps) => {
const [collapseOpen, setCollapseOpen] = useState(false);
const hasUserThumb = session.userProfilePicture !== undefined;
const { classes } = useStyles();
return (
<>
<tr className={classes.dataRow} onClick={() => setCollapseOpen(!collapseOpen)}>
<td>
<Flex wrap="nowrap" gap="xs">
{app?.appearance.iconUrl && <AppAvatar iconUrl={app.appearance.iconUrl} />}
<Text lineClamp={1}>{session.sessionName}</Text>
</Flex>
</td>
<td>
<Flex wrap="nowrap" gap="sm">
{hasUserThumb ? (
<Avatar src={session.userProfilePicture} size="sm" />
) : (
<Avatar src={null} alt={session.username} size="sm">
{session.username?.at(0)?.toUpperCase()}
</Avatar>
)}
<Text>{session.username}</Text>
</Flex>
</td>
<td>
<NowPlayingDisplay session={session} />
</td>
</tr>
<tr>
<td className={classes.collapseTableDataCell} colSpan={3}>
<Collapse in={collapseOpen} w="100%">
<DetailCollapseable session={session} />
</Collapse>
</td>
</tr>
</>
);
};
const useStyles = createStyles(() => ({
dataRow: {
cursor: 'pointer',
},
collapseTableDataCell: {
border: 'none !important',
padding: '0 !important',
},
}));

478
yarn.lock
View File

@@ -680,45 +680,45 @@ __metadata:
languageName: node
linkType: hard
"@floating-ui/core@npm:^1.1.0":
version: 1.1.1
resolution: "@floating-ui/core@npm:1.1.1"
checksum: a8497bf981eedf652d275f7207342a9b24c1a67909dca9e042e2379b24321e6688c7774415f3ea607c466adf82b02d8779513f449376c46b2982f2380c80cd35
"@floating-ui/core@npm:^1.2.1":
version: 1.2.1
resolution: "@floating-ui/core@npm:1.2.1"
checksum: 7a263e15abad4cd98ce3938075c90f76bafef71c67964c83dd7cf1e1916c92ccfa46a4f2b95b403bb180f70b3e7ded118db1cbc3426269ec70e948edf0d19ae2
languageName: node
linkType: hard
"@floating-ui/dom@npm:^1.1.1":
version: 1.1.1
resolution: "@floating-ui/dom@npm:1.1.1"
"@floating-ui/dom@npm:^1.2.1":
version: 1.2.1
resolution: "@floating-ui/dom@npm:1.2.1"
dependencies:
"@floating-ui/core": ^1.1.0
checksum: 8b7f3b98ed7ec0b634e4a0b735253b0442358c5cea8302935fc185b2bd882202a053622abe9248c76d0908645dd35f93adeaed2d64371b2ab76b36725ce3f7d3
"@floating-ui/core": ^1.2.1
checksum: ad6928d5dd934ca8b3dcffdfcacde9d147afc0db4db0c0294b23d5f897224d73c7f0ae578b46d813f0d7ae22a86e7a3f8914fdbcdf4a8d42a1b430d0518f45be
languageName: node
linkType: hard
"@floating-ui/react-dom@npm:^1.2.2":
version: 1.2.2
resolution: "@floating-ui/react-dom@npm:1.2.2"
"@floating-ui/react-dom@npm:^1.3.0":
version: 1.3.0
resolution: "@floating-ui/react-dom@npm:1.3.0"
dependencies:
"@floating-ui/dom": ^1.1.1
"@floating-ui/dom": ^1.2.1
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
checksum: 5cb7879a8fe53ce4ca8361473d93e18806402d6bcde4e935d5aafa2b72032019e62f7d019d7d7145ead1ed829569ac14d6d8c50d7beedcea04cb3d02af661597
checksum: ce0ad3e3bbe43cfd15a6a0d5cccede02175c845862bfab52027995ab99c6b29630180dc7d146f76ebb34730f90a6ab9bf193c8984fe8d7f56062308e4ca98f77
languageName: node
linkType: hard
"@floating-ui/react@npm:^0.19.1":
version: 0.19.1
resolution: "@floating-ui/react@npm:0.19.1"
version: 0.19.2
resolution: "@floating-ui/react@npm:0.19.2"
dependencies:
"@floating-ui/react-dom": ^1.2.2
"@floating-ui/react-dom": ^1.3.0
aria-hidden: ^1.1.3
tabbable: ^6.0.1
peerDependencies:
react: ">=16.8.0"
react-dom: ">=16.8.0"
checksum: b36000fbb7148d8403072ad0408d6b9463bfa9cdc7e8f91cf741dee159b2ca9f73461f3ae56e4c94def67c16db75337d5ea90624e0a5c0dbb064cfa86ea025e2
checksum: 00fd827c2dcf879fec221d89ef5b90836bbecacc236ce2acc787db32ae7311d490cd136b13a8d0b6ab12842554a2ee1110605aa832af71a45c0a7297e342072c
languageName: node
linkType: hard
@@ -774,6 +774,16 @@ __metadata:
languageName: node
linkType: hard
"@jellyfin/sdk@npm:^0.7.0":
version: 0.7.0
resolution: "@jellyfin/sdk@npm:0.7.0"
dependencies:
axios: 0.27.2
compare-versions: 5.0.1
checksum: d7ddae88464e0f2276ec7a793f7e525098a56d96491a450d5e859bf46d74e473a4b4bd5dce2a64ef80484e12e23c14934a4cb20429e89a3c41e52e817e3f31d4
languageName: node
linkType: hard
"@jest/console@npm:^28.1.3":
version: 28.1.3
resolution: "@jest/console@npm:28.1.3"
@@ -1058,133 +1068,133 @@ __metadata:
linkType: hard
"@mantine/core@npm:^5.9.3":
version: 5.10.3
resolution: "@mantine/core@npm:5.10.3"
version: 5.10.4
resolution: "@mantine/core@npm:5.10.4"
dependencies:
"@floating-ui/react": ^0.19.1
"@mantine/styles": 5.10.3
"@mantine/utils": 5.10.3
"@mantine/styles": 5.10.4
"@mantine/utils": 5.10.4
"@radix-ui/react-scroll-area": 1.0.2
react-textarea-autosize: 8.3.4
peerDependencies:
"@mantine/hooks": 5.10.3
"@mantine/hooks": 5.10.4
react: ">=16.8.0"
react-dom: ">=16.8.0"
checksum: 460e613e90ecd94a9414bb93a98046e076256fa54ec5cd0b43d20815755e7862826d912a516591d2a2e0356647d72b293564d2ccb9ca1fb8999da0e963d701bd
checksum: 98cba720fa9764a7a45b13d167ad2dce1af1b639c202a25cf60c8ca439e386dfddefae262e770df62348af90647ba6cbc095c074a8f0582968059450fbbc2ff0
languageName: node
linkType: hard
"@mantine/dates@npm:^5.9.3":
version: 5.10.3
resolution: "@mantine/dates@npm:5.10.3"
version: 5.10.4
resolution: "@mantine/dates@npm:5.10.4"
dependencies:
"@mantine/utils": 5.10.3
"@mantine/utils": 5.10.4
peerDependencies:
"@mantine/core": 5.10.3
"@mantine/hooks": 5.10.3
"@mantine/core": 5.10.4
"@mantine/hooks": 5.10.4
dayjs: ">=1.0.0"
react: ">=16.8.0"
checksum: 80e22b0eb2235a373f0d35979bea7aeea671515962f4d119811145da7086f2258663ceb2d19a6ad23a02b6f08e1c53047778ec37cf559d8e81c9061d9f83a159
checksum: 14a32aa4c16e030266629dfc5171e930d271682de742541b2298d448df11c9fab40e1d8003eabccfd5449a65ef14681993af6426197da4dcad1f509fb9fff932
languageName: node
linkType: hard
"@mantine/dropzone@npm:^5.9.3":
version: 5.10.3
resolution: "@mantine/dropzone@npm:5.10.3"
version: 5.10.4
resolution: "@mantine/dropzone@npm:5.10.4"
dependencies:
"@mantine/utils": 5.10.3
"@mantine/utils": 5.10.4
react-dropzone: 14.2.3
peerDependencies:
"@mantine/core": 5.10.3
"@mantine/hooks": 5.10.3
"@mantine/core": 5.10.4
"@mantine/hooks": 5.10.4
react: ">=16.8.0"
react-dom: ">=16.8.0"
checksum: 550bf8a282220adb3f7564e2ffa7c617480a5ab9d2556c50072b614450ca1d7fc526e8755a635936c4cb76f9a090f91686f690b7e7704320972dd282e00ab1d6
checksum: 0b837b5bc7c982ad9832142c880c1b0f2827de5c2163b76895cac2dbe6204f7c67e466468a3fb00f72482bad957c4b1209820025c4dfc2c25650734df79e208b
languageName: node
linkType: hard
"@mantine/form@npm:^5.9.3":
version: 5.10.3
resolution: "@mantine/form@npm:5.10.3"
version: 5.10.4
resolution: "@mantine/form@npm:5.10.4"
dependencies:
fast-deep-equal: ^3.1.3
klona: ^2.0.5
peerDependencies:
react: ">=16.8.0"
checksum: 88bcf7b37d19e0648500e9da7111d961a3b130ef1164f4c4fc15f606cececdddad614887ff6659e0a0ce3896a4e52e62c2f72758f857e932e903cf412a69ca54
checksum: 00ebc0011981f8dae5e96e833f7e0102067a7bc38b1f6208b377f029fdc8bb703a492f40a688eb015dea3147c3b6e5a7cd26c584b93cc8d2567f0dcb10319759
languageName: node
linkType: hard
"@mantine/hooks@npm:^5.9.3":
version: 5.10.3
resolution: "@mantine/hooks@npm:5.10.3"
version: 5.10.4
resolution: "@mantine/hooks@npm:5.10.4"
peerDependencies:
react: ">=16.8.0"
checksum: 629554658e910dec1c14ecbdaf8e48c1ce2af022044269e73ff069d719a4f9b68428bb75ade5108ace40bd29253658e663c594a237e080226de28705c10c871e
checksum: 41ededb62ea9311303e4b8d577ec21c12ddb339e60e70c3a1f561cb1b2c66fb6e6f29a7a23a89322748779cc06797de749203afd546f2b13180781c0e2873fa6
languageName: node
linkType: hard
"@mantine/modals@npm:^5.9.3":
version: 5.10.3
resolution: "@mantine/modals@npm:5.10.3"
version: 5.10.4
resolution: "@mantine/modals@npm:5.10.4"
dependencies:
"@mantine/utils": 5.10.3
"@mantine/utils": 5.10.4
peerDependencies:
"@mantine/core": 5.10.3
"@mantine/hooks": 5.10.3
"@mantine/core": 5.10.4
"@mantine/hooks": 5.10.4
react: ">=16.8.0"
react-dom: ">=16.8.0"
checksum: b013eb3c68ee1c0f163c1bd4b786c59e4a7f77d596f175ef2a88b1922153c24a154f12a36b65138af778cdd47944869056df5beb921e5d07801f5246b19b8da9
checksum: 82fce48fffbbce11526212b994e2763f0b36a276a86385f5b9ac1b5f1226f39f3f12aa171fe8b9181b755f95dbb869ef88f339e620bfd0ec28b7b0017f6b7fa7
languageName: node
linkType: hard
"@mantine/next@npm:^5.9.3":
version: 5.10.3
resolution: "@mantine/next@npm:5.10.3"
version: 5.10.4
resolution: "@mantine/next@npm:5.10.4"
dependencies:
"@mantine/ssr": 5.10.3
"@mantine/styles": 5.10.3
"@mantine/ssr": 5.10.4
"@mantine/styles": 5.10.4
peerDependencies:
next: "*"
react: ">=16.8.0"
react-dom: ">=16.8.0"
checksum: 78ee3e7f7565318f40f367c8d53edfb164ae10c4fcc788b8792b27ae3f10fad81be8dbfaecd171fd66c43eafc50cc30ea5ab7f3da5421642b3a8c96d5a03d618
checksum: 344590d09cfef4194187f7ea430082d9f22379e264b04fa3a9261a137abf9b1e4681eb7c610b678822b2ad3001f5611e201a73a4612ee8b13d93460d68a28b0c
languageName: node
linkType: hard
"@mantine/notifications@npm:^5.9.3":
version: 5.10.3
resolution: "@mantine/notifications@npm:5.10.3"
version: 5.10.4
resolution: "@mantine/notifications@npm:5.10.4"
dependencies:
"@mantine/utils": 5.10.3
"@mantine/utils": 5.10.4
react-transition-group: 4.4.2
peerDependencies:
"@mantine/core": 5.10.3
"@mantine/hooks": 5.10.3
"@mantine/core": 5.10.4
"@mantine/hooks": 5.10.4
react: ">=16.8.0"
react-dom: ">=16.8.0"
checksum: e4b735725fc7c0558cf0b084f677d432d6bd49220621ff20e32371621ba454a9d8b8eba0a36db7e99a0951cc174cb51b7ec91a9e127cba13330c93f3bcaecb10
checksum: da439698331f09dd1f3efaa470df1f9717f7309c2a61b0bfaa14bd832185fbd0711fbaffe867b0d6978108db30d059909b59c2b7c0ed83d1bd55bc8b7a6d3e7f
languageName: node
linkType: hard
"@mantine/ssr@npm:5.10.3":
version: 5.10.3
resolution: "@mantine/ssr@npm:5.10.3"
"@mantine/ssr@npm:5.10.4":
version: 5.10.4
resolution: "@mantine/ssr@npm:5.10.4"
dependencies:
"@mantine/styles": 5.10.3
"@mantine/styles": 5.10.4
html-react-parser: 1.4.12
peerDependencies:
"@emotion/react": ">=11.9.0"
"@emotion/server": ">=11.4.0"
react: ">=16.8.0"
react-dom: ">=16.8.0"
checksum: 8a6f0140f8fc853e3be8b0ec78908f71378ab76f36efe58ea2b1818139db60658bd12d3b1a56b9e61218262e85e2fbf9488393c3f0a64cb2d24125a27230397f
checksum: 74e5c56b85ea731597aba876941086306abb5ae24faa86d37a5210cfd743aa164e97b29e547563f810ef92b51b3c90bd02ce1a39fbee84cbec2abd2e6ad45ca7
languageName: node
linkType: hard
"@mantine/styles@npm:5.10.3":
version: 5.10.3
resolution: "@mantine/styles@npm:5.10.3"
"@mantine/styles@npm:5.10.4":
version: 5.10.4
resolution: "@mantine/styles@npm:5.10.4"
dependencies:
clsx: 1.1.1
csstype: 3.0.9
@@ -1192,16 +1202,16 @@ __metadata:
"@emotion/react": ">=11.9.0"
react: ">=16.8.0"
react-dom: ">=16.8.0"
checksum: 60fcfd5ccbfd7e1106a24a13c3f705ac4b995214ae038c2d8e7bf5e795cb7c1f5da9ee5e336caedf2a537e77272a05eb315e76df3edb4a466ec158ae6aeaf8b5
checksum: 54af835dca68a457be758570c82eab2d602da19a24da599b2f2c02f451be136a400b2f8efbbdc7d1a677188b57515d3ace23df0b8aa8e37c4ddf3a2fdbce1630
languageName: node
linkType: hard
"@mantine/utils@npm:5.10.3":
version: 5.10.3
resolution: "@mantine/utils@npm:5.10.3"
"@mantine/utils@npm:5.10.4":
version: 5.10.4
resolution: "@mantine/utils@npm:5.10.4"
peerDependencies:
react: ">=16.8.0"
checksum: 063237e49f3c52e3bbcd99e7a8383ac881718d9e1e039d32249231370a463a19e070cea7f90c3c0fea2933c3c162f5509a0f2add015db2aeb90f7945cd954a12
checksum: 96e2602f8500c29b5979d4fe0b3456c8de911ff1bd2ef216d960b23a5370ff6828871aa859538a4004ad095fb63d7e0e76cdfb365bdb930f70f8076d730302c1
languageName: node
linkType: hard
@@ -1877,33 +1887,33 @@ __metadata:
languageName: node
linkType: hard
"@tanstack/query-core@npm:4.24.4":
version: 4.24.4
resolution: "@tanstack/query-core@npm:4.24.4"
checksum: b357e950a41e5769878a3bfe9dd56a66828ccebb2f9396e568e8835bed71eb37926770a461e3aa5bafb7e1121c5141cee86aedf3ced88a2eacf754d545b107cd
"@tanstack/query-core@npm:4.24.6":
version: 4.24.6
resolution: "@tanstack/query-core@npm:4.24.6"
checksum: 495dff04f27d72174051f97676fce0fbe322bca966edb7f174f0005a3363ac0300c31eb06255dafa7ee519a430840542379f5ec9f6846903b6bb878e46c33656
languageName: node
linkType: hard
"@tanstack/react-query-devtools@npm:^4.24.4":
version: 4.24.4
resolution: "@tanstack/react-query-devtools@npm:4.24.4"
version: 4.24.6
resolution: "@tanstack/react-query-devtools@npm:4.24.6"
dependencies:
"@tanstack/match-sorter-utils": ^8.7.0
superjson: ^1.10.0
use-sync-external-store: ^1.2.0
peerDependencies:
"@tanstack/react-query": 4.24.4
"@tanstack/react-query": 4.24.6
react: ^16.8.0 || ^17.0.0 || ^18.0.0
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
checksum: 8b8f1ae8e55f016f25b383baae0000f0b608ec0327ee4eccb0a7b3b1c596b12f68c848e429be84c8a6039bd0a7d5bd36a7232fd7818868f1a3ae3d0462898e26
checksum: 65722242dc040f74fe70748000cc3f24c2cdd45fa2cfc1ee9d846c37c7d3e55438426a4a4973e6eb2a55efb280c0f5ea2ae091bfa493c1f3ca4edac2aba757af
languageName: node
linkType: hard
"@tanstack/react-query@npm:^4.2.1":
version: 4.24.4
resolution: "@tanstack/react-query@npm:4.24.4"
version: 4.24.6
resolution: "@tanstack/react-query@npm:4.24.6"
dependencies:
"@tanstack/query-core": 4.24.4
"@tanstack/query-core": 4.24.6
use-sync-external-store: ^1.2.0
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
@@ -1914,7 +1924,7 @@ __metadata:
optional: true
react-native:
optional: true
checksum: 8cf008d690fc5d336f6471ea2bc0751189f03874dcc7930cf8944fb57fa34e3b5347823775dbd36629d53a7aacb9ce87482b1adb3ad80d277a3a6c73b797f6a2
checksum: 250bc2cba8dd7da61680a8e360fac87ee057d079ee3be950c76dbc063f941119817634857c1cb0d9b12042dd5d4fbe847c02af5dfb89ae8daa0f9339f87ad605
languageName: node
linkType: hard
@@ -2080,9 +2090,9 @@ __metadata:
linkType: hard
"@types/node@npm:*, @types/node@npm:^18.11.18":
version: 18.11.18
resolution: "@types/node@npm:18.11.18"
checksum: 03f17f9480f8d775c8a72da5ea7e9383db5f6d85aa5fefde90dd953a1449bd5e4ffde376f139da4f3744b4c83942166d2a7603969a6f8ea826edfb16e6e3b49d
version: 18.13.0
resolution: "@types/node@npm:18.13.0"
checksum: 4ea10f8802848b01672bce938f678b6774ca2cee0c9774f12275ab064ae07818419c3e2e41d6257ce7ba846d1ea26c63214aa1dfa4166fa3746291752b8c6416
languageName: node
linkType: hard
@@ -2094,9 +2104,9 @@ __metadata:
linkType: hard
"@types/node@npm:^16.10.2":
version: 16.18.11
resolution: "@types/node@npm:16.18.11"
checksum: 2a3b1da13063debe6e26f732defb5f03ef4ef732c3e08daba838d8850433bd00e537ce1a97ce9bcfc4b15db5218d701d1265fae94e0d6926906bec157e6b46e0
version: 16.18.12
resolution: "@types/node@npm:16.18.12"
checksum: fc3271182414f8593018ef8f00b4718116a92f463f619081bd399d9460e7861e1dd7eebc7cf94c23567e418ff397babed077011711aae8d47171b5a81c5bd71d
languageName: node
linkType: hard
@@ -2201,12 +2211,12 @@ __metadata:
linkType: hard
"@typescript-eslint/eslint-plugin@npm:^5.30.7":
version: 5.50.0
resolution: "@typescript-eslint/eslint-plugin@npm:5.50.0"
version: 5.52.0
resolution: "@typescript-eslint/eslint-plugin@npm:5.52.0"
dependencies:
"@typescript-eslint/scope-manager": 5.50.0
"@typescript-eslint/type-utils": 5.50.0
"@typescript-eslint/utils": 5.50.0
"@typescript-eslint/scope-manager": 5.52.0
"@typescript-eslint/type-utils": 5.52.0
"@typescript-eslint/utils": 5.52.0
debug: ^4.3.4
grapheme-splitter: ^1.0.4
ignore: ^5.2.0
@@ -2220,43 +2230,43 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
checksum: 351c4a157a7d717cc3835bdc09324b20d649463738a029c5701e5a38cdb162305ff7d56adff196a0c3245c24ea3167bbdac7f1c30399b8c1d495abbdbc1c53d6
checksum: cff07ee94d8ab2a1b6c33b5c5bf641eff2bf2bebc0f35a9d8b3f128fd610e27a4aaf620bc2ad23608ad161b1810b7e32e5a2e0f746cc5094c3f506f7a14daa34
languageName: node
linkType: hard
"@typescript-eslint/parser@npm:^5.30.7":
version: 5.50.0
resolution: "@typescript-eslint/parser@npm:5.50.0"
version: 5.52.0
resolution: "@typescript-eslint/parser@npm:5.52.0"
dependencies:
"@typescript-eslint/scope-manager": 5.50.0
"@typescript-eslint/types": 5.50.0
"@typescript-eslint/typescript-estree": 5.50.0
"@typescript-eslint/scope-manager": 5.52.0
"@typescript-eslint/types": 5.52.0
"@typescript-eslint/typescript-estree": 5.52.0
debug: ^4.3.4
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
peerDependenciesMeta:
typescript:
optional: true
checksum: 816a421ce9a5c61a2e92499d6d400aed4211ca5b685e0212844b6659f7acfeba1cca0418b462236c44eea6e8a2574cd51ccb7abc2bf4a8cad5b7a275d71ae9bf
checksum: 1d8ff6e932f9c9db8d24b16ce89fd963f0982c38559e500aa1f8dc5cd66abd02f1659dd1a1361ce550def05331803caa69a69a039b54c94fc0f22919a2305c12
languageName: node
linkType: hard
"@typescript-eslint/scope-manager@npm:5.50.0":
version: 5.50.0
resolution: "@typescript-eslint/scope-manager@npm:5.50.0"
"@typescript-eslint/scope-manager@npm:5.52.0":
version: 5.52.0
resolution: "@typescript-eslint/scope-manager@npm:5.52.0"
dependencies:
"@typescript-eslint/types": 5.50.0
"@typescript-eslint/visitor-keys": 5.50.0
checksum: bd49447a834c82cb130e6900644042c3a84195bf7a63483385e90b6454c65856d6f276c997cad6bf9c36c9d0cb168fdde625ce4c78c3b8bcce42da782270794b
"@typescript-eslint/types": 5.52.0
"@typescript-eslint/visitor-keys": 5.52.0
checksum: 9a03fe30f8e90a5106c482478f213eefdd09f2f74e24d9dc59b453885466a758fe6d1cd24d706aed6188fb03c84b16ca6491cf20da6b16b8fc53cad8b8c327f2
languageName: node
linkType: hard
"@typescript-eslint/type-utils@npm:5.50.0":
version: 5.50.0
resolution: "@typescript-eslint/type-utils@npm:5.50.0"
"@typescript-eslint/type-utils@npm:5.52.0":
version: 5.52.0
resolution: "@typescript-eslint/type-utils@npm:5.52.0"
dependencies:
"@typescript-eslint/typescript-estree": 5.50.0
"@typescript-eslint/utils": 5.50.0
"@typescript-eslint/typescript-estree": 5.52.0
"@typescript-eslint/utils": 5.52.0
debug: ^4.3.4
tsutils: ^3.21.0
peerDependencies:
@@ -2264,23 +2274,23 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
checksum: d2fc2fd10ef300865fd6a902ae92aef6c45cddc4359445f1e5c6dc9511063b52d2170cc6b525763395d4171c177b3d0fffd77cf9a2ab7e01fcd7109bd1a5a585
checksum: ac5422040461febab8a2eeec76d969024ccff76203dec357f7220c9b5e0dde96e3e3a76fd4118d42b50bd5bfb3a194aaceeb63417a2ac4e1ebf5e687558a9a10
languageName: node
linkType: hard
"@typescript-eslint/types@npm:5.50.0":
version: 5.50.0
resolution: "@typescript-eslint/types@npm:5.50.0"
checksum: 1189c63d35abeec685dd519fd923926b884e63d5e10e4a9fe995aebfde59b8a2e10773090ec3ba32a0ec408746b18f6a454d9bedb0b6c7ce8b6066547144fb4d
"@typescript-eslint/types@npm:5.52.0":
version: 5.52.0
resolution: "@typescript-eslint/types@npm:5.52.0"
checksum: 018940d61aebf7cf3f7de1b9957446e2ea01f08fe950bef4788c716a3a88f7c42765fe7d80152b0d0428fcd4bd3ace2dfa8c459ba1c59d9a84e951642180f869
languageName: node
linkType: hard
"@typescript-eslint/typescript-estree@npm:5.50.0":
version: 5.50.0
resolution: "@typescript-eslint/typescript-estree@npm:5.50.0"
"@typescript-eslint/typescript-estree@npm:5.52.0":
version: 5.52.0
resolution: "@typescript-eslint/typescript-estree@npm:5.52.0"
dependencies:
"@typescript-eslint/types": 5.50.0
"@typescript-eslint/visitor-keys": 5.50.0
"@typescript-eslint/types": 5.52.0
"@typescript-eslint/visitor-keys": 5.52.0
debug: ^4.3.4
globby: ^11.1.0
is-glob: ^4.0.3
@@ -2289,35 +2299,35 @@ __metadata:
peerDependenciesMeta:
typescript:
optional: true
checksum: cb1ac8d39647da6d52750c713d9635750ed41245ec82f937a159a71ad3bf490ebabfad3b43eeca07bca39d60df30d3a2f31f8bed0061381731d92a62e284b867
checksum: 67d396907fee3d6894e26411a5098a37f07e5d50343189e6361ff7db91c74a7ffe2abd630d11f14c2bda1f4af13edf52b80b11cbccb55b44079c7cec14c9e108
languageName: node
linkType: hard
"@typescript-eslint/utils@npm:5.50.0, @typescript-eslint/utils@npm:^5.10.0, @typescript-eslint/utils@npm:^5.43.0":
version: 5.50.0
resolution: "@typescript-eslint/utils@npm:5.50.0"
"@typescript-eslint/utils@npm:5.52.0, @typescript-eslint/utils@npm:^5.10.0, @typescript-eslint/utils@npm:^5.43.0":
version: 5.52.0
resolution: "@typescript-eslint/utils@npm:5.52.0"
dependencies:
"@types/json-schema": ^7.0.9
"@types/semver": ^7.3.12
"@typescript-eslint/scope-manager": 5.50.0
"@typescript-eslint/types": 5.50.0
"@typescript-eslint/typescript-estree": 5.50.0
"@typescript-eslint/scope-manager": 5.52.0
"@typescript-eslint/types": 5.52.0
"@typescript-eslint/typescript-estree": 5.52.0
eslint-scope: ^5.1.1
eslint-utils: ^3.0.0
semver: ^7.3.7
peerDependencies:
eslint: ^6.0.0 || ^7.0.0 || ^8.0.0
checksum: 4471ae8b24449300e009f1cc09ee0d38cce20ae9171e8fbf4ef752ce4eb87104cc0d813d8f7051b619fa05e1e7c12b748dad49832911685297b1bbfef3c01f0b
checksum: 01906be5262ece36537e9d586e4d2d4791e05752a9354bcb42b1f5bf965f53daa13309c61c3dff5e201ea28c298e4e01cf0c93738afa0099fea0da3b1d8cb3a5
languageName: node
linkType: hard
"@typescript-eslint/visitor-keys@npm:5.50.0":
version: 5.50.0
resolution: "@typescript-eslint/visitor-keys@npm:5.50.0"
"@typescript-eslint/visitor-keys@npm:5.52.0":
version: 5.52.0
resolution: "@typescript-eslint/visitor-keys@npm:5.52.0"
dependencies:
"@typescript-eslint/types": 5.50.0
"@typescript-eslint/types": 5.52.0
eslint-visitor-keys: ^3.3.0
checksum: 55319cb7ee7b78d07d9dc67a388d69fe0b7f11cbc79190e17e7f87a39c9992d08dab3b5872d5a7f01094dda28ad6ac61d3573e59015ef70bf138d4c4f8c45b88
checksum: 33b44f0cd35b7b47f34e89d52e47b8d8200f55af306b22db4de104d79f65907458ea022e548f50d966e32fea150432ac9c1ae65b3001b0ad2ac8a17c0211f370
languageName: node
linkType: hard
@@ -2674,7 +2684,7 @@ __metadata:
languageName: node
linkType: hard
"axios@npm:^0.27.2":
"axios@npm:0.27.2, axios@npm:^0.27.2":
version: 0.27.2
resolution: "axios@npm:0.27.2"
dependencies:
@@ -2944,17 +2954,17 @@ __metadata:
linkType: hard
"cacheable-request@npm:^10.2.1":
version: 10.2.6
resolution: "cacheable-request@npm:10.2.6"
version: 10.2.7
resolution: "cacheable-request@npm:10.2.7"
dependencies:
"@types/http-cache-semantics": ^4.0.1
get-stream: ^6.0.1
http-cache-semantics: ^4.1.0
http-cache-semantics: ^4.1.1
keyv: ^4.5.2
mimic-response: ^4.0.0
normalize-url: ^8.0.0
responselike: ^3.0.0
checksum: 273d6cbcec025d2922a641c72eeb7e566963cc68da99248ff83053c9b140fe46ae1a856e7e8855378112d8d342ff2ec9398d1552a3a8ce4af8fbc21c606bda1f
checksum: 25cfbe0cab755bcee3bf6610b0253414e583289f795a28035616bf3186ecb303e8caf1943cbf42d92410b3f24124a1cdd663dd8ff52ac2c997a5129de5e9557a
languageName: node
linkType: hard
@@ -3005,9 +3015,9 @@ __metadata:
linkType: hard
"caniuse-lite@npm:^1.0.30001406, caniuse-lite@npm:^1.0.30001449":
version: 1.0.30001450
resolution: "caniuse-lite@npm:1.0.30001450"
checksum: 511b360bfc907b2e437699364cf96b83507bc45043926450056642332bcd6f65a1e72540c828534ae15e0ac906e3e9af46cb2bb84458dd580bc31478e9dce282
version: 1.0.30001452
resolution: "caniuse-lite@npm:1.0.30001452"
checksum: de02aad7b71112409f30de53e8080bef0fe612ed95bba8b14fb830f59683e8caabc27bdd520563686965be77f2cb56e239e44b920144630b91d7fe9911ba8ad5
languageName: node
linkType: hard
@@ -3073,9 +3083,9 @@ __metadata:
linkType: hard
"ci-info@npm:^3.2.0":
version: 3.7.1
resolution: "ci-info@npm:3.7.1"
checksum: 72d93d5101ea1c186511277fbd8d06ae8a6e028cc2fb94361e92bf735b39c5ebd192e8d15a66ff8c4e3ed569f87c2f844e96f90e141b2de5c649f77ec34ff601
version: 3.8.0
resolution: "ci-info@npm:3.8.0"
checksum: d0a4d3160497cae54294974a7246202244fff031b0a6ea20dd57b10ec510aa17399c41a1b0982142c105f3255aff2173e5c0dd7302ee1b2f28ba3debda375098
languageName: node
linkType: hard
@@ -3198,6 +3208,13 @@ __metadata:
languageName: node
linkType: hard
"compare-versions@npm:5.0.1":
version: 5.0.1
resolution: "compare-versions@npm:5.0.1"
checksum: 302a4e46224b47b9280cf894c6c87d8df912671fa391dcdbf0e63438d9b0a69fe20dd747fb439e8d54c43af016ff4eaaf0a4c9d8e7ca358bcd12dadf4ad2935e
languageName: node
linkType: hard
"concat-map@npm:0.0.1":
version: 0.0.1
resolution: "concat-map@npm:0.0.1"
@@ -3261,9 +3278,9 @@ __metadata:
linkType: hard
"core-js@npm:^3":
version: 3.27.2
resolution: "core-js@npm:3.27.2"
checksum: 718debd426f55a6b97cf9b757c936be258afd6d4f7052f89d0f96c982d7013e9000b0b006df42831a0cf32adad298e34d6a19052dce9ae1c7ab87162c0c665e0
version: 3.28.0
resolution: "core-js@npm:3.28.0"
checksum: 3155fd0ec16d0089106b145e9595280a4ea4bde0d7ff26aa14364cd4f1c203baf6620c3025acd284f363d08b9f21104101692766ca9a36ffeee7307bdf3e1881
languageName: node
linkType: hard
@@ -3355,7 +3372,14 @@ __metadata:
languageName: node
linkType: hard
"d3-format@npm:1 - 2, d3-format@npm:^1.4.4":
"d3-format@npm:1 - 2":
version: 2.0.0
resolution: "d3-format@npm:2.0.0"
checksum: c4d3c8f9941d097d514d3986f54f21434e08e5876dc08d1d65226447e8e167600d5b9210235bb03fd45327225f04f32d6e365f08f76d2f4b8bff81594851aaf7
languageName: node
linkType: hard
"d3-format@npm:^1.4.4":
version: 1.4.5
resolution: "d3-format@npm:1.4.5"
checksum: 1b8b2c0bca182173bccd290a43e8b635a83fc8cfe52ec878c7bdabb997d47daac11f2b175cebbe73f807f782ad655f542bdfe18180ca5eb3498a3a82da1e06ab
@@ -3419,14 +3443,7 @@ __metadata:
languageName: node
linkType: hard
"d3-time@npm:1 - 2, d3-time@npm:^1.0.11":
version: 1.1.0
resolution: "d3-time@npm:1.1.0"
checksum: 33fcfff94ff093dde2048c190ecca8b39fe0ec8b3c61e9fc39c5f6072ce5b86dd2b91823f086366995422bbbac7f74fd9abdb7efe4f292a73b1c6197c699cc78
languageName: node
linkType: hard
"d3-time@npm:^2.1.1":
"d3-time@npm:1 - 2, d3-time@npm:^2.1.1":
version: 2.1.1
resolution: "d3-time@npm:2.1.1"
dependencies:
@@ -3435,6 +3452,13 @@ __metadata:
languageName: node
linkType: hard
"d3-time@npm:^1.0.11":
version: 1.1.0
resolution: "d3-time@npm:1.1.0"
checksum: 33fcfff94ff093dde2048c190ecca8b39fe0ec8b3c61e9fc39c5f6072ce5b86dd2b91823f086366995422bbbac7f74fd9abdb7efe4f292a73b1c6197c699cc78
languageName: node
linkType: hard
"damerau-levenshtein@npm:^1.0.8":
version: 1.0.8
resolution: "damerau-levenshtein@npm:1.0.8"
@@ -3533,12 +3557,12 @@ __metadata:
linkType: hard
"define-properties@npm:^1.1.3, define-properties@npm:^1.1.4":
version: 1.1.4
resolution: "define-properties@npm:1.1.4"
version: 1.2.0
resolution: "define-properties@npm:1.2.0"
dependencies:
has-property-descriptors: ^1.0.0
object-keys: ^1.1.1
checksum: ce0aef3f9eb193562b5cfb79b2d2c86b6a109dfc9fdcb5f45d680631a1a908c06824ddcdb72b7573b54e26ace07f0a23420aaba0d5c627b34d2c1de8ef527e2b
checksum: e60aee6a19b102df4e2b1f301816804e81ab48bb91f00d0d935f269bf4b3f79c88b39e4f89eaa132890d23267335fd1140dfcd8d5ccd61031a0a2c41a54e33a6
languageName: node
linkType: hard
@@ -3706,9 +3730,9 @@ __metadata:
linkType: hard
"electron-to-chromium@npm:^1.4.284":
version: 1.4.286
resolution: "electron-to-chromium@npm:1.4.286"
checksum: 6b53e2aea63892cb4af85ea4ee5ed2b6d848713519987efcf4c1177a32e2fe6d04a7f591f5bcd1feab0b3c88890c6eaf65b6feb16c0e0319bf07e31de31930af
version: 1.4.297
resolution: "electron-to-chromium@npm:1.4.297"
checksum: d5b83384c378cb22e023abd9ad566abfd573ea7a24109b992f034752bcf77602b67b5a20064a8810ee6bd4db17547d80fa7e30c3602f57a503950e8063491eb2
languageName: node
linkType: hard
@@ -4094,13 +4118,13 @@ __metadata:
linkType: hard
"eslint-plugin-testing-library@npm:^5.5.1":
version: 5.10.0
resolution: "eslint-plugin-testing-library@npm:5.10.0"
version: 5.10.2
resolution: "eslint-plugin-testing-library@npm:5.10.2"
dependencies:
"@typescript-eslint/utils": ^5.43.0
peerDependencies:
eslint: ^7.5.0 || ^8.0.0
checksum: 3278fc4683a99d24ac2b6d2ed0359db1b0509674350e4b9a958a226f57b4b90e070c02e1f4c2806da885d8025c1e8c952cb9a5e9751e69baac3d12cfe6804000
checksum: 3b2b330e62f4a6dc438050006f0d0c97605f6861828b153271dc6d2fafb1e60f4e86fbaa8166c7afd452e3b6cad39413738fd4c8e2eb2def1915c678154676da
languageName: node
linkType: hard
@@ -4172,8 +4196,8 @@ __metadata:
linkType: hard
"eslint@npm:^8.20.0":
version: 8.33.0
resolution: "eslint@npm:8.33.0"
version: 8.34.0
resolution: "eslint@npm:8.34.0"
dependencies:
"@eslint/eslintrc": ^1.4.1
"@humanwhocodes/config-array": ^0.11.8
@@ -4216,7 +4240,7 @@ __metadata:
text-table: ^0.2.0
bin:
eslint: bin/eslint.js
checksum: 727e63ab8b7acf281442323c5971f6afdd5b656fbcebc4476cf54e35af51b2f180617433fc5e1952f0449ca3f43a905527f9407ea4b8a7ea7562fc9c3f278d4c
checksum: 4e13e9eb05ac2248efbb6acae0b2325091235d5c47ba91a4775c7d6760778cbcd358a773ebd42f4629d2ad89e27c02f5d66eb1f737d75d9f5fc411454f83b2e5
languageName: node
linkType: hard
@@ -4632,7 +4656,7 @@ __metadata:
languageName: node
linkType: hard
"get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3":
"get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.0":
version: 1.2.0
resolution: "get-intrinsic@npm:1.2.0"
dependencies:
@@ -4694,7 +4718,7 @@ __metadata:
languageName: node
linkType: hard
"glob@npm:7.1.7, glob@npm:^7.1.3, glob@npm:^7.1.4":
"glob@npm:7.1.7":
version: 7.1.7
resolution: "glob@npm:7.1.7"
dependencies:
@@ -4708,6 +4732,20 @@ __metadata:
languageName: node
linkType: hard
"glob@npm:^7.1.3, glob@npm:^7.1.4":
version: 7.2.3
resolution: "glob@npm:7.2.3"
dependencies:
fs.realpath: ^1.0.0
inflight: ^1.0.4
inherits: 2
minimatch: ^3.1.1
once: ^1.3.0
path-is-absolute: ^1.0.0
checksum: 29452e97b38fa704dabb1d1045350fb2467cf0277e155aa9ff7077e90ad81d1ea9d53d3ee63bd37c05b09a065e90f16aec4a65f5b8de401d1dac40bc5605d133
languageName: node
linkType: hard
"glob@npm:^8.0.1":
version: 8.1.0
resolution: "glob@npm:8.1.0"
@@ -4935,6 +4973,7 @@ __metadata:
"@ctrl/transmission": ^4.1.1
"@emotion/react": ^11.10.5
"@emotion/server": ^11.10.0
"@jellyfin/sdk": ^0.7.0
"@mantine/core": ^5.9.3
"@mantine/dates": ^5.9.3
"@mantine/dropzone": ^5.9.3
@@ -4995,6 +5034,7 @@ __metadata:
typescript: ^4.7.4
uuid: ^8.3.2
video.js: ^8.0.3
xml-js: ^1.6.11
yarn: ^1.22.19
zustand: ^4.1.4
languageName: unknown
@@ -5074,7 +5114,7 @@ __metadata:
languageName: node
linkType: hard
"http-cache-semantics@npm:^4.0.0, http-cache-semantics@npm:^4.1.0":
"http-cache-semantics@npm:^4.0.0, http-cache-semantics@npm:^4.1.0, http-cache-semantics@npm:^4.1.1":
version: 4.1.1
resolution: "http-cache-semantics@npm:4.1.1"
checksum: 83ac0bc60b17a3a36f9953e7be55e5c8f41acc61b22583060e8dedc9dd5e3607c823a88d0926f9150e571f90946835c7fe150732801010845c72cd8bbff1a236
@@ -5178,9 +5218,9 @@ __metadata:
linkType: hard
"immutable@npm:^4.0.0":
version: 4.2.3
resolution: "immutable@npm:4.2.3"
checksum: 11be9a328d5e3a35de47b7b7835e7d89f790bf19595a8de11e1ae19b2bb3be5def00c69928969f1607aa66fe4a3f48e95460b2b58894a83ce70b65c872466940
version: 4.2.4
resolution: "immutable@npm:4.2.4"
checksum: 3be84eded37b05e65cad57bfba630bc1bf170c498b7472144bc02d2650cc9baef79daf03574a9c2e41d195ebb55a1c12c9b312f41ee324b653927b24ad8bcaa7
languageName: node
linkType: hard
@@ -5259,13 +5299,13 @@ __metadata:
linkType: hard
"internal-slot@npm:^1.0.3, internal-slot@npm:^1.0.4":
version: 1.0.4
resolution: "internal-slot@npm:1.0.4"
version: 1.0.5
resolution: "internal-slot@npm:1.0.5"
dependencies:
get-intrinsic: ^1.1.3
get-intrinsic: ^1.2.0
has: ^1.0.3
side-channel: ^1.0.4
checksum: 8974588d06bab4f675573a3b52975370facf6486df51bc0567a982c7024fa29495f10b76c0d4dc742dd951d1b72024fdc1e31bb0bedf1678dc7aacacaf5a4f73
checksum: 97e84046bf9e7574d0956bd98d7162313ce7057883b6db6c5c7b5e5f05688864b0978ba07610c726d15d66544ffe4b1050107d93f8a39ebc59b15d8b429b497a
languageName: node
linkType: hard
@@ -6454,7 +6494,7 @@ __metadata:
languageName: node
linkType: hard
"minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.2":
"minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2":
version: 3.1.2
resolution: "minimatch@npm:3.1.2"
dependencies:
@@ -6472,14 +6512,7 @@ __metadata:
languageName: node
linkType: hard
"minimist@npm:^1.2.0, minimist@npm:^1.2.6":
version: 1.2.7
resolution: "minimist@npm:1.2.7"
checksum: 7346574a1038ca23c32e02252f603801f09384dd1d78b69a943a4e8c2c28730b80e96193882d3d3b22a063445f460e48316b29b8a25addca2d7e5e8f75478bec
languageName: node
linkType: hard
"minimist@npm:~1.2.5":
"minimist@npm:^1.2.0, minimist@npm:^1.2.6, minimist@npm:~1.2.5":
version: 1.2.8
resolution: "minimist@npm:1.2.8"
checksum: 75a6d645fb122dad29c06a7597bddea977258957ed88d7a6df59b5cd3fe4a527e253e9bbf2e783e4b73657f9098b96a5fe96ab8a113655d4109108577ecf85b0
@@ -6547,9 +6580,9 @@ __metadata:
linkType: hard
"minipass@npm:^4.0.0":
version: 4.0.1
resolution: "minipass@npm:4.0.1"
checksum: 48eb3141cc247b44f738944cbd789aedeed9288ebdb64c7de9b3bf23e9e71d611381bfecf643d877d25f7ca9f3d5ab7b6757ef6f46282086812ac5372b7cd291
version: 4.0.3
resolution: "minipass@npm:4.0.3"
checksum: a09f405e2f380ae7f6ee0cbb53b45c1fcc1b6c70fc3896f4d20649d92a10e61892c57bd9960a64cedf6c90b50022cb6c195905b515039c335b423202f99e6f18
languageName: node
linkType: hard
@@ -6600,14 +6633,14 @@ __metadata:
languageName: node
linkType: hard
"ms@npm:2.1.2, ms@npm:^2.1.1":
"ms@npm:2.1.2":
version: 2.1.2
resolution: "ms@npm:2.1.2"
checksum: 673cdb2c3133eb050c745908d8ce632ed2c02d85640e2edb3ace856a2266a813b30c613569bf3354fdf4ea7d1a1494add3bfa95e2713baa27d0c2c71fc44f58f
languageName: node
linkType: hard
"ms@npm:^2.0.0":
"ms@npm:^2.0.0, ms@npm:^2.1.1":
version: 2.1.3
resolution: "ms@npm:2.1.3"
checksum: aa92de608021b242401676e35cfa5aa42dd70cbdc082b916da7fb925c542173e36bce97ea3e804923fe92c0ad991434e4a38327e15a1b5b5f945d66df615ae6d
@@ -6803,9 +6836,9 @@ __metadata:
linkType: hard
"node-releases@npm:^2.0.8":
version: 2.0.9
resolution: "node-releases@npm:2.0.9"
checksum: 3ae6b1b300dc72c1a628861093d339a01aa017d3ad9017b0478384be29d6f9c93b9e26c91fce79728cecaadc04d0f16834b7ae1a018730e3e54962ec8c6aa86f
version: 2.0.10
resolution: "node-releases@npm:2.0.10"
checksum: d784ecde25696a15d449c4433077f5cce620ed30a1656c4abf31282bfc691a70d9618bae6868d247a67914d1be5cc4fde22f65a05f4398cdfb92e0fc83cadfbc
languageName: node
linkType: hard
@@ -7201,11 +7234,11 @@ __metadata:
linkType: hard
"prettier@npm:^2.7.1":
version: 2.8.3
resolution: "prettier@npm:2.8.3"
version: 2.8.4
resolution: "prettier@npm:2.8.4"
bin:
prettier: bin-prettier.js
checksum: 92f2ceb522d454370e02082aa74ad27388672f7cee8975028b59517c069fe643bdc73e322675c8faf2ff173d7a626d1a6389f26b474000308e793aa25fff46e5
checksum: c173064bf3df57b6d93d19aa98753b9b9dd7657212e33b41ada8e2e9f9884066bb9ca0b4005b89b3ab137efffdf8fbe0b462785aba20364798ff4303aadda57e
languageName: node
linkType: hard
@@ -7755,19 +7788,19 @@ __metadata:
linkType: hard
"sass@npm:^1.56.1":
version: 1.58.0
resolution: "sass@npm:1.58.0"
version: 1.58.1
resolution: "sass@npm:1.58.1"
dependencies:
chokidar: ">=3.0.0 <4.0.0"
immutable: ^4.0.0
source-map-js: ">=0.6.2 <2.0.0"
bin:
sass: sass.js
checksum: a7219634881d2de6441fb619787fb1a02e3fa0333fb715be26aa335ba49d6bdb4f1105d9df70a80a67200893022b08346745783dc49046095d94fc6e044492d6
checksum: ff079887d906b5c0dde99084d14ac36336d238c0c07935ff6381bad68f05de212c1ff12657ac1e8a0533523cd7a393126facdc2508d758e7d5700344a0e6ea51
languageName: node
linkType: hard
"sax@npm:>=0.6.0":
"sax@npm:>=0.6.0, sax@npm:^1.2.4":
version: 1.2.4
resolution: "sax@npm:1.2.4"
checksum: d3df7d32b897a2c2f28e941f732c71ba90e27c24f62ee918bd4d9a8cfb3553f2f81e5493c7f0be94a11c1911b643a9108f231dd6f60df3fa9586b5d2e3e9e1fe
@@ -8212,9 +8245,9 @@ __metadata:
linkType: hard
"tabbable@npm:^6.0.1":
version: 6.0.1
resolution: "tabbable@npm:6.0.1"
checksum: 65e378ad69a97416f2fdce34ade11b8ff68b33d9b2d978920a9d285c77e1bb88cb35113a8f00af8c4f0163d788d451a48840a216fa918d6a3f0c554951deb984
version: 6.1.0
resolution: "tabbable@npm:6.1.0"
checksum: 4ca476f10b031f213187078fcbe4b04884b6cf6f3a5f31175ce79ac03fc47ad11b74a8137922e78ac6bb007b50386140e2f9911182885ebc79d0cb7996697985
languageName: node
linkType: hard
@@ -8658,19 +8691,19 @@ __metadata:
linkType: hard
"v8-to-istanbul@npm:^9.0.1":
version: 9.0.1
resolution: "v8-to-istanbul@npm:9.0.1"
version: 9.1.0
resolution: "v8-to-istanbul@npm:9.1.0"
dependencies:
"@jridgewell/trace-mapping": ^0.3.12
"@types/istanbul-lib-coverage": ^2.0.1
convert-source-map: ^1.6.0
checksum: a49c34bf0a3af0c11041a3952a2600913904a983bd1bc87148b5c033bc5c1d02d5a13620fcdbfa2c60bc582a2e2970185780f0c844b4c3a220abf405f8af6311
checksum: 2069d59ee46cf8d83b4adfd8a5c1a90834caffa9f675e4360f1157ffc8578ef0f763c8f32d128334424159bb6b01f3876acd39cd13297b2769405a9da241f8d1
languageName: node
linkType: hard
"video.js@npm:^7 || ^8, video.js@npm:^8.0.3":
version: 8.0.3
resolution: "video.js@npm:8.0.3"
version: 8.0.4
resolution: "video.js@npm:8.0.4"
dependencies:
"@babel/runtime": ^7.12.5
"@videojs/http-streaming": 3.0.0
@@ -8686,7 +8719,7 @@ __metadata:
videojs-contrib-quality-levels: 3.0.0
videojs-font: 3.2.0
videojs-vtt.js: 0.15.4
checksum: 3bb4b334192116c8bcbe254a67fee1655cb829155845afaf274efe5bf8019f9a32081156f697b68b322af91853f0b843ffbbed572cefb307d5f47ea61c6c78b4
checksum: e106e7985355c8039a8534b9e506b7d3dd4685d247777e0a86af1a7396c0c11048efb3d1a954e759250c2576516c8c4099d9039c16857ed4d21f182328a71fa2
languageName: node
linkType: hard
@@ -8868,6 +8901,17 @@ __metadata:
languageName: node
linkType: hard
"xml-js@npm:^1.6.11":
version: 1.6.11
resolution: "xml-js@npm:1.6.11"
dependencies:
sax: ^1.2.4
bin:
xml-js: ./bin/cli.js
checksum: 24a55479919413687105fc2d8ab05e613ebedb1c1bc12258a108e07cff5ef793779297db854800a4edf0281303ebd1f177bc4a588442f5344e62b3dddda26c2b
languageName: node
linkType: hard
"xml2js@npm:^0.4.19":
version: 0.4.23
resolution: "xml2js@npm:0.4.23"
@@ -8969,8 +9013,8 @@ __metadata:
linkType: hard
"zustand@npm:^4.1.4":
version: 4.3.2
resolution: "zustand@npm:4.3.2"
version: 4.3.3
resolution: "zustand@npm:4.3.3"
dependencies:
use-sync-external-store: 1.2.0
peerDependencies:
@@ -8981,6 +9025,6 @@ __metadata:
optional: true
react:
optional: true
checksum: fc443abf5bc9deac0d4e375847e7914e44c7ffc9f7f09b60e466cb9bbbcf5a46706bf2f9c8b9e6e6c9a1c5aea0bd6123cbf9fbcd39788ae27d8494d505969ae8
checksum: fe0277ab0ce14849dea254cbdcfe83d4614364d38e616875f75ef2419f29085f5b03605efabeb33189a4557e647efaa294e0984c4f642e0566f445a7b207cdd6
languageName: node
linkType: hard