diff --git a/.github/workflows/release-matrix.yml b/.github/workflows/release-matrix.yml index 288abcb..981cf59 100644 --- a/.github/workflows/release-matrix.yml +++ b/.github/workflows/release-matrix.yml @@ -8,9 +8,10 @@ jobs: build: strategy: matrix: - build_type: [ ubuntu, macos, windows ] + build_type: [ linux, macos, windows ] + build_arch: [ x64 ] gui: [ gui, cli ] - runs-on: ${{ matrix.build_type }}-latest + runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v2 @@ -38,7 +39,7 @@ jobs: with: upload_url: ${{ github.event.release.upload_url }} asset_name: multi-downloader-nx-${{ matrix.build_type }}-${{ matrix.gui }}.7z - asset_path: ./lib/_builds/multi-downloader-nx-${{ matrix.build_type }}64-${{ matrix.gui }}.7z + asset_path: ./lib/_builds/multi-downloader-nx-${{ matrix.build_type }}-${{ matrix.build_arch }}-${{ matrix.gui }}.7z asset_content_type: application/x-7z-compressed env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} diff --git a/.gitignore b/.gitignore index dcd8c76..9ac97e5 100644 --- a/.gitignore +++ b/.gitignore @@ -24,6 +24,7 @@ cr_token.yml hd_profile.yml hd_sess.yml hd_token.yml +hd_new_token.yml archive.json guistate.json fonts @@ -37,4 +38,7 @@ crunchyendpoints /logs /tmp/*/ /videos/*/ -/tmp/*.* \ No newline at end of file +/tmp/*.* +bin +widevine/* +!widevine/.gitkeep diff --git a/@types/crunchyAndroidEpisodes.d.ts b/@types/crunchyAndroidEpisodes.d.ts index 35845bd..c5488c0 100644 --- a/@types/crunchyAndroidEpisodes.d.ts +++ b/@types/crunchyAndroidEpisodes.d.ts @@ -1,3 +1,5 @@ +import { Images } from './crunchyEpisodeList'; + export interface CrunchyAndroidEpisodes { __class__: string; __href__: string; @@ -5,13 +7,13 @@ export interface CrunchyAndroidEpisodes { __links__: Actions; __actions__: Actions; total: number; - items: CrunchyEpisode[]; + items: CrunchyAndroidEpisode[]; } export interface Actions { } -export interface CrunchyEpisode { +export interface CrunchyAndroidEpisode { __class__: string; __href__: string; __resource_key__: string; @@ -19,7 +21,7 @@ export interface CrunchyEpisode { __actions__: Actions; playback: string; id: string; - channel_id: string; + channel_id: ChannelID; series_id: string; series_title: string; series_slug_title: string; @@ -37,19 +39,19 @@ export interface CrunchyEpisode { next_episode_id: string; next_episode_title: string; hd_flag: boolean; - maturity_ratings: string[]; + maturity_ratings: MaturityRating[]; extended_maturity_rating: Actions; is_mature: boolean; mature_blocked: boolean; - episode_air_date: string; - upload_date: string; - availability_starts: string; - availability_ends: string; + episode_air_date: Date; + upload_date: Date; + availability_starts: Date; + availability_ends: Date; eligible_region: string; available_date: Date; - free_available_date: string; + free_available_date: Date; premium_date: Date; - premium_available_date: string; + premium_available_date: Date; is_subbed: boolean; is_dubbed: boolean; is_clip: boolean; @@ -57,13 +59,13 @@ export interface CrunchyEpisode { seo_description: string; season_tags: string[]; available_offline: boolean; - subtitle_locales: string[]; + subtitle_locales: Locale[]; availability_notes: string; - audio_locale: string; + audio_locale: Locale; versions: Version[]; closed_captions_available: boolean; identifier: string; - media_type: string; + media_type: MediaType; slug: string; images: Images; duration_ms: number; @@ -76,21 +78,17 @@ export interface CrunchyEpisode { } export interface Links { - 'episode/channel': EpisodeChannel; - 'episode/next_episode': EpisodeChannel; - 'episode/season': EpisodeChannel; - 'episode/series': EpisodeChannel; - streams: EpisodeChannel; + 'episode/channel': Link; + 'episode/next_episode': Link; + 'episode/season': Link; + 'episode/series': Link; + streams: Link; } -export interface EpisodeChannel { +export interface Link { href: string; } -export interface Images { - thumbnail: Array; -} - export interface Thumbnail { width: number; height: number; @@ -117,6 +115,18 @@ export enum Locale { jaJP = 'ja-JP', } +export enum MediaType { + Episode = 'episode', +} + +export enum ChannelID { + Crunchyroll = 'crunchyroll', +} + +export enum MaturityRating { + Tv14 = 'TV-14', +} + export interface Version { audio_locale: Locale; guid: string; diff --git a/@types/crunchyAndroidStreams.d.ts b/@types/crunchyAndroidStreams.d.ts index 637995c..c5e9889 100644 --- a/@types/crunchyAndroidStreams.d.ts +++ b/@types/crunchyAndroidStreams.d.ts @@ -3,18 +3,35 @@ export interface CrunchyAndroidStreams { __href__: string; __resource_key__: string; __links__: Links; - __actions__: Actions; + __actions__: Record; media_id: string; - audio_locale: string; - subtitles: { [key: string]: Subtitle }; - closed_captions: Actions; + audio_locale: Locale; + subtitles: Subtitles; + closed_captions: Subtitles; streams: Streams; bifs: string[]; versions: Version[]; - captions: Actions; + captions: Record; } -export interface Actions { +export interface Subtitles { + '': Subtitle; + 'en-US'?: Subtitle; + 'es-LA'?: Subtitle; + 'es-419'?: Subtitle; + 'es-ES'?: Subtitle; + 'pt-BR'?: Subtitle; + 'fr-FR'?: Subtitle; + 'de-DE'?: Subtitle; + 'ar-ME'?: Subtitle; + 'ar-SA'?: Subtitle; + 'it-IT'?: Subtitle; + 'ru-RU'?: Subtitle; + 'tr-TR'?: Subtitle; + 'hi-IN'?: Subtitle; + 'zh-CN'?: Subtitle; + 'ko-KR'?: Subtitle; + 'ja-JP'?: Subtitle; } export interface Links { @@ -30,7 +47,7 @@ export interface Streams { } export interface Download { - hardsub_locale: string; + hardsub_locale: Locale; hardsub_lang?: string; url: string; } @@ -40,13 +57,13 @@ export interface Urls { } export interface Subtitle { - locale: string; + locale: Locale; url: string; format: string; } export interface Version { - audio_locale: string; + audio_locale: Locale; guid: string; original: boolean; variant: string; @@ -54,3 +71,23 @@ export interface Version { media_guid: string; is_premium_only: boolean; } + +export enum Locale { + default = '', + enUS = 'en-US', + esLA = 'es-LA', + es419 = 'es-419', + esES = 'es-ES', + ptBR = 'pt-BR', + frFR = 'fr-FR', + deDE = 'de-DE', + arME = 'ar-ME', + arSA = 'ar-SA', + itIT = 'it-IT', + ruRU = 'ru-RU', + trTR = 'tr-TR', + hiIN = 'hi-IN', + zhCN = 'zh-CN', + koKR = 'ko-KR', + jaJP = 'ja-JP', +} \ No newline at end of file diff --git a/@types/crunchyChapters.d.ts b/@types/crunchyChapters.d.ts new file mode 100644 index 0000000..5aafdb3 --- /dev/null +++ b/@types/crunchyChapters.d.ts @@ -0,0 +1,26 @@ +export interface CrunchyChapters { + [key: string]: CrunchyChapter; + lastUpdate: Date; + mediaId: string; +} + +export interface CrunchyChapter { + approverId: string; + distributionNumber: string; + end: number; + start: number; + title: string; + seriesId: string; + new: boolean; + type: string; +} + +export interface CrunchyOldChapter { + media_id: string; + startTime: number; + endTime: number; + duration: number; + comparedWith: string; + ordering: string; + last_updated: Date; +} \ No newline at end of file diff --git a/@types/crunchyEpisodeList.d.ts b/@types/crunchyEpisodeList.d.ts index ee1fb15..2f57ca4 100644 --- a/@types/crunchyEpisodeList.d.ts +++ b/@types/crunchyEpisodeList.d.ts @@ -1,3 +1,5 @@ +import { Links } from './crunchyAndroidEpisodes'; + export interface CrunchyEpisodeList { total: number; data: CrunchyEpisode[]; @@ -41,27 +43,28 @@ export interface CrunchyEpisode { listing_id: string; episode_air_date: Date; slug: string; - available_date: null; + available_date: Date; subtitle_locales: Locale[]; slug_title: string; available_offline: boolean; description: string; is_subbed: boolean; - premium_date: null; + premium_date: Date; upload_date: Date; season_slug_title: string; closed_captions_available: boolean; episode_number: number; season_tags: any[]; maturity_ratings: MaturityRating[]; - streams_link: string; + streams_link?: string; mature_blocked: boolean; is_clip: boolean; hd_flag: boolean; - hide_season_title?: boolean; - hide_season_number?: boolean; - isSelected?: boolean; - seq_id: string; + hide_season_title?: boolean; + hide_season_number?: boolean; + isSelected?: boolean; + seq_id: string; + __links__?: Links; } export enum Locale { @@ -127,5 +130,5 @@ export interface Version { } export interface Meta { - versions_considered: boolean; + versions_considered?: boolean; } \ No newline at end of file diff --git a/@types/crunchyTypes.d.ts b/@types/crunchyTypes.d.ts index 7e4bf41..a4d24f1 100644 --- a/@types/crunchyTypes.d.ts +++ b/@types/crunchyTypes.d.ts @@ -31,9 +31,14 @@ export type CrunchyDownloadOptions = { dlVideoOnce: boolean, skipmux?: boolean, syncTiming: boolean, + nocleanup: boolean, + chapters: boolean, + fontName: string | undefined, + fontSize: number, + dubLang: string[], } -export type CurnchyMultiDownload = { +export type CrunchyMultiDownload = { dubLang: string[], all?: boolean, but?: boolean, @@ -82,8 +87,18 @@ export type DownloadedMedia = { lang: LanguageItem, path: string, isPrimary?: boolean +} | { + type: 'Audio', + lang: LanguageItem, + path: string, + isPrimary?: boolean +} | { + type: 'Chapters', + lang: LanguageItem, + path: string } | ({ type: 'Subtitle', + signs: boolean, cc: boolean } & sxItem ) diff --git a/@types/messageHandler.d.ts b/@types/messageHandler.d.ts index 3929178..7e63da4 100644 --- a/@types/messageHandler.d.ts +++ b/@types/messageHandler.d.ts @@ -40,7 +40,7 @@ export type QueueItem = { q: number, dlVideoOnce: boolean, dubLang: string[], - image: string + image: string, } & ResolveItemsData export type ResolveItemsData = { @@ -106,7 +106,9 @@ export type FuniStreamData = { force?: 'Y'|'y'|'N'|'n'|'C'|'c', callbackMaker?: forceMuxer: AvailableMuxer | undefined, simul: boolean, skipSubMux: boolean, nocleanup: boolean, override: string[], videoTitle: string, ffmpegOptions: string[], mkvmergeOptions: string[], defaultAudio: LanguageItem, defaultSub: LanguageItem, ccTag: string } export type FuniSubsData = { nosubs?: boolean, sub: boolean, dlsubs: string[], ccTag: string } -export type DownloadData = { id: string, e: string, dubLang: string[], dlsubs: string[], fileName: string, q: number, novids: boolean, noaudio: boolean, dlVideoOnce: boolean } +export type DownloadData = { + hslang?: string; id: string, e: string, dubLang: string[], dlsubs: string[], fileName: string, q: number, novids: boolean, noaudio: boolean, dlVideoOnce: boolean +} export type AuthResponse = ResponseBase; export type FuniSearchReponse = ResponseBase; diff --git a/@types/mpd-parser.d.ts b/@types/mpd-parser.d.ts new file mode 100644 index 0000000..516cf2a --- /dev/null +++ b/@types/mpd-parser.d.ts @@ -0,0 +1,71 @@ +declare module 'mpd-parser' { + export type Segment = { + uri: string, + timeline: number, + duration: number, + resolvedUri: string, + map: { + uri: string, + resolvedUri: string, + }, + number: number, + presentationTime: number + } + + export type Playlist = { + attributes: { + NAME: string, + BANDWIDTH: number, + CODECS: string, + 'PROGRAM-ID': number, + // Following for video only + 'FRAME-RATE'?: number, + AUDIO?: string, // audio stream name + SUBTITLES?: string, + RESOLUTION?: { + width: number, + height: number + } + }, + uri: string, + endList: boolean, + timeline: number, + resolvedUri: string, + targetDuration: number, + discontinuitySequence: number, + discontinuityStarts: [], + timelineStarts: { + start: number, + timeline: number + }[], + mediaSequence: number, + contentProtection?: { + [type: string]: { + pssh?: Uint8Array + } + } + segments: Segment[] + } + + export type Manifest = { + allowCache: boolean, + discontinuityStarts: [], + segments: [], + endList: true, + duration: number, + playlists: Playlist[], + mediaGroups: { + AUDIO: { + audio: { + [name: string]: { + language: string, + autoselect: boolean, + default: boolean, + playlists: Playlist[] + } + } + } + } + } + export function parse(manifest: string): Manifest +} diff --git a/@types/newHidiveEpisode.d.ts b/@types/newHidiveEpisode.d.ts new file mode 100644 index 0000000..90fe2c7 --- /dev/null +++ b/@types/newHidiveEpisode.d.ts @@ -0,0 +1,43 @@ +export interface NewHidiveEpisode { + description: string; + duration: number; + title: string; + categories: string[]; + contentDownload: ContentDownload; + favourite: boolean; + subEvents: any[]; + thumbnailUrl: string; + longDescription: string; + posterUrl: string; + offlinePlaybackLanguages: string[]; + externalAssetId: string; + maxHeight: number; + rating: Rating; + episodeInformation: EpisodeInformation; + id: number; + accessLevel: string; + playerUrlCallback: string; + thumbnailsPreview: string; + displayableTags: any[]; + plugins: any[]; + watchStatus: string; + computedReleases: any[]; + licences: any[]; + type: string; +} + +export interface ContentDownload { + permission: string; + period: string; +} + +export interface EpisodeInformation { + seasonNumber: number; + episodeNumber: number; + season: number; +} + +export interface Rating { + rating: string; + descriptors: any[]; +} \ No newline at end of file diff --git a/@types/newHidivePlayback.d.ts b/@types/newHidivePlayback.d.ts new file mode 100644 index 0000000..f25c863 --- /dev/null +++ b/@types/newHidivePlayback.d.ts @@ -0,0 +1,33 @@ +export interface NewHidivePlayback { + watermark: null; + skipMarkers: any[]; + annotations: null; + dash: Format[]; + hls: Format[]; +} + +export interface Format { + subtitles: Subtitle[]; + url: string; + drm: DRM; +} + +export interface DRM { + encryptionMode: string; + containerType: string; + jwtToken: string; + url: string; + keySystems: string[]; +} + +export interface Subtitle { + format: Formats; + language: string; + url: string; +} + +export enum Formats { + Scc = 'scc', + Srt = 'srt', + Vtt = 'vtt', +} diff --git a/@types/newHidiveSearch.d.ts b/@types/newHidiveSearch.d.ts new file mode 100644 index 0000000..60c70c2 --- /dev/null +++ b/@types/newHidiveSearch.d.ts @@ -0,0 +1,91 @@ +export interface NewHidiveSearch { + results: Result[]; +} + +export interface Result { + hits: Hit[]; + nbHits: number; + page: number; + nbPages: number; + hitsPerPage: number; + exhaustiveNbHits: boolean; + exhaustiveTypo: boolean; + exhaustive: Exhaustive; + query: string; + params: string; + index: string; + renderingContent: RenderingContent; + processingTimeMS: number; + processingTimingsMS: ProcessingTimingsMS; + serverTimeMS: number; +} + +export interface Exhaustive { + nbHits: boolean; + typo: boolean; +} + +export interface Hit { + type: string; + weight: number; + id: number; + name: string; + description: string; + meta: RenderingContent; + coverUrl: string; + smallCoverUrl: string; + seasonsCount: number; + tags: string[]; + localisations: HitLocalisations; + ratings: Ratings; + objectID: string; + _highlightResult: HighlightResult; +} + +export interface HighlightResult { + name: Description; + description: Description; + tags: Description[]; + localisations: HighlightResultLocalisations; +} + +export interface Description { + value: string; + matchLevel: string; + matchedWords: string[]; + fullyHighlighted?: boolean; +} + +export interface HighlightResultLocalisations { + en_US: PurpleEnUS; +} + +export interface PurpleEnUS { + title: Description; + description: Description; +} + +export interface HitLocalisations { + [language: string]: HitLocalization; +} + +export interface HitLocalization { + title: string; + description: string; +} + +export interface RenderingContent { +} + +export interface Ratings { + US: string[]; +} + +export interface ProcessingTimingsMS { + _request: Request; +} + +export interface Request { + queue: number; + roundTrip: number; +} diff --git a/@types/newHidiveSeason.d.ts b/@types/newHidiveSeason.d.ts new file mode 100644 index 0000000..0ed1b37 --- /dev/null +++ b/@types/newHidiveSeason.d.ts @@ -0,0 +1,89 @@ +export interface NewHidiveSeason { + title: string; + description: string; + longDescription: string; + smallCoverUrl: string; + coverUrl: string; + titleUrl: string; + posterUrl: string; + seasonNumber: number; + episodeCount: number; + displayableTags: any[]; + rating: Rating; + contentRating: Rating; + id: number; + series: Series; + episodes: Episode[]; + paging: Paging; + licences: any[]; +} + +export interface Rating { + rating: string; + descriptors: any[]; +} + +export interface Episode { + accessLevel: string; + availablePurchases?: any[]; + licenceIds?: any[]; + type: string; + id: number; + title: string; + description: string; + thumbnailUrl: string; + posterUrl: string; + duration: number; + favourite: boolean; + contentDownload: ContentDownload; + offlinePlaybackLanguages: string[]; + externalAssetId: string; + subEvents: any[]; + maxHeight: number; + thumbnailsPreview: string; + longDescription: string; + episodeInformation: EpisodeInformation; + categories: string[]; + displayableTags: any[]; + watchStatus: string; + computedReleases: any[]; +} + +export interface ContentDownload { + permission: string; +} + +export interface EpisodeInformation { + seasonNumber: number; + episodeNumber: number; + season: number; +} + +export interface Paging { + moreDataAvailable: boolean; + lastSeen: number; +} + +export interface Series { + seriesId: number; + title: string; + description: string; + longDescription: string; + displayableTags: any[]; + rating: Rating; + contentRating: Rating; +} + +export interface NewHidiveSeriesExtra extends Series { + season: NewHidiveSeason; +} + +export interface NewHidiveEpisodeExtra extends Episode { + titleId: number; + nameLong: string; + seasonTitle: string; + seriesTitle: string; + seriesId?: number; + isSelected: boolean; + jwtToken?: string; +} \ No newline at end of file diff --git a/@types/newHidiveSeries.d.ts b/@types/newHidiveSeries.d.ts new file mode 100644 index 0000000..4391406 --- /dev/null +++ b/@types/newHidiveSeries.d.ts @@ -0,0 +1,35 @@ +export interface NewHidiveSeries { + id: number; + title: string; + description: string; + longDescription: string; + smallCoverUrl: string; + coverUrl: string; + titleUrl: string; + posterUrl: string; + seasons: Season[]; + rating: Rating; + contentRating: Rating; + displayableTags: any[]; + paging: Paging; +} + +export interface Rating { + rating: string; + descriptors: any[]; +} + +export interface Paging { + moreDataAvailable: boolean; + lastSeen: number; +} + +export interface Season { + title: string; + description: string; + longDescription: string; + seasonNumber: number; + episodeCount: number; + displayableTags: any[]; + id: number; +} diff --git a/@types/playbackData.d.ts b/@types/playbackData.d.ts index f326a7b..1b6548e 100644 --- a/@types/playbackData.d.ts +++ b/@types/playbackData.d.ts @@ -1,7 +1,7 @@ // Generated by https://quicktype.io export interface PlaybackData { total: number; - data: { [key: string]: { [key: string]: StreamDetails } }; + data: [{ [key: string]: { [key: string]: StreamDetails } }]; meta: Meta; } @@ -56,7 +56,7 @@ export interface Meta { bifs: string[]; versions: Version[]; audio_locale: Locale; - closed_captions: Record; + closed_captions: Subtitles; captions: Record; } diff --git a/Dockerfile b/Dockerfile index 54b108e..9d5ee24 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,13 +15,13 @@ RUN echo 'ffmpeg: "./bin/ffmpeg/ffmpeg"\nmkvmerge: "./bin/mkvtoolnix/mkvmerge"' RUN npm install -g pnpm RUN pnpm i -RUN pnpm run build-ubuntu-gui +RUN pnpm run build-linux-gui # Move build to new Clean Image FROM node WORKDIR "/app" -COPY --from=builder /app/lib/_builds/multi-downloader-nx-ubuntu64-gui ./ +COPY --from=builder /app/lib/_builds/multi-downloader-nx-linux-x64-gui ./ # Install mkvmerge and ffmpeg diff --git a/config/bin-path.yml b/config/bin-path.yml index 3a5de1e..8c08eb7 100644 --- a/config/bin-path.yml +++ b/config/bin-path.yml @@ -1,3 +1,4 @@ ffmpeg: "ffmpeg.exe" mkvmerge: "mkvmerge.exe" ffprobe: "ffprobe.exe" +mp4decrypt: "mp4decrypt.exe" diff --git a/crunchy.ts b/crunchy.ts index 592cb43..67db123 100644 --- a/crunchy.ts +++ b/crunchy.ts @@ -4,11 +4,13 @@ import fs from 'fs-extra'; // package program import packageJson from './package.json'; + // plugins import { console } from './modules/log'; import shlp from 'sei-helper'; import m3u8 from 'm3u8-parsed'; -import streamdl from './modules/hls-download'; +import streamdl, { M3U8Json } from './modules/hls-download'; +import { exec } from './modules/sei-helper-fixes'; // custom modules import * as fontsData from './modules/module.fontsData'; @@ -16,6 +18,8 @@ import * as langsData from './modules/module.langsData'; import * as yamlCfg from './modules/module.cfg-loader'; import * as yargs from './modules/module.app-args'; import Merger, { Font, MergerInput, SubtitleInput } from './modules/module.merger'; +import getKeys, { canDecrypt } from './modules/widevine'; +//import vttConvert from './modules/module.vttconvert'; // args @@ -23,19 +27,21 @@ import Merger, { Font, MergerInput, SubtitleInput } from './modules/module.merge import { domain, api } from './modules/module.api-urls'; import * as reqModule from './modules/module.req'; import { CrunchySearch } from './@types/crunchySearch'; -//import { CrunchyEpisodeList, CrunchyEpisode } from './@types/crunchyEpisodeList'; -import { CrunchyDownloadOptions, CrunchyEpMeta, CrunchyMuxOptions, CurnchyMultiDownload, DownloadedMedia, ParseItem, SeriesSearch, SeriesSearchItem } from './@types/crunchyTypes'; +import { CrunchyEpisodeList, CrunchyEpisode } from './@types/crunchyEpisodeList'; +import { CrunchyDownloadOptions, CrunchyEpMeta, CrunchyMuxOptions, CrunchyMultiDownload, DownloadedMedia, ParseItem, SeriesSearch, SeriesSearchItem } from './@types/crunchyTypes'; import { ObjectInfo } from './@types/objectInfo'; import parseFileName, { Variable } from './modules/module.filename'; -//import { PlaybackData } from './@types/playbackData'; +import { PlaybackData } from './@types/playbackData'; import { downloaded } from './modules/module.downloadArchive'; import parseSelect from './modules/module.parseSelect'; import { AvailableFilenameVars, getDefault } from './modules/module.args'; import { AuthData, AuthResponse, Episode, ResponseBase, SearchData, SearchResponse, SearchResponseItem } from './@types/messageHandler'; import { ServiceClass } from './@types/serviceClassInterface'; import { CrunchyAndroidStreams } from './@types/crunchyAndroidStreams'; -import { CrunchyAndroidEpisodes, CrunchyEpisode } from './@types/crunchyAndroidEpisodes'; +import { CrunchyAndroidEpisodes } from './@types/crunchyAndroidEpisodes'; +import { parse } from './modules/module.transform-mpd'; import { CrunchyAndroidObject } from './@types/crunchyAndroidObject'; +import { CrunchyChapters, CrunchyChapter, CrunchyOldChapter } from './@types/crunchyChapters'; export type sxItem = { language: langsData.LanguageItem, @@ -47,6 +53,7 @@ export type sxItem = { export default class Crunchy implements ServiceClass { public cfg: yamlCfg.ConfigObject; + public api: 'android' | 'web'; private token: Record; private req: reqModule.Req; private cmsToken: { @@ -59,6 +66,7 @@ export default class Crunchy implements ServiceClass { this.cfg = yamlCfg.loadCfg(); this.token = yamlCfg.loadCRToken(); this.req = new reqModule.Req(domain, debug, false, 'cr'); + this.api = 'android'; } public checkToken(): boolean { @@ -68,6 +76,7 @@ export default class Crunchy implements ServiceClass { public async cli() { console.info(`\n=== Multi Downloader NX ${packageJson.version} ===\n`); const argv = yargs.appArgv(this.cfg.cli); + this.api = argv.crapi; if (argv.debug) this.debug = true; @@ -110,7 +119,7 @@ export default class Crunchy implements ServiceClass { const selected = await this.downloadFromSeriesID(argv.series, { ...argv }); if (selected.isOk) { for (const select of selected.value) { - if (!(await this.downloadEpisode(select, {...argv, skipsubs: false }, true))) { + if (!(await this.downloadEpisode(select, {...argv, skipsubs: false}, true))) { console.error(`Unable to download selected episode ${select.episodeNumber}`); return false; } @@ -141,9 +150,13 @@ export default class Crunchy implements ServiceClass { } else if(argv.e){ await this.refreshToken(); + if (argv.dubLang.length > 1) { + console.info('One show can only be downloaded with one dub. Use --srz instead.'); + } + argv.dubLang = [argv.dubLang[0]]; const selected = await this.getObjectById(argv.e, false); for (const select of selected as Partial[]) { - if (!(await this.downloadEpisode(select as CrunchyEpMeta, {...argv, skipsubs: false }))) { + if (!(await this.downloadEpisode(select as CrunchyEpMeta, {...argv, skipsubs: false}))) { console.error(`Unable to download selected episode ${select.episodeNumber}`); return false; } @@ -151,9 +164,13 @@ export default class Crunchy implements ServiceClass { return true; } else if (argv.extid) { await this.refreshToken(); + if (argv.dubLang.length > 1) { + console.info('One show can only be downloaded with one dub. Use --srz instead.'); + } + argv.dubLang = [argv.dubLang[0]]; const selected = await this.getObjectById(argv.extid, false, true); for (const select of selected as Partial[]) { - if (!(await this.downloadEpisode(select as CrunchyEpMeta, {...argv, skipsubs: false }))) { + if (!(await this.downloadEpisode(select as CrunchyEpMeta, {...argv, skipsubs: false}))) { console.error(`Unable to download selected episode ${select.episodeNumber}`); return false; } @@ -350,6 +367,7 @@ export default class Crunchy implements ServiceClass { this.cmsToken.cms.bucket, '/index?', new URLSearchParams({ + 'preferred_audio_language': 'ja-JP', 'Policy': this.cmsToken.cms.policy, 'Signature': this.cmsToken.cms.signature, 'Key-Pair-Id': this.cmsToken.cms.key_pair_id, @@ -766,27 +784,42 @@ export default class Crunchy implements ServiceClass { const showInfo = JSON.parse(showInfoReq.res.body); this.logObject(showInfo.data[0], 0); + let episodeList = { total: 0, data: [], meta: {} } as CrunchyEpisodeList; //get episode info - const reqEpsListOpts = [ - api.beta_cms, - this.cmsToken.cms.bucket, - '/episodes?', - new URLSearchParams({ - 'season_id': id, - 'Policy': this.cmsToken.cms.policy, - 'Signature': this.cmsToken.cms.signature, - 'Key-Pair-Id': this.cmsToken.cms.key_pair_id, - }), - ].join(''); - - const reqEpsList = await this.req.getData(reqEpsListOpts, AuthHeaders); - //const reqEpsList = await this.req.getData(`${api.cms}/seasons/${id}/episodes?preferred_audio_language=ja-JP`, AuthHeaders); - if(!reqEpsList.ok || !reqEpsList.res){ - console.error('Episode List Request FAILED!'); - return { isOk: false, reason: new Error('Episode List request failed. No more information provided.') }; + if (this.api == 'android') { + const reqEpsListOpts = [ + api.beta_cms, + this.cmsToken.cms.bucket, + '/episodes?', + new URLSearchParams({ + 'preferred_audio_language': 'ja-JP', + 'season_id': id, + 'Policy': this.cmsToken.cms.policy, + 'Signature': this.cmsToken.cms.signature, + 'Key-Pair-Id': this.cmsToken.cms.key_pair_id, + }), + ].join(''); + const reqEpsList = await this.req.getData(reqEpsListOpts, AuthHeaders); + if(!reqEpsList.ok || !reqEpsList.res){ + console.error('Episode List Request FAILED!'); + return { isOk: false, reason: new Error('Episode List request failed. No more information provided.') }; + } + //CrunchyEpisodeList + const episodeListAndroid = JSON.parse(reqEpsList.res.body) as CrunchyAndroidEpisodes; + episodeList = { + total: episodeListAndroid.total, + data: episodeListAndroid.items, + meta: {} + }; + } else { + const reqEpsList = await this.req.getData(`${api.cms}/seasons/${id}/episodes?preferred_audio_language=ja-JP`, AuthHeaders); + if(!reqEpsList.ok || !reqEpsList.res){ + console.error('Episode List Request FAILED!'); + return { isOk: false, reason: new Error('Episode List request failed. No more information provided.') }; + } + //CrunchyEpisodeList + episodeList = JSON.parse(reqEpsList.res.body) as CrunchyEpisodeList; } - //CrunchyEpisodeList - const episodeList = JSON.parse(reqEpsList.res.body) as CrunchyAndroidEpisodes; const epNumList: { ep: number[], @@ -802,7 +835,7 @@ export default class Crunchy implements ServiceClass { const doEpsFilter = parseSelect(e as string); const selectedMedia: CrunchyEpMeta[] = []; - episodeList.items.forEach((item) => { + episodeList.data.forEach((item) => { item.hide_season_title = true; if(item.season_title == '' && item.series_title != ''){ item.season_title = item.series_title; @@ -851,12 +884,18 @@ export default class Crunchy implements ServiceClass { image: images[Math.floor(images.length / 2)].source }; // Check for streams_link and update playback var if needed - if (item.__links__.streams.href) { + if (item.__links__?.streams.href) { epMeta.data[0].playback = item.__links__.streams.href; if(!item.playback) { item.playback = item.__links__.streams.href; } } + if (item.streams_link) { + epMeta.data[0].playback = item.streams_link; + if(!item.playback) { + item.playback = item.streams_link; + } + } if (item.versions) { epMeta.data[0].versions = item.versions; } @@ -921,6 +960,7 @@ export default class Crunchy implements ServiceClass { '/channels/crunchyroll/objects', '?', new URLSearchParams({ + 'preferred_audio_language': 'ja-JP', 'external_id': ob, 'Policy': this.cmsToken.cms.policy, 'Signature': this.cmsToken.cms.signature, @@ -963,38 +1003,53 @@ export default class Crunchy implements ServiceClass { }; // reqs - const objectReqOpts = [ - api.beta_cms, - this.cmsToken.cms.bucket, - '/objects/', - doEpsFilter.values.join(','), - '?', - new URLSearchParams({ - 'Policy': this.cmsToken.cms.policy, - 'Signature': this.cmsToken.cms.signature, - 'Key-Pair-Id': this.cmsToken.cms.key_pair_id, - }), - ].join(''); - const objectReq = await this.req.getData(objectReqOpts, AuthHeaders); - //const objectReq = await this.req.getData(`${api.cms}/objects/${doEpsFilter.values.join(',')}?preferred_audio_language=ja-JP`, AuthHeaders); - if(!objectReq.ok || !objectReq.res){ - console.error('Objects Request FAILED!'); - if(objectReq.error && objectReq.error.res && objectReq.error.res.body){ - const objectInfo = JSON.parse(objectReq.error.res.body as string); - console.info('Body:', JSON.stringify(objectInfo, null, '\t')); - objectInfo.error = true; - return objectInfo; + let objectInfo: ObjectInfo = { total: 0, data: [], meta: {} }; + if (this.api == 'android') { + const objectReqOpts = [ + api.beta_cms, + this.cmsToken.cms.bucket, + '/objects/', + doEpsFilter.values.join(','), + '?', + new URLSearchParams({ + 'preferred_audio_language': 'ja-JP', + 'Policy': this.cmsToken.cms.policy, + 'Signature': this.cmsToken.cms.signature, + 'Key-Pair-Id': this.cmsToken.cms.key_pair_id, + }), + ].join(''); + const objectReq = await this.req.getData(objectReqOpts, AuthHeaders); + if(!objectReq.ok || !objectReq.res){ + console.error('Objects Request FAILED!'); + if(objectReq.error && objectReq.error.res && objectReq.error.res.body){ + const objectInfo = JSON.parse(objectReq.error.res.body as string); + console.info('Body:', JSON.stringify(objectInfo, null, '\t')); + objectInfo.error = true; + return objectInfo; + } + return []; } - return []; + const objectInfoAndroid = JSON.parse(objectReq.res.body) as CrunchyAndroidObject; + objectInfo = { + total: objectInfoAndroid.total, + data: objectInfoAndroid.items, + meta: {} + }; + } else { + const objectReq = await this.req.getData(`${api.cms}/objects/${doEpsFilter.values.join(',')}?preferred_audio_language=ja-JP`, AuthHeaders); + if(!objectReq.ok || !objectReq.res){ + console.error('Objects Request FAILED!'); + if(objectReq.error && objectReq.error.res && objectReq.error.res.body){ + const objectInfo = JSON.parse(objectReq.error.res.body as string); + console.info('Body:', JSON.stringify(objectInfo, null, '\t')); + objectInfo.error = true; + return objectInfo; + } + return []; + } + objectInfo = JSON.parse(objectReq.res.body) as ObjectInfo; } - //const objectInfo = JSON.parse(objectReq.res.body) as ObjectInfo; - const objectInfoAndroid = JSON.parse(objectReq.res.body) as CrunchyAndroidObject; - const objectInfo: ObjectInfo = { - total: objectInfoAndroid.total, - data: objectInfoAndroid.items, - meta: {} - }; if(earlyReturn){ return objectInfo; } @@ -1083,6 +1138,9 @@ export default class Crunchy implements ServiceClass { return; } + if (!this.cfg.bin.ffmpeg) + this.cfg.bin = await yamlCfg.loadBinCfg(); + let mediaName = '...'; let fileName; const variables: Variable[] = []; @@ -1117,10 +1175,17 @@ export default class Crunchy implements ServiceClass { //Get Media GUID let mediaId = mMeta.mediaId; - if (mMeta.versions && mMeta.lang) { - currentVersion = mMeta.versions.find(a => a.audio_locale == mMeta.lang?.cr_locale); + if (mMeta.versions) { + if (mMeta.lang) { + currentVersion = mMeta.versions.find(a => a.audio_locale == mMeta.lang?.cr_locale); + } else if (options.dubLang.length == 1) { + const currentLang = langsData.languages.find(a => a.code == options.dubLang[0]); + currentVersion = mMeta.versions.find(a => a.audio_locale == currentLang?.cr_locale); + } else if (mMeta.versions.length == 1) { + currentVersion = mMeta.versions[0]; + } if (!currentVersion?.media_guid) { - console.error('Selected language not found.'); + console.error('Selected language not found in versions.'); continue; } isPrimary = currentVersion.original; @@ -1131,26 +1196,106 @@ export default class Crunchy implements ServiceClass { if (mediaId.includes(':')) mediaId = mediaId.split(':')[1]; - // /cms/v2/BUCKET/crunchyroll/videos/MEDIAID/streams - const videoStreamsReq = [ - api.beta_cms, - `${this.cmsToken.cms.bucket}/videos/${mediaId}/streams`, - '?', - new URLSearchParams({ - 'Policy': this.cmsToken.cms.policy, - 'Signature': this.cmsToken.cms.signature, - 'Key-Pair-Id': this.cmsToken.cms.key_pair_id, - }), - ].join(''); - - let playbackReq = await this.req.getData(videoStreamsReq as string, AuthHeaders); - //console.info(playbackReq.res.body); - //let playbackReq = await this.req.getData(`${api.cms}/videos/${mediaId}/streams`, AuthHeaders); - if(!playbackReq.ok || !playbackReq.res){ - console.error('Request Stream URLs FAILED! Attempting fallback'); + const compiledChapters: string[] = []; + if (options.chapters) { + //Make Chapter Request + const chapterRequest = await this.req.getData(`https://static.crunchyroll.com/skip-events/production/${mMeta.mediaId}.json`); + if(!chapterRequest.ok || !chapterRequest.res){ + //Old Chapter Request Fallback + console.warn('Chapter request failed, attempting old API'); + const oldChapterRequest = await this.req.getData(`https://static.crunchyroll.com/datalab-intro-v2/${mMeta.mediaId}.json`); + if(!oldChapterRequest.ok || !oldChapterRequest.res) { + console.warn('Old Chapter API request failed'); + } else { + console.info('Old Chapter request successful'); + const chapterData = JSON.parse(oldChapterRequest.res.body) as CrunchyOldChapter; + + //Generate Timestamps + const startTime = new Date(0), endTime = new Date(0); + startTime.setSeconds(chapterData.startTime); + endTime.setSeconds(chapterData.endTime); + const startTimeMS = String(chapterData.startTime).split('.')[1], endTimeMS = String(chapterData.endTime).split('.')[1]; + const startMS = startTimeMS ? startTimeMS : '00', endMS = endTimeMS ? endTimeMS : '00'; + const startFormatted = startTime.toISOString().substring(11, 19)+'.'+startMS; + const endFormatted = endTime.toISOString().substring(11, 19)+'.'+endMS; + + //Push Generated Chapters + if (chapterData.startTime > 1) { + compiledChapters.push( + `CHAPTER${(compiledChapters.length/2)+1}=00:00:00.00`, + `CHAPTER${(compiledChapters.length/2)+1}NAME=Prologue` + ); + } + compiledChapters.push( + `CHAPTER${(compiledChapters.length/2)+1}=${startFormatted}`, + `CHAPTER${(compiledChapters.length/2)+1}NAME=Opening` + ); + compiledChapters.push( + `CHAPTER${(compiledChapters.length/2)+1}=${endFormatted}`, + `CHAPTER${(compiledChapters.length/2)+1}NAME=Episode` + ); + } + } else { + //Chapter request succeeded, now let's parse them + console.info('Chapter request successful'); + const chapterData = JSON.parse(chapterRequest.res.body) as CrunchyChapters; + const chapters: CrunchyChapter[] = []; + + //Make a format more usable for the crunchy chapters + for (const chapter in chapterData) { + if (typeof chapterData[chapter] == 'object') { + chapters.push(chapterData[chapter]); + } + } + + if (chapters.length > 0) { + chapters.sort((a, b) => a.start - b.start); + //Loop through all the chapters + for (const chapter of chapters) { + if (!chapter.start || !chapter.end) continue; + //Generate timestamps + const startTime = new Date(0), endTime = new Date(0); + startTime.setSeconds(chapter.start); + endTime.setSeconds(chapter.end); + const startFormatted = startTime.toISOString().substring(11, 19)+'.00'; + const endFormatted = endTime.toISOString().substring(11, 19)+'.00'; + + //Push generated chapters + if (chapter.type == 'intro') { + if (chapter.start > 0) { + compiledChapters.push( + `CHAPTER${(compiledChapters.length/2)+1}=00:00:00.00`, + `CHAPTER${(compiledChapters.length/2)+1}NAME=Prologue` + ); + } + compiledChapters.push( + `CHAPTER${(compiledChapters.length/2)+1}=${startFormatted}`, + `CHAPTER${(compiledChapters.length/2)+1}NAME=Opening` + ); + compiledChapters.push( + `CHAPTER${(compiledChapters.length/2)+1}=${endFormatted}`, + `CHAPTER${(compiledChapters.length/2)+1}NAME=Episode` + ); + } else { + compiledChapters.push( + `CHAPTER${(compiledChapters.length/2)+1}=${startFormatted}`, + `CHAPTER${(compiledChapters.length/2)+1}NAME=${chapter.type.charAt(0).toUpperCase() + chapter.type.slice(1)} Start` + ); + compiledChapters.push( + `CHAPTER${(compiledChapters.length/2)+1}=${endFormatted}`, + `CHAPTER${(compiledChapters.length/2)+1}NAME=${chapter.type.charAt(0).toUpperCase() + chapter.type.slice(1)} End` + ); + } + } + } + } + } + + let pbData = { total: 0, data: {}, meta: {} } as PlaybackData; + if (this.api == 'android') { const videoStreamsReq = [ - domain.api_beta, - mMeta.playback, + api.beta_cms, + `${this.cmsToken.cms.bucket}/videos/${mediaId}/streams`, '?', new URLSearchParams({ 'preferred_audio_language': 'ja-JP', @@ -1159,16 +1304,54 @@ export default class Crunchy implements ServiceClass { 'Key-Pair-Id': this.cmsToken.cms.key_pair_id, }), ].join(''); - playbackReq = await this.req.getData(videoStreamsReq as string, AuthHeaders); - //playbackReq = await this.req.getData(`${domain.api_beta}${mMeta.playback}`, AuthHeaders); - if(!playbackReq.ok || !playbackReq.res){ - console.error('Fallback Request Stream URLs FAILED!'); - return undefined; - } - } - //const pbData = JSON.parse(playbackReq.res.body) as PlaybackData; - const pbData = JSON.parse(playbackReq.res.body) as CrunchyAndroidStreams; + let playbackReq = await this.req.getData(videoStreamsReq as string, AuthHeaders); + if(!playbackReq.ok || !playbackReq.res){ + console.error('Request Stream URLs FAILED! Attempting fallback'); + + const videoStreamsReq = [ + domain.api_beta, + mMeta.playback, + '?', + new URLSearchParams({ + 'preferred_audio_language': 'ja-JP', + 'Policy': this.cmsToken.cms.policy, + 'Signature': this.cmsToken.cms.signature, + 'Key-Pair-Id': this.cmsToken.cms.key_pair_id, + }), + ].join(''); + playbackReq = await this.req.getData(videoStreamsReq as string, AuthHeaders); + if(!playbackReq.ok || !playbackReq.res){ + console.error('Fallback Request Stream URLs FAILED!'); + return undefined; + } + } + const pbDataAndroid = JSON.parse(playbackReq.res.body) as CrunchyAndroidStreams; + pbData = { + total: 0, + data: [pbDataAndroid.streams], + meta: { + audio_locale: pbDataAndroid.audio_locale, + bifs: pbDataAndroid.bifs, + captions: pbDataAndroid.captions, + closed_captions: pbDataAndroid.closed_captions, + media_id: pbDataAndroid.media_id, + subtitles: pbDataAndroid.subtitles, + versions: pbDataAndroid.versions + } + }; + } else { + let playbackReq = await this.req.getData(`${api.cms}/videos/${mediaId}/streams`, AuthHeaders); + if(!playbackReq.ok || !playbackReq.res){ + console.error('Request Stream URLs FAILED! Attempting fallback'); + playbackReq = await this.req.getData(`${domain.api_beta}${mMeta.playback}`, AuthHeaders); + if(!playbackReq.ok || !playbackReq.res){ + console.error('Fallback Request Stream URLs FAILED!'); + return undefined; + } + } + pbData = JSON.parse(playbackReq.res.body) as PlaybackData; + } variables.push(...([ ['title', medias.episodeTitle, true], @@ -1188,11 +1371,19 @@ export default class Crunchy implements ServiceClass { let streams: any[] = []; let hsLangs: string[] = []; - const pbStreams = pbData.streams; + const pbStreams = pbData.data[0]; + + if (!canDecrypt) { + console.warn('Decryption not enabled!'); + } for(const s of Object.keys(pbStreams)){ - if(s.match(/hls/) && !s.match(/drm/) && !s.match(/trailer/)) { - //if((s.match(/hls/) || s.match(/dash/)) && !s.match(/trailer/)) { + if ( + (s.match(/hls/) || s.match(/dash/)) + && !(s.match(/hls/) && s.match(/drm/)) + && !((!canDecrypt || !this.cfg.bin.mp4decrypt) && s.match(/drm/)) + && !s.match(/trailer/) + ) { const pb = Object.values(pbStreams[s]).map(v => { v.hardsub_lang = v.hardsub_locale ? langsData.fixAndFindCrLC(v.hardsub_locale).locale @@ -1214,7 +1405,7 @@ export default class Crunchy implements ServiceClass { return undefined; } - const audDub = langsData.findLang(langsData.fixLanguageTag(pbData.audio_locale as string) || '').code; + const audDub = langsData.findLang(langsData.fixLanguageTag(pbData.meta.audio_locale as string) || '').code; hsLangs = langsData.sortTags(hsLangs); streams = streams.map((s) => { @@ -1293,120 +1484,95 @@ export default class Crunchy implements ServiceClass { dlFailed = true; } else{ - const streamPlaylists = m3u8(streamPlaylistsReq.res.body); - const plServerList: string[] = [], - plStreams: Record> = {}, - plQuality: { - str: string, - dim: string, - CODECS: string, - RESOLUTION: { - width: number, - height: number - } - }[] = []; - for(const pl of streamPlaylists.playlists){ - // set quality - const plResolution = pl.attributes.RESOLUTION; - const plResolutionText = `${plResolution.width}x${plResolution.height}`; - // set codecs - const plCodecs = pl.attributes.CODECS; - // parse uri - const plUri = new URL(pl.uri); - let plServer = plUri.hostname; - // set server list - if(plUri.searchParams.get('cdn')){ - plServer += ` (${plUri.searchParams.get('cdn')})`; - } - if(!plServerList.includes(plServer)){ - plServerList.push(plServer); - } - // add to server - if(!Object.keys(plStreams).includes(plServer)){ - plStreams[plServer] = {}; - } - if( - plStreams[plServer][plResolutionText] - && plStreams[plServer][plResolutionText] != pl.uri - && typeof plStreams[plServer][plResolutionText] != 'undefined' - ){ - console.error(`Non duplicate url for ${plServer} detected, please report to developer!`); - } - else{ - plStreams[plServer][plResolutionText] = pl.uri; - } - // set plQualityStr - const plBandwidth = Math.round(pl.attributes.BANDWIDTH/1024); - const qualityStrAdd = `${plResolutionText} (${plBandwidth}KiB/s)`; - const qualityStrRegx = new RegExp(qualityStrAdd.replace(/(:|\(|\)|\/)/g, '\\$1'), 'm'); - const qualityStrMatch = !plQuality.map(a => a.str).join('\r\n').match(qualityStrRegx); - if(qualityStrMatch){ - plQuality.push({ - str: qualityStrAdd, - dim: plResolutionText, - CODECS: plCodecs, - RESOLUTION: plResolution - }); - } - } + if (streamPlaylistsReq.res.body.match('MPD')) { + //Parse MPD Playlists + const streamPlaylists = parse(streamPlaylistsReq.res.body, langsData.findLang(langsData.fixLanguageTag(pbData.meta.audio_locale as string) || ''), curStream.url.match(/.*\.urlset\//)[0]); - options.x = options.x > plServerList.length ? 1 : options.x; + //Get name of CDNs/Servers + const streamServers = Object.keys(streamPlaylists); - const plSelectedServer = plServerList[options.x - 1]; - const plSelectedList = plStreams[plSelectedServer]; - plQuality.sort((a, b) => { - const aMatch: RegExpMatchArray | never[] = a.dim.match(/[0-9]+/) || []; - const bMatch: RegExpMatchArray | never[] = b.dim.match(/[0-9]+/) || []; - return parseInt(aMatch[0]) - parseInt(bMatch[0]); - }); - let quality = options.q === 0 ? plQuality.length : options.q; - if(quality > plQuality.length) { - console.warn(`The requested quality of ${options.q} is greater than the maximun ${plQuality.length}.\n[WARN] Therefor the maximum will be capped at ${plQuality.length}.`); - quality = plQuality.length; - } - // When best selected video quality is already downloaded - if(dlVideoOnce && options.dlVideoOnce) { - // Select the lowest resolution with the same codecs - while(quality !=1 && plQuality[quality - 1].CODECS == plQuality[quality - 2].CODECS) { - quality--; + options.x = options.x > streamServers.length ? 1 : options.x; + + const selectedServer = streamServers[options.x - 1]; + const selectedList = streamPlaylists[selectedServer]; + + //set Video Qualities + const videos = selectedList.video.map(item => { + return { + ...item, + resolutionText: `${item.quality.width}x${item.quality.height} (${Math.round(item.bandwidth/1024)}KiB/s)` + }; + }); + + const audios = selectedList.audio.map(item => { + return { + ...item, + resolutionText: `${Math.round(item.bandwidth/1000)}kB/s` + }; + }); + + + videos.sort((a, b) => { + return a.quality.width - b.quality.width; + }); + + audios.sort((a, b) => { + return a.bandwidth - b.bandwidth; + }); + + let chosenVideoQuality = options.q === 0 ? videos.length : options.q; + if(chosenVideoQuality > videos.length) { + console.warn(`The requested quality of ${options.q} is greater than the maximum ${videos.length}.\n[WARN] Therefor the maximum will be capped at ${videos.length}.`); + chosenVideoQuality = videos.length; } - } - const selPlUrl = plSelectedList[plQuality.map(a => a.dim)[quality - 1]] ? plSelectedList[plQuality.map(a => a.dim)[quality - 1]] : ''; - console.info(`Servers available:\n\t${plServerList.join('\n\t')}`); - console.info(`Available qualities:\n\t${plQuality.map((a, ind) => `[${ind+1}] ${a.str}`).join('\n\t')}`); + chosenVideoQuality--; + + let chosenAudioQuality = options.q === 0 ? audios.length : options.q; + if(chosenAudioQuality > audios.length) { + chosenAudioQuality = audios.length; + } + chosenAudioQuality--; + + + const chosenVideoSegments = videos[chosenVideoQuality]; + const chosenAudioSegments = audios[chosenAudioQuality]; + + console.info(`Servers available:\n\t${streamServers.join('\n\t')}`); + console.info(`Available Video Qualities:\n\t${videos.map((a, ind) => `[${ind+1}] ${a.resolutionText}`).join('\n\t')}`); + console.info(`Available Audio Qualities:\n\t${audios.map((a, ind) => `[${ind+1}] ${a.resolutionText}`).join('\n\t')}`); - if(selPlUrl != ''){ variables.push({ name: 'height', type: 'number', - replaceWith: quality === 0 ? plQuality[plQuality.length - 1].RESOLUTION.height as number : plQuality[quality - 1].RESOLUTION.height + replaceWith: chosenVideoSegments.quality.height }, { name: 'width', type: 'number', - replaceWith: quality === 0 ? plQuality[plQuality.length - 1].RESOLUTION.width as number : plQuality[quality - 1].RESOLUTION.width + replaceWith: chosenVideoSegments.quality.width }); + const lang = langsData.languages.find(a => a.code === curStream?.audio_lang); if (!lang) { console.error(`Unable to find language for code ${curStream.audio_lang}`); return; } - console.info(`Selected quality: ${Object.keys(plSelectedList).find(a => plSelectedList[a] === selPlUrl)} @ ${plSelectedServer}`); - console.info('Stream URL:', selPlUrl); + console.info(`Selected quality: \n\tVideo: ${chosenVideoSegments.resolutionText}\n\tAudio: ${chosenAudioSegments.resolutionText}\n\tServer: ${selectedServer}`); + console.info('Stream URL:', chosenVideoSegments.segments[0].uri.split(',.urlset')[0]); // TODO check filename fileName = parseFileName(options.fileName, variables, options.numbers, options.override).join(path.sep); const outFile = parseFileName(options.fileName + '.' + (mMeta.lang?.name || lang.name), variables, options.numbers, options.override).join(path.sep); - console.info(`Output filename: ${outFile}`); - const chunkPage = await this.req.getData(selPlUrl); - if(!chunkPage.ok || !chunkPage.res){ - console.error('CAN\'T FETCH VIDEO PLAYLIST!'); - dlFailed = true; - } - else{ - const chunkPlaylist = m3u8(chunkPage.res.body); - const totalParts = chunkPlaylist.segments.length; + + let [audioDownloaded, videoDownloaded] = [false, false]; + + // When best selected video quality is already downloaded + if(dlVideoOnce && options.dlVideoOnce) { + console.info('Already downloaded video, skipping video download...'); + } else { + //Download Video + const totalParts = chosenVideoSegments.segments.length; const mathParts = Math.ceil(totalParts / options.partsize); const mathMsg = `(${mathParts}*${options.partsize})`; - console.info('Total parts in stream:', totalParts, mathMsg); + console.info('Total parts in video stream:', totalParts, mathMsg); tsFile = path.isAbsolute(outFile as string) ? outFile : path.join(this.cfg.dir.content, outFile); const split = outFile.split(path.sep).slice(0, -1); split.forEach((val, ind, arr) => { @@ -1414,10 +1580,13 @@ export default class Crunchy implements ServiceClass { if (!fs.existsSync(path.join(isAbsolut ? '' : this.cfg.dir.content, ...arr.slice(0, ind), val))) fs.mkdirSync(path.join(isAbsolut ? '' : this.cfg.dir.content, ...arr.slice(0, ind), val)); }); - const dlStreamByPl = await new streamdl({ - output: `${tsFile}.ts`, + const videoJson: M3U8Json = { + segments: chosenVideoSegments.segments + }; + const videoDownload = await new streamdl({ + output: `${tsFile}.video.enc.ts`, timeout: options.timeout, - m3u8json: chunkPlaylist, + m3u8json: videoJson, // baseurl: chunkPlaylist.baseUrl, threads: options.partsize, fsRetryTime: options.fsRetryTime * 1000, @@ -1432,22 +1601,309 @@ export default class Crunchy implements ServiceClass { language: lang }) : undefined }).download(); - if(!dlStreamByPl.ok){ - console.error(`DL Stats: ${JSON.stringify(dlStreamByPl.parts)}\n`); + if(!videoDownload.ok){ + console.error(`DL Stats: ${JSON.stringify(videoDownload.parts)}\n`); dlFailed = true; } + dlVideoOnce = true; + videoDownloaded = true; + } + + if (chosenAudioSegments) { + //Download Audio (if available) + const totalParts = chosenAudioSegments.segments.length; + const mathParts = Math.ceil(totalParts / options.partsize); + const mathMsg = `(${mathParts}*${options.partsize})`; + console.info('Total parts in audio stream:', totalParts, mathMsg); + tsFile = path.isAbsolute(outFile as string) ? outFile : path.join(this.cfg.dir.content, outFile); + const split = outFile.split(path.sep).slice(0, -1); + split.forEach((val, ind, arr) => { + const isAbsolut = path.isAbsolute(outFile as string); + if (!fs.existsSync(path.join(isAbsolut ? '' : this.cfg.dir.content, ...arr.slice(0, ind), val))) + fs.mkdirSync(path.join(isAbsolut ? '' : this.cfg.dir.content, ...arr.slice(0, ind), val)); + }); + const audioJson: M3U8Json = { + segments: chosenAudioSegments.segments + }; + const audioDownload = await new streamdl({ + output: `${tsFile}.audio.enc.ts`, + timeout: options.timeout, + m3u8json: audioJson, + // baseurl: chunkPlaylist.baseUrl, + threads: options.partsize, + fsRetryTime: options.fsRetryTime * 1000, + override: options.force, + callback: options.callbackMaker ? options.callbackMaker({ + fileName: `${path.isAbsolute(outFile) ? outFile.slice(this.cfg.dir.content.length) : outFile}`, + image: medias.image, + parent: { + title: medias.seasonTitle + }, + title: medias.episodeTitle, + language: lang + }) : undefined + }).download(); + if(!audioDownload.ok){ + console.error(`DL Stats: ${JSON.stringify(audioDownload.parts)}\n`); + dlFailed = true; + } + audioDownloaded = true; + } + + //Handle Decryption if needed + if ((chosenVideoSegments.pssh || chosenAudioSegments.pssh) && (videoDownloaded || audioDownloaded)) { + const assetIdRegex = chosenVideoSegments.segments[0].uri.match(/\/assets\/(?:p\/)?([^_,]+)/); + const assetId = assetIdRegex ? assetIdRegex[1] : null; + const sessionId = new Date().getUTCMilliseconds().toString().padStart(3, '0') + process.hrtime.bigint().toString().slice(0, 13); + console.info('Decryption Needed, attempting to decrypt'); + + const decReq = await this.req.getData('https://pl.crunchyroll.com/drm/v1/auth', { + 'method': 'POST', + 'body': JSON.stringify({ + 'accounting_id': 'crunchyroll', + 'asset_id': assetId, + 'session_id': sessionId, + 'user_id': this.token.account_id + }) + }); + if(!decReq.ok || !decReq.res){ + console.error('Request to DRM Authentication failed:', decReq.error?.code, decReq.error?.message); + return undefined; + } + const authData = JSON.parse(decReq.res.body) as {'custom_data': string, 'token': string}; + const encryptionKeys = await getKeys(chosenVideoSegments.pssh, 'https://lic.drmtoday.com/license-proxy-widevine/cenc/', { + 'dt-custom-data': authData.custom_data, + 'x-dt-auth-token': authData.token + }); + if (encryptionKeys.length == 0) { + console.error('Failed to get encryption keys'); + return undefined; + } + /*const keys = {} as Record; + encryptionKeys.forEach(function(key) { + keys[key.kid] = key.key; + });*/ + + if (this.cfg.bin.mp4decrypt) { + const commandBase = `--show-progress --key ${encryptionKeys[1].kid}:${encryptionKeys[1].key} `; + const commandVideo = commandBase+`"${tsFile}.video.enc.ts" "${tsFile}.video.ts"`; + const commandAudio = commandBase+`"${tsFile}.audio.enc.ts" "${tsFile}.audio.ts"`; + + if (videoDownloaded) { + console.info('Started decrypting video'); + const decryptVideo = exec('mp4decrypt', `"${this.cfg.bin.mp4decrypt}"`, commandVideo); + if (!decryptVideo.isOk) { + console.error(decryptVideo.err); + console.error(`Decryption failed with exit code ${decryptVideo.err.code}`); + return undefined; + } else { + console.info('Decryption done for video'); + if (!options.nocleanup) { + fs.removeSync(`${tsFile}.video.enc.ts`); + } + files.push({ + type: 'Video', + path: `${tsFile}.video.ts`, + lang: lang, + isPrimary: isPrimary + }); + } + } + + if (audioDownloaded) { + console.info('Started decrypting audio'); + const decryptAudio = exec('mp4decrypt', `"${this.cfg.bin.mp4decrypt}"`, commandAudio); + if (!decryptAudio.isOk) { + console.error(decryptAudio.err); + console.error(`Decryption failed with exit code ${decryptAudio.err.code}`); + return undefined; + } else { + if (!options.nocleanup) { + fs.removeSync(`${tsFile}.audio.enc.ts`); + } + files.push({ + type: 'Audio', + path: `${tsFile}.audio.ts`, + lang: lang, + isPrimary: isPrimary + }); + console.info('Decryption done for audio'); + } + } + } else { + console.warn('mp4decrypt not found, files need decryption. Decryption Keys:', encryptionKeys); + } + } else { files.push({ type: 'Video', - path: `${tsFile}.ts`, + path: `${tsFile}.video.enc.ts`, + lang: lang, + isPrimary: isPrimary + }); + files.push({ + type: 'Audio', + path: `${tsFile}.audio.enc.ts`, lang: lang, isPrimary: isPrimary }); - dlVideoOnce = true; } - } - else{ - console.error('Quality not selected!\n'); - dlFailed = true; + } else { + const streamPlaylists = m3u8(streamPlaylistsReq.res.body); + const plServerList: string[] = [], + plStreams: Record> = {}, + plQuality: { + str: string, + dim: string, + CODECS: string, + RESOLUTION: { + width: number, + height: number + } + }[] = []; + for(const pl of streamPlaylists.playlists){ + // set quality + const plResolution = pl.attributes.RESOLUTION; + const plResolutionText = `${plResolution.width}x${plResolution.height}`; + // set codecs + const plCodecs = pl.attributes.CODECS; + // parse uri + const plUri = new URL(pl.uri); + let plServer = plUri.hostname; + // set server list + if(plUri.searchParams.get('cdn')){ + plServer += ` (${plUri.searchParams.get('cdn')})`; + } + if(!plServerList.includes(plServer)){ + plServerList.push(plServer); + } + // add to server + if(!Object.keys(plStreams).includes(plServer)){ + plStreams[plServer] = {}; + } + if( + plStreams[plServer][plResolutionText] + && plStreams[plServer][plResolutionText] != pl.uri + && typeof plStreams[plServer][plResolutionText] != 'undefined' + ){ + console.error(`Non duplicate url for ${plServer} detected, please report to developer!`); + } + else{ + plStreams[plServer][plResolutionText] = pl.uri; + } + // set plQualityStr + const plBandwidth = Math.round(pl.attributes.BANDWIDTH/1024); + const qualityStrAdd = `${plResolutionText} (${plBandwidth}KiB/s)`; + const qualityStrRegx = new RegExp(qualityStrAdd.replace(/(:|\(|\)|\/)/g, '\\$1'), 'm'); + const qualityStrMatch = !plQuality.map(a => a.str).join('\r\n').match(qualityStrRegx); + if(qualityStrMatch){ + plQuality.push({ + str: qualityStrAdd, + dim: plResolutionText, + CODECS: plCodecs, + RESOLUTION: plResolution + }); + } + } + + options.x = options.x > plServerList.length ? 1 : options.x; + + const plSelectedServer = plServerList[options.x - 1]; + const plSelectedList = plStreams[plSelectedServer]; + plQuality.sort((a, b) => { + const aMatch: RegExpMatchArray | never[] = a.dim.match(/[0-9]+/) || []; + const bMatch: RegExpMatchArray | never[] = b.dim.match(/[0-9]+/) || []; + return parseInt(aMatch[0]) - parseInt(bMatch[0]); + }); + let quality = options.q === 0 ? plQuality.length : options.q; + if(quality > plQuality.length) { + console.warn(`The requested quality of ${options.q} is greater than the maximum ${plQuality.length}.\n[WARN] Therefor the maximum will be capped at ${plQuality.length}.`); + quality = plQuality.length; + } + // When best selected video quality is already downloaded + if(dlVideoOnce && options.dlVideoOnce) { + // Select the lowest resolution with the same codecs + while(quality !=1 && plQuality[quality - 1].CODECS == plQuality[quality - 2].CODECS) { + quality--; + } + } + const selPlUrl = plSelectedList[plQuality.map(a => a.dim)[quality - 1]] ? plSelectedList[plQuality.map(a => a.dim)[quality - 1]] : ''; + console.info(`Servers available:\n\t${plServerList.join('\n\t')}`); + console.info(`Available qualities:\n\t${plQuality.map((a, ind) => `[${ind+1}] ${a.str}`).join('\n\t')}`); + + if(selPlUrl != ''){ + variables.push({ + name: 'height', + type: 'number', + replaceWith: quality === 0 ? plQuality[plQuality.length - 1].RESOLUTION.height as number : plQuality[quality - 1].RESOLUTION.height + }, { + name: 'width', + type: 'number', + replaceWith: quality === 0 ? plQuality[plQuality.length - 1].RESOLUTION.width as number : plQuality[quality - 1].RESOLUTION.width + }); + const lang = langsData.languages.find(a => a.code === curStream?.audio_lang); + if (!lang) { + console.error(`Unable to find language for code ${curStream.audio_lang}`); + return; + } + console.info(`Selected quality: ${Object.keys(plSelectedList).find(a => plSelectedList[a] === selPlUrl)} @ ${plSelectedServer}`); + console.info('Stream URL:', selPlUrl); + // TODO check filename + fileName = parseFileName(options.fileName, variables, options.numbers, options.override).join(path.sep); + const outFile = parseFileName(options.fileName + '.' + (mMeta.lang?.name || lang.name), variables, options.numbers, options.override).join(path.sep); + console.info(`Output filename: ${outFile}`); + const chunkPage = await this.req.getData(selPlUrl); + if(!chunkPage.ok || !chunkPage.res){ + console.error('CAN\'T FETCH VIDEO PLAYLIST!'); + dlFailed = true; + } + else{ + const chunkPlaylist = m3u8(chunkPage.res.body); + const totalParts = chunkPlaylist.segments.length; + const mathParts = Math.ceil(totalParts / options.partsize); + const mathMsg = `(${mathParts}*${options.partsize})`; + console.info('Total parts in stream:', totalParts, mathMsg); + tsFile = path.isAbsolute(outFile as string) ? outFile : path.join(this.cfg.dir.content, outFile); + const split = outFile.split(path.sep).slice(0, -1); + split.forEach((val, ind, arr) => { + const isAbsolut = path.isAbsolute(outFile as string); + if (!fs.existsSync(path.join(isAbsolut ? '' : this.cfg.dir.content, ...arr.slice(0, ind), val))) + fs.mkdirSync(path.join(isAbsolut ? '' : this.cfg.dir.content, ...arr.slice(0, ind), val)); + }); + const dlStreamByPl = await new streamdl({ + output: `${tsFile}.ts`, + timeout: options.timeout, + m3u8json: chunkPlaylist, + // baseurl: chunkPlaylist.baseUrl, + threads: options.partsize, + fsRetryTime: options.fsRetryTime * 1000, + override: options.force, + callback: options.callbackMaker ? options.callbackMaker({ + fileName: `${path.isAbsolute(outFile) ? outFile.slice(this.cfg.dir.content.length) : outFile}`, + image: medias.image, + parent: { + title: medias.seasonTitle + }, + title: medias.episodeTitle, + language: lang + }) : undefined + }).download(); + if(!dlStreamByPl.ok){ + console.error(`DL Stats: ${JSON.stringify(dlStreamByPl.parts)}\n`); + dlFailed = true; + } + files.push({ + type: 'Video', + path: `${tsFile}.ts`, + lang: lang, + isPrimary: isPrimary + }); + dlVideoOnce = true; + } + } + else{ + console.error('Quality not selected!\n'); + dlFailed = true; + } } } } @@ -1456,6 +1912,32 @@ export default class Crunchy implements ServiceClass { console.info('Downloading skipped!'); } + if (compiledChapters.length > 0) { + try { + fileName = parseFileName(options.fileName, variables, options.numbers, options.override).join(path.sep); + const outFile = parseFileName(options.fileName + '.' + mMeta.lang?.name, variables, options.numbers, options.override).join(path.sep); + tsFile = path.isAbsolute(outFile as string) ? outFile : path.join(this.cfg.dir.content, outFile); + const split = outFile.split(path.sep).slice(0, -1); + split.forEach((val, ind, arr) => { + const isAbsolut = path.isAbsolute(outFile as string); + if (!fs.existsSync(path.join(isAbsolut ? '' : this.cfg.dir.content, ...arr.slice(0, ind), val))) + fs.mkdirSync(path.join(isAbsolut ? '' : this.cfg.dir.content, ...arr.slice(0, ind), val)); + }); + const lang = langsData.languages.find(a => a.code === curStream?.audio_lang); + if (!lang) { + console.error(`Unable to find language for code ${curStream.audio_lang}`); + return; + } + fs.writeFileSync(`${tsFile}.txt`, compiledChapters.join('\r\n')); + files.push({ + path: `${tsFile}.txt`, + lang: lang, + type: 'Chapters' + }); + } catch { + console.error('Failed to write chapter file'); + } + } if(options.dlsubs.indexOf('all') > -1){ options.dlsubs = ['all']; @@ -1472,24 +1954,37 @@ export default class Crunchy implements ServiceClass { } if(!options.skipsubs && options.dlsubs.indexOf('none') == -1){ - if(pbData.subtitles && Object.values(pbData.subtitles).length > 0){ - const subsData = Object.values(pbData.subtitles); + if(pbData.meta.subtitles && Object.values(pbData.meta.subtitles).length > 0){ + const subsData = Object.values(pbData.meta.subtitles); + const capsData = Object.values(pbData.meta.closed_captions); const subsDataMapped = subsData.map((s) => { const subLang = langsData.fixAndFindCrLC(s.locale); return { ...s, + isCC: false, locale: subLang, language: subLang.locale }; - }); + }).concat( + capsData.map((s) => { + const subLang = langsData.fixAndFindCrLC(s.locale); + return { + ...s, + isCC: true, + locale: subLang, + language: subLang.locale + }; + }) + ); const subsArr = langsData.sortSubtitles(subsDataMapped, 'language'); for(const subsIndex in subsArr){ const subsItem = subsArr[subsIndex]; const langItem = subsItem.locale; const sxData: Partial = {}; sxData.language = langItem; - const isCC = langItem.code === audDub; - sxData.file = langsData.subsFile(fileName as string, subsIndex, langItem, isCC, options.ccTag); + const isSigns = langItem.code === audDub && !subsItem.isCC; + const isCC = subsItem.isCC; + sxData.file = langsData.subsFile(fileName as string, subsIndex, langItem, isCC, options.ccTag, isSigns, subsItem.format); sxData.path = path.join(this.cfg.dir.content, sxData.file); const split = sxData.path.split(path.sep).slice(0, -1); split.forEach((val, ind, arr) => { @@ -1497,24 +1992,34 @@ export default class Crunchy implements ServiceClass { if (!fs.existsSync(path.join(isAbsolut ? '' : this.cfg.dir.content, ...arr.slice(0, ind), val))) fs.mkdirSync(path.join(isAbsolut ? '' : this.cfg.dir.content, ...arr.slice(0, ind), val)); }); - if (files.some(a => a.type === 'Subtitle' && (a.language.cr_locale == langItem.cr_locale || a.language.locale == langItem.locale) && a.cc === isCC)) + if (files.some(a => a.type === 'Subtitle' && (a.language.cr_locale == langItem.cr_locale || a.language.locale == langItem.locale) && a.cc === isCC && a.signs === isSigns)) continue; if(options.dlsubs.includes('all') || options.dlsubs.includes(langItem.locale)){ const subsAssReq = await this.req.getData(subsItem.url); if(subsAssReq.ok && subsAssReq.res){ - let sBody = '\ufeff' + subsAssReq.res.body; - const sBodySplit = sBody.split('\r\n'); - sBodySplit.splice(2, 0, 'ScaledBorderAndShadow: yes'); - sBody = sBodySplit.join('\r\n'); - sxData.title = sBody.split('\r\n')[1].replace(/^Title: /, ''); - sxData.title = `${langItem.language} / ${sxData.title}`; - sxData.fonts = fontsData.assFonts(sBody) as Font[]; + let sBody; + if (subsItem.format == 'vtt') { + //TODO: look into converting downloaded vtt into ASS + //sBody = vttConvert(subsAssReq.res.body, false, langItem.language, options.fontSize, options.fontName); + sBody = subsAssReq.res.body; + //TODO: look into parsing the fonts from the styles field in the VTT + sxData.fonts = options.fontName ? [options.fontName] as Font[] : []; + } else { + sBody = '\ufeff' + subsAssReq.res.body; + const sBodySplit = sBody.split('\r\n'); + sBodySplit.splice(2, 0, 'ScaledBorderAndShadow: yes'); + sBody = sBodySplit.join('\r\n'); + sxData.title = sBody.split('\r\n')[1].replace(/^Title: /, ''); + sxData.title = `${langItem.language} / ${sxData.title}`; + sxData.fonts = fontsData.assFonts(sBody) as Font[]; + } fs.writeFileSync(sxData.path, sBody); console.info(`Subtitle downloaded: ${sxData.file}`); files.push({ type: 'Subtitle', ...sxData as sxItem, cc: isCC, + signs: isSigns, }); } else{ @@ -1541,32 +2046,67 @@ export default class Crunchy implements ServiceClass { public async muxStreams(data: DownloadedMedia[], options: CrunchyMuxOptions) { this.cfg.bin = await yamlCfg.loadBinCfg(); + let hasAudioStreams = false; if (options.novids || data.filter(a => a.type === 'Video').length === 0) return console.info('Skip muxing since no vids are downloaded'); + if (data.some(a => a.type === 'Audio')) { + hasAudioStreams = true; + } const merger = new Merger({ - onlyVid: [], - skipSubMux: options.skipSubMux, - onlyAudio: [], - output: `${options.output}.${options.mp4 ? 'mp4' : 'mkv'}`, - subtitles: data.filter(a => a.type === 'Subtitle').map((a) : SubtitleInput => { - if (a.type === 'Video') - throw new Error('Never'); - return { - file: a.path, - language: a.language, - closedCaption: a.cc, - }; - }), - simul: false, - keepAllVideos: options.keepAllVideos, - fonts: Merger.makeFontsList(this.cfg.dir.fonts, data.filter(a => a.type === 'Subtitle') as sxItem[]), - videoAndAudio: data.filter(a => a.type === 'Video').map((a) : MergerInput => { + onlyVid: hasAudioStreams ? data.filter(a => a.type === 'Video').map((a) : MergerInput => { if (a.type === 'Subtitle') throw new Error('Never'); return { lang: a.lang, path: a.path, }; + }) : [], + skipSubMux: options.skipSubMux, + onlyAudio: hasAudioStreams ? data.filter(a => a.type === 'Audio').map((a) : MergerInput => { + if (a.type === 'Subtitle') + throw new Error('Never'); + return { + lang: a.lang, + path: a.path, + }; + }) : [], + output: `${options.output}.${options.mp4 ? 'mp4' : 'mkv'}`, + subtitles: data.filter(a => a.type === 'Subtitle').map((a) : SubtitleInput => { + if (a.type === 'Video') + throw new Error('Never'); + if (a.type === 'Audio') + throw new Error('Never'); + if (a.type === 'Chapters') + throw new Error('Never'); + return { + file: a.path, + language: a.language, + closedCaption: a.cc, + signs: a.signs, + }; + }), + simul: false, + keepAllVideos: options.keepAllVideos, + fonts: Merger.makeFontsList(this.cfg.dir.fonts, data.filter(a => a.type === 'Subtitle') as sxItem[]), + videoAndAudio: hasAudioStreams ? [] : data.filter(a => a.type === 'Video').map((a) : MergerInput => { + if (a.type === 'Subtitle') + throw new Error('Never'); + return { + lang: a.lang, + path: a.path, + }; + }), + chapters: data.filter(a => a.type === 'Chapters').map((a) : MergerInput => { + if (a.type === 'Video') + throw new Error('Never'); + if (a.type === 'Audio') + throw new Error('Never'); + if (a.type === 'Subtitle') + throw new Error('Never'); + return { + path: a.path, + lang: a.lang + }; }), videoTitle: options.videoTitle, options: { @@ -1617,18 +2157,18 @@ export default class Crunchy implements ServiceClass { for(const season of Object.keys(result) as unknown as number[]) { for (const key of Object.keys(result[season])) { const s = result[season][key]; - (await this.getSeasonDataById(s))?.items?.forEach(episode => { + (await this.getSeasonDataById(s))?.data?.forEach(episode => { //TODO: Make sure the below code is ok //Prepare the episode array let item; const seasonIdentifier = s.identifier ? s.identifier.split('|')[1] : `S${episode.season_number}`; - if (!(Object.prototype.hasOwnProperty.call(episodes, `${seasonIdentifier}E${episode.episode_number || episode.episode}`))) { - item = episodes[`${seasonIdentifier}E${episode.episode_number || episode.episode}`] = { + if (!(Object.prototype.hasOwnProperty.call(episodes, `${seasonIdentifier}E${episode.episode || episode.episode_number}`))) { + item = episodes[`${seasonIdentifier}E${episode.episode || episode.episode_number}`] = { items: [] as CrunchyEpisode[], langs: [] as langsData.LanguageItem[] }; } else { - item = episodes[`${seasonIdentifier}E${episode.episode_number || episode.episode}`]; + item = episodes[`${seasonIdentifier}E${episode.episode || episode.episode_number}`]; } if (episode.versions) { @@ -1707,7 +2247,7 @@ export default class Crunchy implements ServiceClass { })}; } - public async downloadFromSeriesID(id: string, data: CurnchyMultiDownload) : Promise> { + public async downloadFromSeriesID(id: string, data: CrunchyMultiDownload) : Promise> { const { data: episodes } = await this.listSeriesID(id); console.info(''); console.info('-'.repeat(30)); @@ -1769,12 +2309,18 @@ export default class Crunchy implements ServiceClass { e: epNum, image: images[Math.floor(images.length / 2)].source, }; - if (item.__links__.streams.href) { + if (item.__links__?.streams?.href) { epMeta.data[0].playback = item.__links__.streams.href; if(!item.playback) { item.playback = item.__links__.streams.href; } } + if (item.streams_link) { + epMeta.data[0].playback = item.streams_link; + if(!item.playback) { + item.playback = item.streams_link; + } + } // find episode numbers if(item.playback && ((but && !doEpsFilter.isSelected([epNum, item.id])) || (all || (doEpsFilter.isSelected([epNum, item.id])) && !but))) { if (Object.prototype.hasOwnProperty.call(ret, key)) { @@ -1875,28 +2421,43 @@ export default class Crunchy implements ServiceClass { const showInfo = JSON.parse(showInfoReq.res.body); if (log) this.logObject(showInfo, 0); + + let episodeList = { total: 0, data: [], meta: {} } as CrunchyEpisodeList; //get episode info - - const reqEpsListOpts = [ - api.beta_cms, - this.cmsToken.cms.bucket, - '/episodes?', - new URLSearchParams({ - 'season_id': item.id, - 'Policy': this.cmsToken.cms.policy, - 'Signature': this.cmsToken.cms.signature, - 'Key-Pair-Id': this.cmsToken.cms.key_pair_id, - }), - ].join(''); - - const reqEpsList = await this.req.getData(reqEpsListOpts, AuthHeaders); - //const reqEpsList = await this.req.getData(`${api.cms}/seasons/${item.id}/episodes?preferred_audio_language=ja-JP`, AuthHeaders); - if(!reqEpsList.ok || !reqEpsList.res){ - console.error('Episode List Request FAILED!'); - return; + if (this.api == 'android') { + const reqEpsListOpts = [ + api.beta_cms, + this.cmsToken.cms.bucket, + '/episodes?', + new URLSearchParams({ + 'preferred_audio_language': 'ja-JP', + 'season_id': item.id, + 'Policy': this.cmsToken.cms.policy, + 'Signature': this.cmsToken.cms.signature, + 'Key-Pair-Id': this.cmsToken.cms.key_pair_id, + }), + ].join(''); + const reqEpsList = await this.req.getData(reqEpsListOpts, AuthHeaders); + if(!reqEpsList.ok || !reqEpsList.res){ + console.error('Episode List Request FAILED!'); + return; + } + //CrunchyEpisodeList + const episodeListAndroid = JSON.parse(reqEpsList.res.body) as CrunchyAndroidEpisodes; + episodeList = { + total: episodeListAndroid.total, + data: episodeListAndroid.items, + meta: {} + }; + } else { + const reqEpsList = await this.req.getData(`${api.cms}/seasons/${item.id}/episodes?preferred_audio_language=ja-JP`, AuthHeaders); + if(!reqEpsList.ok || !reqEpsList.res){ + console.error('Episode List Request FAILED!'); + return; + } + //CrunchyEpisodeList + episodeList = JSON.parse(reqEpsList.res.body) as CrunchyEpisodeList; } - //CrunchyEpisodeList - const episodeList = JSON.parse(reqEpsList.res.body) as CrunchyAndroidEpisodes; if(episodeList.total < 1){ console.info(' Season is empty!'); diff --git a/docs/DOCUMENTATION.md b/docs/DOCUMENTATION.md index e6813d3..0101e26 100644 --- a/docs/DOCUMENTATION.md +++ b/docs/DOCUMENTATION.md @@ -1,4 +1,4 @@ -# multi-downloader-nx (4.4.4v) +# multi-downloader-nx (4.5.1v) If you find any bugs in this documentation or in the programm itself please report it [over on GitHub](https://github.com/anidl/multi-downloader-nx/issues). @@ -98,8 +98,7 @@ Get video list by Movie Listing ID | --- | --- | --- | --- | --- | ---| | Crunchyroll | `--series ${ID}` | `string` | `No`| `--srz` | `NaN` | -This command is used only for crunchyroll. - Requested is the ID of a show not a season. +Requested is the ID of a show not a season. #### `-s` | **Service** | **Usage** | **Type** | **Required** | **Alias** | **cli-default Entry** | --- | --- | --- | --- | --- | ---| @@ -136,6 +135,27 @@ If selected, the best selected quality will be downloaded only for the first lan then the worst video quality with the same audio quality will be downloaded for every other language. By the later merge of the videos, no quality difference will be present. This will speed up the download speed, if multiple languages are selected. +#### `--chapters` +| **Service** | **Usage** | **Type** | **Required** | **Alias** | **Default** |**cli-default Entry** +| --- | --- | --- | --- | --- | --- | ---| +| Crunchyroll | `--chapters ` | `boolean` | `No`| `NaN` | `false`| `chapters: ` | + +Will fetch the chapters and add them into the final video. +Currently only works with mkvmerge. +#### `--crapi` +| **Service** | **Usage** | **Type** | **Required** | **Alias** | **Choices** | **Default** |**cli-default Entry** +| --- | --- | --- | --- | --- | --- | --- | ---| +| Crunchyroll | `--crapi ` | `string` | `No`| `NaN` | [`android`, `web`] | `android`| `crapi: ` | + +If set to Android, it has lower quality, but Non-DRM streams, +If set to Web, it has a higher quality adaptive stream, but everything is DRM. +#### `--hdapi` +| **Service** | **Usage** | **Type** | **Required** | **Alias** | **Choices** | **Default** |**cli-default Entry** +| --- | --- | --- | --- | --- | --- | --- | ---| +| Hidive | `--hdapi ` | `string` | `No`| `NaN` | [`old`, `new`] | `old`| `hdapi: ` | + +If set to Old, it has lower quality, but Non-DRM streams, but some people can't use it, +If set to New, it has a higher quality stream, but everything is DRM. #### `--removeBumpers` | **Service** | **Usage** | **Type** | **Required** | **Alias** | **Default** |**cli-default Entry** | --- | --- | --- | --- | --- | --- | ---| diff --git a/docs/README.md b/docs/README.md index 0db5b24..dab0de0 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,11 +8,8 @@ This downloader can download anime from different sites. Currently supported are This application is not endorsed by or affiliated with *Funimation*, *Crunchyroll*, or *Hidive*. This application enables you to download videos for offline viewing which may be forbidden by law in your country. The usage of this application may also cause a violation of the *Terms of Service* between you and the stream provider. This tool is not responsible for your actions; please make an informed decision before using this application. -## Prerequisites +## Dependencies -* NodeJS >= 14.6.0 (https://nodejs.org/) -* NPM >= 6.9.0 (https://www.npmjs.org/) -* PNPM >= 7.0.0 (https://pnpm.io/) * ffmpeg >= 4.0.0 (https://www.videohelp.com/software/ffmpeg) * MKVToolNix >= 60.0.0 (https://www.videohelp.com/software/MKVToolNix) @@ -23,22 +20,53 @@ By default this application uses the following paths to programs (main executabl * `ffmpeg.exe` (From PATH) * `ffprobe.exe` (From PATH) * `mkvmerge.exe` (From PATH) +* `mp4decrypt.exe` (From PATH) To change these paths you need to edit `bin-path.yml` in `./config/` directory. -### Node Modules +## CLI Information -After installing NodeJS with NPM go to directory with `package.json` file and type: `npm i`. Afterwards run `npm run tsc`. You can now find a lib folder containing the js code execute. +See [the documentation](https://github.com/anidl/multi-downloader-nx/blob/master/docs/DOCUMENTATION.md) for a complete list of what options are available. You can define defaults for the commands by editing the `cli-defaults.yml` file in the `./config/` directory. -* [check dependencies](https://david-dm.org/anidl/funimation-downloader-nx) +### Example usage -## CLI Options +#### Logging in -See [the documentation](https://github.com/anidl/multi-downloader-nx/blob/master/docs/DOCUMENTATION.md) +Most services require you to be logged in, in order to download from, an example of how you would login is: -## Build instructions +```shell +AniDL --service {ServiceName} --auth +``` -Please note that nodejs, npm, and pnpm must be installed in your system. For instructions on how to install pnpm, check (https://pnpm.io/installation) +#### Searching + +In order to find the IDs to download, you can search from each service by using the `--search` flag like this: + +```shell +AniDL --service {ServiceName} --search {SearchTerm} +``` + +#### Downloading + +Once you have the ID which you can obtain from using the search or other means, you are ready to download, which you can do like this: + +```shell +AniDL --service {ServiceName} -s {SeasonID} -e {EpisodeNumber} +``` + +## Building and running from source + +### Build Dependencies + +Dependencies that are only required for running from code. These are not required if you are using the prebuilt binaries. + +* NodeJS >= 14.6.0 (https://nodejs.org/) +* NPM >= 6.9.0 (https://www.npmjs.org/) +* PNPM >= 7.0.0 (https://pnpm.io/) + +### Build Instructions + +Please note that NodeJS, NPM, and PNPM must be installed on your system. For instructions on how to install pnpm, check (https://pnpm.io/installation) First clone this repo `git clone https://github.com/anidl/multi-downloader-nx.git`. @@ -47,4 +75,14 @@ Afterwards run `pnpm run tsc false [true if you want gui, false otherwise]`. If you want the `js` files you are done. Just `cd` into the `lib` folder, and run `node index.js --help` to get started with the CLI, or run `node gui.js` to run the GUI -If you want to package the application, run pnpm run build-`{platform}`-`{type}` where `{platform}` is the operating system (currently the choices are windows, ubuntu, macos, and arm) and `{type}` is cli or gui. +If you want to package the application, run pnpm run build-`{platform}`-`{type}` where `{platform}` is the operating system (currently the choices are windows, linux, macos, alpine, android, and arm) and `{type}` is cli or gui. + +## DRM Decryption + +### Decryption Requirements + +* mp4decrypt >= Any (http://www.bento4.com/) - Only required for decrypting + +### Instructions + +In order to decrypt DRM content, you will need to have a dumped CDM, after that you will need to place the CDM files (`device_client_id_blob` and `device_private_key`) into the `./widevine/` directory. For legal reasons we do not include the CDM with the software, and you will have to source one yourself. diff --git a/gui/react/public/favicon.webp b/gui/react/public/favicon.webp new file mode 100644 index 0000000..279efcf Binary files /dev/null and b/gui/react/public/favicon.webp differ diff --git a/gui/react/public/index.html b/gui/react/public/index.html index 92cc7d8..e0f99bb 100644 --- a/gui/react/public/index.html +++ b/gui/react/public/index.html @@ -1,6 +1,8 @@ + Multi Downloader + { const messageHandler = React.useContext(messageChannelContext); - return + return - + - - - - + + diff --git a/gui/react/src/Style.tsx b/gui/react/src/Style.tsx index 4f44a07..8ac45f8 100644 --- a/gui/react/src/Style.tsx +++ b/gui/react/src/Style.tsx @@ -11,10 +11,8 @@ const makeTheme = (mode: 'dark'|'light') : Partial => { const Style: FCWithChildren = ({children}) => { return - - + {children} - ; }; diff --git a/gui/react/src/components/AddToQueue/AddToQueue.tsx b/gui/react/src/components/AddToQueue/AddToQueue.tsx index 98333aa..6e19041 100644 --- a/gui/react/src/components/AddToQueue/AddToQueue.tsx +++ b/gui/react/src/components/AddToQueue/AddToQueue.tsx @@ -1,5 +1,5 @@ import { Add } from '@mui/icons-material'; -import { Box, Button, Dialog, Divider } from '@mui/material'; +import { Box, Button, Dialog, Divider, Typography } from '@mui/material'; import React from 'react'; import DownloadSelector from './DownloadSelector/DownloadSelector'; import EpisodeListing from './DownloadSelector/Listing/EpisodeListing'; @@ -10,14 +10,14 @@ const AddToQueue: React.FC = () => { return - setOpen(false)} maxWidth='md'> - + setOpen(false)} maxWidth='md' PaperProps={{ elevation:4 }}> + - Options + setOpen(false)} /> - diff --git a/gui/react/src/components/AddToQueue/DownloadSelector/DownloadSelector.tsx b/gui/react/src/components/AddToQueue/DownloadSelector/DownloadSelector.tsx index 489b8f1..d1d5ed4 100644 --- a/gui/react/src/components/AddToQueue/DownloadSelector/DownloadSelector.tsx +++ b/gui/react/src/components/AddToQueue/DownloadSelector/DownloadSelector.tsx @@ -1,10 +1,11 @@ import React from 'react'; -import { Box, Button, TextField } from '@mui/material'; +import { Box, Button, Divider, InputBase, Link, MenuItem, Select, TextField, Tooltip, Typography } from '@mui/material'; import useStore from '../../../hooks/useStore'; import MultiSelect from '../../reusable/MultiSelect'; import { messageChannelContext } from '../../../provider/MessageChannel'; import LoadingButton from '@mui/lab/LoadingButton'; import { useSnackbar } from 'notistack'; +import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'; type DownloadSelectorProps = { onFinish?: () => unknown @@ -78,14 +79,36 @@ const DownloadSelector: React.FC = ({ onFinish }) => { setLoading(false); }; - return - + return + + + + + General Options + { dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, id: e.target.value } }); - }} label='Item ID' /> + }} label='Show ID'/> { const parsed = parseInt(e.target.value); if (isNaN(parsed) || parsed < 0 || parsed > 10) @@ -94,13 +117,77 @@ const DownloadSelector: React.FC = ({ onFinish }) => { type: 'downloadOptions', payload: { ...store.downloadOptions, q: parsed } }); - }} label='Quality Level (0 for max)' /> - { - dispatch({ - type: 'downloadOptions', - payload: { ...store.downloadOptions, e: e.target.value } - }); - }} label='Episode Select' /> + }} label='Quality Level (0 for max)'/> + + + + + + + Currently only supported on Hidive + + } + arrow + placement='top'> + + + + + + Episode Options + + + + { + dispatch({ + type: 'downloadOptions', + payload: { ...store.downloadOptions, e: e.target.value } + }); + }} placeholder='Episode Select'/> + + List
Episodes
+
+
+ + +
+ + + Language Options + = ({ onFinish }) => { }} allOption /> + = ({ onFinish }) => { }); }} /> - { + + Comming Soonâ„¢ + + } + arrow placement='top'> + + + + + + + + + + Burns the selected subtitle PERMANENTLY onto the video
You can choose only 1 subtitle per video + + } arrow placement='top'> + +
+
+
+
+
+ + + { dispatch({ type: 'downloadOptions', payload: { ...store.downloadOptions, fileName: e.target.value } }); - }} sx={{ width: '50%' }} label='Filename' /> - - - - - - - - List episodes - Add to Queue + }} sx={{ width: '87%' }} label='Filename Overwrite' /> + + Click here to see the documentation + + } arrow placement='top'> + + + + + + + + Add to Queue + ; }; diff --git a/gui/react/src/components/LogoutButton.tsx b/gui/react/src/components/LogoutButton.tsx index c324dda..916db7a 100644 --- a/gui/react/src/components/LogoutButton.tsx +++ b/gui/react/src/components/LogoutButton.tsx @@ -26,6 +26,7 @@ const LogoutButton: React.FC = () => { startIcon={} variant='contained' onClick={logout} + sx={{ maxHeight: '2.3rem' }} > Service select diff --git a/gui/react/src/components/MainFrame/MainFrame.css b/gui/react/src/components/MainFrame/MainFrame.css deleted file mode 100644 index 2bbc1ad..0000000 --- a/gui/react/src/components/MainFrame/MainFrame.css +++ /dev/null @@ -1,4 +0,0 @@ -.divider-width::before, .divider-width::after { - border-top: 3px solid white !important; - transform: translateY(40%) !important; -} \ No newline at end of file diff --git a/gui/react/src/components/MainFrame/MainFrame.tsx b/gui/react/src/components/MainFrame/MainFrame.tsx index de4db33..425b321 100644 --- a/gui/react/src/components/MainFrame/MainFrame.tsx +++ b/gui/react/src/components/MainFrame/MainFrame.tsx @@ -1,10 +1,9 @@ import { Box } from '@mui/material'; import React from 'react'; -import './MainFrame.css'; import Queue from './Queue/Queue'; const MainFrame: React.FC = () => { - return + return ; }; diff --git a/gui/react/src/components/MainFrame/Queue/Queue.tsx b/gui/react/src/components/MainFrame/Queue/Queue.tsx index 5a79c9e..315354a 100644 --- a/gui/react/src/components/MainFrame/Queue/Queue.tsx +++ b/gui/react/src/components/MainFrame/Queue/Queue.tsx @@ -1,7 +1,8 @@ -import { Box, Button, CircularProgress, Divider, LinearProgress, Skeleton, Typography } from '@mui/material'; +import { Badge, Box, Button, CircularProgress, Divider, IconButton, LinearProgress, Skeleton, Tooltip, Typography } from '@mui/material'; import React from 'react'; import { messageChannelContext } from '../../../provider/MessageChannel'; import { queueContext } from '../../../provider/QueueProvider'; +import DeleteIcon from '@mui/icons-material/Delete'; import useDownloadManager from '../DownloadManager/DownloadManager'; @@ -16,102 +17,393 @@ const Queue: React.FC = () => { return data || queue.length > 0 ? <> {data && <> - - Thumbnail - - - - - {data.downloadInfo.title} - - - Language: {data.downloadInfo.language.name} - - - + + + Thumbnail + + + + + {data.downloadInfo.parent.title} + + {data.downloadInfo.title} + - + + + + Downloading: {data.downloadInfo.language.name} + + + + + - + {data.progress.cur} / {(data.progress.total)} parts ({data.progress.percent}% | {formatTime(data.progress.time)} | {(data.progress.downloadSpeed / 1024 / 1024).toFixed(2)} MB/s | {(data.progress.bytes / 1024 / 1024).toFixed(2)}MB) + + } { current && !data && <> - - Thumbnail - - - - - {current.title} - - - Language: - - - - {current.parent.title} - - - - - - 0 / ? parts (0% | X:XX | 0 MB/s | 0MB) - - + + + Thumbnail + + + + + + {current.parent.title} + + + {current.title} + + + + + Downloading: + + + + + + + + + + 0 / ? parts (0% | XX:XX | 0 MB/s | 0MB) + + + + + + } - {queue.length && data && } {queue.map((queueItem, index, { length }) => { - return - - Thumbnail - - - - - {queueItem.title} + return + + Thumbnail + + + + {queueItem.parent.title} - - Languages: {queueItem.dubLang.join(', ')} + + S{queueItem.parent.season}E{queueItem.episode} + + + {queueItem.title} + + + + + Dub(s): {queueItem.dubLang.join(', ')} + + + Sub(s): {queueItem.dlsubs.join(', ')} + + + Quality: {queueItem.q} - - {queueItem.parent.title} - - - - S{queueItem.parent.season}E{queueItem.episode}
- Quality: {queueItem.q} -
- + }} + sx={{ + backgroundColor: '#ff573a25', + height: '40px', + transition: '250ms', + '&:hover' : { + backgroundColor: '#ff573a', + } + }}> + + + +
+
- {index < length - 1 && } -
; + ; })} - : - + : + Selected episodes will be shown here - - - - - + + + + + + + + + + + + ; diff --git a/gui/react/src/components/MenuBar/MenuBar.tsx b/gui/react/src/components/MenuBar/MenuBar.tsx index 5d74377..9efae16 100644 --- a/gui/react/src/components/MenuBar/MenuBar.tsx +++ b/gui/react/src/components/MenuBar/MenuBar.tsx @@ -44,13 +44,15 @@ const MenuBar: React.FC = () => { if (!msg) return <>; - return + return + + { msg.openFolder('config'); @@ -108,7 +110,7 @@ const MenuBar: React.FC = () => { Version: {store.version} - + {transformService(store.service)} ; diff --git a/gui/react/src/components/StartQueue.tsx b/gui/react/src/components/StartQueue.tsx index ecab378..05b630c 100644 --- a/gui/react/src/components/StartQueue.tsx +++ b/gui/react/src/components/StartQueue.tsx @@ -29,6 +29,7 @@ const StartQueueButton: React.FC = () => { startIcon={start ? : } variant='contained' onClick={change} + sx={{ maxHeight: '2.3rem' }} > { start ? 'Stop Queue' : 'Start Queue' diff --git a/gui/react/src/index.tsx b/gui/react/src/index.tsx index c1e1261..7f4bf6d 100644 --- a/gui/react/src/index.tsx +++ b/gui/react/src/index.tsx @@ -4,13 +4,17 @@ import App from './App'; import ServiceProvider from './provider/ServiceProvider'; import Style from './Style'; import MessageChannel from './provider/MessageChannel'; -import { IconButton } from '@mui/material'; +import { Box, IconButton } from '@mui/material'; import { CloseOutlined } from '@mui/icons-material'; import { SnackbarProvider, SnackbarKey } from 'notistack'; import Store from './provider/Store'; import ErrorHandler from './provider/ErrorHandler'; import QueueProvider from './provider/QueueProvider'; +document.body.style.backgroundColor = "rgb(0, 30, 60)"; +document.body.style.display = 'flex'; +document.body.style.justifyContent = 'center'; + const notistackRef = React.createRef(); const onClickDismiss = (key: SnackbarKey | undefined) => () => { if (notistackRef.current) @@ -34,7 +38,9 @@ root.render( - + + + diff --git a/gui/react/src/provider/ServiceProvider.tsx b/gui/react/src/provider/ServiceProvider.tsx index 9aecfb5..eb770c5 100644 --- a/gui/react/src/provider/ServiceProvider.tsx +++ b/gui/react/src/provider/ServiceProvider.tsx @@ -18,14 +18,12 @@ const ServiceProvider: FCWithChildren = ({ children }) => { }; return service === undefined ? - - Please choose your service + + Please select your service - - - + : diff --git a/gui/react/src/provider/Store.tsx b/gui/react/src/provider/Store.tsx index 5054051..c82ef92 100644 --- a/gui/react/src/provider/Store.tsx +++ b/gui/react/src/provider/Store.tsx @@ -13,6 +13,8 @@ export type DownloadOptions = { all: boolean, but: boolean, novids: boolean, + hslang?: string, + simul: boolean, noaudio: boolean } @@ -48,7 +50,8 @@ const initialState: StoreState = { all: false, but: false, noaudio: false, - novids: false + novids: false, + simul: false }, service: undefined, episodeListing: [], diff --git a/gui/server/services/crunchyroll.ts b/gui/server/services/crunchyroll.ts index 9bc2777..89ad89e 100644 --- a/gui/server/services/crunchyroll.ts +++ b/gui/server/services/crunchyroll.ts @@ -91,6 +91,7 @@ class CrunchyHandler extends Base implements MessageHandler { console.debug(`Got download options: ${JSON.stringify(data)}`); this.setDownloading(true); const _default = yargs.appArgv(this.crunchy.cfg.cli, true); + this.crunchy.api = _default.crapi; const res = await this.crunchy.downloadFromSeriesID(data.id, { dubLang: data.dubLang, e: data.e @@ -98,7 +99,7 @@ class CrunchyHandler extends Base implements MessageHandler { if (res.isOk) { for (const select of res.value) { if (!(await this.crunchy.downloadEpisode(select, {..._default, skipsubs: false, callbackMaker: this.makeProgressHandler.bind(this), q: data.q, fileName: data.fileName, dlsubs: data.dlsubs, dlVideoOnce: data.dlVideoOnce, force: 'y', - novids: data.novids }))) { + novids: data.novids, hslang: data.hslang || 'none' }))) { const er = new Error(`Unable to download episode ${data.e} from ${data.id}`); er.name = 'Download error'; this.alertError(er); diff --git a/gui/server/services/funimation.ts b/gui/server/services/funimation.ts index bee900e..3bfc4eb 100644 --- a/gui/server/services/funimation.ts +++ b/gui/server/services/funimation.ts @@ -70,7 +70,7 @@ class FunimationHandler extends Base implements MessageHandler { }, image: a.image, e: a.episodeID, - episode: a.epsiodeNumber, + episode: a.epsiodeNumber }; })); return true; diff --git a/gui/server/services/hidive.ts b/gui/server/services/hidive.ts index f3da018..a61dd72 100644 --- a/gui/server/services/hidive.ts +++ b/gui/server/services/hidive.ts @@ -26,7 +26,13 @@ class HidiveHandler extends Base implements MessageHandler { return { isOk: true, value: undefined }; } + public async getAPIVersion() { + const _default = yargs.appArgv(this.hidive.cfg.cli, true); + this.hidive.api = _default.hdapi; + } + public async search(data: SearchData): Promise { + await this.getAPIVersion(); console.debug(`Got search options: ${JSON.stringify(data)}`); const hidiveSearch = await this.hidive.doSearch(data); if (!hidiveSearch.isOk) { @@ -42,7 +48,7 @@ class HidiveHandler extends Base implements MessageHandler { public async availableDubCodes(): Promise { const dubLanguageCodesArray: string[] = []; for(const language of languages){ - if (language.hd_locale) + if (language.new_hd_locale) dubLanguageCodesArray.push(language.code); } return [...new Set(dubLanguageCodesArray)]; @@ -51,7 +57,7 @@ class HidiveHandler extends Base implements MessageHandler { public async availableSubCodes(): Promise { const subLanguageCodesArray: string[] = []; for(const language of languages){ - if (language.hd_locale) + if (language.new_hd_locale) subLanguageCodesArray.push(language.locale); } return ['all', 'none', ...new Set(subLanguageCodesArray)]; @@ -62,63 +68,120 @@ class HidiveHandler extends Base implements MessageHandler { if (isNaN(parse) || parse <= 0) return false; console.debug(`Got resolve options: ${JSON.stringify(data)}`); - const res = await this.hidive.getShow(parseInt(data.id), data.e, data.but, data.all); - if (!res.isOk || !res.value) - return res.isOk; - this.addToQueue(res.value.map(item => { - return { - ...data, - ids: [item.Id], - title: item.Name, - parent: { - title: item.seriesTitle, - season: parseFloat(item.SeasonNumberValue+'')+'' - }, - image: item.ScreenShotSmallUrl, - e: parseFloat(item.EpisodeNumberValue+'')+'', - episode: parseFloat(item.EpisodeNumberValue+'')+'', - }; - })); - return true; + await this.getAPIVersion(); + if (this.hidive.api == 'old') { + const res = await this.hidive.getShow(parseInt(data.id), data.e, data.but, data.all); + if (!res.isOk || !res.value) + return res.isOk; + this.addToQueue(res.value.map(item => { + return { + ...data, + ids: [item.Id], + title: item.Name, + parent: { + title: item.seriesTitle, + season: parseFloat(item.SeasonNumberValue+'')+'' + }, + image: item.ScreenShotSmallUrl, + e: parseFloat(item.EpisodeNumberValue+'')+'', + episode: parseFloat(item.EpisodeNumberValue+'')+'', + }; + })); + return true; + } else { + const res = await this.hidive.selectSeries(parseInt(data.id), data.e, data.but, data.all); + if (!res.isOk || !res.value) + return res.isOk; + this.addToQueue(res.value.map(item => { + return { + ...data, + ids: [item.id], + title: item.title, + parent: { + title: item.seriesTitle, + season: item.episodeInformation.seasonNumber+'' + }, + image: item.thumbnailUrl, + e: item.episodeInformation.episodeNumber+'', + episode: item.episodeInformation.episodeNumber+'', + }; + })); + return true; + } } public async listEpisodes(id: string): Promise { const parse = parseInt(id); if (isNaN(parse) || parse <= 0) return { isOk: false, reason: new Error('The ID is invalid') }; - const request = await this.hidive.listShow(parse); - if (!request.isOk || !request.value) - return {isOk: false, reason: new Error('Unknown upstream error, check for additional logs')}; - return { isOk: true, value: request.value.Episodes.map(function(item) { - const language = item.Summary.match(/^Audio: (.*)/m); - language?.shift(); - const description = item.Summary.split('\r\n'); - return { - e: parseFloat(item.EpisodeNumberValue+'')+'', - lang: language ? language[0].split(', ') : [], - name: item.Name, - season: parseFloat(item.SeasonNumberValue+'')+'', - seasonTitle: request.value.Name, - episode: parseFloat(item.EpisodeNumberValue+'')+'', - id: item.Id+'', - img: item.ScreenShotSmallUrl, - description: description ? description[0] : '', - time: '' - }; - })}; + await this.getAPIVersion(); + if (this.hidive.api == 'old') { + const request = await this.hidive.listShow(parse); + if (!request.isOk || !request.value) + return {isOk: false, reason: new Error('Unknown upstream error, check for additional logs')}; + + return { isOk: true, value: request.value.Episodes.map(function(item) { + const language = item.Summary.match(/^Audio: (.*)/m); + language?.shift(); + const description = item.Summary.split('\r\n'); + return { + e: parseFloat(item.EpisodeNumberValue+'')+'', + lang: language ? language[0].split(', ') : [], + name: item.Name, + season: parseFloat(item.SeasonNumberValue+'')+'', + seasonTitle: request.value.Name, + episode: parseFloat(item.EpisodeNumberValue+'')+'', + id: item.Id+'', + img: item.ScreenShotSmallUrl, + description: description ? description[0] : '', + time: '' + }; + })}; + } else { + const request = await this.hidive.listSeries(parse); + if (!request.isOk || !request.value) + return {isOk: false, reason: new Error('Unknown upstream error, check for additional logs')}; + + return { isOk: true, value: request.value.map(function(item) { + const description = item.description.split('\r\n'); + return { + e: item.episodeInformation.episodeNumber+'', + lang: [], + name: item.title, + season: item.episodeInformation.seasonNumber+'', + seasonTitle: request.series.seasons[item.episodeInformation.seasonNumber-1].title, + episode: item.episodeInformation.episodeNumber+'', + id: item.id+'', + img: item.thumbnailUrl, + description: description ? description[0] : '', + time: '' + }; + })}; + } } public async downloadItem(data: DownloadData) { this.setDownloading(true); console.debug(`Got download options: ${JSON.stringify(data)}`); const _default = yargs.appArgv(this.hidive.cfg.cli, true); - const res = await this.hidive.getShow(parseInt(data.id), data.e, false, false); - if (!res.isOk || !res.showData) - return this.alertError(new Error('Download failed upstream, check for additional logs')); + this.hidive.api = _default.hdapi; + if (this.hidive.api == 'old') { + const res = await this.hidive.getShow(parseInt(data.id), data.e, false, false); + if (!res.isOk || !res.showData) + return this.alertError(new Error('Download failed upstream, check for additional logs')); - for (const ep of res.value) { - await this.hidive.getEpisode(ep, {..._default, callbackMaker: this.makeProgressHandler.bind(this), dubLang: data.dubLang, dlsubs: data.dlsubs, fileName: data.fileName, q: data.q, force: 'y', noaudio: data.noaudio, novids: data.novids}); + for (const ep of res.value) { + await this.hidive.getEpisode(ep, {..._default, callbackMaker: this.makeProgressHandler.bind(this), dubLang: data.dubLang, dlsubs: data.dlsubs, fileName: data.fileName, q: data.q, force: 'y', noaudio: data.noaudio, novids: data.novids }); + } + } else { + const res = await this.hidive.selectSeries(parseInt(data.id), data.e, false, false); + if (!res.isOk || !res.showData) + return this.alertError(new Error('Download failed upstream, check for additional logs')); + + for (const ep of res.value) { + await this.hidive.downloadEpisode(ep, {..._default, callbackMaker: this.makeProgressHandler.bind(this), dubLang: data.dubLang, dlsubs: data.dlsubs, fileName: data.fileName, q: data.q, force: 'y', noaudio: data.noaudio, novids: data.novids }); + } } this.sendMessage({ name: 'finish', data: undefined }); this.setDownloading(false); diff --git a/hidive.ts b/hidive.ts index 1681d11..f36ccc6 100644 --- a/hidive.ts +++ b/hidive.ts @@ -10,7 +10,7 @@ import packageJson from './package.json'; import { console } from './modules/log'; import shlp from 'sei-helper'; import m3u8 from 'm3u8-parsed'; -import streamdl from './modules/hls-download'; +import streamdl, { M3U8Json } from './modules/hls-download'; // custom modules import * as fontsData from './modules/module.fontsData'; @@ -34,12 +34,23 @@ import { ServiceClass } from './@types/serviceClassInterface'; import { sxItem } from './crunchy'; import { HidiveSearch } from './@types/hidiveSearch'; import { HidiveDashboard } from './@types/hidiveDashboard'; +import { Hit, NewHidiveSearch } from './@types/newHidiveSearch'; +import { NewHidiveSeries } from './@types/newHidiveSeries'; +import { Episode, NewHidiveEpisodeExtra, NewHidiveSeason, NewHidiveSeriesExtra } from './@types/newHidiveSeason'; +import { NewHidiveEpisode } from './@types/newHidiveEpisode'; +import { NewHidivePlayback, Subtitle } from './@types/newHidivePlayback'; +import { MPDParsed, parse } from './modules/module.transform-mpd'; +import getKeys, { canDecrypt } from './modules/widevine'; +import { exec } from './modules/sei-helper-fixes'; +import { KeyContainer } from './modules/license'; export default class Hidive implements ServiceClass { public cfg: yamlCfg.ConfigObject; private session: Record; + private tokenOld: Record; private token: Record; private req: reqModule.Req; + public api: 'old' | 'new'; private client: { // base ipAddress: string, @@ -58,34 +69,17 @@ export default class Hidive implements ServiceClass { constructor(private debug = false) { this.cfg = yamlCfg.loadCfg(); this.session = yamlCfg.loadHDSession(); - this.token = yamlCfg.loadHDToken(); + this.tokenOld = yamlCfg.loadHDToken(); + this.token = yamlCfg.loadNewHDToken(); this.client = yamlCfg.loadHDProfile() as {ipAddress: string, xNonce: string, xSignature: string, visitId: string, profile: {userId: number, profileId: number, deviceId : string}}; this.req = new reqModule.Req(domain, debug, false, 'hd'); - } - - public async doInit() { - //get client ip - const newIp = await this.reqData('Ping', ''); - if (!newIp.ok || !newIp.res) return false; - this.client.ipAddress = JSON.parse(newIp.res.body).IPAddress; - //get device id - const newDevice = await this.reqData('InitDevice', { 'DeviceName': api.hd_devName }); - if (!newDevice.ok || !newDevice.res) return false; - this.client.profile = Object.assign(this.client.profile, { - deviceId: JSON.parse(newDevice.res.body).Data.DeviceId, - }); - //get visit id - const newVisitId = await this.reqData('InitVisit', {}); - if (!newVisitId.ok || !newVisitId.res) return false; - this.client.visitId = JSON.parse(newVisitId.res.body).Data.VisitId; - //save client - yamlCfg.saveHDProfile(this.client); - return true; + this.api = 'old'; } public async cli() { console.info(`\n=== Multi Downloader NX ${packageJson.version} ===\n`); const argv = yargs.appArgv(this.cfg.cli); + this.api = argv.hdapi; if (argv.debug) this.debug = true; @@ -96,6 +90,16 @@ export default class Hidive implements ServiceClass { console.info(searchItems.res.body); fs.writeFileSync('apitest.json', JSON.stringify(JSON.parse(searchItems.res.body), null, 2));*/ + //new api testing + /*if (this.api == 'new') { + await this.doInit(); + const apiTest = await this.apiReq('/v4/season/18871', '', 'auth', 'GET'); + if(!apiTest.ok || !apiTest.res){return;} + console.info(apiTest.res.body); + fs.writeFileSync('apitest.json', JSON.stringify(JSON.parse(apiTest.res.body), null, 2)); + return console.info('test done'); + }*/ + // load binaries this.cfg.bin = await yamlCfg.loadBinCfg(); if (argv.allDubs) { @@ -115,30 +119,92 @@ export default class Hidive implements ServiceClass { //Search await this.doSearch({ ...argv, search: argv.search as string }); } else if (argv.s && !isNaN(parseInt(argv.s,10)) && parseInt(argv.s,10) > 0) { - //Initilize session - await this.doInit(); - //get selected episodes - const selected = await this.getShow(parseInt(argv.s), argv.e, argv.but, argv.all); - if (selected.isOk && selected.showData) { - for (const select of selected.value) { - //download episode - if (!(await this.getEpisode(select, {...argv}))) { - console.error(`Unable to download selected episode ${parseFloat(select.EpisodeNumberValue+'')}`); - return false; + if (this.api == 'old') { + //Initilize session + await this.doInit(); + //get selected episodes + const selected = await this.getShow(parseInt(argv.s), argv.e, argv.but, argv.all); + if (selected.isOk && selected.showData) { + for (const select of selected.value) { + //download episode + if (!(await this.getEpisode(select, {...argv}))) { + console.error(`Unable to download selected episode ${parseFloat(select.EpisodeNumberValue+'')}`); + return false; + } + } + } + } else { + const selected = await this.selectSeason(parseInt(argv.s), argv.e, argv.but, argv.all); + if (selected.isOk && selected.showData) { + for (const select of selected.value) { + //download episode + if (!(await this.downloadEpisode(select, {...argv}))) { + console.error(`Unable to download selected episode ${select.episodeInformation.episodeNumber}`); + return false; + } } } } return true; + } else if (argv.srz && !isNaN(parseInt(argv.srz,10)) && parseInt(argv.srz,10) > 0) { + const selected = await this.selectSeries(parseInt(argv.srz), argv.e, argv.but, argv.all); + if (selected.isOk && selected.showData) { + for (const select of selected.value) { + //download episode + if (!(await this.downloadEpisode(select, {...argv}))) { + console.error(`Unable to download selected episode ${select.episodeInformation.episodeNumber}`); + return false; + } + } + } } else if (argv.new) { - //Initilize session - await this.doInit(); - //Get Newly Added - await this.getNewlyAdded(argv.page); + if (this.api == 'old') { + //Initilize session + await this.doInit(); + //Get Newly Added + await this.getNewlyAdded(argv.page); + } else { + console.error('--new is not yet implemented in the new API'); + } + } else if(argv.e) { + if (this.api == 'new') { + if (!(await this.downloadSingleEpisode(parseInt(argv.e), {...argv}))) { + console.error(`Unable to download selected episode ${argv.e}`); + return false; + } + } else { + console.error('-e is not supported in the old API'); + } } else { console.info('No option selected or invalid value entered. Try --help.'); } } + public async doInit() { + if (this.api == 'old') { + //get client ip + const newIp = await this.reqData('Ping', ''); + if (!newIp.ok || !newIp.res) return false; + this.client.ipAddress = JSON.parse(newIp.res.body).IPAddress; + //get device id + const newDevice = await this.reqData('InitDevice', { 'DeviceName': api.hd_devName }); + if (!newDevice.ok || !newDevice.res) return false; + this.client.profile = Object.assign(this.client.profile, { + deviceId: JSON.parse(newDevice.res.body).Data.DeviceId, + }); + //get visit id + const newVisitId = await this.reqData('InitVisit', {}); + if (!newVisitId.ok || !newVisitId.res) return false; + this.client.visitId = JSON.parse(newVisitId.res.body).Data.VisitId; + //save client + yamlCfg.saveHDProfile(this.client); + return true; + } else { + //this.refreshToken(); + return true; + } + } + // Generate Nonce public generateNonce(){ const initDate = new Date(); @@ -296,22 +362,182 @@ export default class Hidive implements ServiceClass { } } - public async doAuth(data: AuthData): Promise { - const auth = await this.reqData('Authenticate', {'Email':data.username,'Password':data.password}); - if(!auth.ok || !auth.res) { - console.error('Authentication failed!'); - return { isOk: false, reason: new Error('Authentication failed') }; + public async apiReq(endpoint: string, body: string | object = '', authType: 'refresh' | 'auth' | 'both' | 'other' | 'none' = 'none', method: 'GET' | 'POST' = 'POST', authHeader?: string) { + const options = { + headers: { + 'X-Api-Key': api.hd_new_apiKey, + 'X-App-Var': api.hd_new_version, + 'realm': 'dce.hidive', + 'Referer': 'https://www.hidive.com/', + 'Origin': 'https://www.hidive.com' + } as Record, + method: method as 'GET'|'POST', + url: api.hd_new_api+endpoint as string, + body: body, + useProxy: true + }; + // get request type + const isGet = method == 'GET' ? true : false; + if(!isGet){ + options.body = body == '' ? body : JSON.stringify(body); + options.headers['Content-Type'] = 'application/json'; } - const authData = JSON.parse(auth.res.body).Data; - this.client.profile = Object.assign(this.client.profile, { - userId: authData.User.Id, - profileId: authData.Profiles[0].Id, - }); - yamlCfg.saveHDProfile(this.client); - yamlCfg.saveHDToken(authData); - console.info('[INFO] Auth complete!'); - console.info(`[INFO] Service level for "${data.username}" is ${authData.User.ServiceLevel}`); - return { isOk: true, value: undefined }; + if (authType == 'other') { + options.headers['Authorization'] = authHeader; + } else if (authType == 'auth') { + options.headers['Authorization'] = `Bearer ${this.token.authorisationToken}`; + } else if (authType == 'refresh') { + options.headers['Authorization'] = `Bearer ${this.token.refreshToken}`; + } else if (authType == 'both') { + options.headers['Authorization'] = `Mixed ${this.token.authorisationToken} ${this.token.refreshToken}`; + } + if (this.debug) { + console.debug('[DEBUG] Request params:'); + console.debug(options); + } + const apiReqOpts: reqModule.Params = { + method: options.method, + headers: options.headers as Record, + body: options.body as string + }; + let apiReq = await this.req.getData(options.url, apiReqOpts); + if(!apiReq.ok || !apiReq.res){ + if (apiReq.error && apiReq.error.res.statusCode == 401) { + console.warn('Token expired, refreshing token and retrying.'); + if (await this.refreshToken()) { + if (authType == 'other') { + options.headers['Authorization'] = authHeader; + } else if (authType == 'auth') { + options.headers['Authorization'] = `Bearer ${this.token.authorisationToken}`; + } else if (authType == 'refresh') { + options.headers['Authorization'] = `Bearer ${this.token.refreshToken}`; + } else if (authType == 'both') { + options.headers['Authorization'] = `Mixed ${this.token.authorisationToken} ${this.token.refreshToken}`; + } + apiReq = await this.req.getData(options.url, apiReqOpts); + if(!apiReq.ok || !apiReq.res) { + console.error('API Request Failed!'); + return { + ok: false, + res: apiReq.res, + error: apiReq.error + }; + } + } else { + console.error('Failed to refresh token...'); + return { + ok: false, + res: apiReq.res, + error: apiReq.error + }; + } + } else { + console.error('API Request Failed!'); + return { + ok: false, + res: apiReq.res, + error: apiReq.error + }; + } + } + return { + ok: true, + res: apiReq.res, + }; + } + + public async doAuth(data: AuthData): Promise { + if (this.api == 'old') { + const auth = await this.reqData('Authenticate', {'Email':data.username,'Password':data.password}); + if(!auth.ok || !auth.res) { + console.error('Authentication failed!'); + return { isOk: false, reason: new Error('Authentication failed') }; + } + const authData = JSON.parse(auth.res.body).Data; + this.client.profile = Object.assign(this.client.profile, { + userId: authData.User.Id, + profileId: authData.Profiles[0].Id, + }); + yamlCfg.saveHDProfile(this.client); + yamlCfg.saveHDToken(authData); + console.info('Auth complete!'); + console.info(`Service level for "${data.username}" is ${authData.User.ServiceLevel}`); + return { isOk: true, value: undefined }; + } else { + if (!this.token.refreshToken || !this.token.authorisationToken) { + await this.doAnonymousAuth(); + } + const authReq = await this.apiReq('/v2/login', { + id: data.username, + secret: data.password + }, 'auth'); + if(!authReq.ok || !authReq.res){ + console.error('Authentication failed!'); + return { isOk: false, reason: new Error('Authentication failed') }; + } + const tokens: Record = JSON.parse(authReq.res.body); + for (const token in tokens) { + this.token[token] = tokens[token]; + } + this.token.guest = false; + yamlCfg.saveNewHDToken(this.token); + console.info('Auth complete!'); + return { isOk: true, value: undefined }; + } + } + + public async doAnonymousAuth() { + const authReq = await this.apiReq('/v2/login/guest/checkin'); + if(!authReq.ok || !authReq.res){ + console.error('Authentication failed!'); + return false; + } + const tokens: Record = JSON.parse(authReq.res.body); + for (const token in tokens) { + this.token[token] = tokens[token]; + } + //this.token.expires = new Date(Date.now() + 300); + this.token.guest = true; + yamlCfg.saveNewHDToken(this.token); + return true; + } + + public async refreshToken() { + if (!this.token.refreshToken || !this.token.authorisationToken) { + return await this.doAnonymousAuth(); + } else { + const authReq = await this.apiReq('/v2/token/refresh', { + 'refreshToken': this.token.refreshToken + }, 'auth'); + if(!authReq.ok || !authReq.res){ + console.error('Token refresh failed, reinitializing session...'); + if (!this.initSession()) { + return false; + } else { + return true; + } + } + const tokens: Record = JSON.parse(authReq.res.body); + for (const token in tokens) { + this.token[token] = tokens[token]; + } + yamlCfg.saveNewHDToken(this.token); + return true; + } + } + + public async initSession() { + const authReq = await this.apiReq('/v1/init/', '', 'both', 'GET'); + if(!authReq.ok || !authReq.res){ + console.error('Failed to initialize session.'); + return false; + } + const tokens: Record = JSON.parse(authReq.res.body).authentication; + for (const token in tokens) { + this.token[token] = tokens[token]; + } + yamlCfg.saveNewHDToken(this.token); + return true; } public async genSubsUrl(type: string, file: string) { @@ -323,30 +549,74 @@ export default class Hidive implements ServiceClass { } public async doSearch(data: SearchData): Promise { - const searchReq = await this.reqData('Search', {'Query':data.search}); - if(!searchReq.ok || !searchReq.res){ - console.error('Search FAILED!'); - return { isOk: false, reason: new Error('Search failed. No more information provided') }; - } - const searchData = JSON.parse(searchReq.res.body) as HidiveSearch; - const searchItems = searchData.Data.TitleResults; - if(searchItems.length>0) { - console.info('[INFO] Search Results:'); - for(let i=0;i0) { + console.info('[INFO] Search Results:'); + for(let i=0;i { + return { + id: a.Id+'', + image: a.KeyArtUrl ?? '/notFound.png', + name: a.Name, + rating: a.OverallRating, + desc: a.LongSynopsis + }; + })}; + } else { + const searchReq = await this.req.getData('https://h99xldr8mj-dsn.algolia.net/1/indexes/*/queries?x-algolia-agent=Algolia%20for%20JavaScript%20(3.35.1)%3B%20Browser&x-algolia-application-id=H99XLDR8MJ&x-algolia-api-key=e55ccb3db0399eabe2bfc37a0314c346', { + method: 'POST', + body: JSON.stringify({'requests': + [ + {'indexName':'prod-dce.hidive-livestreaming-events','params':'query='+encodeURIComponent(data.search)+'&facetFilters=%5B%22type%3ALIVE_EVENT%22%5D&hitsPerPage=25'+(data.page ? '&page='+(data.page-1) : '')}, + {'indexName':'prod-dce.hidive-livestreaming-events','params':'query='+encodeURIComponent(data.search)+'&facetFilters=%5B%22type%3AVOD_VIDEO%22%5D&hitsPerPage=25'+(data.page ? '&page='+(data.page-1) : '')}, + {'indexName':'prod-dce.hidive-livestreaming-events','params':'query='+encodeURIComponent(data.search)+'&facetFilters=%5B%22type%3AVOD_PLAYLIST%22%5D&hitsPerPage=25'+(data.page ? '&page='+(data.page-1) : '')}, + {'indexName':'prod-dce.hidive-livestreaming-events','params':'query='+encodeURIComponent(data.search)+'&facetFilters=%5B%22type%3AVOD_SERIES%22%5D&hitsPerPage=25'+(data.page ? '&page='+(data.page-1) : '')} + ] + }) + }); + if(!searchReq.ok || !searchReq.res){ + console.error('Search FAILED!'); + return { isOk: false, reason: new Error('Search failed. No more information provided') }; + } + const searchData = JSON.parse(searchReq.res.body) as NewHidiveSearch; + const searchItems: Hit[] = []; + console.info('Search Results:'); + for (const category of searchData.results) { + for (const hit of category.hits) { + searchItems.push(hit); + let fullType: string; + if (hit.type == 'VOD_SERIES') { + fullType = `Z.${hit.id}`; + } else if (hit.type == 'VOD_VIDEO') { + fullType = `E.${hit.id}`; + } else { + fullType = `${hit.type} #${hit.id}`; + } + console.log(`[${fullType}] ${hit.name} ${hit.seasonsCount ? '('+hit.seasonsCount+' Seasons)' : ''}`); + } + } + return { isOk: true, value: searchItems.filter(a => a.type == 'VOD_SERIES').flatMap((a): SearchResponseItem => { + return { + id: a.id+'', + image: a.coverUrl ?? '/notFound.png', + name: a.name, + rating: -1, + desc: a.description + }; + })}; } - return { isOk: true, value: searchItems.map((a): SearchResponseItem => { - return { - id: a.Id+'', - image: a.KeyArtUrl ?? '/notFound.png', - name: a.Name, - rating: a.OverallRating, - desc: a.LongSynopsis - }; - })}; } public async getNewlyAdded(page?: number) { @@ -376,11 +646,190 @@ export default class Hidive implements ServiceClass { } } + public async getSeries(id: number) { + const getSeriesData = await this.apiReq(`/v4/series/${id}?rpp=20`, '', 'auth', 'GET'); + if (!getSeriesData.ok || !getSeriesData.res) { + console.error('Failed to get Series Data'); + return { isOk: false }; + } + const seriesData = JSON.parse(getSeriesData.res.body) as NewHidiveSeries; + return { isOk: true, value: seriesData }; + } + + /** + * Function to get the season data from the API + * @param id ID of the season + * @param lastSeen Last episode ID seen, used for paging + * @returns + */ + public async getSeason(id: number, lastSeen?: number) { + const getSeasonData = await this.apiReq(`/v4/season/${id}?rpp=20${lastSeen ? '&lastSeen='+lastSeen : ''}`, '', 'auth', 'GET'); + if (!getSeasonData.ok || !getSeasonData.res) { + console.error('Failed to get Season Data'); + return { isOk: false }; + } + const seasonData = JSON.parse(getSeasonData.res.body) as NewHidiveSeason; + return { isOk: true, value: seasonData }; + } + + public async listSeries(id: number) { + const series = await this.getSeries(id); + if (!series.isOk || !series.value) { + console.error('Failed to list series data: Failed to get series'); + return { isOk: false }; + } + console.info(`[Z.${series.value.id}] ${series.value.title} (${series.value.seasons.length} Seasons)`); + for (const seasonData of series.value.seasons) { + const season = await this.getSeason(seasonData.id); + if (!season.isOk || !season.value) { + console.error('Failed to list series data: Failed to get season '+seasonData.id); + return { isOk: false }; + } + console.info(` [S.${season.value.id}] ${season.value.title} (${season.value.episodeCount} Episodes)`); + while (season.value.paging.moreDataAvailable) { + const seasonPage = await this.getSeason(seasonData.id, season.value.paging.lastSeen); + if (!seasonPage.isOk || !seasonPage.value) break; + season.value.episodes = season.value.episodes.concat(seasonPage.value.episodes); + season.value.paging.lastSeen = seasonPage.value.paging.lastSeen; + season.value.paging.moreDataAvailable = seasonPage.value.paging.moreDataAvailable; + } + const episodes: Episode[] = []; + for (const episode of season.value.episodes) { + if (episode.title.includes(' - ')) { + episode.episodeInformation.episodeNumber = parseFloat(episode.title.split(' - ')[0].replace('E', '')); + episode.title = episode.title.split(' - ')[1]; + } + //S${episode.episodeInformation.seasonNumber}E${episode.episodeInformation.episodeNumber} - + episodes.push(episode); + console.info(` [E.${episode.id}] ${episode.title}`); + } + return { isOk: true, value: episodes, series: series.value }; + } + console.info(' No Seasons found!'); + return { isOk: false }; + } + + public async listSeason(id: number) { + const season = await this.getSeason(id); + if (!season.isOk || !season.value) { + console.error('Failed to list series data: Failed to get season '+id); + return { isOk: false }; + } + console.info(` [S.${season.value.id}] ${season.value.title} (${season.value.episodeCount} Episodes)`); + while (season.value.paging.moreDataAvailable) { + const seasonPage = await this.getSeason(id, season.value.paging.lastSeen); + if (!seasonPage.isOk || !seasonPage.value) break; + season.value.episodes = season.value.episodes.concat(seasonPage.value.episodes); + season.value.paging.lastSeen = seasonPage.value.paging.lastSeen; + season.value.paging.moreDataAvailable = seasonPage.value.paging.moreDataAvailable; + } + const episodes: Episode[] = []; + for (const episode of season.value.episodes) { + if (episode.title.includes(' - ')) { + episode.episodeInformation.episodeNumber = parseFloat(episode.title.split(' - ')[0].replace('E', '')); + episode.title = episode.title.split(' - ')[1]; + } + //S${episode.episodeInformation.seasonNumber}E${episode.episodeInformation.episodeNumber} - + episodes.push(episode); + console.info(` [E.${episode.id}] ${episode.title}`); + } + const series: NewHidiveSeriesExtra = {...season.value.series, season: season.value}; + return { isOk: true, value: episodes, series: series }; + } + + /** + * Lists the requested series, and returns the selected episodes + * @param id Series ID + * @param e Selector + * @param but Download all but selected videos + * @param all Whether to download all available videos + * @returns + */ + public async selectSeries(id: number, e: string | undefined, but: boolean, all: boolean) { + const getShowData = await this.listSeries(id); + if (!getShowData.isOk || !getShowData.value) { + return { isOk: false, value: [] }; + } + const showData = getShowData.value; + const doEpsFilter = parseSelect(e as string); + // build selected episodes + const selEpsArr: NewHidiveEpisodeExtra[] = []; let ovaSeq = 1; let movieSeq = 1; + for (let i = 0; i < showData.length; i++) { + const titleId = showData[i].id; + const seriesTitle = getShowData.series.title; + const seasonTitle = getShowData.series.seasons[showData[i].episodeInformation.seasonNumber-1]?.title; + let nameLong = showData[i].title; + if (nameLong.match(/OVA/i)) { + nameLong = 'ova' + (('0' + ovaSeq).slice(-2)); ovaSeq++; + } else if (nameLong.match(/Theatrical/i)) { + nameLong = 'movie' + (('0' + movieSeq).slice(-2)); movieSeq++; + } + let selMark = ''; + if (all || + but && !doEpsFilter.isSelected([parseFloat(showData[i].episodeInformation.episodeNumber+'')+'', showData[i].id+'']) || + !but && doEpsFilter.isSelected([parseFloat(showData[i].episodeInformation.episodeNumber+'')+'', showData[i].id+'']) + ) { + selEpsArr.push({ isSelected: true, titleId, nameLong, seasonTitle, seriesTitle, ...showData[i] }); + selMark = '✓ '; + } + console.info('%s[%s] %s', + selMark, + 'S'+parseFloat(showData[i].episodeInformation.seasonNumber+'')+'E'+parseFloat(showData[i].episodeInformation.episodeNumber+''), + showData[i].title, + ); + } + return { isOk: true, value: selEpsArr, showData: getShowData.series }; + } + + /** + * Lists the requested season, and returns the selected episodes + * @param id Season ID + * @param e Selector + * @param but Download all but selected videos + * @param all Whether to download all available videos + * @returns + */ + public async selectSeason(id: number, e: string | undefined, but: boolean, all: boolean) { + const getShowData = await this.listSeason(id); + if (!getShowData.isOk || !getShowData.value) { + return { isOk: false, value: [] }; + } + const showData = getShowData.value; + const doEpsFilter = parseSelect(e as string); + // build selected episodes + const selEpsArr: NewHidiveEpisodeExtra[] = []; let ovaSeq = 1; let movieSeq = 1; + for (let i = 0; i < showData.length; i++) { + const titleId = showData[i].id; + const seriesTitle = getShowData.series.title; + const seasonTitle = getShowData.series.season.title; + let nameLong = showData[i].title; + if (nameLong.match(/OVA/i)) { + nameLong = 'ova' + (('0' + ovaSeq).slice(-2)); ovaSeq++; + } else if (nameLong.match(/Theatrical/i)) { + nameLong = 'movie' + (('0' + movieSeq).slice(-2)); movieSeq++; + } + let selMark = ''; + if (all || + but && !doEpsFilter.isSelected([parseFloat(showData[i].episodeInformation.episodeNumber+'')+'', showData[i].id+'']) || + !but && doEpsFilter.isSelected([parseFloat(showData[i].episodeInformation.episodeNumber+'')+'', showData[i].id+'']) + ) { + selEpsArr.push({ isSelected: true, titleId, nameLong, seasonTitle, seriesTitle, ...showData[i] }); + selMark = '✓ '; + } + console.info('%s[%s] %s', + selMark, + 'S'+parseFloat(showData[i].episodeInformation.seasonNumber+'')+'E'+parseFloat(showData[i].episodeInformation.episodeNumber+''), + showData[i].title, + ); + } + return { isOk: true, value: selEpsArr, showData: getShowData.series }; + } + public async listShow(id: number) { const getShowData = await this.reqData('GetTitle', { 'Id': id }); if (!getShowData.ok || !getShowData.res) { console.error('Failed to get show data'); - return { isOk: false}; + return { isOk: false }; } const rawShowData = JSON.parse(getShowData.res.body) as HidiveEpisodeList; const showData = rawShowData.Data.Title; @@ -434,14 +883,14 @@ export default class Hidive implements ServiceClass { sumSub ); } - return { isOk: true, value: selEpsArr, showData: showData } ; + return { isOk: true, value: selEpsArr, showData: showData }; } public async getEpisode(selectedEpisode: HidiveEpisodeExtra, options: Record) { const getVideoData = await this.reqData('GetVideos', { 'VideoKey': selectedEpisode.epKey, 'TitleId': selectedEpisode.titleId }); if (getVideoData.ok && getVideoData.res) { const videoData = JSON.parse(getVideoData.res.body) as HidiveVideoList; - const showTitle = `${selectedEpisode.seriesTitle} S${parseFloat(selectedEpisode.SeasonNumberValue+'')}}`; + const showTitle = `${selectedEpisode.seriesTitle} S${parseFloat(selectedEpisode.SeasonNumberValue+'')}`; console.info(`[INFO] ${showTitle} - ${parseFloat(selectedEpisode.EpisodeNumberValue+'')}`); const videoList = videoData.Data.VideoLanguages; const subsList = videoData.Data.CaptionLanguages; @@ -522,6 +971,470 @@ export default class Hidive implements ServiceClass { return { isOk: false, reason: new Error('Unknown download error') }; } + public async downloadEpisode(selectedEpisode: NewHidiveEpisodeExtra, options: Record) { + //Get Episode data + const episodeDataReq = await this.apiReq(`/v4/vod/${selectedEpisode.id}?includePlaybackDetails=URL`, '', 'auth', 'GET'); + if (!episodeDataReq.ok || !episodeDataReq.res) { + console.error('Failed to get episode data'); + return { isOk: false, reason: new Error('Failed to get Episode Data') }; + } + const episodeData = JSON.parse(episodeDataReq.res.body) as NewHidiveEpisode; + + if (!episodeData.playerUrlCallback) { + console.error('Failed to download episode: You do not have access to this'); + return { isOk: false, reason: new Error('You do not have access to this') }; + } + + //Get Playback data + const playbackReq = await this.req.getData(episodeData.playerUrlCallback); + if(!playbackReq.ok || !playbackReq.res){ + console.error('Playback Request Failed'); + return { isOk: false, reason: new Error('Playback request failed') }; + } + const playbackData = JSON.parse(playbackReq.res.body) as NewHidivePlayback; + + //Get actual MPD + const mpdRequest = await this.req.getData(playbackData.dash[0].url); + if(!mpdRequest.ok || !mpdRequest.res){ + console.error('MPD Request Failed'); + return { isOk: false, reason: new Error('MPD request failed') }; + } + const mpd = mpdRequest.res.body as string; + + selectedEpisode.jwtToken = playbackData.dash[0].drm.jwtToken; + + //Output metadata and prepare for download + const availableSubs = playbackData.dash[0].subtitles.filter(a => a.format === 'vtt'); + const showTitle = `${selectedEpisode.seriesTitle} S${selectedEpisode.episodeInformation.seasonNumber}`; + console.info(`[INFO] ${showTitle} - ${selectedEpisode.episodeInformation.episodeNumber}`); + console.info('[INFO] Available dubs and subtitles:'); + console.info('\tAudios: ' + episodeData.offlinePlaybackLanguages.map(a => langsData.languages.find(b => b.code == a)?.name).join('\n\t\t')); + console.info('\tSubs : ' + availableSubs.map(a => langsData.languages.find(b => b.new_hd_locale == a.language)?.name).join('\n\t\t')); + console.info(`[INFO] Selected dub(s): ${options.dubLang.join(', ')}`); + const baseUrl = playbackData.dash[0].url.split('master')[0]; + const parsedmpd = parse(mpd, undefined, baseUrl); + const res = await this.downloadMPD(parsedmpd, availableSubs, selectedEpisode, options); + if (res === undefined || res.error) { + console.error('Failed to download media list'); + return { isOk: false, reason: new Error('Failed to download media list') }; + } else { + if (!options.skipmux) { + await this.muxStreams(res.data, { ...options, output: res.fileName }, false); + } else { + console.info('Skipping mux'); + } + downloaded({ + service: 'hidive', + type: 's' + }, selectedEpisode.titleId+'', [selectedEpisode.episodeInformation.episodeNumber+'']); + return { isOk: res, value: undefined }; + } + } + + public async downloadSingleEpisode(id: number, options: Record) { + //Get Episode data + const episodeDataReq = await this.apiReq(`/v4/vod/${id}?includePlaybackDetails=URL`, '', 'auth', 'GET'); + if (!episodeDataReq.ok || !episodeDataReq.res) { + console.error('Failed to get episode data'); + return { isOk: false, reason: new Error('Failed to get Episode Data') }; + } + const episodeData = JSON.parse(episodeDataReq.res.body) as NewHidiveEpisode; + + if (episodeData.title.includes(' - ')) { + episodeData.episodeInformation.episodeNumber = parseFloat(episodeData.title.split(' - ')[0].replace('E', '')); + episodeData.title = episodeData.title.split(' - ')[1]; + } + + if (!episodeData.playerUrlCallback) { + console.error('Failed to download episode: You do not have access to this'); + return { isOk: false, reason: new Error('You do not have access to this') }; + } + + const seasonData = await this.getSeason(episodeData.episodeInformation.season); + if (!seasonData.isOk || !seasonData.value) { + console.error('Failed to get season data'); + return { isOk: false, reason: new Error('Failed to get season data') }; + } + + //Get Playback data + const playbackReq = await this.req.getData(episodeData.playerUrlCallback); + if(!playbackReq.ok || !playbackReq.res){ + console.error('Playback Request Failed'); + return { isOk: false, reason: new Error('Playback request failed') }; + } + const playbackData = JSON.parse(playbackReq.res.body) as NewHidivePlayback; + + //Get actual MPD + const mpdRequest = await this.req.getData(playbackData.dash[0].url); + if(!mpdRequest.ok || !mpdRequest.res){ + console.error('MPD Request Failed'); + return { isOk: false, reason: new Error('MPD request failed') }; + } + const mpd = mpdRequest.res.body as string; + + const selectedEpisode: NewHidiveEpisodeExtra = { + ...episodeData, + nameLong: episodeData.title, + titleId: episodeData.id, + seasonTitle: seasonData.value.title, + seriesTitle: seasonData.value.series.title, + isSelected: true + }; + + selectedEpisode.jwtToken = playbackData.dash[0].drm.jwtToken; + + //Output metadata and prepare for download + const availableSubs = playbackData.dash[0].subtitles.filter(a => a.format === 'vtt'); + const showTitle = `${selectedEpisode.seriesTitle} S${selectedEpisode.episodeInformation.seasonNumber}`; + console.info(`[INFO] ${showTitle} - ${selectedEpisode.episodeInformation.episodeNumber}`); + console.info('[INFO] Available dubs and subtitles:'); + console.info('\tAudios: ' + episodeData.offlinePlaybackLanguages.map(a => langsData.languages.find(b => b.code == a)?.name).join('\n\t\t')); + console.info('\tSubs : ' + availableSubs.map(a => langsData.languages.find(b => b.new_hd_locale == a.language)?.name).join('\n\t\t')); + console.info(`[INFO] Selected dub(s): ${options.dubLang.join(', ')}`); + const baseUrl = playbackData.dash[0].url.split('master')[0]; + const parsedmpd = parse(mpd, undefined, baseUrl); + const res = await this.downloadMPD(parsedmpd, availableSubs, selectedEpisode, options); + if (res === undefined || res.error) { + console.error('Failed to download media list'); + return { isOk: false, reason: new Error('Failed to download media list') }; + } else { + if (!options.skipmux) { + await this.muxStreams(res.data, { ...options, output: res.fileName }, false); + } else { + console.info('Skipping mux'); + } + downloaded({ + service: 'hidive', + type: 's' + }, selectedEpisode.titleId+'', [selectedEpisode.episodeInformation.episodeNumber+'']); + return { isOk: res, value: undefined }; + } + } + + public async downloadMPD(streamPlaylists: MPDParsed, subs: Subtitle[], selectedEpisode: NewHidiveEpisodeExtra, options: Record) { + //let fileName: string; + const files: DownloadedMedia[] = []; + const variables: Variable[] = []; + let dlFailed = false; + const subsMargin = 0; + const chosenFontSize = options.originalFontSize ? undefined : options.fontSize; + let encryptionKeys: KeyContainer[] | undefined = undefined; + if (!canDecrypt) console.warn('Decryption not enabled!'); + + variables.push(...([ + ['title', selectedEpisode.title, true], + ['episode', selectedEpisode.episodeInformation.episodeNumber, false], + ['service', 'HD', false], + ['seriesTitle', selectedEpisode.seasonTitle, true], + ['showTitle', selectedEpisode.seriesTitle, true], + ['season', selectedEpisode.episodeInformation.seasonNumber, false] + ] as [AvailableFilenameVars, string|number, boolean][]).map((a): Variable => { + return { + name: a[0], + replaceWith: a[1], + type: typeof a[1], + sanitize: a[2] + } as Variable; + })); + + //Get name of CDNs/Servers + const streamServers = Object.keys(streamPlaylists); + + options.x = options.x > streamServers.length ? 1 : options.x; + + const selectedServer = streamServers[options.x - 1]; + const selectedList = streamPlaylists[selectedServer]; + + //set Video Qualities + const videos = selectedList.video.map(item => { + return { + ...item, + resolutionText: `${item.quality.width}x${item.quality.height} (${Math.round(item.bandwidth/1024)}KiB/s)` + }; + }); + + const audios = selectedList.audio.map(item => { + return { + ...item, + resolutionText: `${Math.round(item.bandwidth/1000)}kB/s` + }; + }); + + + videos.sort((a, b) => { + return a.bandwidth - b.bandwidth; + }); + + videos.sort((a, b) => { + return a.quality.width - b.quality.width; + }); + + audios.sort((a, b) => { + return a.bandwidth - b.bandwidth; + }); + + let chosenVideoQuality = options.q === 0 ? videos.length : options.q; + if(chosenVideoQuality > videos.length) { + console.warn(`The requested quality of ${options.q} is greater than the maximum ${videos.length}.\n[WARN] Therefor the maximum will be capped at ${videos.length}.`); + chosenVideoQuality = videos.length; + } + chosenVideoQuality--; + + const chosenVideoSegments = videos[chosenVideoQuality]; + + console.info(`Servers available:\n\t${streamServers.join('\n\t')}`); + console.info(`Available Video Qualities:\n\t${videos.map((a, ind) => `[${ind+1}] ${a.resolutionText}`).join('\n\t')}`); + console.info(`Available Audio Qualities:\n\t${audios.map((a, ind) => `[${ind+1}] ${a.resolutionText}`).join('\n\t')}`); + + variables.push({ + name: 'height', + type: 'number', + replaceWith: chosenVideoSegments.quality.height + }, { + name: 'width', + type: 'number', + replaceWith: chosenVideoSegments.quality.width + }); + + const chosenAudios: typeof audios[0][] = []; + const audioByLanguage: Record = {}; + for (const audio of audios) { + if (!audioByLanguage[audio.language.code]) audioByLanguage[audio.language.code] = []; + audioByLanguage[audio.language.code].push(audio); + } + for (const dubLang of options.dubLang as string[]) { + if (audioByLanguage[dubLang]) { + let chosenAudioQuality = options.q === 0 ? audios.length : options.q; + if(chosenAudioQuality > audioByLanguage[dubLang].length) { + chosenAudioQuality = audioByLanguage[dubLang].length; + } + chosenAudioQuality--; + chosenAudios.push(audioByLanguage[dubLang][chosenAudioQuality]); + } + } + + const fileName = parseFileName(options.fileName, variables, options.numbers, options.override).join(path.sep); + + console.info(`Selected quality: \n\tVideo: ${chosenVideoSegments.resolutionText}\n\tAudio: ${chosenAudios[0].resolutionText}\n\tServer: ${selectedServer}`); + console.info(`Selected (Available) Audio Languages: ${chosenAudios.map(a => a.language.name).join(', ')}`); + console.info('Stream URL:', chosenVideoSegments.segments[0].map.uri.split('/init.mp4')[0]); + + if (!options.novids) { + //Download Video + const totalParts = chosenVideoSegments.segments.length; + const mathParts = Math.ceil(totalParts / options.partsize); + const mathMsg = `(${mathParts}*${options.partsize})`; + console.info('Total parts in video stream:', totalParts, mathMsg); + const tsFile = path.isAbsolute(fileName) ? fileName : path.join(this.cfg.dir.content, fileName); + const split = fileName.split(path.sep).slice(0, -1); + split.forEach((val, ind, arr) => { + const isAbsolut = path.isAbsolute(fileName); + if (!fs.existsSync(path.join(isAbsolut ? '' : this.cfg.dir.content, ...arr.slice(0, ind), val))) + fs.mkdirSync(path.join(isAbsolut ? '' : this.cfg.dir.content, ...arr.slice(0, ind), val)); + }); + const videoJson: M3U8Json = { + segments: chosenVideoSegments.segments + }; + const videoDownload = await new streamdl({ + output: `${tsFile}.video.enc.ts`, + timeout: options.timeout, + m3u8json: videoJson, + // baseurl: chunkPlaylist.baseUrl, + threads: options.partsize, + fsRetryTime: options.fsRetryTime * 1000, + override: options.force, + callback: options.callbackMaker ? options.callbackMaker({ + fileName: `${path.isAbsolute(fileName) ? fileName.slice(this.cfg.dir.content.length) : fileName}`, + image: selectedEpisode.thumbnailUrl, + parent: { + title: selectedEpisode.seriesTitle + }, + title: selectedEpisode.title, + language: chosenAudios[0].language + }) : undefined + }).download(); + if(!videoDownload.ok){ + console.error(`DL Stats: ${JSON.stringify(videoDownload.parts)}\n`); + dlFailed = true; + } else { + if (chosenVideoSegments.pssh) { + console.info('Decryption Needed, attempting to decrypt'); + encryptionKeys = await getKeys(chosenVideoSegments.pssh, 'https://shield-drm.imggaming.com/api/v2/license', { + 'Authorization': `Bearer ${selectedEpisode.jwtToken}`, + 'X-Drm-Info': 'eyJzeXN0ZW0iOiJjb20ud2lkZXZpbmUuYWxwaGEifQ==', + }); + if (encryptionKeys.length == 0) { + console.error('Failed to get encryption keys'); + return undefined; + } + if (this.cfg.bin.mp4decrypt) { + const commandBase = `--show-progress --key ${encryptionKeys[1].kid}:${encryptionKeys[1].key} `; + const commandVideo = commandBase+`"${tsFile}.video.enc.ts" "${tsFile}.video.ts"`; + + console.info('Started decrypting video'); + const decryptVideo = exec('mp4decrypt', `"${this.cfg.bin.mp4decrypt}"`, commandVideo); + if (!decryptVideo.isOk) { + console.error(decryptVideo.err); + console.error(`Decryption failed with exit code ${decryptVideo.err.code}`); + return undefined; + } else { + console.info('Decryption done for video'); + if (!options.nocleanup) { + fs.removeSync(`${tsFile}.video.enc.ts`); + } + files.push({ + type: 'Video', + path: `${tsFile}.video.ts`, + lang: chosenAudios[0].language, + isPrimary: true + }); + } + } else { + console.warn('mp4decrypt not found, files need decryption. Decryption Keys:', encryptionKeys); + } + } + } + } else { + console.info('Skipping Video'); + } + + if (!options.noaudio) { + for (const audio of chosenAudios) { + const chosenAudioSegments = audio; + //Download Audio (if available) + const totalParts = chosenAudioSegments.segments.length; + const mathParts = Math.ceil(totalParts / options.partsize); + const mathMsg = `(${mathParts}*${options.partsize})`; + console.info('Total parts in audio stream:', totalParts, mathMsg); + const outFile = parseFileName(options.fileName + '.' + (chosenAudioSegments.language.name), variables, options.numbers, options.override).join(path.sep); + const tsFile = path.isAbsolute(outFile as string) ? outFile : path.join(this.cfg.dir.content, outFile); + const split = outFile.split(path.sep).slice(0, -1); + split.forEach((val, ind, arr) => { + const isAbsolut = path.isAbsolute(outFile as string); + if (!fs.existsSync(path.join(isAbsolut ? '' : this.cfg.dir.content, ...arr.slice(0, ind), val))) + fs.mkdirSync(path.join(isAbsolut ? '' : this.cfg.dir.content, ...arr.slice(0, ind), val)); + }); + const audioJson: M3U8Json = { + segments: chosenAudioSegments.segments + }; + const audioDownload = await new streamdl({ + output: `${tsFile}.audio.enc.ts`, + timeout: options.timeout, + m3u8json: audioJson, + // baseurl: chunkPlaylist.baseUrl, + threads: options.partsize, + fsRetryTime: options.fsRetryTime * 1000, + override: options.force, + callback: options.callbackMaker ? options.callbackMaker({ + fileName: `${path.isAbsolute(outFile) ? outFile.slice(this.cfg.dir.content.length) : outFile}`, + image: selectedEpisode.thumbnailUrl, + parent: { + title: selectedEpisode.seriesTitle + }, + title: selectedEpisode.title, + language: chosenAudioSegments.language + }) : undefined + }).download(); + if(!audioDownload.ok){ + console.error(`DL Stats: ${JSON.stringify(audioDownload.parts)}\n`); + dlFailed = true; + } + if (chosenAudioSegments.pssh) { + console.info('Decryption Needed, attempting to decrypt'); + if (!encryptionKeys) { + encryptionKeys = await getKeys(chosenVideoSegments.pssh, 'https://shield-drm.imggaming.com/api/v2/license', { + 'Authorization': `Bearer ${selectedEpisode.jwtToken}`, + 'X-Drm-Info': 'eyJzeXN0ZW0iOiJjb20ud2lkZXZpbmUuYWxwaGEifQ==', + }); + } + if (this.cfg.bin.mp4decrypt) { + const commandBase = `--show-progress --key ${encryptionKeys[1].kid}:${encryptionKeys[1].key} `; + const commandAudio = commandBase+`"${tsFile}.audio.enc.ts" "${tsFile}.audio.ts"`; + + console.info('Started decrypting audio'); + const decryptAudio = exec('mp4decrypt', `"${this.cfg.bin.mp4decrypt}"`, commandAudio); + if (!decryptAudio.isOk) { + console.error(decryptAudio.err); + console.error(`Decryption failed with exit code ${decryptAudio.err.code}`); + return undefined; + } else { + if (!options.nocleanup) { + fs.removeSync(`${tsFile}.audio.enc.ts`); + } + files.push({ + type: 'Audio', + path: `${tsFile}.audio.ts`, + lang: chosenAudioSegments.language, + isPrimary: chosenAudioSegments.default + }); + console.info('Decryption done for audio'); + } + } else { + console.warn('mp4decrypt not found, files need decryption. Decryption Keys:', encryptionKeys); + } + } + } + } else { + console.info('Skipping Audio'); + } + + if(options.dlsubs.indexOf('all') > -1){ + options.dlsubs = ['all']; + } + + if (options.nosubs) { + console.info('Subtitles downloading disabled from nosubs flag.'); + options.skipsubs = true; + } + + if(!options.skipsubs && options.dlsubs.indexOf('none') == -1) { + if(subs.length > 0) { + let subIndex = 0; + for(const sub of subs) { + const subLang = langsData.languages.find(a => a.new_hd_locale === sub.language); + if (!subLang) { + console.warn(`Language not found for subtitle language: ${sub.language}, Skipping`); + continue; + } + const sxData: Partial = {}; + sxData.file = langsData.subsFile(fileName as string, subIndex+'', subLang, false, options.ccTag); + sxData.path = path.join(this.cfg.dir.content, sxData.file); + sxData.language = subLang; + if(options.dlsubs.includes('all') || options.dlsubs.includes(subLang.locale)) { + const getVttContent = await this.req.getData(sub.url); + if (getVttContent.ok && getVttContent.res) { + console.info(`Subtitle Downloaded: ${sub.url}`); + //vttConvert(getVttContent.res.body, false, subLang.name, fontSize); + const sBody = vtt(undefined, chosenFontSize, getVttContent.res.body, '', subsMargin, options.fontName); + sxData.title = `${subLang.language} / ${sxData.title}`; + sxData.fonts = fontsData.assFonts(sBody) as Font[]; + fs.writeFileSync(sxData.path, sBody); + console.info(`Subtitle converted: ${sxData.file}`); + files.push({ + type: 'Subtitle', + ...sxData as sxItem, + cc: false + }); + } else{ + console.warn(`Failed to download subtitle: ${sxData.file}`); + } + } + subIndex++; + } + } else{ + console.warn('Can\'t find urls for subtitles!'); + } + } else{ + console.info('Subtitles downloading skipped!'); + } + + return { + error: dlFailed, + data: files, + fileName: fileName ? (path.isAbsolute(fileName) ? fileName : path.join(this.cfg.dir.content, fileName)) || './unknown' : './unknown' + }; + } + public async downloadMediaList(videoUrls: HidiveStreamInfo[], subUrls: HidiveSubtitleInfo[], fontSize: number, options: Record) { let mediaName = '...'; let fileName; @@ -744,12 +1657,13 @@ export default class Hidive implements ServiceClass { const getCssContent = await this.req.getData(await this.genSubsUrl('css', subsXUrl)); const getVttContent = await this.req.getData(await this.genSubsUrl('vtt', subsXUrl)); if (getCssContent.ok && getVttContent.ok && getCssContent.res && getVttContent.res) { + console.info(`Subtitle Downloaded: ${await this.genSubsUrl('vtt', subsXUrl)}`); //vttConvert(getVttContent.res.body, false, subLang.name, fontSize); const sBody = vtt(undefined, chosenFontSize, getVttContent.res.body, getCssContent.res.body, subsMargin, options.fontName); sxData.title = `${subLang.language} / ${sxData.title}`; sxData.fonts = fontsData.assFonts(sBody) as Font[]; fs.writeFileSync(sxData.path, sBody); - console.info(`Subtitle downloaded: ${sxData.file}`); + console.info(`Subtitle Converted: ${sxData.file}`); files.push({ type: 'Subtitle', ...sxData as sxItem, @@ -775,20 +1689,40 @@ export default class Hidive implements ServiceClass { }; } - public async muxStreams(data: DownloadedMedia[], options: Record) { + public async muxStreams(data: DownloadedMedia[], options: Record, inverseTrackOrder: boolean = true) { this.cfg.bin = await yamlCfg.loadBinCfg(); + let hasAudioStreams = false; if (options.novids || data.filter(a => a.type === 'Video').length === 0) return console.info('Skip muxing since no vids are downloaded'); + if (data.some(a => a.type === 'Audio')) { + hasAudioStreams = true; + } const merger = new Merger({ - onlyVid: [], + onlyVid: hasAudioStreams ? data.filter(a => a.type === 'Video').map((a) : MergerInput => { + if (a.type === 'Subtitle') + throw new Error('Never'); + return { + lang: a.lang, + path: a.path, + }; + }) : [], skipSubMux: options.skipSubMux, - inverseTrackOrder: true, + inverseTrackOrder: inverseTrackOrder, keepAllVideos: options.keepAllVideos, - onlyAudio: [], + onlyAudio: hasAudioStreams ? data.filter(a => a.type === 'Audio').map((a) : MergerInput => { + if (a.type === 'Subtitle') + throw new Error('Never'); + return { + lang: a.lang, + path: a.path, + }; + }) : [], output: `${options.output}.${options.mp4 ? 'mp4' : 'mkv'}`, subtitles: data.filter(a => a.type === 'Subtitle').map((a) : SubtitleInput => { if (a.type === 'Video') throw new Error('Never'); + if (a.type === 'Audio') + throw new Error('Never'); return { file: a.path, language: a.language, @@ -801,7 +1735,7 @@ export default class Hidive implements ServiceClass { return !a.uncut as boolean; })[0], fonts: Merger.makeFontsList(this.cfg.dir.fonts, data.filter(a => a.type === 'Subtitle') as sxItem[]), - videoAndAudio: data.filter(a => a.type === 'Video').map((a) : MergerInput => { + videoAndAudio: hasAudioStreams ? [] : data.filter(a => a.type === 'Video').map((a) : MergerInput => { if (a.type === 'Subtitle') throw new Error('Never'); return { diff --git a/modules/build.ts b/modules/build.ts index bd6681a..9901ce9 100644 --- a/modules/build.ts +++ b/modules/build.ts @@ -9,7 +9,7 @@ import { console } from './log'; const buildsDir = './_builds'; const nodeVer = 'node18-'; -type BuildTypes = `${'ubuntu'|'windows'|'macos'|'arm'}64` +type BuildTypes = `${'windows'|'macos'|'linux'|'linuxstatic'|'alpine'}-${'x64'|'arm64'}`|'linuxstatic-armv7' (async () => { const buildType = process.argv[2] as BuildTypes; @@ -21,16 +21,23 @@ type BuildTypes = `${'ubuntu'|'windows'|'macos'|'arm'}64` // main async function buildBinary(buildType: BuildTypes, gui: boolean) { const buildStr = 'multi-downloader-nx'; - const acceptableBuilds = ['windows64','ubuntu64','macos64']; + const acceptablePlatforms = ['windows','linux','linuxstatic','macos','alpine']; + const acceptableArchs = ['x64','arm64']; + const acceptableBuilds: string[] = ['linuxstatic-armv7']; + for (const platform of acceptablePlatforms) { + for (const arch of acceptableArchs) { + acceptableBuilds.push(platform+'-'+arch); + } + } if(!acceptableBuilds.includes(buildType)){ - console.error('[ERROR] unknown build type!'); + console.error('Unknown build type!'); process.exit(1); } await modulesCleanup('.'); if(!fs.existsSync(buildsDir)){ fs.mkdirSync(buildsDir); } - const buildFull = `${buildStr}-${buildType}-${gui ? 'gui' : 'cli'}`; + const buildFull = `${buildStr}-${getFriendlyName(buildType)}-${gui ? 'gui' : 'cli'}`; const buildDir = `${buildsDir}/${buildFull}`; if(fs.existsSync(buildDir)){ fs.removeSync(buildDir); @@ -38,7 +45,7 @@ async function buildBinary(buildType: BuildTypes, gui: boolean) { fs.mkdirSync(buildDir); const buildConfig = [ gui ? 'gui.js' : 'index.js', - '--target', nodeVer + getTarget(buildType), + '--target', nodeVer + buildType, '--output', `${buildDir}/${pkg.short_name}`, ]; console.info(`[Build] Build configuration: ${buildFull}`); @@ -51,6 +58,7 @@ async function buildBinary(buildType: BuildTypes, gui: boolean) { } fs.mkdirSync(`${buildDir}/config`); fs.mkdirSync(`${buildDir}/videos`); + fs.mkdirSync(`${buildDir}/widevine`); fs.copySync('./config/bin-path.yml', `${buildDir}/config/bin-path.yml`); fs.copySync('./config/cli-defaults.yml', `${buildDir}/config/cli-defaults.yml`); fs.copySync('./config/dir-path.yml', `${buildDir}/config/dir-path.yml`); @@ -70,15 +78,12 @@ async function buildBinary(buildType: BuildTypes, gui: boolean) { execSync(`7z a -t7z "${buildsDir}/${buildFull}.7z" "${buildDir}"`,{stdio:[0,1,2]}); } -function getTarget(bt: string) : string { - switch(bt){ - case 'windows64': - return 'windows-x64'; - case 'ubuntu64': - return 'linux-x64'; - case 'macos64': - return 'macos-x64'; - default: - return 'windows-x64'; +function getFriendlyName(buildString: string): string { + if (buildString.includes('armv7')) { + return 'android'; } -} + if (buildString.includes('linuxstatic')) { + buildString = buildString.replace('linuxstatic', 'linux'); + } + return buildString; +} \ No newline at end of file diff --git a/modules/cmac.ts b/modules/cmac.ts new file mode 100644 index 0000000..87d94db --- /dev/null +++ b/modules/cmac.ts @@ -0,0 +1,114 @@ +//Originally from https://github.com/Frooastside/node-widevine/blob/main/src/cmac.ts + +import crypto from 'crypto'; + +export class AES_CMAC { + private readonly BLOCK_SIZE = 16; + private readonly XOR_RIGHT = Buffer.from([0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87]); + private readonly EMPTY_BLOCK_SIZE_BUFFER = Buffer.alloc(this.BLOCK_SIZE); + + private _key: Buffer; + private _subkeys: { first: Buffer; second: Buffer }; + + public constructor(key: Buffer) { + if (![16, 24, 32].includes(key.length)) { + throw new Error('Key size must be 128, 192, or 256 bits.'); + } + this._key = key; + this._subkeys = this._generateSubkeys(); + } + + public calculate(message: Buffer): Buffer { + const blockCount = this._getBlockCount(message); + + let x = this.EMPTY_BLOCK_SIZE_BUFFER; + let y; + + for (let i = 0; i < blockCount - 1; i++) { + const from = i * this.BLOCK_SIZE; + const block = message.subarray(from, from + this.BLOCK_SIZE); + y = this._xor(x, block); + x = this._aes(y); + } + + y = this._xor(x, this._getLastBlock(message)); + x = this._aes(y); + + return x; + } + + private _generateSubkeys(): { first: Buffer; second: Buffer } { + const l = this._aes(this.EMPTY_BLOCK_SIZE_BUFFER); + + let first = this._bitShiftLeft(l); + if (l[0] & 0x80) { + first = this._xor(first, this.XOR_RIGHT); + } + + let second = this._bitShiftLeft(first); + if (first[0] & 0x80) { + second = this._xor(second, this.XOR_RIGHT); + } + + return { first: first, second: second }; + } + + private _getBlockCount(message: Buffer): number { + const blockCount = Math.ceil(message.length / this.BLOCK_SIZE); + return blockCount === 0 ? 1 : blockCount; + } + + private _aes(message: Buffer): Buffer { + const cipher = crypto.createCipheriv(`aes-${this._key.length * 8}-cbc`, this._key, Buffer.alloc(this.BLOCK_SIZE)); + const result = cipher.update(message).subarray(0, 16); + cipher.destroy(); + return result; + } + + private _getLastBlock(message: Buffer): Buffer { + const blockCount = this._getBlockCount(message); + const paddedBlock = this._padding(message, blockCount - 1); + + let complete = false; + if (message.length > 0) { + complete = message.length % this.BLOCK_SIZE === 0; + } + + const key = complete ? this._subkeys.first : this._subkeys.second; + return this._xor(paddedBlock, key); + } + + private _padding(message: Buffer, blockIndex: number): Buffer { + const block = Buffer.alloc(this.BLOCK_SIZE); + + const from = blockIndex * this.BLOCK_SIZE; + + const slice = message.subarray(from, from + this.BLOCK_SIZE); + block.set(slice); + + if (slice.length !== this.BLOCK_SIZE) { + block[slice.length] = 0x80; + } + + return block; + } + + private _bitShiftLeft(input: Buffer): Buffer { + const output = Buffer.alloc(input.length); + let overflow = 0; + for (let i = input.length - 1; i >= 0; i--) { + output[i] = (input[i] << 1) | overflow; + overflow = input[i] & 0x80 ? 1 : 0; + } + return output; + } + + private _xor(a: Buffer, b: Buffer): Buffer { + const length = Math.min(a.length, b.length); + const output = Buffer.alloc(length); + for (let i = 0; i < length; i++) { + output[i] = a[i] ^ b[i]; + } + return output; + } +} \ No newline at end of file diff --git a/modules/hls-download.ts b/modules/hls-download.ts index 3b2ce0c..38ba40c 100644 --- a/modules/hls-download.ts +++ b/modules/hls-download.ts @@ -26,7 +26,7 @@ const fixMiddleWare = (res: Response) => { export type HLSCallback = (data: ProgressData) => unknown; -type M3U8Json = { +export type M3U8Json = { segments: Record[], mediaSequence?: number, } diff --git a/modules/license.ts b/modules/license.ts new file mode 100644 index 0000000..e2a92ea --- /dev/null +++ b/modules/license.ts @@ -0,0 +1,161 @@ +//Originaly from https://github.com/Frooastside/node-widevine/blob/main/src/license.ts + +import crypto from 'crypto'; +import Long from 'long'; +import { AES_CMAC } from './cmac'; +import { + ClientIdentification, + License, + LicenseRequest, + LicenseRequest_RequestType, + LicenseType, + ProtocolVersion, + SignedMessage, + SignedMessage_MessageType, + SignedMessage_SessionKeyType, + WidevinePsshData +} from './license_protocol'; + +const WIDEVINE_SYSTEM_ID = new Uint8Array([237, 239, 139, 169, 121, 214, 74, 206, 163, 200, 39, 220, 213, 29, 33, 237]); + +export type KeyContainer = { + kid: string; + key: string; +}; + +export type ContentDecryptionModule = { + privateKey: Buffer; + identifierBlob: Buffer; +}; + +export class Session { + private _devicePrivateKey: crypto.KeyObject; + private _identifierBlob: ClientIdentification; + private _identifier: Buffer; + private _pssh: Buffer; + private _rawLicenseRequest?: Buffer; + + constructor(contentDecryptionModule: ContentDecryptionModule, pssh: Buffer) { + this._devicePrivateKey = crypto.createPrivateKey(contentDecryptionModule.privateKey); + this._identifierBlob = ClientIdentification.decode(contentDecryptionModule.identifierBlob); + this._identifier = this._generateIdentifier(); + this._pssh = pssh; + } + + createLicenseRequest(): Buffer { + if (!this._pssh.subarray(12, 28).equals(Buffer.from(WIDEVINE_SYSTEM_ID))) { + throw new Error('the pssh is not an actuall pssh'); + } + const pssh = this._parsePSSH(this._pssh); + if (!pssh) { + throw new Error('pssh is invalid'); + } + + const licenseRequest: LicenseRequest = { + type: LicenseRequest_RequestType.NEW, + clientId: this._identifierBlob, + contentId: { + widevinePsshData: { + psshData: [this._pssh.subarray(32)], + licenseType: LicenseType.STREAMING, + requestId: this._identifier + } + }, + requestTime: Long.fromNumber(Date.now()).divide(1000), + protocolVersion: ProtocolVersion.VERSION_2_1, + keyControlNonce: crypto.randomInt(2 ** 31), + keyControlNonceDeprecated: Buffer.alloc(0), + encryptedClientId: undefined + }; + + this._rawLicenseRequest = Buffer.from(LicenseRequest.encode(licenseRequest).finish()); + + const signature = crypto + .createSign('sha1') + .update(this._rawLicenseRequest) + .sign({ key: this._devicePrivateKey, padding: crypto.constants.RSA_PKCS1_PSS_PADDING, saltLength: 20 }); + + const signedLicenseRequest: SignedMessage = { + type: SignedMessage_MessageType.LICENSE_REQUEST, + msg: this._rawLicenseRequest, + signature: Buffer.from(signature), + sessionKey: Buffer.alloc(0), + remoteAttestation: Buffer.alloc(0), + metricData: [], + serviceVersionInfo: undefined, + sessionKeyType: SignedMessage_SessionKeyType.UNDEFINED, + oemcryptoCoreMessage: Buffer.alloc(0) + }; + + return Buffer.from(SignedMessage.encode(signedLicenseRequest).finish()); + } + + parseLicense(rawLicense: Buffer) { + if (!this._rawLicenseRequest) { + throw new Error('please request a license first'); + } + const signedLicense = SignedMessage.decode(rawLicense); + const sessionKey = crypto.privateDecrypt(this._devicePrivateKey, signedLicense.sessionKey); + + const cmac = new AES_CMAC(Buffer.from(sessionKey)); + + const encKeyBase = Buffer.concat([ + Buffer.from('ENCRYPTION'), + Buffer.from('\x00', 'ascii'), + this._rawLicenseRequest, + Buffer.from('\x00\x00\x00\x80', 'ascii') + ]); + const authKeyBase = Buffer.concat([ + Buffer.from('AUTHENTICATION'), + Buffer.from('\x00', 'ascii'), + this._rawLicenseRequest, + Buffer.from('\x00\x00\x02\x00', 'ascii') + ]); + + const encKey = cmac.calculate(Buffer.concat([Buffer.from('\x01'), encKeyBase])); + const serverKey = Buffer.concat([ + cmac.calculate(Buffer.concat([Buffer.from('\x01'), authKeyBase])), + cmac.calculate(Buffer.concat([Buffer.from('\x02'), authKeyBase])) + ]); + /*const clientKey = Buffer.concat([ + cmac.calculate(Buffer.concat([Buffer.from("\x03"), authKeyBase])), + cmac.calculate(Buffer.concat([Buffer.from("\x04"), authKeyBase])) + ]);*/ + + const calculatedSignature = crypto.createHmac('sha256', serverKey).update(signedLicense.msg).digest(); + + if (!calculatedSignature.equals(signedLicense.signature)) { + throw new Error('signatures do not match'); + } + + const license = License.decode(signedLicense.msg); + + return license.key.map((keyContainer) => { + const keyId = keyContainer.id.length ? keyContainer.id.toString('hex') : keyContainer.type.toString(); + const decipher = crypto.createDecipheriv(`aes-${encKey.length * 8}-cbc`, encKey, keyContainer.iv); + const decryptedKey = decipher.update(keyContainer.key); + decipher.destroy(); + const key: KeyContainer = { + kid: keyId, + key: decryptedKey.toString('hex') + }; + return key; + }); + } + + private _parsePSSH(pssh: Buffer): WidevinePsshData | null { + try { + return WidevinePsshData.decode(pssh.subarray(32)); + } catch { + return null; + } + } + + private _generateIdentifier(): Buffer { + return Buffer.from(`${crypto.randomBytes(8).toString('hex')}${'01'}${'00000000000000'}`); + } + + get pssh(): Buffer { + return this._pssh; + } +} \ No newline at end of file diff --git a/modules/license_protocol.proto b/modules/license_protocol.proto new file mode 100644 index 0000000..7a9099c --- /dev/null +++ b/modules/license_protocol.proto @@ -0,0 +1,749 @@ +//Originally from https://github.com/Frooastside/node-widevine/blob/main/src/license_protocol.proto + +syntax = "proto2"; + +package license_protocol; + +enum LicenseType { + STREAMING = 1; + OFFLINE = 2; + // License type decision is left to provider. + AUTOMATIC = 3; +} + +enum PlatformVerificationStatus { + // The platform is not verified. + PLATFORM_UNVERIFIED = 0; + // Tampering detected on the platform. + PLATFORM_TAMPERED = 1; + // The platform has been verified by means of software. + PLATFORM_SOFTWARE_VERIFIED = 2; + // The platform has been verified by means of hardware (e.g. secure boot). + PLATFORM_HARDWARE_VERIFIED = 3; + // Platform verification was not performed. + PLATFORM_NO_VERIFICATION = 4; + // Platform and secure storage capability have been verified by means of + // software. + PLATFORM_SECURE_STORAGE_SOFTWARE_VERIFIED = 5; +} + +// LicenseIdentification is propagated from LicenseRequest to License, +// incrementing version with each iteration. +message LicenseIdentification { + optional bytes request_id = 1; + optional bytes session_id = 2; + optional bytes purchase_id = 3; + optional LicenseType type = 4; + optional int32 version = 5; + optional bytes provider_session_token = 6; +} + +message License { + message Policy { + // Indicates that playback of the content is allowed. + optional bool can_play = 1 [default = false]; + + // Indicates that the license may be persisted to non-volatile + // storage for offline use. + optional bool can_persist = 2 [default = false]; + + // Indicates that renewal of this license is allowed. + optional bool can_renew = 3 [default = false]; + + // For the |*duration*| fields, playback must halt when + // license_start_time (seconds since the epoch (UTC)) + + // license_duration_seconds is exceeded. A value of 0 + // indicates that there is no limit to the duration. + + // Indicates the rental window. + optional int64 rental_duration_seconds = 4 [default = 0]; + + // Indicates the viewing window, once playback has begun. + optional int64 playback_duration_seconds = 5 [default = 0]; + + // Indicates the time window for this specific license. + optional int64 license_duration_seconds = 6 [default = 0]; + + // The |renewal*| fields only apply if |can_renew| is true. + + // The window of time, in which playback is allowed to continue while + // renewal is attempted, yet unsuccessful due to backend problems with + // the license server. + optional int64 renewal_recovery_duration_seconds = 7 [default = 0]; + + // All renewal requests for this license shall be directed to the + // specified URL. + optional string renewal_server_url = 8; + + // How many seconds after license_start_time, before renewal is first + // attempted. + optional int64 renewal_delay_seconds = 9 [default = 0]; + + // Specifies the delay in seconds between subsequent license + // renewal requests, in case of failure. + optional int64 renewal_retry_interval_seconds = 10 [default = 0]; + + // Indicates that the license shall be sent for renewal when usage is + // started. + optional bool renew_with_usage = 11 [default = false]; + + // Indicates to client that license renewal and release requests ought to + // include ClientIdentification (client_id). + optional bool always_include_client_id = 12 [default = false]; + + // Duration of grace period before playback_duration_seconds (short window) + // goes into effect. Optional. + optional int64 play_start_grace_period_seconds = 13 [default = 0]; + + // Enables "soft enforcement" of playback_duration_seconds, letting the user + // finish playback even if short window expires. Optional. + optional bool soft_enforce_playback_duration = 14 [default = false]; + + // Enables "soft enforcement" of rental_duration_seconds. Initial playback + // must always start before rental duration expires. In order to allow + // subsequent playbacks to start after the rental duration expires, + // soft_enforce_playback_duration must be true. Otherwise, subsequent + // playbacks will not be allowed once rental duration expires. Optional. + optional bool soft_enforce_rental_duration = 15 [default = true]; + } + + message KeyContainer { + enum KeyType { + SIGNING = 1; // Exactly one key of this type must appear. + CONTENT = 2; // Content key. + KEY_CONTROL = 3; // Key control block for license renewals. No key. + OPERATOR_SESSION = 4; // wrapped keys for auxiliary crypto operations. + ENTITLEMENT = 5; // Entitlement keys. + OEM_CONTENT = 6; // Partner-specific content key. + } + + // The SecurityLevel enumeration allows the server to communicate the level + // of robustness required by the client, in order to use the key. + enum SecurityLevel { + // Software-based whitebox crypto is required. + SW_SECURE_CRYPTO = 1; + + // Software crypto and an obfuscated decoder is required. + SW_SECURE_DECODE = 2; + + // The key material and crypto operations must be performed within a + // hardware backed trusted execution environment. + HW_SECURE_CRYPTO = 3; + + // The crypto and decoding of content must be performed within a hardware + // backed trusted execution environment. + HW_SECURE_DECODE = 4; + + // The crypto, decoding and all handling of the media (compressed and + // uncompressed) must be handled within a hardware backed trusted + // execution environment. + HW_SECURE_ALL = 5; + } + + message KeyControl { + // |key_control| is documented in: + // Widevine Modular DRM Security Integration Guide for CENC + // If present, the key control must be communicated to the secure + // environment prior to any usage. This message is automatically generated + // by the Widevine License Server SDK. + optional bytes key_control_block = 1; + optional bytes iv = 2; + } + + message OutputProtection { + // Indicates whether HDCP is required on digital outputs, and which + // version should be used. + enum HDCP { + HDCP_NONE = 0; + HDCP_V1 = 1; + HDCP_V2 = 2; + HDCP_V2_1 = 3; + HDCP_V2_2 = 4; + HDCP_V2_3 = 5; + HDCP_NO_DIGITAL_OUTPUT = 0xff; + } + optional HDCP hdcp = 1 [default = HDCP_NONE]; + + // Indicate the CGMS setting to be inserted on analog output. + enum CGMS { + CGMS_NONE = 42; + COPY_FREE = 0; + COPY_ONCE = 2; + COPY_NEVER = 3; + } + optional CGMS cgms_flags = 2 [default = CGMS_NONE]; + + enum HdcpSrmRule { + HDCP_SRM_RULE_NONE = 0; + // In 'required_protection', this means most current SRM is required. + // Update the SRM on the device. If update cannot happen, + // do not allow the key. + // In 'requested_protection', this means most current SRM is requested. + // Update the SRM on the device. If update cannot happen, + // allow use of the key anyway. + CURRENT_SRM = 1; + } + optional HdcpSrmRule hdcp_srm_rule = 3 [default = HDCP_SRM_RULE_NONE]; + // Optional requirement to indicate analog output is not allowed. + optional bool disable_analog_output = 4 [default = false]; + // Optional requirement to indicate digital output is not allowed. + optional bool disable_digital_output = 5 [default = false]; + } + + message VideoResolutionConstraint { + // Minimum and maximum video resolutions in the range (height x width). + optional uint32 min_resolution_pixels = 1; + optional uint32 max_resolution_pixels = 2; + // Optional output protection requirements for this range. If not + // specified, the OutputProtection in the KeyContainer applies. + optional OutputProtection required_protection = 3; + } + + message OperatorSessionKeyPermissions { + // Permissions/key usage flags for operator service keys + // (type = OPERATOR_SESSION). + optional bool allow_encrypt = 1 [default = false]; + optional bool allow_decrypt = 2 [default = false]; + optional bool allow_sign = 3 [default = false]; + optional bool allow_signature_verify = 4 [default = false]; + } + + optional bytes id = 1; + optional bytes iv = 2; + optional bytes key = 3; + optional KeyType type = 4; + optional SecurityLevel level = 5 [default = SW_SECURE_CRYPTO]; + optional OutputProtection required_protection = 6; + // NOTE: Use of requested_protection is not recommended as it is only + // supported on a small number of platforms. + optional OutputProtection requested_protection = 7; + optional KeyControl key_control = 8; + optional OperatorSessionKeyPermissions operator_session_key_permissions = 9; + // Optional video resolution constraints. If the video resolution of the + // content being decrypted/decoded falls within one of the specified ranges, + // the optional required_protections may be applied. Otherwise an error will + // be reported. + // NOTE: Use of this feature is not recommended, as it is only supported on + // a small number of platforms. + repeated VideoResolutionConstraint video_resolution_constraints = 10; + // Optional flag to indicate the key must only be used if the client + // supports anti rollback of the user table. Content provider can query the + // client capabilities to determine if the client support this feature. + optional bool anti_rollback_usage_table = 11 [default = false]; + // Optional not limited to commonly known track types such as SD, HD. + // It can be some provider defined label to identify the track. + optional string track_label = 12; + } + + optional LicenseIdentification id = 1; + optional Policy policy = 2; + repeated KeyContainer key = 3; + // Time of the request in seconds (UTC) as set in + // LicenseRequest.request_time. If this time is not set in the request, + // the local time at the license service is used in this field. + optional int64 license_start_time = 4; + optional bool remote_attestation_verified = 5 [default = false]; + // Client token generated by the content provider. Optional. + optional bytes provider_client_token = 6; + // 4cc code specifying the CENC protection scheme as defined in the CENC 3.0 + // specification. Propagated from Widevine PSSH box. Optional. + optional uint32 protection_scheme = 7; + // 8 byte verification field "HDCPDATA" followed by unsigned 32 bit minimum + // HDCP SRM version (whether the version is for HDCP1 SRM or HDCP2 SRM + // depends on client max_hdcp_version). + // Additional details can be found in Widevine Modular DRM Security + // Integration Guide for CENC. + optional bytes srm_requirement = 8; + // If present this contains a signed SRM file (either HDCP1 SRM or HDCP2 SRM + // depending on client max_hdcp_version) that should be installed on the + // client device. + optional bytes srm_update = 9; + // Indicates the status of any type of platform verification performed by the + // server. + optional PlatformVerificationStatus platform_verification_status = 10 + [default = PLATFORM_NO_VERIFICATION]; + // IDs of the groups for which keys are delivered in this license, if any. + repeated bytes group_ids = 11; +} + +enum ProtocolVersion { + VERSION_2_0 = 20; + VERSION_2_1 = 21; + VERSION_2_2 = 22; +} + +message LicenseRequest { + message ContentIdentification { + message WidevinePsshData { + repeated bytes pssh_data = 1; + optional LicenseType license_type = 2; + optional bytes request_id = 3; // Opaque, client-specified. + } + + message WebmKeyId { + optional bytes header = 1; + optional LicenseType license_type = 2; + optional bytes request_id = 3; // Opaque, client-specified. + } + + message ExistingLicense { + optional LicenseIdentification license_id = 1; + optional int64 seconds_since_started = 2; + optional int64 seconds_since_last_played = 3; + optional bytes session_usage_table_entry = 4; + } + + message InitData { + enum InitDataType { + CENC = 1; + WEBM = 2; + } + + optional InitDataType init_data_type = 1 [default = CENC]; + optional bytes init_data = 2; + optional LicenseType license_type = 3; + optional bytes request_id = 4; + } + + oneof content_id_variant { + // Exactly one of these must be present. + WidevinePsshData widevine_pssh_data = 1; + WebmKeyId webm_key_id = 2; + ExistingLicense existing_license = 3; + InitData init_data = 4; + } + } + + enum RequestType { + NEW = 1; + RENEWAL = 2; + RELEASE = 3; + } + + // The client_id provides information authenticating the calling device. It + // contains the Widevine keybox token that was installed on the device at the + // factory. This field or encrypted_client_id below is required for a valid + // license request, but both should never be present in the same request. + optional ClientIdentification client_id = 1; + optional ContentIdentification content_id = 2; + optional RequestType type = 3; + // Time of the request in seconds (UTC) as set by the client. + optional int64 request_time = 4; + // Old-style decimal-encoded string key control nonce. + optional bytes key_control_nonce_deprecated = 5; + optional ProtocolVersion protocol_version = 6 [default = VERSION_2_0]; + // New-style uint32 key control nonce, please use instead of + // key_control_nonce_deprecated. + optional uint32 key_control_nonce = 7; + // Encrypted ClientIdentification message, used for privacy purposes. + optional EncryptedClientIdentification encrypted_client_id = 8; +} + +message MetricData { + enum MetricType { + // The time spent in the 'stage', specified in microseconds. + LATENCY = 1; + // The UNIX epoch timestamp at which the 'stage' was first accessed in + // microseconds. + TIMESTAMP = 2; + } + + message TypeValue { + optional MetricType type = 1; + // The value associated with 'type'. For example if type == LATENCY, the + // value would be the time in microseconds spent in this 'stage'. + optional int64 value = 2 [default = 0]; + } + + // 'stage' that is currently processing the SignedMessage. Required. + optional string stage_name = 1; + // metric and associated value. + repeated TypeValue metric_data = 2; +} + +message VersionInfo { + // License SDK version reported by the Widevine License SDK. This field + // is populated automatically by the SDK. + optional string license_sdk_version = 1; + // Version of the service hosting the license SDK. This field is optional. + // It may be provided by the hosting service. + optional string license_service_version = 2; +} + +message SignedMessage { + enum MessageType { + LICENSE_REQUEST = 1; + LICENSE = 2; + ERROR_RESPONSE = 3; + SERVICE_CERTIFICATE_REQUEST = 4; + SERVICE_CERTIFICATE = 5; + SUB_LICENSE = 6; + CAS_LICENSE_REQUEST = 7; + CAS_LICENSE = 8; + EXTERNAL_LICENSE_REQUEST = 9; + EXTERNAL_LICENSE = 10; + } + + enum SessionKeyType { + UNDEFINED = 0; + WRAPPED_AES_KEY = 1; + EPHERMERAL_ECC_PUBLIC_KEY = 2; + } + optional MessageType type = 1; + optional bytes msg = 2; + // Required field that contains the signature of the bytes of msg. + // For license requests, the signing algorithm is determined by the + // certificate contained in the request. + // For license responses, the signing algorithm is HMAC with signing key based + // on |session_key|. + optional bytes signature = 3; + // If populated, the contents of this field will be signaled by the + // |session_key_type| type. If the |session_key_type| is WRAPPED_AES_KEY the + // key is the bytes of an encrypted AES key. If the |session_key_type| is + // EPHERMERAL_ECC_PUBLIC_KEY the field contains the bytes of an RFC5208 ASN1 + // serialized ECC public key. + optional bytes session_key = 4; + // Remote attestation data which will be present in the initial license + // request for ChromeOS client devices operating in verified mode. Remote + // attestation challenge data is |msg| field above. Optional. + optional bytes remote_attestation = 5; + + repeated MetricData metric_data = 6; + // Version information from the SDK and license service. This information is + // provided in the license response. + optional VersionInfo service_version_info = 7; + // Optional field that contains the algorithm type used to generate the + // session_key and signature in a LICENSE message. + optional SessionKeyType session_key_type = 8 [default = WRAPPED_AES_KEY]; + // The core message is the simple serialization of fields used by OEMCrypto. + // This field was introduced in OEMCrypto API v16. + optional bytes oemcrypto_core_message = 9; +} + +enum HashAlgorithmProto { + // Unspecified hash algorithm: SHA_256 shall be used for ECC based algorithms + // and SHA_1 shall be used otherwise. + HASH_ALGORITHM_UNSPECIFIED = 0; + HASH_ALGORITHM_SHA_1 = 1; + HASH_ALGORITHM_SHA_256 = 2; + HASH_ALGORITHM_SHA_384 = 3; +} + +// ClientIdentification message used to authenticate the client device. +message ClientIdentification { + enum TokenType { + KEYBOX = 0; + DRM_DEVICE_CERTIFICATE = 1; + REMOTE_ATTESTATION_CERTIFICATE = 2; + OEM_DEVICE_CERTIFICATE = 3; + } + + message NameValue { + optional string name = 1; + optional string value = 2; + } + + // Capabilities which not all clients may support. Used for the license + // exchange protocol only. + message ClientCapabilities { + enum HdcpVersion { + HDCP_NONE = 0; + HDCP_V1 = 1; + HDCP_V2 = 2; + HDCP_V2_1 = 3; + HDCP_V2_2 = 4; + HDCP_V2_3 = 5; + HDCP_NO_DIGITAL_OUTPUT = 0xff; + } + + enum CertificateKeyType { + RSA_2048 = 0; + RSA_3072 = 1; + ECC_SECP256R1 = 2; + ECC_SECP384R1 = 3; + ECC_SECP521R1 = 4; + } + + enum AnalogOutputCapabilities { + ANALOG_OUTPUT_UNKNOWN = 0; + ANALOG_OUTPUT_NONE = 1; + ANALOG_OUTPUT_SUPPORTED = 2; + ANALOG_OUTPUT_SUPPORTS_CGMS_A = 3; + } + + optional bool client_token = 1 [default = false]; + optional bool session_token = 2 [default = false]; + optional bool video_resolution_constraints = 3 [default = false]; + optional HdcpVersion max_hdcp_version = 4 [default = HDCP_NONE]; + optional uint32 oem_crypto_api_version = 5; + // Client has hardware support for protecting the usage table, such as + // storing the generation number in secure memory. For Details, see: + // Widevine Modular DRM Security Integration Guide for CENC + optional bool anti_rollback_usage_table = 6 [default = false]; + // The client shall report |srm_version| if available. + optional uint32 srm_version = 7; + // A device may have SRM data, and report a version, but may not be capable + // of updating SRM data. + optional bool can_update_srm = 8 [default = false]; + repeated CertificateKeyType supported_certificate_key_type = 9; + optional AnalogOutputCapabilities analog_output_capabilities = 10 + [default = ANALOG_OUTPUT_UNKNOWN]; + optional bool can_disable_analog_output = 11 [default = false]; + // Clients can indicate a performance level supported by OEMCrypto. + // This will allow applications and providers to choose an appropriate + // quality of content to serve. Currently defined tiers are + // 1 (low), 2 (medium) and 3 (high). Any other value indicates that + // the resource rating is unavailable or reporting erroneous values + // for that device. For details see, + // Widevine Modular DRM Security Integration Guide for CENC + optional uint32 resource_rating_tier = 12 [default = 0]; + } + + message ClientCredentials { + optional TokenType type = 1 [default = KEYBOX]; + optional bytes token = 2; + } + + // Type of factory-provisioned device root of trust. Optional. + optional TokenType type = 1 [default = KEYBOX]; + // Factory-provisioned device root of trust. Required. + optional bytes token = 2; + // Optional client information name/value pairs. + repeated NameValue client_info = 3; + // Client token generated by the content provider. Optional. + optional bytes provider_client_token = 4; + // Number of licenses received by the client to which the token above belongs. + // Only present if client_token is specified. + optional uint32 license_counter = 5; + // List of non-baseline client capabilities. + optional ClientCapabilities client_capabilities = 6; + // Serialized VmpData message. Optional. + optional bytes vmp_data = 7; + // Optional field that may contain additional provisioning credentials. + repeated ClientCredentials device_credentials = 8; +} + +// EncryptedClientIdentification message used to hold ClientIdentification +// messages encrypted for privacy purposes. +message EncryptedClientIdentification { + // Provider ID for which the ClientIdentifcation is encrypted (owner of + // service certificate). + optional string provider_id = 1; + // Serial number for the service certificate for which ClientIdentification is + // encrypted. + optional bytes service_certificate_serial_number = 2; + // Serialized ClientIdentification message, encrypted with the privacy key + // using AES-128-CBC with PKCS#5 padding. + optional bytes encrypted_client_id = 3; + // Initialization vector needed to decrypt encrypted_client_id. + optional bytes encrypted_client_id_iv = 4; + // AES-128 privacy key, encrypted with the service public key using RSA-OAEP. + optional bytes encrypted_privacy_key = 5; +} + +// DRM certificate definition for user devices, intermediate, service, and root +// certificates. +message DrmCertificate { + enum Type { + ROOT = 0; // ProtoBestPractices: ignore. + DEVICE_MODEL = 1; + DEVICE = 2; + SERVICE = 3; + PROVISIONER = 4; + } + enum ServiceType { + UNKNOWN_SERVICE_TYPE = 0; + LICENSE_SERVER_SDK = 1; + LICENSE_SERVER_PROXY_SDK = 2; + PROVISIONING_SDK = 3; + CAS_PROXY_SDK = 4; + } + enum Algorithm { + UNKNOWN_ALGORITHM = 0; + RSA = 1; + ECC_SECP256R1 = 2; + ECC_SECP384R1 = 3; + ECC_SECP521R1 = 4; + } + + message EncryptionKey { + // Device public key. PKCS#1 ASN.1 DER-encoded. Required. + optional bytes public_key = 1; + // Required. The algorithm field contains the curve used to create the + // |public_key| if algorithm is one of the ECC types. + // The |algorithm| is used for both to determine the if the certificate is + // ECC or RSA. The |algorithm| also specifies the parameters that were used + // to create |public_key| and are used to create an ephemeral session key. + optional Algorithm algorithm = 2 [default = RSA]; + } + + // Type of certificate. Required. + optional Type type = 1; + // 128-bit globally unique serial number of certificate. + // Value is 0 for root certificate. Required. + optional bytes serial_number = 2; + // POSIX time, in seconds, when the certificate was created. Required. + optional uint32 creation_time_seconds = 3; + // POSIX time, in seconds, when the certificate should expire. Value of zero + // denotes indefinite expiry time. For more information on limited lifespan + // DRM certificates see (go/limited-lifespan-drm-certificates). + optional uint32 expiration_time_seconds = 12; + // Device public key. PKCS#1 ASN.1 DER-encoded. Required. + optional bytes public_key = 4; + // Widevine system ID for the device. Required for intermediate and + // user device certificates. + optional uint32 system_id = 5; + // Deprecated field, which used to indicate whether the device was a test + // (non-production) device. The test_device field in ProvisionedDeviceInfo + // below should be observed instead. + optional bool test_device_deprecated = 6 [deprecated = true]; + // Service identifier (web origin) for the provider which owns the + // certificate. Required for service and provisioner certificates. + optional string provider_id = 7; + // This field is used only when type = SERVICE to specify which SDK uses + // service certificate. This repeated field is treated as a set. A certificate + // may be used for the specified service SDK if the appropriate ServiceType + // is specified in this field. + repeated ServiceType service_types = 8; + // Required. The algorithm field contains the curve used to create the + // |public_key| if algorithm is one of the ECC types. + // The |algorithm| is used for both to determine the if the certificate is ECC + // or RSA. The |algorithm| also specifies the parameters that were used to + // create |public_key| and are used to create an ephemeral session key. + optional Algorithm algorithm = 9 [default = RSA]; + // Optional. May be present in DEVICE certificate types. This is the root + // of trust identifier that holds an encrypted value that identifies the + // keybox or other root of trust that was used to provision a DEVICE drm + // certificate. + optional bytes rot_id = 10; + // Optional. May be present in devices that explicitly support dual keys. When + // present the |public_key| is used for verification of received license + // request messages. + optional EncryptionKey encryption_key = 11; +} + +// DrmCertificate signed by a higher (CA) DRM certificate. +message SignedDrmCertificate { + // Serialized certificate. Required. + optional bytes drm_certificate = 1; + // Signature of certificate. Signed with root or intermediate + // certificate specified below. Required. + optional bytes signature = 2; + // SignedDrmCertificate used to sign this certificate. + optional SignedDrmCertificate signer = 3; + // Optional field that indicates the hash algorithm used in signature scheme. + optional HashAlgorithmProto hash_algorithm = 4; +} + +message WidevinePsshData { + enum Type { + SINGLE = 0; // Single PSSH to be used to retrieve content keys. + ENTITLEMENT = 1; // Primary PSSH used to retrieve entitlement keys. + ENTITLED_KEY = 2; // Secondary PSSH containing entitled key(s). + } + + message EntitledKey { + // ID of entitlement key used for wrapping |key|. + optional bytes entitlement_key_id = 1; + // ID of the entitled key. + optional bytes key_id = 2; + // Wrapped key. Required. + optional bytes key = 3; + // IV used for wrapping |key|. Required. + optional bytes iv = 4; + // Size of entitlement key used for wrapping |key|. + optional uint32 entitlement_key_size_bytes = 5 [default = 32]; + } + + // Entitlement or content key IDs. Can onnly present in SINGLE or ENTITLEMENT + // PSSHs. May be repeated to facilitate delivery of multiple keys in a + // single license. Cannot be used in conjunction with content_id or + // group_ids, which are the preferred mechanism. + repeated bytes key_ids = 2; + + // Content identifier which may map to multiple entitlement or content key + // IDs to facilitate the delivery of multiple keys in a single license. + // Cannot be present in conjunction with key_ids, but if used must be in all + // PSSHs. + optional bytes content_id = 4; + + // Crypto period index, for media using key rotation. Always corresponds to + // The content key period. This means that if using entitlement licensing + // the ENTITLED_KEY PSSHs will have sequential crypto_period_index's, whereas + // the ENTITELEMENT PSSHs will have gaps in the sequence. Required if doing + // key rotation. + optional uint32 crypto_period_index = 7; + + // Protection scheme identifying the encryption algorithm. The protection + // scheme is represented as a uint32 value. The uint32 contains 4 bytes each + // representing a single ascii character in one of the 4CC protection scheme + // values. To be deprecated in favor of signaling from content. + // 'cenc' (AES-CTR) protection_scheme = 0x63656E63, + // 'cbc1' (AES-CBC) protection_scheme = 0x63626331, + // 'cens' (AES-CTR pattern encryption) protection_scheme = 0x63656E73, + // 'cbcs' (AES-CBC pattern encryption) protection_scheme = 0x63626373. + optional uint32 protection_scheme = 9; + + // Optional. For media using key rotation, this represents the duration + // of each crypto period in seconds. + optional uint32 crypto_period_seconds = 10; + + // Type of PSSH. Required if not SINGLE. + optional Type type = 11 [default = SINGLE]; + + // Key sequence for Widevine-managed keys. Optional. + optional uint32 key_sequence = 12; + + // Group identifiers for all groups to which the content belongs. This can + // be used to deliver licenses to unlock multiple titles / channels. + // Optional, and may only be present in ENTITLEMENT and ENTITLED_KEY PSSHs, and + // not in conjunction with key_ids. + repeated bytes group_ids = 13; + + // Copy/copies of the content key used to decrypt the media stream in which + // the PSSH box is embedded, each wrapped with a different entitlement key. + // May also contain sub-licenses to support devices with OEMCrypto 13 or + // older. May be repeated if using group entitlement keys. Present only in + // PSSHs of type ENTITLED_KEY. + repeated EntitledKey entitled_keys = 14; + + // Video feature identifier, which is used in conjunction with |content_id| + // to determine the set of keys to be returned in the license. Cannot be + // present in conjunction with |key_ids|. + // Current values are "HDR". + optional string video_feature = 15; + + //////////////////////////// Deprecated Fields //////////////////////////// + enum Algorithm { + UNENCRYPTED = 0; + AESCTR = 1; + }; + optional Algorithm algorithm = 1 [deprecated = true]; + + // Content provider name. + optional string provider = 3 [deprecated = true]; + + // Track type. Acceptable values are SD, HD and AUDIO. Used to + // differentiate content keys used by an asset. + optional string track_type = 5 [deprecated = true]; + + // The name of a registered policy to be used for this asset. + optional string policy = 6 [deprecated = true]; + + // Optional protected context for group content. The grouped_license is a + // serialized SignedMessage. + optional bytes grouped_license = 8 [deprecated = true]; +} + +// File Hashes for Verified Media Path (VMP) support. +message FileHashes { + message Signature { + optional string filename = 1; + optional bool test_signing = 2; //0 - release, 1 - testing + optional bytes SHA512Hash = 3; + optional bool main_exe = 4; //0 for dlls, 1 for exe, this is field 3 in file + optional bytes signature = 5; + } + optional bytes signer = 1; + repeated Signature signatures = 2; +} \ No newline at end of file diff --git a/modules/license_protocol.ts b/modules/license_protocol.ts new file mode 100644 index 0000000..c7ef68c --- /dev/null +++ b/modules/license_protocol.ts @@ -0,0 +1,4996 @@ +//Originally from https://github.com/Frooastside/node-widevine/blob/main/src/license_protocol.ts + +import Long from 'long'; +import _m0 from 'protobufjs/minimal'; + +export const protobufPackage = 'license_protocol'; + +export enum LicenseType { + STREAMING = 1, + OFFLINE = 2, + /** AUTOMATIC - License type decision is left to provider. */ + AUTOMATIC = 3, + UNRECOGNIZED = -1 +} + +export function licenseTypeFromJSON(object: any): LicenseType { + switch (object) { + case 1: + case 'STREAMING': + return LicenseType.STREAMING; + case 2: + case 'OFFLINE': + return LicenseType.OFFLINE; + case 3: + case 'AUTOMATIC': + return LicenseType.AUTOMATIC; + case -1: + case 'UNRECOGNIZED': + default: + return LicenseType.UNRECOGNIZED; + } +} + +export function licenseTypeToJSON(object: LicenseType): string { + switch (object) { + case LicenseType.STREAMING: + return 'STREAMING'; + case LicenseType.OFFLINE: + return 'OFFLINE'; + case LicenseType.AUTOMATIC: + return 'AUTOMATIC'; + case LicenseType.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +export enum PlatformVerificationStatus { + /** PLATFORM_UNVERIFIED - The platform is not verified. */ + PLATFORM_UNVERIFIED = 0, + /** PLATFORM_TAMPERED - Tampering detected on the platform. */ + PLATFORM_TAMPERED = 1, + /** PLATFORM_SOFTWARE_VERIFIED - The platform has been verified by means of software. */ + PLATFORM_SOFTWARE_VERIFIED = 2, + /** PLATFORM_HARDWARE_VERIFIED - The platform has been verified by means of hardware (e.g. secure boot). */ + PLATFORM_HARDWARE_VERIFIED = 3, + /** PLATFORM_NO_VERIFICATION - Platform verification was not performed. */ + PLATFORM_NO_VERIFICATION = 4, + /** + * PLATFORM_SECURE_STORAGE_SOFTWARE_VERIFIED - Platform and secure storage capability have been verified by means of + * software. + */ + PLATFORM_SECURE_STORAGE_SOFTWARE_VERIFIED = 5, + UNRECOGNIZED = -1 +} + +export function platformVerificationStatusFromJSON(object: any): PlatformVerificationStatus { + switch (object) { + case 0: + case 'PLATFORM_UNVERIFIED': + return PlatformVerificationStatus.PLATFORM_UNVERIFIED; + case 1: + case 'PLATFORM_TAMPERED': + return PlatformVerificationStatus.PLATFORM_TAMPERED; + case 2: + case 'PLATFORM_SOFTWARE_VERIFIED': + return PlatformVerificationStatus.PLATFORM_SOFTWARE_VERIFIED; + case 3: + case 'PLATFORM_HARDWARE_VERIFIED': + return PlatformVerificationStatus.PLATFORM_HARDWARE_VERIFIED; + case 4: + case 'PLATFORM_NO_VERIFICATION': + return PlatformVerificationStatus.PLATFORM_NO_VERIFICATION; + case 5: + case 'PLATFORM_SECURE_STORAGE_SOFTWARE_VERIFIED': + return PlatformVerificationStatus.PLATFORM_SECURE_STORAGE_SOFTWARE_VERIFIED; + case -1: + case 'UNRECOGNIZED': + default: + return PlatformVerificationStatus.UNRECOGNIZED; + } +} + +export function platformVerificationStatusToJSON(object: PlatformVerificationStatus): string { + switch (object) { + case PlatformVerificationStatus.PLATFORM_UNVERIFIED: + return 'PLATFORM_UNVERIFIED'; + case PlatformVerificationStatus.PLATFORM_TAMPERED: + return 'PLATFORM_TAMPERED'; + case PlatformVerificationStatus.PLATFORM_SOFTWARE_VERIFIED: + return 'PLATFORM_SOFTWARE_VERIFIED'; + case PlatformVerificationStatus.PLATFORM_HARDWARE_VERIFIED: + return 'PLATFORM_HARDWARE_VERIFIED'; + case PlatformVerificationStatus.PLATFORM_NO_VERIFICATION: + return 'PLATFORM_NO_VERIFICATION'; + case PlatformVerificationStatus.PLATFORM_SECURE_STORAGE_SOFTWARE_VERIFIED: + return 'PLATFORM_SECURE_STORAGE_SOFTWARE_VERIFIED'; + case PlatformVerificationStatus.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +export enum ProtocolVersion { + VERSION_2_0 = 20, + VERSION_2_1 = 21, + VERSION_2_2 = 22, + UNRECOGNIZED = -1 +} + +export function protocolVersionFromJSON(object: any): ProtocolVersion { + switch (object) { + case 20: + case 'VERSION_2_0': + return ProtocolVersion.VERSION_2_0; + case 21: + case 'VERSION_2_1': + return ProtocolVersion.VERSION_2_1; + case 22: + case 'VERSION_2_2': + return ProtocolVersion.VERSION_2_2; + case -1: + case 'UNRECOGNIZED': + default: + return ProtocolVersion.UNRECOGNIZED; + } +} + +export function protocolVersionToJSON(object: ProtocolVersion): string { + switch (object) { + case ProtocolVersion.VERSION_2_0: + return 'VERSION_2_0'; + case ProtocolVersion.VERSION_2_1: + return 'VERSION_2_1'; + case ProtocolVersion.VERSION_2_2: + return 'VERSION_2_2'; + case ProtocolVersion.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +export enum HashAlgorithmProto { + /** + * HASH_ALGORITHM_UNSPECIFIED - Unspecified hash algorithm: SHA_256 shall be used for ECC based algorithms + * and SHA_1 shall be used otherwise. + */ + HASH_ALGORITHM_UNSPECIFIED = 0, + HASH_ALGORITHM_SHA_1 = 1, + HASH_ALGORITHM_SHA_256 = 2, + HASH_ALGORITHM_SHA_384 = 3, + UNRECOGNIZED = -1 +} + +export function hashAlgorithmProtoFromJSON(object: any): HashAlgorithmProto { + switch (object) { + case 0: + case 'HASH_ALGORITHM_UNSPECIFIED': + return HashAlgorithmProto.HASH_ALGORITHM_UNSPECIFIED; + case 1: + case 'HASH_ALGORITHM_SHA_1': + return HashAlgorithmProto.HASH_ALGORITHM_SHA_1; + case 2: + case 'HASH_ALGORITHM_SHA_256': + return HashAlgorithmProto.HASH_ALGORITHM_SHA_256; + case 3: + case 'HASH_ALGORITHM_SHA_384': + return HashAlgorithmProto.HASH_ALGORITHM_SHA_384; + case -1: + case 'UNRECOGNIZED': + default: + return HashAlgorithmProto.UNRECOGNIZED; + } +} + +export function hashAlgorithmProtoToJSON(object: HashAlgorithmProto): string { + switch (object) { + case HashAlgorithmProto.HASH_ALGORITHM_UNSPECIFIED: + return 'HASH_ALGORITHM_UNSPECIFIED'; + case HashAlgorithmProto.HASH_ALGORITHM_SHA_1: + return 'HASH_ALGORITHM_SHA_1'; + case HashAlgorithmProto.HASH_ALGORITHM_SHA_256: + return 'HASH_ALGORITHM_SHA_256'; + case HashAlgorithmProto.HASH_ALGORITHM_SHA_384: + return 'HASH_ALGORITHM_SHA_384'; + case HashAlgorithmProto.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +/** + * LicenseIdentification is propagated from LicenseRequest to License, + * incrementing version with each iteration. + */ +export interface LicenseIdentification { + requestId: Buffer; + sessionId: Buffer; + purchaseId: Buffer; + type: LicenseType; + version: number; + providerSessionToken: Buffer; +} + +export interface License { + id: LicenseIdentification | undefined; + policy: License_Policy | undefined; + key: License_KeyContainer[]; + /** + * Time of the request in seconds (UTC) as set in + * LicenseRequest.request_time. If this time is not set in the request, + * the local time at the license service is used in this field. + */ + licenseStartTime: Long; + remoteAttestationVerified: boolean; + /** Client token generated by the content provider. Optional. */ + providerClientToken: Buffer; + /** + * 4cc code specifying the CENC protection scheme as defined in the CENC 3.0 + * specification. Propagated from Widevine PSSH box. Optional. + */ + protectionScheme: number; + /** + * 8 byte verification field "HDCPDATA" followed by unsigned 32 bit minimum + * HDCP SRM version (whether the version is for HDCP1 SRM or HDCP2 SRM + * depends on client max_hdcp_version). + * Additional details can be found in Widevine Modular DRM Security + * Integration Guide for CENC. + */ + srmRequirement: Buffer; + /** + * If present this contains a signed SRM file (either HDCP1 SRM or HDCP2 SRM + * depending on client max_hdcp_version) that should be installed on the + * client device. + */ + srmUpdate: Buffer; + /** + * Indicates the status of any type of platform verification performed by the + * server. + */ + platformVerificationStatus: PlatformVerificationStatus; + /** IDs of the groups for which keys are delivered in this license, if any. */ + groupIds: Buffer[]; +} + +export interface License_Policy { + /** Indicates that playback of the content is allowed. */ + canPlay: boolean; + /** + * Indicates that the license may be persisted to non-volatile + * storage for offline use. + */ + canPersist: boolean; + /** Indicates that renewal of this license is allowed. */ + canRenew: boolean; + /** Indicates the rental window. */ + rentalDurationSeconds: Long; + /** Indicates the viewing window, once playback has begun. */ + playbackDurationSeconds: Long; + /** Indicates the time window for this specific license. */ + licenseDurationSeconds: Long; + /** + * The window of time, in which playback is allowed to continue while + * renewal is attempted, yet unsuccessful due to backend problems with + * the license server. + */ + renewalRecoveryDurationSeconds: Long; + /** + * All renewal requests for this license shall be directed to the + * specified URL. + */ + renewalServerUrl: string; + /** + * How many seconds after license_start_time, before renewal is first + * attempted. + */ + renewalDelaySeconds: Long; + /** + * Specifies the delay in seconds between subsequent license + * renewal requests, in case of failure. + */ + renewalRetryIntervalSeconds: Long; + /** + * Indicates that the license shall be sent for renewal when usage is + * started. + */ + renewWithUsage: boolean; + /** + * Indicates to client that license renewal and release requests ought to + * include ClientIdentification (client_id). + */ + alwaysIncludeClientId: boolean; + /** + * Duration of grace period before playback_duration_seconds (short window) + * goes into effect. Optional. + */ + playStartGracePeriodSeconds: Long; + /** + * Enables "soft enforcement" of playback_duration_seconds, letting the user + * finish playback even if short window expires. Optional. + */ + softEnforcePlaybackDuration: boolean; + /** + * Enables "soft enforcement" of rental_duration_seconds. Initial playback + * must always start before rental duration expires. In order to allow + * subsequent playbacks to start after the rental duration expires, + * soft_enforce_playback_duration must be true. Otherwise, subsequent + * playbacks will not be allowed once rental duration expires. Optional. + */ + softEnforceRentalDuration: boolean; +} + +export interface License_KeyContainer { + id: Buffer; + iv: Buffer; + key: Buffer; + type: License_KeyContainer_KeyType; + level: License_KeyContainer_SecurityLevel; + requiredProtection: License_KeyContainer_OutputProtection | undefined; + /** + * NOTE: Use of requested_protection is not recommended as it is only + * supported on a small number of platforms. + */ + requestedProtection: License_KeyContainer_OutputProtection | undefined; + keyControl: License_KeyContainer_KeyControl | undefined; + operatorSessionKeyPermissions: License_KeyContainer_OperatorSessionKeyPermissions | undefined; + /** + * Optional video resolution constraints. If the video resolution of the + * content being decrypted/decoded falls within one of the specified ranges, + * the optional required_protections may be applied. Otherwise an error will + * be reported. + * NOTE: Use of this feature is not recommended, as it is only supported on + * a small number of platforms. + */ + videoResolutionConstraints: License_KeyContainer_VideoResolutionConstraint[]; + /** + * Optional flag to indicate the key must only be used if the client + * supports anti rollback of the user table. Content provider can query the + * client capabilities to determine if the client support this feature. + */ + antiRollbackUsageTable: boolean; + /** + * Optional not limited to commonly known track types such as SD, HD. + * It can be some provider defined label to identify the track. + */ + trackLabel: string; +} + +export enum License_KeyContainer_KeyType { + /** SIGNING - Exactly one key of this type must appear. */ + SIGNING = 1, + /** CONTENT - Content key. */ + CONTENT = 2, + /** KEY_CONTROL - Key control block for license renewals. No key. */ + KEY_CONTROL = 3, + /** OPERATOR_SESSION - wrapped keys for auxiliary crypto operations. */ + OPERATOR_SESSION = 4, + /** ENTITLEMENT - Entitlement keys. */ + ENTITLEMENT = 5, + /** OEM_CONTENT - Partner-specific content key. */ + OEM_CONTENT = 6, + UNRECOGNIZED = -1 +} + +export function license_KeyContainer_KeyTypeFromJSON(object: any): License_KeyContainer_KeyType { + switch (object) { + case 1: + case 'SIGNING': + return License_KeyContainer_KeyType.SIGNING; + case 2: + case 'CONTENT': + return License_KeyContainer_KeyType.CONTENT; + case 3: + case 'KEY_CONTROL': + return License_KeyContainer_KeyType.KEY_CONTROL; + case 4: + case 'OPERATOR_SESSION': + return License_KeyContainer_KeyType.OPERATOR_SESSION; + case 5: + case 'ENTITLEMENT': + return License_KeyContainer_KeyType.ENTITLEMENT; + case 6: + case 'OEM_CONTENT': + return License_KeyContainer_KeyType.OEM_CONTENT; + case -1: + case 'UNRECOGNIZED': + default: + return License_KeyContainer_KeyType.UNRECOGNIZED; + } +} + +export function license_KeyContainer_KeyTypeToJSON(object: License_KeyContainer_KeyType): string { + switch (object) { + case License_KeyContainer_KeyType.SIGNING: + return 'SIGNING'; + case License_KeyContainer_KeyType.CONTENT: + return 'CONTENT'; + case License_KeyContainer_KeyType.KEY_CONTROL: + return 'KEY_CONTROL'; + case License_KeyContainer_KeyType.OPERATOR_SESSION: + return 'OPERATOR_SESSION'; + case License_KeyContainer_KeyType.ENTITLEMENT: + return 'ENTITLEMENT'; + case License_KeyContainer_KeyType.OEM_CONTENT: + return 'OEM_CONTENT'; + case License_KeyContainer_KeyType.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +/** + * The SecurityLevel enumeration allows the server to communicate the level + * of robustness required by the client, in order to use the key. + */ +export enum License_KeyContainer_SecurityLevel { + /** SW_SECURE_CRYPTO - Software-based whitebox crypto is required. */ + SW_SECURE_CRYPTO = 1, + /** SW_SECURE_DECODE - Software crypto and an obfuscated decoder is required. */ + SW_SECURE_DECODE = 2, + /** + * HW_SECURE_CRYPTO - The key material and crypto operations must be performed within a + * hardware backed trusted execution environment. + */ + HW_SECURE_CRYPTO = 3, + /** + * HW_SECURE_DECODE - The crypto and decoding of content must be performed within a hardware + * backed trusted execution environment. + */ + HW_SECURE_DECODE = 4, + /** + * HW_SECURE_ALL - The crypto, decoding and all handling of the media (compressed and + * uncompressed) must be handled within a hardware backed trusted + * execution environment. + */ + HW_SECURE_ALL = 5, + UNRECOGNIZED = -1 +} + +export function license_KeyContainer_SecurityLevelFromJSON(object: any): License_KeyContainer_SecurityLevel { + switch (object) { + case 1: + case 'SW_SECURE_CRYPTO': + return License_KeyContainer_SecurityLevel.SW_SECURE_CRYPTO; + case 2: + case 'SW_SECURE_DECODE': + return License_KeyContainer_SecurityLevel.SW_SECURE_DECODE; + case 3: + case 'HW_SECURE_CRYPTO': + return License_KeyContainer_SecurityLevel.HW_SECURE_CRYPTO; + case 4: + case 'HW_SECURE_DECODE': + return License_KeyContainer_SecurityLevel.HW_SECURE_DECODE; + case 5: + case 'HW_SECURE_ALL': + return License_KeyContainer_SecurityLevel.HW_SECURE_ALL; + case -1: + case 'UNRECOGNIZED': + default: + return License_KeyContainer_SecurityLevel.UNRECOGNIZED; + } +} + +export function license_KeyContainer_SecurityLevelToJSON(object: License_KeyContainer_SecurityLevel): string { + switch (object) { + case License_KeyContainer_SecurityLevel.SW_SECURE_CRYPTO: + return 'SW_SECURE_CRYPTO'; + case License_KeyContainer_SecurityLevel.SW_SECURE_DECODE: + return 'SW_SECURE_DECODE'; + case License_KeyContainer_SecurityLevel.HW_SECURE_CRYPTO: + return 'HW_SECURE_CRYPTO'; + case License_KeyContainer_SecurityLevel.HW_SECURE_DECODE: + return 'HW_SECURE_DECODE'; + case License_KeyContainer_SecurityLevel.HW_SECURE_ALL: + return 'HW_SECURE_ALL'; + case License_KeyContainer_SecurityLevel.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +export interface License_KeyContainer_KeyControl { + /** + * |key_control| is documented in: + * Widevine Modular DRM Security Integration Guide for CENC + * If present, the key control must be communicated to the secure + * environment prior to any usage. This message is automatically generated + * by the Widevine License Server SDK. + */ + keyControlBlock: Buffer; + iv: Buffer; +} + +export interface License_KeyContainer_OutputProtection { + hdcp: License_KeyContainer_OutputProtection_HDCP; + cgmsFlags: License_KeyContainer_OutputProtection_CGMS; + hdcpSrmRule: License_KeyContainer_OutputProtection_HdcpSrmRule; + /** Optional requirement to indicate analog output is not allowed. */ + disableAnalogOutput: boolean; + /** Optional requirement to indicate digital output is not allowed. */ + disableDigitalOutput: boolean; +} + +/** + * Indicates whether HDCP is required on digital outputs, and which + * version should be used. + */ +export enum License_KeyContainer_OutputProtection_HDCP { + HDCP_NONE = 0, + HDCP_V1 = 1, + HDCP_V2 = 2, + HDCP_V2_1 = 3, + HDCP_V2_2 = 4, + HDCP_V2_3 = 5, + HDCP_NO_DIGITAL_OUTPUT = 255, + UNRECOGNIZED = -1 +} + +export function license_KeyContainer_OutputProtection_HDCPFromJSON(object: any): License_KeyContainer_OutputProtection_HDCP { + switch (object) { + case 0: + case 'HDCP_NONE': + return License_KeyContainer_OutputProtection_HDCP.HDCP_NONE; + case 1: + case 'HDCP_V1': + return License_KeyContainer_OutputProtection_HDCP.HDCP_V1; + case 2: + case 'HDCP_V2': + return License_KeyContainer_OutputProtection_HDCP.HDCP_V2; + case 3: + case 'HDCP_V2_1': + return License_KeyContainer_OutputProtection_HDCP.HDCP_V2_1; + case 4: + case 'HDCP_V2_2': + return License_KeyContainer_OutputProtection_HDCP.HDCP_V2_2; + case 5: + case 'HDCP_V2_3': + return License_KeyContainer_OutputProtection_HDCP.HDCP_V2_3; + case 255: + case 'HDCP_NO_DIGITAL_OUTPUT': + return License_KeyContainer_OutputProtection_HDCP.HDCP_NO_DIGITAL_OUTPUT; + case -1: + case 'UNRECOGNIZED': + default: + return License_KeyContainer_OutputProtection_HDCP.UNRECOGNIZED; + } +} + +export function license_KeyContainer_OutputProtection_HDCPToJSON(object: License_KeyContainer_OutputProtection_HDCP): string { + switch (object) { + case License_KeyContainer_OutputProtection_HDCP.HDCP_NONE: + return 'HDCP_NONE'; + case License_KeyContainer_OutputProtection_HDCP.HDCP_V1: + return 'HDCP_V1'; + case License_KeyContainer_OutputProtection_HDCP.HDCP_V2: + return 'HDCP_V2'; + case License_KeyContainer_OutputProtection_HDCP.HDCP_V2_1: + return 'HDCP_V2_1'; + case License_KeyContainer_OutputProtection_HDCP.HDCP_V2_2: + return 'HDCP_V2_2'; + case License_KeyContainer_OutputProtection_HDCP.HDCP_V2_3: + return 'HDCP_V2_3'; + case License_KeyContainer_OutputProtection_HDCP.HDCP_NO_DIGITAL_OUTPUT: + return 'HDCP_NO_DIGITAL_OUTPUT'; + case License_KeyContainer_OutputProtection_HDCP.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +/** Indicate the CGMS setting to be inserted on analog output. */ +export enum License_KeyContainer_OutputProtection_CGMS { + CGMS_NONE = 42, + COPY_FREE = 0, + COPY_ONCE = 2, + COPY_NEVER = 3, + UNRECOGNIZED = -1 +} + +export function license_KeyContainer_OutputProtection_CGMSFromJSON(object: any): License_KeyContainer_OutputProtection_CGMS { + switch (object) { + case 42: + case 'CGMS_NONE': + return License_KeyContainer_OutputProtection_CGMS.CGMS_NONE; + case 0: + case 'COPY_FREE': + return License_KeyContainer_OutputProtection_CGMS.COPY_FREE; + case 2: + case 'COPY_ONCE': + return License_KeyContainer_OutputProtection_CGMS.COPY_ONCE; + case 3: + case 'COPY_NEVER': + return License_KeyContainer_OutputProtection_CGMS.COPY_NEVER; + case -1: + case 'UNRECOGNIZED': + default: + return License_KeyContainer_OutputProtection_CGMS.UNRECOGNIZED; + } +} + +export function license_KeyContainer_OutputProtection_CGMSToJSON(object: License_KeyContainer_OutputProtection_CGMS): string { + switch (object) { + case License_KeyContainer_OutputProtection_CGMS.CGMS_NONE: + return 'CGMS_NONE'; + case License_KeyContainer_OutputProtection_CGMS.COPY_FREE: + return 'COPY_FREE'; + case License_KeyContainer_OutputProtection_CGMS.COPY_ONCE: + return 'COPY_ONCE'; + case License_KeyContainer_OutputProtection_CGMS.COPY_NEVER: + return 'COPY_NEVER'; + case License_KeyContainer_OutputProtection_CGMS.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +export enum License_KeyContainer_OutputProtection_HdcpSrmRule { + HDCP_SRM_RULE_NONE = 0, + /** + * CURRENT_SRM - In 'required_protection', this means most current SRM is required. + * Update the SRM on the device. If update cannot happen, + * do not allow the key. + * In 'requested_protection', this means most current SRM is requested. + * Update the SRM on the device. If update cannot happen, + * allow use of the key anyway. + */ + CURRENT_SRM = 1, + UNRECOGNIZED = -1 +} + +export function license_KeyContainer_OutputProtection_HdcpSrmRuleFromJSON(object: any): License_KeyContainer_OutputProtection_HdcpSrmRule { + switch (object) { + case 0: + case 'HDCP_SRM_RULE_NONE': + return License_KeyContainer_OutputProtection_HdcpSrmRule.HDCP_SRM_RULE_NONE; + case 1: + case 'CURRENT_SRM': + return License_KeyContainer_OutputProtection_HdcpSrmRule.CURRENT_SRM; + case -1: + case 'UNRECOGNIZED': + default: + return License_KeyContainer_OutputProtection_HdcpSrmRule.UNRECOGNIZED; + } +} + +export function license_KeyContainer_OutputProtection_HdcpSrmRuleToJSON(object: License_KeyContainer_OutputProtection_HdcpSrmRule): string { + switch (object) { + case License_KeyContainer_OutputProtection_HdcpSrmRule.HDCP_SRM_RULE_NONE: + return 'HDCP_SRM_RULE_NONE'; + case License_KeyContainer_OutputProtection_HdcpSrmRule.CURRENT_SRM: + return 'CURRENT_SRM'; + case License_KeyContainer_OutputProtection_HdcpSrmRule.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +export interface License_KeyContainer_VideoResolutionConstraint { + /** Minimum and maximum video resolutions in the range (height x width). */ + minResolutionPixels: number; + maxResolutionPixels: number; + /** + * Optional output protection requirements for this range. If not + * specified, the OutputProtection in the KeyContainer applies. + */ + requiredProtection: License_KeyContainer_OutputProtection | undefined; +} + +export interface License_KeyContainer_OperatorSessionKeyPermissions { + /** + * Permissions/key usage flags for operator service keys + * (type = OPERATOR_SESSION). + */ + allowEncrypt: boolean; + allowDecrypt: boolean; + allowSign: boolean; + allowSignatureVerify: boolean; +} + +export interface LicenseRequest { + /** + * The client_id provides information authenticating the calling device. It + * contains the Widevine keybox token that was installed on the device at the + * factory. This field or encrypted_client_id below is required for a valid + * license request, but both should never be present in the same request. + */ + clientId: ClientIdentification | undefined; + contentId: LicenseRequest_ContentIdentification | undefined; + type: LicenseRequest_RequestType; + /** Time of the request in seconds (UTC) as set by the client. */ + requestTime: Long; + /** Old-style decimal-encoded string key control nonce. */ + keyControlNonceDeprecated: Buffer; + protocolVersion: ProtocolVersion; + /** + * New-style uint32 key control nonce, please use instead of + * key_control_nonce_deprecated. + */ + keyControlNonce: number; + /** Encrypted ClientIdentification message, used for privacy purposes. */ + encryptedClientId: EncryptedClientIdentification | undefined; +} + +export enum LicenseRequest_RequestType { + NEW = 1, + RENEWAL = 2, + RELEASE = 3, + UNRECOGNIZED = -1 +} + +export function licenseRequest_RequestTypeFromJSON(object: any): LicenseRequest_RequestType { + switch (object) { + case 1: + case 'NEW': + return LicenseRequest_RequestType.NEW; + case 2: + case 'RENEWAL': + return LicenseRequest_RequestType.RENEWAL; + case 3: + case 'RELEASE': + return LicenseRequest_RequestType.RELEASE; + case -1: + case 'UNRECOGNIZED': + default: + return LicenseRequest_RequestType.UNRECOGNIZED; + } +} + +export function licenseRequest_RequestTypeToJSON(object: LicenseRequest_RequestType): string { + switch (object) { + case LicenseRequest_RequestType.NEW: + return 'NEW'; + case LicenseRequest_RequestType.RENEWAL: + return 'RENEWAL'; + case LicenseRequest_RequestType.RELEASE: + return 'RELEASE'; + case LicenseRequest_RequestType.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +export interface LicenseRequest_ContentIdentification { + /** Exactly one of these must be present. */ + widevinePsshData?: LicenseRequest_ContentIdentification_WidevinePsshData | undefined; + webmKeyId?: LicenseRequest_ContentIdentification_WebmKeyId | undefined; + existingLicense?: LicenseRequest_ContentIdentification_ExistingLicense | undefined; + initData?: LicenseRequest_ContentIdentification_InitData | undefined; +} + +export interface LicenseRequest_ContentIdentification_WidevinePsshData { + psshData: Buffer[]; + licenseType: LicenseType; + /** Opaque, client-specified. */ + requestId: Buffer; +} + +export interface LicenseRequest_ContentIdentification_WebmKeyId { + header: Buffer; + licenseType: LicenseType; + /** Opaque, client-specified. */ + requestId: Buffer; +} + +export interface LicenseRequest_ContentIdentification_ExistingLicense { + licenseId: LicenseIdentification | undefined; + secondsSinceStarted: Long; + secondsSinceLastPlayed: Long; + sessionUsageTableEntry: Buffer; +} + +export interface LicenseRequest_ContentIdentification_InitData { + initDataType: LicenseRequest_ContentIdentification_InitData_InitDataType; + initData: Buffer; + licenseType: LicenseType; + requestId: Buffer; +} + +export enum LicenseRequest_ContentIdentification_InitData_InitDataType { + CENC = 1, + WEBM = 2, + UNRECOGNIZED = -1 +} + +export function licenseRequest_ContentIdentification_InitData_InitDataTypeFromJSON( + object: any +): LicenseRequest_ContentIdentification_InitData_InitDataType { + switch (object) { + case 1: + case 'CENC': + return LicenseRequest_ContentIdentification_InitData_InitDataType.CENC; + case 2: + case 'WEBM': + return LicenseRequest_ContentIdentification_InitData_InitDataType.WEBM; + case -1: + case 'UNRECOGNIZED': + default: + return LicenseRequest_ContentIdentification_InitData_InitDataType.UNRECOGNIZED; + } +} + +export function licenseRequest_ContentIdentification_InitData_InitDataTypeToJSON( + object: LicenseRequest_ContentIdentification_InitData_InitDataType +): string { + switch (object) { + case LicenseRequest_ContentIdentification_InitData_InitDataType.CENC: + return 'CENC'; + case LicenseRequest_ContentIdentification_InitData_InitDataType.WEBM: + return 'WEBM'; + case LicenseRequest_ContentIdentification_InitData_InitDataType.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +export interface MetricData { + /** 'stage' that is currently processing the SignedMessage. Required. */ + stageName: string; + /** metric and associated value. */ + metricData: MetricData_TypeValue[]; +} + +export enum MetricData_MetricType { + /** LATENCY - The time spent in the 'stage', specified in microseconds. */ + LATENCY = 1, + /** + * TIMESTAMP - The UNIX epoch timestamp at which the 'stage' was first accessed in + * microseconds. + */ + TIMESTAMP = 2, + UNRECOGNIZED = -1 +} + +export function metricData_MetricTypeFromJSON(object: any): MetricData_MetricType { + switch (object) { + case 1: + case 'LATENCY': + return MetricData_MetricType.LATENCY; + case 2: + case 'TIMESTAMP': + return MetricData_MetricType.TIMESTAMP; + case -1: + case 'UNRECOGNIZED': + default: + return MetricData_MetricType.UNRECOGNIZED; + } +} + +export function metricData_MetricTypeToJSON(object: MetricData_MetricType): string { + switch (object) { + case MetricData_MetricType.LATENCY: + return 'LATENCY'; + case MetricData_MetricType.TIMESTAMP: + return 'TIMESTAMP'; + case MetricData_MetricType.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +export interface MetricData_TypeValue { + type: MetricData_MetricType; + /** + * The value associated with 'type'. For example if type == LATENCY, the + * value would be the time in microseconds spent in this 'stage'. + */ + value: Long; +} + +export interface VersionInfo { + /** + * License SDK version reported by the Widevine License SDK. This field + * is populated automatically by the SDK. + */ + licenseSdkVersion: string; + /** + * Version of the service hosting the license SDK. This field is optional. + * It may be provided by the hosting service. + */ + licenseServiceVersion: string; +} + +export interface SignedMessage { + type: SignedMessage_MessageType; + msg: Buffer; + /** + * Required field that contains the signature of the bytes of msg. + * For license requests, the signing algorithm is determined by the + * certificate contained in the request. + * For license responses, the signing algorithm is HMAC with signing key based + * on |session_key|. + */ + signature: Buffer; + /** + * If populated, the contents of this field will be signaled by the + * |session_key_type| type. If the |session_key_type| is WRAPPED_AES_KEY the + * key is the bytes of an encrypted AES key. If the |session_key_type| is + * EPHERMERAL_ECC_PUBLIC_KEY the field contains the bytes of an RFC5208 ASN1 + * serialized ECC public key. + */ + sessionKey: Buffer; + /** + * Remote attestation data which will be present in the initial license + * request for ChromeOS client devices operating in verified mode. Remote + * attestation challenge data is |msg| field above. Optional. + */ + remoteAttestation: Buffer; + metricData: MetricData[]; + /** + * Version information from the SDK and license service. This information is + * provided in the license response. + */ + serviceVersionInfo: VersionInfo | undefined; + /** + * Optional field that contains the algorithm type used to generate the + * session_key and signature in a LICENSE message. + */ + sessionKeyType: SignedMessage_SessionKeyType; + /** + * The core message is the simple serialization of fields used by OEMCrypto. + * This field was introduced in OEMCrypto API v16. + */ + oemcryptoCoreMessage: Buffer; +} + +export enum SignedMessage_MessageType { + LICENSE_REQUEST = 1, + LICENSE = 2, + ERROR_RESPONSE = 3, + SERVICE_CERTIFICATE_REQUEST = 4, + SERVICE_CERTIFICATE = 5, + SUB_LICENSE = 6, + CAS_LICENSE_REQUEST = 7, + CAS_LICENSE = 8, + EXTERNAL_LICENSE_REQUEST = 9, + EXTERNAL_LICENSE = 10, + UNRECOGNIZED = -1 +} + +export function signedMessage_MessageTypeFromJSON(object: any): SignedMessage_MessageType { + switch (object) { + case 1: + case 'LICENSE_REQUEST': + return SignedMessage_MessageType.LICENSE_REQUEST; + case 2: + case 'LICENSE': + return SignedMessage_MessageType.LICENSE; + case 3: + case 'ERROR_RESPONSE': + return SignedMessage_MessageType.ERROR_RESPONSE; + case 4: + case 'SERVICE_CERTIFICATE_REQUEST': + return SignedMessage_MessageType.SERVICE_CERTIFICATE_REQUEST; + case 5: + case 'SERVICE_CERTIFICATE': + return SignedMessage_MessageType.SERVICE_CERTIFICATE; + case 6: + case 'SUB_LICENSE': + return SignedMessage_MessageType.SUB_LICENSE; + case 7: + case 'CAS_LICENSE_REQUEST': + return SignedMessage_MessageType.CAS_LICENSE_REQUEST; + case 8: + case 'CAS_LICENSE': + return SignedMessage_MessageType.CAS_LICENSE; + case 9: + case 'EXTERNAL_LICENSE_REQUEST': + return SignedMessage_MessageType.EXTERNAL_LICENSE_REQUEST; + case 10: + case 'EXTERNAL_LICENSE': + return SignedMessage_MessageType.EXTERNAL_LICENSE; + case -1: + case 'UNRECOGNIZED': + default: + return SignedMessage_MessageType.UNRECOGNIZED; + } +} + +export function signedMessage_MessageTypeToJSON(object: SignedMessage_MessageType): string { + switch (object) { + case SignedMessage_MessageType.LICENSE_REQUEST: + return 'LICENSE_REQUEST'; + case SignedMessage_MessageType.LICENSE: + return 'LICENSE'; + case SignedMessage_MessageType.ERROR_RESPONSE: + return 'ERROR_RESPONSE'; + case SignedMessage_MessageType.SERVICE_CERTIFICATE_REQUEST: + return 'SERVICE_CERTIFICATE_REQUEST'; + case SignedMessage_MessageType.SERVICE_CERTIFICATE: + return 'SERVICE_CERTIFICATE'; + case SignedMessage_MessageType.SUB_LICENSE: + return 'SUB_LICENSE'; + case SignedMessage_MessageType.CAS_LICENSE_REQUEST: + return 'CAS_LICENSE_REQUEST'; + case SignedMessage_MessageType.CAS_LICENSE: + return 'CAS_LICENSE'; + case SignedMessage_MessageType.EXTERNAL_LICENSE_REQUEST: + return 'EXTERNAL_LICENSE_REQUEST'; + case SignedMessage_MessageType.EXTERNAL_LICENSE: + return 'EXTERNAL_LICENSE'; + case SignedMessage_MessageType.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +export enum SignedMessage_SessionKeyType { + UNDEFINED = 0, + WRAPPED_AES_KEY = 1, + EPHERMERAL_ECC_PUBLIC_KEY = 2, + UNRECOGNIZED = -1 +} + +export function signedMessage_SessionKeyTypeFromJSON(object: any): SignedMessage_SessionKeyType { + switch (object) { + case 0: + case 'UNDEFINED': + return SignedMessage_SessionKeyType.UNDEFINED; + case 1: + case 'WRAPPED_AES_KEY': + return SignedMessage_SessionKeyType.WRAPPED_AES_KEY; + case 2: + case 'EPHERMERAL_ECC_PUBLIC_KEY': + return SignedMessage_SessionKeyType.EPHERMERAL_ECC_PUBLIC_KEY; + case -1: + case 'UNRECOGNIZED': + default: + return SignedMessage_SessionKeyType.UNRECOGNIZED; + } +} + +export function signedMessage_SessionKeyTypeToJSON(object: SignedMessage_SessionKeyType): string { + switch (object) { + case SignedMessage_SessionKeyType.UNDEFINED: + return 'UNDEFINED'; + case SignedMessage_SessionKeyType.WRAPPED_AES_KEY: + return 'WRAPPED_AES_KEY'; + case SignedMessage_SessionKeyType.EPHERMERAL_ECC_PUBLIC_KEY: + return 'EPHERMERAL_ECC_PUBLIC_KEY'; + case SignedMessage_SessionKeyType.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +/** ClientIdentification message used to authenticate the client device. */ +export interface ClientIdentification { + /** Type of factory-provisioned device root of trust. Optional. */ + type: ClientIdentification_TokenType; + /** Factory-provisioned device root of trust. Required. */ + token: Buffer; + /** Optional client information name/value pairs. */ + clientInfo: ClientIdentification_NameValue[]; + /** Client token generated by the content provider. Optional. */ + providerClientToken: Buffer; + /** + * Number of licenses received by the client to which the token above belongs. + * Only present if client_token is specified. + */ + licenseCounter: number; + /** List of non-baseline client capabilities. */ + clientCapabilities: ClientIdentification_ClientCapabilities | undefined; + /** Serialized VmpData message. Optional. */ + vmpData: Buffer; + /** Optional field that may contain additional provisioning credentials. */ + deviceCredentials: ClientIdentification_ClientCredentials[]; +} + +export enum ClientIdentification_TokenType { + KEYBOX = 0, + DRM_DEVICE_CERTIFICATE = 1, + REMOTE_ATTESTATION_CERTIFICATE = 2, + OEM_DEVICE_CERTIFICATE = 3, + UNRECOGNIZED = -1 +} + +export function clientIdentification_TokenTypeFromJSON(object: any): ClientIdentification_TokenType { + switch (object) { + case 0: + case 'KEYBOX': + return ClientIdentification_TokenType.KEYBOX; + case 1: + case 'DRM_DEVICE_CERTIFICATE': + return ClientIdentification_TokenType.DRM_DEVICE_CERTIFICATE; + case 2: + case 'REMOTE_ATTESTATION_CERTIFICATE': + return ClientIdentification_TokenType.REMOTE_ATTESTATION_CERTIFICATE; + case 3: + case 'OEM_DEVICE_CERTIFICATE': + return ClientIdentification_TokenType.OEM_DEVICE_CERTIFICATE; + case -1: + case 'UNRECOGNIZED': + default: + return ClientIdentification_TokenType.UNRECOGNIZED; + } +} + +export function clientIdentification_TokenTypeToJSON(object: ClientIdentification_TokenType): string { + switch (object) { + case ClientIdentification_TokenType.KEYBOX: + return 'KEYBOX'; + case ClientIdentification_TokenType.DRM_DEVICE_CERTIFICATE: + return 'DRM_DEVICE_CERTIFICATE'; + case ClientIdentification_TokenType.REMOTE_ATTESTATION_CERTIFICATE: + return 'REMOTE_ATTESTATION_CERTIFICATE'; + case ClientIdentification_TokenType.OEM_DEVICE_CERTIFICATE: + return 'OEM_DEVICE_CERTIFICATE'; + case ClientIdentification_TokenType.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +export interface ClientIdentification_NameValue { + name: string; + value: string; +} + +/** + * Capabilities which not all clients may support. Used for the license + * exchange protocol only. + */ +export interface ClientIdentification_ClientCapabilities { + clientToken: boolean; + sessionToken: boolean; + videoResolutionConstraints: boolean; + maxHdcpVersion: ClientIdentification_ClientCapabilities_HdcpVersion; + oemCryptoApiVersion: number; + /** + * Client has hardware support for protecting the usage table, such as + * storing the generation number in secure memory. For Details, see: + * Widevine Modular DRM Security Integration Guide for CENC + */ + antiRollbackUsageTable: boolean; + /** The client shall report |srm_version| if available. */ + srmVersion: number; + /** + * A device may have SRM data, and report a version, but may not be capable + * of updating SRM data. + */ + canUpdateSrm: boolean; + supportedCertificateKeyType: ClientIdentification_ClientCapabilities_CertificateKeyType[]; + analogOutputCapabilities: ClientIdentification_ClientCapabilities_AnalogOutputCapabilities; + canDisableAnalogOutput: boolean; + /** + * Clients can indicate a performance level supported by OEMCrypto. + * This will allow applications and providers to choose an appropriate + * quality of content to serve. Currently defined tiers are + * 1 (low), 2 (medium) and 3 (high). Any other value indicates that + * the resource rating is unavailable or reporting erroneous values + * for that device. For details see, + * Widevine Modular DRM Security Integration Guide for CENC + */ + resourceRatingTier: number; +} + +export enum ClientIdentification_ClientCapabilities_HdcpVersion { + HDCP_NONE = 0, + HDCP_V1 = 1, + HDCP_V2 = 2, + HDCP_V2_1 = 3, + HDCP_V2_2 = 4, + HDCP_V2_3 = 5, + HDCP_NO_DIGITAL_OUTPUT = 255, + UNRECOGNIZED = -1 +} + +export function clientIdentification_ClientCapabilities_HdcpVersionFromJSON(object: any): ClientIdentification_ClientCapabilities_HdcpVersion { + switch (object) { + case 0: + case 'HDCP_NONE': + return ClientIdentification_ClientCapabilities_HdcpVersion.HDCP_NONE; + case 1: + case 'HDCP_V1': + return ClientIdentification_ClientCapabilities_HdcpVersion.HDCP_V1; + case 2: + case 'HDCP_V2': + return ClientIdentification_ClientCapabilities_HdcpVersion.HDCP_V2; + case 3: + case 'HDCP_V2_1': + return ClientIdentification_ClientCapabilities_HdcpVersion.HDCP_V2_1; + case 4: + case 'HDCP_V2_2': + return ClientIdentification_ClientCapabilities_HdcpVersion.HDCP_V2_2; + case 5: + case 'HDCP_V2_3': + return ClientIdentification_ClientCapabilities_HdcpVersion.HDCP_V2_3; + case 255: + case 'HDCP_NO_DIGITAL_OUTPUT': + return ClientIdentification_ClientCapabilities_HdcpVersion.HDCP_NO_DIGITAL_OUTPUT; + case -1: + case 'UNRECOGNIZED': + default: + return ClientIdentification_ClientCapabilities_HdcpVersion.UNRECOGNIZED; + } +} + +export function clientIdentification_ClientCapabilities_HdcpVersionToJSON(object: ClientIdentification_ClientCapabilities_HdcpVersion): string { + switch (object) { + case ClientIdentification_ClientCapabilities_HdcpVersion.HDCP_NONE: + return 'HDCP_NONE'; + case ClientIdentification_ClientCapabilities_HdcpVersion.HDCP_V1: + return 'HDCP_V1'; + case ClientIdentification_ClientCapabilities_HdcpVersion.HDCP_V2: + return 'HDCP_V2'; + case ClientIdentification_ClientCapabilities_HdcpVersion.HDCP_V2_1: + return 'HDCP_V2_1'; + case ClientIdentification_ClientCapabilities_HdcpVersion.HDCP_V2_2: + return 'HDCP_V2_2'; + case ClientIdentification_ClientCapabilities_HdcpVersion.HDCP_V2_3: + return 'HDCP_V2_3'; + case ClientIdentification_ClientCapabilities_HdcpVersion.HDCP_NO_DIGITAL_OUTPUT: + return 'HDCP_NO_DIGITAL_OUTPUT'; + case ClientIdentification_ClientCapabilities_HdcpVersion.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +export enum ClientIdentification_ClientCapabilities_CertificateKeyType { + RSA_2048 = 0, + RSA_3072 = 1, + ECC_SECP256R1 = 2, + ECC_SECP384R1 = 3, + ECC_SECP521R1 = 4, + UNRECOGNIZED = -1 +} + +export function clientIdentification_ClientCapabilities_CertificateKeyTypeFromJSON( + object: any +): ClientIdentification_ClientCapabilities_CertificateKeyType { + switch (object) { + case 0: + case 'RSA_2048': + return ClientIdentification_ClientCapabilities_CertificateKeyType.RSA_2048; + case 1: + case 'RSA_3072': + return ClientIdentification_ClientCapabilities_CertificateKeyType.RSA_3072; + case 2: + case 'ECC_SECP256R1': + return ClientIdentification_ClientCapabilities_CertificateKeyType.ECC_SECP256R1; + case 3: + case 'ECC_SECP384R1': + return ClientIdentification_ClientCapabilities_CertificateKeyType.ECC_SECP384R1; + case 4: + case 'ECC_SECP521R1': + return ClientIdentification_ClientCapabilities_CertificateKeyType.ECC_SECP521R1; + case -1: + case 'UNRECOGNIZED': + default: + return ClientIdentification_ClientCapabilities_CertificateKeyType.UNRECOGNIZED; + } +} + +export function clientIdentification_ClientCapabilities_CertificateKeyTypeToJSON( + object: ClientIdentification_ClientCapabilities_CertificateKeyType +): string { + switch (object) { + case ClientIdentification_ClientCapabilities_CertificateKeyType.RSA_2048: + return 'RSA_2048'; + case ClientIdentification_ClientCapabilities_CertificateKeyType.RSA_3072: + return 'RSA_3072'; + case ClientIdentification_ClientCapabilities_CertificateKeyType.ECC_SECP256R1: + return 'ECC_SECP256R1'; + case ClientIdentification_ClientCapabilities_CertificateKeyType.ECC_SECP384R1: + return 'ECC_SECP384R1'; + case ClientIdentification_ClientCapabilities_CertificateKeyType.ECC_SECP521R1: + return 'ECC_SECP521R1'; + case ClientIdentification_ClientCapabilities_CertificateKeyType.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +export enum ClientIdentification_ClientCapabilities_AnalogOutputCapabilities { + ANALOG_OUTPUT_UNKNOWN = 0, + ANALOG_OUTPUT_NONE = 1, + ANALOG_OUTPUT_SUPPORTED = 2, + ANALOG_OUTPUT_SUPPORTS_CGMS_A = 3, + UNRECOGNIZED = -1 +} + +export function clientIdentification_ClientCapabilities_AnalogOutputCapabilitiesFromJSON( + object: any +): ClientIdentification_ClientCapabilities_AnalogOutputCapabilities { + switch (object) { + case 0: + case 'ANALOG_OUTPUT_UNKNOWN': + return ClientIdentification_ClientCapabilities_AnalogOutputCapabilities.ANALOG_OUTPUT_UNKNOWN; + case 1: + case 'ANALOG_OUTPUT_NONE': + return ClientIdentification_ClientCapabilities_AnalogOutputCapabilities.ANALOG_OUTPUT_NONE; + case 2: + case 'ANALOG_OUTPUT_SUPPORTED': + return ClientIdentification_ClientCapabilities_AnalogOutputCapabilities.ANALOG_OUTPUT_SUPPORTED; + case 3: + case 'ANALOG_OUTPUT_SUPPORTS_CGMS_A': + return ClientIdentification_ClientCapabilities_AnalogOutputCapabilities.ANALOG_OUTPUT_SUPPORTS_CGMS_A; + case -1: + case 'UNRECOGNIZED': + default: + return ClientIdentification_ClientCapabilities_AnalogOutputCapabilities.UNRECOGNIZED; + } +} + +export function clientIdentification_ClientCapabilities_AnalogOutputCapabilitiesToJSON( + object: ClientIdentification_ClientCapabilities_AnalogOutputCapabilities +): string { + switch (object) { + case ClientIdentification_ClientCapabilities_AnalogOutputCapabilities.ANALOG_OUTPUT_UNKNOWN: + return 'ANALOG_OUTPUT_UNKNOWN'; + case ClientIdentification_ClientCapabilities_AnalogOutputCapabilities.ANALOG_OUTPUT_NONE: + return 'ANALOG_OUTPUT_NONE'; + case ClientIdentification_ClientCapabilities_AnalogOutputCapabilities.ANALOG_OUTPUT_SUPPORTED: + return 'ANALOG_OUTPUT_SUPPORTED'; + case ClientIdentification_ClientCapabilities_AnalogOutputCapabilities.ANALOG_OUTPUT_SUPPORTS_CGMS_A: + return 'ANALOG_OUTPUT_SUPPORTS_CGMS_A'; + case ClientIdentification_ClientCapabilities_AnalogOutputCapabilities.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +export interface ClientIdentification_ClientCredentials { + type: ClientIdentification_TokenType; + token: Buffer; +} + +/** + * EncryptedClientIdentification message used to hold ClientIdentification + * messages encrypted for privacy purposes. + */ +export interface EncryptedClientIdentification { + /** + * Provider ID for which the ClientIdentifcation is encrypted (owner of + * service certificate). + */ + providerId: string; + /** + * Serial number for the service certificate for which ClientIdentification is + * encrypted. + */ + serviceCertificateSerialNumber: Buffer; + /** + * Serialized ClientIdentification message, encrypted with the privacy key + * using AES-128-CBC with PKCS#5 padding. + */ + encryptedClientId: Buffer; + /** Initialization vector needed to decrypt encrypted_client_id. */ + encryptedClientIdIv: Buffer; + /** AES-128 privacy key, encrypted with the service public key using RSA-OAEP. */ + encryptedPrivacyKey: Buffer; +} + +/** + * DRM certificate definition for user devices, intermediate, service, and root + * certificates. + */ +export interface DrmCertificate { + /** Type of certificate. Required. */ + type: DrmCertificate_Type; + /** + * 128-bit globally unique serial number of certificate. + * Value is 0 for root certificate. Required. + */ + serialNumber: Buffer; + /** POSIX time, in seconds, when the certificate was created. Required. */ + creationTimeSeconds: number; + /** + * POSIX time, in seconds, when the certificate should expire. Value of zero + * denotes indefinite expiry time. For more information on limited lifespan + * DRM certificates see (go/limited-lifespan-drm-certificates). + */ + expirationTimeSeconds: number; + /** Device public key. PKCS#1 ASN.1 DER-encoded. Required. */ + publicKey: Buffer; + /** + * Widevine system ID for the device. Required for intermediate and + * user device certificates. + */ + systemId: number; + /** + * Deprecated field, which used to indicate whether the device was a test + * (non-production) device. The test_device field in ProvisionedDeviceInfo + * below should be observed instead. + * + * @deprecated + */ + testDeviceDeprecated: boolean; + /** + * Service identifier (web origin) for the provider which owns the + * certificate. Required for service and provisioner certificates. + */ + providerId: string; + /** + * This field is used only when type = SERVICE to specify which SDK uses + * service certificate. This repeated field is treated as a set. A certificate + * may be used for the specified service SDK if the appropriate ServiceType + * is specified in this field. + */ + serviceTypes: DrmCertificate_ServiceType[]; + /** + * Required. The algorithm field contains the curve used to create the + * |public_key| if algorithm is one of the ECC types. + * The |algorithm| is used for both to determine the if the certificate is ECC + * or RSA. The |algorithm| also specifies the parameters that were used to + * create |public_key| and are used to create an ephemeral session key. + */ + algorithm: DrmCertificate_Algorithm; + /** + * Optional. May be present in DEVICE certificate types. This is the root + * of trust identifier that holds an encrypted value that identifies the + * keybox or other root of trust that was used to provision a DEVICE drm + * certificate. + */ + rotId: Buffer; + /** + * Optional. May be present in devices that explicitly support dual keys. When + * present the |public_key| is used for verification of received license + * request messages. + */ + encryptionKey: DrmCertificate_EncryptionKey | undefined; +} + +export enum DrmCertificate_Type { + /** ROOT - ProtoBestPractices: ignore. */ + ROOT = 0, + DEVICE_MODEL = 1, + DEVICE = 2, + SERVICE = 3, + PROVISIONER = 4, + UNRECOGNIZED = -1 +} + +export function drmCertificate_TypeFromJSON(object: any): DrmCertificate_Type { + switch (object) { + case 0: + case 'ROOT': + return DrmCertificate_Type.ROOT; + case 1: + case 'DEVICE_MODEL': + return DrmCertificate_Type.DEVICE_MODEL; + case 2: + case 'DEVICE': + return DrmCertificate_Type.DEVICE; + case 3: + case 'SERVICE': + return DrmCertificate_Type.SERVICE; + case 4: + case 'PROVISIONER': + return DrmCertificate_Type.PROVISIONER; + case -1: + case 'UNRECOGNIZED': + default: + return DrmCertificate_Type.UNRECOGNIZED; + } +} + +export function drmCertificate_TypeToJSON(object: DrmCertificate_Type): string { + switch (object) { + case DrmCertificate_Type.ROOT: + return 'ROOT'; + case DrmCertificate_Type.DEVICE_MODEL: + return 'DEVICE_MODEL'; + case DrmCertificate_Type.DEVICE: + return 'DEVICE'; + case DrmCertificate_Type.SERVICE: + return 'SERVICE'; + case DrmCertificate_Type.PROVISIONER: + return 'PROVISIONER'; + case DrmCertificate_Type.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +export enum DrmCertificate_ServiceType { + UNKNOWN_SERVICE_TYPE = 0, + LICENSE_SERVER_SDK = 1, + LICENSE_SERVER_PROXY_SDK = 2, + PROVISIONING_SDK = 3, + CAS_PROXY_SDK = 4, + UNRECOGNIZED = -1 +} + +export function drmCertificate_ServiceTypeFromJSON(object: any): DrmCertificate_ServiceType { + switch (object) { + case 0: + case 'UNKNOWN_SERVICE_TYPE': + return DrmCertificate_ServiceType.UNKNOWN_SERVICE_TYPE; + case 1: + case 'LICENSE_SERVER_SDK': + return DrmCertificate_ServiceType.LICENSE_SERVER_SDK; + case 2: + case 'LICENSE_SERVER_PROXY_SDK': + return DrmCertificate_ServiceType.LICENSE_SERVER_PROXY_SDK; + case 3: + case 'PROVISIONING_SDK': + return DrmCertificate_ServiceType.PROVISIONING_SDK; + case 4: + case 'CAS_PROXY_SDK': + return DrmCertificate_ServiceType.CAS_PROXY_SDK; + case -1: + case 'UNRECOGNIZED': + default: + return DrmCertificate_ServiceType.UNRECOGNIZED; + } +} + +export function drmCertificate_ServiceTypeToJSON(object: DrmCertificate_ServiceType): string { + switch (object) { + case DrmCertificate_ServiceType.UNKNOWN_SERVICE_TYPE: + return 'UNKNOWN_SERVICE_TYPE'; + case DrmCertificate_ServiceType.LICENSE_SERVER_SDK: + return 'LICENSE_SERVER_SDK'; + case DrmCertificate_ServiceType.LICENSE_SERVER_PROXY_SDK: + return 'LICENSE_SERVER_PROXY_SDK'; + case DrmCertificate_ServiceType.PROVISIONING_SDK: + return 'PROVISIONING_SDK'; + case DrmCertificate_ServiceType.CAS_PROXY_SDK: + return 'CAS_PROXY_SDK'; + case DrmCertificate_ServiceType.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +export enum DrmCertificate_Algorithm { + UNKNOWN_ALGORITHM = 0, + RSA = 1, + ECC_SECP256R1 = 2, + ECC_SECP384R1 = 3, + ECC_SECP521R1 = 4, + UNRECOGNIZED = -1 +} + +export function drmCertificate_AlgorithmFromJSON(object: any): DrmCertificate_Algorithm { + switch (object) { + case 0: + case 'UNKNOWN_ALGORITHM': + return DrmCertificate_Algorithm.UNKNOWN_ALGORITHM; + case 1: + case 'RSA': + return DrmCertificate_Algorithm.RSA; + case 2: + case 'ECC_SECP256R1': + return DrmCertificate_Algorithm.ECC_SECP256R1; + case 3: + case 'ECC_SECP384R1': + return DrmCertificate_Algorithm.ECC_SECP384R1; + case 4: + case 'ECC_SECP521R1': + return DrmCertificate_Algorithm.ECC_SECP521R1; + case -1: + case 'UNRECOGNIZED': + default: + return DrmCertificate_Algorithm.UNRECOGNIZED; + } +} + +export function drmCertificate_AlgorithmToJSON(object: DrmCertificate_Algorithm): string { + switch (object) { + case DrmCertificate_Algorithm.UNKNOWN_ALGORITHM: + return 'UNKNOWN_ALGORITHM'; + case DrmCertificate_Algorithm.RSA: + return 'RSA'; + case DrmCertificate_Algorithm.ECC_SECP256R1: + return 'ECC_SECP256R1'; + case DrmCertificate_Algorithm.ECC_SECP384R1: + return 'ECC_SECP384R1'; + case DrmCertificate_Algorithm.ECC_SECP521R1: + return 'ECC_SECP521R1'; + case DrmCertificate_Algorithm.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +export interface DrmCertificate_EncryptionKey { + /** Device public key. PKCS#1 ASN.1 DER-encoded. Required. */ + publicKey: Buffer; + /** + * Required. The algorithm field contains the curve used to create the + * |public_key| if algorithm is one of the ECC types. + * The |algorithm| is used for both to determine the if the certificate is + * ECC or RSA. The |algorithm| also specifies the parameters that were used + * to create |public_key| and are used to create an ephemeral session key. + */ + algorithm: DrmCertificate_Algorithm; +} + +/** DrmCertificate signed by a higher (CA) DRM certificate. */ +export interface SignedDrmCertificate { + /** Serialized certificate. Required. */ + drmCertificate: Buffer; + /** + * Signature of certificate. Signed with root or intermediate + * certificate specified below. Required. + */ + signature: Buffer; + /** SignedDrmCertificate used to sign this certificate. */ + signer: SignedDrmCertificate | undefined; + /** Optional field that indicates the hash algorithm used in signature scheme. */ + hashAlgorithm: HashAlgorithmProto; +} + +export interface WidevinePsshData { + /** + * Entitlement or content key IDs. Can onnly present in SINGLE or ENTITLEMENT + * PSSHs. May be repeated to facilitate delivery of multiple keys in a + * single license. Cannot be used in conjunction with content_id or + * group_ids, which are the preferred mechanism. + */ + keyIds: Buffer[]; + /** + * Content identifier which may map to multiple entitlement or content key + * IDs to facilitate the delivery of multiple keys in a single license. + * Cannot be present in conjunction with key_ids, but if used must be in all + * PSSHs. + */ + contentId: Buffer; + /** + * Crypto period index, for media using key rotation. Always corresponds to + * The content key period. This means that if using entitlement licensing + * the ENTITLED_KEY PSSHs will have sequential crypto_period_index's, whereas + * the ENTITELEMENT PSSHs will have gaps in the sequence. Required if doing + * key rotation. + */ + cryptoPeriodIndex: number; + /** + * Protection scheme identifying the encryption algorithm. The protection + * scheme is represented as a uint32 value. The uint32 contains 4 bytes each + * representing a single ascii character in one of the 4CC protection scheme + * values. To be deprecated in favor of signaling from content. + * 'cenc' (AES-CTR) protection_scheme = 0x63656E63, + * 'cbc1' (AES-CBC) protection_scheme = 0x63626331, + * 'cens' (AES-CTR pattern encryption) protection_scheme = 0x63656E73, + * 'cbcs' (AES-CBC pattern encryption) protection_scheme = 0x63626373. + */ + protectionScheme: number; + /** + * Optional. For media using key rotation, this represents the duration + * of each crypto period in seconds. + */ + cryptoPeriodSeconds: number; + /** Type of PSSH. Required if not SINGLE. */ + type: WidevinePsshData_Type; + /** Key sequence for Widevine-managed keys. Optional. */ + keySequence: number; + /** + * Group identifiers for all groups to which the content belongs. This can + * be used to deliver licenses to unlock multiple titles / channels. + * Optional, and may only be present in ENTITLEMENT and ENTITLED_KEY PSSHs, and + * not in conjunction with key_ids. + */ + groupIds: Buffer[]; + /** + * Copy/copies of the content key used to decrypt the media stream in which + * the PSSH box is embedded, each wrapped with a different entitlement key. + * May also contain sub-licenses to support devices with OEMCrypto 13 or + * older. May be repeated if using group entitlement keys. Present only in + * PSSHs of type ENTITLED_KEY. + */ + entitledKeys: WidevinePsshData_EntitledKey[]; + /** + * Video feature identifier, which is used in conjunction with |content_id| + * to determine the set of keys to be returned in the license. Cannot be + * present in conjunction with |key_ids|. + * Current values are "HDR". + */ + videoFeature: string; + /** @deprecated */ + algorithm: WidevinePsshData_Algorithm; + /** + * Content provider name. + * + * @deprecated + */ + provider: string; + /** + * Track type. Acceptable values are SD, HD and AUDIO. Used to + * differentiate content keys used by an asset. + * + * @deprecated + */ + trackType: string; + /** + * The name of a registered policy to be used for this asset. + * + * @deprecated + */ + policy: string; + /** + * Optional protected context for group content. The grouped_license is a + * serialized SignedMessage. + * + * @deprecated + */ + groupedLicense: Buffer; +} + +export enum WidevinePsshData_Type { + /** SINGLE - Single PSSH to be used to retrieve content keys. */ + SINGLE = 0, + /** ENTITLEMENT - Primary PSSH used to retrieve entitlement keys. */ + ENTITLEMENT = 1, + /** ENTITLED_KEY - Secondary PSSH containing entitled key(s). */ + ENTITLED_KEY = 2, + UNRECOGNIZED = -1 +} + +export function widevinePsshData_TypeFromJSON(object: any): WidevinePsshData_Type { + switch (object) { + case 0: + case 'SINGLE': + return WidevinePsshData_Type.SINGLE; + case 1: + case 'ENTITLEMENT': + return WidevinePsshData_Type.ENTITLEMENT; + case 2: + case 'ENTITLED_KEY': + return WidevinePsshData_Type.ENTITLED_KEY; + case -1: + case 'UNRECOGNIZED': + default: + return WidevinePsshData_Type.UNRECOGNIZED; + } +} + +export function widevinePsshData_TypeToJSON(object: WidevinePsshData_Type): string { + switch (object) { + case WidevinePsshData_Type.SINGLE: + return 'SINGLE'; + case WidevinePsshData_Type.ENTITLEMENT: + return 'ENTITLEMENT'; + case WidevinePsshData_Type.ENTITLED_KEY: + return 'ENTITLED_KEY'; + case WidevinePsshData_Type.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +/** ////////////////////////// Deprecated Fields //////////////////////////// */ +export enum WidevinePsshData_Algorithm { + UNENCRYPTED = 0, + AESCTR = 1, + UNRECOGNIZED = -1 +} + +export function widevinePsshData_AlgorithmFromJSON(object: any): WidevinePsshData_Algorithm { + switch (object) { + case 0: + case 'UNENCRYPTED': + return WidevinePsshData_Algorithm.UNENCRYPTED; + case 1: + case 'AESCTR': + return WidevinePsshData_Algorithm.AESCTR; + case -1: + case 'UNRECOGNIZED': + default: + return WidevinePsshData_Algorithm.UNRECOGNIZED; + } +} + +export function widevinePsshData_AlgorithmToJSON(object: WidevinePsshData_Algorithm): string { + switch (object) { + case WidevinePsshData_Algorithm.UNENCRYPTED: + return 'UNENCRYPTED'; + case WidevinePsshData_Algorithm.AESCTR: + return 'AESCTR'; + case WidevinePsshData_Algorithm.UNRECOGNIZED: + default: + return 'UNRECOGNIZED'; + } +} + +export interface WidevinePsshData_EntitledKey { + /** ID of entitlement key used for wrapping |key|. */ + entitlementKeyId: Buffer; + /** ID of the entitled key. */ + keyId: Buffer; + /** Wrapped key. Required. */ + key: Buffer; + /** IV used for wrapping |key|. Required. */ + iv: Buffer; + /** Size of entitlement key used for wrapping |key|. */ + entitlementKeySizeBytes: number; +} + +/** File Hashes for Verified Media Path (VMP) support. */ +export interface FileHashes { + signer: Buffer; + signatures: FileHashes_Signature[]; +} + +export interface FileHashes_Signature { + filename: string; + /** 0 - release, 1 - testing */ + testSigning: boolean; + SHA512Hash: Buffer; + /** 0 for dlls, 1 for exe, this is field 3 in file */ + mainExe: boolean; + signature: Buffer; +} + +function createBaseLicenseIdentification(): LicenseIdentification { + return { + requestId: Buffer.alloc(0), + sessionId: Buffer.alloc(0), + purchaseId: Buffer.alloc(0), + type: 1, + version: 0, + providerSessionToken: Buffer.alloc(0) + }; +} + +export const LicenseIdentification = { + encode(message: LicenseIdentification, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.requestId.length !== 0) { + writer.uint32(10).bytes(message.requestId); + } + if (message.sessionId.length !== 0) { + writer.uint32(18).bytes(message.sessionId); + } + if (message.purchaseId.length !== 0) { + writer.uint32(26).bytes(message.purchaseId); + } + if (message.type !== 1) { + writer.uint32(32).int32(message.type); + } + if (message.version !== 0) { + writer.uint32(40).int32(message.version); + } + if (message.providerSessionToken.length !== 0) { + writer.uint32(50).bytes(message.providerSessionToken); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): LicenseIdentification { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLicenseIdentification(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.requestId = reader.bytes() as Buffer; + break; + case 2: + message.sessionId = reader.bytes() as Buffer; + break; + case 3: + message.purchaseId = reader.bytes() as Buffer; + break; + case 4: + message.type = reader.int32() as any; + break; + case 5: + message.version = reader.int32(); + break; + case 6: + message.providerSessionToken = reader.bytes() as Buffer; + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): LicenseIdentification { + return { + requestId: isSet(object.requestId) ? Buffer.from(bytesFromBase64(object.requestId)) : Buffer.alloc(0), + sessionId: isSet(object.sessionId) ? Buffer.from(bytesFromBase64(object.sessionId)) : Buffer.alloc(0), + purchaseId: isSet(object.purchaseId) ? Buffer.from(bytesFromBase64(object.purchaseId)) : Buffer.alloc(0), + type: isSet(object.type) ? licenseTypeFromJSON(object.type) : 1, + version: isSet(object.version) ? Number(object.version) : 0, + providerSessionToken: isSet(object.providerSessionToken) ? Buffer.from(bytesFromBase64(object.providerSessionToken)) : Buffer.alloc(0) + }; + }, + + toJSON(message: LicenseIdentification): unknown { + const obj: any = {}; + message.requestId !== undefined && (obj.requestId = base64FromBytes(message.requestId !== undefined ? message.requestId : Buffer.alloc(0))); + message.sessionId !== undefined && (obj.sessionId = base64FromBytes(message.sessionId !== undefined ? message.sessionId : Buffer.alloc(0))); + message.purchaseId !== undefined && (obj.purchaseId = base64FromBytes(message.purchaseId !== undefined ? message.purchaseId : Buffer.alloc(0))); + message.type !== undefined && (obj.type = licenseTypeToJSON(message.type)); + message.version !== undefined && (obj.version = Math.round(message.version)); + message.providerSessionToken !== undefined && + (obj.providerSessionToken = base64FromBytes(message.providerSessionToken !== undefined ? message.providerSessionToken : Buffer.alloc(0))); + return obj; + }, + + fromPartial, I>>(object: I): LicenseIdentification { + const message = createBaseLicenseIdentification(); + message.requestId = object.requestId ?? Buffer.alloc(0); + message.sessionId = object.sessionId ?? Buffer.alloc(0); + message.purchaseId = object.purchaseId ?? Buffer.alloc(0); + message.type = object.type ?? 1; + message.version = object.version ?? 0; + message.providerSessionToken = object.providerSessionToken ?? Buffer.alloc(0); + return message; + } +}; + +function createBaseLicense(): License { + return { + id: undefined, + policy: undefined, + key: [], + licenseStartTime: Long.ZERO, + remoteAttestationVerified: false, + providerClientToken: Buffer.alloc(0), + protectionScheme: 0, + srmRequirement: Buffer.alloc(0), + srmUpdate: Buffer.alloc(0), + platformVerificationStatus: 0, + groupIds: [] + }; +} + +export const License = { + encode(message: License, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.id !== undefined) { + LicenseIdentification.encode(message.id, writer.uint32(10).fork()).ldelim(); + } + if (message.policy !== undefined) { + License_Policy.encode(message.policy, writer.uint32(18).fork()).ldelim(); + } + for (const v of message.key) { + License_KeyContainer.encode(v!, writer.uint32(26).fork()).ldelim(); + } + if (!message.licenseStartTime.isZero()) { + writer.uint32(32).int64(message.licenseStartTime); + } + if (message.remoteAttestationVerified === true) { + writer.uint32(40).bool(message.remoteAttestationVerified); + } + if (message.providerClientToken.length !== 0) { + writer.uint32(50).bytes(message.providerClientToken); + } + if (message.protectionScheme !== 0) { + writer.uint32(56).uint32(message.protectionScheme); + } + if (message.srmRequirement.length !== 0) { + writer.uint32(66).bytes(message.srmRequirement); + } + if (message.srmUpdate.length !== 0) { + writer.uint32(74).bytes(message.srmUpdate); + } + if (message.platformVerificationStatus !== 0) { + writer.uint32(80).int32(message.platformVerificationStatus); + } + for (const v of message.groupIds) { + writer.uint32(90).bytes(v!); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): License { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLicense(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = LicenseIdentification.decode(reader, reader.uint32()); + break; + case 2: + message.policy = License_Policy.decode(reader, reader.uint32()); + break; + case 3: + message.key.push(License_KeyContainer.decode(reader, reader.uint32())); + break; + case 4: + message.licenseStartTime = reader.int64() as Long; + break; + case 5: + message.remoteAttestationVerified = reader.bool(); + break; + case 6: + message.providerClientToken = reader.bytes() as Buffer; + break; + case 7: + message.protectionScheme = reader.uint32(); + break; + case 8: + message.srmRequirement = reader.bytes() as Buffer; + break; + case 9: + message.srmUpdate = reader.bytes() as Buffer; + break; + case 10: + message.platformVerificationStatus = reader.int32() as any; + break; + case 11: + message.groupIds.push(reader.bytes() as Buffer); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): License { + return { + id: isSet(object.id) ? LicenseIdentification.fromJSON(object.id) : undefined, + policy: isSet(object.policy) ? License_Policy.fromJSON(object.policy) : undefined, + key: Array.isArray(object?.key) ? object.key.map((e: any) => License_KeyContainer.fromJSON(e)) : [], + licenseStartTime: isSet(object.licenseStartTime) ? Long.fromValue(object.licenseStartTime) : Long.ZERO, + remoteAttestationVerified: isSet(object.remoteAttestationVerified) ? Boolean(object.remoteAttestationVerified) : false, + providerClientToken: isSet(object.providerClientToken) ? Buffer.from(bytesFromBase64(object.providerClientToken)) : Buffer.alloc(0), + protectionScheme: isSet(object.protectionScheme) ? Number(object.protectionScheme) : 0, + srmRequirement: isSet(object.srmRequirement) ? Buffer.from(bytesFromBase64(object.srmRequirement)) : Buffer.alloc(0), + srmUpdate: isSet(object.srmUpdate) ? Buffer.from(bytesFromBase64(object.srmUpdate)) : Buffer.alloc(0), + platformVerificationStatus: isSet(object.platformVerificationStatus) + ? platformVerificationStatusFromJSON(object.platformVerificationStatus) + : 0, + groupIds: Array.isArray(object?.groupIds) ? object.groupIds.map((e: any) => Buffer.from(bytesFromBase64(e))) : [] + }; + }, + + toJSON(message: License): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = message.id ? LicenseIdentification.toJSON(message.id) : undefined); + message.policy !== undefined && (obj.policy = message.policy ? License_Policy.toJSON(message.policy) : undefined); + if (message.key) { + obj.key = message.key.map((e) => (e ? License_KeyContainer.toJSON(e) : undefined)); + } else { + obj.key = []; + } + message.licenseStartTime !== undefined && (obj.licenseStartTime = (message.licenseStartTime || Long.ZERO).toString()); + message.remoteAttestationVerified !== undefined && (obj.remoteAttestationVerified = message.remoteAttestationVerified); + message.providerClientToken !== undefined && + (obj.providerClientToken = base64FromBytes(message.providerClientToken !== undefined ? message.providerClientToken : Buffer.alloc(0))); + message.protectionScheme !== undefined && (obj.protectionScheme = Math.round(message.protectionScheme)); + message.srmRequirement !== undefined && + (obj.srmRequirement = base64FromBytes(message.srmRequirement !== undefined ? message.srmRequirement : Buffer.alloc(0))); + message.srmUpdate !== undefined && (obj.srmUpdate = base64FromBytes(message.srmUpdate !== undefined ? message.srmUpdate : Buffer.alloc(0))); + message.platformVerificationStatus !== undefined && + (obj.platformVerificationStatus = platformVerificationStatusToJSON(message.platformVerificationStatus)); + if (message.groupIds) { + obj.groupIds = message.groupIds.map((e) => base64FromBytes(e !== undefined ? e : Buffer.alloc(0))); + } else { + obj.groupIds = []; + } + return obj; + }, + + fromPartial, I>>(object: I): License { + const message = createBaseLicense(); + message.id = object.id !== undefined && object.id !== null ? LicenseIdentification.fromPartial(object.id) : undefined; + message.policy = object.policy !== undefined && object.policy !== null ? License_Policy.fromPartial(object.policy) : undefined; + message.key = object.key?.map((e) => License_KeyContainer.fromPartial(e)) || []; + message.licenseStartTime = + object.licenseStartTime !== undefined && object.licenseStartTime !== null ? Long.fromValue(object.licenseStartTime) : Long.ZERO; + message.remoteAttestationVerified = object.remoteAttestationVerified ?? false; + message.providerClientToken = object.providerClientToken ?? Buffer.alloc(0); + message.protectionScheme = object.protectionScheme ?? 0; + message.srmRequirement = object.srmRequirement ?? Buffer.alloc(0); + message.srmUpdate = object.srmUpdate ?? Buffer.alloc(0); + message.platformVerificationStatus = object.platformVerificationStatus ?? 0; + message.groupIds = object.groupIds?.map((e) => e) || []; + return message; + } +}; + +function createBaseLicense_Policy(): License_Policy { + return { + canPlay: false, + canPersist: false, + canRenew: false, + rentalDurationSeconds: Long.ZERO, + playbackDurationSeconds: Long.ZERO, + licenseDurationSeconds: Long.ZERO, + renewalRecoveryDurationSeconds: Long.ZERO, + renewalServerUrl: '', + renewalDelaySeconds: Long.ZERO, + renewalRetryIntervalSeconds: Long.ZERO, + renewWithUsage: false, + alwaysIncludeClientId: false, + playStartGracePeriodSeconds: Long.ZERO, + softEnforcePlaybackDuration: false, + softEnforceRentalDuration: false + }; +} + +export const License_Policy = { + encode(message: License_Policy, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.canPlay === true) { + writer.uint32(8).bool(message.canPlay); + } + if (message.canPersist === true) { + writer.uint32(16).bool(message.canPersist); + } + if (message.canRenew === true) { + writer.uint32(24).bool(message.canRenew); + } + if (!message.rentalDurationSeconds.isZero()) { + writer.uint32(32).int64(message.rentalDurationSeconds); + } + if (!message.playbackDurationSeconds.isZero()) { + writer.uint32(40).int64(message.playbackDurationSeconds); + } + if (!message.licenseDurationSeconds.isZero()) { + writer.uint32(48).int64(message.licenseDurationSeconds); + } + if (!message.renewalRecoveryDurationSeconds.isZero()) { + writer.uint32(56).int64(message.renewalRecoveryDurationSeconds); + } + if (message.renewalServerUrl !== '') { + writer.uint32(66).string(message.renewalServerUrl); + } + if (!message.renewalDelaySeconds.isZero()) { + writer.uint32(72).int64(message.renewalDelaySeconds); + } + if (!message.renewalRetryIntervalSeconds.isZero()) { + writer.uint32(80).int64(message.renewalRetryIntervalSeconds); + } + if (message.renewWithUsage === true) { + writer.uint32(88).bool(message.renewWithUsage); + } + if (message.alwaysIncludeClientId === true) { + writer.uint32(96).bool(message.alwaysIncludeClientId); + } + if (!message.playStartGracePeriodSeconds.isZero()) { + writer.uint32(104).int64(message.playStartGracePeriodSeconds); + } + if (message.softEnforcePlaybackDuration === true) { + writer.uint32(112).bool(message.softEnforcePlaybackDuration); + } + if (message.softEnforceRentalDuration === true) { + writer.uint32(120).bool(message.softEnforceRentalDuration); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): License_Policy { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLicense_Policy(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.canPlay = reader.bool(); + break; + case 2: + message.canPersist = reader.bool(); + break; + case 3: + message.canRenew = reader.bool(); + break; + case 4: + message.rentalDurationSeconds = reader.int64() as Long; + break; + case 5: + message.playbackDurationSeconds = reader.int64() as Long; + break; + case 6: + message.licenseDurationSeconds = reader.int64() as Long; + break; + case 7: + message.renewalRecoveryDurationSeconds = reader.int64() as Long; + break; + case 8: + message.renewalServerUrl = reader.string(); + break; + case 9: + message.renewalDelaySeconds = reader.int64() as Long; + break; + case 10: + message.renewalRetryIntervalSeconds = reader.int64() as Long; + break; + case 11: + message.renewWithUsage = reader.bool(); + break; + case 12: + message.alwaysIncludeClientId = reader.bool(); + break; + case 13: + message.playStartGracePeriodSeconds = reader.int64() as Long; + break; + case 14: + message.softEnforcePlaybackDuration = reader.bool(); + break; + case 15: + message.softEnforceRentalDuration = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): License_Policy { + return { + canPlay: isSet(object.canPlay) ? Boolean(object.canPlay) : false, + canPersist: isSet(object.canPersist) ? Boolean(object.canPersist) : false, + canRenew: isSet(object.canRenew) ? Boolean(object.canRenew) : false, + rentalDurationSeconds: isSet(object.rentalDurationSeconds) ? Long.fromValue(object.rentalDurationSeconds) : Long.ZERO, + playbackDurationSeconds: isSet(object.playbackDurationSeconds) ? Long.fromValue(object.playbackDurationSeconds) : Long.ZERO, + licenseDurationSeconds: isSet(object.licenseDurationSeconds) ? Long.fromValue(object.licenseDurationSeconds) : Long.ZERO, + renewalRecoveryDurationSeconds: isSet(object.renewalRecoveryDurationSeconds) + ? Long.fromValue(object.renewalRecoveryDurationSeconds) + : Long.ZERO, + renewalServerUrl: isSet(object.renewalServerUrl) ? String(object.renewalServerUrl) : '', + renewalDelaySeconds: isSet(object.renewalDelaySeconds) ? Long.fromValue(object.renewalDelaySeconds) : Long.ZERO, + renewalRetryIntervalSeconds: isSet(object.renewalRetryIntervalSeconds) ? Long.fromValue(object.renewalRetryIntervalSeconds) : Long.ZERO, + renewWithUsage: isSet(object.renewWithUsage) ? Boolean(object.renewWithUsage) : false, + alwaysIncludeClientId: isSet(object.alwaysIncludeClientId) ? Boolean(object.alwaysIncludeClientId) : false, + playStartGracePeriodSeconds: isSet(object.playStartGracePeriodSeconds) ? Long.fromValue(object.playStartGracePeriodSeconds) : Long.ZERO, + softEnforcePlaybackDuration: isSet(object.softEnforcePlaybackDuration) ? Boolean(object.softEnforcePlaybackDuration) : false, + softEnforceRentalDuration: isSet(object.softEnforceRentalDuration) ? Boolean(object.softEnforceRentalDuration) : false + }; + }, + + toJSON(message: License_Policy): unknown { + const obj: any = {}; + message.canPlay !== undefined && (obj.canPlay = message.canPlay); + message.canPersist !== undefined && (obj.canPersist = message.canPersist); + message.canRenew !== undefined && (obj.canRenew = message.canRenew); + message.rentalDurationSeconds !== undefined && (obj.rentalDurationSeconds = (message.rentalDurationSeconds || Long.ZERO).toString()); + message.playbackDurationSeconds !== undefined && (obj.playbackDurationSeconds = (message.playbackDurationSeconds || Long.ZERO).toString()); + message.licenseDurationSeconds !== undefined && (obj.licenseDurationSeconds = (message.licenseDurationSeconds || Long.ZERO).toString()); + message.renewalRecoveryDurationSeconds !== undefined && + (obj.renewalRecoveryDurationSeconds = (message.renewalRecoveryDurationSeconds || Long.ZERO).toString()); + message.renewalServerUrl !== undefined && (obj.renewalServerUrl = message.renewalServerUrl); + message.renewalDelaySeconds !== undefined && (obj.renewalDelaySeconds = (message.renewalDelaySeconds || Long.ZERO).toString()); + message.renewalRetryIntervalSeconds !== undefined && + (obj.renewalRetryIntervalSeconds = (message.renewalRetryIntervalSeconds || Long.ZERO).toString()); + message.renewWithUsage !== undefined && (obj.renewWithUsage = message.renewWithUsage); + message.alwaysIncludeClientId !== undefined && (obj.alwaysIncludeClientId = message.alwaysIncludeClientId); + message.playStartGracePeriodSeconds !== undefined && + (obj.playStartGracePeriodSeconds = (message.playStartGracePeriodSeconds || Long.ZERO).toString()); + message.softEnforcePlaybackDuration !== undefined && (obj.softEnforcePlaybackDuration = message.softEnforcePlaybackDuration); + message.softEnforceRentalDuration !== undefined && (obj.softEnforceRentalDuration = message.softEnforceRentalDuration); + return obj; + }, + + fromPartial, I>>(object: I): License_Policy { + const message = createBaseLicense_Policy(); + message.canPlay = object.canPlay ?? false; + message.canPersist = object.canPersist ?? false; + message.canRenew = object.canRenew ?? false; + message.rentalDurationSeconds = + object.rentalDurationSeconds !== undefined && object.rentalDurationSeconds !== null ? Long.fromValue(object.rentalDurationSeconds) : Long.ZERO; + message.playbackDurationSeconds = + object.playbackDurationSeconds !== undefined && object.playbackDurationSeconds !== null + ? Long.fromValue(object.playbackDurationSeconds) + : Long.ZERO; + message.licenseDurationSeconds = + object.licenseDurationSeconds !== undefined && object.licenseDurationSeconds !== null + ? Long.fromValue(object.licenseDurationSeconds) + : Long.ZERO; + message.renewalRecoveryDurationSeconds = + object.renewalRecoveryDurationSeconds !== undefined && object.renewalRecoveryDurationSeconds !== null + ? Long.fromValue(object.renewalRecoveryDurationSeconds) + : Long.ZERO; + message.renewalServerUrl = object.renewalServerUrl ?? ''; + message.renewalDelaySeconds = + object.renewalDelaySeconds !== undefined && object.renewalDelaySeconds !== null ? Long.fromValue(object.renewalDelaySeconds) : Long.ZERO; + message.renewalRetryIntervalSeconds = + object.renewalRetryIntervalSeconds !== undefined && object.renewalRetryIntervalSeconds !== null + ? Long.fromValue(object.renewalRetryIntervalSeconds) + : Long.ZERO; + message.renewWithUsage = object.renewWithUsage ?? false; + message.alwaysIncludeClientId = object.alwaysIncludeClientId ?? false; + message.playStartGracePeriodSeconds = + object.playStartGracePeriodSeconds !== undefined && object.playStartGracePeriodSeconds !== null + ? Long.fromValue(object.playStartGracePeriodSeconds) + : Long.ZERO; + message.softEnforcePlaybackDuration = object.softEnforcePlaybackDuration ?? false; + message.softEnforceRentalDuration = object.softEnforceRentalDuration ?? false; + return message; + } +}; + +function createBaseLicense_KeyContainer(): License_KeyContainer { + return { + id: Buffer.alloc(0), + iv: Buffer.alloc(0), + key: Buffer.alloc(0), + type: 1, + level: 1, + requiredProtection: undefined, + requestedProtection: undefined, + keyControl: undefined, + operatorSessionKeyPermissions: undefined, + videoResolutionConstraints: [], + antiRollbackUsageTable: false, + trackLabel: '' + }; +} + +export const License_KeyContainer = { + encode(message: License_KeyContainer, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.id.length !== 0) { + writer.uint32(10).bytes(message.id); + } + if (message.iv.length !== 0) { + writer.uint32(18).bytes(message.iv); + } + if (message.key.length !== 0) { + writer.uint32(26).bytes(message.key); + } + if (message.type !== 1) { + writer.uint32(32).int32(message.type); + } + if (message.level !== 1) { + writer.uint32(40).int32(message.level); + } + if (message.requiredProtection !== undefined) { + License_KeyContainer_OutputProtection.encode(message.requiredProtection, writer.uint32(50).fork()).ldelim(); + } + if (message.requestedProtection !== undefined) { + License_KeyContainer_OutputProtection.encode(message.requestedProtection, writer.uint32(58).fork()).ldelim(); + } + if (message.keyControl !== undefined) { + License_KeyContainer_KeyControl.encode(message.keyControl, writer.uint32(66).fork()).ldelim(); + } + if (message.operatorSessionKeyPermissions !== undefined) { + License_KeyContainer_OperatorSessionKeyPermissions.encode(message.operatorSessionKeyPermissions, writer.uint32(74).fork()).ldelim(); + } + for (const v of message.videoResolutionConstraints) { + License_KeyContainer_VideoResolutionConstraint.encode(v!, writer.uint32(82).fork()).ldelim(); + } + if (message.antiRollbackUsageTable === true) { + writer.uint32(88).bool(message.antiRollbackUsageTable); + } + if (message.trackLabel !== '') { + writer.uint32(98).string(message.trackLabel); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): License_KeyContainer { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLicense_KeyContainer(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.id = reader.bytes() as Buffer; + break; + case 2: + message.iv = reader.bytes() as Buffer; + break; + case 3: + message.key = reader.bytes() as Buffer; + break; + case 4: + message.type = reader.int32() as any; + break; + case 5: + message.level = reader.int32() as any; + break; + case 6: + message.requiredProtection = License_KeyContainer_OutputProtection.decode(reader, reader.uint32()); + break; + case 7: + message.requestedProtection = License_KeyContainer_OutputProtection.decode(reader, reader.uint32()); + break; + case 8: + message.keyControl = License_KeyContainer_KeyControl.decode(reader, reader.uint32()); + break; + case 9: + message.operatorSessionKeyPermissions = License_KeyContainer_OperatorSessionKeyPermissions.decode(reader, reader.uint32()); + break; + case 10: + message.videoResolutionConstraints.push(License_KeyContainer_VideoResolutionConstraint.decode(reader, reader.uint32())); + break; + case 11: + message.antiRollbackUsageTable = reader.bool(); + break; + case 12: + message.trackLabel = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): License_KeyContainer { + return { + id: isSet(object.id) ? Buffer.from(bytesFromBase64(object.id)) : Buffer.alloc(0), + iv: isSet(object.iv) ? Buffer.from(bytesFromBase64(object.iv)) : Buffer.alloc(0), + key: isSet(object.key) ? Buffer.from(bytesFromBase64(object.key)) : Buffer.alloc(0), + type: isSet(object.type) ? license_KeyContainer_KeyTypeFromJSON(object.type) : 1, + level: isSet(object.level) ? license_KeyContainer_SecurityLevelFromJSON(object.level) : 1, + requiredProtection: isSet(object.requiredProtection) ? License_KeyContainer_OutputProtection.fromJSON(object.requiredProtection) : undefined, + requestedProtection: isSet(object.requestedProtection) ? License_KeyContainer_OutputProtection.fromJSON(object.requestedProtection) : undefined, + keyControl: isSet(object.keyControl) ? License_KeyContainer_KeyControl.fromJSON(object.keyControl) : undefined, + operatorSessionKeyPermissions: isSet(object.operatorSessionKeyPermissions) + ? License_KeyContainer_OperatorSessionKeyPermissions.fromJSON(object.operatorSessionKeyPermissions) + : undefined, + videoResolutionConstraints: Array.isArray(object?.videoResolutionConstraints) + ? object.videoResolutionConstraints.map((e: any) => License_KeyContainer_VideoResolutionConstraint.fromJSON(e)) + : [], + antiRollbackUsageTable: isSet(object.antiRollbackUsageTable) ? Boolean(object.antiRollbackUsageTable) : false, + trackLabel: isSet(object.trackLabel) ? String(object.trackLabel) : '' + }; + }, + + toJSON(message: License_KeyContainer): unknown { + const obj: any = {}; + message.id !== undefined && (obj.id = base64FromBytes(message.id !== undefined ? message.id : Buffer.alloc(0))); + message.iv !== undefined && (obj.iv = base64FromBytes(message.iv !== undefined ? message.iv : Buffer.alloc(0))); + message.key !== undefined && (obj.key = base64FromBytes(message.key !== undefined ? message.key : Buffer.alloc(0))); + message.type !== undefined && (obj.type = license_KeyContainer_KeyTypeToJSON(message.type)); + message.level !== undefined && (obj.level = license_KeyContainer_SecurityLevelToJSON(message.level)); + message.requiredProtection !== undefined && + (obj.requiredProtection = message.requiredProtection ? License_KeyContainer_OutputProtection.toJSON(message.requiredProtection) : undefined); + message.requestedProtection !== undefined && + (obj.requestedProtection = message.requestedProtection ? License_KeyContainer_OutputProtection.toJSON(message.requestedProtection) : undefined); + message.keyControl !== undefined && + (obj.keyControl = message.keyControl ? License_KeyContainer_KeyControl.toJSON(message.keyControl) : undefined); + message.operatorSessionKeyPermissions !== undefined && + (obj.operatorSessionKeyPermissions = message.operatorSessionKeyPermissions + ? License_KeyContainer_OperatorSessionKeyPermissions.toJSON(message.operatorSessionKeyPermissions) + : undefined); + if (message.videoResolutionConstraints) { + obj.videoResolutionConstraints = message.videoResolutionConstraints.map((e) => + e ? License_KeyContainer_VideoResolutionConstraint.toJSON(e) : undefined + ); + } else { + obj.videoResolutionConstraints = []; + } + message.antiRollbackUsageTable !== undefined && (obj.antiRollbackUsageTable = message.antiRollbackUsageTable); + message.trackLabel !== undefined && (obj.trackLabel = message.trackLabel); + return obj; + }, + + fromPartial, I>>(object: I): License_KeyContainer { + const message = createBaseLicense_KeyContainer(); + message.id = object.id ?? Buffer.alloc(0); + message.iv = object.iv ?? Buffer.alloc(0); + message.key = object.key ?? Buffer.alloc(0); + message.type = object.type ?? 1; + message.level = object.level ?? 1; + message.requiredProtection = + object.requiredProtection !== undefined && object.requiredProtection !== null + ? License_KeyContainer_OutputProtection.fromPartial(object.requiredProtection) + : undefined; + message.requestedProtection = + object.requestedProtection !== undefined && object.requestedProtection !== null + ? License_KeyContainer_OutputProtection.fromPartial(object.requestedProtection) + : undefined; + message.keyControl = + object.keyControl !== undefined && object.keyControl !== null ? License_KeyContainer_KeyControl.fromPartial(object.keyControl) : undefined; + message.operatorSessionKeyPermissions = + object.operatorSessionKeyPermissions !== undefined && object.operatorSessionKeyPermissions !== null + ? License_KeyContainer_OperatorSessionKeyPermissions.fromPartial(object.operatorSessionKeyPermissions) + : undefined; + message.videoResolutionConstraints = + object.videoResolutionConstraints?.map((e) => License_KeyContainer_VideoResolutionConstraint.fromPartial(e)) || []; + message.antiRollbackUsageTable = object.antiRollbackUsageTable ?? false; + message.trackLabel = object.trackLabel ?? ''; + return message; + } +}; + +function createBaseLicense_KeyContainer_KeyControl(): License_KeyContainer_KeyControl { + return { keyControlBlock: Buffer.alloc(0), iv: Buffer.alloc(0) }; +} + +export const License_KeyContainer_KeyControl = { + encode(message: License_KeyContainer_KeyControl, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.keyControlBlock.length !== 0) { + writer.uint32(10).bytes(message.keyControlBlock); + } + if (message.iv.length !== 0) { + writer.uint32(18).bytes(message.iv); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): License_KeyContainer_KeyControl { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLicense_KeyContainer_KeyControl(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.keyControlBlock = reader.bytes() as Buffer; + break; + case 2: + message.iv = reader.bytes() as Buffer; + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): License_KeyContainer_KeyControl { + return { + keyControlBlock: isSet(object.keyControlBlock) ? Buffer.from(bytesFromBase64(object.keyControlBlock)) : Buffer.alloc(0), + iv: isSet(object.iv) ? Buffer.from(bytesFromBase64(object.iv)) : Buffer.alloc(0) + }; + }, + + toJSON(message: License_KeyContainer_KeyControl): unknown { + const obj: any = {}; + message.keyControlBlock !== undefined && + (obj.keyControlBlock = base64FromBytes(message.keyControlBlock !== undefined ? message.keyControlBlock : Buffer.alloc(0))); + message.iv !== undefined && (obj.iv = base64FromBytes(message.iv !== undefined ? message.iv : Buffer.alloc(0))); + return obj; + }, + + fromPartial, I>>(object: I): License_KeyContainer_KeyControl { + const message = createBaseLicense_KeyContainer_KeyControl(); + message.keyControlBlock = object.keyControlBlock ?? Buffer.alloc(0); + message.iv = object.iv ?? Buffer.alloc(0); + return message; + } +}; + +function createBaseLicense_KeyContainer_OutputProtection(): License_KeyContainer_OutputProtection { + return { hdcp: 0, cgmsFlags: 0, hdcpSrmRule: 0, disableAnalogOutput: false, disableDigitalOutput: false }; +} + +export const License_KeyContainer_OutputProtection = { + encode(message: License_KeyContainer_OutputProtection, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.hdcp !== 0) { + writer.uint32(8).int32(message.hdcp); + } + if (message.cgmsFlags !== 0) { + writer.uint32(16).int32(message.cgmsFlags); + } + if (message.hdcpSrmRule !== 0) { + writer.uint32(24).int32(message.hdcpSrmRule); + } + if (message.disableAnalogOutput === true) { + writer.uint32(32).bool(message.disableAnalogOutput); + } + if (message.disableDigitalOutput === true) { + writer.uint32(40).bool(message.disableDigitalOutput); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): License_KeyContainer_OutputProtection { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLicense_KeyContainer_OutputProtection(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.hdcp = reader.int32() as any; + break; + case 2: + message.cgmsFlags = reader.int32() as any; + break; + case 3: + message.hdcpSrmRule = reader.int32() as any; + break; + case 4: + message.disableAnalogOutput = reader.bool(); + break; + case 5: + message.disableDigitalOutput = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): License_KeyContainer_OutputProtection { + return { + hdcp: isSet(object.hdcp) ? license_KeyContainer_OutputProtection_HDCPFromJSON(object.hdcp) : 0, + cgmsFlags: isSet(object.cgmsFlags) ? license_KeyContainer_OutputProtection_CGMSFromJSON(object.cgmsFlags) : 0, + hdcpSrmRule: isSet(object.hdcpSrmRule) ? license_KeyContainer_OutputProtection_HdcpSrmRuleFromJSON(object.hdcpSrmRule) : 0, + disableAnalogOutput: isSet(object.disableAnalogOutput) ? Boolean(object.disableAnalogOutput) : false, + disableDigitalOutput: isSet(object.disableDigitalOutput) ? Boolean(object.disableDigitalOutput) : false + }; + }, + + toJSON(message: License_KeyContainer_OutputProtection): unknown { + const obj: any = {}; + message.hdcp !== undefined && (obj.hdcp = license_KeyContainer_OutputProtection_HDCPToJSON(message.hdcp)); + message.cgmsFlags !== undefined && (obj.cgmsFlags = license_KeyContainer_OutputProtection_CGMSToJSON(message.cgmsFlags)); + message.hdcpSrmRule !== undefined && (obj.hdcpSrmRule = license_KeyContainer_OutputProtection_HdcpSrmRuleToJSON(message.hdcpSrmRule)); + message.disableAnalogOutput !== undefined && (obj.disableAnalogOutput = message.disableAnalogOutput); + message.disableDigitalOutput !== undefined && (obj.disableDigitalOutput = message.disableDigitalOutput); + return obj; + }, + + fromPartial, I>>(object: I): License_KeyContainer_OutputProtection { + const message = createBaseLicense_KeyContainer_OutputProtection(); + message.hdcp = object.hdcp ?? 0; + message.cgmsFlags = object.cgmsFlags ?? 0; + message.hdcpSrmRule = object.hdcpSrmRule ?? 0; + message.disableAnalogOutput = object.disableAnalogOutput ?? false; + message.disableDigitalOutput = object.disableDigitalOutput ?? false; + return message; + } +}; + +function createBaseLicense_KeyContainer_VideoResolutionConstraint(): License_KeyContainer_VideoResolutionConstraint { + return { minResolutionPixels: 0, maxResolutionPixels: 0, requiredProtection: undefined }; +} + +export const License_KeyContainer_VideoResolutionConstraint = { + encode(message: License_KeyContainer_VideoResolutionConstraint, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.minResolutionPixels !== 0) { + writer.uint32(8).uint32(message.minResolutionPixels); + } + if (message.maxResolutionPixels !== 0) { + writer.uint32(16).uint32(message.maxResolutionPixels); + } + if (message.requiredProtection !== undefined) { + License_KeyContainer_OutputProtection.encode(message.requiredProtection, writer.uint32(26).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): License_KeyContainer_VideoResolutionConstraint { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLicense_KeyContainer_VideoResolutionConstraint(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.minResolutionPixels = reader.uint32(); + break; + case 2: + message.maxResolutionPixels = reader.uint32(); + break; + case 3: + message.requiredProtection = License_KeyContainer_OutputProtection.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): License_KeyContainer_VideoResolutionConstraint { + return { + minResolutionPixels: isSet(object.minResolutionPixels) ? Number(object.minResolutionPixels) : 0, + maxResolutionPixels: isSet(object.maxResolutionPixels) ? Number(object.maxResolutionPixels) : 0, + requiredProtection: isSet(object.requiredProtection) ? License_KeyContainer_OutputProtection.fromJSON(object.requiredProtection) : undefined + }; + }, + + toJSON(message: License_KeyContainer_VideoResolutionConstraint): unknown { + const obj: any = {}; + message.minResolutionPixels !== undefined && (obj.minResolutionPixels = Math.round(message.minResolutionPixels)); + message.maxResolutionPixels !== undefined && (obj.maxResolutionPixels = Math.round(message.maxResolutionPixels)); + message.requiredProtection !== undefined && + (obj.requiredProtection = message.requiredProtection ? License_KeyContainer_OutputProtection.toJSON(message.requiredProtection) : undefined); + return obj; + }, + + fromPartial, I>>( + object: I + ): License_KeyContainer_VideoResolutionConstraint { + const message = createBaseLicense_KeyContainer_VideoResolutionConstraint(); + message.minResolutionPixels = object.minResolutionPixels ?? 0; + message.maxResolutionPixels = object.maxResolutionPixels ?? 0; + message.requiredProtection = + object.requiredProtection !== undefined && object.requiredProtection !== null + ? License_KeyContainer_OutputProtection.fromPartial(object.requiredProtection) + : undefined; + return message; + } +}; + +function createBaseLicense_KeyContainer_OperatorSessionKeyPermissions(): License_KeyContainer_OperatorSessionKeyPermissions { + return { allowEncrypt: false, allowDecrypt: false, allowSign: false, allowSignatureVerify: false }; +} + +export const License_KeyContainer_OperatorSessionKeyPermissions = { + encode(message: License_KeyContainer_OperatorSessionKeyPermissions, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.allowEncrypt === true) { + writer.uint32(8).bool(message.allowEncrypt); + } + if (message.allowDecrypt === true) { + writer.uint32(16).bool(message.allowDecrypt); + } + if (message.allowSign === true) { + writer.uint32(24).bool(message.allowSign); + } + if (message.allowSignatureVerify === true) { + writer.uint32(32).bool(message.allowSignatureVerify); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): License_KeyContainer_OperatorSessionKeyPermissions { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLicense_KeyContainer_OperatorSessionKeyPermissions(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.allowEncrypt = reader.bool(); + break; + case 2: + message.allowDecrypt = reader.bool(); + break; + case 3: + message.allowSign = reader.bool(); + break; + case 4: + message.allowSignatureVerify = reader.bool(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): License_KeyContainer_OperatorSessionKeyPermissions { + return { + allowEncrypt: isSet(object.allowEncrypt) ? Boolean(object.allowEncrypt) : false, + allowDecrypt: isSet(object.allowDecrypt) ? Boolean(object.allowDecrypt) : false, + allowSign: isSet(object.allowSign) ? Boolean(object.allowSign) : false, + allowSignatureVerify: isSet(object.allowSignatureVerify) ? Boolean(object.allowSignatureVerify) : false + }; + }, + + toJSON(message: License_KeyContainer_OperatorSessionKeyPermissions): unknown { + const obj: any = {}; + message.allowEncrypt !== undefined && (obj.allowEncrypt = message.allowEncrypt); + message.allowDecrypt !== undefined && (obj.allowDecrypt = message.allowDecrypt); + message.allowSign !== undefined && (obj.allowSign = message.allowSign); + message.allowSignatureVerify !== undefined && (obj.allowSignatureVerify = message.allowSignatureVerify); + return obj; + }, + + fromPartial, I>>( + object: I + ): License_KeyContainer_OperatorSessionKeyPermissions { + const message = createBaseLicense_KeyContainer_OperatorSessionKeyPermissions(); + message.allowEncrypt = object.allowEncrypt ?? false; + message.allowDecrypt = object.allowDecrypt ?? false; + message.allowSign = object.allowSign ?? false; + message.allowSignatureVerify = object.allowSignatureVerify ?? false; + return message; + } +}; + +function createBaseLicenseRequest(): LicenseRequest { + return { + clientId: undefined, + contentId: undefined, + type: 1, + requestTime: Long.ZERO, + keyControlNonceDeprecated: Buffer.alloc(0), + protocolVersion: 20, + keyControlNonce: 0, + encryptedClientId: undefined + }; +} + +export const LicenseRequest = { + encode(message: LicenseRequest, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.clientId !== undefined) { + ClientIdentification.encode(message.clientId, writer.uint32(10).fork()).ldelim(); + } + if (message.contentId !== undefined) { + LicenseRequest_ContentIdentification.encode(message.contentId, writer.uint32(18).fork()).ldelim(); + } + if (message.type !== 1) { + writer.uint32(24).int32(message.type); + } + if (!message.requestTime.isZero()) { + writer.uint32(32).int64(message.requestTime); + } + if (message.keyControlNonceDeprecated.length !== 0) { + writer.uint32(42).bytes(message.keyControlNonceDeprecated); + } + if (message.protocolVersion !== 20) { + writer.uint32(48).int32(message.protocolVersion); + } + if (message.keyControlNonce !== 0) { + writer.uint32(56).uint32(message.keyControlNonce); + } + if (message.encryptedClientId !== undefined) { + EncryptedClientIdentification.encode(message.encryptedClientId, writer.uint32(66).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): LicenseRequest { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLicenseRequest(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.clientId = ClientIdentification.decode(reader, reader.uint32()); + break; + case 2: + message.contentId = LicenseRequest_ContentIdentification.decode(reader, reader.uint32()); + break; + case 3: + message.type = reader.int32() as any; + break; + case 4: + message.requestTime = reader.int64() as Long; + break; + case 5: + message.keyControlNonceDeprecated = reader.bytes() as Buffer; + break; + case 6: + message.protocolVersion = reader.int32() as any; + break; + case 7: + message.keyControlNonce = reader.uint32(); + break; + case 8: + message.encryptedClientId = EncryptedClientIdentification.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): LicenseRequest { + return { + clientId: isSet(object.clientId) ? ClientIdentification.fromJSON(object.clientId) : undefined, + contentId: isSet(object.contentId) ? LicenseRequest_ContentIdentification.fromJSON(object.contentId) : undefined, + type: isSet(object.type) ? licenseRequest_RequestTypeFromJSON(object.type) : 1, + requestTime: isSet(object.requestTime) ? Long.fromValue(object.requestTime) : Long.ZERO, + keyControlNonceDeprecated: isSet(object.keyControlNonceDeprecated) + ? Buffer.from(bytesFromBase64(object.keyControlNonceDeprecated)) + : Buffer.alloc(0), + protocolVersion: isSet(object.protocolVersion) ? protocolVersionFromJSON(object.protocolVersion) : 20, + keyControlNonce: isSet(object.keyControlNonce) ? Number(object.keyControlNonce) : 0, + encryptedClientId: isSet(object.encryptedClientId) ? EncryptedClientIdentification.fromJSON(object.encryptedClientId) : undefined + }; + }, + + toJSON(message: LicenseRequest): unknown { + const obj: any = {}; + message.clientId !== undefined && (obj.clientId = message.clientId ? ClientIdentification.toJSON(message.clientId) : undefined); + message.contentId !== undefined && + (obj.contentId = message.contentId ? LicenseRequest_ContentIdentification.toJSON(message.contentId) : undefined); + message.type !== undefined && (obj.type = licenseRequest_RequestTypeToJSON(message.type)); + message.requestTime !== undefined && (obj.requestTime = (message.requestTime || Long.ZERO).toString()); + message.keyControlNonceDeprecated !== undefined && + (obj.keyControlNonceDeprecated = base64FromBytes( + message.keyControlNonceDeprecated !== undefined ? message.keyControlNonceDeprecated : Buffer.alloc(0) + )); + message.protocolVersion !== undefined && (obj.protocolVersion = protocolVersionToJSON(message.protocolVersion)); + message.keyControlNonce !== undefined && (obj.keyControlNonce = Math.round(message.keyControlNonce)); + message.encryptedClientId !== undefined && + (obj.encryptedClientId = message.encryptedClientId ? EncryptedClientIdentification.toJSON(message.encryptedClientId) : undefined); + return obj; + }, + + fromPartial, I>>(object: I): LicenseRequest { + const message = createBaseLicenseRequest(); + message.clientId = object.clientId !== undefined && object.clientId !== null ? ClientIdentification.fromPartial(object.clientId) : undefined; + message.contentId = + object.contentId !== undefined && object.contentId !== null ? LicenseRequest_ContentIdentification.fromPartial(object.contentId) : undefined; + message.type = object.type ?? 1; + message.requestTime = object.requestTime !== undefined && object.requestTime !== null ? Long.fromValue(object.requestTime) : Long.ZERO; + message.keyControlNonceDeprecated = object.keyControlNonceDeprecated ?? Buffer.alloc(0); + message.protocolVersion = object.protocolVersion ?? 20; + message.keyControlNonce = object.keyControlNonce ?? 0; + message.encryptedClientId = + object.encryptedClientId !== undefined && object.encryptedClientId !== null + ? EncryptedClientIdentification.fromPartial(object.encryptedClientId) + : undefined; + return message; + } +}; + +function createBaseLicenseRequest_ContentIdentification(): LicenseRequest_ContentIdentification { + return { widevinePsshData: undefined, webmKeyId: undefined, existingLicense: undefined, initData: undefined }; +} + +export const LicenseRequest_ContentIdentification = { + encode(message: LicenseRequest_ContentIdentification, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.widevinePsshData !== undefined) { + LicenseRequest_ContentIdentification_WidevinePsshData.encode(message.widevinePsshData, writer.uint32(10).fork()).ldelim(); + } + if (message.webmKeyId !== undefined) { + LicenseRequest_ContentIdentification_WebmKeyId.encode(message.webmKeyId, writer.uint32(18).fork()).ldelim(); + } + if (message.existingLicense !== undefined) { + LicenseRequest_ContentIdentification_ExistingLicense.encode(message.existingLicense, writer.uint32(26).fork()).ldelim(); + } + if (message.initData !== undefined) { + LicenseRequest_ContentIdentification_InitData.encode(message.initData, writer.uint32(34).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): LicenseRequest_ContentIdentification { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLicenseRequest_ContentIdentification(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.widevinePsshData = LicenseRequest_ContentIdentification_WidevinePsshData.decode(reader, reader.uint32()); + break; + case 2: + message.webmKeyId = LicenseRequest_ContentIdentification_WebmKeyId.decode(reader, reader.uint32()); + break; + case 3: + message.existingLicense = LicenseRequest_ContentIdentification_ExistingLicense.decode(reader, reader.uint32()); + break; + case 4: + message.initData = LicenseRequest_ContentIdentification_InitData.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): LicenseRequest_ContentIdentification { + return { + widevinePsshData: isSet(object.widevinePsshData) + ? LicenseRequest_ContentIdentification_WidevinePsshData.fromJSON(object.widevinePsshData) + : undefined, + webmKeyId: isSet(object.webmKeyId) ? LicenseRequest_ContentIdentification_WebmKeyId.fromJSON(object.webmKeyId) : undefined, + existingLicense: isSet(object.existingLicense) + ? LicenseRequest_ContentIdentification_ExistingLicense.fromJSON(object.existingLicense) + : undefined, + initData: isSet(object.initData) ? LicenseRequest_ContentIdentification_InitData.fromJSON(object.initData) : undefined + }; + }, + + toJSON(message: LicenseRequest_ContentIdentification): unknown { + const obj: any = {}; + message.widevinePsshData !== undefined && + (obj.widevinePsshData = message.widevinePsshData + ? LicenseRequest_ContentIdentification_WidevinePsshData.toJSON(message.widevinePsshData) + : undefined); + message.webmKeyId !== undefined && + (obj.webmKeyId = message.webmKeyId ? LicenseRequest_ContentIdentification_WebmKeyId.toJSON(message.webmKeyId) : undefined); + message.existingLicense !== undefined && + (obj.existingLicense = message.existingLicense + ? LicenseRequest_ContentIdentification_ExistingLicense.toJSON(message.existingLicense) + : undefined); + message.initData !== undefined && + (obj.initData = message.initData ? LicenseRequest_ContentIdentification_InitData.toJSON(message.initData) : undefined); + return obj; + }, + + fromPartial, I>>(object: I): LicenseRequest_ContentIdentification { + const message = createBaseLicenseRequest_ContentIdentification(); + message.widevinePsshData = + object.widevinePsshData !== undefined && object.widevinePsshData !== null + ? LicenseRequest_ContentIdentification_WidevinePsshData.fromPartial(object.widevinePsshData) + : undefined; + message.webmKeyId = + object.webmKeyId !== undefined && object.webmKeyId !== null + ? LicenseRequest_ContentIdentification_WebmKeyId.fromPartial(object.webmKeyId) + : undefined; + message.existingLicense = + object.existingLicense !== undefined && object.existingLicense !== null + ? LicenseRequest_ContentIdentification_ExistingLicense.fromPartial(object.existingLicense) + : undefined; + message.initData = + object.initData !== undefined && object.initData !== null + ? LicenseRequest_ContentIdentification_InitData.fromPartial(object.initData) + : undefined; + return message; + } +}; + +function createBaseLicenseRequest_ContentIdentification_WidevinePsshData(): LicenseRequest_ContentIdentification_WidevinePsshData { + return { psshData: [], licenseType: 1, requestId: Buffer.alloc(0) }; +} + +export const LicenseRequest_ContentIdentification_WidevinePsshData = { + encode(message: LicenseRequest_ContentIdentification_WidevinePsshData, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + for (const v of message.psshData) { + writer.uint32(10).bytes(v!); + } + if (message.licenseType !== 1) { + writer.uint32(16).int32(message.licenseType); + } + if (message.requestId.length !== 0) { + writer.uint32(26).bytes(message.requestId); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): LicenseRequest_ContentIdentification_WidevinePsshData { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLicenseRequest_ContentIdentification_WidevinePsshData(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.psshData.push(reader.bytes() as Buffer); + break; + case 2: + message.licenseType = reader.int32() as any; + break; + case 3: + message.requestId = reader.bytes() as Buffer; + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): LicenseRequest_ContentIdentification_WidevinePsshData { + return { + psshData: Array.isArray(object?.psshData) ? object.psshData.map((e: any) => Buffer.from(bytesFromBase64(e))) : [], + licenseType: isSet(object.licenseType) ? licenseTypeFromJSON(object.licenseType) : 1, + requestId: isSet(object.requestId) ? Buffer.from(bytesFromBase64(object.requestId)) : Buffer.alloc(0) + }; + }, + + toJSON(message: LicenseRequest_ContentIdentification_WidevinePsshData): unknown { + const obj: any = {}; + if (message.psshData) { + obj.psshData = message.psshData.map((e) => base64FromBytes(e !== undefined ? e : Buffer.alloc(0))); + } else { + obj.psshData = []; + } + message.licenseType !== undefined && (obj.licenseType = licenseTypeToJSON(message.licenseType)); + message.requestId !== undefined && (obj.requestId = base64FromBytes(message.requestId !== undefined ? message.requestId : Buffer.alloc(0))); + return obj; + }, + + fromPartial, I>>( + object: I + ): LicenseRequest_ContentIdentification_WidevinePsshData { + const message = createBaseLicenseRequest_ContentIdentification_WidevinePsshData(); + message.psshData = object.psshData?.map((e) => e) || []; + message.licenseType = object.licenseType ?? 1; + message.requestId = object.requestId ?? Buffer.alloc(0); + return message; + } +}; + +function createBaseLicenseRequest_ContentIdentification_WebmKeyId(): LicenseRequest_ContentIdentification_WebmKeyId { + return { header: Buffer.alloc(0), licenseType: 1, requestId: Buffer.alloc(0) }; +} + +export const LicenseRequest_ContentIdentification_WebmKeyId = { + encode(message: LicenseRequest_ContentIdentification_WebmKeyId, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.header.length !== 0) { + writer.uint32(10).bytes(message.header); + } + if (message.licenseType !== 1) { + writer.uint32(16).int32(message.licenseType); + } + if (message.requestId.length !== 0) { + writer.uint32(26).bytes(message.requestId); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): LicenseRequest_ContentIdentification_WebmKeyId { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLicenseRequest_ContentIdentification_WebmKeyId(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.header = reader.bytes() as Buffer; + break; + case 2: + message.licenseType = reader.int32() as any; + break; + case 3: + message.requestId = reader.bytes() as Buffer; + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): LicenseRequest_ContentIdentification_WebmKeyId { + return { + header: isSet(object.header) ? Buffer.from(bytesFromBase64(object.header)) : Buffer.alloc(0), + licenseType: isSet(object.licenseType) ? licenseTypeFromJSON(object.licenseType) : 1, + requestId: isSet(object.requestId) ? Buffer.from(bytesFromBase64(object.requestId)) : Buffer.alloc(0) + }; + }, + + toJSON(message: LicenseRequest_ContentIdentification_WebmKeyId): unknown { + const obj: any = {}; + message.header !== undefined && (obj.header = base64FromBytes(message.header !== undefined ? message.header : Buffer.alloc(0))); + message.licenseType !== undefined && (obj.licenseType = licenseTypeToJSON(message.licenseType)); + message.requestId !== undefined && (obj.requestId = base64FromBytes(message.requestId !== undefined ? message.requestId : Buffer.alloc(0))); + return obj; + }, + + fromPartial, I>>( + object: I + ): LicenseRequest_ContentIdentification_WebmKeyId { + const message = createBaseLicenseRequest_ContentIdentification_WebmKeyId(); + message.header = object.header ?? Buffer.alloc(0); + message.licenseType = object.licenseType ?? 1; + message.requestId = object.requestId ?? Buffer.alloc(0); + return message; + } +}; + +function createBaseLicenseRequest_ContentIdentification_ExistingLicense(): LicenseRequest_ContentIdentification_ExistingLicense { + return { + licenseId: undefined, + secondsSinceStarted: Long.ZERO, + secondsSinceLastPlayed: Long.ZERO, + sessionUsageTableEntry: Buffer.alloc(0) + }; +} + +export const LicenseRequest_ContentIdentification_ExistingLicense = { + encode(message: LicenseRequest_ContentIdentification_ExistingLicense, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.licenseId !== undefined) { + LicenseIdentification.encode(message.licenseId, writer.uint32(10).fork()).ldelim(); + } + if (!message.secondsSinceStarted.isZero()) { + writer.uint32(16).int64(message.secondsSinceStarted); + } + if (!message.secondsSinceLastPlayed.isZero()) { + writer.uint32(24).int64(message.secondsSinceLastPlayed); + } + if (message.sessionUsageTableEntry.length !== 0) { + writer.uint32(34).bytes(message.sessionUsageTableEntry); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): LicenseRequest_ContentIdentification_ExistingLicense { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLicenseRequest_ContentIdentification_ExistingLicense(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.licenseId = LicenseIdentification.decode(reader, reader.uint32()); + break; + case 2: + message.secondsSinceStarted = reader.int64() as Long; + break; + case 3: + message.secondsSinceLastPlayed = reader.int64() as Long; + break; + case 4: + message.sessionUsageTableEntry = reader.bytes() as Buffer; + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): LicenseRequest_ContentIdentification_ExistingLicense { + return { + licenseId: isSet(object.licenseId) ? LicenseIdentification.fromJSON(object.licenseId) : undefined, + secondsSinceStarted: isSet(object.secondsSinceStarted) ? Long.fromValue(object.secondsSinceStarted) : Long.ZERO, + secondsSinceLastPlayed: isSet(object.secondsSinceLastPlayed) ? Long.fromValue(object.secondsSinceLastPlayed) : Long.ZERO, + sessionUsageTableEntry: isSet(object.sessionUsageTableEntry) ? Buffer.from(bytesFromBase64(object.sessionUsageTableEntry)) : Buffer.alloc(0) + }; + }, + + toJSON(message: LicenseRequest_ContentIdentification_ExistingLicense): unknown { + const obj: any = {}; + message.licenseId !== undefined && (obj.licenseId = message.licenseId ? LicenseIdentification.toJSON(message.licenseId) : undefined); + message.secondsSinceStarted !== undefined && (obj.secondsSinceStarted = (message.secondsSinceStarted || Long.ZERO).toString()); + message.secondsSinceLastPlayed !== undefined && (obj.secondsSinceLastPlayed = (message.secondsSinceLastPlayed || Long.ZERO).toString()); + message.sessionUsageTableEntry !== undefined && + (obj.sessionUsageTableEntry = base64FromBytes(message.sessionUsageTableEntry !== undefined ? message.sessionUsageTableEntry : Buffer.alloc(0))); + return obj; + }, + + fromPartial, I>>( + object: I + ): LicenseRequest_ContentIdentification_ExistingLicense { + const message = createBaseLicenseRequest_ContentIdentification_ExistingLicense(); + message.licenseId = object.licenseId !== undefined && object.licenseId !== null ? LicenseIdentification.fromPartial(object.licenseId) : undefined; + message.secondsSinceStarted = + object.secondsSinceStarted !== undefined && object.secondsSinceStarted !== null ? Long.fromValue(object.secondsSinceStarted) : Long.ZERO; + message.secondsSinceLastPlayed = + object.secondsSinceLastPlayed !== undefined && object.secondsSinceLastPlayed !== null + ? Long.fromValue(object.secondsSinceLastPlayed) + : Long.ZERO; + message.sessionUsageTableEntry = object.sessionUsageTableEntry ?? Buffer.alloc(0); + return message; + } +}; + +function createBaseLicenseRequest_ContentIdentification_InitData(): LicenseRequest_ContentIdentification_InitData { + return { initDataType: 1, initData: Buffer.alloc(0), licenseType: 1, requestId: Buffer.alloc(0) }; +} + +export const LicenseRequest_ContentIdentification_InitData = { + encode(message: LicenseRequest_ContentIdentification_InitData, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.initDataType !== 1) { + writer.uint32(8).int32(message.initDataType); + } + if (message.initData.length !== 0) { + writer.uint32(18).bytes(message.initData); + } + if (message.licenseType !== 1) { + writer.uint32(24).int32(message.licenseType); + } + if (message.requestId.length !== 0) { + writer.uint32(34).bytes(message.requestId); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): LicenseRequest_ContentIdentification_InitData { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseLicenseRequest_ContentIdentification_InitData(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.initDataType = reader.int32() as any; + break; + case 2: + message.initData = reader.bytes() as Buffer; + break; + case 3: + message.licenseType = reader.int32() as any; + break; + case 4: + message.requestId = reader.bytes() as Buffer; + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): LicenseRequest_ContentIdentification_InitData { + return { + initDataType: isSet(object.initDataType) ? licenseRequest_ContentIdentification_InitData_InitDataTypeFromJSON(object.initDataType) : 1, + initData: isSet(object.initData) ? Buffer.from(bytesFromBase64(object.initData)) : Buffer.alloc(0), + licenseType: isSet(object.licenseType) ? licenseTypeFromJSON(object.licenseType) : 1, + requestId: isSet(object.requestId) ? Buffer.from(bytesFromBase64(object.requestId)) : Buffer.alloc(0) + }; + }, + + toJSON(message: LicenseRequest_ContentIdentification_InitData): unknown { + const obj: any = {}; + message.initDataType !== undefined && (obj.initDataType = licenseRequest_ContentIdentification_InitData_InitDataTypeToJSON(message.initDataType)); + message.initData !== undefined && (obj.initData = base64FromBytes(message.initData !== undefined ? message.initData : Buffer.alloc(0))); + message.licenseType !== undefined && (obj.licenseType = licenseTypeToJSON(message.licenseType)); + message.requestId !== undefined && (obj.requestId = base64FromBytes(message.requestId !== undefined ? message.requestId : Buffer.alloc(0))); + return obj; + }, + + fromPartial, I>>( + object: I + ): LicenseRequest_ContentIdentification_InitData { + const message = createBaseLicenseRequest_ContentIdentification_InitData(); + message.initDataType = object.initDataType ?? 1; + message.initData = object.initData ?? Buffer.alloc(0); + message.licenseType = object.licenseType ?? 1; + message.requestId = object.requestId ?? Buffer.alloc(0); + return message; + } +}; + +function createBaseMetricData(): MetricData { + return { stageName: '', metricData: [] }; +} + +export const MetricData = { + encode(message: MetricData, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.stageName !== '') { + writer.uint32(10).string(message.stageName); + } + for (const v of message.metricData) { + MetricData_TypeValue.encode(v!, writer.uint32(18).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): MetricData { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMetricData(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.stageName = reader.string(); + break; + case 2: + message.metricData.push(MetricData_TypeValue.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): MetricData { + return { + stageName: isSet(object.stageName) ? String(object.stageName) : '', + metricData: Array.isArray(object?.metricData) ? object.metricData.map((e: any) => MetricData_TypeValue.fromJSON(e)) : [] + }; + }, + + toJSON(message: MetricData): unknown { + const obj: any = {}; + message.stageName !== undefined && (obj.stageName = message.stageName); + if (message.metricData) { + obj.metricData = message.metricData.map((e) => (e ? MetricData_TypeValue.toJSON(e) : undefined)); + } else { + obj.metricData = []; + } + return obj; + }, + + fromPartial, I>>(object: I): MetricData { + const message = createBaseMetricData(); + message.stageName = object.stageName ?? ''; + message.metricData = object.metricData?.map((e) => MetricData_TypeValue.fromPartial(e)) || []; + return message; + } +}; + +function createBaseMetricData_TypeValue(): MetricData_TypeValue { + return { type: 1, value: Long.ZERO }; +} + +export const MetricData_TypeValue = { + encode(message: MetricData_TypeValue, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.type !== 1) { + writer.uint32(8).int32(message.type); + } + if (!message.value.isZero()) { + writer.uint32(16).int64(message.value); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): MetricData_TypeValue { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseMetricData_TypeValue(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.type = reader.int32() as any; + break; + case 2: + message.value = reader.int64() as Long; + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): MetricData_TypeValue { + return { + type: isSet(object.type) ? metricData_MetricTypeFromJSON(object.type) : 1, + value: isSet(object.value) ? Long.fromValue(object.value) : Long.ZERO + }; + }, + + toJSON(message: MetricData_TypeValue): unknown { + const obj: any = {}; + message.type !== undefined && (obj.type = metricData_MetricTypeToJSON(message.type)); + message.value !== undefined && (obj.value = (message.value || Long.ZERO).toString()); + return obj; + }, + + fromPartial, I>>(object: I): MetricData_TypeValue { + const message = createBaseMetricData_TypeValue(); + message.type = object.type ?? 1; + message.value = object.value !== undefined && object.value !== null ? Long.fromValue(object.value) : Long.ZERO; + return message; + } +}; + +function createBaseVersionInfo(): VersionInfo { + return { licenseSdkVersion: '', licenseServiceVersion: '' }; +} + +export const VersionInfo = { + encode(message: VersionInfo, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.licenseSdkVersion !== '') { + writer.uint32(10).string(message.licenseSdkVersion); + } + if (message.licenseServiceVersion !== '') { + writer.uint32(18).string(message.licenseServiceVersion); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): VersionInfo { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseVersionInfo(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.licenseSdkVersion = reader.string(); + break; + case 2: + message.licenseServiceVersion = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): VersionInfo { + return { + licenseSdkVersion: isSet(object.licenseSdkVersion) ? String(object.licenseSdkVersion) : '', + licenseServiceVersion: isSet(object.licenseServiceVersion) ? String(object.licenseServiceVersion) : '' + }; + }, + + toJSON(message: VersionInfo): unknown { + const obj: any = {}; + message.licenseSdkVersion !== undefined && (obj.licenseSdkVersion = message.licenseSdkVersion); + message.licenseServiceVersion !== undefined && (obj.licenseServiceVersion = message.licenseServiceVersion); + return obj; + }, + + fromPartial, I>>(object: I): VersionInfo { + const message = createBaseVersionInfo(); + message.licenseSdkVersion = object.licenseSdkVersion ?? ''; + message.licenseServiceVersion = object.licenseServiceVersion ?? ''; + return message; + } +}; + +function createBaseSignedMessage(): SignedMessage { + return { + type: 1, + msg: Buffer.alloc(0), + signature: Buffer.alloc(0), + sessionKey: Buffer.alloc(0), + remoteAttestation: Buffer.alloc(0), + metricData: [], + serviceVersionInfo: undefined, + sessionKeyType: 0, + oemcryptoCoreMessage: Buffer.alloc(0) + }; +} + +export const SignedMessage = { + encode(message: SignedMessage, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.type !== 1) { + writer.uint32(8).int32(message.type); + } + if (message.msg.length !== 0) { + writer.uint32(18).bytes(message.msg); + } + if (message.signature.length !== 0) { + writer.uint32(26).bytes(message.signature); + } + if (message.sessionKey.length !== 0) { + writer.uint32(34).bytes(message.sessionKey); + } + if (message.remoteAttestation.length !== 0) { + writer.uint32(42).bytes(message.remoteAttestation); + } + for (const v of message.metricData) { + MetricData.encode(v!, writer.uint32(50).fork()).ldelim(); + } + if (message.serviceVersionInfo !== undefined) { + VersionInfo.encode(message.serviceVersionInfo, writer.uint32(58).fork()).ldelim(); + } + if (message.sessionKeyType !== 0) { + writer.uint32(64).int32(message.sessionKeyType); + } + if (message.oemcryptoCoreMessage.length !== 0) { + writer.uint32(74).bytes(message.oemcryptoCoreMessage); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): SignedMessage { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSignedMessage(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.type = reader.int32() as any; + break; + case 2: + message.msg = reader.bytes() as Buffer; + break; + case 3: + message.signature = reader.bytes() as Buffer; + break; + case 4: + message.sessionKey = reader.bytes() as Buffer; + break; + case 5: + message.remoteAttestation = reader.bytes() as Buffer; + break; + case 6: + message.metricData.push(MetricData.decode(reader, reader.uint32())); + break; + case 7: + message.serviceVersionInfo = VersionInfo.decode(reader, reader.uint32()); + break; + case 8: + message.sessionKeyType = reader.int32() as any; + break; + case 9: + message.oemcryptoCoreMessage = reader.bytes() as Buffer; + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): SignedMessage { + return { + type: isSet(object.type) ? signedMessage_MessageTypeFromJSON(object.type) : 1, + msg: isSet(object.msg) ? Buffer.from(bytesFromBase64(object.msg)) : Buffer.alloc(0), + signature: isSet(object.signature) ? Buffer.from(bytesFromBase64(object.signature)) : Buffer.alloc(0), + sessionKey: isSet(object.sessionKey) ? Buffer.from(bytesFromBase64(object.sessionKey)) : Buffer.alloc(0), + remoteAttestation: isSet(object.remoteAttestation) ? Buffer.from(bytesFromBase64(object.remoteAttestation)) : Buffer.alloc(0), + metricData: Array.isArray(object?.metricData) ? object.metricData.map((e: any) => MetricData.fromJSON(e)) : [], + serviceVersionInfo: isSet(object.serviceVersionInfo) ? VersionInfo.fromJSON(object.serviceVersionInfo) : undefined, + sessionKeyType: isSet(object.sessionKeyType) ? signedMessage_SessionKeyTypeFromJSON(object.sessionKeyType) : 0, + oemcryptoCoreMessage: isSet(object.oemcryptoCoreMessage) ? Buffer.from(bytesFromBase64(object.oemcryptoCoreMessage)) : Buffer.alloc(0) + }; + }, + + toJSON(message: SignedMessage): unknown { + const obj: any = {}; + message.type !== undefined && (obj.type = signedMessage_MessageTypeToJSON(message.type)); + message.msg !== undefined && (obj.msg = base64FromBytes(message.msg !== undefined ? message.msg : Buffer.alloc(0))); + message.signature !== undefined && (obj.signature = base64FromBytes(message.signature !== undefined ? message.signature : Buffer.alloc(0))); + message.sessionKey !== undefined && (obj.sessionKey = base64FromBytes(message.sessionKey !== undefined ? message.sessionKey : Buffer.alloc(0))); + message.remoteAttestation !== undefined && + (obj.remoteAttestation = base64FromBytes(message.remoteAttestation !== undefined ? message.remoteAttestation : Buffer.alloc(0))); + if (message.metricData) { + obj.metricData = message.metricData.map((e) => (e ? MetricData.toJSON(e) : undefined)); + } else { + obj.metricData = []; + } + message.serviceVersionInfo !== undefined && + (obj.serviceVersionInfo = message.serviceVersionInfo ? VersionInfo.toJSON(message.serviceVersionInfo) : undefined); + message.sessionKeyType !== undefined && (obj.sessionKeyType = signedMessage_SessionKeyTypeToJSON(message.sessionKeyType)); + message.oemcryptoCoreMessage !== undefined && + (obj.oemcryptoCoreMessage = base64FromBytes(message.oemcryptoCoreMessage !== undefined ? message.oemcryptoCoreMessage : Buffer.alloc(0))); + return obj; + }, + + fromPartial, I>>(object: I): SignedMessage { + const message = createBaseSignedMessage(); + message.type = object.type ?? 1; + message.msg = object.msg ?? Buffer.alloc(0); + message.signature = object.signature ?? Buffer.alloc(0); + message.sessionKey = object.sessionKey ?? Buffer.alloc(0); + message.remoteAttestation = object.remoteAttestation ?? Buffer.alloc(0); + message.metricData = object.metricData?.map((e) => MetricData.fromPartial(e)) || []; + message.serviceVersionInfo = + object.serviceVersionInfo !== undefined && object.serviceVersionInfo !== null ? VersionInfo.fromPartial(object.serviceVersionInfo) : undefined; + message.sessionKeyType = object.sessionKeyType ?? 0; + message.oemcryptoCoreMessage = object.oemcryptoCoreMessage ?? Buffer.alloc(0); + return message; + } +}; + +function createBaseClientIdentification(): ClientIdentification { + return { + type: 0, + token: Buffer.alloc(0), + clientInfo: [], + providerClientToken: Buffer.alloc(0), + licenseCounter: 0, + clientCapabilities: undefined, + vmpData: Buffer.alloc(0), + deviceCredentials: [] + }; +} + +export const ClientIdentification = { + encode(message: ClientIdentification, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.type !== 0) { + writer.uint32(8).int32(message.type); + } + if (message.token.length !== 0) { + writer.uint32(18).bytes(message.token); + } + for (const v of message.clientInfo) { + ClientIdentification_NameValue.encode(v!, writer.uint32(26).fork()).ldelim(); + } + if (message.providerClientToken.length !== 0) { + writer.uint32(34).bytes(message.providerClientToken); + } + if (message.licenseCounter !== 0) { + writer.uint32(40).uint32(message.licenseCounter); + } + if (message.clientCapabilities !== undefined) { + ClientIdentification_ClientCapabilities.encode(message.clientCapabilities, writer.uint32(50).fork()).ldelim(); + } + if (message.vmpData.length !== 0) { + writer.uint32(58).bytes(message.vmpData); + } + for (const v of message.deviceCredentials) { + ClientIdentification_ClientCredentials.encode(v!, writer.uint32(66).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): ClientIdentification { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseClientIdentification(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.type = reader.int32() as any; + break; + case 2: + message.token = reader.bytes() as Buffer; + break; + case 3: + message.clientInfo.push(ClientIdentification_NameValue.decode(reader, reader.uint32())); + break; + case 4: + message.providerClientToken = reader.bytes() as Buffer; + break; + case 5: + message.licenseCounter = reader.uint32(); + break; + case 6: + message.clientCapabilities = ClientIdentification_ClientCapabilities.decode(reader, reader.uint32()); + break; + case 7: + message.vmpData = reader.bytes() as Buffer; + break; + case 8: + message.deviceCredentials.push(ClientIdentification_ClientCredentials.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): ClientIdentification { + return { + type: isSet(object.type) ? clientIdentification_TokenTypeFromJSON(object.type) : 0, + token: isSet(object.token) ? Buffer.from(bytesFromBase64(object.token)) : Buffer.alloc(0), + clientInfo: Array.isArray(object?.clientInfo) ? object.clientInfo.map((e: any) => ClientIdentification_NameValue.fromJSON(e)) : [], + providerClientToken: isSet(object.providerClientToken) ? Buffer.from(bytesFromBase64(object.providerClientToken)) : Buffer.alloc(0), + licenseCounter: isSet(object.licenseCounter) ? Number(object.licenseCounter) : 0, + clientCapabilities: isSet(object.clientCapabilities) ? ClientIdentification_ClientCapabilities.fromJSON(object.clientCapabilities) : undefined, + vmpData: isSet(object.vmpData) ? Buffer.from(bytesFromBase64(object.vmpData)) : Buffer.alloc(0), + deviceCredentials: Array.isArray(object?.deviceCredentials) + ? object.deviceCredentials.map((e: any) => ClientIdentification_ClientCredentials.fromJSON(e)) + : [] + }; + }, + + toJSON(message: ClientIdentification): unknown { + const obj: any = {}; + message.type !== undefined && (obj.type = clientIdentification_TokenTypeToJSON(message.type)); + message.token !== undefined && (obj.token = base64FromBytes(message.token !== undefined ? message.token : Buffer.alloc(0))); + if (message.clientInfo) { + obj.clientInfo = message.clientInfo.map((e) => (e ? ClientIdentification_NameValue.toJSON(e) : undefined)); + } else { + obj.clientInfo = []; + } + message.providerClientToken !== undefined && + (obj.providerClientToken = base64FromBytes(message.providerClientToken !== undefined ? message.providerClientToken : Buffer.alloc(0))); + message.licenseCounter !== undefined && (obj.licenseCounter = Math.round(message.licenseCounter)); + message.clientCapabilities !== undefined && + (obj.clientCapabilities = message.clientCapabilities ? ClientIdentification_ClientCapabilities.toJSON(message.clientCapabilities) : undefined); + message.vmpData !== undefined && (obj.vmpData = base64FromBytes(message.vmpData !== undefined ? message.vmpData : Buffer.alloc(0))); + if (message.deviceCredentials) { + obj.deviceCredentials = message.deviceCredentials.map((e) => (e ? ClientIdentification_ClientCredentials.toJSON(e) : undefined)); + } else { + obj.deviceCredentials = []; + } + return obj; + }, + + fromPartial, I>>(object: I): ClientIdentification { + const message = createBaseClientIdentification(); + message.type = object.type ?? 0; + message.token = object.token ?? Buffer.alloc(0); + message.clientInfo = object.clientInfo?.map((e) => ClientIdentification_NameValue.fromPartial(e)) || []; + message.providerClientToken = object.providerClientToken ?? Buffer.alloc(0); + message.licenseCounter = object.licenseCounter ?? 0; + message.clientCapabilities = + object.clientCapabilities !== undefined && object.clientCapabilities !== null + ? ClientIdentification_ClientCapabilities.fromPartial(object.clientCapabilities) + : undefined; + message.vmpData = object.vmpData ?? Buffer.alloc(0); + message.deviceCredentials = object.deviceCredentials?.map((e) => ClientIdentification_ClientCredentials.fromPartial(e)) || []; + return message; + } +}; + +function createBaseClientIdentification_NameValue(): ClientIdentification_NameValue { + return { name: '', value: '' }; +} + +export const ClientIdentification_NameValue = { + encode(message: ClientIdentification_NameValue, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.name !== '') { + writer.uint32(10).string(message.name); + } + if (message.value !== '') { + writer.uint32(18).string(message.value); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): ClientIdentification_NameValue { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseClientIdentification_NameValue(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.name = reader.string(); + break; + case 2: + message.value = reader.string(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): ClientIdentification_NameValue { + return { + name: isSet(object.name) ? String(object.name) : '', + value: isSet(object.value) ? String(object.value) : '' + }; + }, + + toJSON(message: ClientIdentification_NameValue): unknown { + const obj: any = {}; + message.name !== undefined && (obj.name = message.name); + message.value !== undefined && (obj.value = message.value); + return obj; + }, + + fromPartial, I>>(object: I): ClientIdentification_NameValue { + const message = createBaseClientIdentification_NameValue(); + message.name = object.name ?? ''; + message.value = object.value ?? ''; + return message; + } +}; + +function createBaseClientIdentification_ClientCapabilities(): ClientIdentification_ClientCapabilities { + return { + clientToken: false, + sessionToken: false, + videoResolutionConstraints: false, + maxHdcpVersion: 0, + oemCryptoApiVersion: 0, + antiRollbackUsageTable: false, + srmVersion: 0, + canUpdateSrm: false, + supportedCertificateKeyType: [], + analogOutputCapabilities: 0, + canDisableAnalogOutput: false, + resourceRatingTier: 0 + }; +} + +export const ClientIdentification_ClientCapabilities = { + encode(message: ClientIdentification_ClientCapabilities, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.clientToken === true) { + writer.uint32(8).bool(message.clientToken); + } + if (message.sessionToken === true) { + writer.uint32(16).bool(message.sessionToken); + } + if (message.videoResolutionConstraints === true) { + writer.uint32(24).bool(message.videoResolutionConstraints); + } + if (message.maxHdcpVersion !== 0) { + writer.uint32(32).int32(message.maxHdcpVersion); + } + if (message.oemCryptoApiVersion !== 0) { + writer.uint32(40).uint32(message.oemCryptoApiVersion); + } + if (message.antiRollbackUsageTable === true) { + writer.uint32(48).bool(message.antiRollbackUsageTable); + } + if (message.srmVersion !== 0) { + writer.uint32(56).uint32(message.srmVersion); + } + if (message.canUpdateSrm === true) { + writer.uint32(64).bool(message.canUpdateSrm); + } + writer.uint32(74).fork(); + for (const v of message.supportedCertificateKeyType) { + writer.int32(v); + } + writer.ldelim(); + if (message.analogOutputCapabilities !== 0) { + writer.uint32(80).int32(message.analogOutputCapabilities); + } + if (message.canDisableAnalogOutput === true) { + writer.uint32(88).bool(message.canDisableAnalogOutput); + } + if (message.resourceRatingTier !== 0) { + writer.uint32(96).uint32(message.resourceRatingTier); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): ClientIdentification_ClientCapabilities { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseClientIdentification_ClientCapabilities(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.clientToken = reader.bool(); + break; + case 2: + message.sessionToken = reader.bool(); + break; + case 3: + message.videoResolutionConstraints = reader.bool(); + break; + case 4: + message.maxHdcpVersion = reader.int32() as any; + break; + case 5: + message.oemCryptoApiVersion = reader.uint32(); + break; + case 6: + message.antiRollbackUsageTable = reader.bool(); + break; + case 7: + message.srmVersion = reader.uint32(); + break; + case 8: + message.canUpdateSrm = reader.bool(); + break; + case 9: + if ((tag & 7) === 2) { + const end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) { + message.supportedCertificateKeyType.push(reader.int32() as any); + } + } else { + message.supportedCertificateKeyType.push(reader.int32() as any); + } + break; + case 10: + message.analogOutputCapabilities = reader.int32() as any; + break; + case 11: + message.canDisableAnalogOutput = reader.bool(); + break; + case 12: + message.resourceRatingTier = reader.uint32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): ClientIdentification_ClientCapabilities { + return { + clientToken: isSet(object.clientToken) ? Boolean(object.clientToken) : false, + sessionToken: isSet(object.sessionToken) ? Boolean(object.sessionToken) : false, + videoResolutionConstraints: isSet(object.videoResolutionConstraints) ? Boolean(object.videoResolutionConstraints) : false, + maxHdcpVersion: isSet(object.maxHdcpVersion) ? clientIdentification_ClientCapabilities_HdcpVersionFromJSON(object.maxHdcpVersion) : 0, + oemCryptoApiVersion: isSet(object.oemCryptoApiVersion) ? Number(object.oemCryptoApiVersion) : 0, + antiRollbackUsageTable: isSet(object.antiRollbackUsageTable) ? Boolean(object.antiRollbackUsageTable) : false, + srmVersion: isSet(object.srmVersion) ? Number(object.srmVersion) : 0, + canUpdateSrm: isSet(object.canUpdateSrm) ? Boolean(object.canUpdateSrm) : false, + supportedCertificateKeyType: Array.isArray(object?.supportedCertificateKeyType) + ? object.supportedCertificateKeyType.map((e: any) => clientIdentification_ClientCapabilities_CertificateKeyTypeFromJSON(e)) + : [], + analogOutputCapabilities: isSet(object.analogOutputCapabilities) + ? clientIdentification_ClientCapabilities_AnalogOutputCapabilitiesFromJSON(object.analogOutputCapabilities) + : 0, + canDisableAnalogOutput: isSet(object.canDisableAnalogOutput) ? Boolean(object.canDisableAnalogOutput) : false, + resourceRatingTier: isSet(object.resourceRatingTier) ? Number(object.resourceRatingTier) : 0 + }; + }, + + toJSON(message: ClientIdentification_ClientCapabilities): unknown { + const obj: any = {}; + message.clientToken !== undefined && (obj.clientToken = message.clientToken); + message.sessionToken !== undefined && (obj.sessionToken = message.sessionToken); + message.videoResolutionConstraints !== undefined && (obj.videoResolutionConstraints = message.videoResolutionConstraints); + message.maxHdcpVersion !== undefined && (obj.maxHdcpVersion = clientIdentification_ClientCapabilities_HdcpVersionToJSON(message.maxHdcpVersion)); + message.oemCryptoApiVersion !== undefined && (obj.oemCryptoApiVersion = Math.round(message.oemCryptoApiVersion)); + message.antiRollbackUsageTable !== undefined && (obj.antiRollbackUsageTable = message.antiRollbackUsageTable); + message.srmVersion !== undefined && (obj.srmVersion = Math.round(message.srmVersion)); + message.canUpdateSrm !== undefined && (obj.canUpdateSrm = message.canUpdateSrm); + if (message.supportedCertificateKeyType) { + obj.supportedCertificateKeyType = message.supportedCertificateKeyType.map((e) => + clientIdentification_ClientCapabilities_CertificateKeyTypeToJSON(e) + ); + } else { + obj.supportedCertificateKeyType = []; + } + message.analogOutputCapabilities !== undefined && + (obj.analogOutputCapabilities = clientIdentification_ClientCapabilities_AnalogOutputCapabilitiesToJSON(message.analogOutputCapabilities)); + message.canDisableAnalogOutput !== undefined && (obj.canDisableAnalogOutput = message.canDisableAnalogOutput); + message.resourceRatingTier !== undefined && (obj.resourceRatingTier = Math.round(message.resourceRatingTier)); + return obj; + }, + + fromPartial, I>>(object: I): ClientIdentification_ClientCapabilities { + const message = createBaseClientIdentification_ClientCapabilities(); + message.clientToken = object.clientToken ?? false; + message.sessionToken = object.sessionToken ?? false; + message.videoResolutionConstraints = object.videoResolutionConstraints ?? false; + message.maxHdcpVersion = object.maxHdcpVersion ?? 0; + message.oemCryptoApiVersion = object.oemCryptoApiVersion ?? 0; + message.antiRollbackUsageTable = object.antiRollbackUsageTable ?? false; + message.srmVersion = object.srmVersion ?? 0; + message.canUpdateSrm = object.canUpdateSrm ?? false; + message.supportedCertificateKeyType = object.supportedCertificateKeyType?.map((e) => e) || []; + message.analogOutputCapabilities = object.analogOutputCapabilities ?? 0; + message.canDisableAnalogOutput = object.canDisableAnalogOutput ?? false; + message.resourceRatingTier = object.resourceRatingTier ?? 0; + return message; + } +}; + +function createBaseClientIdentification_ClientCredentials(): ClientIdentification_ClientCredentials { + return { type: 0, token: Buffer.alloc(0) }; +} + +export const ClientIdentification_ClientCredentials = { + encode(message: ClientIdentification_ClientCredentials, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.type !== 0) { + writer.uint32(8).int32(message.type); + } + if (message.token.length !== 0) { + writer.uint32(18).bytes(message.token); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): ClientIdentification_ClientCredentials { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseClientIdentification_ClientCredentials(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.type = reader.int32() as any; + break; + case 2: + message.token = reader.bytes() as Buffer; + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): ClientIdentification_ClientCredentials { + return { + type: isSet(object.type) ? clientIdentification_TokenTypeFromJSON(object.type) : 0, + token: isSet(object.token) ? Buffer.from(bytesFromBase64(object.token)) : Buffer.alloc(0) + }; + }, + + toJSON(message: ClientIdentification_ClientCredentials): unknown { + const obj: any = {}; + message.type !== undefined && (obj.type = clientIdentification_TokenTypeToJSON(message.type)); + message.token !== undefined && (obj.token = base64FromBytes(message.token !== undefined ? message.token : Buffer.alloc(0))); + return obj; + }, + + fromPartial, I>>(object: I): ClientIdentification_ClientCredentials { + const message = createBaseClientIdentification_ClientCredentials(); + message.type = object.type ?? 0; + message.token = object.token ?? Buffer.alloc(0); + return message; + } +}; + +function createBaseEncryptedClientIdentification(): EncryptedClientIdentification { + return { + providerId: '', + serviceCertificateSerialNumber: Buffer.alloc(0), + encryptedClientId: Buffer.alloc(0), + encryptedClientIdIv: Buffer.alloc(0), + encryptedPrivacyKey: Buffer.alloc(0) + }; +} + +export const EncryptedClientIdentification = { + encode(message: EncryptedClientIdentification, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.providerId !== '') { + writer.uint32(10).string(message.providerId); + } + if (message.serviceCertificateSerialNumber.length !== 0) { + writer.uint32(18).bytes(message.serviceCertificateSerialNumber); + } + if (message.encryptedClientId.length !== 0) { + writer.uint32(26).bytes(message.encryptedClientId); + } + if (message.encryptedClientIdIv.length !== 0) { + writer.uint32(34).bytes(message.encryptedClientIdIv); + } + if (message.encryptedPrivacyKey.length !== 0) { + writer.uint32(42).bytes(message.encryptedPrivacyKey); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): EncryptedClientIdentification { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseEncryptedClientIdentification(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.providerId = reader.string(); + break; + case 2: + message.serviceCertificateSerialNumber = reader.bytes() as Buffer; + break; + case 3: + message.encryptedClientId = reader.bytes() as Buffer; + break; + case 4: + message.encryptedClientIdIv = reader.bytes() as Buffer; + break; + case 5: + message.encryptedPrivacyKey = reader.bytes() as Buffer; + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): EncryptedClientIdentification { + return { + providerId: isSet(object.providerId) ? String(object.providerId) : '', + serviceCertificateSerialNumber: isSet(object.serviceCertificateSerialNumber) + ? Buffer.from(bytesFromBase64(object.serviceCertificateSerialNumber)) + : Buffer.alloc(0), + encryptedClientId: isSet(object.encryptedClientId) ? Buffer.from(bytesFromBase64(object.encryptedClientId)) : Buffer.alloc(0), + encryptedClientIdIv: isSet(object.encryptedClientIdIv) ? Buffer.from(bytesFromBase64(object.encryptedClientIdIv)) : Buffer.alloc(0), + encryptedPrivacyKey: isSet(object.encryptedPrivacyKey) ? Buffer.from(bytesFromBase64(object.encryptedPrivacyKey)) : Buffer.alloc(0) + }; + }, + + toJSON(message: EncryptedClientIdentification): unknown { + const obj: any = {}; + message.providerId !== undefined && (obj.providerId = message.providerId); + message.serviceCertificateSerialNumber !== undefined && + (obj.serviceCertificateSerialNumber = base64FromBytes( + message.serviceCertificateSerialNumber !== undefined ? message.serviceCertificateSerialNumber : Buffer.alloc(0) + )); + message.encryptedClientId !== undefined && + (obj.encryptedClientId = base64FromBytes(message.encryptedClientId !== undefined ? message.encryptedClientId : Buffer.alloc(0))); + message.encryptedClientIdIv !== undefined && + (obj.encryptedClientIdIv = base64FromBytes(message.encryptedClientIdIv !== undefined ? message.encryptedClientIdIv : Buffer.alloc(0))); + message.encryptedPrivacyKey !== undefined && + (obj.encryptedPrivacyKey = base64FromBytes(message.encryptedPrivacyKey !== undefined ? message.encryptedPrivacyKey : Buffer.alloc(0))); + return obj; + }, + + fromPartial, I>>(object: I): EncryptedClientIdentification { + const message = createBaseEncryptedClientIdentification(); + message.providerId = object.providerId ?? ''; + message.serviceCertificateSerialNumber = object.serviceCertificateSerialNumber ?? Buffer.alloc(0); + message.encryptedClientId = object.encryptedClientId ?? Buffer.alloc(0); + message.encryptedClientIdIv = object.encryptedClientIdIv ?? Buffer.alloc(0); + message.encryptedPrivacyKey = object.encryptedPrivacyKey ?? Buffer.alloc(0); + return message; + } +}; + +function createBaseDrmCertificate(): DrmCertificate { + return { + type: 0, + serialNumber: Buffer.alloc(0), + creationTimeSeconds: 0, + expirationTimeSeconds: 0, + publicKey: Buffer.alloc(0), + systemId: 0, + testDeviceDeprecated: false, + providerId: '', + serviceTypes: [], + algorithm: 0, + rotId: Buffer.alloc(0), + encryptionKey: undefined + }; +} + +export const DrmCertificate = { + encode(message: DrmCertificate, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.type !== 0) { + writer.uint32(8).int32(message.type); + } + if (message.serialNumber.length !== 0) { + writer.uint32(18).bytes(message.serialNumber); + } + if (message.creationTimeSeconds !== 0) { + writer.uint32(24).uint32(message.creationTimeSeconds); + } + if (message.expirationTimeSeconds !== 0) { + writer.uint32(96).uint32(message.expirationTimeSeconds); + } + if (message.publicKey.length !== 0) { + writer.uint32(34).bytes(message.publicKey); + } + if (message.systemId !== 0) { + writer.uint32(40).uint32(message.systemId); + } + if (message.testDeviceDeprecated === true) { + writer.uint32(48).bool(message.testDeviceDeprecated); + } + if (message.providerId !== '') { + writer.uint32(58).string(message.providerId); + } + writer.uint32(66).fork(); + for (const v of message.serviceTypes) { + writer.int32(v); + } + writer.ldelim(); + if (message.algorithm !== 0) { + writer.uint32(72).int32(message.algorithm); + } + if (message.rotId.length !== 0) { + writer.uint32(82).bytes(message.rotId); + } + if (message.encryptionKey !== undefined) { + DrmCertificate_EncryptionKey.encode(message.encryptionKey, writer.uint32(90).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): DrmCertificate { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseDrmCertificate(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.type = reader.int32() as any; + break; + case 2: + message.serialNumber = reader.bytes() as Buffer; + break; + case 3: + message.creationTimeSeconds = reader.uint32(); + break; + case 12: + message.expirationTimeSeconds = reader.uint32(); + break; + case 4: + message.publicKey = reader.bytes() as Buffer; + break; + case 5: + message.systemId = reader.uint32(); + break; + case 6: + message.testDeviceDeprecated = reader.bool(); + break; + case 7: + message.providerId = reader.string(); + break; + case 8: + if ((tag & 7) === 2) { + const end2 = reader.uint32() + reader.pos; + while (reader.pos < end2) { + message.serviceTypes.push(reader.int32() as any); + } + } else { + message.serviceTypes.push(reader.int32() as any); + } + break; + case 9: + message.algorithm = reader.int32() as any; + break; + case 10: + message.rotId = reader.bytes() as Buffer; + break; + case 11: + message.encryptionKey = DrmCertificate_EncryptionKey.decode(reader, reader.uint32()); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): DrmCertificate { + return { + type: isSet(object.type) ? drmCertificate_TypeFromJSON(object.type) : 0, + serialNumber: isSet(object.serialNumber) ? Buffer.from(bytesFromBase64(object.serialNumber)) : Buffer.alloc(0), + creationTimeSeconds: isSet(object.creationTimeSeconds) ? Number(object.creationTimeSeconds) : 0, + expirationTimeSeconds: isSet(object.expirationTimeSeconds) ? Number(object.expirationTimeSeconds) : 0, + publicKey: isSet(object.publicKey) ? Buffer.from(bytesFromBase64(object.publicKey)) : Buffer.alloc(0), + systemId: isSet(object.systemId) ? Number(object.systemId) : 0, + testDeviceDeprecated: isSet(object.testDeviceDeprecated) ? Boolean(object.testDeviceDeprecated) : false, + providerId: isSet(object.providerId) ? String(object.providerId) : '', + serviceTypes: Array.isArray(object?.serviceTypes) ? object.serviceTypes.map((e: any) => drmCertificate_ServiceTypeFromJSON(e)) : [], + algorithm: isSet(object.algorithm) ? drmCertificate_AlgorithmFromJSON(object.algorithm) : 0, + rotId: isSet(object.rotId) ? Buffer.from(bytesFromBase64(object.rotId)) : Buffer.alloc(0), + encryptionKey: isSet(object.encryptionKey) ? DrmCertificate_EncryptionKey.fromJSON(object.encryptionKey) : undefined + }; + }, + + toJSON(message: DrmCertificate): unknown { + const obj: any = {}; + message.type !== undefined && (obj.type = drmCertificate_TypeToJSON(message.type)); + message.serialNumber !== undefined && + (obj.serialNumber = base64FromBytes(message.serialNumber !== undefined ? message.serialNumber : Buffer.alloc(0))); + message.creationTimeSeconds !== undefined && (obj.creationTimeSeconds = Math.round(message.creationTimeSeconds)); + message.expirationTimeSeconds !== undefined && (obj.expirationTimeSeconds = Math.round(message.expirationTimeSeconds)); + message.publicKey !== undefined && (obj.publicKey = base64FromBytes(message.publicKey !== undefined ? message.publicKey : Buffer.alloc(0))); + message.systemId !== undefined && (obj.systemId = Math.round(message.systemId)); + message.testDeviceDeprecated !== undefined && (obj.testDeviceDeprecated = message.testDeviceDeprecated); + message.providerId !== undefined && (obj.providerId = message.providerId); + if (message.serviceTypes) { + obj.serviceTypes = message.serviceTypes.map((e) => drmCertificate_ServiceTypeToJSON(e)); + } else { + obj.serviceTypes = []; + } + message.algorithm !== undefined && (obj.algorithm = drmCertificate_AlgorithmToJSON(message.algorithm)); + message.rotId !== undefined && (obj.rotId = base64FromBytes(message.rotId !== undefined ? message.rotId : Buffer.alloc(0))); + message.encryptionKey !== undefined && + (obj.encryptionKey = message.encryptionKey ? DrmCertificate_EncryptionKey.toJSON(message.encryptionKey) : undefined); + return obj; + }, + + fromPartial, I>>(object: I): DrmCertificate { + const message = createBaseDrmCertificate(); + message.type = object.type ?? 0; + message.serialNumber = object.serialNumber ?? Buffer.alloc(0); + message.creationTimeSeconds = object.creationTimeSeconds ?? 0; + message.expirationTimeSeconds = object.expirationTimeSeconds ?? 0; + message.publicKey = object.publicKey ?? Buffer.alloc(0); + message.systemId = object.systemId ?? 0; + message.testDeviceDeprecated = object.testDeviceDeprecated ?? false; + message.providerId = object.providerId ?? ''; + message.serviceTypes = object.serviceTypes?.map((e) => e) || []; + message.algorithm = object.algorithm ?? 0; + message.rotId = object.rotId ?? Buffer.alloc(0); + message.encryptionKey = + object.encryptionKey !== undefined && object.encryptionKey !== null + ? DrmCertificate_EncryptionKey.fromPartial(object.encryptionKey) + : undefined; + return message; + } +}; + +function createBaseDrmCertificate_EncryptionKey(): DrmCertificate_EncryptionKey { + return { publicKey: Buffer.alloc(0), algorithm: 0 }; +} + +export const DrmCertificate_EncryptionKey = { + encode(message: DrmCertificate_EncryptionKey, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.publicKey.length !== 0) { + writer.uint32(10).bytes(message.publicKey); + } + if (message.algorithm !== 0) { + writer.uint32(16).int32(message.algorithm); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): DrmCertificate_EncryptionKey { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseDrmCertificate_EncryptionKey(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.publicKey = reader.bytes() as Buffer; + break; + case 2: + message.algorithm = reader.int32() as any; + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): DrmCertificate_EncryptionKey { + return { + publicKey: isSet(object.publicKey) ? Buffer.from(bytesFromBase64(object.publicKey)) : Buffer.alloc(0), + algorithm: isSet(object.algorithm) ? drmCertificate_AlgorithmFromJSON(object.algorithm) : 0 + }; + }, + + toJSON(message: DrmCertificate_EncryptionKey): unknown { + const obj: any = {}; + message.publicKey !== undefined && (obj.publicKey = base64FromBytes(message.publicKey !== undefined ? message.publicKey : Buffer.alloc(0))); + message.algorithm !== undefined && (obj.algorithm = drmCertificate_AlgorithmToJSON(message.algorithm)); + return obj; + }, + + fromPartial, I>>(object: I): DrmCertificate_EncryptionKey { + const message = createBaseDrmCertificate_EncryptionKey(); + message.publicKey = object.publicKey ?? Buffer.alloc(0); + message.algorithm = object.algorithm ?? 0; + return message; + } +}; + +function createBaseSignedDrmCertificate(): SignedDrmCertificate { + return { drmCertificate: Buffer.alloc(0), signature: Buffer.alloc(0), signer: undefined, hashAlgorithm: 0 }; +} + +export const SignedDrmCertificate = { + encode(message: SignedDrmCertificate, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.drmCertificate.length !== 0) { + writer.uint32(10).bytes(message.drmCertificate); + } + if (message.signature.length !== 0) { + writer.uint32(18).bytes(message.signature); + } + if (message.signer !== undefined) { + SignedDrmCertificate.encode(message.signer, writer.uint32(26).fork()).ldelim(); + } + if (message.hashAlgorithm !== 0) { + writer.uint32(32).int32(message.hashAlgorithm); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): SignedDrmCertificate { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseSignedDrmCertificate(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.drmCertificate = reader.bytes() as Buffer; + break; + case 2: + message.signature = reader.bytes() as Buffer; + break; + case 3: + message.signer = SignedDrmCertificate.decode(reader, reader.uint32()); + break; + case 4: + message.hashAlgorithm = reader.int32() as any; + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): SignedDrmCertificate { + return { + drmCertificate: isSet(object.drmCertificate) ? Buffer.from(bytesFromBase64(object.drmCertificate)) : Buffer.alloc(0), + signature: isSet(object.signature) ? Buffer.from(bytesFromBase64(object.signature)) : Buffer.alloc(0), + signer: isSet(object.signer) ? SignedDrmCertificate.fromJSON(object.signer) : undefined, + hashAlgorithm: isSet(object.hashAlgorithm) ? hashAlgorithmProtoFromJSON(object.hashAlgorithm) : 0 + }; + }, + + toJSON(message: SignedDrmCertificate): unknown { + const obj: any = {}; + message.drmCertificate !== undefined && + (obj.drmCertificate = base64FromBytes(message.drmCertificate !== undefined ? message.drmCertificate : Buffer.alloc(0))); + message.signature !== undefined && (obj.signature = base64FromBytes(message.signature !== undefined ? message.signature : Buffer.alloc(0))); + message.signer !== undefined && (obj.signer = message.signer ? SignedDrmCertificate.toJSON(message.signer) : undefined); + message.hashAlgorithm !== undefined && (obj.hashAlgorithm = hashAlgorithmProtoToJSON(message.hashAlgorithm)); + return obj; + }, + + fromPartial, I>>(object: I): SignedDrmCertificate { + const message = createBaseSignedDrmCertificate(); + message.drmCertificate = object.drmCertificate ?? Buffer.alloc(0); + message.signature = object.signature ?? Buffer.alloc(0); + message.signer = object.signer !== undefined && object.signer !== null ? SignedDrmCertificate.fromPartial(object.signer) : undefined; + message.hashAlgorithm = object.hashAlgorithm ?? 0; + return message; + } +}; + +function createBaseWidevinePsshData(): WidevinePsshData { + return { + keyIds: [], + contentId: Buffer.alloc(0), + cryptoPeriodIndex: 0, + protectionScheme: 0, + cryptoPeriodSeconds: 0, + type: 0, + keySequence: 0, + groupIds: [], + entitledKeys: [], + videoFeature: '', + algorithm: 0, + provider: '', + trackType: '', + policy: '', + groupedLicense: Buffer.alloc(0) + }; +} + +export const WidevinePsshData = { + encode(message: WidevinePsshData, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + for (const v of message.keyIds) { + writer.uint32(18).bytes(v!); + } + if (message.contentId.length !== 0) { + writer.uint32(34).bytes(message.contentId); + } + if (message.cryptoPeriodIndex !== 0) { + writer.uint32(56).uint32(message.cryptoPeriodIndex); + } + if (message.protectionScheme !== 0) { + writer.uint32(72).uint32(message.protectionScheme); + } + if (message.cryptoPeriodSeconds !== 0) { + writer.uint32(80).uint32(message.cryptoPeriodSeconds); + } + if (message.type !== 0) { + writer.uint32(88).int32(message.type); + } + if (message.keySequence !== 0) { + writer.uint32(96).uint32(message.keySequence); + } + for (const v of message.groupIds) { + writer.uint32(106).bytes(v!); + } + for (const v of message.entitledKeys) { + WidevinePsshData_EntitledKey.encode(v!, writer.uint32(114).fork()).ldelim(); + } + if (message.videoFeature !== '') { + writer.uint32(122).string(message.videoFeature); + } + if (message.algorithm !== 0) { + writer.uint32(8).int32(message.algorithm); + } + if (message.provider !== '') { + writer.uint32(26).string(message.provider); + } + if (message.trackType !== '') { + writer.uint32(42).string(message.trackType); + } + if (message.policy !== '') { + writer.uint32(50).string(message.policy); + } + if (message.groupedLicense.length !== 0) { + writer.uint32(66).bytes(message.groupedLicense); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): WidevinePsshData { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseWidevinePsshData(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 2: + message.keyIds.push(reader.bytes() as Buffer); + break; + case 4: + message.contentId = reader.bytes() as Buffer; + break; + case 7: + message.cryptoPeriodIndex = reader.uint32(); + break; + case 9: + message.protectionScheme = reader.uint32(); + break; + case 10: + message.cryptoPeriodSeconds = reader.uint32(); + break; + case 11: + message.type = reader.int32() as any; + break; + case 12: + message.keySequence = reader.uint32(); + break; + case 13: + message.groupIds.push(reader.bytes() as Buffer); + break; + case 14: + message.entitledKeys.push(WidevinePsshData_EntitledKey.decode(reader, reader.uint32())); + break; + case 15: + message.videoFeature = reader.string(); + break; + case 1: + message.algorithm = reader.int32() as any; + break; + case 3: + message.provider = reader.string(); + break; + case 5: + message.trackType = reader.string(); + break; + case 6: + message.policy = reader.string(); + break; + case 8: + message.groupedLicense = reader.bytes() as Buffer; + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): WidevinePsshData { + return { + keyIds: Array.isArray(object?.keyIds) ? object.keyIds.map((e: any) => Buffer.from(bytesFromBase64(e))) : [], + contentId: isSet(object.contentId) ? Buffer.from(bytesFromBase64(object.contentId)) : Buffer.alloc(0), + cryptoPeriodIndex: isSet(object.cryptoPeriodIndex) ? Number(object.cryptoPeriodIndex) : 0, + protectionScheme: isSet(object.protectionScheme) ? Number(object.protectionScheme) : 0, + cryptoPeriodSeconds: isSet(object.cryptoPeriodSeconds) ? Number(object.cryptoPeriodSeconds) : 0, + type: isSet(object.type) ? widevinePsshData_TypeFromJSON(object.type) : 0, + keySequence: isSet(object.keySequence) ? Number(object.keySequence) : 0, + groupIds: Array.isArray(object?.groupIds) ? object.groupIds.map((e: any) => Buffer.from(bytesFromBase64(e))) : [], + entitledKeys: Array.isArray(object?.entitledKeys) ? object.entitledKeys.map((e: any) => WidevinePsshData_EntitledKey.fromJSON(e)) : [], + videoFeature: isSet(object.videoFeature) ? String(object.videoFeature) : '', + algorithm: isSet(object.algorithm) ? widevinePsshData_AlgorithmFromJSON(object.algorithm) : 0, + provider: isSet(object.provider) ? String(object.provider) : '', + trackType: isSet(object.trackType) ? String(object.trackType) : '', + policy: isSet(object.policy) ? String(object.policy) : '', + groupedLicense: isSet(object.groupedLicense) ? Buffer.from(bytesFromBase64(object.groupedLicense)) : Buffer.alloc(0) + }; + }, + + toJSON(message: WidevinePsshData): unknown { + const obj: any = {}; + if (message.keyIds) { + obj.keyIds = message.keyIds.map((e) => base64FromBytes(e !== undefined ? e : Buffer.alloc(0))); + } else { + obj.keyIds = []; + } + message.contentId !== undefined && (obj.contentId = base64FromBytes(message.contentId !== undefined ? message.contentId : Buffer.alloc(0))); + message.cryptoPeriodIndex !== undefined && (obj.cryptoPeriodIndex = Math.round(message.cryptoPeriodIndex)); + message.protectionScheme !== undefined && (obj.protectionScheme = Math.round(message.protectionScheme)); + message.cryptoPeriodSeconds !== undefined && (obj.cryptoPeriodSeconds = Math.round(message.cryptoPeriodSeconds)); + message.type !== undefined && (obj.type = widevinePsshData_TypeToJSON(message.type)); + message.keySequence !== undefined && (obj.keySequence = Math.round(message.keySequence)); + if (message.groupIds) { + obj.groupIds = message.groupIds.map((e) => base64FromBytes(e !== undefined ? e : Buffer.alloc(0))); + } else { + obj.groupIds = []; + } + if (message.entitledKeys) { + obj.entitledKeys = message.entitledKeys.map((e) => (e ? WidevinePsshData_EntitledKey.toJSON(e) : undefined)); + } else { + obj.entitledKeys = []; + } + message.videoFeature !== undefined && (obj.videoFeature = message.videoFeature); + message.algorithm !== undefined && (obj.algorithm = widevinePsshData_AlgorithmToJSON(message.algorithm)); + message.provider !== undefined && (obj.provider = message.provider); + message.trackType !== undefined && (obj.trackType = message.trackType); + message.policy !== undefined && (obj.policy = message.policy); + message.groupedLicense !== undefined && + (obj.groupedLicense = base64FromBytes(message.groupedLicense !== undefined ? message.groupedLicense : Buffer.alloc(0))); + return obj; + }, + + fromPartial, I>>(object: I): WidevinePsshData { + const message = createBaseWidevinePsshData(); + message.keyIds = object.keyIds?.map((e) => e) || []; + message.contentId = object.contentId ?? Buffer.alloc(0); + message.cryptoPeriodIndex = object.cryptoPeriodIndex ?? 0; + message.protectionScheme = object.protectionScheme ?? 0; + message.cryptoPeriodSeconds = object.cryptoPeriodSeconds ?? 0; + message.type = object.type ?? 0; + message.keySequence = object.keySequence ?? 0; + message.groupIds = object.groupIds?.map((e) => e) || []; + message.entitledKeys = object.entitledKeys?.map((e) => WidevinePsshData_EntitledKey.fromPartial(e)) || []; + message.videoFeature = object.videoFeature ?? ''; + message.algorithm = object.algorithm ?? 0; + message.provider = object.provider ?? ''; + message.trackType = object.trackType ?? ''; + message.policy = object.policy ?? ''; + message.groupedLicense = object.groupedLicense ?? Buffer.alloc(0); + return message; + } +}; + +function createBaseWidevinePsshData_EntitledKey(): WidevinePsshData_EntitledKey { + return { + entitlementKeyId: Buffer.alloc(0), + keyId: Buffer.alloc(0), + key: Buffer.alloc(0), + iv: Buffer.alloc(0), + entitlementKeySizeBytes: 0 + }; +} + +export const WidevinePsshData_EntitledKey = { + encode(message: WidevinePsshData_EntitledKey, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.entitlementKeyId.length !== 0) { + writer.uint32(10).bytes(message.entitlementKeyId); + } + if (message.keyId.length !== 0) { + writer.uint32(18).bytes(message.keyId); + } + if (message.key.length !== 0) { + writer.uint32(26).bytes(message.key); + } + if (message.iv.length !== 0) { + writer.uint32(34).bytes(message.iv); + } + if (message.entitlementKeySizeBytes !== 0) { + writer.uint32(40).uint32(message.entitlementKeySizeBytes); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): WidevinePsshData_EntitledKey { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseWidevinePsshData_EntitledKey(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.entitlementKeyId = reader.bytes() as Buffer; + break; + case 2: + message.keyId = reader.bytes() as Buffer; + break; + case 3: + message.key = reader.bytes() as Buffer; + break; + case 4: + message.iv = reader.bytes() as Buffer; + break; + case 5: + message.entitlementKeySizeBytes = reader.uint32(); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): WidevinePsshData_EntitledKey { + return { + entitlementKeyId: isSet(object.entitlementKeyId) ? Buffer.from(bytesFromBase64(object.entitlementKeyId)) : Buffer.alloc(0), + keyId: isSet(object.keyId) ? Buffer.from(bytesFromBase64(object.keyId)) : Buffer.alloc(0), + key: isSet(object.key) ? Buffer.from(bytesFromBase64(object.key)) : Buffer.alloc(0), + iv: isSet(object.iv) ? Buffer.from(bytesFromBase64(object.iv)) : Buffer.alloc(0), + entitlementKeySizeBytes: isSet(object.entitlementKeySizeBytes) ? Number(object.entitlementKeySizeBytes) : 0 + }; + }, + + toJSON(message: WidevinePsshData_EntitledKey): unknown { + const obj: any = {}; + message.entitlementKeyId !== undefined && + (obj.entitlementKeyId = base64FromBytes(message.entitlementKeyId !== undefined ? message.entitlementKeyId : Buffer.alloc(0))); + message.keyId !== undefined && (obj.keyId = base64FromBytes(message.keyId !== undefined ? message.keyId : Buffer.alloc(0))); + message.key !== undefined && (obj.key = base64FromBytes(message.key !== undefined ? message.key : Buffer.alloc(0))); + message.iv !== undefined && (obj.iv = base64FromBytes(message.iv !== undefined ? message.iv : Buffer.alloc(0))); + message.entitlementKeySizeBytes !== undefined && (obj.entitlementKeySizeBytes = Math.round(message.entitlementKeySizeBytes)); + return obj; + }, + + fromPartial, I>>(object: I): WidevinePsshData_EntitledKey { + const message = createBaseWidevinePsshData_EntitledKey(); + message.entitlementKeyId = object.entitlementKeyId ?? Buffer.alloc(0); + message.keyId = object.keyId ?? Buffer.alloc(0); + message.key = object.key ?? Buffer.alloc(0); + message.iv = object.iv ?? Buffer.alloc(0); + message.entitlementKeySizeBytes = object.entitlementKeySizeBytes ?? 0; + return message; + } +}; + +function createBaseFileHashes(): FileHashes { + return { signer: Buffer.alloc(0), signatures: [] }; +} + +export const FileHashes = { + encode(message: FileHashes, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.signer.length !== 0) { + writer.uint32(10).bytes(message.signer); + } + for (const v of message.signatures) { + FileHashes_Signature.encode(v!, writer.uint32(18).fork()).ldelim(); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): FileHashes { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseFileHashes(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.signer = reader.bytes() as Buffer; + break; + case 2: + message.signatures.push(FileHashes_Signature.decode(reader, reader.uint32())); + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): FileHashes { + return { + signer: isSet(object.signer) ? Buffer.from(bytesFromBase64(object.signer)) : Buffer.alloc(0), + signatures: Array.isArray(object?.signatures) ? object.signatures.map((e: any) => FileHashes_Signature.fromJSON(e)) : [] + }; + }, + + toJSON(message: FileHashes): unknown { + const obj: any = {}; + message.signer !== undefined && (obj.signer = base64FromBytes(message.signer !== undefined ? message.signer : Buffer.alloc(0))); + if (message.signatures) { + obj.signatures = message.signatures.map((e) => (e ? FileHashes_Signature.toJSON(e) : undefined)); + } else { + obj.signatures = []; + } + return obj; + }, + + fromPartial, I>>(object: I): FileHashes { + const message = createBaseFileHashes(); + message.signer = object.signer ?? Buffer.alloc(0); + message.signatures = object.signatures?.map((e) => FileHashes_Signature.fromPartial(e)) || []; + return message; + } +}; + +function createBaseFileHashes_Signature(): FileHashes_Signature { + return { filename: '', testSigning: false, SHA512Hash: Buffer.alloc(0), mainExe: false, signature: Buffer.alloc(0) }; +} + +export const FileHashes_Signature = { + encode(message: FileHashes_Signature, writer: _m0.Writer = _m0.Writer.create()): _m0.Writer { + if (message.filename !== '') { + writer.uint32(10).string(message.filename); + } + if (message.testSigning === true) { + writer.uint32(16).bool(message.testSigning); + } + if (message.SHA512Hash.length !== 0) { + writer.uint32(26).bytes(message.SHA512Hash); + } + if (message.mainExe === true) { + writer.uint32(32).bool(message.mainExe); + } + if (message.signature.length !== 0) { + writer.uint32(42).bytes(message.signature); + } + return writer; + }, + + decode(input: _m0.Reader | Uint8Array, length?: number): FileHashes_Signature { + const reader = input instanceof _m0.Reader ? input : new _m0.Reader(input); + const end = length === undefined ? reader.len : reader.pos + length; + const message = createBaseFileHashes_Signature(); + while (reader.pos < end) { + const tag = reader.uint32(); + switch (tag >>> 3) { + case 1: + message.filename = reader.string(); + break; + case 2: + message.testSigning = reader.bool(); + break; + case 3: + message.SHA512Hash = reader.bytes() as Buffer; + break; + case 4: + message.mainExe = reader.bool(); + break; + case 5: + message.signature = reader.bytes() as Buffer; + break; + default: + reader.skipType(tag & 7); + break; + } + } + return message; + }, + + fromJSON(object: any): FileHashes_Signature { + return { + filename: isSet(object.filename) ? String(object.filename) : '', + testSigning: isSet(object.testSigning) ? Boolean(object.testSigning) : false, + SHA512Hash: isSet(object.SHA512Hash) ? Buffer.from(bytesFromBase64(object.SHA512Hash)) : Buffer.alloc(0), + mainExe: isSet(object.mainExe) ? Boolean(object.mainExe) : false, + signature: isSet(object.signature) ? Buffer.from(bytesFromBase64(object.signature)) : Buffer.alloc(0) + }; + }, + + toJSON(message: FileHashes_Signature): unknown { + const obj: any = {}; + message.filename !== undefined && (obj.filename = message.filename); + message.testSigning !== undefined && (obj.testSigning = message.testSigning); + message.SHA512Hash !== undefined && (obj.SHA512Hash = base64FromBytes(message.SHA512Hash !== undefined ? message.SHA512Hash : Buffer.alloc(0))); + message.mainExe !== undefined && (obj.mainExe = message.mainExe); + message.signature !== undefined && (obj.signature = base64FromBytes(message.signature !== undefined ? message.signature : Buffer.alloc(0))); + return obj; + }, + + fromPartial, I>>(object: I): FileHashes_Signature { + const message = createBaseFileHashes_Signature(); + message.filename = object.filename ?? ''; + message.testSigning = object.testSigning ?? false; + message.SHA512Hash = object.SHA512Hash ?? Buffer.alloc(0); + message.mainExe = object.mainExe ?? false; + message.signature = object.signature ?? Buffer.alloc(0); + return message; + } +}; + +declare let self: any | undefined; +declare let window: any | undefined; +declare let global: any | undefined; +const tsProtoGlobalThis: any = (() => { + if (typeof globalThis !== 'undefined') { + return globalThis; + } + if (typeof self !== 'undefined') { + return self; + } + if (typeof window !== 'undefined') { + return window; + } + if (typeof global !== 'undefined') { + return global; + } + throw 'Unable to locate global object'; +})(); + +function bytesFromBase64(b64: string): Uint8Array { + if (tsProtoGlobalThis.Buffer) { + return Uint8Array.from(tsProtoGlobalThis.Buffer.from(b64, 'base64')); + } else { + const bin = tsProtoGlobalThis.atob(b64); + const arr = new Uint8Array(bin.length); + for (let i = 0; i < bin.length; ++i) { + arr[i] = bin.charCodeAt(i); + } + return arr; + } +} + +function base64FromBytes(arr: Uint8Array): string { + if (tsProtoGlobalThis.Buffer) { + return tsProtoGlobalThis.Buffer.from(arr).toString('base64'); + } else { + const bin: string[] = []; + arr.forEach((byte) => { + bin.push(String.fromCharCode(byte)); + }); + return tsProtoGlobalThis.btoa(bin.join('')); + } +} + +type Builtin = Date | Function | Uint8Array | string | number | boolean | undefined; //eslint-disable-line + +export type DeepPartial = T extends Builtin + ? T + : T extends Long + ? string | number | Long + : T extends Array + ? Array> + : T extends ReadonlyArray + ? ReadonlyArray> + : T extends {} //eslint-disable-line + ? { [K in keyof T]?: DeepPartial } + : Partial; + +type KeysOfUnion = T extends T ? keyof T : never; +export type Exact = P extends Builtin + ? P + : P & { [K in keyof P]: Exact } & { [K in Exclude>]: never }; + +if (_m0.util.Long !== Long) { + _m0.util.Long = Long as any; + _m0.configure(); +} + +function isSet(value: any): boolean { + return value !== null && value !== undefined; +} \ No newline at end of file diff --git a/modules/module.api-urls.ts b/modules/module.api-urls.ts index 603f25b..6dffd45 100644 --- a/modules/module.api-urls.ts +++ b/modules/module.api-urls.ts @@ -7,7 +7,8 @@ const domain = { www_beta: 'https://beta.crunchyroll.com', api_beta: 'https://beta-api.crunchyroll.com', hd_www: 'https://www.hidive.com', - hd_api: 'https://api.hidive.com' + hd_api: 'https://api.hidive.com', + hd_new: 'https://dce-frontoffice.imggaming.com' }; export type APIType = { @@ -41,6 +42,9 @@ export type APIType = { hd_clientWeb: string, hd_clientExo: string, hd_api: string, + hd_new_api: string, + hd_new_apiKey: string, + hd_new_version: string, } // api urls @@ -77,6 +81,10 @@ const api: APIType = { hd_clientWeb: 'okhttp/3.4.1', hd_clientExo: 'smartexoplayer/1.6.0.R (Linux;Android 6.0) ExoPlayerLib/2.6.0', hd_api: `${domain.hd_api}/api/v1`, + //Hidive New API + hd_new_api: `${domain.hd_new}/api`, + hd_new_apiKey: '857a1e5d-e35e-4fdf-805b-a87b6f8364bf', + hd_new_version: '6.0.1.bbf09a2' }; // set header diff --git a/modules/module.app-args.ts b/modules/module.app-args.ts index 60c281e..7e7629e 100644 --- a/modules/module.app-args.ts +++ b/modules/module.app-args.ts @@ -31,7 +31,8 @@ let argvC: { new: boolean | undefined; 'movie-listing': string | undefined; series: string | undefined; - s: string | undefined; + s: string | undefined; + srz: string | undefined; e: string | undefined; extid: string | undefined; q: number; @@ -64,6 +65,9 @@ let argvC: { _: (string | number)[]; $0: string; dlVideoOnce: boolean; + chapters: boolean; + crapi: 'android' | 'web'; + hdapi: 'old' | 'new'; removeBumpers: boolean; originalFontSize: boolean; keepAllVideos: boolean; diff --git a/modules/module.args.ts b/modules/module.args.ts index b6197da..3540483 100644 --- a/modules/module.args.ts +++ b/modules/module.args.ts @@ -138,8 +138,7 @@ const args: TAppArg[] = [ group: 'dl', alias: 'srz', describe: 'Get season list by series ID', - docDescribe: 'This command is used only for crunchyroll.' - + '\n Requested is the ID of a show not a season.', + docDescribe: 'Requested is the ID of a show not a season.', service: ['crunchy'], type: 'string', usage: '${ID}' @@ -203,6 +202,47 @@ const args: TAppArg[] = [ default: false } }, + { + name: 'chapters', + describe: 'Will fetch the chapters and add them into the final video', + type: 'boolean', + group: 'dl', + service: ['crunchy'], + docDescribe: 'Will fetch the chapters and add them into the final video.' + + '\nCurrently only works with mkvmerge.', + usage: '', + default: { + default: false + } + }, + { + name: 'crapi', + describe: 'Selects the API type for Crunchyroll', + type: 'string', + group: 'dl', + service: ['crunchy'], + docDescribe: 'If set to Android, it has lower quality, but Non-DRM streams,' + + '\nIf set to Web, it has a higher quality adaptive stream, but everything is DRM.', + usage: '', + choices: ['android', 'web'], + default: { + default: 'android' + } + }, + { + name: 'hdapi', + describe: 'Selects the API type for Hidive', + type: 'string', + group: 'dl', + service: ['hidive'], + docDescribe: 'If set to Old, it has lower quality, but Non-DRM streams, but some people can\'t use it,' + + '\nIf set to New, it has a higher quality stream, but everything is DRM.', + usage: '', + choices: ['old', 'new'], + default: { + default: 'old' + } + }, { name: 'removeBumpers', describe: 'Remove bumpers from final video', diff --git a/modules/module.cfg-loader.ts b/modules/module.cfg-loader.ts index e81ac82..6f39d8c 100644 --- a/modules/module.cfg-loader.ts +++ b/modules/module.cfg-loader.ts @@ -26,7 +26,8 @@ const stateFile = path.join(workingDir, 'config', 'guistate'); const tokenFile = { funi: path.join(workingDir, 'config', 'funi_token'), cr: path.join(workingDir, 'config', 'cr_token'), - hd: path.join(workingDir, 'config', 'hd_token') + hd: path.join(workingDir, 'config', 'hd_token'), + hdNew: path.join(workingDir, 'config', 'hd_new_token') }; export const ensureConfig = () => { @@ -82,7 +83,8 @@ export type ConfigObject = { bin: { ffmpeg?: string, mkvmerge?: string, - ffprobe?: string + ffprobe?: string, + mp4decrypt?: string }, cli: { [key: string]: any @@ -146,7 +148,8 @@ const loadBinCfg = async () => { const defaultBin = { ffmpeg: 'ffmpeg', mkvmerge: 'mkvmerge', - ffprobe: 'ffprobe' + ffprobe: 'ffprobe', + mp4decrypt: 'mp4decrypt' }; const keys = Object.keys(defaultBin) as (keyof typeof defaultBin)[]; for(const dir of keys){ @@ -240,7 +243,7 @@ const saveHDSession = (data: Record) => { const loadHDToken = () => { - let token = loadYamlCfgFile(tokenFile.cr, true); + let token = loadYamlCfgFile(tokenFile.hd, true); if(typeof token !== 'object' || token === null || Array.isArray(token)){ token = {}; } @@ -290,6 +293,25 @@ const loadHDProfile = () => { return profile; }; +const loadNewHDToken = () => { + let token = loadYamlCfgFile(tokenFile.hdNew, true); + if(typeof token !== 'object' || token === null || Array.isArray(token)){ + token = {}; + } + return token; +}; + +const saveNewHDToken = (data: Record) => { + const cfgFolder = path.dirname(tokenFile.hdNew); + try{ + fs.ensureDirSync(cfgFolder); + fs.writeFileSync(`${tokenFile.hdNew}.yml`, yaml.stringify(data)); + } + catch(e){ + console.error('Can\'t save token file to disk!'); + } +}; + const loadFuniToken = () => { const loadedToken = loadYamlCfgFile<{ token?: string @@ -361,6 +383,8 @@ export { loadHDSession, saveHDToken, loadHDToken, + saveNewHDToken, + loadNewHDToken, saveHDProfile, loadHDProfile, getState, diff --git a/modules/module.langsData.ts b/modules/module.langsData.ts index c4ffbf1..56ca413 100644 --- a/modules/module.langsData.ts +++ b/modules/module.langsData.ts @@ -3,6 +3,7 @@ export type LanguageItem = { cr_locale?: string, hd_locale?: string, + new_hd_locale?: string, locale: string, code: string, name: string, @@ -13,12 +14,12 @@ export type LanguageItem = { } const languages: LanguageItem[] = [ - { cr_locale: 'en-US', hd_locale: 'English', funi_locale: 'enUS', locale: 'en', code: 'eng', name: 'English' }, + { cr_locale: 'en-US', new_hd_locale: 'en-US', hd_locale: 'English', funi_locale: 'enUS', locale: 'en', code: 'eng', name: 'English' }, { cr_locale: 'en-IN', locale: 'en-IN', code: 'eng', name: 'English (India)', }, - { cr_locale: 'es-LA', hd_locale: 'Spanish LatAm', funi_name: 'Spanish (LAS)', funi_name_lagacy: 'Spanish (Latin Am)', funi_locale: 'esLA', locale: 'es-419', code: 'spa', name: 'Spanish', language: 'Latin American Spanish' }, + { cr_locale: 'es-LA', new_hd_locale: 'es-MX', hd_locale: 'Spanish LatAm', funi_name: 'Spanish (LAS)', funi_name_lagacy: 'Spanish (Latin Am)', funi_locale: 'esLA', locale: 'es-419', code: 'spa', name: 'Spanish', language: 'Latin American Spanish' }, { cr_locale: 'es-419',hd_locale: 'Spanish', locale: 'es-419', code: 'spa-419', name: 'Spanish', language: 'Latin American Spanish' }, { cr_locale: 'es-ES', hd_locale: 'Spanish Europe', locale: 'es-ES', code: 'spa-ES', name: 'Castilian', language: 'European Spanish' }, - { cr_locale: 'pt-BR', hd_locale: 'Portuguese', funi_name: 'Portuguese (Brazil)', funi_locale: 'ptBR', locale: 'pt-BR', code: 'por', name: 'Portuguese', language: 'Brazilian Portuguese' }, + { cr_locale: 'pt-BR', new_hd_locale: 'pt-BR', hd_locale: 'Portuguese', funi_name: 'Portuguese (Brazil)', funi_locale: 'ptBR', locale: 'pt-BR', code: 'por', name: 'Portuguese', language: 'Brazilian Portuguese' }, { cr_locale: 'pt-PT', locale: 'pt-PT', code: 'por', name: 'Portuguese (Portugal)', language: 'Portugues (Portugal)' }, { cr_locale: 'fr-FR', hd_locale: 'French', locale: 'fr', code: 'fra', name: 'French' }, { cr_locale: 'de-DE', hd_locale: 'German', locale: 'de', code: 'deu', name: 'German' }, @@ -142,9 +143,9 @@ const sortTags = (data: string[]) => { return sort.map(e => e.locale as string); }; -const subsFile = (fnOutput:string, subsIndex: string, langItem: LanguageItem, isCC: boolean, ccTag: string) => { +const subsFile = (fnOutput:string, subsIndex: string, langItem: LanguageItem, isCC: boolean, ccTag: string, isSigns?: boolean, format?: string) => { subsIndex = (parseInt(subsIndex) + 1).toString().padStart(2, '0'); - return `${fnOutput}.${subsIndex}.${langItem.code}.${langItem.language}${isCC ? `.${ccTag}` : ''}.ass`; + return `${fnOutput}.${subsIndex}.${langItem.code}.${langItem.language}${isCC ? `.${ccTag}` : ''}${isSigns ? '.signs' : ''}.${format ? format : 'ass'}`; }; // construct dub langs const diff --git a/modules/module.merger.ts b/modules/module.merger.ts index 5cf98f5..e3d8b56 100644 --- a/modules/module.merger.ts +++ b/modules/module.merger.ts @@ -21,6 +21,7 @@ export type SubtitleInput = { language: LanguageItem, file: string, closedCaption?: boolean, + signs?: boolean, delay?: number } @@ -37,6 +38,7 @@ export type MergerOptions = { onlyVid: MergerInput[], onlyAudio: MergerInput[], subtitles: SubtitleInput[], + chapters?: MergerInput[], ccTag: string, output: string, videoTitle?: string, @@ -162,7 +164,7 @@ class Merger { args.push(`-i "${sub.file}"`); } - if (this.options.output.split('.').pop() === 'mkv') + if (this.options.output.split('.').pop() === 'mkv') { if (this.options.fonts) { let fontIndex = 0; for (const font of this.options.fonts) { @@ -170,6 +172,9 @@ class Merger { fontIndex++; } } + } + + //TODO: Make it possible for chapters to work with ffmpeg merging args.push(...metaData); args.push(...this.options.subtitles.map((_, subIndex) => `-map ${subIndex + index}`)); @@ -178,7 +183,7 @@ class Merger { '-c:a copy', this.options.output.split('.').pop()?.toLowerCase() === 'mp4' ? '-c:s mov_text' : '-c:s ass', ...this.options.subtitles.map((sub, subindex) => `-metadata:s:s:${subindex} title="${ - (sub.language.language || sub.language.name) + `${sub.closedCaption === true ? ` ${this.options.ccTag}` : ''}` + (sub.language.language || sub.language.name) + `${sub.closedCaption === true ? ` ${this.options.ccTag}` : ''}` + `${sub.signs === true ? ' Signs' : ''}` }" -metadata:s:s:${subindex} language=${sub.language.code}`) ); args.push(...this.options.options.ffmpeg); @@ -281,7 +286,7 @@ class Merger { `--sync 0:-${Math.ceil(subObj.delay*1000)}` ); } - args.push('--track-name', `0:"${(subObj.language.language || subObj.language.name) + `${subObj.closedCaption === true ? ` ${this.options.ccTag}` : ''}`}"`); + args.push('--track-name', `0:"${(subObj.language.language || subObj.language.name) + `${subObj.closedCaption === true ? ` ${this.options.ccTag}` : ''}` + `${subObj.signs === true ? ' Signs' : ''}`}"`); args.push('--language', `0:"${subObj.language.code}"`); //TODO: look into making Closed Caption default if it's the only sub of the default language downloaded if (this.options.defaults.sub.code === subObj.language.code && !subObj.closedCaption) { @@ -296,6 +301,7 @@ class Merger { '--no-subtitles', ); } + if (this.options.fonts && this.options.fonts.length > 0) { for (const f of this.options.fonts) { args.push('--attachment-name', f.name); @@ -308,6 +314,10 @@ class Merger { ); } + if (this.options.chapters && this.options.chapters.length > 0) { + args.push(`--chapters "${this.options.chapters[0].path}"`); + } + return args.join(' '); }; @@ -405,6 +415,7 @@ class Merger { public cleanUp() { this.options.onlyAudio.concat(this.options.onlyVid).concat(this.options.videoAndAudio).forEach(a => fs.unlinkSync(a.path)); + this.options.chapters?.forEach(a => fs.unlinkSync(a.path)); this.options.subtitles.forEach(a => fs.unlinkSync(a.file)); } diff --git a/modules/module.req.ts b/modules/module.req.ts index 31dbcc4..232abe0 100644 --- a/modules/module.req.ts +++ b/modules/module.req.ts @@ -61,7 +61,9 @@ class Req { options.headers = {...options.headers, ...params.headers}; } if(options.method == 'POST'){ - (options.headers as Headers)['Content-Type'] = 'application/x-www-form-urlencoded'; + if (!(options.headers as Headers)['Content-Type']) { + (options.headers as Headers)['Content-Type'] = 'application/x-www-form-urlencoded'; + } } if(params.body){ options.body = params.body; diff --git a/modules/module.transform-mpd.ts b/modules/module.transform-mpd.ts new file mode 100644 index 0000000..a56a42c --- /dev/null +++ b/modules/module.transform-mpd.ts @@ -0,0 +1,122 @@ +import { parse as mpdParse } from 'mpd-parser'; +import { LanguageItem, findLang, languages } from './module.langsData'; + +type Segment = { + uri: string; + timeline: number; + duration: number; + map: { + uri: string; + }; + number: number; + presentationTime: number; +} + +export type PlaylistItem = { + pssh?: string, + bandwidth: number, + segments: Segment[] +} + + +type AudioPlayList = { + language: LanguageItem, + default: boolean +} & PlaylistItem + +type VideoPlayList = { + quality: { + width: number, + height: number + } +} & PlaylistItem + +export type MPDParsed = { + [server: string]: { + audio: AudioPlayList[], + video: VideoPlayList[] + } +} + +export function parse(manifest: string, language?: LanguageItem, url?: string) { + if (!manifest.includes('BaseURL') && url) { + manifest = manifest.replace(/(]*>)/gm, `$1${url}`); + } + const parsed = mpdParse(manifest); + const ret: MPDParsed = {}; + + for (const item of Object.values(parsed.mediaGroups.AUDIO.audio)){ + for (const playlist of item.playlists) { + const host = new URL(playlist.resolvedUri).hostname; + if (!Object.prototype.hasOwnProperty.call(ret, host)) + ret[host] = { audio: [], video: [] }; + + //Find and add audio language if it is found in the MPD + let audiolang: LanguageItem; + const foundlanguage = findLang(languages.find(a => a.code === item.language)?.cr_locale ?? 'unknown'); + if (item.language) { + audiolang = foundlanguage; + } else { + audiolang = language ? language : foundlanguage; + } + const pItem: AudioPlayList = { + bandwidth: playlist.attributes.BANDWIDTH, + language: audiolang, + default: item.default, + segments: playlist.segments.map((segment): Segment => { + const uri = segment.resolvedUri; + const map_uri = segment.map.resolvedUri; + return { + duration: segment.duration, + map: { uri: map_uri }, + number: segment.number, + presentationTime: segment.presentationTime, + timeline: segment.timeline, + uri + }; + }) + }; + + if (playlist.contentProtection && + playlist.contentProtection?.['com.widevine.alpha'].pssh) + pItem.pssh = arrayBufferToBase64(playlist.contentProtection['com.widevine.alpha'].pssh); + + ret[host].audio.push(pItem); + } + } + + for (const playlist of parsed.playlists) { + const host = new URL(playlist.resolvedUri).hostname; + if (!Object.prototype.hasOwnProperty.call(ret, host)) + ret[host] = { audio: [], video: [] }; + + const pItem: VideoPlayList = { + bandwidth: playlist.attributes.BANDWIDTH, + quality: playlist.attributes.RESOLUTION!, + segments: playlist.segments.map((segment): Segment => { + const uri = segment.resolvedUri; + const map_uri = segment.map.resolvedUri; + return { + duration: segment.duration, + map: { uri: map_uri }, + number: segment.number, + presentationTime: segment.presentationTime, + timeline: segment.timeline, + uri + }; + }) + }; + + if (playlist.contentProtection && + playlist.contentProtection?.['com.widevine.alpha'].pssh) + pItem.pssh = arrayBufferToBase64(playlist.contentProtection['com.widevine.alpha'].pssh); + + ret[host].video.push(pItem); + } + + return ret; +} + +function arrayBufferToBase64(buffer: Uint8Array): string { + return Buffer.from(buffer).toString('base64'); +} diff --git a/modules/module.vtt2ass.ts b/modules/module.vtt2ass.ts index a661fa3..9c5f7ea 100644 --- a/modules/module.vtt2ass.ts +++ b/modules/module.vtt2ass.ts @@ -69,7 +69,7 @@ function loadCSS(cssStr: string): Css { function parseStyle(stylegroup: string, line: string, style: any) { const defaultSFont = rFont == '' ? defaultStyleFont : rFont; //redeclare cause of let - if (stylegroup.startsWith('Subtitle') || stylegroup.startsWith('Song')) { //base for dialog, everything else use defaultStyle + if (stylegroup.startsWith('Subtitle') || stylegroup.startsWith('Song') || stylegroup.startsWith('Q0') || stylegroup.startsWith('Q1')) { //base for dialog, everything else use defaultStyle style = `${defaultSFont},${fontSize},&H00FFFFFF,&H000000FF,&H00000000,&H00000000,0,0,0,0,100,100,0,0,1,2.6,0,2,20,20,46,1`; } @@ -261,6 +261,7 @@ function convert(css: Css, vtt: Vtt[]) { song_cap: [], }; const linesMap: Record = {}; + let previousLine: ReturnType | undefined = undefined; for (const l in vtt) { const x = convertLine(stylesMap, vtt[l]); if (x.ind !== '' && linesMap[x.ind] !== undefined) { @@ -278,7 +279,17 @@ function convert(css: Css, vtt: Vtt[]) { linesMap[x.ind] = events[x.type as keyof typeof events].length - 1; } } - + /** + * What cursed code have I brought upon this land? + * This checks if a subtitle should be multi-line, and if it is, pops the just inserted + * subtitle and the previous subtitle, and merges them into a single subtitle. + */ + if (previousLine?.start == x.start && previousLine.type == x.type && previousLine.style == x.style) { + events[x.type as keyof typeof events].pop(); + const previousLinePop = events[x.type as keyof typeof events].pop(); + events[x.type as keyof typeof events].push(previousLinePop + '\\N'+x.text); + } + previousLine = x; } if (events.subtitle.length > 0) { ass = ass.concat( @@ -399,6 +410,23 @@ function vtt(group: string | undefined, xFontSize: number | undefined, vttStr: s fontSize = xFontSize && xFontSize > 0 ? xFontSize : 34; // 1em to pix tmMrg = timeMargin ? timeMargin : 0; // rFont = replaceFont ? replaceFont : rFont; + if (vttStr.match(/::cue(?:.(.+)\))?{([^}]+)}/g)) { + const cssLines = []; + let defaultCss = ''; + const cssGroups = vttStr.matchAll(/::cue(?:.(.+)\))?{([^}]+)}/g); + for (const cssGroup of cssGroups) { + //Below code will bulldoze defined sizes for custom ones + /*if (!options.originalFontSize) { + cssGroup[2] = cssGroup[2].replace(/( font-size:.+?;)/g, '').replace(/(font-size:.+?;)/g, ''); + }*/ + if (cssGroup[1]) { + cssLines.push(`${cssGroup[1]}{${defaultCss}${cssGroup[2]}}`); + } else { + defaultCss = cssGroup[2]; + } + } + cssStr += cssLines.join('\r\n'); + } return convert( loadCSS(cssStr), loadVTT(vttStr) diff --git a/modules/widevine.ts b/modules/widevine.ts new file mode 100644 index 0000000..3d7c88d --- /dev/null +++ b/modules/widevine.ts @@ -0,0 +1,77 @@ +import { KeyContainer, Session } from './license'; +import fs from 'fs'; +import { console } from './log'; +import got from 'got'; +import { workingDir } from './module.cfg-loader'; +import path from 'path'; +import { ReadError, Response } from 'got'; + +//read cdm files located in the same directory +let privateKey: Buffer, identifierBlob: Buffer; +export let canDecrypt: boolean; +try { + privateKey = fs.readFileSync(path.join(workingDir, 'widevine', 'device_private_key')); + identifierBlob = fs.readFileSync(path.join(workingDir, 'widevine', 'device_client_id_blob')); + canDecrypt = true; +} catch (e) { + canDecrypt = false; +} + +export default async function getKeys(pssh: string | undefined, licenseServer: string, authData: Record): Promise { + if (!pssh || !canDecrypt) return []; + //pssh found in the mpd manifest + const psshBuffer = Buffer.from( + pssh, + 'base64' + ); + + //Create a new widevine session + const session = new Session({ privateKey, identifierBlob }, psshBuffer); + + //Generate license + let response; + try { + response = await got(licenseServer, { + method: 'POST', + body: session.createLicenseRequest(), + headers: authData, + responseType: 'text' + }); + } catch(_error){ + const error = _error as { + name: string + } & ReadError & { + res: Response + }; + if(error.response && error.response.statusCode && error.response.statusMessage){ + console.error(`${error.name} ${error.response.statusCode}: ${error.response.statusMessage}`); + } else{ + console.error(`${error.name}: ${error.code || error.message}`); + } + if(error.response && !error.res){ + error.res = error.response; + const docTitle = (error.res.body as string).match(/(.*)<\/title>/); + if(error.res.body && docTitle){ + console.error(docTitle[1]); + } + } + if(error.res && error.res.body && error.response.statusCode + && error.response.statusCode != 404 && error.response.statusCode != 403){ + console.error('Body:', error.res.body); + } + return []; + } + + if (response.statusCode === 200) { + //Parse License and return keys + try { + const json = JSON.parse(response.body); + return session.parseLicense(Buffer.from(json['license'], 'base64')); + } catch { + return session.parseLicense(response.rawBody); + } + } else { + console.info('License request failed:', response.statusMessage, response.body); + return []; + } +} diff --git a/package.json b/package.json index fcf19e4..aceab43 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "multi-downloader-nx", "short_name": "aniDL", - "version": "4.4.4", + "version": "4.5.1", "description": "Downloader for Crunchyroll, Funimation, or Hidive via CLI or GUI", "keywords": [ "download", @@ -45,6 +45,8 @@ "@babel/core": "^7.22.9", "@babel/plugin-syntax-flow": "^7.22.5", "@babel/plugin-transform-react-jsx": "^7.22.5", + "@types/xmldom": "^0.1.34", + "@yao-pkg/pkg": "^5.11.1", "cheerio": "1.0.0-rc.12", "cors": "^2.8.5", "dotenv": "^16.3.1", @@ -56,12 +58,16 @@ "got": "^11.8.6", "iso-639": "^0.2.2", "log4js": "^6.9.1", + "long": "^5.2.3", "lookpath": "^1.2.2", "m3u8-parsed": "^1.3.0", + "mpd-parser": "^1.3.0", "open": "^8.4.2", + "protobufjs": "^7.2.5", "sei-helper": "^3.3.0", "typescript-eslint": "0.0.1-alpha.0", "ws": "^8.13.0", + "xmldom": "^0.6.0", "yaml": "^2.3.1", "yargs": "^17.7.2" }, @@ -69,7 +75,6 @@ "@types/cors": "^2.8.13", "@types/express": "^4.17.17", "@types/ffprobe": "^1.1.4", - "@types/ffprobe-static": "^2.0.1", "@types/fs-extra": "^11.0.1", "@types/node": "^18.15.11", "@types/ws": "^8.5.5", @@ -82,9 +87,10 @@ "eslint-config-react-app": "^7.0.1", "eslint-plugin-import": "^2.27.5", "eslint-plugin-react": "7.32.2", - "pkg": "^5.8.1", + "protoc": "^1.1.3", "removeNPMAbsolutePaths": "^3.0.1", "ts-node": "^10.9.1", + "ts-proto": "^1.169.1", "typescript": "5.1.6" }, "scripts": { @@ -92,19 +98,24 @@ "start": "pnpm prestart && cd lib && node gui.js", "docs": "ts-node modules/build-docs.ts", "tsc": "ts-node tsc.ts", + "proto:compile": "protoc --plugin=protoc-gen-ts_proto=.\\node_modules\\.bin\\protoc-gen-ts_proto.cmd --ts_proto_opt=\"esModuleInterop=true\" --ts_proto_opt=\"forceLong=long\" --ts_proto_opt=\"env=node\" --ts_proto_out=. modules/*.proto", "prebuild-cli": "pnpm run tsc false false", - "build-windows-cli": "pnpm run prebuild-cli && cd lib && node modules/build windows64", - "build-ubuntu-cli": "pnpm run prebuild-cli && cd lib && node modules/build ubuntu64", - "build-arm-cli": "pnpm run prebuild-cli && cd lib && node modules/build arm64", - "build-macos-cli": "pnpm run prebuild-cli && cd lib && node modules/build macos64", + "build-windows-cli": "pnpm run prebuild-cli && cd lib && node modules/build windows-x64", + "build-linux-cli": "pnpm run prebuild-cli && cd lib && node modules/build linuxstatic-x64", + "build-arm-cli": "pnpm run prebuild-cli && cd lib && node modules/build linux-arm64", + "build-macos-cli": "pnpm run prebuild-cli && cd lib && node modules/build macos-x64", + "build-alpine-cli": "pnpm run prebuild-cli && cd lib && node modules/build alpine-x64", + "build-android-cli": "pnpm run prebuild-cli && cd lib && node modules/build linuxstatic-armv7", "prebuild-gui": "pnpm run tsc", - "build-windows-gui": "pnpm run prebuild-gui && cd lib && node modules/build windows64 true", - "build-ubuntu-gui": "pnpm run prebuild-gui && cd lib && node modules/build ubuntu64 true", - "build-arm-gui": "pnpm run prebuild-gui && cd lib && node modules/build arm64 true", - "build-macos-gui": "pnpm run prebuild-gui && cd lib && node modules/build macos64 true", + "build-windows-gui": "pnpm run prebuild-gui && cd lib && node modules/build windows-x64 true", + "build-linux-gui": "pnpm run prebuild-gui && cd lib && node modules/build linuxstatic-x64 true", + "build-arm-gui": "pnpm run prebuild-gui && cd lib && node modules/build linux-arm64 true", + "build-macos-gui": "pnpm run prebuild-gui && cd lib && node modules/build macos-x64 true", + "build-alpine-gui": "pnpm run prebuild-gui && cd lib && node modules/build alpine-x64 true", + "build-android-gui": "pnpm run prebuild-gui && cd lib && node modules/build linuxstatic-armv7 true", "eslint": "eslint *.js modules", "eslint-fix": "eslint *.js modules --fix", "pretest": "pnpm run tsc", - "test": "pnpm run pretest && cd lib && node modules/build windows64 && node modules/build ubuntu64 && node modules/build macos64" + "test": "pnpm run pretest && cd lib && node modules/build windows-x64 && node modules/build linuxstatic-x64 && node modules/build macos-x64" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ba0e602..48aad3c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,13 +7,19 @@ settings: dependencies: '@babel/core': specifier: ^7.22.9 - version: 7.22.9 + version: 7.24.0 '@babel/plugin-syntax-flow': specifier: ^7.22.5 - version: 7.22.5(@babel/core@7.22.9) + version: 7.23.3(@babel/core@7.24.0) '@babel/plugin-transform-react-jsx': specifier: ^7.22.5 - version: 7.22.5(@babel/core@7.22.9) + version: 7.23.4(@babel/core@7.24.0) + '@types/xmldom': + specifier: ^0.1.34 + version: 0.1.34 + '@yao-pkg/pkg': + specifier: ^5.11.1 + version: 5.11.5 cheerio: specifier: 1.0.0-rc.12 version: 1.0.0-rc.12 @@ -22,13 +28,13 @@ dependencies: version: 2.8.5 dotenv: specifier: ^16.3.1 - version: 16.3.1 + version: 16.4.5 eslint-plugin-import: specifier: ^2.27.5 - version: 2.27.5(@typescript-eslint/parser@6.0.0)(eslint@8.45.0) + version: 2.29.1(@typescript-eslint/parser@6.0.0)(eslint@8.57.0) express: specifier: ^4.18.2 - version: 4.18.2 + version: 4.18.3 ffprobe: specifier: ^1.1.2 version: 1.1.2 @@ -37,7 +43,7 @@ dependencies: version: 4.0.0 fs-extra: specifier: ^11.1.1 - version: 11.1.1 + version: 11.2.0 got: specifier: ^11.8.6 version: 11.8.6 @@ -47,15 +53,24 @@ dependencies: log4js: specifier: ^6.9.1 version: 6.9.1 + long: + specifier: ^5.2.3 + version: 5.2.3 lookpath: specifier: ^1.2.2 version: 1.2.2 m3u8-parsed: specifier: ^1.3.0 version: 1.3.0 + mpd-parser: + specifier: ^1.3.0 + version: 1.3.0 open: specifier: ^8.4.2 version: 8.4.2 + protobufjs: + specifier: ^7.2.5 + version: 7.2.6 sei-helper: specifier: ^3.3.0 version: 3.3.0 @@ -64,10 +79,13 @@ dependencies: version: 0.0.1-alpha.0 ws: specifier: ^8.13.0 - version: 8.13.0 + version: 8.16.0 + xmldom: + specifier: ^0.6.0 + version: 0.6.0 yaml: specifier: ^2.3.1 - version: 2.3.1 + version: 2.4.1 yargs: specifier: ^17.7.2 version: 17.7.2 @@ -75,58 +93,55 @@ dependencies: devDependencies: '@types/cors': specifier: ^2.8.13 - version: 2.8.13 + version: 2.8.17 '@types/express': specifier: ^4.17.17 - version: 4.17.17 + version: 4.17.21 '@types/ffprobe': specifier: ^1.1.4 - version: 1.1.4 - '@types/ffprobe-static': - specifier: ^2.0.1 - version: 2.0.1 + version: 1.1.8 '@types/fs-extra': specifier: ^11.0.1 - version: 11.0.1 + version: 11.0.4 '@types/node': specifier: ^18.15.11 version: 18.15.11 '@types/ws': specifier: ^8.5.5 - version: 8.5.5 + version: 8.5.10 '@types/yargs': specifier: ^17.0.24 - version: 17.0.24 + version: 17.0.32 '@typescript-eslint/eslint-plugin': specifier: ^6.0.0 - version: 6.0.0(@typescript-eslint/parser@6.0.0)(eslint@8.45.0)(typescript@5.1.6) + version: 6.0.0(@typescript-eslint/parser@6.0.0)(eslint@8.57.0)(typescript@5.1.6) '@typescript-eslint/parser': specifier: ^6.0.0 - version: 6.0.0(eslint@8.45.0)(typescript@5.1.6) + version: 6.0.0(eslint@8.57.0)(typescript@5.1.6) '@vercel/webpack-asset-relocator-loader': specifier: ^1.7.3 version: 1.7.3 - '@yao-pkg/pkg': - specifier: ^5.11.1 - version: 5.11.1 eslint: specifier: ^8.45.0 - version: 8.45.0 + version: 8.57.0 eslint-config-react-app: specifier: ^7.0.1 - version: 7.0.1(@babel/plugin-syntax-flow@7.22.5)(@babel/plugin-transform-react-jsx@7.22.5)(eslint@8.45.0)(typescript@5.1.6) + version: 7.0.1(@babel/plugin-syntax-flow@7.23.3)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)(typescript@5.1.6) eslint-plugin-react: specifier: 7.32.2 - version: 7.32.2(eslint@8.45.0) - pkg: - specifier: ^5.8.1 - version: 5.8.1 + version: 7.32.2(eslint@8.57.0) + protoc: + specifier: ^1.1.3 + version: 1.1.3 removeNPMAbsolutePaths: specifier: ^3.0.1 version: 3.0.1 ts-node: specifier: ^10.9.1 - version: 10.9.1(@types/node@18.15.11)(typescript@5.1.6) + version: 10.9.2(@types/node@18.15.11)(typescript@5.1.6) + ts-proto: + specifier: ^1.169.1 + version: 1.169.1 typescript: specifier: 5.1.6 version: 5.1.6 @@ -144,43 +159,32 @@ packages: '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.18 - /@babel/code-frame@7.21.4: - resolution: {integrity: sha512-LYvhNKfwWSPpocw8GI7gpK2nq3HSDuEPC/uSYaALSJu9xjsalaaYFOq0Pwt5KmVqwEbZlDu81aLXwBOmD/Fv9g==} + /@babel/code-frame@7.23.5: + resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/highlight': 7.18.6 - dev: true + '@babel/highlight': 7.23.4 + chalk: 2.4.2 - /@babel/code-frame@7.22.5: - resolution: {integrity: sha512-Xmwn266vad+6DAqEB2A6V/CcZVp62BbwVmcOJc2RPuwih1kw02TjQvWVWlcKGbBPd+8/0V5DEkOcizRGYsspYQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/highlight': 7.22.5 - - /@babel/compat-data@7.21.4: - resolution: {integrity: sha512-/DYyDpeCfaVinT40FPGdkkb+lYSKvsVuMjDAG7jPOWWiM1ibOaB9CXJAlc4d1QpP/U2q2P9jbrSlClKSErd55g==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/compat-data@7.22.9: - resolution: {integrity: sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ==} + /@babel/compat-data@7.23.5: + resolution: {integrity: sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw==} engines: {node: '>=6.9.0'} - /@babel/core@7.22.9: - resolution: {integrity: sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w==} + /@babel/core@7.24.0: + resolution: {integrity: sha512-fQfkg0Gjkza3nf0c7/w6Xf34BW4YvzNfACRLmmb7XRLa6XHdR+K9AlJlxneFfWYf6uhOzuzZVTjF/8KfndZANw==} engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.2.1 - '@babel/code-frame': 7.22.5 - '@babel/generator': 7.22.9 - '@babel/helper-compilation-targets': 7.22.9(@babel/core@7.22.9) - '@babel/helper-module-transforms': 7.22.9(@babel/core@7.22.9) - '@babel/helpers': 7.22.6 - '@babel/parser': 7.22.7 - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.8 - '@babel/types': 7.22.5 - convert-source-map: 1.9.0 + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.6 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0) + '@babel/helpers': 7.24.0 + '@babel/parser': 7.24.0 + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.0 + '@babel/types': 7.24.0 + convert-source-map: 2.0.0 debug: 4.3.4 gensync: 1.0.0-beta.2 json5: 2.2.3 @@ -188,230 +192,155 @@ packages: transitivePeerDependencies: - supports-color - /@babel/eslint-parser@7.21.3(@babel/core@7.22.9)(eslint@8.45.0): + /@babel/eslint-parser@7.21.3(@babel/core@7.24.0)(eslint@8.57.0): resolution: {integrity: sha512-kfhmPimwo6k4P8zxNs8+T7yR44q1LdpsZdE1NkCsVlfiuTPRfnGgjaF8Qgug9q9Pou17u6wneYF0lDCZJATMFg==} engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} peerDependencies: '@babel/core': '>=7.11.0' eslint: ^7.5.0 || ^8.0.0 dependencies: - '@babel/core': 7.22.9 + '@babel/core': 7.24.0 '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 - eslint: 8.45.0 + eslint: 8.57.0 eslint-visitor-keys: 2.1.0 semver: 6.3.1 dev: true - /@babel/generator@7.18.2: - resolution: {integrity: sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.0 - '@jridgewell/gen-mapping': 0.3.3 - jsesc: 2.5.2 - dev: true - - /@babel/generator@7.22.9: - resolution: {integrity: sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.0 - '@jridgewell/gen-mapping': 0.3.3 - '@jridgewell/trace-mapping': 0.3.18 - jsesc: 2.5.2 - /@babel/generator@7.23.0: resolution: {integrity: sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.24.0 '@jridgewell/gen-mapping': 0.3.3 '@jridgewell/trace-mapping': 0.3.18 jsesc: 2.5.2 + dev: false - /@babel/helper-annotate-as-pure@7.18.6: - resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} + /@babel/generator@7.23.6: + resolution: {integrity: sha512-qrSfCYxYQB5owCmGLbl8XRpX1ytXlpueOb0N0UmQwA073KZxejgQTzAmJezxvpwQD9uGtK2shHdi55QT+MbjIw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 - dev: true + '@babel/types': 7.24.0 + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.18 + jsesc: 2.5.2 /@babel/helper-annotate-as-pure@7.22.5: resolution: {integrity: sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.24.0 /@babel/helper-builder-binary-assignment-operator-visitor@7.18.9: resolution: {integrity: sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-explode-assignable-expression': 7.18.6 - '@babel/types': 7.23.0 + '@babel/types': 7.24.0 dev: true - /@babel/helper-compilation-targets@7.21.4(@babel/core@7.22.9): - resolution: {integrity: sha512-Fa0tTuOXZ1iL8IeDFUWCzjZcn+sJGd9RZdH9esYVjEejGmzf+FFYQpMi/kZUk2kPy/q1H3/GPw7np8qar/stfg==} + /@babel/helper-compilation-targets@7.23.6: + resolution: {integrity: sha512-9JB548GZoQVmzrFgp8o7KxdgkTGm6xs9DW0o/Pim72UDjzr5ObUQ6ZzYPqA+g9OTS2bBQoctLJrky0RDCAWRgQ==} engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 dependencies: - '@babel/compat-data': 7.21.4 - '@babel/core': 7.22.9 - '@babel/helper-validator-option': 7.21.0 - browserslist: 4.21.5 - lru-cache: 5.1.1 - semver: 6.3.1 - dev: true - - /@babel/helper-compilation-targets@7.22.9(@babel/core@7.22.9): - resolution: {integrity: sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/compat-data': 7.22.9 - '@babel/core': 7.22.9 - '@babel/helper-validator-option': 7.22.5 - browserslist: 4.21.9 + '@babel/compat-data': 7.23.5 + '@babel/helper-validator-option': 7.23.5 + browserslist: 4.23.0 lru-cache: 5.1.1 semver: 6.3.1 - /@babel/helper-create-class-features-plugin@7.21.4(@babel/core@7.22.9): + /@babel/helper-create-class-features-plugin@7.21.4(@babel/core@7.24.0): resolution: {integrity: sha512-46QrX2CQlaFRF4TkwfTt6nJD7IHq8539cCL7SDpqWSDeJKY1xylKKY5F/33mJhLZ3mFvKv2gGrVS6NkyF6qs+Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.21.0 + '@babel/core': 7.24.0 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 '@babel/helper-member-expression-to-functions': 7.21.0 '@babel/helper-optimise-call-expression': 7.18.6 '@babel/helper-replace-supers': 7.20.7 '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 - '@babel/helper-split-export-declaration': 7.18.6 + '@babel/helper-split-export-declaration': 7.22.6 transitivePeerDependencies: - supports-color dev: true - /@babel/helper-create-regexp-features-plugin@7.21.4(@babel/core@7.22.9): + /@babel/helper-create-regexp-features-plugin@7.21.4(@babel/core@7.24.0): resolution: {integrity: sha512-M00OuhU+0GyZ5iBBN9czjugzWrEq2vDpf/zCYHxxf93ul/Q5rv+a5h+/+0WnI1AebHNVtl5bFV0qsJoH23DbfA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-annotate-as-pure': 7.18.6 + '@babel/core': 7.24.0 + '@babel/helper-annotate-as-pure': 7.22.5 regexpu-core: 5.3.2 dev: true - /@babel/helper-define-polyfill-provider@0.3.3(@babel/core@7.22.9): + /@babel/helper-define-polyfill-provider@0.3.3(@babel/core@7.24.0): resolution: {integrity: sha512-z5aQKU4IzbqCC1XH0nAqfsFLMVSo22SBKUc0BxGrLkolTdPTructy0ToNnlO2zA4j9Q/7pjMZf0DSY+DSTYzww==} peerDependencies: '@babel/core': ^7.4.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.22.9) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-plugin-utils': 7.22.5 debug: 4.3.4 lodash.debounce: 4.0.8 - resolve: 1.22.2 + resolve: 1.22.8 semver: 6.3.1 transitivePeerDependencies: - supports-color dev: true - /@babel/helper-environment-visitor@7.18.9: - resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-environment-visitor@7.22.5: - resolution: {integrity: sha512-XGmhECfVA/5sAt+H+xpSg0mfrHq6FzNr9Oxh7PSEBBRUb/mL7Kz3NICXb194rCqAEdxkhPT1a88teizAFyvk8Q==} + /@babel/helper-environment-visitor@7.22.20: + resolution: {integrity: sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==} engines: {node: '>=6.9.0'} /@babel/helper-explode-assignable-expression@7.18.6: resolution: {integrity: sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.24.0 dev: true - /@babel/helper-function-name@7.21.0: - resolution: {integrity: sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==} + /@babel/helper-function-name@7.23.0: + resolution: {integrity: sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.20.7 - '@babel/types': 7.23.0 - dev: true - - /@babel/helper-function-name@7.22.5: - resolution: {integrity: sha512-wtHSq6jMRE3uF2otvfuD3DIvVhOsSNshQl0Qrd7qC9oQJzHvOL4qQXlQn2916+CXGywIjpGuIkoyZRRxHPiNQQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.22.5 - '@babel/types': 7.23.0 - - /@babel/helper-hoist-variables@7.18.6: - resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.0 - dev: true + '@babel/template': 7.24.0 + '@babel/types': 7.24.0 /@babel/helper-hoist-variables@7.22.5: resolution: {integrity: sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.24.0 /@babel/helper-member-expression-to-functions@7.21.0: resolution: {integrity: sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.24.0 dev: true - /@babel/helper-module-imports@7.21.4: - resolution: {integrity: sha512-orajc5T2PsRYUN3ZryCEFeMDYwyw09c/pZeaQEZPH0MpKzSvn3e0uXsDBu3k03VI+9DBiRo+l22BfKTpKwa/Wg==} + /@babel/helper-module-imports@7.22.15: + resolution: {integrity: sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 - dev: true + '@babel/types': 7.24.0 - /@babel/helper-module-imports@7.22.5: - resolution: {integrity: sha512-8Dl6+HD/cKifutF5qGd/8ZJi84QeAKh+CEe1sBzz8UayBBGg1dAIJrdHOcOM5b2MpzWL2yuotJTtGjETq0qjXg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.0 - - /@babel/helper-module-transforms@7.21.2: - resolution: {integrity: sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-module-imports': 7.21.4 - '@babel/helper-simple-access': 7.20.2 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/helper-validator-identifier': 7.22.20 - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.4 - '@babel/types': 7.23.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-module-transforms@7.22.9(@babel/core@7.22.9): - resolution: {integrity: sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ==} + /@babel/helper-module-transforms@7.23.3(@babel/core@7.24.0): + resolution: {integrity: sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-module-imports': 7.22.5 + '@babel/core': 7.24.0 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-module-imports': 7.22.15 '@babel/helper-simple-access': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 '@babel/helper-validator-identifier': 7.22.20 @@ -420,29 +349,24 @@ packages: resolution: {integrity: sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 - dev: true - - /@babel/helper-plugin-utils@7.20.2: - resolution: {integrity: sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==} - engines: {node: '>=6.9.0'} + '@babel/types': 7.24.0 dev: true /@babel/helper-plugin-utils@7.22.5: resolution: {integrity: sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg==} engines: {node: '>=6.9.0'} - /@babel/helper-remap-async-to-generator@7.18.9(@babel/core@7.22.9): + /@babel/helper-remap-async-to-generator@7.18.9(@babel/core@7.24.0): resolution: {integrity: sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-environment-visitor': 7.18.9 + '@babel/core': 7.24.0 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-wrap-function': 7.20.5 - '@babel/types': 7.23.0 + '@babel/types': 7.24.0 transitivePeerDependencies: - supports-color dev: true @@ -451,1110 +375,1057 @@ packages: resolution: {integrity: sha512-vujDMtB6LVfNW13jhlCrp48QNslK6JXi7lQG736HVbHz/mbf4Dc7tIRh1Xf5C0rF7BP8iiSxGMCmY6Ci1ven3A==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-environment-visitor': 7.18.9 + '@babel/helper-environment-visitor': 7.22.20 '@babel/helper-member-expression-to-functions': 7.21.0 '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.4 - '@babel/types': 7.23.0 + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.0 + '@babel/types': 7.24.0 transitivePeerDependencies: - supports-color dev: true - /@babel/helper-simple-access@7.20.2: - resolution: {integrity: sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.0 - dev: true - /@babel/helper-simple-access@7.22.5: resolution: {integrity: sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.24.0 /@babel/helper-skip-transparent-expression-wrappers@7.20.0: resolution: {integrity: sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 - dev: true - - /@babel/helper-split-export-declaration@7.18.6: - resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.24.0 dev: true /@babel/helper-split-export-declaration@7.22.6: resolution: {integrity: sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==} engines: {node: '>=6.9.0'} dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.24.0 - /@babel/helper-string-parser@7.22.5: - resolution: {integrity: sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==} + /@babel/helper-string-parser@7.23.4: + resolution: {integrity: sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ==} engines: {node: '>=6.9.0'} /@babel/helper-validator-identifier@7.22.20: resolution: {integrity: sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==} engines: {node: '>=6.9.0'} - /@babel/helper-validator-option@7.21.0: - resolution: {integrity: sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-validator-option@7.22.5: - resolution: {integrity: sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw==} + /@babel/helper-validator-option@7.23.5: + resolution: {integrity: sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw==} engines: {node: '>=6.9.0'} /@babel/helper-wrap-function@7.20.5: resolution: {integrity: sha512-bYMxIWK5mh+TgXGVqAtnu5Yn1un+v8DDZtqyzKRLUzrh70Eal2O3aZ7aPYiMADO4uKlkzOiRiZ6GX5q3qxvW9Q==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-function-name': 7.21.0 - '@babel/template': 7.20.7 - '@babel/traverse': 7.21.4 - '@babel/types': 7.23.0 + '@babel/helper-function-name': 7.23.0 + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.0 + '@babel/types': 7.24.0 transitivePeerDependencies: - supports-color dev: true - /@babel/helpers@7.22.6: - resolution: {integrity: sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA==} + /@babel/helpers@7.24.0: + resolution: {integrity: sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/template': 7.22.5 - '@babel/traverse': 7.22.8 - '@babel/types': 7.23.0 + '@babel/template': 7.24.0 + '@babel/traverse': 7.24.0 + '@babel/types': 7.24.0 transitivePeerDependencies: - supports-color - /@babel/highlight@7.18.6: - resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} + /@babel/highlight@7.23.4: + resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} engines: {node: '>=6.9.0'} dependencies: '@babel/helper-validator-identifier': 7.22.20 chalk: 2.4.2 js-tokens: 4.0.0 - dev: true - - /@babel/highlight@7.22.5: - resolution: {integrity: sha512-BSKlD1hgnedS5XRnGOljZawtag7H1yPfQp0tdNJCHoH6AZ+Pcm9VvkrK59/Yy593Ypg0zMxH2BxD1VPYUQ7UIw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.22.20 - chalk: 2.4.2 - js-tokens: 4.0.0 - - /@babel/parser@7.18.4: - resolution: {integrity: sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.23.0 - dev: true - - /@babel/parser@7.22.7: - resolution: {integrity: sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.23.0 /@babel/parser@7.23.0: resolution: {integrity: sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==} engines: {node: '>=6.0.0'} hasBin: true dependencies: - '@babel/types': 7.23.0 + '@babel/types': 7.24.0 + dev: false - /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.18.6(@babel/core@7.22.9): + /@babel/parser@7.24.0: + resolution: {integrity: sha512-QuP/FxEAzMSjXygs8v4N9dvdXzEHN4W1oF3PxuWAtPo08UdM17u89RDMgjLn/mlc56iM0HlLmVkO/wgR+rDgHg==} + engines: {node: '>=6.0.0'} + hasBin: true + dependencies: + '@babel/types': 7.24.0 + + /@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.20.7(@babel/core@7.22.9): + /@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@7.20.7(@babel/core@7.24.0): resolution: {integrity: sha512-sbr9+wNE5aXMBBFBICk01tt7sBf2Oc9ikRFEcem/ZORup9IMUdNhW7/wVLEbbtlWOsEubJet46mHAL2C8+2jKQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.13.0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 - '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.22.9) + '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.24.0) dev: true - /@babel/plugin-proposal-async-generator-functions@7.20.7(@babel/core@7.22.9): + /@babel/plugin-proposal-async-generator-functions@7.20.7(@babel/core@7.24.0): resolution: {integrity: sha512-xMbiLsn/8RK7Wq7VeVytytS2L6qE69bXPB10YCmMdDZbKF4okCqY74pI/jJQ/8U0b/F6NrT2+14b8/P9/3AMGA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.22.9) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.9) + '@babel/core': 7.24.0 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.24.0) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.0) transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.22.9): + /@babel/plugin-proposal-class-properties@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-create-class-features-plugin': 7.21.4(@babel/core@7.22.9) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-create-class-features-plugin': 7.21.4(@babel/core@7.24.0) + '@babel/helper-plugin-utils': 7.22.5 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-proposal-class-static-block@7.21.0(@babel/core@7.22.9): + /@babel/plugin-proposal-class-static-block@7.21.0(@babel/core@7.24.0): resolution: {integrity: sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.12.0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-create-class-features-plugin': 7.21.4(@babel/core@7.22.9) - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.9) + '@babel/core': 7.24.0 + '@babel/helper-create-class-features-plugin': 7.21.4(@babel/core@7.24.0) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.0) transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-proposal-decorators@7.21.0(@babel/core@7.22.9): + /@babel/plugin-proposal-decorators@7.21.0(@babel/core@7.24.0): resolution: {integrity: sha512-MfgX49uRrFUTL/HvWtmx3zmpyzMMr4MTj3d527MLlr/4RTT9G/ytFFP7qet2uM2Ve03b+BkpWUpK+lRXnQ+v9w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-create-class-features-plugin': 7.21.4(@babel/core@7.22.9) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-create-class-features-plugin': 7.21.4(@babel/core@7.24.0) + '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-replace-supers': 7.20.7 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/plugin-syntax-decorators': 7.21.0(@babel/core@7.22.9) + '@babel/helper-split-export-declaration': 7.22.6 + '@babel/plugin-syntax-decorators': 7.21.0(@babel/core@7.24.0) transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-proposal-dynamic-import@7.18.6(@babel/core@7.22.9): + /@babel/plugin-proposal-dynamic-import@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.9) + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.0) dev: true - /@babel/plugin-proposal-export-namespace-from@7.18.9(@babel/core@7.22.9): + /@babel/plugin-proposal-export-namespace-from@7.18.9(@babel/core@7.24.0): resolution: {integrity: sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.9) + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.0) dev: true - /@babel/plugin-proposal-json-strings@7.18.6(@babel/core@7.22.9): + /@babel/plugin-proposal-json-strings@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.9) + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.0) dev: true - /@babel/plugin-proposal-logical-assignment-operators@7.20.7(@babel/core@7.22.9): + /@babel/plugin-proposal-logical-assignment-operators@7.20.7(@babel/core@7.24.0): resolution: {integrity: sha512-y7C7cZgpMIjWlKE5T7eJwp+tnRYM89HmRvWM5EQuB5BoHEONjmQ8lSNmBUwOyy/GFRsohJED51YBF79hE1djug==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.9) + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.0) dev: true - /@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.22.9): + /@babel/plugin-proposal-nullish-coalescing-operator@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.9) + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.0) dev: true - /@babel/plugin-proposal-numeric-separator@7.18.6(@babel/core@7.22.9): + /@babel/plugin-proposal-numeric-separator@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.9) + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.0) dev: true - /@babel/plugin-proposal-object-rest-spread@7.20.7(@babel/core@7.22.9): + /@babel/plugin-proposal-object-rest-spread@7.20.7(@babel/core@7.24.0): resolution: {integrity: sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/compat-data': 7.21.4 - '@babel/core': 7.22.9 - '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.22.9) - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.9) - '@babel/plugin-transform-parameters': 7.21.3(@babel/core@7.22.9) + '@babel/compat-data': 7.23.5 + '@babel/core': 7.24.0 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.0) + '@babel/plugin-transform-parameters': 7.21.3(@babel/core@7.24.0) dev: true - /@babel/plugin-proposal-optional-catch-binding@7.18.6(@babel/core@7.22.9): + /@babel/plugin-proposal-optional-catch-binding@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.9) + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.0) dev: true - /@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.22.9): + /@babel/plugin-proposal-optional-chaining@7.21.0(@babel/core@7.24.0): resolution: {integrity: sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.9) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.0) dev: true - /@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.22.9): + /@babel/plugin-proposal-private-methods@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-create-class-features-plugin': 7.21.4(@babel/core@7.22.9) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-create-class-features-plugin': 7.21.4(@babel/core@7.24.0) + '@babel/helper-plugin-utils': 7.22.5 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-proposal-private-property-in-object@7.21.0(@babel/core@7.22.9): + /@babel/plugin-proposal-private-property-in-object@7.21.0(@babel/core@7.24.0): resolution: {integrity: sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-create-class-features-plugin': 7.21.4(@babel/core@7.22.9) - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.22.9) + '@babel/core': 7.24.0 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.21.4(@babel/core@7.24.0) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.0) transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-proposal-unicode-property-regex@7.18.6(@babel/core@7.22.9): + /@babel/plugin-proposal-unicode-property-regex@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w==} engines: {node: '>=4'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-create-regexp-features-plugin': 7.21.4(@babel/core@7.22.9) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-create-regexp-features-plugin': 7.21.4(@babel/core@7.24.0) + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.22.9): + /@babel/plugin-syntax-async-generators@7.8.4(@babel/core@7.24.0): resolution: {integrity: sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.22.9): + /@babel/plugin-syntax-class-properties@7.12.13(@babel/core@7.24.0): resolution: {integrity: sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.22.9): + /@babel/plugin-syntax-class-static-block@7.14.5(@babel/core@7.24.0): resolution: {integrity: sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-decorators@7.21.0(@babel/core@7.22.9): + /@babel/plugin-syntax-decorators@7.21.0(@babel/core@7.24.0): resolution: {integrity: sha512-tIoPpGBR8UuM4++ccWN3gifhVvQu7ZizuR1fklhRJrd5ewgbkUS+0KVFeWWxELtn18NTLoW32XV7zyOgIAiz+w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.22.9): + /@babel/plugin-syntax-dynamic-import@7.8.3(@babel/core@7.24.0): resolution: {integrity: sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.22.9): + /@babel/plugin-syntax-export-namespace-from@7.8.3(@babel/core@7.24.0): resolution: {integrity: sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-flow@7.22.5(@babel/core@7.22.9): - resolution: {integrity: sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ==} + /@babel/plugin-syntax-flow@7.23.3(@babel/core@7.24.0): + resolution: {integrity: sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 + '@babel/core': 7.24.0 '@babel/helper-plugin-utils': 7.22.5 - /@babel/plugin-syntax-import-assertions@7.20.0(@babel/core@7.22.9): + /@babel/plugin-syntax-import-assertions@7.20.0(@babel/core@7.24.0): resolution: {integrity: sha512-IUh1vakzNoWalR8ch/areW7qFopR2AEw03JlG7BbrDqmQ4X3q9uuipQwSGrUn7oGiemKjtSLDhNtQHzMHr1JdQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.22.9): + /@babel/plugin-syntax-json-strings@7.8.3(@babel/core@7.24.0): resolution: {integrity: sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-jsx@7.21.4(@babel/core@7.22.9): - resolution: {integrity: sha512-5hewiLct5OKyh6PLKEYaFclcqtIgCb6bmELouxjF6up5q3Sov7rOayW4RwhbaBL0dit8rA80GNfY+UuDp2mBbQ==} + /@babel/plugin-syntax-jsx@7.23.3(@babel/core@7.24.0): + resolution: {integrity: sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 - dev: true - - /@babel/plugin-syntax-jsx@7.22.5(@babel/core@7.22.9): - resolution: {integrity: sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.22.9 + '@babel/core': 7.24.0 '@babel/helper-plugin-utils': 7.22.5 - /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.22.9): + /@babel/plugin-syntax-logical-assignment-operators@7.10.4(@babel/core@7.24.0): resolution: {integrity: sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.22.9): + /@babel/plugin-syntax-nullish-coalescing-operator@7.8.3(@babel/core@7.24.0): resolution: {integrity: sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.22.9): + /@babel/plugin-syntax-numeric-separator@7.10.4(@babel/core@7.24.0): resolution: {integrity: sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.22.9): + /@babel/plugin-syntax-object-rest-spread@7.8.3(@babel/core@7.24.0): resolution: {integrity: sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.22.9): + /@babel/plugin-syntax-optional-catch-binding@7.8.3(@babel/core@7.24.0): resolution: {integrity: sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.22.9): + /@babel/plugin-syntax-optional-chaining@7.8.3(@babel/core@7.24.0): resolution: {integrity: sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.22.9): + /@babel/plugin-syntax-private-property-in-object@7.14.5(@babel/core@7.24.0): resolution: {integrity: sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.22.9): + /@babel/plugin-syntax-top-level-await@7.14.5(@babel/core@7.24.0): resolution: {integrity: sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-syntax-typescript@7.21.4(@babel/core@7.22.9): + /@babel/plugin-syntax-typescript@7.21.4(@babel/core@7.24.0): resolution: {integrity: sha512-xz0D39NvhQn4t4RNsHmDnnsaQizIlUkdtYvLs8La1BlfjQ6JEwxkJGeqJMW2tAXx+q6H+WFuUTXNdYVpEya0YA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-arrow-functions@7.20.7(@babel/core@7.22.9): + /@babel/plugin-transform-arrow-functions@7.20.7(@babel/core@7.24.0): resolution: {integrity: sha512-3poA5E7dzDomxj9WXWwuD6A5F3kc7VXwIJO+E+J8qtDtS+pXPAhrgEyh+9GBwBgPq1Z+bB+/JD60lp5jsN7JPQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-async-to-generator@7.20.7(@babel/core@7.22.9): + /@babel/plugin-transform-async-to-generator@7.20.7(@babel/core@7.24.0): resolution: {integrity: sha512-Uo5gwHPT9vgnSXQxqGtpdufUiWp96gk7yiP4Mp5bm1QMkEmLXBO7PAGYbKoJ6DhAwiNkcHFBol/x5zZZkL/t0Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-module-imports': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.22.9) + '@babel/core': 7.24.0 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-remap-async-to-generator': 7.18.9(@babel/core@7.24.0) transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-block-scoped-functions@7.18.6(@babel/core@7.22.9): + /@babel/plugin-transform-block-scoped-functions@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-block-scoping@7.21.0(@babel/core@7.22.9): + /@babel/plugin-transform-block-scoping@7.21.0(@babel/core@7.24.0): resolution: {integrity: sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-classes@7.21.0(@babel/core@7.22.9): + /@babel/plugin-transform-classes@7.21.0(@babel/core@7.24.0): resolution: {integrity: sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.22.9) - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.21.0 + '@babel/core': 7.24.0 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 '@babel/helper-optimise-call-expression': 7.18.6 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-replace-supers': 7.20.7 - '@babel/helper-split-export-declaration': 7.18.6 + '@babel/helper-split-export-declaration': 7.22.6 globals: 11.12.0 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-computed-properties@7.20.7(@babel/core@7.22.9): + /@babel/plugin-transform-computed-properties@7.20.7(@babel/core@7.24.0): resolution: {integrity: sha512-Lz7MvBK6DTjElHAmfu6bfANzKcxpyNPeYBGEafyA6E5HtRpjpZwU+u7Qrgz/2OR0z+5TvKYbPdphfSaAcZBrYQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/template': 7.20.7 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/template': 7.24.0 dev: true - /@babel/plugin-transform-destructuring@7.21.3(@babel/core@7.22.9): + /@babel/plugin-transform-destructuring@7.21.3(@babel/core@7.24.0): resolution: {integrity: sha512-bp6hwMFzuiE4HqYEyoGJ/V2LeIWn+hLVKc4pnj++E5XQptwhtcGmSayM029d/j2X1bPKGTlsyPwAubuU22KhMA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-dotall-regex@7.18.6(@babel/core@7.22.9): + /@babel/plugin-transform-dotall-regex@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-create-regexp-features-plugin': 7.21.4(@babel/core@7.22.9) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-create-regexp-features-plugin': 7.21.4(@babel/core@7.24.0) + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-duplicate-keys@7.18.9(@babel/core@7.22.9): + /@babel/plugin-transform-duplicate-keys@7.18.9(@babel/core@7.24.0): resolution: {integrity: sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-exponentiation-operator@7.18.6(@babel/core@7.22.9): + /@babel/plugin-transform-exponentiation-operator@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 + '@babel/core': 7.24.0 '@babel/helper-builder-binary-assignment-operator-visitor': 7.18.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-flow-strip-types@7.21.0(@babel/core@7.22.9): + /@babel/plugin-transform-flow-strip-types@7.21.0(@babel/core@7.24.0): resolution: {integrity: sha512-FlFA2Mj87a6sDkW4gfGrQQqwY/dLlBAyJa2dJEZ+FHXUVHBflO2wyKvg+OOEzXfrKYIa4HWl0mgmbCzt0cMb7w==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-flow': 7.22.5(@babel/core@7.22.9) + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-flow': 7.23.3(@babel/core@7.24.0) dev: true - /@babel/plugin-transform-for-of@7.21.0(@babel/core@7.22.9): + /@babel/plugin-transform-for-of@7.21.0(@babel/core@7.24.0): resolution: {integrity: sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-function-name@7.18.9(@babel/core@7.22.9): + /@babel/plugin-transform-function-name@7.18.9(@babel/core@7.24.0): resolution: {integrity: sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.22.9) - '@babel/helper-function-name': 7.21.0 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-function-name': 7.23.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-literals@7.18.9(@babel/core@7.22.9): + /@babel/plugin-transform-literals@7.18.9(@babel/core@7.24.0): resolution: {integrity: sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-member-expression-literals@7.18.6(@babel/core@7.22.9): + /@babel/plugin-transform-member-expression-literals@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-modules-amd@7.20.11(@babel/core@7.22.9): + /@babel/plugin-transform-modules-amd@7.20.11(@babel/core@7.24.0): resolution: {integrity: sha512-NuzCt5IIYOW0O30UvqktzHYR2ud5bOWbY0yaxWZ6G+aFzOMJvrs5YHNikrbdaT15+KNO31nPOy5Fim3ku6Zb5g==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.20.2 - transitivePeerDependencies: - - supports-color + '@babel/core': 7.24.0 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0) + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-modules-commonjs@7.21.2(@babel/core@7.22.9): + /@babel/plugin-transform-modules-commonjs@7.21.2(@babel/core@7.24.0): resolution: {integrity: sha512-Cln+Yy04Gxua7iPdj6nOV96smLGjpElir5YwzF0LBPKoPlLDNJePNlrGGaybAJkd0zKRnOVXOgizSqPYMNYkzA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-simple-access': 7.20.2 - transitivePeerDependencies: - - supports-color + '@babel/core': 7.24.0 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-simple-access': 7.22.5 dev: true - /@babel/plugin-transform-modules-systemjs@7.20.11(@babel/core@7.22.9): + /@babel/plugin-transform-modules-systemjs@7.20.11(@babel/core@7.24.0): resolution: {integrity: sha512-vVu5g9BPQKSFEmvt2TA4Da5N+QVS66EX21d8uoOihC+OCpUoGvzVsXeqFdtAEfVa5BILAeFt+U7yVmLbQnAJmw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-hoist-variables': 7.22.5 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0) + '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-validator-identifier': 7.22.20 - transitivePeerDependencies: - - supports-color dev: true - /@babel/plugin-transform-modules-umd@7.18.6(@babel/core@7.22.9): + /@babel/plugin-transform-modules-umd@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-module-transforms': 7.21.2 - '@babel/helper-plugin-utils': 7.20.2 - transitivePeerDependencies: - - supports-color + '@babel/core': 7.24.0 + '@babel/helper-module-transforms': 7.23.3(@babel/core@7.24.0) + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-named-capturing-groups-regex@7.20.5(@babel/core@7.22.9): + /@babel/plugin-transform-named-capturing-groups-regex@7.20.5(@babel/core@7.24.0): resolution: {integrity: sha512-mOW4tTzi5iTLnw+78iEq3gr8Aoq4WNRGpmSlrogqaiCBoR1HFhpU4JkpQFOHfeYx3ReVIFWOQJS4aZBRvuZ6mA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-create-regexp-features-plugin': 7.21.4(@babel/core@7.22.9) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-create-regexp-features-plugin': 7.21.4(@babel/core@7.24.0) + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-new-target@7.18.6(@babel/core@7.22.9): + /@babel/plugin-transform-new-target@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-object-super@7.18.6(@babel/core@7.22.9): + /@babel/plugin-transform-object-super@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-replace-supers': 7.20.7 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-parameters@7.21.3(@babel/core@7.22.9): + /@babel/plugin-transform-parameters@7.21.3(@babel/core@7.24.0): resolution: {integrity: sha512-Wxc+TvppQG9xWFYatvCGPvZ6+SIUxQ2ZdiBP+PHYMIjnPXD+uThCshaz4NZOnODAtBjjcVQQ/3OKs9LW28purQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-property-literals@7.18.6(@babel/core@7.22.9): + /@babel/plugin-transform-property-literals@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-react-display-name@7.18.6(@babel/core@7.22.9): + /@babel/plugin-transform-react-display-name@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-react-jsx-development@7.18.6(@babel/core@7.22.9): + /@babel/plugin-transform-react-jsx-development@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/plugin-transform-react-jsx': 7.22.5(@babel/core@7.22.9) + '@babel/core': 7.24.0 + '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.24.0) dev: true - /@babel/plugin-transform-react-jsx@7.22.5(@babel/core@7.22.9): - resolution: {integrity: sha512-rog5gZaVbUip5iWDMTYbVM15XQq+RkUKhET/IHR6oizR+JEoN6CAfTTuHcK4vwUyzca30qqHqEpzBOnaRMWYMA==} + /@babel/plugin-transform-react-jsx@7.23.4(@babel/core@7.24.0): + resolution: {integrity: sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 + '@babel/core': 7.24.0 '@babel/helper-annotate-as-pure': 7.22.5 - '@babel/helper-module-imports': 7.22.5 + '@babel/helper-module-imports': 7.22.15 '@babel/helper-plugin-utils': 7.22.5 - '@babel/plugin-syntax-jsx': 7.22.5(@babel/core@7.22.9) - '@babel/types': 7.22.5 + '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.24.0) + '@babel/types': 7.24.0 - /@babel/plugin-transform-react-pure-annotations@7.18.6(@babel/core@7.22.9): + /@babel/plugin-transform-react-pure-annotations@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-regenerator@7.20.5(@babel/core@7.22.9): + /@babel/plugin-transform-regenerator@7.20.5(@babel/core@7.24.0): resolution: {integrity: sha512-kW/oO7HPBtntbsahzQ0qSE3tFvkFwnbozz3NWFhLGqH75vLEg+sCGngLlhVkePlCs3Jv0dBBHDzCHxNiFAQKCQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 regenerator-transform: 0.15.1 dev: true - /@babel/plugin-transform-reserved-words@7.18.6(@babel/core@7.22.9): + /@babel/plugin-transform-reserved-words@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-runtime@7.21.4(@babel/core@7.22.9): + /@babel/plugin-transform-runtime@7.21.4(@babel/core@7.24.0): resolution: {integrity: sha512-1J4dhrw1h1PqnNNpzwxQ2UBymJUF8KuPjAAnlLwZcGhHAIqUigFW7cdK6GHoB64ubY4qXQNYknoUeks4Wz7CUA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-module-imports': 7.21.4 - '@babel/helper-plugin-utils': 7.20.2 - babel-plugin-polyfill-corejs2: 0.3.3(@babel/core@7.22.9) - babel-plugin-polyfill-corejs3: 0.6.0(@babel/core@7.22.9) - babel-plugin-polyfill-regenerator: 0.4.1(@babel/core@7.22.9) + '@babel/core': 7.24.0 + '@babel/helper-module-imports': 7.22.15 + '@babel/helper-plugin-utils': 7.22.5 + babel-plugin-polyfill-corejs2: 0.3.3(@babel/core@7.24.0) + babel-plugin-polyfill-corejs3: 0.6.0(@babel/core@7.24.0) + babel-plugin-polyfill-regenerator: 0.4.1(@babel/core@7.24.0) semver: 6.3.1 transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-shorthand-properties@7.18.6(@babel/core@7.22.9): + /@babel/plugin-transform-shorthand-properties@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-spread@7.20.7(@babel/core@7.22.9): + /@babel/plugin-transform-spread@7.20.7(@babel/core@7.24.0): resolution: {integrity: sha512-ewBbHQ+1U/VnH1fxltbJqDeWBU1oNLG8Dj11uIv3xVf7nrQu0bPGe5Rf716r7K5Qz+SqtAOVswoVunoiBtGhxw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 '@babel/helper-skip-transparent-expression-wrappers': 7.20.0 dev: true - /@babel/plugin-transform-sticky-regex@7.18.6(@babel/core@7.22.9): + /@babel/plugin-transform-sticky-regex@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-template-literals@7.18.9(@babel/core@7.22.9): + /@babel/plugin-transform-template-literals@7.18.9(@babel/core@7.24.0): resolution: {integrity: sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-typeof-symbol@7.18.9(@babel/core@7.22.9): + /@babel/plugin-transform-typeof-symbol@7.18.9(@babel/core@7.24.0): resolution: {integrity: sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-typescript@7.21.3(@babel/core@7.22.9): + /@babel/plugin-transform-typescript@7.21.3(@babel/core@7.24.0): resolution: {integrity: sha512-RQxPz6Iqt8T0uw/WsJNReuBpWpBqs/n7mNo18sKLoTbMp+UrEekhH+pKSVC7gWz+DNjo9gryfV8YzCiT45RgMw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-create-class-features-plugin': 7.21.4(@babel/core@7.22.9) - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-syntax-typescript': 7.21.4(@babel/core@7.22.9) + '@babel/core': 7.24.0 + '@babel/helper-annotate-as-pure': 7.22.5 + '@babel/helper-create-class-features-plugin': 7.21.4(@babel/core@7.24.0) + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-syntax-typescript': 7.21.4(@babel/core@7.24.0) transitivePeerDependencies: - supports-color dev: true - /@babel/plugin-transform-unicode-escapes@7.18.10(@babel/core@7.22.9): + /@babel/plugin-transform-unicode-escapes@7.18.10(@babel/core@7.24.0): resolution: {integrity: sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/plugin-transform-unicode-regex@7.18.6(@babel/core@7.22.9): + /@babel/plugin-transform-unicode-regex@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-create-regexp-features-plugin': 7.21.4(@babel/core@7.22.9) - '@babel/helper-plugin-utils': 7.20.2 + '@babel/core': 7.24.0 + '@babel/helper-create-regexp-features-plugin': 7.21.4(@babel/core@7.24.0) + '@babel/helper-plugin-utils': 7.22.5 dev: true - /@babel/preset-env@7.21.4(@babel/core@7.22.9): + /@babel/preset-env@7.21.4(@babel/core@7.24.0): resolution: {integrity: sha512-2W57zHs2yDLm6GD5ZpvNn71lZ0B/iypSdIeq25OurDKji6AdzV07qp4s3n1/x5BqtiGaTrPN3nerlSCaC5qNTw==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/compat-data': 7.21.4 - '@babel/core': 7.22.9 - '@babel/helper-compilation-targets': 7.21.4(@babel/core@7.22.9) - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-validator-option': 7.21.0 - '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.20.7(@babel/core@7.22.9) - '@babel/plugin-proposal-async-generator-functions': 7.20.7(@babel/core@7.22.9) - '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-proposal-class-static-block': 7.21.0(@babel/core@7.22.9) - '@babel/plugin-proposal-dynamic-import': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-proposal-export-namespace-from': 7.18.9(@babel/core@7.22.9) - '@babel/plugin-proposal-json-strings': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-proposal-logical-assignment-operators': 7.20.7(@babel/core@7.22.9) - '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-proposal-numeric-separator': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.22.9) - '@babel/plugin-proposal-optional-catch-binding': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.22.9) - '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-proposal-private-property-in-object': 7.21.0(@babel/core@7.22.9) - '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.22.9) - '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.22.9) - '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.22.9) - '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.22.9) - '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.22.9) - '@babel/plugin-syntax-import-assertions': 7.20.0(@babel/core@7.22.9) - '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.22.9) - '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.22.9) - '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.22.9) - '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.22.9) - '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.22.9) - '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.22.9) - '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.22.9) - '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.22.9) - '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.22.9) - '@babel/plugin-transform-arrow-functions': 7.20.7(@babel/core@7.22.9) - '@babel/plugin-transform-async-to-generator': 7.20.7(@babel/core@7.22.9) - '@babel/plugin-transform-block-scoped-functions': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-transform-block-scoping': 7.21.0(@babel/core@7.22.9) - '@babel/plugin-transform-classes': 7.21.0(@babel/core@7.22.9) - '@babel/plugin-transform-computed-properties': 7.20.7(@babel/core@7.22.9) - '@babel/plugin-transform-destructuring': 7.21.3(@babel/core@7.22.9) - '@babel/plugin-transform-dotall-regex': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-transform-duplicate-keys': 7.18.9(@babel/core@7.22.9) - '@babel/plugin-transform-exponentiation-operator': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-transform-for-of': 7.21.0(@babel/core@7.22.9) - '@babel/plugin-transform-function-name': 7.18.9(@babel/core@7.22.9) - '@babel/plugin-transform-literals': 7.18.9(@babel/core@7.22.9) - '@babel/plugin-transform-member-expression-literals': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-transform-modules-amd': 7.20.11(@babel/core@7.22.9) - '@babel/plugin-transform-modules-commonjs': 7.21.2(@babel/core@7.22.9) - '@babel/plugin-transform-modules-systemjs': 7.20.11(@babel/core@7.22.9) - '@babel/plugin-transform-modules-umd': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-transform-named-capturing-groups-regex': 7.20.5(@babel/core@7.22.9) - '@babel/plugin-transform-new-target': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-transform-object-super': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-transform-parameters': 7.21.3(@babel/core@7.22.9) - '@babel/plugin-transform-property-literals': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-transform-regenerator': 7.20.5(@babel/core@7.22.9) - '@babel/plugin-transform-reserved-words': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-transform-shorthand-properties': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-transform-spread': 7.20.7(@babel/core@7.22.9) - '@babel/plugin-transform-sticky-regex': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-transform-template-literals': 7.18.9(@babel/core@7.22.9) - '@babel/plugin-transform-typeof-symbol': 7.18.9(@babel/core@7.22.9) - '@babel/plugin-transform-unicode-escapes': 7.18.10(@babel/core@7.22.9) - '@babel/plugin-transform-unicode-regex': 7.18.6(@babel/core@7.22.9) - '@babel/preset-modules': 0.1.5(@babel/core@7.22.9) - '@babel/types': 7.23.0 - babel-plugin-polyfill-corejs2: 0.3.3(@babel/core@7.22.9) - babel-plugin-polyfill-corejs3: 0.6.0(@babel/core@7.22.9) - babel-plugin-polyfill-regenerator: 0.4.1(@babel/core@7.22.9) + '@babel/compat-data': 7.23.5 + '@babel/core': 7.24.0 + '@babel/helper-compilation-targets': 7.23.6 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.23.5 + '@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining': 7.20.7(@babel/core@7.24.0) + '@babel/plugin-proposal-async-generator-functions': 7.20.7(@babel/core@7.24.0) + '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-proposal-class-static-block': 7.21.0(@babel/core@7.24.0) + '@babel/plugin-proposal-dynamic-import': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-proposal-export-namespace-from': 7.18.9(@babel/core@7.24.0) + '@babel/plugin-proposal-json-strings': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-proposal-logical-assignment-operators': 7.20.7(@babel/core@7.24.0) + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-proposal-numeric-separator': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-proposal-object-rest-spread': 7.20.7(@babel/core@7.24.0) + '@babel/plugin-proposal-optional-catch-binding': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.24.0) + '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-proposal-private-property-in-object': 7.21.0(@babel/core@7.24.0) + '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-syntax-async-generators': 7.8.4(@babel/core@7.24.0) + '@babel/plugin-syntax-class-properties': 7.12.13(@babel/core@7.24.0) + '@babel/plugin-syntax-class-static-block': 7.14.5(@babel/core@7.24.0) + '@babel/plugin-syntax-dynamic-import': 7.8.3(@babel/core@7.24.0) + '@babel/plugin-syntax-export-namespace-from': 7.8.3(@babel/core@7.24.0) + '@babel/plugin-syntax-import-assertions': 7.20.0(@babel/core@7.24.0) + '@babel/plugin-syntax-json-strings': 7.8.3(@babel/core@7.24.0) + '@babel/plugin-syntax-logical-assignment-operators': 7.10.4(@babel/core@7.24.0) + '@babel/plugin-syntax-nullish-coalescing-operator': 7.8.3(@babel/core@7.24.0) + '@babel/plugin-syntax-numeric-separator': 7.10.4(@babel/core@7.24.0) + '@babel/plugin-syntax-object-rest-spread': 7.8.3(@babel/core@7.24.0) + '@babel/plugin-syntax-optional-catch-binding': 7.8.3(@babel/core@7.24.0) + '@babel/plugin-syntax-optional-chaining': 7.8.3(@babel/core@7.24.0) + '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.24.0) + '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.24.0) + '@babel/plugin-transform-arrow-functions': 7.20.7(@babel/core@7.24.0) + '@babel/plugin-transform-async-to-generator': 7.20.7(@babel/core@7.24.0) + '@babel/plugin-transform-block-scoped-functions': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-transform-block-scoping': 7.21.0(@babel/core@7.24.0) + '@babel/plugin-transform-classes': 7.21.0(@babel/core@7.24.0) + '@babel/plugin-transform-computed-properties': 7.20.7(@babel/core@7.24.0) + '@babel/plugin-transform-destructuring': 7.21.3(@babel/core@7.24.0) + '@babel/plugin-transform-dotall-regex': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-transform-duplicate-keys': 7.18.9(@babel/core@7.24.0) + '@babel/plugin-transform-exponentiation-operator': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-transform-for-of': 7.21.0(@babel/core@7.24.0) + '@babel/plugin-transform-function-name': 7.18.9(@babel/core@7.24.0) + '@babel/plugin-transform-literals': 7.18.9(@babel/core@7.24.0) + '@babel/plugin-transform-member-expression-literals': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-transform-modules-amd': 7.20.11(@babel/core@7.24.0) + '@babel/plugin-transform-modules-commonjs': 7.21.2(@babel/core@7.24.0) + '@babel/plugin-transform-modules-systemjs': 7.20.11(@babel/core@7.24.0) + '@babel/plugin-transform-modules-umd': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-transform-named-capturing-groups-regex': 7.20.5(@babel/core@7.24.0) + '@babel/plugin-transform-new-target': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-transform-object-super': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-transform-parameters': 7.21.3(@babel/core@7.24.0) + '@babel/plugin-transform-property-literals': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-transform-regenerator': 7.20.5(@babel/core@7.24.0) + '@babel/plugin-transform-reserved-words': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-transform-shorthand-properties': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-transform-spread': 7.20.7(@babel/core@7.24.0) + '@babel/plugin-transform-sticky-regex': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-transform-template-literals': 7.18.9(@babel/core@7.24.0) + '@babel/plugin-transform-typeof-symbol': 7.18.9(@babel/core@7.24.0) + '@babel/plugin-transform-unicode-escapes': 7.18.10(@babel/core@7.24.0) + '@babel/plugin-transform-unicode-regex': 7.18.6(@babel/core@7.24.0) + '@babel/preset-modules': 0.1.5(@babel/core@7.24.0) + '@babel/types': 7.24.0 + babel-plugin-polyfill-corejs2: 0.3.3(@babel/core@7.24.0) + babel-plugin-polyfill-corejs3: 0.6.0(@babel/core@7.24.0) + babel-plugin-polyfill-regenerator: 0.4.1(@babel/core@7.24.0) core-js-compat: 3.30.0 semver: 6.3.1 transitivePeerDependencies: - supports-color dev: true - /@babel/preset-modules@0.1.5(@babel/core@7.22.9): + /@babel/preset-modules@0.1.5(@babel/core@7.24.0): resolution: {integrity: sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-transform-dotall-regex': 7.18.6(@babel/core@7.22.9) - '@babel/types': 7.23.0 + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/plugin-proposal-unicode-property-regex': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-transform-dotall-regex': 7.18.6(@babel/core@7.24.0) + '@babel/types': 7.24.0 esutils: 2.0.3 dev: true - /@babel/preset-react@7.18.6(@babel/core@7.22.9): + /@babel/preset-react@7.18.6(@babel/core@7.24.0): resolution: {integrity: sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-validator-option': 7.21.0 - '@babel/plugin-transform-react-display-name': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-transform-react-jsx': 7.22.5(@babel/core@7.22.9) - '@babel/plugin-transform-react-jsx-development': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-transform-react-pure-annotations': 7.18.6(@babel/core@7.22.9) + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.23.5 + '@babel/plugin-transform-react-display-name': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.24.0) + '@babel/plugin-transform-react-jsx-development': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-transform-react-pure-annotations': 7.18.6(@babel/core@7.24.0) dev: true - /@babel/preset-typescript@7.21.4(@babel/core@7.22.9): + /@babel/preset-typescript@7.21.4(@babel/core@7.24.0): resolution: {integrity: sha512-sMLNWY37TCdRH/bJ6ZeeOH1nPuanED7Ai9Y/vH31IPqalioJ6ZNFUWONsakhv4r4n+I6gm5lmoE0olkgib/j/A==} engines: {node: '>=6.9.0'} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-plugin-utils': 7.20.2 - '@babel/helper-validator-option': 7.21.0 - '@babel/plugin-syntax-jsx': 7.21.4(@babel/core@7.22.9) - '@babel/plugin-transform-modules-commonjs': 7.21.2(@babel/core@7.22.9) - '@babel/plugin-transform-typescript': 7.21.3(@babel/core@7.22.9) + '@babel/core': 7.24.0 + '@babel/helper-plugin-utils': 7.22.5 + '@babel/helper-validator-option': 7.23.5 + '@babel/plugin-syntax-jsx': 7.23.3(@babel/core@7.24.0) + '@babel/plugin-transform-modules-commonjs': 7.21.2(@babel/core@7.24.0) + '@babel/plugin-transform-typescript': 7.21.3(@babel/core@7.24.0) transitivePeerDependencies: - supports-color dev: true @@ -1569,80 +1440,45 @@ packages: dependencies: regenerator-runtime: 0.13.11 - /@babel/template@7.20.7: - resolution: {integrity: sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==} + /@babel/template@7.24.0: + resolution: {integrity: sha512-Bkf2q8lMB0AFpX0NFEqSbx1OkTHf0f+0j82mkw+ZpzBnkk7e9Ql0891vlfgi+kHwOk8tQjiQHpqh4LaSa0fKEA==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.21.4 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 - dev: true + '@babel/code-frame': 7.23.5 + '@babel/parser': 7.24.0 + '@babel/types': 7.24.0 - /@babel/template@7.22.5: - resolution: {integrity: sha512-X7yV7eiwAxdj9k94NEylvbVHLiVG1nvzCV2EAowhxLTwODV1jl9UzZ48leOC0sH7OnuHrIkllaBgneUykIcZaw==} + /@babel/traverse@7.24.0: + resolution: {integrity: sha512-HfuJlI8qq3dEDmNU5ChzzpZRWq+oxCZQyMzIMEqLho+AQnhMnKQUzH6ydo3RBl/YjPCuk68Y6s0Gx0AeyULiWw==} engines: {node: '>=6.9.0'} dependencies: - '@babel/code-frame': 7.22.5 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 - - /@babel/traverse@7.21.4: - resolution: {integrity: sha512-eyKrRHKdyZxqDm+fV1iqL9UAHMoIg0nDaGqfIOd8rKH17m5snv7Gn4qgjBoFfLz9APvjFU/ICT00NVCv1Epp8Q==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.21.4 - '@babel/generator': 7.23.0 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.21.0 - '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 - debug: 4.3.4 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/traverse@7.22.8: - resolution: {integrity: sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.22.5 - '@babel/generator': 7.23.0 - '@babel/helper-environment-visitor': 7.22.5 - '@babel/helper-function-name': 7.22.5 + '@babel/code-frame': 7.23.5 + '@babel/generator': 7.23.6 + '@babel/helper-environment-visitor': 7.22.20 + '@babel/helper-function-name': 7.23.0 '@babel/helper-hoist-variables': 7.22.5 '@babel/helper-split-export-declaration': 7.22.6 - '@babel/parser': 7.23.0 - '@babel/types': 7.23.0 + '@babel/parser': 7.24.0 + '@babel/types': 7.24.0 debug: 4.3.4 globals: 11.12.0 transitivePeerDependencies: - supports-color - /@babel/types@7.19.0: - resolution: {integrity: sha512-YuGopBq3ke25BVSiS6fgF49Ul9gH1x70Bcr6bqRLjWCkcX8Hre1/5+z+IiWOIerRMSSEfGZVB9z9kyq7wVs9YA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.22.5 - '@babel/helper-validator-identifier': 7.22.20 - to-fast-properties: 2.0.0 - dev: true - - /@babel/types@7.22.5: - resolution: {integrity: sha512-zo3MIHGOkPOfoRXitsgHLjEXmlDaD/5KU1Uzuc9GNiZPhSqVxVRtxuPaSBZDsYZ9qV88AjtMtWW7ww98loJ9KA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.22.5 - '@babel/helper-validator-identifier': 7.22.20 - to-fast-properties: 2.0.0 - /@babel/types@7.23.0: resolution: {integrity: sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==} engines: {node: '>=6.9.0'} dependencies: - '@babel/helper-string-parser': 7.22.5 + '@babel/helper-string-parser': 7.23.4 + '@babel/helper-validator-identifier': 7.22.20 + to-fast-properties: 2.0.0 + dev: false + + /@babel/types@7.24.0: + resolution: {integrity: sha512-+j7a5c253RfKh8iABBhywc8NSfP5LURe7Uh4qpsh6jc+aLJguvmIUBdjSdEMQv2bENrCR5MfRdjGo7vzS/ob7w==} + engines: {node: '>=6.9.0'} + dependencies: + '@babel/helper-string-parser': 7.23.4 '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 @@ -1653,21 +1489,21 @@ packages: '@jridgewell/trace-mapping': 0.3.9 dev: true - /@eslint-community/eslint-utils@4.4.0(eslint@8.45.0): + /@eslint-community/eslint-utils@4.4.0(eslint@8.57.0): resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 8.45.0 - eslint-visitor-keys: 3.4.1 + eslint: 8.57.0 + eslint-visitor-keys: 3.4.3 - /@eslint-community/regexpp@4.5.0: - resolution: {integrity: sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==} + /@eslint-community/regexpp@4.10.0: + resolution: {integrity: sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} - /@eslint/eslintrc@2.1.0: - resolution: {integrity: sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==} + /@eslint/eslintrc@2.1.4: + resolution: {integrity: sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 @@ -1682,15 +1518,15 @@ packages: transitivePeerDependencies: - supports-color - /@eslint/js@8.44.0: - resolution: {integrity: sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==} + /@eslint/js@8.57.0: + resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - /@humanwhocodes/config-array@0.11.10: - resolution: {integrity: sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==} + /@humanwhocodes/config-array@0.11.14: + resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} dependencies: - '@humanwhocodes/object-schema': 1.2.1 + '@humanwhocodes/object-schema': 2.0.2 debug: 4.3.4 minimatch: 3.1.2 transitivePeerDependencies: @@ -1700,8 +1536,8 @@ packages: resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - /@humanwhocodes/object-schema@1.2.1: - resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} + /@humanwhocodes/object-schema@2.0.2: + resolution: {integrity: sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==} /@jridgewell/gen-mapping@0.3.3: resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} @@ -1767,6 +1603,39 @@ packages: '@nodelib/fs.scandir': 2.1.5 fastq: 1.15.0 + /@protobufjs/aspromise@1.1.2: + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + /@protobufjs/base64@1.1.2: + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + /@protobufjs/codegen@2.0.4: + resolution: {integrity: sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==} + + /@protobufjs/eventemitter@1.1.0: + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + + /@protobufjs/fetch@1.1.0: + resolution: {integrity: sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==} + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/inquire': 1.1.0 + + /@protobufjs/float@1.0.2: + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + /@protobufjs/inquire@1.1.0: + resolution: {integrity: sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==} + + /@protobufjs/path@1.1.2: + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + /@protobufjs/pool@1.1.0: + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + /@protobufjs/utf8@1.1.0: + resolution: {integrity: sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==} + /@rushstack/eslint-patch@1.2.0: resolution: {integrity: sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg==} dev: true @@ -1821,8 +1690,8 @@ packages: '@types/node': 18.15.11 dev: true - /@types/cors@2.8.13: - resolution: {integrity: sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==} + /@types/cors@2.8.17: + resolution: {integrity: sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==} dependencies: '@types/node': 18.15.11 dev: true @@ -1835,8 +1704,8 @@ packages: '@types/range-parser': 1.2.4 dev: true - /@types/express@4.17.17: - resolution: {integrity: sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q==} + /@types/express@4.17.21: + resolution: {integrity: sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ==} dependencies: '@types/body-parser': 1.19.2 '@types/express-serve-static-core': 4.17.33 @@ -1844,16 +1713,12 @@ packages: '@types/serve-static': 1.15.1 dev: true - /@types/ffprobe-static@2.0.1: - resolution: {integrity: sha512-V5CrKUfms0lBGSXliKmKzSFFZWgJusQks1YfjRI/+2dXFF+aK7qBAarCe/ryYHQI44jYQX7xtlgH0fCuJepuGQ==} + /@types/ffprobe@1.1.8: + resolution: {integrity: sha512-qPxx8Dy0HyH12hQCESN39NQOmU2Yl2b7tCyUhWy0l11HQv/8Yv7U+vcaveFXmXK8hcAP0oj29DPFuSM7vcC3Tg==} dev: true - /@types/ffprobe@1.1.4: - resolution: {integrity: sha512-gtfU+bD4FDoF1S2ybmIWEIz0K5ijeHpi+CgJUtXl3FTGnf+61HmsZksqDn8M9M9lRJU9SRyMLt5yrIwUSep4Uw==} - dev: true - - /@types/fs-extra@11.0.1: - resolution: {integrity: sha512-MxObHvNl4A69ofaTRU8DFqvgzzv8s9yRtaPPm5gud9HDNvpB3GPQFvNuTWAI59B9huVGV5jXYJwbCsmBsOGYWA==} + /@types/fs-extra@11.0.4: + resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} dependencies: '@types/jsonfile': 6.1.1 '@types/node': 18.15.11 @@ -1863,8 +1728,8 @@ packages: resolution: {integrity: sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==} dev: false - /@types/json-schema@7.0.11: - resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} + /@types/json-schema@7.0.15: + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} dev: true /@types/json5@0.0.29: @@ -1907,8 +1772,8 @@ packages: '@types/node': 18.15.11 dev: false - /@types/semver@7.3.13: - resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==} + /@types/semver@7.5.8: + resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} dev: true /@types/serve-static@1.15.1: @@ -1918,23 +1783,27 @@ packages: '@types/node': 18.15.11 dev: true - /@types/ws@8.5.5: - resolution: {integrity: sha512-lwhs8hktwxSjf9UaZ9tG5M03PGogvFaH8gUgLNbN9HKIg0dvv6q+gkSuJ8HN4/VbyxkuLzCjlN7GquQ0gUJfIg==} + /@types/ws@8.5.10: + resolution: {integrity: sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A==} dependencies: '@types/node': 18.15.11 dev: true + /@types/xmldom@0.1.34: + resolution: {integrity: sha512-7eZFfxI9XHYjJJuugddV6N5YNeXgQE1lArWOcd1eCOKWb/FGs5SIjacSYuEJuwhsGS3gy4RuZ5EUIcqYscuPDA==} + dev: false + /@types/yargs-parser@21.0.0: resolution: {integrity: sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==} dev: true - /@types/yargs@17.0.24: - resolution: {integrity: sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==} + /@types/yargs@17.0.32: + resolution: {integrity: sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==} dependencies: '@types/yargs-parser': 21.0.0 dev: true - /@typescript-eslint/eslint-plugin@5.57.1(@typescript-eslint/parser@5.57.1)(eslint@8.45.0)(typescript@5.1.6): + /@typescript-eslint/eslint-plugin@5.57.1(@typescript-eslint/parser@5.57.1)(eslint@8.57.0)(typescript@5.1.6): resolution: {integrity: sha512-1MeobQkQ9tztuleT3v72XmY0XuKXVXusAhryoLuU5YZ+mXoYKZP9SQ7Flulh1NX4DTjpGTc2b/eMu4u7M7dhnQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -1945,13 +1814,13 @@ packages: typescript: optional: true dependencies: - '@eslint-community/regexpp': 4.5.0 - '@typescript-eslint/parser': 5.57.1(eslint@8.45.0)(typescript@5.1.6) + '@eslint-community/regexpp': 4.10.0 + '@typescript-eslint/parser': 5.57.1(eslint@8.57.0)(typescript@5.1.6) '@typescript-eslint/scope-manager': 5.57.1 - '@typescript-eslint/type-utils': 5.57.1(eslint@8.45.0)(typescript@5.1.6) - '@typescript-eslint/utils': 5.57.1(eslint@8.45.0)(typescript@5.1.6) + '@typescript-eslint/type-utils': 5.57.1(eslint@8.57.0)(typescript@5.1.6) + '@typescript-eslint/utils': 5.57.1(eslint@8.57.0)(typescript@5.1.6) debug: 4.3.4 - eslint: 8.45.0 + eslint: 8.57.0 grapheme-splitter: 1.0.4 ignore: 5.2.4 natural-compare-lite: 1.4.0 @@ -1962,7 +1831,7 @@ packages: - supports-color dev: true - /@typescript-eslint/eslint-plugin@6.0.0(@typescript-eslint/parser@6.0.0)(eslint@8.45.0)(typescript@5.1.6): + /@typescript-eslint/eslint-plugin@6.0.0(@typescript-eslint/parser@6.0.0)(eslint@8.57.0)(typescript@5.1.6): resolution: {integrity: sha512-xuv6ghKGoiq856Bww/yVYnXGsKa588kY3M0XK7uUW/3fJNNULKRfZfSBkMTSpqGG/8ZCXCadfh8G/z/B4aqS/A==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -1973,14 +1842,14 @@ packages: typescript: optional: true dependencies: - '@eslint-community/regexpp': 4.5.0 - '@typescript-eslint/parser': 6.0.0(eslint@8.45.0)(typescript@5.1.6) + '@eslint-community/regexpp': 4.10.0 + '@typescript-eslint/parser': 6.0.0(eslint@8.57.0)(typescript@5.1.6) '@typescript-eslint/scope-manager': 6.0.0 - '@typescript-eslint/type-utils': 6.0.0(eslint@8.45.0)(typescript@5.1.6) - '@typescript-eslint/utils': 6.0.0(eslint@8.45.0)(typescript@5.1.6) + '@typescript-eslint/type-utils': 6.0.0(eslint@8.57.0)(typescript@5.1.6) + '@typescript-eslint/utils': 6.0.0(eslint@8.57.0)(typescript@5.1.6) '@typescript-eslint/visitor-keys': 6.0.0 debug: 4.3.4 - eslint: 8.45.0 + eslint: 8.57.0 grapheme-splitter: 1.0.4 graphemer: 1.4.0 ignore: 5.2.4 @@ -1993,20 +1862,20 @@ packages: - supports-color dev: true - /@typescript-eslint/experimental-utils@5.57.1(eslint@8.45.0)(typescript@5.1.6): + /@typescript-eslint/experimental-utils@5.57.1(eslint@8.57.0)(typescript@5.1.6): resolution: {integrity: sha512-5F5s8mpM1Y0RQ5iWzKQPQm5cmhARgcMfUwyHX1ZZFL8Tm0PyzyQ+9jgYSMaW74XXvpDg9/KdmMICLlwNwKtO7w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - '@typescript-eslint/utils': 5.57.1(eslint@8.45.0)(typescript@5.1.6) - eslint: 8.45.0 + '@typescript-eslint/utils': 5.57.1(eslint@8.57.0)(typescript@5.1.6) + eslint: 8.57.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/parser@5.57.1(eslint@8.45.0)(typescript@5.1.6): + /@typescript-eslint/parser@5.57.1(eslint@8.57.0)(typescript@5.1.6): resolution: {integrity: sha512-hlA0BLeVSA/wBPKdPGxoVr9Pp6GutGoY380FEhbVi0Ph4WNe8kLvqIRx76RSQt1lynZKfrXKs0/XeEk4zZycuA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -2020,13 +1889,13 @@ packages: '@typescript-eslint/types': 5.57.1 '@typescript-eslint/typescript-estree': 5.57.1(typescript@5.1.6) debug: 4.3.4 - eslint: 8.45.0 + eslint: 8.57.0 typescript: 5.1.6 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@6.0.0(eslint@8.45.0)(typescript@5.1.6): + /@typescript-eslint/parser@6.0.0(eslint@8.57.0)(typescript@5.1.6): resolution: {integrity: sha512-TNaufYSPrr1U8n+3xN+Yp9g31vQDJqhXzzPSHfQDLcaO4tU+mCfODPxCwf4H530zo7aUBE3QIdxCXamEnG04Tg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -2041,7 +1910,7 @@ packages: '@typescript-eslint/typescript-estree': 6.0.0(typescript@5.1.6) '@typescript-eslint/visitor-keys': 6.0.0 debug: 4.3.4 - eslint: 8.45.0 + eslint: 8.57.0 typescript: 5.1.6 transitivePeerDependencies: - supports-color @@ -2061,7 +1930,7 @@ packages: '@typescript-eslint/types': 6.0.0 '@typescript-eslint/visitor-keys': 6.0.0 - /@typescript-eslint/type-utils@5.57.1(eslint@8.45.0)(typescript@5.1.6): + /@typescript-eslint/type-utils@5.57.1(eslint@8.57.0)(typescript@5.1.6): resolution: {integrity: sha512-/RIPQyx60Pt6ga86hKXesXkJ2WOS4UemFrmmq/7eOyiYjYv/MUSHPlkhU6k9T9W1ytnTJueqASW+wOmW4KrViw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: @@ -2072,16 +1941,16 @@ packages: optional: true dependencies: '@typescript-eslint/typescript-estree': 5.57.1(typescript@5.1.6) - '@typescript-eslint/utils': 5.57.1(eslint@8.45.0)(typescript@5.1.6) + '@typescript-eslint/utils': 5.57.1(eslint@8.57.0)(typescript@5.1.6) debug: 4.3.4 - eslint: 8.45.0 + eslint: 8.57.0 tsutils: 3.21.0(typescript@5.1.6) typescript: 5.1.6 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/type-utils@6.0.0(eslint@8.45.0)(typescript@5.1.6): + /@typescript-eslint/type-utils@6.0.0(eslint@8.57.0)(typescript@5.1.6): resolution: {integrity: sha512-ah6LJvLgkoZ/pyJ9GAdFkzeuMZ8goV6BH7eC9FPmojrnX9yNCIsfjB+zYcnex28YO3RFvBkV6rMV6WpIqkPvoQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -2092,9 +1961,9 @@ packages: optional: true dependencies: '@typescript-eslint/typescript-estree': 6.0.0(typescript@5.1.6) - '@typescript-eslint/utils': 6.0.0(eslint@8.45.0)(typescript@5.1.6) + '@typescript-eslint/utils': 6.0.0(eslint@8.57.0)(typescript@5.1.6) debug: 4.3.4 - eslint: 8.45.0 + eslint: 8.57.0 ts-api-utils: 1.0.1(typescript@5.1.6) typescript: 5.1.6 transitivePeerDependencies: @@ -2151,19 +2020,19 @@ packages: transitivePeerDependencies: - supports-color - /@typescript-eslint/utils@5.57.1(eslint@8.45.0)(typescript@5.1.6): + /@typescript-eslint/utils@5.57.1(eslint@8.57.0)(typescript@5.1.6): resolution: {integrity: sha512-kN6vzzf9NkEtawECqze6v99LtmDiUJCVpvieTFA1uL7/jDghiJGubGZ5csicYHU1Xoqb3oH/R5cN5df6W41Nfg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.45.0) - '@types/json-schema': 7.0.11 - '@types/semver': 7.3.13 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.8 '@typescript-eslint/scope-manager': 5.57.1 '@typescript-eslint/types': 5.57.1 '@typescript-eslint/typescript-estree': 5.57.1(typescript@5.1.6) - eslint: 8.45.0 + eslint: 8.57.0 eslint-scope: 5.1.1 semver: 7.5.4 transitivePeerDependencies: @@ -2171,19 +2040,19 @@ packages: - typescript dev: true - /@typescript-eslint/utils@6.0.0(eslint@8.45.0)(typescript@5.1.6): + /@typescript-eslint/utils@6.0.0(eslint@8.57.0)(typescript@5.1.6): resolution: {integrity: sha512-SOr6l4NB6HE4H/ktz0JVVWNXqCJTOo/mHnvIte1ZhBQ0Cvd04x5uKZa3zT6tiodL06zf5xxdK8COiDvPnQ27JQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: eslint: ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.45.0) - '@types/json-schema': 7.0.11 - '@types/semver': 7.3.13 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@types/json-schema': 7.0.15 + '@types/semver': 7.5.8 '@typescript-eslint/scope-manager': 6.0.0 '@typescript-eslint/types': 6.0.0 '@typescript-eslint/typescript-estree': 6.0.0(typescript@5.1.6) - eslint: 8.45.0 + eslint: 8.57.0 eslint-scope: 5.1.1 semver: 7.5.4 transitivePeerDependencies: @@ -2196,7 +2065,7 @@ packages: engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: '@typescript-eslint/types': 5.57.1 - eslint-visitor-keys: 3.4.1 + eslint-visitor-keys: 3.4.3 dev: true /@typescript-eslint/visitor-keys@6.0.0: @@ -2204,7 +2073,10 @@ packages: engines: {node: ^16.0.0 || >=18.0.0} dependencies: '@typescript-eslint/types': 6.0.0 - eslint-visitor-keys: 3.4.1 + eslint-visitor-keys: 3.4.3 + + /@ungap/structured-clone@1.2.0: + resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} /@vercel/webpack-asset-relocator-loader@1.7.3: resolution: {integrity: sha512-vizrI18v8Lcb1PmNNUBz7yxPxxXoOeuaVEjTG9MjvDrphjiSxFZrRJ5tIghk+qdLFRCXI5HBCshgobftbmrC5g==} @@ -2221,8 +2093,22 @@ packages: url-toolkit: 2.2.5 dev: false - /@yao-pkg/pkg-fetch@3.5.7: - resolution: {integrity: sha512-DhuvjBZsdrUrkXC+eYZljxCxZ8QrjPQRGhJEA8+hUsKhmPyg+FUn6ebOfN6B7ioiJg7GsVpUJt57hALBCj9epA==} + /@videojs/vhs-utils@4.0.0: + resolution: {integrity: sha512-xJp7Yd4jMLwje2vHCUmi8MOUU76nxiwII3z4Eg3Ucb+6rrkFVGosrXlMgGnaLjq724j3wzNElRZ71D/CKrTtxg==} + engines: {node: '>=8', npm: '>=5'} + dependencies: + '@babel/runtime': 7.21.0 + global: 4.4.0 + url-toolkit: 2.2.5 + dev: false + + /@xmldom/xmldom@0.8.10: + resolution: {integrity: sha512-2WALfTl4xo2SkGCYRt6rDTFfk9R1czmBvUQy12gK2KuRKIpWEhcbbzy8EZXtz/jkRqHX8bFEc6FC1HjX4TUWYw==} + engines: {node: '>=10.0.0'} + dev: false + + /@yao-pkg/pkg-fetch@3.5.9: + resolution: {integrity: sha512-usMwwqFCd2B7k+V87u6kiTesyDSlw+3LpiuYBWe+UgryvSOk/NXjx3XVCub8hQoi0bCREbdQ6NDBqminyHJJrg==} hasBin: true dependencies: chalk: 4.1.2 @@ -2236,16 +2122,16 @@ packages: transitivePeerDependencies: - encoding - supports-color - dev: true + dev: false - /@yao-pkg/pkg@5.11.1: - resolution: {integrity: sha512-y++Kd/kMZcp0UeI2GWB9+55WsDqZp3XCjHGzC4Nsao0tlGjhnNOB+TPhZhLTOCL1V4ApaKkH8zzPcpaTCtvM8g==} + /@yao-pkg/pkg@5.11.5: + resolution: {integrity: sha512-NPFXCn+5bAYZKej7jI92+mXiWG/LA6pEIJCXgI4MM3aYhUFrQOPrYKYr3cGXGs9lkgKGovlnMcKGDjwJ3B7rCQ==} hasBin: true dependencies: '@babel/generator': 7.23.0 '@babel/parser': 7.23.0 '@babel/types': 7.23.0 - '@yao-pkg/pkg-fetch': 3.5.7 + '@yao-pkg/pkg-fetch': 3.5.9 chalk: 4.1.2 fs-extra: 9.1.0 globby: 11.1.0 @@ -2254,12 +2140,12 @@ packages: minimist: 1.2.8 multistream: 4.1.0 prebuild-install: 7.1.1 - resolve: 1.22.2 + resolve: 1.22.8 stream-meter: 1.0.4 transitivePeerDependencies: - encoding - supports-color - dev: true + dev: false /JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} @@ -2294,12 +2180,6 @@ packages: engines: {node: '>=0.4.0'} hasBin: true - /acorn@8.8.2: - resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - /agent-base@6.0.2: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} @@ -2307,7 +2187,7 @@ packages: debug: 4.3.4 transitivePeerDependencies: - supports-color - dev: true + dev: false /ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} @@ -2346,58 +2226,92 @@ packages: deep-equal: 2.2.0 dev: true - /array-buffer-byte-length@1.0.0: - resolution: {integrity: sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==} + /array-buffer-byte-length@1.0.1: + resolution: {integrity: sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - is-array-buffer: 3.0.2 + call-bind: 1.0.7 + is-array-buffer: 3.0.4 /array-flatten@1.1.1: resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} dev: false - /array-includes@3.1.6: - resolution: {integrity: sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==} + /array-includes@3.1.7: + resolution: {integrity: sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - get-intrinsic: 1.2.0 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 + get-intrinsic: 1.2.4 is-string: 1.0.7 /array-union@2.1.0: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} - /array.prototype.flat@1.3.1: - resolution: {integrity: sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==} + /array.prototype.filter@1.0.3: + resolution: {integrity: sha512-VizNcj/RGJiUyQBgzwxzE5oHdeuXY5hSbbmKMlphj1cy1Vl7Pn2asCGbSrru6hSQjmCzqTBPVWAF/whmEOVHbw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - es-shim-unscopables: 1.0.0 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 + es-array-method-boxes-properly: 1.0.0 + is-string: 1.0.7 - /array.prototype.flatmap@1.3.1: - resolution: {integrity: sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==} + /array.prototype.findlastindex@1.2.4: + resolution: {integrity: sha512-hzvSHUshSpCflDR1QMUBLHGHP1VIEBegT4pix9H/Z92Xw3ySoy6c2qh7lJWTJnRJ8JCZ9bJNCgTyYaJGcJu6xQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - es-shim-unscopables: 1.0.0 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 + es-errors: 1.3.0 + es-shim-unscopables: 1.0.2 - /array.prototype.tosorted@1.1.1: - resolution: {integrity: sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==} + /array.prototype.flat@1.3.2: + resolution: {integrity: sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - es-shim-unscopables: 1.0.0 - get-intrinsic: 1.2.0 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 + es-shim-unscopables: 1.0.2 + + /array.prototype.flatmap@1.3.2: + resolution: {integrity: sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 + es-shim-unscopables: 1.0.2 + + /array.prototype.tosorted@1.1.3: + resolution: {integrity: sha512-/DdH4TiTmOKzyQbp/eadcCVexiCb36xJg7HshYOYJnNZFDj33GEv0P7GxsynpShhq4OLYJzbGcBDkLsDt7MnNg==} + dependencies: + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 + es-errors: 1.3.0 + es-shim-unscopables: 1.0.2 dev: true + /arraybuffer.prototype.slice@1.0.3: + resolution: {integrity: sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.1 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 + is-array-buffer: 3.0.4 + is-shared-array-buffer: 1.0.3 + /ast-types-flow@0.0.7: resolution: {integrity: sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==} dev: true @@ -2409,11 +2323,13 @@ packages: /at-least-node@1.0.0: resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} engines: {node: '>= 4.0.0'} - dev: true + dev: false - /available-typed-arrays@1.0.5: - resolution: {integrity: sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==} + /available-typed-arrays@1.0.7: + resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + dependencies: + possible-typed-array-names: 1.0.0 /axe-core@4.6.3: resolution: {integrity: sha512-/BQzOX780JhsxDnPpH4ZiyrJAzcd8AfzFPkv+89veFSr1rcMjuq2JDCwypKaPeB6ljHp9KjXhPpjgCvQlWYuqg==} @@ -2432,41 +2348,41 @@ packages: dependencies: '@babel/runtime': 7.21.0 cosmiconfig: 7.1.0 - resolve: 1.22.2 + resolve: 1.22.8 dev: true - /babel-plugin-polyfill-corejs2@0.3.3(@babel/core@7.22.9): + /babel-plugin-polyfill-corejs2@0.3.3(@babel/core@7.24.0): resolution: {integrity: sha512-8hOdmFYFSZhqg2C/JgLUQ+t52o5nirNwaWM2B9LWteozwIvM14VSwdsCAUET10qT+kmySAlseadmfeeSWFCy+Q==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/compat-data': 7.21.4 - '@babel/core': 7.22.9 - '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.22.9) + '@babel/compat-data': 7.23.5 + '@babel/core': 7.24.0 + '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.24.0) semver: 6.3.1 transitivePeerDependencies: - supports-color dev: true - /babel-plugin-polyfill-corejs3@0.6.0(@babel/core@7.22.9): + /babel-plugin-polyfill-corejs3@0.6.0(@babel/core@7.24.0): resolution: {integrity: sha512-+eHqR6OPcBhJOGgsIar7xoAB1GcSwVUA3XjAd7HJNzOXT4wv6/H7KIdA/Nc60cvUlDbKApmqNvD1B1bzOt4nyA==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.22.9) + '@babel/core': 7.24.0 + '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.24.0) core-js-compat: 3.30.0 transitivePeerDependencies: - supports-color dev: true - /babel-plugin-polyfill-regenerator@0.4.1(@babel/core@7.22.9): + /babel-plugin-polyfill-regenerator@0.4.1(@babel/core@7.24.0): resolution: {integrity: sha512-NtQGmyQDXjQqQ+IzRkBVwEOz9lQ4zxAQZgoAYEtU9dJjnl1Oc98qnN7jcp+bE7O7aYzVpavXE3/VKXNzUbh7aw==} peerDependencies: '@babel/core': ^7.0.0-0 dependencies: - '@babel/core': 7.22.9 - '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.22.9) + '@babel/core': 7.24.0 + '@babel/helper-define-polyfill-provider': 0.3.3(@babel/core@7.24.0) transitivePeerDependencies: - supports-color dev: true @@ -2478,20 +2394,20 @@ packages: /babel-preset-react-app@10.0.1: resolution: {integrity: sha512-b0D9IZ1WhhCWkrTXyFuIIgqGzSkRIH5D5AmB0bXbzYAB1OBAwHcUeyWW2LorutLWF5btNo/N7r/cIdmvvKJlYg==} dependencies: - '@babel/core': 7.22.9 - '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-proposal-decorators': 7.21.0(@babel/core@7.22.9) - '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-proposal-numeric-separator': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.22.9) - '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-proposal-private-property-in-object': 7.21.0(@babel/core@7.22.9) - '@babel/plugin-transform-flow-strip-types': 7.21.0(@babel/core@7.22.9) - '@babel/plugin-transform-react-display-name': 7.18.6(@babel/core@7.22.9) - '@babel/plugin-transform-runtime': 7.21.4(@babel/core@7.22.9) - '@babel/preset-env': 7.21.4(@babel/core@7.22.9) - '@babel/preset-react': 7.18.6(@babel/core@7.22.9) - '@babel/preset-typescript': 7.21.4(@babel/core@7.22.9) + '@babel/core': 7.24.0 + '@babel/plugin-proposal-class-properties': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-proposal-decorators': 7.21.0(@babel/core@7.24.0) + '@babel/plugin-proposal-nullish-coalescing-operator': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-proposal-numeric-separator': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-proposal-optional-chaining': 7.21.0(@babel/core@7.24.0) + '@babel/plugin-proposal-private-methods': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-proposal-private-property-in-object': 7.21.0(@babel/core@7.24.0) + '@babel/plugin-transform-flow-strip-types': 7.21.0(@babel/core@7.24.0) + '@babel/plugin-transform-react-display-name': 7.18.6(@babel/core@7.24.0) + '@babel/plugin-transform-runtime': 7.21.4(@babel/core@7.24.0) + '@babel/preset-env': 7.21.4(@babel/core@7.24.0) + '@babel/preset-react': 7.18.6(@babel/core@7.24.0) + '@babel/preset-typescript': 7.21.4(@babel/core@7.24.0) '@babel/runtime': 7.21.0 babel-plugin-macros: 3.1.0 babel-plugin-transform-react-remove-prop-types: 0.4.24 @@ -2504,6 +2420,19 @@ packages: /base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: false + + /big-integer@1.6.52: + resolution: {integrity: sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==} + engines: {node: '>=0.6'} + dev: true + + /binary@0.3.0: + resolution: {integrity: sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==} + dependencies: + buffers: 0.1.1 + chainsaw: 0.1.0 + dev: true /bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} @@ -2511,9 +2440,14 @@ packages: buffer: 5.7.1 inherits: 2.0.4 readable-stream: 3.6.2 + dev: false - /body-parser@1.20.1: - resolution: {integrity: sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==} + /bluebird@3.4.7: + resolution: {integrity: sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==} + dev: true + + /body-parser@1.20.2: + resolution: {integrity: sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} dependencies: bytes: 3.1.2 @@ -2525,7 +2459,7 @@ packages: iconv-lite: 0.4.24 on-finished: 2.4.1 qs: 6.11.0 - raw-body: 2.5.1 + raw-body: 2.5.2 type-is: 1.6.18 unpipe: 1.0.0 transitivePeerDependencies: @@ -2548,32 +2482,32 @@ packages: dependencies: fill-range: 7.0.1 - /browserslist@4.21.5: - resolution: {integrity: sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==} + /browserslist@4.23.0: + resolution: {integrity: sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001474 - electron-to-chromium: 1.4.356 - node-releases: 2.0.10 - update-browserslist-db: 1.0.10(browserslist@4.21.5) - dev: true + caniuse-lite: 1.0.30001599 + electron-to-chromium: 1.4.708 + node-releases: 2.0.14 + update-browserslist-db: 1.0.13(browserslist@4.23.0) - /browserslist@4.21.9: - resolution: {integrity: sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - dependencies: - caniuse-lite: 1.0.30001516 - electron-to-chromium: 1.4.461 - node-releases: 2.0.13 - update-browserslist-db: 1.0.11(browserslist@4.21.9) + /buffer-indexof-polyfill@1.0.2: + resolution: {integrity: sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==} + engines: {node: '>=0.10'} + dev: true /buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} dependencies: base64-js: 1.5.1 ieee754: 1.2.1 + dev: false + + /buffers@0.1.1: + resolution: {integrity: sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==} + engines: {node: '>=0.2.0'} + dev: true /bytes@3.1.2: resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} @@ -2598,22 +2532,33 @@ packages: responselike: 2.0.1 dev: false - /call-bind@1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} + /call-bind@1.0.7: + resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} + engines: {node: '>= 0.4'} dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.2.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + set-function-length: 1.2.2 /callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} - /caniuse-lite@1.0.30001474: - resolution: {integrity: sha512-iaIZ8gVrWfemh5DG3T9/YqarVZoYf0r188IjaGwx68j4Pf0SGY6CQkmJUIE+NZHkkecQGohzXmBGEwWDr9aM3Q==} + /caniuse-lite@1.0.30001599: + resolution: {integrity: sha512-LRAQHZ4yT1+f9LemSMeqdMpMxZcc4RMWdj4tiFe3G8tNkWK+E58g+/tzotb5cU6TbcVJLr4fySiAW7XmxQvZQA==} + + /case-anything@2.1.13: + resolution: {integrity: sha512-zlOQ80VrQ2Ue+ymH5OuM/DlDq64mEm+B9UTdHULv5osUMD6HalNTblf2b1u/m6QecjsnOkBpqVZ+XPwIVsy7Ng==} + engines: {node: '>=12.13'} dev: true - /caniuse-lite@1.0.30001516: - resolution: {integrity: sha512-Wmec9pCBY8CWbmI4HsjBeQLqDTqV91nFVR83DnZpYyRnPI1wePDsTg0bGLPC5VU/3OIZV1fmxEea1b+tFKe86g==} + /chainsaw@0.1.0: + resolution: {integrity: sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==} + dependencies: + traverse: 0.3.9 + dev: true /chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} @@ -2656,7 +2601,7 @@ packages: /chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} - dev: true + dev: false /cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} @@ -2664,7 +2609,7 @@ packages: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 - dev: true + dev: false /cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} @@ -2675,12 +2620,34 @@ packages: wrap-ansi: 7.0.0 dev: false + /clone-buffer@1.0.0: + resolution: {integrity: sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==} + engines: {node: '>= 0.10'} + dev: true + /clone-response@1.0.3: resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==} dependencies: mimic-response: 1.0.1 dev: false + /clone-stats@1.0.0: + resolution: {integrity: sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==} + dev: true + + /clone@2.1.2: + resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} + engines: {node: '>=0.8'} + dev: true + + /cloneable-readable@1.1.3: + resolution: {integrity: sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==} + dependencies: + inherits: 2.0.4 + process-nextick-args: 2.0.1 + readable-stream: 2.3.8 + dev: true + /color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} dependencies: @@ -2724,8 +2691,8 @@ packages: engines: {node: '>= 0.6'} dev: false - /convert-source-map@1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} + /convert-source-map@2.0.0: + resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} /cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} @@ -2739,12 +2706,11 @@ packages: /core-js-compat@3.30.0: resolution: {integrity: sha512-P5A2h/9mRYZFIAP+5Ab8ns6083IyVpSclU74UNvbGVQ8VM7n3n3/g2yF3AkKQ9NXz2O+ioxLbEWKnDtgsFamhg==} dependencies: - browserslist: 4.21.5 + browserslist: 4.23.0 dev: true /core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - dev: true /cors@2.8.5: resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} @@ -2796,6 +2762,35 @@ packages: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} dev: true + /data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + dev: true + + /data-view-buffer@1.0.1: + resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + /data-view-byte-length@1.0.1: + resolution: {integrity: sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + + /data-view-byte-offset@1.0.0: + resolution: {integrity: sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + es-errors: 1.3.0 + is-data-view: 1.0.1 + /date-format@4.0.14: resolution: {integrity: sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==} engines: {node: '>=4.0'} @@ -2838,33 +2833,34 @@ packages: engines: {node: '>=10'} dependencies: mimic-response: 3.1.0 + dev: false /deep-equal@2.2.0: resolution: {integrity: sha512-RdpzE0Hv4lhowpIUKKMJfeH6C1pXdtT1/it80ubgWqwI3qpuxUBpC1S4hnHg+zjnuOoDkzUtUCEEkG+XG5l3Mw==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 es-get-iterator: 1.1.3 - get-intrinsic: 1.2.0 + get-intrinsic: 1.2.4 is-arguments: 1.1.1 - is-array-buffer: 3.0.2 + is-array-buffer: 3.0.4 is-date-object: 1.0.5 is-regex: 1.1.4 - is-shared-array-buffer: 1.0.2 + is-shared-array-buffer: 1.0.3 isarray: 2.0.5 object-is: 1.1.5 object-keys: 1.1.1 - object.assign: 4.1.4 - regexp.prototype.flags: 1.4.3 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 side-channel: 1.0.4 which-boxed-primitive: 1.0.2 which-collection: 1.0.1 - which-typed-array: 1.1.9 + which-typed-array: 1.1.15 dev: true /deep-extend@0.6.0: resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} engines: {node: '>=4.0.0'} - dev: true + dev: false /deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -2880,16 +2876,25 @@ packages: native-promise-only: 0.8.1 dev: false + /define-data-property@1.1.4: + resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} + engines: {node: '>= 0.4'} + dependencies: + es-define-property: 1.0.0 + es-errors: 1.3.0 + gopd: 1.0.1 + /define-lazy-prop@2.0.0: resolution: {integrity: sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==} engines: {node: '>=8'} dev: false - /define-properties@1.2.0: - resolution: {integrity: sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==} + /define-properties@1.2.1: + resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==} engines: {node: '>= 0.4'} dependencies: - has-property-descriptors: 1.0.0 + define-data-property: 1.1.4 + has-property-descriptors: 1.0.2 object-keys: 1.1.1 /delayed-stream@1.0.0: @@ -2907,10 +2912,16 @@ packages: engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} dev: false + /detect-libc@1.0.3: + resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} + engines: {node: '>=0.10'} + hasBin: true + dev: true + /detect-libc@2.0.2: resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} engines: {node: '>=8'} - dev: true + dev: false /diff@4.0.2: resolution: {integrity: sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==} @@ -2966,24 +2977,33 @@ packages: domhandler: 5.0.3 dev: false - /dotenv@16.3.1: - resolution: {integrity: sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==} + /dotenv@16.4.5: + resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==} engines: {node: '>=12'} dev: false + /dprint-node@1.0.8: + resolution: {integrity: sha512-iVKnUtYfGrYcW1ZAlfR/F59cUVL8QIhWoBJoSjkkdua/dkWIgjZfiLMeTjiB06X0ZLkQ0M2C1VbUj/CxkIf1zg==} + dependencies: + detect-libc: 1.0.3 + dev: true + + /duplexer2@0.1.4: + resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==} + dependencies: + readable-stream: 2.3.8 + dev: true + /ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} dev: false - /electron-to-chromium@1.4.356: - resolution: {integrity: sha512-nEftV1dRX3omlxAj42FwqRZT0i4xd2dIg39sog/CnCJeCcL1TRd2Uh0i9Oebgv8Ou0vzTPw++xc+Z20jzS2B6A==} - dev: true - - /electron-to-chromium@1.4.461: - resolution: {integrity: sha512-1JkvV2sgEGTDXjdsaQCeSwYYuhLRphRpc+g6EHTFELJXEiznLt3/0pZ9JuAOQ5p2rI3YxKTbivtvajirIfhrEQ==} + /electron-to-chromium@1.4.708: + resolution: {integrity: sha512-iWgEEvREL4GTXXHKohhh33+6Y8XkPI5eHihDmm8zUk5Zo7HICEW+wI/j5kJ2tbuNUCXJ/sNXa03ajW635DiJXA==} /emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + dev: false /emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} @@ -2998,6 +3018,7 @@ packages: resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} dependencies: once: 1.4.0 + dev: false /entities@4.4.0: resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==} @@ -3010,50 +3031,121 @@ packages: is-arrayish: 0.2.1 dev: true - /es-abstract@1.21.2: - resolution: {integrity: sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg==} + /es-abstract@1.22.5: + resolution: {integrity: sha512-oW69R+4q2wG+Hc3KZePPZxOiisRIqfKBVo/HLx94QcJeWGU/8sZhCvc829rd1kS366vlJbzBfXf9yWwf0+Ko7w==} engines: {node: '>= 0.4'} dependencies: - array-buffer-byte-length: 1.0.0 - available-typed-arrays: 1.0.5 - call-bind: 1.0.2 - es-set-tostringtag: 2.0.1 + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-set-tostringtag: 2.0.3 es-to-primitive: 1.2.1 - function.prototype.name: 1.1.5 - get-intrinsic: 1.2.0 - get-symbol-description: 1.0.0 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 globalthis: 1.0.3 gopd: 1.0.1 - has: 1.0.3 - has-property-descriptors: 1.0.0 - has-proto: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 has-symbols: 1.0.3 - internal-slot: 1.0.5 - is-array-buffer: 3.0.2 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 is-callable: 1.2.7 - is-negative-zero: 2.0.2 + is-negative-zero: 2.0.3 is-regex: 1.1.4 - is-shared-array-buffer: 1.0.2 + is-shared-array-buffer: 1.0.3 is-string: 1.0.7 - is-typed-array: 1.1.10 + is-typed-array: 1.1.13 is-weakref: 1.0.2 - object-inspect: 1.12.3 + object-inspect: 1.13.1 object-keys: 1.1.1 - object.assign: 4.1.4 - regexp.prototype.flags: 1.4.3 - safe-regex-test: 1.0.0 - string.prototype.trim: 1.2.7 - string.prototype.trimend: 1.0.6 - string.prototype.trimstart: 1.0.6 - typed-array-length: 1.0.4 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.7 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.5 unbox-primitive: 1.0.2 - which-typed-array: 1.1.9 + which-typed-array: 1.1.15 + + /es-abstract@1.23.1: + resolution: {integrity: sha512-r+YVn6hTqQb+P5kK0u3KeDqrmhHKm+OhU/Mw4jSL4eQtOxXmp75fXIUUb3sUqFZOlb/YtW5JRaIfEC3UyjYUZQ==} + engines: {node: '>= 0.4'} + dependencies: + array-buffer-byte-length: 1.0.1 + arraybuffer.prototype.slice: 1.0.3 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + data-view-buffer: 1.0.1 + data-view-byte-length: 1.0.1 + data-view-byte-offset: 1.0.0 + es-define-property: 1.0.0 + es-errors: 1.3.0 + es-object-atoms: 1.0.0 + es-set-tostringtag: 2.0.3 + es-to-primitive: 1.2.1 + function.prototype.name: 1.1.6 + get-intrinsic: 1.2.4 + get-symbol-description: 1.0.2 + globalthis: 1.0.3 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + has-proto: 1.0.3 + has-symbols: 1.0.3 + hasown: 2.0.2 + internal-slot: 1.0.7 + is-array-buffer: 3.0.4 + is-callable: 1.2.7 + is-data-view: 1.0.1 + is-negative-zero: 2.0.3 + is-regex: 1.1.4 + is-shared-array-buffer: 1.0.3 + is-string: 1.0.7 + is-typed-array: 1.1.13 + is-weakref: 1.0.2 + object-inspect: 1.13.1 + object-keys: 1.1.1 + object.assign: 4.1.5 + regexp.prototype.flags: 1.5.2 + safe-array-concat: 1.1.2 + safe-regex-test: 1.0.3 + string.prototype.trim: 1.2.9 + string.prototype.trimend: 1.0.8 + string.prototype.trimstart: 1.0.7 + typed-array-buffer: 1.0.2 + typed-array-byte-length: 1.0.1 + typed-array-byte-offset: 1.0.2 + typed-array-length: 1.0.5 + unbox-primitive: 1.0.2 + which-typed-array: 1.1.15 + + /es-array-method-boxes-properly@1.0.0: + resolution: {integrity: sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==} + + /es-define-property@1.0.0: + resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==} + engines: {node: '>= 0.4'} + dependencies: + get-intrinsic: 1.2.4 + + /es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} /es-get-iterator@1.1.3: resolution: {integrity: sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw==} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.0 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 is-arguments: 1.1.1 is-map: 2.0.2 @@ -3063,18 +3155,24 @@ packages: stop-iteration-iterator: 1.0.0 dev: true - /es-set-tostringtag@2.0.1: - resolution: {integrity: sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==} + /es-object-atoms@1.0.0: + resolution: {integrity: sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.0 - has: 1.0.3 - has-tostringtag: 1.0.0 + es-errors: 1.3.0 - /es-shim-unscopables@1.0.0: - resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} + /es-set-tostringtag@2.0.3: + resolution: {integrity: sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==} + engines: {node: '>= 0.4'} dependencies: - has: 1.0.3 + get-intrinsic: 1.2.4 + has-tostringtag: 1.0.2 + hasown: 2.0.2 + + /es-shim-unscopables@1.0.2: + resolution: {integrity: sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==} + dependencies: + hasown: 2.0.2 /es-to-primitive@1.2.1: resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} @@ -3100,7 +3198,7 @@ packages: resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} engines: {node: '>=10'} - /eslint-config-react-app@7.0.1(@babel/plugin-syntax-flow@7.22.5)(@babel/plugin-transform-react-jsx@7.22.5)(eslint@8.45.0)(typescript@5.1.6): + /eslint-config-react-app@7.0.1(@babel/plugin-syntax-flow@7.23.3)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0)(typescript@5.1.6): resolution: {integrity: sha512-K6rNzvkIeHaTd8m/QEh1Zko0KI7BACWkkneSs6s9cKZC/J27X3eZR6Upt1jkmZ/4FK+XUOPPxMEN7+lbUXfSlA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -3110,21 +3208,21 @@ packages: typescript: optional: true dependencies: - '@babel/core': 7.22.9 - '@babel/eslint-parser': 7.21.3(@babel/core@7.22.9)(eslint@8.45.0) + '@babel/core': 7.24.0 + '@babel/eslint-parser': 7.21.3(@babel/core@7.24.0)(eslint@8.57.0) '@rushstack/eslint-patch': 1.2.0 - '@typescript-eslint/eslint-plugin': 5.57.1(@typescript-eslint/parser@5.57.1)(eslint@8.45.0)(typescript@5.1.6) - '@typescript-eslint/parser': 5.57.1(eslint@8.45.0)(typescript@5.1.6) + '@typescript-eslint/eslint-plugin': 5.57.1(@typescript-eslint/parser@5.57.1)(eslint@8.57.0)(typescript@5.1.6) + '@typescript-eslint/parser': 5.57.1(eslint@8.57.0)(typescript@5.1.6) babel-preset-react-app: 10.0.1 confusing-browser-globals: 1.0.11 - eslint: 8.45.0 - eslint-plugin-flowtype: 8.0.3(@babel/plugin-syntax-flow@7.22.5)(@babel/plugin-transform-react-jsx@7.22.5)(eslint@8.45.0) - eslint-plugin-import: 2.27.5(@typescript-eslint/parser@5.57.1)(eslint@8.45.0) - eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.57.1)(eslint@8.45.0)(typescript@5.1.6) - eslint-plugin-jsx-a11y: 6.7.1(eslint@8.45.0) - eslint-plugin-react: 7.32.2(eslint@8.45.0) - eslint-plugin-react-hooks: 4.6.0(eslint@8.45.0) - eslint-plugin-testing-library: 5.10.2(eslint@8.45.0)(typescript@5.1.6) + eslint: 8.57.0 + eslint-plugin-flowtype: 8.0.3(@babel/plugin-syntax-flow@7.23.3)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0) + eslint-plugin-import: 2.29.1(@typescript-eslint/parser@5.57.1)(eslint@8.57.0) + eslint-plugin-jest: 25.7.0(@typescript-eslint/eslint-plugin@5.57.1)(eslint@8.57.0)(typescript@5.1.6) + eslint-plugin-jsx-a11y: 6.7.1(eslint@8.57.0) + eslint-plugin-react: 7.32.2(eslint@8.57.0) + eslint-plugin-react-hooks: 4.6.0(eslint@8.57.0) + eslint-plugin-testing-library: 5.10.2(eslint@8.57.0)(typescript@5.1.6) typescript: 5.1.6 transitivePeerDependencies: - '@babel/plugin-syntax-flow' @@ -3135,17 +3233,17 @@ packages: - supports-color dev: true - /eslint-import-resolver-node@0.3.7: - resolution: {integrity: sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==} + /eslint-import-resolver-node@0.3.9: + resolution: {integrity: sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==} dependencies: debug: 3.2.7 - is-core-module: 2.11.0 - resolve: 1.22.2 + is-core-module: 2.13.1 + resolve: 1.22.8 transitivePeerDependencies: - supports-color - /eslint-module-utils@2.7.4(@typescript-eslint/parser@5.57.1)(eslint-import-resolver-node@0.3.7)(eslint@8.45.0): - resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} + /eslint-module-utils@2.8.1(@typescript-eslint/parser@5.57.1)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): + resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -3165,16 +3263,16 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 5.57.1(eslint@8.45.0)(typescript@5.1.6) + '@typescript-eslint/parser': 5.57.1(eslint@8.57.0)(typescript@5.1.6) debug: 3.2.7 - eslint: 8.45.0 - eslint-import-resolver-node: 0.3.7 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color dev: true - /eslint-module-utils@2.7.4(@typescript-eslint/parser@6.0.0)(eslint-import-resolver-node@0.3.7)(eslint@8.45.0): - resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} + /eslint-module-utils@2.8.1(@typescript-eslint/parser@6.0.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): + resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -3194,15 +3292,15 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 6.0.0(eslint@8.45.0)(typescript@5.1.6) + '@typescript-eslint/parser': 6.0.0(eslint@8.57.0)(typescript@5.1.6) debug: 3.2.7 - eslint: 8.45.0 - eslint-import-resolver-node: 0.3.7 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color dev: false - /eslint-plugin-flowtype@8.0.3(@babel/plugin-syntax-flow@7.22.5)(@babel/plugin-transform-react-jsx@7.22.5)(eslint@8.45.0): + /eslint-plugin-flowtype@8.0.3(@babel/plugin-syntax-flow@7.23.3)(@babel/plugin-transform-react-jsx@7.23.4)(eslint@8.57.0): resolution: {integrity: sha512-dX8l6qUL6O+fYPtpNRideCFSpmWOUVx5QcaGLVqe/vlDiBSe4vYljDWDETwnyFzpl7By/WVIu6rcrniCgH9BqQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -3210,15 +3308,15 @@ packages: '@babel/plugin-transform-react-jsx': ^7.14.9 eslint: ^8.1.0 dependencies: - '@babel/plugin-syntax-flow': 7.22.5(@babel/core@7.22.9) - '@babel/plugin-transform-react-jsx': 7.22.5(@babel/core@7.22.9) - eslint: 8.45.0 + '@babel/plugin-syntax-flow': 7.23.3(@babel/core@7.24.0) + '@babel/plugin-transform-react-jsx': 7.23.4(@babel/core@7.24.0) + eslint: 8.57.0 lodash: 4.17.21 string-natural-compare: 3.0.1 dev: true - /eslint-plugin-import@2.27.5(@typescript-eslint/parser@5.57.1)(eslint@8.45.0): - resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@5.57.1)(eslint@8.57.0): + resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -3227,31 +3325,33 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 5.57.1(eslint@8.45.0)(typescript@5.1.6) - array-includes: 3.1.6 - array.prototype.flat: 1.3.1 - array.prototype.flatmap: 1.3.1 + '@typescript-eslint/parser': 5.57.1(eslint@8.57.0)(typescript@5.1.6) + array-includes: 3.1.7 + array.prototype.findlastindex: 1.2.4 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 debug: 3.2.7 doctrine: 2.1.0 - eslint: 8.45.0 - eslint-import-resolver-node: 0.3.7 - eslint-module-utils: 2.7.4(@typescript-eslint/parser@5.57.1)(eslint-import-resolver-node@0.3.7)(eslint@8.45.0) - has: 1.0.3 - is-core-module: 2.11.0 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@5.57.1)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + hasown: 2.0.2 + is-core-module: 2.13.1 is-glob: 4.0.3 minimatch: 3.1.2 - object.values: 1.1.6 - resolve: 1.22.2 - semver: 6.3.0 - tsconfig-paths: 3.14.2 + object.fromentries: 2.0.7 + object.groupby: 1.0.2 + object.values: 1.1.7 + semver: 6.3.1 + tsconfig-paths: 3.15.0 transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color dev: true - /eslint-plugin-import@2.27.5(@typescript-eslint/parser@6.0.0)(eslint@8.45.0): - resolution: {integrity: sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==} + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@6.0.0)(eslint@8.57.0): + resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} engines: {node: '>=4'} peerDependencies: '@typescript-eslint/parser': '*' @@ -3260,30 +3360,32 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 6.0.0(eslint@8.45.0)(typescript@5.1.6) - array-includes: 3.1.6 - array.prototype.flat: 1.3.1 - array.prototype.flatmap: 1.3.1 + '@typescript-eslint/parser': 6.0.0(eslint@8.57.0)(typescript@5.1.6) + array-includes: 3.1.7 + array.prototype.findlastindex: 1.2.4 + array.prototype.flat: 1.3.2 + array.prototype.flatmap: 1.3.2 debug: 3.2.7 doctrine: 2.1.0 - eslint: 8.45.0 - eslint-import-resolver-node: 0.3.7 - eslint-module-utils: 2.7.4(@typescript-eslint/parser@6.0.0)(eslint-import-resolver-node@0.3.7)(eslint@8.45.0) - has: 1.0.3 - is-core-module: 2.11.0 + eslint: 8.57.0 + eslint-import-resolver-node: 0.3.9 + eslint-module-utils: 2.8.1(@typescript-eslint/parser@6.0.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + hasown: 2.0.2 + is-core-module: 2.13.1 is-glob: 4.0.3 minimatch: 3.1.2 - object.values: 1.1.6 - resolve: 1.22.2 - semver: 6.3.0 - tsconfig-paths: 3.14.2 + object.fromentries: 2.0.7 + object.groupby: 1.0.2 + object.values: 1.1.7 + semver: 6.3.1 + tsconfig-paths: 3.15.0 transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack - supports-color dev: false - /eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@5.57.1)(eslint@8.45.0)(typescript@5.1.6): + /eslint-plugin-jest@25.7.0(@typescript-eslint/eslint-plugin@5.57.1)(eslint@8.57.0)(typescript@5.1.6): resolution: {integrity: sha512-PWLUEXeeF7C9QGKqvdSbzLOiLTx+bno7/HC9eefePfEb257QFHg7ye3dh80AZVkaa/RQsBB1Q/ORQvg2X7F0NQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} peerDependencies: @@ -3296,15 +3398,15 @@ packages: jest: optional: true dependencies: - '@typescript-eslint/eslint-plugin': 5.57.1(@typescript-eslint/parser@5.57.1)(eslint@8.45.0)(typescript@5.1.6) - '@typescript-eslint/experimental-utils': 5.57.1(eslint@8.45.0)(typescript@5.1.6) - eslint: 8.45.0 + '@typescript-eslint/eslint-plugin': 5.57.1(@typescript-eslint/parser@5.57.1)(eslint@8.57.0)(typescript@5.1.6) + '@typescript-eslint/experimental-utils': 5.57.1(eslint@8.57.0)(typescript@5.1.6) + eslint: 8.57.0 transitivePeerDependencies: - supports-color - typescript dev: true - /eslint-plugin-jsx-a11y@6.7.1(eslint@8.45.0): + /eslint-plugin-jsx-a11y@6.7.1(eslint@8.57.0): resolution: {integrity: sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA==} engines: {node: '>=4.0'} peerDependencies: @@ -3312,64 +3414,64 @@ packages: dependencies: '@babel/runtime': 7.21.0 aria-query: 5.1.3 - array-includes: 3.1.6 - array.prototype.flatmap: 1.3.1 + array-includes: 3.1.7 + array.prototype.flatmap: 1.3.2 ast-types-flow: 0.0.7 axe-core: 4.6.3 axobject-query: 3.1.1 damerau-levenshtein: 1.0.8 emoji-regex: 9.2.2 - eslint: 8.45.0 + eslint: 8.57.0 has: 1.0.3 jsx-ast-utils: 3.3.3 language-tags: 1.0.5 minimatch: 3.1.2 - object.entries: 1.1.6 - object.fromentries: 2.0.6 + object.entries: 1.1.7 + object.fromentries: 2.0.7 semver: 6.3.1 dev: true - /eslint-plugin-react-hooks@4.6.0(eslint@8.45.0): + /eslint-plugin-react-hooks@4.6.0(eslint@8.57.0): resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} engines: {node: '>=10'} peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 dependencies: - eslint: 8.45.0 + eslint: 8.57.0 dev: true - /eslint-plugin-react@7.32.2(eslint@8.45.0): + /eslint-plugin-react@7.32.2(eslint@8.57.0): resolution: {integrity: sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==} engines: {node: '>=4'} peerDependencies: eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 dependencies: - array-includes: 3.1.6 - array.prototype.flatmap: 1.3.1 - array.prototype.tosorted: 1.1.1 + array-includes: 3.1.7 + array.prototype.flatmap: 1.3.2 + array.prototype.tosorted: 1.1.3 doctrine: 2.1.0 - eslint: 8.45.0 + eslint: 8.57.0 estraverse: 5.3.0 jsx-ast-utils: 3.3.3 minimatch: 3.1.2 - object.entries: 1.1.6 - object.fromentries: 2.0.6 - object.hasown: 1.1.2 - object.values: 1.1.6 + object.entries: 1.1.7 + object.fromentries: 2.0.7 + object.hasown: 1.1.3 + object.values: 1.1.7 prop-types: 15.8.1 - resolve: 2.0.0-next.4 - semver: 6.3.0 - string.prototype.matchall: 4.0.8 + resolve: 2.0.0-next.5 + semver: 6.3.1 + string.prototype.matchall: 4.0.10 dev: true - /eslint-plugin-testing-library@5.10.2(eslint@8.45.0)(typescript@5.1.6): + /eslint-plugin-testing-library@5.10.2(eslint@8.57.0)(typescript@5.1.6): resolution: {integrity: sha512-f1DmDWcz5SDM+IpCkEX0lbFqrrTs8HRsEElzDEqN/EBI0hpRj8Cns5+IVANXswE8/LeybIJqPAOQIFu2j5Y5sw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0, npm: '>=6'} peerDependencies: eslint: ^7.5.0 || ^8.0.0 dependencies: - '@typescript-eslint/utils': 5.57.1(eslint@8.45.0)(typescript@5.1.6) - eslint: 8.45.0 + '@typescript-eslint/utils': 5.57.1(eslint@8.57.0)(typescript@5.1.6) + eslint: 8.57.0 transitivePeerDependencies: - supports-color - typescript @@ -3383,8 +3485,8 @@ packages: estraverse: 4.3.0 dev: true - /eslint-scope@7.2.1: - resolution: {integrity: sha512-CvefSOsDdaYYvxChovdrPo/ZGt8d5lrJWleAc1diXRKhHGiTYEI26cvo8Kle/wGnsizoCJjK73FMg1/IkIwiNA==} + /eslint-scope@7.2.2: + resolution: {integrity: sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: esrecurse: 4.3.0 @@ -3395,30 +3497,31 @@ packages: engines: {node: '>=10'} dev: true - /eslint-visitor-keys@3.4.1: - resolution: {integrity: sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==} + /eslint-visitor-keys@3.4.3: + resolution: {integrity: sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - /eslint@8.45.0: - resolution: {integrity: sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==} + /eslint@8.57.0: + resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.4.0(eslint@8.45.0) - '@eslint-community/regexpp': 4.5.0 - '@eslint/eslintrc': 2.1.0 - '@eslint/js': 8.44.0 - '@humanwhocodes/config-array': 0.11.10 + '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) + '@eslint-community/regexpp': 4.10.0 + '@eslint/eslintrc': 2.1.4 + '@eslint/js': 8.57.0 + '@humanwhocodes/config-array': 0.11.14 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 + '@ungap/structured-clone': 1.2.0 ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 debug: 4.3.4 doctrine: 3.0.0 escape-string-regexp: 4.0.0 - eslint-scope: 7.2.1 - eslint-visitor-keys: 3.4.1 + eslint-scope: 7.2.2 + eslint-visitor-keys: 3.4.3 espree: 9.6.1 esquery: 1.5.0 esutils: 2.0.3 @@ -3450,7 +3553,7 @@ packages: dependencies: acorn: 8.10.0 acorn-jsx: 5.3.2(acorn@8.10.0) - eslint-visitor-keys: 3.4.1 + eslint-visitor-keys: 3.4.3 /esquery@1.5.0: resolution: {integrity: sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==} @@ -3485,15 +3588,15 @@ packages: /expand-template@2.0.3: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} engines: {node: '>=6'} - dev: true + dev: false - /express@4.18.2: - resolution: {integrity: sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==} + /express@4.18.3: + resolution: {integrity: sha512-6VyCijWQ+9O7WuVMTRBTl+cjNNIzD5cY5mQ1WM8r/LEkI2u8EYpOotESNwzNlyCn3g+dmjKYI6BmNneSr/FSRw==} engines: {node: '>= 0.10.0'} dependencies: accepts: 1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.1 + body-parser: 1.20.2 content-disposition: 0.5.4 content-type: 1.0.5 cookie: 0.5.0 @@ -3550,6 +3653,14 @@ packages: dependencies: reusify: 1.0.4 + /fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + dev: true + /ffprobe@1.1.2: resolution: {integrity: sha512-a+oTbhyeM7Z8PRy+mpzmVUAnATZT7z4BO94HSKeqHupdmjiKZ1djzcZkyoyXA21zCOCG7oVRrsBMmvvtmzoz4g==} dependencies: @@ -3616,6 +3727,13 @@ packages: mime-types: 2.1.35 dev: false + /formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + dependencies: + fetch-blob: 3.2.0 + dev: true + /forwarded@0.2.0: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} @@ -3631,14 +3749,14 @@ packages: dependencies: inherits: 2.0.4 readable-stream: 2.3.8 - dev: true + dev: false /fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} - dev: true + dev: false - /fs-extra@11.1.1: - resolution: {integrity: sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ==} + /fs-extra@11.2.0: + resolution: {integrity: sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==} engines: {node: '>=14.14'} dependencies: graceful-fs: 4.2.11 @@ -3663,21 +3781,34 @@ packages: graceful-fs: 4.2.11 jsonfile: 6.1.0 universalify: 2.0.0 - dev: true + dev: false /fs.realpath@1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} + /fstream@1.0.12: + resolution: {integrity: sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==} + engines: {node: '>=0.6'} + dependencies: + graceful-fs: 4.2.11 + inherits: 2.0.4 + mkdirp: 0.5.6 + rimraf: 2.7.1 + dev: true + /function-bind@1.1.1: resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - /function.prototype.name@1.1.5: - resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} + /function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + /function.prototype.name@1.1.6: + resolution: {integrity: sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 functions-have-names: 1.2.3 /functions-have-names@1.2.3: @@ -3690,13 +3821,17 @@ packages: /get-caller-file@2.0.5: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + dev: false - /get-intrinsic@1.2.0: - resolution: {integrity: sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q==} + /get-intrinsic@1.2.4: + resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} + engines: {node: '>= 0.4'} dependencies: - function-bind: 1.1.1 - has: 1.0.3 + es-errors: 1.3.0 + function-bind: 1.1.2 + has-proto: 1.0.3 has-symbols: 1.0.3 + hasown: 2.0.2 /get-stream@5.2.0: resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} @@ -3705,16 +3840,17 @@ packages: pump: 3.0.0 dev: false - /get-symbol-description@1.0.0: - resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} + /get-symbol-description@1.0.2: + resolution: {integrity: sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.0 + call-bind: 1.0.7 + es-errors: 1.3.0 + get-intrinsic: 1.2.4 /github-from-package@0.0.0: resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==} - dev: true + dev: false /glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} @@ -3759,7 +3895,7 @@ packages: resolution: {integrity: sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==} engines: {node: '>= 0.4'} dependencies: - define-properties: 1.2.0 + define-properties: 1.2.1 /globby@11.1.0: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} @@ -3775,7 +3911,7 @@ packages: /gopd@1.0.1: resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==} dependencies: - get-intrinsic: 1.2.0 + get-intrinsic: 1.2.4 /got@11.8.6: resolution: {integrity: sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==} @@ -3815,21 +3951,21 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} - /has-property-descriptors@1.0.0: - resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} + /has-property-descriptors@1.0.2: + resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} dependencies: - get-intrinsic: 1.2.0 + es-define-property: 1.0.0 - /has-proto@1.0.1: - resolution: {integrity: sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==} + /has-proto@1.0.3: + resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==} engines: {node: '>= 0.4'} /has-symbols@1.0.3: resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} engines: {node: '>= 0.4'} - /has-tostringtag@1.0.0: - resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} + /has-tostringtag@1.0.2: + resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==} engines: {node: '>= 0.4'} dependencies: has-symbols: 1.0.3 @@ -3840,6 +3976,12 @@ packages: dependencies: function-bind: 1.1.1 + /hasown@2.0.2: + resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} + engines: {node: '>= 0.4'} + dependencies: + function-bind: 1.1.2 + /htmlparser2@8.0.2: resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} dependencies: @@ -3880,7 +4022,7 @@ packages: debug: 4.3.4 transitivePeerDependencies: - supports-color - dev: true + dev: false /iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} @@ -3891,6 +4033,7 @@ packages: /ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: false /ignore@5.2.4: resolution: {integrity: sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==} @@ -3918,14 +4061,14 @@ packages: /ini@1.3.8: resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - dev: true + dev: false - /internal-slot@1.0.5: - resolution: {integrity: sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==} + /internal-slot@1.0.7: + resolution: {integrity: sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==} engines: {node: '>= 0.4'} dependencies: - get-intrinsic: 1.2.0 - has: 1.0.3 + es-errors: 1.3.0 + hasown: 2.0.2 side-channel: 1.0.4 /into-stream@6.0.0: @@ -3934,7 +4077,7 @@ packages: dependencies: from2: 2.3.0 p-is-promise: 3.0.0 - dev: true + dev: false /ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} @@ -3945,16 +4088,16 @@ packages: resolution: {integrity: sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - has-tostringtag: 1.0.0 + call-bind: 1.0.7 + has-tostringtag: 1.0.2 dev: true - /is-array-buffer@3.0.2: - resolution: {integrity: sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==} + /is-array-buffer@3.0.4: + resolution: {integrity: sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.0 - is-typed-array: 1.1.10 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 /is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} @@ -3969,8 +4112,8 @@ packages: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - has-tostringtag: 1.0.0 + call-bind: 1.0.7 + has-tostringtag: 1.0.2 /is-callable@1.2.7: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} @@ -3980,18 +4123,30 @@ packages: resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} dependencies: has: 1.0.3 + dev: true + + /is-core-module@2.13.1: + resolution: {integrity: sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==} + dependencies: + hasown: 2.0.2 /is-core-module@2.9.0: resolution: {integrity: sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==} dependencies: has: 1.0.3 - dev: true + dev: false + + /is-data-view@1.0.1: + resolution: {integrity: sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==} + engines: {node: '>= 0.4'} + dependencies: + is-typed-array: 1.1.13 /is-date-object@1.0.5: resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} engines: {node: '>= 0.4'} dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 /is-docker@2.2.1: resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} @@ -4006,6 +4161,7 @@ packages: /is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} + dev: false /is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} @@ -4017,15 +4173,15 @@ packages: resolution: {integrity: sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg==} dev: true - /is-negative-zero@2.0.2: - resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} + /is-negative-zero@2.0.3: + resolution: {integrity: sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==} engines: {node: '>= 0.4'} /is-number-object@1.0.7: resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} engines: {node: '>= 0.4'} dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} @@ -4039,23 +4195,24 @@ packages: resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - has-tostringtag: 1.0.0 + call-bind: 1.0.7 + has-tostringtag: 1.0.2 /is-set@2.0.2: resolution: {integrity: sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g==} dev: true - /is-shared-array-buffer@1.0.2: - resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} + /is-shared-array-buffer@1.0.3: + resolution: {integrity: sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 /is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} engines: {node: '>= 0.4'} dependencies: - has-tostringtag: 1.0.0 + has-tostringtag: 1.0.2 /is-symbol@1.0.4: resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} @@ -4063,15 +4220,11 @@ packages: dependencies: has-symbols: 1.0.3 - /is-typed-array@1.1.10: - resolution: {integrity: sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==} + /is-typed-array@1.1.13: + resolution: {integrity: sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==} engines: {node: '>= 0.4'} dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.2 - for-each: 0.3.3 - gopd: 1.0.1 - has-tostringtag: 1.0.0 + which-typed-array: 1.1.15 /is-weakmap@2.0.1: resolution: {integrity: sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA==} @@ -4080,13 +4233,13 @@ packages: /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 /is-weakset@2.0.2: resolution: {integrity: sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg==} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.0 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 dev: true /is-wsl@2.2.0: @@ -4098,11 +4251,9 @@ packages: /isarray@1.0.0: resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - dev: true /isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} - dev: true /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} @@ -4167,6 +4318,7 @@ packages: universalify: 2.0.0 optionalDependencies: graceful-fs: 4.2.11 + dev: false /jsonparse@1.3.1: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} @@ -4177,8 +4329,8 @@ packages: resolution: {integrity: sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==} engines: {node: '>=4.0'} dependencies: - array-includes: 3.1.6 - object.assign: 4.1.4 + array-includes: 3.1.7 + object.assign: 4.1.5 dev: true /keyv@4.5.2: @@ -4208,6 +4360,10 @@ packages: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} dev: true + /listenercount@1.0.1: + resolution: {integrity: sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==} + dev: true + /locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} @@ -4238,6 +4394,9 @@ packages: - supports-color dev: false + /long@5.2.3: + resolution: {integrity: sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==} + /lookpath@1.2.2: resolution: {integrity: sha512-k2Gmn8iV6qdME3ztZC2spubmQISimFOPLuQKiPaLcVdRz0IpdxrNClVepMlyTJlhodm/zG/VfbkWERm3kUIh+Q==} engines: {npm: '>=6.13.4'} @@ -4336,6 +4495,7 @@ packages: /mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} + dev: false /min-document@2.19.0: resolution: {integrity: sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ==} @@ -4353,8 +4513,25 @@ packages: /mkdirp-classic@0.5.3: resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==} + dev: false + + /mkdirp@0.5.6: + resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} + hasBin: true + dependencies: + minimist: 1.2.8 dev: true + /mpd-parser@1.3.0: + resolution: {integrity: sha512-WgeIwxAqkmb9uTn4ClicXpEQYCEduDqRKfmUdp4X8vmghKfBNXZLYpREn9eqrDx/Tf5LhzRcJLSpi4ohfV742Q==} + hasBin: true + dependencies: + '@babel/runtime': 7.21.0 + '@videojs/vhs-utils': 4.0.0 + '@xmldom/xmldom': 0.8.10 + global: 4.4.0 + dev: false + /ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} dev: false @@ -4370,11 +4547,11 @@ packages: dependencies: once: 1.4.0 readable-stream: 3.6.2 - dev: true + dev: false /napi-build-utils@1.0.2: resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==} - dev: true + dev: false /native-promise-only@0.8.1: resolution: {integrity: sha512-zkVhZUA3y8mbz652WrL5x0fB0ehrBkulWT3TomAQ9iDtyXZvzKeEA6GPxAItBYeNYl5yngKRX612qHOhvMkDeg==} @@ -4397,6 +4574,11 @@ packages: engines: {node: '>=10'} dependencies: semver: 7.5.4 + dev: false + + /node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} dev: true /node-fetch@2.7.0: @@ -4409,14 +4591,19 @@ packages: optional: true dependencies: whatwg-url: 5.0.0 + dev: false + + /node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 dev: true - /node-releases@2.0.10: - resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==} - dev: true - - /node-releases@2.0.13: - resolution: {integrity: sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ==} + /node-releases@2.0.14: + resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} /normalize-url@6.1.0: resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} @@ -4433,62 +4620,70 @@ packages: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} - /object-inspect@1.12.3: - resolution: {integrity: sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==} + /object-inspect@1.13.1: + resolution: {integrity: sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==} /object-is@1.1.5: resolution: {integrity: sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 + call-bind: 1.0.7 + define-properties: 1.2.1 dev: true /object-keys@1.1.1: resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} engines: {node: '>= 0.4'} - /object.assign@4.1.4: - resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} + /object.assign@4.1.5: + resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 + call-bind: 1.0.7 + define-properties: 1.2.1 has-symbols: 1.0.3 object-keys: 1.1.1 - /object.entries@1.1.6: - resolution: {integrity: sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==} + /object.entries@1.1.7: + resolution: {integrity: sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 dev: true - /object.fromentries@2.0.6: - resolution: {integrity: sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==} + /object.fromentries@2.0.7: + resolution: {integrity: sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - dev: true + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 - /object.hasown@1.1.2: - resolution: {integrity: sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==} + /object.groupby@1.0.2: + resolution: {integrity: sha512-bzBq58S+x+uo0VjurFT0UktpKHOZmv4/xePiOA1nbB9pMqpGK7rUPNgf+1YC+7mE+0HzhTMqNUuCqvKhj6FnBw==} dependencies: - define-properties: 1.2.0 - es-abstract: 1.21.2 + array.prototype.filter: 1.0.3 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 + es-errors: 1.3.0 + + /object.hasown@1.1.3: + resolution: {integrity: sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA==} + dependencies: + define-properties: 1.2.1 + es-abstract: 1.22.5 dev: true - /object.values@1.1.6: - resolution: {integrity: sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==} + /object.values@1.1.7: + resolution: {integrity: sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 /on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} @@ -4530,7 +4725,7 @@ packages: /p-is-promise@3.0.0: resolution: {integrity: sha512-Wo8VsW4IRQSKVXsJCn7TomUaVtyfjVDn3nUP7kE967BQk0CwFpdbZs0X0uk5sW9mkBa9eNM7hCMaG93WUAwxYQ==} engines: {node: '>=8'} - dev: true + dev: false /p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} @@ -4554,7 +4749,7 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} dependencies: - '@babel/code-frame': 7.21.4 + '@babel/code-frame': 7.23.5 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -4608,50 +4803,9 @@ packages: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - /pkg-fetch@3.4.2: - resolution: {integrity: sha512-0+uijmzYcnhC0hStDjm/cl2VYdrmVVBpe7Q8k9YBojxmR5tG8mvR9/nooQq3QSXiQqORDVOTY3XqMEqJVIzkHA==} - hasBin: true - dependencies: - chalk: 4.1.2 - fs-extra: 9.1.0 - https-proxy-agent: 5.0.1 - node-fetch: 2.7.0 - progress: 2.0.3 - semver: 7.5.4 - tar-fs: 2.1.1 - yargs: 16.2.0 - transitivePeerDependencies: - - encoding - - supports-color - dev: true - - /pkg@5.8.1: - resolution: {integrity: sha512-CjBWtFStCfIiT4Bde9QpJy0KeH19jCfwZRJqHFDFXfhUklCx8JoFmMj3wgnEYIwGmZVNkhsStPHEOnrtrQhEXA==} - hasBin: true - peerDependencies: - node-notifier: '>=9.0.1' - peerDependenciesMeta: - node-notifier: - optional: true - dependencies: - '@babel/generator': 7.18.2 - '@babel/parser': 7.18.4 - '@babel/types': 7.19.0 - chalk: 4.1.2 - fs-extra: 9.1.0 - globby: 11.1.0 - into-stream: 6.0.0 - is-core-module: 2.9.0 - minimist: 1.2.8 - multistream: 4.1.0 - pkg-fetch: 3.4.2 - prebuild-install: 7.1.1 - resolve: 1.22.2 - stream-meter: 1.0.4 - transitivePeerDependencies: - - encoding - - supports-color - dev: true + /possible-typed-array-names@1.0.0: + resolution: {integrity: sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==} + engines: {node: '>= 0.4'} /prebuild-install@7.1.1: resolution: {integrity: sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==} @@ -4670,7 +4824,7 @@ packages: simple-get: 4.0.1 tar-fs: 2.1.1 tunnel-agent: 0.6.0 - dev: true + dev: false /prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} @@ -4678,7 +4832,6 @@ packages: /process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - dev: true /process@0.11.10: resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} @@ -4688,7 +4841,7 @@ packages: /progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} - dev: true + dev: false /prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -4698,6 +4851,38 @@ packages: react-is: 16.13.1 dev: true + /protobufjs@7.2.6: + resolution: {integrity: sha512-dgJaEDDL6x8ASUZ1YqWciTRrdOuYNzoOf27oHNfdyvKqHr5i0FV7FSLU+aIeFjyFgVxrpTOtQUi0BLLBymZaBw==} + engines: {node: '>=12.0.0'} + requiresBuild: true + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.4 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.0 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.0 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.0 + '@types/node': 18.15.11 + long: 5.2.3 + + /protoc@1.1.3: + resolution: {integrity: sha512-Vy4OBxCcF0W38YrZZRFix659gFu8ujIxVDP1SUBK9ELzyeMSBe8m8tYyYlX1PI5j9gse9hWu4c4nzQaHesAf8Q==} + hasBin: true + requiresBuild: true + dependencies: + glob: 7.2.3 + mkdirp: 0.5.6 + node-fetch: 3.3.2 + rimraf: 3.0.2 + unzipper: 0.10.14 + uuid: 9.0.1 + vinyl: 2.2.1 + dev: true + /proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -4711,6 +4896,7 @@ packages: dependencies: end-of-stream: 1.4.4 once: 1.4.0 + dev: false /punycode@2.3.0: resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} @@ -4736,8 +4922,8 @@ packages: engines: {node: '>= 0.6'} dev: false - /raw-body@2.5.1: - resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} + /raw-body@2.5.2: + resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} dependencies: bytes: 3.1.2 @@ -4754,7 +4940,7 @@ packages: ini: 1.3.8 minimist: 1.2.8 strip-json-comments: 2.0.1 - dev: true + dev: false /react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} @@ -4770,7 +4956,6 @@ packages: safe-buffer: 5.1.2 string_decoder: 1.1.1 util-deprecate: 1.0.2 - dev: true /readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} @@ -4779,6 +4964,7 @@ packages: inherits: 2.0.4 string_decoder: 1.3.0 util-deprecate: 1.0.2 + dev: false /regenerate-unicode-properties@10.1.0: resolution: {integrity: sha512-d1VudCLoIGitcU/hEg2QqvyGZQmdC0Lf8BqdOMXGFSvJP4bNV1+XqbPQeHHLD51Jh4QJJ225dlIFvY4Ly6MXmQ==} @@ -4800,13 +4986,14 @@ packages: '@babel/runtime': 7.21.0 dev: true - /regexp.prototype.flags@1.4.3: - resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} + /regexp.prototype.flags@1.5.2: + resolution: {integrity: sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - functions-have-names: 1.2.3 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-errors: 1.3.0 + set-function-name: 2.0.2 /regexpu-core@5.3.2: resolution: {integrity: sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ==} @@ -4827,15 +5014,25 @@ packages: jsesc: 0.5.0 dev: true + /remove-trailing-separator@1.1.0: + resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} + dev: true + /removeNPMAbsolutePaths@3.0.1: resolution: {integrity: sha512-rJc1aHu5LT4rncs7gga/asiyQG+G1TkweO7L27D/oMBtfbHmSFSp7RgUtrfuZzk9c/4P2xHjHnD+cUNzWRFB4A==} engines: {node: '>=4.0.0'} hasBin: true dev: true + /replace-ext@1.0.1: + resolution: {integrity: sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==} + engines: {node: '>= 0.10'} + dev: true + /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} + dev: false /resolve-alpn@1.2.1: resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} @@ -4852,12 +5049,21 @@ packages: is-core-module: 2.11.0 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 + dev: true - /resolve@2.0.0-next.4: - resolution: {integrity: sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==} + /resolve@1.22.8: + resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} hasBin: true dependencies: - is-core-module: 2.11.0 + is-core-module: 2.13.1 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + /resolve@2.0.0-next.5: + resolution: {integrity: sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA==} + hasBin: true + dependencies: + is-core-module: 2.13.1 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 dev: true @@ -4876,6 +5082,13 @@ packages: resolution: {integrity: sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==} dev: false + /rimraf@2.7.1: + resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} + hasBin: true + dependencies: + glob: 7.2.3 + dev: true + /rimraf@3.0.2: resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} hasBin: true @@ -4887,18 +5100,28 @@ packages: dependencies: queue-microtask: 1.2.3 + /safe-array-concat@1.1.2: + resolution: {integrity: sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==} + engines: {node: '>=0.4'} + dependencies: + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + has-symbols: 1.0.3 + isarray: 2.0.5 + /safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - dev: true /safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} + dev: false - /safe-regex-test@1.0.0: - resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} + /safe-regex-test@1.0.3: + resolution: {integrity: sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.0 + call-bind: 1.0.7 + es-errors: 1.3.0 is-regex: 1.1.4 /safer-buffer@2.1.2: @@ -4909,10 +5132,6 @@ packages: resolution: {integrity: sha512-tHKNxiY5H5YayQ0QkxOvDZl35bH5OW2ptjk04j887hHA/pbj8ggsIKs7tb+wI7zViHOOY4JQorpQ8Jnj4LMitQ==} dev: false - /semver@6.3.0: - resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} - hasBin: true - /semver@6.3.1: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true @@ -4957,6 +5176,30 @@ packages: - supports-color dev: false + /set-function-length@1.2.2: + resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + function-bind: 1.1.2 + get-intrinsic: 1.2.4 + gopd: 1.0.1 + has-property-descriptors: 1.0.2 + + /set-function-name@2.0.2: + resolution: {integrity: sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==} + engines: {node: '>= 0.4'} + dependencies: + define-data-property: 1.1.4 + es-errors: 1.3.0 + functions-have-names: 1.2.3 + has-property-descriptors: 1.0.2 + + /setimmediate@1.0.5: + resolution: {integrity: sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==} + dev: true + /setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} dev: false @@ -4974,13 +5217,13 @@ packages: /side-channel@1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.2.0 - object-inspect: 1.12.3 + call-bind: 1.0.7 + get-intrinsic: 1.2.4 + object-inspect: 1.13.1 /simple-concat@1.0.1: resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==} - dev: true + dev: false /simple-get@4.0.1: resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==} @@ -4988,7 +5231,7 @@ packages: decompress-response: 6.0.0 once: 1.4.0 simple-concat: 1.0.1 - dev: true + dev: false /slash@3.0.0: resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} @@ -5003,14 +5246,14 @@ packages: resolution: {integrity: sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ==} engines: {node: '>= 0.4'} dependencies: - internal-slot: 1.0.5 + internal-slot: 1.0.7 dev: true /stream-meter@1.0.4: resolution: {integrity: sha512-4sOEtrbgFotXwnEuzzsQBYEV1elAeFSO8rSGeTwabuX1RRn/kEq9JVH7I0MRBhKVRR0sJkr0M0QCH7yOLf9fhQ==} dependencies: readable-stream: 2.3.8 - dev: true + dev: false /streamroller@3.1.5: resolution: {integrity: sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==} @@ -5034,52 +5277,55 @@ packages: emoji-regex: 8.0.0 is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + dev: false - /string.prototype.matchall@4.0.8: - resolution: {integrity: sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==} + /string.prototype.matchall@4.0.10: + resolution: {integrity: sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ==} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 - get-intrinsic: 1.2.0 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 + get-intrinsic: 1.2.4 has-symbols: 1.0.3 - internal-slot: 1.0.5 - regexp.prototype.flags: 1.4.3 + internal-slot: 1.0.7 + regexp.prototype.flags: 1.5.2 + set-function-name: 2.0.2 side-channel: 1.0.4 dev: true - /string.prototype.trim@1.2.7: - resolution: {integrity: sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==} + /string.prototype.trim@1.2.9: + resolution: {integrity: sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==} engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.23.1 + es-object-atoms: 1.0.0 - /string.prototype.trimend@1.0.6: - resolution: {integrity: sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==} + /string.prototype.trimend@1.0.8: + resolution: {integrity: sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-object-atoms: 1.0.0 - /string.prototype.trimstart@1.0.6: - resolution: {integrity: sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==} + /string.prototype.trimstart@1.0.7: + resolution: {integrity: sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==} dependencies: - call-bind: 1.0.2 - define-properties: 1.2.0 - es-abstract: 1.21.2 + call-bind: 1.0.7 + define-properties: 1.2.1 + es-abstract: 1.22.5 /string_decoder@1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} dependencies: safe-buffer: 5.1.2 - dev: true /string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} dependencies: safe-buffer: 5.2.1 + dev: false /strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} @@ -5094,7 +5340,7 @@ packages: /strip-json-comments@2.0.1: resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} engines: {node: '>=0.10.0'} - dev: true + dev: false /strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} @@ -5123,7 +5369,7 @@ packages: mkdirp-classic: 0.5.3 pump: 3.0.0 tar-stream: 2.2.0 - dev: true + dev: false /tar-stream@2.2.0: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} @@ -5134,7 +5380,7 @@ packages: fs-constants: 1.0.0 inherits: 2.0.4 readable-stream: 3.6.2 - dev: true + dev: false /text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} @@ -5160,6 +5406,10 @@ packages: /tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false + + /traverse@0.3.9: + resolution: {integrity: sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==} dev: true /ts-api-utils@1.0.1(typescript@5.1.6): @@ -5170,8 +5420,8 @@ packages: dependencies: typescript: 5.1.6 - /ts-node@10.9.1(@types/node@18.15.11)(typescript@5.1.6): - resolution: {integrity: sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==} + /ts-node@10.9.2(@types/node@18.15.11)(typescript@5.1.6): + resolution: {integrity: sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==} hasBin: true peerDependencies: '@swc/core': '>=1.2.50' @@ -5190,7 +5440,7 @@ packages: '@tsconfig/node14': 1.0.3 '@tsconfig/node16': 1.0.3 '@types/node': 18.15.11 - acorn: 8.8.2 + acorn: 8.10.0 acorn-walk: 8.2.0 arg: 4.1.3 create-require: 1.1.1 @@ -5201,8 +5451,31 @@ packages: yn: 3.1.1 dev: true - /tsconfig-paths@3.14.2: - resolution: {integrity: sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==} + /ts-poet@6.7.0: + resolution: {integrity: sha512-A0wvFtpkTCWPw7ftTIwbEH+L+7ul4CU0x3jXKQ+kCnmEQIAOwhpUaBmcAYKxZCxHae9/MUl4LbyTqw25BpzW5Q==} + dependencies: + dprint-node: 1.0.8 + dev: true + + /ts-proto-descriptors@1.15.0: + resolution: {integrity: sha512-TYyJ7+H+7Jsqawdv+mfsEpZPTIj9siDHS6EMCzG/z3b/PZiphsX+mWtqFfFVe5/N0Th6V3elK9lQqjnrgTOfrg==} + dependencies: + long: 5.2.3 + protobufjs: 7.2.6 + dev: true + + /ts-proto@1.169.1: + resolution: {integrity: sha512-MHdllDrtFCabxvIyUqze7/4vSh55SEgwirpthGVUGt3pMqIpmmrDyBv0vDk/RCjBxm0/LIWVMnXlOjBxYaE1rA==} + hasBin: true + dependencies: + case-anything: 2.1.13 + protobufjs: 7.2.6 + ts-poet: 6.7.0 + ts-proto-descriptors: 1.15.0 + dev: true + + /tsconfig-paths@3.15.0: + resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} dependencies: '@types/json5': 0.0.29 json5: 1.0.2 @@ -5227,7 +5500,7 @@ packages: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} dependencies: safe-buffer: 5.2.1 - dev: true + dev: false /type-check@0.4.0: resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} @@ -5247,12 +5520,45 @@ packages: mime-types: 2.1.35 dev: false - /typed-array-length@1.0.4: - resolution: {integrity: sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==} + /typed-array-buffer@1.0.2: + resolution: {integrity: sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==} + engines: {node: '>= 0.4'} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 + es-errors: 1.3.0 + is-typed-array: 1.1.13 + + /typed-array-byte-length@1.0.1: + resolution: {integrity: sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 for-each: 0.3.3 - is-typed-array: 1.1.10 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + /typed-array-byte-offset@1.0.2: + resolution: {integrity: sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==} + engines: {node: '>= 0.4'} + dependencies: + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + + /typed-array-length@1.0.5: + resolution: {integrity: sha512-yMi0PlwuznKHxKmcpoOdeLwxBoVPkqZxd7q2FgMkmD3bNwvF5VW0+UlUQ1k1vmktTu4Yu13Q0RIxEP8+B+wloA==} + engines: {node: '>= 0.4'} + dependencies: + call-bind: 1.0.7 + for-each: 0.3.3 + gopd: 1.0.1 + has-proto: 1.0.3 + is-typed-array: 1.1.13 + possible-typed-array-names: 1.0.0 /typescript-eslint@0.0.1-alpha.0: resolution: {integrity: sha512-1hNKM37dAWML/2ltRXupOq2uqcdRQyDFphl+341NTPXFLLLiDhErXx8VtaSLh3xP7SyHZdcCgpt9boYYVb3fQg==} @@ -5266,7 +5572,7 @@ packages: /unbox-primitive@1.0.2: resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} dependencies: - call-bind: 1.0.2 + call-bind: 1.0.7 has-bigints: 1.0.2 has-symbols: 1.0.3 which-boxed-primitive: 1.0.2 @@ -5302,30 +5608,35 @@ packages: /universalify@2.0.0: resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} engines: {node: '>= 10.0.0'} + dev: false /unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} dev: false - /update-browserslist-db@1.0.10(browserslist@4.21.5): - resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' + /unzipper@0.10.14: + resolution: {integrity: sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==} dependencies: - browserslist: 4.21.5 - escalade: 3.1.1 - picocolors: 1.0.0 + big-integer: 1.6.52 + binary: 0.3.0 + bluebird: 3.4.7 + buffer-indexof-polyfill: 1.0.2 + duplexer2: 0.1.4 + fstream: 1.0.12 + graceful-fs: 4.2.11 + listenercount: 1.0.1 + readable-stream: 2.3.8 + setimmediate: 1.0.5 dev: true - /update-browserslist-db@1.0.11(browserslist@4.21.9): - resolution: {integrity: sha512-dCwEFf0/oT85M1fHBg4F0jtLwJrutGoHSQXCh7u4o2t1drG+c0a9Flnqww6XUKSfQMPpJBRjU8d4RXB09qtvaA==} + /update-browserslist-db@1.0.13(browserslist@4.23.0): + resolution: {integrity: sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==} hasBin: true peerDependencies: browserslist: '>= 4.21.0' dependencies: - browserslist: 4.21.9 + browserslist: 4.23.0 escalade: 3.1.1 picocolors: 1.0.0 @@ -5346,6 +5657,11 @@ packages: engines: {node: '>= 0.4.0'} dev: false + /uuid@9.0.1: + resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} + hasBin: true + dev: true + /v8-compile-cache-lib@3.0.1: resolution: {integrity: sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==} dev: true @@ -5355,16 +5671,33 @@ packages: engines: {node: '>= 0.8'} dev: false + /vinyl@2.2.1: + resolution: {integrity: sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==} + engines: {node: '>= 0.10'} + dependencies: + clone: 2.1.2 + clone-buffer: 1.0.0 + clone-stats: 1.0.0 + cloneable-readable: 1.1.3 + remove-trailing-separator: 1.1.0 + replace-ext: 1.0.1 + dev: true + + /web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + dev: true + /webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - dev: true + dev: false /whatwg-url@5.0.0: resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} dependencies: tr46: 0.0.3 webidl-conversions: 3.0.1 - dev: true + dev: false /which-boxed-primitive@1.0.2: resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} @@ -5384,16 +5717,15 @@ packages: is-weakset: 2.0.2 dev: true - /which-typed-array@1.1.9: - resolution: {integrity: sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA==} + /which-typed-array@1.1.15: + resolution: {integrity: sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==} engines: {node: '>= 0.4'} dependencies: - available-typed-arrays: 1.0.5 - call-bind: 1.0.2 + available-typed-arrays: 1.0.7 + call-bind: 1.0.7 for-each: 0.3.3 gopd: 1.0.1 - has-tostringtag: 1.0.0 - is-typed-array: 1.1.10 + has-tostringtag: 1.0.2 /which@2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} @@ -5409,12 +5741,13 @@ packages: ansi-styles: 4.3.0 string-width: 4.2.3 strip-ansi: 6.0.1 + dev: false /wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - /ws@8.13.0: - resolution: {integrity: sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==} + /ws@8.16.0: + resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -5426,9 +5759,15 @@ packages: optional: true dev: false + /xmldom@0.6.0: + resolution: {integrity: sha512-iAcin401y58LckRZ0TkI4k0VSM1Qg0KGSc3i8rU+xrxe19A/BN1zHyVSJY7uoutVlaTSzYyk/v5AmkewAP7jtg==} + engines: {node: '>=10.0.0'} + dev: false + /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} + dev: false /yallist@3.1.1: resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} @@ -5441,15 +5780,16 @@ packages: engines: {node: '>= 6'} dev: true - /yaml@2.3.1: - resolution: {integrity: sha512-2eHWfjaoXgTBC2jNM1LRef62VQa0umtvRiDSk6HSzW7RvS5YtkabJrwYLLEKWBc8a5U2PTSCs+dJjUTJdlHsWQ==} + /yaml@2.4.1: + resolution: {integrity: sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==} engines: {node: '>= 14'} + hasBin: true dev: false /yargs-parser@20.2.9: resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'} - dev: true + dev: false /yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} @@ -5467,7 +5807,7 @@ packages: string-width: 4.2.3 y18n: 5.0.8 yargs-parser: 20.2.9 - dev: true + dev: false /yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} diff --git a/tsc.ts b/tsc.ts index a62dc55..8b2eedd 100644 --- a/tsc.ts +++ b/tsc.ts @@ -34,6 +34,7 @@ const ignore = [ './config/updates.json$', './config/cr_token.yml$', './config/funi_token.yml$', + './config/new_hd_token.yml$', './config/hd_token.yml$', './config/hd_sess.yml$', './config/hd_profile.yml$', @@ -42,7 +43,10 @@ const ignore = [ './fonts*', './gui/react*', './dev.js$', - '*/node_modules/*' + '*/node_modules/*', + './widevine/*', + './videos/*', + './logs/*', ].map(a => a.replace(/\*/g, '[^]*').replace(/\.\//g, escapeRegExp(__dirname) + '/').replace(/\//g, path.sep === '\\' ? '\\\\' : '/')).map(a => new RegExp(a, 'i')); export { ignore }; diff --git a/widevine/.gitkeep b/widevine/.gitkeep new file mode 100644 index 0000000..e69de29