1782 lines
67 KiB
TypeScript
1782 lines
67 KiB
TypeScript
/**
|
|
* This file was auto-generated by openapi-typescript.
|
|
* Do not make direct changes to the file.
|
|
*/
|
|
|
|
export interface paths {
|
|
"/radio/catalog/episode/context/{episodeId}": {
|
|
/** Takes a episode id and returns the context. Supports ODM and podcast episodes. */
|
|
get: operations["GetEpisodeContext"];
|
|
};
|
|
"/radio/catalog/programsContext/{programId}": {
|
|
/** Gets navigation aid for a programId. */
|
|
get: operations["GetProgramContext"];
|
|
};
|
|
"/radio/catalog/programs/{programId}": {
|
|
/** Gets the program page for a program id */
|
|
get: operations["GetProgram"];
|
|
};
|
|
"/radio/catalog/series/{seriesId}/type": {
|
|
/** Gets the radio series type */
|
|
get: operations["GetSeriesType"];
|
|
};
|
|
"/radio/catalog/series/{seriesId}": {
|
|
/** Gets a radio series page */
|
|
get: operations["GetSeries"];
|
|
};
|
|
"/radio/catalog/series/{seriesId}/episodes": {
|
|
/** Gets episodes for a radio series */
|
|
get: operations["GetSeriesepisodes"];
|
|
};
|
|
"/radio/catalog/series/{seriesId}/seasons/{seasonId}": {
|
|
/** Gets a season for a radio series */
|
|
get: operations["GetSeriesSeason"];
|
|
};
|
|
"/radio/catalog/series/{seriesId}/seasons/{seasonId}/episodes": {
|
|
/** Gets episodes for a radio series season */
|
|
get: operations["GetSeriesSeasonEpisodes"];
|
|
};
|
|
"/radio/catalog/extramaterial/{id}/clips": {
|
|
/** Gets clip extramaterials for a radio or podcast series */
|
|
get: operations["GetExtramaterialClips"];
|
|
};
|
|
"/radio/catalog/version/{id}": {
|
|
/** Gets the preferred series type (ODM or podcast) */
|
|
get: operations["GetVersion"];
|
|
};
|
|
"/radio/catalog/podcast/{podcastId}": {
|
|
/** Gets a podcast page */
|
|
get: operations["GetPodcast"];
|
|
};
|
|
"/radio/catalog/podcast/{podcastId}/episodes": {
|
|
/** Gets episodes for a podcast series */
|
|
get: operations["GetPodcastepisodes"];
|
|
};
|
|
"/radio/catalog/podcast/{podcastId}/episodes/{podcastEpisodeId}": {
|
|
/** Gets a podcast episode */
|
|
get: operations["GetPodcastEpisode"];
|
|
};
|
|
"/radio/catalog/podcast/{podcastId}/seasons/{seasonId}": {
|
|
/** Gets a season for a podcast series */
|
|
get: operations["GetPodcastSeason"];
|
|
};
|
|
"/radio/catalog/podcast/{podcastId}/seasons/{seasonId}/episodes": {
|
|
/** Gets episodes for a podcast series season */
|
|
get: operations["GetPodcastSeasonEpisodes"];
|
|
};
|
|
}
|
|
|
|
export interface components {
|
|
schemas: {
|
|
EpisodeContext: {
|
|
type: components["schemas"]["Type"];
|
|
_links: {
|
|
self: components["schemas"]["HalLink"];
|
|
series?: components["schemas"]["HalLinkNameAndTitle"];
|
|
season?: components["schemas"]["EpisodeSeasonHalLink"];
|
|
episode: components["schemas"]["HalLink"];
|
|
};
|
|
};
|
|
SeriesHalResource: {
|
|
_links: components["schemas"]["SeriesHalLinks"];
|
|
seriesType: components["schemas"]["SeriesType"];
|
|
type: components["schemas"]["Type"];
|
|
seasonDisplayType: components["schemas"]["SeasonDisplayType"];
|
|
series: components["schemas"]["SeriesViewModel"];
|
|
_embedded: components["schemas"]["SeriesHalEmbedded"];
|
|
};
|
|
SeriesViewModel: {
|
|
id: string;
|
|
highlightedEpisode?: string;
|
|
nextEpisode?: components["schemas"]["NextEpisode"];
|
|
titles: components["schemas"]["Titles"];
|
|
category: components["schemas"]["Category"];
|
|
/** @description The array is empty if no images are present */
|
|
image: components["schemas"]["Image"][];
|
|
/** @description The array is empty if no images are present */
|
|
posterImage: components["schemas"]["Image"][];
|
|
/** @description The array is empty if no images are present */
|
|
backdropImage: components["schemas"]["Image"][];
|
|
/** @description The array is empty if no images are present */
|
|
squareImage: components["schemas"]["Image"][];
|
|
};
|
|
/** @description `StandardSeries` only gets episodes embedded. `SequentialSeries` gets seasons included. `UmbrellaSeries` gets both episodes and seasons included. */
|
|
SeriesHalEmbedded: {
|
|
episodes?: components["schemas"]["EpisodesSeriesHalEmbedded"];
|
|
/** @description By default 1 season is embedded. Umbrella series with seasonDisplayType 'manual' gets all seasons embedded. */
|
|
seasons?: components["schemas"]["SeasonSeriesHalEmbedded"][];
|
|
};
|
|
SeasonSeriesHalEmbedded: {
|
|
_links?: components["schemas"]["SeasonSeriesHalEmbeddedLinks"];
|
|
id: string;
|
|
titles: components["schemas"]["Titles"];
|
|
hasAvailableEpisodes: boolean;
|
|
episodeCount: number;
|
|
/** @description The array is empty if no images are present */
|
|
image?: components["schemas"]["Image"][];
|
|
episodes?: components["schemas"]["EpisodesSeriesHalEmbedded"];
|
|
/** @description Array of badges for this season. Only "new"-badge currently supported. Only applicable for seasons in Umbrella-podcasts. Otherwise not in response. */
|
|
badges?: components["schemas"]["Badge"][];
|
|
/** @description Number of new episodes in this season. Used in conjunction with `progressesForNewEpisodes`-link to check progresses for new episodes in season. New-badge should be removed if the number of new episodes matches the number of episodes with started/finished progress. Only applicable for seasons in Umbrella-podcasts. Otherwise not in response. */
|
|
newEpisodesCount?: number;
|
|
} & {
|
|
links: unknown;
|
|
};
|
|
SeasonSeriesHalEmbeddedLinks: {
|
|
self: components["schemas"]["HalLink"];
|
|
/** @description Links to check progresses for new episodes in season. Used in conjuction with `newEpisodesCount`. Only applicable for seasons in Umbrella-podcasts. Otherwise not in response. */
|
|
progressesForNewEpisodes?: components["schemas"]["HalLinkTemplated"][];
|
|
};
|
|
SeasonHalLinks: {
|
|
self: components["schemas"]["HalLink"];
|
|
series?: components["schemas"]["HalLinkNameAndTitle"];
|
|
podcast?: components["schemas"]["HalLinkNameAndTitle"];
|
|
episodes: components["schemas"]["HalLink"];
|
|
extraMaterial?: components["schemas"]["HalLink"];
|
|
};
|
|
PodcastSeasonHalLinks: {
|
|
self: components["schemas"]["HalLink"];
|
|
series?: components["schemas"]["HalLinkNameAndTitle"];
|
|
podcast?: components["schemas"]["HalLinkNameAndTitle"];
|
|
episodes: components["schemas"]["HalLink"];
|
|
extraMaterial?: components["schemas"]["HalLink"];
|
|
favourite?: components["schemas"]["HalLinkTemplated"];
|
|
share?: components["schemas"]["HalLinkShare"];
|
|
};
|
|
EpisodesSeriesHalEmbedded: {
|
|
_links: components["schemas"]["EpisodesHalLinks"];
|
|
_embedded: components["schemas"]["EpisodesEpisodesHalEmbedded"];
|
|
};
|
|
EpisodesEpisodesHalEmbedded: {
|
|
episodes?: components["schemas"]["EpisodeHalResource"][];
|
|
};
|
|
EpisodesHalLinks: {
|
|
self: components["schemas"]["HalLink"];
|
|
next?: components["schemas"]["HalLink"];
|
|
prev?: components["schemas"]["HalLink"];
|
|
progresses?: components["schemas"]["ProgressesHalLinks"];
|
|
};
|
|
EpisodesHalResource: {
|
|
_links: components["schemas"]["EpisodesHalLinks"];
|
|
seriesType: components["schemas"]["SeriesType"];
|
|
_embedded: components["schemas"]["EpisodesEpisodesHalEmbedded"];
|
|
};
|
|
EpisodeHalResource: {
|
|
_links: components["schemas"]["EpisodeHalLinks"];
|
|
id: string;
|
|
episodeId: string;
|
|
date: string;
|
|
titles: components["schemas"]["Titles"];
|
|
originalTitle?: string;
|
|
/** @description The array is empty if no images are present */
|
|
image?: components["schemas"]["Image"][];
|
|
/** @description Duration of the episode. We use the [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601#Durations) format for duration. */
|
|
duration: string;
|
|
/** Format: int32 */
|
|
durationInSeconds: number;
|
|
usageRights: components["schemas"]["UsageRightsVm"];
|
|
/** Format: int32 */
|
|
productionYear?: number;
|
|
availability: components["schemas"]["AvailabilityVm"];
|
|
contributors?: components["schemas"]["ContributorVm"][];
|
|
/** @description Array of badges indication statuses */
|
|
badges?: components["schemas"]["Badge"][];
|
|
};
|
|
EpisodeHalLinks: {
|
|
self: components["schemas"]["HalLink"];
|
|
playback: components["schemas"]["HalLink"];
|
|
series: components["schemas"]["HalLinkNameAndTitle"];
|
|
season?: components["schemas"]["EpisodeSeasonHalLink"];
|
|
favourite?: components["schemas"]["HalLinkTemplated"];
|
|
share?: components["schemas"]["HalLinkShare"];
|
|
progress?: components["schemas"]["HalLinkTemplated"];
|
|
};
|
|
PodcastSeasonHalResource: {
|
|
_links: components["schemas"]["PodcastSeasonHalLinks"];
|
|
seriesType: components["schemas"]["SeriesType"];
|
|
type: components["schemas"]["Type"];
|
|
titles: components["schemas"]["Titles"];
|
|
category: components["schemas"]["Category"];
|
|
/** @description The array is empty if no images are present */
|
|
image?: components["schemas"]["Image"][];
|
|
/** @description The array is empty if no images are present */
|
|
posterImage?: components["schemas"]["Image"][];
|
|
/** @description The array is empty if no images are present */
|
|
backdropImage?: components["schemas"]["Image"][];
|
|
/** @description The array is empty if no images are present */
|
|
squareImage?: components["schemas"]["Image"][];
|
|
hasAvailableEpisodes: boolean;
|
|
episodeCount: number;
|
|
_embedded: {
|
|
episodes?: components["schemas"]["EpisodesSeriesHalEmbedded"];
|
|
};
|
|
};
|
|
SeasonHalResource: {
|
|
_links: components["schemas"]["SeasonHalLinks"];
|
|
seriesType: components["schemas"]["SeriesType"];
|
|
type: components["schemas"]["Type"];
|
|
titles: components["schemas"]["Titles"];
|
|
/** @description The array is empty if no images are present */
|
|
image?: components["schemas"]["Image"][];
|
|
/** @description The array is empty if no images are present */
|
|
posterImage?: components["schemas"]["Image"][];
|
|
/** @description The array is empty if no images are present */
|
|
backdropImage?: components["schemas"]["Image"][];
|
|
/** @description The array is empty if no images are present */
|
|
squareImage?: components["schemas"]["Image"][];
|
|
hasAvailableEpisodes: boolean;
|
|
episodeCount: number;
|
|
_embedded: {
|
|
episodes?: components["schemas"]["EpisodesSeriesHalEmbedded"];
|
|
};
|
|
};
|
|
SeriesTypeHalResource: {
|
|
_links: components["schemas"]["SeriesTypeHalLinks"];
|
|
seriesType: components["schemas"]["SeriesType"];
|
|
};
|
|
SeriesTypeHalLinks: {
|
|
self: components["schemas"]["HalLink"];
|
|
};
|
|
SeriesHalLinks: {
|
|
self: components["schemas"]["HalLink"];
|
|
highlightedEpisode?: components["schemas"]["HalLinkTemplated"];
|
|
favourite?: components["schemas"]["HalLinkTemplated"];
|
|
seasons: components["schemas"]["HalLinkNameAndTitle"][];
|
|
podcast?: components["schemas"]["HalLink"];
|
|
episodes?: components["schemas"]["EpisodesHalLink"];
|
|
userData?: components["schemas"]["HalLinkTemplated"];
|
|
extraMaterial?: components["schemas"]["HalLink"];
|
|
preferred?: components["schemas"]["HalLink"];
|
|
};
|
|
OdmProgramsHalResource: {
|
|
_links: components["schemas"]["ProgramsHalLinks"];
|
|
id: string;
|
|
episodeId: string;
|
|
date: string;
|
|
programInformation: components["schemas"]["ProgramInformation"];
|
|
contributors?: components["schemas"]["OdmContributorVm"][];
|
|
/** @description The array is empty if no images are present */
|
|
image: components["schemas"]["Image"][];
|
|
titles: components["schemas"]["Titles"];
|
|
availability: components["schemas"]["AvailabilityVm"];
|
|
category: components["schemas"]["OdmCategory"];
|
|
usageRights?: components["schemas"]["UsageRightsVm"];
|
|
/** Format: int32 */
|
|
productionYear?: number;
|
|
duration: components["schemas"]["Duration"];
|
|
indexPoints?: components["schemas"]["IndexPoint"][];
|
|
/** @description Playlist only applies to ODM episodes - podcast episodes does not have playlists. */
|
|
playlist?: components["schemas"]["LiveElement"][];
|
|
};
|
|
PodcastEpisodeHalResource: {
|
|
_links: components["schemas"]["ProgramsHalLinks"];
|
|
id: string;
|
|
episodeId: string;
|
|
date: string;
|
|
category: components["schemas"]["Category"];
|
|
programInformation: components["schemas"]["ProgramInformation"];
|
|
/** @description The array is empty if no images are present */
|
|
image: components["schemas"]["Image"][];
|
|
titles: components["schemas"]["Titles"];
|
|
/** @description Podcast indexpoints use the same contract as odm index points but only Title and StartPoint will be set */
|
|
indexPoints?: components["schemas"]["IndexPoint"][];
|
|
availability: components["schemas"]["AvailabilityVm"];
|
|
usageRights?: components["schemas"]["UsageRightsVm"];
|
|
duration: components["schemas"]["Duration"];
|
|
};
|
|
LiveElement: {
|
|
title?: string;
|
|
description?: string;
|
|
programId?: string;
|
|
channelId?: string;
|
|
/** @description DateTime formatted string */
|
|
startTime?: string;
|
|
/** @description ISO-8601 duration of the playlist element */
|
|
duration?: string;
|
|
type?: string;
|
|
programTitle?: string;
|
|
/** @description ISO-8601 duration calculated from the episode start time */
|
|
startPoint?: string;
|
|
};
|
|
IndexPoint: {
|
|
title?: string;
|
|
mentioned?: string[];
|
|
subjectList?: string[];
|
|
contributors?: components["schemas"]["ContributorVm"][];
|
|
description?: string;
|
|
/** @description ISO-8601 duration calculated from the episode start time */
|
|
startPoint?: string;
|
|
};
|
|
ProgramInformation: {
|
|
details?: components["schemas"]["DetailsVm"];
|
|
originalTitle?: string;
|
|
};
|
|
ProgramsHalLinks: {
|
|
self: components["schemas"]["HalLink"];
|
|
playback: components["schemas"]["HalLink"];
|
|
series?: components["schemas"]["HalLinkNameAndTitle"];
|
|
season?: components["schemas"]["EpisodeSeasonHalLink"];
|
|
favourite?: components["schemas"]["HalLinkTemplated"];
|
|
share?: components["schemas"]["HalLinkShare"];
|
|
progress?: components["schemas"]["HalLinkTemplated"];
|
|
extraMaterial?: components["schemas"]["HalLink"];
|
|
};
|
|
DetailsVm: {
|
|
displayValue: string;
|
|
accessibilityValue: string;
|
|
};
|
|
/** @description Applies to Standard, News and Umbrella series. The date and display value for the next upcoming episode. */
|
|
NextEpisode: {
|
|
date?: string;
|
|
/** @description Display text for when the episode will be available */
|
|
displayValue?: string;
|
|
};
|
|
/**
|
|
* @description Follows the guidelines from https://nrkconfluence.atlassian.net/l/c/y03p59M0
|
|
* @example {
|
|
* "title": "1. Stolt fortid, stor framtid",
|
|
* "subtitle": "Helena prøver å få kontakt med Camilla før sesongens første kamp mot Rosenborg. Espen jobbar desperat for å redde økonomien i klubben."
|
|
* }
|
|
*/
|
|
Titles: {
|
|
title: string;
|
|
subtitle?: string | null;
|
|
};
|
|
UsageRightsVm: {
|
|
from: components["schemas"]["UsageRightsDateVm"];
|
|
to: components["schemas"]["UsageRightsDateVm"];
|
|
geoBlock: components["schemas"]["GeoBlockVm"];
|
|
};
|
|
UsageRightsDateVm: {
|
|
date: string;
|
|
displayValue: string;
|
|
};
|
|
GeoBlockVm: {
|
|
isGeoBlocked: boolean;
|
|
displayValue: components["schemas"]["GeoBlockDisplayValue"];
|
|
};
|
|
/** @enum {string} */
|
|
AvailabilityStatus:
|
|
| "coming"
|
|
| "available"
|
|
| "expires"
|
|
| "expired"
|
|
| "notAvailableOnline";
|
|
/**
|
|
* @example {
|
|
* "href": "/some/url"
|
|
* }
|
|
*/
|
|
HalLink: {
|
|
href: string;
|
|
};
|
|
/**
|
|
* @description Episodes link are included for `StandardSeries` and `UmbrellaSeries`. `SequentialSeries` has no notion of episodes, only seasons.
|
|
* @example {
|
|
* "href": "/some/url"
|
|
* }
|
|
*/
|
|
EpisodesHalLink: {
|
|
href: string;
|
|
};
|
|
HalLinkTemplated: {
|
|
href: string;
|
|
templated: boolean;
|
|
};
|
|
HalLinkShare: {
|
|
/** @description Query param `e` for episode, `p` for podcast, `s` for series. https://radio.nrk.no/lytt?s=saann-er-du{&autoplay} */
|
|
href: string;
|
|
templated: boolean;
|
|
};
|
|
/**
|
|
* @example {
|
|
* "href": "/tv/catalog/series/radioresepsjonen/seasons/201912",
|
|
* "name": "201912",
|
|
* "title": "Desember 2019"
|
|
* }
|
|
*/
|
|
HalLinkNameAndTitle: {
|
|
href: string;
|
|
name: string;
|
|
title: string;
|
|
};
|
|
/**
|
|
* @example {
|
|
* "href": "/tv/catalog/series/radioresepsjonen/seasons/201912",
|
|
* "name": "201912",
|
|
* "title": "Desember 2019",
|
|
* "seriesType": "standard"
|
|
* }
|
|
*/
|
|
EpisodeSeasonHalLink: {
|
|
href: string;
|
|
name: string;
|
|
title: string;
|
|
/** @enum {string} */
|
|
seriesType: "standard" | "news" | "sequential" | "umbrella";
|
|
};
|
|
/**
|
|
* @example {
|
|
* "id": "nyheter",
|
|
* "name": "Nyheter"
|
|
* }
|
|
*/
|
|
Category: {
|
|
id: string;
|
|
name: string;
|
|
};
|
|
/**
|
|
* @example {
|
|
* "id": "nyheter",
|
|
* "displayValue": "Nyheter"
|
|
* }
|
|
*/
|
|
OdmCategory: {
|
|
id: string;
|
|
displayValue: string;
|
|
};
|
|
/**
|
|
* @example {
|
|
* "url": "https://gfx.nrk.no/urxQMSXF-WnbfjBH5ke2igaWzubx5CSW-Z6FOsEAclhA",
|
|
* "width": 1920
|
|
* }
|
|
*/
|
|
Image: {
|
|
/** Format: uri */
|
|
url: string;
|
|
/** Format: int32 */
|
|
width: number;
|
|
};
|
|
/** @enum {string} */
|
|
SeriesType: "sequential" | "news" | "standard" | "umbrella";
|
|
/** @enum {string} */
|
|
Type: "series" | "podcast";
|
|
/** @enum {string} */
|
|
SortDirection: "desc" | "asc";
|
|
/** @enum {string} */
|
|
SeasonDisplayType: "number" | "month" | "quarter" | "year" | "manual";
|
|
/** @description Progresses link output applies to all episodes in the given list. */
|
|
ProgressesHalLinks: components["schemas"]["ProgressesHalLink"][];
|
|
/**
|
|
* @description ProgressHalLink consists of a list of comma-separated programIds that we gzip, base64 and url encode to avoid exceeding character limit in the url.
|
|
* @example {
|
|
* "href": "/tv/userdata/{userId}/progress/series/radioresepsjonen?contentIds=H4sIAAAAAAAAC_Pzc3M0tDQwNTIxtNTxg3GMkTlGhpYAsMOBOyYAAAA",
|
|
* "templated": true
|
|
* }
|
|
*/
|
|
ProgressesHalLink: {
|
|
href: string;
|
|
templated: boolean;
|
|
};
|
|
/** @enum {string} */
|
|
GeoBlockDisplayValue: "Verden" | "Norge";
|
|
/** @description Represents the Availability of a Program based on the active usage rights. */
|
|
AvailabilityVm: {
|
|
status: components["schemas"]["AvailabilityStatus"];
|
|
/** @description Label should only be displayed if HasLabel is true. */
|
|
hasLabel: boolean;
|
|
/**
|
|
* @description Label to be showed to the user based on the AvailabilityStatus.
|
|
* Example: "Tilgjengelig i morgen"
|
|
*/
|
|
label?: string;
|
|
};
|
|
ContributorVm: {
|
|
role: string;
|
|
name: string[];
|
|
};
|
|
OdmContributorVm: {
|
|
role: string;
|
|
name: string[];
|
|
};
|
|
/** @description Duration of the episode. We use the [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601#Durations) format for duration. */
|
|
Duration: {
|
|
/** Format: int32 */
|
|
seconds: number;
|
|
displayValue: string;
|
|
iso8601: string;
|
|
};
|
|
ExtraMaterialClipsHalResource: {
|
|
_links: components["schemas"]["ExtraMaterialClipsHalLinks"];
|
|
/**
|
|
* Format: int32
|
|
* @description Total number of clips for the given series/podcast. The number is only an indication, and does not reflect the number of non-playable clips. I.e. do not use this field for any kind of logic.
|
|
*/
|
|
totalClips: number;
|
|
_embedded: components["schemas"]["ExtraMaterialClipsHalEmbedded"];
|
|
};
|
|
/** @description Aggregated info for clips */
|
|
ExtraMaterialClipsHalEmbedded: {
|
|
metadata?: {
|
|
displayAspectRatio: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["DisplayAspectRatio"];
|
|
/**
|
|
* @description Clip length. The string is formatted as https://en.wikipedia.org/wiki/ISO_8601#Durations
|
|
* @example PT2M0S
|
|
*/
|
|
duration: string;
|
|
id: string;
|
|
/** @enum {undefined} */
|
|
playability: "nonPlayable" | "playable";
|
|
preplay: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PreplayVm"];
|
|
/** @description Link to full metadata */
|
|
_links: {
|
|
self: components["schemas"]["HalLink"];
|
|
};
|
|
}[];
|
|
};
|
|
ExtraMaterialClipsHalLinks: {
|
|
self: components["schemas"]["HalLink"];
|
|
share: components["schemas"]["HalLink"];
|
|
};
|
|
Badge: {
|
|
label?: string;
|
|
/** @enum {undefined} */
|
|
type?: "new";
|
|
};
|
|
};
|
|
}
|
|
|
|
export interface operations {
|
|
/** Takes a episode id and returns the context. Supports ODM and podcast episodes. */
|
|
GetEpisodeContext: {
|
|
parameters: {
|
|
path: {
|
|
/** The episode id */
|
|
episodeId: string;
|
|
};
|
|
};
|
|
responses: {
|
|
/** Success */
|
|
200: {
|
|
content: {
|
|
"application/json": components["schemas"]["EpisodeContext"];
|
|
};
|
|
};
|
|
/** Episode not found */
|
|
404: unknown;
|
|
};
|
|
};
|
|
/** Gets navigation aid for a programId. */
|
|
GetProgramContext: {
|
|
parameters: {
|
|
path: {
|
|
/** The program id */
|
|
programId: string;
|
|
};
|
|
};
|
|
responses: {
|
|
/** Success */
|
|
200: {
|
|
content: {
|
|
"application/json": components["schemas"]["EpisodeContext"];
|
|
};
|
|
};
|
|
/** Program not found */
|
|
404: unknown;
|
|
};
|
|
};
|
|
/** Gets the program page for a program id */
|
|
GetProgram: {
|
|
parameters: {
|
|
path: {
|
|
/** The program id */
|
|
programId: string;
|
|
};
|
|
};
|
|
responses: {
|
|
/** Success */
|
|
200: {
|
|
content: {
|
|
"application/json": components["schemas"]["OdmProgramsHalResource"];
|
|
};
|
|
};
|
|
/** Program not found */
|
|
404: unknown;
|
|
};
|
|
};
|
|
/** Gets the radio series type */
|
|
GetSeriesType: {
|
|
parameters: {
|
|
path: {
|
|
/** The series id */
|
|
seriesId: string;
|
|
};
|
|
};
|
|
responses: {
|
|
/** Success */
|
|
200: {
|
|
content: {
|
|
"application/json": components["schemas"]["SeriesTypeHalResource"];
|
|
};
|
|
};
|
|
/** Series not found */
|
|
404: unknown;
|
|
};
|
|
};
|
|
/** Gets a radio series page */
|
|
GetSeries: {
|
|
parameters: {
|
|
path: {
|
|
/** The series id */
|
|
seriesId: string;
|
|
};
|
|
query: {
|
|
/** This parameter only affects Standard and News Series. Default is 10. */
|
|
pageSize?: number;
|
|
};
|
|
};
|
|
responses: {
|
|
/** Success */
|
|
200: {
|
|
content: {
|
|
"application/json": components["schemas"]["SeriesHalResource"];
|
|
};
|
|
};
|
|
/** Series not found */
|
|
404: unknown;
|
|
};
|
|
};
|
|
/** Gets episodes for a radio series */
|
|
GetSeriesepisodes: {
|
|
parameters: {
|
|
path: {
|
|
/** The series id */
|
|
seriesId: string;
|
|
};
|
|
query: {
|
|
/** Number of episodes returned. Default is 10 */
|
|
pageSize?: number;
|
|
/** Which page to take from */
|
|
page?: number;
|
|
/** Sorts episodes by date (Only applies for standard series episodes) */
|
|
sort?: components["schemas"]["SortDirection"];
|
|
};
|
|
};
|
|
responses: {
|
|
/** Success */
|
|
200: {
|
|
content: {
|
|
"application/json": components["schemas"]["EpisodesHalResource"];
|
|
};
|
|
};
|
|
/** Series not found */
|
|
404: unknown;
|
|
};
|
|
};
|
|
/** Gets a season for a radio series */
|
|
GetSeriesSeason: {
|
|
parameters: {
|
|
path: {
|
|
/** The series id */
|
|
seriesId: string;
|
|
/** The season id */
|
|
seasonId: string;
|
|
};
|
|
};
|
|
responses: {
|
|
/** Success */
|
|
200: {
|
|
content: {
|
|
"application/json": components["schemas"]["SeasonHalResource"];
|
|
};
|
|
};
|
|
/** Series or season not found */
|
|
404: unknown;
|
|
};
|
|
};
|
|
/** Gets episodes for a radio series season */
|
|
GetSeriesSeasonEpisodes: {
|
|
parameters: {
|
|
path: {
|
|
/** The series id */
|
|
seriesId: string;
|
|
/** The season id */
|
|
seasonId: string;
|
|
};
|
|
query: {
|
|
/** Number of episodes returned. Default is 10 */
|
|
pageSize?: number;
|
|
/** Which page to take from */
|
|
page?: number;
|
|
/** Sorts episodes by date (only applies for standard series episodes) */
|
|
sort?: components["schemas"]["SortDirection"];
|
|
};
|
|
};
|
|
responses: {
|
|
/** Success */
|
|
200: {
|
|
content: {
|
|
"application/json": components["schemas"]["EpisodesHalResource"];
|
|
};
|
|
};
|
|
/** Series or season not found */
|
|
404: unknown;
|
|
};
|
|
};
|
|
/** Gets clip extramaterials for a radio or podcast series */
|
|
GetExtramaterialClips: {
|
|
parameters: {
|
|
path: {
|
|
/** The series or podcast id */
|
|
id: string;
|
|
};
|
|
query: {
|
|
/** Number of clips returned. Default is 10 */
|
|
pageSize?: number;
|
|
/** Which page to take from. Default is 1 */
|
|
page?: number;
|
|
/** Sorts videos by date. Default is 'desc' */
|
|
sort?: components["schemas"]["SortDirection"];
|
|
};
|
|
};
|
|
responses: {
|
|
/** Success */
|
|
200: {
|
|
content: {
|
|
"application/json": components["schemas"]["ExtraMaterialClipsHalResource"];
|
|
};
|
|
};
|
|
/** No podcast or series with id found */
|
|
404: unknown;
|
|
};
|
|
};
|
|
/** Gets the preferred series type (ODM or podcast) */
|
|
GetVersion: {
|
|
parameters: {
|
|
path: {
|
|
/** The series or podcast id */
|
|
id: string;
|
|
};
|
|
};
|
|
responses: {
|
|
/** Success */
|
|
200: {
|
|
content: {
|
|
"application/json": components["schemas"]["SeriesHalResource"];
|
|
};
|
|
};
|
|
/** Not found */
|
|
404: unknown;
|
|
};
|
|
};
|
|
/** Gets a podcast page */
|
|
GetPodcast: {
|
|
parameters: {
|
|
path: {
|
|
/** The podcast id */
|
|
podcastId: string;
|
|
};
|
|
query: {
|
|
/** Default is 10. */
|
|
pageSize?: number;
|
|
};
|
|
};
|
|
responses: {
|
|
/** Success */
|
|
200: {
|
|
content: {
|
|
"application/json": components["schemas"]["SeriesHalResource"];
|
|
};
|
|
};
|
|
/** Podcast not found */
|
|
404: unknown;
|
|
};
|
|
};
|
|
/** Gets episodes for a podcast series */
|
|
GetPodcastepisodes: {
|
|
parameters: {
|
|
path: {
|
|
/** The podcast id */
|
|
podcastId: string;
|
|
};
|
|
query: {
|
|
/** Number of episodes returned. Default is 10 */
|
|
pageSize?: number;
|
|
/** Which page to take from */
|
|
page?: number;
|
|
/** Sorts episodes by date (only applies for standard series episodes) */
|
|
sort?: components["schemas"]["SortDirection"];
|
|
};
|
|
};
|
|
responses: {
|
|
/** Success */
|
|
200: {
|
|
content: {
|
|
"application/json": components["schemas"]["EpisodesHalResource"];
|
|
};
|
|
};
|
|
/** Podcast not found */
|
|
404: unknown;
|
|
};
|
|
};
|
|
/** Gets a podcast episode */
|
|
GetPodcastEpisode: {
|
|
parameters: {
|
|
path: {
|
|
/** The podcast id */
|
|
podcastId: string;
|
|
/** The podcast episode id */
|
|
podcastEpisodeId: string;
|
|
};
|
|
};
|
|
responses: {
|
|
/** Success */
|
|
200: {
|
|
content: {
|
|
"application/json": components["schemas"]["PodcastEpisodeHalResource"];
|
|
};
|
|
};
|
|
/** Podcast or episode not found */
|
|
404: unknown;
|
|
};
|
|
};
|
|
/** Gets a season for a podcast series */
|
|
GetPodcastSeason: {
|
|
parameters: {
|
|
path: {
|
|
/** The podcast id */
|
|
podcastId: string;
|
|
/** The season id */
|
|
seasonId: string;
|
|
};
|
|
};
|
|
responses: {
|
|
/** Success */
|
|
200: {
|
|
content: {
|
|
"application/json": components["schemas"]["PodcastSeasonHalResource"];
|
|
};
|
|
};
|
|
/** Podcast or season not found */
|
|
404: unknown;
|
|
};
|
|
};
|
|
/** Gets episodes for a podcast series season */
|
|
GetPodcastSeasonEpisodes: {
|
|
parameters: {
|
|
path: {
|
|
/** The podcast id */
|
|
podcastId: string;
|
|
/** The season id */
|
|
seasonId: string;
|
|
};
|
|
query: {
|
|
/** Number of episodes returned. Default is 10 */
|
|
pageSize?: number;
|
|
/** Which page to take from */
|
|
page?: number;
|
|
/** Sorts episodes by date (only applies for standard series episodes) */
|
|
sort?: components["schemas"]["SortDirection"];
|
|
};
|
|
};
|
|
responses: {
|
|
/** Success */
|
|
200: {
|
|
content: {
|
|
"application/json": components["schemas"]["EpisodesHalResource"];
|
|
};
|
|
};
|
|
/** Podcast or season not found */
|
|
404: unknown;
|
|
};
|
|
};
|
|
}
|
|
|
|
export interface external {
|
|
"https://psapi.nrk.no/documentation/openapi/playback/openapi.json": {
|
|
paths: {
|
|
"/playback/debug": {
|
|
get: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["operations"]["getPlaybackDebug"];
|
|
};
|
|
"/playback/dnslist": {
|
|
get: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["operations"]["getPlaybackDnsList"];
|
|
};
|
|
"/playback/manifest/{id}": {
|
|
/** This endpoint is just for clients that doesn't know its context */
|
|
get: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["operations"]["getPlaybackManifestRedirect"];
|
|
};
|
|
"/playback/manifest/program/{programId}": {
|
|
get: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["operations"]["getPlaybackProgramManifest"];
|
|
};
|
|
"/playback/manifest/channel/{channelId}": {
|
|
get: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["operations"]["getPlaybackChannelManifest"];
|
|
};
|
|
"/playback/manifest/clip/{clipId}": {
|
|
get: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["operations"]["getPlaybackClipManifest"];
|
|
};
|
|
"/playback/metadata/{id}": {
|
|
/** This endpoint is just for clients that doesn't know its context */
|
|
get: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["operations"]["getPlaybackMetadataRedirect"];
|
|
};
|
|
"/playback/metadata/program/{programId}": {
|
|
get: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["operations"]["getPlaybackProgramMetadata"];
|
|
};
|
|
"/playback/metadata/channel/{channelId}": {
|
|
get: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["operations"]["getPlaybackChannelMetadata"];
|
|
};
|
|
"/playback/metadata/clip/{clipId}": {
|
|
get: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["operations"]["getPlaybackClipMetadata"];
|
|
};
|
|
};
|
|
components: {
|
|
schemas: {
|
|
DnsList: {
|
|
/** @description Gets list of DomainNames used by applications */
|
|
domainNames: string[];
|
|
_links: {
|
|
self: {
|
|
href: string;
|
|
};
|
|
};
|
|
};
|
|
DebugData: {
|
|
_links: {
|
|
self: {
|
|
href: string;
|
|
};
|
|
};
|
|
playbackData: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlaybackDataVm"];
|
|
locationData: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LocationDataVm"];
|
|
};
|
|
PlaybackDataVm: {
|
|
maxBitrate: number;
|
|
minBitrate: number;
|
|
startBitrate: number;
|
|
springStreamContentType: string;
|
|
useNepOriginLive: boolean;
|
|
useNepOriginOdm: boolean;
|
|
cedexisDeviceId: string;
|
|
appVersion: string;
|
|
osVersion: string;
|
|
isBeta: boolean;
|
|
originalUa: string;
|
|
wurflId: string | null;
|
|
distributionFormat: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["DistributionFormat"];
|
|
deviceGroupName: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["DeviceGroupName"];
|
|
playerPlatform: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayerPlatform"];
|
|
customManifestParameters: (
|
|
| "AudioOnly"
|
|
| "DolbyOnly"
|
|
| "IFramePlaylist"
|
|
| "MuxAudio"
|
|
| "NoAudioOnly"
|
|
| "NoIFramePlaylist"
|
|
| "NoMuxAudi"
|
|
| "NoSignalDiscontinuities"
|
|
| "SignalDiscontinuities"
|
|
)[];
|
|
subtitlesDistribution: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["SubtitlesDistribution"];
|
|
};
|
|
/** @enum {string} */
|
|
DistributionFormat:
|
|
| "Dash"
|
|
| "Hds"
|
|
| "Hls"
|
|
| "ProgressiveDownload"
|
|
| "ProgressiveMp3";
|
|
/** @enum {string} */
|
|
DeviceGroupName: "Desktop" | "Mobile" | "SetTopUnit" | "Tablet" | "Tv";
|
|
/** @enum {string} */
|
|
PlayerPlatform:
|
|
| "Altibox"
|
|
| "AltiboxHls"
|
|
| "Android"
|
|
| "AndroidTv"
|
|
| "AppleTv"
|
|
| "AppleTv4"
|
|
| "CanalDigitalKabelTv"
|
|
| "CanalDigitalSatellitt"
|
|
| "Chromecast"
|
|
| "ChromecastLegacy"
|
|
| "GenericHls"
|
|
| "Get"
|
|
| "GoogleAssistant"
|
|
| "Ios"
|
|
| "Lg"
|
|
| "LgLegacy"
|
|
| "LgNetcast"
|
|
| "Ludo"
|
|
| "Panasonic"
|
|
| "Philips"
|
|
| "PlayStation3"
|
|
| "PlayStation4"
|
|
| "RiksTv"
|
|
| "SamsungOrsay"
|
|
| "SamsungTizen"
|
|
| "Sony"
|
|
| "TelenorKabelTv"
|
|
| "TelenorLegacyKabelTv"
|
|
| "WindowsPhone"
|
|
| "WindowsPhone8"
|
|
| "WorkStationHls";
|
|
/** @enum {string} */
|
|
SubtitlesDistribution: "Manifest" | "NoSubtitles" | "Sideload";
|
|
LocationDataVm: {
|
|
clientIpAddress: string;
|
|
countryCode: string;
|
|
isIpNorwegian: boolean;
|
|
overriddenClientIpAddress: string;
|
|
overriddenCountryCode: string;
|
|
overriddenLookupSource: string;
|
|
forwardedFor: string;
|
|
realIp: string;
|
|
};
|
|
ManifestResponse: Partial<
|
|
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableManifest"]
|
|
> &
|
|
Partial<
|
|
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["NonPlayableManifest"]
|
|
>;
|
|
PlayableManifest: {
|
|
/** @enum {string} */
|
|
playability: "playable";
|
|
playable: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableElementVm"];
|
|
statistics: {
|
|
scores: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ScoresStatisticsVm"];
|
|
ga: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["GoogleAnalyticsVm"];
|
|
conviva: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ConvivaStatisticsVm"];
|
|
luna: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LunaStatisticsVm"];
|
|
};
|
|
nonPlayable: unknown | null;
|
|
id: string;
|
|
streamingMode: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableStreamingMode"];
|
|
availability: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["AvailabilityVm"];
|
|
displayAspectRatio: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["DisplayAspectRatio"];
|
|
sourceMedium: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableSourceMedium"];
|
|
_links: {
|
|
self: {
|
|
href: string;
|
|
};
|
|
metadata: {
|
|
href: string;
|
|
/** @enum {string} */
|
|
name: "metadata";
|
|
};
|
|
};
|
|
};
|
|
NonPlayableManifest: {
|
|
/** @enum {string} */
|
|
playability: "nonPlayable";
|
|
playable: unknown | null;
|
|
statistics: {
|
|
scores: unknown | null;
|
|
ga: unknown | null;
|
|
luna: unknown | null;
|
|
};
|
|
nonPlayable: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["NonPlayableElementVm"];
|
|
id: string;
|
|
streamingMode: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableStreamingMode"];
|
|
availability: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["AvailabilityVm"];
|
|
displayAspectRatio: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["DisplayAspectRatio"];
|
|
sourceMedium: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableSourceMedium"];
|
|
_links: {
|
|
self: {
|
|
href: string;
|
|
};
|
|
metadata: {
|
|
href: string;
|
|
/** @enum {string} */
|
|
name: "metadata";
|
|
};
|
|
};
|
|
};
|
|
PlayableElementVm: {
|
|
endSequenceStartTime: string | null;
|
|
duration: string | null;
|
|
/** @description List of mediaAssets */
|
|
assets: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["MediaUrlVm"][];
|
|
/** @description Livebuffer if element is live */
|
|
liveBuffer: Partial<
|
|
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LiveBufferVm"]
|
|
> | null;
|
|
/** @description List of subtitles */
|
|
subtitles: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["SubtitlesVm"][];
|
|
};
|
|
MediaUrlVm: {
|
|
/** @description The media URL itself. */
|
|
url: string;
|
|
format: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableFormat"];
|
|
mimeType: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableMimeType"];
|
|
/** @description True if program is marked as HDSecure, false otherwise */
|
|
encrypted: boolean;
|
|
};
|
|
/**
|
|
* @description The video format for the resource identified by the URL.
|
|
* @enum {string}
|
|
*/
|
|
PlayableFormat: "HDS" | "HLS" | "MP4";
|
|
/**
|
|
* @description The mimetype that corresponds to the specified format.
|
|
* @enum {string}
|
|
*/
|
|
PlayableMimeType:
|
|
| "application/adobe-f4m"
|
|
| "application/mp4"
|
|
| "application/vnd.apple.mpegurl"
|
|
| "audio/mp4"
|
|
| "video/mp4";
|
|
LiveBufferVm: {
|
|
/** @description Live buffer startTime */
|
|
bufferStartTime: string | null;
|
|
/** @description Live buffer length */
|
|
bufferDuration: string;
|
|
bufferType: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LiveBufferType"];
|
|
};
|
|
/**
|
|
* @description Type of liveBuffer
|
|
* @enum {string}
|
|
*/
|
|
LiveBufferType: "fixed" | "growing" | "none" | "sliding";
|
|
SubtitlesVm: {
|
|
type: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["SubtitleType"];
|
|
language: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["SubtitleLanguage"];
|
|
label: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["SubtitleLabel"];
|
|
defaultOn: boolean;
|
|
webVtt: string;
|
|
};
|
|
/** @enum {string} */
|
|
SubtitleType: "gbr" | "mix" | "nor" | "ttv";
|
|
/** @enum {string} */
|
|
SubtitleLanguage: "en" | "nb";
|
|
/** @enum {string} */
|
|
SubtitleLabel: "English" | "Norsk tekst" | "Tekstet for hørselshemmede";
|
|
ScoresStatisticsVm: {
|
|
springStreamSite: string;
|
|
springStreamStream: string;
|
|
springStreamContentType: string;
|
|
springStreamProgramId: string;
|
|
};
|
|
/**
|
|
* @description * dimension1: ID. KILDESYSTEM:UNIK_IDENTIFIKATOR
|
|
* * dimension2: Tittel
|
|
* * dimension3: Publiseringsår.
|
|
* * dimension4: Publiseringsmåned.
|
|
* * dimension5: Publiseringsdag. [01, 31]
|
|
* * dimension10: Kilde-ID
|
|
* * dimension21: Serie. Kun relevant for episoder/instalments.
|
|
* * dimension22: Episodenummer. Kun relevant for episoder (instalments?).
|
|
* * dimension23: Kategori
|
|
* * dimension25: Mediatype [video | audio]
|
|
* * dimension26: Mediakategori [live | ondemand]
|
|
* * dimension29: Platform
|
|
* [Ekstern doc](https://github.com/nrkno/analytics-docs/blob/master/docs/schema.md)
|
|
*/
|
|
GoogleAnalyticsVm: { [key: string]: string };
|
|
ConvivaStatisticsVm: {
|
|
/**
|
|
* @description A string identifying the current video application.
|
|
* Example: Desktop-Ludo
|
|
*/
|
|
playerName: string;
|
|
/**
|
|
* @description A unique, human-readable identifier for the content.
|
|
* Example: DMTV23400617-smaken-av-den-rette
|
|
*/
|
|
assetName: string;
|
|
/**
|
|
* @description Duration of the video content. In seconds.
|
|
* When duration is unknown, eg channels: -1
|
|
*/
|
|
duration: number;
|
|
streamType: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ConvivaStreamType"];
|
|
/**
|
|
* @description The URL from where this video content will be downloaded. For
|
|
* manifest-based streaming protocols, it should be the URL of the top-level
|
|
* manifest.
|
|
*/
|
|
streamUrl: string;
|
|
custom: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ConvivaCustomProperties"];
|
|
};
|
|
/** @enum {string} */
|
|
ConvivaStreamType: "LIVE" | "VOD";
|
|
/**
|
|
* @description A string-to-string dictionary of custom metadata.
|
|
* When a property does not have a value, the string "None" should be used
|
|
*/
|
|
ConvivaCustomProperties: {
|
|
/**
|
|
* @description ContentId for current content
|
|
* Example: DMTV23400617
|
|
*/
|
|
contentId: string;
|
|
/**
|
|
* @description Name of series
|
|
* Not set for channels and content without series
|
|
* Example: naar-kjemien-stemmer
|
|
*/
|
|
series: string;
|
|
/**
|
|
* @description Title of current content
|
|
* Example: smaken-av-den-rette
|
|
*/
|
|
title: string;
|
|
/**
|
|
* @description EpisodeNumber for current content
|
|
* Not set for channels and content without series
|
|
* Example: 5 (as string)
|
|
*/
|
|
episode: string;
|
|
/**
|
|
* @description Main category of the content
|
|
* Example: underholdning
|
|
*/
|
|
category: string;
|
|
mediaType: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ConvivaMediaType"];
|
|
/**
|
|
* @description Name of selected CDN
|
|
* Example: Telenor-Cdn
|
|
*/
|
|
cdnName: string;
|
|
/** @description Application version number, set by player */
|
|
applicationVersion: string;
|
|
/**
|
|
* @description Application name, set by player
|
|
* Example: LudoHTML5PlayerAdapter (HTML5/Native HLS, hls.js, Flashls, ...)
|
|
*/
|
|
applicationName: string;
|
|
/**
|
|
* @description ServiceName, set by player
|
|
* Example: tv.nrk.no, nrk.no, nrksuper.no
|
|
*/
|
|
serviceName: string;
|
|
contentType: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ConvivaContentType"];
|
|
};
|
|
/**
|
|
* @description MediaType for current content
|
|
* @enum {string}
|
|
*/
|
|
ConvivaMediaType: "Audio" | "Video";
|
|
/**
|
|
* @description Type of content
|
|
* @enum {string}
|
|
*/
|
|
ConvivaContentType:
|
|
| "Channel"
|
|
| "Clip"
|
|
| "Event"
|
|
| "Podcast"
|
|
| "Program";
|
|
LunaStatisticsVm: {
|
|
config: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LunaConfig"];
|
|
data: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LunaPayload"];
|
|
};
|
|
LunaConfig: {
|
|
beacon: string;
|
|
};
|
|
LunaPayload: {
|
|
show: string | null;
|
|
title: string;
|
|
category: string | null;
|
|
contentLength: string | null;
|
|
device: string;
|
|
playerId: string;
|
|
deliveryType: string;
|
|
playerInfo: string;
|
|
cdnName: string;
|
|
};
|
|
/** @enum {string} */
|
|
PlayableStreamingMode: "live" | "onDemand";
|
|
AvailabilityVm: {
|
|
/** @description Standardized text about the availability of the media element. */
|
|
information: string;
|
|
/**
|
|
* @description Indicates that the media element may not be played outside the range of
|
|
* Norwegian IP addresses.
|
|
*/
|
|
isGeoBlocked: boolean;
|
|
/**
|
|
* @description Only applicable for on-demand media elements. Will be null for live media
|
|
* elements.
|
|
*/
|
|
onDemand: Partial<
|
|
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["OnDemandUsageRights"]
|
|
> | null;
|
|
/**
|
|
* @description Only applicable for live media elements. Will be null for on-demand media
|
|
* elements.
|
|
*/
|
|
live:
|
|
| (Partial<{
|
|
/** @enum {string} */
|
|
type: "channel";
|
|
/** @enum {boolean} */
|
|
isOngoing: true;
|
|
transmissionInterval: unknown | null;
|
|
}> &
|
|
Partial<{
|
|
/** @enum {string} */
|
|
type: "transmission";
|
|
isOngoing: boolean;
|
|
transmissionInterval: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LiveTransmissionIntervalVm"];
|
|
}>)
|
|
| null;
|
|
externalEmbeddingAllowed: boolean;
|
|
};
|
|
LiveTransmissionIntervalVm: {
|
|
from: string;
|
|
to: string;
|
|
};
|
|
/** @enum {string} */
|
|
DisplayAspectRatio: "16:9" | "1:1" | "2:3" | "4:3" | "9:16";
|
|
OnDemandUsageRights: {
|
|
from: string;
|
|
to: string;
|
|
hasRightsNow: boolean;
|
|
};
|
|
/** @enum {string} */
|
|
PlayableSourceMedium: "audio" | "video";
|
|
NonPlayableElementVm: {
|
|
reason: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["NonPlayableReason"];
|
|
messageType: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["NonPlayableMessageType"];
|
|
/**
|
|
* @description Standard message for end user describing why the media element is not
|
|
* playable.
|
|
*/
|
|
endUserMessage: string;
|
|
/** @description URL to the help page referred to in the end user message. */
|
|
helpUrl: string;
|
|
/**
|
|
* @description URL to page with links to content available outside Norway (i.e. content that
|
|
* isn't geo-blocked).
|
|
*/
|
|
availableAbroadUrl: string | null;
|
|
};
|
|
/** @enum {string} */
|
|
NonPlayableReason: "blocked" | "notransmission" | "unavailable";
|
|
/** @enum {string} */
|
|
NonPlayableMessageType:
|
|
| "ChannelIsGeoblocked"
|
|
| "ChannelUnavailable"
|
|
| "NoMessage"
|
|
| "ProgramIsGeoblocked"
|
|
| "ProgramIsInLiveBuffer"
|
|
| "ProgramIsNotTranscoded"
|
|
| "ProgramRightsHasExpired"
|
|
| "ProgramRightsHasNotStarted"
|
|
| "ProgramUnavailable";
|
|
/** @enum {string} */
|
|
AvailabilityLabel: "Av" | "Synstolk" | "Tegnspråk";
|
|
SeriesLink: {
|
|
href: string;
|
|
/** @enum {string} */
|
|
name: "series";
|
|
};
|
|
NextLink: {
|
|
href: string;
|
|
/** @enum {string} */
|
|
name: "next";
|
|
};
|
|
/** @enum {string} */
|
|
ManifestLinkName: "default" | "synstolk" | "tegntolk";
|
|
SkipDialogInfoVm: {
|
|
startIntroInSeconds: number;
|
|
endIntroInSeconds: number;
|
|
startCreditsInSeconds: number;
|
|
startIntro: string;
|
|
endIntro: string;
|
|
startCredits: string;
|
|
};
|
|
IndexPointVm: {
|
|
/** @description IndexPoint title */
|
|
title: string;
|
|
/** @description IndexPoint Duration */
|
|
startPoint: string;
|
|
};
|
|
PosterImageVm: {
|
|
url: string;
|
|
pixelWidth: number;
|
|
};
|
|
/** @description Image to show before play */
|
|
PosterVm: {
|
|
/** @description List of images in different sizes */
|
|
images: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PosterImageVm"][];
|
|
};
|
|
/** @description Title to show before play */
|
|
TitlesVm: {
|
|
title: string;
|
|
subtitle: string;
|
|
};
|
|
PreplayVm: {
|
|
titles: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["TitlesVm"];
|
|
/** @description Description to show before play */
|
|
description: string;
|
|
poster: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PosterVm"];
|
|
/** @description List of index points */
|
|
indexPoints: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["IndexPointVm"][];
|
|
};
|
|
LegalAgeRating: {
|
|
code: string;
|
|
displayValue: string;
|
|
displayAge: string;
|
|
};
|
|
LegalAgeBodyRated: {
|
|
/** @enum {string} */
|
|
status: "rated";
|
|
rating: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LegalAgeRating"];
|
|
};
|
|
LegalAgeBodyExempt: {
|
|
/** @enum {string} */
|
|
status: "exempt";
|
|
};
|
|
LegalAgeVm: {
|
|
legalReference: string;
|
|
body: Partial<
|
|
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LegalAgeBodyExempt"]
|
|
> &
|
|
Partial<
|
|
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LegalAgeBodyRated"]
|
|
>;
|
|
};
|
|
PlayableMetadataVm: {
|
|
/** @description Uri to resolve to get the media manifest */
|
|
resolve: string;
|
|
};
|
|
PlayableMetadata: {
|
|
/** @enum {string} */
|
|
playability: "playable";
|
|
playable: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableMetadataVm"];
|
|
nonPlayable: unknown | null;
|
|
id: string;
|
|
streamingMode: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableStreamingMode"];
|
|
duration: string | null;
|
|
availability: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["AvailabilityVm"];
|
|
legalAge: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LegalAgeVm"];
|
|
preplay: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PreplayVm"];
|
|
displayAspectRatio: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["DisplayAspectRatio"];
|
|
skipDialogInfo: Partial<
|
|
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["SkipDialogInfoVm"]
|
|
> | null;
|
|
sourceMedium: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableSourceMedium"];
|
|
_links: {
|
|
self: {
|
|
href: string;
|
|
};
|
|
manifests: Partial<
|
|
{
|
|
href: string;
|
|
name: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ManifestLinkName"];
|
|
}[]
|
|
> | null;
|
|
next: Partial<
|
|
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["NextLink"]
|
|
> | null;
|
|
series?: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["SeriesLink"];
|
|
progress?: {
|
|
href: string;
|
|
/** @enum {boolean} */
|
|
templated: true;
|
|
};
|
|
};
|
|
_embedded: {
|
|
manifests: Partial<
|
|
{
|
|
id: string;
|
|
availabilityLabel: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["AvailabilityLabel"];
|
|
_links: {
|
|
self: {
|
|
href: string;
|
|
name: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ManifestLinkName"];
|
|
};
|
|
};
|
|
}[]
|
|
> | null;
|
|
};
|
|
};
|
|
NonPlayableMetadata: {
|
|
/** @enum {string} */
|
|
playability: "nonPlayable";
|
|
playable: unknown | null;
|
|
nonPlayable: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["NonPlayableElementVm"];
|
|
id: string;
|
|
streamingMode: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableStreamingMode"];
|
|
duration: string | null;
|
|
availability: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["AvailabilityVm"];
|
|
legalAge: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["LegalAgeVm"];
|
|
preplay: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PreplayVm"];
|
|
displayAspectRatio: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["DisplayAspectRatio"];
|
|
skipDialogInfo: Partial<
|
|
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["SkipDialogInfoVm"]
|
|
> | null;
|
|
sourceMedium: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableSourceMedium"];
|
|
_links: {
|
|
self: {
|
|
href: string;
|
|
};
|
|
manifests: Partial<
|
|
{
|
|
href: string;
|
|
name: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ManifestLinkName"];
|
|
}[]
|
|
> | null;
|
|
next: Partial<
|
|
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["NextLink"]
|
|
> | null;
|
|
series?: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["SeriesLink"];
|
|
progress?: {
|
|
href: string;
|
|
/** @enum {boolean} */
|
|
templated: true;
|
|
};
|
|
};
|
|
_embedded: {
|
|
manifests: Partial<
|
|
{
|
|
id: string;
|
|
availabilityLabel: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["AvailabilityLabel"];
|
|
_links: {
|
|
self: {
|
|
href: string;
|
|
name: external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ManifestLinkName"];
|
|
};
|
|
};
|
|
}[]
|
|
> | null;
|
|
};
|
|
};
|
|
MetadataResponse: Partial<
|
|
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["PlayableMetadata"]
|
|
> &
|
|
Partial<
|
|
external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["NonPlayableMetadata"]
|
|
>;
|
|
};
|
|
};
|
|
operations: {
|
|
getPlaybackDebug: {
|
|
responses: {
|
|
/** OK */
|
|
200: {
|
|
content: {
|
|
"application/json": external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["DebugData"];
|
|
};
|
|
};
|
|
};
|
|
};
|
|
getPlaybackDnsList: {
|
|
responses: {
|
|
/** OK */
|
|
200: {
|
|
content: {
|
|
"application/json": external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["DnsList"];
|
|
};
|
|
};
|
|
};
|
|
};
|
|
/** This endpoint is just for clients that doesn't know its context */
|
|
getPlaybackManifestRedirect: {
|
|
parameters: {
|
|
path: {
|
|
/**
|
|
* The unique ID for the playback element.
|
|
* Different kinds of media elements have different kinds of IDs.
|
|
* - On-demand (PRF): Four letters and eight digits. Example: MSUB19120216
|
|
* - Klipp (Potion / Foss2): GUID.
|
|
* - Klipp (Foss1): The letter `f` followed by a sequence of digits.
|
|
* - Klipp (Guri): A sequence of digits.
|
|
* - Podcast: Prefix "nrkno-poddkast-". Example: nrkno-poddkast-10908-146680-20122018123000
|
|
* - Kanal: The name of the channel. Example: nrk1
|
|
*/
|
|
id: string;
|
|
};
|
|
query: {
|
|
/** Is the client in in Super-universe or not. Used to get correct statistics and content */
|
|
inSuperUniverse?: string;
|
|
/** PreferredBandwidth could be used to limit the number of qualities in the HLS manifest. Legal values: low, mid, high, auto */
|
|
preferredBandwidth?: string;
|
|
/** PreferredCdn could be used to get the CDN used in the last request. Overrides Cedexis. The value that should be passed in exists as a header, named: CdnName */
|
|
preferredCdn?: string;
|
|
/** Use to activate liveToVod on playback */
|
|
live2Vod?: string;
|
|
};
|
|
};
|
|
responses: {
|
|
/** OK */
|
|
200: {
|
|
content: {
|
|
"application/json": external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ManifestResponse"];
|
|
};
|
|
};
|
|
};
|
|
};
|
|
getPlaybackProgramManifest: {
|
|
parameters: {
|
|
path: {
|
|
/**
|
|
* The unique ID for the playback element.
|
|
* Different kinds of media elements have different kinds of IDs.
|
|
* - On-demand (PRF): Four letters and eight digits. Example: MSUB19120216
|
|
*/
|
|
programId: string;
|
|
};
|
|
query: {
|
|
/** Is the client in in Super-universe or not. Used to get correct statistics and content */
|
|
inSuperUniverse?: string;
|
|
/** PreferredBandwidth could be used to limit the number of qualities in the HLS manifest. Legal values: low, mid, high, auto */
|
|
preferredBandwidth?: string;
|
|
/** PreferredCdn could be used to get the CDN used in the last request. Overrides Cedexis. The value that should be passed in exists as a header, named: CdnName */
|
|
preferredCdn?: string;
|
|
/** Used to request HLS manifest for offline. This overrides/ignores preferredBandwith. Tablet/phone information is pulled from User-Agent */
|
|
offline?: "standard" | "high";
|
|
};
|
|
};
|
|
responses: {
|
|
/** OK */
|
|
200: {
|
|
content: {
|
|
"application/json": external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ManifestResponse"];
|
|
};
|
|
};
|
|
};
|
|
};
|
|
getPlaybackChannelManifest: {
|
|
parameters: {
|
|
path: {
|
|
/**
|
|
* The unique ID for the playback element.
|
|
* Different kinds of media elements have different kinds of IDs.
|
|
* - Kanal: The name of the channel. Example: nrk1
|
|
*/
|
|
channelId: string;
|
|
};
|
|
query: {
|
|
/** Is the client in in Super-universe or not. Used to get correct statistics and content */
|
|
inSuperUniverse?: string;
|
|
/** PreferredBandwidth could be used to limit the number of qualities in the HLS manifest. Legal values: low, mid, high, auto */
|
|
preferredBandwidth?: string;
|
|
/** PreferredCdn could be used to get the CDN used in the last request. Overrides Cedexis. The value that should be passed in exists as a header, named: CdnName */
|
|
preferredCdn?: string;
|
|
};
|
|
};
|
|
responses: {
|
|
/** OK */
|
|
200: {
|
|
content: {
|
|
"application/json": external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ManifestResponse"];
|
|
};
|
|
};
|
|
};
|
|
};
|
|
getPlaybackClipManifest: {
|
|
parameters: {
|
|
path: {
|
|
/**
|
|
* The unique ID for the playback element.
|
|
* Different kinds of media elements have different kinds of IDs.
|
|
* - Klipp (Potion / Foss2): GUID.
|
|
* - Klipp (Foss1): The letter `f` followed by a sequence of digits.
|
|
* - Klipp (Guri): A sequence of digits.
|
|
*/
|
|
clipId: string;
|
|
};
|
|
query: {
|
|
/** PreferredBandwidth could be used to limit the number of qualities in the HLS manifest. Legal values: low, mid, high, auto */
|
|
preferredBandwidth?: string;
|
|
/** PreferredCdn could be used to get the CDN used in the last request. Overrides Cedexis. The value that should be passed in exists as a header, named: CdnName */
|
|
preferredCdn?: string;
|
|
};
|
|
};
|
|
responses: {
|
|
/** OK */
|
|
200: {
|
|
content: {
|
|
"application/json": external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["ManifestResponse"];
|
|
};
|
|
};
|
|
};
|
|
};
|
|
/** This endpoint is just for clients that doesn't know its context */
|
|
getPlaybackMetadataRedirect: {
|
|
parameters: {
|
|
path: {
|
|
/**
|
|
* The unique ID for the playback element.
|
|
* Different kinds of media elements have different kinds of IDs.
|
|
* - On-demand (PRF): Four letters and eight digits. Example: MSUB19120216
|
|
* - Klipp (Potion / Foss2): GUID.
|
|
* - Klipp (Foss1): The letter `f` followed by a sequence of digits.
|
|
* - Klipp (Guri): A sequence of digits.
|
|
* - Podcast: Prefix "nrkno-poddkast-". Example: nrkno-poddkast-10908-146680-20122018123000
|
|
* - Kanal: The name of the channel. Example: nrk1
|
|
*/
|
|
id: string;
|
|
};
|
|
query: {
|
|
/** Use to activate liveToVod on playback */
|
|
live2Vod?: string;
|
|
};
|
|
};
|
|
responses: {
|
|
/** OK */
|
|
200: {
|
|
content: {
|
|
"application/json": external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["MetadataResponse"];
|
|
};
|
|
};
|
|
};
|
|
};
|
|
getPlaybackProgramMetadata: {
|
|
parameters: {
|
|
path: {
|
|
/**
|
|
* The unique ID for the playback element.
|
|
* Different kinds of media elements have different kinds of IDs.
|
|
* - On-demand (PRF): Four letters and eight digits. Example: MSUB19120216
|
|
*/
|
|
programId: string;
|
|
};
|
|
};
|
|
responses: {
|
|
/** OK */
|
|
200: {
|
|
content: {
|
|
"application/json": external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["MetadataResponse"];
|
|
};
|
|
};
|
|
};
|
|
};
|
|
getPlaybackChannelMetadata: {
|
|
parameters: {
|
|
path: {
|
|
/**
|
|
* The unique ID for the playback element.
|
|
* Different kinds of media elements have different kinds of IDs.
|
|
* - Kanal: The name of the channel. Example: nrk1
|
|
*/
|
|
channelId: string;
|
|
};
|
|
};
|
|
responses: {
|
|
/** OK */
|
|
200: {
|
|
content: {
|
|
"application/json": external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["MetadataResponse"];
|
|
};
|
|
};
|
|
};
|
|
};
|
|
getPlaybackClipMetadata: {
|
|
parameters: {
|
|
path: {
|
|
/**
|
|
* The unique ID for the playback element.
|
|
* Different kinds of media elements have different kinds of IDs.
|
|
* - Klipp (Potion / Foss2): GUID.
|
|
* - Klipp (Foss1): The letter `f` followed by a sequence of digits.
|
|
* - Klipp (Guri): A sequence of digits.
|
|
*/
|
|
clipId: string;
|
|
};
|
|
};
|
|
responses: {
|
|
/** OK */
|
|
200: {
|
|
content: {
|
|
"application/json": external["https://psapi.nrk.no/documentation/openapi/playback/openapi.json"]["components"]["schemas"]["MetadataResponse"];
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
};
|
|
}
|