diff --git a/app/src/debug/assets/wolfskin-titles.json b/app/src/debug/assets/wolfskin-titles.json deleted file mode 100644 index c7559aaa..00000000 --- a/app/src/debug/assets/wolfskin-titles.json +++ /dev/null @@ -1 +0,0 @@ -{"profiles":[{"key":"justin","name":"Justin","initial":"J","color":"#62c4ff","destinations":{"Home":{"kind":"home"},"Movies":{"kind":"library","collection":"movies"},"Shows":{"kind":"library","collection":"shows"},"Anime":{"kind":"library","collection":"anime"},"Discover":{"kind":"discover","collection":"discover"}},"movies":[{"id":"movie-the-girl-who-leapt-through-time-2006","title":"The Girl Who Leapt Through Time","year":2006,"type":"movie","runtimeSeconds":5886,"seasonCount":null,"communityRating":7.772,"criticRating":87,"genres":["Fantasy","Animation","Drama"],"overview":"When 17-year-old Makoto Konno gains the ability to 'leap' backwards through time, she immediately sets about improving her grades and preventing personal mishaps. However, she soon realises that changing the past\u2026","poster":"assets/movie-the-girl-who-leapt-through-time-2006-poster.jpg","backdrop":"assets/movie-the-girl-who-leapt-through-time-2006-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T17:39:11.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":14069,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":87,"rtCriticsLabel":"Fresh","rtAudience":90,"rtAudienceLabel":"Upright","imdb":7.6,"imdbVotes":76917,"tmdb":7.775,"tmdbVotes":2345}},{"id":"movie-locke-2014","title":"Locke","year":2014,"type":"movie","runtimeSeconds":5090,"seasonCount":null,"communityRating":6.891,"criticRating":91,"genres":["Drama","Thriller"],"overview":"Ivan Locke has worked hard to craft a good life for himself. Tonight, that life will collapse around him. On the eve of the biggest challenge of his career, Ivan receives a phone call that sets in motion a series of\u2026","poster":"assets/movie-locke-2014-poster.jpg","backdrop":"assets/movie-locke-2014-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T17:38:48.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":210479,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":90,"rtCriticsLabel":"Certified Fresh","rtAudience":72,"rtAudienceLabel":"Upright","imdb":7.1,"imdbVotes":171265,"tmdb":6.889,"tmdbVotes":3088}},{"id":"movie-look-who-s-back-2015","title":"Look Who's Back","year":2015,"type":"movie","runtimeSeconds":6936,"seasonCount":null,"communityRating":6.793,"criticRating":null,"genres":["Comedy"],"overview":"When Adolf Hitler reawakens at the site of his former bunker in present-day Berlin, he is mistaken for a comedian and quickly becomes a media phenomenon.","poster":"assets/movie-look-who-s-back-2015-poster.jpg","backdrop":"assets/movie-look-who-s-back-2015-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:27:48.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":318917,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":81,"rtAudienceLabel":"Upright","imdb":7,"imdbVotes":54672,"tmdb":6.796,"tmdbVotes":1990}},{"id":"movie-memories-1995","title":"Memories","year":1995,"type":"movie","runtimeSeconds":6805,"seasonCount":null,"communityRating":7.465,"criticRating":null,"genres":["Fantasy","Animation","Science Fiction"],"overview":"Three back-to-back anime films by three different directors make up this sci-fi trilogy three years in the making.","poster":"assets/movie-memories-1995-poster.jpg","backdrop":"assets/movie-memories-1995-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-30T21:36:03.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":42994,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":82,"rtAudienceLabel":"Upright","imdb":7.5,"imdbVotes":26638,"tmdb":7.459,"tmdbVotes":622}},{"id":"movie-reincarnated-2012","title":"Reincarnated","year":2012,"type":"movie","runtimeSeconds":5759,"seasonCount":null,"communityRating":6.145,"criticRating":28,"genres":["Music","Documentary"],"overview":"Evolution as an artist is often times what separates legends from the more mundane. After being heavily influenced by his experience in Jamaica \u2013 and his subsequent name change from Snoop Dogg to Snoop Lion \u2013 the LBC\u2026","poster":"assets/movie-reincarnated-2012-poster.jpg","backdrop":"assets/movie-reincarnated-2012-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:27:26.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":123431,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":28,"rtCriticsLabel":"Rotten","rtAudience":41,"rtAudienceLabel":"Spilled","imdb":6.2,"imdbVotes":2563,"tmdb":6.1,"tmdbVotes":69}},{"id":"movie-shipwrecked-nightmare-at-sea-2026","title":"Shipwrecked: Nightmare at Sea","year":2026,"type":"movie","runtimeSeconds":5385,"seasonCount":null,"communityRating":7.181,"criticRating":null,"genres":["Documentary"],"overview":"Never-before-seen footage and survivor accounts trace the 2012 shipwreck of a luxury cruise and the disaster that ensued, in this immersive documentary.","poster":"assets/movie-shipwrecked-nightmare-at-sea-2026-poster.jpg","backdrop":"assets/movie-shipwrecked-nightmare-at-sea-2026-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-20T20:11:43.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":1715492,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":6.5,"imdbVotes":5080,"tmdb":7.172,"tmdbVotes":87}},{"id":"movie-steins-gate-the-movie-load-region-of-deja-vu-2013","title":"Steins;Gate: The Movie - Load Region of D\u00e9j\u00e0 Vu","year":2013,"type":"movie","runtimeSeconds":5403,"seasonCount":null,"communityRating":7.8,"criticRating":null,"genres":["Animation","Mystery","Sci-Fi"],"overview":"After the events of the anime, Rintarou begins to feel the repercussions of extensive time travel, and eventually completely fades from reality. Kurisu, being the only companion to remember him, now must find a way\u2026","poster":"assets/movie-steins-gate-the-movie-load-region-of-deja-vu-2013-poster.jpg","backdrop":"assets/movie-steins-gate-the-movie-load-region-of-deja-vu-2013-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-22T14:55:54.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","artwork":{"posterKind":"poster","backdropKind":"backdrop"}}],"shows":[{"id":"tv-andor-2022","title":"Andor","year":2022,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":8.293,"criticRating":null,"genres":["Sci-Fi & Fantasy","Action & Adventure","Drama"],"overview":"In an era filled with danger, deception and intrigue, Cassian Andor will discover the difference he can make in the struggle against the tyrannical Galactic Empire. He embarks on a path that is destined to turn him\u2026","poster":"assets/tv-andor-2022-poster.jpg","backdrop":"assets/tv-andor-2022-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0432996Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":83867,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":96,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.321,"tmdbVotes":2312}},{"id":"tv-the-boys-2019","title":"The Boys","year":2019,"type":"tv","runtimeSeconds":null,"seasonCount":5,"communityRating":8.443,"criticRating":null,"genres":["Sci-Fi & Fantasy","Action & Adventure"],"overview":"A group of vigilantes known informally as \u201cThe Boys\u201d set out to take down corrupt superheroes with no more than blue-collar grit and a willingness to fight dirty.","poster":"assets/tv-the-boys-2019-poster.jpg","backdrop":"assets/tv-the-boys-2019-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0410131Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":76479,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":92,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.4,"tmdbVotes":13628}},{"id":"tv-californication-2007","title":"Californication","year":2007,"type":"tv","runtimeSeconds":1680,"seasonCount":7,"communityRating":7.632,"criticRating":null,"genres":["Comedy","Drama"],"overview":"A self-loathing, alcoholic writer attempts to repair his damaged relationships with his daughter and her mother while combating sex addiction, a budding drug problem, and the seeming inability to avoid making bad\u2026","poster":"assets/tv-californication-2007-poster.jpg","backdrop":"assets/tv-californication-2007-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0428037Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":1215,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":57,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.62,"tmdbVotes":1406}},{"id":"tv-firefly-2002","title":"Firefly","year":2002,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":8.347,"criticRating":null,"genres":["Drama","Action & Adventure","Sci-Fi & Fantasy"],"overview":"In the year 2517, the universe is a vast frontier where lawlessness reigns and adventure awaits! Join Captain Malcolm Reynolds and his ragtag crew aboard the spaceship Serenity as they navigate the fringes of\u2026","poster":"assets/tv-firefly-2002-poster.jpg","backdrop":"assets/tv-firefly-2002-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-20T11:40:08.4202369Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":1437,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":77,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.351,"tmdbVotes":2550}},{"id":"tv-fleabag-2016","title":"Fleabag","year":2016,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":8.278,"criticRating":null,"genres":["Comedy","Drama"],"overview":"A portrait into the mind of a dry-witted, sexual, angry, porn-watching, grief-riddled woman, trying to make sense of the world. As she hurls herself headlong at modern living, Fleabag is thrown roughly up against the\u2026","poster":"assets/tv-fleabag-2016-poster.jpg","backdrop":"assets/tv-fleabag-2016-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T17:42:25.4848214Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":67070,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.3,"tmdbVotes":1993}},{"id":"tv-gravity-falls-2012","title":"Gravity Falls","year":2012,"type":"tv","runtimeSeconds":1320,"seasonCount":2,"communityRating":8.619,"criticRating":null,"genres":["Action & Adventure","Animation","Comedy"],"overview":"Twin brother and sister Dipper and Mabel Pines are in for an unexpected adventure when they spend the summer helping their great uncle Stan run a tourist trap in the mysterious town of Gravity Falls, Oregon.","poster":"assets/tv-gravity-falls-2012-poster.jpg","backdrop":"assets/tv-gravity-falls-2012-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0435827Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":40075,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.624,"tmdbVotes":3647}},{"id":"tv-invincible-2021","title":"INVINCIBLE","year":2021,"type":"tv","runtimeSeconds":null,"seasonCount":4,"communityRating":8.638,"criticRating":null,"genres":["Animation","Drama","Sci-Fi & Fantasy"],"overview":"Mark Grayson is a normal teenager except for the fact that his father is the most powerful superhero on the planet. Shortly after his seventeenth birthday, Mark begins to develop powers of his own and enters into his\u2026","poster":"assets/tv-invincible-2021-poster.jpg","backdrop":"assets/tv-invincible-2021-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.040159Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":95557,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":99,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.6,"tmdbVotes":6155}},{"id":"tv-the-legend-of-korra-2012","title":"The Legend of Korra","year":2012,"type":"tv","runtimeSeconds":1380,"seasonCount":4,"communityRating":8.2,"criticRating":null,"genres":["Animation","Action & Adventure","Sci-Fi & Fantasy"],"overview":"Avatar Korra, a headstrong, rebellious, feisty young woman who continually challenges and breaks with tradition, is on her quest to become a fully realized Avatar. In this story, the Avatar struggles to find balance\u2026","poster":"assets/tv-the-legend-of-korra-2012-poster.jpg","backdrop":"assets/tv-the-legend-of-korra-2012-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-20T00:19:23.2494945Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":33880,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":88,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.221,"tmdbVotes":2482}},{"id":"tv-love-death-robots-2019","title":"Love, Death & Robots","year":2019,"type":"tv","runtimeSeconds":null,"seasonCount":4,"communityRating":8.205,"criticRating":null,"genres":["Animation","Sci-Fi & Fantasy"],"overview":"Terrifying creatures, wicked surprises and dark comedy converge in this NSFW anthology of animated stories presented by Tim Miller and David Fincher.","poster":"assets/tv-love-death-robots-2019-poster.jpg","backdrop":"assets/tv-love-death-robots-2019-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-20T11:31:20.8818757Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":86831,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":89,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.203,"tmdbVotes":4238}},{"id":"tv-norsemen-2016","title":"Norsemen","year":2016,"type":"tv","runtimeSeconds":1800,"seasonCount":3,"communityRating":7.177,"criticRating":null,"genres":["Comedy","Drama"],"overview":"Norsemen is an epic and humorous drama series set in the Viking Age. The residents of an 8th-century Viking village experience political rivalry, social change and innovations that upend their culture and way of life.","poster":"assets/tv-norsemen-2016-poster.jpg","backdrop":"assets/tv-norsemen-2016-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.034182Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":68126,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.2,"tmdbVotes":233}},{"id":"tv-rick-and-morty-2013","title":"Rick and Morty","year":2013,"type":"tv","runtimeSeconds":null,"seasonCount":9,"communityRating":8.679,"criticRating":null,"genres":["Animation","Comedy","Sci-Fi & Fantasy"],"overview":"Follows a sociopathic genius scientist who drags his inherently timid grandson on adventures across the universe.","poster":"assets/tv-rick-and-morty-2013-poster.jpg","backdrop":"assets/tv-rick-and-morty-2013-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0419581Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":60625,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":91,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.7,"tmdbVotes":11548}},{"id":"tv-secret-level-2024","title":"Secret Level","year":2024,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":7.411,"criticRating":null,"genres":["Animation","Sci-Fi & Fantasy","Action & Adventure"],"overview":"Adult animated series of original short stories which are set within the worlds of beloved video games. Each episode serves as a gateway to a new adventure, unlocking exciting worlds from beloved gaming classics and\u2026","poster":"assets/tv-secret-level-2024-poster.jpg","backdrop":"assets/tv-secret-level-2024-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0336417Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":261579,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":65,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.392,"tmdbVotes":612}},{"id":"tv-silo-2023","title":"Silo","year":2023,"type":"tv","runtimeSeconds":null,"seasonCount":3,"communityRating":8.178,"criticRating":null,"genres":["Sci-Fi & Fantasy","Drama"],"overview":"In a ruined and toxic future, thousands live in a giant silo deep underground. After its sheriff breaks a cardinal rule and residents die mysteriously, engineer Juliette starts to uncover shocking secrets and the\u2026","poster":"assets/tv-silo-2023-poster.jpg","backdrop":"assets/tv-silo-2023-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0346526Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":125988,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":92,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.232,"tmdbVotes":2881}},{"id":"tv-south-park-1997","title":"South Park","year":1997,"type":"tv","runtimeSeconds":null,"seasonCount":29,"communityRating":8.336,"criticRating":null,"genres":["Animation","Comedy"],"overview":"Follow the misadventures of four irreverent grade-schoolers in the quiet, dysfunctional town of South Park, Colorado.","poster":"assets/tv-south-park-1997-poster.jpg","backdrop":"assets/tv-south-park-1997-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0456124Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":2190,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":80,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.332,"tmdbVotes":5250}}],"anime":[{"id":"tv-bleach-2004","title":"Bleach","year":2004,"type":"tv","runtimeSeconds":1440,"seasonCount":17,"communityRating":8.363,"criticRating":null,"genres":["Action & Adventure","Animation","Sci-Fi & Fantasy"],"overview":"For as long as he can remember, Ichigo Kurosaki has been able to see ghosts. But when he meets Rukia, a Soul Reaper who battles evil spirits known as Hollows, he finds his life is changed forever. Now, with a\u2026","poster":"assets/tv-bleach-2004-poster.jpg","backdrop":"assets/tv-bleach-2004-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0359827Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":30984,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.4,"tmdbVotes":2331}},{"id":"tv-chainsaw-man-2022","title":"Chainsaw Man","year":2022,"type":"tv","runtimeSeconds":1440,"seasonCount":1,"communityRating":8.515,"criticRating":null,"genres":["Animation","Action & Adventure","Sci-Fi & Fantasy"],"overview":"Denji has a simple dream\u2014to live a happy and peaceful life, spending time with a girl he likes. This is a far cry from reality, however, as Denji is forced by the yakuza into killing devils in order to pay off his\u2026","poster":"assets/tv-chainsaw-man-2022-poster.jpg","backdrop":"assets/tv-chainsaw-man-2022-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-20T22:28:13.2095501Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":114410,"artwork":{"posterKind":"center_crop","backdropKind":"backdrop"},"ratings":{"rtCritics":97,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.508,"tmdbVotes":2364}},{"id":"tv-cyberpunk-edgerunners-2022","title":"Cyberpunk: Edgerunners","year":2022,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":8.466,"criticRating":null,"genres":["Animation","Action & Adventure","Sci-Fi & Fantasy"],"overview":"In a dystopia riddled with corruption and cybernetic implants, a talented but reckless street kid strives to become a mercenary outlaw \u2014 an edgerunner.","poster":"assets/tv-cyberpunk-edgerunners-2022-poster.jpg","backdrop":"assets/tv-cyberpunk-edgerunners-2022-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-20T22:28:13.2093107Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":105248,"artwork":{"posterKind":"center_crop","backdropKind":"backdrop"},"ratings":{"rtCritics":89,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.507,"tmdbVotes":2132}},{"id":"tv-dan-da-dan-2024","title":"Dan Da Dan","year":2024,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":8.538,"criticRating":null,"genres":["Animation","Action & Adventure","Comedy"],"overview":"In a bet to prove whether ghosts or aliens exist, two high schoolers face terrifying paranormal threats, gain superpowers and maybe even fall in love?!","poster":"assets/tv-dan-da-dan-2024-poster.jpg","backdrop":"assets/tv-dan-da-dan-2024-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-22T10:31:16.2652252Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":240411,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.517,"tmdbVotes":986}},{"id":"tv-dr-stone-2019","title":"Dr. STONE","year":2019,"type":"tv","runtimeSeconds":1440,"seasonCount":4,"communityRating":8.541,"criticRating":null,"genres":["Animation","Action & Adventure","Comedy"],"overview":"One fateful day, all of humanity was petrified by a blinding flash of light. After several millennia, high schooler Taiju awakens and finds himself lost in a world of statues. However, he\u2019s not alone! His\u2026","poster":"assets/tv-dr-stone-2019-poster.jpg","backdrop":"assets/tv-dr-stone-2019-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-20T22:28:13.2091579Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":86031,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.53,"tmdbVotes":1814}},{"id":"tv-frieren-beyond-journey-s-end-2023","title":"Frieren: Beyond Journey's End","year":2023,"type":"tv","runtimeSeconds":1500,"seasonCount":2,"communityRating":8.803,"criticRating":null,"genres":["Animation","Action & Adventure","Drama"],"overview":"After the party of heroes defeated the Demon King, they restored peace to the land and returned to lives of solitude. Generations pass, and the elven mage Frieren comes face to face with humanity\u2019s mortality. She\u2026","poster":"assets/tv-frieren-beyond-journey-s-end-2023-poster.jpg","backdrop":"assets/tv-frieren-beyond-journey-s-end-2023-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-20T22:28:13.2094435Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":209867,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.826,"tmdbVotes":1016}},{"id":"tv-fullmetal-alchemist-brotherhood-2009","title":"Fullmetal Alchemist: Brotherhood","year":2009,"type":"tv","runtimeSeconds":1500,"seasonCount":1,"communityRating":8.7,"criticRating":null,"genres":["Animation","Action & Adventure","Sci-Fi & Fantasy"],"overview":"Disregard for alchemy\u2019s laws ripped half of Edward Elric\u2019s limbs from his body and left his brother Alphonse\u2019s soul clinging to a suit of armor. To restore what was lost, the brothers seek the Philosopher\u2019s Stone.\u2026","poster":"assets/tv-fullmetal-alchemist-brotherhood-2009-poster.jpg","backdrop":"assets/tv-fullmetal-alchemist-brotherhood-2009-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-20T10:27:12.3573939Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":31911,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.7,"tmdbVotes":2633}},{"id":"tv-jujutsu-kaisen-2020","title":"JUJUTSU KAISEN","year":2020,"type":"tv","runtimeSeconds":1440,"seasonCount":3,"communityRating":8.583,"criticRating":null,"genres":["Animation","Action & Adventure","Sci-Fi & Fantasy"],"overview":"Yuji Itadori is a boy with tremendous physical strength, though he lives a completely ordinary high school life. One day, to save a classmate who has been attacked by curses, he eats the finger of Ryomen Sukuna,\u2026","poster":"assets/tv-jujutsu-kaisen-2020-poster.jpg","backdrop":"assets/tv-jujutsu-kaisen-2020-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-20T22:28:13.207573Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":95479,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.574,"tmdbVotes":4735}},{"id":"tv-kaiju-no-8-2024","title":"Kaiju No. 8","year":2024,"type":"tv","runtimeSeconds":1440,"seasonCount":2,"communityRating":8.436,"criticRating":null,"genres":["Animation","Action & Adventure","Sci-Fi & Fantasy"],"overview":"In a world plagued by creatures known as Kaiju, Kafka Hibino aspired to enlist in The Defense Force. He makes a promise to enlist with his childhood friend, Mina Ashiro. Soon, life takes them in separate ways. While\u2026","poster":"assets/tv-kaiju-no-8-2024-poster.jpg","backdrop":"assets/tv-kaiju-no-8-2024-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-22T10:31:16.2646566Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":207468,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.4,"tmdbVotes":836}},{"id":"tv-my-hero-academia-2016","title":"My Hero Academia","year":2016,"type":"tv","runtimeSeconds":1440,"seasonCount":8,"communityRating":8.607,"criticRating":null,"genres":["Action & Adventure","Animation","Sci-Fi & Fantasy"],"overview":"After he saves a bully from a Villain, a normal student is granted a superpower that allows him to attend a high school training academy for Heroes.","poster":"assets/tv-my-hero-academia-2016-poster.jpg","backdrop":"assets/tv-my-hero-academia-2016-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-20T22:28:13.2089315Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":65930,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.6,"tmdbVotes":5426}},{"id":"tv-neon-genesis-evangelion-1995","title":"Neon Genesis Evangelion","year":1995,"type":"tv","runtimeSeconds":1500,"seasonCount":1,"communityRating":8.568,"criticRating":null,"genres":["Sci-Fi & Fantasy","Animation","Drama"],"overview":"At the turn of the century, the Angels returned to Earth, seeking to wipe out humanity in an apocalyptic fury. Devastated, mankind's last remnants moved underground to wait for the day when the Angels would come back\u2026","poster":"assets/tv-neon-genesis-evangelion-1995-poster.jpg","backdrop":"assets/tv-neon-genesis-evangelion-1995-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0340629Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":890,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.56,"tmdbVotes":2205}},{"id":"tv-record-of-ragnarok-2021","title":"Record of Ragnarok","year":2021,"type":"tv","runtimeSeconds":null,"seasonCount":3,"communityRating":8.402,"criticRating":null,"genres":["Action & Adventure","Animation","Sci-Fi & Fantasy"],"overview":"Before eradicating humankind from the world, the gods give them one last chance to prove themselves worthy of survival. Let the Ragnarok battles begin.","poster":"assets/tv-record-of-ragnarok-2021-poster.jpg","backdrop":"assets/tv-record-of-ragnarok-2021-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-20T22:28:13.2085766Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":114868,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.403,"tmdbVotes":1929}},{"id":"tv-sakamoto-days-2025","title":"SAKAMOTO DAYS","year":2025,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":8.071,"criticRating":null,"genres":["Animation","Comedy","Action & Adventure"],"overview":"Once the greatest hitman of all, Taro Sakamoto retired in the name of love. But when his past catches up, he must fight to protect his beloved family.","poster":"assets/tv-sakamoto-days-2025-poster.jpg","backdrop":"assets/tv-sakamoto-days-2025-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-22T10:31:16.266066Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":207332,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.057,"tmdbVotes":375}},{"id":"tv-sentenced-to-be-a-hero-2025","title":"Sentenced to Be a Hero","year":2025,"type":"tv","runtimeSeconds":1440,"seasonCount":1,"communityRating":8.338,"criticRating":null,"genres":["Animation","Sci-Fi & Fantasy","Action & Adventure"],"overview":"In a world where heroism is a punishment, Xylo Forbartz, a condemned goddess killer, battles endless hordes of monstrous abominations as part of Penal Hero Unit 9004. Death is no escape, only a cycle of resurrection\u2026","poster":"assets/tv-sentenced-to-be-a-hero-2025-poster.jpg","backdrop":"assets/tv-sentenced-to-be-a-hero-2025-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-22T10:31:16.2666791Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":249907,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.244,"tmdbVotes":129}},{"id":"tv-spy-x-family-2022","title":"SPY x FAMILY","year":2022,"type":"tv","runtimeSeconds":1440,"seasonCount":3,"communityRating":8.506,"criticRating":null,"genres":["Animation","Action & Adventure","Comedy"],"overview":"A spy, an assassin and a telepath come together to pose as a family, each for their own reasons, while hiding their true identities from each other.","poster":"assets/tv-spy-x-family-2022-poster.jpg","backdrop":"assets/tv-spy-x-family-2022-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-22T10:31:16.2670364Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":120089,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.5,"tmdbVotes":2382}},{"id":"tv-the-tatami-galaxy-2010","title":"The Tatami Galaxy","year":2010,"type":"tv","runtimeSeconds":1500,"seasonCount":2,"communityRating":8.271,"criticRating":null,"genres":["Animation","Comedy","Drama"],"overview":"When a college dropout stops for a late night bite at a mysterious ramen stand, he crosses paths with a self-proclaimed deity of matrimony. This bizarre meeting sends the young man hurtling through a horrifying\u2026","poster":"assets/tv-the-tatami-galaxy-2010-poster.jpg","backdrop":"assets/tv-the-tatami-galaxy-2010-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-18T05:52:51.0023256Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":36243,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.3,"tmdbVotes":152}},{"id":"tv-vinland-saga-2019","title":"Vinland Saga","year":2019,"type":"tv","runtimeSeconds":1500,"seasonCount":2,"communityRating":8.527,"criticRating":null,"genres":["Animation","War & Politics","Action & Adventure"],"overview":"For a thousand years, the Vikings have made quite a name and reputation for themselves as the strongest families with a thirst for violence. Thorfinn, the son of one of the Vikings' greatest warriors, spends his\u2026","poster":"assets/tv-vinland-saga-2019-poster.jpg","backdrop":"assets/tv-vinland-saga-2019-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-20T22:28:13.207389Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":88803,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.509,"tmdbVotes":1064}},{"id":"tv-yu-yu-hakusho-1992","title":"Yu Yu Hakusho","year":1992,"type":"tv","runtimeSeconds":1440,"seasonCount":4,"communityRating":8.5,"criticRating":null,"genres":["Animation","Action & Adventure","Sci-Fi & Fantasy"],"overview":"After dying to save a boy, delinquent tough guy Yusuke Urameshi is granted another chance at life by redeeming himself as a \"Spirit Detective.\"","poster":"assets/tv-yu-yu-hakusho-1992-poster.jpg","backdrop":"assets/tv-yu-yu-hakusho-1992-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-19T21:46:01.5733049Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":30669,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.475,"tmdbVotes":519}}],"resume":[],"nextUp":[{"id":"episode-three-monsters-1992-s1e6","title":"Three Monsters","year":1992,"type":"episode","runtimeSeconds":1421,"seasonCount":null,"communityRating":7.4,"criticRating":null,"genres":["Animation","Action","Adventure"],"overview":"Yusuke receives his first real case as Spirit Detective. Three demon thieves have muscled their way into King Yama's sacred vault, stealing the three Artifacts of Darkness. Yusuke must recover the artifacts and bring\u2026","poster":"assets/episode-three-monsters-1992-s1e6-poster.jpg","backdrop":"assets/episode-three-monsters-1992-s1e6-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-19T21:59:21.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"Yu Yu Hakusho","seasonNumber":1,"episodeNumber":6,"artwork":{"posterKind":"poster","backdropKind":"backdrop"}},{"id":"episode-all-hands-on-deck-class-1-a-2021-s5e1","title":"All Hands on Deck! Class 1-A","year":2021,"type":"episode","runtimeSeconds":1433,"seasonCount":null,"communityRating":6.938,"criticRating":null,"genres":["Animation","Action","Adventure"],"overview":"There's an emergency drill at U.A. High School, and Class 1-A is requested to report for duty!","poster":"assets/episode-all-hands-on-deck-class-1-a-2021-s5e1-poster.jpg","backdrop":"assets/episode-all-hands-on-deck-class-1-a-2021-s5e1-backdrop.jpg","played":false,"playCount":2,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-22T04:04:50.0000000Z","lastPlayedAt":"2026-10-19T17:47:09.3028025Z","availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"My Hero Academia","seasonNumber":5,"episodeNumber":1,"artwork":{"posterKind":"poster","backdropKind":"backdrop"}},{"id":"episode-erickerhead-2026-s9e6","title":"Erickerhead","year":2026,"type":"episode","runtimeSeconds":1357,"seasonCount":null,"communityRating":8.196,"criticRating":null,"genres":[],"overview":"Rick's stomach is mad, broh. But it's all-you-can-eat-and-drink here, broh!","poster":"assets/episode-erickerhead-2026-s9e6-poster.jpg","backdrop":"assets/episode-erickerhead-2026-s9e6-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-28T10:23:23.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"Rick and Morty","seasonNumber":9,"episodeNumber":6,"artwork":{"posterKind":"poster","backdropKind":"backdrop"}},{"id":"episode-girls-interrupted-2007-s1e7","title":"Girls, Interrupted","year":2007,"type":"episode","runtimeSeconds":1642,"seasonCount":null,"communityRating":7.4,"criticRating":null,"genres":["Comedy","Drama"],"overview":"Hank is disturbed by Becca's negative reaction towards the concept of happy endings, even more so when he finds out that it is partially his fault.\nMarcy comes up with the idea of a threesome with Charlie and Dani,\u2026","poster":"assets/episode-girls-interrupted-2007-s1e7-poster.jpg","backdrop":"assets/episode-girls-interrupted-2007-s1e7-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-05T02:46:18.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"Californication","seasonNumber":1,"episodeNumber":7,"artwork":{"posterKind":"poster","backdropKind":"backdrop"}},{"id":"episode-announcement-2022-s1e7","title":"Announcement","year":2022,"type":"episode","runtimeSeconds":3012,"seasonCount":null,"communityRating":7.8,"criticRating":null,"genres":["Action","Adventure","Drama"],"overview":"The repercussions of the Aldhani heist reach all the way to Coruscant, while Cassian returns home.","poster":"assets/episode-announcement-2022-s1e7-poster.jpg","backdrop":"assets/episode-announcement-2022-s1e7-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T12:56:24.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"Andor","seasonNumber":1,"episodeNumber":7,"artwork":{"posterKind":"poster","backdropKind":"backdrop"}},{"id":"episode-south-american-biker-gangs-2026-s29e1","title":"South American Biker Gangs","year":2026,"type":"episode","runtimeSeconds":1335,"seasonCount":null,"communityRating":6.4,"criticRating":null,"genres":["Animation","Comedy"],"overview":"When e-bikes arrive in South America, the boys take over the streets and the parents of South America can hardly recognize South America.","poster":"assets/episode-south-american-biker-gangs-2026-s29e1-poster.jpg","backdrop":"assets/episode-south-american-biker-gangs-2026-s29e1-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-01T06:40:46.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"South Park","seasonNumber":29,"episodeNumber":1,"artwork":{"posterKind":"poster","backdropKind":"backdrop"}}],"recentlyAdded":[{"id":"movie-steins-gate-the-movie-load-region-of-deja-vu-2013","title":"Steins;Gate: The Movie - Load Region of D\u00e9j\u00e0 Vu","year":2013,"type":"movie","runtimeSeconds":5403,"seasonCount":null,"communityRating":7.8,"criticRating":null,"genres":["Animation","Mystery","Sci-Fi"],"overview":"After the events of the anime, Rintarou begins to feel the repercussions of extensive time travel, and eventually completely fades from reality. Kurisu, being the only companion to remember him, now must find a way\u2026","poster":"assets/movie-steins-gate-the-movie-load-region-of-deja-vu-2013-poster.jpg","backdrop":"assets/movie-steins-gate-the-movie-load-region-of-deja-vu-2013-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-22T14:55:54.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","artwork":{"posterKind":"poster","backdropKind":"backdrop"}},{"id":"tv-yu-yu-hakusho-1992","title":"Yu Yu Hakusho","year":1992,"type":"tv","runtimeSeconds":1440,"seasonCount":4,"communityRating":8.5,"criticRating":null,"genres":["Animation","Action & Adventure","Sci-Fi & Fantasy"],"overview":"After dying to save a boy, delinquent tough guy Yusuke Urameshi is granted another chance at life by redeeming himself as a \"Spirit Detective.\"","poster":"assets/tv-yu-yu-hakusho-1992-poster.jpg","backdrop":"assets/tv-yu-yu-hakusho-1992-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-19T21:46:01.5733049Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":30669,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.475,"tmdbVotes":519}},{"id":"movie-memories-1995","title":"Memories","year":1995,"type":"movie","runtimeSeconds":6805,"seasonCount":null,"communityRating":7.465,"criticRating":null,"genres":["Fantasy","Animation","Science Fiction"],"overview":"Three back-to-back anime films by three different directors make up this sci-fi trilogy three years in the making.","poster":"assets/movie-memories-1995-poster.jpg","backdrop":"assets/movie-memories-1995-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-30T21:36:03.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":42994,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":82,"rtAudienceLabel":"Upright","imdb":7.5,"imdbVotes":26638,"tmdb":7.459,"tmdbVotes":622}},{"id":"tv-firefly-2002","title":"Firefly","year":2002,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":8.347,"criticRating":null,"genres":["Drama","Action & Adventure","Sci-Fi & Fantasy"],"overview":"In the year 2517, the universe is a vast frontier where lawlessness reigns and adventure awaits! Join Captain Malcolm Reynolds and his ragtag crew aboard the spaceship Serenity as they navigate the fringes of\u2026","poster":"assets/tv-firefly-2002-poster.jpg","backdrop":"assets/tv-firefly-2002-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-20T11:40:08.4202369Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":1437,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":77,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.351,"tmdbVotes":2550}},{"id":"tv-love-death-robots-2019","title":"Love, Death & Robots","year":2019,"type":"tv","runtimeSeconds":null,"seasonCount":4,"communityRating":8.205,"criticRating":null,"genres":["Animation","Sci-Fi & Fantasy"],"overview":"Terrifying creatures, wicked surprises and dark comedy converge in this NSFW anthology of animated stories presented by Tim Miller and David Fincher.","poster":"assets/tv-love-death-robots-2019-poster.jpg","backdrop":"assets/tv-love-death-robots-2019-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-20T11:31:20.8818757Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":86831,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":89,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.203,"tmdbVotes":4238}},{"id":"tv-the-legend-of-korra-2012","title":"The Legend of Korra","year":2012,"type":"tv","runtimeSeconds":1380,"seasonCount":4,"communityRating":8.2,"criticRating":null,"genres":["Animation","Action & Adventure","Sci-Fi & Fantasy"],"overview":"Avatar Korra, a headstrong, rebellious, feisty young woman who continually challenges and breaks with tradition, is on her quest to become a fully realized Avatar. In this story, the Avatar struggles to find balance\u2026","poster":"assets/tv-the-legend-of-korra-2012-poster.jpg","backdrop":"assets/tv-the-legend-of-korra-2012-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-20T00:19:23.2494945Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":33880,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":88,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.221,"tmdbVotes":2482}},{"id":"tv-spy-x-family-2022","title":"SPY x FAMILY","year":2022,"type":"tv","runtimeSeconds":1440,"seasonCount":3,"communityRating":8.506,"criticRating":null,"genres":["Animation","Action & Adventure","Comedy"],"overview":"A spy, an assassin and a telepath come together to pose as a family, each for their own reasons, while hiding their true identities from each other.","poster":"assets/tv-spy-x-family-2022-poster.jpg","backdrop":"assets/tv-spy-x-family-2022-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-22T10:31:16.2670364Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":120089,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.5,"tmdbVotes":2382}},{"id":"tv-sentenced-to-be-a-hero-2025","title":"Sentenced to Be a Hero","year":2025,"type":"tv","runtimeSeconds":1440,"seasonCount":1,"communityRating":8.338,"criticRating":null,"genres":["Animation","Sci-Fi & Fantasy","Action & Adventure"],"overview":"In a world where heroism is a punishment, Xylo Forbartz, a condemned goddess killer, battles endless hordes of monstrous abominations as part of Penal Hero Unit 9004. Death is no escape, only a cycle of resurrection\u2026","poster":"assets/tv-sentenced-to-be-a-hero-2025-poster.jpg","backdrop":"assets/tv-sentenced-to-be-a-hero-2025-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-22T10:31:16.2666791Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":249907,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.244,"tmdbVotes":129}},{"id":"tv-sakamoto-days-2025","title":"SAKAMOTO DAYS","year":2025,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":8.071,"criticRating":null,"genres":["Animation","Comedy","Action & Adventure"],"overview":"Once the greatest hitman of all, Taro Sakamoto retired in the name of love. But when his past catches up, he must fight to protect his beloved family.","poster":"assets/tv-sakamoto-days-2025-poster.jpg","backdrop":"assets/tv-sakamoto-days-2025-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-22T10:31:16.266066Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":207332,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.057,"tmdbVotes":375}},{"id":"tv-dan-da-dan-2024","title":"Dan Da Dan","year":2024,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":8.538,"criticRating":null,"genres":["Animation","Action & Adventure","Comedy"],"overview":"In a bet to prove whether ghosts or aliens exist, two high schoolers face terrifying paranormal threats, gain superpowers and maybe even fall in love?!","poster":"assets/tv-dan-da-dan-2024-poster.jpg","backdrop":"assets/tv-dan-da-dan-2024-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-22T10:31:16.2652252Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":240411,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.517,"tmdbVotes":986}},{"id":"tv-kaiju-no-8-2024","title":"Kaiju No. 8","year":2024,"type":"tv","runtimeSeconds":1440,"seasonCount":2,"communityRating":8.436,"criticRating":null,"genres":["Animation","Action & Adventure","Sci-Fi & Fantasy"],"overview":"In a world plagued by creatures known as Kaiju, Kafka Hibino aspired to enlist in The Defense Force. He makes a promise to enlist with his childhood friend, Mina Ashiro. Soon, life takes them in separate ways. While\u2026","poster":"assets/tv-kaiju-no-8-2024-poster.jpg","backdrop":"assets/tv-kaiju-no-8-2024-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-22T10:31:16.2646566Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":207468,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.4,"tmdbVotes":836}},{"id":"tv-chainsaw-man-2022","title":"Chainsaw Man","year":2022,"type":"tv","runtimeSeconds":1440,"seasonCount":1,"communityRating":8.515,"criticRating":null,"genres":["Animation","Action & Adventure","Sci-Fi & Fantasy"],"overview":"Denji has a simple dream\u2014to live a happy and peaceful life, spending time with a girl he likes. This is a far cry from reality, however, as Denji is forced by the yakuza into killing devils in order to pay off his\u2026","poster":"assets/tv-chainsaw-man-2022-poster.jpg","backdrop":"assets/tv-chainsaw-man-2022-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-20T22:28:13.2095501Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":114410,"artwork":{"posterKind":"center_crop","backdropKind":"backdrop"},"ratings":{"rtCritics":97,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.508,"tmdbVotes":2364}}],"discover":[{"id":"movie-the-amazing-spider-man-2012","title":"The Amazing Spider-Man","year":2012,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action","Adventure","Science Fiction"],"overview":"A teenage Peter Parker grapples with both high school and amazing super-human crises as his alter-ego Spider-Man.","poster":"assets/movie-the-amazing-spider-man-2012-poster.jpg","backdrop":"assets/movie-the-amazing-spider-man-2012-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":1930,"ratings":{"rtCritics":71,"rtCriticsLabel":"Certified Fresh","rtAudience":77,"rtAudienceLabel":"Upright","imdb":7,"imdbVotes":791938,"tmdb":6.768,"tmdbVotes":19312}},{"id":"movie-the-amazing-spider-man-2-2014","title":"The Amazing Spider-Man 2","year":2014,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action","Adventure","Science Fiction"],"overview":"For Peter Parker, life is busy. Between taking out the bad guys as Spider-Man and spending time with the person he loves, Gwen Stacy, high school graduation cannot come quickly enough. Peter has not forgotten about\u2026","poster":"assets/movie-the-amazing-spider-man-2-2014-poster.jpg","backdrop":"assets/movie-the-amazing-spider-man-2-2014-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":102382,"ratings":{"rtCritics":51,"rtCriticsLabel":"Rotten","rtAudience":64,"rtAudienceLabel":"Upright","imdb":6.6,"imdbVotes":611981,"tmdb":6.567,"tmdbVotes":14919}},{"id":"movie-the-animatrix-2003","title":"The Animatrix","year":2003,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Animation","Science Fiction"],"overview":"Straight from the creators of the groundbreaking Matrix trilogy, this collection of short animated films from the world's leading anime directors fuses computer graphics and Japanese anime to provide the background\u2026","poster":"assets/movie-the-animatrix-2003-poster.jpg","backdrop":"assets/movie-the-animatrix-2003-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":55931,"ratings":{"rtCritics":86,"rtCriticsLabel":"Fresh","rtAudience":78,"rtAudienceLabel":"Upright","imdb":7.3,"imdbVotes":91929,"tmdb":7.221,"tmdbVotes":1872}},{"id":"movie-ant-man-and-the-wasp-quantumania-2023","title":"Ant-Man and the Wasp: Quantumania","year":2023,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action","Adventure","Science Fiction"],"overview":"Super-Hero partners Scott Lang and Hope van Dyne, along with with Hope's parents Janet van Dyne and Hank Pym, and Scott's daughter Cassie Lang, find themselves exploring the Quantum Realm, interacting with strange\u2026","poster":"assets/movie-ant-man-and-the-wasp-quantumania-2023-poster.jpg","backdrop":"assets/movie-ant-man-and-the-wasp-quantumania-2023-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":640146,"ratings":{"rtCritics":46,"rtCriticsLabel":"Rotten","rtAudience":81,"rtAudienceLabel":"Upright","imdb":6,"imdbVotes":281738,"tmdb":6.197,"tmdbVotes":6236}},{"id":"movie-appleseed-alpha-2014","title":"Appleseed Alpha","year":2014,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Animation","Science Fiction","Action"],"overview":"The Third World War (2099\u20132126) devastated part of the Earth. Former nations are reforming while new powers emerge, and groups of humans struggle to survive in ruined cities. The story follows Deunan Knute and her\u2026","poster":"assets/movie-appleseed-alpha-2014-poster.jpg","backdrop":"assets/movie-appleseed-alpha-2014-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"center_crop","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":269650,"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":59,"rtAudienceLabel":"Spilled","imdb":6.5,"imdbVotes":9689,"tmdb":6.808,"tmdbVotes":436}},{"id":"movie-aquaman-and-the-lost-kingdom-2023","title":"Aquaman and the Lost Kingdom","year":2023,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action","Adventure","Fantasy"],"overview":"Black Manta seeks revenge on Aquaman for his father's death. Wielding the Black Trident's power, he becomes a formidable foe. To defend Atlantis, Arthur (Aquaman) forges an alliance with his imprisoned brother. They\u2026","poster":"assets/movie-aquaman-and-the-lost-kingdom-2023-poster.jpg","backdrop":"assets/movie-aquaman-and-the-lost-kingdom-2023-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":572802,"ratings":{"rtCritics":33,"rtCriticsLabel":"Rotten","rtAudience":79,"rtAudienceLabel":"Upright","imdb":5.6,"imdbVotes":122422,"tmdb":6.48,"tmdbVotes":3748}},{"id":"movie-the-avengers-2012","title":"The Avengers","year":2012,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Science Fiction","Action","Adventure"],"overview":"When an unexpected enemy emerges and threatens global safety and security, Nick Fury, director of the international peacekeeping agency known as S.H.I.E.L.D., finds himself in need of a team to pull the world back\u2026","poster":"assets/movie-the-avengers-2012-poster.jpg","backdrop":"assets/movie-the-avengers-2012-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":24428,"ratings":{"rtCritics":91,"rtCriticsLabel":"Certified Fresh","rtAudience":91,"rtAudienceLabel":"Upright","imdb":8,"imdbVotes":1590693,"tmdb":8.084,"tmdbVotes":40262}},{"id":"movie-avengers-confidential-black-widow-punisher-2014","title":"Avengers Confidential: Black Widow & Punisher","year":2014,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Animation","Science Fiction","Action"],"overview":"When the Punisher takes out a black-market weapons dealer, he stumbles upon a far-reaching terrorist plot devised by a group known as Leviathan.","poster":"assets/movie-avengers-confidential-black-widow-punisher-2014-poster.jpg","backdrop":"assets/movie-avengers-confidential-black-widow-punisher-2014-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":257346,"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":55,"rtAudienceLabel":"Spilled","imdb":5.7,"imdbVotes":5166,"tmdb":6.368,"tmdbVotes":303}},{"id":"movie-avengers-age-of-ultron-2015","title":"Avengers: Age of Ultron","year":2015,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action","Adventure","Science Fiction"],"overview":"When Tony Stark tries to jumpstart a dormant peacekeeping program, things go awry and Earth\u2019s Mightiest Heroes are put to the ultimate test as the fate of the planet hangs in the balance. As the villainous Ultron\u2026","poster":"assets/movie-avengers-age-of-ultron-2015-poster.jpg","backdrop":"assets/movie-avengers-age-of-ultron-2015-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":99861,"ratings":{"rtCritics":75,"rtCriticsLabel":"Certified Fresh","rtAudience":82,"rtAudienceLabel":"Upright","imdb":7.3,"imdbVotes":1025876,"tmdb":7.278,"tmdbVotes":25289}},{"id":"movie-avengers-infinity-war-2018","title":"Avengers: Infinity War","year":2018,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Adventure","Action","Science Fiction"],"overview":"As the Avengers and their allies have continued to protect the world from threats too large for any one hero to handle, a new danger has emerged from the cosmic shadows: Thanos. A despot of intergalactic infamy, his\u2026","poster":"assets/movie-avengers-infinity-war-2018-poster.jpg","backdrop":"assets/movie-avengers-infinity-war-2018-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":299536,"ratings":{"rtCritics":85,"rtCriticsLabel":"Certified Fresh","rtAudience":92,"rtAudienceLabel":"Upright","imdb":8.4,"imdbVotes":1421954,"tmdb":8.246,"tmdbVotes":33331}},{"id":"movie-batman-ninja-2018","title":"Batman Ninja","year":2018,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Animation","Action","Science Fiction"],"overview":"Batman, along with many of his allies and adversaries, finds himself transported to feudal Japan by Gorilla Grodd's time displacement machine.","poster":"assets/movie-batman-ninja-2018-poster.jpg","backdrop":"assets/movie-batman-ninja-2018-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":485942,"ratings":{"rtCritics":84,"rtCriticsLabel":"Fresh","rtAudience":60,"rtAudienceLabel":"Upright","imdb":5.6,"imdbVotes":24579,"tmdb":5.9,"tmdbVotes":1106}},{"id":"movie-batman-v-superman-dawn-of-justice-2016","title":"Batman v Superman: Dawn of Justice","year":2016,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action","Adventure","Fantasy"],"overview":"Fearing the actions of a god-like Super Hero left unchecked, Gotham City\u2019s own formidable, forceful vigilante takes on Metropolis\u2019s most revered, modern-day savior, while the world wrestles with what sort of hero it\u2026","poster":"assets/movie-batman-v-superman-dawn-of-justice-2016-poster.jpg","backdrop":"assets/movie-batman-v-superman-dawn-of-justice-2016-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":209112,"ratings":{"rtCritics":28,"rtCriticsLabel":"Rotten","rtAudience":63,"rtAudienceLabel":"Upright","imdb":6.4,"imdbVotes":801382,"tmdb":6.014,"tmdbVotes":19527}},{"id":"movie-batman-the-dark-knight-returns-part-1-2012","title":"Batman: The Dark Knight Returns, Part 1","year":2012,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Science Fiction","Action","Animation"],"overview":"Batman has not been seen for ten years. A new breed of criminal ravages Gotham City, forcing 55-year-old Bruce Wayne back into the cape and cowl. But, does he still have what it takes to fight crime in a new era?","poster":"assets/movie-batman-the-dark-knight-returns-part-1-2012-poster.jpg","backdrop":"assets/movie-batman-the-dark-knight-returns-part-1-2012-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":123025,"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":93,"rtAudienceLabel":"Upright","imdb":7.9,"imdbVotes":68943,"tmdb":7.742,"tmdbVotes":1766}},{"id":"movie-black-adam-2022","title":"Black Adam","year":2022,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action","Adventure","Science Fiction"],"overview":"Nearly 5,000 years after he was bestowed with the almighty powers of the Egyptian gods\u2014and imprisoned just as quickly\u2014Black Adam is freed from his earthly tomb, ready to unleash his unique form of justice on the\u2026","poster":"assets/movie-black-adam-2022-poster.jpg","backdrop":"assets/movie-black-adam-2022-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":436270,"ratings":{"rtCritics":39,"rtCriticsLabel":"Rotten","rtAudience":87,"rtAudienceLabel":"Upright","imdb":6.1,"imdbVotes":309624,"tmdb":6.747,"tmdbVotes":7370}},{"id":"movie-black-panther-2018","title":"Black Panther","year":2018,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action","Adventure","Science Fiction"],"overview":"King T'Challa returns home to the reclusive, technologically advanced African nation of Wakanda to serve as his country's new leader. However, T'Challa soon finds that he is challenged for the throne by factions\u2026","poster":"assets/movie-black-panther-2018-poster.jpg","backdrop":"assets/movie-black-panther-2018-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":284054,"ratings":{"rtCritics":96,"rtCriticsLabel":"Certified Fresh","rtAudience":null,"rtAudienceLabel":"Spilled","imdb":7.3,"imdbVotes":931120,"tmdb":7.36,"tmdbVotes":24190}},{"id":"movie-black-panther-wakanda-forever-2022","title":"Black Panther: Wakanda Forever","year":2022,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action","Adventure","Science Fiction"],"overview":"Queen Ramonda, Shuri, M\u2019Baku, Okoye and the Dora Milaje fight to protect their nation from intervening world powers in the wake of King T\u2019Challa\u2019s death. As the Wakandans strive to embrace their next chapter, the\u2026","poster":"assets/movie-black-panther-wakanda-forever-2022-poster.jpg","backdrop":"assets/movie-black-panther-wakanda-forever-2022-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":505642,"ratings":{"rtCritics":84,"rtCriticsLabel":"Certified Fresh","rtAudience":93,"rtAudienceLabel":"Upright","imdb":6.6,"imdbVotes":405088,"tmdb":6.984,"tmdbVotes":7920}},{"id":"movie-blame-2017","title":"BLAME!","year":2017,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action","Drama","Science Fiction"],"overview":"In the distant technological future, civilization has reached its ultimate Net-based form. An \"infection\" in the past caused the automated systems to spiral out of order, resulting in a multi-leveled city structure\u2026","poster":"assets/movie-blame-2017-poster.jpg","backdrop":"assets/movie-blame-2017-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":409421,"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":61,"rtAudienceLabel":"Upright","imdb":6.6,"imdbVotes":10258,"tmdb":6.523,"tmdbVotes":370}},{"id":"movie-bleach-the-movie-fade-to-black-2008","title":"Bleach the Movie: Fade to Black","year":2008,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action","Animation","Fantasy"],"overview":"A strange disturbance in the World of the Living sends Ichigo and Kon to the Soul Society, where the Seireitei has been devastated by an explosion of reishi and Rukia is missing. Stranger still, none of the Soul\u2026","poster":"assets/movie-bleach-the-movie-fade-to-black-2008-poster.jpg","backdrop":"assets/movie-bleach-the-movie-fade-to-black-2008-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":17165,"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":67,"rtAudienceLabel":"Upright","imdb":7.1,"imdbVotes":3693,"tmdb":7.1,"tmdbVotes":206}},{"id":"tv-90-day-fiance-before-the-90-days-2017","title":"90 Day Fianc\u00e9: Before the 90 Days","year":2017,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Reality"],"overview":"Follow couples who have an existing relationship online, but haven't met in person. We'll experience their journey as they travel to the other's foreign country for the first time in an attempt to establish an\u2026","poster":"assets/tv-90-day-fiance-before-the-90-days-2017-poster.jpg","backdrop":"assets/tv-90-day-fiance-before-the-90-days-2017-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":73319,"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.5,"tmdbVotes":45}},{"id":"tv-90-day-fiance-the-other-way-2019","title":"90 Day Fianc\u00e9: The Other Way","year":2019,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Reality"],"overview":"Americans move to a foreign country all in the name of love. Will uprooting their lives in the United States pay off, or will they be packing up and moving back to America brokenhearted?","poster":"assets/tv-90-day-fiance-the-other-way-2019-poster.jpg","backdrop":"assets/tv-90-day-fiance-the-other-way-2019-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":90046,"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.8,"tmdbVotes":34}},{"id":"tv-the-100-2014","title":"The 100","year":2014,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Sci-Fi & Fantasy","Action & Adventure","Drama"],"overview":"100 years in the future, when the Earth has been abandoned due to radioactivity, the last surviving humans live on an ark orbiting the planet \u2014 but the ark won't last forever. So the repressive regime picks 100\u2026","poster":"assets/tv-the-100-2014-poster.jpg","backdrop":"assets/tv-the-100-2014-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":48866,"ratings":{"rtCritics":93,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.878,"tmdbVotes":8855}},{"id":"tv-the-abbott-and-costello-show-1952","title":"The Abbott and Costello Show","year":1952,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Comedy"],"overview":"Bud and Lou are unemployed actors living in Mr. Fields\u2019 boarding house. Lou\u2019s girlfriend Hillary lives across the hall. Many situations arise leading to slapstick and puns.","poster":"assets/tv-the-abbott-and-costello-show-1952-poster.jpg","backdrop":"assets/tv-the-abbott-and-costello-show-1952-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":11821,"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.2,"tmdbVotes":22}},{"id":"tv-accel-world-2012","title":"Accel World","year":2012,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Animation","Action & Adventure","Drama"],"overview":"A short, overweight student uses the Neuro Link, an evolution of the Nerve Gear, to escape himself from the reality. But his skills in the virtual world brings him to the attention of Kuroyukihime, a popular student\u2026","poster":"assets/tv-accel-world-2012-poster.jpg","backdrop":"assets/tv-accel-world-2012-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"center_crop","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":43167,"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.429,"tmdbVotes":163}},{"id":"tv-ahsoka-2023","title":"Ahsoka","year":2023,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Sci-Fi & Fantasy","Action & Adventure","Drama"],"overview":"Former Jedi Knight Ahsoka Tano investigates an emerging threat to a vulnerable galaxy.","poster":"assets/tv-ahsoka-2023-poster.jpg","backdrop":"assets/tv-ahsoka-2023-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":114461,"ratings":{"rtCritics":85,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.4,"tmdbVotes":1351}},{"id":"tv-american-dad-2005","title":"American Dad!","year":2005,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Animation","Comedy"],"overview":"The series focuses on an eccentric motley crew that is the Smith family and their three housemates: Father, husband, and breadwinner Stan Smith; his better half housewife, Francine Smith; their college-aged daughter,\u2026","poster":"assets/tv-american-dad-2005-poster.jpg","backdrop":"assets/tv-american-dad-2005-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":1433,"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.022,"tmdbVotes":2481}},{"id":"tv-american-gods-2017","title":"American Gods","year":2017,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Mystery","Sci-Fi & Fantasy"],"overview":"An ex-con becomes the traveling partner of a conman who turns out to be one of the older gods trying to recruit troops to battle the upstart deities. Based on Neil Gaiman's fantasy novel.","poster":"assets/tv-american-gods-2017-poster.jpg","backdrop":"assets/tv-american-gods-2017-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":46639,"ratings":{"rtCritics":75,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.1,"tmdbVotes":1852}},{"id":"tv-andromeda-2000","title":"Andromeda","year":2000,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action & Adventure","Drama","Sci-Fi & Fantasy"],"overview":"Captain Dylan Hunt and his crew quest to restore a government that once presided over an extended peace and prosperity.","poster":"assets/tv-andromeda-2000-poster.jpg","backdrop":"assets/tv-andromeda-2000-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":2985,"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.068,"tmdbVotes":315}},{"id":"tv-aqua-teen-hunger-force-2000","title":"Aqua Teen Hunger Force","year":2000,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Animation","Comedy"],"overview":"The surreal adventures of three anthropomorphic fast food items: Master Shake, Frylock and Meatwad, and their human nextdoor neighbor, Carl Brutananadilewski.","poster":"assets/tv-aqua-teen-hunger-force-2000-poster.jpg","backdrop":"assets/tv-aqua-teen-hunger-force-2000-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":251,"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.5,"tmdbVotes":272}},{"id":"tv-arifureta-from-commonplace-to-world-s-strongest-2019","title":"Arifureta: From Commonplace to World's Strongest","year":2019,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Animation","Action & Adventure","Sci-Fi & Fantasy"],"overview":"Hajime Nagumo and his high school class are suddenly summoned to a fantastical land as heroes. But while most of his classmates have powerful stats and abilities, Hajime does not. Underappreciated and unprepared, he\u2026","poster":"assets/tv-arifureta-from-commonplace-to-world-s-strongest-2019-poster.jpg","backdrop":"assets/tv-arifureta-from-commonplace-to-world-s-strongest-2019-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":86034,"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.382,"tmdbVotes":662}},{"id":"tv-arrow-2012","title":"Arrow","year":2012,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Crime","Drama","Action & Adventure"],"overview":"Spoiled billionaire playboy Oliver Queen is missing and presumed dead when his yacht is lost at sea. He returns five years later a changed man, determined to clean up the city as a hooded vigilante armed with a bow.","poster":"assets/tv-arrow-2012-poster.jpg","backdrop":"assets/tv-arrow-2012-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":1412,"ratings":{"rtCritics":86,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.834,"tmdbVotes":6537}},{"id":"tv-avatar-the-last-airbender-2024","title":"Avatar: The Last Airbender","year":2024,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action & Adventure","Sci-Fi & Fantasy","Drama"],"overview":"A young boy known as the Avatar must master the four elemental powers to save a world at war \u2014 and fight a ruthless enemy bent on stopping him.","poster":"assets/tv-avatar-the-last-airbender-2024-poster.jpg","backdrop":"assets/tv-avatar-the-last-airbender-2024-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":82452,"ratings":{"rtCritics":66,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.8,"tmdbVotes":1406}},{"id":"tv-avatar-seven-havens-2026","title":"Avatar: Seven Havens","year":2026,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Animation","Action & Adventure","Sci-Fi & Fantasy"],"overview":"In a world shattered by a devastating cataclysm, a young Earthbender discovers she's the new Avatar after Korra. But in this dangerous era, that title marks her as humanity's destroyer, not its savior. Hunted by both\u2026","poster":"assets/tv-avatar-seven-havens-2026-poster.jpg","backdrop":"assets/tv-avatar-seven-havens-2026-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":284833,"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.9,"tmdbVotes":183}},{"id":"tv-batman-the-brave-and-the-bold-2008","title":"Batman: The Brave and the Bold","year":2008,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Animation","Action & Adventure","Sci-Fi & Fantasy"],"overview":"The Caped Crusader is teamed up with Blue Beetle, Green Arrow, Aquaman and countless others in his quest to uphold justice.","poster":"assets/tv-batman-the-brave-and-the-bold-2008-poster.jpg","backdrop":"assets/tv-batman-the-brave-and-the-bold-2008-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":15804,"ratings":{"rtCritics":96,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.6,"tmdbVotes":295}},{"id":"tv-batwoman-2019","title":"Batwoman","year":2019,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Sci-Fi & Fantasy","Action & Adventure"],"overview":"Kate Kane, armed with a passion for social justice and a flair for speaking her mind, soars onto the streets of Gotham as Batwoman, an out lesbian and highly trained street fighter primed to snuff out the failing\u2026","poster":"assets/tv-batwoman-2019-poster.jpg","backdrop":"assets/tv-batwoman-2019-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":89247,"ratings":{"rtCritics":83,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.8,"tmdbVotes":1619}},{"id":"tv-big-mouth-2017","title":"Big Mouth","year":2017,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Comedy","Animation"],"overview":"Teenage friends find their lives upended by the wonders and horrors of puberty in this edgy comedy from real-life pals Nick Kroll and Andrew Goldberg.","poster":"assets/tv-big-mouth-2017-poster.jpg","backdrop":"assets/tv-big-mouth-2017-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":74204,"ratings":{"rtCritics":95,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.591,"tmdbVotes":1274}},{"id":"tv-black-lightning-2018","title":"Black Lightning","year":2018,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action & Adventure","Sci-Fi & Fantasy","Drama"],"overview":"Jefferson Pierce is a man wrestling with a secret. As the father of two daughters and principal of a charter high school that also serves as a safe haven for young people in a New Orleans neighborhood overrun by gang\u2026","poster":"assets/tv-black-lightning-2018-poster.jpg","backdrop":"assets/tv-black-lightning-2018-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":71663,"ratings":{"rtCritics":92,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.907,"tmdbVotes":991}}],"discoverySource":{"state":"materialized_snapshot","rankKnown":false,"selection":"First 18 alphabetically indexed movie stubs and first 18 series stubs, not ranked feed order","observedAt":"2026-11-04T20:42:12.030108+00:00"}},{"key":"mindel","name":"Mindel","initial":"M","color":"#ff9d72","destinations":{"Home":{"kind":"home"},"Movies":{"kind":"library","collection":"movies"},"Shows":{"kind":"library","collection":"shows"},"Discover":{"kind":"discover","collection":"discover"}},"movies":[{"id":"movie-chicago-2002","title":"Chicago","year":2002,"type":"movie","runtimeSeconds":6808,"seasonCount":null,"communityRating":7.131,"criticRating":87,"genres":["Comedy","Crime","Drama"],"overview":"Murderesses Velma Kelly and Roxie Hart find themselves on death row together and fight for the fame that will keep them from the gallows in 1920s Chicago.","poster":"assets/movie-chicago-2002-poster.jpg","backdrop":"assets/movie-chicago-2002-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:24:53.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":1574,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":87,"rtCriticsLabel":"Certified Fresh","rtAudience":83,"rtAudienceLabel":"Upright","imdb":7.2,"imdbVotes":259272,"tmdb":7.135,"tmdbVotes":3025}},{"id":"movie-coherence-2014","title":"Coherence","year":2014,"type":"movie","runtimeSeconds":5286,"seasonCount":null,"communityRating":7.21,"criticRating":89,"genres":["Thriller","Science Fiction"],"overview":"Four couples gather for dinner the night a mysterious and powerful comet passes overhead.","poster":"assets/movie-coherence-2014-poster.jpg","backdrop":"assets/movie-coherence-2014-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2017-08-12T23:49:00.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":220289,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":89,"rtCriticsLabel":"Certified Fresh","rtAudience":81,"rtAudienceLabel":"Upright","imdb":7.1,"imdbVotes":180354,"tmdb":7.208,"tmdbVotes":3702}},{"id":"movie-the-killing-of-a-sacred-deer-2017","title":"The Killing of a Sacred Deer","year":2017,"type":"movie","runtimeSeconds":7262,"seasonCount":null,"communityRating":7.003,"criticRating":79,"genres":["Drama","Thriller","Mystery"],"overview":"Dr. Steven Murphy is a renowned cardiovascular surgeon who presides over a spotless household with his wife and two children. Lurking at the margins of his idyllic suburban existence is Martin, a fatherless teen who\u2026","poster":"assets/movie-the-killing-of-a-sacred-deer-2017-poster.jpg","backdrop":"assets/movie-the-killing-of-a-sacred-deer-2017-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-22T21:49:26.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":399057,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":79,"rtCriticsLabel":"Certified Fresh","rtAudience":63,"rtAudienceLabel":"Upright","imdb":7,"imdbVotes":219488,"tmdb":7.001,"tmdbVotes":4640}},{"id":"movie-night-is-short-walk-on-girl-2017","title":"Night Is Short, Walk On Girl","year":2017,"type":"movie","runtimeSeconds":5548,"seasonCount":null,"communityRating":7.421,"criticRating":90,"genres":["Comedy","Romance","Animation"],"overview":"As a group of university students go out for a night on the town, a sophomore known only as \"The Girl with Black Hair\" experiences a series of surreal encounters with the local nightlife \u2013 all the while unaware of\u2026","poster":"assets/movie-night-is-short-walk-on-girl-2017-poster.jpg","backdrop":"assets/movie-night-is-short-walk-on-girl-2017-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T17:39:14.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":430214,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":90,"rtCriticsLabel":"Fresh","rtAudience":84,"rtAudienceLabel":"Upright","imdb":7.5,"imdbVotes":7640,"tmdb":7.4,"tmdbVotes":267}},{"id":"movie-thelma-louise-1991","title":"Thelma & Louise","year":1991,"type":"movie","runtimeSeconds":7786,"seasonCount":null,"communityRating":7.596,"criticRating":87,"genres":["Drama","Crime","Adventure"],"overview":"Taking a break from their dreary lives, close friends Thelma and Louise embark on a short weekend trip that ends in unforeseen incriminating circumstances. As fugitives, both women rediscover the strength of their\u2026","poster":"assets/movie-thelma-louise-1991-poster.jpg","backdrop":"assets/movie-thelma-louise-1991-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:24:40.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":1541,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":87,"rtCriticsLabel":"Certified Fresh","rtAudience":82,"rtAudienceLabel":"Upright","imdb":7.6,"imdbVotes":197947,"tmdb":7.594,"tmdbVotes":4063}},{"id":"movie-vicky-cristina-barcelona-2008","title":"Vicky Cristina Barcelona","year":2008,"type":"movie","runtimeSeconds":5804,"seasonCount":null,"communityRating":6.798,"criticRating":80,"genres":["Drama","Romance"],"overview":"Two girlfriends on a summer holiday in Spain become enamored with the same painter, unaware that his ex-wife, with whom he has a tempestuous relationship, is about to re-enter the picture.","poster":"assets/movie-vicky-cristina-barcelona-2008-poster.jpg","backdrop":"assets/movie-vicky-cristina-barcelona-2008-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:25:34.0000000Z","lastPlayedAt":"2026-08-11T20:12:57.3064089Z","availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":5038,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":80,"rtCriticsLabel":"Certified Fresh","rtAudience":74,"rtAudienceLabel":"Upright","imdb":7.1,"imdbVotes":283286,"tmdb":6.797,"tmdbVotes":4164}}],"shows":[{"id":"tv-all-creatures-great-small-2020","title":"All Creatures Great & Small","year":2020,"type":"tv","runtimeSeconds":3000,"seasonCount":7,"communityRating":8.2,"criticRating":null,"genres":["Drama","Comedy"],"overview":"The heartwarming and humorous adventures of a young country vet in the Yorkshire Dales in the 1930s. A remake of the 1978 series.","poster":"assets/tv-all-creatures-great-small-2020-poster.jpg","backdrop":"assets/tv-all-creatures-great-small-2020-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-11-04T20:13:03.4266156Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":108255,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":99,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.2,"tmdbVotes":168}},{"id":"tv-back-to-life-2019","title":"Back to Life","year":2019,"type":"tv","runtimeSeconds":1500,"seasonCount":2,"communityRating":7.367,"criticRating":null,"genres":["Comedy","Drama"],"overview":"When Miri Matteson returns home after eighteen years, can she integrate back into her old life? With a terrible event from her past hanging over her, it won\u2019t be easy.","poster":"assets/tv-back-to-life-2019-poster.jpg","backdrop":"assets/tv-back-to-life-2019-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0688758Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":88510,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.4,"tmdbVotes":65}},{"id":"tv-big-boys-2022","title":"Big Boys","year":2022,"type":"tv","runtimeSeconds":1440,"seasonCount":3,"communityRating":7.6,"criticRating":null,"genres":["Comedy","Drama"],"overview":"Two boys from very different ends of the 'spectrum of masculinity' become best friends at Brent University freshers' week; in their first year of uni, they explore, experiment and try to discover themselves, helping\u2026","poster":"assets/tv-big-boys-2022-poster.jpg","backdrop":"assets/tv-big-boys-2022-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-11-04T20:25:58.2156837Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":202851,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.6,"tmdbVotes":49}},{"id":"tv-call-the-midwife-2012","title":"Call the Midwife","year":2012,"type":"tv","runtimeSeconds":3120,"seasonCount":15,"communityRating":7.5,"criticRating":null,"genres":["Drama"],"overview":"Drama following the lives of a group of midwives working in the poverty-stricken East End of London during the 1950s, based on the best-selling memoirs of Jennifer Worth.","poster":"assets/tv-call-the-midwife-2012-poster.jpg","backdrop":"assets/tv-call-the-midwife-2012-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0377216Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":39793,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.577,"tmdbVotes":267}},{"id":"tv-derry-girls-2018","title":"Derry Girls","year":2018,"type":"tv","runtimeSeconds":1380,"seasonCount":3,"communityRating":8.144,"criticRating":null,"genres":["Comedy","Drama"],"overview":"Amidst the political conflict of Northern Ireland in the 1990s, five secondary school students square off with the universal challenges of being a teenager.","poster":"assets/tv-derry-girls-2018-poster.jpg","backdrop":"assets/tv-derry-girls-2018-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-02T20:01:55.8955537Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":76148,"artwork":{"posterKind":"center_crop","backdropKind":"backdrop"},"ratings":{"rtCritics":99,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.138,"tmdbVotes":454}},{"id":"tv-desperate-housewives-2004","title":"Desperate Housewives","year":2004,"type":"tv","runtimeSeconds":2520,"seasonCount":8,"communityRating":7.896,"criticRating":null,"genres":["Mystery","Drama","Comedy"],"overview":"Looking down on her friends and family isn't a way of life for Mary Alice Young... it's a way of death. One day, in her perfect house, in the loveliest of suburbs, Mary Alice ended it all. Now she's taking us into\u2026","poster":"assets/tv-desperate-housewives-2004-poster.jpg","backdrop":"assets/tv-desperate-housewives-2004-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-29T20:56:40.3505596Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":693,"artwork":{"posterKind":"poster","backdropKind":"center_crop"},"ratings":{"rtCritics":72,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.896,"tmdbVotes":2171}},{"id":"tv-the-diplomat-2023","title":"The Diplomat","year":2023,"type":"tv","runtimeSeconds":null,"seasonCount":4,"communityRating":7.569,"criticRating":null,"genres":["Drama","War & Politics"],"overview":"Amid an international crisis, a US diplomat contends with her high-profile job as ambassador to the UK and her strained marriage to a political star.","poster":"assets/tv-the-diplomat-2023-poster.jpg","backdrop":"assets/tv-the-diplomat-2023-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0640348Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":203857,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":93,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.652,"tmdbVotes":521}},{"id":"tv-the-durrells-2016","title":"The Durrells","year":2016,"type":"tv","runtimeSeconds":2760,"seasonCount":4,"communityRating":7.402,"criticRating":null,"genres":["Drama","Comedy","Family"],"overview":"In 1935, financially strapped widow Louisa Durrell, whose life has fallen apart, decides to move from England, with her four children (three sons, one daughter), to the island of Corfu, Greece. Once there, the family\u2026","poster":"assets/tv-the-durrells-2016-poster.jpg","backdrop":"assets/tv-the-durrells-2016-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0619436Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":66134,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":94,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.4,"tmdbVotes":127}},{"id":"tv-etoile-2025","title":"\u00c9toile","year":2025,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":7.197,"criticRating":null,"genres":["Comedy","Drama"],"overview":"In an ambitious gambit to save their storied institutions, two world-renowned ballet companies in New York City and Paris swap their most talented stars.","poster":"assets/tv-etoile-2025-poster.jpg","backdrop":"assets/tv-etoile-2025-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0601383Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":225383,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":86,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.3,"tmdbVotes":40}},{"id":"tv-gilmore-girls-2000","title":"Gilmore Girls","year":2000,"type":"tv","runtimeSeconds":2640,"seasonCount":7,"communityRating":7.893,"criticRating":null,"genres":["Comedy","Drama"],"overview":"Set in the charming town of Stars Hollow, Connecticut, the series follows the captivating lives of Lorelai and Rory Gilmore, a mother/daughter pair who have a relationship most people only dream of.","poster":"assets/tv-gilmore-girls-2000-poster.jpg","backdrop":"assets/tv-gilmore-girls-2000-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0631035Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":4586,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.9,"tmdbVotes":1339}},{"id":"tv-ginny-georgia-2021","title":"Ginny & Georgia","year":2021,"type":"tv","runtimeSeconds":null,"seasonCount":3,"communityRating":8.026,"criticRating":null,"genres":["Comedy","Drama"],"overview":"Free-spirited Georgia and her two kids, Ginny and Austin, move north in search of a fresh start but find that the road to new beginnings can be bumpy.","poster":"assets/tv-ginny-georgia-2021-poster.jpg","backdrop":"assets/tv-ginny-georgia-2021-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0694828Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":117581,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":68,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8,"tmdbVotes":1840}},{"id":"tv-hellcats-2010","title":"Hellcats","year":2010,"type":"tv","runtimeSeconds":2460,"seasonCount":1,"communityRating":7.5,"criticRating":null,"genres":["Drama"],"overview":"Pre-law student Marti Perkins' world is flipped upside down when she loses her scholarship, and realizes the only way she can stay in school is by reigniting her dormant teen gymnastic skills to win a place on Lancer\u2026","poster":"assets/tv-hellcats-2010-poster.jpg","backdrop":"assets/tv-hellcats-2010-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-22T20:39:02.7719318Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":32504,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":65,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.5,"tmdbVotes":116}},{"id":"tv-high-potential-2024","title":"High Potential","year":2024,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":8.201,"criticRating":null,"genres":["Drama","Crime","Mystery"],"overview":"Morgan is a single mom with an exceptional mind, whose unconventional knack for solving crimes leads to an unusual and unstoppable partnership with a by-the-book seasoned detective.","poster":"assets/tv-high-potential-2024-poster.jpg","backdrop":"assets/tv-high-potential-2024-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0686091Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":226637,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":98,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.3,"tmdbVotes":707}},{"id":"tv-how-to-get-to-heaven-from-belfast-2026","title":"How to Get to Heaven from Belfast","year":2026,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":7.027,"criticRating":null,"genres":["Mystery","Comedy","Drama"],"overview":"Three lifelong pals embark on a chaotic quest to solve the mystery of their old friend's suspicious death and keep their own dark secret under wraps.","poster":"assets/tv-how-to-get-to-heaven-from-belfast-2026-poster.jpg","backdrop":"assets/tv-how-to-get-to-heaven-from-belfast-2026-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0683192Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":233079,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":95,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.063,"tmdbVotes":95}},{"id":"tv-the-hunting-wives-2025","title":"The Hunting Wives","year":2025,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":6.932,"criticRating":null,"genres":["Drama","Mystery"],"overview":"Sophie trades New England for East Texas and falls into a wealthy socialite's magnetic orbit \u2014 where a clique of housewives hide deadly secrets.","poster":"assets/tv-the-hunting-wives-2025-poster.jpg","backdrop":"assets/tv-the-hunting-wives-2025-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-20T19:42:46.3227892Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":244447,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":81,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.964,"tmdbVotes":112}},{"id":"tv-the-lost-flowers-of-alice-hart-2023","title":"The Lost Flowers of Alice Hart","year":2023,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":7.634,"criticRating":null,"genres":["Drama","Mystery"],"overview":"After losing her parents in a mysterious fire, nine-year-old Alice Hart is raised by her grandmother June on a flower farm where she learns there are secrets within secrets. But years on, an unearthed betrayal sees\u2026","poster":"assets/tv-the-lost-flowers-of-alice-hart-2023-poster.jpg","backdrop":"assets/tv-the-lost-flowers-of-alice-hart-2023-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0607236Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":125816,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":82,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.64,"tmdbVotes":161}},{"id":"tv-love-is-blind-2020","title":"Love Is Blind","year":2020,"type":"tv","runtimeSeconds":null,"seasonCount":11,"communityRating":6.261,"criticRating":null,"genres":["Reality"],"overview":"Nick and Vanessa Lachey host this social experiment where single men and women look for love and get engaged, all before meeting in person.","poster":"assets/tv-love-is-blind-2020-poster.jpg","backdrop":"assets/tv-love-is-blind-2020-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-22T17:11:08.2447226Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":99353,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":66,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.233,"tmdbVotes":118}},{"id":"tv-maximum-pleasure-guaranteed-2026","title":"Maximum Pleasure Guaranteed","year":2026,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":6.676,"criticRating":null,"genres":["Comedy"],"overview":"A newly divorced mom falls down a dangerous rabbit hole of blackmail, murder, and youth soccer.","poster":"assets/tv-maximum-pleasure-guaranteed-2026-poster.jpg","backdrop":"assets/tv-maximum-pleasure-guaranteed-2026-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-07T21:04:02.8277793Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":285404,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":93,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.799,"tmdbVotes":92}},{"id":"tv-minx-2022","title":"Minx","year":2022,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":6.833,"criticRating":null,"genres":["Comedy","Drama"],"overview":"An earnest young feminist joins forces with a low-rent publisher to make the world's first erotic magazine for women.","poster":"assets/tv-minx-2022-poster.jpg","backdrop":"assets/tv-minx-2022-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0653613Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":118303,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":93,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.9,"tmdbVotes":123}},{"id":"tv-offspring-2010","title":"Offspring","year":2010,"type":"tv","runtimeSeconds":3600,"seasonCount":7,"communityRating":6.9,"criticRating":null,"genres":["Drama"],"overview":"An exuberant drama set in Melbourne's Fitzroy, centering on Nina Proudman and her struggle to deal with her fabulously messy family, her hunt for a decent love life and her tendency to overthink and fly off into fantasy.","poster":"assets/tv-offspring-2010-poster.jpg","backdrop":"assets/tv-offspring-2010-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0664581Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":33155,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.9,"tmdbVotes":27}},{"id":"tv-only-murders-in-the-building-2021","title":"Only Murders in the Building","year":2021,"type":"tv","runtimeSeconds":null,"seasonCount":5,"communityRating":8.398,"criticRating":null,"genres":["Comedy","Mystery","Crime"],"overview":"Three strangers share an obsession with true crime and suddenly find themselves wrapped up in one.","poster":"assets/tv-only-murders-in-the-building-2021-poster.jpg","backdrop":"assets/tv-only-murders-in-the-building-2021-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-11-04T20:25:58.2163301Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":107113,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":95,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.398,"tmdbVotes":2333}},{"id":"tv-outlander-blood-of-my-blood-2025","title":"Outlander: Blood of My Blood","year":2025,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":8.542,"criticRating":null,"genres":["Drama"],"overview":"From the battlefields of World War I to the rugged Highlands of 18th century Scotland, two fated couples must defy the forces that seek to tear them apart, unfolding in surprising and unforeseen ways in this romantic\u2026","poster":"assets/tv-outlander-blood-of-my-blood-2025-poster.jpg","backdrop":"assets/tv-outlander-blood-of-my-blood-2025-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0691373Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":207484,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":94,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.738,"tmdbVotes":124}},{"id":"tv-rivals-2024","title":"Rivals","year":2024,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":7.44,"criticRating":null,"genres":["Drama"],"overview":"It is 1986 and Britain is booming. \"Rivals\" dives headfirst into the cutthroat world of TV where hair-dos are big and ambitions are even bigger. Deals are brokered in boardrooms, as well as bedrooms. Nobody can be\u2026","poster":"assets/tv-rivals-2024-poster.jpg","backdrop":"assets/tv-rivals-2024-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0645815Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":208921,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":96,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.4,"tmdbVotes":93}},{"id":"tv-rooster-2026","title":"Rooster","year":2026,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":7.431,"criticRating":null,"genres":["Comedy"],"overview":"On a college campus, an author navigates a complicated relationship with his daughter.","poster":"assets/tv-rooster-2026-poster.jpg","backdrop":"assets/tv-rooster-2026-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.063389Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":254953,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":88,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.423,"tmdbVotes":144}},{"id":"tv-sex-and-the-city-1998","title":"Sex and the City","year":1998,"type":"tv","runtimeSeconds":null,"seasonCount":6,"communityRating":7.365,"criticRating":null,"genres":["Drama","Comedy"],"overview":"Based on the bestselling book by Candace Bushnell, Sex and the City tells the story of four best friends, all single and in their late thirties, as they pursue their careers and talk about their sex lives, all while\u2026","poster":"assets/tv-sex-and-the-city-1998-poster.jpg","backdrop":"assets/tv-sex-and-the-city-1998-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0679324Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":105,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":70,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.351,"tmdbVotes":2220}},{"id":"tv-skymed-2022","title":"SkyMed","year":2022,"type":"tv","runtimeSeconds":2640,"seasonCount":4,"communityRating":6.665,"criticRating":null,"genres":["Drama"],"overview":"Life, death and drama at 20,000 feet. The series weaves together intense character journeys and high-stakes medical rescues, as we follow the triumphs, heartbreaks and tribulations of budding nurses and pilots flying\u2026","poster":"assets/tv-skymed-2022-poster.jpg","backdrop":"assets/tv-skymed-2022-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-22T19:44:29.2431354Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":133908,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.699,"tmdbVotes":98}},{"id":"tv-so-you-think-you-can-dance-2008","title":"So You Think You Can Dance","year":2008,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":9.8,"criticRating":null,"genres":["Family","Reality"],"overview":"So You Think You Can Dance is a joint Belgian-Dutch dance competition show broadcast on RTL 5 and vtm television stations. The first season was broadcast only in the Netherlands, whereas starting with season 2, the\u2026","poster":"assets/tv-so-you-think-you-can-dance-2008-poster.jpg","backdrop":"assets/tv-so-you-think-you-can-dance-2008-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-23T11:11:35.4124418Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":40231,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":9.8,"tmdbVotes":4}},{"id":"tv-the-white-lotus-2021","title":"The White Lotus","year":2021,"type":"tv","runtimeSeconds":null,"seasonCount":3,"communityRating":7.597,"criticRating":null,"genres":["Comedy","Drama","Mystery"],"overview":"Follow the exploits of various guests and employees at an exclusive tropical resort over the span of a week as with each passing day, a darker complexity emerges in these picture-perfect travelers, the hotel\u2019s\u2026","poster":"assets/tv-the-white-lotus-2021-poster.jpg","backdrop":"assets/tv-the-white-lotus-2021-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-20T02:45:52.8742674Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":111803,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":90,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.599,"tmdbVotes":1604}},{"id":"tv-yellowjackets-2021","title":"Yellowjackets","year":2021,"type":"tv","runtimeSeconds":null,"seasonCount":3,"communityRating":7.431,"criticRating":null,"genres":["Drama","Mystery"],"overview":"This equal parts survival epic, psychological horror story and coming-of-age drama tells the saga of a team of wildly talented high school girls soccer players who become the (un)lucky survivors of a plane crash deep\u2026","poster":"assets/tv-yellowjackets-2021-poster.jpg","backdrop":"assets/tv-yellowjackets-2021-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-11-04T20:31:47.4592756Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":117488,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":92,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.431,"tmdbVotes":1070}}],"anime":[],"resume":[{"id":"episode-sex-and-the-country-2001-s4e9","title":"Sex and the Country","year":2001,"type":"episode","runtimeSeconds":1751,"seasonCount":null,"communityRating":5.9,"criticRating":null,"genres":["Comedy","Drama","Romance"],"overview":"Carrie is dragged to Aidan's country home in Suffern, New York. Charlotte visits the MacDougal \"compound\" in Connecticut. Miranda yells at Steve when he tells her he has testicular cancer but has no clue about his\u2026","poster":"assets/episode-sex-and-the-country-2001-s4e9-poster.jpg","backdrop":"assets/episode-sex-and-the-country-2001-s4e9-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":96.08,"progress":0.0549,"addedAt":"2026-07-17T10:53:15.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"Sex and the City","seasonNumber":4,"episodeNumber":9,"artwork":{"posterKind":"poster","backdropKind":"backdrop"}}],"nextUp":[{"id":"episode-what-more-do-i-need-2008-s5e7","title":"What More Do I Need?","year":2008,"type":"episode","runtimeSeconds":2521,"seasonCount":null,"communityRating":8,"criticRating":null,"genres":["Comedy","Drama","Mystery"],"overview":"Lynette and Tom uncover the unsettling truth about son Porter. Gabrielle suspects Carlos' best client, Virginia, has ulterior motives. Bree's moment of weakness could bring her great embarrassment and shame.\u2026","poster":"assets/episode-what-more-do-i-need-2008-s5e7-poster.jpg","backdrop":"assets/episode-what-more-do-i-need-2008-s5e7-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-29T14:37:28.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"Desperate Housewives","seasonNumber":5,"episodeNumber":7,"artwork":{"posterKind":"center_crop","backdropKind":"backdrop"}},{"id":"episode-new-day-2021-s1e2","title":"New Day","year":2021,"type":"episode","runtimeSeconds":3445,"seasonCount":null,"communityRating":7.143,"criticRating":null,"genres":["Comedy","Drama"],"overview":"A cautiously optimistic Belinda walks a fine line with Tanya, while Armond brainstorms ways to deal with Shane. After her husband belittles her work, Rachel approaches Nicole for advice. Paula and Olivia lose track\u2026","poster":"assets/episode-new-day-2021-s1e2-poster.jpg","backdrop":"assets/episode-new-day-2021-s1e2-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-19T22:18:57.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"The White Lotus","seasonNumber":1,"episodeNumber":2,"artwork":{"posterKind":"poster","backdropKind":"backdrop"}},{"id":"episode-the-uncomfortability-2010-s1e2","title":"The Uncomfortability","year":2010,"type":"episode","runtimeSeconds":2687,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Comedy","Drama"],"overview":"Nina's insecurities are revealed when a patient poses an awkward request. Meanwhile Geraldine decides to try online dating, and Jimmy is an unexpected saviour to Cherie and Darcy.","poster":"assets/episode-the-uncomfortability-2010-s1e2-poster.jpg","backdrop":"assets/episode-the-uncomfortability-2010-s1e2-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T11:47:42.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"Offspring","seasonNumber":1,"episodeNumber":2,"artwork":{"posterKind":"poster","backdropKind":"backdrop"}},{"id":"episode-episode-2-2016-s1e2","title":"Episode 2","year":2016,"type":"episode","runtimeSeconds":2766,"seasonCount":null,"communityRating":8.3,"criticRating":null,"genres":["Biography","Comedy","Drama"],"overview":"Larry falls dangerously ill, and it falls to Theo and his neighbour Sven to put their rudimentary medical skills to the task of saving his life. The family's money worries continue, but Spiros brings them good news\u2026","poster":"assets/episode-episode-2-2016-s1e2-poster.jpg","backdrop":"assets/episode-episode-2-2016-s1e2-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-31T07:29:17.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"The Durrells","seasonNumber":1,"episodeNumber":2,"artwork":{"posterKind":"poster","backdropKind":"backdrop"}},{"id":"episode-remembrance-day-2026-s2e1","title":"Remembrance Day","year":2026,"type":"episode","runtimeSeconds":3822,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Fantasy","Romance"],"overview":"The fiery crosses have been lit across the Highlands; lovers must part, as the call to arms brings friends and enemies home and the Jacobite Rebellion begins in earnest.","poster":"assets/episode-remembrance-day-2026-s2e1-poster.jpg","backdrop":"assets/episode-remembrance-day-2026-s2e1-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-19T03:50:07.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"Outlander: Blood of My Blood","seasonNumber":2,"episodeNumber":1,"artwork":{"posterKind":"poster","backdropKind":"backdrop"}},{"id":"episode-one-of-us-2024-s1e7","title":"One of Us","year":2024,"type":"episode","runtimeSeconds":2555,"seasonCount":null,"communityRating":7.7,"criticRating":null,"genres":[],"overview":"Morgan agrees to show Ava around the LAPD, but things quickly take a dangerous turn when the precinct is held hostage by the friends of a recently convicted man. Can Morgan and the detectives outsmart their captors\u2026","poster":"assets/episode-one-of-us-2024-s1e7-poster.jpg","backdrop":"assets/episode-one-of-us-2024-s1e7-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T13:57:22.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"High Potential","seasonNumber":1,"episodeNumber":7,"artwork":{"posterKind":"poster","backdropKind":"backdrop"}},{"id":"episode-the-breakup-part-2-2001-s1e17","title":"The Breakup, Part 2","year":2001,"type":"episode","runtimeSeconds":2669,"seasonCount":null,"communityRating":7.4,"criticRating":null,"genres":["Comedy","Drama"],"overview":"After recent events, Rory keeps busy, refusing to give in to self-pity. Meanwhile, Stars Hollow's residents rally around her, much to her dismay.","poster":"assets/episode-the-breakup-part-2-2001-s1e17-poster.jpg","backdrop":"assets/episode-the-breakup-part-2-2001-s1e17-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T11:28:05.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"Gilmore Girls","seasonNumber":1,"episodeNumber":17,"artwork":{"posterKind":"poster","backdropKind":"backdrop"}},{"id":"episode-i-heart-ny-2002-s4e18","title":"I Heart NY","year":2002,"type":"episode","runtimeSeconds":1905,"seasonCount":null,"communityRating":6.667,"criticRating":null,"genres":["Comedy","Drama","Romance"],"overview":"Carrie is shocked to find out that Big is moving to Napa, California and plans to give him a New York send-off. Charlotte begins dating another recent divorc\u00e9. Miranda prepares for the new baby as her delivery date\u2026","poster":"assets/episode-i-heart-ny-2002-s4e18-poster.jpg","backdrop":"assets/episode-i-heart-ny-2002-s4e18-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T12:35:14.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"Sex and the City","seasonNumber":4,"episodeNumber":18,"artwork":{"posterKind":"poster","backdropKind":"backdrop"}}],"recentlyAdded":[{"id":"tv-yellowjackets-2021","title":"Yellowjackets","year":2021,"type":"tv","runtimeSeconds":null,"seasonCount":3,"communityRating":7.431,"criticRating":null,"genres":["Drama","Mystery"],"overview":"This equal parts survival epic, psychological horror story and coming-of-age drama tells the saga of a team of wildly talented high school girls soccer players who become the (un)lucky survivors of a plane crash deep\u2026","poster":"assets/tv-yellowjackets-2021-poster.jpg","backdrop":"assets/tv-yellowjackets-2021-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-11-04T20:31:47.4592756Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":117488,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":92,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.431,"tmdbVotes":1070}},{"id":"tv-only-murders-in-the-building-2021","title":"Only Murders in the Building","year":2021,"type":"tv","runtimeSeconds":null,"seasonCount":5,"communityRating":8.398,"criticRating":null,"genres":["Comedy","Mystery","Crime"],"overview":"Three strangers share an obsession with true crime and suddenly find themselves wrapped up in one.","poster":"assets/tv-only-murders-in-the-building-2021-poster.jpg","backdrop":"assets/tv-only-murders-in-the-building-2021-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-11-04T20:25:58.2163301Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":107113,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":95,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.398,"tmdbVotes":2333}},{"id":"tv-big-boys-2022","title":"Big Boys","year":2022,"type":"tv","runtimeSeconds":1440,"seasonCount":3,"communityRating":7.6,"criticRating":null,"genres":["Comedy","Drama"],"overview":"Two boys from very different ends of the 'spectrum of masculinity' become best friends at Brent University freshers' week; in their first year of uni, they explore, experiment and try to discover themselves, helping\u2026","poster":"assets/tv-big-boys-2022-poster.jpg","backdrop":"assets/tv-big-boys-2022-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-11-04T20:25:58.2156837Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":202851,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.6,"tmdbVotes":49}},{"id":"tv-all-creatures-great-small-2020","title":"All Creatures Great & Small","year":2020,"type":"tv","runtimeSeconds":3000,"seasonCount":7,"communityRating":8.2,"criticRating":null,"genres":["Drama","Comedy"],"overview":"The heartwarming and humorous adventures of a young country vet in the Yorkshire Dales in the 1930s. A remake of the 1978 series.","poster":"assets/tv-all-creatures-great-small-2020-poster.jpg","backdrop":"assets/tv-all-creatures-great-small-2020-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-11-04T20:13:03.4266156Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":108255,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":99,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.2,"tmdbVotes":168}},{"id":"movie-the-killing-of-a-sacred-deer-2017","title":"The Killing of a Sacred Deer","year":2017,"type":"movie","runtimeSeconds":7262,"seasonCount":null,"communityRating":7.003,"criticRating":79,"genres":["Drama","Thriller","Mystery"],"overview":"Dr. Steven Murphy is a renowned cardiovascular surgeon who presides over a spotless household with his wife and two children. Lurking at the margins of his idyllic suburban existence is Martin, a fatherless teen who\u2026","poster":"assets/movie-the-killing-of-a-sacred-deer-2017-poster.jpg","backdrop":"assets/movie-the-killing-of-a-sacred-deer-2017-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-22T21:49:26.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":399057,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":79,"rtCriticsLabel":"Certified Fresh","rtAudience":63,"rtAudienceLabel":"Upright","imdb":7,"imdbVotes":219488,"tmdb":7.001,"tmdbVotes":4640}},{"id":"tv-derry-girls-2018","title":"Derry Girls","year":2018,"type":"tv","runtimeSeconds":1380,"seasonCount":3,"communityRating":8.144,"criticRating":null,"genres":["Comedy","Drama"],"overview":"Amidst the political conflict of Northern Ireland in the 1990s, five secondary school students square off with the universal challenges of being a teenager.","poster":"assets/tv-derry-girls-2018-poster.jpg","backdrop":"assets/tv-derry-girls-2018-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-02T20:01:55.8955537Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":76148,"artwork":{"posterKind":"center_crop","backdropKind":"backdrop"},"ratings":{"rtCritics":99,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.138,"tmdbVotes":454}},{"id":"tv-so-you-think-you-can-dance-2008","title":"So You Think You Can Dance","year":2008,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":9.8,"criticRating":null,"genres":["Family","Reality"],"overview":"So You Think You Can Dance is a joint Belgian-Dutch dance competition show broadcast on RTL 5 and vtm television stations. The first season was broadcast only in the Netherlands, whereas starting with season 2, the\u2026","poster":"assets/tv-so-you-think-you-can-dance-2008-poster.jpg","backdrop":"assets/tv-so-you-think-you-can-dance-2008-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-23T11:11:35.4124418Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":40231,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":9.8,"tmdbVotes":4}},{"id":"tv-hellcats-2010","title":"Hellcats","year":2010,"type":"tv","runtimeSeconds":2460,"seasonCount":1,"communityRating":7.5,"criticRating":null,"genres":["Drama"],"overview":"Pre-law student Marti Perkins' world is flipped upside down when she loses her scholarship, and realizes the only way she can stay in school is by reigniting her dormant teen gymnastic skills to win a place on Lancer\u2026","poster":"assets/tv-hellcats-2010-poster.jpg","backdrop":"assets/tv-hellcats-2010-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-22T20:39:02.7719318Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":32504,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":65,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.5,"tmdbVotes":116}},{"id":"tv-skymed-2022","title":"SkyMed","year":2022,"type":"tv","runtimeSeconds":2640,"seasonCount":4,"communityRating":6.665,"criticRating":null,"genres":["Drama"],"overview":"Life, death and drama at 20,000 feet. The series weaves together intense character journeys and high-stakes medical rescues, as we follow the triumphs, heartbreaks and tribulations of budding nurses and pilots flying\u2026","poster":"assets/tv-skymed-2022-poster.jpg","backdrop":"assets/tv-skymed-2022-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-22T19:44:29.2431354Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":133908,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.699,"tmdbVotes":98}},{"id":"tv-love-is-blind-2020","title":"Love Is Blind","year":2020,"type":"tv","runtimeSeconds":null,"seasonCount":11,"communityRating":6.261,"criticRating":null,"genres":["Reality"],"overview":"Nick and Vanessa Lachey host this social experiment where single men and women look for love and get engaged, all before meeting in person.","poster":"assets/tv-love-is-blind-2020-poster.jpg","backdrop":"assets/tv-love-is-blind-2020-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-22T17:11:08.2447226Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":99353,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":66,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.233,"tmdbVotes":118}},{"id":"tv-the-hunting-wives-2025","title":"The Hunting Wives","year":2025,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":6.932,"criticRating":null,"genres":["Drama","Mystery"],"overview":"Sophie trades New England for East Texas and falls into a wealthy socialite's magnetic orbit \u2014 where a clique of housewives hide deadly secrets.","poster":"assets/tv-the-hunting-wives-2025-poster.jpg","backdrop":"assets/tv-the-hunting-wives-2025-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-20T19:42:46.3227892Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":244447,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":81,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.964,"tmdbVotes":112}},{"id":"tv-the-white-lotus-2021","title":"The White Lotus","year":2021,"type":"tv","runtimeSeconds":null,"seasonCount":3,"communityRating":7.597,"criticRating":null,"genres":["Comedy","Drama","Mystery"],"overview":"Follow the exploits of various guests and employees at an exclusive tropical resort over the span of a week as with each passing day, a darker complexity emerges in these picture-perfect travelers, the hotel\u2019s\u2026","poster":"assets/tv-the-white-lotus-2021-poster.jpg","backdrop":"assets/tv-the-white-lotus-2021-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-20T02:45:52.8742674Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":111803,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":90,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.599,"tmdbVotes":1604}}],"discover":[{"id":"movie-across-the-hall-2009","title":"Across the Hall","year":2009,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Thriller","Mystery"],"overview":"Convinced that his fiancee is cheating on him, a man follows her to a hotel and calls his best friend to help him avoid a calamity.","poster":"assets/movie-across-the-hall-2009-poster.jpg","backdrop":"assets/movie-across-the-hall-2009-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":21469,"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":39,"rtAudienceLabel":"Spilled","imdb":5.8,"imdbVotes":5130,"tmdb":6,"tmdbVotes":129}},{"id":"movie-addicted-2014","title":"Addicted","year":2014,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Thriller"],"overview":"A gallerist risks her family and flourishing career when she enters into an affair with a talented painter and slowly loses control of her life.","poster":"assets/movie-addicted-2014-poster.jpg","backdrop":"assets/movie-addicted-2014-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":235271,"ratings":{"rtCritics":7,"rtCriticsLabel":"Rotten","rtAudience":51,"rtAudienceLabel":"Spilled","imdb":5,"imdbVotes":13131,"tmdb":5.928,"tmdbVotes":466}},{"id":"movie-adulterers-2016","title":"Adulterers","year":2016,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Thriller","Drama"],"overview":"On a steamy New Orleans afternoon, Sam Deuprey decides to surprise his beautiful wife, Ashley, for their anniversary and comes home early. But Ashley is not alone in the bedroom. She and her lover, Damien are about\u2026","poster":"assets/movie-adulterers-2016-poster.jpg","backdrop":"assets/movie-adulterers-2016-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":376004,"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":37,"rtAudienceLabel":"Spilled","imdb":5.1,"imdbVotes":2144,"tmdb":6.2,"tmdbVotes":116}},{"id":"movie-alone-with-her-2006","title":"Alone With Her","year":2006,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Crime","Drama","Thriller"],"overview":"The harrowing story of a disturbed young man's attempts to win the affections of an unsuspecting young woman. When Doug first sees Amy, he instantly falls for her and begins to watch her every move, going so far as\u2026","poster":"assets/movie-alone-with-her-2006-poster.jpg","backdrop":"assets/movie-alone-with-her-2006-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":18206,"ratings":{"rtCritics":70,"rtCriticsLabel":"Fresh","rtAudience":46,"rtAudienceLabel":"Spilled","imdb":6,"imdbVotes":4359,"tmdb":5.9,"tmdbVotes":94}},{"id":"movie-awake-2007","title":"Awake","year":2007,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Thriller","Crime","Mystery"],"overview":"While undergoing heart surgery, a man experiences a phenomenon called \u2018anesthetic awareness\u2019, which leaves him awake but paralyzed throughout the operation. As various obstacles present themselves, his wife must make\u2026","poster":"assets/movie-awake-2007-poster.jpg","backdrop":"assets/movie-awake-2007-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":13483,"ratings":{"rtCritics":23,"rtCriticsLabel":"Rotten","rtAudience":55,"rtAudienceLabel":"Spilled","imdb":6.5,"imdbVotes":89389,"tmdb":6.586,"tmdbVotes":1649}},{"id":"movie-black-bear-2020","title":"Black Bear","year":2020,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Thriller"],"overview":"At a remote lake house in the Adirondack Mountains, a couple entertains an out-of-town guest looking for inspiration in her filmmaking. The group quickly falls into a calculated game of desire, manipulation, and\u2026","poster":"assets/movie-black-bear-2020-poster.jpg","backdrop":"assets/movie-black-bear-2020-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":624788,"ratings":{"rtCritics":89,"rtCriticsLabel":"Certified Fresh","rtAudience":64,"rtAudienceLabel":"Upright","imdb":6.5,"imdbVotes":18408,"tmdb":6.337,"tmdbVotes":315}},{"id":"movie-butterfly-on-a-wheel-2007","title":"Butterfly on a Wheel","year":2007,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Crime","Drama","Thriller"],"overview":"A sociopathic kidnapper methodically pushes a desperate pair of parents to their absolute breaking point.","poster":"assets/movie-butterfly-on-a-wheel-2007-poster.jpg","backdrop":"assets/movie-butterfly-on-a-wheel-2007-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":13250,"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":61,"rtAudienceLabel":"Upright","imdb":6.6,"imdbVotes":35409,"tmdb":6.457,"tmdbVotes":595}},{"id":"movie-careful-what-you-wish-for-2015","title":"Careful What You Wish For","year":2015,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Thriller"],"overview":"A guy gets more than he bargained for after entering into an affair with the wife of an investment banker. Soon, a suspicious death and substantial life insurance policy embroil him in a scandal.","poster":"assets/movie-careful-what-you-wish-for-2015-poster.jpg","backdrop":"assets/movie-careful-what-you-wish-for-2015-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":317744,"ratings":{"rtCritics":17,"rtCriticsLabel":"Rotten","rtAudience":61,"rtAudienceLabel":"Upright","imdb":5.6,"imdbVotes":9452,"tmdb":6.129,"tmdbVotes":446}},{"id":"movie-crime-of-passion-1956","title":"Crime of Passion","year":1956,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Crime","Thriller"],"overview":"Kathy leaves the newspaper business to marry homicide detective Bill, but is frustrated by his lack of ambition and the banality of life in the suburbs. Her drive to advance Bill's career soon takes her down a\u2026","poster":"assets/movie-crime-of-passion-1956-poster.jpg","backdrop":"assets/movie-crime-of-passion-1956-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"center_crop","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":1920,"ratings":{"rtCritics":80,"rtCriticsLabel":"Fresh","rtAudience":34,"rtAudienceLabel":"Spilled","imdb":6.4,"imdbVotes":3750,"tmdb":6.1,"tmdbVotes":57}},{"id":"movie-deep-water-2022","title":"Deep Water","year":2022,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Mystery","Thriller"],"overview":"A well-to-do husband who allows his wife to have affairs in order to avoid a divorce becomes a prime suspect in the disappearance of her lovers.","poster":"assets/movie-deep-water-2022-poster.jpg","backdrop":"assets/movie-deep-water-2022-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":619979,"ratings":{"rtCritics":35,"rtCriticsLabel":"Rotten","rtAudience":25,"rtAudienceLabel":"Spilled","imdb":5.5,"imdbVotes":74098,"tmdb":5.834,"tmdbVotes":1755}},{"id":"movie-derailed-2005","title":"Derailed","year":2005,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Thriller"],"overview":"When two married business executives having an affair are blackmailed by a violent criminal, they are forced to turn the tables on him to save their families.","poster":"assets/movie-derailed-2005-poster.jpg","backdrop":"assets/movie-derailed-2005-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":8999,"ratings":{"rtCritics":20,"rtCriticsLabel":"Rotten","rtAudience":58,"rtAudienceLabel":"Spilled","imdb":6.6,"imdbVotes":79563,"tmdb":6.405,"tmdbVotes":1193}},{"id":"movie-die-my-love-2025","title":"Die My Love","year":2025,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama"],"overview":"After inheriting a remote Montana house, Jackson moves there from New York with his partner Grace, and the couple soon welcome a child. As Jackson becomes increasingly absent and rural isolation sets in, Grace\u2026","poster":"assets/movie-die-my-love-2025-poster.jpg","backdrop":"assets/movie-die-my-love-2025-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":1033148,"ratings":{"rtCritics":74,"rtCriticsLabel":"Certified Fresh","rtAudience":45,"rtAudienceLabel":"Spilled","imdb":6,"imdbVotes":50664,"tmdb":6.1,"tmdbVotes":683}},{"id":"movie-dream-house-2011","title":"Dream House","year":2011,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Mystery","Drama","Thriller"],"overview":"Publisher Will Atenton quits a lucrative job in New York to relocate his wife, Libby, and their daughters to a quaint town in New England. However, as they settle into their home the Atentons discover that a woman\u2026","poster":"assets/movie-dream-house-2011-poster.jpg","backdrop":"assets/movie-dream-house-2011-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":69668,"ratings":{"rtCritics":7,"rtCriticsLabel":"Rotten","rtAudience":36,"rtAudienceLabel":"Spilled","imdb":6,"imdbVotes":71386,"tmdb":6.212,"tmdbVotes":1480}},{"id":"movie-dream-lover-1994","title":"Dream Lover","year":1994,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Mystery","Thriller"],"overview":"Not long after they cross paths at an art gallery, architect Ray Reardon and hypnotically sensual Lena are married with children. But as strange incidents occur, Ray begins to realize he may not really know the woman\u2026","poster":"assets/movie-dream-lover-1994-poster.jpg","backdrop":"assets/movie-dream-lover-1994-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":18190,"ratings":{"rtCritics":57,"rtCriticsLabel":"Rotten","rtAudience":38,"rtAudienceLabel":"Spilled","imdb":6.2,"imdbVotes":7865,"tmdb":6.844,"tmdbVotes":167}},{"id":"movie-drop-2025","title":"Drop","year":2025,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Mystery","Thriller"],"overview":"Violet, a widowed mother on her first date in years, arrives at an upscale restaurant where she is relieved that her date, Henry, is more charming and handsome than she expected. But their chemistry begins to curdle\u2026","poster":"assets/movie-drop-2025-poster.jpg","backdrop":"assets/movie-drop-2025-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":1249213,"ratings":{"rtCritics":83,"rtCriticsLabel":"Certified Fresh","rtAudience":79,"rtAudienceLabel":"Upright","imdb":6.1,"imdbVotes":61018,"tmdb":6.275,"tmdbVotes":1023}},{"id":"movie-eastern-promises-2007","title":"Eastern Promises","year":2007,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Thriller","Crime","Mystery"],"overview":"A Russian teenager living in London dies during childbirth but leaves clues in her diary that could tie her child to a rape involving a violent Russian mob family.","poster":"assets/movie-eastern-promises-2007-poster.jpg","backdrop":"assets/movie-eastern-promises-2007-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":2252,"ratings":{"rtCritics":89,"rtCriticsLabel":"Certified Fresh","rtAudience":83,"rtAudienceLabel":"Upright","imdb":7.6,"imdbVotes":281015,"tmdb":7.349,"tmdbVotes":3900}},{"id":"movie-faces-1968","title":"Faces","year":1968,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama"],"overview":"Middle-aged suburban husband Richard abruptly tells his wife, Maria, that he wants a divorce. As Richard takes up with a younger woman, Maria enjoys a night on the town with her friends and meets a younger man. As\u2026","poster":"assets/movie-faces-1968-poster.jpg","backdrop":"assets/movie-faces-1968-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"center_crop","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":753,"ratings":{"rtCritics":83,"rtCriticsLabel":"Fresh","rtAudience":86,"rtAudienceLabel":"Upright","imdb":7.4,"imdbVotes":12950,"tmdb":7.093,"tmdbVotes":227}},{"id":"movie-fatale-2020","title":"Fatale","year":2020,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Thriller"],"overview":"After a wild one-night stand, successful sports agent Derrick Tyler watches his perfect life slowly disappear when he discovers the sexy and mysterious woman he risked everything for is determined police detective\u2026","poster":"assets/movie-fatale-2020-poster.jpg","backdrop":"assets/movie-fatale-2020-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":549514,"ratings":{"rtCritics":46,"rtCriticsLabel":"Rotten","rtAudience":87,"rtAudienceLabel":"Upright","imdb":5.5,"imdbVotes":16392,"tmdb":6,"tmdbVotes":401}},{"id":"tv-56-days-2026","title":"56 Days","year":2026,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Crime","Mystery"],"overview":"When an unidentified body is found in a luxury apartment linked to Oliver Kennedy and his girlfriend Ciara Wyse, Detectives Lee Reardon and Karl Connolly reconstruct the couple's deadly romance across the past 56 days.","poster":"assets/tv-56-days-2026-poster.jpg","backdrop":"assets/tv-56-days-2026-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":241372,"ratings":{"rtCritics":60,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.388,"tmdbVotes":245}},{"id":"tv-90-day-fiance-before-the-90-days-2017","title":"90 Day Fianc\u00e9: Before the 90 Days","year":2017,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Reality"],"overview":"Follow couples who have an existing relationship online, but haven't met in person. We'll experience their journey as they travel to the other's foreign country for the first time in an attempt to establish an\u2026","poster":"assets/tv-90-day-fiance-before-the-90-days-2017-poster.jpg","backdrop":"assets/tv-90-day-fiance-before-the-90-days-2017-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":73319,"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.5,"tmdbVotes":45}},{"id":"tv-90-day-fiance-the-other-way-2019","title":"90 Day Fianc\u00e9: The Other Way","year":2019,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Reality"],"overview":"Americans move to a foreign country all in the name of love. Will uprooting their lives in the United States pay off, or will they be packing up and moving back to America brokenhearted?","poster":"assets/tv-90-day-fiance-the-other-way-2019-poster.jpg","backdrop":"assets/tv-90-day-fiance-the-other-way-2019-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":90046,"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.8,"tmdbVotes":34}},{"id":"tv-absolutely-fabulous-1992","title":"Absolutely Fabulous","year":1992,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Comedy"],"overview":"Set in the world of fashion and PR, immature fun-loving mother Edina Monsoon and her best friend Patsy drive Eddie's sensible daughter, Saffron, up the wall with their constant drug abuse and outrageous selfishness.\u2026","poster":"assets/tv-absolutely-fabulous-1992-poster.jpg","backdrop":"assets/tv-absolutely-fabulous-1992-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":4493,"ratings":{"rtCritics":96,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.6,"tmdbVotes":198}},{"id":"tv-the-afterparty-2022","title":"The Afterparty","year":2022,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Mystery","Comedy","Crime"],"overview":"Nothing is as it seems in this hilarious murder mystery where each suspect's story is told through a different film genre.","poster":"assets/tv-the-afterparty-2022-poster.jpg","backdrop":"assets/tv-the-afterparty-2022-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":106454,"ratings":{"rtCritics":92,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.071,"tmdbVotes":245}},{"id":"tv-agatha-christie-s-marple-2004","title":"Agatha Christie's Marple","year":2004,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Crime","Mystery"],"overview":"The adventures of Miss Jane Marple, an elderly spinster living in the quiet little village of St Mary Mead. During her many visits to friends and relatives in other villages, Miss Marple often stumbles upon\u2026","poster":"assets/tv-agatha-christie-s-marple-2004-poster.jpg","backdrop":"assets/tv-agatha-christie-s-marple-2004-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":6127,"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.9,"tmdbVotes":152}},{"id":"tv-all-american-homecoming-2022","title":"All American: Homecoming","year":2022,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama"],"overview":"Follow the journeys of Simone Hicks, a tennis hopeful from Beverly Hills, and elite baseball player Damon Sims from Chicago, as they navigate life at the prestigious HBCU Bringston University.","poster":"assets/tv-all-american-homecoming-2022-poster.jpg","backdrop":"assets/tv-all-american-homecoming-2022-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":153723,"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.3,"tmdbVotes":70}},{"id":"tv-and-just-like-that-2021","title":"And Just Like That\u2026","year":2021,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Comedy","Drama"],"overview":"This new chapter of \u201cSex and the City\u201d follows Carrie, Miranda and Charlotte as they navigate the journey from the complicated reality of life and friendship in their 30s to the even more complicated reality of life\u2026","poster":"assets/tv-and-just-like-that-2021-poster.jpg","backdrop":"assets/tv-and-just-like-that-2021-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":116450,"ratings":{"rtCritics":52,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.211,"tmdbVotes":556}},{"id":"tv-anne-with-an-e-2017","title":"Anne with an E","year":2017,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Family"],"overview":"A coming-of-age story about an outsider who, against all odds and numerous challenges, fights for love and acceptance and for her place in the world. The series centers on a young orphaned girl in the late 1890s,\u2026","poster":"assets/tv-anne-with-an-e-2017-poster.jpg","backdrop":"assets/tv-anne-with-an-e-2017-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":70785,"ratings":{"rtCritics":63,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.7,"tmdbVotes":5019}},{"id":"tv-awkward-2011","title":"Awkward.","year":2011,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Comedy","Drama"],"overview":"An irreverent look at the conflict, chaos and humor that defines teenage life through the eyes of 15-year-old Jenna Hamilton whose life begins to change when a simple accident becomes an epic misunderstanding and is\u2026","poster":"assets/tv-awkward-2011-poster.jpg","backdrop":"assets/tv-awkward-2011-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":39859,"ratings":{"rtCritics":78,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.4,"tmdbVotes":427}},{"id":"tv-the-baby-sitters-club-2020","title":"The Baby-Sitters Club","year":2020,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Kids","Drama"],"overview":"In this contemporary take on the beloved book series, five best friends launch a baby-sitting business that's big on fun and adventure.","poster":"assets/tv-the-baby-sitters-club-2020-poster.jpg","backdrop":"assets/tv-the-baby-sitters-club-2020-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":100412,"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.9,"tmdbVotes":506}},{"id":"tv-ballers-2015","title":"Ballers","year":2015,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Comedy"],"overview":"Looking at the lives of former and current football players, the show follows former superstar Spencer Strasmore as he gets his life on track in retirement while mentoring other current and former players through the\u2026","poster":"assets/tv-ballers-2015-poster.jpg","backdrop":"assets/tv-ballers-2015-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":62704,"ratings":{"rtCritics":72,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.809,"tmdbVotes":820}},{"id":"tv-baretta-1975","title":"Baretta","year":1975,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Crime","Drama","Mystery"],"overview":"Baretta is an American detective television series which ran on ABC from 1975 to 1978. The show was a milder version of a successful 1973\u201374 ABC series, Toma, starring Tony Musante as chameleon-like, real-life New\u2026","poster":"assets/tv-baretta-1975-poster.jpg","backdrop":"assets/tv-baretta-1975-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":3216,"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.5,"tmdbVotes":43}},{"id":"tv-based-on-a-true-story-2023","title":"Based on a True Story","year":2023,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Comedy","Drama"],"overview":"The lives of a realtor, a plumber and a former tennis star unexpectedly collide, exposing America\u2019s obsession with true crime, murder and the slow-close toilet seat.","poster":"assets/tv-based-on-a-true-story-2023-poster.jpg","backdrop":"assets/tv-based-on-a-true-story-2023-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":197373,"ratings":{"rtCritics":79,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7,"tmdbVotes":160}},{"id":"tv-the-beast-in-me-2025","title":"The Beast in Me","year":2025,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Mystery"],"overview":"A famous author is pulled into a twisted mind game with her rich, powerful new neighbor \u2014 who might be a murderer.","poster":"assets/tv-the-beast-in-me-2025-poster.jpg","backdrop":"assets/tv-the-beast-in-me-2025-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":250504,"ratings":{"rtCritics":85,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.072,"tmdbVotes":334}},{"id":"tv-big-city-greens-2018","title":"Big City Greens","year":2018,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Family","Animation","Comedy"],"overview":"The offbeat adventures of 10-year-old Cricket Green, a mischievous and optimistic country boy who moves to the big city with his wildly out of place family \u2013 older sister Tilly, father Bill and Gramma Alice.","poster":"assets/tv-big-city-greens-2018-poster.jpg","backdrop":"assets/tv-big-city-greens-2018-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":80587,"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.555,"tmdbVotes":82}},{"id":"tv-the-bold-type-2017","title":"The Bold Type","year":2017,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Comedy"],"overview":"A glimpse into the outrageous lives of Jane, Kat and Sutton, who are working at the nation's top women's magazine, Scarlet, while navigating their careers, identities and individual voices.","poster":"assets/tv-the-bold-type-2017-poster.jpg","backdrop":"assets/tv-the-bold-type-2017-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":69630,"ratings":{"rtCritics":89,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.7,"tmdbVotes":204}},{"id":"tv-brassic-2019","title":"Brassic","year":2019,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Comedy","Drama","Crime"],"overview":"A group of working-class friends finding unconventional ways to win at life in suburban northern England. These lads have dealt, scammed, bribed and conned their way through adolescence, but now, their dealing and\u2026","poster":"assets/tv-brassic-2019-poster.jpg","backdrop":"assets/tv-brassic-2019-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":92621,"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.336,"tmdbVotes":263}}],"discoverySource":{"state":"materialized_snapshot","rankKnown":false,"selection":"First 18 alphabetically indexed movie stubs and first 18 series stubs, not ranked feed order","observedAt":"2026-11-04T20:42:12.030108+00:00"}},{"key":"shared","name":"Shared","initial":"S","color":"#9be38f","destinations":{"Home":{"kind":"home"},"Movies":{"kind":"library","collection":"movies"},"Shows":{"kind":"library","collection":"shows"},"Discover":{"kind":"discover","collection":"discover"}},"movies":[{"id":"movie-american-gangster-2007","title":"American Gangster","year":2007,"type":"movie","runtimeSeconds":10546,"seasonCount":null,"communityRating":7.595,"criticRating":81,"genres":["Drama","Crime"],"overview":"Loosely based on the criminal career of Frank Lucas, a gangster from La Grange, North Carolina, who smuggled heroin into the United States on American service planes returning from the Vietnam War, before being\u2026","poster":"assets/movie-american-gangster-2007-poster.jpg","backdrop":"assets/movie-american-gangster-2007-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-08-23T10:22:36.0000000Z","lastPlayedAt":"2026-08-30T21:05:39.7952451Z","availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":4982,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":81,"rtCriticsLabel":"Certified Fresh","rtAudience":90,"rtAudienceLabel":"Upright","imdb":7.8,"imdbVotes":495656,"tmdb":7.599,"tmdbVotes":6350}},{"id":"movie-annie-hall-1977","title":"Annie Hall","year":1977,"type":"movie","runtimeSeconds":5604,"seasonCount":null,"communityRating":7.712,"criticRating":97,"genres":["Comedy","Drama","Romance"],"overview":"New York comedian Alvy Singer falls in love with the ditsy Annie Hall.","poster":"assets/movie-annie-hall-1977-poster.jpg","backdrop":"assets/movie-annie-hall-1977-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:24:23.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":703,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":97,"rtCriticsLabel":"Certified Fresh","rtAudience":92,"rtAudienceLabel":"Upright","imdb":7.9,"imdbVotes":293349,"tmdb":7.71,"tmdbVotes":4391}},{"id":"movie-apocalypse-now-1979","title":"Apocalypse Now","year":1979,"type":"movie","runtimeSeconds":8835,"seasonCount":null,"communityRating":8.261,"criticRating":91,"genres":["Drama","War"],"overview":"At the height of the Vietnam war, Captain Benjamin Willard is sent on a dangerous mission that, officially, \"does not exist, nor will it ever exist.\" His goal is to locate - and eliminate - a mysterious Green Beret\u2026","poster":"assets/movie-apocalypse-now-1979-poster.jpg","backdrop":"assets/movie-apocalypse-now-1979-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:22:25.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":28,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":91,"rtCriticsLabel":"Certified Fresh","rtAudience":94,"rtAudienceLabel":"Upright","imdb":8.4,"imdbVotes":781424,"tmdb":8.3,"tmdbVotes":9526}},{"id":"movie-arrival-2016","title":"Arrival","year":2016,"type":"movie","runtimeSeconds":6967,"seasonCount":null,"communityRating":7.636,"criticRating":94,"genres":["Drama","Science Fiction","Mystery"],"overview":"Taking place after alien crafts land around the world, an expert linguist is recruited by the military to determine whether they come in peace or are a threat.","poster":"assets/movie-arrival-2016-poster.jpg","backdrop":"assets/movie-arrival-2016-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-14T19:54:12.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":329865,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":94,"rtCriticsLabel":"Certified Fresh","rtAudience":83,"rtAudienceLabel":"Upright","imdb":7.9,"imdbVotes":883621,"tmdb":7.638,"tmdbVotes":20125}},{"id":"movie-avatar-aang-the-last-airbender-2026","title":"Avatar Aang: The Last Airbender","year":2026,"type":"movie","runtimeSeconds":5930,"seasonCount":null,"communityRating":9.147,"criticRating":90,"genres":["Animation","Adventure","Fantasy"],"overview":"Avatar Aang, the world's last Airbender, learns of an ancient power that could save his culture from extinction. With the help of his friends, he embarks on a global quest to find it before it falls into the wrong\u2026","poster":"assets/movie-avatar-aang-the-last-airbender-2026-poster.jpg","backdrop":"assets/movie-avatar-aang-the-last-airbender-2026-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-25T09:53:09.0000000Z","lastPlayedAt":"2026-08-02T19:22:33.6155383Z","availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":980431,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":90,"rtCriticsLabel":"Certified Fresh","rtAudience":99,"rtAudienceLabel":"Upright","imdb":7.7,"imdbVotes":30792,"tmdb":9,"tmdbVotes":1417}},{"id":"movie-bohemian-rhapsody-2018","title":"Bohemian Rhapsody","year":2018,"type":"movie","runtimeSeconds":8077,"seasonCount":null,"communityRating":7.95,"criticRating":60,"genres":["Music","Drama"],"overview":"Singer Freddie Mercury, guitarist Brian May, drummer Roger Taylor and bass guitarist John Deacon take the music world by storm when they form the rock 'n' roll band Queen in 1970. Hit songs become instant classics.\u2026","poster":"assets/movie-bohemian-rhapsody-2018-poster.jpg","backdrop":"assets/movie-bohemian-rhapsody-2018-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:28:20.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":424694,"artwork":{"posterKind":"center_crop","backdropKind":"backdrop"},"ratings":{"rtCritics":60,"rtCriticsLabel":"Fresh","rtAudience":85,"rtAudienceLabel":"Upright","imdb":7.9,"imdbVotes":655894,"tmdb":7.947,"tmdbVotes":18196}},{"id":"movie-the-boy-and-the-heron-2023","title":"The Boy and the Heron","year":2023,"type":"movie","runtimeSeconds":7437,"seasonCount":null,"communityRating":7.4,"criticRating":96,"genres":["Animation","Fantasy","Drama"],"overview":"While the Second World War rages, the teenage Mahito, haunted by his mother's tragic death, is relocated from Tokyo to the serene rural home of his new stepmother Natsuko, a woman who bears a striking resemblance to\u2026","poster":"assets/movie-the-boy-and-the-heron-2023-poster.jpg","backdrop":"assets/movie-the-boy-and-the-heron-2023-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:25:15.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":508883,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":96,"rtCriticsLabel":"Certified Fresh","rtAudience":88,"rtAudienceLabel":"Upright","imdb":7.3,"imdbVotes":152169,"tmdb":7.387,"tmdbVotes":2893}},{"id":"movie-braveheart-1995","title":"Braveheart","year":1995,"type":"movie","runtimeSeconds":10665,"seasonCount":null,"communityRating":7.945,"criticRating":74,"genres":["Drama","History","War"],"overview":"Enraged at the slaughter of Murron, his new bride and childhood love, Scottish warrior William Wallace slays a platoon of the local English lord's soldiers. This leads the village to revolt and, eventually, the\u2026","poster":"assets/movie-braveheart-1995-poster.jpg","backdrop":"assets/movie-braveheart-1995-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-10T21:24:28.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":197,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":74,"rtCriticsLabel":"Certified Fresh","rtAudience":85,"rtAudienceLabel":"Upright","imdb":8.3,"imdbVotes":1174990,"tmdb":7.947,"tmdbVotes":11584}},{"id":"movie-the-breakfast-club-1985","title":"The Breakfast Club","year":1985,"type":"movie","runtimeSeconds":5833,"seasonCount":null,"communityRating":7.7,"criticRating":87,"genres":["Comedy","Drama"],"overview":"Five high school students from different walks of life endure a Saturday detention under a power-hungry principal. The disparate group includes rebel John, princess Claire, outcast Allison, brainy Brian and Andrew,\u2026","poster":"assets/movie-the-breakfast-club-1985-poster.jpg","backdrop":"assets/movie-the-breakfast-club-1985-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:25:03.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":2108,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":87,"rtCriticsLabel":"Certified Fresh","rtAudience":92,"rtAudienceLabel":"Upright","imdb":7.8,"imdbVotes":478743,"tmdb":7.713,"tmdbVotes":8815}},{"id":"movie-castle-in-the-sky-1986","title":"Castle in the Sky","year":1986,"type":"movie","runtimeSeconds":7474,"seasonCount":null,"communityRating":8,"criticRating":97,"genres":["Adventure","Fantasy","Animation"],"overview":"A young boy and a girl with a magic crystal must race against pirates and foreign agents in a search for a legendary floating castle.","poster":"assets/movie-castle-in-the-sky-1986-poster.jpg","backdrop":"assets/movie-castle-in-the-sky-1986-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:23:09.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":10515,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":96,"rtCriticsLabel":"Fresh","rtAudience":91,"rtAudienceLabel":"Upright","imdb":8,"imdbVotes":201545,"tmdb":7.972,"tmdbVotes":4868}},{"id":"movie-citizen-kane-1941","title":"Citizen Kane","year":1941,"type":"movie","runtimeSeconds":7173,"seasonCount":null,"communityRating":7.966,"criticRating":99,"genres":["Mystery","Drama"],"overview":"Newspaper magnate Charles Foster Kane is taken from his mother as a boy and made the ward of a rich industrialist. As a result, every well-meaning, tyrannical or self-destructive move he makes for the rest of his\u2026","poster":"assets/movie-citizen-kane-1941-poster.jpg","backdrop":"assets/movie-citizen-kane-1941-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:22:16.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":15,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":99,"rtCriticsLabel":"Certified Fresh","rtAudience":98,"rtAudienceLabel":"Upright","imdb":8.2,"imdbVotes":498321,"tmdb":7.962,"tmdbVotes":6324}},{"id":"movie-conclave-2024","title":"Conclave","year":2024,"type":"movie","runtimeSeconds":7230,"seasonCount":null,"communityRating":7.19,"criticRating":93,"genres":["Drama","Thriller"],"overview":"After the unexpected death of the Pope, Cardinal Lawrence is tasked with managing the covert and ancient ritual of electing a new one. Sequestered in the Vatican with the Catholic Church\u2019s most powerful leaders until\u2026","poster":"assets/movie-conclave-2024-poster.jpg","backdrop":"assets/movie-conclave-2024-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:30:41.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":974576,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":93,"rtCriticsLabel":"Certified Fresh","rtAudience":86,"rtAudienceLabel":"Upright","imdb":7.4,"imdbVotes":290498,"tmdb":7.19,"tmdbVotes":3744}},{"id":"movie-the-dry-2021","title":"The Dry","year":2021,"type":"movie","runtimeSeconds":7037,"seasonCount":null,"communityRating":6.779,"criticRating":null,"genres":["Crime","Thriller","Mystery"],"overview":"Aaron Falk returns to his drought-stricken hometown to attend a tragic funeral. But his return opens a decades-old wound - the unsolved death of a teenage girl.","poster":"assets/movie-the-dry-2021-poster.jpg","backdrop":"assets/movie-the-dry-2021-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:29:20.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":567797,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":90,"rtCriticsLabel":"Certified Fresh","rtAudience":89,"rtAudienceLabel":"Upright","imdb":6.8,"imdbVotes":41935,"tmdb":6.8,"tmdbVotes":892}},{"id":"movie-easy-a-2010","title":"Easy A","year":2010,"type":"movie","runtimeSeconds":5545,"seasonCount":null,"communityRating":6.8,"criticRating":85,"genres":["Comedy"],"overview":"Olive, an average high school student, sees her below-the-radar existence turn around overnight once she decides to use the school's gossip grapevine to advance her social standing. Now her classmates are turning\u2026","poster":"assets/movie-easy-a-2010-poster.jpg","backdrop":"assets/movie-easy-a-2010-backdrop.jpg","played":true,"playCount":1,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-17T19:59:04.0000000Z","lastPlayedAt":"2026-10-17T20:02:51.1083337Z","availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":37735,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":85,"rtCriticsLabel":"Certified Fresh","rtAudience":77,"rtAudienceLabel":"Upright","imdb":7,"imdbVotes":448780,"tmdb":6.8,"tmdbVotes":7619}},{"id":"movie-el-camino-a-breaking-bad-movie-2019","title":"El Camino: A Breaking Bad Movie","year":2019,"type":"movie","runtimeSeconds":7362,"seasonCount":null,"communityRating":7.055,"criticRating":92,"genres":["Crime","Drama","Thriller"],"overview":"In the wake of his dramatic escape from captivity, Jesse Pinkman must come to terms with his past in order to forge some kind of future.","poster":"assets/movie-el-camino-a-breaking-bad-movie-2019-poster.jpg","backdrop":"assets/movie-el-camino-a-breaking-bad-movie-2019-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-21T23:31:11.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":559969,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":92,"rtCriticsLabel":"Certified Fresh","rtAudience":81,"rtAudienceLabel":"Upright","imdb":7.3,"imdbVotes":354488,"tmdb":7.056,"tmdbVotes":5950}},{"id":"movie-emancipation-2022","title":"Emancipation","year":2022,"type":"movie","runtimeSeconds":7949,"seasonCount":null,"communityRating":7.7,"criticRating":45,"genres":["Drama","War","History"],"overview":"Inspired by the gripping true story of a man who would do anything for his family\u2014and for freedom. When Peter, an enslaved man, risks his life to escape and return to his family, he embarks on a perilous journey of\u2026","poster":"assets/movie-emancipation-2022-poster.jpg","backdrop":"assets/movie-emancipation-2022-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-10T20:37:34.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":715931,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":45,"rtCriticsLabel":"Rotten","rtAudience":58,"rtAudienceLabel":"Spilled","imdb":6.3,"imdbVotes":32079,"tmdb":7.744,"tmdbVotes":1319}},{"id":"movie-fighting-with-my-family-2019","title":"Fighting with My Family","year":2019,"type":"movie","runtimeSeconds":6509,"seasonCount":null,"communityRating":6.84,"criticRating":93,"genres":["Comedy"],"overview":"Born into a tight-knit wrestling family, Paige and her brother Zak are ecstatic when they get the once-in-a-lifetime opportunity to try out for the WWE. But when only Paige earns a spot in the competitive training\u2026","poster":"assets/movie-fighting-with-my-family-2019-poster.jpg","backdrop":"assets/movie-fighting-with-my-family-2019-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-22T22:10:59.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":445629,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":93,"rtCriticsLabel":"Certified Fresh","rtAudience":86,"rtAudienceLabel":"Upright","imdb":7,"imdbVotes":94576,"tmdb":6.837,"tmdbVotes":1952}},{"id":"movie-force-of-nature-the-dry-2-2024","title":"Force of Nature: The Dry 2","year":2024,"type":"movie","runtimeSeconds":6753,"seasonCount":null,"communityRating":6.3,"criticRating":66,"genres":["Mystery","Thriller"],"overview":"When five women take part in a corporate hiking retreat and only four come out on the other side, Federal Agents Aaron Falk and Carmen Cooper head deep into the Victorian mountain ranges to investigate in the hopes\u2026","poster":"assets/movie-force-of-nature-the-dry-2-2024-poster.jpg","backdrop":"assets/movie-force-of-nature-the-dry-2-2024-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:29:49.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":832262,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":66,"rtCriticsLabel":"Fresh","rtAudience":43,"rtAudienceLabel":"Spilled","imdb":5.9,"imdbVotes":10343,"tmdb":6.269,"tmdbVotes":305}},{"id":"movie-free-state-of-jones-2016","title":"Free State of Jones","year":2016,"type":"movie","runtimeSeconds":8376,"seasonCount":null,"communityRating":6.79,"criticRating":48,"genres":["Action","Drama","History"],"overview":"In 1863, Mississippi farmer Newt Knight serves as a medic for the Confederate Army. Opposed to slavery, Knight would rather help the wounded than fight the Union. After his nephew dies in battle, Newt returns home to\u2026","poster":"assets/movie-free-state-of-jones-2016-poster.jpg","backdrop":"assets/movie-free-state-of-jones-2016-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-11T17:56:53.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":316152,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":48,"rtCriticsLabel":"Rotten","rtAudience":64,"rtAudienceLabel":"Upright","imdb":6.9,"imdbVotes":68931,"tmdb":6.788,"tmdbVotes":1730}},{"id":"movie-from-up-on-poppy-hill-2011","title":"From Up on Poppy Hill","year":2011,"type":"movie","runtimeSeconds":5482,"seasonCount":null,"communityRating":7.5,"criticRating":87,"genres":["Animation","Drama"],"overview":"Yokohama, 1963. Japan is picking itself up from the devastation of World War II and preparing to host the 1964 Olympics\u2014and the mood is one of both optimism and conflict as the young generation struggles to throw off\u2026","poster":"assets/movie-from-up-on-poppy-hill-2011-poster.jpg","backdrop":"assets/movie-from-up-on-poppy-hill-2011-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-07T14:41:03.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":83389,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":87,"rtCriticsLabel":"Certified Fresh","rtAudience":80,"rtAudienceLabel":"Upright","imdb":7.4,"imdbVotes":60769,"tmdb":7.509,"tmdbVotes":2026}},{"id":"movie-ghost-in-the-shell-1995","title":"Ghost in the Shell","year":1995,"type":"movie","runtimeSeconds":4959,"seasonCount":null,"communityRating":7.929,"criticRating":95,"genres":["Action","Animation","Science Fiction"],"overview":"In the year 2029, the barriers of our world have been broken down by the net and by cybernetics, but this brings new vulnerability to humans in the form of brain-hacking. When a highly-wanted hacker known as 'The\u2026","poster":"assets/movie-ghost-in-the-shell-1995-poster.jpg","backdrop":"assets/movie-ghost-in-the-shell-1995-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:22:57.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":9323,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":97,"rtCriticsLabel":"Certified Fresh","rtAudience":90,"rtAudienceLabel":"Upright","imdb":7.9,"imdbVotes":178061,"tmdb":7.928,"tmdbVotes":4130}},{"id":"movie-ghost-in-the-shell-2-innocence-2004","title":"Ghost in the Shell 2: Innocence","year":2004,"type":"movie","runtimeSeconds":5950,"seasonCount":null,"communityRating":7.352,"criticRating":65,"genres":["Animation","Drama","Science Fiction"],"overview":"Cyborg detective Batou is assigned to investigate a series of murders committed by gynoids\u2014doll-like cyborgs, which all malfunctioned, killed, then self-destructed afterwards. The brains of the gynoids initialize in\u2026","poster":"assets/movie-ghost-in-the-shell-2-innocence-2004-poster.jpg","backdrop":"assets/movie-ghost-in-the-shell-2-innocence-2004-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:23:38.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":12140,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":65,"rtCriticsLabel":"Fresh","rtAudience":80,"rtAudienceLabel":"Upright","imdb":7.4,"imdbVotes":43280,"tmdb":7.356,"tmdbVotes":1049}},{"id":"movie-the-godfather-1972","title":"The Godfather","year":1972,"type":"movie","runtimeSeconds":10603,"seasonCount":null,"communityRating":8.687,"criticRating":97,"genres":["Drama","Crime"],"overview":"Spanning the years 1945 to 1955, a chronicle of the fictional Italian-American Corleone crime family. When organized crime family patriarch, Vito Corleone barely survives an attempt on his life, his youngest son,\u2026","poster":"assets/movie-the-godfather-1972-poster.jpg","backdrop":"assets/movie-the-godfather-1972-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:24:12.0000000Z","lastPlayedAt":"2026-09-18T19:24:44.9855867Z","availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":238,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":97,"rtCriticsLabel":"Certified Fresh","rtAudience":98,"rtAudienceLabel":"Upright","imdb":9.2,"imdbVotes":2262024,"tmdb":8.688,"tmdbVotes":23907}},{"id":"movie-the-godfather-part-ii-1974","title":"The Godfather Part II","year":1974,"type":"movie","runtimeSeconds":12031,"seasonCount":null,"communityRating":8.573,"criticRating":96,"genres":["Drama","Crime"],"overview":"In the continuing saga of the Corleone crime family, a young Vito Corleone grows up in Sicily and in 1910s New York. In the 1950s, Michael Corleone attempts to expand the family business into Las Vegas, Hollywood and\u2026","poster":"assets/movie-the-godfather-part-ii-1974-poster.jpg","backdrop":"assets/movie-the-godfather-part-ii-1974-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:24:18.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":240,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":96,"rtCriticsLabel":"Certified Fresh","rtAudience":97,"rtAudienceLabel":"Upright","imdb":9,"imdbVotes":1521308,"tmdb":8.571,"tmdbVotes":14559}},{"id":"movie-the-godfather-part-iii-1990","title":"The Godfather Part III","year":1990,"type":"movie","runtimeSeconds":9476,"seasonCount":null,"communityRating":7.416,"criticRating":67,"genres":["Crime","Drama","Thriller"],"overview":"In the midst of trying to legitimize his business dealings in 1979 New York and Italy, aging mafia don, Michael Corleone seeks forgiveness for his sins while taking a young protege under his wing.","poster":"assets/movie-the-godfather-part-iii-1990-poster.jpg","backdrop":"assets/movie-the-godfather-part-iii-1990-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:26:29.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":242,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":68,"rtCriticsLabel":"Fresh","rtAudience":68,"rtAudienceLabel":"Upright","imdb":7.5,"imdbVotes":462448,"tmdb":7.413,"tmdbVotes":7159}},{"id":"movie-gosford-park-2001","title":"Gosford Park","year":2001,"type":"movie","runtimeSeconds":8247,"seasonCount":null,"communityRating":6.815,"criticRating":87,"genres":["Drama","Mystery","Thriller"],"overview":"In 1930s England, a group of pretentious rich and famous gather together for a weekend of relaxation at a hunting resort. But when a murder occurs, each one of these interesting characters becomes a suspect.","poster":"assets/movie-gosford-park-2001-poster.jpg","backdrop":"assets/movie-gosford-park-2001-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:25:49.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":5279,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":87,"rtCriticsLabel":"Certified Fresh","rtAudience":78,"rtAudienceLabel":"Upright","imdb":7.2,"imdbVotes":103883,"tmdb":6.822,"tmdbVotes":1317}},{"id":"movie-grave-of-the-fireflies-1988","title":"Grave of the Fireflies","year":1988,"type":"movie","runtimeSeconds":5313,"seasonCount":null,"communityRating":8.45,"criticRating":100,"genres":["Animation","Drama","War"],"overview":"In the final months of World War II, 14-year-old Seita and his sister Setsuko are orphaned when their mother is killed during an air raid in Kobe, Japan. After a falling out with their aunt, they move into an\u2026","poster":"assets/movie-grave-of-the-fireflies-1988-poster.jpg","backdrop":"assets/movie-grave-of-the-fireflies-1988-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:24:14.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":12477,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Certified Fresh","rtAudience":95,"rtAudienceLabel":"Upright","imdb":8.5,"imdbVotes":399802,"tmdb":8.45,"tmdbVotes":6938}},{"id":"movie-the-great-gatsby-2013","title":"The Great Gatsby","year":2013,"type":"movie","runtimeSeconds":8525,"seasonCount":null,"communityRating":7.346,"criticRating":49,"genres":["Drama","Romance"],"overview":"Nick Carraway arrives in New York in 1922, an era of loose morals, glittering jazz and bootleg kings. Chasing his own American Dream, Nick encounters the mysterious millionaire Gatsby and his bewitching cousin Daisy.\u2026","poster":"assets/movie-the-great-gatsby-2013-poster.jpg","backdrop":"assets/movie-the-great-gatsby-2013-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:26:50.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":64682,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":48,"rtCriticsLabel":"Rotten","rtAudience":67,"rtAudienceLabel":"Upright","imdb":7.2,"imdbVotes":651882,"tmdb":7.346,"tmdbVotes":13290}},{"id":"movie-the-hours-2002","title":"The Hours","year":2002,"type":"movie","runtimeSeconds":6887,"seasonCount":null,"communityRating":7.25,"criticRating":79,"genres":["Drama"],"overview":"The story of three women searching for more potent, meaningful lives. Each is alive at a different time and place, all are linked by their yearnings and their fears. Their stories intertwine, and finally come\u2026","poster":"assets/movie-the-hours-2002-poster.jpg","backdrop":"assets/movie-the-hours-2002-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:23:27.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":590,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":79,"rtCriticsLabel":"Certified Fresh","rtAudience":84,"rtAudienceLabel":"Upright","imdb":7.5,"imdbVotes":148367,"tmdb":7.249,"tmdbVotes":1931}},{"id":"movie-howl-s-moving-castle-2004","title":"Howl's Moving Castle","year":2004,"type":"movie","runtimeSeconds":7149,"seasonCount":null,"communityRating":8.4,"criticRating":88,"genres":["Fantasy","Animation","Adventure"],"overview":"Sophie, a young milliner, is turned into an elderly woman by a witch who enters her shop and curses her. She encounters a wizard named Howl and gets caught up in his resistance to fighting for the king.","poster":"assets/movie-howl-s-moving-castle-2004-poster.jpg","backdrop":"assets/movie-howl-s-moving-castle-2004-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:22:47.0000000Z","lastPlayedAt":"2026-05-21T18:46:08.0000000Z","availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":4935,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":87,"rtCriticsLabel":"Certified Fresh","rtAudience":93,"rtAudienceLabel":"Upright","imdb":8.2,"imdbVotes":524520,"tmdb":8.391,"tmdbVotes":11642}},{"id":"movie-in-the-heights-2021","title":"In the Heights","year":2021,"type":"movie","runtimeSeconds":8579,"seasonCount":null,"communityRating":7.111,"criticRating":null,"genres":["Drama","Romance"],"overview":"The story of Usnavi, a bodega owner who has mixed feelings about closing his store and retiring to the Dominican Republic or staying in Washington Heights.","poster":"assets/movie-in-the-heights-2021-poster.jpg","backdrop":"assets/movie-in-the-heights-2021-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:29:11.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":467909,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":94,"rtCriticsLabel":"Certified Fresh","rtAudience":94,"rtAudienceLabel":"Upright","imdb":7.2,"imdbVotes":56513,"tmdb":7.104,"tmdbVotes":826}},{"id":"movie-jennifer-s-body-2009","title":"Jennifer's Body","year":2009,"type":"movie","runtimeSeconds":6450,"seasonCount":null,"communityRating":6.012,"criticRating":47,"genres":["Horror","Comedy"],"overview":"Jennifer, a gorgeous, seductive cheerleader takes evil to a whole new level after she's possessed by a sinister demon. Now it's up to her best friend to stop Jennifer's reign of terror before it's too late.","poster":"assets/movie-jennifer-s-body-2009-poster.jpg","backdrop":"assets/movie-jennifer-s-body-2009-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-30T03:37:04.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":19994,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":47,"rtCriticsLabel":"Rotten","rtAudience":36,"rtAudienceLabel":"Spilled","imdb":5.6,"imdbVotes":179710,"tmdb":6.013,"tmdbVotes":4481}},{"id":"movie-kiki-s-delivery-service-1989","title":"Kiki's Delivery Service","year":1989,"type":"movie","runtimeSeconds":6183,"seasonCount":null,"communityRating":7.839,"criticRating":null,"genres":["Animation","Family","Fantasy"],"overview":"A young witch, on her mandatory year of independent life, finds fitting into a new community difficult while she supports herself by running an air courier service.","poster":"assets/movie-kiki-s-delivery-service-1989-poster.jpg","backdrop":"assets/movie-kiki-s-delivery-service-1989-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:24:20.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":16859,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":98,"rtCriticsLabel":"Certified Fresh","rtAudience":89,"rtAudienceLabel":"Upright","imdb":7.8,"imdbVotes":192477,"tmdb":7.839,"tmdbVotes":4811}},{"id":"movie-the-last-of-the-mohicans-1992","title":"The Last of the Mohicans","year":1992,"type":"movie","runtimeSeconds":6874,"seasonCount":null,"communityRating":7.388,"criticRating":88,"genres":["History","War","Drama"],"overview":"In war-torn colonial America, in the midst of a bloody battle between British, the French and Native American allies, the aristocratic daughter of a British Colonel and her party are captured by a group of Huron\u2026","poster":"assets/movie-the-last-of-the-mohicans-1992-poster.jpg","backdrop":"assets/movie-the-last-of-the-mohicans-1992-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-10T20:59:22.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":9361,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":88,"rtCriticsLabel":"Certified Fresh","rtAudience":88,"rtAudienceLabel":"Upright","imdb":7.6,"imdbVotes":210791,"tmdb":7.39,"tmdbVotes":3593}},{"id":"movie-the-last-samurai-2003","title":"The Last Samurai","year":2003,"type":"movie","runtimeSeconds":9251,"seasonCount":null,"communityRating":7.61,"criticRating":65,"genres":["Drama","Action","War"],"overview":"Nathan Algren is an American hired to instruct the Japanese army in the ways of modern warfare, which finds him learning to respect the samurai and the honorable principles that rule them. Pressed to destroy the\u2026","poster":"assets/movie-the-last-samurai-2003-poster.jpg","backdrop":"assets/movie-the-last-samurai-2003-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-26T05:25:10.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":616,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":66,"rtCriticsLabel":"Fresh","rtAudience":83,"rtAudienceLabel":"Upright","imdb":7.8,"imdbVotes":512982,"tmdb":7.614,"tmdbVotes":7887}},{"id":"movie-lemony-snicket-s-a-series-of-unfortunate-events-2004","title":"Lemony Snicket's A Series of Unfortunate Events","year":2004,"type":"movie","runtimeSeconds":6479,"seasonCount":null,"communityRating":6.8,"criticRating":72,"genres":["Adventure","Comedy","Family"],"overview":"Three wealthy children's parents are killed in a fire. When they are sent to a distant relative, they find out that he is plotting to kill them and seize their fortune.","poster":"assets/movie-lemony-snicket-s-a-series-of-unfortunate-events-2004-poster.jpg","backdrop":"assets/movie-lemony-snicket-s-a-series-of-unfortunate-events-2004-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:26:09.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":11774,"artwork":{"posterKind":"center_crop","backdropKind":"backdrop"},"ratings":{"rtCritics":72,"rtCriticsLabel":"Fresh","rtAudience":63,"rtAudienceLabel":"Upright","imdb":6.8,"imdbVotes":233636,"tmdb":6.82,"tmdbVotes":5447}},{"id":"movie-the-lighthouse-2019","title":"The Lighthouse","year":2019,"type":"movie","runtimeSeconds":6549,"seasonCount":null,"communityRating":7.463,"criticRating":90,"genres":["Drama","Fantasy","Thriller"],"overview":"Two lighthouse keepers try to maintain their sanity while living on a remote and mysterious New England island in the 1890s.","poster":"assets/movie-the-lighthouse-2019-poster.jpg","backdrop":"assets/movie-the-lighthouse-2019-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:29:01.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":503919,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":90,"rtCriticsLabel":"Certified Fresh","rtAudience":72,"rtAudienceLabel":"Upright","imdb":7.3,"imdbVotes":312344,"tmdb":7.46,"tmdbVotes":5895}},{"id":"movie-locke-2014","title":"Locke","year":2014,"type":"movie","runtimeSeconds":5090,"seasonCount":null,"communityRating":6.888,"criticRating":91,"genres":["Drama","Thriller"],"overview":"Ivan Locke has worked hard to craft a good life for himself. Tonight, that life will collapse around him. On the eve of the biggest challenge of his career, Ivan receives a phone call that sets in motion a series of\u2026","poster":"assets/movie-locke-2014-poster.jpg","backdrop":"assets/movie-locke-2014-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T17:38:48.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":210479,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":90,"rtCriticsLabel":"Certified Fresh","rtAudience":72,"rtAudienceLabel":"Upright","imdb":7.1,"imdbVotes":171265,"tmdb":6.889,"tmdbVotes":3088}},{"id":"movie-the-matrix-1999","title":"The Matrix","year":1999,"type":"movie","runtimeSeconds":8179,"seasonCount":null,"communityRating":8.259,"criticRating":83,"genres":["Action","Science Fiction"],"overview":"Set in the 22nd century, The Matrix tells the story of a computer hacker who joins a group of underground insurgents fighting the vast and powerful computers who now rule the earth.","poster":"assets/movie-the-matrix-1999-poster.jpg","backdrop":"assets/movie-the-matrix-1999-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:18:12.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":603,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":83,"rtCriticsLabel":"Certified Fresh","rtAudience":85,"rtAudienceLabel":"Upright","imdb":8.7,"imdbVotes":2289808,"tmdb":8.262,"tmdbVotes":29153}},{"id":"movie-the-matrix-reloaded-2003","title":"The Matrix Reloaded","year":2003,"type":"movie","runtimeSeconds":8298,"seasonCount":null,"communityRating":7.085,"criticRating":74,"genres":["Adventure","Action","Thriller"],"overview":"The Resistance builds in numbers as humans are freed from the Matrix and brought to the city of Zion. Neo discovers his superpowers, including the ability to see the code inside the Matrix. With machine sentinels\u2026","poster":"assets/movie-the-matrix-reloaded-2003-poster.jpg","backdrop":"assets/movie-the-matrix-reloaded-2003-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:24:03.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":604,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":73,"rtCriticsLabel":"Certified Fresh","rtAudience":72,"rtAudienceLabel":"Upright","imdb":7.2,"imdbVotes":678013,"tmdb":7.087,"tmdbVotes":12504}},{"id":"movie-the-matrix-resurrections-2021","title":"The Matrix Resurrections","year":2021,"type":"movie","runtimeSeconds":8875,"seasonCount":null,"communityRating":6.303,"criticRating":63,"genres":["Science Fiction","Action","Adventure"],"overview":"Plagued by strange memories, Neo's life takes an unexpected turn when he finds himself back inside the Matrix.","poster":"assets/movie-the-matrix-resurrections-2021-poster.jpg","backdrop":"assets/movie-the-matrix-resurrections-2021-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:31:22.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":624860,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":63,"rtCriticsLabel":"Fresh","rtAudience":63,"rtAudienceLabel":"Upright","imdb":5.6,"imdbVotes":307780,"tmdb":6.294,"tmdbVotes":6842}},{"id":"movie-the-matrix-revolutions-2003","title":"The Matrix Revolutions","year":2003,"type":"movie","runtimeSeconds":7756,"seasonCount":null,"communityRating":6.758,"criticRating":33,"genres":["Adventure","Action","Thriller"],"overview":"The human city of Zion defends itself against the massive invasion of the machines as Neo fights to end the war at another front while also opposing the rogue Agent Smith.","poster":"assets/movie-the-matrix-revolutions-2003-poster.jpg","backdrop":"assets/movie-the-matrix-revolutions-2003-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:25:47.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":605,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":34,"rtCriticsLabel":"Rotten","rtAudience":60,"rtAudienceLabel":"Upright","imdb":6.8,"imdbVotes":581553,"tmdb":6.762,"tmdbVotes":11292}},{"id":"movie-mercy-2026","title":"Mercy","year":2026,"type":"movie","runtimeSeconds":5968,"seasonCount":null,"communityRating":7.077,"criticRating":null,"genres":["Science Fiction","Thriller","Crime"],"overview":"In the near future, a detective stands on trial accused of murdering his wife. He has ninety minutes to prove his innocence to the advanced AI Judge he once championed, before it determines his fate.","poster":"assets/movie-mercy-2026-poster.jpg","backdrop":"assets/movie-mercy-2026-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:31:40.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":1236153,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":24,"rtCriticsLabel":"Rotten","rtAudience":81,"rtAudienceLabel":"Upright","imdb":6.2,"imdbVotes":83878,"tmdb":7.054,"tmdbVotes":1812}},{"id":"movie-normal-2026","title":"Normal","year":2026,"type":"movie","runtimeSeconds":5514,"seasonCount":null,"communityRating":7.267,"criticRating":77,"genres":["Action","Crime","Thriller"],"overview":"An unassuming substitute sheriff with a troubled past responds to a bank robbery in a small, sleepy town and unknowingly uncovers something far more explosive.","poster":"assets/movie-normal-2026-poster.jpg","backdrop":"assets/movie-normal-2026-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-08-21T08:33:18.0000000Z","lastPlayedAt":"2026-09-24T23:07:52.1161581Z","availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":1242332,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":78,"rtCriticsLabel":"Certified Fresh","rtAudience":75,"rtAudienceLabel":"Upright","imdb":6.3,"imdbVotes":37501,"tmdb":7.241,"tmdbVotes":786}},{"id":"movie-outlaw-king-2018","title":"Outlaw King","year":2018,"type":"movie","runtimeSeconds":7297,"seasonCount":null,"communityRating":6.829,"criticRating":63,"genres":["Action","History","War"],"overview":"Forced into exile by the English after being crowned King of Scotland, legendary warrior Robert the Bruce fights to reclaim the throne.","poster":"assets/movie-outlaw-king-2018-poster.jpg","backdrop":"assets/movie-outlaw-king-2018-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:28:32.0000000Z","lastPlayedAt":"2026-07-26T22:35:35.0000000Z","availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":454227,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":63,"rtCriticsLabel":"Fresh","rtAudience":69,"rtAudienceLabel":"Upright","imdb":6.9,"imdbVotes":89876,"tmdb":6.844,"tmdbVotes":1780}},{"id":"movie-panic-room-2002","title":"Panic Room","year":2002,"type":"movie","runtimeSeconds":6717,"seasonCount":null,"communityRating":6.794,"criticRating":76,"genres":["Crime","Drama","Thriller"],"overview":"Trapped in their New York brownstone's panic room, a hidden chamber built as a sanctuary in the event of break-ins, newly divorced Meg Altman and her young daughter Sarah play a deadly game of cat-and-mouse with\u2026","poster":"assets/movie-panic-room-2002-poster.jpg","backdrop":"assets/movie-panic-room-2002-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-19T20:50:01.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":4547,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":76,"rtCriticsLabel":"Certified Fresh","rtAudience":64,"rtAudienceLabel":"Upright","imdb":6.8,"imdbVotes":317468,"tmdb":6.796,"tmdbVotes":5653}},{"id":"movie-the-patriot-2000","title":"The Patriot","year":2000,"type":"movie","runtimeSeconds":9887,"seasonCount":null,"communityRating":7.214,"criticRating":61,"genres":["Drama","History","War"],"overview":"After proving himself on the field of battle in the French and Indian War, Benjamin Martin wants nothing more to do with such things, preferring the simple life of a farmer. But when his son Gabriel enlists in the\u2026","poster":"assets/movie-the-patriot-2000-poster.jpg","backdrop":"assets/movie-the-patriot-2000-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-10T20:50:00.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":2024,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":61,"rtCriticsLabel":"Fresh","rtAudience":81,"rtAudienceLabel":"Upright","imdb":7.2,"imdbVotes":317639,"tmdb":7.215,"tmdbVotes":4535}},{"id":"movie-peaky-blinders-the-immortal-man-2026","title":"Peaky Blinders: The Immortal Man","year":2026,"type":"movie","runtimeSeconds":6844,"seasonCount":null,"communityRating":7.187,"criticRating":90,"genres":["Crime","Drama"],"overview":"After his estranged son gets embroiled in a Nazi plot, self-exiled gangster Tommy Shelby must return to Birmingham to save his family \u2014 and his nation.","poster":"assets/movie-peaky-blinders-the-immortal-man-2026-poster.jpg","backdrop":"assets/movie-peaky-blinders-the-immortal-man-2026-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:30:01.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":875828,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":90,"rtCriticsLabel":"Certified Fresh","rtAudience":87,"rtAudienceLabel":"Upright","imdb":6.5,"imdbVotes":92130,"tmdb":7.189,"tmdbVotes":1304}},{"id":"movie-ponyo-2008","title":"Ponyo","year":2008,"type":"movie","runtimeSeconds":6530,"seasonCount":null,"communityRating":7.763,"criticRating":91,"genres":["Animation","Fantasy","Family"],"overview":"When Sosuke, a young boy who lives on a clifftop overlooking the sea, rescues a stranded goldfish named Ponyo, he discovers more than he bargained for. Ponyo is a curious, energetic young creature who yearns to be\u2026","poster":"assets/movie-ponyo-2008-poster.jpg","backdrop":"assets/movie-ponyo-2008-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:23:53.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":12429,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":91,"rtCriticsLabel":"Certified Fresh","rtAudience":84,"rtAudienceLabel":"Upright","imdb":7.6,"imdbVotes":190294,"tmdb":7.759,"tmdbVotes":5050}},{"id":"movie-porco-rosso-1992","title":"Porco Rosso","year":1992,"type":"movie","runtimeSeconds":5600,"seasonCount":null,"communityRating":7.794,"criticRating":96,"genres":["Animation","Adventure","Fantasy"],"overview":"In Italy in the 1930s, sky pirates in biplanes terrorize wealthy cruise ships as they sail the Adriatic Sea. The only pilot brave enough to stop the scourge is the mysterious Porco Rosso, a former World War I flying\u2026","poster":"assets/movie-porco-rosso-1992-poster.jpg","backdrop":"assets/movie-porco-rosso-1992-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:23:22.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":11621,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":96,"rtCriticsLabel":"Fresh","rtAudience":87,"rtAudienceLabel":"Upright","imdb":7.7,"imdbVotes":119396,"tmdb":7.789,"tmdbVotes":3879}},{"id":"movie-princess-mononoke-1997","title":"Princess Mononoke","year":1997,"type":"movie","runtimeSeconds":8003,"seasonCount":null,"communityRating":8.321,"criticRating":93,"genres":["Adventure","Fantasy","Animation"],"overview":"Ashitaka, a prince of the disappearing Emishi people, is cursed by a demonized boar god and must journey to the west to find a cure. Along the way, he encounters San, a young human woman fighting to protect the\u2026","poster":"assets/movie-princess-mononoke-1997-poster.jpg","backdrop":"assets/movie-princess-mononoke-1997-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:22:28.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":128,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":94,"rtCriticsLabel":"Certified Fresh","rtAudience":99,"rtAudienceLabel":"Upright","imdb":8.3,"imdbVotes":493735,"tmdb":8.321,"tmdbVotes":9438}},{"id":"movie-prisoners-2013","title":"Prisoners","year":2013,"type":"movie","runtimeSeconds":9192,"seasonCount":null,"communityRating":8.106,"criticRating":81,"genres":["Drama","Thriller","Crime"],"overview":"After his six-year-old daughter is abducted, a desperate father takes justice into his own hands when he loses faith in the detective leading the investigation, setting both men on a collision course as the search\u2026","poster":"assets/movie-prisoners-2013-poster.jpg","backdrop":"assets/movie-prisoners-2013-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:27:33.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":146233,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":82,"rtCriticsLabel":"Certified Fresh","rtAudience":87,"rtAudienceLabel":"Upright","imdb":8.2,"imdbVotes":963062,"tmdb":8.105,"tmdbVotes":13722}},{"id":"movie-racing-stripes-2005","title":"Racing Stripes","year":2005,"type":"movie","runtimeSeconds":6117,"seasonCount":null,"communityRating":5.945,"criticRating":35,"genres":["Comedy","Family"],"overview":"Shattered illusions are hard to repair -- especially for a good-hearted zebra named Stripes who's spent his life on a Kentucky farm amidst the sorely mistaken notion that he's a debonair thoroughbred. Once he faces\u2026","poster":"assets/movie-racing-stripes-2005-poster.jpg","backdrop":"assets/movie-racing-stripes-2005-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:26:02.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":6439,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":35,"rtCriticsLabel":"Rotten","rtAudience":42,"rtAudienceLabel":"Spilled","imdb":5.3,"imdbVotes":19569,"tmdb":5.962,"tmdbVotes":705}},{"id":"movie-requiem-for-a-dream-2000","title":"Requiem for a Dream","year":2000,"type":"movie","runtimeSeconds":6086,"seasonCount":null,"communityRating":8.005,"criticRating":80,"genres":["Crime","Drama"],"overview":"The drug-induced utopias of four Coney Island residents are shattered when their addictions run deep.","poster":"assets/movie-requiem-for-a-dream-2000-poster.jpg","backdrop":"assets/movie-requiem-for-a-dream-2000-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:24:15.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":641,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":81,"rtCriticsLabel":"Certified Fresh","rtAudience":93,"rtAudienceLabel":"Upright","imdb":8.3,"imdbVotes":989090,"tmdb":8,"tmdbVotes":11454}},{"id":"movie-rogue-one-a-star-wars-story-2016","title":"Rogue One: A Star Wars Story","year":2016,"type":"movie","runtimeSeconds":8038,"seasonCount":null,"communityRating":7.51,"criticRating":84,"genres":["Action","Adventure","Science Fiction"],"overview":"A rogue band of resistance fighters unite for a mission to steal the Death Star plans and bring a new hope to the galaxy.","poster":"assets/movie-rogue-one-a-star-wars-story-2016-poster.jpg","backdrop":"assets/movie-rogue-one-a-star-wars-story-2016-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:28:00.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":330459,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":84,"rtCriticsLabel":"Certified Fresh","rtAudience":87,"rtAudienceLabel":"Upright","imdb":7.8,"imdbVotes":768365,"tmdb":7.512,"tmdbVotes":16937}},{"id":"movie-secondhand-lions-2003","title":"Secondhand Lions","year":2003,"type":"movie","runtimeSeconds":6547,"seasonCount":null,"communityRating":7.237,"criticRating":60,"genres":["Family","Comedy","Drama"],"overview":"The comedic adventures of an introverted boy left on the doorstep of a pair of reluctant, eccentric great-uncles, whose exotic remembrances stir the boy's spirit and re-ignite the men's lives.","poster":"assets/movie-secondhand-lions-2003-poster.jpg","backdrop":"assets/movie-secondhand-lions-2003-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-12T07:16:13.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":13156,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":59,"rtCriticsLabel":"Rotten","rtAudience":84,"rtAudienceLabel":"Upright","imdb":7.5,"imdbVotes":66911,"tmdb":7.242,"tmdbVotes":872}},{"id":"movie-the-secret-life-of-pets-2-2019","title":"The Secret Life of Pets 2","year":2019,"type":"movie","runtimeSeconds":5164,"seasonCount":null,"communityRating":6.95,"criticRating":60,"genres":["Animation","Comedy","Family"],"overview":"Max the terrier must cope with some major life changes when his owner gets married and has a baby. When the family takes a trip to the countryside, nervous Max has numerous run-ins with canine-intolerant cows,\u2026","poster":"assets/movie-the-secret-life-of-pets-2-2019-poster.jpg","backdrop":"assets/movie-the-secret-life-of-pets-2-2019-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-05T07:00:53.0000000Z","lastPlayedAt":"2026-09-17T18:07:00.7024231Z","availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":412117,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":60,"rtCriticsLabel":"Fresh","rtAudience":90,"rtAudienceLabel":"Upright","imdb":6.4,"imdbVotes":80464,"tmdb":6.948,"tmdbVotes":3450}},{"id":"movie-self-reliance-2024","title":"Self Reliance","year":2024,"type":"movie","runtimeSeconds":5461,"seasonCount":null,"communityRating":5.888,"criticRating":73,"genres":["Comedy","Thriller"],"overview":"When a man is offered a million dollars to play a game in which hunters try to kill him, he thinks he has found the perfect loophole: they can only attack when he\u2019s alone. His only problem is that none of his friends\u2026","poster":"assets/movie-self-reliance-2024-poster.jpg","backdrop":"assets/movie-self-reliance-2024-backdrop.jpg","played":false,"playCount":1,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:31:00.0000000Z","lastPlayedAt":"2026-10-02T19:59:16.9286868Z","availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":1072876,"artwork":{"posterKind":"center_crop","backdropKind":"backdrop"},"ratings":{"rtCritics":73,"rtCriticsLabel":"Certified Fresh","rtAudience":56,"rtAudienceLabel":"Spilled","imdb":6,"imdbVotes":23771,"tmdb":5.866,"tmdbVotes":346}},{"id":"movie-serpico-1973","title":"Serpico","year":1973,"type":"movie","runtimeSeconds":7805,"seasonCount":null,"communityRating":7.5,"criticRating":93,"genres":["Crime","Drama","History"],"overview":"New York cop Frank Serpico blows the whistle on the rampant corruption in the force only to have his comrades turn against him.","poster":"assets/movie-serpico-1973-poster.jpg","backdrop":"assets/movie-serpico-1973-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-10T21:45:02.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":9040,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":93,"rtCriticsLabel":"Certified Fresh","rtAudience":88,"rtAudienceLabel":"Upright","imdb":7.7,"imdbVotes":149750,"tmdb":7.525,"tmdbVotes":2323}},{"id":"movie-shaft-2000","title":"Shaft","year":2000,"type":"movie","runtimeSeconds":5960,"seasonCount":null,"communityRating":6.026,"criticRating":67,"genres":["Action","Adventure","Crime"],"overview":"New York police detective John Shaft arrests Walter Wade Jr. for a racially motivated slaying. But the only eyewitness disappears, and Wade jumps bail for Switzerland. Two years later Wade returns to face trial,\u2026","poster":"assets/movie-shaft-2000-poster.jpg","backdrop":"assets/movie-shaft-2000-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-10T21:30:40.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":479,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":68,"rtCriticsLabel":"Fresh","rtAudience":40,"rtAudienceLabel":"Spilled","imdb":6,"imdbVotes":86257,"tmdb":6.024,"tmdbVotes":1531}},{"id":"movie-a-silent-voice-the-movie-2016","title":"A Silent Voice: The Movie","year":2016,"type":"movie","runtimeSeconds":7804,"seasonCount":null,"communityRating":8.398,"criticRating":null,"genres":["Animation","Drama","Romance"],"overview":"Shouya Ishida starts bullying the new girl in class, Shouko Nishimiya, because she is deaf. But as the teasing continues, the rest of the class starts to turn on Shouya for his lack of compassion. When they leave\u2026","poster":"assets/movie-a-silent-voice-the-movie-2016-poster.jpg","backdrop":"assets/movie-a-silent-voice-the-movie-2016-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T17:39:46.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":378064,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":95,"rtCriticsLabel":"Fresh","rtAudience":94,"rtAudienceLabel":"Upright","imdb":8.2,"imdbVotes":151926,"tmdb":8.396,"tmdbVotes":4764}},{"id":"movie-sinbad-legend-of-the-seven-seas-2003","title":"Sinbad: Legend of the Seven Seas","year":2003,"type":"movie","runtimeSeconds":5143,"seasonCount":null,"communityRating":7.067,"criticRating":44,"genres":["Action","Adventure","Animation"],"overview":"The sailor of legend is framed by the goddess Eris for the theft of the Book of Peace, and must travel to her realm at the end of the world to retrieve it and save the life of his childhood friend Prince Proteus.","poster":"assets/movie-sinbad-legend-of-the-seven-seas-2003-poster.jpg","backdrop":"assets/movie-sinbad-legend-of-the-seven-seas-2003-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:26:25.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":14411,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":46,"rtCriticsLabel":"Rotten","rtAudience":57,"rtAudienceLabel":"Spilled","imdb":6.8,"imdbVotes":65298,"tmdb":7.071,"tmdbVotes":2323}},{"id":"movie-sleeping-with-other-people-2015","title":"Sleeping with Other People","year":2015,"type":"movie","runtimeSeconds":6076,"seasonCount":null,"communityRating":6.274,"criticRating":64,"genres":["Comedy","Romance"],"overview":"Can two serial cheaters get a second chance at love? After a one-night stand in college, New Yorkers Lainey and Jake meet by chance twelve years later and discover they each have the same problem: because of their\u2026","poster":"assets/movie-sleeping-with-other-people-2015-poster.jpg","backdrop":"assets/movie-sleeping-with-other-people-2015-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:27:42.0000000Z","lastPlayedAt":"2026-07-17T17:50:44.0000000Z","availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":288036,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":64,"rtCriticsLabel":"Fresh","rtAudience":56,"rtAudienceLabel":"Spilled","imdb":6.5,"imdbVotes":52275,"tmdb":6.275,"tmdbVotes":1020}},{"id":"movie-snowpiercer-2013","title":"Snowpiercer","year":2013,"type":"movie","runtimeSeconds":7573,"seasonCount":null,"communityRating":6.909,"criticRating":94,"genres":["Action","Science Fiction","Drama"],"overview":"In a future where a failed global-warming experiment kills off most life on the planet, a class system evolves aboard the Snowpiercer; a train that travels around the globe via a perpetual-motion engine.","poster":"assets/movie-snowpiercer-2013-poster.jpg","backdrop":"assets/movie-snowpiercer-2013-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:27:07.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":110415,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":94,"rtCriticsLabel":"Certified Fresh","rtAudience":72,"rtAudienceLabel":"Upright","imdb":7.1,"imdbVotes":426976,"tmdb":6.9,"tmdbVotes":10807}},{"id":"movie-spider-man-brand-new-day-2026","title":"Spider-Man: Brand New Day","year":2026,"type":"movie","runtimeSeconds":8701,"seasonCount":null,"communityRating":8.374,"criticRating":90,"genres":["Science Fiction","Action","Adventure"],"overview":"Fighting crime full-time as Spider-Man in a world that doesn't remember him\u2014and the pressure of seeing his old friends move on without him\u2014sparks a change in Peter Parker he may not have the power to control. But\u2026","poster":"assets/movie-spider-man-brand-new-day-2026-poster.jpg","backdrop":"assets/movie-spider-man-brand-new-day-2026-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-10T14:14:27.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":969681,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":90,"rtCriticsLabel":"Certified Fresh","rtAudience":97,"rtAudienceLabel":"Upright","imdb":7.9,"imdbVotes":366886,"tmdb":8.5,"tmdbVotes":6537}},{"id":"movie-spider-man-far-from-home-2019","title":"Spider-Man: Far From Home","year":2019,"type":"movie","runtimeSeconds":7762,"seasonCount":null,"communityRating":7.389,"criticRating":91,"genres":["Action","Adventure","Science Fiction"],"overview":"Peter Parker and his friends go on a summer trip to Europe. However, they will hardly be able to rest - Peter will have to agree to help Nick Fury uncover the mystery of creatures that cause natural disasters and\u2026","poster":"assets/movie-spider-man-far-from-home-2019-poster.jpg","backdrop":"assets/movie-spider-man-far-from-home-2019-backdrop.jpg","played":true,"playCount":1,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-10T14:25:47.0000000Z","lastPlayedAt":"2026-10-10T17:50:35.6193119Z","availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":429617,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":91,"rtCriticsLabel":"Certified Fresh","rtAudience":95,"rtAudienceLabel":"Upright","imdb":7.3,"imdbVotes":682887,"tmdb":7.387,"tmdbVotes":17847}},{"id":"movie-spider-man-homecoming-2017","title":"Spider-Man: Homecoming","year":2017,"type":"movie","runtimeSeconds":8008,"seasonCount":null,"communityRating":7.333,"criticRating":92,"genres":["Action","Adventure","Science Fiction"],"overview":"Following the events of Captain America: Civil War, Peter Parker, with the help of his mentor Tony Stark, tries to balance his life as an ordinary high school student in Queens, New York City, with fighting crime as\u2026","poster":"assets/movie-spider-man-homecoming-2017-poster.jpg","backdrop":"assets/movie-spider-man-homecoming-2017-backdrop.jpg","played":true,"playCount":1,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-10T14:33:13.0000000Z","lastPlayedAt":"2026-10-10T20:31:23.4444213Z","availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":315635,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":92,"rtCriticsLabel":"Certified Fresh","rtAudience":87,"rtAudienceLabel":"Upright","imdb":7.4,"imdbVotes":840974,"tmdb":7.332,"tmdbVotes":24183}},{"id":"movie-spider-man-no-way-home-2021","title":"Spider-Man: No Way Home","year":2021,"type":"movie","runtimeSeconds":8890,"seasonCount":null,"communityRating":7.947,"criticRating":93,"genres":["Action","Adventure","Science Fiction"],"overview":"Peter Parker is unmasked and no longer able to separate his normal life from the high-stakes of being a super-hero. When he asks for help from Doctor Strange the stakes become even more dangerous, forcing him to\u2026","poster":"assets/movie-spider-man-no-way-home-2021-poster.jpg","backdrop":"assets/movie-spider-man-no-way-home-2021-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-10T14:21:05.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":634649,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":93,"rtCriticsLabel":"Certified Fresh","rtAudience":97,"rtAudienceLabel":"Upright","imdb":8.1,"imdbVotes":1082660,"tmdb":7.947,"tmdbVotes":23505}},{"id":"movie-spirited-away-2001","title":"Spirited Away","year":2001,"type":"movie","runtimeSeconds":7472,"seasonCount":null,"communityRating":8.535,"criticRating":96,"genres":["Animation","Family","Fantasy"],"overview":"A young girl, Chihiro, becomes trapped in a strange new world of spirits. When her parents undergo a mysterious transformation, she must call upon the courage she never knew she had to free her family.","poster":"assets/movie-spirited-away-2001-poster.jpg","backdrop":"assets/movie-spirited-away-2001-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:22:42.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":129,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":96,"rtCriticsLabel":"Certified Fresh","rtAudience":99,"rtAudienceLabel":"Upright","imdb":8.6,"imdbVotes":987658,"tmdb":8.536,"tmdbVotes":19176}},{"id":"movie-the-substance-2024","title":"The Substance","year":2024,"type":"movie","runtimeSeconds":8531,"seasonCount":null,"communityRating":7.135,"criticRating":89,"genres":["Horror","Science Fiction"],"overview":"A fading celebrity decides to use a black market drug, a cell-replicating substance that temporarily creates a younger, better version of herself.","poster":"assets/movie-the-substance-2024-poster.jpg","backdrop":"assets/movie-the-substance-2024-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:30:22.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":933260,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":89,"rtCriticsLabel":"Certified Fresh","rtAudience":76,"rtAudienceLabel":"Upright","imdb":7.2,"imdbVotes":466542,"tmdb":7.13,"tmdbVotes":6746}},{"id":"movie-the-tale-of-the-princess-kaguya-2013","title":"The Tale of The Princess Kaguya","year":2013,"type":"movie","runtimeSeconds":8218,"seasonCount":null,"communityRating":8.1,"criticRating":100,"genres":["Animation","Drama","Fantasy"],"overview":"Found inside a shining stalk of bamboo by an old bamboo cutter and his wife, a tiny girl grows rapidly into an exquisite young lady. The mysterious young princess enthrals all who encounter her. But, ultimately, she\u2026","poster":"assets/movie-the-tale-of-the-princess-kaguya-2013-poster.jpg","backdrop":"assets/movie-the-tale-of-the-princess-kaguya-2013-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-07T13:40:15.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":149871,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Certified Fresh","rtAudience":90,"rtAudienceLabel":"Upright","imdb":8,"imdbVotes":63574,"tmdb":8.083,"tmdbVotes":2079}},{"id":"movie-taxi-driver-1976","title":"Taxi Driver","year":1976,"type":"movie","runtimeSeconds":6831,"seasonCount":null,"communityRating":8.121,"criticRating":89,"genres":["Crime","Drama"],"overview":"Suffering from insomnia, disturbed loner Travis Bickle takes a job as a New York City cabbie, haunting the streets nightly, growing increasingly detached from reality as he dreams of cleaning up the filthy city.","poster":"assets/movie-taxi-driver-1976-poster.jpg","backdrop":"assets/movie-taxi-driver-1976-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:23:04.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":103,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":89,"rtCriticsLabel":"Certified Fresh","rtAudience":93,"rtAudienceLabel":"Upright","imdb":8.2,"imdbVotes":1046700,"tmdb":8.116,"tmdbVotes":13973}},{"id":"movie-triangle-of-sadness-2022","title":"Triangle of Sadness","year":2022,"type":"movie","runtimeSeconds":8833,"seasonCount":null,"communityRating":7.005,"criticRating":71,"genres":["Comedy","Drama"],"overview":"A celebrity model couple are invited on a luxury cruise for the uber-rich, helmed by an unhinged, alcoholic captain. What first appears Instagrammable ends catastrophically, leaving the survivors stranded on a desert\u2026","poster":"assets/movie-triangle-of-sadness-2022-poster.jpg","backdrop":"assets/movie-triangle-of-sadness-2022-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:29:00.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":497828,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":72,"rtCriticsLabel":"Fresh","rtAudience":80,"rtAudienceLabel":"Upright","imdb":7.2,"imdbVotes":221069,"tmdb":7,"tmdbVotes":3104}},{"id":"movie-tsotsi-2005","title":"Tsotsi","year":2005,"type":"movie","runtimeSeconds":5663,"seasonCount":null,"communityRating":6.937,"criticRating":82,"genres":["Crime","Drama"],"overview":"A young South African boy from the Johannesburg ghetto named Tsotsi, meaning Gangster, leaves home as a child to get away from his helpless parents. Now a teenage thug, Tsotsi finds a baby in the back seat of a car\u2026","poster":"assets/movie-tsotsi-2005-poster.jpg","backdrop":"assets/movie-tsotsi-2005-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:24:58.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":868,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":82,"rtCriticsLabel":"Certified Fresh","rtAudience":86,"rtAudienceLabel":"Upright","imdb":7.2,"imdbVotes":32526,"tmdb":6.941,"tmdbVotes":372}},{"id":"movie-unknown-number-the-high-school-catfish-2025","title":"Unknown Number: The High School Catfish","year":2025,"type":"movie","runtimeSeconds":5691,"seasonCount":null,"communityRating":6.746,"criticRating":85,"genres":["Documentary"],"overview":"Vulgar, taunting texts blow up the phones of a teen and her boyfriend. Who's sending them \u2014 and why? This twisty documentary reveals the shocking answer.","poster":"assets/movie-unknown-number-the-high-school-catfish-2025-poster.jpg","backdrop":"assets/movie-unknown-number-the-high-school-catfish-2025-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:32:10.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":1517772,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":85,"rtCriticsLabel":"Fresh","rtAudience":69,"rtAudienceLabel":"Upright","imdb":6.7,"imdbVotes":23039,"tmdb":6.737,"tmdbVotes":257}},{"id":"movie-the-uprising-2026","title":"The Uprising","year":2026,"type":"movie","runtimeSeconds":7684,"seasonCount":null,"communityRating":7.846,"criticRating":55,"genres":["Action","Drama","History"],"overview":"As war and plague devastate 14th-century England, a humble peasant ignites a rebellion, uniting an army of commoners to defy the King\u2019s might in a desperate fight for justice and survival.","poster":"assets/movie-the-uprising-2026-poster.jpg","backdrop":"assets/movie-the-uprising-2026-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-11-02T16:37:03.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":977942,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":57,"rtCriticsLabel":"Rotten","rtAudience":65,"rtAudienceLabel":"Upright","imdb":6.2,"imdbVotes":6622,"tmdb":7.8,"tmdbVotes":404}},{"id":"movie-vice-2018","title":"Vice","year":2018,"type":"movie","runtimeSeconds":7948,"seasonCount":null,"communityRating":7.013,"criticRating":64,"genres":["Drama","Comedy","History"],"overview":"George W. Bush picks Dick Cheney, the CEO of Halliburton Co., to be his Republican running mate in the 2000 presidential election. No stranger to politics, Cheney's impressive r\u00e9sum\u00e9 includes stints as White House\u2026","poster":"assets/movie-vice-2018-poster.jpg","backdrop":"assets/movie-vice-2018-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:28:30.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":429197,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":64,"rtCriticsLabel":"Fresh","rtAudience":61,"rtAudienceLabel":"Upright","imdb":7.2,"imdbVotes":177299,"tmdb":7.014,"tmdbVotes":3723}},{"id":"movie-warriors-of-the-wind-1984","title":"Warriors of the Wind","year":1984,"type":"movie","runtimeSeconds":7022,"seasonCount":null,"communityRating":7.941,"criticRating":87,"genres":["Adventure","Animation","Fantasy"],"overview":"After a global war, the seaside kingdom known as the Valley of the Wind remains one of the last strongholds on Earth untouched by a poisonous jungle and the powerful insects that guard it. Led by the courageous\u2026","poster":"assets/movie-warriors-of-the-wind-1984-poster.jpg","backdrop":"assets/movie-warriors-of-the-wind-1984-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:22:20.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":81,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":87,"rtCriticsLabel":"Fresh","rtAudience":91,"rtAudienceLabel":"Upright","imdb":8,"imdbVotes":200154,"tmdb":7.94,"tmdbVotes":4260}},{"id":"movie-we-bury-the-dead-2026","title":"We Bury the Dead","year":2026,"type":"movie","runtimeSeconds":5693,"seasonCount":null,"communityRating":6.153,"criticRating":87,"genres":["Horror","Thriller"],"overview":"After a catastrophic military disaster reanimates the dead, Ava searches for her missing husband amidst an increasingly hostile world.","poster":"assets/movie-we-bury-the-dead-2026-poster.jpg","backdrop":"assets/movie-we-bury-the-dead-2026-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-08-26T05:36:00.4272328Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":1198984,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":87,"rtCriticsLabel":"Certified Fresh","rtAudience":45,"rtAudienceLabel":"Spilled","imdb":5.6,"imdbVotes":20693,"tmdb":6.137,"tmdbVotes":433}},{"id":"movie-white-hot-the-rise-fall-of-abercrombie-fitch-2022","title":"White Hot: The Rise & Fall of Abercrombie & Fitch","year":2022,"type":"movie","runtimeSeconds":5187,"seasonCount":null,"communityRating":5.663,"criticRating":66,"genres":["Documentary"],"overview":"All the cool kids were wearing it. This documentary explores A&F's pop culture reign in the late '90s and early 2000s and how it thrived on exclusion.","poster":"assets/movie-white-hot-the-rise-fall-of-abercrombie-fitch-2022-poster.jpg","backdrop":"assets/movie-white-hot-the-rise-fall-of-abercrombie-fitch-2022-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:30:34.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":953371,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":66,"rtCriticsLabel":"Fresh","rtAudience":29,"rtAudienceLabel":"Spilled","imdb":5.8,"imdbVotes":5655,"tmdb":5.7,"tmdbVotes":102}},{"id":"movie-the-wild-robot-2024","title":"The Wild Robot","year":2024,"type":"movie","runtimeSeconds":6101,"seasonCount":null,"communityRating":8.308,"criticRating":97,"genres":["Family","Animation","Science Fiction"],"overview":"After a shipwreck, an intelligent robot called Roz is stranded on an uninhabited island. To survive the harsh environment, Roz bonds with the island's animals and cares for an orphaned baby goose.","poster":"assets/movie-the-wild-robot-2024-poster.jpg","backdrop":"assets/movie-the-wild-robot-2024-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:31:49.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":1184918,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":97,"rtCriticsLabel":"Certified Fresh","rtAudience":98,"rtAudienceLabel":"Upright","imdb":8.1,"imdbVotes":241134,"tmdb":8.309,"tmdbVotes":6819}},{"id":"movie-the-wind-rises-2013","title":"The Wind Rises","year":2013,"type":"movie","runtimeSeconds":8031,"seasonCount":null,"communityRating":7.784,"criticRating":88,"genres":["Animation","Drama","History"],"overview":"A lifelong love of flight inspires Japanese aviation engineer Jiro Horikoshi, whose storied career includes the creation of the A-6M World War II fighter plane.","poster":"assets/movie-the-wind-rises-2013-poster.jpg","backdrop":"assets/movie-the-wind-rises-2013-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T10:24:38.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":149870,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":89,"rtCriticsLabel":"Certified Fresh","rtAudience":85,"rtAudienceLabel":"Upright","imdb":7.8,"imdbVotes":115756,"tmdb":7.783,"tmdbVotes":3536}},{"id":"movie-the-witcher-nightmare-of-the-wolf-2021","title":"The Witcher: Nightmare of the Wolf","year":2021,"type":"movie","runtimeSeconds":5015,"seasonCount":null,"communityRating":7.422,"criticRating":100,"genres":["Animation","Action","Fantasy"],"overview":"Escaping from poverty to become a witcher, Vesemir slays monsters for coin and glory, but when a new menace rises, he must face the demons of his past.","poster":"assets/movie-the-witcher-nightmare-of-the-wolf-2021-poster.jpg","backdrop":"assets/movie-the-witcher-nightmare-of-the-wolf-2021-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-26T04:42:03.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":666243,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":83,"rtAudienceLabel":"Upright","imdb":7.2,"imdbVotes":55759,"tmdb":7.407,"tmdbVotes":1159}},{"id":"movie-the-witcher-sirens-of-the-deep-2025","title":"The Witcher: Sirens of the Deep","year":2025,"type":"movie","runtimeSeconds":5517,"seasonCount":null,"communityRating":6.8,"criticRating":60,"genres":["Animation","Fantasy","Action"],"overview":"When human sailors are attacked by mysterious creatures of the deep, only one person can stop the war between land and sea: the Witcher, Geralt of Rivia.","poster":"assets/movie-the-witcher-sirens-of-the-deep-2025-poster.jpg","backdrop":"assets/movie-the-witcher-sirens-of-the-deep-2025-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-26T05:03:26.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":1203329,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":60,"rtCriticsLabel":"Fresh","rtAudience":37,"rtAudienceLabel":"Spilled","imdb":6.1,"imdbVotes":11799,"tmdb":6.741,"tmdbVotes":303}}],"shows":[{"id":"tv-adults-2025","title":"Adults","year":2025,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":6.495,"criticRating":null,"genres":["Comedy"],"overview":"A group of twenty-somethings in New York trying to be good people, despite being neither \"good\" nor \"people\" yet.","poster":"assets/tv-adults-2025-poster.jpg","backdrop":"assets/tv-adults-2025-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-23T21:01:41.1814765Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":260458,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":88,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.5,"tmdbVotes":102}},{"id":"tv-american-crime-story-2016","title":"American Crime Story","year":2016,"type":"tv","runtimeSeconds":null,"seasonCount":3,"communityRating":7.573,"criticRating":null,"genres":["Crime","Drama"],"overview":"An anthology series centered around some of history's most famous criminal investigations.","poster":"assets/tv-american-crime-story-2016-poster.jpg","backdrop":"assets/tv-american-crime-story-2016-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0490488Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":64513,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":84,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.585,"tmdbVotes":1094}},{"id":"tv-american-primeval-2025","title":"American Primeval","year":2025,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":7.691,"criticRating":null,"genres":["Western","Drama","Action & Adventure"],"overview":"A mother and son fleeing from their past form a found family while confronting a harsh landscape of freedom and cruelty in the American West.","poster":"assets/tv-american-primeval-2025-poster.jpg","backdrop":"assets/tv-american-primeval-2025-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0573221Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":215866,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":71,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.741,"tmdbVotes":538}},{"id":"tv-arrested-development-2003","title":"Arrested Development","year":2003,"type":"tv","runtimeSeconds":null,"seasonCount":5,"communityRating":7.925,"criticRating":null,"genres":["Comedy"],"overview":"The story of a wealthy family that lost everything, and the one son who had no choice but to keep them all together.","poster":"assets/tv-arrested-development-2003-poster.jpg","backdrop":"assets/tv-arrested-development-2003-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0513048Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":4589,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":75,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.906,"tmdbVotes":1793}},{"id":"tv-avatar-the-last-airbender-2005","title":"Avatar: The Last Airbender","year":2005,"type":"tv","runtimeSeconds":1440,"seasonCount":3,"communityRating":8.78,"criticRating":null,"genres":["Animation","Action & Adventure","Sci-Fi & Fantasy"],"overview":"In a war-torn world of elemental magic, a young boy reawakens to undertake a dangerous mystic quest to fulfill his destiny as the Avatar, and bring peace to the world.","poster":"assets/tv-avatar-the-last-airbender-2005-poster.jpg","backdrop":"assets/tv-avatar-the-last-airbender-2005-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0504536Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":246,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.787,"tmdbVotes":5215}},{"id":"tv-b-b-vol-liefde-2021","title":"B&B Vol Liefde","year":2021,"type":"tv","runtimeSeconds":3720,"seasonCount":1,"communityRating":7.2,"criticRating":null,"genres":["Reality"],"overview":"B&B Vol Liefde is a heartwarming adventure, full of romance, excitement, and unforgettable moments. Adventurous Dutch B&B owners abroad throw their doors wide open and let their hearts speak, determined to find that\u2026","poster":"assets/tv-b-b-vol-liefde-2021-poster.jpg","backdrop":"assets/tv-b-b-vol-liefde-2021-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-31T22:30:11.129657Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":124428,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.2,"tmdbVotes":10}},{"id":"tv-the-bear-2022","title":"The Bear","year":2022,"type":"tv","runtimeSeconds":null,"seasonCount":5,"communityRating":8.139,"criticRating":null,"genres":["Drama","Comedy"],"overview":"Carmy, a young fine-dining chef, comes home to Chicago to run his family sandwich shop. As he fights to transform the shop and himself, he works alongside a rough-around-the-edges crew that ultimately reveal\u2026","poster":"assets/tv-the-bear-2022-poster.jpg","backdrop":"assets/tv-the-bear-2022-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0467371Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":136315,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":93,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.158,"tmdbVotes":2025}},{"id":"tv-blue-planet-ii-2017","title":"Blue Planet II","year":2017,"type":"tv","runtimeSeconds":3600,"seasonCount":1,"communityRating":8.64,"criticRating":null,"genres":["Documentary","Family"],"overview":"There is nowhere more powerful and unforgiving yet more beautiful and compelling than the ocean. Join us and explore the greatest yet least known parts of our planet.","poster":"assets/tv-blue-planet-ii-2017-poster.jpg","backdrop":"assets/tv-blue-planet-ii-2017-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0634849Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":74313,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":97,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.6,"tmdbVotes":380}},{"id":"tv-breeders-2020","title":"Breeders","year":2020,"type":"tv","runtimeSeconds":1500,"seasonCount":4,"communityRating":6.8,"criticRating":null,"genres":["Comedy"],"overview":"Exposing the parental-paradox that it is possible, in the very same moment, to love your child to the horizon of the universe, while being apoplectically angry enough to want to send them there.","poster":"assets/tv-breeders-2020-poster.jpg","backdrop":"assets/tv-breeders-2020-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-28T18:54:21.8885435Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":93290,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":92,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.8,"tmdbVotes":104}},{"id":"tv-chernobyl-2019","title":"Chernobyl","year":2019,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":8.718,"criticRating":null,"genres":["Drama"],"overview":"The true story of one of the worst man-made catastrophes in history: the catastrophic nuclear accident at Chernobyl. A tale of the brave men and women who sacrificed to save Europe from unimaginable disaster.","poster":"assets/tv-chernobyl-2019-poster.jpg","backdrop":"assets/tv-chernobyl-2019-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0469903Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":87108,"artwork":{"posterKind":"poster","backdropKind":"center_crop"},"ratings":{"rtCritics":95,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.731,"tmdbVotes":8496}},{"id":"tv-community-2009","title":"Community","year":2009,"type":"tv","runtimeSeconds":null,"seasonCount":6,"communityRating":7.997,"criticRating":null,"genres":["Comedy"],"overview":"Follow the lives of a group of students at what is possibly the world\u2019s worst community college in the fictional locale of Greendale, Colorado.","poster":"assets/tv-community-2009-poster.jpg","backdrop":"assets/tv-community-2009-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0531416Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":18347,"artwork":{"posterKind":"center_crop","backdropKind":"backdrop"},"ratings":{"rtCritics":88,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.994,"tmdbVotes":2226}},{"id":"tv-dead-end-job-2026","title":"Dead-End Job","year":2026,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":7.7,"criticRating":null,"genres":["Mystery"],"overview":"Drowning in debt, a young man takes lucrative part-time jobs from a mysterious agency \u2014 only to find his hustle for more money turning nightmarish.","poster":"assets/tv-dead-end-job-2026-poster.jpg","backdrop":"assets/tv-dead-end-job-2026-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-11-04T18:58:01.8352857Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":289517,"artwork":{"posterKind":"center_crop","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.7,"tmdbVotes":38}},{"id":"tv-dopesick-2021","title":"Dopesick","year":2021,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":8.015,"criticRating":null,"genres":["Crime","Drama"],"overview":"The story of how one company triggered the worst drug epidemic in American history. Look into the epicenter of America's struggle with opioid addiction, from a distressed Virginia mining community, to the hallways of\u2026","poster":"assets/tv-dopesick-2021-poster.jpg","backdrop":"assets/tv-dopesick-2021-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0580168Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":110695,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":89,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.035,"tmdbVotes":565}},{"id":"tv-dune-prophecy-2024","title":"Dune: Prophecy","year":2024,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":7.213,"criticRating":null,"genres":["Sci-Fi & Fantasy","Drama","Action & Adventure"],"overview":"Ten thousand years before the ascension of Paul Atreides, sisters Valya and Tula Harkonnen establish the fabled sect and female order that would become known as the Bene Gesserit to control the future of humankind.","poster":"assets/tv-dune-prophecy-2024-poster.jpg","backdrop":"assets/tv-dune-prophecy-2024-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-11-04T18:23:01.2908568Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":90228,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":64,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.213,"tmdbVotes":677}},{"id":"tv-east-of-eden-2026","title":"East of Eden","year":2026,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":7.931,"criticRating":null,"genres":["Drama","Crime"],"overview":"In the early 1900s, a fiercely independent woman drives a rift between two brothers, igniting a saga that unfolds across two generations.","poster":"assets/tv-east-of-eden-2026-poster.jpg","backdrop":"assets/tv-east-of-eden-2026-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-23T18:07:11.3965096Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":258165,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":88,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.982,"tmdbVotes":139}},{"id":"tv-fallout-2024","title":"Fallout","year":2024,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":8.124,"criticRating":null,"genres":["Action & Adventure","Sci-Fi & Fantasy","Drama"],"overview":"The story of haves and have-nots in a world in which there's almost nothing left to have. 200 years after the apocalypse, the gentle denizens of luxury fallout shelters are forced to return to the irradiated\u2026","poster":"assets/tv-fallout-2024-poster.jpg","backdrop":"assets/tv-fallout-2024-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0669262Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":106379,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":94,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.106,"tmdbVotes":3233}},{"id":"tv-fawlty-towers-1975","title":"Fawlty Towers","year":1975,"type":"tv","runtimeSeconds":1800,"seasonCount":2,"communityRating":8.295,"criticRating":null,"genres":["Comedy"],"overview":"Owner Basil Fawlty, his wife Sybil, a chambermaid Polly, and Spanish waiter Manuel attempt to run their hotel amidst farcical situations and an array of demanding guests.","poster":"assets/tv-fawlty-towers-1975-poster.jpg","backdrop":"assets/tv-fawlty-towers-1975-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-19T23:26:39.7658344Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":2207,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.296,"tmdbVotes":867}},{"id":"tv-the-final-problem-2026","title":"The Final Problem","year":2026,"type":"tv","runtimeSeconds":3420,"seasonCount":1,"communityRating":7.041,"criticRating":null,"genres":["Crime","Mystery"],"overview":"In the spring of 1959, a retired actor, who previously played Sherlock Holmes, must investigate a murder at a small hotel on a tiny island near Mallorca.","poster":"assets/tv-the-final-problem-2026-poster.jpg","backdrop":"assets/tv-the-final-problem-2026-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-11-04T19:16:12.4822791Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":290720,"artwork":{"posterKind":"center_crop","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.041,"tmdbVotes":49}},{"id":"tv-the-four-seasons-2025","title":"The Four Seasons","year":2025,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":6.879,"criticRating":null,"genres":["Comedy"],"overview":"The decades-long friendship between three married couples is tested when one divorces, complicating their tradition of quarterly weekend getaways.","poster":"assets/tv-the-four-seasons-2025-poster.jpg","backdrop":"assets/tv-the-four-seasons-2025-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-28T18:36:42.5326384Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":243316,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":81,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.892,"tmdbVotes":204}},{"id":"tv-the-get-down-2016","title":"The Get Down","year":2016,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":7.3,"criticRating":null,"genres":["Drama"],"overview":"In 1977 New York City, the talented and soulful youth of the South Bronx chase dreams and breakneck beats to transform music history.","poster":"assets/tv-the-get-down-2016-poster.jpg","backdrop":"assets/tv-the-get-down-2016-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0497737Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":65345,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":81,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.3,"tmdbVotes":196}},{"id":"tv-how-to-change-your-mind-2022","title":"How to Change Your Mind","year":2022,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":7.76,"criticRating":null,"genres":["Documentary","Mystery"],"overview":"Author Michael Pollan leads the way in this docuseries exploring the history and uses of psychedelics, including LSD, psilocybin, MDMA and mescaline.","poster":"assets/tv-how-to-change-your-mind-2022-poster.jpg","backdrop":"assets/tv-how-to-change-your-mind-2022-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0601399Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":204304,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.8,"tmdbVotes":53}},{"id":"tv-interrogation-2020","title":"Interrogation","year":2020,"type":"tv","runtimeSeconds":2700,"seasonCount":1,"communityRating":6.788,"criticRating":null,"genres":["Drama","Crime"],"overview":"Based on a true story that spanned more than 30 years in which a young man was charged and convicted of brutally murdering his mother. Each episode is structured around an interrogation taken directly from the real\u2026","poster":"assets/tv-interrogation-2020-poster.jpg","backdrop":"assets/tv-interrogation-2020-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-26T05:52:06.1068207Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":96488,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":57,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.9,"tmdbVotes":54}},{"id":"tv-it-s-always-sunny-in-philadelphia-2005","title":"It's Always Sunny in Philadelphia","year":2005,"type":"tv","runtimeSeconds":null,"seasonCount":18,"communityRating":8.2,"criticRating":null,"genres":["Comedy"],"overview":"Four egocentric friends run a neighborhood Irish pub in Philadelphia and try to find their way through the adult world of work and relationships. Unfortunately, their warped views and precarious judgments often lead\u2026","poster":"assets/tv-it-s-always-sunny-in-philadelphia-2005-poster.jpg","backdrop":"assets/tv-it-s-always-sunny-in-philadelphia-2005-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0485774Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":2710,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":94,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.253,"tmdbVotes":1457}},{"id":"tv-a-knight-of-the-seven-kingdoms-2026","title":"A Knight of the Seven Kingdoms","year":2026,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":8.431,"criticRating":null,"genres":["Drama","Sci-Fi & Fantasy","Action & Adventure"],"overview":"A century before the events of Game of Thrones, two unlikely heroes wandered Westeros: a young, naive but courageous knight, Ser Duncan the Tall, and his diminutive squire, Egg. Set in an age when the Targaryen line\u2026","poster":"assets/tv-a-knight-of-the-seven-kingdoms-2026-poster.jpg","backdrop":"assets/tv-a-knight-of-the-seven-kingdoms-2026-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0493344Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":224372,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":94,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.4,"tmdbVotes":1266}},{"id":"tv-landman-2024","title":"Landman","year":2024,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":8.194,"criticRating":null,"genres":["Drama"],"overview":"Set in the proverbial boomtowns of West-Texas and a modern-day tale of fortune-seeking in the world of oil rigs, the series is an upstairs/downstairs story of roughnecks and wildcat billionaires that are fueling a\u2026","poster":"assets/tv-landman-2024-poster.jpg","backdrop":"assets/tv-landman-2024-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-22T21:38:18.0973875Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":157741,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":80,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.209,"tmdbVotes":668}},{"id":"tv-the-last-of-us-2023","title":"The Last of Us","year":2023,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":8.419,"criticRating":null,"genres":["Drama"],"overview":"Twenty years after modern civilization has been destroyed, Joel, a hardened survivor, is hired to smuggle Ellie, a 14-year-old girl, out of an oppressive quarantine zone. What starts as a small job soon becomes a\u2026","poster":"assets/tv-the-last-of-us-2023-poster.jpg","backdrop":"assets/tv-the-last-of-us-2023-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0640955Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":100088,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":94,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.4,"tmdbVotes":7485}},{"id":"tv-last-samurai-standing-2025","title":"Last Samurai Standing","year":2025,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":7.805,"criticRating":null,"genres":["Action & Adventure","Drama"],"overview":"In the early Meiji era, Shujiro, once known as an undefeated samurai, decides to participate in a deadly survival game to save his family and villagers.","poster":"assets/tv-last-samurai-standing-2025-poster.jpg","backdrop":"assets/tv-last-samurai-standing-2025-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0622526Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":252193,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.812,"tmdbVotes":271}},{"id":"tv-lord-of-the-flies-2026","title":"Lord of the Flies","year":2026,"type":"tv","runtimeSeconds":3480,"seasonCount":1,"communityRating":7.571,"criticRating":null,"genres":["Drama","Action & Adventure"],"overview":"After a plane crash, a group of schoolboys find themselves stranded on a tropical island without adults. Ralph is elected leader and, with the help of the intelligent Piggy, strives to maintain order and\u2026","poster":"assets/tv-lord-of-the-flies-2026-poster.jpg","backdrop":"assets/tv-lord-of-the-flies-2026-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0645648Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":270572,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":91,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.58,"tmdbVotes":138}},{"id":"tv-the-lord-of-the-rings-the-rings-of-power-2022","title":"The Lord of the Rings: The Rings of Power","year":2022,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":7.233,"criticRating":null,"genres":["Action & Adventure","Sci-Fi & Fantasy","Drama"],"overview":"Beginning in a time of relative peace, we follow an ensemble cast of characters as they confront the re-emergence of evil to Middle-earth. From the darkest depths of the Misty Mountains, to the majestic forests of\u2026","poster":"assets/tv-the-lord-of-the-rings-the-rings-of-power-2022-poster.jpg","backdrop":"assets/tv-the-lord-of-the-rings-the-rings-of-power-2022-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0618904Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":84773,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":84,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.211,"tmdbVotes":4003}},{"id":"tv-love-death-robots-2019","title":"Love, Death & Robots","year":2019,"type":"tv","runtimeSeconds":null,"seasonCount":4,"communityRating":8.21,"criticRating":null,"genres":["Animation","Sci-Fi & Fantasy"],"overview":"Terrifying creatures, wicked surprises and dark comedy converge in this NSFW anthology of animated stories presented by Tim Miller and David Fincher.","poster":"assets/tv-love-death-robots-2019-poster.jpg","backdrop":"assets/tv-love-death-robots-2019-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0460964Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":86831,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":89,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.203,"tmdbVotes":4238}},{"id":"tv-maniac-2018","title":"Maniac","year":2018,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":7.338,"criticRating":null,"genres":["Comedy","Drama","Sci-Fi & Fantasy"],"overview":"Two strangers are drawn to a mysterious pharmaceutical trial that will, they're assured, with no complications or side-effects whatsoever, solve all of their problems, permanently. Things do not go as planned.","poster":"assets/tv-maniac-2018-poster.jpg","backdrop":"assets/tv-maniac-2018-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-20T19:42:30.955548Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":73411,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":84,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.323,"tmdbVotes":1073}},{"id":"tv-mussolini-son-of-the-century-2024","title":"Mussolini: Son of the Century","year":2024,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":8.135,"criticRating":null,"genres":["Drama","War & Politics"],"overview":"The rise of Benito Mussolini and the birth of fascism in Italy, chronicling a country\u2019s surrender to dictatorship and the relentless ascent of a man who rose from his ashes time and again.","poster":"assets/tv-mussolini-son-of-the-century-2024-poster.jpg","backdrop":"assets/tv-mussolini-son-of-the-century-2024-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0586588Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":212333,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":96,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.1,"tmdbVotes":179}},{"id":"tv-the-night-manager-2016","title":"The Night Manager","year":2016,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":7.74,"criticRating":null,"genres":["Drama","Mystery","Crime"],"overview":"Former British soldier Jonathan Pine navigates the shadowy recesses of Whitehall and Washington where an unholy alliance operates between the intelligence community and the secret arms trade. To infiltrate the inner\u2026","poster":"assets/tv-the-night-manager-2016-poster.jpg","backdrop":"assets/tv-the-night-manager-2016-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0663672Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":61859,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":88,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.7,"tmdbVotes":1422}},{"id":"tv-one-piece-2023","title":"ONE PIECE","year":2023,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":8.118,"criticRating":null,"genres":["Action & Adventure","Sci-Fi & Fantasy"],"overview":"With his straw hat and ragtag crew, young pirate Monkey D. Luffy goes on an epic voyage for treasure.","poster":"assets/tv-one-piece-2023-poster.jpg","backdrop":"assets/tv-one-piece-2023-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0439378Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":111110,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":93,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.104,"tmdbVotes":1988}},{"id":"tv-only-murders-in-the-building-2021","title":"Only Murders in the Building","year":2021,"type":"tv","runtimeSeconds":null,"seasonCount":5,"communityRating":8.438,"criticRating":null,"genres":["Comedy","Mystery","Crime"],"overview":"Three strangers share an obsession with true crime and suddenly find themselves wrapped up in one.","poster":"assets/tv-only-murders-in-the-building-2021-poster.jpg","backdrop":"assets/tv-only-murders-in-the-building-2021-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0594614Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":107113,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":95,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.398,"tmdbVotes":2333}},{"id":"tv-over-the-garden-wall-2014","title":"Over the Garden Wall","year":2014,"type":"tv","runtimeSeconds":720,"seasonCount":1,"communityRating":8.6,"criticRating":null,"genres":["Mystery","Sci-Fi & Fantasy","Animation"],"overview":"Two brothers, Wirt and Greg, find themselves lost in the Unknown; a strange forest adrift in time. With the help of a wise old Woodsman and a foul-tempered bluebird named Beatrice, Wirt and Greg must travel across\u2026","poster":"assets/tv-over-the-garden-wall-2014-poster.jpg","backdrop":"assets/tv-over-the-garden-wall-2014-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0455757Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":61617,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.6,"tmdbVotes":1854}},{"id":"tv-peaky-blinders-2013","title":"Peaky Blinders","year":2013,"type":"tv","runtimeSeconds":null,"seasonCount":6,"communityRating":8.5,"criticRating":null,"genres":["Drama","Crime"],"overview":"A gangster family epic set in 1919 Birmingham, England and centered on a gang who sew razor blades in the peaks of their caps, and their fierce boss Tommy Shelby, who means to move up in the world.","poster":"assets/tv-peaky-blinders-2013-poster.jpg","backdrop":"assets/tv-peaky-blinders-2013-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0539185Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":60574,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":93,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.5,"tmdbVotes":11506}},{"id":"tv-the-pitt-2025","title":"The Pitt","year":2025,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":8.729,"criticRating":null,"genres":["Drama"],"overview":"The staff of Pittsburgh's Trauma Medical Center work around the clock to save lives in an overcrowded and underfunded emergency department.","poster":"assets/tv-the-pitt-2025-poster.jpg","backdrop":"assets/tv-the-pitt-2025-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0582942Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":250307,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":96,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.731,"tmdbVotes":1046}},{"id":"tv-pluribus-2025","title":"Pluribus","year":2025,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":7.936,"criticRating":null,"genres":["Drama","Sci-Fi & Fantasy"],"overview":"The most miserable person on Earth must save the world from happiness.","poster":"assets/tv-pluribus-2025-poster.jpg","backdrop":"assets/tv-pluribus-2025-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0674462Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":225171,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":99,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.921,"tmdbVotes":1191}},{"id":"tv-ripley-2024","title":"RIPLEY","year":2024,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":7.911,"criticRating":null,"genres":["Drama"],"overview":"A grifter in 1960s New York is hired to convince a wealthy man's son to return home from Italy and begins a life of deceit, fraud and murder.","poster":"assets/tv-ripley-2024-poster.jpg","backdrop":"assets/tv-ripley-2024-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0658942Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":94028,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":86,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.909,"tmdbVotes":453}},{"id":"tv-say-nothing-2024","title":"Say Nothing","year":2024,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":7.462,"criticRating":null,"genres":["Drama","Crime"],"overview":"Through the eyes of various Irish Republican Army (IRA) members, explore the extremes some people will go to in the name of their beliefs, the way a deeply divided society can suddenly tip over into armed conflict,\u2026","poster":"assets/tv-say-nothing-2024-poster.jpg","backdrop":"assets/tv-say-nothing-2024-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0499752Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":245256,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":94,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.475,"tmdbVotes":122}},{"id":"tv-severance-2022","title":"Severance","year":2022,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":8.396,"criticRating":null,"genres":["Drama","Mystery","Sci-Fi & Fantasy"],"overview":"Mark leads a team of office workers whose memories have been surgically divided between their work and personal lives. When a mysterious colleague appears outside of work, it begins a journey to discover the truth\u2026","poster":"assets/tv-severance-2022-poster.jpg","backdrop":"assets/tv-severance-2022-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0598478Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":95396,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":95,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.389,"tmdbVotes":3095}},{"id":"tv-six-feet-under-2001","title":"Six Feet Under","year":2001,"type":"tv","runtimeSeconds":null,"seasonCount":5,"communityRating":8.115,"criticRating":null,"genres":["Drama"],"overview":"When death is your business, what is your life? For the Fisher family, the world outside of their family-owned funeral home continues to be at least as challenging as\u2014and far less predictable than\u2014the one inside.","poster":"assets/tv-six-feet-under-2001-poster.jpg","backdrop":"assets/tv-six-feet-under-2001-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-09-26T04:04:05.108787Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":1274,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":81,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.1,"tmdbVotes":1192}},{"id":"tv-undercover-2019","title":"Undercover","year":2019,"type":"tv","runtimeSeconds":3000,"seasonCount":3,"communityRating":7.5,"criticRating":null,"genres":["Crime","Drama"],"overview":"Undercover agents infiltrate a drug kingpin's operation by posing as a couple at the campground where he spends his weekends. Inspired by real events.","poster":"assets/tv-undercover-2019-poster.jpg","backdrop":"assets/tv-undercover-2019-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0570153Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":86942,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.5,"tmdbVotes":186}},{"id":"tv-upload-2020","title":"Upload","year":2020,"type":"tv","runtimeSeconds":null,"seasonCount":4,"communityRating":7.781,"criticRating":null,"genres":["Comedy","Sci-Fi & Fantasy","Drama"],"overview":"In 2033, people who are near death can be \u201cuploaded\u201d into virtual reality hotels run by 6 tech firms. Cash-strapped Nora lives in Brooklyn and works customer service for the luxurious \u201cLakeview\u201d digital afterlife.\u2026","poster":"assets/tv-upload-2020-poster.jpg","backdrop":"assets/tv-upload-2020-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0566967Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":86248,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":87,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.757,"tmdbVotes":1511}},{"id":"tv-the-walk-in-2022","title":"The Walk-In","year":2022,"type":"tv","runtimeSeconds":2760,"seasonCount":1,"communityRating":6.9,"criticRating":null,"genres":["Drama","Crime"],"overview":"Forced to flee the UK and go into hiding in the 1990s, when he became a mole from within the BNP, Matthew Collins returned to Britain to make a new life for himself, working with young white men in the fight against\u2026","poster":"assets/tv-the-walk-in-2022-poster.jpg","backdrop":"assets/tv-the-walk-in-2022-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0654569Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":210664,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":80,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7,"tmdbVotes":50}},{"id":"tv-the-white-lotus-2021","title":"The White Lotus","year":2021,"type":"tv","runtimeSeconds":null,"seasonCount":3,"communityRating":7.596,"criticRating":null,"genres":["Comedy","Drama","Mystery"],"overview":"Follow the exploits of various guests and employees at an exclusive tropical resort over the span of a week as with each passing day, a darker complexity emerges in these picture-perfect travelers, the hotel\u2019s\u2026","poster":"assets/tv-the-white-lotus-2021-poster.jpg","backdrop":"assets/tv-the-white-lotus-2021-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0546438Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":111803,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":90,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.599,"tmdbVotes":1604}},{"id":"tv-widow-s-bay-2026","title":"Widow's Bay","year":2026,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":8.172,"criticRating":null,"genres":["Drama","Comedy","Mystery"],"overview":"The mayor of a New England town resolves to turn it into the next tourist hot spot, despite local warnings that it's cursed.","poster":"assets/tv-widow-s-bay-2026-poster.jpg","backdrop":"assets/tv-widow-s-bay-2026-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-20T10:27:12.7003979Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":270476,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":98,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8,"tmdbVotes":585}},{"id":"tv-the-witcher-2019","title":"The Witcher","year":2019,"type":"tv","runtimeSeconds":null,"seasonCount":4,"communityRating":7.905,"criticRating":null,"genres":["Drama","Action & Adventure"],"overview":"Geralt of Rivia, a mutated monster-hunter for hire, journeys toward his destiny in a turbulent world where people often prove more wicked than beasts.","poster":"assets/tv-the-witcher-2019-poster.jpg","backdrop":"assets/tv-the-witcher-2019-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0552369Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":71912,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":75,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.88,"tmdbVotes":6997}},{"id":"tv-yellowjackets-2021","title":"Yellowjackets","year":2021,"type":"tv","runtimeSeconds":null,"seasonCount":3,"communityRating":7.449,"criticRating":null,"genres":["Drama","Mystery"],"overview":"This equal parts survival epic, psychological horror story and coming-of-age drama tells the saga of a team of wildly talented high school girls soccer players who become the (un)lucky survivors of a plane crash deep\u2026","poster":"assets/tv-yellowjackets-2021-poster.jpg","backdrop":"assets/tv-yellowjackets-2021-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T15:45:22.0577612Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":117488,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":92,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.431,"tmdbVotes":1070}}],"anime":[],"resume":[{"id":"episode-episode-1-2025-s1e1","title":"Episode 1","year":2025,"type":"episode","runtimeSeconds":3618,"seasonCount":null,"communityRating":7.357,"criticRating":null,"genres":["Biography","Drama","History"],"overview":"Mussolini had just founded the Fasci di Combattimento when D'Annunzio took Fiume. Mussolini hoped to capitalize on the poet's achievement in the electoral arena.","poster":"assets/episode-episode-1-2025-s1e1-poster.jpg","backdrop":"assets/episode-episode-1-2025-s1e1-backdrop.jpg","played":false,"playCount":1,"resumeSeconds":489.55,"progress":0.1353,"addedAt":"2026-07-17T13:52:48.0000000Z","lastPlayedAt":"2026-11-04T19:01:49.9731435Z","availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"Mussolini: Son of the Century","seasonNumber":1,"episodeNumber":1,"artwork":{"posterKind":"center_crop","backdropKind":"backdrop"}}],"nextUp":[{"id":"episode-no-honeymoon-2020-s1e8","title":"No Honeymoon","year":2020,"type":"episode","runtimeSeconds":1499,"seasonCount":null,"communityRating":6.7,"criticRating":null,"genres":["Comedy","Drama"],"overview":"Paul attempts to focus on his upcoming wedding but is constantly thwarted by his family; Ally is distracted by work, Luke is misbehaving at school and Leah (Stella Gonet) doesn\u2019t understand why they are even\u2026","poster":"assets/episode-no-honeymoon-2020-s1e8-poster.jpg","backdrop":"assets/episode-no-honeymoon-2020-s1e8-backdrop.jpg","played":false,"playCount":1,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-28T19:00:50.0000000Z","lastPlayedAt":"2026-11-03T20:57:58.3314947Z","availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"Breeders","seasonNumber":1,"episodeNumber":8,"artwork":{"posterKind":"poster","backdropKind":"backdrop"}},{"id":"episode-notapusy-2005-s3e4","title":"Notapusy","year":2005,"type":"episode","runtimeSeconds":1334,"seasonCount":null,"communityRating":8.125,"criticRating":null,"genres":["Comedy"],"overview":"To prove he's a man to Rita, Michael and his nephew Steve Holt compete in the Church And State Fair's annual triathlon. George Sr. tries to scare some at-risk youth, and Tobias tries to help George-Michael's\u2026","poster":"assets/episode-notapusy-2005-s3e4-poster.jpg","backdrop":"assets/episode-notapusy-2005-s3e4-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T12:17:58.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"Arrested Development","seasonNumber":3,"episodeNumber":4,"artwork":{"posterKind":"poster","backdropKind":"backdrop"}},{"id":"episode-the-man-who-would-be-vogue-2018-s2e1","title":"The Man Who Would Be Vogue","year":2018,"type":"episode","runtimeSeconds":3203,"seasonCount":null,"communityRating":7.459,"criticRating":null,"genres":["Biography","Crime","Drama"],"overview":"The murder of Gianni Versace turns the eyes of the world onto Miami Beach.","poster":"assets/episode-the-man-who-would-be-vogue-2018-s2e1-poster.jpg","backdrop":"assets/episode-the-man-who-would-be-vogue-2018-s2e1-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T13:29:35.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"American Crime Story","seasonNumber":2,"episodeNumber":1,"artwork":{"posterKind":"poster","backdropKind":"backdrop"}},{"id":"episode-tomorrow-2024-s3e1","title":"Tomorrow","year":2024,"type":"episode","runtimeSeconds":2207,"seasonCount":null,"communityRating":7.6,"criticRating":null,"genres":["Comedy","Drama"],"overview":"The next day and the days that led to it.","poster":"assets/episode-tomorrow-2024-s3e1-poster.jpg","backdrop":"assets/episode-tomorrow-2024-s3e1-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-07-17T13:46:39.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"The Bear","seasonNumber":3,"episodeNumber":1,"artwork":{"posterKind":"poster","backdropKind":"backdrop"}},{"id":"episode-episode-1-2025-s1e1","title":"Episode 1","year":2025,"type":"episode","runtimeSeconds":3618,"seasonCount":null,"communityRating":7.357,"criticRating":null,"genres":["Biography","Drama","History"],"overview":"Mussolini had just founded the Fasci di Combattimento when D'Annunzio took Fiume. Mussolini hoped to capitalize on the poet's achievement in the electoral arena.","poster":"assets/episode-episode-1-2025-s1e1-poster.jpg","backdrop":"assets/episode-episode-1-2025-s1e1-backdrop.jpg","played":false,"playCount":1,"resumeSeconds":489.55,"progress":0.1353,"addedAt":"2026-07-17T13:52:48.0000000Z","lastPlayedAt":"2026-11-04T19:01:49.9731435Z","availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","seriesTitle":"Mussolini: Son of the Century","seasonNumber":1,"episodeNumber":1,"artwork":{"posterKind":"center_crop","backdropKind":"backdrop"}}],"recentlyAdded":[{"id":"tv-the-final-problem-2026","title":"The Final Problem","year":2026,"type":"tv","runtimeSeconds":3420,"seasonCount":1,"communityRating":7.041,"criticRating":null,"genres":["Crime","Mystery"],"overview":"In the spring of 1959, a retired actor, who previously played Sherlock Holmes, must investigate a murder at a small hotel on a tiny island near Mallorca.","poster":"assets/tv-the-final-problem-2026-poster.jpg","backdrop":"assets/tv-the-final-problem-2026-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-11-04T19:16:12.4822791Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":290720,"artwork":{"posterKind":"center_crop","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.041,"tmdbVotes":49}},{"id":"tv-dead-end-job-2026","title":"Dead-End Job","year":2026,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":7.7,"criticRating":null,"genres":["Mystery"],"overview":"Drowning in debt, a young man takes lucrative part-time jobs from a mysterious agency \u2014 only to find his hustle for more money turning nightmarish.","poster":"assets/tv-dead-end-job-2026-poster.jpg","backdrop":"assets/tv-dead-end-job-2026-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-11-04T18:58:01.8352857Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":289517,"artwork":{"posterKind":"center_crop","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.7,"tmdbVotes":38}},{"id":"tv-dune-prophecy-2024","title":"Dune: Prophecy","year":2024,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":7.213,"criticRating":null,"genres":["Sci-Fi & Fantasy","Drama","Action & Adventure"],"overview":"Ten thousand years before the ascension of Paul Atreides, sisters Valya and Tula Harkonnen establish the fabled sect and female order that would become known as the Bene Gesserit to control the future of humankind.","poster":"assets/tv-dune-prophecy-2024-poster.jpg","backdrop":"assets/tv-dune-prophecy-2024-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-11-04T18:23:01.2908568Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":90228,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":64,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.213,"tmdbVotes":677}},{"id":"movie-the-uprising-2026","title":"The Uprising","year":2026,"type":"movie","runtimeSeconds":7684,"seasonCount":null,"communityRating":7.846,"criticRating":55,"genres":["Action","Drama","History"],"overview":"As war and plague devastate 14th-century England, a humble peasant ignites a rebellion, uniting an army of commoners to defy the King\u2019s might in a desperate fight for justice and survival.","poster":"assets/movie-the-uprising-2026-poster.jpg","backdrop":"assets/movie-the-uprising-2026-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-11-02T16:37:03.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":977942,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":57,"rtCriticsLabel":"Rotten","rtAudience":65,"rtAudienceLabel":"Upright","imdb":6.2,"imdbVotes":6622,"tmdb":7.8,"tmdbVotes":404}},{"id":"movie-jennifer-s-body-2009","title":"Jennifer's Body","year":2009,"type":"movie","runtimeSeconds":6450,"seasonCount":null,"communityRating":6.012,"criticRating":47,"genres":["Horror","Comedy"],"overview":"Jennifer, a gorgeous, seductive cheerleader takes evil to a whole new level after she's possessed by a sinister demon. Now it's up to her best friend to stop Jennifer's reign of terror before it's too late.","poster":"assets/movie-jennifer-s-body-2009-poster.jpg","backdrop":"assets/movie-jennifer-s-body-2009-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-30T03:37:04.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":19994,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":47,"rtCriticsLabel":"Rotten","rtAudience":36,"rtAudienceLabel":"Spilled","imdb":5.6,"imdbVotes":179710,"tmdb":6.013,"tmdbVotes":4481}},{"id":"tv-breeders-2020","title":"Breeders","year":2020,"type":"tv","runtimeSeconds":1500,"seasonCount":4,"communityRating":6.8,"criticRating":null,"genres":["Comedy"],"overview":"Exposing the parental-paradox that it is possible, in the very same moment, to love your child to the horizon of the universe, while being apoplectically angry enough to want to send them there.","poster":"assets/tv-breeders-2020-poster.jpg","backdrop":"assets/tv-breeders-2020-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-28T18:54:21.8885435Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":93290,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":92,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.8,"tmdbVotes":104}},{"id":"tv-the-four-seasons-2025","title":"The Four Seasons","year":2025,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":6.879,"criticRating":null,"genres":["Comedy"],"overview":"The decades-long friendship between three married couples is tested when one divorces, complicating their tradition of quarterly weekend getaways.","poster":"assets/tv-the-four-seasons-2025-poster.jpg","backdrop":"assets/tv-the-four-seasons-2025-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-28T18:36:42.5326384Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":243316,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":81,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.892,"tmdbVotes":204}},{"id":"tv-adults-2025","title":"Adults","year":2025,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":6.495,"criticRating":null,"genres":["Comedy"],"overview":"A group of twenty-somethings in New York trying to be good people, despite being neither \"good\" nor \"people\" yet.","poster":"assets/tv-adults-2025-poster.jpg","backdrop":"assets/tv-adults-2025-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-23T21:01:41.1814765Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":260458,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":88,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.5,"tmdbVotes":102}},{"id":"tv-east-of-eden-2026","title":"East of Eden","year":2026,"type":"tv","runtimeSeconds":null,"seasonCount":1,"communityRating":7.931,"criticRating":null,"genres":["Drama","Crime"],"overview":"In the early 1900s, a fiercely independent woman drives a rift between two brothers, igniting a saga that unfolds across two generations.","poster":"assets/tv-east-of-eden-2026-poster.jpg","backdrop":"assets/tv-east-of-eden-2026-backdrop.jpg","played":true,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-23T18:07:11.3965096Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":258165,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":88,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.982,"tmdbVotes":139}},{"id":"movie-fighting-with-my-family-2019","title":"Fighting with My Family","year":2019,"type":"movie","runtimeSeconds":6509,"seasonCount":null,"communityRating":6.84,"criticRating":93,"genres":["Comedy"],"overview":"Born into a tight-knit wrestling family, Paige and her brother Zak are ecstatic when they get the once-in-a-lifetime opportunity to try out for the WWE. But when only Paige earns a spot in the competitive training\u2026","poster":"assets/movie-fighting-with-my-family-2019-poster.jpg","backdrop":"assets/movie-fighting-with-my-family-2019-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-22T22:10:59.0000000Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":445629,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":93,"rtCriticsLabel":"Certified Fresh","rtAudience":86,"rtAudienceLabel":"Upright","imdb":7,"imdbVotes":94576,"tmdb":6.837,"tmdbVotes":1952}},{"id":"tv-landman-2024","title":"Landman","year":2024,"type":"tv","runtimeSeconds":null,"seasonCount":2,"communityRating":8.194,"criticRating":null,"genres":["Drama"],"overview":"Set in the proverbial boomtowns of West-Texas and a modern-day tale of fortune-seeking in the world of oil rigs, the series is an upstairs/downstairs story of roughnecks and wildcat billionaires that are fueling a\u2026","poster":"assets/tv-landman-2024-poster.jpg","backdrop":"assets/tv-landman-2024-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-22T21:38:18.0973875Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":157741,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":80,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.209,"tmdbVotes":668}},{"id":"tv-fawlty-towers-1975","title":"Fawlty Towers","year":1975,"type":"tv","runtimeSeconds":1800,"seasonCount":2,"communityRating":8.295,"criticRating":null,"genres":["Comedy"],"overview":"Owner Basil Fawlty, his wife Sybil, a chambermaid Polly, and Spanish waiter Manuel attempt to run their hotel amidst farcical situations and an array of demanding guests.","poster":"assets/tv-fawlty-towers-1975-poster.jpg","backdrop":"assets/tv-fawlty-towers-1975-backdrop.jpg","played":false,"playCount":0,"resumeSeconds":0.0,"progress":0,"addedAt":"2026-10-19T23:26:39.7658344Z","lastPlayedAt":null,"availability":"in_library","availabilityEvidence":"viewer_scoped_jellyfin_library","source":"jellyfin_library","tmdbId":2207,"artwork":{"posterKind":"poster","backdropKind":"backdrop"},"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.296,"tmdbVotes":867}}],"discover":[{"id":"movie-12-years-a-slave-2013","title":"12 Years a Slave","year":2013,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","History"],"overview":"In the pre-Civil War United States, Solomon Northup, a free black man from upstate New York, is abducted and sold into slavery. Facing cruelty as well as unexpected kindnesses Solomon struggles not only to stay\u2026","poster":"assets/movie-12-years-a-slave-2013-poster.jpg","backdrop":"assets/movie-12-years-a-slave-2013-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":76203,"ratings":{"rtCritics":95,"rtCriticsLabel":"Certified Fresh","rtAudience":90,"rtAudienceLabel":"Upright","imdb":8.1,"imdbVotes":796313,"tmdb":7.927,"tmdbVotes":12335}},{"id":"movie-101-dalmatians-ii-patch-s-london-adventure-2003","title":"101 Dalmatians II: Patch's London Adventure","year":2003,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Family","Animation","Adventure"],"overview":"Being one of 101 takes its toll on Patch, who doesn't feel unique. When he's accidentally left behind on moving day, he meets his idol, Thunderbolt, who enlists him on a publicity campaign.","poster":"assets/movie-101-dalmatians-ii-patch-s-london-adventure-2003-poster.jpg","backdrop":"assets/movie-101-dalmatians-ii-patch-s-london-adventure-2003-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":13654,"ratings":{"rtCritics":67,"rtCriticsLabel":"Fresh","rtAudience":41,"rtAudienceLabel":"Spilled","imdb":5.7,"imdbVotes":12343,"tmdb":6.025,"tmdbVotes":1274}},{"id":"movie-absolution-2024","title":"Absolution","year":2024,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action","Crime","Thriller"],"overview":"An aging ex-boxer gangster working as muscle for a Boston crime boss receives an upsetting diagnosis. Despite a faltering memory, he attempts to rectify the sins of his past and reconnect with his estranged\u2026","poster":"assets/movie-absolution-2024-poster.jpg","backdrop":"assets/movie-absolution-2024-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":974453,"ratings":{"rtCritics":56,"rtCriticsLabel":"Rotten","rtAudience":32,"rtAudienceLabel":"Spilled","imdb":5.2,"imdbVotes":11413,"tmdb":5.906,"tmdbVotes":564}},{"id":"movie-addicted-2014","title":"Addicted","year":2014,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Thriller"],"overview":"A gallerist risks her family and flourishing career when she enters into an affair with a talented painter and slowly loses control of her life.","poster":"assets/movie-addicted-2014-poster.jpg","backdrop":"assets/movie-addicted-2014-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":235271,"ratings":{"rtCritics":7,"rtCriticsLabel":"Rotten","rtAudience":51,"rtAudienceLabel":"Spilled","imdb":5,"imdbVotes":13131,"tmdb":5.928,"tmdbVotes":466}},{"id":"movie-all-the-money-in-the-world-2017","title":"All the Money in the World","year":2017,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Crime","History","Thriller"],"overview":"The story of the kidnapping of 16-year-old John Paul Getty III and the desperate attempt by his devoted mother to convince his billionaire grandfather Jean Paul Getty to pay the ransom.","poster":"assets/movie-all-the-money-in-the-world-2017-poster.jpg","backdrop":"assets/movie-all-the-money-in-the-world-2017-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":446791,"ratings":{"rtCritics":79,"rtCriticsLabel":"Certified Fresh","rtAudience":66,"rtAudienceLabel":"Upright","imdb":6.8,"imdbVotes":97448,"tmdb":6.493,"tmdbVotes":2493}},{"id":"movie-the-alto-knights-2025","title":"The Alto Knights","year":2025,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Crime","Drama"],"overview":"Two of New York's most notorious organized crime bosses, Frank Costello and Vito Genovese, vie for control of the city's streets. Once the best of friends, petty jealousies and a series of betrayals place them on a\u2026","poster":"assets/movie-the-alto-knights-2025-poster.jpg","backdrop":"assets/movie-the-alto-knights-2025-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":1013601,"ratings":{"rtCritics":39,"rtCriticsLabel":"Rotten","rtAudience":71,"rtAudienceLabel":"Upright","imdb":5.9,"imdbVotes":23017,"tmdb":6.223,"tmdbVotes":485}},{"id":"movie-the-amazing-spider-man-2-2014","title":"The Amazing Spider-Man 2","year":2014,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action","Adventure","Science Fiction"],"overview":"For Peter Parker, life is busy. Between taking out the bad guys as Spider-Man and spending time with the person he loves, Gwen Stacy, high school graduation cannot come quickly enough. Peter has not forgotten about\u2026","poster":"assets/movie-the-amazing-spider-man-2-2014-poster.jpg","backdrop":"assets/movie-the-amazing-spider-man-2-2014-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":102382,"ratings":{"rtCritics":51,"rtCriticsLabel":"Rotten","rtAudience":64,"rtAudienceLabel":"Upright","imdb":6.6,"imdbVotes":611981,"tmdb":6.567,"tmdbVotes":14919}},{"id":"movie-ant-man-and-the-wasp-quantumania-2023","title":"Ant-Man and the Wasp: Quantumania","year":2023,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action","Adventure","Science Fiction"],"overview":"Super-Hero partners Scott Lang and Hope van Dyne, along with with Hope's parents Janet van Dyne and Hank Pym, and Scott's daughter Cassie Lang, find themselves exploring the Quantum Realm, interacting with strange\u2026","poster":"assets/movie-ant-man-and-the-wasp-quantumania-2023-poster.jpg","backdrop":"assets/movie-ant-man-and-the-wasp-quantumania-2023-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":640146,"ratings":{"rtCritics":46,"rtCriticsLabel":"Rotten","rtAudience":81,"rtAudienceLabel":"Upright","imdb":6,"imdbVotes":281738,"tmdb":6.197,"tmdbVotes":6236}},{"id":"movie-arctic-dogs-2019","title":"Arctic Dogs","year":2019,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Animation","Adventure","Comedy"],"overview":"Animals band together to save the day when the evil Otto Von Walrus hatches a sinister scheme to accelerate global warming and melt the Arctic Circle.","poster":"assets/movie-arctic-dogs-2019-poster.jpg","backdrop":"assets/movie-arctic-dogs-2019-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":416153,"ratings":{"rtCritics":13,"rtCriticsLabel":"Rotten","rtAudience":60,"rtAudienceLabel":"Upright","imdb":4.9,"imdbVotes":2580,"tmdb":5.9,"tmdbVotes":148}},{"id":"movie-the-avengers-2012","title":"The Avengers","year":2012,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Science Fiction","Action","Adventure"],"overview":"When an unexpected enemy emerges and threatens global safety and security, Nick Fury, director of the international peacekeeping agency known as S.H.I.E.L.D., finds himself in need of a team to pull the world back\u2026","poster":"assets/movie-the-avengers-2012-poster.jpg","backdrop":"assets/movie-the-avengers-2012-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":24428,"ratings":{"rtCritics":91,"rtCriticsLabel":"Certified Fresh","rtAudience":91,"rtAudienceLabel":"Upright","imdb":8,"imdbVotes":1590693,"tmdb":8.084,"tmdbVotes":40262}},{"id":"movie-black-bear-2020","title":"Black Bear","year":2020,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Thriller"],"overview":"At a remote lake house in the Adirondack Mountains, a couple entertains an out-of-town guest looking for inspiration in her filmmaking. The group quickly falls into a calculated game of desire, manipulation, and\u2026","poster":"assets/movie-black-bear-2020-poster.jpg","backdrop":"assets/movie-black-bear-2020-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":624788,"ratings":{"rtCritics":89,"rtCriticsLabel":"Certified Fresh","rtAudience":64,"rtAudienceLabel":"Upright","imdb":6.5,"imdbVotes":18408,"tmdb":6.337,"tmdbVotes":315}},{"id":"movie-black-panther-2018","title":"Black Panther","year":2018,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action","Adventure","Science Fiction"],"overview":"King T'Challa returns home to the reclusive, technologically advanced African nation of Wakanda to serve as his country's new leader. However, T'Challa soon finds that he is challenged for the throne by factions\u2026","poster":"assets/movie-black-panther-2018-poster.jpg","backdrop":"assets/movie-black-panther-2018-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":284054,"ratings":{"rtCritics":96,"rtCriticsLabel":"Certified Fresh","rtAudience":null,"rtAudienceLabel":"Spilled","imdb":7.3,"imdbVotes":931120,"tmdb":7.36,"tmdbVotes":24190}},{"id":"movie-a-bronx-tale-1993","title":"A Bronx Tale","year":1993,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Crime"],"overview":"Set in the Bronx during the tumultuous 1960s, an adolescent boy is torn between his honest, working-class father and a violent yet charismatic crime boss. Complicating matters is the youngster's growing attraction -\u2026","poster":"assets/movie-a-bronx-tale-1993-poster.jpg","backdrop":"assets/movie-a-bronx-tale-1993-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":1607,"ratings":{"rtCritics":97,"rtCriticsLabel":"Fresh","rtAudience":92,"rtAudienceLabel":"Upright","imdb":7.8,"imdbVotes":191930,"tmdb":7.913,"tmdbVotes":3075}},{"id":"movie-by-any-means-2026","title":"By Any Means","year":2026,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Thriller","History","Crime"],"overview":"In 1960s Mississippi, a young Black FBI agent is forced to partner with a notorious mafia hitman to investigate a wave of brutal civil rights murders.","poster":"assets/movie-by-any-means-2026-poster.jpg","backdrop":"assets/movie-by-any-means-2026-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":1380417,"ratings":{"rtCritics":49,"rtCriticsLabel":"Rotten","rtAudience":88,"rtAudienceLabel":"Upright","imdb":6.8,"imdbVotes":3534,"tmdb":6.6,"tmdbVotes":92}},{"id":"movie-captain-america-civil-war-2016","title":"Captain America: Civil War","year":2016,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Adventure","Action","Science Fiction"],"overview":"Following the events of Age of Ultron, the collective governments of the world pass an act designed to regulate all superhuman activity. This polarizes opinion amongst the Avengers, causing two factions to side with\u2026","poster":"assets/movie-captain-america-civil-war-2016-poster.jpg","backdrop":"assets/movie-captain-america-civil-war-2016-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":271110,"ratings":{"rtCritics":90,"rtCriticsLabel":"Certified Fresh","rtAudience":89,"rtAudienceLabel":"Upright","imdb":7.8,"imdbVotes":954943,"tmdb":7.455,"tmdbVotes":24808}},{"id":"movie-captain-america-the-first-avenger-2011","title":"Captain America: The First Avenger","year":2011,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action","Adventure","Science Fiction"],"overview":"During World War II, Steve Rogers is a sickly man from Brooklyn who's transformed into super-soldier Captain America to aid in the war effort. Rogers must stop the Red Skull \u2013 Adolf Hitler's ruthless head of\u2026","poster":"assets/movie-captain-america-the-first-avenger-2011-poster.jpg","backdrop":"assets/movie-captain-america-the-first-avenger-2011-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":1771,"ratings":{"rtCritics":80,"rtCriticsLabel":"Certified Fresh","rtAudience":75,"rtAudienceLabel":"Upright","imdb":6.9,"imdbVotes":993453,"tmdb":7.012,"tmdbVotes":23473}},{"id":"movie-captain-america-the-winter-soldier-2014","title":"Captain America: The Winter Soldier","year":2014,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action","Adventure","Science Fiction"],"overview":"After the cataclysmic events in New York with The Avengers, Steve Rogers, aka Captain America is living quietly in Washington, D.C. and trying to adjust to the modern world. But when a S.H.I.E.L.D. colleague comes\u2026","poster":"assets/movie-captain-america-the-winter-soldier-2014-poster.jpg","backdrop":"assets/movie-captain-america-the-winter-soldier-2014-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":100402,"ratings":{"rtCritics":90,"rtCriticsLabel":"Certified Fresh","rtAudience":92,"rtAudienceLabel":"Upright","imdb":7.7,"imdbVotes":995514,"tmdb":7.654,"tmdbVotes":20688}},{"id":"movie-careful-what-you-wish-for-2015","title":"Careful What You Wish For","year":2015,"type":"movie","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Thriller"],"overview":"A guy gets more than he bargained for after entering into an affair with the wife of an investment banker. Soon, a suspicious death and substantial life insurance policy embroil him in a scandal.","poster":"assets/movie-careful-what-you-wish-for-2015-poster.jpg","backdrop":"assets/movie-careful-what-you-wish-for-2015-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":317744,"ratings":{"rtCritics":17,"rtCriticsLabel":"Rotten","rtAudience":61,"rtAudienceLabel":"Upright","imdb":5.6,"imdbVotes":9452,"tmdb":6.129,"tmdbVotes":446}},{"id":"tv-12-monkeys-2015","title":"12 Monkeys","year":2015,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Sci-Fi & Fantasy","Drama"],"overview":"The provocative story of Cole, a time traveler from a decimated future in a high-stakes race against the clock. Utilizing a dangerous and untested method of time travel, he journeys from 2043 to the present day on a\u2026","poster":"assets/tv-12-monkeys-2015-poster.jpg","backdrop":"assets/tv-12-monkeys-2015-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":60948,"ratings":{"rtCritics":88,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.441,"tmdbVotes":1245}},{"id":"tv-90-day-fiance-before-the-90-days-2017","title":"90 Day Fianc\u00e9: Before the 90 Days","year":2017,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Reality"],"overview":"Follow couples who have an existing relationship online, but haven't met in person. We'll experience their journey as they travel to the other's foreign country for the first time in an attempt to establish an\u2026","poster":"assets/tv-90-day-fiance-before-the-90-days-2017-poster.jpg","backdrop":"assets/tv-90-day-fiance-before-the-90-days-2017-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":73319,"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.5,"tmdbVotes":45}},{"id":"tv-90-day-fiance-the-other-way-2019","title":"90 Day Fianc\u00e9: The Other Way","year":2019,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Reality"],"overview":"Americans move to a foreign country all in the name of love. Will uprooting their lives in the United States pay off, or will they be packing up and moving back to America brokenhearted?","poster":"assets/tv-90-day-fiance-the-other-way-2019-poster.jpg","backdrop":"assets/tv-90-day-fiance-the-other-way-2019-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":90046,"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.8,"tmdbVotes":34}},{"id":"tv-the-100-2014","title":"The 100","year":2014,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Sci-Fi & Fantasy","Action & Adventure","Drama"],"overview":"100 years in the future, when the Earth has been abandoned due to radioactivity, the last surviving humans live on an ark orbiting the planet \u2014 but the ark won't last forever. So the repressive regime picks 100\u2026","poster":"assets/tv-the-100-2014-poster.jpg","backdrop":"assets/tv-the-100-2014-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":48866,"ratings":{"rtCritics":93,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.878,"tmdbVotes":8855}},{"id":"tv-accused-2023","title":"Accused","year":2023,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Crime","Drama"],"overview":"In this crime anthology series, viewers discover how an ordinary person got caught up in an extraordinary situation, ultimately revealing how one wrong turn leads to another, until it\u2019s too late to turn back. Told\u2026","poster":"assets/tv-accused-2023-poster.jpg","backdrop":"assets/tv-accused-2023-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":202097,"ratings":{"rtCritics":61,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.851,"tmdbVotes":87}},{"id":"tv-after-life-2019","title":"After Life","year":2019,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Comedy","Drama"],"overview":"Tony had a perfect life. But after his wife Lisa suddenly dies, Tony changes. After contemplating taking his own life, he decides instead to live long enough to punish the world by saying and doing whatever he likes\u2026","poster":"assets/tv-after-life-2019-poster.jpg","backdrop":"assets/tv-after-life-2019-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":79410,"ratings":{"rtCritics":72,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.902,"tmdbVotes":1169}},{"id":"tv-all-creatures-great-and-small-1978","title":"All Creatures Great and Small","year":1978,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Comedy","Drama"],"overview":"The trials and misadventures of the staff at a country veterinary office in Yorkshire. James Herriot, a young animal surgeon, moves to a small Yorkshire town to begin his first job.","poster":"assets/tv-all-creatures-great-and-small-1978-poster.jpg","backdrop":"assets/tv-all-creatures-great-and-small-1978-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"center_crop","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":7406,"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.8,"tmdbVotes":50}},{"id":"tv-american-housewife-2016","title":"American Housewife","year":2016,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Comedy"],"overview":"A family comedy narrated by Katie, a strong-willed mother, raising her flawed family in a wealthy town filled with perfect wives and their perfect offspring.","poster":"assets/tv-american-housewife-2016-poster.jpg","backdrop":"assets/tv-american-housewife-2016-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":67117,"ratings":{"rtCritics":null,"rtCriticsLabel":"Rotten","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.7,"tmdbVotes":187}},{"id":"tv-atlantis-2013","title":"Atlantis","year":2013,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action & Adventure","Sci-Fi & Fantasy"],"overview":"A fantasy drama set in a world of legendary heroes and mythical creatures. Far from home and desperate for answers, Jason washes up on the shores of an ancient land. A mysterious place; a world of bull leaping, of\u2026","poster":"assets/tv-atlantis-2013-poster.jpg","backdrop":"assets/tv-atlantis-2013-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":47054,"ratings":{"rtCritics":62,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.4,"tmdbVotes":155}},{"id":"tv-avatar-the-last-airbender-2024","title":"Avatar: The Last Airbender","year":2024,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Action & Adventure","Sci-Fi & Fantasy","Drama"],"overview":"A young boy known as the Avatar must master the four elemental powers to save a world at war \u2014 and fight a ruthless enemy bent on stopping him.","poster":"assets/tv-avatar-the-last-airbender-2024-poster.jpg","backdrop":"assets/tv-avatar-the-last-airbender-2024-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":82452,"ratings":{"rtCritics":66,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.8,"tmdbVotes":1406}},{"id":"tv-avatar-seven-havens-2026","title":"Avatar: Seven Havens","year":2026,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Animation","Action & Adventure","Sci-Fi & Fantasy"],"overview":"In a world shattered by a devastating cataclysm, a young Earthbender discovers she's the new Avatar after Korra. But in this dangerous era, that title marks her as humanity's destroyer, not its savior. Hunted by both\u2026","poster":"assets/tv-avatar-seven-havens-2026-poster.jpg","backdrop":"assets/tv-avatar-seven-havens-2026-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":284833,"ratings":{"rtCritics":100,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.9,"tmdbVotes":183}},{"id":"tv-batman-the-brave-and-the-bold-2008","title":"Batman: The Brave and the Bold","year":2008,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Animation","Action & Adventure","Sci-Fi & Fantasy"],"overview":"The Caped Crusader is teamed up with Blue Beetle, Green Arrow, Aquaman and countless others in his quest to uphold justice.","poster":"assets/tv-batman-the-brave-and-the-bold-2008-poster.jpg","backdrop":"assets/tv-batman-the-brave-and-the-bold-2008-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":15804,"ratings":{"rtCritics":96,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.6,"tmdbVotes":295}},{"id":"tv-beat-bobby-flay-2013","title":"Beat Bobby Flay","year":2013,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Reality"],"overview":"Two talented chefs go head-to-head for the chance to Beat Bobby Flay. To get to Bobby the chefs must first face off against each other, creating a spectacular dish with a secret ingredient of Bobby's choice. Judges\u2026","poster":"assets/tv-beat-bobby-flay-2013-poster.jpg","backdrop":"assets/tv-beat-bobby-flay-2013-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":62481,"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.5,"tmdbVotes":31}},{"id":"tv-benson-1979","title":"Benson","year":1979,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Comedy"],"overview":"A butler deals with life at the governor's mansion.","poster":"assets/tv-benson-1979-poster.jpg","backdrop":"assets/tv-benson-1979-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":1849,"ratings":{"rtCritics":null,"rtCriticsLabel":null,"rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7,"tmdbVotes":46}},{"id":"tv-black-rabbit-2025","title":"Black Rabbit","year":2025,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Crime"],"overview":"A rising-star restaurateur is forced into New York's criminal underworld when his chaotic brother returns to town with loan sharks on his trail.","poster":"assets/tv-black-rabbit-2025-poster.jpg","backdrop":"assets/tv-black-rabbit-2025-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":249039,"ratings":{"rtCritics":66,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":6.983,"tmdbVotes":240}},{"id":"tv-black-ish-2014","title":"black-ish","year":2014,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Comedy"],"overview":"A family man struggles to gain a sense of cultural identity while raising his kids in a predominantly white, upper-middle-class neighborhood.","poster":"assets/tv-black-ish-2014-poster.jpg","backdrop":"assets/tv-black-ish-2014-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":61381,"ratings":{"rtCritics":92,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.1,"tmdbVotes":352}},{"id":"tv-breaking-bad-2008","title":"Breaking Bad","year":2008,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Drama","Crime"],"overview":"Walter White, a New Mexico chemistry teacher, is diagnosed with Stage III cancer and given a prognosis of only two years left to live. He becomes filled with a sense of fearlessness and an unrelenting desire to\u2026","poster":"assets/tv-breaking-bad-2008-poster.jpg","backdrop":"assets/tv-breaking-bad-2008-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"center_crop","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":1396,"ratings":{"rtCritics":96,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":8.959,"tmdbVotes":19030}},{"id":"tv-the-capture-2019","title":"The Capture","year":2019,"type":"tv","runtimeSeconds":null,"seasonCount":null,"communityRating":null,"criticRating":null,"genres":["Crime","Drama","Mystery"],"overview":"When soldier Shaun Emery's conviction for a murder in Afghanistan is overturned due to flawed video evidence, he returns to life as a free man with his young daughter. But when damning CCTV footage from a night out\u2026","poster":"assets/tv-the-capture-2019-poster.jpg","backdrop":"assets/tv-the-capture-2019-backdrop.jpg","played":null,"playCount":null,"resumeSeconds":null,"progress":null,"addedAt":null,"lastPlayedAt":null,"availability":"not_here","availabilityEvidence":"retained_profile_membership_and_native_request_ledger","source":"materialized_personal_recommendation","rank":null,"watchStateKnown":false,"artwork":{"posterKind":"poster","backdropKind":"poster_crop"},"availabilityIsSnapshot":true,"tmdbId":93166,"ratings":{"rtCritics":97,"rtCriticsLabel":"Fresh","rtAudience":null,"rtAudienceLabel":null,"imdb":null,"imdbVotes":null,"tmdb":7.634,"tmdbVotes":361}}],"discoverySource":{"state":"materialized_snapshot","rankKnown":false,"selection":"First 18 alphabetically indexed movie stubs and first 18 series stubs, not ranked feed order","observedAt":"2026-11-04T20:42:12.030108+00:00"}}],"cast":{"movie:14069":[{"name":"Riisa Naka","character":"Makoto Konno (voice)","img":"tqFHQiJUycuob3ytvilaAWDlbQ8.jpg","order":0},{"name":"Takuya Ishida","character":"Chiaki Mamiya (voice)","img":"aHQk6XxqyJinfvrVRADEIg31nOk.jpg","order":1},{"name":"Mitsutaka Itakura","character":"Kousuke Tsuda (voice)","img":"mnKYU7HIsuRkx3YjdRO5FLXCdX5.jpg","order":2},{"name":"Ayami Kakiuchi","character":"Yuri Hayakawa (voice)","img":"lUhVV9u5VGMCNdCAVhGzg8GFSdo.jpg","order":3},{"name":"Mitsuki Tanimura","character":"Kaho Fujitani (voice)","img":"xV9UrP8kZdxOiTI2efDFhp3t4iA.jpg","order":4},{"name":"Yuki Sekido","character":"Miyuki Konno (voice)","img":"7LVYeFTgUpjYDrxnU7Wm5ZQUX9t.jpg","order":5},{"name":"Utawaka Katsura","character":"Makoto's Father (voice)","img":"j0GXzLelO1dOzI7d1WVIwQXhLz8.jpg","order":6},{"name":"Midori Ando","character":"Makoto's Mother (voice)","img":"26R1LBiSOkkP08saSsz6LmVTY16.jpg","order":7},{"name":"Fumihiko Tachiki","character":"Fukushima (voice)","img":null,"order":8},{"name":"Keiko Yamamoto","character":"Auntie (voice)","img":null,"order":9},{"name":"Shiori Yokohari","character":"Moriko Uesugi (voice)","img":null,"order":10},{"name":"Sonoka Matsuoka","character":"Sekimi Nowake (voice)","img":null,"order":11},{"name":"Takayuki Handa","character":"Kato (voice)","img":null,"order":12},{"name":"Maho Kurashima","character":"Female Newscaster A (voice)","img":null,"order":13},{"name":"Keiko Aizawa","character":"School Nurse / Answering Machine (voice)","img":null,"order":14}],"movie:210479":[{"name":"Tom Hardy","character":"Ivan Locke","img":"d81K0RH8UX7tZj49tZaQhZ9ewH.jpg","order":0},{"name":"Ruth Wilson","character":"Katrina (voice)","img":"fdFVatb9pt5dfT9tDK8tikKWafS.jpg","order":1},{"name":"Andrew Scott","character":"Donal (voice)","img":"4F8XpjyQCvtuu21WFm5d8RF5Rl.jpg","order":2},{"name":"Olivia Colman","character":"Bethan (voice)","img":"lawJUdbLb1YW0niaYjiVGR9IBG8.jpg","order":3},{"name":"Tom Holland","character":"Eddie (voice)","img":"xKBAaPIa1c7tzZD3Y0MhBLv4hPE.jpg","order":4},{"name":"Ben Daniels","character":"Gareth (voice)","img":"phEIvq0Ay2KjI5ewmVvpQ1a29GJ.jpg","order":5},{"name":"Bill Milner","character":"Sean (voice)","img":"bLgmpSFgEiSFNshqmdl3EIZkRZm.jpg","order":6},{"name":"Alice Lowe","character":"Sister Margaret (voice)","img":"v4sRxLpRpHEd9vbk43wm9VL0v0K.jpg","order":7},{"name":"Danny Webb","character":"Cassidy (voice)","img":null,"order":8},{"name":"Lee Ross","character":"PC Davids (voice)","img":null,"order":9},{"name":"Silas Carson","character":"Dr. Gullu (voice)","img":null,"order":10},{"name":"Kirsty Dillon","character":"Gareth's Wife (voice)","img":null,"order":11}],"movie:318917":[{"name":"Oliver Masucci","character":"Adolf Hitler","img":"fjJc03z1cOlMxLZbC1qihsq3C37.jpg","order":0},{"name":"Fabian Busch","character":"Fabian Sawatzki","img":"lpEs9yDsMQlsbm0RVsvDIleCXcI.jpg","order":1},{"name":"Christoph Maria Herbst","character":"Christoph Sensenbrink","img":"8v3lDa0QCJlDtOx9flqlMNIA3uf.jpg","order":2},{"name":"Katja Riemann","character":"Bellini","img":"waayy0jpNbxLDQ8JO1uRDng8SLF.jpg","order":3},{"name":"Franziska Wulf","character":"Kr\u00f6meier","img":"yxGsAKnrJZs2g6q4unNgkfm7NAA.jpg","order":4},{"name":"Lars Rudolph","character":"Shop Owner","img":"qiWu2gphSg64igYl3Nx0hEIOQF3.jpg","order":5},{"name":"Michael Kessler","character":"Michael Witzigmann","img":"sh4ANkKoIHgmHtkKQbJvF8y0Fjq.jpg","order":6},{"name":"Thomas Thieme","character":"K\u00e4rrner","img":"omWXGbeRR32MWuYhpnLOSqJ6xkO.jpg","order":7},{"name":"Frank Plasberg","character":"Frank Plasberg","img":null,"order":8},{"name":"Thomas M. K\u00f6ppl","character":"Etiquette Coach","img":null,"order":9},{"name":"Marc-Marvin Israel","character":"Football Boy","img":null,"order":10},{"name":"David Gebigke","character":"Football Boy","img":null,"order":11},{"name":"Paul Busche","character":"Football Boy","img":null,"order":12},{"name":"Gerdy Zint","character":"Pantomime","img":null,"order":13},{"name":"Nancy Maria Br\u00fcning","character":"Mother with Stroller","img":null,"order":14}],"movie:42994":[{"name":"Tsutomu Isobe","character":"Heinz Beckner (voice)","img":"qP5vQMIbLNvSsSFkEMLZRVt4ZW5.jpg","order":0},{"name":"Koichi Yamadera","character":"Miguel Costrela (voice)","img":"biov5jENp2XYfehkcdnRvi796Wi.jpg","order":1},{"name":"Shozo Iizuka","character":"Ivanov (voice)","img":"msqe5A1q5YUUND0RhzB9dw1AEAO.jpg","order":2},{"name":"Shigeru Chiba","character":"Aoshima (voice)","img":"mF5YJxApTYKBVFJDrEC9IrJ5ooV.jpg","order":3},{"name":"Gara Takashima","character":"Eva Friedel (voice)","img":"5L0kzTVITmOQdQ94NhicKM8ecCX.jpg","order":4},{"name":"Ami Hasegawa","character":"Emily (voice)","img":null,"order":5},{"name":"Hideyuki Hori","character":"Nobuo Tanaka (voice)","img":"fbWWkhe7GVSlhBljY89rJd01OnA.jpg","order":6},{"name":"Kenichi Ogata","character":"Oomaeda (voice)","img":"iQLEawIP2593yrGy22GzLSpnfgl.jpg","order":7},{"name":"Osamu Saka","character":"Kamata (voice)","img":null,"order":8},{"name":"Hisako Kyoda","character":"Grandma (voice)","img":null,"order":9},{"name":"Michio Hazama","character":"Nirasaki (voice)","img":null,"order":10},{"name":"Kayoko Fujii","character":"Sakiko (voice)","img":null,"order":11},{"name":"Ryoichi Tanaka","character":"General Officer (voice)","img":null,"order":12},{"name":"Tetsuya Iwanaga","character":"Nobuo's Brother (voice)","img":null,"order":13},{"name":"Yuu Hayashi","character":"Boy (voice)","img":null,"order":14}],"movie:123431":[{"name":"Snoop Dogg","character":"Self","img":"rbxBK2m6fEq0oHeMoBUMVYkJEdJ.jpg","order":0},{"name":"Dr. Dre","character":"Self","img":"xm2pYFBggiXSkFBV2I612i3fDd3.jpg","order":1},{"name":"Daz Dillinger","character":"Self","img":"nAxS5l9vb1C8ltCp9yAa0f6lazu.jpg","order":2},{"name":"Angela Hunte","character":"Self","img":null,"order":3},{"name":"Ariel Rechtshaid","character":"Self","img":"lF06PTNYrlXeJ3DYApvOcPXJr87.jpg","order":4},{"name":"Dre Skull","character":"Self","img":null,"order":5},{"name":"Jahdan Blakkamoore","character":"Self","img":null,"order":6},{"name":"Bunny Wailer","character":"Self","img":"oMHMLhoV3ry8aOfdvs1kxyowhNq.jpg","order":7},{"name":"Damian Marley","character":"Self","img":null,"order":8},{"name":"Louis Farrakhan","character":"Self","img":null,"order":9},{"name":"Shante Broadus","character":"Self","img":null,"order":10},{"name":"Cori Broadus","character":"Self","img":null,"order":11},{"name":"Maxine Stowe","character":"Self","img":null,"order":12},{"name":"Stewart Copeland","character":"Self","img":null,"order":13},{"name":"Diplo","character":"Self","img":null,"order":14}],"movie:1715492":[{"name":"John Scimone","character":"Self","img":null,"order":0},{"name":"Meghan Scimone","character":"Self","img":null,"order":1},{"name":"Patricia Sandoval","character":"Self","img":null,"order":2},{"name":"Nicholas Taliaferro","character":"Self","img":null,"order":3},{"name":"Stefania Vincenzi","character":"Self","img":null,"order":4},{"name":"Manrico Giampedroni","character":"Self","img":null,"order":5},{"name":"Rose Metcalf","character":"Self","img":null,"order":6},{"name":"Francesco Schettino","character":"Self (Archive Footage)","img":null,"order":7},{"name":"Manoj Singh","character":"Self","img":null,"order":8},{"name":"Francesco Boaria","character":"Self","img":null,"order":9},{"name":"Pier Luigi Foschi","character":"Self","img":null,"order":10},{"name":"Alessandro Cantelli-Forti","character":"Self","img":null,"order":11},{"name":"Barbie Latza Nadeau","character":"Self","img":null,"order":12}],"tv:83867":[{"name":"Diego Luna","character":"Cassian Andor","img":"qwbjcyDN37OHiln4a6P4LP31o7F.jpg","order":0},{"name":"Anton Lesser","character":"Major Partagaz","img":"x0lmqgkmphvOCSTHk2oxsaxA9Ra.jpg","order":3},{"name":"Muhannad Bhaier","character":"Wilmon","img":"5hn7WeXi6wguwxTPTSmcmzHAs9.jpg","order":4},{"name":"Stellan Skarsg\u00e5rd","character":"Luthen Rael","img":"mW7xmtGV4y79kQGn0zkKVGDMAmw.jpg","order":5},{"name":"Denise Gough","character":"Dedra Meero","img":"wWcby4ARYqr8d92ZdjyQcfaiJBW.jpg","order":6},{"name":"Kyle Soller","character":"Syril Karn","img":"rLzduQpYJnZJKkXv3jRc7MDHwoI.jpg","order":7},{"name":"Adria Arjona","character":"Bix Caleen","img":"hzu7OqTmNCT1xdCdmwBSf2yJvaO.jpg","order":8},{"name":"Genevieve O'Reilly","character":"Mon Mothma","img":"4eOoW1PNBZfxRW0g8RmYH8bL6mq.jpg","order":9},{"name":"Faye Marsay","character":"Vel Sartha","img":null,"order":10},{"name":"Elizabeth Dulau","character":"Kleya Marki","img":null,"order":11},{"name":"Alastair Mackenzie","character":"Perrin Fertha","img":null,"order":501},{"name":"Dave Chapman","character":"B2EMO (voice)","img":null,"order":509},{"name":"Robert Emms","character":"Supervisor Lonni Jung","img":null,"order":538},{"name":"Michael Jenn","character":"Supervisor Lagret","img":null,"order":539},{"name":"Jacob James Beswick","character":"Attendant Heert","img":null,"order":619}],"tv:76479":[{"name":"Karl Urban","character":"Billy Butcher","img":"7Y96dAfg0HcFrcLjlD5eD9N0uj4.jpg","order":0},{"name":"Jack Quaid","character":"Hugh 'Hughie' Campbell","img":"320qW5yEbxpmyxQ3evmClJbtKag.jpg","order":1},{"name":"Antony Starr","character":"Homelander","img":"xx3As5SWcE8vYOKZgtjDjqmT3jc.jpg","order":2},{"name":"Erin Moriarty","character":"Annie January / Starlight","img":"2tFblvjBRUYwcVT1V1i79Ppd6wG.jpg","order":3},{"name":"Jessie T. Usher","character":"Reggie Franklin / A-Train","img":null,"order":5},{"name":"Laz Alonso","character":"Marvin T. 'Mother's Milk' Milk / M.M.","img":"nmgOd3X2Xn3jIp9OLCRJzLExRWN.jpg","order":6},{"name":"Chace Crawford","character":"Kevin Moskowitz / The Deep","img":"yWZILsr2mBQBCG1LOcCYYshIbts.jpg","order":7},{"name":"Tomer Capone","character":"Serge / Frenchie","img":"r6s7dkYZUJpd00C7p9itT6Gp8XB.jpg","order":8},{"name":"Karen Fukuhara","character":"Kimiko Miyashiro","img":"sG6CWLdENCtzukNFkFYyPxqyRmS.jpg","order":9},{"name":"Nathan Mitchell","character":"Earving / Black Noir","img":null,"order":10},{"name":"Colby Minifie","character":"Ashley Barrett","img":null,"order":13},{"name":"Claudia Doumit","character":"Victoria 'Vic' Neuman","img":null,"order":14},{"name":"Cameron Crovetti","character":"Ryan","img":null,"order":16},{"name":"Dominique McElligott","character":"Maggie Shaw / Queen Maeve","img":null,"order":242},{"name":"Nneka Elliott","character":"Nneka Elliott","img":null,"order":894}],"tv:1215":[{"name":"David Duchovny","character":"Hank Moody","img":"fD8GuLHOOSSAG98VjwN3NhAmqAJ.jpg","order":0},{"name":"Natascha McElhone","character":"Karen van der Beek","img":"9pxaoasotR1pdCXYSfN1pkm0geO.jpg","order":1},{"name":"Evan Handler","character":"Charlie Runkle","img":"yU0OXeZ0K1ppe1o9SpHiAMHy1rc.jpg","order":2},{"name":"Pamela Adlon","character":"Marcy Runkle","img":"5eIRHUbNOH7ibXa0IfUfFvj5I5L.jpg","order":3},{"name":"Rachel Miner","character":"Dani","img":null,"order":4},{"name":"Madeleine Martin","character":"Becca Moody","img":"hOntuFYAMwn9QaXT0AwLCPU79ce.jpg","order":5},{"name":"Madeline Zima","character":"Mia Lewis","img":"6hmUs5Q1EETapn32yKNt3c3i1sn.jpg","order":6},{"name":"Callum Keith Rennie","character":"Lew Ashby","img":null,"order":7},{"name":"Carla Gallo","character":"Daisy","img":null,"order":513},{"name":"Embeth Davidtz","character":"Felicia Koons","img":null,"order":514},{"name":"Kathleen Turner","character":"Sue Collini","img":null,"order":522},{"name":"Jason Beghe","character":"Richard Bates","img":"hrTwOPWek7nkPJgFhh6inFu7vSS.jpg","order":534},{"name":"Stephen Tobolowsky","character":"Stu Beggs","img":"uL8yfcm0dCFYFQt052kczVQVvac.jpg","order":671},{"name":"Michael Imperioli","character":"Rick Rath","img":null,"order":843},{"name":"Oliver Cooper","character":"Levon","img":null,"order":844}],"tv:1437":[{"name":"Nathan Fillion","character":"Mal Reynolds","img":"aW6vCxkUZtwb6iH2Wf88Uq0XNVv.jpg","order":0},{"name":"Gina Torres","character":"Zo\u00eb Washburne","img":"ukDNHgvEgdU95eaw6pngiAPucv4.jpg","order":1},{"name":"Alan Tudyk","character":"Hoban Washburne","img":"jUuUbPuMGonFT5E2pcs4alfqaCN.jpg","order":2},{"name":"Morena Baccarin","character":"Inara Serra","img":"4gyHyg6FJ1oFczOm5pmMkdEEo2J.jpg","order":3},{"name":"Adam Baldwin","character":"Jayne Cobb","img":"lfbyJWNWGbiYfU0Yr1tjn6Trd2V.jpg","order":4},{"name":"Jewel Staite","character":"Kaylee Frye","img":"ztxDIZvuPreUixO6ZPxwkCg2UlO.jpg","order":5},{"name":"Sean Maher","character":"Simon Tam","img":"o7splcOIVAdbHnwohJOUAvXWVlk.jpg","order":6},{"name":"Michael Fairman","character":"Adelai Niska","img":null,"order":7},{"name":"Summer Glau","character":"River Tam","img":"rDTxblyw0AwU5oSeksgP7GwMyrF.jpg","order":8},{"name":"Ron Glass","character":"Derrial Book","img":null,"order":9},{"name":"Gregory Itzin","character":"Magistrate Higgins","img":null,"order":10},{"name":"Isabella Hofmann","character":"Regan Tam","img":null,"order":11},{"name":"Jeff Ricketts","character":"Man","img":null,"order":540},{"name":"Dennis Cockrum","character":"Other Man","img":null,"order":541},{"name":"Mark Sheppard","character":"Badger","img":null,"order":613}],"tv:67070":[{"name":"Phoebe Waller-Bridge","character":"Fleabag","img":"5VbadQsYCKdiJysP01LJFPmYB8A.jpg","order":0},{"name":"Sian Clifford","character":"Claire","img":"rIqcwewXdkrDTMTwX56QPa7MNTC.jpg","order":1},{"name":"Jenny Rainsford","character":"Boo","img":"pVwR9hsEiHzVTo9giCjR3vIfa8W.jpg","order":2},{"name":"Andrew Scott","character":"The Priest","img":"4F8XpjyQCvtuu21WFm5d8RF5Rl.jpg","order":3},{"name":"Ben Aldridge","character":"Arsehole Guy","img":null,"order":507},{"name":"Jo Martin","character":"Pam","img":null,"order":509},{"name":"Olivia Colman","character":"Godmother","img":"lawJUdbLb1YW0niaYjiVGR9IBG8.jpg","order":510},{"name":"Bill Paterson","character":"Dad","img":"mk5vpYLmER7asqOhEwVKXD3P3YE.jpg","order":511},{"name":"Jamie Demetriou","character":"Bus Rodent","img":null,"order":512},{"name":"Hugh Skinner","character":"Harry","img":"7MHdNxS1gRnx0ZQGPrfS5eRjMe3.jpg","order":513},{"name":"Hugh Dennis","character":"Bank Manager","img":null,"order":514},{"name":"Brett Gelman","character":"Martin","img":"ub2IuMWFNQGYghHTPq0lpmn2Ue0.jpg","order":515},{"name":"Anthony Welsh","character":"Jack","img":null,"order":516},{"name":"Kae Alexander","character":"Elaine","img":null,"order":523},{"name":"David Hargreaves","character":"Chatty Joe","img":null,"order":530}],"tv:40075":[{"name":"Jason Ritter","character":"Dipper Pines (voice)","img":null,"order":0},{"name":"Kristen Schaal","character":"Mabel Pines (voice)","img":null,"order":1},{"name":"Alex Hirsch","character":"Grunkle Stan / Soos Ramirez / Bill Cipher / Old Man McGucket (voice)","img":null,"order":2},{"name":"Linda Cardellini","character":"Wendy Corduroy (voice)","img":null,"order":3},{"name":"Will Forte","character":"Tyler Cutebiker (voice)","img":null,"order":13},{"name":"Gregg Turkington","character":"Young Toby Determined (voice)","img":null,"order":166},{"name":"Carl Faruolo","character":"Grenda (voice)","img":null,"order":170},{"name":"Jennifer Coolidge","character":"Lazy Susan (voice)","img":null,"order":175},{"name":"Dee Bradley Baker","character":"Waddles (voice) / Additional Voices (voice)","img":null,"order":399},{"name":"John DiMaggio","character":"Manly Dan / Pinball Cowboy Skeleton (voice)","img":null,"order":469},{"name":"Kevin Michael Richardson","character":"Sheriff Blubs / Ghost / Ancient Heads / Basketball Player / Manly Dan (voice)","img":null,"order":561},{"name":"Grey DeLisle","character":"Mrs. Gleeful (voice)","img":null,"order":582},{"name":"Matt Chapman","character":"Mermando / Additional Voices (voice)","img":null,"order":591},{"name":"Niki Yang","character":"Candy Chiu (voice)","img":null,"order":650},{"name":"T.J. Miller","character":"Robbie Valentino (voice)","img":null,"order":664}],"tv:95557":[{"name":"Steven Yeun","character":"Mark Grayson / Invincible (voice)","img":null,"order":0},{"name":"Sandra Oh","character":"Debbie Grayson (voice)","img":null,"order":1},{"name":"J.K. Simmons","character":"Nolan Grayson / Omni-Man (voice)","img":null,"order":2},{"name":"Dan Navarro","character":"Hazmat Responder / Additional Voices (voice)","img":null,"order":547},{"name":"Ami Shukla","character":"Additional Voices (voice)","img":null,"order":548},{"name":"Nyima Funk","character":"Additional Voices (voice)","img":null,"order":558},{"name":"Zazie Beetz","character":"Amber (voice)","img":null,"order":567},{"name":"Walton Goggins","character":"Cecil (voice)","img":null,"order":568},{"name":"Gillian Jacobs","character":"Eve (voice)","img":null,"order":574},{"name":"Jason Mantzoukas","character":"Rex / Zombie #2 (voice)","img":null,"order":588},{"name":"Chris Diamantopoulos","character":"Pete / Donald / Todd (voice)","img":null,"order":596},{"name":"Khary Payton","character":"Black Samson / Martian (voice)","img":null,"order":601},{"name":"Ross Marquand","character":"Immortal / Rudy / Kursk (voice)","img":null,"order":628},{"name":"Grey DeLisle","character":"Monster Girl / Thula / Woman (voice)","img":null,"order":656},{"name":"Bobby Kesselman","character":"Additional Voices (voice)","img":null,"order":734}],"tv:33880":[{"name":"Janet Varney","character":"Korra (voice)","img":null,"order":0},{"name":"David Faustino","character":"Mako (voice)","img":null,"order":1},{"name":"P.J. Byrne","character":"Bolin (voice)","img":null,"order":2},{"name":"Seychelle Gabriel","character":"Asami Sato (voice)","img":null,"order":3},{"name":"Mindy Sterling","character":"Lin Beifong (voice)","img":null,"order":6},{"name":"Adrian LaTourelle","character":"Unalaq (voice)","img":null,"order":9},{"name":"J.K. Simmons","character":"Mushi (voice)","img":null,"order":68},{"name":"Dee Bradley Baker","character":"Juicy (voice)","img":null,"order":324},{"name":"Kiernan Shipka","character":"Jinora (voice)","img":null,"order":500},{"name":"Darcy Rose Byrnes","character":"Ikki (voice)","img":null,"order":503},{"name":"Logan Wells","character":"Meelo (voice)","img":null,"order":504},{"name":"John Michael Higgins","character":"Varrick (voice)","img":null,"order":549},{"name":"Richard Riehle","character":"Bumi (voice)","img":null,"order":551},{"name":"Maria Bamford","character":"Pema (voice)","img":null,"order":556},{"name":"Jeff Bennett","character":"Shiro Shinobi / Fishmonger / Ring Announcer (voice)","img":null,"order":568}],"tv:86831":[{"name":"Josh Brener","character":"K-VRC (voice)","img":null,"order":237},{"name":"Matthew Yang King","character":"Host (voice)","img":null,"order":520},{"name":"Nolan North","character":"Vladimir (voice)","img":null,"order":555},{"name":"Ike Amadi","character":"Platoon Sergeant (voice)","img":null,"order":566},{"name":"Time Winters","character":"Dicko (voice)","img":null,"order":584},{"name":"Emily O'Brien","character":"Eve (voice)","img":null,"order":592},{"name":"Chris Cox","character":"Male Backgound (voice)","img":null,"order":592},{"name":"Noshir Dalal","character":"Beaumont (voice)","img":null,"order":599},{"name":"Michelle C. Bonilla","character":"Commander / Pilot (voice)","img":null,"order":599},{"name":"Stanton Lee","character":"Sergeant Howard (voice)","img":null,"order":602},{"name":"Fred Tatasciore","character":"Creature / TV Santa (voice)","img":null,"order":608},{"name":"Scott Whyte","character":"Trot (voice)","img":null,"order":618},{"name":"Caitlin McKenna","character":"Additional Voices (voice)","img":null,"order":622},{"name":"Piotr Michael","character":"Investor (voice)","img":null,"order":636},{"name":"Chris Parnell","character":"The Cat (voice)","img":null,"order":653}],"tv:68126":[{"name":"Trond Fausa Aurv\u00e5g","character":"Rufus","img":null,"order":0},{"name":"Jon \u00d8igarden","character":"Jarl Varg","img":null,"order":1},{"name":"K\u00e5re Conradi","character":"Orm","img":null,"order":2},{"name":"Silje Torp","character":"Fr\u00f8ya","img":null,"order":3},{"name":"Mikkel Bratt Silset","character":"Ragnar","img":null,"order":4},{"name":"Nils J\u00f8rgen Kaalstad","character":"Arvid","img":null,"order":5},{"name":"Kristine Riis","character":"Liv","img":null,"order":6},{"name":"Bj\u00f8rn Hallgeir Myrene","character":"Torstein Hund","img":null,"order":7},{"name":"Marian Saastad Ottesen","character":"Hildur","img":null,"order":8},{"name":"Nikis Theophilakis","character":"Olvar / Eigil","img":null,"order":9},{"name":"\u00d8ystein Martinsen","character":"Kark","img":null,"order":10},{"name":"Christian Skolmen","character":"H\u00e5kon","img":null,"order":11},{"name":"Erik Aleksander Schjerven","character":"Magnus","img":null,"order":12},{"name":"Ingar Helge Gimle","character":"Nomadeh\u00f8vding","img":null,"order":13},{"name":"Finn Schau","character":"Lovgiveren","img":null,"order":14}],"tv:60625":[{"name":"Justin Roiland","character":"Rick Sanchez / Morty Smith (voice)","img":null,"order":0},{"name":"Chris Parnell","character":"Jerry Smith (voice)","img":null,"order":1},{"name":"Spencer Grammer","character":"Summer Smith (voice)","img":null,"order":2},{"name":"Sarah Chalke","character":"Beth Smith (voice)","img":null,"order":3},{"name":"Ian Cardoni","character":"Rick Sanchez (voice)","img":null,"order":4},{"name":"Harry Belden","character":"Morty Smith (voice)","img":null,"order":6},{"name":"Dan Harmon","character":"Alejandro (voice)","img":null,"order":688},{"name":"Kari Wahlgren","character":"Roy's Wife (voice)","img":null,"order":715},{"name":"Maurice LaMarche","character":"Roy's Teacher / Gromflamite Fed (voice)","img":null,"order":743},{"name":"Tom Kenny","character":"Conroy / Federation Admiral / Additional Voices (voice)","img":null,"order":750},{"name":"Ryan Ridley","character":"Head Vampire (voice)","img":null,"order":752},{"name":"Brandon Johnson","character":"Mr. Goldenfold / Black Mailman (voice)","img":null,"order":755},{"name":"Nolan North","character":"Jerry's High School Friend (voice)","img":null,"order":757},{"name":"Rob Schrab","character":"Town Resident (voice)","img":null,"order":768},{"name":"Nick Reczynski","character":"Snake Humanoid (voice)","img":null,"order":815}],"tv:261579":[{"name":"Keanu Reeves","character":"Pilot (voice)","img":null,"order":500},{"name":"Parry Shen","character":"MC (young) (voice)","img":null,"order":501},{"name":"Ping Wu","character":"MC (Old) (voice)","img":null,"order":502},{"name":"Lydia Look","character":"Li (voice)","img":null,"order":503},{"name":"Nelson Lee","character":"Sean (voice)","img":null,"order":504},{"name":"Feodor Chin","character":"Thug (voice)","img":null,"order":505},{"name":"Rae Lim","character":"MC (Child) (voice)","img":null,"order":506},{"name":"Erin Yvette","character":"The Voice (voice)","img":null,"order":507},{"name":"Temuera Morrison","character":"Old Salt (voice)","img":null,"order":508},{"name":"Patrick Schwarzenegger","character":"The Kid (voice)","img":null,"order":509},{"name":"Steve Blum","character":"Dispatch / Mechanic (voice)","img":null,"order":510},{"name":"Noah Manzoor","character":"Solon (voice)","img":null,"order":511},{"name":"Madeleine Knight","character":"Mora (voice)","img":null,"order":512},{"name":"Aleks Le","character":"Yi Xing (voice)","img":null,"order":556},{"name":"Fred Tatasciore","character":"Helldiver (voice)","img":null,"order":558}],"tv:125988":[{"name":"Rebecca Ferguson","character":"Juliette Nichols","img":null,"order":0},{"name":"Common","character":"Robert Sims","img":null,"order":1},{"name":"Chinaza Uche","character":"Paul Billings","img":null,"order":2},{"name":"Shane McRae","character":"Knox","img":null,"order":4},{"name":"Remmie Milner","character":"Shirley Campbell","img":null,"order":6},{"name":"Alexandria Riley","character":"Camille Sims","img":null,"order":7},{"name":"Billy Postlethwaite","character":"Hank Murphy","img":null,"order":12},{"name":"Tim Robbins","character":"Bernard Holland","img":null,"order":15},{"name":"Clare Perkins","character":"Carla McLain","img":null,"order":17},{"name":"Harriet Walter","character":"Martha Walker","img":null,"order":18},{"name":"Avi Nash","character":"Lukas Kyle","img":null,"order":20},{"name":"Rick Gomez","character":"Patrick Kennedy","img":null,"order":21},{"name":"Olatunji Ayofe","character":"Teddy","img":null,"order":502},{"name":"Chipo Chung","character":"Sandy","img":null,"order":506},{"name":"Caitlin Zoz","character":"Kathleen Billings","img":null,"order":542}],"tv:2190":[{"name":"Isaac Hayes","character":"Chef (voice)","img":null,"order":2},{"name":"Mary Kay Bergman","character":"Liane Cartman / Wendy Testaburger / Sharon Marsh / Sheila Broflovski (voice)","img":null,"order":3},{"name":"Mona Marshall","character":"Sheila Broflovski (voice)","img":null,"order":4},{"name":"Sebastian Yu","character":"Ike Broflovski (voice)","img":null,"order":7},{"name":"Jessie Jo Thomas","character":"","img":null,"order":8},{"name":"Milan Agnone","character":"Ike Broflovski (voice)","img":null,"order":9},{"name":"Trey Parker","character":"Eric Cartman / Stan Marsh / Randy Marsh / Mr. Garrison (voice)","img":null,"order":10},{"name":"Matt Stone","character":"Kyle Broflovski / Kenny McCormick / Butters Stotch (voice)","img":null,"order":11},{"name":"Jennifer Howell","character":"Bebe Stevens (voice)","img":null,"order":11},{"name":"April Stewart","character":"Wendy Testaburger / Liane Cartman / Dora M\u00e1rquez (voice)","img":null,"order":65},{"name":"Eliza Schneider","character":"Liane Cartman (voice)","img":null,"order":79},{"name":"Kyle McCulloch","character":"Excalibur Hotel Employee (voice)","img":null,"order":512},{"name":"Jonathan Kimmel","character":"","img":null,"order":528},{"name":"John Hansen","character":"","img":null,"order":534},{"name":"Adrien Beard","character":"Tolkien Black (voice)","img":null,"order":554}],"tv:30984":[{"name":"Masakazu Morita","character":"Ichigo Kurosaki (voice)","img":null,"order":0},{"name":"Fumiko Orikasa","character":"Rukia Kuchiki (voice)","img":null,"order":1},{"name":"Hiroki Yasumoto","character":"Yasutora Sado (voice)","img":null,"order":2},{"name":"Yuki Matsuoka","character":"Orihime Inoue (voice)","img":null,"order":3},{"name":"Noriaki Sugiyama","character":"Uryu Ishida (voice)","img":null,"order":4},{"name":"Kentaro Ito","character":"Renji Abarai (voice)","img":null,"order":47},{"name":"Ryotaro Okiayu","character":"Byakuya Kuchki (voice)","img":null,"order":48},{"name":"Mitsuaki Madono","character":"Kon (voice)","img":null,"order":49},{"name":"Toshiyuki Morikawa","character":"Kaname T\u014dsen (voice)","img":null,"order":133},{"name":"Kiyoyuki Yanada","character":"Tessai Tsukabishi (voice)","img":null,"order":500},{"name":"Katsuyuki Konishi","character":"Shuhei Hisagi (voice)","img":null,"order":501},{"name":"Shin-ichiro Miki","character":"Kisuke Urahara (voice)","img":null,"order":504},{"name":"Masaya Onosaka","character":"Gejigeji mukade (voice)","img":null,"order":505},{"name":"Ryusei Nakao","character":"Mayuri Kurotsuchi (voice)","img":null,"order":509},{"name":"Takayuki Sugo","character":"Yhwach (voice)","img":null,"order":517}],"tv:114410":[{"name":"Kikunosuke Toya","character":"Denji (voice)","img":null,"order":0},{"name":"Tomori Kusunoki","character":"Makima (voice)","img":null,"order":1},{"name":"Shogo Sakata","character":"Aki Hayakawa (voice)","img":null,"order":2},{"name":"Fairouz Ai","character":"Power (voice)","img":null,"order":3},{"name":"Mariya Ise","character":"Himeno (voice)","img":null,"order":500},{"name":"Marina Inoue","character":"Child Denji (voice)","img":null,"order":507},{"name":"Kenjiro Tsuda","character":"Kishibe (voice)","img":null,"order":519},{"name":"Taku Yashiro","character":"Arai (voice)","img":null,"order":520},{"name":"Karin Takahashi","character":"Kobeni (voice)","img":null,"order":521},{"name":"Shiori Izawa","character":"Pochita (voice)","img":null,"order":522},{"name":"Mitsutoshi Shundo","character":"Announcer (voice)","img":null,"order":528},{"name":"Hironori Kondoh","character":"Eternity Devil (voice)","img":null,"order":538},{"name":"Noriyuki Tsuyuki","character":"Henchman D (voice)","img":null,"order":542},{"name":"Daiki Hamano","character":"Samurai Sword (voice)","img":null,"order":546},{"name":"You Taichi","character":"Sawatari (voice)","img":null,"order":547}],"tv:105248":[{"name":"KENN","character":"David Martinez (voice)","img":null,"order":0},{"name":"Koki Uchiyama","character":"D (voice)","img":null,"order":1},{"name":"Momoka Terasawa","character":"Roman (voice)","img":null,"order":2},{"name":"Akari Kito","character":"Talia (voice)","img":null,"order":3},{"name":"Kentaro Tone","character":"Weak (voice)","img":null,"order":4},{"name":"Kento Shiraishi","character":"Maelstrom (voice)","img":null,"order":531},{"name":"Kenjiro Tsuda","character":"Ripperdoc (voice)","img":null,"order":568},{"name":"Aoi Yuki","character":"Lucy (voice)","img":null,"order":571},{"name":"Kazuhiko Inoue","character":"Faraday (voice)","img":null,"order":573},{"name":"Tomoyo Kurosawa","character":"Rebecca (voice)","img":null,"order":574},{"name":"Takako Honda","character":"Kiwi (voice)","img":null,"order":575},{"name":"Ryuho Nagaoka","character":"Driver (voice)","img":null,"order":627},{"name":"Akemi Okamura","character":"Avida (voice)","img":null,"order":668},{"name":"Aoi Koga","character":"Capri (voice)","img":null,"order":669},{"name":"Yasunori Matsumoto","character":"Kiril (voice)","img":null,"order":670}],"tv:240411":[{"name":"Shion Wakayama","character":"Momo Ayase (voice)","img":null,"order":0},{"name":"Natsuki Hanae","character":"Ken 'Okarun' Takakura (voice)","img":null,"order":1},{"name":"Mayumi Tanaka","character":"Turbo Granny (voice)","img":null,"order":2},{"name":"Nana Mizuki","character":"Seiko (voice)","img":null,"order":3},{"name":"Kaori Maeda","character":"Miko (voice)","img":null,"order":500},{"name":"Miyu Tomita","character":"Muko (voice)","img":null,"order":501},{"name":"Ayane Sakura","character":"Aira Shiratori (voice)","img":null,"order":519},{"name":"Aya Yamane","character":"Tsubame (voice)","img":null,"order":520},{"name":"Natsu Yorita","character":"Anzu (voice)","img":null,"order":521},{"name":"Koji Seki","character":"Male Teacher (voice)","img":null,"order":527},{"name":"Koseki Kogure","character":"Student C (voice)","img":null,"order":527},{"name":"Yukiko Motoyoshi","character":"Female Student A (voice)","img":null,"order":528},{"name":"Kazuya Nakai","character":"Serpoian A / Serpoian B / Serpoian C (voice)","img":null,"order":533},{"name":"Tomokazu Seki","character":"Dover Demon (voice)","img":null,"order":536},{"name":"Kaito Ishikawa","character":"Jin 'Jiji' Enjouji (voice)","img":null,"order":541}],"tv:86031":[{"name":"Yusuke Kobayashi","character":"Senku Ishigami (voice)","img":null,"order":0},{"name":"Makoto Furukawa","character":"Taiju Oki (voice)","img":null,"order":1},{"name":"Kana Ichinose","character":"Yuzuriha Ogawa (voice)","img":null,"order":2},{"name":"Manami Numakura","character":"Kohaku (voice)","img":null,"order":3},{"name":"Yuichi Nakamura","character":"Tsukasa (voice)","img":null,"order":4},{"name":"Gen Sato","character":"Chrome (voice)","img":null,"order":5},{"name":"Ayumu Murase","character":"Ginro (voice)","img":null,"order":6},{"name":"Yuya Hirose","character":"Science Club Member (voice)","img":null,"order":501},{"name":"Aoi Ichikawa","character":"Science Club Member (voice)","img":null,"order":502},{"name":"Haruki Ishiya","character":"Science Club Member (voice)","img":null,"order":503},{"name":"Kouichi Souma","character":"Teacher (voice)","img":null,"order":504},{"name":"Keiji Fujiwara","character":"Byakuya Ishigami (voice)","img":null,"order":508},{"name":"Kengo Kawanishi","character":"Asagiri Gen (voice)","img":null,"order":526},{"name":"Ryota Suzuki","character":"Nanami Ryuusui (voice)","img":null,"order":527},{"name":"Karin Takahashi","character":"Suika (Voice)","img":null,"order":528}],"tv:209867":[{"name":"Atsumi Tanezaki","character":"Frieren (voice)","img":null,"order":0},{"name":"Kana Ichinose","character":"Fern (voice)","img":null,"order":1},{"name":"Chiaki Kobayashi","character":"Stark (voice)","img":null,"order":2},{"name":"Nobuhiko Okamoto","character":"Himmel (voice)","img":null,"order":3},{"name":"Hiroki Touchi","character":"\ud558\uc774\ud130 (voice)","img":null,"order":4},{"name":"Yoji Ueda","character":"Eisen (voice)","img":null,"order":5},{"name":"Kento Shiraishi","character":"Falsch (voice)","img":null,"order":550},{"name":"Azumi Waki","character":"Kanne (voice)","img":null,"order":565},{"name":"Sayumi Suzushiro","character":"Lawine (voice)","img":null,"order":566},{"name":"Ikumi Hasegawa","character":"\u00dcbel (voice)","img":null,"order":567},{"name":"Haruka Terui","character":"Sense (voice)","img":null,"order":568},{"name":"Tarusuke Shingaki","character":"Genau (voice)","img":null,"order":569},{"name":"Masafumi Kobatake","character":"Mining Worker (voice)","img":null,"order":572},{"name":"Jiro Saito","character":"Denken (voice)","img":null,"order":576},{"name":"Eiji Hanawa","character":"Richter (voice)","img":null,"order":577}],"tv:31911":[{"name":"Romi Park","character":"Edward Elric (voice)","img":null,"order":0},{"name":"Shin-ichiro Miki","character":"Roy Mustang (voice)","img":null,"order":2},{"name":"Fumiko Orikasa","character":"Riza Hawkeye (voice)","img":null,"order":3},{"name":"Megumi Takamoto","character":"Winry Rockbell (voice)","img":null,"order":4},{"name":"Rie Kugimiya","character":"Alphonse Elric (voice)","img":null,"order":341},{"name":"Hidekatsu Shibata","character":"King Bradley (voice)","img":null,"order":505},{"name":"Kenji Utsumi","character":"Louis Armstrong (voice)","img":null,"order":507},{"name":"Kenta Miyake","character":"Scar (voice)","img":null,"order":535},{"name":"Minami Takayama","character":"Envy (voice)","img":null,"order":541},{"name":"Iemasa Kayumi","character":"Father (voice)","img":null,"order":552},{"name":"Biichi Sato","character":"Doctor (voice)","img":null,"order":559},{"name":"Mamoru Miyano","character":"Ling Yao (voice)","img":null,"order":587},{"name":"Mai Gotou","character":"May Chang (voice)","img":null,"order":590},{"name":"Yuki Hayashi","character":"Military (voice)","img":null,"order":630},{"name":"Takashi Hikida","character":"Ishvalan A (voice)","img":null,"order":689}],"tv:95479":[{"name":"Takaya Kuroda","character":"Masamichi Yaga (voice)","img":null,"order":549},{"name":"Nobunaga Shimazaki","character":"Mahito (voice)","img":null,"order":600},{"name":"Tomokazu Seki","character":"Panda (voice)","img":null,"order":602},{"name":"Mikako Komatsu","character":"Maki Zen'in (voice)","img":null,"order":603},{"name":"Kenjiro Tsuda","character":"Kento Nanami (voice)","img":null,"order":605},{"name":"Junichi Suwabe","character":"Ryomen Sukuna (voice)","img":null,"order":612},{"name":"Shigeru Chiba","character":"Grandfather (voice)","img":"mF5YJxApTYKBVFJDrEC9IrJ5ooV.jpg","order":654},{"name":"Aya Endo","character":"Shoko Ieiri (voice)","img":null,"order":666},{"name":"Mitsuo Iwata","character":"Spectator (voice)","img":null,"order":685},{"name":"Yuichi Nakamura","character":"Satoru Gojo (voice)","img":null,"order":686},{"name":"Asami Seto","character":"Transfigured Human (voice)","img":null,"order":687},{"name":"Junya Enoki","character":"Yuji Itadori (voice)","img":null,"order":689},{"name":"Takahiro Sakurai","character":"Suguru Geto (voice)","img":null,"order":718},{"name":"Yoshiko Sakakibara","character":"Tengen (voice)","img":null,"order":739},{"name":"Yuma Uchida","character":"Megumi Fushiguro (voice)","img":null,"order":849}],"tv:207468":[{"name":"Masaya Fukunishi","character":"Kafka Hibino / Kaiju No. 8 (voice)","img":null,"order":0},{"name":"Asami Seto","character":"Mina Ashiro (voice)","img":null,"order":1},{"name":"Wataru Katoh","character":"Reno Ichikawa (voice)","img":null,"order":2},{"name":"Kengo Kawanishi","character":"Soshiro Hoshina (voice)","img":null,"order":4},{"name":"Fairouz Ai","character":"Kaiju No. 15 (voice)","img":null,"order":322},{"name":"Nene Hieda","character":"Akari Minase (voice)","img":null,"order":546},{"name":"Tomohiro Ono","character":"Shimoen (voice)","img":null,"order":551},{"name":"Genta Nakamura","character":"Operator (voice)","img":null,"order":569},{"name":"Takayuki Sugo","character":"Keiji Itami (voice)","img":null,"order":575},{"name":"Ryosuke Higa","character":"Ministry of Defense Staff Member (voice)","img":null,"order":577},{"name":"Shota Yamamoto","character":"Mebari (voice)","img":null,"order":612},{"name":"Yuuki Shin","character":"Iharu Furuhashi (voice)","img":null,"order":625},{"name":"Keisuke Komoto","character":"Haruichi Izumo (voice)","img":null,"order":626},{"name":"Shunsuke Takeuchi","character":"Aoi Kaguragi (voice)","img":null,"order":627},{"name":"Sayaka Senbongi","character":"Konomi Okonogi (voice)","img":null,"order":628}],"tv:65930":[{"name":"Daiki Yamashita","character":"Izuku Midoriya (voice)","img":null,"order":0},{"name":"Tarusuke Shingaki","character":"Mirio Togata (voice)","img":null,"order":1},{"name":"Nobuhiko Okamoto","character":"Katsuki Bakugo (voice)","img":null,"order":2},{"name":"Kenta Miyake","character":"All Might (voice)","img":null,"order":3},{"name":"Yuki Kaji","character":"Shoto Todoroki (voice)","img":null,"order":6},{"name":"Seiran Kobayashi","character":"Eri (voice)","img":null,"order":8},{"name":"Ayane Sakura","character":"Ochako Uraraka (voice)","img":null,"order":48},{"name":"Aoi Yuki","character":"Setsuna Tokage (voice)","img":null,"order":51},{"name":"Junichi Suwabe","character":"Jurota Shishida (voice)","img":null,"order":60},{"name":"Kaito Ishikawa","character":"Tenya Iida (voice)","img":null,"order":91},{"name":"Kenjiro Tsuda","character":"Overhaul (voice)","img":null,"order":505},{"name":"Koki Uchiyama","character":"Tomura Shigaraki (voice)","img":null,"order":546},{"name":"Hiro Shimono","character":"Dabi (voice)","img":null,"order":571},{"name":"Kiyotaka Furushima","character":"Kido (voice)","img":null,"order":583},{"name":"Tetsu Inada","character":"Endeavor (voice)","img":null,"order":585}],"tv:890":[{"name":"Megumi Ogata","character":"Shinji Ikari (voice)","img":null,"order":0},{"name":"Kotono Mitsuishi","character":"Misato Katsuragi (voice)","img":null,"order":1},{"name":"Megumi Hayashibara","character":"Rei Ayanami (voice)","img":null,"order":2},{"name":"Yuko Miyamura","character":"Asuka Langley Soryu (voice)","img":null,"order":3},{"name":"Yuriko Yamaguchi","character":"Dr. Ritsuko Akagi (voice)","img":null,"order":4},{"name":"Fumihiko Tachiki","character":"Gendo Ikari (voice)","img":null,"order":5},{"name":"Motomu Kiyokawa","character":"Kozo Fuyutsuki (voice)","img":null,"order":6},{"name":"Miki Nagasawa","character":"Maya Ibuki (voice)","img":null,"order":7},{"name":"Mugihito","character":"Keel Lorenz (voice)","img":null,"order":500},{"name":"Junko Iwao","character":"Hikari Horaki (voice)","img":null,"order":501},{"name":"Tetsuya Iwanaga","character":"Kensuke Aida (voice)","img":null,"order":503},{"name":"Tomokazu Seki","character":"Touji Suzuhara (voice)","img":null,"order":505},{"name":"Takehito Koyasu","character":"Shigeru Aoba (voice)","img":null,"order":505},{"name":"Koichi Yamadera","character":"Ryouji Kaji (voice)","img":"biov5jENp2XYfehkcdnRvi796Wi.jpg","order":506},{"name":"Hiro Yuuki","character":"Makoto Hyuuga (voice)","img":null,"order":508}],"tv:114868":[{"name":"Tomoyo Kurosawa","character":"G\u00f6ll (voice)","img":null,"order":1},{"name":"Wataru Takagi","character":"Zeus (voice)","img":null,"order":2},{"name":"Junichi Suwabe","character":"Hermes (voice)","img":null,"order":3},{"name":"Soma Saito","character":"Adam (voice)","img":null,"order":4},{"name":"Miyuki Sawashiro","character":"Narrator (voice)","img":null,"order":87},{"name":"Tatsuhisa Suzuki","character":"Shiva (voice)","img":null,"order":501},{"name":"Rie Tanaka","character":"Aphrodite (voice)","img":null,"order":502},{"name":"Yukihiro Nozuyama","character":"Heimdall (voice)","img":null,"order":516},{"name":"Koji Ishii","character":"Zhang Fei (voice)","img":null,"order":524},{"name":"Naoko Komatsu","character":"Eve (voice)","img":null,"order":525},{"name":"Taisuke Nakano","character":"Huginn (voice)","img":null,"order":531},{"name":"Daiki Hamano","character":"God (voice)","img":null,"order":532},{"name":"Chiko Mizumori","character":"Iori Miyamoto (voice)","img":null,"order":534},{"name":"Tomohiro Yamaguchi","character":"Man (voice)","img":null,"order":535},{"name":"Satoru Ito","character":"Spectator (voice)","img":null,"order":539}],"tv:207332":[{"name":"Tomokazu Sugita","character":"Taro Sakamoto (voice)","img":null,"order":0},{"name":"Nobunaga Shimazaki","character":"Shin Asakura (voice)","img":null,"order":1},{"name":"Ayane Sakura","character":"Lu Shaotang (voice)","img":null,"order":2},{"name":"Nao Toyama","character":"Aoi Sakamoto (voice)","img":null,"order":3},{"name":"Hina Kino","character":"Hana Sakamoto (voice)","img":null,"order":4},{"name":"Ryota Suzuki","character":"Heisuke Mashimo (voice)","img":null,"order":5},{"name":"Natsuki Hanae","character":"Yoichi Nagumo (voice)","img":null,"order":6},{"name":"Taku Yashiro","character":"Shishiba (voice)","img":null,"order":7},{"name":"Saori Hayami","character":"Osaragi (voice)","img":null,"order":8},{"name":"Hiroki Yasumoto","character":"Hyou (voice)","img":null,"order":9},{"name":"Hochu Otsuka","character":"Takamura (voice)","img":null,"order":10},{"name":"Daisuke Namikawa","character":"Kei Uzuki (voice)","img":null,"order":11},{"name":"Nobuhiko Okamoto","character":"Natsuki Seba (voice)","img":null,"order":500},{"name":"Yuhko Kaida","character":"Dump (voice)","img":null,"order":501},{"name":"Ryota Takeuchi","character":"Minimalist (voice)","img":null,"order":502}],"tv:249907":[{"name":"Yohei Azakami","character":"Xylo Forbartz (voice)","img":null,"order":0},{"name":"Mayu Iizuka","character":"Teoritta (voice)","img":null,"order":1},{"name":"Shizuka Ishigami","character":"Patouche Kivia (voice)","img":null,"order":2},{"name":"Shun Horie","character":"Dotta Luzlas (voice)","img":null,"order":3},{"name":"Shunichi Toki","character":"Venetim Leopold (voice)","img":null,"order":4},{"name":"Yoji Ueda","character":"Norgayu Senridge (voice)","img":null,"order":5},{"name":"Yoshitsugu Matsuoka","character":"Tatsuya (voice)","img":null,"order":6},{"name":"Jun Fukushima","character":"Tsav (voice)","img":null,"order":7},{"name":"Shoya Chiba","character":"Jace Pertilact (voice)","img":null,"order":8},{"name":"Yoko Hikasa","character":"Neely (voice)","img":null,"order":9}],"tv:120089":[{"name":"Takuya Eguchi","character":"Loid Forger (voice)","img":null,"order":0},{"name":"Atsumi Tanezaki","character":"Anya Forger (voice)","img":null,"order":1},{"name":"Saori Hayami","character":"Yor Forger (voice)","img":null,"order":2},{"name":"Kenichirou Matsuda","character":"Narration (voice)","img":null,"order":345},{"name":"Emiri Kato","character":"Agent M (voice)","img":null,"order":602},{"name":"Hiroki Goto","character":"Eden College Teacher (voice)","img":null,"order":611},{"name":"Hana Sato","character":"Onboard Announcement (voice)","img":null,"order":618},{"name":"Emiko Takeuchi","character":"Nurse (voice)","img":null,"order":643},{"name":"Mirei Kumagai","character":"Berlint General Hospital Doctor (voice)","img":null,"order":644},{"name":"Shoumaru Zouza","character":"Vides (voice)","img":null,"order":677},{"name":"Yuhko Kaida","character":"Sylvia Sherwood (voice)","img":null,"order":685},{"name":"Marie Ooi","character":"Gram Gretcher (voice)","img":null,"order":687},{"name":"Motoki Sakuma","character":"Wolson (voice)","img":null,"order":689},{"name":"Takaaki Torashima","character":"Secretary (voice)","img":null,"order":690},{"name":"Masafumi Kobatake","character":"Barkeeper (voice)","img":null,"order":694}],"tv:36243":[{"name":"Shintaro Asanuma","character":"'I' (Watashi) (voice)","img":null,"order":0},{"name":"Hiroyuki Yoshino","character":"Ozu (voice)","img":null,"order":1},{"name":"Keiji Fujiwara","character":"Higuchi (voice)","img":null,"order":2},{"name":"Yuhko Kaida","character":"Hanuki (voice)","img":null,"order":4},{"name":"Maaya Sakamoto","character":"Akashi (voice)","img":null,"order":5},{"name":"Junichi Suwabe","character":"Jogasaki (voice)","img":null,"order":6}],"tv:88803":[{"name":"Yuto Uemura","character":"Thorfinn (voice)","img":null,"order":0},{"name":"Naoya Uchida","character":"Askeladd (voice)","img":null,"order":1},{"name":"Shunsuke Takeuchi","character":"Einar (voice)","img":null,"order":2},{"name":"Kensho Ono","character":"Canute (voice)","img":null,"order":3},{"name":"Hiroki Yasumoto","character":"Bjorn (voice)","img":null,"order":4},{"name":"Akio Otsuka","character":"Thorkell (voice)","img":null,"order":5},{"name":"Yusuke Ohta","character":"Guard (voice)","img":null,"order":589},{"name":"Yoshiaki Hasegawa","character":"Scout of Thorkell's Troops (voice)","img":null,"order":596},{"name":"Takayuki Nakatsukasa","character":"Member of Askeladd's Mercenaries (voice)","img":null,"order":631},{"name":"Takuya Nakashima","character":"Retainer (voice)","img":null,"order":639},{"name":"Tsuguo Mogami","character":"Soldier of the English Army (voice)","img":null,"order":644},{"name":"Hiroki Goto","character":"Torgrim (voice)","img":null,"order":657},{"name":"Masato Niwa","character":"Wild Dog (voice)","img":null,"order":660},{"name":"Taito Ban","character":"Merchant (voice)","img":null,"order":662},{"name":"Shinya Takahashi","character":"Thegn (voice)","img":null,"order":678}],"tv:30669":[{"name":"Nozomu Sasaki","character":"Y\u016bsuke Urameshi (voice)","img":null,"order":1},{"name":"Shigeru Chiba","character":"Kazuma Kuwabara (voice)","img":"mF5YJxApTYKBVFJDrEC9IrJ5ooV.jpg","order":2},{"name":"Megumi Ogata","character":"Kurama/Sh\u016bichi Minamino (voice)","img":null,"order":3},{"name":"Nobuyuki Hiyama","character":"Hiei (voice)","img":null,"order":4},{"name":"Yuri Amano","character":"Keiko Yukimura (voice)","img":null,"order":5},{"name":"Hisako Kyoda","character":"Genkai (voice)","img":null,"order":6},{"name":"Mayumi Tanaka","character":"Koenma (voice)","img":null,"order":7},{"name":"Ai Orikasa","character":"Shizuru Kuwabara (voice)","img":null,"order":8},{"name":"Tomomichi Nishimura","character":"Narration (voice)","img":null,"order":10},{"name":"Sanae Miyuki","character":"Botan","img":null,"order":10},{"name":"Yuri Shiratori","character":"Yukina (voice)","img":null,"order":12},{"name":"Katsumi Suzuki","character":"Toguro (voice)","img":null,"order":13},{"name":"Rokuro Naya","character":"Sensui Shinobu (voice)","img":null,"order":14}],"movie:1930":[{"name":"Andrew Garfield","character":"Spider-Man / Peter Parker","img":null,"order":0},{"name":"Emma Stone","character":"Gwen Stacy","img":null,"order":1},{"name":"Rhys Ifans","character":"The Lizard / Dr. Curt Connors","img":null,"order":2},{"name":"Denis Leary","character":"Captain Stacy","img":null,"order":3},{"name":"Martin Sheen","character":"Uncle Ben","img":null,"order":4},{"name":"Sally Field","character":"Aunt May","img":null,"order":5},{"name":"Irrfan Khan","character":"Rajit Ratha","img":null,"order":6},{"name":"Campbell Scott","character":"Richard Parker","img":null,"order":7},{"name":"Embeth Davidtz","character":"Mary Parker","img":null,"order":8},{"name":"Chris Zylka","character":"Flash Thompson","img":null,"order":9},{"name":"Max Charles","character":"Peter Parker (Age 4)","img":null,"order":10},{"name":"C. Thomas Howell","character":"Jack's Father","img":null,"order":11},{"name":"Jake Keiffer","character":"Jack","img":null,"order":12},{"name":"Kari Coleman","character":"Helen Stacy","img":null,"order":13},{"name":"Michael Barra","character":"Store Clerk","img":null,"order":14}],"movie:102382":[{"name":"Andrew Garfield","character":"Spider-Man / Peter Parker","img":null,"order":0},{"name":"Emma Stone","character":"Gwen Stacy","img":null,"order":1},{"name":"Jamie Foxx","character":"Electro / Max Dillon","img":null,"order":2},{"name":"Dane DeHaan","character":"Green Goblin / Harry Osborn","img":null,"order":3},{"name":"Colm Feore","character":"Donald Menken","img":null,"order":4},{"name":"Felicity Jones","character":"Felicia","img":null,"order":5},{"name":"Paul Giamatti","character":"Aleksei Sytsevich","img":null,"order":6},{"name":"Sally Field","character":"Aunt May","img":null,"order":7},{"name":"Embeth Davidtz","character":"Mary Parker","img":null,"order":8},{"name":"Campbell Scott","character":"Richard Parker","img":null,"order":9},{"name":"Marton Csokas","character":"Dr. Ashley Kafka","img":null,"order":10},{"name":"Louis Cancelmi","character":"Man in Black Suit","img":null,"order":11},{"name":"Max Charles","character":"Young Peter Parker","img":null,"order":12},{"name":"B.J. Novak","character":"Allistar Smythe","img":null,"order":13},{"name":"Sarah Gadon","character":"Kari","img":null,"order":14}],"movie:55931":[{"name":"Keanu Reeves","character":"Neo (\"Kid's Story\") (voice)","img":null,"order":0},{"name":"Carrie-Anne Moss","character":"Trinity (\"Kid's Story\" and \"A Detective Story\") (voice)","img":null,"order":1},{"name":"Clayton Watson","character":"The Kid (\"Kid's Story\") (voice)","img":null,"order":2},{"name":"Pamela Adlon","character":"Jue (\"Final Flight of the Osiris\") / Manabu (\"Beyond\") (voice)","img":"5eIRHUbNOH7ibXa0IfUfFvj5I5L.jpg","order":3},{"name":"Melinda Clarke","character":"Alexa (\"Matriculated\") (voice)","img":null,"order":4},{"name":"John DiMaggio","character":"Crew Man (\"Final Flight of the Osiris\") / Kaiser (\"Program\") (voice)","img":null,"order":5},{"name":"Kevin Michael Richardson","character":"Thadeus (\"Final Flight of Osiris\") / Cop (\"Kid's Story\") / Agent #2 (\"World Record\")","img":null,"order":6},{"name":"Tom Kenny","character":"Operator (\"Final Flight of Osiris\")","img":null,"order":7},{"name":"Rick Gomez","character":"Pilot (\"Final Flight of Osiris\")","img":null,"order":8},{"name":"Tara Strong","character":"Crew Woman (\"Final Flight of Osiris\") / Nurse (\"World Record\") / Misha (\"Beyond\")","img":null,"order":9},{"name":"Bette Ford","character":"Old Woman (\"Final Flight of Osiris\")","img":null,"order":10},{"name":"Julia Fletcher","character":"The Instructor (\"The Second Renaissance Part I & II\") / Narrator (\"World Record\")","img":null,"order":11},{"name":"Dane A. Davis","character":"01 Versatran Spokesman (\"The Second Renaissance Part I & II\")","img":null,"order":12},{"name":"Debi Derryberry","character":"Kid (\"The Second Renaissance Part I & II\")","img":null,"order":13},{"name":"Jill Talley","character":"Mother (\"The Second Renaissance Part I & II\")","img":null,"order":14}],"movie:640146":[{"name":"Paul Rudd","character":"Scott Lang / Ant-Man","img":null,"order":0},{"name":"Evangeline Lilly","character":"Hope Van Dyne / The Wasp","img":null,"order":1},{"name":"Michael Douglas","character":"Dr. Hank Pym","img":null,"order":2},{"name":"Michelle Pfeiffer","character":"Janet Van Dyne","img":null,"order":3},{"name":"Jonathan Majors","character":"Kang the Conqueror","img":null,"order":4},{"name":"Kathryn Newton","character":"Cassie Lang","img":null,"order":5},{"name":"Corey Stoll","character":"M.O.D.O.K.","img":null,"order":6},{"name":"Bill Murray","character":"Lord Krylar","img":null,"order":7},{"name":"Katy O'Brian","character":"Jentorra","img":null,"order":8},{"name":"William Jackson Harper","character":"Quaz","img":null,"order":9},{"name":"Jamie Andrew Cutler","character":"Xolum","img":null,"order":10},{"name":"David Dastmalchian","character":"Veb (voice)","img":null,"order":11},{"name":"Randall Park","character":"Jimmy Woo","img":null,"order":12},{"name":"Mark Weinman","character":"Patrol Police Officer / On-Set M.O.D.O.K.","img":null,"order":13},{"name":"Ross Mullan","character":"Axia Restaurant Maitre D'","img":null,"order":14}],"movie:269650":[{"name":"Yuka Komatsu","character":"Deunan Knute (voice)","img":null,"order":0},{"name":"Junichi Suwabe","character":"Briareos Hecatonchires (voice)","img":null,"order":1},{"name":"Aoi Yuki","character":"Iris (voice)","img":null,"order":2},{"name":"Hiroki Takahashi","character":"Olson (voice)","img":null,"order":3},{"name":"Hiroki Touchi","character":"Talos (voice)","img":null,"order":4},{"name":"Kaori Nazuka","character":"Nyx (voice)","img":null,"order":5},{"name":"Tessyo Genda","character":"Two Horns (voice)","img":null,"order":6},{"name":"Katsunosuke Hori","character":"Mathews (voice)","img":null,"order":7},{"name":"Hisanori Yoshida","character":"(voice)","img":null,"order":8},{"name":"Shinichiro Kamio","character":"(voice)","img":null,"order":9},{"name":"Yoshiki Nakajima","character":"(voice)","img":null,"order":10},{"name":"Yuki Yonai","character":"(voice)","img":null,"order":11},{"name":"Mao Satonaka","character":"(voice)","img":null,"order":12}],"movie:572802":[{"name":"Jason Momoa","character":"Arthur","img":null,"order":0},{"name":"Patrick Wilson","character":"Orm","img":null,"order":1},{"name":"Yahya Abdul-Mateen II","character":"Black Manta","img":null,"order":2},{"name":"Randall Park","character":"Dr. Shin","img":null,"order":3},{"name":"Amber Heard","character":"Mera","img":null,"order":4},{"name":"Nicole Kidman","character":"Atlanna","img":null,"order":5},{"name":"Dolph Lundgren","character":"King Nereus","img":null,"order":6},{"name":"Temuera Morrison","character":"Tom","img":null,"order":7},{"name":"Lillah Indya Moore","character":"Karshon","img":null,"order":8},{"name":"Pilou Asb\u00e6k","character":"Kordax","img":null,"order":9},{"name":"Jani Zhao","character":"Stingray","img":null,"order":10},{"name":"Vincent Regan","character":"Atlan","img":null,"order":11},{"name":"Martin Short","character":"Kingfish (voice)","img":null,"order":12},{"name":"John Rhys-Davies","character":"Brine King (voice)","img":null,"order":13},{"name":"Natalia Safran","character":"Council Lady","img":null,"order":14}],"movie:24428":[{"name":"Robert Downey Jr.","character":"Tony Stark / Iron Man","img":null,"order":0},{"name":"Chris Evans","character":"Steve Rogers / Captain America","img":null,"order":1},{"name":"Mark Ruffalo","character":"Bruce Banner / The Hulk","img":null,"order":2},{"name":"Chris Hemsworth","character":"Thor","img":null,"order":3},{"name":"Scarlett Johansson","character":"Natasha Romanoff / Black Widow","img":null,"order":4},{"name":"Jeremy Renner","character":"Clint Barton / Hawkeye","img":null,"order":5},{"name":"Tom Hiddleston","character":"Loki","img":null,"order":6},{"name":"Clark Gregg","character":"Agent Phil Coulson","img":null,"order":7},{"name":"Cobie Smulders","character":"Agent Maria Hill","img":null,"order":8},{"name":"Stellan Skarsg\u00e5rd","character":"Selvig","img":"mW7xmtGV4y79kQGn0zkKVGDMAmw.jpg","order":9},{"name":"Samuel L. Jackson","character":"Nick Fury","img":null,"order":10},{"name":"Gwyneth Paltrow","character":"Pepper Potts","img":null,"order":11},{"name":"Paul Bettany","character":"Jarvis (voice)","img":null,"order":12},{"name":"Alexis Denisof","character":"The Other","img":null,"order":13},{"name":"Tina Benko","character":"NASA Scientist","img":null,"order":14}],"movie:257346":[{"name":"Miyuki Sawashiro","character":"Natasha Romanoff / Black Widow (voice)","img":null,"order":0},{"name":"Tessyo Genda","character":"Frank Castle / The Punisher (voice)","img":null,"order":1},{"name":"Hideaki Tezuka","character":"Nick Fury (voice)","img":null,"order":2},{"name":"Hiroki Touchi","character":"Elihas Starr (voice)","img":null,"order":3},{"name":"Ryuuzaburou Ootomo","character":"Cain (voice)","img":null,"order":4},{"name":"Junko Minagawa","character":"Maria Hill (voice)","img":null,"order":5},{"name":"Daisuke Namikawa","character":"Amadeus Cho (voice)","img":null,"order":6},{"name":"Masashi Sugawara","character":"Orion (voice)","img":null,"order":7},{"name":"Yuichi Karasuma","character":"The Hulk (voice)","img":null,"order":8},{"name":"Hisashi Izumi","character":"Ren (voice)","img":null,"order":9},{"name":"Keiji Fujiwara","character":"Tony Stark / Iron Man (voice)","img":null,"order":10},{"name":"Shuhei Sakaguchi","character":"Clint Barton / Hawkeye (voice)","img":null,"order":11}],"movie:99861":[{"name":"Robert Downey Jr.","character":"Tony Stark / Iron Man","img":null,"order":0},{"name":"Chris Hemsworth","character":"Thor","img":null,"order":1},{"name":"Mark Ruffalo","character":"Bruce Banner / Hulk","img":null,"order":2},{"name":"Chris Evans","character":"Steve Rogers / Captain America","img":null,"order":3},{"name":"Scarlett Johansson","character":"Natasha Romanoff / Black Widow","img":null,"order":4},{"name":"Jeremy Renner","character":"Clint Barton / Hawkeye","img":null,"order":5},{"name":"James Spader","character":"Ultron (voice)","img":null,"order":6},{"name":"Samuel L. Jackson","character":"Nick Fury","img":null,"order":7},{"name":"Don Cheadle","character":"James Rhodes / War Machine","img":null,"order":8},{"name":"Aaron Taylor-Johnson","character":"Pietro Maximoff / Quicksilver","img":null,"order":9},{"name":"Elizabeth Olsen","character":"Wanda Maximoff / Scarlet Witch","img":null,"order":10},{"name":"Paul Bettany","character":"Jarvis / Vision","img":null,"order":11},{"name":"Cobie Smulders","character":"Maria Hill","img":null,"order":12},{"name":"Anthony Mackie","character":"Sam Wilson / The Falcon","img":null,"order":13},{"name":"Hayley Atwell","character":"Peggy Carter","img":null,"order":14}],"movie:299536":[{"name":"Robert Downey Jr.","character":"Tony Stark / Iron Man","img":null,"order":0},{"name":"Chris Evans","character":"Steve Rogers / Captain America","img":null,"order":1},{"name":"Chris Hemsworth","character":"Thor","img":null,"order":2},{"name":"Josh Brolin","character":"Thanos","img":null,"order":3},{"name":"Mark Ruffalo","character":"Bruce Banner / Hulk","img":null,"order":4},{"name":"Scarlett Johansson","character":"Natasha Romanoff / Black Widow","img":null,"order":5},{"name":"Don Cheadle","character":"James Rhodes / War Machine","img":null,"order":6},{"name":"Benedict Cumberbatch","character":"Doctor Strange","img":null,"order":7},{"name":"Tom Holland","character":"Peter Parker / Spider-Man","img":"xKBAaPIa1c7tzZD3Y0MhBLv4hPE.jpg","order":8},{"name":"Chadwick Boseman","character":"T'Challa / Black Panther","img":null,"order":9},{"name":"Zoe Salda\u00f1a","character":"Gamora","img":null,"order":10},{"name":"Karen Gillan","character":"Nebula","img":null,"order":11},{"name":"Tom Hiddleston","character":"Loki","img":null,"order":12},{"name":"Paul Bettany","character":"Vision","img":null,"order":13},{"name":"Elizabeth Olsen","character":"Wanda Maximoff / Scarlet Witch","img":null,"order":14}],"movie:485942":[{"name":"Koichi Yamadera","character":"Batman / Bruce Wayne (voice)","img":"biov5jENp2XYfehkcdnRvi796Wi.jpg","order":0},{"name":"Wataru Takagi","character":"The Joker (voice)","img":null,"order":1},{"name":"Rie Kugimiya","character":"Harley Quinn / Harleen Quinzel (voice)","img":null,"order":2},{"name":"Ai Kakuma","character":"Catwoman / Selina Kyle (voice)","img":null,"order":3},{"name":"Hochu Otsuka","character":"Alfred Pennyworth (voice)","img":null,"order":4},{"name":"Daisuke Ono","character":"Nightwing / Dick Grayson (voice)","img":null,"order":5},{"name":"Akira Ishida","character":"Red Hood / Jason Todd (voice)","img":null,"order":6},{"name":"Kengo Kawanishi","character":"Red Robin / Tim Drake (voice)","img":null,"order":7},{"name":"Yuki Kaji","character":"Robin / Damian Wayne (voice)","img":null,"order":8},{"name":"Junichi Suwabe","character":"Deathstroke / Slade Wilson (voice)","img":null,"order":9},{"name":"Cho","character":"The Penguin / Oswald Cobblepot (voice)","img":null,"order":10},{"name":"Takehito Koyasu","character":"Gorilla Grodd (voice)","img":null,"order":11},{"name":"Toshiyuki Morikawa","character":"Two-Face / Harvey Dent (voice)","img":null,"order":12},{"name":"Atsuko Tanaka","character":"Poison Ivy / Pamela Isley (voice)","img":null,"order":13},{"name":"Kenta Miyake","character":"Bane (voice)","img":null,"order":14}],"movie:209112":[{"name":"Ben Affleck","character":"Bruce Wayne / Batman","img":null,"order":0},{"name":"Henry Cavill","character":"Clark Kent / Superman","img":null,"order":1},{"name":"Jesse Eisenberg","character":"Lex Luthor","img":null,"order":2},{"name":"Gal Gadot","character":"Diana Prince / Wonder Woman","img":null,"order":3},{"name":"Amy Adams","character":"Lois","img":null,"order":4},{"name":"Diane Lane","character":"Martha Kent","img":null,"order":5},{"name":"Laurence Fishburne","character":"Perry White","img":null,"order":6},{"name":"Jeremy Irons","character":"Alfred","img":null,"order":7},{"name":"Holly Hunter","character":"Senator Finch","img":null,"order":8},{"name":"Scoot McNairy","character":"Wallace Keefe","img":null,"order":9},{"name":"Callan Mulvey","character":"Anatoli Knyazev","img":null,"order":10},{"name":"Tao Okamoto","character":"Mercy Graves","img":null,"order":11},{"name":"Brandon Spink","character":"Young Bruce Wayne","img":null,"order":12},{"name":"Lauren Cohan","character":"Martha Wayne","img":null,"order":13},{"name":"Alan D. Purwin","character":"Wayne Industries Pilot","img":null,"order":14}],"movie:123025":[{"name":"Peter Weller","character":"Batman / Bruce Wayne (voice)","img":null,"order":0},{"name":"Ariel Winter","character":"Robin / Carrie Kelley (voice)","img":null,"order":1},{"name":"David Selby","character":"James Gordon (voice)","img":null,"order":2},{"name":"Wade Williams","character":"Harvey Dent / Two-Face (voice)","img":null,"order":3},{"name":"Michael McKean","character":"Dr. Bartholomew Wolper (voice)","img":null,"order":4},{"name":"Rob Paulsen","character":"Jeff Adams (voice)","img":null,"order":5},{"name":"Gary Anthony Williams","character":"Mutant Leader / Anchor Bill (voice)","img":null,"order":6},{"name":"Gary Anthony Sturgis","character":"Silk / Other Spike / Young Mutant (voice)","img":null,"order":7},{"name":"Paget Brewster","character":"Lana Lang (voice)","img":null,"order":8},{"name":"Carlos Alazraqui","character":"Hernando / TV Host (voice)","img":null,"order":9},{"name":"Dee Bradley Baker","character":"Don / Fat Mutant / Additional Voices (voice)","img":null,"order":10},{"name":"Maria Canals-Barrera","character":"Yindel (voice)","img":null,"order":11},{"name":"Cathy Cavadini","character":"Joanie / Woman with Hot Dog (voice)","img":null,"order":12},{"name":"Townsend Coleman","character":"Morrie / Civilian (voice)","img":null,"order":13},{"name":"Grey DeLisle","character":"Anchor Carla / Female Mutant (voice)","img":null,"order":14}],"movie:436270":[{"name":"Dwayne Johnson","character":"Black Adam / Teth Adam","img":null,"order":0},{"name":"Aldis Hodge","character":"Hawkman / Carter Hall","img":null,"order":1},{"name":"Noah Centineo","character":"Atom Smasher / Al Rothstein","img":null,"order":2},{"name":"Sarah Shahi","character":"Adrianna Tomaz","img":null,"order":3},{"name":"Quintessa Swindell","character":"Cyclone / Maxine Hunkel","img":null,"order":4},{"name":"Marwan Kenzari","character":"Ishmael / Sabbac / King Ahk-Ton","img":null,"order":5},{"name":"Mo Amer","character":"Karim","img":null,"order":6},{"name":"Bodhi Sabongui","character":"Amon Tomaz","img":null,"order":7},{"name":"Pierce Brosnan","character":"Dr. Fate / Kent Nelson","img":null,"order":8},{"name":"James Cusati-Moyer","character":"Samir","img":null,"order":9},{"name":"Jalon Christian","character":"Hurut","img":null,"order":10},{"name":"Benjamin Patterson","character":"Skinny Teth Adam","img":null,"order":11},{"name":"Odelya Halevi","character":"Shiruta","img":null,"order":12},{"name":"Uli Latukefu","character":"The Champion","img":null,"order":13},{"name":"Jennifer Holland","character":"Emilia Harcourt","img":null,"order":14}],"movie:284054":[{"name":"Chadwick Boseman","character":"T'Challa / Black Panther","img":null,"order":0},{"name":"Michael B. Jordan","character":"Erik Killmonger","img":null,"order":1},{"name":"Lupita Nyong'o","character":"Nakia","img":null,"order":2},{"name":"Danai Gurira","character":"Okoye","img":null,"order":3},{"name":"Martin Freeman","character":"Everett K. Ross","img":null,"order":4},{"name":"Daniel Kaluuya","character":"W'Kabi","img":null,"order":5},{"name":"Letitia Wright","character":"Shuri","img":null,"order":6},{"name":"Winston Duke","character":"M'Baku","img":null,"order":7},{"name":"Sterling K. Brown","character":"N'Jobu","img":null,"order":8},{"name":"Angela Bassett","character":"Ramonda","img":null,"order":9},{"name":"Forest Whitaker","character":"Zuri","img":null,"order":10},{"name":"Andy Serkis","character":"Ulysses Klaue","img":null,"order":11},{"name":"Florence Kasumba","character":"Ayo","img":null,"order":12},{"name":"John Kani","character":"T'Chaka","img":null,"order":13},{"name":"David S. Lee","character":"Limbani","img":null,"order":14}],"movie:505642":[{"name":"Letitia Wright","character":"Shuri","img":null,"order":0},{"name":"Tenoch Huerta Mej\u00eda","character":"Namor","img":null,"order":1},{"name":"Lupita Nyong'o","character":"Nakia","img":null,"order":2},{"name":"Danai Gurira","character":"Okoye","img":null,"order":3},{"name":"Winston Duke","character":"M'Baku","img":null,"order":4},{"name":"Angela Bassett","character":"Ramonda","img":null,"order":5},{"name":"Martin Freeman","character":"Everett Ross","img":null,"order":6},{"name":"Julia Louis-Dreyfus","character":"Valentina Allegra de Fontaine","img":null,"order":7},{"name":"Dominique Thorne","character":"Riri","img":null,"order":8},{"name":"Florence Kasumba","character":"Ayo","img":null,"order":9},{"name":"Michaela Coel","character":"Aneka","img":null,"order":10},{"name":"Alex Livinalli","character":"Attuma","img":null,"order":11},{"name":"Mabel Cadena","character":"Namora","img":null,"order":12},{"name":"Michael B. Jordan","character":"Killmonger","img":null,"order":13},{"name":"Isaach de Bankol\u00e9","character":"River Tribe Elder","img":null,"order":14}],"movie:409421":[{"name":"Takahiro Sakurai","character":"Killy (voice)","img":null,"order":0},{"name":"Kana Hanazawa","character":"Cibo (voice)","img":null,"order":1},{"name":"Sora Amamiya","character":"Zuru (voice)","img":null,"order":2},{"name":"Mamoru Miyano","character":"Sutezo (voice)","img":null,"order":3},{"name":"Aya Suzaki","character":"Tae (voice)","img":null,"order":4},{"name":"Nobunaga Shimazaki","character":"Fusata (voice)","img":null,"order":5},{"name":"Nanako Mori","character":"Fuku (voice)","img":null,"order":6},{"name":"Kazuhiro Yamaji","character":"Pop (voice)","img":null,"order":7}],"movie:17165":[{"name":"Masakazu Morita","character":"Ichigo Kurosaki (voice)","img":null,"order":0},{"name":"Fumiko Orikasa","character":"Rukia Kuchiki (voice)","img":null,"order":1},{"name":"Kentaro Ito","character":"Renji Abarai (voice)","img":null,"order":2},{"name":"Aya Hirano","character":"Homura (voice)","img":null,"order":3},{"name":"Hiroshi Kamiya","character":"Shizuku (voice)","img":null,"order":4},{"name":"Mitsuaki Madono","character":"Kon (voice)","img":null,"order":5},{"name":"Jun Fukuyama","character":"Yumichika Ayasegawa (voice)","img":null,"order":6},{"name":"Taro Yamaguchi","character":"Sasakibe Choujiro (voice)","img":null,"order":7},{"name":"Takako Honda","character":"Jinta Hanakari (voice)","img":null,"order":8},{"name":"Katsuyuki Konishi","character":"Shuuhei Hisagi (voice)","img":null,"order":9},{"name":"Rintaro Nishi","character":"Tetsuzaemon Iba (voice)","img":null,"order":10},{"name":"Tetsu Inada","character":"Sajin Komamura (voice)","img":null,"order":11},{"name":"Fumiko Orikasa","character":"Hisana Kuchiki (voice)","img":null,"order":12},{"name":"Rie Kugimiya","character":"Nemu Kurotsuchi (voice)","img":null,"order":13},{"name":"Hisayo Mochizuki","character":"Yachiru Kusajishi (voice)","img":null,"order":14}],"tv:73319":[{"name":"Ed Brown","character":"Self","img":null,"order":0},{"name":"Rosemarie Vega","character":"Self","img":null,"order":1},{"name":"Angela Deem","character":"Self","img":null,"order":2},{"name":"Michael Ilesanmi","character":"Self","img":null,"order":3}],"tv:90046":[],"tv:48866":[{"name":"Eliza Taylor","character":"Clarke Griffin","img":null,"order":0},{"name":"Bob Morley","character":"Bellamy Blake","img":null,"order":1},{"name":"Lindsey Morgan","character":"Raven Reyes","img":null,"order":2},{"name":"Marie Avgeropoulos","character":"Octavia Blake","img":null,"order":3},{"name":"Richard Harmon","character":"John Murphy","img":null,"order":5},{"name":"Luisa d'Oliveira","character":"Emori","img":null,"order":7},{"name":"Christopher Larkin","character":"Monty Green","img":null,"order":9},{"name":"Tati Gabrielle","character":"Gaia","img":null,"order":11},{"name":"Devon Bostick","character":"Jasper Jordan","img":null,"order":13},{"name":"Isaiah Washington","character":"Thelonious Jaha","img":null,"order":15},{"name":"Henry Ian Cusick","character":"Marcus Kane","img":null,"order":16},{"name":"Adina Porter","character":"Indra","img":null,"order":20},{"name":"Jarod Joseph","character":"Nathan Miller","img":null,"order":21},{"name":"Ricky Whittle","character":"Lincoln","img":null,"order":25},{"name":"Paige Turco","character":"Judge","img":null,"order":102}],"tv:11821":[{"name":"Bud Abbott","character":"Bud Abbott","img":null,"order":0},{"name":"Lou Costello","character":"Lou Costello","img":null,"order":1},{"name":"Joe Besser","character":"Stinky Davis","img":null,"order":500},{"name":"Hillary Brooke","character":"Hillary Brooke","img":null,"order":539},{"name":"Gordon Jones","character":"Mike Kelly","img":null,"order":540},{"name":"Sid Fields","character":"Sid Fields","img":null,"order":561},{"name":"Joe Kirk","character":"Mr. Bacciagalupe","img":null,"order":567},{"name":"Murray Leonard","character":"Doctor","img":null,"order":587},{"name":"Bobby Barber","character":"Tout","img":null,"order":614},{"name":"Joan Shawlee","character":"Marriage License Bureau Clerk","img":null,"order":634},{"name":"Dorothy Granger","character":"Arguing Wife","img":null,"order":642},{"name":"Milt Bronson","character":"Sam Speedy","img":null,"order":646},{"name":"Ray Walker","character":"Police Lt. Smith","img":null,"order":653},{"name":"Lucien Littlefield","character":"First Man","img":null,"order":658},{"name":"Veda Ann Borg","character":"Crazy Lady","img":null,"order":663}],"tv:43167":[{"name":"Yuki Kaji","character":"Arita Haruyuki","img":null,"order":0},{"name":"Sachika Misawa","character":"Kuroyuki-hime","img":null,"order":1},{"name":"Ayako Kawasumi","character":"Kakei Mihaya","img":null,"order":2},{"name":"Kenichi Suzumura","character":"Ash Roller","img":null,"order":3},{"name":"Aki Toyosaki","character":"Kurashima Chiyuri","img":null,"order":4},{"name":"Shintaro Asanuma","character":"Mayuzumi Takumu","img":null,"order":5},{"name":"Sanae Kobayashi","character":"Noumi Seiji","img":null,"order":6},{"name":"Rina Hidaka","character":"Kouzuki Yuniko","img":null,"order":7},{"name":"Haruka Tomatsu","character":"Wakamiya Megumi","img":null,"order":8}],"tv:114461":[{"name":"Rosario Dawson","character":"Ahsoka Tano","img":null,"order":0},{"name":"Natasha Liu Bordizzo","character":"Sabine Wren","img":null,"order":1},{"name":"Ivanna Sakhno","character":"Shin Hati","img":null,"order":2},{"name":"Ray Stevenson","character":"Baylan Skoll","img":null,"order":2},{"name":"Mary Elizabeth Winstead","character":"Hera Syndulla","img":null,"order":3},{"name":"Lars Mikkelsen","character":"Grand Admiral Thrawn","img":null,"order":4},{"name":"Eman Esfandi","character":"Ezra Bridger","img":null,"order":5},{"name":"Diana Lee Inosanto","character":"Morgan Elsbeth","img":null,"order":5},{"name":"Rory McCann","character":"Baylan Skoll","img":null,"order":6},{"name":"David Tennant","character":"Huyang (voice)","img":null,"order":6},{"name":"Hayden Christensen","character":"Anakin Skywalker","img":null,"order":7},{"name":"Paul Darnell","character":"Marrok","img":null,"order":512},{"name":"Chris Bartlett","character":"Home One Protocol Droid","img":null,"order":519},{"name":"Nican Robinson","character":"First Officer Vic Hawkins","img":null,"order":526},{"name":"Dawn Dininger","character":"Lieutenant Beyta","img":null,"order":546}],"tv:1433":[{"name":"Seth MacFarlane","character":"Stan Smith / Roger (voice)","img":null,"order":0},{"name":"Wendy Schaal","character":"Francine Smith (voice)","img":null,"order":1},{"name":"Rachael MacFarlane","character":"Hayley Smith (voice)","img":null,"order":2},{"name":"Scott Grimes","character":"Steve Smith (voice)","img":null,"order":3},{"name":"Dee Bradley Baker","character":"Klaus (voice)","img":null,"order":4},{"name":"Jeff Fischer","character":"Kidnapper (voice)","img":null,"order":204},{"name":"Mike Barker","character":"Terry Bates / Researcher (voice)","img":null,"order":1590},{"name":"Kevin Michael Richardson","character":"Rerun (voice)","img":null,"order":1824},{"name":"Mike Henry","character":"Jackson / Maitre D' (voice)","img":null,"order":1927},{"name":"Eddie Kaye Thomas","character":"Barry Robinson / Spike (voice)","img":null,"order":1967},{"name":"Patrick Stewart","character":"Avery Bullock as B (voice)","img":null,"order":2007},{"name":"Curtis Armstrong","character":"","img":null,"order":2028},{"name":"David Koechner","character":"Dick Reynolds (voice)","img":null,"order":2052},{"name":"Daisuke Suzuki","character":"Toshi Yoshida (voice)","img":null,"order":2054},{"name":"Richard Kind","character":"Car Salesman (voice)","img":null,"order":2057}],"tv:46639":[{"name":"Ricky Whittle","character":"Shadow Moon","img":null,"order":0},{"name":"Ian McShane","character":"Mr. Wednesday / God Odin","img":null,"order":1},{"name":"Emily Browning","character":"Laura Moon","img":null,"order":2},{"name":"Pablo Schreiber","character":"Mad Sweeney","img":null,"order":3},{"name":"Yetide Badaki","character":"Bilquis","img":null,"order":4},{"name":"Crispin Glover","character":"Mr. World","img":null,"order":5},{"name":"Bruce Langley","character":"Technical Boy","img":null,"order":6},{"name":"Omid Abtahi","character":"Salim","img":null,"order":7},{"name":"Kenzie Delo","character":"Herman","img":null,"order":9},{"name":"Demore Barnes","character":"Mr. Ibis","img":null,"order":611},{"name":"Herizen F. Guardiola","character":"Oshun","img":null,"order":612},{"name":"Peter Stormare","character":"Czernobog","img":null,"order":619},{"name":"Julia Sweeney","character":"Ann-Marie Hinzelmann","img":null,"order":620},{"name":"Eric Johnson","character":"Chad Mulligan","img":null,"order":621},{"name":"Lela Loren","character":"Marguerite Olsen","img":null,"order":624}],"tv:2985":[{"name":"Kevin Sorbo","character":"Dylan Hunt","img":null,"order":0},{"name":"Lisa Ryder","character":"Beka Valentine","img":null,"order":1},{"name":"Laura Bertram","character":"Trance Gemini","img":null,"order":2},{"name":"Gordon Michael Woolvett","character":"Seamus Harper","img":null,"order":3},{"name":"Lexa Doig","character":"Andromeda Ascendant","img":null,"order":4},{"name":"Brandy Ledford","character":"Doyle","img":null,"order":5},{"name":"Keith Hamilton Cobb","character":"Tyr Anasazi","img":null,"order":6},{"name":"Brent Stait","character":"Rev Bem","img":null,"order":7},{"name":"Steve Bacic","character":"Gaheris Rhade","img":null,"order":424},{"name":"Rik Kiviaho","character":"High Guard Captain Perim","img":null,"order":666},{"name":"Janyse Jaud","character":"Cavava (voice)","img":null,"order":677},{"name":"Robert Saunders","character":"Spirit of the Abyss","img":null,"order":689},{"name":"Jim Byrnes","character":"Virgil Vox","img":null,"order":775},{"name":"Nicholas Lea","character":"Tri-Lorn","img":null,"order":777},{"name":"Carmen Moore","character":"Tri-Jema","img":null,"order":813}],"tv:251":[{"name":"Dana Snyder","character":"Master Shake (voice)","img":null,"order":0},{"name":"Carey Means","character":"Frylock (voice)","img":null,"order":1},{"name":"Dave Willis","character":"Meatwad / Carl (voice)","img":null,"order":3},{"name":"Mike Schatz","character":"Emory (voice)","img":null,"order":6},{"name":"Andy Merrill","character":"Oglethorpe / Merle (voice)","img":null,"order":145},{"name":"Schoolly D","character":"Boost Mobile Phone (voice)","img":null,"order":333},{"name":"Matt Maiellaro","character":"Err / Cybernetic Ghost of Christmas Past (voice)","img":null,"order":396},{"name":"C. Martin Croker","character":"Birds (voice)","img":null,"order":455},{"name":"H. Jon Benjamin","character":"Don Shake","img":null,"order":576},{"name":"MC Chris","character":"Little Brittle (voice)","img":null,"order":617},{"name":"George Lowe","character":"George Lowe (voice)","img":null,"order":642},{"name":"Scott Hilley","character":"George Washington (voice)","img":null,"order":642},{"name":"Eugene Mirman","character":"Dr. Eugene Mirman (voice)","img":null,"order":660},{"name":"Edward Hastings","character":"Panda Furry (voice)","img":null,"order":661},{"name":"Nick Ingkatanuwat","character":"Tour Guide (voice)","img":null,"order":670}],"tv:86034":[{"name":"Toshinari Fukamachi","character":"Hajime Nagumo (voice)","img":null,"order":0},{"name":"Yuuki Kuwahara","character":"Yue (voice)","img":null,"order":1},{"name":"Minami Takahashi","character":"Shea Haulia (voice)","img":null,"order":2},{"name":"Yoko Hikasa","character":"Tio Klarus (voice)","img":null,"order":3},{"name":"Saori Onishi","character":"Kaori Shirasaki (voice)","img":null,"order":4},{"name":"Yumiri Hanamori","character":"Shizuku Yaegashi (voice)","img":null,"order":5},{"name":"Ai Kakuma","character":"Aiko Hatayama (voice)","img":null,"order":6},{"name":"Yui Ogura","character":"Myu (voice)","img":null,"order":7},{"name":"Noriko Shibasaki","character":"Liliana S. B. Heiligh (voice)","img":null,"order":8},{"name":"Katsuyuki Konishi","character":"Freid Bagwa (voice)","img":null,"order":10},{"name":"Makoto Ishii","character":"Mikhail (voice)","img":null,"order":11},{"name":"Hiroshi Watanabe","character":"Haulia Yao (voice)","img":null,"order":12},{"name":"Rina Sato","character":"Nun (voice)","img":null,"order":269},{"name":"Tetsuya Kakihara","character":"K\u014dki Amanogawa (voice)","img":null,"order":563},{"name":"Yasuhiro Mamiya","character":"Meld Loggins (voice)","img":null,"order":564}],"tv:1412":[{"name":"Stephen Amell","character":"Oliver Queen / Green Arrow","img":null,"order":0},{"name":"David Ramsey","character":"John Diggle / Spartan","img":null,"order":1},{"name":"Rick Gonzalez","character":"Rene Ramirez / Wild Dog","img":null,"order":4},{"name":"Susanna Thompson","character":"Moira Queen","img":null,"order":5},{"name":"Emily Bett Rickards","character":"Felicity Smoak","img":null,"order":13},{"name":"Paul Blackthorne","character":"Quentin Lance","img":null,"order":14},{"name":"Colton Haynes","character":"Roy Harper / Arsenal","img":null,"order":19},{"name":"John Barrowman","character":"Malcolm Merlyn","img":null,"order":26},{"name":"Echo Kellum","character":"Curtis Holt","img":null,"order":27},{"name":"Katie Cassidy","character":"Black Siren","img":null,"order":34},{"name":"Willa Holland","character":"Thea Queen / Speedy","img":null,"order":96},{"name":"Juliana Harkavy","character":"Dinah Drake / Black Canary","img":null,"order":223},{"name":"Manu Bennett","character":"Slade Wilson / Deathstroke","img":null,"order":279},{"name":"Audrey Marie Anderson","character":"Lyla Michaels","img":null,"order":1444},{"name":"Keri Adams","character":"Bethany Snow","img":null,"order":1589}],"tv:82452":[{"name":"Gordon Cormier","character":"Aang","img":null,"order":0},{"name":"Kiawentiio","character":"Katara","img":null,"order":1},{"name":"Ian Ousley","character":"Sokka","img":null,"order":2},{"name":"Dallas Liu","character":"Zuko","img":null,"order":3},{"name":"Paul Sun-Hyung Lee","character":"Uncle Iroh","img":null,"order":4},{"name":"Miyako","character":"Toph Beifong","img":null,"order":5},{"name":"Ken Leung","character":"Commander Zhao","img":null,"order":6},{"name":"Daniel Dae Kim","character":"Fire Lord Ozai","img":null,"order":7},{"name":"Ruy Iskandar","character":"Lieutenant Jee","img":null,"order":504},{"name":"Maria Zhang","character":"Suki","img":null,"order":523},{"name":"Thalia Tran","character":"Mai","img":null,"order":532},{"name":"Momona Tamada","character":"Ty Lee","img":null,"order":533},{"name":"Matthew Yang King","character":"Appa/Momo(voice)","img":null,"order":568},{"name":"Elizabeth Yu","character":"Azula","img":null,"order":575},{"name":"Dee Bradley Baker","character":"Appa/Momo(voice)","img":null,"order":629}],"tv:284833":[{"name":"Saheli Khan","character":"Pavi (voice)","img":null,"order":0},{"name":"Aishwarya 'Aishu' Devan","character":"Nisha (voice)","img":null,"order":1},{"name":"Major Curda","character":"Jae (voice)","img":null,"order":2},{"name":"Akshay Khanna","character":"Karthik (voice)","img":null,"order":3},{"name":"Sakina Jaffrey","character":"Agam (voice)","img":null,"order":4},{"name":"Eric Bauza","character":"Jin-woo / Pich / One Guy in the Crowd / Crowd / Airbenders / Firebenders (voice)","img":null,"order":502},{"name":"Tobit Raphael","character":"Ulan / Bending Cadet #1 / Bending Cadets (voice)","img":null,"order":509},{"name":"Dee Bradley Baker","character":"Geet / Ruhi (voice)","img":null,"order":510},{"name":"Darren Barnet","character":"Daemin (voice)","img":null,"order":511},{"name":"Clyde Kusatsu","character":"Commander Bountan / Crowd / Airbenders / Firebenders (voice)","img":null,"order":513},{"name":"Sarah Anne","character":"Fang / Bending Cadet #5 / Elloran Girl (voice)","img":null,"order":514},{"name":"Brycen Taylor Hall","character":"Ping (voice)","img":null,"order":515},{"name":"Xanthe Huynh","character":"Lan / Elloran Citizens (voice)","img":null,"order":516},{"name":"Kimberly Woods","character":"Lucky Cadet / Bending Cadet #2 / Bending Cadets (voice)","img":null,"order":519},{"name":"Zehra Fazal","character":"Bending Cadet #3 / Bending Cadet #4 / Masked Elloran Woman (voice)","img":null,"order":519}],"tv:15804":[{"name":"Diedrich Bader","character":"Batman (voice)","img":null,"order":0},{"name":"James Arnold Taylor","character":"Green Arrow / Jace (voice)","img":null,"order":523},{"name":"John DiMaggio","character":"Aquaman / Mr. Freeze (voice)","img":null,"order":549},{"name":"Jeff Bennett","character":"Buddy / OMAC (voice)","img":null,"order":553},{"name":"Tara Strong","character":"Mary/Billy Batson (voice)","img":null,"order":606},{"name":"Jason Marsden","character":"Scooby-Doo Robin (voice)","img":null,"order":628},{"name":"Tom Kenny","character":"Babyface / Plastic Man (voice)","img":null,"order":648},{"name":"Dee Bradley Baker","character":"Felix Faust / Fluke (voice)","img":null,"order":665},{"name":"Kevin Michael Richardson","character":"Lex Luthor (voice)","img":null,"order":667},{"name":"Greg Ellis","character":"Cavalier / Computer Voice / Nuclear Engineer (voice)","img":null,"order":673},{"name":"Corey Burton","character":"Silver Cyclone (voice)","img":null,"order":682},{"name":"Nicholas Guest","character":"Question (voice)","img":null,"order":722},{"name":"Will Friedle","character":"Blue Beetle (voice)","img":null,"order":733},{"name":"Grey DeLisle","character":"Daphne (voice)","img":null,"order":736},{"name":"Tom Everett Scott","character":"Booster Gold (voice)","img":null,"order":759}],"tv:89247":[{"name":"Ruby Rose","character":"Kate Kane / Batwoman","img":null,"order":1},{"name":"Javicia Leslie","character":"Ryan Wilder / Batwoman","img":null,"order":2},{"name":"Rachel Skarsten","character":"Alice / Beth Kane","img":null,"order":3},{"name":"Meagan Tandy","character":"Sophie Moore","img":null,"order":4},{"name":"Nicole Kang","character":"Mary Hamilton","img":null,"order":5},{"name":"Camrus Johnson","character":"Luke Fox","img":null,"order":6},{"name":"Dougray Scott","character":"Jacob Kane","img":null,"order":7},{"name":"Nick Creegan","character":"Marquis Jet","img":null,"order":8},{"name":"Robin Givens","character":"Jada Jet","img":null,"order":9},{"name":"Elizabeth Anweis","character":"Catherine Hamilton-Kane","img":null,"order":10},{"name":"Christina Wolfe","character":"Julia Pennyworth","img":null,"order":679},{"name":"Rachel Maddow","character":"Vesper Fairchild (voice)","img":null,"order":836},{"name":"Sam Littlefield","character":"Mouse","img":null,"order":841},{"name":"Nathan Owens","character":"Ocean","img":null,"order":842},{"name":"Allison Riley","character":"Dana Dewitt","img":null,"order":859}],"tv:74204":[{"name":"Nick Kroll","character":"Nick Birch / Maury the Hormone Monster / Coach Steve / Lola Skumpy / Rick the Hormone Monster (voice)","img":null,"order":0},{"name":"John Mulaney","character":"Andrew Glouberman (voice)","img":null,"order":1},{"name":"Jessi Klein","character":"Jessi Glaser (voice)","img":null,"order":2},{"name":"Jason Mantzoukas","character":"Jay Bilzerian (voice)","img":null,"order":4},{"name":"Maya Rudolph","character":"Diane Birch / Connie the Hormone Monstress (voice)","img":null,"order":5},{"name":"Fred Armisen","character":"Elliot Birch (voice)","img":null,"order":6},{"name":"Jordan Peele","character":"Ghost of Duke Ellington (voice)","img":null,"order":7},{"name":"Ayo Edebiri","character":"Missy Foreman-Greenwald (voice)","img":null,"order":91},{"name":"Andrew Rannells","character":"Leander / Matthew MacDell (voice)","img":null,"order":136},{"name":"Jenny Slate","character":"Pharmacist / Caitlin (voice)","img":null,"order":149},{"name":"Joe Wengert","character":"Caleb / Go-Gurt Thief / Teacher (voice)","img":null,"order":578},{"name":"Paula Pell","character":"(voice)","img":null,"order":622},{"name":"Neil Casey","character":"Detective Dumont (voice)","img":null,"order":624},{"name":"June Diane Raphael","character":"","img":null,"order":639},{"name":"Richard Kind","character":"","img":null,"order":674}],"tv:71663":[{"name":"Cress Williams","character":"Jefferson Pierce / Black Lightning","img":null,"order":0},{"name":"Nafessa Williams","character":"Anissa Pierce / Thunder / Blackbird","img":null,"order":1},{"name":"China Anne McClain","character":"Jennifer Pierce / Lightning","img":null,"order":2},{"name":"Christine Adams","character":"Lynn Pierce","img":null,"order":3},{"name":"Marvin Jones III","character":"Tobias Whale","img":null,"order":4},{"name":"James Remar","character":"Peter Gambi","img":null,"order":5},{"name":"Jordan Calloway","character":"Khalil Payne / Painkiller","img":null,"order":6},{"name":"Chantal Thuy","character":"Grace Choi","img":null,"order":7},{"name":"Damon Gupton","character":"Bill Henderson (voice)","img":null,"order":211},{"name":"Clifton Powell","character":"Reverend Jeremiah Holt","img":null,"order":730},{"name":"Bill Duke","character":"Agent Percy Odell","img":null,"order":801},{"name":"Jennifer Riker","character":"Dr. Helga Jace","img":null,"order":802},{"name":"Christopher Ammanuel","character":"Baron / TC","img":null,"order":818},{"name":"William Catlett","character":"Latavious 'Lala' Johnson","img":null,"order":853},{"name":"Jahking Guillory","character":"Brandon","img":null,"order":855}],"movie:1574":[{"name":"Ren\u00e9e Zellweger","character":"Roxie Hart","img":null,"order":0},{"name":"Catherine Zeta-Jones","character":"Velma Kelly","img":null,"order":1},{"name":"Richard Gere","character":"Billy Flynn","img":null,"order":2},{"name":"Queen Latifah","character":"Matron Mama Morton","img":null,"order":3},{"name":"John C. Reilly","character":"Amos Hart","img":null,"order":4},{"name":"Colm Feore","character":"Harrison","img":null,"order":5},{"name":"Dominic West","character":"Fred Casely","img":null,"order":6},{"name":"Christine Baranski","character":"Mary Sunshine","img":null,"order":7},{"name":"Ekaterina Chtchelkanova","character":"Katalin Helinski \"Hunyak\"","img":null,"order":8},{"name":"Lucy Liu","character":"Kitty Baxter","img":null,"order":9},{"name":"Taye Diggs","character":"Bandleader","img":null,"order":10},{"name":"Mya","character":"Mona","img":null,"order":11},{"name":"Deidre Goodwin","character":"June","img":null,"order":12},{"name":"Denise Faye","character":"Annie","img":null,"order":13},{"name":"Susan Misner","character":"Liz","img":null,"order":14}],"movie:220289":[{"name":"Emily Baldoni","character":"Em","img":null,"order":0},{"name":"Maury Sterling","character":"Kevin","img":null,"order":1},{"name":"Nicholas Brendon","character":"Mike","img":null,"order":2},{"name":"Lauren Maher","character":"Laurie","img":null,"order":3},{"name":"Elizabeth Gracen","character":"Beth","img":null,"order":4},{"name":"Hugo Armstrong","character":"Hugh","img":null,"order":5},{"name":"Lorene Scafaria","character":"Lee","img":null,"order":6},{"name":"Alex Manugian","character":"Amir","img":null,"order":7},{"name":"Kelly Donovan","character":"Extra","img":null,"order":8},{"name":"Aqueela Zoll","character":"Extra","img":null,"order":9},{"name":"Mark Ballou","character":"Extra","img":null,"order":10},{"name":"Alexis Boozer Sterling","character":"Extra","img":null,"order":11}],"movie:399057":[{"name":"Colin Farrell","character":"Steven Murphy","img":null,"order":0},{"name":"Nicole Kidman","character":"Anna Murphy","img":null,"order":1},{"name":"Barry Keoghan","character":"Martin Lang","img":null,"order":2},{"name":"Raffey Cassidy","character":"Kim Murphy","img":null,"order":3},{"name":"Sunny Suljic","character":"Bob Murphy","img":null,"order":4},{"name":"Bill Camp","character":"Matthew Williams","img":null,"order":5},{"name":"Alicia Silverstone","character":"Martin's Mother","img":null,"order":6},{"name":"Herb Caillouet","character":"Ed Thompson (Hospital Director)","img":null,"order":7},{"name":"Barry G. Bernson","character":"Dr. Larry Banks","img":null,"order":8},{"name":"Denise Dal Vera","character":"Mary Williams","img":null,"order":9},{"name":"Drew Logan","character":"Principal","img":null,"order":10},{"name":"Michael Trester","character":"Elderly Man","img":null,"order":11},{"name":"Anita Farmer Bergman","character":"Nurse (uncredited)","img":null,"order":12},{"name":"Lea Hutton Beasmore","character":"Conference Guest (uncredited)","img":null,"order":13},{"name":"Dylan Keith Adams","character":"Doctor at Conference and Event Dinner (uncredited)","img":null,"order":14}],"movie:430214":[{"name":"Gen Hoshino","character":"Senpai (voice)","img":null,"order":0},{"name":"Kana Hanazawa","character":"The Girl with Black Hair (voice)","img":null,"order":1},{"name":"Ami Koshimizu","character":"Naoko (voice)","img":null,"order":2},{"name":"Aoi Yuki","character":"Princess Daruma (voice)","img":null,"order":3},{"name":"Hiroshi Kamiya","character":"Director of School Festival Operations (voice)","img":null,"order":4},{"name":"Chikara Honda","character":"Bookstore Shopkeeper Gabi (voice)","img":null,"order":5},{"name":"Hiroyuki Yoshino","character":"God of the Old Books Market (voice)","img":null,"order":6},{"name":"Junichi Suwabe","character":"Nise-J\u014dgasaki (voice)","img":null,"order":7},{"name":"Kazuhiro Yamaji","character":"Todo (voice)","img":null,"order":8},{"name":"Kazuya Nakai","character":"Seitar\u014d Higuchi (voice)","img":null,"order":9},{"name":"Mugihito","character":"Ri Haku (voice)","img":null,"order":10},{"name":"Nobuyuki Hiyama","character":"Johnny (voice)","img":null,"order":11},{"name":"Ryuji Akiyama","character":"Don Underwear (voice)","img":null,"order":12},{"name":"Seiko Niizuma","character":"Kiko (voice)","img":null,"order":13},{"name":"S\u014dichi Nakaoka","character":"K\u014dsaka (voice)","img":null,"order":14}],"movie:1541":[{"name":"Susan Sarandon","character":"Louise","img":null,"order":0},{"name":"Geena Davis","character":"Thelma","img":null,"order":1},{"name":"Harvey Keitel","character":"Hal","img":null,"order":2},{"name":"Michael Madsen","character":"Jimmy","img":null,"order":3},{"name":"Christopher McDonald","character":"Darryl","img":null,"order":4},{"name":"Stephen Tobolowsky","character":"Max","img":"uL8yfcm0dCFYFQt052kczVQVvac.jpg","order":5},{"name":"Brad Pitt","character":"J.D.","img":null,"order":6},{"name":"Timothy Carhart","character":"Harlan","img":null,"order":7},{"name":"Lucinda Jenney","character":"Lena, the Waitress","img":null,"order":8},{"name":"Jason Beghe","character":"State Trooper","img":"hrTwOPWek7nkPJgFhh6inFu7vSS.jpg","order":9},{"name":"Sonny Carl Davis","character":"Albert","img":null,"order":10},{"name":"Ken Swofford","character":"Major","img":null,"order":11},{"name":"Shelly Desai","character":"East Indian Motel Clerk","img":null,"order":12},{"name":"Carol Mansell","character":"Waitress","img":null,"order":13},{"name":"Stephen Polk","character":"Surveilance Man","img":null,"order":14}],"movie:5038":[{"name":"Scarlett Johansson","character":"Cristina","img":null,"order":0},{"name":"Rebecca Hall","character":"Vicky","img":null,"order":1},{"name":"Javier Bardem","character":"Juan Antonio Gonzalo","img":null,"order":2},{"name":"Pen\u00e9lope Cruz","character":"Mar\u00eda Elena","img":null,"order":3},{"name":"Christopher Evan Welch","character":"Narrator (voice)","img":null,"order":4},{"name":"Chris Messina","character":"Doug","img":null,"order":5},{"name":"Patricia Clarkson","character":"Judy Nash","img":null,"order":6},{"name":"Kevin Dunn","character":"Mark Nash","img":null,"order":7},{"name":"Julio Perill\u00e1n","character":"Charles","img":null,"order":8},{"name":"Ricard Salom","character":"Art Gallery Guest","img":null,"order":9},{"name":"Maurice Sonnenberg","character":"Art Gallery Guest","img":null,"order":10},{"name":"Manel Barcel\u00f3","character":"Doctor","img":null,"order":11},{"name":"Josep Maria Dom\u00e8nech","character":"Julio","img":null,"order":12},{"name":"Emilio de Benito","character":"Guitarist in Asturias","img":null,"order":13},{"name":"Jaume Montan\u00e9","character":"Juan Antonio's Friend","img":null,"order":14}],"tv:108255":[{"name":"Nicholas Ralph","character":"James Herriot","img":null,"order":0},{"name":"Samuel West","character":"Siegfried Farnon","img":null,"order":1},{"name":"Anna Madeley","character":"Mrs Hall","img":null,"order":2},{"name":"Callum Woodhouse","character":"Tristan Farnon","img":null,"order":3},{"name":"Rachel Shenton","character":"Helen Herriot","img":null,"order":4},{"name":"James Anthony-Rose","character":"Richard Carmody","img":null,"order":500},{"name":"Mollie Winnard","character":"Maggie","img":null,"order":528},{"name":"Maimie McCoy","character":"Dorothy","img":null,"order":530},{"name":"Drew Cain","character":"James Herriot Senior","img":null,"order":535},{"name":"Will Thorp","character":"Gerald Hammond","img":null,"order":539},{"name":"Matthew Lewis","character":"Hugh Hulton","img":null,"order":552},{"name":"Patricia Hodge","character":"Mrs. Pumphrey","img":null,"order":553},{"name":"Imogen Clawson","character":"Jenny Alderson","img":null,"order":556},{"name":"Tony Pitts","character":"Richard Alderson","img":null,"order":558},{"name":"Gaia Wise","character":"Charlotte Beauvoir","img":null,"order":582}],"tv:88510":[{"name":"Daisy Haggard","character":"Miri Matteson","img":null,"order":0},{"name":"Geraldine James","character":"Caroline Matteson","img":null,"order":1},{"name":"Richard Durden","character":"Oscar Matteson","img":null,"order":2},{"name":"Jo Martin","character":"Janice","img":null,"order":3},{"name":"Adeel Akhtar","character":"Billy","img":null,"order":4},{"name":"Jamie Michie","character":"Dom","img":null,"order":5},{"name":"Christine Bottomley","character":"Mandy","img":null,"order":6},{"name":"Frank Feys","character":"Samuel","img":null,"order":502},{"name":"Liam Williams","character":"Nathan","img":null,"order":504},{"name":"Imogen Gurney","character":"Lara","img":null,"order":505},{"name":"Juliet Cowan","character":"Tina","img":null,"order":510},{"name":"Lizzy McInnerny","character":"Norah Boback","img":null,"order":515},{"name":"Adrian Edmondson","character":"John Boback","img":null,"order":516},{"name":"Keir Charles","character":"Mark","img":null,"order":520},{"name":"Hebe Bartlett","character":"Cerys","img":null,"order":522}],"tv:202851":[{"name":"Jack Rooke","character":"Narrator (voice)","img":null,"order":0},{"name":"Dylan Llewellyn","character":"Jack","img":null,"order":1},{"name":"Camille Coduri","character":"Peggy","img":null,"order":2},{"name":"Jon Pointing","character":"Danny","img":null,"order":3},{"name":"Katy Wix","character":"Jules","img":null,"order":4},{"name":"Izuka Hoyle","character":"Corinne","img":null,"order":5},{"name":"Olisa Odele","character":"Yemi","img":null,"order":6},{"name":"Harriet Webb","character":"Shannon","img":null,"order":7},{"name":"Annette Badland","character":"Nanny Bingo","img":null,"order":8},{"name":"Robert Gilbert","character":"Tim","img":null,"order":501},{"name":"Sheila Reid","character":"Iris","img":null,"order":502},{"name":"Lucia Keskin","character":"Kelly","img":null,"order":503},{"name":"Shane Zaza","character":"Tariq","img":null,"order":504},{"name":"Callum Mardy","character":"Ash","img":null,"order":505},{"name":"Ian Burfield","character":"Lance (voice)","img":null,"order":506}],"tv:39793":[{"name":"Vanessa Redgrave","character":"Jennifer Worth (voice)","img":null,"order":0},{"name":"Jenny Agutter","character":"Sister Julienne","img":null,"order":2},{"name":"Judy Parfitt","character":"Sister Monica Joan","img":null,"order":3},{"name":"Linda Bassett","character":"Phyllis Crane","img":null,"order":12},{"name":"Stephen McGann","character":"Dr Patrick Turner","img":null,"order":14},{"name":"Alice Brown","character":"Angela Turner","img":null,"order":23},{"name":"Laura Main","character":"Nurse Shelagh Turner","img":null,"order":24},{"name":"Cliff Parisi","character":"Fred Buckle","img":null,"order":26},{"name":"Georgie Glen","character":"Miss Millicent Higgins","img":null,"order":28},{"name":"Victoria Yeates","character":"Sister Winifred","img":null,"order":35},{"name":"Annabelle Apsion","character":"Violet Buckle","img":null,"order":87},{"name":"Max Macmillan","character":"Timothy Turner","img":null,"order":94},{"name":"Helen George","character":"Nurse Trixie Aylward","img":null,"order":102},{"name":"Zephryn Taitte","character":"Cyril Robinson","img":null,"order":104},{"name":"April Rae Hoang","character":"May Tang","img":null,"order":237}],"tv:76148":[{"name":"Saoirse-Monica Jackson","character":"Erin Quinn","img":null,"order":0},{"name":"Louisa Harland","character":"Orla McCool","img":null,"order":1},{"name":"Nicola Coughlan","character":"Clare Devlin","img":null,"order":2},{"name":"Jamie Lee O'Donnell","character":"Michelle Mallon","img":null,"order":3},{"name":"Dylan Llewellyn","character":"James Maguire","img":null,"order":4},{"name":"Tara Lynne O'Neill","character":"Ma Mary Quinn","img":null,"order":5},{"name":"Tommy Tiernan","character":"Da Gerry Quinn","img":null,"order":6},{"name":"Kathy Kiera Clarke","character":"Aunt Sarah","img":null,"order":7},{"name":"Ian McElhinney","character":"Granda Joe","img":null,"order":8},{"name":"Siobh\u00e1n McSweeney","character":"Sister Michael","img":null,"order":9},{"name":"Leah O'Rourke","character":"Jenny Joyce","img":null,"order":10},{"name":"Donna Traynor","character":"Donna Traynor","img":null,"order":555},{"name":"Beccy Henderson","character":"Aisling","img":null,"order":558},{"name":"Claire Rafferty","character":"Miss Mooney","img":null,"order":559},{"name":"Phillipa Dunne","character":"Geraldine Devlin","img":null,"order":572}],"tv:693":[{"name":"Teri Hatcher","character":"Susan Mayer","img":null,"order":0},{"name":"Felicity Huffman","character":"Lynette Scavo","img":null,"order":1},{"name":"Marcia Cross","character":"Bree Van de Kamp","img":null,"order":2},{"name":"Eva Longoria","character":"Gabrielle Solis","img":null,"order":3},{"name":"Ricardo Chavira","character":"Carlos Solis","img":null,"order":4},{"name":"Doug Savant","character":"Tom Scavo","img":null,"order":5},{"name":"Nicollette Sheridan","character":"Edie Britt","img":null,"order":6},{"name":"Mark Moses","character":"Paul Young","img":null,"order":7},{"name":"James Denton","character":"Mike Delfino","img":null,"order":8},{"name":"Brenda Strong","character":"Mary Alice Young","img":null,"order":10},{"name":"Kyle MacLachlan","character":"Orson Hodge","img":null,"order":14},{"name":"Shawn Pyfrom","character":"Andrew Van de Kamp","img":null,"order":19},{"name":"Andrea Bowen","character":"Julie Mayer","img":null,"order":21},{"name":"Kathryn Joosten","character":"Karen McCluskey","img":null,"order":25},{"name":"Joy Jorgensen","character":"Danielle Van de Kamp","img":null,"order":717}],"tv:203857":[{"name":"Keri Russell","character":"Ambassador Kate Wyler","img":null,"order":0},{"name":"Rufus Sewell","character":"Hal Wyler","img":null,"order":1},{"name":"David Gyasi","character":"Foreign Secretary Austin Dennison","img":null,"order":2},{"name":"Ali Ahn","character":"Eidra Park","img":null,"order":3},{"name":"Rory Kinnear","character":"Prime Minister Nicol Trowbridge","img":null,"order":4},{"name":"Ato Essandoh","character":"Stuart Hayford","img":null,"order":5},{"name":"Allison Janney","character":"Grace Penn","img":null,"order":7},{"name":"Nana Mensah","character":"Billie Appiah","img":null,"order":8},{"name":"Celia Imrie","character":"Meg Roylin","img":null,"order":500},{"name":"Penny Downie","character":"Frances Munning","img":null,"order":505},{"name":"Adam Silver","character":"Howard","img":null,"order":506},{"name":"Tim Delap","character":"Byron","img":null,"order":507},{"name":"Kenichiro Thomson","character":"Martin","img":null,"order":508},{"name":"Georgie Henley","character":"Pensy","img":null,"order":509},{"name":"Graham Miller","character":"Neil Barrow","img":null,"order":572}],"tv:66134":[{"name":"Keeley Hawes","character":"Louisa Durrell","img":null,"order":0},{"name":"Josh O'Connor","character":"Lawrence Durrell","img":null,"order":1},{"name":"Milo Parker","character":"Gerald Durrell","img":null,"order":2},{"name":"Daisy Waterstone","character":"Margo Durrell","img":null,"order":3},{"name":"Callum Woodhouse","character":"Leslie Durrell","img":null,"order":4},{"name":"Alexis Georgoulis","character":"Spiros Halikiopoulos","img":null,"order":5},{"name":"Yorgos Karamihos","character":"Theo Stephanides","img":null,"order":6},{"name":"Anna Savva","character":"Lugaretzia","img":null,"order":8},{"name":"Lucy Black","character":"Florence Petridis","img":null,"order":79},{"name":"Ben Hall","character":"Donald","img":null,"order":525},{"name":"Nikorestis Chaniotakis","character":"Pavlos the Monk","img":null,"order":553},{"name":"Elli Tringou","character":"Daphne Likourgou","img":null,"order":553},{"name":"Ulric von der Esch","character":"Sven","img":null,"order":578},{"name":"Alexis Conran","character":"Dr. Petridis","img":null,"order":579},{"name":"Miles Jupp","character":"Basil","img":null,"order":584}],"tv:225383":[{"name":"Luke Kirby","character":"Jack McMillan","img":null,"order":0},{"name":"Charlotte Gainsbourg","character":"Genevi\u00e8ve Lavigne","img":null,"order":1},{"name":"Lou de La\u00e2ge","character":"Cheyenne Toussaint","img":null,"order":2},{"name":"Gideon Glick","character":"Tobias Bell","img":null,"order":3},{"name":"David Alvarez","character":"Gael Rodriguez","img":null,"order":4},{"name":"Ivan du Pontavice","character":"Gabin","img":null,"order":5},{"name":"Ta\u00efs Vinolo","character":"Mishi Duplessis","img":null,"order":6},{"name":"David Haig","character":"Nicholas","img":null,"order":7},{"name":"LaMay Zhang","character":"Susu","img":null,"order":8},{"name":"Simon Callow","character":"Crispin Shamblee","img":null,"order":9},{"name":"Yanic Truesdale","character":"Rapha\u00ebl Marchand","img":null,"order":10},{"name":"Etai Benson","character":"Curt","img":null,"order":500},{"name":"Steve Belanger","character":"Al","img":null,"order":501}],"tv:4586":[{"name":"Lauren Graham","character":"Lorelai Gilmore","img":null,"order":0},{"name":"Alexis Bledel","character":"Rory Gilmore","img":null,"order":1},{"name":"Scott Patterson","character":"Luke Danes","img":null,"order":2},{"name":"Melissa McCarthy","character":"Sookie St. James","img":null,"order":3},{"name":"Keiko Agena","character":"Lane Kim","img":null,"order":4},{"name":"Yanic Truesdale","character":"Michel Gerard","img":null,"order":5},{"name":"Liza Weil","character":"Paris Geller","img":null,"order":6},{"name":"Jared Padalecki","character":"Dean Forester","img":null,"order":8},{"name":"Matt Czuchry","character":"Logan Huntzberger","img":null,"order":9},{"name":"Kelly Bishop","character":"Emily Gilmore","img":null,"order":10},{"name":"Edward Herrmann","character":"Richard Gilmore","img":null,"order":12},{"name":"Sean Gunn","character":"Kirk Gleason","img":null,"order":60},{"name":"Liz Torres","character":"Miss Patty","img":null,"order":692},{"name":"Michael Winters","character":"Taylor Doose","img":null,"order":697},{"name":"Jackson Douglas","character":"Jackson Belleville","img":null,"order":746}],"tv:117581":[{"name":"Antonia Gentry","character":"Virginia 'Ginny' Miller","img":null,"order":0},{"name":"Brianne Howey","character":"Georgia Miller","img":null,"order":1},{"name":"Diesel La Torraca","character":"Austin Miller","img":null,"order":2},{"name":"Jennifer Robertson","character":"Ellen Baker","img":null,"order":3},{"name":"Felix Mallard","character":"Marcus Baker","img":null,"order":4},{"name":"Sara Waisglass","character":"Maxine Baker","img":null,"order":5},{"name":"Scott Porter","character":"Mayor Paul Randolph","img":null,"order":6},{"name":"Raymond Ablack","character":"Joe","img":null,"order":7},{"name":"Mason Temple","character":"Hunter Chen","img":null,"order":8},{"name":"Katie Douglas","character":"Abigail 'Abby' Littman","img":null,"order":9},{"name":"Chelsea Clark","character":"Norah","img":null,"order":10},{"name":"Nikki Roumel","character":"Young Georgia","img":null,"order":205},{"name":"Sabrina Grdevich","character":"Cynthia Fuller","img":null,"order":502},{"name":"Colton Gobbo","character":"Jordan","img":null,"order":503},{"name":"Tyssen Smith","character":"Brodie","img":null,"order":504}],"tv:32504":[{"name":"Aly Michalka","character":"Marti Perkins","img":null,"order":0},{"name":"Ashley French","character":"Savannah Monroe","img":null,"order":1},{"name":"Heather Hemmens","character":"Alice Verdura","img":null,"order":2},{"name":"Robbie Jones","character":"Lewis Flynn","img":null,"order":3},{"name":"Matt Barr","character":"Dan Patch","img":null,"order":4},{"name":"Gail O'Grady","character":"Wanda Perkins","img":null,"order":5},{"name":"Sharon Leal","character":"Vanessa Lodge","img":null,"order":6},{"name":"Aaron Douglas","character":"Bill Marsh","img":null,"order":500},{"name":"Jeff Hephner","character":"Red Raymond","img":null,"order":501},{"name":"D. B. Woodside","character":"Derrick Altman","img":null,"order":502},{"name":"Elena Esovolova","character":"Patty Wedgerman","img":null,"order":503},{"name":"Emma Lahana","character":"Charlotte Monroe","img":null,"order":504},{"name":"Teryl Rothery","character":"Layne Monroe","img":null,"order":505},{"name":"Lauren Watson","character":"Judge (uncredited)","img":null,"order":506},{"name":"John Pyper-Ferguson","character":"Rex Perkins","img":null,"order":507}],"tv:226637":[{"name":"Kaitlin Olson","character":"Morgan Gillory","img":null,"order":0},{"name":"Daniel Sunjata","character":"Adam Karadec","img":null,"order":1},{"name":"Judy Reyes","character":"Selena Soto","img":null,"order":2},{"name":"Javicia Leslie","character":"Daphne Forrester","img":null,"order":3},{"name":"Deniz Akdeniz","character":"Lev 'Oz' Ozdil","img":null,"order":4},{"name":"Amirah J","character":"Ava Gillory","img":null,"order":5},{"name":"Matthew Lamb","character":"Elliot Radovic","img":null,"order":6},{"name":"Taran Killam","character":"Ludo Radovic","img":null,"order":500},{"name":"Garret Dillahunt","character":"Lieutenant Melon","img":null,"order":520},{"name":"TJ Lee","character":"Officer Lin","img":null,"order":522},{"name":"J. D. Pardo","character":"Tom","img":null,"order":570},{"name":"Mekhi Phifer","character":"Arthur Ellis","img":null,"order":686},{"name":"Steve Howey","character":"Nick Wagner","img":null,"order":719},{"name":"John Pyper-Ferguson","character":"Eric Hayworth","img":null,"order":754},{"name":"Susan Kelechi Watson","character":"Lucia","img":null,"order":774}],"tv:233079":[{"name":"Roisin Gallagher","character":"Saoirse","img":null,"order":0},{"name":"Sin\u00e9ad Keenan","character":"Robyn","img":null,"order":1},{"name":"Caoilfhionn Dunne","character":"Dara","img":null,"order":2},{"name":"Darragh Hand","character":"Liam","img":null,"order":3},{"name":"Natasha O'Keeffe","character":"Greta","img":null,"order":500},{"name":"Bronagh Gallagher","character":"Booker","img":null,"order":501},{"name":"Emmett J. Scanlan","character":"Owen","img":null,"order":502},{"name":"Emma Canning","character":"Young Greta","img":null,"order":503},{"name":"Michelle Fairley","character":"Margo","img":null,"order":504},{"name":"Jenn Murray","character":"Jamie","img":null,"order":510},{"name":"Eleanor Methven","character":"Mrs. Friel","img":null,"order":511},{"name":"Ardal O'Hanlon","character":"S\u00e9amus","img":null,"order":512},{"name":"Tom Basden","character":"Seb","img":null,"order":513},{"name":"Matilda Freeman","character":"Maria","img":null,"order":515},{"name":"Josh Finan","character":"Andrew Sampson","img":null,"order":520}],"tv:244447":[{"name":"Brittany Snow","character":"Sophie O\u2019Neill","img":null,"order":0},{"name":"Malin Akerman","character":"Margo Banks","img":null,"order":1},{"name":"Dermot Mulroney","character":"Jed Banks","img":null,"order":2},{"name":"Katie Lowes","character":"Jill Thompson","img":null,"order":3},{"name":"Jaime Ray Newman","character":"Callie","img":null,"order":4},{"name":"George Ferrier","character":"Brad Thompson","img":null,"order":4},{"name":"Chrissy Metz","character":"Starr Jackson","img":null,"order":4},{"name":"Evan Jonigkeit","character":"Graham O\u2019Neill","img":null,"order":5},{"name":"Alex Fitzalan","character":"Lincoln Trout","img":null,"order":6},{"name":"Hunter Emery","character":"Deputy Walter Flynn","img":null,"order":8},{"name":"Steve D'Avria","character":"Sheriff's Deputy","img":null,"order":9},{"name":"Karen Rodriguez","character":"Deputy Wanda Salazar","img":null,"order":10},{"name":"Madison Wolfe","character":"Abby Jackson","img":null,"order":503},{"name":"Alexandria DeBerry","character":"Taylor Tucker","img":null,"order":504},{"name":"Joyce Glenn","character":"Monae Roberts","img":null,"order":505}],"tv:125816":[{"name":"Sigourney Weaver","character":"June Hart","img":null,"order":0},{"name":"Alycia Debnam-Carey","character":"Alice Hart","img":null,"order":1},{"name":"Alyla Browne","character":"Young Alice Hart","img":null,"order":2},{"name":"Leah Purcell","character":"Twig","img":null,"order":3},{"name":"Frankie Adams","character":"Candy","img":null,"order":4},{"name":"Tilda Cobham-Hervey","character":"Agnes Hart","img":null,"order":5},{"name":"Asher Keddie","character":"Sally Morgan","img":null,"order":6},{"name":"Alexander England","character":"John Morgan","img":null,"order":7},{"name":"Charlie Vickers","character":"Clem Hart","img":null,"order":8},{"name":"Sebasti\u00e1n Zurita","character":"Dylan","img":null,"order":9},{"name":"Maggie Dence","character":"Boo","img":null,"order":502},{"name":"Dalara Williams","character":"Myf","img":null,"order":504},{"name":"Amy Kersey","character":"Rosie","img":null,"order":506},{"name":"Vivienne Awosoga","character":"Lulu","img":null,"order":514},{"name":"Shareena Clanton","character":"Ruby","img":null,"order":515}],"tv:99353":[{"name":"Nick Lachey","character":"Self - Host","img":null,"order":0},{"name":"Vanessa Lachey","character":"Self - Host","img":null,"order":1},{"name":"Cole Barnett","character":"Self - Contestant","img":null,"order":511},{"name":"Paul Peden","character":"Self - Contestant","img":null,"order":545},{"name":"Colleen Reed","character":"Self - Contestant","img":null,"order":581},{"name":"Matt Bolton","character":"Self - Contestant","img":null,"order":583},{"name":"Micah Lussier","character":"Self - Video Message","img":null,"order":594},{"name":"Alexa Alfia","character":"Self - Contestant","img":null,"order":602},{"name":"Brennon Lemieux","character":"Self - Video Message","img":null,"order":605},{"name":"Tiffany Pennywell","character":"Self - Contestant","img":null,"order":606},{"name":"Brett Brown","character":"Self - Video Message","img":null,"order":607},{"name":"Chelsea Griffin Appiah","character":"Self - Contestant","img":null,"order":607},{"name":"Zack Goytowski","character":"Self - Video Message","img":null,"order":608},{"name":"Kwame Appiah","character":"Self - Video Message","img":null,"order":610},{"name":"Bliss Poureetezadi","character":"Self - Video Message","img":null,"order":616}],"tv:285404":[{"name":"Tatiana Maslany","character":"Paula Sanders","img":null,"order":0},{"name":"Jake Johnson","character":"Karl Hendricks","img":null,"order":1},{"name":"Dolly de Leon","character":"Detective Sofia Gonzalez","img":null,"order":2},{"name":"Jessy Hodges","character":"Mallory","img":null,"order":3},{"name":"Jon Michael Hill","character":"Detective Baxter","img":null,"order":4},{"name":"Charlie Hall","character":"Rudy","img":null,"order":5},{"name":"Kiarra Hamagami Goldberg","character":"Geri","img":null,"order":6},{"name":"Nola Wallace","character":"Hazel","img":null,"order":7},{"name":"Brandon Flynn","character":"Trevor","img":null,"order":500},{"name":"Nina Bloomgarden","character":"Ash","img":null,"order":502},{"name":"Daniel Dale","character":"Sky","img":null,"order":504},{"name":"Remy Auberjonois","character":"Doug","img":null,"order":505},{"name":"Grace Porter","character":"Gwynn","img":null,"order":506},{"name":"Raymond Lee","character":"Steve","img":null,"order":507},{"name":"Murray Bartlett","character":"Dennis","img":null,"order":509}],"tv:118303":[{"name":"Ophelia Lovibond","character":"Joyce","img":null,"order":0},{"name":"Jake Johnson","character":"Doug","img":null,"order":1},{"name":"Michael Angarano","character":"Glenn","img":null,"order":2},{"name":"Jessica Lowe","character":"Bambi","img":null,"order":3},{"name":"Oscar Montoya","character":"Richie","img":null,"order":4},{"name":"Lennon Parham","character":"Shelly","img":null,"order":5},{"name":"Idara Victor","character":"Tina","img":null,"order":6},{"name":"Sofia Gonzalez","character":"Rita","img":null,"order":554},{"name":"David Lee Hess","character":"Phil","img":null,"order":557},{"name":"Jaeden Bettencourt","character":"Tommy","img":null,"order":572},{"name":"Rich Sommer","character":"Lenny","img":null,"order":576},{"name":"Elizabeth Perkins","character":"Constance","img":null,"order":579},{"name":"Lincoln A. Castellanos","character":"Daniel","img":null,"order":597},{"name":"Liora Belle","character":"Millie","img":null,"order":744},{"name":"Vera Myers","character":"Bottom Dollar Playmate (uncredited)","img":null,"order":766}],"tv:33155":[{"name":"Don Hany","character":"","img":null,"order":0},{"name":"Asher Keddie","character":"Nina Proudman","img":null,"order":1},{"name":"Deborah Mailman","character":"","img":null,"order":2},{"name":"Kat Stewart","character":"Billie Proudman","img":null,"order":3},{"name":"Richard Davies","character":"Jimmy Proudman","img":null,"order":4},{"name":"Linda Cropper","character":"Geraldine Proudman","img":null,"order":5},{"name":"Jane Harber","character":"Zara Perkich","img":null,"order":6},{"name":"Alicia Gardiner","character":"Kim Akerholt","img":null,"order":7},{"name":"Eddie Perfect","character":"Mick Holland","img":null,"order":8},{"name":"John Waters","character":"","img":null,"order":9},{"name":"Matthew Le Nevez","character":"","img":null,"order":10},{"name":"Lachy Hulme","character":"","img":null,"order":11},{"name":"Clare Bowditch","character":"Rosanna Harding","img":null,"order":12},{"name":"Kate Atkinson","character":"Renee","img":null,"order":508},{"name":"Shannon Berry","character":"Brody Jordan","img":null,"order":511}],"tv:107113":[{"name":"Steve Martin","character":"Charles-Haden Savage","img":null,"order":0},{"name":"Martin Short","character":"Oliver Putnam","img":null,"order":1},{"name":"Selena Gomez","character":"Mabel Mora","img":null,"order":2},{"name":"Amy Ryan","character":"Jan Bellows","img":null,"order":3},{"name":"Michael Cyril Creighton","character":"Howard Morris","img":null,"order":5},{"name":"Jackie Hoffman","character":"Uma Heller","img":null,"order":542},{"name":"Da'Vine Joy Randolph","character":"Donna Williams","img":null,"order":567},{"name":"Vanessa Aspillaga","character":"Ursula","img":null,"order":576},{"name":"Teddy Coluca","character":"Lester","img":null,"order":577},{"name":"Russell G. Jones","character":"Grover Stanley","img":null,"order":583},{"name":"Jayne Houdyshell","character":"Bunny Folger","img":null,"order":586},{"name":"Ryan Broussard","character":"Will Putnam","img":null,"order":588},{"name":"Meryl Streep","character":"Loretta Durkin","img":null,"order":598},{"name":"Paul Rudd","character":"Ben Glenroy","img":null,"order":644},{"name":"Richard Kind","character":"Vince Fish","img":null,"order":659}],"tv:207484":[{"name":"Harriet Slater","character":"Ellen MacKenzie","img":null,"order":0},{"name":"Jamie Roy","character":"Brian Fraser","img":null,"order":1},{"name":"Hermione Corfield","character":"Julia Moriston Beauchamp","img":null,"order":2},{"name":"Jeremy Irvine","character":"Henry Beauchamp","img":null,"order":3},{"name":"Tony Curran","character":"Lord Lovat (Simon Fraser)","img":null,"order":4},{"name":"S\u00e9amus McLean Ross","character":"Colum MacKenzie","img":null,"order":5},{"name":"Sam Retford","character":"Dougal MacKenzie","img":null,"order":6},{"name":"Rory Alexander","character":"Murtagh Fitzgibbons Fraser","img":null,"order":7},{"name":"Conor MacNeill","character":"Ned Gowan","img":null,"order":8},{"name":"Sara Vickers","character":"Davina Porter","img":null,"order":9},{"name":"Sadhbh Malin","character":"Jocasta MacKenzie Cameron","img":null,"order":502},{"name":"Jhon Lumsden","character":"Malcolm Grant","img":null,"order":503},{"name":"Sally Messham","character":"Mrs. Fitzgibbons","img":null,"order":506},{"name":"Terence Rae","character":"Arch Bug","img":null,"order":507},{"name":"Chick Allan","character":"Balloch","img":null,"order":514}],"tv:208921":[{"name":"David Tennant","character":"Tony Baddingham","img":null,"order":0},{"name":"Aidan Turner","character":"Declan O'Hara","img":null,"order":1},{"name":"Danny Dyer","character":"Freddie Jones","img":null,"order":2},{"name":"Alex Hassell","character":"Rupert Campbell-Black","img":null,"order":3},{"name":"Nafessa Williams","character":"Cameron Cook","img":null,"order":4},{"name":"Bella Maclean","character":"Taggie O'Hara","img":null,"order":5},{"name":"Katherine Parkinson","character":"Lizzie Vereker","img":null,"order":6},{"name":"Victoria Smurfit","character":"Maud O'Hara","img":null,"order":7},{"name":"Claire Rushbrook","character":"Lady Monica Baddingham","img":null,"order":8},{"name":"Oliver Chris","character":"James Vereker","img":null,"order":9},{"name":"Lisa McGrillis","character":"Valerie Jones","img":null,"order":10},{"name":"Emily Atack","character":"Sarah Stratton","img":null,"order":11},{"name":"Rufus Jones","character":"Paul Stratton","img":null,"order":12},{"name":"Luke Pasqualino","character":"Basil 'Bas' Baddingham","img":null,"order":13},{"name":"Catriona Chandler","character":"Caitlin O'Hara","img":null,"order":14}],"tv:254953":[{"name":"Steve Carell","character":"Greg Russo","img":null,"order":0},{"name":"Charly Clive","character":"Katie Russo","img":null,"order":1},{"name":"Danielle Deadwyler","character":"Dylan Shepard","img":null,"order":2},{"name":"Phil Dunster","character":"Archie Bates","img":null,"order":3},{"name":"John C. McGinley","character":"Walter Mann","img":null,"order":4},{"name":"Lauren Tsai","character":"Sunny Salewski","img":null,"order":5},{"name":"Annie Mumolo","character":"Cristle","img":null,"order":500},{"name":"Rory Scovel","character":"Officer Donnie Mullins","img":null,"order":501},{"name":"Cece Abbey","character":"Maya","img":null,"order":503},{"name":"Xavier Beloved","character":"George Heitman","img":null,"order":504},{"name":"Noah Grismer","character":"J.D.","img":null,"order":507},{"name":"Madison Hu","character":"Eva","img":null,"order":508},{"name":"Evan Jachelski","character":"Spooner","img":null,"order":509},{"name":"Maximo Salas","character":"Tommy Newton","img":null,"order":515},{"name":"Robby Hoffman","character":"Mo","img":null,"order":518}],"tv:105":[{"name":"Sarah Jessica Parker","character":"Carrie Bradshaw","img":null,"order":0},{"name":"Kim Cattrall","character":"Samantha Jones","img":null,"order":1},{"name":"Cynthia Nixon","character":"Miranda Hobbes","img":null,"order":2},{"name":"Kristin Davis","character":"Charlotte York","img":null,"order":3},{"name":"Lynn Cohen","character":"Magda","img":null,"order":826},{"name":"Willie Garson","character":"Stanford Blatch","img":null,"order":962},{"name":"Mario Cantone","character":"Anthony Marantino","img":null,"order":964},{"name":"Chris Noth","character":"Mr. Big","img":null,"order":982},{"name":"Kyle MacLachlan","character":"Trey MacDougal","img":null,"order":1001},{"name":"David Eigenberg","character":"Steve Brady","img":null,"order":1022},{"name":"Frances Sternhagen","character":"Bunny MacDougal","img":null,"order":1023},{"name":"John Corbett","character":"Aidan Shaw","img":null,"order":1026},{"name":"James Remar","character":"Richard Wright","img":null,"order":1040},{"name":"Jason Lewis","character":"Jerry 'Smith' Jerrod","img":null,"order":1062},{"name":"Evan Handler","character":"Harry Goldenblatt","img":"yU0OXeZ0K1ppe1o9SpHiAMHy1rc.jpg","order":1096}],"tv:133908":[{"name":"Natasha Calis","character":"Hayley Roberts","img":null,"order":0},{"name":"Morgan Holmstrom","character":"Crystal Highway","img":null,"order":1},{"name":"Aaron Ashmore","character":"William \"Wheezer\" Heaseman","img":null,"order":2},{"name":"Mercedes Morris","character":"Lexi Martine","img":null,"order":3},{"name":"Praneet Akilla","character":"Jay \"Chopper\" Chopra","img":null,"order":4},{"name":"Aason Nadjiwan","character":"Austen Bodie","img":null,"order":5},{"name":"Alexander Eling","character":"Wyatt Ellis","img":null,"order":6},{"name":"Thomas Elms","character":"Milosz Nowak","img":null,"order":8},{"name":"Kheon Clarke","character":"Tristan Green","img":null,"order":10},{"name":"Rebecca Kwan","character":"Emma Lin","img":null,"order":12},{"name":"Braeden Clarke","character":"Jeremy Wood","img":null,"order":14},{"name":"Emilia McCarthy","character":"Madison Van Camp","img":null,"order":15},{"name":"Patrick Kwok-Choon","character":"Trevor Sung","img":null,"order":16},{"name":"Sydney Kuhne","character":"Stef","img":null,"order":17},{"name":"Anthony Grant","character":"TJ","img":null,"order":18}],"tv:40231":[{"name":"EliZe","character":"Self - Presenter","img":null,"order":0},{"name":"Dan Karaty","character":"Self - Jury","img":null,"order":1},{"name":"Euvgenia Parakhina","character":"Self - Jury","img":null,"order":2},{"name":"Jaakko Toivonen","character":"Self - Jury","img":null,"order":3},{"name":"Nicky Vernieuwe","character":"Self - Jury","img":null,"order":4},{"name":"Marco Gerris","character":"Self - Jury","img":null,"order":5},{"name":"Min Hee Bervoets","character":"Self - Jury","img":null,"order":6},{"name":"Roberto da Costa","character":"Guest Jury","img":null,"order":7},{"name":"Brahim Attaeb","character":"Guest Jury","img":null,"order":8},{"name":"Eszteca Noya","character":"Guest Jury","img":null,"order":9},{"name":"Dennis Weening","character":"Self - Presenter","img":null,"order":10},{"name":"Ish A\u00eft Hamou","character":"Self - Jury","img":null,"order":11},{"name":"Eline De Munck","character":"Self - Presenter","img":null,"order":12},{"name":"Jan Kooijman","character":"Self - Jury","img":null,"order":13},{"name":"Wendy van Dijk","character":"Self - Jury","img":null,"order":257}],"tv:111803":[{"name":"Leslie Bibb","character":"Kate Bohr","img":null,"order":0},{"name":"Jennifer Coolidge","character":"Tanya McQuoid","img":null,"order":1},{"name":"Carrie Coon","character":"Laurie Duffy","img":null,"order":1},{"name":"Walton Goggins","character":"Rick Hatchett","img":null,"order":2},{"name":"Sarah Catherine Hook","character":"Piper Ratliff","img":null,"order":3},{"name":"Jason Isaacs","character":"Timothy Ratliff","img":null,"order":4},{"name":"Jon Gries","character":"Greg Hunt","img":null,"order":5},{"name":"Parker Posey","character":"Victoria Ratliff","img":null,"order":5},{"name":"Patrick Schwarzenegger","character":"Saxon Ratliff","img":null,"order":6},{"name":"Tayme Thapthimthong","character":"Gaitok","img":null,"order":7},{"name":"Aimee Lou Wood","character":"Chelsea","img":null,"order":8},{"name":"LISA","character":"Mook","img":null,"order":9},{"name":"Michelle Monaghan","character":"Jaclyn Lemon","img":null,"order":10},{"name":"Natasha Rothwell","character":"Belinda Lindsey","img":null,"order":11},{"name":"Sam Nivola","character":"Lochlan Ratliff","img":null,"order":12}],"tv:117488":[{"name":"Melanie Lynskey","character":"Shauna Sadecki","img":null,"order":0},{"name":"Tawny Cypress","character":"Taissa Turner","img":null,"order":1},{"name":"Sophie N\u00e9lisse","character":"Teen Shauna Shipman","img":null,"order":3},{"name":"Jasmin Savoy Brown","character":"Teen Taissa Turner","img":null,"order":4},{"name":"Sophie Thatcher","character":"Teen Natalie Scatorccio","img":null,"order":5},{"name":"Sammi Hanratty","character":"Teen Misty Quigley","img":null,"order":6},{"name":"Steven Krueger","character":"Ben Scott","img":null,"order":7},{"name":"Warren Kole","character":"Jeff Sadecki","img":null,"order":8},{"name":"Courtney Eaton","character":"Teen Lottie Matthews","img":null,"order":9},{"name":"Lauren Ambrose","character":"Van Palmer","img":null,"order":10},{"name":"Christina Ricci","character":"Misty Quigley","img":null,"order":11},{"name":"Kevin Alves","character":"Teen Travis","img":null,"order":14},{"name":"Liv Hewson","character":"Teen Van Palmer","img":null,"order":15},{"name":"Sarah Desjardins","character":"Callie Sadecki","img":null,"order":16},{"name":"Alexa Barajas","character":"Teen Mari Ibarra","img":null,"order":18}],"movie:21469":[{"name":"Mike Vogel","character":"Julian","img":null,"order":0},{"name":"Brittany Murphy","character":"June","img":null,"order":1},{"name":"Danny Pino","character":"Terry","img":null,"order":2},{"name":"Brad Greenquist","character":"The Porter","img":null,"order":3},{"name":"Arie Verveen","character":"Lucas","img":null,"order":4},{"name":"Natalie Smyka","character":"Anna","img":null,"order":5},{"name":"Guillermo D\u00edaz","character":"The Cook","img":null,"order":6},{"name":"Dov Davidoff","character":"The Bellhop","img":null,"order":7},{"name":"William Stanford Davis","character":"Custodian","img":null,"order":8},{"name":"Erika Ringor","character":"Detective","img":null,"order":9},{"name":"Mark Engelhardt","character":"Officer","img":null,"order":10},{"name":"Chase Kim","character":"Police Officer","img":null,"order":11},{"name":"Erika Seifred","character":"Dominatrix","img":null,"order":12},{"name":"Cameron Cash","character":"Georgie (uncredited)","img":null,"order":13}],"movie:235271":[{"name":"Sharon Leal","character":"Zoe Reynard","img":null,"order":0},{"name":"Boris Kodjoe","character":"Jason Reynard","img":null,"order":1},{"name":"John Newberg","character":"Balthazar Crayne","img":null,"order":2},{"name":"Brandon Gonzales","character":"Tony","img":null,"order":3},{"name":"Cameron Mills","character":"10-year-old Zoe","img":null,"order":4},{"name":"Emayatzy Corinealdi","character":"Brina","img":null,"order":5},{"name":"Garrett Hines","character":"Benny","img":null,"order":6},{"name":"Hunter Burke","character":"Shane","img":null,"order":7},{"name":"Kat Graham","character":"Diamond","img":null,"order":8},{"name":"Maria Howell","character":"Nina","img":null,"order":9},{"name":"Omer Mughal","character":"Handsome Man","img":null,"order":10},{"name":"Tasha Smith","character":"Marcella","img":null,"order":11},{"name":"Tyson Beckford","character":"Corey","img":null,"order":12},{"name":"William Levy","character":"Quentin Matthews","img":null,"order":13},{"name":"Mikayla Donlon","character":"Girl on Playground","img":null,"order":14}],"movie:376004":[{"name":"Sean Faris","character":"Samuel Deuprey","img":null,"order":0},{"name":"Danielle Savre","character":"Ashley","img":null,"order":1},{"name":"Mehcad Brooks","character":"Damien","img":null,"order":2},{"name":"Stephanie Charles","character":"Lola","img":null,"order":3},{"name":"Steffinnie Phrommany","character":"Jasmine","img":null,"order":4},{"name":"Rebecca Reaney","character":"Rebecca Scott","img":null,"order":5},{"name":"Phillip Brock","character":"Jimmy","img":null,"order":6},{"name":"Robert Eric Wise","character":"Tyrone","img":null,"order":7}],"movie:18206":[{"name":"Colin Hanks","character":"Doug","img":null,"order":0},{"name":"Ana Claudia Talanc\u00f3n","character":"Amy","img":null,"order":1},{"name":"Jordana Spiro","character":"Jen","img":null,"order":2},{"name":"Jonathon Trent","character":"Matt","img":null,"order":3},{"name":"Alex Boling","character":"Barrista","img":null,"order":4},{"name":"Tony Armatrading","character":"Cop","img":null,"order":5}],"movie:13483":[{"name":"Hayden Christensen","character":"Clay Beresford","img":null,"order":0},{"name":"Jessica Alba","character":"Sam Lockwood","img":null,"order":1},{"name":"Terrence Howard","character":"Dr. Jack Harper","img":null,"order":2},{"name":"Lena Olin","character":"Lilith Beresford","img":null,"order":3},{"name":"Christopher McDonald","character":"Dr. Larry Lupin","img":null,"order":4},{"name":"Sam Robards","character":"Clayton Beresford Sr.","img":null,"order":5},{"name":"Arliss Howard","character":"Dr. Jonathan Neyer","img":null,"order":6},{"name":"Fisher Stevens","character":"Dr. Puttnam","img":null,"order":7},{"name":"Georgina Chapman","character":"Penny Carver","img":null,"order":8},{"name":"David Harbour","character":"Dracula","img":null,"order":9},{"name":"Steven Hinkle","character":"Young Clay","img":null,"order":10},{"name":"Denis O'Hare","character":"Financial News Analyst","img":null,"order":11},{"name":"Charlie Hewson","character":"Brian the Orderly","img":null,"order":12},{"name":"Court Young","character":"Officer Doherty","img":null,"order":13},{"name":"Poorna Jagannathan","character":"Dr. Neyer's Nurse","img":null,"order":14}],"movie:624788":[{"name":"Aubrey Plaza","character":"Allison","img":null,"order":0},{"name":"Christopher Abbott","character":"Gabe","img":null,"order":1},{"name":"Sarah Gadon","character":"Blair","img":null,"order":2},{"name":"Paola L\u00e1zaro","character":"Cahya","img":null,"order":3},{"name":"Grantham Coleman","character":"Baako","img":null,"order":4},{"name":"Lindsay Burdge","character":"Maude","img":null,"order":5},{"name":"Lou Gonzalez","character":"Chris","img":null,"order":6},{"name":"Shannon O'Neill","character":"Simone","img":null,"order":7},{"name":"Alexander Koch","character":"Mike","img":null,"order":8},{"name":"Jennifer Kim","character":"Nora","img":null,"order":9},{"name":"Kevin Barker","character":"John the Gaffer","img":null,"order":10},{"name":"Mary Borrello","character":"1st AC","img":null,"order":11},{"name":"Rob Turbovsky","character":"2nd AC","img":null,"order":12},{"name":"Haitao Zeng","character":"PA","img":null,"order":13}],"movie:13250":[{"name":"Pierce Brosnan","character":"Tom Ryan","img":null,"order":0},{"name":"Maria Bello","character":"Abby Randall","img":null,"order":1},{"name":"Gerard Butler","character":"Neil Randall","img":null,"order":2},{"name":"Emma Karwandy","character":"Sophie Randall","img":null,"order":3},{"name":"Claudette Mink","character":"Judy Ryan","img":null,"order":4},{"name":"Desiree Zurowski","character":"Helen Schriver","img":null,"order":5},{"name":"Nicholas Lea","character":"Jerry Crane","img":null,"order":6},{"name":"Peter Keleghan","character":"Karl Granger","img":null,"order":7},{"name":"Samantha Ferris","character":"Diane","img":null,"order":8},{"name":"Malcolm Stewart","character":"Dave Carver","img":null,"order":9},{"name":"Callum Keith Rennie","character":"Det. McGill","img":null,"order":10},{"name":"Dustin Milligan","character":"Matt Ryan","img":null,"order":11},{"name":"Julie Patzwald","character":"Female Teller","img":null,"order":12},{"name":"Jason McKinnon","character":"French Waiter","img":null,"order":13},{"name":"Kurt Evans","character":"Maitre D'","img":null,"order":14}],"movie:317744":[{"name":"Nick Jonas","character":"Doug Martin","img":null,"order":0},{"name":"Isabel Lucas","character":"Lena Harper","img":null,"order":1},{"name":"Dermot Mulroney","character":"Eliott Harper","img":null,"order":2},{"name":"Kandyse McClure","character":"Angie Alvarez","img":null,"order":3},{"name":"Graham Rogers","character":"Carson","img":null,"order":4},{"name":"Marc Macaulay","character":"Gordon","img":null,"order":5},{"name":"David Sherrill","character":"Brian Martin","img":null,"order":6},{"name":"Kevin J. O'Connor","character":"Pier/Patron du bar","img":null,"order":7},{"name":"Paul Sorvino","character":"Sheriff Big Jack","img":null,"order":8},{"name":"Alex ter Avest","character":"Emma Shalloway","img":null,"order":9},{"name":"John Driskell Hopkins","character":"Gus","img":null,"order":10},{"name":"Ross Gallo","character":"Lena's Lawyer","img":null,"order":11},{"name":"Kiki Harris","character":"Emily/Doug's mother","img":null,"order":12}],"movie:1920":[{"name":"Barbara Stanwyck","character":"Kathy Ferguson","img":null,"order":0},{"name":"Sterling Hayden","character":"Lt. William Doyle","img":null,"order":1},{"name":"Raymond Burr","character":"Inspector Tony Pope","img":null,"order":2},{"name":"Fay Wray","character":"Alice Pope","img":null,"order":3},{"name":"Virginia Grey","character":"Sara Alidas","img":null,"order":4},{"name":"Royal Dano","character":"Capt. Charlie Alidas","img":null,"order":5},{"name":"Robert Griffin","character":"Police Sgt. James","img":null,"order":6},{"name":"Dennis Cross","character":"Police Sgt. Jules","img":null,"order":7},{"name":"Jay Adler","character":"Mr. Nalence","img":null,"order":8},{"name":"Stuart Whitman","character":"Laboratory Technician","img":null,"order":9},{"name":"Malcolm Atterbury","character":"Police Officer Spitz","img":null,"order":10},{"name":"Robert Quarry","character":"Sam, Reporter","img":null,"order":11},{"name":"Gail Bonney","character":"Mrs. London","img":null,"order":12},{"name":"Joe Conley","character":"Delivery Boy","img":null,"order":13},{"name":"Ralph Brooks","character":"Reporter in Newspaper Office (Uncredited)","img":null,"order":14}],"movie:619979":[{"name":"Ben Affleck","character":"Vic Van Allen","img":null,"order":0},{"name":"Ana de Armas","character":"Melinda Van Allen","img":null,"order":1},{"name":"Tracy Letts","character":"Don Wilson","img":null,"order":2},{"name":"Lil Rel Howery","character":"Grant","img":null,"order":3},{"name":"Dash Mihok","character":"Jonas Fernandez","img":null,"order":4},{"name":"Finn Wittrock","character":"Tony Cameron","img":null,"order":5},{"name":"Kristen Connolly","character":"Kelly Wilson","img":null,"order":6},{"name":"Jacob Elordi","character":"Charlie De Lisle","img":null,"order":7},{"name":"Rachel Blanchard","character":"Kristin Peterson","img":null,"order":8},{"name":"Michael Braun","character":"Jeff Peterson","img":null,"order":9},{"name":"Jade Fernandez","character":"Jen Fernandez","img":null,"order":10},{"name":"Grace Jenkins","character":"Trixie","img":null,"order":11},{"name":"Brendan Miller","character":"Joel Dash","img":null,"order":12},{"name":"Devyn A. Tyler","character":"Mary Washington","img":null,"order":13},{"name":"Jeff Pope","character":"Chief Nichols","img":null,"order":14}],"movie:8999":[{"name":"Clive Owen","character":"Charles Schine","img":null,"order":0},{"name":"Jennifer Aniston","character":"Lucinda Harris","img":null,"order":1},{"name":"Vincent Cassel","character":"LaRoche","img":null,"order":2},{"name":"Melissa George","character":"Deanna Schine","img":null,"order":3},{"name":"Giancarlo Esposito","character":"Detective Church","img":null,"order":4},{"name":"David Morrissey","character":"Sam Griffin","img":null,"order":5},{"name":"Georgina Chapman","character":"Candy","img":null,"order":6},{"name":"Denis O'Hare","character":"Jerry","img":null,"order":7},{"name":"Tom Conti","character":"Eliot Firth","img":null,"order":8},{"name":"Addison Timlin","character":"Amy Schine","img":null,"order":9},{"name":"RZA","character":"Winston Boyko","img":null,"order":10},{"name":"Xzibit","character":"Dexter","img":null,"order":11},{"name":"Sandra Bee","character":"Train Conductor","img":null,"order":12},{"name":"William Armstrong","character":"Accountant","img":null,"order":13},{"name":"Rachael Blake","character":"Susan Davis","img":null,"order":14}],"movie:1033148":[{"name":"Jennifer Lawrence","character":"Grace","img":null,"order":0},{"name":"Robert Pattinson","character":"Jackson","img":null,"order":1},{"name":"Sissy Spacek","character":"Pam","img":null,"order":2},{"name":"LaKeith Stanfield","character":"Karl","img":null,"order":3},{"name":"Nick Nolte","character":"Harry","img":null,"order":4},{"name":"Gabrielle Rose","character":"Jen","img":null,"order":5},{"name":"Clare Coulter","character":"Courtney","img":null,"order":6},{"name":"Sarah Lind","character":"Cheryl","img":null,"order":7},{"name":"Luke Camilleri","character":"Greg","img":null,"order":8},{"name":"Victor Zinck Jr.","character":"Tom","img":null,"order":9},{"name":"Debs Howard","character":"Marsha","img":null,"order":10},{"name":"Phillip Forest Lewitski","character":"Charlie","img":null,"order":11},{"name":"Georgina Lightning","character":"Kathleen the Orderly","img":null,"order":12},{"name":"Darren Moore","character":"Gerry","img":null,"order":13},{"name":"Lauren Viau","character":"Bessie","img":null,"order":14}],"movie:69668":[{"name":"Daniel Craig","character":"Will Atenton","img":null,"order":0},{"name":"Naomi Watts","character":"Ann Patterson","img":null,"order":1},{"name":"Rachel Weisz","character":"Libby Atenton","img":null,"order":2},{"name":"Marton Csokas","character":"Jack Patterson","img":null,"order":3},{"name":"Elias Koteas","character":"Boyce","img":null,"order":4},{"name":"Taylor Geare","character":"Trish","img":null,"order":5},{"name":"Claire Geare","character":"Dee Dee","img":null,"order":6},{"name":"Rachel Fox","character":"Chloe Patterson","img":null,"order":7},{"name":"Jane Alexander","character":"Dr. Greeley","img":null,"order":8},{"name":"Brian Murray","character":"Dr. Medlin","img":null,"order":9},{"name":"Bernadette Quigley","character":"Heather Keeler","img":null,"order":10},{"name":"Sarah Gadon","character":"Cindi","img":null,"order":11},{"name":"Gregory Smith","character":"Artie","img":null,"order":12},{"name":"David Huband","character":"Officer Nelson","img":null,"order":13},{"name":"Martin Roach","character":"Tommy","img":null,"order":14}],"movie:18190":[{"name":"James Spader","character":"Ray Reardon","img":null,"order":0},{"name":"M\u00e4dchen Amick","character":"Lena Mathers","img":null,"order":1},{"name":"Fredric Lehne","character":"Larry","img":null,"order":2},{"name":"Bess Armstrong","character":"Elaine","img":null,"order":3},{"name":"Larry Miller","character":"Norman","img":null,"order":4},{"name":"Kathleen York","character":"Martha","img":null,"order":5},{"name":"Kate Williamson","character":"Mrs. Sneeder","img":null,"order":6},{"name":"Tom Lillard","character":"Hank Sneeder","img":null,"order":7},{"name":"William Shockley","character":"Buddy","img":null,"order":8},{"name":"Carl Sundstrom","character":"Officer","img":null,"order":9},{"name":"Irwin Keyes","character":"Officer","img":null,"order":10},{"name":"Joel McKinnon Miller","character":"Minister","img":null,"order":11},{"name":"Joseph Scoren","character":"Martha's Lawyer (as Joseph Scorsiani)","img":null,"order":12},{"name":"Archie Lang","character":"Judge #1","img":null,"order":13},{"name":"Clyde Kusatsu","character":"Judge Kurita","img":null,"order":14}],"movie:1249213":[{"name":"Meghann Fahy","character":"Violet","img":null,"order":0},{"name":"Brandon Sklenar","character":"Henry","img":null,"order":1},{"name":"Reed Diamond","character":"Richard","img":null,"order":2},{"name":"Violett Beane","character":"Jen","img":null,"order":3},{"name":"Jeffery Self","character":"Matt","img":null,"order":4},{"name":"Jacob Robinson","character":"Toby","img":null,"order":5},{"name":"Gabrielle Ryan","character":"Cara","img":null,"order":6},{"name":"Ed Weeks","character":"Phil","img":null,"order":7},{"name":"Travis Nelson","character":"Connor","img":null,"order":8},{"name":"Sarah McCormack","character":"Hostess","img":null,"order":9},{"name":"Ben Pelletier","character":"Bearded Man / Masked Man","img":null,"order":10},{"name":"Saoirse Hayden","character":"Green Prom Dress Girl","img":null,"order":11},{"name":"Fiona Browne","character":"Diane","img":null,"order":12},{"name":"Stephanie Karam","character":"Young Woman (Zoom)","img":null,"order":13},{"name":"Michael Shea","character":"Blake","img":null,"order":14}],"movie:2252":[{"name":"Viggo Mortensen","character":"Nikolai Luzhin","img":null,"order":0},{"name":"Naomi Watts","character":"Anna Ivanovna Khitrova","img":null,"order":1},{"name":"Vincent Cassel","character":"Kirill","img":null,"order":2},{"name":"Armin Mueller-Stahl","character":"Semyon","img":null,"order":3},{"name":"Sin\u00e9ad Cusack","character":"Helen","img":null,"order":4},{"name":"Donald Sumpter","character":"Yuri","img":null,"order":5},{"name":"Jerzy Skolimowski","character":"Stepan","img":null,"order":6},{"name":"Josef Altin","character":"Ekrem","img":null,"order":7},{"name":"Aleksandar Mikic","character":"Soyka","img":null,"order":8},{"name":"Sarah-Jeanne Labrosse","character":"Tatiana","img":null,"order":9},{"name":"Lalita Ahmed","character":"Customer","img":null,"order":10},{"name":"Tatiana Maslany","character":"Tatiana (voice)","img":null,"order":11},{"name":"Tereza Srbova","character":"Kirilenko","img":null,"order":12},{"name":"David Papava","character":"Chechen","img":null,"order":13},{"name":"Tamer Hassan","character":"Chechen","img":null,"order":14}],"movie:753":[{"name":"John Marley","character":"Richard Forst","img":null,"order":0},{"name":"Gena Rowlands","character":"Jeannie Rapp","img":null,"order":1},{"name":"Lynn Carlin","character":"Maria Forst","img":null,"order":2},{"name":"Fred Draper","character":"Freddie Draper","img":null,"order":3},{"name":"Seymour Cassel","character":"Chet","img":null,"order":4},{"name":"Val Avery","character":"Jim McCarthy","img":null,"order":5},{"name":"Dorothy Gulliver","character":"Florence","img":null,"order":6},{"name":"Joanne Moore Jordan","character":"Louise Draper","img":null,"order":7},{"name":"Darlene Conley","character":"Billy Mae","img":null,"order":8},{"name":"Gene Darfler","character":"Joe Jackson","img":null,"order":9},{"name":"Elizabeth Deering","character":"Stella","img":null,"order":10},{"name":"George Dunn","character":"Comedian (as George Dunne)","img":null,"order":11},{"name":"Laurie Mock","character":"Barmaid","img":null,"order":12},{"name":"Christina Crawford","character":"Woman Scattering Coins on Bar","img":null,"order":13},{"name":"George Sims","character":"Bartender","img":null,"order":14}],"movie:549514":[{"name":"Hilary Swank","character":"Det. Valerie Quinlan","img":null,"order":0},{"name":"Michael Ealy","character":"Derrick Tyler","img":null,"order":1},{"name":"Mike Colter","character":"Rafe Grimes","img":null,"order":2},{"name":"Damaris Lewis","character":"Tracie Tyler","img":null,"order":3},{"name":"Tyrin Turner","character":"Tyrin Abenathy","img":null,"order":4},{"name":"Danny Pino","character":"Carter Heywood","img":null,"order":5},{"name":"Geoffrey Owens","character":"Bill Cranepool","img":null,"order":6},{"name":"David Hoflin","character":"Officer Lowe","img":null,"order":7},{"name":"Sam Daly","character":"Officer Stallman","img":null,"order":8},{"name":"Lance Stephenson","character":"Sports Star Cameo","img":null,"order":9},{"name":"Chic Daniel","character":"Investigator","img":null,"order":10},{"name":"Stephen O'Mahoney","character":"Uniformed Police Officer","img":null,"order":11},{"name":"Lexa Gluck","character":"Carter's Trophy Wife","img":null,"order":12},{"name":"Oakley Bull","character":"Haley Older / Haley Younger","img":null,"order":13},{"name":"Ian Stanley","character":"First Officer","img":null,"order":14}],"tv:241372":[{"name":"Dove Cameron","character":"Ciara Wyse","img":null,"order":0},{"name":"Avan Jogia","character":"Oliver Kennedy","img":null,"order":1},{"name":"Dorian Missick","character":"Karl Connelly","img":null,"order":2},{"name":"Karla Souza","character":"Lee Reardon","img":null,"order":3},{"name":"Kingston Rumi Southwick","character":"Young Oliver","img":null,"order":4},{"name":"Patch Darragh","character":"Dan Troxler","img":null,"order":5},{"name":"Kira Guloien","character":"Jane Miller","img":null,"order":6},{"name":"Megan Peta Hill","character":"Shyla","img":null,"order":7}],"tv:4493":[{"name":"Jennifer Saunders","character":"Edina Monsoon","img":null,"order":0},{"name":"Joanna Lumley","character":"Patsy Stone","img":null,"order":1},{"name":"Julia Sawalha","character":"Saffron 'Saffy' Monsoon","img":null,"order":2},{"name":"June Whitfield","character":"Mother","img":null,"order":3},{"name":"Jane Horrocks","character":"Bubble / Katy Grin","img":null,"order":118},{"name":"Naoko Mori","character":"Sarah","img":null,"order":505},{"name":"Christopher Malcolm","character":"Justin","img":null,"order":509},{"name":"Kathy Burke","character":"Magda","img":null,"order":510},{"name":"Harriet Thorpe","character":"Fleur","img":null,"order":512},{"name":"Christopher Ryan","character":"Marshall","img":null,"order":513},{"name":"Mo Gaffney","character":"Bo","img":null,"order":514},{"name":"Lulu","character":"Self","img":null,"order":514},{"name":"Helen Lederer","character":"Catriona","img":null,"order":518},{"name":"Tilly Blackwood","character":"Lady Candida De Denison-Bender","img":null,"order":624},{"name":"Llewella Gideon","character":"Nurse","img":null,"order":641}],"tv:106454":[{"name":"Tiffany Haddish","character":"Detective Danner","img":null,"order":0},{"name":"Sam Richardson","character":"Aniq","img":null,"order":1},{"name":"Zo\u00eb Chao","character":"Zoe","img":null,"order":2},{"name":"Ben Schwartz","character":"Yasper","img":null,"order":3},{"name":"Jamie Demetriou","character":"Walt","img":null,"order":7},{"name":"John Early","character":"Detective Culp","img":null,"order":8},{"name":"John Cho","character":"Ulysses","img":null,"order":10},{"name":"Paul Walter Hauser","character":"Travis","img":null,"order":11},{"name":"Ken Jeong","character":"Feng","img":null,"order":12},{"name":"Anna Konkle","character":"Hannah","img":null,"order":13},{"name":"Poppy Liu","character":"Grace","img":null,"order":14},{"name":"Elizabeth Perkins","character":"Isabel","img":null,"order":15},{"name":"Jack Whitehall","character":"Sebastian","img":null,"order":16},{"name":"Zach Woods","character":"Edgar","img":null,"order":17},{"name":"Vivian Wu","character":"Vivian","img":null,"order":18}],"tv:6127":[{"name":"Julia McKenzie","character":"Miss Marple","img":null,"order":0},{"name":"Geraldine McEwan","character":"Miss Marple","img":null,"order":1},{"name":"Emilia Fox","character":"Joanna Burton","img":null,"order":2},{"name":"Sylvia Syms","character":"Lavinia Pinkerton","img":null,"order":500},{"name":"Russell Tovey","character":"PC Terence Reed","img":null,"order":501},{"name":"Hugo Speer","character":"James Abbot","img":null,"order":502},{"name":"Shirley Henderson","character":"Honoria Waynflete","img":null,"order":503},{"name":"Margo Stilley","character":"Bridget Conway","img":null,"order":504},{"name":"Steve Pemberton","character":"Henry Wake","img":null,"order":505},{"name":"Benedict Cumberbatch","character":"Luke Fitzwilliam","img":null,"order":506},{"name":"Anna Chancellor","character":"Lydia Horton","img":null,"order":507},{"name":"Jemma Redgrave","character":"Jessie Humbleby","img":null,"order":508},{"name":"Lyndsey Marshal","character":"Amy Gibbs","img":null,"order":509},{"name":"David Haig","character":"Major Hugh Horton","img":null,"order":510},{"name":"Joanna Lumley","character":"Dolly Bantry","img":null,"order":679}],"tv:153723":[{"name":"Geffri Maya","character":"Simone Hicks","img":null,"order":0},{"name":"Peyton Alex Smith","character":"Damon Sims","img":null,"order":1},{"name":"Kelly Jenrette","character":"Amara Patterson","img":null,"order":2},{"name":"Cory Hardrict","character":"Marcus Turner","img":null,"order":3},{"name":"Sylvester Powell","character":"Jessie 'JR' Raymond","img":null,"order":4},{"name":"Camille Hyde","character":"Thea Mays","img":null,"order":5},{"name":"Mitchell Edwards","character":"Cam Watkins","img":null,"order":6},{"name":"Netta Walker","character":"Keisha McCalla","img":null,"order":7},{"name":"Rhoyle Ivy King","character":"Nathaniel Hardin","img":null,"order":8},{"name":"Leonard Roberts","character":"Zeke Allen","img":null,"order":505},{"name":"Derek Rivera","character":"Santiago Reyes","img":null,"order":510},{"name":"Joe Holt","character":"Jesse","img":null,"order":529},{"name":"Heather Lynn Harris","character":"Gabrielle","img":null,"order":554},{"name":"Martin Bobb-Semple","character":"Orlando 'Lando' Johnson","img":null,"order":555},{"name":"Taylor Polidore","character":"Tootie","img":null,"order":579}],"tv:116450":[{"name":"Sarah Jessica Parker","character":"Carrie Bradshaw","img":null,"order":0},{"name":"Cynthia Nixon","character":"Miranda Hobbes","img":null,"order":1},{"name":"Kristin Davis","character":"Charlotte York","img":null,"order":2},{"name":"Sara Ramirez","character":"Che Diaz","img":null,"order":3},{"name":"Cathy Ang","character":"Lily Goldenblatt","img":null,"order":4},{"name":"Mario Cantone","character":"Anthony Marentino","img":null,"order":5},{"name":"Sarita Choudhury","character":"Seema Patel","img":null,"order":6},{"name":"Evan Handler","character":"Harry Goldenblatt","img":"yU0OXeZ0K1ppe1o9SpHiAMHy1rc.jpg","order":7},{"name":"Christopher Jackson","character":"Herbert Wexley","img":null,"order":8},{"name":"Nicole Ari Parker","character":"Lisa Todd Wexley","img":null,"order":9},{"name":"Alexa Swinton","character":"Rose 'Rock' Goldenblatt","img":null,"order":10},{"name":"Karen Pittman","character":"Dr. Nya Wallace","img":null,"order":11},{"name":"Niall Cunningham","character":"Brady Hobbes","img":null,"order":12},{"name":"Alexander Bello","character":"Henry Wexley","img":null,"order":515},{"name":"Sebastiano Pigazzi","character":"Giuseppe","img":null,"order":620}],"tv:70785":[{"name":"Amybeth McNulty","character":"Anne Shirley","img":null,"order":0},{"name":"Geraldine James","character":"Marilla Cuthbert","img":null,"order":1},{"name":"R.H. Thomson","character":"Matthew Cuthbert","img":null,"order":2},{"name":"Dalila Bela","character":"Diana Barry","img":null,"order":3},{"name":"Lucas Jade Zumann","character":"Gilbert Blythe","img":null,"order":4},{"name":"Corrine Koslo","character":"Rachel Lynde","img":null,"order":5},{"name":"Jonathan Holmes","character":"Mr. William Barry","img":null,"order":539},{"name":"Helen Johns","character":"Mrs. Eliza Barry","img":null,"order":543},{"name":"Lia Pappas-Kemps","character":"Jane Andrews","img":null,"order":567},{"name":"Kyla Matthews","character":"Ruby Gillis","img":null,"order":569},{"name":"Miranda McKeon","character":"Josie Pye","img":null,"order":570},{"name":"Jacob Horsley","character":"Charlie Sloane","img":null,"order":572},{"name":"Jacob Ursomarzo","character":"Moody Spurgeon","img":null,"order":573},{"name":"Dalmar Abuzeid","character":"Sebastian 'Bash' Lacroix","img":null,"order":574},{"name":"Aymeric Jett Montaz","character":"Jerry Baynard","img":null,"order":579}],"tv:39859":[{"name":"Ashley Rickards","character":"Jenna Hamilton","img":null,"order":0},{"name":"Beau Mirchoff","character":"Matty McKibben","img":null,"order":1},{"name":"Nikki DeLoach","character":"Lacey Hamilton","img":null,"order":2},{"name":"Jillian Rose Reed","character":"Tamara Kaplan","img":null,"order":4},{"name":"Brett Davern","character":"Jake Rosati","img":null,"order":5},{"name":"Molly Tarlov","character":"Sadie Saxton","img":null,"order":6},{"name":"Desi Lydic","character":"Valerie Marks","img":null,"order":7},{"name":"Jessica Lu","character":"Ming Huang","img":null,"order":8},{"name":"Greer Grammer","character":"Lissa Miller","img":null,"order":9},{"name":"Meaghan Jette Martin","character":"Julie #2","img":null,"order":10},{"name":"Wesam Keesh","character":"Kyle Cohen","img":null,"order":522},{"name":"Barret Swatek","character":"Ally Saxton","img":null,"order":617},{"name":"Monty Geer","character":"Cole","img":null,"order":642},{"name":"Evan Crooks","character":"Theo","img":null,"order":643},{"name":"Niko Pepaj","character":"Sergio","img":null,"order":694}],"tv:100412":[{"name":"Sophie Grace","character":"Kristy Thomas","img":null,"order":0},{"name":"Momona Tamada","character":"Claudia Kishi","img":null,"order":1},{"name":"Shay Rudolph","character":"Stacey McGill","img":null,"order":2},{"name":"Malia Baker","character":"Mary Anne Spier","img":null,"order":3},{"name":"Alicia Silverstone","character":"Elizabeth Thomas-Brewer","img":null,"order":500},{"name":"Mark Feuerstein","character":"Watson Brewer","img":null,"order":501},{"name":"Takayo Fischer","character":"Mimi Yamamoto","img":null,"order":502},{"name":"Benjamin Goas","character":"David Michael Thomas","img":null,"order":505},{"name":"Sophia Reid-Gantzert","character":"Karen Brewer","img":null,"order":509},{"name":"Marc Evan Jackson","character":"Richard Spier","img":null,"order":515},{"name":"Xochitl Gomez","character":"Dawn Schafer","img":null,"order":536},{"name":"Jessica Elaina Eason","character":"Sharon Porter","img":null,"order":537},{"name":"Vivian Watson","character":"Mallory Pike","img":null,"order":562},{"name":"Anais Lee","character":"Jessi Ramsey","img":null,"order":577},{"name":"Kyndra Sanchez","character":"Dawn Schafer","img":null,"order":587}],"tv:62704":[{"name":"Dwayne Johnson","character":"Spencer Strassmore","img":null,"order":0},{"name":"Rob Corddry","character":"Joe Krutel","img":null,"order":1},{"name":"John David Washington","character":"Ricky Jerret","img":null,"order":2},{"name":"Omar Benson Miller","character":"Charles Greane","img":null,"order":3},{"name":"Troy Garity","character":"Jason Antolotti","img":null,"order":4},{"name":"London Brown","character":"Reggie","img":null,"order":5},{"name":"Donovan W. Carter","character":"Vernon Littlefield","img":null,"order":6},{"name":"Arielle Kebbel","character":"Tracy Legette","img":null,"order":7},{"name":"Jazmyn Simon","character":"Julie Greane","img":null,"order":9},{"name":"Brittany S. Hall","character":"Amber","img":null,"order":10},{"name":"Dul\u00e9 Hill","character":"Larry Siefert","img":null,"order":501},{"name":"Richard Schiff","character":"Brett Anderson","img":null,"order":503},{"name":"Jay Glazer","character":"Jay Glazer","img":null,"order":647},{"name":"Carl McDowell","character":"TTD","img":null,"order":673},{"name":"Robert Wisdom","character":"Dennis","img":null,"order":674}],"tv:3216":[{"name":"Robert Blake","character":"Det. Tony Baretta","img":null,"order":0},{"name":"Dana Elcar","character":"Inspector Shiller","img":null,"order":1},{"name":"Sharon Cintron","character":"","img":null,"order":2},{"name":"Burt Young","character":"Solomon","img":null,"order":368},{"name":"Michael D. Roberts","character":"","img":null,"order":500},{"name":"Val Avery","character":"","img":null,"order":501},{"name":"Joshua Shelley","character":"","img":null,"order":502},{"name":"Timothy Carey","character":"","img":null,"order":554},{"name":"Sharon Cintron","character":"","img":null,"order":565},{"name":"Art Metrano","character":"","img":null,"order":649},{"name":"Tom Ewell","character":"","img":null,"order":667},{"name":"Strother Martin","character":"","img":null,"order":678},{"name":"Ron Thompson","character":"","img":null,"order":689},{"name":"Elisha Cook Jr.","character":"","img":null,"order":700},{"name":"Angelo Rossitto","character":"Little Moe (uncredited)","img":null,"order":708}],"tv:197373":[{"name":"Kaley Cuoco","character":"Ava Bartlett","img":null,"order":0},{"name":"Chris Messina","character":"Nathan Bartlett","img":null,"order":1},{"name":"Tom Bateman","character":"Matt Pierce","img":null,"order":2},{"name":"Priscilla Quintana","character":"Ruby Gale","img":null,"order":3},{"name":"Liana Liberato","character":"Tory Thompson","img":null,"order":4},{"name":"Li Jun Li","character":"Michelle","img":null,"order":502},{"name":"Annabelle Dexter-Jones","character":"Serena","img":null,"order":503},{"name":"Aisha Alfa","character":"Carolyn","img":null,"order":504},{"name":"Alex Alomar Akpobome","character":"Ryan","img":null,"order":505},{"name":"June Diane Raphael","character":"Romy Lipinski","img":null,"order":506},{"name":"Brandon Keener","character":"Paul","img":null,"order":507},{"name":"Miles Mussenden","character":"Detective Quincy Burrell","img":null,"order":508},{"name":"Jessica St. Clair","character":"Rochelle Lipinski","img":null,"order":519},{"name":"Sebastian Quinn","character":"Carlos","img":null,"order":521},{"name":"Melissa Fumero","character":"Drew","img":null,"order":559}],"tv:250504":[{"name":"Claire Danes","character":"Agatha 'Aggie' Wiggs","img":null,"order":0},{"name":"Matthew Rhys","character":"Nile Jarvis","img":null,"order":1},{"name":"Brittany Snow","character":"Nina Jarvis","img":null,"order":2},{"name":"Natalie Morales","character":"Shelley Morris","img":null,"order":3},{"name":"Jonathan Banks","character":"Martin Jarvis","img":null,"order":500},{"name":"Tim Guinee","character":"Rick 'Wrecking Ball' Jarvis","img":null,"order":501},{"name":"David Lyons","character":"Brian Abbott","img":null,"order":502},{"name":"Bubba Weiler","character":"Teddy Fenig","img":null,"order":503},{"name":"Deirdre O'Connell","character":"Carol McGiddish","img":null,"order":504},{"name":"Leonard Gerome","character":"Cooper Morris-Wiggs","img":null,"order":508},{"name":"Hettienne Park","character":"Erika Breton","img":null,"order":514},{"name":"Aleyse Shannon","character":"Olivia Benitez","img":null,"order":515},{"name":"Julie Ann Emery","character":"Lila Jarvis","img":null,"order":519},{"name":"Amir Arison","character":"Frank Breton","img":null,"order":520},{"name":"Peter Grosz","character":"Elijah Garrity","img":null,"order":526}],"tv:80587":[{"name":"Chris Houghton","character":"Cricket Green (voice)","img":null,"order":0},{"name":"Marieve Herington","character":"Tilly Green (voice)","img":null,"order":1},{"name":"Bob Joles","character":"Bill Green (voice)","img":null,"order":2},{"name":"Artemis Pebdani","character":"Alice 'Gramma' Green (voice)","img":null,"order":3},{"name":"Zeno Robinson","character":"Remy (voice)","img":null,"order":4},{"name":"Wendi McLendon-Covey","character":"Nancy Green (voice)","img":null,"order":5},{"name":"Raven-Symon\u00e9","character":"Maria Media (voice)","img":null,"order":503},{"name":"Anna Akana","character":"Gloria (voice)","img":null,"order":512},{"name":"Danny Trejo","character":"Vasquez (voice)","img":null,"order":513},{"name":"Andy Daly","character":"Officer Keys (voice)","img":null,"order":514},{"name":"Paul Scheer","character":"Chip Whistler (voice)","img":null,"order":516},{"name":"Vladimir Caama\u00f1o","character":"Juan Pablo (voice)","img":null,"order":517},{"name":"Jenna Ortega","character":"Gabriella Espinosa (voice)","img":null,"order":521},{"name":"Paul F. Tompkins","character":"Tooth Fairy (voice)","img":null,"order":523},{"name":"Shane Houghton","character":"Driver Construction Worker (voice)","img":null,"order":541}],"tv:69630":[{"name":"Katie Stevens","character":"Jane Sloan","img":null,"order":0},{"name":"Aisha Dee","character":"Kat Edison","img":null,"order":1},{"name":"Meghann Fahy","character":"Sutton Brady","img":null,"order":2},{"name":"Melora Hardin","character":"Jacqueline Carlyle","img":null,"order":3},{"name":"Stephen Conrad Moore","character":"Oliver Grayson","img":null,"order":4},{"name":"Matt Ward","character":"Alex Crawford","img":null,"order":5},{"name":"Sam Page","character":"Richard 'Dick' Mott","img":null,"order":6},{"name":"Nikohl Boosheri","character":"Aden 'Adena' El Amin","img":null,"order":7},{"name":"Luca James Lee","character":"Ben Chau","img":null,"order":625},{"name":"Alexis Floyd","character":"Tia Clayton","img":null,"order":699},{"name":"Peter Vack","character":"Patrick Duchand","img":null,"order":711},{"name":"Adam Capriolo","character":"Andrew Morrison","img":null,"order":856},{"name":"Stephanie Costa","character":"Sage Aiello","img":null,"order":857},{"name":"Dan Jeannotte","character":"Ryan Decker","img":null,"order":859},{"name":"Gildart Jackson","character":"Ian Carlyle","img":null,"order":860}],"tv:92621":[{"name":"Joseph Gilgun","character":"Vincent \"Vinnie\" O'Neill","img":null,"order":0},{"name":"Michelle Keegan","character":"Erin Croft","img":null,"order":1},{"name":"Steve Evets","character":"Jim","img":null,"order":2},{"name":"Damien Molony","character":"Dylan Golding","img":null,"order":3},{"name":"Bronagh Gallagher","character":"Carol Dennings","img":null,"order":4},{"name":"Tom Hanson","character":"Leslie \"Cardi\" Titt","img":null,"order":5},{"name":"Aaron Heffernan","character":"Ashley \"Ash\" Dennings","img":null,"order":6},{"name":"Joanna Higson","character":"Mary \"Sugar\" Jones","img":null,"order":7},{"name":"Parth Thakerar","character":"Jehan \"JJ\" Jovani","img":null,"order":8},{"name":"Ryan Sampson","character":"Thomas \"Tommo\" Schaffner","img":null,"order":9},{"name":"Dominic West","character":"Dr. Chris Coxley","img":null,"order":10},{"name":"Ramon Tikaram","character":"Terence McCann","img":null,"order":11},{"name":"Tadhg Murphy","character":"Gary Cullen","img":null,"order":14},{"name":"Neil Ashton","character":"David \"Davey\" MacDonagh","img":null,"order":16},{"name":"Jude Riordan","character":"Tyler Croft","img":null,"order":501}],"movie:4982":[{"name":"Denzel Washington","character":"Frank Lucas","img":null,"order":0},{"name":"Russell Crowe","character":"Richie Roberts","img":null,"order":1},{"name":"Josh Brolin","character":"Detective Trupo","img":null,"order":2},{"name":"Chiwetel Ejiofor","character":"Huey Lucas","img":null,"order":3},{"name":"Cuba Gooding Jr.","character":"Nicky Barnes","img":null,"order":4},{"name":"Lymari Nadal","character":"Eva","img":null,"order":5},{"name":"Ted Levine","character":"Lou Toback","img":null,"order":6},{"name":"Armand Assante","character":"Dominic Cattano","img":null,"order":7},{"name":"John Ortiz","character":"Javier J. Rivera","img":null,"order":8},{"name":"John Hawkes","character":"Freddie Spearman","img":null,"order":9},{"name":"RZA","character":"Moses Jones","img":null,"order":10},{"name":"Yul Vazquez","character":"Alfonso Abruzzo","img":null,"order":11},{"name":"Ruby Dee","character":"Mama Lucas","img":null,"order":12},{"name":"Idris Elba","character":"Tango","img":null,"order":13},{"name":"Carla Gugino","character":"Laurie Roberts","img":null,"order":14}],"movie:703":[{"name":"Diane Keaton","character":"Annie Hall","img":null,"order":0},{"name":"Woody Allen","character":"Alvy Singer","img":null,"order":1},{"name":"Tony Roberts","character":"Rob","img":null,"order":2},{"name":"Carol Kane","character":"Allison","img":null,"order":3},{"name":"Paul Simon","character":"Tony Lacey","img":null,"order":4},{"name":"Shelley Duvall","character":"Pam","img":null,"order":5},{"name":"Janet Margolin","character":"Robin","img":null,"order":6},{"name":"Colleen Dewhurst","character":"Mrs. Hall","img":null,"order":7},{"name":"Christopher Walken","character":"Duane Hall","img":null,"order":8},{"name":"Donald Symington","character":"Dad Hall","img":null,"order":9},{"name":"Helen Ludlam","character":"Grammy Hall","img":null,"order":10},{"name":"Mordecai Lawner","character":"Alvy's Dad","img":null,"order":11},{"name":"Joan Neuman","character":"Alvy's Mom","img":null,"order":12},{"name":"Jonathan Munk","character":"Alvy - Age 9","img":null,"order":13},{"name":"Ruth Volner","character":"Alvy's Aunt","img":null,"order":14}],"movie:28":[{"name":"Martin Sheen","character":"Captain Benjamin Willard","img":null,"order":0},{"name":"Marlon Brando","character":"Colonel Walter Kurtz","img":null,"order":1},{"name":"Frederic Forrest","character":"Jay 'Chef' Hicks","img":null,"order":2},{"name":"Albert Hall","character":"Chief Phillips","img":null,"order":3},{"name":"Laurence Fishburne","character":"Tyrone 'Clean' Miller","img":null,"order":4},{"name":"Sam Bottoms","character":"Lance B. Johnson","img":null,"order":5},{"name":"Robert Duvall","character":"Lieutenant Colonel Bill Kilgore","img":null,"order":6},{"name":"G.D. Spradlin","character":"General Corman","img":null,"order":7},{"name":"Harrison Ford","character":"Colonel","img":null,"order":8},{"name":"Jerry Ziesmer","character":"Jerry, Civilian","img":null,"order":9},{"name":"Scott Glenn","character":"Lieutenant Richard M. Colby","img":null,"order":10},{"name":"Kerry Rossall","character":"Mike from San Diego","img":null,"order":11},{"name":"James Keane","character":"Kilgore's Gunner","img":null,"order":12},{"name":"Tom Mason","character":"Supply Sergeant","img":null,"order":13},{"name":"Cynthia Wood","character":"Playmate of the Year","img":null,"order":14}],"movie:329865":[{"name":"Amy Adams","character":"Louise Banks","img":null,"order":0},{"name":"Jeremy Renner","character":"Ian Donnelly","img":null,"order":1},{"name":"Forest Whitaker","character":"Colonel Weber","img":null,"order":2},{"name":"Michael Stuhlbarg","character":"Agent Halpern","img":null,"order":3},{"name":"Mark O'Brien","character":"Captain Marks","img":null,"order":4},{"name":"Tzi Ma","character":"General Shang","img":null,"order":5},{"name":"Abigail Pniowsky","character":"8-Year-Old Hannah","img":null,"order":6},{"name":"Julia Scarlett Dan","character":"12-Year-Old Hannah","img":null,"order":7},{"name":"Jadyn Malone","character":"6-Year-Old Hannah","img":null,"order":8},{"name":"Frank Schorpion","character":"Dr. Kettler","img":null,"order":9},{"name":"Lucas Chartier-Dessert","character":"Private Lasky","img":null,"order":10},{"name":"Christian Jadah","character":"Private Combs","img":null,"order":11},{"name":"Lucy Van Oldenbarneveld","character":"CNAC Anchor","img":null,"order":12},{"name":"Andrew Shaver","character":"Environmental Tech","img":null,"order":13},{"name":"Pat Kiely","character":"Environmental Tech","img":null,"order":14}],"movie:980431":[{"name":"Eric Nam","character":"Aang (voice)","img":null,"order":0},{"name":"Dave Bautista","character":"Tagah (voice)","img":null,"order":1},{"name":"Jessica Matten","character":"Katara (voice)","img":null,"order":2},{"name":"Rom\u00e1n Zaragoza","character":"Sokka (voice)","img":null,"order":3},{"name":"Steven Yeun","character":"Zuko (voice)","img":null,"order":4},{"name":"Dionne Quan","character":"Toph (voice)","img":null,"order":5},{"name":"Dee Bradley Baker","character":"Appa / Momo (voice)","img":null,"order":6},{"name":"Freida Pinto","character":"Avatar Sonam (voice)","img":null,"order":7},{"name":"Ke Huy Quan","character":"Avatar Xian (voice)","img":null,"order":8},{"name":"Taika Waititi","character":"Gorillavark (voice)","img":null,"order":9},{"name":"Geraldine Viswanathan","character":"Kallik (voice)","img":null,"order":10},{"name":"Peta Sergeant","character":"Jie (voice)","img":null,"order":11},{"name":"Jonathan Ohye","character":"Yuddah (voice)","img":null,"order":12},{"name":"Vic Chao","character":"Hong (voice)","img":null,"order":13},{"name":"Fran\u00e7ois Chau","character":"Monk Gyatso (voice)","img":null,"order":14}],"movie:424694":[{"name":"Rami Malek","character":"Freddie Mercury","img":null,"order":0},{"name":"Gwilym Lee","character":"Brian May","img":null,"order":1},{"name":"Ben Hardy","character":"Roger Taylor","img":null,"order":2},{"name":"Joseph Mazzello","character":"John Deacon","img":null,"order":3},{"name":"Lucy Boynton","character":"Mary Austin","img":null,"order":4},{"name":"Aidan Gillen","character":"John Reid","img":null,"order":5},{"name":"Allen Leech","character":"Paul Prenter","img":null,"order":6},{"name":"Tom Hollander","character":"Jim Beach","img":null,"order":7},{"name":"Mike Myers","character":"Ray Foster","img":null,"order":8},{"name":"Aaron McCusker","character":"Jim Hutton","img":null,"order":9},{"name":"Meneka Das","character":"Jer Bulsara","img":null,"order":10},{"name":"Ace Bhatti","character":"Bomi Bulsara","img":null,"order":11},{"name":"Priya Blackburn","character":"Kashmira Bulsara","img":null,"order":12},{"name":"Max Bennett","character":"David","img":null,"order":13},{"name":"Dermot Murphy","character":"Bob Geldof","img":null,"order":14}],"movie:508883":[{"name":"Soma Santoki","character":"Mahito Maki (voice)","img":null,"order":0},{"name":"Masaki Suda","character":"Gray Heron (voice)","img":null,"order":1},{"name":"Ko Shibasaki","character":"Kiriko (voice)","img":null,"order":2},{"name":"Aimyon","character":"Lady Himi (voice)","img":null,"order":3},{"name":"Yoshino Kimura","character":"Natsuko (voice)","img":null,"order":4},{"name":"Takuya Kimura","character":"Shoichi Maki (voice)","img":null,"order":5},{"name":"Keiko Takeshita","character":"Izumi (voice)","img":null,"order":6},{"name":"Jun Fubuki","character":"Utako (voice)","img":null,"order":7},{"name":"Sawako Agawa","character":"Eriko (voice)","img":null,"order":8},{"name":"Karen Takizawa","character":"Warawara (voice)","img":null,"order":9},{"name":"Shinobu Otake","character":"Aiko (voice)","img":null,"order":10},{"name":"Jun Kunimura","character":"The Parakeet King (voice)","img":null,"order":11},{"name":"Kaoru Kobayashi","character":"Noble Pelican (voice)","img":null,"order":12},{"name":"Sh\u014dhei Hino","character":"Granduncle (voice)","img":null,"order":13}],"movie:197":[{"name":"Mel Gibson","character":"William Wallace","img":null,"order":0},{"name":"Catherine McCormack","character":"Murron MacClannough","img":null,"order":1},{"name":"Sophie Marceau","character":"Princess Isabelle","img":null,"order":2},{"name":"Patrick McGoohan","character":"King Edward","img":null,"order":3},{"name":"Angus Macfadyen","character":"Robert the Bruce","img":null,"order":4},{"name":"Brendan Gleeson","character":"Hamish Campbell","img":null,"order":5},{"name":"James Robinson","character":"Young William Wallace","img":null,"order":6},{"name":"James Cosmo","character":"Campbell","img":null,"order":7},{"name":"Sean McGinley","character":"MacClannough","img":null,"order":8},{"name":"Gerda Stevenson","character":"Mother MacClannough","img":null,"order":9},{"name":"Mhairi Calvey","character":"Young Murron MacClannough","img":null,"order":10},{"name":"Jeanne Marine","character":"Nicolette","img":null,"order":11},{"name":"Sean Lawlor","character":"Malcolm Wallace","img":null,"order":12},{"name":"Sandy Nelson","character":"John Wallace","img":null,"order":13},{"name":"Alan Tall","character":"Elder Stewart","img":null,"order":14}],"movie:2108":[{"name":"Emilio Estevez","character":"Andrew Clark","img":null,"order":0},{"name":"Judd Nelson","character":"John Bender","img":null,"order":1},{"name":"Molly Ringwald","character":"Claire Standish","img":null,"order":2},{"name":"Anthony Michael Hall","character":"Brian Johnson","img":null,"order":3},{"name":"Ally Sheedy","character":"Allison Reynolds","img":null,"order":4},{"name":"Paul Gleason","character":"Richard Vernon","img":null,"order":5},{"name":"John Kapelos","character":"Carl","img":null,"order":6},{"name":"Perry Crawford","character":"Allison's Father","img":null,"order":7},{"name":"Mary Christian","character":"Brian's Sister","img":null,"order":8},{"name":"Ron Dean","character":"Andy's Father","img":null,"order":9},{"name":"Tim Gamble","character":"Claire's Father","img":null,"order":10},{"name":"Fran Gargano","character":"Allison's Mom","img":null,"order":11},{"name":"Mercedes Hall","character":"Brian's Mom","img":null,"order":12},{"name":"John Hughes","character":"Brian\u2019s Father (uncredited)","img":null,"order":13},{"name":"Jonathan Chapin","character":"Janitor (uncredited)","img":null,"order":14}],"movie:10515":[{"name":"Keiko Yokozawa","character":"Sheeta (voice)","img":null,"order":0},{"name":"Mayumi Tanaka","character":"Pazu (voice)","img":null,"order":1},{"name":"Minori Terada","character":"Muska (voice)","img":null,"order":2},{"name":"Kotoe Hatsui","character":"Dola (voice)","img":null,"order":3},{"name":"Fujio Tokita","character":"Uncle Pomme (voice)","img":null,"order":4},{"name":"Ichiro Nagai","character":"Shogun Mouro (voice)","img":null,"order":5},{"name":"Hiroshi Ito","character":"Oyakata (voice)","img":null,"order":6},{"name":"Machiko Washio","character":"Okami (voice)","img":null,"order":7},{"name":"Takuz\u014d Kamiyama","character":"Charles / Shalulu (voice)","img":null,"order":8},{"name":"Yoshito Yasuhara","character":"Louis (voice)","img":null,"order":9},{"name":"Sukekiyo Kameyama","character":"Henri (voice)","img":null,"order":10},{"name":"Eken Mine","character":"Underling (voice)","img":null,"order":11},{"name":"TARAKO","character":"Madge (voice)","img":null,"order":12},{"name":"Masashi Sugawara","character":"Underling (voice)","img":null,"order":13},{"name":"Reiko Suzuki","character":"Sheeta's Grandmother (voice)","img":null,"order":14}],"movie:15":[{"name":"Orson Welles","character":"Charles Foster Kane","img":null,"order":0},{"name":"Joseph Cotten","character":"Jedediah Leland","img":null,"order":1},{"name":"Dorothy Comingore","character":"Susan Alexander Kane","img":null,"order":2},{"name":"Ray Collins","character":"Jim W. Gettys","img":null,"order":3},{"name":"George Coulouris","character":"Walter Parks Thatcher","img":null,"order":4},{"name":"Agnes Moorehead","character":"Mary Kane","img":null,"order":5},{"name":"Paul Stewart","character":"Raymond","img":null,"order":6},{"name":"Ruth Warrick","character":"Emily Norton Kane","img":null,"order":7},{"name":"Erskine Sanford","character":"Herbert Carter","img":null,"order":8},{"name":"William Alland","character":"Jerry Thompson/Narrator","img":null,"order":9},{"name":"Everett Sloane","character":"Mr. Bernstein","img":null,"order":10},{"name":"Fortunio Bonanova","character":"Signor Matiste","img":null,"order":11},{"name":"Gus Schilling","character":"John","img":null,"order":12},{"name":"Philip Van Zandt","character":"Mr. Rawlston","img":null,"order":13},{"name":"Georgia Backus","character":"Bertha Anderson","img":null,"order":14}],"movie:974576":[{"name":"Ralph Fiennes","character":"Lawrence","img":null,"order":0},{"name":"Stanley Tucci","character":"Bellini","img":null,"order":1},{"name":"John Lithgow","character":"Tremblay","img":null,"order":2},{"name":"Isabella Rossellini","character":"Sister Agnes","img":null,"order":3},{"name":"Lucian Msamati","character":"Adeyemi","img":null,"order":4},{"name":"Carlos Diehz","character":"Benitez","img":null,"order":5},{"name":"Sergio Castellitto","character":"Tedesco","img":null,"order":6},{"name":"Br\u00edan F. O'Byrne","character":"O'Malley","img":null,"order":7},{"name":"Merab Ninidze","character":"Sabbadin","img":null,"order":8},{"name":"Thomas Loibl","character":"Mandorff","img":null,"order":9},{"name":"Jacek Koman","character":"Wozniak","img":null,"order":10},{"name":"Bruno Novelli","character":"Dead Pope","img":null,"order":11},{"name":"Rony Kramer","character":"Mendoza","img":null,"order":12},{"name":"Valerio Da Silva","character":"Father Haas","img":null,"order":13},{"name":"Joseph Mydell","character":"Nakitanda","img":null,"order":14}],"movie:567797":[{"name":"Eric Bana","character":"Aaron Falk","img":null,"order":0},{"name":"Genevieve O'Reilly","character":"Gretchen Schoner","img":"4eOoW1PNBZfxRW0g8RmYH8bL6mq.jpg","order":1},{"name":"Keir O'Donnell","character":"Greg Raco","img":null,"order":2},{"name":"John Polson","character":"Scott Whitlam","img":null,"order":3},{"name":"Matt Nable","character":"Grant Dow","img":null,"order":4},{"name":"Eddie Baroo","character":"McMurdo","img":null,"order":5},{"name":"Martin Dingle Wall","character":"Luke Hadler","img":null,"order":6},{"name":"Julia Blake","character":"Barb Hadler","img":null,"order":7},{"name":"Bruce Spence","character":"Gerry Hadler","img":null,"order":8},{"name":"BeBe Bettencourt","character":"Ellie Deacon","img":null,"order":9},{"name":"Jeremy Lindsay Taylor","character":"Erik Falk","img":null,"order":10},{"name":"Miranda Tapsell","character":"Rita Raco","img":null,"order":11},{"name":"Renee Lim","character":"Sandra Whitlam","img":null,"order":12},{"name":"James Frecheville","character":"Sullivan","img":null,"order":13},{"name":"William Zappa","character":"Mal Deacon","img":null,"order":14}],"movie:37735":[{"name":"Emma Stone","character":"Olive","img":null,"order":0},{"name":"Penn Badgley","character":"Woodchuck Todd","img":null,"order":1},{"name":"Amanda Bynes","character":"Marianne","img":null,"order":2},{"name":"Dan Byrd","character":"Brandon","img":null,"order":3},{"name":"Thomas Haden Church","character":"Mr. Griffith","img":null,"order":4},{"name":"Patricia Clarkson","character":"Rosemary","img":null,"order":5},{"name":"Cam Gigandet","character":"Micah","img":null,"order":6},{"name":"Lisa Kudrow","character":"Mrs. Griffith","img":null,"order":7},{"name":"Malcolm McDowell","character":"Principal Gibbons","img":null,"order":8},{"name":"Aly Michalka","character":"Rhiannon","img":null,"order":9},{"name":"Stanley Tucci","character":"Dill","img":null,"order":10},{"name":"Fred Armisen","character":"Pastor","img":null,"order":11},{"name":"Juliette Goglia","character":"Eighth Grade Olive","img":null,"order":12},{"name":"Jake Sandvig","character":"Anson","img":null,"order":13},{"name":"Morgan Rusler","character":"Mr. Abernathy","img":null,"order":14}],"movie:559969":[{"name":"Aaron Paul","character":"Jesse","img":null,"order":0},{"name":"Jesse Plemons","character":"Todd","img":null,"order":1},{"name":"Charles Baker","character":"Skinny Pete","img":null,"order":2},{"name":"Matt Jones","character":"Badger","img":null,"order":3},{"name":"Scott MacArthur","character":"Neil","img":null,"order":4},{"name":"Larry Hankin","character":"Old Joe","img":null,"order":5},{"name":"Scott Shepherd","character":"Casey","img":null,"order":6},{"name":"Tom Bower","character":"Lou","img":null,"order":7},{"name":"Robert Forster","character":"Ed","img":null,"order":8},{"name":"Jonathan Banks","character":"Mike","img":null,"order":9},{"name":"Bryan Cranston","character":"Walt","img":null,"order":10},{"name":"Krysten Ritter","character":"Jane","img":null,"order":11},{"name":"Kevin Rankin","character":"Kenny","img":null,"order":12},{"name":"Tess Harper","character":"Mrs. Pinkman","img":null,"order":13},{"name":"Michael Bofshever","character":"Mr. Pinkman","img":null,"order":14}],"movie:715931":[{"name":"Will Smith","character":"Peter","img":null,"order":0},{"name":"Ben Foster","character":"Jim Fassel","img":null,"order":1},{"name":"Charmaine Bingwa","character":"Dodienne","img":null,"order":2},{"name":"Gilbert Owuor","character":"Gordon","img":null,"order":3},{"name":"Ronnie Gene Blevins","character":"Harrington","img":null,"order":4},{"name":"Aaron Moten","character":"Knowls","img":null,"order":5},{"name":"Jabbar Lewis","character":"Tomas","img":null,"order":6},{"name":"Michael Luwoye","character":"John","img":null,"order":7},{"name":"Steven Ogg","character":"Howard","img":null,"order":8},{"name":"Grant Harvey","character":"Leeds","img":null,"order":9},{"name":"Mustafa Shakir","character":"Lt. Andrew Cailloux","img":null,"order":10},{"name":"Paul Ben-Victor","character":"Major G. Halstead","img":null,"order":11},{"name":"David Denman","character":"General William Dwight","img":null,"order":12},{"name":"Jesse C. Boyd","character":"Mike Hurley","img":null,"order":13},{"name":"Imani Pullum","character":"Betsy","img":null,"order":14}],"movie:445629":[{"name":"Florence Pugh","character":"Saraya 'Paige' Knight","img":null,"order":0},{"name":"Lena Headey","character":"Julia 'Sweet Saraya' Knight","img":null,"order":1},{"name":"Nick Frost","character":"Patrick 'Rowdy Ricky' Knight","img":null,"order":2},{"name":"Vince Vaughn","character":"Hutch Morgan","img":null,"order":3},{"name":"Jack Lowden","character":"Zak 'Zodiac' Knight","img":null,"order":4},{"name":"Dwayne Johnson","character":"Dwayne 'The Rock' Johnson","img":null,"order":5},{"name":"Thea Trinidad","character":"AJ Lee","img":null,"order":6},{"name":"Aqueela Zoll","character":"Kirsten","img":null,"order":7},{"name":"Stephen Merchant","character":"Hugh","img":null,"order":8},{"name":"Julia Davis","character":"Daphne","img":null,"order":9},{"name":"James Burrows","character":"Roy Knight","img":null,"order":10},{"name":"Hannah Rae","character":"Courtney","img":null,"order":11},{"name":"Kim Matula","character":"Jeri-Lynn","img":null,"order":12},{"name":"Paul Wight","character":"Big Show","img":null,"order":13},{"name":"Stephen Farrelly","character":"Sheamus","img":null,"order":14}],"movie:832262":[{"name":"Eric Bana","character":"Aaron Falk","img":null,"order":0},{"name":"Anna Torv","character":"Alice","img":null,"order":1},{"name":"Deborra-Lee Furness","character":"Jill Bailey","img":null,"order":2},{"name":"Robin McLeavy","character":"Lauren","img":null,"order":3},{"name":"Sisi Stringer","character":"Beth","img":null,"order":4},{"name":"Lucy Ansell","character":"Bree","img":null,"order":5},{"name":"Jacqueline McKenzie","character":"Carmen Cooper","img":null,"order":6},{"name":"Jeremy Lindsay Taylor","character":"Erik Falk","img":null,"order":7},{"name":"Richard Roxburgh","character":"Daniel Bailey","img":null,"order":8},{"name":"Tony Briggs","character":"Ian Chase","img":null,"order":9},{"name":"Kenneth Radley","character":"Sergeant King","img":null,"order":10},{"name":"Ash Ricardo","character":"Jennifer Falk","img":null,"order":11},{"name":"Ingrid Torelli","character":"Margot","img":null,"order":12},{"name":"Matilda May Pawsey","character":"Rebecca","img":null,"order":13},{"name":"Archie Thomson","character":"Aaron Falk","img":null,"order":14}],"movie:316152":[{"name":"Matthew McConaughey","character":"Newton Knight","img":null,"order":0},{"name":"Gugu Mbatha-Raw","character":"Rachel","img":null,"order":1},{"name":"Mahershala Ali","character":"Moses Washington","img":null,"order":2},{"name":"Keri Russell","character":"Serena Knight","img":null,"order":3},{"name":"Jacob Lofland","character":"Daniel","img":null,"order":4},{"name":"Sean Bridgers","character":"Sumrall","img":null,"order":5},{"name":"Brad Carter","character":"Lieutenant Barbour","img":null,"order":6},{"name":"Jane McNeill","character":"Miss Ellie","img":null,"order":7},{"name":"Gary Grubbs","character":"Prosecuting Attorney","img":null,"order":8},{"name":"Christopher Berry","character":"Jasper","img":null,"order":9},{"name":"Joe Chrest","character":"Amos Deason","img":null,"order":10},{"name":"David Jensen","character":"Quitman","img":null,"order":11},{"name":"Kurt Krause","character":"Injured Soldier","img":null,"order":12},{"name":"Carlton Caudle","character":"Confederate Color Guard","img":null,"order":13},{"name":"Martin Bats Bradford","character":"Freedman 1","img":null,"order":14}],"movie:83389":[{"name":"Masami Nagasawa","character":"Umi Matsuzaki (voice)","img":null,"order":0},{"name":"Junichi Okada","character":"Shun Kazama / Yuichiro Sawamura (voice)","img":null,"order":1},{"name":"Keiko Takeshita","character":"Hana Matsuzaki (voice)","img":null,"order":2},{"name":"Yuriko Ishida","character":"Miki Hokuto (voice)","img":null,"order":3},{"name":"Rumi Hiiragi","character":"Sachiko Hirokoji (voice)","img":null,"order":4},{"name":"Jun Fubuki","character":"Ryoko Matsuzaki (voice)","img":null,"order":5},{"name":"Takashi Naito","character":"Yoshio Onodera (voice)","img":null,"order":6},{"name":"Shunsuke Kazama","character":"Shiro Mizunuma / Hiroshi Tachibana (voice)","img":null,"order":7},{"name":"Nao Omori","character":"Akio Kazama (voice)","img":null,"order":8},{"name":"Teruyuki Kagawa","character":"Tokumaru Board Chairman (voice)","img":null,"order":9},{"name":"Haruka Shiraishi","character":"Sora Matsuzaki (voice)","img":null,"order":10},{"name":"Tsubasa Kobayashi","character":"Riku Matsuzaki (voice)","img":null,"order":11},{"name":"Ayako Ito","character":"Secretary to the Tokumaru Board Chairman (voice)","img":null,"order":12},{"name":"Naoya Fujimaki","character":"Tokumaru Front Desk Receptionist (voice)","img":null,"order":13},{"name":"Toshimi Kanno","character":"Nobuko (voice)","img":null,"order":14}],"movie:9323":[{"name":"Atsuko Tanaka","character":"Motoko Kusanagi (voice)","img":null,"order":0},{"name":"Akio Otsuka","character":"Batou (voice)","img":null,"order":1},{"name":"Iemasa Kayumi","character":"Puppetmaster (voice)","img":null,"order":2},{"name":"Koichi Yamadera","character":"Togusa (voice)","img":"biov5jENp2XYfehkcdnRvi796Wi.jpg","order":3},{"name":"Yutaka Nakano","character":"Ishikawa (voice)","img":null,"order":4},{"name":"Tamio Ohki","character":"Aramaki (voice)","img":null,"order":5},{"name":"Tessyo Genda","character":"Director Nakamura (voice)","img":null,"order":6},{"name":"Masakazu Namaki","character":"Dr. Willis (voice)","img":null,"order":7},{"name":"Masato Yamanouchi","character":"Minister of Foreign Affairs (voice)","img":null,"order":8},{"name":"Shinji Ogawa","character":"Gaik\u00f4kan (voice)","img":null,"order":9},{"name":"Mitsuru Miyamoto","character":"Mizuho Daita (voice)","img":null,"order":10},{"name":"Kazuhiro Yamaji","character":"Garbage Collector A (voice)","img":null,"order":11},{"name":"Shigeru Chiba","character":"Garbage Collector B (voice)","img":"mF5YJxApTYKBVFJDrEC9IrJ5ooV.jpg","order":12},{"name":"Hiroshi Yanaka","character":"Coroner (voice)","img":null,"order":13},{"name":"Ginzo Matsuo","character":"Old Man (voice)","img":null,"order":14}],"movie:12140":[{"name":"Atsuko Tanaka","character":"Motoko Kusanagi (voice)","img":null,"order":0},{"name":"Akio Otsuka","character":"Batou (voice)","img":null,"order":1},{"name":"Koichi Yamadera","character":"Togusa (voice)","img":"biov5jENp2XYfehkcdnRvi796Wi.jpg","order":2},{"name":"Tamio Ohki","character":"Section 9 Department Chief Aramaki (voice)","img":null,"order":3},{"name":"Yutaka Nakano","character":"Ishikawa (voice)","img":null,"order":4},{"name":"Hiroaki Hirata","character":"Koga (voice)","img":null,"order":5},{"name":"Masaki Terasoma","character":"Azuma (voice)","img":null,"order":6},{"name":"Sumi Mutoh","character":"Mysterious Woman (voice)","img":null,"order":7},{"name":"Yuzuru Fujimoto","character":"Criminal (voice)","img":null,"order":8},{"name":"Sukekiyo Kameyama","character":"Rin (voice)","img":null,"order":9},{"name":"Ryuji Nakagi","character":"Wakabayashi (voice)","img":null,"order":10},{"name":"Fumihiko Tachiki","character":"Bodyguard (voice)","img":null,"order":11},{"name":"Minoru Hirano","character":"Cyborg Doctor (voice)","img":null,"order":12},{"name":"Katsunosuke Hori","character":"Chief of Forensics Division (voice)","img":null,"order":13},{"name":"Naoto Takenaka","character":"Kim (voice)","img":null,"order":14}],"movie:238":[{"name":"Marlon Brando","character":"Don Vito Corleone","img":null,"order":0},{"name":"Al Pacino","character":"Michael Corleone","img":null,"order":1},{"name":"James Caan","character":"Sonny Corleone","img":null,"order":2},{"name":"Robert Duvall","character":"Tom Hagen","img":null,"order":3},{"name":"Richard S. Castellano","character":"Clemenza","img":null,"order":4},{"name":"Diane Keaton","character":"Kay Adams","img":null,"order":5},{"name":"Talia Shire","character":"Connie Corleone Rizzi","img":null,"order":6},{"name":"Gianni Russo","character":"Carlo Rizzi","img":null,"order":7},{"name":"Sterling Hayden","character":"Captain McCluskey","img":null,"order":8},{"name":"John Marley","character":"Jack Woltz","img":null,"order":9},{"name":"Richard Conte","character":"Barzini","img":null,"order":10},{"name":"Al Lettieri","character":"Sollozzo","img":null,"order":11},{"name":"Abe Vigoda","character":"Sal Tessio","img":null,"order":12},{"name":"John Cazale","character":"Fredo Corleone","img":null,"order":13},{"name":"Rudy Bond","character":"Cuneo","img":null,"order":14}],"movie:240":[{"name":"Al Pacino","character":"Don Michael Corleone","img":null,"order":0},{"name":"Robert Duvall","character":"Tom Hagen","img":null,"order":1},{"name":"Diane Keaton","character":"Kay Corleone","img":null,"order":2},{"name":"Robert De Niro","character":"Vito Corleone","img":null,"order":3},{"name":"John Cazale","character":"Frederico 'Fredo' Corleone","img":null,"order":4},{"name":"Talia Shire","character":"Constanzia 'Connie' Corleone","img":null,"order":5},{"name":"Lee Strasberg","character":"Hyman Roth","img":null,"order":6},{"name":"Michael V. Gazzo","character":"Frank Pentangeli","img":null,"order":7},{"name":"G.D. Spradlin","character":"Senator Pat Geary","img":null,"order":8},{"name":"Richard Bright","character":"Al Neri","img":null,"order":9},{"name":"Gastone Moschin","character":"Don Fanucci","img":null,"order":10},{"name":"Tom Rosqui","character":"Rocco Lampone","img":null,"order":11},{"name":"Bruno Kirby","character":"Young Clemenza","img":null,"order":12},{"name":"Frank Sivero","character":"Genco Abbandando","img":null,"order":13},{"name":"Francesca De Sapio","character":"Young Mama Corleone","img":null,"order":14}],"movie:242":[{"name":"Al Pacino","character":"Michael Corleone","img":null,"order":0},{"name":"Diane Keaton","character":"Kay Adams","img":null,"order":1},{"name":"Talia Shire","character":"Connie Corleone Rizzi","img":null,"order":2},{"name":"Andy Garcia","character":"Vincent Mancini","img":null,"order":3},{"name":"Eli Wallach","character":"Don Altobello","img":null,"order":4},{"name":"Joe Mantegna","character":"Joey Zasa","img":null,"order":5},{"name":"George Hamilton","character":"B.J. Harrison","img":null,"order":6},{"name":"Bridget Fonda","character":"Grace Hamilton","img":null,"order":7},{"name":"Sofia Coppola","character":"Mary Corleone","img":null,"order":8},{"name":"Raf Vallone","character":"Cardinal Lamberto","img":null,"order":9},{"name":"Franc D'Ambrosio","character":"Anthony Corleone","img":null,"order":10},{"name":"Donal Donnelly","character":"Archbishop Gilday","img":null,"order":11},{"name":"Richard Bright","character":"Al Neri","img":null,"order":12},{"name":"Helmut Berger","character":"Frederick Keinszig","img":null,"order":13},{"name":"Don Novello","character":"Dominic Abbandando","img":null,"order":14}],"movie:5279":[{"name":"Maggie Smith","character":"Constance Trentham","img":null,"order":0},{"name":"Michael Gambon","character":"William McCordle","img":null,"order":1},{"name":"Kristin Scott Thomas","character":"Sylvia McCordle","img":null,"order":2},{"name":"Camilla Rutherford","character":"Isobel McCordle","img":null,"order":3},{"name":"Charles Dance","character":"Raymond Stockbridge","img":null,"order":4},{"name":"Geraldine Somerville","character":"Louisa Stockbridge","img":null,"order":5},{"name":"Tom Hollander","character":"Anthony Meredith","img":null,"order":6},{"name":"Natasha Wightman","character":"Lavinia Meredith","img":null,"order":7},{"name":"Jeremy Northam","character":"Ivor Novello","img":null,"order":8},{"name":"Bob Balaban","character":"Morris Weissman","img":null,"order":9},{"name":"James Wilby","character":"Freddie Nesbitt","img":null,"order":10},{"name":"Claudie Blakley","character":"Mabel Nesbitt","img":null,"order":11},{"name":"Laurence Fox","character":"Rupert Standish","img":null,"order":12},{"name":"Trent Ford","character":"Jeremy Blond","img":null,"order":13},{"name":"Ryan Phillippe","character":"Henry Denton","img":null,"order":14}],"movie:12477":[{"name":"Tsutomu Tatsumi","character":"Seita (voice)","img":null,"order":0},{"name":"Ayano Shiraishi","character":"Setsuko (voice)","img":null,"order":1},{"name":"Yoshiko Shinohara","character":"Mother (voice)","img":null,"order":2},{"name":"Akemi Yamaguchi","character":"Auntie (voice)","img":null,"order":3},{"name":"Masayo Sakai","character":"Woman who takes care of Setsuko (voice)","img":null,"order":4},{"name":"Kozo Hashida","character":"Obayashi Chairman (voice)","img":null,"order":5},{"name":"Kazumi Nozaki","character":"Cousin (voice)","img":null,"order":6},{"name":"Yoshio Matsuoka","character":"Gosaku (voice)","img":null,"order":7},{"name":"Masahiro Kanetake","character":"Aunt's House Guest (voice)","img":null,"order":8},{"name":"Kiyoshi Yanagawa","character":"Patrolman (voice)","img":null,"order":9},{"name":"Hajime Maki","character":"Man who arrests Seita (voice)","img":null,"order":10},{"name":"Atsuo Omotem","character":"Person in Bank (voice)","img":null,"order":11},{"name":"Teruhisa Harita","character":"Station Worker (voice)","img":null,"order":12},{"name":"Hiroshi Tanaka","character":"Person in Bank (voice)","img":null,"order":13},{"name":"Michio Denpo","character":"Station Worker / Doctor (voice)","img":null,"order":14}],"movie:64682":[{"name":"Leonardo DiCaprio","character":"Jay Gatsby","img":null,"order":0},{"name":"Tobey Maguire","character":"Nick Carraway","img":null,"order":1},{"name":"Carey Mulligan","character":"Daisy Buchanan","img":null,"order":2},{"name":"Joel Edgerton","character":"Tom Buchanan","img":null,"order":3},{"name":"Elizabeth Debicki","character":"Jordan Baker","img":null,"order":4},{"name":"Isla Fisher","character":"Myrtle Wilson","img":null,"order":5},{"name":"Jason Clarke","character":"George Wilson","img":null,"order":6},{"name":"Amitabh Bachchan","character":"Meyer Wolfsheim","img":null,"order":7},{"name":"Callan McAuliffe","character":"Teen Jay Gatsby","img":null,"order":8},{"name":"Adelaide Clemens","character":"Catherine","img":null,"order":9},{"name":"Steve Bisley","character":"Dan Cody","img":null,"order":10},{"name":"Richard Carter","character":"Herzog","img":null,"order":11},{"name":"Jack Thompson","character":"Dr. Walter Perkins","img":null,"order":12},{"name":"Vince Colosimo","character":"Michaelis","img":null,"order":13},{"name":"Max Cullen","character":"Owl Eyes","img":null,"order":14}],"movie:590":[{"name":"Nicole Kidman","character":"Virginia Woolf","img":null,"order":0},{"name":"Julianne Moore","character":"Laura Brown","img":null,"order":1},{"name":"Meryl Streep","character":"Clarissa Vaughan","img":null,"order":2},{"name":"Stephen Dillane","character":"Leonard Woolf","img":null,"order":3},{"name":"Jack Rovello","character":"Richie","img":null,"order":4},{"name":"Ed Harris","character":"Richard Brown","img":null,"order":5},{"name":"Miranda Richardson","character":"Vanessa Bell","img":null,"order":6},{"name":"John C. Reilly","character":"Dan Brown","img":null,"order":7},{"name":"Allison Janney","character":"Sally Lester","img":null,"order":8},{"name":"George Loftus","character":"Quentin Bell","img":null,"order":9},{"name":"Charley Ramm","character":"Julian Bell","img":null,"order":10},{"name":"Sophie Wyburd","character":"Angelica Bell","img":null,"order":11},{"name":"Lyndsey Marshal","character":"Lottie Hope","img":null,"order":12},{"name":"Linda Bassett","character":"Nelly Boxall","img":null,"order":13},{"name":"Christian Coulson","character":"Ralph Partridge","img":null,"order":14}],"movie:4935":[{"name":"Chieko Baisho","character":"Sophie (voice)","img":null,"order":0},{"name":"Takuya Kimura","character":"Howl (voice)","img":null,"order":1},{"name":"Akihiro Miwa","character":"Witch of the Waste (voice)","img":null,"order":2},{"name":"Tatsuya Gashuin","character":"Calcifer (voice)","img":null,"order":3},{"name":"Ryunosuke Kamiki","character":"Markl (voice)","img":null,"order":4},{"name":"Mitsunori Isaki","character":"Kosho (voice)","img":null,"order":5},{"name":"Yo Oizumi","character":"Prince Justin / Turnip Head (voice)","img":null,"order":6},{"name":"Akio Otsuka","character":"King of Ingary (voice)","img":null,"order":7},{"name":"Daijir\u014d Harada","character":"Heen (voice)","img":null,"order":8},{"name":"Haruko Kat\u014d","character":"Madame Suliman (voice)","img":null,"order":9},{"name":"Makoto Yasumura","character":"(voice)","img":null,"order":10},{"name":"Manabu Muraji","character":"(voice)","img":null,"order":11},{"name":"Keiko Tsukamoto","character":"(voice)","img":null,"order":12},{"name":"Tsuzuki Kayako","character":"(voice)","img":null,"order":13},{"name":"Seiji Sasaki","character":"(voice)","img":null,"order":14}],"movie:467909":[{"name":"Anthony Ramos","character":"Usnavi","img":null,"order":0},{"name":"Corey Hawkins","character":"Benny","img":null,"order":1},{"name":"Leslie Grace","character":"Nina Rosario","img":null,"order":2},{"name":"Melissa Barrera","character":"Vanessa","img":null,"order":3},{"name":"Olga Merediz","character":"Abuela Claudia","img":null,"order":4},{"name":"Daphne Rubin-Vega","character":"Daniela","img":null,"order":5},{"name":"Gregory D\u00edaz IV","character":"Sonny","img":null,"order":6},{"name":"Marc Anthony","character":"Gapo","img":null,"order":7},{"name":"Jimmy Smits","character":"Kevin Rosario","img":null,"order":8},{"name":"Stephanie Beatriz","character":"Carla","img":null,"order":9},{"name":"Dascha Polanco","character":"Cuca","img":null,"order":10},{"name":"Noah Catala","character":"Graffiti Pete","img":null,"order":11},{"name":"Lin-Manuel Miranda","character":"Pirag\u00fcero","img":null,"order":12},{"name":"Mateo G\u00f3mez","character":"Alejandro","img":null,"order":13},{"name":"Patrick Page","character":"Pike","img":null,"order":14}],"movie:19994":[{"name":"Megan Fox","character":"Jennifer","img":null,"order":0},{"name":"Amanda Seyfried","character":"Needy","img":null,"order":1},{"name":"Johnny Simmons","character":"Chip","img":null,"order":2},{"name":"Adam Brody","character":"Nikolai","img":null,"order":3},{"name":"Sal Cortez","character":"Chas","img":null,"order":4},{"name":"Ryan Levine","character":"Mick","img":null,"order":5},{"name":"Juan Riedinger","character":"Dirk","img":null,"order":6},{"name":"Colin Askey","character":"Keyboardist","img":null,"order":7},{"name":"Chris Pratt","character":"Roman Duda","img":null,"order":8},{"name":"Juno Rinaldi","character":"Officer Warzak","img":null,"order":9},{"name":"Kyle Gallner","character":"Colin Gray","img":null,"order":10},{"name":"Josh Emerson","character":"Jonas Kozelle","img":null,"order":11},{"name":"J.K. Simmons","character":"Mr. Wroblewski","img":null,"order":12},{"name":"Amy Sedaris","character":"Needy's Mom","img":null,"order":13},{"name":"Cynthia Stevenson","character":"Chip's Mom","img":null,"order":14}],"movie:16859":[{"name":"Minami Takayama","character":"Kiki / Ursula (voice)","img":null,"order":0},{"name":"Rei Sakuma","character":"Jiji (voice)","img":null,"order":1},{"name":"Kappei Yamaguchi","character":"Tombo (voice)","img":null,"order":2},{"name":"Keiko Toda","character":"Osono (voice)","img":null,"order":3},{"name":"Mieko Nobusawa","character":"Kokiri (voice)","img":null,"order":4},{"name":"Koichi Miura","character":"Okino (voice)","img":null,"order":5},{"name":"Haruko Kat\u014d","character":"Old Lady (voice)","img":null,"order":6},{"name":"Hiroko Seki","character":"Bertha (voice)","img":null,"order":7},{"name":"Yuriko Fuchizaki","character":"Ketto (voice)","img":null,"order":8},{"name":"Koichi Yamadera","character":"Bakery Worker / Policeman (voice)","img":"biov5jENp2XYfehkcdnRvi796Wi.jpg","order":9},{"name":"Kikuko Inoue","character":"Maki (voice)","img":null,"order":10},{"name":"Yuko Kobayashi","character":"Young Senpai Witch (voice)","img":null,"order":11},{"name":"Mika Doi","character":"Ketto's Mother (voice)","img":null,"order":12},{"name":"Takaya Hashi","character":"Ketto's Father (voice)","img":null,"order":13},{"name":"Chika Sakamoto","character":"Baby (voice)","img":null,"order":14}],"movie:9361":[{"name":"Daniel Day-Lewis","character":"Hawkeye","img":null,"order":0},{"name":"Madeleine Stowe","character":"Cora","img":null,"order":1},{"name":"Jodhi May","character":"Alice","img":null,"order":2},{"name":"Russell Means","character":"Chingachgook","img":null,"order":3},{"name":"Wes Studi","character":"Magua","img":null,"order":4},{"name":"Eric Schweig","character":"Uncas","img":null,"order":5},{"name":"Steven Waddington","character":"Heyward","img":null,"order":6},{"name":"Maurice Ro\u00ebves","character":"Colonel Munro","img":null,"order":7},{"name":"Pete Postlethwaite","character":"Captain Beams","img":null,"order":8},{"name":"Colm Meaney","character":"Major Ambrose","img":null,"order":9},{"name":"Patrice Ch\u00e9reau","character":"General Montcalm","img":null,"order":10},{"name":"Edward Blatchford","character":"Jack Winthrop","img":null,"order":11},{"name":"Terry Kinney","character":"John Cameron","img":null,"order":12},{"name":"Tracey Ellis","character":"Alexandra Cameron","img":null,"order":13},{"name":"Justin M. Rice","character":"James Cameron","img":null,"order":14}],"movie:616":[{"name":"Tom Cruise","character":"Nathan Algren","img":null,"order":0},{"name":"Ken Watanabe","character":"Moritsugu Katsumoto","img":null,"order":1},{"name":"Timothy Spall","character":"Simon Graham","img":null,"order":2},{"name":"Tony Goldwyn","character":"Col. Benjamin Bagley","img":null,"order":3},{"name":"Hiroyuki Sanada","character":"Ujio","img":null,"order":4},{"name":"Koyuki","character":"Taka","img":null,"order":5},{"name":"Shin Koyamada","character":"Nobutada","img":null,"order":6},{"name":"Billy Connolly","character":"Zebulon Gant","img":null,"order":7},{"name":"Togo Igawa","character":"General Hasegawa","img":null,"order":8},{"name":"Shichinosuke Nakamura","character":"Emperor Meiji","img":null,"order":9},{"name":"Masato Harada","character":"Omura","img":null,"order":10},{"name":"William Atherton","character":"Winchester Rep","img":null,"order":11},{"name":"Chad Lindberg","character":"Winchester Rep Assistant","img":null,"order":12},{"name":"Scott Wilson","character":"Ambassador Swanbeck","img":null,"order":13},{"name":"Ray Godshall Sr.","character":"Convention Hall Attendee","img":null,"order":14}],"movie:11774":[{"name":"Emily Browning","character":"Violet Baudelaire","img":null,"order":0},{"name":"Liam Aiken","character":"Klaus Baudelaire","img":null,"order":1},{"name":"Kara Hoffman","character":"Sunny Baudelaire","img":null,"order":2},{"name":"Shelby Hoffman","character":"Sunny Baudelaire","img":null,"order":3},{"name":"Jim Carrey","character":"Count Olaf / Dr. Stephano / Captain Sham","img":null,"order":4},{"name":"Jude Law","character":"Lemony Snicket","img":null,"order":5},{"name":"Timothy Spall","character":"Mr. Poe","img":null,"order":6},{"name":"Meryl Streep","character":"Josephine Anwhistle","img":null,"order":7},{"name":"Billy Connolly","character":"Dr. Montgomery Montgomery","img":null,"order":8},{"name":"Catherine O'Hara","character":"Justice Strauss","img":null,"order":9},{"name":"Jennifer Coolidge","character":"White-Faced Women","img":null,"order":10},{"name":"Jane Adams","character":"White-Faced Women","img":null,"order":11},{"name":"Craig Ferguson","character":"Person of Indeterminate Gender","img":null,"order":12},{"name":"Luis Guzm\u00e1n","character":"Bald Man","img":null,"order":13},{"name":"Jamie Harris","character":"Hook-Handed Man","img":null,"order":14}],"movie:503919":[{"name":"Robert Pattinson","character":"Thomas Howard","img":null,"order":0},{"name":"Willem Dafoe","character":"Thomas Wake","img":null,"order":1},{"name":"Valeriia Karaman","character":"Mermaid","img":null,"order":2},{"name":"Logan Hawkes","character":"Ephraim Winslow","img":null,"order":3},{"name":"Kyla Nicolle","character":"Woman on the Rocks","img":null,"order":4},{"name":"Shaun Clarke","character":"Departing Wickie","img":null,"order":5},{"name":"Pierre Richard","character":"Departing Assistant Wickie","img":null,"order":6},{"name":"Preston Hudson","character":"Tender Mate","img":null,"order":7},{"name":"Jeff Cruts","character":"Tender Mate","img":null,"order":8}],"movie:603":[{"name":"Keanu Reeves","character":"Neo","img":null,"order":0},{"name":"Laurence Fishburne","character":"Morpheus","img":null,"order":1},{"name":"Carrie-Anne Moss","character":"Trinity","img":null,"order":2},{"name":"Hugo Weaving","character":"Agent Smith","img":null,"order":3},{"name":"Gloria Foster","character":"Oracle","img":null,"order":4},{"name":"Joe Pantoliano","character":"Cypher","img":null,"order":5},{"name":"Marcus Chong","character":"Tank","img":null,"order":6},{"name":"Julian Arahanga","character":"Apoc","img":null,"order":7},{"name":"Matt Doran","character":"Mouse","img":null,"order":8},{"name":"Belinda McClory","character":"Switch","img":null,"order":9},{"name":"Anthony Ray Parker","character":"Dozer","img":null,"order":10},{"name":"Paul Goddard","character":"Agent Brown","img":null,"order":11},{"name":"Robert Taylor","character":"Agent Jones","img":null,"order":12},{"name":"David Aston","character":"Rhineheart","img":null,"order":13},{"name":"Marc Aden Gray","character":"Choi","img":null,"order":14}],"movie:604":[{"name":"Keanu Reeves","character":"Neo","img":null,"order":0},{"name":"Laurence Fishburne","character":"Morpheus","img":null,"order":1},{"name":"Carrie-Anne Moss","character":"Trinity","img":null,"order":2},{"name":"Hugo Weaving","character":"Agent Smith","img":null,"order":3},{"name":"Jada Pinkett Smith","character":"Niobe","img":null,"order":4},{"name":"Gloria Foster","character":"The Oracle","img":null,"order":5},{"name":"Harold Perrineau","character":"Link","img":null,"order":6},{"name":"Monica Bellucci","character":"Persephone","img":null,"order":7},{"name":"Harry Lennix","character":"Commander Lock","img":null,"order":8},{"name":"Lambert Wilson","character":"The Merovingian","img":null,"order":9},{"name":"Randall Duk Kim","character":"Keymaker","img":null,"order":10},{"name":"Nona Gaye","character":"Zee","img":null,"order":11},{"name":"Anthony Zerbe","character":"Councillor Hamann","img":null,"order":12},{"name":"Daniel Bernhardt","character":"Agent Johnson","img":null,"order":13},{"name":"Helmut Bakaitis","character":"The Architect","img":null,"order":14}],"movie:624860":[{"name":"Keanu Reeves","character":"Neo / Thomas Anderson","img":null,"order":0},{"name":"Carrie-Anne Moss","character":"Trinity / Tiffany","img":null,"order":1},{"name":"Yahya Abdul-Mateen II","character":"Morpheus / Agent Smith","img":null,"order":2},{"name":"Jonathan Groff","character":"Smith","img":null,"order":3},{"name":"Jessica Henwick","character":"Bugs","img":null,"order":4},{"name":"Neil Patrick Harris","character":"The Analyst","img":null,"order":5},{"name":"Jada Pinkett Smith","character":"Niobe","img":null,"order":6},{"name":"Priyanka Chopra Jonas","character":"Sati","img":null,"order":7},{"name":"Christina Ricci","character":"Gwyn de Vere","img":null,"order":8},{"name":"Lambert Wilson","character":"The Merovingian","img":null,"order":9},{"name":"Andrew Lewis Caldwell","character":"Jude","img":null,"order":10},{"name":"Toby Onwumere","character":"Sequoia","img":null,"order":11},{"name":"Max Riemelt","character":"Sheperd","img":null,"order":12},{"name":"Joshua Grothe","character":"FunktI\u00f8n","img":null,"order":13},{"name":"Brian J. Smith","character":"Berg","img":null,"order":14}],"movie:605":[{"name":"Keanu Reeves","character":"Neo","img":null,"order":0},{"name":"Laurence Fishburne","character":"Morpheus","img":null,"order":1},{"name":"Carrie-Anne Moss","character":"Trinity","img":null,"order":2},{"name":"Hugo Weaving","character":"Agent Smith","img":null,"order":3},{"name":"Jada Pinkett Smith","character":"Niobe","img":null,"order":4},{"name":"Mary Alice","character":"The Oracle","img":null,"order":5},{"name":"Harold Perrineau","character":"Link","img":null,"order":6},{"name":"Collin Chou","character":"Seraph","img":null,"order":7},{"name":"Harry Lennix","character":"Commander Lock","img":null,"order":8},{"name":"Ian Bliss","character":"Bane","img":null,"order":9},{"name":"Lambert Wilson","character":"Merovingian","img":null,"order":10},{"name":"Bruce Spence","character":"Trainman","img":null,"order":11},{"name":"Monica Bellucci","character":"Persephone","img":null,"order":12},{"name":"Nona Gaye","character":"Zee","img":null,"order":13},{"name":"Anthony Zerbe","character":"Councillor Hamann","img":null,"order":14}],"movie:1236153":[{"name":"Chris Pratt","character":"Chris Raven","img":null,"order":0},{"name":"Rebecca Ferguson","character":"Judge Maddox","img":null,"order":1},{"name":"Kali Reis","character":"Jacqueline 'Jaq' Diallo","img":null,"order":2},{"name":"Kylie Rogers","character":"Britt Raven","img":null,"order":3},{"name":"Chris Sullivan","character":"Rob Nelson","img":null,"order":4},{"name":"Jeff Pierre","character":"Patrick Burke","img":null,"order":5},{"name":"Annabelle Wallis","character":"Nicole Raven","img":null,"order":6},{"name":"Rafi Gavron","character":"Holt Charles","img":null,"order":7},{"name":"Kenneth Choi","character":"Ray Vale","img":null,"order":8},{"name":"Jamie McBride","character":"Dan Vogel","img":null,"order":9},{"name":"Ross Gosla","character":"David Webb","img":null,"order":10},{"name":"Mark Daneri","character":"Jeff Martin","img":null,"order":11},{"name":"Haydn Dalton","character":"Bill Peterson","img":null,"order":12},{"name":"Michael C. Mahon","character":"Booking Sergeant","img":null,"order":13},{"name":"Noah Fearnley","character":"Tattoed Sleazebag","img":null,"order":14}],"movie:1242332":[{"name":"Bob Odenkirk","character":"Ulysses Richardson","img":null,"order":0},{"name":"Henry Winkler","character":"Mayor Kibner","img":null,"order":1},{"name":"Lena Headey","character":"Moira","img":null,"order":2},{"name":"Billy MacLellan","character":"Deputy Mike Nelson","img":null,"order":3},{"name":"Ryan Allen","character":"Deputy Blaine Anderson","img":null,"order":4},{"name":"Reena Jolly","character":"Lori","img":null,"order":5},{"name":"Brendan Fletcher","character":"Keith","img":null,"order":6},{"name":"Peter Shinkoda","character":"Joe","img":null,"order":7},{"name":"Jess McLeod","character":"Alex","img":null,"order":8},{"name":"Alex MacMillan","character":"Kent","img":null,"order":9},{"name":"Dan De Jaeger","character":"Ernie","img":null,"order":10},{"name":"John C. MacDonald","character":"Kenny","img":null,"order":11},{"name":"David Lawrence Brown","character":"Dr. Walter Vilie","img":null,"order":12},{"name":"Derek Barnes","character":"James","img":null,"order":13},{"name":"Megan MacArton","character":"Mary Beth","img":null,"order":14}],"movie:454227":[{"name":"Chris Pine","character":"Robert Bruce, Earl of Carrick","img":null,"order":0},{"name":"Aaron Taylor-Johnson","character":"James Douglas, Lord of Douglas","img":null,"order":1},{"name":"Florence Pugh","character":"Elizabeth Burgh","img":null,"order":2},{"name":"Billy Howle","character":"Edward, Prince of Wales","img":null,"order":3},{"name":"Sam Spruell","character":"Aymer de Valence, Earl of Pembroke","img":null,"order":4},{"name":"Tony Curran","character":"Angus Og Macdonald, Lord of Islay","img":null,"order":5},{"name":"Callan Mulvey","character":"John III Comyn, Lord of Badenoch","img":null,"order":6},{"name":"James Cosmo","character":"Robert Bruce Senior","img":null,"order":7},{"name":"Stephen Dillane","character":"King Edward I of England","img":null,"order":8},{"name":"Steven Cree","character":"Sir Christopher Seton","img":null,"order":9},{"name":"Alastair Mackenzie","character":"John Strathbogie, Earl of Atholl","img":null,"order":10},{"name":"Chris Fulton","character":"Euan Bruce","img":null,"order":11},{"name":"Lorne MacFadyen","character":"Neil Bruce","img":null,"order":12},{"name":"Jack Greenlees","character":"Alexander Bruce","img":null,"order":13},{"name":"Rebecca Robin","character":"Queen Margaret of England","img":null,"order":14}],"movie:4547":[{"name":"Jodie Foster","character":"Meg Altman","img":null,"order":0},{"name":"Kristen Stewart","character":"Sarah Altman","img":null,"order":1},{"name":"Forest Whitaker","character":"Burnham","img":null,"order":2},{"name":"Dwight Yoakam","character":"Raoul","img":null,"order":3},{"name":"Jared Leto","character":"Junior","img":null,"order":4},{"name":"Patrick Bauchau","character":"Stephen Altman","img":null,"order":5},{"name":"Ann Magnuson","character":"Lydia Lynch","img":null,"order":6},{"name":"Ian Buchanan","character":"Evan Kurlander","img":null,"order":7},{"name":"Andrew Kevin Walker","character":"Sleepy Neighbor","img":null,"order":8},{"name":"Paul Schulze","character":"Officer Keeney","img":null,"order":9},{"name":"Mel Rodriguez","character":"Officer Morales","img":null,"order":10},{"name":"Richard Conant","character":"SWAT Cop","img":null,"order":11},{"name":"Paul Simon","character":"SWAT Cop","img":null,"order":12},{"name":"Victor Thrash","character":"SWAT Cop","img":null,"order":13},{"name":"Ken Turner","character":"SWAT Cop","img":null,"order":14}],"movie:2024":[{"name":"Mel Gibson","character":"Benjamin Martin","img":null,"order":0},{"name":"Heath Ledger","character":"Gabriel Martin","img":null,"order":1},{"name":"Joely Richardson","character":"Charlotte Selton","img":null,"order":2},{"name":"Jason Isaacs","character":"Col. William Tavington","img":null,"order":3},{"name":"Chris Cooper","character":"Col. Harry Burwell","img":null,"order":4},{"name":"Tch\u00e9ky Karyo","character":"Jean Villeneuve","img":null,"order":5},{"name":"Ren\u00e9 Auberjonois","character":"Reverend Oliver","img":null,"order":6},{"name":"Lisa Brenner","character":"Anne Howard","img":null,"order":7},{"name":"Tom Wilkinson","character":"Gen. Cornwallis","img":null,"order":8},{"name":"Donal Logue","character":"Dan Scott","img":null,"order":9},{"name":"Leon Rippy","character":"John Billings","img":null,"order":10},{"name":"Adam Baldwin","character":"Capt. Wilkins","img":"lfbyJWNWGbiYfU0Yr1tjn6Trd2V.jpg","order":11},{"name":"Jay Arlen Jones","character":"Occam","img":null,"order":12},{"name":"Joey D. Vieira","character":"Peter Howard","img":null,"order":13},{"name":"Gregory Smith","character":"Thomas Martin","img":null,"order":14}],"movie:875828":[{"name":"Cillian Murphy","character":"Tommy Shelby","img":null,"order":0},{"name":"Barry Keoghan","character":"Duke Shelby","img":null,"order":1},{"name":"Rebecca Ferguson","character":"Kaulo / Zelda","img":null,"order":2},{"name":"Tim Roth","character":"John Beckett","img":null,"order":3},{"name":"Stephen Graham","character":"Hayden Stagg","img":null,"order":4},{"name":"Sophie Rundle","character":"Ada Shelby","img":null,"order":5},{"name":"Ned Dennehy","character":"Charlie Strong","img":null,"order":6},{"name":"Packy Lee","character":"Johnny Dogs","img":null,"order":7},{"name":"Ian Peck","character":"Curly","img":null,"order":8},{"name":"Jay Lycurgo","character":"Elijah","img":null,"order":9},{"name":"Kasper Hilton-Hille","character":"Karl Thorne","img":null,"order":10},{"name":"Ruby Ashbourne Serkis","character":"Agnes Shelby","img":null,"order":11},{"name":"Bonnie Stott","character":"Ruby","img":null,"order":12},{"name":"Thomas Arnold","character":"Virgil","img":null,"order":13},{"name":"Sam Baker Jones","character":"Jake","img":null,"order":14}],"movie:12429":[{"name":"Yuria Kozuki","character":"Ponyo (voice)","img":null,"order":0},{"name":"Hiroki Doi","character":"Sosuke (voice)","img":null,"order":1},{"name":"George Tokoro","character":"Fujimoto (voice)","img":null,"order":2},{"name":"Tomoko Yamaguchi","character":"Risa (voice)","img":null,"order":3},{"name":"Yuki Amami","character":"Gran Mamare (voice)","img":null,"order":4},{"name":"Kazushige Nagashima","character":"Koichi (voice)","img":null,"order":5},{"name":"Akiko Yano","character":"Ponyo's Sister (voice)","img":null,"order":6},{"name":"Shin'ichi Hatori","character":"Anchorman (voice)","img":null,"order":7},{"name":"Tokie Hidari","character":"Kayo (voice)","img":null,"order":8},{"name":"Rumi Hiiragi","character":"Young Mother (voice)","img":null,"order":9},{"name":"Tomoko Naraoka","character":"Yoshie (voice)","img":null,"order":10},{"name":"Kazuko Yoshiyuki","character":"Toki (voice)","img":null,"order":11},{"name":"Eimi Hiraoka","character":"Kumiko (voice)","img":null,"order":12},{"name":"Nozomi \u014chashi","character":"Karen (voice)","img":null,"order":13},{"name":"Akiko Takeguchi","character":"Noriko (voice)","img":null,"order":14}],"movie:11621":[{"name":"Sh\u016bichir\u014d Moriyama","character":"Porco Rosso (voice)","img":null,"order":0},{"name":"Tokiko Kato","character":"Madame Gina (voice)","img":null,"order":1},{"name":"Bunshi Katsura VI","character":"Grandpa Piccolo (voice)","img":null,"order":2},{"name":"Tsunehiko Kamij\u00f4","character":"Mamma Aiuto Boss (voice)","img":null,"order":3},{"name":"Akemi Okamura","character":"Fio Piccolo (voice)","img":null,"order":4},{"name":"Akio Otsuka","character":"Donald Curtis (voice)","img":null,"order":5},{"name":"Hiroko Seki","character":"Granny (voice)","img":null,"order":6},{"name":"Masayuki Inagaki","character":"Major Ferrarin (voice)","img":null,"order":7},{"name":"Reiz\u014d Nomoto","character":"Mamma Aiuto Gang Member (voice)","img":null,"order":8},{"name":"Osamu Saka","character":"Mamma Aiuto Gang Member (voice)","img":null,"order":9},{"name":"Yu Shimaka","character":"Mamma Aiuto Gang Member (voice)","img":null,"order":10},{"name":"Yuzuru Fujimoto","character":"Mamma Aiuto Gang Member (voice)","img":null,"order":11},{"name":"Tatsuyuki Jinnai","character":"Mamma Aiuto Gang Member (voice)","img":null,"order":12},{"name":"Kazunori Arai","character":"Mamma Aiuto Gang Member (voice)","img":null,"order":13},{"name":"Nobuo Tanaka","character":"Mamma Aiuto Gang Member (voice)","img":null,"order":14}],"movie:128":[{"name":"Yoji Matsuda","character":"Ashitaka (voice)","img":null,"order":0},{"name":"Yuriko Ishida","character":"San / Kaya (voice)","img":null,"order":1},{"name":"Yuko Tanaka","character":"Eboshi Gozen (voice)","img":null,"order":2},{"name":"Kaoru Kobayashi","character":"Jikobo (voice)","img":null,"order":3},{"name":"Masahiko Nishimura","character":"Kouroku (voice)","img":null,"order":4},{"name":"Tsunehiko Kamij\u00f4","character":"Gonza (voice)","img":null,"order":5},{"name":"Akihiro Miwa","character":"Mrs. Moro (voice)","img":null,"order":6},{"name":"Mitsuko Mori","character":"Mrs. Hii (voice)","img":null,"order":7},{"name":"Hisaya Morishige","character":"Chief of Affairs (voice)","img":null,"order":8},{"name":"Sumi Shimamoto","character":"Toki (voice)","img":null,"order":9},{"name":"Tetsu Watanabe","character":"Wild Dog (voice)","img":null,"order":10},{"name":"Makoto Sat\u014d","character":"Tatari God (voice)","img":null,"order":11},{"name":"Akira Nagoya","character":"Cowherd (voice)","img":null,"order":12},{"name":"Kei Iinuma","character":"Chief of the Sick (voice)","img":null,"order":13},{"name":"Tsuzuki Kayako","character":"Kiyo (voice)","img":null,"order":14}],"movie:146233":[{"name":"Hugh Jackman","character":"Keller Dover","img":null,"order":0},{"name":"Jake Gyllenhaal","character":"Detective Loki","img":null,"order":1},{"name":"Viola Davis","character":"Nancy Birch","img":null,"order":2},{"name":"Maria Bello","character":"Grace Dover","img":null,"order":3},{"name":"Terrence Howard","character":"Franklin Birch","img":null,"order":4},{"name":"Melissa Leo","character":"Holly Jones","img":null,"order":5},{"name":"Paul Dano","character":"Alex Jones","img":null,"order":6},{"name":"Dylan Minnette","character":"Ralph Dover","img":null,"order":7},{"name":"Zo\u00eb Soul","character":"Eliza Birch","img":null,"order":8},{"name":"Erin Gerasimovich","character":"Anna Dover","img":null,"order":9},{"name":"Kyla-Drew","character":"Joy Birch","img":null,"order":10},{"name":"Wayne Duvall","character":"Captain Richard O'Malley","img":null,"order":11},{"name":"Len Cariou","character":"Father Patrick Dunn","img":null,"order":12},{"name":"David Dastmalchian","character":"Bob Taylor","img":null,"order":13},{"name":"Brad James","character":"Officer Carter","img":null,"order":14}],"movie:6439":[{"name":"Frankie Muniz","character":"Stripes (voice)","img":null,"order":0},{"name":"Hayden Panettiere","character":"Channing Walsh","img":null,"order":1},{"name":"Bruce Greenwood","character":"Nolan Walsh","img":null,"order":2},{"name":"Mandy Moore","character":"Sandy (voice)","img":null,"order":3},{"name":"Wendie Malick","character":"Clara Dalrymple","img":null,"order":4},{"name":"M. Emmet Walsh","character":"Woodzie","img":null,"order":5},{"name":"Snoop Dogg","character":"Lightning (voice)","img":"rbxBK2m6fEq0oHeMoBUMVYkJEdJ.jpg","order":6},{"name":"Michael Clarke Duncan","character":"Clydesdale (voice)","img":null,"order":7},{"name":"Jeff Foxworthy","character":"Reggie (voice)","img":null,"order":8},{"name":"Whoopi Goldberg","character":"Franny (voice)","img":null,"order":9},{"name":"Steve Harvey","character":"Buzz (voice)","img":null,"order":10},{"name":"David Spade","character":"Scuzz (voice)","img":null,"order":11},{"name":"Dustin Hoffman","character":"Tucker (voice)","img":null,"order":12},{"name":"Joshua Jackson","character":"Trenton's Pride (voice)","img":null,"order":13},{"name":"Joe Pantoliano","character":"Goose (voice)","img":null,"order":14}],"movie:641":[{"name":"Ellen Burstyn","character":"Sara Goldfarb","img":null,"order":0},{"name":"Jared Leto","character":"Harry Goldfarb","img":null,"order":1},{"name":"Jennifer Connelly","character":"Marion Silver","img":null,"order":2},{"name":"Marlon Wayans","character":"Tyrone C. Love","img":null,"order":3},{"name":"Christopher McDonald","character":"Tappy Tibbons","img":null,"order":4},{"name":"Louise Lasser","character":"Ada","img":null,"order":5},{"name":"Marcia Jean Kurtz","character":"Rae","img":null,"order":6},{"name":"Janet Sarno","character":"Mrs. Pearlman","img":null,"order":7},{"name":"Suzanne Shepherd","character":"Mrs. Scarlini","img":null,"order":8},{"name":"Joanne Gordon","character":"Mrs. Ovadia","img":null,"order":9},{"name":"Charlotte Aronofsky","character":"Mrs. Miles","img":null,"order":10},{"name":"Mark Margolis","character":"Mr. Rabinowitz","img":null,"order":11},{"name":"Michael Kaycheck","character":"Donut Cop","img":null,"order":12},{"name":"Jack A. O'Connell","character":"Corn Dog Stand Boss","img":null,"order":13},{"name":"Chas Mastin","character":"Lyle Russel","img":null,"order":14}],"movie:330459":[{"name":"Felicity Jones","character":"Jyn Erso","img":null,"order":0},{"name":"Diego Luna","character":"Cassian Andor","img":"qwbjcyDN37OHiln4a6P4LP31o7F.jpg","order":1},{"name":"Alan Tudyk","character":"K-2SO","img":"jUuUbPuMGonFT5E2pcs4alfqaCN.jpg","order":2},{"name":"Donnie Yen","character":"Chirrut Imwe","img":null,"order":3},{"name":"Jiang Wen","character":"Baze Malbus","img":null,"order":4},{"name":"Ben Mendelsohn","character":"Orson Krennic","img":null,"order":5},{"name":"Guy Henry","character":"Governor Tarkin","img":null,"order":6},{"name":"Forest Whitaker","character":"Saw Gerrera","img":null,"order":7},{"name":"Riz Ahmed","character":"Bodhi Rook","img":null,"order":8},{"name":"Mads Mikkelsen","character":"Galen Erso","img":null,"order":9},{"name":"Jimmy Smits","character":"Bail Organa","img":null,"order":10},{"name":"Alistair Petrie","character":"General Draven","img":null,"order":11},{"name":"Genevieve O'Reilly","character":"Mon Mothma","img":"4eOoW1PNBZfxRW0g8RmYH8bL6mq.jpg","order":12},{"name":"Ben Daniels","character":"General Merrick","img":"phEIvq0Ay2KjI5ewmVvpQ1a29GJ.jpg","order":13},{"name":"Paul Kasey","character":"Admiral Raddus","img":null,"order":14}],"movie:13156":[{"name":"Michael Caine","character":"Garth","img":null,"order":0},{"name":"Robert Duvall","character":"Hub","img":null,"order":1},{"name":"Haley Joel Osment","character":"Walter","img":null,"order":2},{"name":"Josh Lucas","character":"Adult Walter","img":null,"order":3},{"name":"Kyra Sedgwick","character":"Mae","img":null,"order":4},{"name":"Christian Kane","character":"Young Hub","img":null,"order":5},{"name":"Nicky Katt","character":"Stan","img":null,"order":6},{"name":"Eric Balfour","character":"Sheik's Grandson","img":null,"order":7},{"name":"Kevin Haberer","character":"Young Garth","img":null,"order":8},{"name":"Emmanuelle Vaugier","character":"Jasmine","img":null,"order":9},{"name":"Mitchel Musso","character":"Boy","img":null,"order":10},{"name":"Marc Musso","character":"Boy","img":null,"order":11},{"name":"Michael O'Neill","character":"Ralph","img":null,"order":12},{"name":"Deirdre O'Connell","character":"Helen","img":null,"order":13},{"name":"Adam Ozturk","character":"The Sheik","img":null,"order":14}],"movie:412117":[{"name":"Patton Oswalt","character":"Max (voice)","img":null,"order":0},{"name":"Kevin Hart","character":"Snowball (voice)","img":null,"order":1},{"name":"Eric Stonestreet","character":"Duke (voice)","img":null,"order":2},{"name":"Jenny Slate","character":"Gidget (voice)","img":null,"order":3},{"name":"Tiffany Haddish","character":"Daisy (voice)","img":null,"order":4},{"name":"Lake Bell","character":"Chloe (voice)","img":null,"order":5},{"name":"Nick Kroll","character":"Sergei (voice)","img":null,"order":6},{"name":"Dana Carvey","character":"Pops (voice)","img":null,"order":7},{"name":"Ellie Kemper","character":"Katie (voice)","img":null,"order":8},{"name":"Harrison Ford","character":"Rooster (voice)","img":null,"order":9},{"name":"Chris Renaud","character":"Norman / Additional Voices (voice)","img":null,"order":10},{"name":"Bobby Moynihan","character":"Mel (voice)","img":null,"order":11},{"name":"Hannibal Buress","character":"Buddy (voice)","img":null,"order":12},{"name":"Pete Holmes","character":"Chuck (voice)","img":null,"order":13},{"name":"Henry Lynch","character":"Liam (voice)","img":null,"order":14}],"movie:1072876":[{"name":"Jake Johnson","character":"Tommy","img":null,"order":0},{"name":"Anna Kendrick","character":"Maddy","img":null,"order":1},{"name":"Natalie Morales","character":"Theresa","img":null,"order":2},{"name":"Andy Samberg","character":"Andy Samberg","img":null,"order":3},{"name":"Mary Holland","character":"Amy","img":null,"order":4},{"name":"Emily Hampshire","character":"Mary","img":null,"order":5},{"name":"Nancy Lenehan","character":"Laurie","img":null,"order":6},{"name":"Daryl J. Johnson","character":"Malcolm","img":null,"order":7},{"name":"Miriam Flynn","character":"Becky Ann","img":null,"order":8},{"name":"Boban Marjanovi\u0107","character":"7 Foot Man","img":null,"order":9},{"name":"Biff Wiff","character":"James / Walter","img":null,"order":10},{"name":"Eduardo Franco","character":"P.A. Ninja","img":null,"order":11},{"name":"Jeff Kober","character":"Cowboy","img":null,"order":12},{"name":"Christopher Lloyd","character":"Dennis Walcott","img":null,"order":13},{"name":"Theo Wilson","character":"Sinbad Guy","img":null,"order":14}],"movie:9040":[{"name":"Al Pacino","character":"Officer Frank Serpico","img":null,"order":0},{"name":"John Randolph","character":"Sidney Green","img":null,"order":1},{"name":"Jack Kehoe","character":"Tom Keough","img":null,"order":2},{"name":"Biff McGuire","character":"Captain McClain","img":null,"order":3},{"name":"Barbara Eda-Young","character":"Laurie","img":null,"order":4},{"name":"Cornelia Sharpe","character":"Leslie Lane","img":null,"order":5},{"name":"Tony Roberts","character":"Bob Blair","img":null,"order":6},{"name":"John Medici","character":"Pasquale","img":null,"order":7},{"name":"Allan Rich","character":"D. A. Tauber","img":null,"order":8},{"name":"Norman Ornellas","character":"Rubello","img":null,"order":9},{"name":"Edward Grover","character":"Lombardo","img":null,"order":10},{"name":"Albert Henderson","character":"Peluce","img":null,"order":11},{"name":"Hank Garrett","character":"Malone","img":null,"order":12},{"name":"Damien Leake","character":"Joey","img":null,"order":13},{"name":"Joseph Bova","character":"Potts","img":null,"order":14}],"movie:479":[{"name":"Samuel L. Jackson","character":"John Shaft","img":null,"order":0},{"name":"Vanessa Williams","character":"Carmen Vasquez","img":null,"order":1},{"name":"Jeffrey Wright","character":"Peoples Hernandez","img":null,"order":2},{"name":"Christian Bale","character":"Walter Wade, Jr.","img":null,"order":3},{"name":"Busta Rhymes","character":"Rasaan","img":null,"order":4},{"name":"Dan Hedaya","character":"Jack Roselli","img":null,"order":5},{"name":"Toni Collette","character":"Diane Palmieri","img":null,"order":6},{"name":"Richard Roundtree","character":"\"Uncle\" John Shaft","img":null,"order":7},{"name":"Ruben Santiago-Hudson","character":"Jimmy Groves","img":null,"order":8},{"name":"Josef Sommer","character":"Curt Flemming","img":null,"order":9},{"name":"Lynne Thigpen","character":"Carla Howard","img":null,"order":10},{"name":"Philip Bosco","character":"Walter Wade Senior","img":null,"order":11},{"name":"Pat Hingle","character":"Judge Dennis Bradford","img":null,"order":12},{"name":"Lee Tergesen","character":"Luger","img":null,"order":13},{"name":"Daniel von Bargen","character":"Lt Kearney","img":null,"order":14}],"movie:378064":[{"name":"Miyu Irino","character":"Shouya Ishida (voice)","img":null,"order":0},{"name":"Saori Hayami","character":"Shouko Nishimiya (voice)","img":null,"order":1},{"name":"Aoi Yuki","character":"Yuzuru Nishimiya (voice)","img":null,"order":2},{"name":"Kensho Ono","character":"Tomohiro Nagatsuka (voice)","img":null,"order":3},{"name":"Yuki Kaneko","character":"Naoka Ueno (voice)","img":null,"order":4},{"name":"Yui Ishikawa","character":"Miyoko Sahara (voice)","img":null,"order":5},{"name":"Megumi Han","character":"Miki Kawai (voice)","img":null,"order":6},{"name":"Toshiyuki Toyonaga","character":"Satoshi Mashiba (voice)","img":null,"order":7},{"name":"Mayu Matsuoka","character":"Shouya Ishida as an Elementary School Boy (voice)","img":null,"order":8},{"name":"Sachiko Kojima","character":"Kazuki Shimada as an Elementary School Boy (voice)","img":null,"order":9},{"name":"Hana Takeda","character":"Keisuke Hirose as an Elementary School Boy (voice)","img":null,"order":10},{"name":"Fuminori Komatsu","character":"Takeuchi-sensei (voice)","img":null,"order":11},{"name":"Ikuko Tani","character":"Ito Nishimiya (voice)","img":null,"order":12},{"name":"Erena Kamata","character":"Maria Ishida (voice)","img":null,"order":13},{"name":"Ayano Hamaguchi","character":"Shouya's Sister (voice)","img":null,"order":14}],"movie:14411":[{"name":"Brad Pitt","character":"Sinbad (voice)","img":null,"order":0},{"name":"Catherine Zeta-Jones","character":"Marina (voice)","img":null,"order":1},{"name":"Michelle Pfeiffer","character":"Eris (voice)","img":null,"order":2},{"name":"Joseph Fiennes","character":"Proteus (voice)","img":null,"order":3},{"name":"Dennis Haysbert","character":"Kale (voice)","img":null,"order":4},{"name":"Timothy West","character":"Dymas (voice)","img":null,"order":5},{"name":"Adriano Giannini","character":"Rat (voice)","img":null,"order":6},{"name":"Raman Hui Shing-Ngai","character":"Jin (voice)","img":null,"order":7},{"name":"Chung Chan","character":"Li (voice)","img":null,"order":8},{"name":"Jim Cummings","character":"Luca / Additional Voices (voice)","img":null,"order":9},{"name":"Conrad Vernon","character":"Jed (voice)","img":null,"order":10},{"name":"Andrew Birch","character":"Grum / Chum (voice)","img":null,"order":11},{"name":"Chris Miller","character":"Tower Guard (voice)","img":null,"order":12},{"name":"Frank Welker","character":"Spike (voice) (uncredited)","img":null,"order":13}],"movie:288036":[{"name":"Jason Sudeikis","character":"Jake Harper","img":null,"order":0},{"name":"Alison Brie","character":"Lainey Dalton","img":null,"order":1},{"name":"Adam Scott","character":"Matthew Sobvechik","img":null,"order":2},{"name":"Jason Mantzoukas","character":"Xander","img":null,"order":3},{"name":"Natasha Lyonne","character":"Kara","img":null,"order":4},{"name":"Adam Brody","character":"Sam","img":null,"order":5},{"name":"Amanda Peet","character":"Paula","img":null,"order":6},{"name":"Katherine Waterston","character":"Emma","img":null,"order":7},{"name":"Marc Blucas","character":"Chris Smith","img":null,"order":8},{"name":"Margarita Levieva","character":"Hannah","img":null,"order":9},{"name":"Andrea Savage","character":"Naomi","img":null,"order":10},{"name":"Daniella Pineda","character":"Danica","img":null,"order":11},{"name":"Remy Nozik","character":"George","img":null,"order":12},{"name":"Megan Guinan","character":"Alice","img":null,"order":13},{"name":"Anna Margaret Hollyman","character":"Renee","img":null,"order":14}],"movie:110415":[{"name":"Chris Evans","character":"Curtis","img":null,"order":0},{"name":"Song Kang-ho","character":"Namgoong Minsu","img":null,"order":1},{"name":"Ed Harris","character":"Wilford","img":null,"order":2},{"name":"John Hurt","character":"Gilliam","img":null,"order":3},{"name":"Tilda Swinton","character":"Mason","img":null,"order":4},{"name":"Jamie Bell","character":"Edgar","img":null,"order":5},{"name":"Octavia Spencer","character":"Tanya","img":null,"order":6},{"name":"Ewen Bremner","character":"Andrew","img":null,"order":7},{"name":"Ko Asung","character":"Yona","img":null,"order":8},{"name":"Alison Pill","character":"Teacher","img":null,"order":9},{"name":"Luke Pasqualino","character":"Grey","img":null,"order":10},{"name":"Vlad Ivanov","character":"Franco The Elder","img":null,"order":11},{"name":"Adnan Haskovi\u0107","character":"Franco The Younger","img":null,"order":12},{"name":"Emma Levie","character":"Claude","img":null,"order":13},{"name":"Steve Park","character":"Fuyu","img":null,"order":14}],"movie:969681":[{"name":"Tom Holland","character":"Peter Parker / Spider-Man","img":"xKBAaPIa1c7tzZD3Y0MhBLv4hPE.jpg","order":0},{"name":"Sadie Sink","character":"Jean Grey","img":null,"order":1},{"name":"Tramell Tillman","character":"William 'Bill' Metzger","img":null,"order":2},{"name":"Zendaya","character":"MJ","img":null,"order":3},{"name":"Jacob Batalon","character":"Ned Leeds","img":null,"order":4},{"name":"Jon Bernthal","character":"Frank Castle / Punisher","img":null,"order":5},{"name":"Mark Ruffalo","character":"Bruce Banner / Hulk","img":null,"order":6},{"name":"Florence Pugh","character":"Yelena Belova / Black Widow","img":null,"order":7},{"name":"Liza Col\u00f3n-Zayas","character":"Detective Jean DeWolff","img":null,"order":8},{"name":"Marisa Tomei","character":"May Parker","img":null,"order":9},{"name":"Naomi Watts","character":"E.V. (voice)","img":null,"order":10},{"name":"Michael Mando","character":"Mac Gargan / Scorpion","img":null,"order":11},{"name":"Keith David","character":"Narrator of Spider Video (voice)","img":null,"order":12},{"name":"Marvin Jones III","character":"Tombstone","img":null,"order":13},{"name":"Olivia Booth-Ford","character":"Sara","img":null,"order":14}],"movie:429617":[{"name":"Tom Holland","character":"Peter Parker / Spider-Man","img":"xKBAaPIa1c7tzZD3Y0MhBLv4hPE.jpg","order":0},{"name":"Jake Gyllenhaal","character":"Quentin Beck / Mysterio","img":null,"order":1},{"name":"Samuel L. Jackson","character":"Nick Fury","img":null,"order":2},{"name":"Marisa Tomei","character":"May Parker","img":null,"order":3},{"name":"Jon Favreau","character":"Happy Hogan","img":null,"order":4},{"name":"Zendaya","character":"MJ","img":null,"order":5},{"name":"Jacob Batalon","character":"Ned Leeds","img":null,"order":6},{"name":"Tony Revolori","character":"Flash Thompson","img":null,"order":7},{"name":"Angourie Rice","character":"Betty Brant","img":null,"order":8},{"name":"Remy Hii","character":"Brad Davis","img":null,"order":9},{"name":"Martin Starr","character":"Mr. Harrington","img":null,"order":10},{"name":"JB Smoove","character":"Mr. Dell","img":null,"order":11},{"name":"Jorge Lendeborg Jr.","character":"Jason Ionello","img":null,"order":12},{"name":"Cobie Smulders","character":"Maria Hill","img":null,"order":13},{"name":"Numan Acar","character":"Dimitri","img":null,"order":14}],"movie:315635":[{"name":"Tom Holland","character":"Peter Parker / Spider-Man","img":"xKBAaPIa1c7tzZD3Y0MhBLv4hPE.jpg","order":0},{"name":"Michael Keaton","character":"Adrian Toomes / Vulture","img":null,"order":1},{"name":"Robert Downey Jr.","character":"Tony Stark / Iron Man","img":null,"order":2},{"name":"Marisa Tomei","character":"May Parker","img":null,"order":3},{"name":"Jon Favreau","character":"Happy Hogan","img":null,"order":4},{"name":"Gwyneth Paltrow","character":"Pepper Potts","img":null,"order":5},{"name":"Zendaya","character":"Michelle","img":null,"order":6},{"name":"Donald Glover","character":"Aaron Davis","img":null,"order":7},{"name":"Jacob Batalon","character":"Ned","img":null,"order":8},{"name":"Laura Harrier","character":"Liz","img":null,"order":9},{"name":"Tony Revolori","character":"Flash","img":null,"order":10},{"name":"Bokeem Woodbine","character":"Herman Schultz / Shocker #2","img":null,"order":11},{"name":"Tyne Daly","character":"Anne Marie Hoag","img":null,"order":12},{"name":"Abraham Attah","character":"Abraham","img":null,"order":13},{"name":"Hannibal Buress","character":"Coach Wilson","img":null,"order":14}],"movie:634649":[{"name":"Tom Holland","character":"Peter Parker / Spider-Man","img":"xKBAaPIa1c7tzZD3Y0MhBLv4hPE.jpg","order":0},{"name":"Zendaya","character":"MJ","img":null,"order":1},{"name":"Benedict Cumberbatch","character":"Doctor Strange","img":null,"order":2},{"name":"Jacob Batalon","character":"Ned Leeds","img":null,"order":3},{"name":"Jon Favreau","character":"Happy Hogan","img":null,"order":4},{"name":"Jamie Foxx","character":"Max Dillon / Electro","img":null,"order":5},{"name":"Willem Dafoe","character":"Norman Osborn / Green Goblin","img":null,"order":6},{"name":"Alfred Molina","character":"Dr. Otto Octavius / Doc Ock","img":null,"order":7},{"name":"Benedict Wong","character":"Wong","img":null,"order":8},{"name":"Tony Revolori","character":"Flash Thompson","img":null,"order":9},{"name":"Marisa Tomei","character":"May Parker","img":null,"order":10},{"name":"Andrew Garfield","character":"Peter Parker / Spider-Man","img":null,"order":11},{"name":"Tobey Maguire","character":"Peter Parker / Spider-Man","img":null,"order":12},{"name":"Angourie Rice","character":"Betty Brant","img":null,"order":13},{"name":"Arian Moayed","character":"Agent Cleary","img":null,"order":14}],"movie:129":[{"name":"Rumi Hiiragi","character":"Chihiro (voice)","img":null,"order":0},{"name":"Miyu Irino","character":"Haku (voice)","img":null,"order":1},{"name":"Mari Natsuki","character":"Yubaba / Zeniba (voice)","img":null,"order":2},{"name":"Takashi Naito","character":"Father (voice)","img":null,"order":3},{"name":"Yasuko Sawaguchi","character":"Mother (voice)","img":null,"order":4},{"name":"Tatsuya Gashuin","character":"Aogaeru (voice)","img":null,"order":5},{"name":"Ryunosuke Kamiki","character":"Boh (voice)","img":null,"order":6},{"name":"Yumi Tamai","character":"Rin (voice)","img":null,"order":7},{"name":"Yo Oizumi","character":"Bandai Frog (voice)","img":null,"order":8},{"name":"Koba Hayashi","character":"River Spirit (voice)","img":null,"order":9},{"name":"Tsunehiko Kamij\u00f4","character":"Chichiyaku (voice)","img":null,"order":10},{"name":"Takehiko Ono","character":"Aniyaku (voice)","img":null,"order":11},{"name":"Bunta Sugawara","character":"Kamaji (voice)","img":null,"order":12},{"name":"Shigeru Wakita","character":"(voice)","img":null,"order":13},{"name":"Shirou Saitou","character":"(voice)","img":null,"order":14}],"movie:933260":[{"name":"Demi Moore","character":"Elisabeth","img":null,"order":0},{"name":"Margaret Qualley","character":"Sue","img":null,"order":1},{"name":"Dennis Quaid","character":"Harvey","img":null,"order":2},{"name":"Edward Hamilton-Clark","character":"Fred","img":null,"order":3},{"name":"Gore Abrams","character":"Oliver","img":null,"order":4},{"name":"Oscar Lesage","character":"Troy","img":null,"order":5},{"name":"Christian Erickson","character":"Man at Diner","img":null,"order":6},{"name":"Robin Greer","character":"Male Nurse","img":null,"order":7},{"name":"Tom Morton","character":"Doctor","img":null,"order":8},{"name":"Hugo Diego Garcia","character":"Diego - Boyfriend","img":null,"order":9},{"name":"Daniel Knight","character":"Casting Director","img":null,"order":10},{"name":"Jonathon Carley","character":"Assistant Casting Director","img":null,"order":11},{"name":"Jiselle Henderkott","character":"Girl Auditioning / New Year's Eve Show Dancer","img":null,"order":12},{"name":"Akil Wingate","character":"TV Host","img":null,"order":13},{"name":"Vincent Colombe","character":"Man in Suit #1 - Harvey's Office","img":null,"order":14}],"movie:149871":[{"name":"Aki Asakura","character":"The Princess Kaguya (voice)","img":null,"order":0},{"name":"Takeo Chii","character":"Sanuki no Miyatsuko (voice)","img":null,"order":1},{"name":"Nobuko Miyamoto","character":"\u014cna / Narrator (voice)","img":null,"order":2},{"name":"Kengo Kora","character":"Sutemaru (voice)","img":null,"order":3},{"name":"Atsuko Takahata","character":"Lady Sagami (voice)","img":null,"order":4},{"name":"Tomoko Tabata","character":"Menowarawa (voice)","img":null,"order":5},{"name":"Shinosuke Tatekawa","character":"Lord Inbe no Akita (voice)","img":null,"order":6},{"name":"Takaya Kamikawa","character":"Prince Ishitsukuri (voice)","img":null,"order":7},{"name":"Hikaru Ij\u016bin","character":"Minister of the Right Abe (voice)","img":null,"order":8},{"name":"Ryudo Uzaki","character":"Grand Counselor Otomo (voice)","img":null,"order":9},{"name":"Shichinosuke Nakamura","character":"The Emperor (voice)","img":null,"order":10},{"name":"Isao Hashizume","character":"Prince Kuramochi (voice)","img":null,"order":11},{"name":"Tatsuya Nakadai","character":"Charcoal-maker Old Man (voice)","img":null,"order":12},{"name":"Yukiji Asaoka","character":"Kita no kata (voice)","img":null,"order":13},{"name":"Tamaki Kojo","character":"Middle Counselor Isonokami (voice)","img":null,"order":14}],"movie:103":[{"name":"Robert De Niro","character":"Travis Bickle","img":null,"order":0},{"name":"Jodie Foster","character":"Iris","img":null,"order":1},{"name":"Cybill Shepherd","character":"Betsy","img":null,"order":2},{"name":"Harvey Keitel","character":"Sport","img":null,"order":3},{"name":"Peter Boyle","character":"Wizard","img":null,"order":4},{"name":"Leonard Harris","character":"Charles Palantine","img":null,"order":5},{"name":"Albert Brooks","character":"Tom","img":null,"order":6},{"name":"Diahnne Abbott","character":"Concession Girl","img":null,"order":7},{"name":"Frank Adu","character":"Angry Black Man","img":null,"order":8},{"name":"Victor Argo","character":"Melio","img":null,"order":9},{"name":"Gino Ardito","character":"Policeman at Rally","img":null,"order":10},{"name":"Garth Avery","character":"Iris' Friend","img":null,"order":11},{"name":"Harry Cohn","character":"Cabbie in Bellmore","img":null,"order":12},{"name":"Cooper Cunningham","character":"Hooker in Cab","img":null,"order":13},{"name":"Brenda Dickson","character":"Soap Opera Woman","img":null,"order":14}],"movie:497828":[{"name":"Harris Dickinson","character":"Carl","img":null,"order":0},{"name":"Charlbi Dean","character":"Yaya","img":null,"order":1},{"name":"Dolly de Leon","character":"Abigail","img":null,"order":2},{"name":"Woody Harrelson","character":"The Captain","img":null,"order":3},{"name":"Zlatko Buri\u0107","character":"Dimitry","img":null,"order":4},{"name":"Vicki Berlin","character":"Paula","img":null,"order":5},{"name":"Henrik Dorsin","character":"Jarmo","img":null,"order":6},{"name":"Iris Berben","character":"Therese","img":null,"order":7},{"name":"Jean-Christophe Folly","character":"Nelson","img":null,"order":8},{"name":"Amanda Walker","character":"Clementine","img":null,"order":9},{"name":"Oliver Ford Davies","character":"Winston","img":null,"order":10},{"name":"Sunnyi Melles","character":"Vera","img":null,"order":11},{"name":"Thobias Thorwid","character":"Lewis","img":null,"order":12},{"name":"Jiannis Moustos","character":"Driver","img":null,"order":13},{"name":"Timoleon Gketsos","character":"Handsome Crewman","img":null,"order":14}],"movie:868":[{"name":"Presley Chweneyagae","character":"Tsotsi","img":null,"order":0},{"name":"Jerry Mofokeng","character":"Morris","img":null,"order":1},{"name":"Terry Pheto","character":"Miriam","img":null,"order":2},{"name":"Zenzo Ngqobe","character":"Butcher","img":null,"order":3},{"name":"Zola","character":"Fela","img":null,"order":4},{"name":"Rapulana Seiphemo","character":"John Dube","img":null,"order":5},{"name":"Nambitha Mpumlwana","character":"Pumla Dube","img":null,"order":6},{"name":"Percy Matsemela","character":"Sergeant Zuma","img":null,"order":7},{"name":"Thembi Nyandeni","character":"Soekie","img":null,"order":8},{"name":"Owen Sejake","character":"Gumboot Dlamini","img":null,"order":9},{"name":"Israel Makoe","character":"Tsotsi's father","img":null,"order":10},{"name":"Sindi Khambule","character":"Tsotsi's Mother","img":null,"order":11},{"name":"Benny Moshe","character":"Young Tsotsi","img":null,"order":12},{"name":"Mothusi Magano","character":"Boston","img":null,"order":13},{"name":"Kenneth Nkosi","character":"Aap","img":null,"order":14}],"movie:1517772":[{"name":"Lauryn Licari","character":"Self","img":null,"order":0},{"name":"Owen McKenny","character":"Self","img":null,"order":1},{"name":"Sophie Weber","character":"Self","img":null,"order":2},{"name":"Macy Johnston","character":"Self","img":null,"order":3},{"name":"Shawn Licari","character":"Self","img":null,"order":4},{"name":"Kendra Licari","character":"Self","img":null,"order":5},{"name":"Dave McKenny","character":"Self","img":null,"order":6},{"name":"Jill McKenny","character":"Self","img":null,"order":7},{"name":"Bill Chillman","character":"Self - The Superintendent","img":null,"order":8},{"name":"Dan Boyer","character":"Self - Principal","img":null,"order":9},{"name":"Khloe Wilson","character":"Self","img":null,"order":10},{"name":"Craig Wilson","character":"Self","img":null,"order":11},{"name":"Tami Wilson","character":"Self","img":null,"order":12},{"name":"Korin Weber","character":"Self","img":null,"order":13},{"name":"Bradley Peter","character":"Self - FBI Liason","img":null,"order":14}],"movie:977942":[{"name":"Andrew Garfield","character":"Ploughman","img":null,"order":0},{"name":"Jamie Bell","character":"John Ball","img":null,"order":1},{"name":"Stephen Dillane","character":"Archbishop Sudbury","img":null,"order":2},{"name":"Woody Norman","character":"King Richard II","img":null,"order":3},{"name":"Tom Hollander","character":"Treasurer Hales","img":null,"order":4},{"name":"Cosmo Jarvis","character":"Wat Tyler","img":null,"order":5},{"name":"Thomasin McKenzie","character":"Alyce","img":null,"order":6},{"name":"Jonny Lee Miller","character":"Mayor Walworth","img":null,"order":7},{"name":"Katherine Waterston","character":"Countess","img":null,"order":8},{"name":"Stanley Townsend","character":"Chief Justice Bealknap","img":null,"order":9},{"name":"Sky Yang","character":"Scribe","img":null,"order":10},{"name":"D\u00f3nal Finn","character":"Village Priest","img":null,"order":11},{"name":"Gerald Tyler","character":"Lord Beauchamp","img":null,"order":12},{"name":"Simon Kunz","character":"Sir John Newton","img":null,"order":13},{"name":"Mark Redhead","character":"Lord Peterborough","img":null,"order":14}],"movie:429197":[{"name":"Christian Bale","character":"Dick Cheney","img":null,"order":0},{"name":"Amy Adams","character":"Lynne Cheney","img":null,"order":1},{"name":"Steve Carell","character":"Donald Rumsfeld","img":null,"order":2},{"name":"Sam Rockwell","character":"George W. Bush","img":null,"order":3},{"name":"Alison Pill","character":"Mary Cheney","img":null,"order":4},{"name":"Eddie Marsan","character":"Paul Wolfowitz","img":null,"order":5},{"name":"Justin Kirk","character":"Scooter Libby","img":null,"order":6},{"name":"LisaGay Hamilton","character":"Condoleezza Rice","img":null,"order":7},{"name":"Jesse Plemons","character":"Kurt","img":null,"order":8},{"name":"Bill Camp","character":"Gerald Ford","img":null,"order":9},{"name":"Don McManus","character":"David Addington","img":null,"order":10},{"name":"Lily Rabe","character":"Liz Cheney","img":null,"order":11},{"name":"Shea Whigham","character":"Wayne Vincent","img":null,"order":12},{"name":"Stephen Adly Guirgis","character":"George Tenet","img":null,"order":13},{"name":"Tyler Perry","character":"Colin Powell","img":null,"order":14}],"movie:81":[{"name":"Sumi Shimamoto","character":"Nausica\u00e4 (voice)","img":null,"order":0},{"name":"Ichiro Nagai","character":"Mito (voice)","img":null,"order":1},{"name":"Gor\u014d Naya","character":"Yupa (voice)","img":null,"order":2},{"name":"Yoji Matsuda","character":"Asbel (voice)","img":null,"order":3},{"name":"Yoshiko Sakakibara","character":"Kushana (voice)","img":null,"order":4},{"name":"Iemasa Kayumi","character":"Kurotowa (voice)","img":null,"order":5},{"name":"Hisako Kyoda","character":"Obaba (voice)","img":null,"order":6},{"name":"Mahito Tsujimura","character":"Jihl (voice)","img":null,"order":7},{"name":"Mina Tominaga","character":"Lastel (voice)","img":null,"order":8},{"name":"Kohei Miyauchi","character":"Gol (voice)","img":null,"order":9},{"name":"Joji Yanami","character":"Gikkuri (voice)","img":null,"order":10},{"name":"Minoru Yada","character":"Niga (voice)","img":null,"order":11},{"name":"Rihoko Yoshida","character":"Teto / Girl C (voice)","img":null,"order":12},{"name":"Tetsuo Mizutori","character":"Commando (voice)","img":null,"order":13},{"name":"Masako Sugaya","character":"Girl A (voice)","img":null,"order":14}],"movie:1198984":[{"name":"Daisy Ridley","character":"Ava","img":null,"order":0},{"name":"Brenton Thwaites","character":"Clay","img":null,"order":1},{"name":"Mark Coles Smith","character":"Riley","img":null,"order":2},{"name":"Matt Whelan","character":"Mitch","img":null,"order":3},{"name":"Chloe Hurst","character":"Katie Harris","img":null,"order":4},{"name":"Kym Jackson","character":"Lt. Wilkie","img":null,"order":5},{"name":"Holly Hargreaves","character":"Mrs. Smith","img":null,"order":6},{"name":"Deanna Cooney","character":"Bianca","img":null,"order":7},{"name":"Elijah Williams","character":"Greg","img":null,"order":8},{"name":"Salme Geransar","character":"Private Clarkson","img":null,"order":9},{"name":"Luke Jai McIntosh","character":"Cadet","img":null,"order":10},{"name":"Joel Jackson","character":"Anxious Bus Volunteer","img":null,"order":11},{"name":"Dan Paris","character":"Captain Vance","img":null,"order":12},{"name":"Nicola Bartlett","character":"Woman on Plane","img":null,"order":13},{"name":"Kim Fleming","character":"Briefing Colonel","img":null,"order":14}],"movie:953371":[{"name":"Benjamin O'Keefe","character":"Self - Activist & Public Speaker","img":null,"order":0},{"name":"Bobby Blanski","character":"Self - Former A&F Model","img":null,"order":1},{"name":"Ryan Daharsh","character":"Self - Former A&F Model","img":null,"order":2},{"name":"Jennifer Sheahan","character":"Self - Former Store Employee","img":null,"order":3},{"name":"Dr. Anthony Ocampo","character":"Self - Former Store Employee","img":null,"order":4},{"name":"Sapna Maheshwari","character":"Self - Business Reporter, NY Times","img":null,"order":5},{"name":"Alan Karo","character":"Self - Fashion Marketing & Advertising Executive","img":null,"order":6},{"name":"Treva Lindsey","character":"Self - Professor of History, Ohio State University","img":null,"order":7},{"name":"Carla Barrientos","character":"Self - Former Store Employee","img":null,"order":8},{"name":"Robin Givhan","character":"Self - Senior Critic-at-Large, Washington Post","img":null,"order":9},{"name":"Jose Sanchez","character":"Self - Former A&F Recruiter","img":null,"order":10},{"name":"Moe Tkacik","character":"Self - Journalist","img":null,"order":11},{"name":"Mike Jeffries","character":"Self - Former A&F CEO (archive footage)","img":null,"order":12},{"name":"Charles Martin","character":"Self - Former A&F Design VP","img":null,"order":13},{"name":"Cindy Smith-Maglione","character":"Self - Former A&F VP of Merchandising","img":null,"order":14}],"movie:1184918":[{"name":"Lupita Nyong'o","character":"Roz / Rummage (voice)","img":null,"order":0},{"name":"Pedro Pascal","character":"Fink (voice)","img":null,"order":1},{"name":"Kit Connor","character":"Brightbill (voice)","img":null,"order":2},{"name":"Bill Nighy","character":"Longneck (voice)","img":null,"order":3},{"name":"Stephanie Hsu","character":"Vontra (voice)","img":null,"order":4},{"name":"Matt Berry","character":"Paddler (voice)","img":null,"order":5},{"name":"Ving Rhames","character":"Thunderbolt (voice)","img":null,"order":6},{"name":"Mark Hamill","character":"Thorn (voice)","img":null,"order":7},{"name":"Catherine O'Hara","character":"Pinktail (voice)","img":null,"order":8},{"name":"Boone Storm","character":"Baby Brightbill (voice)","img":null,"order":9},{"name":"Alexandra Novelle","character":"Snowdown (voice)","img":null,"order":10},{"name":"Raphael Alejandro","character":"Peck (voice)","img":null,"order":11},{"name":"Paul-Mik\u00e9l Williams","character":"Feather (voice)","img":null,"order":12},{"name":"Eddie Park","character":"Honkington (voice)","img":null,"order":13},{"name":"Dee Bradley Baker","character":"Raccoons / Squirrels / Badgers (voice)","img":null,"order":14}],"movie:149870":[{"name":"Hideaki Anno","character":"Jiro Horikoshi (voice)","img":null,"order":0},{"name":"Hidetoshi Nishijima","character":"Honj\u00f4 (voice)","img":null,"order":1},{"name":"Miori Takimoto","character":"Naoko Satomi (voice)","img":null,"order":2},{"name":"Masahiko Nishimura","character":"Kurokawa (voice)","img":null,"order":3},{"name":"Stephen Alpert","character":"Castorp (voice)","img":null,"order":4},{"name":"Mansai Nomura","character":"Giovanni Battista (voice)","img":null,"order":5},{"name":"Jun Kunimura","character":"Hattori (voice)","img":null,"order":6},{"name":"Mirai Shida","character":"Kayo Horikoshi (voice)","img":null,"order":7},{"name":"Shinobu Otake","character":"Mrs. Kurokawa (voice)","img":null,"order":8},{"name":"Morio Kazama","character":"Satomi (voice)","img":null,"order":9},{"name":"Keiko Takeshita","character":"Jir\u00f4's mother (voice)","img":null,"order":10},{"name":"Sascha","character":"German Security Guard / Flight Engineer (voice)","img":null,"order":11},{"name":"Kaichi Kaburagi","character":"Young Jiro Horikoshi (voice)","img":null,"order":12},{"name":"Maki Shinta","character":"Young Kayo Horikoshi (voice)","img":null,"order":13},{"name":"Berndt Otto","character":"(voice)","img":null,"order":14}],"movie:666243":[{"name":"Theo James","character":"Vesemir (voice)","img":null,"order":0},{"name":"Mary McDonnell","character":"Lady Zerbst (voice)","img":null,"order":1},{"name":"Lara Pulver","character":"Tetra Gilcrest (voice)","img":null,"order":2},{"name":"Graham McTavish","character":"Deglan (voice)","img":null,"order":3},{"name":"Tom Canton","character":"Filavandrel (voice)","img":null,"order":4},{"name":"David Errigo Jr.","character":"Young Vesemir / Young Remus (voice)","img":null,"order":5},{"name":"Jennifer Hale","character":"Illyana / Noblewoman (voice)","img":null,"order":6},{"name":"Kari Wahlgren","character":"Kitsu / Boy (voice)","img":null,"order":7},{"name":"Matthew Yang King","character":"Luka / Skogar (voice)","img":null,"order":8},{"name":"Darryl Kurylo","character":"Sven / Nobleman (voice)","img":null,"order":9},{"name":"Keith Ferguson","character":"Lord Carlisle / Reidrich (voice)","img":null,"order":10},{"name":"Jennie Kwan","character":"Young Luka (voice)","img":null,"order":11},{"name":"AJ LoCascio","character":"Young Sven (voice)","img":null,"order":12},{"name":"Michaela Dietz","character":"Tomas (voice)","img":null,"order":13},{"name":"Harry Hissrich","character":"Young Boy (Geralt) (voice)","img":null,"order":14}],"movie:1203329":[{"name":"Doug Cockle","character":"Geralt (voice)","img":null,"order":0},{"name":"Joey Batey","character":"Jaskier / Young Jaskier (voice)","img":null,"order":1},{"name":"Christina Wren","character":"Essi (voice)","img":null,"order":2},{"name":"Emily Carey","character":"Sh'eenaz (voice)","img":null,"order":3},{"name":"Camrus Johnson","character":"Agloval (voice)","img":null,"order":4},{"name":"Simon Templeman","character":"King Usveldt (voice)","img":null,"order":5},{"name":"Mallory Jansen","character":"Melusina / Princess Nispen (voice)","img":null,"order":6},{"name":"Anya Chalotra","character":"Yennefer (voice)","img":null,"order":7},{"name":"Ray Chase","character":"Zelest (voice)","img":null,"order":8},{"name":"Cynthia Kaye McWilliams","character":"Queen Dahut (voice)","img":null,"order":9},{"name":"Ramon Tikaram","character":"King Basim (voice)","img":null,"order":10},{"name":"Kari Wahlgren","character":"Zmarra / Vodnik Assassin (voice)","img":null,"order":11},{"name":"Stephen Fu","character":"Deroua (voice)","img":null,"order":12},{"name":"George Ackles","character":"Drouhard (voice)","img":null,"order":13},{"name":"Brian George","character":"Barkeep / Herald (voice)","img":null,"order":14}],"tv:260458":[{"name":"Malik Elassal","character":"Samir Rahman","img":null,"order":0},{"name":"Lucy Freyer","character":"Billie Schaeffer","img":null,"order":1},{"name":"Jack Innanen","character":"Paul Baker","img":null,"order":2},{"name":"Amita Rao","character":"Issa Damani","img":null,"order":3},{"name":"Owen Thiele","character":"Anton Evans","img":null,"order":4},{"name":"Julia Fox","character":"Julia Fox","img":null,"order":500},{"name":"Rachel Marsh","character":"Carly","img":null,"order":502},{"name":"Charlie Cox","character":"Mr. Teacher","img":null,"order":521},{"name":"Julian Manjerico","character":"Zack-Carlos","img":null,"order":576},{"name":"Martha Girvin","character":"Serena","img":null,"order":582},{"name":"Andrea Pavlovic","character":"Lily","img":null,"order":585},{"name":"Meghan Swaby","character":"Mary","img":null,"order":587},{"name":"Liam Cullagh","character":"OJ","img":null,"order":594},{"name":"Will Sennett","character":"Roach","img":null,"order":595},{"name":"Joey Dardano","character":"Schnee","img":null,"order":596}],"tv:64513":[{"name":"Sterling K. Brown","character":"Christopher Darden","img":null,"order":0},{"name":"Kenneth Choi","character":"Lance Ito","img":null,"order":3},{"name":"Beanie Feldstein","character":"Monica Lewinsky","img":null,"order":5},{"name":"Christian Clemenson","character":"Bill Hodgman","img":null,"order":7},{"name":"Sarah Paulson","character":"Linda Tripp","img":null,"order":9},{"name":"Cuba Gooding Jr.","character":"O. J. Simpson","img":null,"order":9},{"name":"Margo Martindale","character":"Lucianne Goldberg","img":null,"order":11},{"name":"Bruce Greenwood","character":"Gil Garcetti","img":null,"order":12},{"name":"Edie Falco","character":"Hillary Clinton","img":null,"order":13},{"name":"Nathan Lane","character":"F. Lee Bailey","img":null,"order":14},{"name":"Clive Owen","character":"Bill Clinton","img":null,"order":15},{"name":"David Schwimmer","character":"Robert Kardashian","img":null,"order":18},{"name":"John Travolta","character":"Robert Shapiro","img":null,"order":19},{"name":"Courtney B. Vance","character":"Johnnie Cochran","img":null,"order":20},{"name":"Annaleigh Ashford","character":"Elizabeth Cote","img":null,"order":398}],"tv:215866":[{"name":"Taylor Kitsch","character":"Isaac Reed","img":null,"order":0},{"name":"Betty Gilpin","character":"Sara Rowell","img":null,"order":1},{"name":"Dane DeHaan","character":"Jacob Pratt","img":null,"order":2},{"name":"Saura Lightfoot-Leon","character":"Abish Pratt","img":null,"order":3},{"name":"Derek Hinkey","character":"Red Feather","img":null,"order":4},{"name":"Joe Tippett","character":"James Wolsey","img":null,"order":5},{"name":"Jai Courtney","character":"Virgil Cutter","img":null,"order":6},{"name":"Preston Mota","character":"Devin Rowell","img":null,"order":7},{"name":"Shawnee Pourier","character":"Two Moons","img":null,"order":8},{"name":"Shea Whigham","character":"Jim Bridger","img":null,"order":9},{"name":"Kyle Davis","character":"Tilly","img":null,"order":500},{"name":"Tokala Black Elk","character":"Buffalo Run","img":null,"order":501},{"name":"Nick Hargrove","character":"Cottrell","img":null,"order":502},{"name":"Alex Fine","character":"Gant","img":null,"order":504},{"name":"Andrew P. Logan","character":"Lucas","img":null,"order":506}],"tv:4589":[{"name":"Jason Bateman","character":"Michael Bluth","img":null,"order":0},{"name":"Portia de Rossi","character":"Lindsay Bluth F\u00fcnke","img":null,"order":1},{"name":"Will Arnett","character":"Gob Bluth","img":null,"order":2},{"name":"Michael Cera","character":"George Michael Bluth","img":null,"order":3},{"name":"Alia Shawkat","character":"Maeby F\u00fcnke","img":null,"order":4},{"name":"Tony Hale","character":"Byron 'Buster' Bluth","img":null,"order":5},{"name":"David Cross","character":"Tobias F\u00fcnke","img":null,"order":6},{"name":"Jeffrey Tambor","character":"George Bluth Sr.","img":null,"order":7},{"name":"Jessica Walter","character":"Lucille Bluth","img":null,"order":8},{"name":"Ron Howard","character":"Narrator","img":null,"order":9},{"name":"Justin Grant Wade","character":"Steve Holt","img":null,"order":508},{"name":"Liza Minnelli","character":"Lucille Austero","img":null,"order":520},{"name":"Mae Whitman","character":"Ann Veal","img":null,"order":533},{"name":"John Beard","character":"John Beard","img":null,"order":609},{"name":"Henry Winkler","character":"Barry Zuckerkorn","img":null,"order":635}],"tv:246":[{"name":"Zach Tyler Eisen","character":"Aang (voice)","img":null,"order":0},{"name":"Mae Whitman","character":"Katara (voice)","img":null,"order":1},{"name":"Jack De Sena","character":"Sokka (voice)","img":null,"order":2},{"name":"Dante Basco","character":"Zuko (voice)","img":null,"order":3},{"name":"Mako","character":"Iroh (voice)","img":null,"order":4},{"name":"Dee Bradley Baker","character":"Appa / Momo (voice)","img":null,"order":7},{"name":"Cricket Leigh","character":"Mai (voice)","img":null,"order":9},{"name":"Olivia Hack","character":"Ty Lee (voice)","img":null,"order":10},{"name":"Michaela Jill Murphy","character":"Toph Beifong (voice)","img":null,"order":173},{"name":"Andr\u00e9 Sogliuzzo","character":"Captain (voice)","img":null,"order":378},{"name":"Grey DeLisle","character":"Azula / Additional Voices (voice)","img":null,"order":491},{"name":"Greg Baldwin","character":"Iroh / Combustion Man (voice)","img":null,"order":545},{"name":"Mark Hamill","character":"Ozai (voice)","img":null,"order":581},{"name":"Jennie Kwan","character":"Suki (voice)","img":null,"order":624},{"name":"Jim Meskimen","character":"Avatar Kuruk (voice)","img":null,"order":657}],"tv:124428":[{"name":"Jeroen Kijk in de Vegte","character":"Voice-over","img":null,"order":0},{"name":"Martijn Bolhoeve","character":"Self - Owner of a B&B in Hua Hin, Thailand","img":null,"order":2},{"name":"Joy van Swieten","character":"Self - Owner of a B&B in Malaga, Spain","img":null,"order":3},{"name":"Marian Trott","character":"Self - Owner of a B&B in Budens, Portugal","img":null,"order":4},{"name":"Bram Eijgenhuijsen","character":"Self - Owner of a B&B in Norrhult, Sweden","img":null,"order":5},{"name":"Debbie de Jong","character":"Self - Owner of a B&B in Sant Andreu del Terri, Spain","img":null,"order":6},{"name":"Leendert Wijland","character":"Self - Owner of a B&B in La Roche-En-Ardenne, Belgium","img":null,"order":7},{"name":"Petri Damen","character":"Self - Owner of a B&B in Monclar, France","img":null,"order":8},{"name":"Walter Spangenberg","character":"Self - Owner of a B&B in Troche, France","img":null,"order":9},{"name":"Iris Villas","character":"Self - Owner of a B&B in Sparto, Greece","img":null,"order":13},{"name":"Robert Jan van Rheenen","character":"Self - Owner of a B&B in Dornoch, Scotland","img":null,"order":14},{"name":"Arno van Wilpe","character":"Self - Owner of a B&B in Payzac, France","img":null,"order":15},{"name":"Mike Verkoelen","character":"Self - Owner of a B&B in Ma\u00e7anet de la Selva, Spain","img":null,"order":16},{"name":"Paul Visser","character":"Self - Partner of Debbie de Jong","img":null,"order":48},{"name":"Dani Zijlstra","character":"Self - Partner of Joy van Swieten","img":null,"order":49}],"tv:136315":[{"name":"Jeremy Allen White","character":"Carmen 'Carmy' Berzatto","img":null,"order":0},{"name":"Ebon Moss-Bachrach","character":"Richard 'Richie' Jerimovich","img":null,"order":1},{"name":"Ayo Edebiri","character":"Sydney Adamu","img":null,"order":2},{"name":"Lionel Boyce","character":"Marcus Brooks","img":null,"order":3},{"name":"Abby Elliott","character":"Natalie 'Sugar' Berzatto","img":null,"order":4},{"name":"Matty Matheson","character":"Neil Fak","img":null,"order":5},{"name":"Liza Col\u00f3n-Zayas","character":"Bettina 'Tina' Marrero","img":null,"order":6},{"name":"Edwin Lee Gibson","character":"Ebraheim","img":null,"order":8},{"name":"Oliver Platt","character":"Uncle Jimmy 'Cicero' Kalinowski","img":null,"order":500},{"name":"Christopher Zucchero","character":"Chi-Chi","img":null,"order":505},{"name":"Chris Witaske","character":"Pete Katinsky","img":null,"order":513},{"name":"Corey Hendrix","character":"Gary 'Sweeps' Woods","img":null,"order":536},{"name":"Jose M. Cervantes","character":"Angel","img":null,"order":537},{"name":"Richard Esteras","character":"Manny","img":null,"order":538},{"name":"Ricky Staffieri","character":"Theodore Fak","img":null,"order":548}],"tv:74313":[{"name":"David Attenborough","character":"Self - Presenter","img":null,"order":0}],"tv:93290":[{"name":"Martin Freeman","character":"Paul Worsley","img":null,"order":0},{"name":"Daisy Haggard","character":"Ally Grant","img":null,"order":1},{"name":"Eve Prenelle","character":"Ava Worsley","img":null,"order":4},{"name":"Alex Eastwood","character":"Luke Worsley","img":null,"order":5},{"name":"Oscar Kennedy","character":"Luke Worsley","img":null,"order":6},{"name":"Zo\u00eb Athena","character":"Ava Worsley","img":null,"order":7},{"name":"George Wakeman","character":"Luke Worsley","img":null,"order":345},{"name":"Jayda Eyles","character":"Young Ava","img":null,"order":346},{"name":"Tim Steed","character":"Carl","img":null,"order":501},{"name":"Patrick Baladi","character":"Darren","img":null,"order":504},{"name":"Alun Armstrong","character":"Jim","img":null,"order":514},{"name":"Joanna Bacon","character":"Jackie","img":null,"order":515},{"name":"Stella Gonet","character":"Leah","img":null,"order":516},{"name":"Hugh Quarshie","character":"Alex","img":null,"order":519},{"name":"Aliyah Sesay","character":"Grace","img":null,"order":520}],"tv:87108":[{"name":"Jared Harris","character":"Valery Legasov","img":null,"order":0},{"name":"Stellan Skarsg\u00e5rd","character":"Boris Shcherbina","img":"mW7xmtGV4y79kQGn0zkKVGDMAmw.jpg","order":1},{"name":"Emily Watson","character":"Ulana Khomyuk","img":null,"order":2},{"name":"Paul Ritter","character":"Anatoly Dyatlov","img":null,"order":3},{"name":"Jessie Buckley","character":"Lyudmilla Ignatenko","img":null,"order":4},{"name":"Adam Nagaitis","character":"Vasily Ignatenko","img":null,"order":5},{"name":"Sam Troughton","character":"Alexandr Akimov","img":null,"order":6},{"name":"Robert Emms","character":"Leonid Toptunov","img":null,"order":7},{"name":"Con O'Neill","character":"Viktor Bryukhanov","img":null,"order":8},{"name":"Adrian Rawlins","character":"Nikolai Fomin","img":null,"order":9},{"name":"Alan Williams","character":"KGB Chairman Charkov","img":null,"order":10},{"name":"David Dencik","character":"Mikhail Gorbachev","img":null,"order":11},{"name":"Mark Lewis Jones","character":"General Pikalov","img":null,"order":12},{"name":"Ralph Ineson","character":"General Tarakanov","img":null,"order":13},{"name":"Barry Keoghan","character":"Pavel","img":null,"order":14}],"tv:18347":[{"name":"Joel McHale","character":"Jeff Winger","img":null,"order":0},{"name":"Gillian Jacobs","character":"Britta Perry","img":null,"order":1},{"name":"Alison Brie","character":"Annie Edison","img":null,"order":2},{"name":"Donald Glover","character":"Troy Barnes","img":null,"order":3},{"name":"Yvette Nicole Brown","character":"Shirley Bennett","img":null,"order":4},{"name":"Jim Rash","character":"Dean Craig Pelton","img":null,"order":5},{"name":"Danny Pudi","character":"Abed Nadir","img":null,"order":6},{"name":"Chevy Chase","character":"Pierce Hawthorne","img":null,"order":7},{"name":"Ken Jeong","character":"Ben Chang","img":null,"order":10},{"name":"John Oliver","character":"Professor Ian Duncan","img":null,"order":154},{"name":"Charley Koontz","character":"Neil","img":null,"order":1003},{"name":"Danielle Kaplowitz","character":"Vicki","img":null,"order":1034},{"name":"Erik Charles Nielsen","character":"Garrett Lambert","img":null,"order":1035},{"name":"Dino Stamatopoulos","character":"Star-Burns","img":null,"order":1046},{"name":"Richard Erdman","character":"Leonard","img":null,"order":1049}],"tv:289517":[{"name":"Lee Jae-wook","character":"Byeon Hyeok-jun","img":null,"order":0},{"name":"Go Min-si","character":"Eum Yeon-joo","img":null,"order":1},{"name":"Kim Min-ha","character":"Byeon Ji-yoon","img":null,"order":2},{"name":"Lee Hee-jun","character":"Head of Spider Staffing Agency","img":null,"order":3},{"name":"Choi Hyun-wook","character":"Choi Hee-dong","img":null,"order":500},{"name":"Yoon Kyung-ho","character":"Jo Jun-seop","img":null,"order":501},{"name":"Cho Hyun-chul","character":"Cinephile","img":null,"order":502},{"name":"Yoon Byung-hee","character":"Theater Manager","img":null,"order":503},{"name":"Seo Jae-hee","character":"Director of Yangcheon Bio Clinic","img":null,"order":504},{"name":"Ko Chang-seok","character":"Foreman","img":null,"order":505},{"name":"Kim Si-eun","character":"Woman on the bridge","img":null,"order":506}],"tv:110695":[{"name":"Michael Keaton","character":"Samuel Finnix","img":null,"order":0},{"name":"Peter Sarsgaard","character":"Rick Mountcastle","img":null,"order":1},{"name":"Michael Stuhlbarg","character":"Richard Sackler","img":null,"order":2},{"name":"Will Poulter","character":"Billy Cutler","img":null,"order":3},{"name":"John Hoogenakker","character":"Randy Ramseyer","img":null,"order":4},{"name":"Kaitlyn Dever","character":"Betsy Mallum","img":null,"order":5},{"name":"Rosario Dawson","character":"Bridget Meyer","img":null,"order":6},{"name":"Will Chase","character":"Michael Friedman","img":null,"order":7},{"name":"Cleopatra Coleman","character":"Grace Pell","img":null,"order":8},{"name":"Parker Sack","character":"Dirk","img":null,"order":9},{"name":"Mare Winningham","character":"Diane Mallum","img":null,"order":504},{"name":"Ian Unterman","character":"Jonathan Sackler","img":null,"order":505},{"name":"Jake McDorman","character":"John Brownlee","img":null,"order":506},{"name":"Phillipa Soo","character":"Amber Collins","img":null,"order":507},{"name":"Brendan Patrick Connor","character":"Howard Udell","img":null,"order":508}],"tv:90228":[{"name":"Emily Watson","character":"Mother Superior Valya Harkonnen","img":null,"order":0},{"name":"Olivia Williams","character":"Reverend Mother Tula Harkonnen","img":null,"order":1},{"name":"Travis Fimmel","character":"Desmond Hart","img":null,"order":2},{"name":"Jodhi May","character":"Empress Natalya Arat Corrino","img":null,"order":3},{"name":"Sarah-Sofie Boussnina","character":"Princess Ynez Corrino","img":null,"order":4},{"name":"Chloe Lea","character":"Sister Lila","img":null,"order":5},{"name":"Chris Mason","character":"Keiran Atreides","img":null,"order":6},{"name":"Shalom Brune-Franklin","character":"Mikaela","img":null,"order":7},{"name":"Jade Anouka","character":"Sister Theodosia","img":null,"order":9},{"name":"Edward Davis","character":"Harrow Harkonnen","img":null,"order":10},{"name":"Josh Heuston","character":"Constantine Corrino","img":null,"order":11},{"name":"Faoileann Cunningham","character":"Sister Jen","img":null,"order":12},{"name":"Aoife Hinds","character":"Sister Emeline","img":null,"order":13},{"name":"Indira Varma","character":"","img":null,"order":14},{"name":"Ashley Walters","character":"","img":null,"order":15}],"tv:258165":[{"name":"Florence Pugh","character":"Cathy Ames","img":null,"order":0},{"name":"Christopher Abbott","character":"Adam Trask","img":null,"order":1},{"name":"Mike Faist","character":"Charles Trask","img":null,"order":2},{"name":"Joseph Zada","character":"Caleb Trask","img":null,"order":253},{"name":"Robert Morgan","character":"Sheriff Quinn","img":null,"order":500},{"name":"Christopher Sommers","character":"Mr. Bacon","img":null,"order":501},{"name":"Brad McMurray","character":"Joe Valery","img":null,"order":502},{"name":"Vaughan Reilly","character":"Adolescent Cathy","img":null,"order":503},{"name":"Hoon Lee","character":"Lee","img":null,"order":505},{"name":"Ciar\u00e1n Hinds","character":"Samuel Hamilton","img":null,"order":506},{"name":"Tandi Wright","character":"Mrs. Garb","img":null,"order":507},{"name":"Anita Hegh","character":"Liza Hamilton","img":null,"order":508},{"name":"Oscar Redding","character":"Rabbit Holman","img":null,"order":509},{"name":"Amelia Reynolds","character":"Ethel","img":null,"order":510},{"name":"Jonah Wren Phillips","character":"Young Aron Trask","img":null,"order":512}],"tv:106379":[{"name":"Ella Purnell","character":"Lucy MacLean","img":null,"order":0},{"name":"Aaron Moten","character":"Maximus","img":null,"order":1},{"name":"Mois\u00e9s Arias","character":"Norm MacLean","img":null,"order":2},{"name":"Frances Turner","character":"Barb Howard","img":null,"order":3},{"name":"Kyle MacLachlan","character":"Overseer Hank MacLean","img":null,"order":4},{"name":"Walton Goggins","character":"The Ghoul / Cooper Howard","img":null,"order":5},{"name":"Leslie Uggams","character":"Betty Pearson","img":null,"order":501},{"name":"Michael Cristofer","character":"Elder Cleric Quintus","img":null,"order":502},{"name":"Johnny Pemberton","character":"Thaddeus","img":null,"order":503},{"name":"Zach Cherry","character":"Woody Thomas","img":null,"order":506},{"name":"Annabel O'Hagan","character":"Stephanie Harper","img":null,"order":507},{"name":"Dave Register","character":"Chet","img":null,"order":508},{"name":"Rodrigo Luzzi","character":"Reg McPhee","img":null,"order":509},{"name":"Leer Leary","character":"Davey","img":null,"order":515},{"name":"Amir Carr","character":"Young Maximus","img":null,"order":527}],"tv:2207":[{"name":"John Cleese","character":"Basil Fawlty","img":null,"order":0},{"name":"Prunella Scales","character":"Sybil Fawlty","img":null,"order":1},{"name":"Connie Booth","character":"Polly Sherman","img":null,"order":2},{"name":"Andrew Sachs","character":"Manuel","img":null,"order":3},{"name":"Ballard Berkeley","character":"Major Gowen","img":null,"order":4},{"name":"Brian Hall","character":"Terry the Chef","img":null,"order":5},{"name":"Gilly Flower","character":"Miss Tibbs","img":null,"order":6},{"name":"Renee Roberts","character":"Miss Gatsby","img":null,"order":7},{"name":"Michael Gwynn","character":"Lord Melbury","img":null,"order":500},{"name":"Diana King","character":"Mrs. Rachel Lloyd","img":null,"order":501},{"name":"David Kelly","character":"O'Reilly","img":null,"order":502},{"name":"Brenda Cowling","character":"Sister","img":null,"order":503},{"name":"Elizabeth Benson","character":"Mrs. Heath","img":null,"order":540},{"name":"Terence Conoley","character":"Mr. Johnston","img":null,"order":548},{"name":"George Lee","character":"Delivery Man","img":null,"order":565}],"tv:290720":[{"name":"Jose Coronado","character":"Basil","img":null,"order":0},{"name":"Mar\u00eda Valverde","character":"Adela Figueora","img":null,"order":1},{"name":"Marti\u00f1o Rivas","character":"Fox\u00e1","img":null,"order":2},{"name":"Maribel Verd\u00fa","character":"Raquel Auslander","img":null,"order":3},{"name":"Gonzalo de Castro","character":"Fonseca","img":null,"order":4},{"name":"Cristina Kovani","character":"Vicky","img":null,"order":5},{"name":"Jos\u00e9 Condessa","character":"Toni","img":null,"order":6},{"name":"Pep\u00f3n Nieto","character":"Seruya","img":null,"order":7},{"name":"Daniel Holgu\u00edn","character":"Gerard","img":null,"order":8},{"name":"Michael Stobbe","character":"Se\u00f1or Klemmer","img":null,"order":9},{"name":"Yaiza Guimar\u00e9","character":"Se\u00f1ora Klemmer","img":null,"order":10},{"name":"Almudena Salort","character":"Catalina","img":null,"order":11},{"name":"Paloma Bloyd","character":"Elisa","img":null,"order":12}],"tv:243316":[{"name":"Tina Fey","character":"Kate","img":null,"order":0},{"name":"Steve Carell","character":"Nick Pagano","img":null,"order":1},{"name":"Colman Domingo","character":"Danny","img":null,"order":2},{"name":"Erika Henningsen","character":"Ginny","img":null,"order":3},{"name":"Kerri Kenney","character":"Anne Pagano","img":null,"order":4},{"name":"Will Forte","character":"Jack","img":null,"order":5},{"name":"Marco Calvani","character":"Claude","img":null,"order":6},{"name":"Julia Lester","character":"Lila","img":null,"order":502},{"name":"Alan Alda","character":"Don","img":null,"order":503},{"name":"Ashlyn Maddox","character":"Beth","img":null,"order":509},{"name":"Eric Elizaga","character":"Desk Clerk","img":null,"order":513},{"name":"Toby Huss","character":"Terry","img":null,"order":519},{"name":"Blake Russell","character":"State Trooper","img":null,"order":528},{"name":"Steven Pasquale","character":"Mark Brett","img":null,"order":531},{"name":"Brielle Pribbernow","character":"Boardwalk Kid","img":null,"order":532}],"tv:65345":[{"name":"Justice Smith","character":"Ezekiel Figuero","img":null,"order":0},{"name":"Shameik Moore","character":"Shaolin Fantastic","img":null,"order":1},{"name":"Herizen F. Guardiola","character":"Mylene Cruz","img":null,"order":2},{"name":"Skylan Brooks","character":"Ra-Ra Kipling","img":null,"order":3},{"name":"Jaden Smith","character":"Marcus 'Dizzee' Kipling","img":null,"order":4},{"name":"Tremaine Brown Jr.","character":"Boo-Boo Kipling","img":null,"order":5},{"name":"Yahya Abdul-Mateen II","character":"Clarence 'Cadillac' Caldwell","img":null,"order":6},{"name":"Jimmy Smits","character":"Francisco 'Papa Fuerte' Cruz","img":null,"order":7},{"name":"Stefan\u00e9e Martin","character":"Yolanda Kipling","img":null,"order":8},{"name":"Shyrley Rodriguez","character":"Regina Diaz","img":null,"order":9},{"name":"Mamoudou Athie","character":"Grandmaster Flash","img":null,"order":10},{"name":"Giancarlo Esposito","character":"Pastor Ramon Cruz","img":null,"order":11},{"name":"Ron Cephas Jones","character":"Winston Kipling","img":null,"order":505},{"name":"RayJonaldy Rodriguez","character":"Silent Carlito","img":null,"order":506},{"name":"Zuri Reed","character":"Zulu Girl Yvonne","img":null,"order":508}],"tv:204304":[{"name":"Michael Pollan","character":"Self","img":null,"order":0},{"name":"Ann Shulgin","character":"Self - Author, Mentor & Guide Therapist","img":null,"order":500},{"name":"Alexander Shulgin","character":"Self - Chemist, Author & Professor (archive footage)","img":null,"order":501},{"name":"Rick Doblin","character":"Self - Founder, MAPS","img":null,"order":502},{"name":"Paul F. Daley","character":"Self","img":null,"order":503}],"tv:96488":[{"name":"Peter Sarsgaard","character":"David Russell","img":null,"order":0},{"name":"Kyle Gallner","character":"Eric Fisher","img":null,"order":1},{"name":"David Strathairn","character":"Henry Fisher","img":null,"order":2},{"name":"Kodi Smit-McPhee","character":"Chris Keller","img":null,"order":3},{"name":"Jersey Johnston","character":"Debbie Russell","img":null,"order":533},{"name":"Frank Whaley","character":"Detective James Connor","img":null,"order":577},{"name":"Ellen Humphreys","character":"Sharon Russell","img":null,"order":578},{"name":"Melinda McGraw","character":"Faith Turner","img":null,"order":579},{"name":"Chad L. Coleman","character":"Mr. Franklin","img":null,"order":604},{"name":"Joanna Going","character":"Mrs. Fisher","img":null,"order":621},{"name":"Ebon Moss-Bachrach","character":"Trey Carano","img":null,"order":622},{"name":"Autry Haydon-Wilson","character":"Young Amy Harlow","img":null,"order":623},{"name":"Vincent D'Onofrio","character":"Sgt. Ian Lynch","img":null,"order":624},{"name":"Andre Royo","character":"Charlie Shannon","img":null,"order":625},{"name":"Barbie Robertson","character":"Debbie Russell","img":null,"order":636}],"tv:2710":[{"name":"Charlie Day","character":"Charlie Kelly","img":null,"order":0},{"name":"Glenn Howerton","character":"Dennis Reynolds","img":null,"order":1},{"name":"Rob Mac","character":"Ronald 'Mac' McDonald","img":null,"order":2},{"name":"Kaitlin Olson","character":"Dee Reynolds","img":null,"order":3},{"name":"Danny DeVito","character":"Frank Reynolds","img":null,"order":4},{"name":"Artemis Pebdani","character":"Artemis","img":null,"order":6},{"name":"Mary Elizabeth Ellis","character":"Waitress","img":null,"order":7},{"name":"David Hornsby","character":"Matthew 'Rickety Cricket' Mara","img":null,"order":8},{"name":"Lynne Marie Stewart","character":"Charlie's Mom","img":null,"order":216},{"name":"Sandy Martin","character":"Mac's Mom","img":null,"order":847},{"name":"Jimmi Simpson","character":"Liam McPoyle","img":null,"order":1009},{"name":"Nate Mooney","character":"Ryan McPoyle","img":null,"order":1011},{"name":"Andrew Friedman","character":"Uncle Jack","img":null,"order":1140},{"name":"Lance Barber","character":"Bill Ponderosa","img":null,"order":1201},{"name":"Gregory Scott Cummins","character":"Luther","img":null,"order":1230}],"tv:224372":[{"name":"Peter Claffey","character":"Ser Duncan 'Dunk' the Tall","img":null,"order":0},{"name":"Dexter Sol Ansell","character":"Egg","img":null,"order":1},{"name":"Ross Anderson","character":"Ser Humfrey Hardyng","img":null,"order":500},{"name":"Daniel Monks","character":"Ser Manfred Dondarrion","img":null,"order":504},{"name":"Tom Vaughan-Lawlor","character":"Plummer","img":null,"order":505},{"name":"Sam Spruell","character":"Prince Maekar Targaryen","img":null,"order":510},{"name":"Finn Bennett","character":"Prince Aerion 'Brightflame' Targaryen","img":null,"order":511},{"name":"Bertie Carvel","character":"Prince Baelor 'Breakspear' Targaryen","img":null,"order":512},{"name":"Danny Webb","character":"Ser Arlan of Pennytree","img":null,"order":513},{"name":"Tanzyn Crawford","character":"Tanselle","img":null,"order":514},{"name":"Henry Ashton","character":"Prince Daeron 'the Drunken' Targaryen","img":null,"order":517},{"name":"Edward Ashley","character":"Ser Steffon Fossoway","img":null,"order":518},{"name":"Cara Harris","character":"Lady Gwin","img":null,"order":527},{"name":"Shaun Thomas","character":"Ser Raymun 'The Reluctant' Fossoway","img":null,"order":532},{"name":"Daniel Ings","character":"Ser Lyonel 'The Laughing Storm' Baratheon","img":null,"order":543}],"tv:157741":[{"name":"Billy Bob Thornton","character":"Tommy Norris","img":null,"order":0},{"name":"Demi Moore","character":"Cami Miller","img":null,"order":1},{"name":"Andy Garcia","character":"Gallino","img":null,"order":2},{"name":"Ali Larter","character":"Angela Norris","img":null,"order":3},{"name":"Jacob Lofland","character":"Cooper Norris","img":null,"order":4},{"name":"Michelle Randolph","character":"Ainsley Norris","img":null,"order":5},{"name":"Paulina Ch\u00e1vez","character":"Ariana Medina","img":null,"order":6},{"name":"Kayla Wallace","character":"Rebecca Falcone","img":null,"order":7},{"name":"Mark Collie","character":"Sheriff Walt Joeberg","img":null,"order":8},{"name":"James Jordan","character":"Dale Bradley","img":null,"order":9},{"name":"Jon Hamm","character":"Monty Miller","img":null,"order":10},{"name":"Sam Elliott","character":"Thomas 'T.L.' Norris","img":null,"order":11},{"name":"Colm Feore","character":"Nathan","img":null,"order":501},{"name":"Mustafa Speaks","character":"Boss","img":null,"order":531},{"name":"Caleb Martin","character":"Ben 'BR' Reynolds","img":null,"order":611}],"tv:100088":[{"name":"Bella Ramsey","character":"Ellie Williams","img":null,"order":1},{"name":"Gabriel Luna","character":"Tommy Miller","img":null,"order":2},{"name":"Isabela Merced","character":"Dina","img":null,"order":3},{"name":"Young Mazino","character":"Jesse","img":null,"order":4},{"name":"Pedro Pascal","character":"Joel Miller","img":null,"order":164},{"name":"Anna Torv","character":"Tess","img":null,"order":523},{"name":"Lamar Johnson","character":"Henry Burrell","img":null,"order":565},{"name":"Rutina Wesley","character":"Maria","img":null,"order":567},{"name":"Samuel Hoeksema","character":"Museum Clicker","img":null,"order":571},{"name":"Kaitlyn Dever","character":"Abby Anderson","img":null,"order":576},{"name":"Danny Ramirez","character":"Manny Alvarez","img":null,"order":577},{"name":"Tati Gabrielle","character":"Nora","img":null,"order":578},{"name":"Spencer Lord","character":"Owen","img":null,"order":579},{"name":"Robert John Burke","character":"Seth","img":null,"order":580},{"name":"Ariela Barer","character":"Mel","img":null,"order":581}],"tv:252193":[{"name":"Junichi Okada","character":"Shujiro Saga","img":null,"order":0},{"name":"Yumia Fujisaki","character":"Futaba Katsuki","img":null,"order":1},{"name":"Kaya Kiyohara","character":"Iroha Kinugasa","img":null,"order":2},{"name":"Masahiro Higashide","character":"Kyojin Tsuge","img":null,"order":3},{"name":"Taichi Saotome","character":"Shikura Adashino","img":null,"order":4},{"name":"Yuya Endo","character":"Sansuke Gion","img":null,"order":5},{"name":"Hideaki Ito","character":"Bukotsu Kanjiya","img":null,"order":6},{"name":"Hiroshi Abe","character":"Okabe Gentosai","img":null,"order":7},{"name":"Gaku Hamada","character":"Kawaji Toshiyoshi","img":null,"order":501},{"name":"Arata Iura","character":"Okubo Toshimichi","img":null,"order":502},{"name":"Yuya Matsuura","character":"Kouemon Tachikawa","img":null,"order":504},{"name":"Nobi Nakanishi","character":"Narrator","img":null,"order":505},{"name":"Tetsushi Tanaka","character":"Hisoka Maejima","img":null,"order":506},{"name":"Kairi Jo","character":"Shinjiro Sayama","img":null,"order":514},{"name":"Taiiku Okazaki","character":"Keage Jinroku","img":null,"order":519}],"tv:270572":[{"name":"Winston Sawyers","character":"Ralph","img":null,"order":0},{"name":"David McKenna","character":"Nicholas \"Piggy\"","img":null,"order":1},{"name":"Lox Pratt","character":"Jack Merridew","img":null,"order":2},{"name":"Ike Talbut","character":"Simon Camborne","img":null,"order":3},{"name":"Thomas Connor","character":"Roger","img":null,"order":4},{"name":"Cornelius Brandreth","character":"Maurice","img":null,"order":5},{"name":"Cassius Flemyng","character":"Eric","img":null,"order":6},{"name":"Noah Flemyng","character":"Sam","img":null,"order":7},{"name":"Harrison Metcalf","character":"Frankie","img":null,"order":8},{"name":"Rafael de Belligny","character":"Robert","img":null,"order":9},{"name":"Felix Tandon","character":"William","img":null,"order":10},{"name":"Beau Thompson","character":"Philip","img":null,"order":11},{"name":"Kai Wilson","character":"Jasper","img":null,"order":12},{"name":"Freddie Lee-Grey","character":"Percival","img":null,"order":13},{"name":"Tom Page-Turner","character":"Bill","img":null,"order":14}],"tv:84773":[{"name":"Morfydd Clark","character":"Galadriel","img":null,"order":1},{"name":"Charlie Vickers","character":"Halbrand","img":null,"order":1},{"name":"Robert Aramayo","character":"Elrond","img":null,"order":3},{"name":"Charles Edwards","character":"Lord Celebrimbor","img":null,"order":4},{"name":"Owain Arthur","character":"Durin IV","img":null,"order":5},{"name":"Sophia Nomvete","character":"Disa","img":null,"order":6},{"name":"Daniel Weyman","character":"The Stranger","img":null,"order":7},{"name":"Markella Kavenagh","character":"Elanor 'Nori' Brandyfoot","img":null,"order":8},{"name":"Megan Richards","character":"Poppy Proudfellow","img":null,"order":9},{"name":"Ismael Cruz Cordova","character":"Arondir","img":null,"order":10},{"name":"Lloyd Owen","character":"Elendil","img":null,"order":11},{"name":"Benjamin Walker","character":"High King Gil-Galad","img":null,"order":16},{"name":"Cynthia Addai-Robinson","character":"M\u00edriel","img":null,"order":17},{"name":"Trystan Gravelle","character":"Pharaz\u00f4n","img":null,"order":18},{"name":"Ema Horvath","character":"E\u00e4rien","img":null,"order":19}],"tv:73411":[{"name":"Emma Stone","character":"Annie Landsberg","img":null,"order":0},{"name":"Jonah Hill","character":"Owen Milgrim","img":null,"order":1},{"name":"Sonoya Mizuno","character":"Dr. Azumi Fujita","img":null,"order":2},{"name":"Justin Theroux","character":"Dr. James K. Mantleray","img":null,"order":8},{"name":"Sally Field","character":"Dr. Greta Mantleray","img":null,"order":9},{"name":"Aaralyn Anderson","character":"Australia","img":null,"order":347},{"name":"James Monroe Iglehart","character":"Carl","img":null,"order":539},{"name":"Dai Ishiguro","character":"Head Control Tech","img":null,"order":540},{"name":"Gabriel Byrne","character":"Porter Milgrim","img":null,"order":546},{"name":"Kathleen Choe","character":"3","img":null,"order":547},{"name":"Allyce Beasley","character":"11","img":null,"order":550},{"name":"Stephen Hill","character":"7","img":null,"order":553},{"name":"Danny Hoch","character":"5","img":null,"order":556},{"name":"Billy Magnussen","character":"Jed Milgrim","img":null,"order":559},{"name":"Sejal Shah","character":"First Medical Tech","img":null,"order":562}],"tv:212333":[{"name":"Luca Marinelli","character":"Benito Mussolini","img":null,"order":0},{"name":"Francesco Russo","character":"Cesare Rossi","img":null,"order":1},{"name":"Barbara Chichiarelli","character":"Margherita Sarfatti","img":null,"order":2},{"name":"Benedetta Cimatti","character":"Rachele Mussolini","img":null,"order":3},{"name":"Gaetano Bruno","character":"Giacomo Matteotti","img":null,"order":4},{"name":"Maurizio Lombardi","character":"Emilio De Bono","img":null,"order":5},{"name":"Gianmarco Vettori","character":"Dino Grandi","img":null,"order":6},{"name":"Massimo De Lorenzo","character":"Alfredo Rocco","img":null,"order":7},{"name":"Fulvio Falzarano","character":"Giovanni Giolitti","img":null,"order":8},{"name":"Amedeo Gull\u00e0","character":"Augusto Malacria","img":null,"order":9},{"name":"Federico Majorana","character":"Amerigo Dumini","img":null,"order":500},{"name":"Lorenzo Zurzolo","character":"Italo Balbo","img":null,"order":501},{"name":"Vincenzo Nemolato","character":"King Vittorio Emanuele III","img":null,"order":502},{"name":"Giovanni Alfieri","character":"Amleto Poverno","img":null,"order":503},{"name":"Gabriele Falsetta","character":"Roberto Farinacci","img":null,"order":504}],"tv:61859":[{"name":"Tom Hiddleston","character":"Jonathan Pine","img":null,"order":0},{"name":"Hugh Laurie","character":"Richard Roper","img":null,"order":1},{"name":"Diego Calva","character":"Teddy Dos Santos","img":null,"order":2},{"name":"Camila Morrone","character":"Roxana Bola\u00f1os","img":null,"order":3},{"name":"Douglas Hodge","character":"Rex Mayhew","img":null,"order":5},{"name":"Elizabeth Debicki","character":"Jed Marshall","img":null,"order":6},{"name":"Paul Chahidi","character":"Basil Karapetian","img":null,"order":7},{"name":"David Harewood","character":"Joel Steadman","img":null,"order":8},{"name":"Hayley Squires","character":"Sally Price-Jones","img":null,"order":9},{"name":"Tom Hollander","character":"Lance Corkoran","img":null,"order":14},{"name":"Olivia Colman","character":"Angela Burr","img":"lawJUdbLb1YW0niaYjiVGR9IBG8.jpg","order":19},{"name":"Michael Nardone","character":"Frisky","img":null,"order":20},{"name":"Alistair Petrie","character":"Sandy Langbourne","img":null,"order":21},{"name":"Aure Atika","character":"","img":null,"order":281},{"name":"Noah Jupe","character":"","img":null,"order":380}],"tv:111110":[{"name":"I\u00f1aki Godoy","character":"Monkey D. Luffy","img":null,"order":0},{"name":"Emily Rudd","character":"Nami","img":null,"order":1},{"name":"Mackenyu","character":"Roronoa Zoro","img":null,"order":2},{"name":"Jacob Gibson","character":"Usopp","img":null,"order":3},{"name":"Vincent Regan","character":"Vice-Admiral Garp","img":null,"order":4},{"name":"Jeff Ward","character":"Buggy the Clown","img":null,"order":5},{"name":"Taz Skylar","character":"Sanji","img":null,"order":6},{"name":"Charithra Chandran","character":"Miss Wednesday / Nefertari Vivi","img":null,"order":7},{"name":"Mikaela Hoover","character":"Tony Tony Chopper (voice)","img":null,"order":8},{"name":"Morgan Davies","character":"Koby","img":null,"order":10},{"name":"Lera Abova","character":"Miss All Sunday","img":null,"order":11},{"name":"Armand Aucamp","character":"Bogard","img":null,"order":510},{"name":"McKinley Belcher III","character":"Captain Arlong","img":null,"order":546},{"name":"Jandre le Roux","character":"Kuroobi","img":null,"order":551},{"name":"Aidan Scott","character":"Helmeppo","img":null,"order":592}],"tv:61617":[{"name":"Elijah Wood","character":"Wirt (voice)","img":null,"order":0},{"name":"Collin Dean","character":"Gregory (voice)","img":null,"order":1},{"name":"Melanie Lynskey","character":"Beatrice (voice)","img":null,"order":2},{"name":"Samuel Ramey","character":"The Beast (voice)","img":null,"order":3},{"name":"Christopher Lloyd","character":"The Woodsman (voice)","img":null,"order":4},{"name":"Janet Klein","character":"Miss Langtree (voice)","img":null,"order":500},{"name":"Deborah Voigt","character":"Queen of the Clouds / Additional Voices (voice)","img":null,"order":501},{"name":"Chris Isaak","character":"Enoch / Additional Voices (voice)","img":null,"order":503},{"name":"John Cleese","character":"Adelaide (voice)","img":null,"order":510},{"name":"Sam Marin","character":"Old Man Langtree (voice)","img":null,"order":512},{"name":"Emily Brundige","character":"Sara / Additional Voices (voice)","img":null,"order":519},{"name":"Fred Stoller","character":"Fred The Horse (voice)","img":null,"order":521},{"name":"Cole Sanchez","character":"Jason Funderberker / Additional Voices (voice)","img":null,"order":521},{"name":"Shirley Jones","character":"Beatrice's Mother / Additional Voices (voice)","img":null,"order":523},{"name":"Jack Jones","character":"Gregory's Frog (voice)","img":null,"order":526}],"tv:60574":[{"name":"Cillian Murphy","character":"Thomas Shelby","img":null,"order":0},{"name":"Paul Anderson","character":"Arthur Shelby","img":null,"order":1},{"name":"Joe Cole","character":"John Shelby","img":null,"order":2},{"name":"Helen McCrory","character":"Polly Gray","img":null,"order":4},{"name":"Sophie Rundle","character":"Ada Shelby","img":null,"order":6},{"name":"Natasha O'Keeffe","character":"Lizzie Stark","img":null,"order":12},{"name":"Finn Cole","character":"Michael Gray","img":null,"order":14},{"name":"Ian Peck","character":"Curly","img":null,"order":15},{"name":"Tom Hardy","character":"Alfie Solomons","img":"d81K0RH8UX7tZj49tZaQhZ9ewH.jpg","order":16},{"name":"Ned Dennehy","character":"Charlie Strong","img":null,"order":17},{"name":"Harry Kirton","character":"Finn Shelby","img":null,"order":87},{"name":"Kate Phillips","character":"Linda Shelby","img":null,"order":104},{"name":"Annabelle Wallis","character":"Grace Shelby","img":null,"order":181},{"name":"Aimee-Ffion Edwards","character":"Esme Shelby","img":null,"order":606},{"name":"Packy Lee","character":"Johnny Dogs","img":null,"order":621}],"tv:250307":[{"name":"Noah Wyle","character":"Dr. Michael 'Robby' Robinavitch","img":null,"order":0},{"name":"Patrick Ball","character":"Dr. Frank Langdon","img":null,"order":2},{"name":"Katherine LaNasa","character":"Charge Nurse Dana Evans","img":null,"order":3},{"name":"Supriya Ganesh","character":"Dr. Samira Mohan","img":null,"order":4},{"name":"Fiona Dourif","character":"Dr. Cassie McKay","img":null,"order":5},{"name":"Taylor Dearden","character":"Dr. Melissa King","img":null,"order":6},{"name":"Isa Briones","character":"Dr. Trinity Santos","img":null,"order":7},{"name":"Gerran Howell","character":"Student Doctor Dennis Whitaker","img":null,"order":8},{"name":"Shabana Azeez","character":"Student Doctor Victoria Javadi","img":null,"order":9},{"name":"Alexandra Metz","character":"Dr. Yolanda Garcia","img":null,"order":508},{"name":"Ned Brower","character":"Nurse Jesse","img":null,"order":523},{"name":"Amielynn Abellera","character":"Nurse Perlah Alawi","img":null,"order":707},{"name":"Jalen Thomas Brooks","character":"Nurse Mateo Diaz","img":null,"order":708},{"name":"Brandon Mendez Homer","character":"Nurse Donald 'Donnie' Donahue","img":null,"order":709},{"name":"Kristin Villanueva","character":"Nurse Princess","img":null,"order":710}],"tv:225171":[{"name":"Rhea Seehorn","character":"Carol Sturka","img":null,"order":0},{"name":"Karolina Wydra","character":"Zosia","img":null,"order":1},{"name":"Carlos-Manuel Vesga","character":"Manousos Oviedo","img":null,"order":2},{"name":"Miriam Shor","character":"Helen","img":null,"order":500},{"name":"Samba Schutte","character":"Mr. Diabat\u00e9","img":null,"order":524},{"name":"Menik Gooneratne","character":"Laxmi","img":null,"order":525},{"name":"Darinka Arones","character":"Kusimayu","img":null,"order":526},{"name":"Anna Mhairi","character":"Vesper","img":null,"order":527},{"name":"Max Reeves","character":"Margaux","img":null,"order":528},{"name":"Olivia Rouyre","character":"Genevieve","img":null,"order":529},{"name":"Rayaan Kamal Khan","character":"Ravi","img":null,"order":532},{"name":"Elena Est\u00e9r","character":"T'ika","img":null,"order":537},{"name":"Soledad Campos","character":"Maternal Other","img":null,"order":559},{"name":"Jennifer Esquivel","character":"Sisa","img":null,"order":581},{"name":"Patrick Fabian","character":"Others' Phone Answering Service (voice) (uncredited)","img":null,"order":591}],"tv:94028":[{"name":"Andrew Scott","character":"Tom Ripley","img":"4F8XpjyQCvtuu21WFm5d8RF5Rl.jpg","order":0},{"name":"Dakota Fanning","character":"Marge Sherwood","img":null,"order":1},{"name":"Johnny Flynn","character":"Dickie Greenleaf","img":null,"order":2},{"name":"Kenneth Lonergan","character":"Herbert Greenleaf","img":null,"order":500},{"name":"Francesca Romana Bergamo","character":"Ermelinda","img":null,"order":511},{"name":"Pasquale Esposito","character":"Pucci","img":null,"order":512},{"name":"Arcangelo Iannace","character":"Giulio","img":null,"order":513},{"name":"Vittorio Viviani","character":"Matteo","img":null,"order":514},{"name":"Eliot Sumner","character":"Frederick 'Freddie' Miles","img":null,"order":515},{"name":"Bokeem Woodbine","character":"Alvin MacCarron","img":null,"order":516},{"name":"Renato Solpietro","character":"Carlo","img":null,"order":519},{"name":"Francesco Formichetti","character":"Sanremo Desk Clerk","img":null,"order":523},{"name":"Margherita Buy","character":"Sig. Silvana Buffi","img":null,"order":540},{"name":"Maurizio Lombardi","character":"Inspector Pietro Ravini","img":null,"order":544},{"name":"Gennaro Arena","character":"Naples Kid","img":null,"order":578}],"tv:245256":[{"name":"Lola Petticrew","character":"Dolours Price","img":null,"order":0},{"name":"Maxine Peake","character":"Older Dolours Price","img":null,"order":1},{"name":"Hazel Doupe","character":"Marian Price","img":null,"order":2},{"name":"Anthony Boyle","character":"Brendan Hughes","img":null,"order":3},{"name":"Tom Vaughan-Lawlor","character":"Older Brendan Hughes","img":null,"order":4},{"name":"Josh Finan","character":"Gerry Adams","img":null,"order":5},{"name":"Rory Kinnear","character":"Frank Kitson","img":null,"order":6},{"name":"Seamus O'Hara","character":"Mackers","img":null,"order":500},{"name":"Helen Behan","character":"Older Marian Price","img":null,"order":501},{"name":"Michael Colgan","character":"Older Gerry Adams","img":null,"order":502},{"name":"Conor O'Donnell","character":"Eamon","img":null,"order":503},{"name":"James Doherty","character":"Chief Inspector","img":null,"order":504},{"name":"Bill Jones","character":"Ian","img":null,"order":505},{"name":"Shannon Watson","character":"Make-up Artist","img":null,"order":506},{"name":"Emma Canning","character":"Kathleen","img":null,"order":508}],"tv:95396":[{"name":"Adam Scott","character":"Mark Scout","img":null,"order":0},{"name":"Britt Lower","character":"Helly Riggs","img":null,"order":1},{"name":"Tramell Tillman","character":"Seth Milchick","img":null,"order":2},{"name":"Zach Cherry","character":"Dylan George","img":null,"order":3},{"name":"Patricia Arquette","character":"Harmony Cobel","img":null,"order":4},{"name":"Jen Tullock","character":"Devon Scout-Hale","img":null,"order":5},{"name":"Michael Chernus","character":"Ricken Hale","img":null,"order":6},{"name":"Dichen Lachman","character":"Ms. Casey","img":null,"order":7},{"name":"Sarah Bock","character":"Eustice Huang","img":null,"order":8},{"name":"John Turturro","character":"Irving Bailiff","img":null,"order":9},{"name":"Christopher Walken","character":"Burt Goodman","img":null,"order":10},{"name":"Sydney Cole Alexander","character":"Natalie Kalen","img":null,"order":515},{"name":"Karen Aldridge","character":"Asal Regabhi","img":null,"order":522},{"name":"Michael Cumpsty","character":"Doug Graner","img":null,"order":529},{"name":"Claudia Robinson","character":"Felicia","img":null,"order":537}],"tv:1274":[{"name":"Peter Krause","character":"Nate Fisher","img":null,"order":0},{"name":"Michael C. Hall","character":"David Fisher","img":null,"order":1},{"name":"Frances Conroy","character":"Ruth Fisher","img":null,"order":2},{"name":"Lauren Ambrose","character":"Claire Fisher","img":null,"order":3},{"name":"Freddy Rodr\u00edguez","character":"Federico Diaz","img":null,"order":4},{"name":"Mathew St. Patrick","character":"Keith Charles","img":null,"order":5},{"name":"Rachel Griffiths","character":"Brenda Chenowith","img":null,"order":6},{"name":"Ben Foster","character":"Russell Corwin","img":null,"order":7},{"name":"Justina Machado","character":"Vanessa Diaz","img":null,"order":8},{"name":"Jeremy Sisto","character":"Billy Chenowith","img":null,"order":10},{"name":"Richard Jenkins","character":"Nathaniel Fisher","img":null,"order":11},{"name":"Lili Taylor","character":"Lisa Kimmel Fisher","img":null,"order":12},{"name":"James Cromwell","character":"George Sibley","img":null,"order":13},{"name":"Bronwyn Tosh","character":"Maya Fisher","img":null,"order":559},{"name":"Brenna Tosh","character":"Maya Fisher","img":null,"order":608}],"tv:86942":[{"name":"Tom Waes","character":"Bob Lemmens","img":null,"order":0},{"name":"Frank Lammers","character":"Ferry Bouman","img":null,"order":1},{"name":"Raymond Thiry","character":"John Zwart","img":null,"order":2},{"name":"Elise Schaap","character":"Danielle Bouman","img":null,"order":4},{"name":"Anna Drijver","character":"Kim De Rooij","img":null,"order":5},{"name":"Jeroen Van der Ven","character":"Patrick Dierickx","img":null,"order":6},{"name":"Ruth Becquart","character":"Nathalie Geudens","img":null,"order":7},{"name":"Manou Kersting","character":"Nick Janssens","img":null,"order":8},{"name":"Wim Willaert","character":"Laurent Berger","img":null,"order":10},{"name":"Sebastien Dewaele","character":"Jean-Pierre Berger","img":null,"order":11},{"name":"Emma Verlinden","character":"Polly","img":null,"order":187},{"name":"Katrien De Ruysscher","character":"Liesbeth Mertens","img":null,"order":553},{"name":"Robbie Cleiren","character":"Marc Gevers","img":null,"order":554},{"name":"Lieke van den Broek","character":"Sonja Van Kamp","img":null,"order":562},{"name":"Celest Henri Cornelis","character":"Jackson Geudens","img":null,"order":582}],"tv:86248":[{"name":"Robbie Amell","character":"Nathan Brown","img":null,"order":0},{"name":"Andy Allo","character":"Nora Antony","img":null,"order":1},{"name":"Allegra Edwards","character":"Ingrid Kannerman","img":null,"order":2},{"name":"Zainab Johnson","character":"Aleesha","img":null,"order":3},{"name":"Kevin Bigley","character":"Luke","img":null,"order":4},{"name":"Owen Daniels","character":"A.I. Guy","img":null,"order":5},{"name":"Andrea Rosen","character":"Lucy Slack","img":null,"order":6},{"name":"Josh Banday","character":"Ivan Spelich","img":null,"order":8},{"name":"Mackenzie Cardwell","character":"Tinsley","img":null,"order":9},{"name":"Andy Thompson","character":"Lionel Winter","img":null,"order":600},{"name":"Barclay Hope","character":"Oliver Kannerman","img":null,"order":607},{"name":"William B. Davis","character":"David Choak","img":null,"order":624},{"name":"Chloe Coleman","character":"Nevaeh","img":null,"order":632},{"name":"Yvetta Fisher","character":"Batia","img":null,"order":633},{"name":"Jessica Tuck","character":"Viv","img":null,"order":651}],"tv:210664":[{"name":"Stephen Graham","character":"Matthew Collins","img":null,"order":0},{"name":"Jason Flemyng","character":"Nick","img":null,"order":1},{"name":"Leanne Best","character":"Alison","img":null,"order":2},{"name":"Andrew Ellis","character":"Robbie","img":null,"order":3},{"name":"Chris Coghill","character":"Chris","img":null,"order":4},{"name":"Dean-Charles Chapman","character":"Jack","img":null,"order":5},{"name":"Sami Amber","character":"Billy","img":null,"order":6},{"name":"Steven Miller","character":"Young Lenny","img":null,"order":500}],"tv:270476":[{"name":"Matthew Rhys","character":"Mayor Tom Loftis","img":null,"order":0},{"name":"Kate O'Flynn","character":"Patricia Moyer","img":null,"order":1},{"name":"Kevin Carroll","character":"Sheriff Bechir Clemmons","img":null,"order":2},{"name":"Dale Dickey","character":"Rosemary","img":null,"order":3},{"name":"Kingston Rumi Southwick","character":"Evan Loftis","img":null,"order":4},{"name":"Stephen Root","character":"Wyck Crawford","img":null,"order":5},{"name":"Neil Casey","character":"Kurt","img":null,"order":500},{"name":"Jeff Hiller","character":"Dale","img":null,"order":501},{"name":"K Callan","character":"Ruth","img":null,"order":503},{"name":"Kylie McNeill","character":"Kelly","img":null,"order":504},{"name":"Beck Nolan","character":"PJ","img":null,"order":505},{"name":"Charles Van Flaherty","character":"Gil","img":null,"order":506},{"name":"Nancy Lenehan","character":"Gerrie","img":null,"order":508},{"name":"Christian Clemenson","character":"Dr. Morgan","img":null,"order":509},{"name":"Sipiwe Moyo","character":"Chelle","img":null,"order":529}],"tv:71912":[{"name":"Henry Cavill","character":"Geralt of Rivia","img":null,"order":0},{"name":"Anya Chalotra","character":"Yennefer of Vengerberg","img":null,"order":2},{"name":"Freya Allan","character":"Princess Cirilla 'Ciri' of Cintra","img":null,"order":3},{"name":"Joey Batey","character":"Jaskier / The Sandpiper","img":null,"order":4},{"name":"Eamon Farren","character":"Cahir","img":null,"order":5},{"name":"Mim\u00ee M. Khayisa","character":"Fringilla Vigo","img":null,"order":6},{"name":"Anna Shaffer","character":"Triss Merigold","img":null,"order":7},{"name":"Mahesh Jadu","character":"Vilgefortz of Roggeveen","img":null,"order":8},{"name":"Cassie Clare","character":"Philippa Eilhart","img":null,"order":11},{"name":"MyAnna Buring","character":"Tissaia De Vries","img":null,"order":14},{"name":"Mecia Simson","character":"Francesca Findabair","img":null,"order":18},{"name":"Bart Edwards","character":"The White Flame","img":null,"order":345},{"name":"Wilson Mbomio","character":"Dara","img":null,"order":500},{"name":"Therica Wilson-Read","character":"Sabrina","img":null,"order":542},{"name":"Royce Pierreson","character":"Istredd","img":null,"order":671}],"movie:76203":[{"name":"Chiwetel Ejiofor","character":"Solomon Northup","img":null,"order":0},{"name":"Michael Fassbender","character":"Edwin Epps","img":null,"order":1},{"name":"Lupita Nyong'o","character":"Patsey","img":null,"order":2},{"name":"Benedict Cumberbatch","character":"William Ford","img":null,"order":3},{"name":"Paul Dano","character":"John Tibeats","img":null,"order":4},{"name":"Sarah Paulson","character":"Mary Epps","img":null,"order":5},{"name":"Adepero Oduye","character":"Eliza","img":null,"order":6},{"name":"Scoot McNairy","character":"Brown","img":null,"order":7},{"name":"Paul Giamatti","character":"Theophilus Freeman","img":null,"order":8},{"name":"Brad Pitt","character":"Samuel Bass","img":null,"order":9},{"name":"Michael Kenneth Williams","character":"Robert","img":null,"order":10},{"name":"Alfre Woodard","character":"Mistress Shaw","img":null,"order":11},{"name":"Chris Chalk","character":"Clemens","img":null,"order":12},{"name":"Taran Killam","character":"Hamilton","img":null,"order":13},{"name":"Bill Camp","character":"Radburn","img":null,"order":14}],"movie:13654":[{"name":"Barry Bostwick","character":"Thunderbolt (voice)","img":null,"order":0},{"name":"Jason Alexander","character":"Lightning (voice)","img":null,"order":1},{"name":"Martin Short","character":"Lars (voice)","img":null,"order":2},{"name":"Bobby Lockwood","character":"Patch (voice)","img":null,"order":3},{"name":"Susanne Blakeslee","character":"Cruella (voice)","img":null,"order":4},{"name":"Samuel West","character":"Pongo (voice)","img":null,"order":5},{"name":"Maurice LaMarche","character":"Horace (voice)","img":null,"order":6},{"name":"Jeff Bennett","character":"Jasper (voice)","img":null,"order":7},{"name":"Jodi Benson","character":"Anita (voice)","img":null,"order":8},{"name":"Tim Bentinck","character":"Roger (voice)","img":null,"order":9},{"name":"Kath Soucie","character":"Perdita (voice)","img":null,"order":10},{"name":"Mary MacLeod","character":"Nanny (voice)","img":null,"order":11},{"name":"Michael Lerner","character":"Producer (voice)","img":null,"order":12},{"name":"Kathryn Beaumont","character":"Additional Voices (voice)","img":null,"order":13},{"name":"Nicolette Little","character":"Additional Voices (voice)","img":null,"order":14}],"movie:974453":[{"name":"Liam Neeson","character":"Thug","img":null,"order":0},{"name":"Ron Perlman","character":"Charlie Conner","img":null,"order":1},{"name":"Yolonda Ross","character":"Woman","img":null,"order":2},{"name":"Frankie Shaw","character":"Daisy","img":null,"order":3},{"name":"Daniel Diemer","character":"Kyle Conner","img":null,"order":4},{"name":"Jimmy Gonzales","character":"Diego Machado","img":null,"order":5},{"name":"Josh Drennen","character":"Thug's Dad","img":null,"order":6},{"name":"Deanna Tarraza","character":"Araceli","img":null,"order":7},{"name":"Terrence Pulliam","character":"Dre","img":null,"order":8},{"name":"Omar Moustafa Ghonim","character":"Armando","img":null,"order":9},{"name":"Tom Kemp","character":"Burt","img":null,"order":10},{"name":"Ryan Homchick","character":"Dr. Gruber","img":null,"order":11},{"name":"William Xifaras","character":"Kiko","img":null,"order":12},{"name":"Kris Eivers","character":"Priest","img":null,"order":13},{"name":"Ryan Caraway","character":"George","img":null,"order":14}],"movie:446791":[{"name":"Michelle Williams","character":"Gail Harris","img":null,"order":0},{"name":"Mark Wahlberg","character":"Fletcher Chase","img":null,"order":1},{"name":"Christopher Plummer","character":"Jean Paul Getty","img":null,"order":2},{"name":"Charlie Plummer","character":"John Paul Getty III","img":null,"order":3},{"name":"Romain Duris","character":"Cinquanta","img":null,"order":4},{"name":"Timothy Hutton","character":"Oswald Hinge","img":null,"order":5},{"name":"Charlie Shotwell","character":"John Paul Getty III (Age 7)","img":null,"order":6},{"name":"Andrew Buchan","character":"John Paul Getty II","img":null,"order":7},{"name":"Marco Leonardi","character":"Saverio Mammoliti","img":null,"order":8},{"name":"Giuseppe Bonifati","character":"Giovanni Iacovoni","img":null,"order":9},{"name":"Nicolas Vaporidis","character":"Il Tamia 'Chipmunk'","img":null,"order":10},{"name":"Andrea Piedimonte Bodini","character":"Corvo","img":null,"order":11},{"name":"Guglielmo Favilla","character":"Piccolino","img":null,"order":12},{"name":"Adele Tirante","character":"Maria","img":null,"order":13},{"name":"Stacy Martin","character":"Nancy","img":null,"order":14}],"movie:1013601":[{"name":"Robert De Niro","character":"Vito Genovese / Frank Costello","img":null,"order":0},{"name":"Debra Messing","character":"Bobbie Costello","img":null,"order":1},{"name":"Cosmo Jarvis","character":"Vincent Gigante","img":null,"order":2},{"name":"Kathrine Narducci","character":"Anna Genovese","img":null,"order":3},{"name":"Michael Rispoli","character":"Albert Anastasia","img":null,"order":4},{"name":"Michael Adler","character":"Senator Tobey","img":null,"order":5},{"name":"Ed Amatrudo","character":"Rudolph Halley","img":null,"order":6},{"name":"Joe Bacino","character":"Joe Profaci","img":null,"order":7},{"name":"Anthony J. Gallo","character":"Tommy Lucchese","img":null,"order":8},{"name":"Wallace Langham","character":"Senator Estes Kefauver","img":null,"order":9},{"name":"Louis Mustillo","character":"Joe Bonanno","img":null,"order":10},{"name":"Frank Piccirillo","character":"Richie Boiardo","img":null,"order":11},{"name":"Matt Servitto","character":"George Wolf","img":null,"order":12},{"name":"Robert Uricola","character":"Tony Bender","img":null,"order":13},{"name":"Belmont Cameli","character":"Frankie Boy","img":null,"order":14}],"movie:416153":[{"name":"James Franco","character":"Lemmy (voice)","img":null,"order":0},{"name":"Jeremy Renner","character":"Swifty (voice)","img":null,"order":1},{"name":"Alec Baldwin","character":"PB (voice)","img":null,"order":2},{"name":"Anjelica Huston","character":"Magda (voice)","img":null,"order":3},{"name":"Michael Madsen","character":"Duke (voice)","img":null,"order":4},{"name":"Heidi Klum","character":"Jade / Bertha (voice)","img":null,"order":5},{"name":"John Cleese","character":"Otto von Walrus (voice)","img":null,"order":6},{"name":"Omar Sy","character":"Leopold (voice)","img":null,"order":7},{"name":"Laurie Holden","character":"Dakota (voice)","img":null,"order":8},{"name":"Donny Falsetti","character":"Dusty (voice)","img":null,"order":9},{"name":"Susan Spano","character":"Mary (voice)","img":null,"order":10},{"name":"Jason Deline","character":"Naz Narwahl (voice)","img":null,"order":11},{"name":"Aaron Woodley","character":"Puffin Leader (voice)","img":null,"order":12},{"name":"Lucie Hager","character":"Countdown Inka (voice)","img":null,"order":13},{"name":"Lillian Moloy","character":"Young Jade","img":null,"order":14}],"movie:1607":[{"name":"Robert De Niro","character":"Lorenzo Anello","img":null,"order":0},{"name":"Chazz Palminteri","character":"Sonny LoSpecchio","img":null,"order":1},{"name":"Lillo Brancato","character":"Calogero 'C' Anello (Age 17)","img":null,"order":2},{"name":"Francis Capra","character":"Calogero 'C' Anello (Age 9)","img":null,"order":3},{"name":"Taral Hicks","character":"Jane Williams","img":null,"order":4},{"name":"Kathrine Narducci","character":"Rosina Anello","img":null,"order":5},{"name":"Clem Caserta","character":"Jimmy Whispers","img":null,"order":6},{"name":"Alfred Sauchelli, Jr.","character":"Bobby Bars","img":null,"order":7},{"name":"Frank Pietrangolare","character":"Danny K.O.","img":null,"order":8},{"name":"Joe Pesci","character":"Carmine","img":null,"order":9},{"name":"Robert D'Andrea","character":"Tony Toupee","img":null,"order":10},{"name":"Eddie Montanaro","character":"Eddie Mush","img":null,"order":11},{"name":"Fred Fischer","character":"JoJo 'The Whale'","img":null,"order":12},{"name":"Dave Salerno","character":"Frankie Coffeecake","img":null,"order":13},{"name":"Joseph D'Onofrio","character":"Slick (Age 17)","img":null,"order":14}],"movie:1380417":[{"name":"Yahya Abdul-Mateen II","character":"Wayne Strider","img":null,"order":0},{"name":"Mark Wahlberg","character":"Gregory Scarpa","img":null,"order":1},{"name":"Nicole Beharie","character":"Allison Strider","img":null,"order":2},{"name":"Josh Lucas","character":"Special Agent Everett Rhodes","img":null,"order":3},{"name":"David Strathairn","character":"Special Agent Roy K. Moore","img":null,"order":4},{"name":"Giancarlo Esposito","character":"Vernon Dahmer","img":null,"order":5},{"name":"Ethan Embry","character":"Sam Bowers","img":null,"order":6},{"name":"LisaGay Hamilton","character":"Ms. Rebecca Brewer","img":null,"order":7},{"name":"LaChanze","character":"Hattie Dahmer","img":null,"order":8},{"name":"Biko Eisen-Martin","character":"Special Agent Archie Crawford","img":null,"order":9},{"name":"Will Brittain","character":"Billy Roy Pitts","img":null,"order":10},{"name":"DeVere Jehl","character":"Edgar Ray Killen","img":null,"order":11},{"name":"Jody Thompson","character":"Lawrence Byrd","img":null,"order":12},{"name":"Zach Lane","character":"Howard Styles","img":null,"order":13},{"name":"Lee Perkins","character":"Sheriff Mitchell","img":null,"order":14}],"movie:271110":[{"name":"Chris Evans","character":"Steve Rogers / Captain America","img":null,"order":0},{"name":"Robert Downey Jr.","character":"Tony Stark / Iron Man","img":null,"order":1},{"name":"Scarlett Johansson","character":"Natasha Romanoff / Black Widow","img":null,"order":2},{"name":"Sebastian Stan","character":"Bucky Barnes / Winter Soldier","img":null,"order":3},{"name":"Anthony Mackie","character":"Sam Wilson / Falcon","img":null,"order":4},{"name":"Don Cheadle","character":"Lieutenant James Rhodes / War Machine","img":null,"order":5},{"name":"Jeremy Renner","character":"Clint Barton / Hawkeye","img":null,"order":6},{"name":"Chadwick Boseman","character":"T'Challa / Black Panther","img":null,"order":7},{"name":"Paul Bettany","character":"Vision","img":null,"order":8},{"name":"Elizabeth Olsen","character":"Wanda Maximoff / Scarlet Witch","img":null,"order":9},{"name":"Paul Rudd","character":"Scott Lang / Ant-Man","img":null,"order":10},{"name":"Emily VanCamp","character":"Sharon Carter","img":null,"order":11},{"name":"Tom Holland","character":"Peter Parker / Spider-Man","img":"xKBAaPIa1c7tzZD3Y0MhBLv4hPE.jpg","order":12},{"name":"Daniel Br\u00fchl","character":"Zemo","img":null,"order":13},{"name":"Frank Grillo","character":"Brock Rumlow / Crossbones","img":null,"order":14}],"movie:1771":[{"name":"Chris Evans","character":"Captain America / Steve Rogers","img":null,"order":0},{"name":"Hayley Atwell","character":"Peggy Carter","img":null,"order":1},{"name":"Sebastian Stan","character":"James Buchanan 'Bucky' Barnes","img":null,"order":2},{"name":"Tommy Lee Jones","character":"Colonel Chester Phillips","img":null,"order":3},{"name":"Hugo Weaving","character":"Johann Schmidt / Red Skull","img":null,"order":4},{"name":"Dominic Cooper","character":"Howard Stark","img":null,"order":5},{"name":"Richard Armitage","character":"Heinz Kruger","img":null,"order":6},{"name":"Stanley Tucci","character":"Dr. Abraham Erskine","img":null,"order":7},{"name":"Samuel L. Jackson","character":"Nick Fury","img":null,"order":8},{"name":"Toby Jones","character":"Dr. Arnim Zola","img":null,"order":9},{"name":"Neal McDonough","character":"Timothy 'Dum Dum' Dugan","img":null,"order":10},{"name":"Derek Luke","character":"Gabe Jones","img":null,"order":11},{"name":"Kenneth Choi","character":"Jim Morita","img":null,"order":12},{"name":"JJ Feild","character":"James Montgomery Falsworth","img":null,"order":13},{"name":"Bruno Ricci","character":"Jacques Dernier","img":null,"order":14}],"movie:100402":[{"name":"Chris Evans","character":"Steve Rogers / Captain America","img":null,"order":0},{"name":"Samuel L. Jackson","character":"Nick Fury","img":null,"order":1},{"name":"Scarlett Johansson","character":"Natasha Romanoff / Black Widow","img":null,"order":2},{"name":"Robert Redford","character":"Alexander Pierce","img":null,"order":3},{"name":"Sebastian Stan","character":"Bucky Barnes / Winter Soldier","img":null,"order":4},{"name":"Anthony Mackie","character":"Sam Wilson / Falcon","img":null,"order":5},{"name":"Cobie Smulders","character":"Maria Hill","img":null,"order":6},{"name":"Frank Grillo","character":"Brock Rumlow","img":null,"order":7},{"name":"Maximiliano Hern\u00e1ndez","character":"Jasper Sitwell","img":null,"order":8},{"name":"Emily VanCamp","character":"Kate / Agent 13","img":null,"order":9},{"name":"Hayley Atwell","character":"Peggy Carter","img":null,"order":10},{"name":"Toby Jones","character":"Dr. Arnim Zola","img":null,"order":11},{"name":"Stan Lee","character":"Smithsonian Guard","img":null,"order":12},{"name":"Callan Mulvey","character":"Jack Rollins","img":null,"order":13},{"name":"Jenny Agutter","character":"Councilwoman Hawley","img":null,"order":14}],"tv:60948":[{"name":"Aaron Stanford","character":"James Cole","img":null,"order":0},{"name":"Amanda Schull","character":"Cassandra Railly","img":null,"order":1},{"name":"Kirk Acevedo","character":"Jos\u00e9 Ramse","img":null,"order":2},{"name":"Barbara Sukowa","character":"Katarina Jones","img":null,"order":3},{"name":"Emily Hampshire","character":"Jennifer Goines","img":null,"order":4},{"name":"Todd Stashwick","character":"Deacon","img":null,"order":6},{"name":"Noah Bean","character":"Aaron Marker","img":null,"order":7},{"name":"Alisen Richmond-Peck","character":"Striking Woman","img":null,"order":366},{"name":"Scottie Thompson","character":"Vivian Rutledge","img":null,"order":519},{"name":"Peter DaCunha","character":"Samuel Ramse","img":null,"order":760},{"name":"Murray Furrow","character":"Lasky","img":null,"order":797},{"name":"Andrew Gillies","character":"Julian Adler","img":null,"order":800},{"name":"Tom Noonan","character":"Pallid Man","img":null,"order":805},{"name":"Demore Barnes","character":"Marcus Whitley","img":null,"order":806},{"name":"Brooke Williams","character":"Hannah Jones","img":null,"order":807}],"tv:202097":[{"name":"Jill Hennessy","character":"Lynn Harmon","img":null,"order":501},{"name":"Oakes Fegley","character":"Devin Harmon","img":null,"order":502},{"name":"Robert Wisdom","character":"Mitch Becker","img":null,"order":503},{"name":"J. Harrison Ghee","character":"Kevin Milstead","img":null,"order":504},{"name":"Evan Marsh","character":"Alex Harmon","img":null,"order":505},{"name":"Sonny McKnight","character":"Young Devin (Age 3)","img":null,"order":506},{"name":"Coleby Wojtak-Hissong","character":"Young Devin (Age 5)","img":null,"order":507},{"name":"Athan Giazitzidis","character":"Young Alex","img":null,"order":508},{"name":"Ali Momen","character":"Principal Sam Canosa","img":null,"order":509},{"name":"Tara Rosling","character":"Dr. Laurie Grotstein","img":null,"order":510},{"name":"Deklon Roberts","character":"Captain Kramer","img":null,"order":511},{"name":"Seema Doad","character":"Uniformed Officer","img":null,"order":512},{"name":"Michael Chiklis","character":"Dr. Scott Harmon","img":null,"order":596},{"name":"Daniel Maslany","character":"Public Defender Eli Demille","img":null,"order":633},{"name":"Matthew James Thomas","character":"Alexei","img":null,"order":639}],"tv:79410":[{"name":"Ricky Gervais","character":"Tony","img":null,"order":0},{"name":"Tom Basden","character":"Matt","img":null,"order":1},{"name":"Kerry Godliman","character":"Lisa","img":null,"order":2},{"name":"David Bradley","character":"Ray","img":null,"order":3},{"name":"Joe Wilkinson","character":"Pat","img":null,"order":4},{"name":"Roisin Conaty","character":"Daphne \"Roxy\"","img":null,"order":6},{"name":"Tony Way","character":"Lenny","img":null,"order":7},{"name":"Diane Morgan","character":"Kath","img":null,"order":9},{"name":"Ashley Jensen","character":"Emma","img":null,"order":11},{"name":"Tommy Finnegan","character":"George","img":null,"order":12},{"name":"Jo Hartley","character":"June","img":null,"order":13},{"name":"Penelope Wilton","character":"Anne","img":null,"order":14},{"name":"David Earl","character":"Brian","img":null,"order":15},{"name":"Ethan Lawrence","character":"James","img":null,"order":16},{"name":"Michelle Greenidge","character":"Valerie","img":null,"order":17}],"tv:7406":[{"name":"Lynda Bellingham","character":"Helen Herriot","img":null,"order":0},{"name":"Robert Hardy","character":"Siegfried Farnon","img":null,"order":1},{"name":"Christopher Timothy","character":"James Herriot","img":null,"order":2},{"name":"Carol Drinkwater","character":"Helen Herriot","img":null,"order":3},{"name":"Mary Hignett","character":"Mrs. Hall","img":null,"order":4},{"name":"Margaretta Scott","character":"Mrs. Pumphrey","img":null,"order":7},{"name":"Teddy Turner","character":"Hodgekin","img":null,"order":8},{"name":"Peter Davison","character":"Tristan Farnon","img":null,"order":10},{"name":"John McGlynn","character":"Calum Buchanan","img":null,"order":11},{"name":"Jean Heywood","character":"Mrs Alton","img":null,"order":12},{"name":"Peter Martin","character":"Handshaw","img":null,"order":839},{"name":"Oliver Wilson","character":"Jimmy Herriot","img":null,"order":928},{"name":"Rebecca Smith","character":"Rosie Herriot","img":null,"order":929},{"name":"John Sharp","character":"Mr. Biggins","img":null,"order":952},{"name":"Andrea Gibb","character":"Deidre Buchanan","img":null,"order":971}],"tv:67117":[{"name":"Katy Mixon","character":"Katie Otto","img":null,"order":0},{"name":"Diedrich Bader","character":"Greg Otto","img":null,"order":1},{"name":"Meg Donnelly","character":"Taylor Otto","img":null,"order":2},{"name":"Giselle Eisenberg","character":"Anna-Kat Otto","img":null,"order":3},{"name":"Julia Butters","character":"Anna-Kat Otto","img":null,"order":4},{"name":"Daniel DiMaggio","character":"Oliver Otto","img":null,"order":5},{"name":"Carly Hughes","character":"Angela","img":null,"order":6},{"name":"Ali Wong","character":"Doris","img":null,"order":7},{"name":"Jerry Lambert","character":"Principal Ablin","img":null,"order":515},{"name":"Logan Pepper","character":"Cooper Bradford","img":null,"order":518},{"name":"Peyton Meyer","character":"Trip Windsor","img":null,"order":519},{"name":"Wendie Malick","character":"Kathryn","img":null,"order":532},{"name":"Carly Craig","character":"Tara","img":null,"order":541},{"name":"Evan O'Toole","character":"Franklin","img":null,"order":565},{"name":"Julie Meyer","character":"Maria","img":null,"order":634}],"tv:47054":[{"name":"Mark Addy","character":"Hercules","img":null,"order":0},{"name":"Jack Donnelly","character":"Jason","img":null,"order":1},{"name":"Robert Emms","character":"Pythagoras","img":null,"order":2},{"name":"Aiysha Hart","character":"Ariadne","img":null,"order":3},{"name":"Sarah Parish","character":"Pasiphae","img":null,"order":4},{"name":"Juliet Stevenson","character":"The Oracle","img":null,"order":5},{"name":"Jemima Rooper","character":"Medusa","img":null,"order":6},{"name":"Amy Manson","character":"Medea","img":null,"order":7},{"name":"Alexander Siddig","character":"Minos","img":null,"order":8},{"name":"Vincent Regan","character":"Dion","img":null,"order":9},{"name":"Lorcan Cranitch","character":"Cilix","img":null,"order":10},{"name":"Robert Lindsay","character":"Daedalus","img":null,"order":11},{"name":"Anya Taylor-Joy","character":"Cassandra","img":null,"order":514},{"name":"Stuart Davidson","character":"Lysis's Masseur","img":null,"order":516},{"name":"Kate Davies-Speak","character":"Atlantean","img":null,"order":533}],"tv:62481":[{"name":"Bobby Flay","character":"Self","img":null,"order":0},{"name":"Giada De Laurentiis","character":"Self","img":null,"order":475},{"name":"Michael Symon","character":"Self","img":null,"order":493},{"name":"Scott Conant","character":"Self - Guest Judge","img":null,"order":503},{"name":"Alex Guarnaschelli","character":"Self - Guest Judge","img":null,"order":512},{"name":"Eddie Jackson","character":"Self","img":null,"order":512},{"name":"Sunny Anderson","character":"Self","img":null,"order":515},{"name":"Jet Tila","character":"Self","img":null,"order":524},{"name":"Anne Burrell","character":"Self","img":null,"order":526},{"name":"Ted Allen","character":"Self","img":null,"order":534},{"name":"Simon Majumdar","character":"Self","img":null,"order":536},{"name":"Geoffrey Zakarian","character":"Self","img":null,"order":537},{"name":"Michael Voltaggio","character":"Self","img":null,"order":549},{"name":"Amanda Freitag","character":"Self","img":null,"order":569},{"name":"Katie Lee Biegel","character":"Self","img":null,"order":645}],"tv:1849":[{"name":"Robert Guillaume","character":"Benson DuBois","img":null,"order":0},{"name":"James Noble","character":"Eugene Gatling","img":null,"order":1},{"name":"Inga Swenson","character":"Gretchen Kraus","img":null,"order":2},{"name":"Caroline McWilliams","character":"Marcy Hill","img":null,"order":3},{"name":"Missy Gold","character":"Katie Gatling","img":null,"order":4},{"name":"Ethan Phillips","character":"Pete Downey","img":null,"order":5},{"name":"Didi Conn","character":"Denise Stevens","img":null,"order":6},{"name":"Lewis J. Stadlen","character":"John Taylor","img":null,"order":7},{"name":"Ren\u00e9 Auberjonois","character":"Clayton Endicott III","img":null,"order":8},{"name":"Billie Bird","character":"Rose Cassidy","img":null,"order":9},{"name":"Beverly Todd","character":"Casey Turner","img":null,"order":507},{"name":"Ren\u00e9 Enr\u00edquez","character":"","img":null,"order":509},{"name":"Norman Bartold","character":"","img":null,"order":513},{"name":"G.W. Bailey","character":"","img":null,"order":539},{"name":"Jerry Seinfeld","character":"Frankie","img":null,"order":552}],"tv:249039":[{"name":"Jason Bateman","character":"Vince Friedken","img":null,"order":0},{"name":"Jude Law","character":"Jake Friedken","img":null,"order":1},{"name":"Chris Coy","character":"Babbitt","img":null,"order":2},{"name":"Troy Kotsur","character":"Joe Mancuso","img":null,"order":3},{"name":"Abbey Lee","character":"Anna","img":null,"order":4},{"name":"Odessa Young","character":"Gen","img":null,"order":5},{"name":"Robin de Jes\u00fas","character":"Tony","img":null,"order":6},{"name":"Cleopatra Coleman","character":"Estelle","img":null,"order":500},{"name":"\u1e62\u1ecdp\u1eb9\u0301 D\u00ecr\u00eds\u00f9","character":"Wes","img":null,"order":501},{"name":"Amaka Okafor","character":"Roxie","img":null,"order":502},{"name":"Dagmara Dominczyk","character":"Val","img":null,"order":503},{"name":"Don Harvey","character":"Matt","img":null,"order":504},{"name":"Gus Birney","character":"Mel Whitney","img":null,"order":505},{"name":"Forrest Weber","character":"Junior","img":null,"order":506},{"name":"Michael Cash","character":"Hunter","img":null,"order":510}],"tv:61381":[{"name":"Anthony Anderson","character":"Andre Johnson","img":null,"order":0},{"name":"Tracee Ellis Ross","character":"Rainbow Johnson","img":null,"order":1},{"name":"Yara Shahidi","character":"Zoey Johnson","img":null,"order":2},{"name":"Marcus Scribner","character":"Junior Johnson","img":null,"order":3},{"name":"Marsai Martin","character":"Diane Johnson","img":null,"order":4},{"name":"Miles Brown","character":"Jack Johnson","img":null,"order":5},{"name":"Jenifer Lewis","character":"Ruby Johnson","img":null,"order":6},{"name":"Deon Cole","character":"Charlie Telphy","img":null,"order":7},{"name":"Peter MacKenzie","character":"Leslie Stevens","img":null,"order":8},{"name":"Jeff Meacham","character":"Josh Oppenhol","img":null,"order":9},{"name":"Katlyn Nichol","character":"Olivia Lockhart","img":null,"order":10},{"name":"Laurence Fishburne","character":"Pops Johnson","img":null,"order":500},{"name":"Nelson Franklin","character":"Connor Stevens","img":null,"order":534},{"name":"Berlin Gross","character":"Devante Johnson","img":null,"order":562},{"name":"August Gross","character":"Devante Johnson","img":null,"order":563}],"tv:1396":[{"name":"Bryan Cranston","character":"Walter White","img":null,"order":0},{"name":"Aaron Paul","character":"Jesse Pinkman","img":null,"order":1},{"name":"Anna Gunn","character":"Skyler White","img":null,"order":2},{"name":"RJ Mitte","character":"Walter White Jr.","img":null,"order":3},{"name":"Dean Norris","character":"Hank Schrader","img":null,"order":4},{"name":"Betsy Brandt","character":"Marie Schrader","img":null,"order":5},{"name":"Giancarlo Esposito","character":"Gustavo Fring","img":null,"order":6},{"name":"Bob Odenkirk","character":"Saul Goodman","img":null,"order":7},{"name":"Steven Michael Quezada","character":"Steven Gomez","img":null,"order":8},{"name":"Jonathan Banks","character":"Mike Ehrmantraut","img":null,"order":9},{"name":"Christopher Cousins","character":"Ted Beneke","img":null,"order":604},{"name":"Michael Shamus Wiles","character":"ASAC George Merkert","img":null,"order":606},{"name":"Lavell Crawford","character":"Huell","img":null,"order":637},{"name":"Charles Baker","character":"Skinny Pete","img":null,"order":656},{"name":"Matt Jones","character":"Badger","img":null,"order":658}],"tv:93166":[{"name":"Holliday Grainger","character":"DI Rachel Carey","img":null,"order":0},{"name":"Callum Turner","character":"Shaun Emery","img":null,"order":1},{"name":"Ben Miles","character":"Commander Danny Hart","img":null,"order":2},{"name":"Lia Williams","character":"DSU Gemma Garland","img":null,"order":3},{"name":"Ron Perlman","character":"Frank Napier","img":null,"order":4},{"name":"Laura Haddock","character":"Hannah Roberts","img":null,"order":5},{"name":"Barry Ward","character":"Charlie Hall","img":null,"order":6},{"name":"Ginny Holder","character":"DC / DI Nadia Latif","img":null,"order":7},{"name":"Cavan Clerkin","character":"DS Patrick Flynn","img":null,"order":8},{"name":"Indira Varma","character":"Khadija Khan","img":null,"order":10},{"name":"Tessa Wong","character":"DC Chloe Tan","img":null,"order":12},{"name":"Andy Nyman","character":"Rowan Gill","img":null,"order":13},{"name":"Daisy Waterstone","character":"Abigail Carey","img":null,"order":15},{"name":"Nigel Lindsay","character":"DSI / DSU Tom Kendricks","img":null,"order":106},{"name":"Paapa Essiedu","character":"Isaac Turner","img":null,"order":160}]},"availableArt":["assets/cast/26R1LBiSOkkP08saSsz6LmVTY16.jpg","assets/cast/2tFblvjBRUYwcVT1V1i79Ppd6wG.jpg","assets/cast/320qW5yEbxpmyxQ3evmClJbtKag.jpg","assets/cast/4F8XpjyQCvtuu21WFm5d8RF5Rl.jpg","assets/cast/4eOoW1PNBZfxRW0g8RmYH8bL6mq.jpg","assets/cast/4gyHyg6FJ1oFczOm5pmMkdEEo2J.jpg","assets/cast/5L0kzTVITmOQdQ94NhicKM8ecCX.jpg","assets/cast/5VbadQsYCKdiJysP01LJFPmYB8A.jpg","assets/cast/5eIRHUbNOH7ibXa0IfUfFvj5I5L.jpg","assets/cast/5hn7WeXi6wguwxTPTSmcmzHAs9.jpg","assets/cast/6hmUs5Q1EETapn32yKNt3c3i1sn.jpg","assets/cast/7LVYeFTgUpjYDrxnU7Wm5ZQUX9t.jpg","assets/cast/7MHdNxS1gRnx0ZQGPrfS5eRjMe3.jpg","assets/cast/7Y96dAfg0HcFrcLjlD5eD9N0uj4.jpg","assets/cast/8v3lDa0QCJlDtOx9flqlMNIA3uf.jpg","assets/cast/9pxaoasotR1pdCXYSfN1pkm0geO.jpg","assets/cast/aHQk6XxqyJinfvrVRADEIg31nOk.jpg","assets/cast/aW6vCxkUZtwb6iH2Wf88Uq0XNVv.jpg","assets/cast/bLgmpSFgEiSFNshqmdl3EIZkRZm.jpg","assets/cast/biov5jENp2XYfehkcdnRvi796Wi.jpg","assets/cast/d81K0RH8UX7tZj49tZaQhZ9ewH.jpg","assets/cast/fD8GuLHOOSSAG98VjwN3NhAmqAJ.jpg","assets/cast/fbWWkhe7GVSlhBljY89rJd01OnA.jpg","assets/cast/fdFVatb9pt5dfT9tDK8tikKWafS.jpg","assets/cast/fjJc03z1cOlMxLZbC1qihsq3C37.jpg","assets/cast/hOntuFYAMwn9QaXT0AwLCPU79ce.jpg","assets/cast/hrTwOPWek7nkPJgFhh6inFu7vSS.jpg","assets/cast/hzu7OqTmNCT1xdCdmwBSf2yJvaO.jpg","assets/cast/iQLEawIP2593yrGy22GzLSpnfgl.jpg","assets/cast/j0GXzLelO1dOzI7d1WVIwQXhLz8.jpg","assets/cast/jUuUbPuMGonFT5E2pcs4alfqaCN.jpg","assets/cast/lF06PTNYrlXeJ3DYApvOcPXJr87.jpg","assets/cast/lUhVV9u5VGMCNdCAVhGzg8GFSdo.jpg","assets/cast/lawJUdbLb1YW0niaYjiVGR9IBG8.jpg","assets/cast/lfbyJWNWGbiYfU0Yr1tjn6Trd2V.jpg","assets/cast/lpEs9yDsMQlsbm0RVsvDIleCXcI.jpg","assets/cast/mF5YJxApTYKBVFJDrEC9IrJ5ooV.jpg","assets/cast/mW7xmtGV4y79kQGn0zkKVGDMAmw.jpg","assets/cast/mk5vpYLmER7asqOhEwVKXD3P3YE.jpg","assets/cast/mnKYU7HIsuRkx3YjdRO5FLXCdX5.jpg","assets/cast/msqe5A1q5YUUND0RhzB9dw1AEAO.jpg","assets/cast/nAxS5l9vb1C8ltCp9yAa0f6lazu.jpg","assets/cast/nmgOd3X2Xn3jIp9OLCRJzLExRWN.jpg","assets/cast/o7splcOIVAdbHnwohJOUAvXWVlk.jpg","assets/cast/oMHMLhoV3ry8aOfdvs1kxyowhNq.jpg","assets/cast/omWXGbeRR32MWuYhpnLOSqJ6xkO.jpg","assets/cast/pVwR9hsEiHzVTo9giCjR3vIfa8W.jpg","assets/cast/phEIvq0Ay2KjI5ewmVvpQ1a29GJ.jpg","assets/cast/qP5vQMIbLNvSsSFkEMLZRVt4ZW5.jpg","assets/cast/qiWu2gphSg64igYl3Nx0hEIOQF3.jpg","assets/cast/qwbjcyDN37OHiln4a6P4LP31o7F.jpg","assets/cast/r6s7dkYZUJpd00C7p9itT6Gp8XB.jpg","assets/cast/rDTxblyw0AwU5oSeksgP7GwMyrF.jpg","assets/cast/rIqcwewXdkrDTMTwX56QPa7MNTC.jpg","assets/cast/rLzduQpYJnZJKkXv3jRc7MDHwoI.jpg","assets/cast/rbxBK2m6fEq0oHeMoBUMVYkJEdJ.jpg","assets/cast/sG6CWLdENCtzukNFkFYyPxqyRmS.jpg","assets/cast/sh4ANkKoIHgmHtkKQbJvF8y0Fjq.jpg","assets/cast/tqFHQiJUycuob3ytvilaAWDlbQ8.jpg","assets/cast/uL8yfcm0dCFYFQt052kczVQVvac.jpg","assets/cast/ub2IuMWFNQGYghHTPq0lpmn2Ue0.jpg","assets/cast/ukDNHgvEgdU95eaw6pngiAPucv4.jpg","assets/cast/v4sRxLpRpHEd9vbk43wm9VL0v0K.jpg","assets/cast/wWcby4ARYqr8d92ZdjyQcfaiJBW.jpg","assets/cast/waayy0jpNbxLDQ8JO1uRDng8SLF.jpg","assets/cast/x0lmqgkmphvOCSTHk2oxsaxA9Ra.jpg","assets/cast/xKBAaPIa1c7tzZD3Y0MhBLv4hPE.jpg","assets/cast/xV9UrP8kZdxOiTI2efDFhp3t4iA.jpg","assets/cast/xm2pYFBggiXSkFBV2I612i3fDd3.jpg","assets/cast/xx3As5SWcE8vYOKZgtjDjqmT3jc.jpg","assets/cast/yU0OXeZ0K1ppe1o9SpHiAMHy1rc.jpg","assets/cast/yWZILsr2mBQBCG1LOcCYYshIbts.jpg","assets/cast/yxGsAKnrJZs2g6q4unNgkfm7NAA.jpg","assets/cast/ztxDIZvuPreUixO6ZPxwkCg2UlO.jpg","assets/episode-all-hands-on-deck-class-1-a-2021-s5e1-backdrop.jpg","assets/episode-all-hands-on-deck-class-1-a-2021-s5e1-poster.jpg","assets/episode-announcement-2022-s1e7-backdrop.jpg","assets/episode-announcement-2022-s1e7-poster.jpg","assets/episode-episode-1-2025-s1e1-backdrop.jpg","assets/episode-episode-1-2025-s1e1-poster.jpg","assets/episode-episode-2-2016-s1e2-backdrop.jpg","assets/episode-episode-2-2016-s1e2-poster.jpg","assets/episode-erickerhead-2026-s9e6-backdrop.jpg","assets/episode-erickerhead-2026-s9e6-poster.jpg","assets/episode-girls-interrupted-2007-s1e7-backdrop.jpg","assets/episode-girls-interrupted-2007-s1e7-poster.jpg","assets/episode-i-heart-ny-2002-s4e18-backdrop.jpg","assets/episode-i-heart-ny-2002-s4e18-poster.jpg","assets/episode-new-day-2021-s1e2-backdrop.jpg","assets/episode-new-day-2021-s1e2-poster.jpg","assets/episode-no-honeymoon-2020-s1e8-backdrop.jpg","assets/episode-no-honeymoon-2020-s1e8-poster.jpg","assets/episode-notapusy-2005-s3e4-backdrop.jpg","assets/episode-notapusy-2005-s3e4-poster.jpg","assets/episode-one-of-us-2024-s1e7-backdrop.jpg","assets/episode-one-of-us-2024-s1e7-poster.jpg","assets/episode-remembrance-day-2026-s2e1-backdrop.jpg","assets/episode-remembrance-day-2026-s2e1-poster.jpg","assets/episode-sex-and-the-country-2001-s4e9-backdrop.jpg","assets/episode-sex-and-the-country-2001-s4e9-poster.jpg","assets/episode-south-american-biker-gangs-2026-s29e1-backdrop.jpg","assets/episode-south-american-biker-gangs-2026-s29e1-poster.jpg","assets/episode-the-breakup-part-2-2001-s1e17-backdrop.jpg","assets/episode-the-breakup-part-2-2001-s1e17-poster.jpg","assets/episode-the-man-who-would-be-vogue-2018-s2e1-backdrop.jpg","assets/episode-the-man-who-would-be-vogue-2018-s2e1-poster.jpg","assets/episode-the-uncomfortability-2010-s1e2-backdrop.jpg","assets/episode-the-uncomfortability-2010-s1e2-poster.jpg","assets/episode-three-monsters-1992-s1e6-backdrop.jpg","assets/episode-three-monsters-1992-s1e6-poster.jpg","assets/episode-tomorrow-2024-s3e1-backdrop.jpg","assets/episode-tomorrow-2024-s3e1-poster.jpg","assets/episode-what-more-do-i-need-2008-s5e7-backdrop.jpg","assets/episode-what-more-do-i-need-2008-s5e7-poster.jpg","assets/movie-101-dalmatians-ii-patch-s-london-adventure-2003-backdrop.jpg","assets/movie-101-dalmatians-ii-patch-s-london-adventure-2003-poster.jpg","assets/movie-a-bronx-tale-1993-backdrop.jpg","assets/movie-a-bronx-tale-1993-poster.jpg","assets/movie-a-silent-voice-the-movie-2016-backdrop.jpg","assets/movie-a-silent-voice-the-movie-2016-poster.jpg","assets/movie-absolution-2024-backdrop.jpg","assets/movie-absolution-2024-poster.jpg","assets/movie-across-the-hall-2009-backdrop.jpg","assets/movie-across-the-hall-2009-poster.jpg","assets/movie-addicted-2014-backdrop.jpg","assets/movie-addicted-2014-poster.jpg","assets/movie-adulterers-2016-backdrop.jpg","assets/movie-adulterers-2016-poster.jpg","assets/movie-all-the-money-in-the-world-2017-backdrop.jpg","assets/movie-all-the-money-in-the-world-2017-poster.jpg","assets/movie-alone-with-her-2006-backdrop.jpg","assets/movie-alone-with-her-2006-poster.jpg","assets/movie-american-gangster-2007-backdrop.jpg","assets/movie-american-gangster-2007-poster.jpg","assets/movie-annie-hall-1977-backdrop.jpg","assets/movie-annie-hall-1977-poster.jpg","assets/movie-ant-man-and-the-wasp-quantumania-2023-backdrop.jpg","assets/movie-ant-man-and-the-wasp-quantumania-2023-poster.jpg","assets/movie-appleseed-alpha-2014-backdrop.jpg","assets/movie-appleseed-alpha-2014-poster.jpg","assets/movie-aquaman-and-the-lost-kingdom-2023-backdrop.jpg","assets/movie-aquaman-and-the-lost-kingdom-2023-poster.jpg","assets/movie-arctic-dogs-2019-backdrop.jpg","assets/movie-arctic-dogs-2019-poster.jpg","assets/movie-arrival-2016-backdrop.jpg","assets/movie-arrival-2016-poster.jpg","assets/movie-avatar-aang-the-last-airbender-2026-backdrop.jpg","assets/movie-avatar-aang-the-last-airbender-2026-poster.jpg","assets/movie-avengers-age-of-ultron-2015-backdrop.jpg","assets/movie-avengers-age-of-ultron-2015-poster.jpg","assets/movie-avengers-confidential-black-widow-punisher-2014-backdrop.jpg","assets/movie-avengers-confidential-black-widow-punisher-2014-poster.jpg","assets/movie-avengers-infinity-war-2018-backdrop.jpg","assets/movie-avengers-infinity-war-2018-poster.jpg","assets/movie-awake-2007-backdrop.jpg","assets/movie-awake-2007-poster.jpg","assets/movie-batman-ninja-2018-backdrop.jpg","assets/movie-batman-ninja-2018-poster.jpg","assets/movie-batman-the-dark-knight-returns-part-1-2012-backdrop.jpg","assets/movie-batman-the-dark-knight-returns-part-1-2012-poster.jpg","assets/movie-batman-v-superman-dawn-of-justice-2016-backdrop.jpg","assets/movie-batman-v-superman-dawn-of-justice-2016-poster.jpg","assets/movie-black-adam-2022-backdrop.jpg","assets/movie-black-adam-2022-poster.jpg","assets/movie-black-bear-2020-backdrop.jpg","assets/movie-black-bear-2020-poster.jpg","assets/movie-black-panther-2018-backdrop.jpg","assets/movie-black-panther-2018-poster.jpg","assets/movie-black-panther-wakanda-forever-2022-backdrop.jpg","assets/movie-black-panther-wakanda-forever-2022-poster.jpg","assets/movie-blame-2017-backdrop.jpg","assets/movie-blame-2017-poster.jpg","assets/movie-bleach-the-movie-fade-to-black-2008-backdrop.jpg","assets/movie-bleach-the-movie-fade-to-black-2008-poster.jpg","assets/movie-butterfly-on-a-wheel-2007-backdrop.jpg","assets/movie-butterfly-on-a-wheel-2007-poster.jpg","assets/movie-captain-america-civil-war-2016-backdrop.jpg","assets/movie-captain-america-civil-war-2016-poster.jpg","assets/movie-careful-what-you-wish-for-2015-backdrop.jpg","assets/movie-careful-what-you-wish-for-2015-poster.jpg","assets/movie-castle-in-the-sky-1986-backdrop.jpg","assets/movie-castle-in-the-sky-1986-poster.jpg","assets/movie-chicago-2002-backdrop.jpg","assets/movie-chicago-2002-poster.jpg","assets/movie-citizen-kane-1941-backdrop.jpg","assets/movie-citizen-kane-1941-poster.jpg","assets/movie-conclave-2024-backdrop.jpg","assets/movie-conclave-2024-poster.jpg","assets/movie-crime-of-passion-1956-backdrop.jpg","assets/movie-crime-of-passion-1956-poster.jpg","assets/movie-deep-water-2022-backdrop.jpg","assets/movie-deep-water-2022-poster.jpg","assets/movie-derailed-2005-backdrop.jpg","assets/movie-derailed-2005-poster.jpg","assets/movie-dream-house-2011-backdrop.jpg","assets/movie-dream-house-2011-poster.jpg","assets/movie-dream-lover-1994-backdrop.jpg","assets/movie-dream-lover-1994-poster.jpg","assets/movie-drop-2025-backdrop.jpg","assets/movie-drop-2025-poster.jpg","assets/movie-eastern-promises-2007-backdrop.jpg","assets/movie-eastern-promises-2007-poster.jpg","assets/movie-el-camino-a-breaking-bad-movie-2019-backdrop.jpg","assets/movie-el-camino-a-breaking-bad-movie-2019-poster.jpg","assets/movie-fatale-2020-backdrop.jpg","assets/movie-fatale-2020-poster.jpg","assets/movie-force-of-nature-the-dry-2-2024-backdrop.jpg","assets/movie-force-of-nature-the-dry-2-2024-poster.jpg","assets/movie-ghost-in-the-shell-1995-backdrop.jpg","assets/movie-ghost-in-the-shell-1995-poster.jpg","assets/movie-ghost-in-the-shell-2-innocence-2004-backdrop.jpg","assets/movie-ghost-in-the-shell-2-innocence-2004-poster.jpg","assets/movie-gosford-park-2001-backdrop.jpg","assets/movie-gosford-park-2001-poster.jpg","assets/movie-howl-s-moving-castle-2004-backdrop.jpg","assets/movie-howl-s-moving-castle-2004-poster.jpg","assets/movie-in-the-heights-2021-backdrop.jpg","assets/movie-in-the-heights-2021-poster.jpg","assets/movie-kiki-s-delivery-service-1989-backdrop.jpg","assets/movie-kiki-s-delivery-service-1989-poster.jpg","assets/movie-lemony-snicket-s-a-series-of-unfortunate-events-2004-backdrop.jpg","assets/movie-lemony-snicket-s-a-series-of-unfortunate-events-2004-poster.jpg","assets/movie-locke-2014-backdrop.jpg","assets/movie-locke-2014-poster.jpg","assets/movie-memories-1995-backdrop.jpg","assets/movie-memories-1995-poster.jpg","assets/movie-night-is-short-walk-on-girl-2017-backdrop.jpg","assets/movie-night-is-short-walk-on-girl-2017-poster.jpg","assets/movie-panic-room-2002-backdrop.jpg","assets/movie-panic-room-2002-poster.jpg","assets/movie-ponyo-2008-backdrop.jpg","assets/movie-ponyo-2008-poster.jpg","assets/movie-porco-rosso-1992-backdrop.jpg","assets/movie-porco-rosso-1992-poster.jpg","assets/movie-princess-mononoke-1997-backdrop.jpg","assets/movie-princess-mononoke-1997-poster.jpg","assets/movie-prisoners-2013-backdrop.jpg","assets/movie-prisoners-2013-poster.jpg","assets/movie-racing-stripes-2005-backdrop.jpg","assets/movie-racing-stripes-2005-poster.jpg","assets/movie-secondhand-lions-2003-backdrop.jpg","assets/movie-secondhand-lions-2003-poster.jpg","assets/movie-shaft-2000-backdrop.jpg","assets/movie-shaft-2000-poster.jpg","assets/movie-sinbad-legend-of-the-seven-seas-2003-backdrop.jpg","assets/movie-sinbad-legend-of-the-seven-seas-2003-poster.jpg","assets/movie-sleeping-with-other-people-2015-backdrop.jpg","assets/movie-sleeping-with-other-people-2015-poster.jpg","assets/movie-snowpiercer-2013-backdrop.jpg","assets/movie-snowpiercer-2013-poster.jpg","assets/movie-spider-man-brand-new-day-2026-backdrop.jpg","assets/movie-spider-man-brand-new-day-2026-poster.jpg","assets/movie-spider-man-far-from-home-2019-backdrop.jpg","assets/movie-spider-man-far-from-home-2019-poster.jpg","assets/movie-spider-man-homecoming-2017-backdrop.jpg","assets/movie-spider-man-homecoming-2017-poster.jpg","assets/movie-spider-man-no-way-home-2021-backdrop.jpg","assets/movie-spider-man-no-way-home-2021-poster.jpg","assets/movie-spirited-away-2001-backdrop.jpg","assets/movie-spirited-away-2001-poster.jpg","assets/movie-the-alto-knights-2025-backdrop.jpg","assets/movie-the-alto-knights-2025-poster.jpg","assets/movie-the-amazing-spider-man-2-2014-backdrop.jpg","assets/movie-the-amazing-spider-man-2-2014-poster.jpg","assets/movie-the-amazing-spider-man-2012-backdrop.jpg","assets/movie-the-amazing-spider-man-2012-poster.jpg","assets/movie-the-animatrix-2003-backdrop.jpg","assets/movie-the-animatrix-2003-poster.jpg","assets/movie-the-avengers-2012-backdrop.jpg","assets/movie-the-avengers-2012-poster.jpg","assets/movie-the-boy-and-the-heron-2023-backdrop.jpg","assets/movie-the-boy-and-the-heron-2023-poster.jpg","assets/movie-the-breakfast-club-1985-backdrop.jpg","assets/movie-the-breakfast-club-1985-poster.jpg","assets/movie-the-dry-2021-backdrop.jpg","assets/movie-the-dry-2021-poster.jpg","assets/movie-the-girl-who-leapt-through-time-2006-backdrop.jpg","assets/movie-the-girl-who-leapt-through-time-2006-poster.jpg","assets/movie-the-godfather-1972-backdrop.jpg","assets/movie-the-godfather-1972-poster.jpg","assets/movie-the-godfather-part-iii-1990-backdrop.jpg","assets/movie-the-godfather-part-iii-1990-poster.jpg","assets/movie-the-great-gatsby-2013-backdrop.jpg","assets/movie-the-great-gatsby-2013-poster.jpg","assets/movie-the-killing-of-a-sacred-deer-2017-backdrop.jpg","assets/movie-the-killing-of-a-sacred-deer-2017-poster.jpg","assets/movie-the-lighthouse-2019-backdrop.jpg","assets/movie-the-lighthouse-2019-poster.jpg","assets/movie-the-secret-life-of-pets-2-2019-backdrop.jpg","assets/movie-the-secret-life-of-pets-2-2019-poster.jpg","assets/movie-the-tale-of-the-princess-kaguya-2013-backdrop.jpg","assets/movie-the-tale-of-the-princess-kaguya-2013-poster.jpg","assets/movie-the-wild-robot-2024-backdrop.jpg","assets/movie-the-wild-robot-2024-poster.jpg","assets/movie-the-witcher-nightmare-of-the-wolf-2021-backdrop.jpg","assets/movie-the-witcher-nightmare-of-the-wolf-2021-poster.jpg","assets/movie-the-witcher-sirens-of-the-deep-2025-backdrop.jpg","assets/movie-the-witcher-sirens-of-the-deep-2025-poster.jpg","assets/movie-thelma-louise-1991-backdrop.jpg","assets/movie-thelma-louise-1991-poster.jpg","assets/movie-triangle-of-sadness-2022-backdrop.jpg","assets/movie-triangle-of-sadness-2022-poster.jpg","assets/movie-vice-2018-backdrop.jpg","assets/movie-vice-2018-poster.jpg","assets/tv-12-monkeys-2015-backdrop.jpg","assets/tv-12-monkeys-2015-poster.jpg","assets/tv-56-days-2026-backdrop.jpg","assets/tv-56-days-2026-poster.jpg","assets/tv-a-knight-of-the-seven-kingdoms-2026-backdrop.jpg","assets/tv-a-knight-of-the-seven-kingdoms-2026-poster.jpg","assets/tv-absolutely-fabulous-1992-backdrop.jpg","assets/tv-absolutely-fabulous-1992-poster.jpg","assets/tv-accel-world-2012-backdrop.jpg","assets/tv-accel-world-2012-poster.jpg","assets/tv-accused-2023-backdrop.jpg","assets/tv-accused-2023-poster.jpg","assets/tv-after-life-2019-backdrop.jpg","assets/tv-after-life-2019-poster.jpg","assets/tv-agatha-christie-s-marple-2004-backdrop.jpg","assets/tv-agatha-christie-s-marple-2004-poster.jpg","assets/tv-ahsoka-2023-backdrop.jpg","assets/tv-ahsoka-2023-poster.jpg","assets/tv-all-creatures-great-and-small-1978-backdrop.jpg","assets/tv-all-creatures-great-and-small-1978-poster.jpg","assets/tv-all-creatures-great-small-2020-backdrop.jpg","assets/tv-all-creatures-great-small-2020-poster.jpg","assets/tv-american-dad-2005-backdrop.jpg","assets/tv-american-dad-2005-poster.jpg","assets/tv-american-gods-2017-backdrop.jpg","assets/tv-american-gods-2017-poster.jpg","assets/tv-american-housewife-2016-backdrop.jpg","assets/tv-american-housewife-2016-poster.jpg","assets/tv-american-primeval-2025-backdrop.jpg","assets/tv-american-primeval-2025-poster.jpg","assets/tv-and-just-like-that-2021-backdrop.jpg","assets/tv-and-just-like-that-2021-poster.jpg","assets/tv-andor-2022-backdrop.jpg","assets/tv-andor-2022-poster.jpg","assets/tv-andromeda-2000-backdrop.jpg","assets/tv-andromeda-2000-poster.jpg","assets/tv-anne-with-an-e-2017-backdrop.jpg","assets/tv-anne-with-an-e-2017-poster.jpg","assets/tv-aqua-teen-hunger-force-2000-backdrop.jpg","assets/tv-aqua-teen-hunger-force-2000-poster.jpg","assets/tv-arifureta-from-commonplace-to-world-s-strongest-2019-backdrop.jpg","assets/tv-arifureta-from-commonplace-to-world-s-strongest-2019-poster.jpg","assets/tv-arrow-2012-backdrop.jpg","assets/tv-arrow-2012-poster.jpg","assets/tv-atlantis-2013-backdrop.jpg","assets/tv-atlantis-2013-poster.jpg","assets/tv-avatar-seven-havens-2026-backdrop.jpg","assets/tv-avatar-seven-havens-2026-poster.jpg","assets/tv-avatar-the-last-airbender-2005-backdrop.jpg","assets/tv-avatar-the-last-airbender-2005-poster.jpg","assets/tv-avatar-the-last-airbender-2024-backdrop.jpg","assets/tv-avatar-the-last-airbender-2024-poster.jpg","assets/tv-awkward-2011-backdrop.jpg","assets/tv-awkward-2011-poster.jpg","assets/tv-back-to-life-2019-backdrop.jpg","assets/tv-back-to-life-2019-poster.jpg","assets/tv-ballers-2015-backdrop.jpg","assets/tv-ballers-2015-poster.jpg","assets/tv-baretta-1975-backdrop.jpg","assets/tv-baretta-1975-poster.jpg","assets/tv-based-on-a-true-story-2023-backdrop.jpg","assets/tv-based-on-a-true-story-2023-poster.jpg","assets/tv-batman-the-brave-and-the-bold-2008-backdrop.jpg","assets/tv-batman-the-brave-and-the-bold-2008-poster.jpg","assets/tv-batwoman-2019-backdrop.jpg","assets/tv-batwoman-2019-poster.jpg","assets/tv-big-boys-2022-backdrop.jpg","assets/tv-big-boys-2022-poster.jpg","assets/tv-big-city-greens-2018-backdrop.jpg","assets/tv-big-city-greens-2018-poster.jpg","assets/tv-big-mouth-2017-backdrop.jpg","assets/tv-big-mouth-2017-poster.jpg","assets/tv-black-lightning-2018-backdrop.jpg","assets/tv-black-lightning-2018-poster.jpg","assets/tv-black-rabbit-2025-backdrop.jpg","assets/tv-black-rabbit-2025-poster.jpg","assets/tv-bleach-2004-backdrop.jpg","assets/tv-bleach-2004-poster.jpg","assets/tv-brassic-2019-backdrop.jpg","assets/tv-brassic-2019-poster.jpg","assets/tv-breaking-bad-2008-backdrop.jpg","assets/tv-breaking-bad-2008-poster.jpg","assets/tv-californication-2007-backdrop.jpg","assets/tv-californication-2007-poster.jpg","assets/tv-chainsaw-man-2022-backdrop.jpg","assets/tv-chainsaw-man-2022-poster.jpg","assets/tv-cyberpunk-edgerunners-2022-backdrop.jpg","assets/tv-cyberpunk-edgerunners-2022-poster.jpg","assets/tv-derry-girls-2018-backdrop.jpg","assets/tv-derry-girls-2018-poster.jpg","assets/tv-desperate-housewives-2004-backdrop.jpg","assets/tv-desperate-housewives-2004-poster.jpg","assets/tv-dune-prophecy-2024-backdrop.jpg","assets/tv-dune-prophecy-2024-poster.jpg","assets/tv-etoile-2025-backdrop.jpg","assets/tv-etoile-2025-poster.jpg","assets/tv-fallout-2024-backdrop.jpg","assets/tv-fallout-2024-poster.jpg","assets/tv-firefly-2002-backdrop.jpg","assets/tv-firefly-2002-poster.jpg","assets/tv-fleabag-2016-backdrop.jpg","assets/tv-fleabag-2016-poster.jpg","assets/tv-gilmore-girls-2000-backdrop.jpg","assets/tv-gilmore-girls-2000-poster.jpg","assets/tv-high-potential-2024-backdrop.jpg","assets/tv-high-potential-2024-poster.jpg","assets/tv-invincible-2021-backdrop.jpg","assets/tv-invincible-2021-poster.jpg","assets/tv-last-samurai-standing-2025-backdrop.jpg","assets/tv-last-samurai-standing-2025-poster.jpg","assets/tv-lord-of-the-flies-2026-backdrop.jpg","assets/tv-lord-of-the-flies-2026-poster.jpg","assets/tv-love-death-robots-2019-backdrop.jpg","assets/tv-love-death-robots-2019-poster.jpg","assets/tv-maniac-2018-backdrop.jpg","assets/tv-maniac-2018-poster.jpg","assets/tv-neon-genesis-evangelion-1995-backdrop.jpg","assets/tv-neon-genesis-evangelion-1995-poster.jpg","assets/tv-norsemen-2016-backdrop.jpg","assets/tv-norsemen-2016-poster.jpg","assets/tv-one-piece-2023-backdrop.jpg","assets/tv-one-piece-2023-poster.jpg","assets/tv-only-murders-in-the-building-2021-backdrop.jpg","assets/tv-only-murders-in-the-building-2021-poster.jpg","assets/tv-over-the-garden-wall-2014-backdrop.jpg","assets/tv-over-the-garden-wall-2014-poster.jpg","assets/tv-pluribus-2025-backdrop.jpg","assets/tv-pluribus-2025-poster.jpg","assets/tv-rick-and-morty-2013-backdrop.jpg","assets/tv-rick-and-morty-2013-poster.jpg","assets/tv-secret-level-2024-backdrop.jpg","assets/tv-secret-level-2024-poster.jpg","assets/tv-severance-2022-backdrop.jpg","assets/tv-severance-2022-poster.jpg","assets/tv-sex-and-the-city-1998-backdrop.jpg","assets/tv-sex-and-the-city-1998-poster.jpg","assets/tv-the-100-2014-backdrop.jpg","assets/tv-the-100-2014-poster.jpg","assets/tv-the-abbott-and-costello-show-1952-backdrop.jpg","assets/tv-the-abbott-and-costello-show-1952-poster.jpg","assets/tv-the-afterparty-2022-backdrop.jpg","assets/tv-the-afterparty-2022-poster.jpg","assets/tv-the-bear-2022-backdrop.jpg","assets/tv-the-bear-2022-poster.jpg","assets/tv-the-beast-in-me-2025-backdrop.jpg","assets/tv-the-beast-in-me-2025-poster.jpg","assets/tv-the-bold-type-2017-backdrop.jpg","assets/tv-the-bold-type-2017-poster.jpg","assets/tv-the-boys-2019-backdrop.jpg","assets/tv-the-boys-2019-poster.jpg","assets/tv-the-capture-2019-backdrop.jpg","assets/tv-the-capture-2019-poster.jpg","assets/tv-the-durrells-2016-backdrop.jpg","assets/tv-the-durrells-2016-poster.jpg","assets/tv-the-final-problem-2026-backdrop.jpg","assets/tv-the-final-problem-2026-poster.jpg","assets/tv-the-legend-of-korra-2012-backdrop.jpg","assets/tv-the-legend-of-korra-2012-poster.jpg","assets/tv-the-lord-of-the-rings-the-rings-of-power-2022-backdrop.jpg","assets/tv-the-lord-of-the-rings-the-rings-of-power-2022-poster.jpg","assets/tv-the-night-manager-2016-backdrop.jpg","assets/tv-the-night-manager-2016-poster.jpg","assets/tv-the-tatami-galaxy-2010-backdrop.jpg","assets/tv-the-tatami-galaxy-2010-poster.jpg","assets/tv-the-white-lotus-2021-backdrop.jpg","assets/tv-the-white-lotus-2021-poster.jpg","assets/tv-the-witcher-2019-backdrop.jpg","assets/tv-the-witcher-2019-poster.jpg","assets/tv-upload-2020-backdrop.jpg","assets/tv-upload-2020-poster.jpg","assets/tv-widow-s-bay-2026-backdrop.jpg","assets/tv-widow-s-bay-2026-poster.jpg","assets/tv-yellowjackets-2021-backdrop.jpg","assets/tv-yellowjackets-2021-poster.jpg"]} diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/26R1LBiSOkkP08saSsz6LmVTY16.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/26R1LBiSOkkP08saSsz6LmVTY16.jpg deleted file mode 100644 index 12a79fbe..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/26R1LBiSOkkP08saSsz6LmVTY16.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/2tFblvjBRUYwcVT1V1i79Ppd6wG.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/2tFblvjBRUYwcVT1V1i79Ppd6wG.jpg deleted file mode 100644 index 51c11420..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/2tFblvjBRUYwcVT1V1i79Ppd6wG.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/320qW5yEbxpmyxQ3evmClJbtKag.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/320qW5yEbxpmyxQ3evmClJbtKag.jpg deleted file mode 100644 index 0c5b151f..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/320qW5yEbxpmyxQ3evmClJbtKag.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/4F8XpjyQCvtuu21WFm5d8RF5Rl.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/4F8XpjyQCvtuu21WFm5d8RF5Rl.jpg deleted file mode 100644 index a639becf..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/4F8XpjyQCvtuu21WFm5d8RF5Rl.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/4eOoW1PNBZfxRW0g8RmYH8bL6mq.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/4eOoW1PNBZfxRW0g8RmYH8bL6mq.jpg deleted file mode 100644 index f0a4e83a..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/4eOoW1PNBZfxRW0g8RmYH8bL6mq.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/4gyHyg6FJ1oFczOm5pmMkdEEo2J.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/4gyHyg6FJ1oFczOm5pmMkdEEo2J.jpg deleted file mode 100644 index b28de566..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/4gyHyg6FJ1oFczOm5pmMkdEEo2J.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/5L0kzTVITmOQdQ94NhicKM8ecCX.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/5L0kzTVITmOQdQ94NhicKM8ecCX.jpg deleted file mode 100644 index 35a785df..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/5L0kzTVITmOQdQ94NhicKM8ecCX.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/5VbadQsYCKdiJysP01LJFPmYB8A.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/5VbadQsYCKdiJysP01LJFPmYB8A.jpg deleted file mode 100644 index 41618a2e..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/5VbadQsYCKdiJysP01LJFPmYB8A.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/5eIRHUbNOH7ibXa0IfUfFvj5I5L.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/5eIRHUbNOH7ibXa0IfUfFvj5I5L.jpg deleted file mode 100644 index 5c6e94de..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/5eIRHUbNOH7ibXa0IfUfFvj5I5L.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/5hn7WeXi6wguwxTPTSmcmzHAs9.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/5hn7WeXi6wguwxTPTSmcmzHAs9.jpg deleted file mode 100644 index 1b59f62f..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/5hn7WeXi6wguwxTPTSmcmzHAs9.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/6hmUs5Q1EETapn32yKNt3c3i1sn.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/6hmUs5Q1EETapn32yKNt3c3i1sn.jpg deleted file mode 100644 index 21dc4e89..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/6hmUs5Q1EETapn32yKNt3c3i1sn.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/7LVYeFTgUpjYDrxnU7Wm5ZQUX9t.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/7LVYeFTgUpjYDrxnU7Wm5ZQUX9t.jpg deleted file mode 100644 index dde817a1..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/7LVYeFTgUpjYDrxnU7Wm5ZQUX9t.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/7MHdNxS1gRnx0ZQGPrfS5eRjMe3.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/7MHdNxS1gRnx0ZQGPrfS5eRjMe3.jpg deleted file mode 100644 index 5094cb73..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/7MHdNxS1gRnx0ZQGPrfS5eRjMe3.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/7Y96dAfg0HcFrcLjlD5eD9N0uj4.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/7Y96dAfg0HcFrcLjlD5eD9N0uj4.jpg deleted file mode 100644 index 1f88cd10..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/7Y96dAfg0HcFrcLjlD5eD9N0uj4.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/8v3lDa0QCJlDtOx9flqlMNIA3uf.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/8v3lDa0QCJlDtOx9flqlMNIA3uf.jpg deleted file mode 100644 index 5d5930b7..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/8v3lDa0QCJlDtOx9flqlMNIA3uf.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/9pxaoasotR1pdCXYSfN1pkm0geO.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/9pxaoasotR1pdCXYSfN1pkm0geO.jpg deleted file mode 100644 index 6a483975..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/9pxaoasotR1pdCXYSfN1pkm0geO.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/aHQk6XxqyJinfvrVRADEIg31nOk.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/aHQk6XxqyJinfvrVRADEIg31nOk.jpg deleted file mode 100644 index a1df3481..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/aHQk6XxqyJinfvrVRADEIg31nOk.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/aW6vCxkUZtwb6iH2Wf88Uq0XNVv.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/aW6vCxkUZtwb6iH2Wf88Uq0XNVv.jpg deleted file mode 100644 index 50197dbe..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/aW6vCxkUZtwb6iH2Wf88Uq0XNVv.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/bLgmpSFgEiSFNshqmdl3EIZkRZm.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/bLgmpSFgEiSFNshqmdl3EIZkRZm.jpg deleted file mode 100644 index 5aa08a58..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/bLgmpSFgEiSFNshqmdl3EIZkRZm.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/biov5jENp2XYfehkcdnRvi796Wi.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/biov5jENp2XYfehkcdnRvi796Wi.jpg deleted file mode 100644 index 07813572..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/biov5jENp2XYfehkcdnRvi796Wi.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/d81K0RH8UX7tZj49tZaQhZ9ewH.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/d81K0RH8UX7tZj49tZaQhZ9ewH.jpg deleted file mode 100644 index 77d5fe66..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/d81K0RH8UX7tZj49tZaQhZ9ewH.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/fD8GuLHOOSSAG98VjwN3NhAmqAJ.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/fD8GuLHOOSSAG98VjwN3NhAmqAJ.jpg deleted file mode 100644 index 3c66e9a4..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/fD8GuLHOOSSAG98VjwN3NhAmqAJ.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/fbWWkhe7GVSlhBljY89rJd01OnA.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/fbWWkhe7GVSlhBljY89rJd01OnA.jpg deleted file mode 100644 index 15a25098..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/fbWWkhe7GVSlhBljY89rJd01OnA.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/fdFVatb9pt5dfT9tDK8tikKWafS.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/fdFVatb9pt5dfT9tDK8tikKWafS.jpg deleted file mode 100644 index 60531535..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/fdFVatb9pt5dfT9tDK8tikKWafS.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/fjJc03z1cOlMxLZbC1qihsq3C37.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/fjJc03z1cOlMxLZbC1qihsq3C37.jpg deleted file mode 100644 index 989ce70d..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/fjJc03z1cOlMxLZbC1qihsq3C37.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/hOntuFYAMwn9QaXT0AwLCPU79ce.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/hOntuFYAMwn9QaXT0AwLCPU79ce.jpg deleted file mode 100644 index 783d7043..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/hOntuFYAMwn9QaXT0AwLCPU79ce.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/hrTwOPWek7nkPJgFhh6inFu7vSS.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/hrTwOPWek7nkPJgFhh6inFu7vSS.jpg deleted file mode 100644 index 5f9dc239..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/hrTwOPWek7nkPJgFhh6inFu7vSS.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/hzu7OqTmNCT1xdCdmwBSf2yJvaO.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/hzu7OqTmNCT1xdCdmwBSf2yJvaO.jpg deleted file mode 100644 index 2b3d2015..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/hzu7OqTmNCT1xdCdmwBSf2yJvaO.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/iQLEawIP2593yrGy22GzLSpnfgl.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/iQLEawIP2593yrGy22GzLSpnfgl.jpg deleted file mode 100644 index 5965e06d..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/iQLEawIP2593yrGy22GzLSpnfgl.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/j0GXzLelO1dOzI7d1WVIwQXhLz8.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/j0GXzLelO1dOzI7d1WVIwQXhLz8.jpg deleted file mode 100644 index 0921d96c..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/j0GXzLelO1dOzI7d1WVIwQXhLz8.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/jUuUbPuMGonFT5E2pcs4alfqaCN.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/jUuUbPuMGonFT5E2pcs4alfqaCN.jpg deleted file mode 100644 index 7e03f82b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/jUuUbPuMGonFT5E2pcs4alfqaCN.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/lF06PTNYrlXeJ3DYApvOcPXJr87.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/lF06PTNYrlXeJ3DYApvOcPXJr87.jpg deleted file mode 100644 index 01f41d25..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/lF06PTNYrlXeJ3DYApvOcPXJr87.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/lUhVV9u5VGMCNdCAVhGzg8GFSdo.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/lUhVV9u5VGMCNdCAVhGzg8GFSdo.jpg deleted file mode 100644 index 8baff3f2..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/lUhVV9u5VGMCNdCAVhGzg8GFSdo.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/lawJUdbLb1YW0niaYjiVGR9IBG8.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/lawJUdbLb1YW0niaYjiVGR9IBG8.jpg deleted file mode 100644 index 11d18b7a..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/lawJUdbLb1YW0niaYjiVGR9IBG8.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/lfbyJWNWGbiYfU0Yr1tjn6Trd2V.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/lfbyJWNWGbiYfU0Yr1tjn6Trd2V.jpg deleted file mode 100644 index 64a37106..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/lfbyJWNWGbiYfU0Yr1tjn6Trd2V.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/lpEs9yDsMQlsbm0RVsvDIleCXcI.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/lpEs9yDsMQlsbm0RVsvDIleCXcI.jpg deleted file mode 100644 index 5ff2d6a1..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/lpEs9yDsMQlsbm0RVsvDIleCXcI.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/mF5YJxApTYKBVFJDrEC9IrJ5ooV.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/mF5YJxApTYKBVFJDrEC9IrJ5ooV.jpg deleted file mode 100644 index 2a4445ce..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/mF5YJxApTYKBVFJDrEC9IrJ5ooV.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/mW7xmtGV4y79kQGn0zkKVGDMAmw.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/mW7xmtGV4y79kQGn0zkKVGDMAmw.jpg deleted file mode 100644 index 21dd5ffe..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/mW7xmtGV4y79kQGn0zkKVGDMAmw.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/mk5vpYLmER7asqOhEwVKXD3P3YE.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/mk5vpYLmER7asqOhEwVKXD3P3YE.jpg deleted file mode 100644 index b4189cd0..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/mk5vpYLmER7asqOhEwVKXD3P3YE.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/mnKYU7HIsuRkx3YjdRO5FLXCdX5.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/mnKYU7HIsuRkx3YjdRO5FLXCdX5.jpg deleted file mode 100644 index 40aee939..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/mnKYU7HIsuRkx3YjdRO5FLXCdX5.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/msqe5A1q5YUUND0RhzB9dw1AEAO.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/msqe5A1q5YUUND0RhzB9dw1AEAO.jpg deleted file mode 100644 index afc0e401..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/msqe5A1q5YUUND0RhzB9dw1AEAO.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/nAxS5l9vb1C8ltCp9yAa0f6lazu.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/nAxS5l9vb1C8ltCp9yAa0f6lazu.jpg deleted file mode 100644 index 2e179e76..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/nAxS5l9vb1C8ltCp9yAa0f6lazu.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/nmgOd3X2Xn3jIp9OLCRJzLExRWN.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/nmgOd3X2Xn3jIp9OLCRJzLExRWN.jpg deleted file mode 100644 index 5a261d60..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/nmgOd3X2Xn3jIp9OLCRJzLExRWN.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/o7splcOIVAdbHnwohJOUAvXWVlk.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/o7splcOIVAdbHnwohJOUAvXWVlk.jpg deleted file mode 100644 index 4cdadf08..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/o7splcOIVAdbHnwohJOUAvXWVlk.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/oMHMLhoV3ry8aOfdvs1kxyowhNq.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/oMHMLhoV3ry8aOfdvs1kxyowhNq.jpg deleted file mode 100644 index 99b5bcd6..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/oMHMLhoV3ry8aOfdvs1kxyowhNq.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/omWXGbeRR32MWuYhpnLOSqJ6xkO.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/omWXGbeRR32MWuYhpnLOSqJ6xkO.jpg deleted file mode 100644 index 1ee336bd..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/omWXGbeRR32MWuYhpnLOSqJ6xkO.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/pVwR9hsEiHzVTo9giCjR3vIfa8W.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/pVwR9hsEiHzVTo9giCjR3vIfa8W.jpg deleted file mode 100644 index 4dbe126b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/pVwR9hsEiHzVTo9giCjR3vIfa8W.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/phEIvq0Ay2KjI5ewmVvpQ1a29GJ.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/phEIvq0Ay2KjI5ewmVvpQ1a29GJ.jpg deleted file mode 100644 index b673a5b2..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/phEIvq0Ay2KjI5ewmVvpQ1a29GJ.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/qP5vQMIbLNvSsSFkEMLZRVt4ZW5.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/qP5vQMIbLNvSsSFkEMLZRVt4ZW5.jpg deleted file mode 100644 index ed34c316..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/qP5vQMIbLNvSsSFkEMLZRVt4ZW5.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/qiWu2gphSg64igYl3Nx0hEIOQF3.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/qiWu2gphSg64igYl3Nx0hEIOQF3.jpg deleted file mode 100644 index e5fd3f84..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/qiWu2gphSg64igYl3Nx0hEIOQF3.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/qwbjcyDN37OHiln4a6P4LP31o7F.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/qwbjcyDN37OHiln4a6P4LP31o7F.jpg deleted file mode 100644 index 4132aac4..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/qwbjcyDN37OHiln4a6P4LP31o7F.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/r6s7dkYZUJpd00C7p9itT6Gp8XB.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/r6s7dkYZUJpd00C7p9itT6Gp8XB.jpg deleted file mode 100644 index 8ae18ac0..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/r6s7dkYZUJpd00C7p9itT6Gp8XB.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/rDTxblyw0AwU5oSeksgP7GwMyrF.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/rDTxblyw0AwU5oSeksgP7GwMyrF.jpg deleted file mode 100644 index 8d6c9a83..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/rDTxblyw0AwU5oSeksgP7GwMyrF.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/rIqcwewXdkrDTMTwX56QPa7MNTC.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/rIqcwewXdkrDTMTwX56QPa7MNTC.jpg deleted file mode 100644 index 0b985c84..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/rIqcwewXdkrDTMTwX56QPa7MNTC.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/rLzduQpYJnZJKkXv3jRc7MDHwoI.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/rLzduQpYJnZJKkXv3jRc7MDHwoI.jpg deleted file mode 100644 index 7377c541..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/rLzduQpYJnZJKkXv3jRc7MDHwoI.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/rbxBK2m6fEq0oHeMoBUMVYkJEdJ.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/rbxBK2m6fEq0oHeMoBUMVYkJEdJ.jpg deleted file mode 100644 index f23bdc49..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/rbxBK2m6fEq0oHeMoBUMVYkJEdJ.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/sG6CWLdENCtzukNFkFYyPxqyRmS.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/sG6CWLdENCtzukNFkFYyPxqyRmS.jpg deleted file mode 100644 index 755a5276..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/sG6CWLdENCtzukNFkFYyPxqyRmS.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/sh4ANkKoIHgmHtkKQbJvF8y0Fjq.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/sh4ANkKoIHgmHtkKQbJvF8y0Fjq.jpg deleted file mode 100644 index c1a9d397..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/sh4ANkKoIHgmHtkKQbJvF8y0Fjq.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/tqFHQiJUycuob3ytvilaAWDlbQ8.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/tqFHQiJUycuob3ytvilaAWDlbQ8.jpg deleted file mode 100644 index 5b2de159..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/tqFHQiJUycuob3ytvilaAWDlbQ8.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/uL8yfcm0dCFYFQt052kczVQVvac.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/uL8yfcm0dCFYFQt052kczVQVvac.jpg deleted file mode 100644 index 4f1e2f21..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/uL8yfcm0dCFYFQt052kczVQVvac.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/ub2IuMWFNQGYghHTPq0lpmn2Ue0.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/ub2IuMWFNQGYghHTPq0lpmn2Ue0.jpg deleted file mode 100644 index 725372ad..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/ub2IuMWFNQGYghHTPq0lpmn2Ue0.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/ukDNHgvEgdU95eaw6pngiAPucv4.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/ukDNHgvEgdU95eaw6pngiAPucv4.jpg deleted file mode 100644 index 7ed17793..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/ukDNHgvEgdU95eaw6pngiAPucv4.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/v4sRxLpRpHEd9vbk43wm9VL0v0K.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/v4sRxLpRpHEd9vbk43wm9VL0v0K.jpg deleted file mode 100644 index 2118c505..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/v4sRxLpRpHEd9vbk43wm9VL0v0K.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/wWcby4ARYqr8d92ZdjyQcfaiJBW.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/wWcby4ARYqr8d92ZdjyQcfaiJBW.jpg deleted file mode 100644 index 3a609d1e..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/wWcby4ARYqr8d92ZdjyQcfaiJBW.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/waayy0jpNbxLDQ8JO1uRDng8SLF.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/waayy0jpNbxLDQ8JO1uRDng8SLF.jpg deleted file mode 100644 index b650362b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/waayy0jpNbxLDQ8JO1uRDng8SLF.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/x0lmqgkmphvOCSTHk2oxsaxA9Ra.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/x0lmqgkmphvOCSTHk2oxsaxA9Ra.jpg deleted file mode 100644 index 3d3f33ee..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/x0lmqgkmphvOCSTHk2oxsaxA9Ra.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/xKBAaPIa1c7tzZD3Y0MhBLv4hPE.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/xKBAaPIa1c7tzZD3Y0MhBLv4hPE.jpg deleted file mode 100644 index fba488ba..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/xKBAaPIa1c7tzZD3Y0MhBLv4hPE.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/xV9UrP8kZdxOiTI2efDFhp3t4iA.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/xV9UrP8kZdxOiTI2efDFhp3t4iA.jpg deleted file mode 100644 index eb015896..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/xV9UrP8kZdxOiTI2efDFhp3t4iA.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/xm2pYFBggiXSkFBV2I612i3fDd3.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/xm2pYFBggiXSkFBV2I612i3fDd3.jpg deleted file mode 100644 index bc482f04..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/xm2pYFBggiXSkFBV2I612i3fDd3.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/xx3As5SWcE8vYOKZgtjDjqmT3jc.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/xx3As5SWcE8vYOKZgtjDjqmT3jc.jpg deleted file mode 100644 index dd70f23a..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/xx3As5SWcE8vYOKZgtjDjqmT3jc.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/yU0OXeZ0K1ppe1o9SpHiAMHy1rc.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/yU0OXeZ0K1ppe1o9SpHiAMHy1rc.jpg deleted file mode 100644 index dd0796e7..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/yU0OXeZ0K1ppe1o9SpHiAMHy1rc.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/yWZILsr2mBQBCG1LOcCYYshIbts.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/yWZILsr2mBQBCG1LOcCYYshIbts.jpg deleted file mode 100644 index 04d476bb..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/yWZILsr2mBQBCG1LOcCYYshIbts.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/yxGsAKnrJZs2g6q4unNgkfm7NAA.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/yxGsAKnrJZs2g6q4unNgkfm7NAA.jpg deleted file mode 100644 index 6e7a492b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/yxGsAKnrJZs2g6q4unNgkfm7NAA.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/cast/ztxDIZvuPreUixO6ZPxwkCg2UlO.jpg b/app/src/debug/assets/wolfskin-titles/assets/cast/ztxDIZvuPreUixO6ZPxwkCg2UlO.jpg deleted file mode 100644 index 6883cc09..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/cast/ztxDIZvuPreUixO6ZPxwkCg2UlO.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-all-hands-on-deck-class-1-a-2021-s5e1-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-all-hands-on-deck-class-1-a-2021-s5e1-backdrop.jpg deleted file mode 100644 index f5b2f94c..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-all-hands-on-deck-class-1-a-2021-s5e1-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-all-hands-on-deck-class-1-a-2021-s5e1-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-all-hands-on-deck-class-1-a-2021-s5e1-poster.jpg deleted file mode 100644 index cf571b93..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-all-hands-on-deck-class-1-a-2021-s5e1-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-announcement-2022-s1e7-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-announcement-2022-s1e7-backdrop.jpg deleted file mode 100644 index a874a0c0..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-announcement-2022-s1e7-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-announcement-2022-s1e7-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-announcement-2022-s1e7-poster.jpg deleted file mode 100644 index df5dc498..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-announcement-2022-s1e7-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-episode-1-2025-s1e1-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-episode-1-2025-s1e1-backdrop.jpg deleted file mode 100644 index f2519b04..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-episode-1-2025-s1e1-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-episode-1-2025-s1e1-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-episode-1-2025-s1e1-poster.jpg deleted file mode 100644 index 77febd79..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-episode-1-2025-s1e1-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-episode-2-2016-s1e2-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-episode-2-2016-s1e2-backdrop.jpg deleted file mode 100644 index 3f8bdeec..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-episode-2-2016-s1e2-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-episode-2-2016-s1e2-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-episode-2-2016-s1e2-poster.jpg deleted file mode 100644 index d29448bb..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-episode-2-2016-s1e2-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-erickerhead-2026-s9e6-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-erickerhead-2026-s9e6-backdrop.jpg deleted file mode 100644 index 1c4c0ffc..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-erickerhead-2026-s9e6-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-erickerhead-2026-s9e6-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-erickerhead-2026-s9e6-poster.jpg deleted file mode 100644 index b95c4890..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-erickerhead-2026-s9e6-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-girls-interrupted-2007-s1e7-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-girls-interrupted-2007-s1e7-backdrop.jpg deleted file mode 100644 index ffff979b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-girls-interrupted-2007-s1e7-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-girls-interrupted-2007-s1e7-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-girls-interrupted-2007-s1e7-poster.jpg deleted file mode 100644 index 38428e76..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-girls-interrupted-2007-s1e7-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-i-heart-ny-2002-s4e18-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-i-heart-ny-2002-s4e18-backdrop.jpg deleted file mode 100644 index 57beacc1..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-i-heart-ny-2002-s4e18-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-i-heart-ny-2002-s4e18-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-i-heart-ny-2002-s4e18-poster.jpg deleted file mode 100644 index e546cc6d..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-i-heart-ny-2002-s4e18-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-new-day-2021-s1e2-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-new-day-2021-s1e2-backdrop.jpg deleted file mode 100644 index 1f747323..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-new-day-2021-s1e2-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-new-day-2021-s1e2-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-new-day-2021-s1e2-poster.jpg deleted file mode 100644 index 2f23d1fa..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-new-day-2021-s1e2-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-no-honeymoon-2020-s1e8-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-no-honeymoon-2020-s1e8-backdrop.jpg deleted file mode 100644 index 9d95ba77..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-no-honeymoon-2020-s1e8-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-no-honeymoon-2020-s1e8-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-no-honeymoon-2020-s1e8-poster.jpg deleted file mode 100644 index 49c61208..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-no-honeymoon-2020-s1e8-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-notapusy-2005-s3e4-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-notapusy-2005-s3e4-backdrop.jpg deleted file mode 100644 index ecb7e8cd..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-notapusy-2005-s3e4-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-notapusy-2005-s3e4-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-notapusy-2005-s3e4-poster.jpg deleted file mode 100644 index 02b0dd43..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-notapusy-2005-s3e4-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-one-of-us-2024-s1e7-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-one-of-us-2024-s1e7-backdrop.jpg deleted file mode 100644 index 66bb4d00..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-one-of-us-2024-s1e7-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-one-of-us-2024-s1e7-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-one-of-us-2024-s1e7-poster.jpg deleted file mode 100644 index 00a07ca7..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-one-of-us-2024-s1e7-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-remembrance-day-2026-s2e1-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-remembrance-day-2026-s2e1-backdrop.jpg deleted file mode 100644 index 23a242da..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-remembrance-day-2026-s2e1-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-remembrance-day-2026-s2e1-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-remembrance-day-2026-s2e1-poster.jpg deleted file mode 100644 index 930943b0..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-remembrance-day-2026-s2e1-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-sex-and-the-country-2001-s4e9-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-sex-and-the-country-2001-s4e9-backdrop.jpg deleted file mode 100644 index 57beacc1..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-sex-and-the-country-2001-s4e9-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-sex-and-the-country-2001-s4e9-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-sex-and-the-country-2001-s4e9-poster.jpg deleted file mode 100644 index e546cc6d..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-sex-and-the-country-2001-s4e9-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-south-american-biker-gangs-2026-s29e1-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-south-american-biker-gangs-2026-s29e1-backdrop.jpg deleted file mode 100644 index cd0aec39..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-south-american-biker-gangs-2026-s29e1-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-south-american-biker-gangs-2026-s29e1-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-south-american-biker-gangs-2026-s29e1-poster.jpg deleted file mode 100644 index d8568d54..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-south-american-biker-gangs-2026-s29e1-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-the-breakup-part-2-2001-s1e17-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-the-breakup-part-2-2001-s1e17-backdrop.jpg deleted file mode 100644 index b42ba953..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-the-breakup-part-2-2001-s1e17-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-the-breakup-part-2-2001-s1e17-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-the-breakup-part-2-2001-s1e17-poster.jpg deleted file mode 100644 index 23b668cb..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-the-breakup-part-2-2001-s1e17-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-the-man-who-would-be-vogue-2018-s2e1-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-the-man-who-would-be-vogue-2018-s2e1-backdrop.jpg deleted file mode 100644 index 84944d39..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-the-man-who-would-be-vogue-2018-s2e1-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-the-man-who-would-be-vogue-2018-s2e1-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-the-man-who-would-be-vogue-2018-s2e1-poster.jpg deleted file mode 100644 index 4086bf17..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-the-man-who-would-be-vogue-2018-s2e1-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-the-uncomfortability-2010-s1e2-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-the-uncomfortability-2010-s1e2-backdrop.jpg deleted file mode 100644 index bc22e11a..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-the-uncomfortability-2010-s1e2-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-the-uncomfortability-2010-s1e2-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-the-uncomfortability-2010-s1e2-poster.jpg deleted file mode 100644 index ae305043..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-the-uncomfortability-2010-s1e2-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-three-monsters-1992-s1e6-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-three-monsters-1992-s1e6-backdrop.jpg deleted file mode 100644 index ba65ca2d..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-three-monsters-1992-s1e6-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-three-monsters-1992-s1e6-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-three-monsters-1992-s1e6-poster.jpg deleted file mode 100644 index f5843766..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-three-monsters-1992-s1e6-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-tomorrow-2024-s3e1-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-tomorrow-2024-s3e1-backdrop.jpg deleted file mode 100644 index 9c9cca57..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-tomorrow-2024-s3e1-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-tomorrow-2024-s3e1-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-tomorrow-2024-s3e1-poster.jpg deleted file mode 100644 index bbf0ab28..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-tomorrow-2024-s3e1-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-what-more-do-i-need-2008-s5e7-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-what-more-do-i-need-2008-s5e7-backdrop.jpg deleted file mode 100644 index 40ec3001..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-what-more-do-i-need-2008-s5e7-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/episode-what-more-do-i-need-2008-s5e7-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/episode-what-more-do-i-need-2008-s5e7-poster.jpg deleted file mode 100644 index 13f0f7b3..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/episode-what-more-do-i-need-2008-s5e7-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-101-dalmatians-ii-patch-s-london-adventure-2003-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-101-dalmatians-ii-patch-s-london-adventure-2003-backdrop.jpg deleted file mode 100644 index f0d6f752..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-101-dalmatians-ii-patch-s-london-adventure-2003-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-101-dalmatians-ii-patch-s-london-adventure-2003-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-101-dalmatians-ii-patch-s-london-adventure-2003-poster.jpg deleted file mode 100644 index b9b72894..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-101-dalmatians-ii-patch-s-london-adventure-2003-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-a-bronx-tale-1993-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-a-bronx-tale-1993-backdrop.jpg deleted file mode 100644 index 15c11ff7..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-a-bronx-tale-1993-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-a-bronx-tale-1993-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-a-bronx-tale-1993-poster.jpg deleted file mode 100644 index f7444271..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-a-bronx-tale-1993-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-a-silent-voice-the-movie-2016-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-a-silent-voice-the-movie-2016-backdrop.jpg deleted file mode 100644 index b386b136..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-a-silent-voice-the-movie-2016-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-a-silent-voice-the-movie-2016-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-a-silent-voice-the-movie-2016-poster.jpg deleted file mode 100644 index 580b22f4..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-a-silent-voice-the-movie-2016-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-absolution-2024-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-absolution-2024-backdrop.jpg deleted file mode 100644 index eb28037c..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-absolution-2024-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-absolution-2024-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-absolution-2024-poster.jpg deleted file mode 100644 index 3ce49112..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-absolution-2024-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-across-the-hall-2009-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-across-the-hall-2009-backdrop.jpg deleted file mode 100644 index 6c1ee8ac..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-across-the-hall-2009-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-across-the-hall-2009-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-across-the-hall-2009-poster.jpg deleted file mode 100644 index 52362b4e..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-across-the-hall-2009-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-addicted-2014-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-addicted-2014-backdrop.jpg deleted file mode 100644 index 5c016976..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-addicted-2014-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-addicted-2014-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-addicted-2014-poster.jpg deleted file mode 100644 index e9a03c14..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-addicted-2014-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-adulterers-2016-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-adulterers-2016-backdrop.jpg deleted file mode 100644 index 331391ed..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-adulterers-2016-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-adulterers-2016-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-adulterers-2016-poster.jpg deleted file mode 100644 index 8b65745b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-adulterers-2016-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-all-the-money-in-the-world-2017-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-all-the-money-in-the-world-2017-backdrop.jpg deleted file mode 100644 index ac4b828a..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-all-the-money-in-the-world-2017-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-all-the-money-in-the-world-2017-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-all-the-money-in-the-world-2017-poster.jpg deleted file mode 100644 index 8beb2f7f..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-all-the-money-in-the-world-2017-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-alone-with-her-2006-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-alone-with-her-2006-backdrop.jpg deleted file mode 100644 index ddf8f1dc..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-alone-with-her-2006-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-alone-with-her-2006-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-alone-with-her-2006-poster.jpg deleted file mode 100644 index 7ce6fa96..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-alone-with-her-2006-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-american-gangster-2007-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-american-gangster-2007-backdrop.jpg deleted file mode 100644 index cb5c5de7..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-american-gangster-2007-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-american-gangster-2007-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-american-gangster-2007-poster.jpg deleted file mode 100644 index 0f41d299..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-american-gangster-2007-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-annie-hall-1977-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-annie-hall-1977-backdrop.jpg deleted file mode 100644 index 16d0b27d..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-annie-hall-1977-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-annie-hall-1977-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-annie-hall-1977-poster.jpg deleted file mode 100644 index 9023a691..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-annie-hall-1977-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-ant-man-and-the-wasp-quantumania-2023-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-ant-man-and-the-wasp-quantumania-2023-backdrop.jpg deleted file mode 100644 index 2a99846d..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-ant-man-and-the-wasp-quantumania-2023-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-ant-man-and-the-wasp-quantumania-2023-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-ant-man-and-the-wasp-quantumania-2023-poster.jpg deleted file mode 100644 index 030addf0..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-ant-man-and-the-wasp-quantumania-2023-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-appleseed-alpha-2014-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-appleseed-alpha-2014-backdrop.jpg deleted file mode 100644 index 82579b86..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-appleseed-alpha-2014-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-appleseed-alpha-2014-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-appleseed-alpha-2014-poster.jpg deleted file mode 100644 index 62bd0afa..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-appleseed-alpha-2014-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-aquaman-and-the-lost-kingdom-2023-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-aquaman-and-the-lost-kingdom-2023-backdrop.jpg deleted file mode 100644 index 6693cb6d..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-aquaman-and-the-lost-kingdom-2023-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-aquaman-and-the-lost-kingdom-2023-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-aquaman-and-the-lost-kingdom-2023-poster.jpg deleted file mode 100644 index 4550bdaa..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-aquaman-and-the-lost-kingdom-2023-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-arctic-dogs-2019-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-arctic-dogs-2019-backdrop.jpg deleted file mode 100644 index 1794c99d..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-arctic-dogs-2019-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-arctic-dogs-2019-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-arctic-dogs-2019-poster.jpg deleted file mode 100644 index 07552443..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-arctic-dogs-2019-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-arrival-2016-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-arrival-2016-backdrop.jpg deleted file mode 100644 index 605724e7..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-arrival-2016-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-arrival-2016-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-arrival-2016-poster.jpg deleted file mode 100644 index fe224a15..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-arrival-2016-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-avatar-aang-the-last-airbender-2026-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-avatar-aang-the-last-airbender-2026-backdrop.jpg deleted file mode 100644 index d3b12fe0..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-avatar-aang-the-last-airbender-2026-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-avatar-aang-the-last-airbender-2026-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-avatar-aang-the-last-airbender-2026-poster.jpg deleted file mode 100644 index f57f1052..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-avatar-aang-the-last-airbender-2026-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-avengers-age-of-ultron-2015-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-avengers-age-of-ultron-2015-backdrop.jpg deleted file mode 100644 index f739d620..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-avengers-age-of-ultron-2015-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-avengers-age-of-ultron-2015-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-avengers-age-of-ultron-2015-poster.jpg deleted file mode 100644 index 300840ff..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-avengers-age-of-ultron-2015-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-avengers-confidential-black-widow-punisher-2014-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-avengers-confidential-black-widow-punisher-2014-backdrop.jpg deleted file mode 100644 index 8163931a..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-avengers-confidential-black-widow-punisher-2014-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-avengers-confidential-black-widow-punisher-2014-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-avengers-confidential-black-widow-punisher-2014-poster.jpg deleted file mode 100644 index b096fff2..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-avengers-confidential-black-widow-punisher-2014-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-avengers-infinity-war-2018-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-avengers-infinity-war-2018-backdrop.jpg deleted file mode 100644 index 90dc4672..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-avengers-infinity-war-2018-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-avengers-infinity-war-2018-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-avengers-infinity-war-2018-poster.jpg deleted file mode 100644 index 57df9298..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-avengers-infinity-war-2018-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-awake-2007-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-awake-2007-backdrop.jpg deleted file mode 100644 index 6ddd7f59..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-awake-2007-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-awake-2007-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-awake-2007-poster.jpg deleted file mode 100644 index 32595897..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-awake-2007-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-batman-ninja-2018-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-batman-ninja-2018-backdrop.jpg deleted file mode 100644 index 9b538d9f..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-batman-ninja-2018-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-batman-ninja-2018-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-batman-ninja-2018-poster.jpg deleted file mode 100644 index 7f59127b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-batman-ninja-2018-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-batman-the-dark-knight-returns-part-1-2012-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-batman-the-dark-knight-returns-part-1-2012-backdrop.jpg deleted file mode 100644 index 9d385801..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-batman-the-dark-knight-returns-part-1-2012-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-batman-the-dark-knight-returns-part-1-2012-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-batman-the-dark-knight-returns-part-1-2012-poster.jpg deleted file mode 100644 index ce5623fe..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-batman-the-dark-knight-returns-part-1-2012-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-batman-v-superman-dawn-of-justice-2016-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-batman-v-superman-dawn-of-justice-2016-backdrop.jpg deleted file mode 100644 index b4fa63b9..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-batman-v-superman-dawn-of-justice-2016-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-batman-v-superman-dawn-of-justice-2016-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-batman-v-superman-dawn-of-justice-2016-poster.jpg deleted file mode 100644 index f8115170..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-batman-v-superman-dawn-of-justice-2016-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-black-adam-2022-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-black-adam-2022-backdrop.jpg deleted file mode 100644 index 3232fb22..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-black-adam-2022-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-black-adam-2022-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-black-adam-2022-poster.jpg deleted file mode 100644 index dde008b5..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-black-adam-2022-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-black-bear-2020-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-black-bear-2020-backdrop.jpg deleted file mode 100644 index 4b0b262f..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-black-bear-2020-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-black-bear-2020-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-black-bear-2020-poster.jpg deleted file mode 100644 index 61c8860f..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-black-bear-2020-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-black-panther-2018-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-black-panther-2018-backdrop.jpg deleted file mode 100644 index f0b8de8a..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-black-panther-2018-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-black-panther-2018-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-black-panther-2018-poster.jpg deleted file mode 100644 index 6fdaa3d2..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-black-panther-2018-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-black-panther-wakanda-forever-2022-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-black-panther-wakanda-forever-2022-backdrop.jpg deleted file mode 100644 index ac7ad532..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-black-panther-wakanda-forever-2022-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-black-panther-wakanda-forever-2022-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-black-panther-wakanda-forever-2022-poster.jpg deleted file mode 100644 index d0219a75..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-black-panther-wakanda-forever-2022-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-blame-2017-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-blame-2017-backdrop.jpg deleted file mode 100644 index f39cf5ce..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-blame-2017-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-blame-2017-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-blame-2017-poster.jpg deleted file mode 100644 index 8d50255f..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-blame-2017-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-bleach-the-movie-fade-to-black-2008-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-bleach-the-movie-fade-to-black-2008-backdrop.jpg deleted file mode 100644 index f426d0ce..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-bleach-the-movie-fade-to-black-2008-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-bleach-the-movie-fade-to-black-2008-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-bleach-the-movie-fade-to-black-2008-poster.jpg deleted file mode 100644 index d3619fbd..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-bleach-the-movie-fade-to-black-2008-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-butterfly-on-a-wheel-2007-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-butterfly-on-a-wheel-2007-backdrop.jpg deleted file mode 100644 index e49fe1d5..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-butterfly-on-a-wheel-2007-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-butterfly-on-a-wheel-2007-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-butterfly-on-a-wheel-2007-poster.jpg deleted file mode 100644 index b54cc5c7..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-butterfly-on-a-wheel-2007-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-captain-america-civil-war-2016-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-captain-america-civil-war-2016-backdrop.jpg deleted file mode 100644 index 5700c4e7..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-captain-america-civil-war-2016-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-captain-america-civil-war-2016-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-captain-america-civil-war-2016-poster.jpg deleted file mode 100644 index 426142ef..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-captain-america-civil-war-2016-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-careful-what-you-wish-for-2015-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-careful-what-you-wish-for-2015-backdrop.jpg deleted file mode 100644 index 988e20d5..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-careful-what-you-wish-for-2015-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-careful-what-you-wish-for-2015-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-careful-what-you-wish-for-2015-poster.jpg deleted file mode 100644 index b58ce600..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-careful-what-you-wish-for-2015-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-castle-in-the-sky-1986-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-castle-in-the-sky-1986-backdrop.jpg deleted file mode 100644 index f785c549..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-castle-in-the-sky-1986-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-castle-in-the-sky-1986-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-castle-in-the-sky-1986-poster.jpg deleted file mode 100644 index a6a99fee..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-castle-in-the-sky-1986-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-chicago-2002-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-chicago-2002-backdrop.jpg deleted file mode 100644 index 6b3d02a3..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-chicago-2002-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-chicago-2002-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-chicago-2002-poster.jpg deleted file mode 100644 index 1def9414..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-chicago-2002-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-citizen-kane-1941-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-citizen-kane-1941-backdrop.jpg deleted file mode 100644 index d41a10ef..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-citizen-kane-1941-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-citizen-kane-1941-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-citizen-kane-1941-poster.jpg deleted file mode 100644 index f26414a7..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-citizen-kane-1941-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-conclave-2024-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-conclave-2024-backdrop.jpg deleted file mode 100644 index db0a7fcd..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-conclave-2024-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-conclave-2024-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-conclave-2024-poster.jpg deleted file mode 100644 index c6aecefa..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-conclave-2024-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-crime-of-passion-1956-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-crime-of-passion-1956-backdrop.jpg deleted file mode 100644 index 6c70a452..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-crime-of-passion-1956-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-crime-of-passion-1956-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-crime-of-passion-1956-poster.jpg deleted file mode 100644 index 4acfa871..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-crime-of-passion-1956-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-deep-water-2022-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-deep-water-2022-backdrop.jpg deleted file mode 100644 index bec98992..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-deep-water-2022-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-deep-water-2022-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-deep-water-2022-poster.jpg deleted file mode 100644 index 018d4f4b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-deep-water-2022-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-derailed-2005-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-derailed-2005-backdrop.jpg deleted file mode 100644 index e958449b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-derailed-2005-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-derailed-2005-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-derailed-2005-poster.jpg deleted file mode 100644 index d93f3124..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-derailed-2005-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-dream-house-2011-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-dream-house-2011-backdrop.jpg deleted file mode 100644 index 29ecc103..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-dream-house-2011-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-dream-house-2011-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-dream-house-2011-poster.jpg deleted file mode 100644 index d3444637..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-dream-house-2011-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-dream-lover-1994-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-dream-lover-1994-backdrop.jpg deleted file mode 100644 index 7f5a31ac..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-dream-lover-1994-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-dream-lover-1994-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-dream-lover-1994-poster.jpg deleted file mode 100644 index 3b563cf9..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-dream-lover-1994-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-drop-2025-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-drop-2025-backdrop.jpg deleted file mode 100644 index ee642530..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-drop-2025-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-drop-2025-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-drop-2025-poster.jpg deleted file mode 100644 index 4cf7d66b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-drop-2025-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-eastern-promises-2007-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-eastern-promises-2007-backdrop.jpg deleted file mode 100644 index 9096a0fa..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-eastern-promises-2007-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-eastern-promises-2007-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-eastern-promises-2007-poster.jpg deleted file mode 100644 index 01a26f3b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-eastern-promises-2007-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-el-camino-a-breaking-bad-movie-2019-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-el-camino-a-breaking-bad-movie-2019-backdrop.jpg deleted file mode 100644 index 8edc02a6..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-el-camino-a-breaking-bad-movie-2019-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-el-camino-a-breaking-bad-movie-2019-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-el-camino-a-breaking-bad-movie-2019-poster.jpg deleted file mode 100644 index 7a62df45..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-el-camino-a-breaking-bad-movie-2019-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-fatale-2020-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-fatale-2020-backdrop.jpg deleted file mode 100644 index b13c33c6..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-fatale-2020-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-fatale-2020-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-fatale-2020-poster.jpg deleted file mode 100644 index dda9d622..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-fatale-2020-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-force-of-nature-the-dry-2-2024-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-force-of-nature-the-dry-2-2024-backdrop.jpg deleted file mode 100644 index 3735ee63..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-force-of-nature-the-dry-2-2024-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-force-of-nature-the-dry-2-2024-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-force-of-nature-the-dry-2-2024-poster.jpg deleted file mode 100644 index 93ba0d71..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-force-of-nature-the-dry-2-2024-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-ghost-in-the-shell-1995-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-ghost-in-the-shell-1995-backdrop.jpg deleted file mode 100644 index 716b8a87..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-ghost-in-the-shell-1995-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-ghost-in-the-shell-1995-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-ghost-in-the-shell-1995-poster.jpg deleted file mode 100644 index 58d221ba..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-ghost-in-the-shell-1995-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-ghost-in-the-shell-2-innocence-2004-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-ghost-in-the-shell-2-innocence-2004-backdrop.jpg deleted file mode 100644 index 4a9931ed..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-ghost-in-the-shell-2-innocence-2004-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-ghost-in-the-shell-2-innocence-2004-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-ghost-in-the-shell-2-innocence-2004-poster.jpg deleted file mode 100644 index ae262147..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-ghost-in-the-shell-2-innocence-2004-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-gosford-park-2001-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-gosford-park-2001-backdrop.jpg deleted file mode 100644 index 42c4cea6..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-gosford-park-2001-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-gosford-park-2001-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-gosford-park-2001-poster.jpg deleted file mode 100644 index 6a6aa651..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-gosford-park-2001-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-howl-s-moving-castle-2004-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-howl-s-moving-castle-2004-backdrop.jpg deleted file mode 100644 index 0aeef2ba..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-howl-s-moving-castle-2004-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-howl-s-moving-castle-2004-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-howl-s-moving-castle-2004-poster.jpg deleted file mode 100644 index 042a6c80..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-howl-s-moving-castle-2004-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-in-the-heights-2021-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-in-the-heights-2021-backdrop.jpg deleted file mode 100644 index 7cd4ee24..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-in-the-heights-2021-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-in-the-heights-2021-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-in-the-heights-2021-poster.jpg deleted file mode 100644 index e05bfdb0..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-in-the-heights-2021-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-kiki-s-delivery-service-1989-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-kiki-s-delivery-service-1989-backdrop.jpg deleted file mode 100644 index 2a108f0c..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-kiki-s-delivery-service-1989-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-kiki-s-delivery-service-1989-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-kiki-s-delivery-service-1989-poster.jpg deleted file mode 100644 index 80a59b1e..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-kiki-s-delivery-service-1989-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-lemony-snicket-s-a-series-of-unfortunate-events-2004-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-lemony-snicket-s-a-series-of-unfortunate-events-2004-backdrop.jpg deleted file mode 100644 index 38203b77..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-lemony-snicket-s-a-series-of-unfortunate-events-2004-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-lemony-snicket-s-a-series-of-unfortunate-events-2004-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-lemony-snicket-s-a-series-of-unfortunate-events-2004-poster.jpg deleted file mode 100644 index 4c78fee9..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-lemony-snicket-s-a-series-of-unfortunate-events-2004-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-locke-2014-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-locke-2014-backdrop.jpg deleted file mode 100644 index a24e64ab..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-locke-2014-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-locke-2014-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-locke-2014-poster.jpg deleted file mode 100644 index 94ebe97d..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-locke-2014-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-memories-1995-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-memories-1995-backdrop.jpg deleted file mode 100644 index 2fcaeaad..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-memories-1995-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-memories-1995-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-memories-1995-poster.jpg deleted file mode 100644 index f3725b42..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-memories-1995-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-night-is-short-walk-on-girl-2017-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-night-is-short-walk-on-girl-2017-backdrop.jpg deleted file mode 100644 index da38be48..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-night-is-short-walk-on-girl-2017-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-night-is-short-walk-on-girl-2017-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-night-is-short-walk-on-girl-2017-poster.jpg deleted file mode 100644 index c6fa6a26..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-night-is-short-walk-on-girl-2017-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-panic-room-2002-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-panic-room-2002-backdrop.jpg deleted file mode 100644 index ec877751..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-panic-room-2002-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-panic-room-2002-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-panic-room-2002-poster.jpg deleted file mode 100644 index 0b2a0d30..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-panic-room-2002-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-ponyo-2008-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-ponyo-2008-backdrop.jpg deleted file mode 100644 index 8aa4ecbd..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-ponyo-2008-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-ponyo-2008-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-ponyo-2008-poster.jpg deleted file mode 100644 index f548e831..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-ponyo-2008-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-porco-rosso-1992-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-porco-rosso-1992-backdrop.jpg deleted file mode 100644 index 63d8112e..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-porco-rosso-1992-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-porco-rosso-1992-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-porco-rosso-1992-poster.jpg deleted file mode 100644 index 4a6a2bd1..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-porco-rosso-1992-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-princess-mononoke-1997-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-princess-mononoke-1997-backdrop.jpg deleted file mode 100644 index 9486d2cf..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-princess-mononoke-1997-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-princess-mononoke-1997-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-princess-mononoke-1997-poster.jpg deleted file mode 100644 index 21dd9359..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-princess-mononoke-1997-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-prisoners-2013-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-prisoners-2013-backdrop.jpg deleted file mode 100644 index 724008c5..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-prisoners-2013-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-prisoners-2013-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-prisoners-2013-poster.jpg deleted file mode 100644 index 411b149b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-prisoners-2013-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-racing-stripes-2005-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-racing-stripes-2005-backdrop.jpg deleted file mode 100644 index 1d332cec..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-racing-stripes-2005-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-racing-stripes-2005-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-racing-stripes-2005-poster.jpg deleted file mode 100644 index cc2ef2ce..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-racing-stripes-2005-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-secondhand-lions-2003-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-secondhand-lions-2003-backdrop.jpg deleted file mode 100644 index 7ea43937..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-secondhand-lions-2003-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-secondhand-lions-2003-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-secondhand-lions-2003-poster.jpg deleted file mode 100644 index 33408fa0..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-secondhand-lions-2003-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-shaft-2000-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-shaft-2000-backdrop.jpg deleted file mode 100644 index 13f14f93..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-shaft-2000-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-shaft-2000-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-shaft-2000-poster.jpg deleted file mode 100644 index 6b2b79ce..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-shaft-2000-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-sinbad-legend-of-the-seven-seas-2003-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-sinbad-legend-of-the-seven-seas-2003-backdrop.jpg deleted file mode 100644 index d04685fe..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-sinbad-legend-of-the-seven-seas-2003-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-sinbad-legend-of-the-seven-seas-2003-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-sinbad-legend-of-the-seven-seas-2003-poster.jpg deleted file mode 100644 index 428bb38b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-sinbad-legend-of-the-seven-seas-2003-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-sleeping-with-other-people-2015-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-sleeping-with-other-people-2015-backdrop.jpg deleted file mode 100644 index df5bb046..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-sleeping-with-other-people-2015-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-sleeping-with-other-people-2015-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-sleeping-with-other-people-2015-poster.jpg deleted file mode 100644 index a5ffff1f..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-sleeping-with-other-people-2015-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-snowpiercer-2013-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-snowpiercer-2013-backdrop.jpg deleted file mode 100644 index c1281a9c..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-snowpiercer-2013-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-snowpiercer-2013-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-snowpiercer-2013-poster.jpg deleted file mode 100644 index be1873fd..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-snowpiercer-2013-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-brand-new-day-2026-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-brand-new-day-2026-backdrop.jpg deleted file mode 100644 index 2fdaadb4..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-brand-new-day-2026-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-brand-new-day-2026-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-brand-new-day-2026-poster.jpg deleted file mode 100644 index 51fa155f..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-brand-new-day-2026-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-far-from-home-2019-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-far-from-home-2019-backdrop.jpg deleted file mode 100644 index d09f655a..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-far-from-home-2019-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-far-from-home-2019-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-far-from-home-2019-poster.jpg deleted file mode 100644 index 28521997..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-far-from-home-2019-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-homecoming-2017-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-homecoming-2017-backdrop.jpg deleted file mode 100644 index 6088fadf..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-homecoming-2017-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-homecoming-2017-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-homecoming-2017-poster.jpg deleted file mode 100644 index 97fc9c05..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-homecoming-2017-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-no-way-home-2021-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-no-way-home-2021-backdrop.jpg deleted file mode 100644 index a76afec9..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-no-way-home-2021-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-no-way-home-2021-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-no-way-home-2021-poster.jpg deleted file mode 100644 index bc92a4cd..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-spider-man-no-way-home-2021-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-spirited-away-2001-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-spirited-away-2001-backdrop.jpg deleted file mode 100644 index af91c123..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-spirited-away-2001-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-spirited-away-2001-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-spirited-away-2001-poster.jpg deleted file mode 100644 index 5a79da62..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-spirited-away-2001-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-alto-knights-2025-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-alto-knights-2025-backdrop.jpg deleted file mode 100644 index ea619c14..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-alto-knights-2025-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-alto-knights-2025-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-alto-knights-2025-poster.jpg deleted file mode 100644 index bb009cbf..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-alto-knights-2025-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-amazing-spider-man-2-2014-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-amazing-spider-man-2-2014-backdrop.jpg deleted file mode 100644 index 7c5878b7..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-amazing-spider-man-2-2014-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-amazing-spider-man-2-2014-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-amazing-spider-man-2-2014-poster.jpg deleted file mode 100644 index 4de2711f..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-amazing-spider-man-2-2014-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-amazing-spider-man-2012-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-amazing-spider-man-2012-backdrop.jpg deleted file mode 100644 index 75ae9b64..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-amazing-spider-man-2012-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-amazing-spider-man-2012-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-amazing-spider-man-2012-poster.jpg deleted file mode 100644 index c1aec876..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-amazing-spider-man-2012-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-animatrix-2003-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-animatrix-2003-backdrop.jpg deleted file mode 100644 index 7d67ccb0..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-animatrix-2003-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-animatrix-2003-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-animatrix-2003-poster.jpg deleted file mode 100644 index 65553d47..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-animatrix-2003-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-avengers-2012-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-avengers-2012-backdrop.jpg deleted file mode 100644 index 83636f25..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-avengers-2012-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-avengers-2012-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-avengers-2012-poster.jpg deleted file mode 100644 index be87067c..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-avengers-2012-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-boy-and-the-heron-2023-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-boy-and-the-heron-2023-backdrop.jpg deleted file mode 100644 index a19dc77b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-boy-and-the-heron-2023-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-boy-and-the-heron-2023-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-boy-and-the-heron-2023-poster.jpg deleted file mode 100644 index 094df64e..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-boy-and-the-heron-2023-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-breakfast-club-1985-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-breakfast-club-1985-backdrop.jpg deleted file mode 100644 index 9f979cd8..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-breakfast-club-1985-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-breakfast-club-1985-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-breakfast-club-1985-poster.jpg deleted file mode 100644 index d1823120..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-breakfast-club-1985-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-dry-2021-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-dry-2021-backdrop.jpg deleted file mode 100644 index 2f016498..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-dry-2021-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-dry-2021-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-dry-2021-poster.jpg deleted file mode 100644 index a0379f2f..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-dry-2021-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-girl-who-leapt-through-time-2006-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-girl-who-leapt-through-time-2006-backdrop.jpg deleted file mode 100644 index 6e920467..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-girl-who-leapt-through-time-2006-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-girl-who-leapt-through-time-2006-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-girl-who-leapt-through-time-2006-poster.jpg deleted file mode 100644 index ded6cd2a..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-girl-who-leapt-through-time-2006-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-godfather-1972-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-godfather-1972-backdrop.jpg deleted file mode 100644 index 8fbb8f2a..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-godfather-1972-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-godfather-1972-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-godfather-1972-poster.jpg deleted file mode 100644 index 94111d9b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-godfather-1972-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-godfather-part-iii-1990-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-godfather-part-iii-1990-backdrop.jpg deleted file mode 100644 index d2080487..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-godfather-part-iii-1990-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-godfather-part-iii-1990-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-godfather-part-iii-1990-poster.jpg deleted file mode 100644 index abbe5e99..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-godfather-part-iii-1990-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-great-gatsby-2013-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-great-gatsby-2013-backdrop.jpg deleted file mode 100644 index 7a4f8a32..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-great-gatsby-2013-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-great-gatsby-2013-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-great-gatsby-2013-poster.jpg deleted file mode 100644 index e949fb3e..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-great-gatsby-2013-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-killing-of-a-sacred-deer-2017-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-killing-of-a-sacred-deer-2017-backdrop.jpg deleted file mode 100644 index dd755ee8..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-killing-of-a-sacred-deer-2017-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-killing-of-a-sacred-deer-2017-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-killing-of-a-sacred-deer-2017-poster.jpg deleted file mode 100644 index 83464d4c..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-killing-of-a-sacred-deer-2017-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-lighthouse-2019-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-lighthouse-2019-backdrop.jpg deleted file mode 100644 index 862c064a..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-lighthouse-2019-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-lighthouse-2019-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-lighthouse-2019-poster.jpg deleted file mode 100644 index 15f26533..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-lighthouse-2019-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-secret-life-of-pets-2-2019-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-secret-life-of-pets-2-2019-backdrop.jpg deleted file mode 100644 index 698f4ad2..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-secret-life-of-pets-2-2019-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-secret-life-of-pets-2-2019-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-secret-life-of-pets-2-2019-poster.jpg deleted file mode 100644 index fe50c2f8..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-secret-life-of-pets-2-2019-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-tale-of-the-princess-kaguya-2013-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-tale-of-the-princess-kaguya-2013-backdrop.jpg deleted file mode 100644 index b9157b91..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-tale-of-the-princess-kaguya-2013-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-tale-of-the-princess-kaguya-2013-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-tale-of-the-princess-kaguya-2013-poster.jpg deleted file mode 100644 index 882621cb..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-tale-of-the-princess-kaguya-2013-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-wild-robot-2024-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-wild-robot-2024-backdrop.jpg deleted file mode 100644 index bb48460b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-wild-robot-2024-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-wild-robot-2024-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-wild-robot-2024-poster.jpg deleted file mode 100644 index 0894754d..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-wild-robot-2024-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-witcher-nightmare-of-the-wolf-2021-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-witcher-nightmare-of-the-wolf-2021-backdrop.jpg deleted file mode 100644 index cb5bfb28..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-witcher-nightmare-of-the-wolf-2021-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-witcher-nightmare-of-the-wolf-2021-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-witcher-nightmare-of-the-wolf-2021-poster.jpg deleted file mode 100644 index 6db33db1..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-witcher-nightmare-of-the-wolf-2021-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-witcher-sirens-of-the-deep-2025-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-witcher-sirens-of-the-deep-2025-backdrop.jpg deleted file mode 100644 index aad8ea2c..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-witcher-sirens-of-the-deep-2025-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-the-witcher-sirens-of-the-deep-2025-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-the-witcher-sirens-of-the-deep-2025-poster.jpg deleted file mode 100644 index 8a54bc7f..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-the-witcher-sirens-of-the-deep-2025-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-thelma-louise-1991-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-thelma-louise-1991-backdrop.jpg deleted file mode 100644 index a35327a9..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-thelma-louise-1991-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-thelma-louise-1991-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-thelma-louise-1991-poster.jpg deleted file mode 100644 index 5a4ff0ab..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-thelma-louise-1991-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-triangle-of-sadness-2022-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-triangle-of-sadness-2022-backdrop.jpg deleted file mode 100644 index 7c9b445d..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-triangle-of-sadness-2022-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-triangle-of-sadness-2022-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-triangle-of-sadness-2022-poster.jpg deleted file mode 100644 index aee092c6..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-triangle-of-sadness-2022-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-vice-2018-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-vice-2018-backdrop.jpg deleted file mode 100644 index 2918db3a..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-vice-2018-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/movie-vice-2018-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/movie-vice-2018-poster.jpg deleted file mode 100644 index 76855126..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/movie-vice-2018-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-12-monkeys-2015-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-12-monkeys-2015-backdrop.jpg deleted file mode 100644 index 3d2825f5..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-12-monkeys-2015-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-12-monkeys-2015-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-12-monkeys-2015-poster.jpg deleted file mode 100644 index 96e3596e..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-12-monkeys-2015-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-56-days-2026-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-56-days-2026-backdrop.jpg deleted file mode 100644 index dcda667a..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-56-days-2026-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-56-days-2026-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-56-days-2026-poster.jpg deleted file mode 100644 index 64ca587b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-56-days-2026-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-a-knight-of-the-seven-kingdoms-2026-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-a-knight-of-the-seven-kingdoms-2026-backdrop.jpg deleted file mode 100644 index ce12fc71..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-a-knight-of-the-seven-kingdoms-2026-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-a-knight-of-the-seven-kingdoms-2026-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-a-knight-of-the-seven-kingdoms-2026-poster.jpg deleted file mode 100644 index 79f1351c..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-a-knight-of-the-seven-kingdoms-2026-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-absolutely-fabulous-1992-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-absolutely-fabulous-1992-backdrop.jpg deleted file mode 100644 index 2df9722d..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-absolutely-fabulous-1992-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-absolutely-fabulous-1992-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-absolutely-fabulous-1992-poster.jpg deleted file mode 100644 index afd371a9..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-absolutely-fabulous-1992-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-accel-world-2012-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-accel-world-2012-backdrop.jpg deleted file mode 100644 index 1f5f6bdc..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-accel-world-2012-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-accel-world-2012-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-accel-world-2012-poster.jpg deleted file mode 100644 index 207b1dd1..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-accel-world-2012-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-accused-2023-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-accused-2023-backdrop.jpg deleted file mode 100644 index d41c6397..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-accused-2023-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-accused-2023-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-accused-2023-poster.jpg deleted file mode 100644 index 74af010a..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-accused-2023-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-after-life-2019-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-after-life-2019-backdrop.jpg deleted file mode 100644 index eaf9a4fa..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-after-life-2019-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-after-life-2019-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-after-life-2019-poster.jpg deleted file mode 100644 index 4fae4e33..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-after-life-2019-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-agatha-christie-s-marple-2004-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-agatha-christie-s-marple-2004-backdrop.jpg deleted file mode 100644 index 0c52f2e6..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-agatha-christie-s-marple-2004-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-agatha-christie-s-marple-2004-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-agatha-christie-s-marple-2004-poster.jpg deleted file mode 100644 index ea7dda99..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-agatha-christie-s-marple-2004-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-ahsoka-2023-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-ahsoka-2023-backdrop.jpg deleted file mode 100644 index 7343fb32..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-ahsoka-2023-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-ahsoka-2023-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-ahsoka-2023-poster.jpg deleted file mode 100644 index a29d6cb4..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-ahsoka-2023-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-all-creatures-great-and-small-1978-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-all-creatures-great-and-small-1978-backdrop.jpg deleted file mode 100644 index 909ae1ba..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-all-creatures-great-and-small-1978-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-all-creatures-great-and-small-1978-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-all-creatures-great-and-small-1978-poster.jpg deleted file mode 100644 index 5b1666e6..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-all-creatures-great-and-small-1978-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-all-creatures-great-small-2020-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-all-creatures-great-small-2020-backdrop.jpg deleted file mode 100644 index d2bcc88d..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-all-creatures-great-small-2020-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-all-creatures-great-small-2020-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-all-creatures-great-small-2020-poster.jpg deleted file mode 100644 index b506f990..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-all-creatures-great-small-2020-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-american-dad-2005-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-american-dad-2005-backdrop.jpg deleted file mode 100644 index 75a1948b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-american-dad-2005-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-american-dad-2005-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-american-dad-2005-poster.jpg deleted file mode 100644 index 1f9e239a..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-american-dad-2005-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-american-gods-2017-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-american-gods-2017-backdrop.jpg deleted file mode 100644 index 4817c690..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-american-gods-2017-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-american-gods-2017-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-american-gods-2017-poster.jpg deleted file mode 100644 index c02c46da..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-american-gods-2017-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-american-housewife-2016-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-american-housewife-2016-backdrop.jpg deleted file mode 100644 index bf758ae0..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-american-housewife-2016-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-american-housewife-2016-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-american-housewife-2016-poster.jpg deleted file mode 100644 index 5f92bf05..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-american-housewife-2016-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-american-primeval-2025-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-american-primeval-2025-backdrop.jpg deleted file mode 100644 index c3bfe5e1..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-american-primeval-2025-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-american-primeval-2025-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-american-primeval-2025-poster.jpg deleted file mode 100644 index 7f10e6aa..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-american-primeval-2025-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-and-just-like-that-2021-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-and-just-like-that-2021-backdrop.jpg deleted file mode 100644 index 59c981e5..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-and-just-like-that-2021-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-and-just-like-that-2021-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-and-just-like-that-2021-poster.jpg deleted file mode 100644 index 9904c74b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-and-just-like-that-2021-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-andor-2022-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-andor-2022-backdrop.jpg deleted file mode 100644 index a874a0c0..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-andor-2022-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-andor-2022-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-andor-2022-poster.jpg deleted file mode 100644 index df5dc498..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-andor-2022-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-andromeda-2000-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-andromeda-2000-backdrop.jpg deleted file mode 100644 index 199249d7..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-andromeda-2000-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-andromeda-2000-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-andromeda-2000-poster.jpg deleted file mode 100644 index 67b766b0..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-andromeda-2000-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-anne-with-an-e-2017-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-anne-with-an-e-2017-backdrop.jpg deleted file mode 100644 index 15e325c9..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-anne-with-an-e-2017-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-anne-with-an-e-2017-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-anne-with-an-e-2017-poster.jpg deleted file mode 100644 index 55d443b4..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-anne-with-an-e-2017-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-aqua-teen-hunger-force-2000-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-aqua-teen-hunger-force-2000-backdrop.jpg deleted file mode 100644 index d0e37959..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-aqua-teen-hunger-force-2000-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-aqua-teen-hunger-force-2000-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-aqua-teen-hunger-force-2000-poster.jpg deleted file mode 100644 index e0c97321..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-aqua-teen-hunger-force-2000-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-arifureta-from-commonplace-to-world-s-strongest-2019-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-arifureta-from-commonplace-to-world-s-strongest-2019-backdrop.jpg deleted file mode 100644 index 9300e20f..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-arifureta-from-commonplace-to-world-s-strongest-2019-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-arifureta-from-commonplace-to-world-s-strongest-2019-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-arifureta-from-commonplace-to-world-s-strongest-2019-poster.jpg deleted file mode 100644 index 6a8f9a24..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-arifureta-from-commonplace-to-world-s-strongest-2019-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-arrow-2012-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-arrow-2012-backdrop.jpg deleted file mode 100644 index b32f5aca..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-arrow-2012-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-arrow-2012-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-arrow-2012-poster.jpg deleted file mode 100644 index adee3bb7..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-arrow-2012-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-atlantis-2013-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-atlantis-2013-backdrop.jpg deleted file mode 100644 index 39ecc0d6..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-atlantis-2013-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-atlantis-2013-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-atlantis-2013-poster.jpg deleted file mode 100644 index 5cd5f098..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-atlantis-2013-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-avatar-seven-havens-2026-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-avatar-seven-havens-2026-backdrop.jpg deleted file mode 100644 index dacfd59e..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-avatar-seven-havens-2026-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-avatar-seven-havens-2026-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-avatar-seven-havens-2026-poster.jpg deleted file mode 100644 index 61f459c6..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-avatar-seven-havens-2026-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-avatar-the-last-airbender-2005-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-avatar-the-last-airbender-2005-backdrop.jpg deleted file mode 100644 index f60120da..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-avatar-the-last-airbender-2005-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-avatar-the-last-airbender-2005-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-avatar-the-last-airbender-2005-poster.jpg deleted file mode 100644 index 6f99263a..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-avatar-the-last-airbender-2005-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-avatar-the-last-airbender-2024-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-avatar-the-last-airbender-2024-backdrop.jpg deleted file mode 100644 index ad740218..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-avatar-the-last-airbender-2024-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-avatar-the-last-airbender-2024-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-avatar-the-last-airbender-2024-poster.jpg deleted file mode 100644 index 9d46c2ff..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-avatar-the-last-airbender-2024-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-awkward-2011-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-awkward-2011-backdrop.jpg deleted file mode 100644 index 1ca5e56c..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-awkward-2011-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-awkward-2011-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-awkward-2011-poster.jpg deleted file mode 100644 index 8da6e8e2..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-awkward-2011-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-back-to-life-2019-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-back-to-life-2019-backdrop.jpg deleted file mode 100644 index 7ffef681..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-back-to-life-2019-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-back-to-life-2019-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-back-to-life-2019-poster.jpg deleted file mode 100644 index b00730a8..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-back-to-life-2019-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-ballers-2015-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-ballers-2015-backdrop.jpg deleted file mode 100644 index c4685e84..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-ballers-2015-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-ballers-2015-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-ballers-2015-poster.jpg deleted file mode 100644 index f1c18f69..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-ballers-2015-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-baretta-1975-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-baretta-1975-backdrop.jpg deleted file mode 100644 index 4d61dfbe..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-baretta-1975-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-baretta-1975-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-baretta-1975-poster.jpg deleted file mode 100644 index ceef0c9d..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-baretta-1975-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-based-on-a-true-story-2023-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-based-on-a-true-story-2023-backdrop.jpg deleted file mode 100644 index b59c0e58..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-based-on-a-true-story-2023-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-based-on-a-true-story-2023-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-based-on-a-true-story-2023-poster.jpg deleted file mode 100644 index 386d3d90..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-based-on-a-true-story-2023-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-batman-the-brave-and-the-bold-2008-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-batman-the-brave-and-the-bold-2008-backdrop.jpg deleted file mode 100644 index 69e567cb..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-batman-the-brave-and-the-bold-2008-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-batman-the-brave-and-the-bold-2008-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-batman-the-brave-and-the-bold-2008-poster.jpg deleted file mode 100644 index a864f50c..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-batman-the-brave-and-the-bold-2008-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-batwoman-2019-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-batwoman-2019-backdrop.jpg deleted file mode 100644 index d04a1a20..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-batwoman-2019-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-batwoman-2019-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-batwoman-2019-poster.jpg deleted file mode 100644 index 7ca86592..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-batwoman-2019-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-big-boys-2022-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-big-boys-2022-backdrop.jpg deleted file mode 100644 index c7c91e2d..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-big-boys-2022-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-big-boys-2022-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-big-boys-2022-poster.jpg deleted file mode 100644 index 93e1e86a..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-big-boys-2022-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-big-city-greens-2018-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-big-city-greens-2018-backdrop.jpg deleted file mode 100644 index 381774e7..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-big-city-greens-2018-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-big-city-greens-2018-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-big-city-greens-2018-poster.jpg deleted file mode 100644 index ef024946..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-big-city-greens-2018-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-big-mouth-2017-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-big-mouth-2017-backdrop.jpg deleted file mode 100644 index 760e0262..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-big-mouth-2017-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-big-mouth-2017-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-big-mouth-2017-poster.jpg deleted file mode 100644 index 4f535fec..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-big-mouth-2017-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-black-lightning-2018-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-black-lightning-2018-backdrop.jpg deleted file mode 100644 index 3a0854c9..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-black-lightning-2018-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-black-lightning-2018-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-black-lightning-2018-poster.jpg deleted file mode 100644 index 733f5cbc..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-black-lightning-2018-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-black-rabbit-2025-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-black-rabbit-2025-backdrop.jpg deleted file mode 100644 index 48df9d46..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-black-rabbit-2025-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-black-rabbit-2025-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-black-rabbit-2025-poster.jpg deleted file mode 100644 index 3ff9aeed..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-black-rabbit-2025-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-bleach-2004-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-bleach-2004-backdrop.jpg deleted file mode 100644 index ef8eaaa3..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-bleach-2004-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-bleach-2004-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-bleach-2004-poster.jpg deleted file mode 100644 index b233e033..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-bleach-2004-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-brassic-2019-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-brassic-2019-backdrop.jpg deleted file mode 100644 index 86d3d806..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-brassic-2019-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-brassic-2019-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-brassic-2019-poster.jpg deleted file mode 100644 index 73b77df2..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-brassic-2019-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-breaking-bad-2008-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-breaking-bad-2008-backdrop.jpg deleted file mode 100644 index e4ac4ae3..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-breaking-bad-2008-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-breaking-bad-2008-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-breaking-bad-2008-poster.jpg deleted file mode 100644 index c4f7217c..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-breaking-bad-2008-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-californication-2007-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-californication-2007-backdrop.jpg deleted file mode 100644 index ffff979b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-californication-2007-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-californication-2007-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-californication-2007-poster.jpg deleted file mode 100644 index 38428e76..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-californication-2007-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-chainsaw-man-2022-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-chainsaw-man-2022-backdrop.jpg deleted file mode 100644 index f1fbee3e..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-chainsaw-man-2022-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-chainsaw-man-2022-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-chainsaw-man-2022-poster.jpg deleted file mode 100644 index a3779772..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-chainsaw-man-2022-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-cyberpunk-edgerunners-2022-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-cyberpunk-edgerunners-2022-backdrop.jpg deleted file mode 100644 index 2920cf5a..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-cyberpunk-edgerunners-2022-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-cyberpunk-edgerunners-2022-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-cyberpunk-edgerunners-2022-poster.jpg deleted file mode 100644 index 8d338532..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-cyberpunk-edgerunners-2022-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-derry-girls-2018-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-derry-girls-2018-backdrop.jpg deleted file mode 100644 index 76fae98c..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-derry-girls-2018-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-derry-girls-2018-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-derry-girls-2018-poster.jpg deleted file mode 100644 index 56a8cd79..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-derry-girls-2018-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-desperate-housewives-2004-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-desperate-housewives-2004-backdrop.jpg deleted file mode 100644 index 40ec3001..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-desperate-housewives-2004-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-desperate-housewives-2004-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-desperate-housewives-2004-poster.jpg deleted file mode 100644 index 0c4c38bc..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-desperate-housewives-2004-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-dune-prophecy-2024-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-dune-prophecy-2024-backdrop.jpg deleted file mode 100644 index 5b940b9f..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-dune-prophecy-2024-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-dune-prophecy-2024-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-dune-prophecy-2024-poster.jpg deleted file mode 100644 index eef2a4f3..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-dune-prophecy-2024-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-etoile-2025-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-etoile-2025-backdrop.jpg deleted file mode 100644 index a8e9576c..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-etoile-2025-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-etoile-2025-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-etoile-2025-poster.jpg deleted file mode 100644 index f078bc89..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-etoile-2025-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-fallout-2024-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-fallout-2024-backdrop.jpg deleted file mode 100644 index c9d6a190..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-fallout-2024-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-fallout-2024-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-fallout-2024-poster.jpg deleted file mode 100644 index 5e87a07d..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-fallout-2024-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-firefly-2002-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-firefly-2002-backdrop.jpg deleted file mode 100644 index fa3b7604..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-firefly-2002-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-firefly-2002-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-firefly-2002-poster.jpg deleted file mode 100644 index 9ad599b3..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-firefly-2002-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-fleabag-2016-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-fleabag-2016-backdrop.jpg deleted file mode 100644 index e5a83462..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-fleabag-2016-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-fleabag-2016-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-fleabag-2016-poster.jpg deleted file mode 100644 index bd3ccea5..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-fleabag-2016-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-gilmore-girls-2000-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-gilmore-girls-2000-backdrop.jpg deleted file mode 100644 index b42ba953..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-gilmore-girls-2000-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-gilmore-girls-2000-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-gilmore-girls-2000-poster.jpg deleted file mode 100644 index 23b668cb..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-gilmore-girls-2000-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-high-potential-2024-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-high-potential-2024-backdrop.jpg deleted file mode 100644 index 66bb4d00..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-high-potential-2024-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-high-potential-2024-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-high-potential-2024-poster.jpg deleted file mode 100644 index 00a07ca7..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-high-potential-2024-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-invincible-2021-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-invincible-2021-backdrop.jpg deleted file mode 100644 index e8120387..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-invincible-2021-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-invincible-2021-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-invincible-2021-poster.jpg deleted file mode 100644 index c278e37e..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-invincible-2021-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-last-samurai-standing-2025-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-last-samurai-standing-2025-backdrop.jpg deleted file mode 100644 index c85a210b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-last-samurai-standing-2025-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-last-samurai-standing-2025-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-last-samurai-standing-2025-poster.jpg deleted file mode 100644 index a9789909..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-last-samurai-standing-2025-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-lord-of-the-flies-2026-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-lord-of-the-flies-2026-backdrop.jpg deleted file mode 100644 index 1249a8f3..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-lord-of-the-flies-2026-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-lord-of-the-flies-2026-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-lord-of-the-flies-2026-poster.jpg deleted file mode 100644 index b1229ed8..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-lord-of-the-flies-2026-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-love-death-robots-2019-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-love-death-robots-2019-backdrop.jpg deleted file mode 100644 index 3694bfc4..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-love-death-robots-2019-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-love-death-robots-2019-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-love-death-robots-2019-poster.jpg deleted file mode 100644 index 08449aa9..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-love-death-robots-2019-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-maniac-2018-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-maniac-2018-backdrop.jpg deleted file mode 100644 index 9d46de1d..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-maniac-2018-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-maniac-2018-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-maniac-2018-poster.jpg deleted file mode 100644 index a1985217..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-maniac-2018-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-neon-genesis-evangelion-1995-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-neon-genesis-evangelion-1995-backdrop.jpg deleted file mode 100644 index d80e17c1..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-neon-genesis-evangelion-1995-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-neon-genesis-evangelion-1995-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-neon-genesis-evangelion-1995-poster.jpg deleted file mode 100644 index f86cd698..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-neon-genesis-evangelion-1995-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-norsemen-2016-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-norsemen-2016-backdrop.jpg deleted file mode 100644 index 58805e67..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-norsemen-2016-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-norsemen-2016-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-norsemen-2016-poster.jpg deleted file mode 100644 index e7206b88..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-norsemen-2016-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-one-piece-2023-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-one-piece-2023-backdrop.jpg deleted file mode 100644 index 3fa4a282..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-one-piece-2023-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-one-piece-2023-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-one-piece-2023-poster.jpg deleted file mode 100644 index 286e6260..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-one-piece-2023-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-only-murders-in-the-building-2021-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-only-murders-in-the-building-2021-backdrop.jpg deleted file mode 100644 index 0b768d54..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-only-murders-in-the-building-2021-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-only-murders-in-the-building-2021-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-only-murders-in-the-building-2021-poster.jpg deleted file mode 100644 index a6b147a4..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-only-murders-in-the-building-2021-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-over-the-garden-wall-2014-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-over-the-garden-wall-2014-backdrop.jpg deleted file mode 100644 index 43ac4428..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-over-the-garden-wall-2014-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-over-the-garden-wall-2014-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-over-the-garden-wall-2014-poster.jpg deleted file mode 100644 index 34b1ed84..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-over-the-garden-wall-2014-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-pluribus-2025-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-pluribus-2025-backdrop.jpg deleted file mode 100644 index e64c0268..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-pluribus-2025-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-pluribus-2025-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-pluribus-2025-poster.jpg deleted file mode 100644 index 1ea4711b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-pluribus-2025-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-rick-and-morty-2013-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-rick-and-morty-2013-backdrop.jpg deleted file mode 100644 index 1c4c0ffc..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-rick-and-morty-2013-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-rick-and-morty-2013-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-rick-and-morty-2013-poster.jpg deleted file mode 100644 index b95c4890..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-rick-and-morty-2013-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-secret-level-2024-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-secret-level-2024-backdrop.jpg deleted file mode 100644 index 54d2a13e..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-secret-level-2024-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-secret-level-2024-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-secret-level-2024-poster.jpg deleted file mode 100644 index 1b6e67f6..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-secret-level-2024-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-severance-2022-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-severance-2022-backdrop.jpg deleted file mode 100644 index a24c03bd..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-severance-2022-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-severance-2022-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-severance-2022-poster.jpg deleted file mode 100644 index 5a29d6f9..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-severance-2022-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-sex-and-the-city-1998-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-sex-and-the-city-1998-backdrop.jpg deleted file mode 100644 index 57beacc1..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-sex-and-the-city-1998-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-sex-and-the-city-1998-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-sex-and-the-city-1998-poster.jpg deleted file mode 100644 index e546cc6d..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-sex-and-the-city-1998-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-100-2014-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-100-2014-backdrop.jpg deleted file mode 100644 index 8d41cb22..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-100-2014-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-100-2014-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-100-2014-poster.jpg deleted file mode 100644 index 4d254cb0..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-100-2014-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-abbott-and-costello-show-1952-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-abbott-and-costello-show-1952-backdrop.jpg deleted file mode 100644 index 53e1d593..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-abbott-and-costello-show-1952-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-abbott-and-costello-show-1952-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-abbott-and-costello-show-1952-poster.jpg deleted file mode 100644 index 7d6768ea..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-abbott-and-costello-show-1952-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-afterparty-2022-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-afterparty-2022-backdrop.jpg deleted file mode 100644 index 72ca19db..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-afterparty-2022-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-afterparty-2022-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-afterparty-2022-poster.jpg deleted file mode 100644 index 9beacde2..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-afterparty-2022-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-bear-2022-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-bear-2022-backdrop.jpg deleted file mode 100644 index 9c9cca57..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-bear-2022-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-bear-2022-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-bear-2022-poster.jpg deleted file mode 100644 index bbf0ab28..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-bear-2022-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-beast-in-me-2025-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-beast-in-me-2025-backdrop.jpg deleted file mode 100644 index e7727a79..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-beast-in-me-2025-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-beast-in-me-2025-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-beast-in-me-2025-poster.jpg deleted file mode 100644 index c78c5cf0..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-beast-in-me-2025-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-bold-type-2017-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-bold-type-2017-backdrop.jpg deleted file mode 100644 index dd84deab..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-bold-type-2017-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-bold-type-2017-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-bold-type-2017-poster.jpg deleted file mode 100644 index f663eb8b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-bold-type-2017-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-boys-2019-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-boys-2019-backdrop.jpg deleted file mode 100644 index a834d9fb..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-boys-2019-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-boys-2019-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-boys-2019-poster.jpg deleted file mode 100644 index f67ff16f..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-boys-2019-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-capture-2019-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-capture-2019-backdrop.jpg deleted file mode 100644 index 42256fc1..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-capture-2019-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-capture-2019-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-capture-2019-poster.jpg deleted file mode 100644 index a4039011..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-capture-2019-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-durrells-2016-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-durrells-2016-backdrop.jpg deleted file mode 100644 index 3f8bdeec..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-durrells-2016-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-durrells-2016-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-durrells-2016-poster.jpg deleted file mode 100644 index d29448bb..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-durrells-2016-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-final-problem-2026-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-final-problem-2026-backdrop.jpg deleted file mode 100644 index 61a310d8..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-final-problem-2026-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-final-problem-2026-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-final-problem-2026-poster.jpg deleted file mode 100644 index f0332826..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-final-problem-2026-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-legend-of-korra-2012-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-legend-of-korra-2012-backdrop.jpg deleted file mode 100644 index ab6086bd..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-legend-of-korra-2012-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-legend-of-korra-2012-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-legend-of-korra-2012-poster.jpg deleted file mode 100644 index a7086d5e..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-legend-of-korra-2012-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-lord-of-the-rings-the-rings-of-power-2022-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-lord-of-the-rings-the-rings-of-power-2022-backdrop.jpg deleted file mode 100644 index 0b88fd4b..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-lord-of-the-rings-the-rings-of-power-2022-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-lord-of-the-rings-the-rings-of-power-2022-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-lord-of-the-rings-the-rings-of-power-2022-poster.jpg deleted file mode 100644 index dc387fcd..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-lord-of-the-rings-the-rings-of-power-2022-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-night-manager-2016-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-night-manager-2016-backdrop.jpg deleted file mode 100644 index 327aa449..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-night-manager-2016-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-night-manager-2016-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-night-manager-2016-poster.jpg deleted file mode 100644 index 7ab2dbf5..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-night-manager-2016-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-tatami-galaxy-2010-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-tatami-galaxy-2010-backdrop.jpg deleted file mode 100644 index a267b4cb..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-tatami-galaxy-2010-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-tatami-galaxy-2010-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-tatami-galaxy-2010-poster.jpg deleted file mode 100644 index 5324dc75..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-tatami-galaxy-2010-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-white-lotus-2021-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-white-lotus-2021-backdrop.jpg deleted file mode 100644 index 1f747323..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-white-lotus-2021-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-white-lotus-2021-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-white-lotus-2021-poster.jpg deleted file mode 100644 index 2f23d1fa..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-white-lotus-2021-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-witcher-2019-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-witcher-2019-backdrop.jpg deleted file mode 100644 index acca834e..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-witcher-2019-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-the-witcher-2019-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-the-witcher-2019-poster.jpg deleted file mode 100644 index f5eb8f59..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-the-witcher-2019-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-upload-2020-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-upload-2020-backdrop.jpg deleted file mode 100644 index f350a49c..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-upload-2020-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-upload-2020-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-upload-2020-poster.jpg deleted file mode 100644 index 547d3b7a..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-upload-2020-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-widow-s-bay-2026-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-widow-s-bay-2026-backdrop.jpg deleted file mode 100644 index 03b1c335..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-widow-s-bay-2026-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-widow-s-bay-2026-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-widow-s-bay-2026-poster.jpg deleted file mode 100644 index 8c02a0d7..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-widow-s-bay-2026-poster.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-yellowjackets-2021-backdrop.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-yellowjackets-2021-backdrop.jpg deleted file mode 100644 index 960c2d23..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-yellowjackets-2021-backdrop.jpg and /dev/null differ diff --git a/app/src/debug/assets/wolfskin-titles/assets/tv-yellowjackets-2021-poster.jpg b/app/src/debug/assets/wolfskin-titles/assets/tv-yellowjackets-2021-poster.jpg deleted file mode 100644 index c7e16a57..00000000 Binary files a/app/src/debug/assets/wolfskin-titles/assets/tv-yellowjackets-2021-poster.jpg and /dev/null differ diff --git a/app/src/default/AndroidManifest.xml b/app/src/default/AndroidManifest.xml deleted file mode 100644 index c59612c7..00000000 --- a/app/src/default/AndroidManifest.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/app/src/test/java/org/justinvisser/wolfskin/tv/ShellRoutingTest.kt b/app/src/test/java/org/justinvisser/wolfskin/tv/ShellRoutingTest.kt index a5b181f7..d1944584 100644 --- a/app/src/test/java/org/justinvisser/wolfskin/tv/ShellRoutingTest.kt +++ b/app/src/test/java/org/justinvisser/wolfskin/tv/ShellRoutingTest.kt @@ -54,17 +54,4 @@ class ShellRoutingTest { assertEquals(Destination.Search("name"), resolveUpstreamDestination(Destination.Search("name"), enabled, libraries)) } } - - @Test fun titleRolloutOwnsOnlyFilmSeriesEpisodeAndPerson() { - val id = UUID.fromString("00000000-0000-0000-0000-000000000001") - for (kind in listOf(BaseItemKind.MOVIE, BaseItemKind.SERIES, BaseItemKind.EPISODE, BaseItemKind.PERSON)) { - val destination = Destination.MediaItem(id, kind) - assertNull(resolveUpstreamDestination(destination, true, libraries)) - assertEquals(destination, resolveUpstreamDestination(destination, false, libraries)) - } - for (kind in listOf(BaseItemKind.COLLECTION_FOLDER, BaseItemKind.AUDIO, BaseItemKind.MUSIC_ALBUM, BaseItemKind.BOX_SET)) { - val destination = Destination.MediaItem(id, kind) - assertEquals(destination, resolveUpstreamDestination(destination, true, libraries)) - } - } } diff --git a/app/src/test/java/org/justinvisser/wolfskin/tv/TitleAsyncFocusTest.kt b/app/src/test/java/org/justinvisser/wolfskin/tv/TitleAsyncFocusTest.kt deleted file mode 100644 index 8316538b..00000000 --- a/app/src/test/java/org/justinvisser/wolfskin/tv/TitleAsyncFocusTest.kt +++ /dev/null @@ -1,165 +0,0 @@ -package org.justinvisser.wolfskin.tv - -import android.app.Application -import androidx.activity.ComponentActivity -import androidx.compose.ui.input.key.Key -import androidx.compose.ui.test.junit4.createAndroidComposeRule -import androidx.compose.ui.test.assertIsDisplayed -import androidx.compose.ui.test.onNodeWithTag -import androidx.compose.ui.test.onRoot -import androidx.compose.ui.test.performKeyInput -import androidx.compose.ui.test.pressKey -import androidx.lifecycle.viewModelScope -import com.github.damontecres.wholphin.preferences.AppPreferences -import com.github.damontecres.wholphin.preferences.UserPreferences -import com.github.damontecres.wholphin.services.NavigationManager -import io.mockk.coEvery -import io.mockk.mockk -import kotlinx.coroutines.CompletableDeferred -import kotlinx.coroutines.cancel -import org.junit.After -import org.junit.Assert.* -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.justinvisser.wolfskin.design.ShellPerson -import org.justinvisser.wolfskin.design.RecoveryMessage -import org.justinvisser.wolfskin.design.TitleConnection -import org.justinvisser.wolfskin.design.ShellState -import org.justinvisser.wolfskin.design.TitleItem -import org.justinvisser.wolfskin.design.TitlePageData -import org.justinvisser.wolfskin.design.TitleReadStatus -import org.justinvisser.wolfskin.design.TitleSheet -import org.justinvisser.wolfskin.design.TitleTrack -import org.justinvisser.wolfskin.design.TitleVersion -import org.justinvisser.wolfskin.design.WolfskinTheme -import org.justinvisser.wolfskin.tv.read.TitleReadFacade -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config -import java.util.UUID - -/** A delayed service reply exercises the production destination, view-model and Android focus transfer. */ -@RunWith(RobolectricTestRunner::class) -@Config(sdk = [34], application = Application::class, qualifiers = "w960dp-h540dp-xhdpi") -class TitleAsyncFocusTest { - @get:Rule val rule = createAndroidComposeRule() - private lateinit var viewModel: WolfskinTitleViewModel - - @After fun dispose() { - if (::viewModel.isInitialized) viewModel.viewModelScope.cancel() - } - - @Test fun loadingToReadyRestoresRealKeyFocusAndSheetReturn() { - val id = UUID.fromString("00000000-0000-0000-0000-000000000012") - val ready = CompletableDeferred() - val facade = mockk() - coEvery { facade.readSaved(id, any()) } returns null - coEvery { facade.read(id, any(), any()) } coAnswers { ready.await() } - viewModel = WolfskinTitleViewModel(rule.activity, facade, mockk(), mockk(relaxed = true)) - val person = ShellPerson("justin", "Justin", "J", false) - val route = titleRoute(id.toString()) - val shell = ShellState(listOf(person), person.key).apply { - pickerVisible = false - pickerLaunch = false - enterDestination(route) - } - val preferences = UserPreferences(AppPreferences.getDefaultInstance(), null) - rule.setContent { WolfskinTheme { TitleDestination(route, shell, preferences, viewModel = viewModel) } } - rule.waitUntil { viewModel.title?.data?.status == TitleReadStatus.Loading } - rule.waitForIdle() - assertTrue(shell.navFocused) - press(Key.DirectionDown) - assertTrue("The initial skeleton cannot receive nav Down", shell.navFocused) - - val source = TitleVersion("first", "Original", "1080p", "", "", "MKV", listOf(TitleTrack(3, "English", true)), emptyList()) - rule.runOnIdle { - ready.complete(TitlePageData(TitleItem(id.toString(), "A held film", "movie", held = true), versions = listOf(source, source.copy(id = "second", name = "Alternate")))) - } - rule.waitUntil { viewModel.title?.data?.status == TitleReadStatus.Ready && !shell.navFocused } - press(Key.DirectionRight) - val state = requireNotNull(viewModel.title) - assertEquals("version", state.options[state.column].id) - press(Key.DirectionCenter) - assertEquals(TitleSheet.Version, state.sheet) - rule.runOnIdle { rule.activity.onBackPressedDispatcher.onBackPressed() } - assertNull(state.sheet) - press(Key.DirectionRight) - assertEquals("tracks", state.options[state.column].id) - assertFalse(shell.navFocused) - } - - @Test fun loadingPersonFocusesItsFirstCreditBeforeRealRemoteNavigation() { - val id = UUID.fromString("00000000-0000-0000-0000-000000000013") - val reply = CompletableDeferred() - val facade = mockk() - coEvery { facade.readPersonSaved(id) } returns null - coEvery { facade.readPerson(id, 0) } coAnswers { reply.await() } - viewModel = WolfskinTitleViewModel(rule.activity, facade, mockk(), mockk(relaxed = true)) - val viewer = ShellPerson("justin", "Justin", "J", false) - val route = personRoute(id.toString()) - val shell = ShellState(listOf(viewer), viewer.key).apply { - pickerVisible = false - pickerLaunch = false - enterDestination(route) - } - rule.setContent { WolfskinTheme { - TitleDestination(route, shell, UserPreferences(AppPreferences.getDefaultInstance(), null), viewModel = viewModel) - } } - rule.waitUntil { viewModel.title?.data?.status == TitleReadStatus.Loading } - rule.waitForIdle() - assertTrue(shell.navFocused) - press(Key.DirectionDown) - assertTrue(shell.navFocused) - rule.runOnIdle { - reply.complete(org.justinvisser.wolfskin.tv.read.PersonRead( - org.justinvisser.wolfskin.design.TitlePerson(id.toString(), "Actor"), - listOf(TitleItem("first-credit", "First credit", "movie"), TitleItem("second-credit", "Second credit", "movie")), - )) - } - rule.waitUntil(timeoutMillis = 5000) { viewModel.person != null || viewModel.title?.data?.status == TitleReadStatus.Unavailable } - assertNotNull("A real person reply must populate the performer destination", viewModel.person) - rule.waitForIdle() - assertFalse("The loaded person must transfer nav ownership to its first credit", shell.navFocused) - assertEquals(0, viewModel.person!!.index) - press(Key.DirectionRight) - assertEquals(1, viewModel.person!!.index) - assertFalse(shell.navFocused) - } - - @Test fun failedRetryKeepsThePersonsSavedTitleAndShowsSharedRecovery() { - val id = UUID.fromString("00000000-0000-0000-0000-000000000014") - val reads = java.util.concurrent.atomic.AtomicInteger() - val saved = TitlePageData(TitleItem(id.toString(), "Saved title", "movie"), - connection = TitleConnection.Offline, savedAt = "20:42") - val facade = mockk() - coEvery { facade.readSaved(id, any()) } returns saved - coEvery { facade.read(id, any(), any()) } coAnswers { - reads.incrementAndGet() - throw java.io.IOException("offline") - } - viewModel = WolfskinTitleViewModel(rule.activity, facade, mockk(), mockk(relaxed = true)) - val viewer = ShellPerson("justin", "Justin", "J", false) - val route = titleRoute(id.toString()) - val shell = ShellState(listOf(viewer), viewer.key).apply { - pickerVisible = false; pickerLaunch = false; enterDestination(route) - } - rule.setContent { WolfskinTheme { - TitleDestination(route, shell, UserPreferences(AppPreferences.getDefaultInstance(), null), viewModel = viewModel) - } } - rule.waitUntil(timeoutMillis = 5000) { reads.get() == 1 && viewModel.title?.toast != null } - rule.waitForIdle() - assertEquals("20:42", shell.navSavedAt) - assertEquals("retry", viewModel.title!!.options[viewModel.title!!.column].id) - rule.runOnIdle { viewModel.title!!.toast = null } - press(Key.DirectionCenter) - rule.waitUntil(timeoutMillis = 5000) { reads.get() == 2 && viewModel.title?.toast != null } - rule.waitForIdle() - assertEquals("Saved title", viewModel.title!!.data.item.name) - assertEquals("20:42", shell.navSavedAt) - assertEquals(RecoveryMessage.StillUnreachable, viewModel.title!!.toast) - assertFalse(shell.navFocused) - rule.onNodeWithTag("recovery-toast").assertIsDisplayed() - } - - private fun press(key: Key) { rule.onRoot().performKeyInput { pressKey(key) } } -} diff --git a/app/src/test/java/org/justinvisser/wolfskin/tv/TitleCaptureTest.kt b/app/src/test/java/org/justinvisser/wolfskin/tv/TitleCaptureTest.kt deleted file mode 100644 index 90d6fcc1..00000000 --- a/app/src/test/java/org/justinvisser/wolfskin/tv/TitleCaptureTest.kt +++ /dev/null @@ -1,218 +0,0 @@ -package org.justinvisser.wolfskin.tv - -import android.app.Application -import android.graphics.Bitmap -import android.graphics.BitmapFactory -import android.view.View -import android.view.WindowManager -import androidx.activity.ComponentActivity -import androidx.compose.foundation.layout.requiredSize -import androidx.compose.runtime.CompositionLocalProvider -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.asImageBitmap -import androidx.compose.ui.test.junit4.createAndroidComposeRule -import androidx.compose.ui.test.onRoot -import androidx.compose.ui.test.onAllNodesWithTag -import androidx.compose.ui.test.onNodeWithTag -import androidx.compose.ui.test.performSemanticsAction -import androidx.compose.ui.semantics.SemanticsActions -import androidx.compose.ui.text.TextLayoutResult -import androidx.compose.ui.test.SemanticsMatcher -import androidx.compose.ui.graphics.toArgb -import com.github.takahirom.roborazzi.captureRoboImage -import org.json.JSONObject -import org.junit.Before -import org.junit.After -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.justinvisser.wolfskin.design.LocalTitleBitmaps -import org.justinvisser.wolfskin.design.PersonState -import org.justinvisser.wolfskin.design.PersonSurface -import org.justinvisser.wolfskin.design.ShellKey -import org.justinvisser.wolfskin.design.ShellState -import org.justinvisser.wolfskin.design.TitleConnection -import org.justinvisser.wolfskin.design.TitlePageData -import org.justinvisser.wolfskin.design.TitleReadStatus -import org.justinvisser.wolfskin.design.TitleState -import org.justinvisser.wolfskin.design.TitleSurface -import org.justinvisser.wolfskin.design.WolfskinTheme -import org.justinvisser.wolfskin.design.WolfskinTokens -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config -import org.robolectric.annotation.GraphicsMode -import java.io.File -import java.util.Locale - -/** Frozen local art feeds the shipped Compose surface; no test can call a live server. */ -@RunWith(RobolectricTestRunner::class) -@Config(sdk = [34], application = Application::class, qualifiers = "w960dp-h540dp-xhdpi") -@GraphicsMode(GraphicsMode.Mode.NATIVE) -class TitleCaptureTest { - @get:Rule val rule = createAndroidComposeRule() - private lateinit var fixture: TitleFixture - private var previousLocale = Locale.getDefault() - - @Before fun fullscreen() { - previousLocale = Locale.getDefault() - Locale.setDefault(Locale.US) - rule.activity.window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN) - @Suppress("DEPRECATION") - rule.activity.window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY - fixture = TitleFixture(rule.activity.assets.open("wolfskin-titles.json").bufferedReader().use { JSONObject(it.readText()) }) - } - @After fun restoreLocale() { Locale.setDefault(previousLocale) } - - private fun capture(number: Int, title: String = "Locke", person: String = "justin", transform: (TitlePageData) -> TitlePageData = { it }, configure: (TitleState, ShellState) -> Unit = { _, _ -> }) { - val data = transform(fixture.title(title, person)) - val shell = ShellState(fixture.people, person).apply { pickerVisible = false; pickerLaunch = false; enterDestination("title/${data.item.id}") } - val state = TitleState(data, shell.person) {} - configure(state, shell) - val bitmaps = decodeArt(data) - rule.setContent { - WolfskinTheme { CompositionLocalProvider(LocalTitleBitmaps provides bitmaps) { - TitleSurface(state, shell, Modifier.requiredSize(WolfskinTokens.Shell.stageWidth, WolfskinTokens.Shell.stageHeight)) - } } - } - if (number == 55) rule.runOnIdle { - shell.view.listState.requestScrollToItem(1, -(WolfskinTokens.Layout.pinnedLine.value * 2).toInt()) - } - save(number) - } - - private fun decodeArt(data: TitlePageData): Map { - val requests = buildList> { - data.item.backdrop?.let { add(Triple(it, 1280, 720)) } - if (data.item.backdrop == null || data.item.isPosterBackdrop) data.item.poster?.let { add(Triple(it, 420, 630)) } - data.cast.forEach { person -> person.portrait?.let { add(Triple(it, 200, 200)) } } - data.related.forEach { item -> item.poster?.let { add(Triple(it, 256, 384)) } } - data.episodes.forEach { item -> - (if (item.isPosterBackdrop) item.poster else item.backdrop)?.let { add(Triple(it, 416, 234)) } - } - } - return requests.distinctBy { it.first }.associate { (path, width, height) -> - val bitmap = rule.activity.assets.open(path.removePrefix("file:///android_asset/")).use { BitmapFactory.decodeStream(it)!! } - val scale = maxOf(width.toFloat() / bitmap.width, height.toFloat() / bitmap.height).coerceAtMost(1f) - val scaled = Bitmap.createScaledBitmap(bitmap, (bitmap.width * scale).toInt(), (bitmap.height * scale).toInt(), true) - if (scaled !== bitmap) bitmap.recycle() - path to scaled.asImageBitmap() - } - } - - private fun save(number: Int) { - rule.mainClock.advanceTimeBy(1000) - rule.waitForIdle() - val directory = File(requireNotNull(System.getProperty("wolfskin.captureDirectory"))).apply { mkdirs() } - rule.onRoot().captureRoboImage(File(directory, "st-${number.toString().padStart(3, '0')}.png").absolutePath) - val heading = rule.onAllNodesWithTag("title-heading").fetchSemanticsNodes().singleOrNull() - if (heading != null) { - val layouts = mutableListOf() - rule.onNodeWithTag("title-heading").performSemanticsAction(SemanticsActions.GetTextLayoutResult) { action -> action(layouts) } - val layout = layouts.single() - val metrics = JSONObject().put("title", layout.layoutInput.text.text).put("lineCount", layout.lineCount) - .put("lineWidthsPx", org.json.JSONArray(List(layout.lineCount) { layout.getLineRight(it) - layout.getLineLeft(it) })) - .put("ellipsized", org.json.JSONArray(List(layout.lineCount) { layout.isLineEllipsized(it) })) - .put("maxWidthPx", layout.layoutInput.constraints.maxWidth).put("fontSizeSp", layout.layoutInput.style.fontSize.value) - .put("requestedWeight", layout.layoutInput.style.fontWeight?.weight) - .put("boundsPx", org.json.JSONArray(listOf(heading.boundsInRoot.left, heading.boundsInRoot.top, heading.boundsInRoot.right, heading.boundsInRoot.bottom))) - File(directory, "st-${number.toString().padStart(3, '0')}-layout.json").writeText(metrics.toString(2)) - } - recordTextMetrics(directory, number) - recordElements(directory, number) - } - - private fun recordTextMetrics(directory: File, number: Int) { - val elements = rule.onAllNodes(SemanticsMatcher.keyIsDefined(SemanticsActions.GetTextLayoutResult), useUnmergedTree = true) - val records = org.json.JSONArray() - elements.fetchSemanticsNodes().forEachIndexed { index, node -> - if (node.boundsInRoot.width > 0 && node.boundsInRoot.height > 0) { - val layouts = mutableListOf() - elements[index].performSemanticsAction(SemanticsActions.GetTextLayoutResult) { action -> action(layouts) } - val layout = layouts.single() - records.put(JSONObject().put("text", layout.layoutInput.text.text) - .put("fontSizeSp", layout.layoutInput.style.fontSize.value) - .put("weight", layout.layoutInput.style.fontWeight?.weight) - .put("colourArgb", Integer.toUnsignedString(layout.layoutInput.style.color.toArgb(), 16)) - .put("lineHeightSp", layout.layoutInput.style.lineHeight.value.takeIf { it.isFinite() } ?: JSONObject.NULL) - .put("lineCount", layout.lineCount) - .put("boundsPx", org.json.JSONArray(listOf(node.boundsInRoot.left, node.boundsInRoot.top, node.boundsInRoot.right, node.boundsInRoot.bottom))) - .put("spans", org.json.JSONArray(layout.layoutInput.text.spanStyles.map { span -> - JSONObject().put("start", span.start).put("end", span.end).put("weight", span.item.fontWeight?.weight) - }))) - } - } - File(directory, "st-${number.toString().padStart(3, '0')}-text.json").writeText(records.toString(2)) - } - - private fun recordElements(directory: File, number: Int) { - val tag = androidx.compose.ui.semantics.SemanticsProperties.TestTag - val description = androidx.compose.ui.semantics.SemanticsProperties.ContentDescription - val matcher = SemanticsMatcher.keyIsDefined(tag) or SemanticsMatcher.keyIsDefined(description) - val records = org.json.JSONArray() - rule.onAllNodes(matcher, useUnmergedTree = true).fetchSemanticsNodes().forEach { node -> - records.put(JSONObject() - .put("tag", if (node.config.contains(tag)) node.config[tag] else JSONObject.NULL) - .put("description", if (node.config.contains(description)) org.json.JSONArray(node.config[description]) else JSONObject.NULL) - .put("boundsPx", org.json.JSONArray(listOf(node.boundsInRoot.left, node.boundsInRoot.top, node.boundsInRoot.right, node.boundsInRoot.bottom)))) - } - File(directory, "st-${number.toString().padStart(3, '0')}-elements.json").writeText(records.toString(2)) - } - - private fun option(state: TitleState, id: String) { state.focus("header", state.options.indexOfFirst { it.id == id }) } - private fun open(state: TitleState, shell: ShellState, id: String) { - option(state, id) - state.key(ShellKey.Ok, true, 0, shell) - state.key(ShellKey.Ok, false, 0, shell) - } - - @Test fun st042_heldMovie() = capture(42, "The Girl Who Leapt Through Time") - @Test fun st043_options() = capture(43) { state, _ -> option(state, "version") } - @Test fun st044_versions() = capture(44) { state, shell -> open(state, shell, "version") } - @Test fun st045_rememberedVersion() = capture(45) { state, _ -> state.versionId = "v2"; option(state, "version") } - @Test fun st046_tracks() = capture(46) { state, shell -> open(state, shell, "tracks") } - @Test fun st047_mediaInfo() = capture(47) { state, shell -> open(state, shell, "more") } - @Test fun st048_trailerNoApp() = capture(48) { state, _ -> option(state, "trailer"); state.toast = "No YouTube app is available to play this trailer." } - @Test fun st049_watched() = capture(49, transform = { it.copy(watchTarget = it.watchTarget.copy(watched = true)) }) { state, _ -> option(state, "watched") } - @Test fun st050_seriesConfirm() = capture(50, "Andor") { state, shell -> open(state, shell, "watched") } - @Test fun st051_episodeRestart() = capture(51, "episode-sex-and-the-country-2001-s4e9", "mindel") { state, _ -> option(state, "restart") } - @Test fun st052_filmCast() = capture(52) { state, shell -> - state.focus("cast", 0) - state.key(ShellKey.Right, true, 0, shell) - state.key(ShellKey.Right, false, 0, shell) - } - @Test fun st053_seriesCast() = capture(53, "Andor") { state, _ -> state.focus("cast", 0) } - @Test fun st054_initialsCast() = capture(54, "Spirited Away", "shared") { state, _ -> state.focus("cast", 0) } - @Test fun st055_castLoading() = capture(55, transform = { it.copy(cast = emptyList(), castStatus = TitleReadStatus.Loading) }) - @Test fun st056_castUnavailable() = capture(56, transform = { it.copy(cast = emptyList(), castStatus = TitleReadStatus.Unavailable) }) { state, _ -> state.focus("related", 0) } - @Test fun st057_person() { - val (person, credits) = fixture.person("Tom Holland", "justin") - val shell = ShellState(fixture.people, "justin").apply { pickerVisible = false; enterDestination("person/Tom Holland") } - val state = PersonState(person, credits, {}) - val data = TitlePageData(credits.first(), cast = listOf(person), related = credits) - val art = decodeArt(data) - rule.setContent { WolfskinTheme { CompositionLocalProvider(LocalTitleBitmaps provides art) { - PersonSurface(state, shell, Modifier.requiredSize(WolfskinTokens.Shell.stageWidth, WolfskinTokens.Shell.stageHeight)) - } } } - save(57) - } - @Test fun st058_hiddenReceipt() = capture(58, "The Amazing Spider-Man") { state, shell -> open(state, shell, "hide") } - @Test fun st059_hiddenPick() = capture(59, "The Amazing Spider-Man", transform = { it.copy(hidden = true) }) { state, _ -> option(state, "unhide") } - @Test fun st060_titleNav() = capture(60) { _, shell -> shell.focusNav(0) } - @Test fun st061_loading() = capture(61, transform = { it.copy(status = TitleReadStatus.Loading) }) { _, shell -> shell.focusNav(0) } - @Test fun st062_error() = capture(62, transform = { it.copy(status = TitleReadStatus.Unavailable) }) - @Test fun st063_signedOut() = capture(63, "The Amazing Spider-Man", transform = { it.copy(connection = TitleConnection.SignedOut) }) - @Test fun st064_seriesNext() = capture(64, "Andor") - @Test fun st065_resumeEpisode() = capture(65, "episode-sex-and-the-country-2001-s4e9", "mindel") - @Test fun st066_notHeld() = capture(66, "The Amazing Spider-Man") - @Test fun st067_trailerFallback() = capture(67, "The Amazing Spider-Man") - @Test fun st068_requested() = capture(68, "The Amazing Spider-Man", transform = { it.copy(requestedStage = "Searching", requestActor = "Justin") }) - @Test fun st069_missingArt() = capture(69, "The Amazing Spider-Man", transform = { it.copy(item = it.item.copy(poster = null, backdrop = null)) }) - @Test fun st070_offline() = capture(70, "The Amazing Spider-Man", transform = { - it.copy(connection = TitleConnection.Offline, savedAt = "20:42", item = it.item.copy(ratings = emptyList())) - }) - @Test fun st104_relatedPlate() = capture(104, "The Girl Who Leapt Through Time") { state, _ -> state.focus("related", state.data.related.indexOfFirst { it.name == "INVINCIBLE" }.coerceAtLeast(0)) } - @Test fun st106_heldRatings() = capture(106, "American Gangster", "shared") - @Test fun st107_seriesEpisodeRatings() = capture(107, "Andor") - @Test fun st108_resumingEpisodeRatings() = capture(108, "episode-sex-and-the-country-2001-s4e9", "mindel") - @Test fun st109_noRatings() = capture(109, "The Amazing Spider-Man") -} diff --git a/app/src/test/java/org/justinvisser/wolfskin/tv/TitleKeysTest.kt b/app/src/test/java/org/justinvisser/wolfskin/tv/TitleKeysTest.kt deleted file mode 100644 index 6df8426d..00000000 --- a/app/src/test/java/org/justinvisser/wolfskin/tv/TitleKeysTest.kt +++ /dev/null @@ -1,345 +0,0 @@ -package org.justinvisser.wolfskin.tv - -import android.app.Application -import androidx.activity.ComponentActivity -import androidx.activity.compose.BackHandler -import androidx.compose.ui.input.key.Key -import androidx.compose.ui.test.junit4.createAndroidComposeRule -import androidx.compose.ui.test.onRoot -import androidx.compose.ui.test.performKeyInput -import androidx.compose.ui.test.pressKey -import androidx.compose.ui.test.onNodeWithTag -import androidx.compose.ui.test.performMouseInput -import androidx.compose.ui.test.onNodeWithText -import androidx.compose.ui.test.performSemanticsAction -import androidx.compose.ui.semantics.SemanticsActions -import androidx.compose.ui.text.TextLayoutResult -import org.justinvisser.wolfskin.design.WolfskinTokens -import org.json.JSONArray -import org.json.JSONObject -import org.junit.Assert.* -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.justinvisser.wolfskin.design.ShellAction -import org.justinvisser.wolfskin.design.ShellState -import org.justinvisser.wolfskin.design.TitleAction -import org.justinvisser.wolfskin.design.TitleConnection -import org.justinvisser.wolfskin.design.TitleReadStatus -import org.justinvisser.wolfskin.design.TitleSheet -import org.justinvisser.wolfskin.design.TitleState -import org.justinvisser.wolfskin.design.TitleSurface -import org.justinvisser.wolfskin.design.WolfskinTheme -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config -import org.robolectric.annotation.GraphicsMode - -/** Approved title-entry suffixes replay Android keys through the rendered title and shared shell. */ -@RunWith(RobolectricTestRunner::class) -@Config(sdk = [34], application = Application::class, qualifiers = "w960dp-h540dp-xhdpi") -class TitleKeysTest { - @get:Rule val rule = createAndroidComposeRule() - private lateinit var fixture: TitleFixture - private val effects = mutableListOf() - private val shellEffects = mutableListOf() - private lateinit var state: TitleState - private lateinit var shell: ShellState - private lateinit var paths: List - - @Before fun fixtures() { - fixture = TitleFixture(rule.activity.assets.open("wolfskin-titles.json").bufferedReader().use { JSONObject(it.readText()) }) - val data = javaClass.getResourceAsStream("/title-press-paths.json")!!.bufferedReader().use { JSONArray(it.readText()) } - paths = List(data.length()) { data.getJSONObject(it) } - } - - private fun render(title: String = "Locke", transform: (org.justinvisser.wolfskin.design.TitlePageData) -> org.justinvisser.wolfskin.design.TitlePageData = { it }) { - shell = ShellState(fixture.people, "justin", shellEffects::add).apply { pickerVisible = false; pickerLaunch = false; enterDestination(titleRoute(title)) } - state = TitleState(transform(fixture.title(title, "justin")), shell.person, effects::add) - rule.setContent { WolfskinTheme { - BackHandler { state.back(shell) } - TitleSurface(state, shell) - } } - } - - private fun press(key: Key) { rule.onRoot().performKeyInput { pressKey(key) } } - private fun replay(end: String): Int { - val path = paths.single { it.getString("end") == end } - render(path.getString("title")) - val keys = path.getJSONArray("keys") - var presses = 0 - for (index in path.getInt("entryPresses") until keys.length()) { - val key = when (keys.getString(index)) { - "UP" -> Key.DirectionUp - "DOWN" -> Key.DirectionDown - "LEFT" -> Key.DirectionLeft - "RIGHT" -> Key.DirectionRight - "OK" -> Key.DirectionCenter - else -> error("Unknown replay key") - } - press(key) - presses++ - } - return presses - } - - @Test fun titleToNavOnePressFromEntry() { - assertEquals(1, replay("nav")) - assertTrue(shell.navFocused) - assertEquals(shell.currentTab, shell.navIndex) - } - - @Test fun switchPersonFivePressesFromTitleEntry() { - assertEquals(5, replay("person-mindel")) - assertEquals("mindel", shell.person.key) - assertEquals("home", shell.route) - assertFalse(shell.pickerVisible) - assertTrue(shellEffects.last() is ShellAction.Person) - } - - @Test fun lockeSecondVersionSixPressesFromTitleEntry() { - assertEquals(6, replay("play-version-2")) - assertEquals("v2", state.versionId) - assertNull(state.sheet) - assertEquals("play", state.options[state.column].id) - assertTrue(effects.last() is TitleAction.Play) - assertEquals("Locke", (effects.last() as TitleAction.Play).item.name) - } - - @Test fun lockeCastTwoPressesFromTitleEntry() { - assertEquals(2, replay("person-Tom Hardy")) - assertEquals("cast", state.row) - assertEquals("Tom Hardy", (effects.single() as TitleAction.Person).person.name) - } - - @Test fun sheetBackRestoresItsOpeningOptionAndChosenVersion() { - render() - press(Key.DirectionRight) - press(Key.DirectionCenter) - assertEquals(TitleSheet.Version, state.sheet) - press(Key.DirectionDown) - press(Key.DirectionCenter) - assertEquals("v2", state.versionId) - assertEquals("Version", state.options[state.column].label) - press(Key.DirectionCenter) - assertEquals(1, state.sheetIndex) - press(Key.Back) - assertNull(state.sheet) - assertEquals("Version", state.options[state.column].label) - assertFalse(shell.navFocused) - } - - @Test fun trackChoiceStaysInSheetAndOffRemainsAnExplicitChoice() { - render() - press(Key.DirectionRight); press(Key.DirectionRight); press(Key.DirectionCenter) - assertEquals(TitleSheet.Tracks, state.sheet) - press(Key.DirectionDown); press(Key.DirectionCenter) - assertEquals(1, state.audioIndex) - assertEquals(TitleSheet.Tracks, state.sheet) - press(Key.DirectionDown); press(Key.DirectionDown); press(Key.DirectionCenter) - assertEquals(2, state.subtitleIndex) - press(Key.DirectionUp); press(Key.DirectionCenter) - assertEquals(-1, state.subtitleIndex) - press(Key.Back) - assertNull(state.sheet) - assertEquals("tracks", state.options[state.column].id) - } - - @Test fun castLoadingAndUnavailableAreNeverFocusable() { - render(transform = { it.copy(cast = emptyList(), castStatus = TitleReadStatus.Loading) }) - press(Key.DirectionDown) - assertEquals("related", state.row) - assertFalse(state.rows.contains("cast")) - } - - @Test fun wholeSeriesRequiresConfirmationButEpisodesDoNot() { - render("Andor") - rule.runOnIdle { state.focus("header", state.options.indexOfFirst { it.id == "watched" }) } - press(Key.DirectionCenter) - assertEquals(TitleSheet.ConfirmWatched, state.sheet) - assertFalse(state.watched) - press(Key.DirectionRight); press(Key.DirectionCenter) - assertFalse(state.watched) - assertTrue(effects.none { it is TitleAction.Watched }) - press(Key.DirectionCenter); press(Key.DirectionCenter) - assertTrue(state.watched) - assertTrue(effects.last() is TitleAction.Watched) - } - - @Test fun titlesNobodyHoldsHaveNoTrailerUntilTheCatalogueFieldExists() { - render("The Amazing Spider-Man") - assertTrue(state.options.none { it.id == "trailer" }) - assertEquals("Request", state.options.first().label) - rule.runOnIdle { state.update(state.data.copy(connection = TitleConnection.SignedOut)) } - assertEquals(listOf("retry"), state.options.map { it.id }) - } - - @Test fun hiddenReceiptUndoRestoresTitleAndOptionInPlace() { - render("The Amazing Spider-Man") - press(Key.DirectionRight); press(Key.DirectionRight); press(Key.DirectionCenter) - assertTrue(state.data.hidden) - assertEquals(TitleSheet.HiddenReceipt, state.sheet) - press(Key.DirectionCenter) - assertFalse(state.data.hidden) - assertNull(state.sheet) - assertEquals("hide", state.options[state.column].id) - } - - @Test fun heldOkCannotChooseTheVersionInTheSheetItOpened() { - render() - press(Key.DirectionRight) - rule.runOnIdle { - rule.activity.dispatchKeyEvent(android.view.KeyEvent(0, 0, android.view.KeyEvent.ACTION_DOWN, android.view.KeyEvent.KEYCODE_DPAD_CENTER, 0)) - repeat(5) { index -> rule.activity.dispatchKeyEvent(android.view.KeyEvent(0, 0, android.view.KeyEvent.ACTION_DOWN, android.view.KeyEvent.KEYCODE_DPAD_CENTER, index + 1)) } - rule.activity.dispatchKeyEvent(android.view.KeyEvent(0, 0, android.view.KeyEvent.ACTION_UP, android.view.KeyEvent.KEYCODE_DPAD_CENTER, 0)) - } - assertEquals(TitleSheet.Version, state.sheet) - assertTrue(effects.none { it is TitleAction.Version }) - } - - @Test fun episodeWatchedToggleKeepsItsIdentityAndDoesNotAskAboutTheSeries() { - val episode = requireNotNull(fixture.title("Andor", "justin").playTarget) - render(episode.id) - rule.runOnIdle { state.focus("header", state.options.indexOfFirst { it.id == "watched" }) } - press(Key.DirectionCenter) - assertNull(state.sheet) - val change = effects.single() as TitleAction.Watched - assertEquals(episode.id, change.item.id) - assertEquals(!episode.watched, change.watched) - } - - @Test fun aPendingSeasonSkipsItsEpisodeSkeletons() { - render("Andor") - rule.runOnIdle { state.showSeasonLoading() } - press(Key.DirectionDown); press(Key.DirectionDown) - assertEquals("cast", state.row) - rule.runOnIdle { state.restoreSeason() } - press(Key.DirectionUp) - assertEquals("episodes", state.row) - } - - @Test fun aFailedOlderVersionWriteCannotUndoTheNewerChoice() { - render() - press(Key.DirectionRight); press(Key.DirectionCenter); press(Key.DirectionDown); press(Key.DirectionCenter) - val first = effects.last() as TitleAction.Version - press(Key.DirectionCenter); press(Key.DirectionUp); press(Key.DirectionCenter) - val second = effects.last() as TitleAction.Version - rule.runOnIdle { state.rejectPlayback(first); state.confirmPlayback(second) } - assertEquals("v1", state.versionId) - press(Key.DirectionCenter); press(Key.DirectionDown); press(Key.DirectionCenter) - val failed = effects.last() as TitleAction.Version - rule.runOnIdle { state.rejectPlayback(failed) } - assertEquals("v1", state.versionId) - } - - @Test fun aNewRowUsesTheNearestHorizontalCardBeforeItsOwnRememberedCard() { - render() - repeat(4) { press(Key.DirectionRight) } - val x = rule.onNodeWithTag("title-option-trailer").fetchSemanticsNode().boundsInRoot.center.x - val cast = state.data.cast.take(WolfskinTokens.Card.personSlots) - val nearest = cast.indices.minBy { index -> - kotlin.math.abs(rule.onNodeWithTag("title-cast-${cast[index].id}").fetchSemanticsNode().boundsInRoot.center.x - x) - } - press(Key.DirectionDown) - assertEquals(nearest, state.column) - press(Key.DirectionRight) - val remembered = state.column - press(Key.DirectionUp); press(Key.DirectionDown) - assertEquals(remembered, state.column) - } - - @Test fun wheelThenRemoteLandsOnTheFirstVisibleFocusableRow() { - render() - rule.onNodeWithTag("title-page").performMouseInput { scroll(800f) } - val expected = rule.runOnIdle { - shell.view.listState.layoutInfo.visibleItemsInfo.first { - it.key in state.rows && it.offset + it.size > WolfskinTokens.Layout.pinnedLine.value * 2 - }.key as String - } - assertNotEquals("header", expected) - press(Key.DirectionDown) - assertEquals(expected, state.row) - } - @Test fun seriesOptionsKeepTheCompleteHouseholdActionLabel() { - render("Andor") - val layouts = mutableListOf() - rule.onNodeWithText("Add for someone", useUnmergedTree = true) - .performSemanticsAction(SemanticsActions.GetTextLayoutResult) { action -> action(layouts) } - val layout = layouts.single() - assertFalse("The final pill must not shrink to its icon or a clipped label", layout.didOverflowWidth) - assertEquals(1, layout.lineCount) - } - - @Test fun anInitialLoadNeverExposesStaleCastBelowItsSkeleton() { - render(transform = { it.copy(status = TitleReadStatus.Loading) }) - rule.onNodeWithText("Cast").assertDoesNotExist() - press(Key.DirectionDown) - assertTrue(shell.navFocused) - assertEquals("header", state.row) - rule.runOnIdle { rule.activity.onBackPressedDispatcher.onBackPressed() } - assertEquals(listOf(TitleAction.Pop), effects) - } - - - @Test fun unratedFactsDoNotReserveAnEmptyRatingsSlot() { - render("The Amazing Spider-Man", transform = { - it.copy(item = it.item.copy(ratings = emptyList(), genres = listOf("Drama"), runtimeSeconds = 0), - cast = emptyList(), related = emptyList()) - }) - val year = rule.onNodeWithText("2012", useUnmergedTree = true).fetchSemanticsNode().boundsInRoot - val genre = rule.onNodeWithText("Drama", useUnmergedTree = true).fetchSemanticsNode().boundsInRoot - assertEquals(WolfskinTokens.Title.factsGap.value * 2, genre.left - year.right, 1f) - } - - @GraphicsMode(GraphicsMode.Mode.NATIVE) - @Test fun mediaInfoRowsPreserveTheirDeclaredLineBoxes() { - render() - rule.runOnIdle { state.focus("header", state.options.indexOfFirst { it.id == "more" }) } - press(Key.DirectionCenter) - val container = rule.onNodeWithText("Container", useUnmergedTree = true).fetchSemanticsNode().boundsInRoot - val size = rule.onNodeWithText("Size", useUnmergedTree = true).fetchSemanticsNode().boundsInRoot - val expectedPitch = (WolfskinTokens.Title.infoKey.lineHeight.value + WolfskinTokens.Title.infoRowGap.value) * 2 - assertEquals("Stacked facts retain the CSS line-box rhythm", expectedPitch, size.top - container.top, 1f) - val lastSubtitle = rule.onNodeWithText("Dutch", useUnmergedTree = true).fetchSemanticsNode().boundsInRoot - assertEquals("Fourteen stacked lines do not accumulate native pixel rounding", 526.2f, lastSubtitle.top - container.top, 1f) - } - - @GraphicsMode(GraphicsMode.Mode.NATIVE) - @Test fun filmHeaderKeepsItsFixedCssStack() { - render() - assertEquals(358f, rule.onNodeWithTag("title-facts").fetchSemanticsNode().boundsInRoot.top, 1f) - assertEquals(410f, rule.onNodeWithTag("title-overview").fetchSemanticsNode().boundsInRoot.top, 1f) - assertEquals(553f, rule.onNodeWithTag("title-actions").fetchSemanticsNode().boundsInRoot.top, 1f) - } - - @GraphicsMode(GraphicsMode.Mode.NATIVE) - @Test fun episodeProgressReclaimsItsNegativeMarginBeforeTheActionRow() { - render("Andor") - assertEquals(603f, rule.onNodeWithTag("title-actions").fetchSemanticsNode().boundsInRoot.top, 1f) - } - - @Test fun everyLongTrackChoiceAndDoneRemainInsideTheVisibleSheet() { - render(transform = { data -> - val source = data.versions.first().copy( - audio = List(3) { org.justinvisser.wolfskin.design.TitleTrack(it + 3, "Audio ${it + 1}") }, - subtitles = List(15) { org.justinvisser.wolfskin.design.TitleTrack(it + 20, "Subtitle ${it + 1}") }, - ) - data.copy(versions = listOf(source)) - }) - rule.runOnIdle { state.focus("header", state.options.indexOfFirst { it.id == "tracks" }) } - press(Key.DirectionCenter) - val bottom = rule.onRoot().fetchSemanticsNode().boundsInRoot.bottom - val labels = (1..3).map { "Audio $it" } + "Off" + (1..15).map { "Subtitle $it" } + "Done" - labels.forEachIndexed { index, label -> - if (index > 0) press(Key.DirectionDown) - rule.waitForIdle() - val bounds = rule.onNodeWithText(label, useUnmergedTree = true).fetchSemanticsNode().boundsInRoot - assertTrue("$label must have visible height: $bounds", bounds.height > 20) - assertTrue("$label stays above the viewport bottom: $bounds / $bottom", bounds.bottom <= bottom) - assertTrue("$label stays below the viewport top: $bounds", bounds.top >= 0) - } - press(Key.DirectionCenter) - assertNull(state.sheet) - assertFalse(shell.navFocused) - } -} diff --git a/app/src/test/java/org/justinvisser/wolfskin/tv/TitleLaunchKeysTest.kt b/app/src/test/java/org/justinvisser/wolfskin/tv/TitleLaunchKeysTest.kt deleted file mode 100644 index 07636e5a..00000000 --- a/app/src/test/java/org/justinvisser/wolfskin/tv/TitleLaunchKeysTest.kt +++ /dev/null @@ -1,132 +0,0 @@ -package org.justinvisser.wolfskin.tv - -import android.app.Application -import androidx.activity.ComponentActivity -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.input.key.Key -import androidx.compose.ui.test.junit4.createAndroidComposeRule -import androidx.compose.ui.test.onRoot -import androidx.compose.ui.test.performKeyInput -import androidx.compose.ui.test.pressKey -import org.json.JSONArray -import org.json.JSONObject -import org.junit.Assert.* -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.justinvisser.wolfskin.design.* -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config - -/** Full launch paths render the real picker, Home hero/shelves, title and person surfaces. */ -@RunWith(RobolectricTestRunner::class) -@Config(sdk = [34], application = Application::class, qualifiers = "w960dp-h540dp-xhdpi") -class TitleLaunchKeysTest { - @get:Rule val rule = createAndroidComposeRule() - private lateinit var fixture: TitleFixture - private lateinit var home: HomeFixture - private lateinit var shell: ShellState - private var title by mutableStateOf(null) - private var person by mutableStateOf(null) - private val actions = mutableListOf() - private val shellActions = mutableListOf() - private lateinit var paths: List - - @Before fun launch() { - fixture = TitleFixture(rule.activity.assets.open("wolfskin-titles.json").bufferedReader().use { JSONObject(it.readText()) }) - home = HomeFixture(rule.activity) - val source = javaClass.getResourceAsStream("/title-press-paths.json")!!.bufferedReader().use { JSONArray(it.readText()) } - paths = List(source.length()) { source.getJSONObject(it) } - shell = ShellState(fixture.people, "justin") { action -> - shellActions.add(action) - if (action is ShellAction.Person) { title = null; person = null } - } - rule.setContent { WolfskinTheme { - val performer = person - val page = title - val snapshot = remember(shell.person.key) { home.snapshot(shell.person.key) } - when { - performer != null -> PersonSurface(performer, shell) - page != null -> TitleSurface(page, shell) - else -> ShellSurface(shell) { modifier -> - HomeScreen(shell, snapshot, modifier) { action -> - if (action is HomeAction.Details) openTitle(action.title.id) - } - } - } - } } - } - - private fun openTitle(id: String) { - val data = fixture.title(id, shell.person.key) - title = TitleState(data, shell.person, ::act) - person = null - shell.enterDestination(titleRoute(id)) - } - - private fun act(action: TitleAction) { - actions.add(action) - when (action) { - is TitleAction.Person -> { - val (actor, credits) = fixture.person(action.person.id, shell.person.key) - person = PersonState(actor, credits, ::act) - shell.enterDestination(personRoute(actor.id)) - } - is TitleAction.OpenTitle -> openTitle(action.item.id) - else -> Unit - } - } - - private fun replay(end: String, expectedPresses: Int) { - val path = paths.single { it.getString("end") == end } - val keys = path.getJSONArray("keys") - assertEquals(expectedPresses, path.getInt("presses")) - assertEquals(expectedPresses, keys.length()) - for (index in 0 until keys.length()) { - val key = when (keys.getString(index)) { - "UP" -> Key.DirectionUp; "DOWN" -> Key.DirectionDown - "LEFT" -> Key.DirectionLeft; "RIGHT" -> Key.DirectionRight - "OK" -> Key.DirectionCenter - else -> error("Unknown launch replay key") - } - rule.onRoot().performKeyInput { pressKey(key) } - } - } - - @Test fun titleToNavTakesFourPressesFromTheRealHomeHero() { - replay("nav", 4) - assertNotNull(title) - assertTrue(shell.navFocused) - assertEquals(shell.currentTab, shell.navIndex) - } - - @Test fun switchingPersonFromATitleTakesEightLaunchPresses() { - replay("person-mindel", 8) - assertEquals("mindel", shell.person.key) - assertFalse(shell.pickerVisible) - assertEquals("home", shell.route) - assertTrue(shellActions.last() is ShellAction.Person) - } - - @Test fun lockeVersionTwoAndPlayTakesFifteenLaunchPresses() { - replay("play-version-2", 15) - val page = requireNotNull(title) - assertEquals("Locke", page.data.item.name) - assertEquals("v2", page.versionId) - assertNull(page.sheet) - assertEquals("play", page.options[page.column].id) - assertEquals("Locke", (actions.last() as TitleAction.Play).item.name) - } - - @Test fun lockeToTomHardyTakesElevenLaunchPresses() { - replay("person-Tom Hardy", 11) - assertEquals("Tom Hardy", requireNotNull(person).person.name) - assertEquals(0, person!!.index) - assertFalse(shell.navFocused) - assertTrue(actions.last() is TitleAction.Person) - } -} diff --git a/app/src/test/java/org/justinvisser/wolfskin/tv/TitleLocaleTest.kt b/app/src/test/java/org/justinvisser/wolfskin/tv/TitleLocaleTest.kt deleted file mode 100644 index e9462bff..00000000 --- a/app/src/test/java/org/justinvisser/wolfskin/tv/TitleLocaleTest.kt +++ /dev/null @@ -1,57 +0,0 @@ -package org.justinvisser.wolfskin.tv - -import android.app.Application -import androidx.activity.ComponentActivity -import androidx.compose.ui.semantics.SemanticsActions -import androidx.compose.ui.test.junit4.createAndroidComposeRule -import androidx.compose.ui.test.onAllNodesWithText -import androidx.compose.ui.test.onLast -import androidx.compose.ui.test.performSemanticsAction -import androidx.compose.ui.text.TextLayoutResult -import org.junit.Assert.assertEquals -import org.junit.Assert.assertFalse -import org.junit.Rule -import org.junit.Test -import org.junit.runner.RunWith -import org.justinvisser.wolfskin.design.ShellPerson -import org.justinvisser.wolfskin.design.ShellState -import org.justinvisser.wolfskin.design.TitleConnection -import org.justinvisser.wolfskin.design.TitleItem -import org.justinvisser.wolfskin.design.TitlePageData -import org.justinvisser.wolfskin.design.LibraryRating -import org.justinvisser.wolfskin.design.TitleState -import org.justinvisser.wolfskin.design.TitleSurface -import org.justinvisser.wolfskin.design.WolfskinTheme -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config -import org.robolectric.annotation.GraphicsMode -import java.util.Locale - -/** Native text layout proves locale formatting still fits the focused poster's one-line plate. */ -@RunWith(RobolectricTestRunner::class) -@Config(sdk = [34], application = Application::class, qualifiers = "w960dp-h540dp-xhdpi") -@GraphicsMode(GraphicsMode.Mode.NATIVE) -class TitleLocaleTest { - @get:Rule val rule = createAndroidComposeRule() - - private fun render(locale: Locale, expected: String) { - val previous = Locale.getDefault() - try { - Locale.setDefault(locale) - val person = ShellPerson("justin", "Justin", "J", false) - val item = TitleItem("movie:1", "Title", "movie", ratings = listOf(LibraryRating("tmdb", 7.8))) - val shell = ShellState(listOf(person), person.key).apply { pickerVisible = false; enterDestination("title/movie:1") } - val state = TitleState(TitlePageData(item, related = listOf(item.copy(id = "movie:2")), connection = TitleConnection.SignedIn), person) {} - state.focus("related", 0) - rule.setContent { WolfskinTheme { TitleSurface(state, shell) } } - rule.mainClock.advanceTimeBy(1000) - val layouts = mutableListOf() - rule.onAllNodesWithText(expected, useUnmergedTree = true).onLast().performSemanticsAction(SemanticsActions.GetTextLayoutResult) { get -> get(layouts) } - assertEquals(1, layouts.single().lineCount) - assertFalse(layouts.single().didOverflowWidth) - } finally { Locale.setDefault(previous) } - } - - @Test fun dutchScoreUsesCommaOnTheNativePlate() = render(Locale.forLanguageTag("nl-NL"), "7,8") - @Test fun englishScoreUsesPointOnTheNativePlate() = render(Locale.US, "7.8") -} diff --git a/app/src/test/java/org/justinvisser/wolfskin/tv/TitleReadFacadeTest.kt b/app/src/test/java/org/justinvisser/wolfskin/tv/TitleReadFacadeTest.kt deleted file mode 100644 index 1a672f67..00000000 --- a/app/src/test/java/org/justinvisser/wolfskin/tv/TitleReadFacadeTest.kt +++ /dev/null @@ -1,203 +0,0 @@ -package org.justinvisser.wolfskin.tv - -import android.app.Application -import android.content.Context -import com.github.damontecres.wholphin.WholphinApplication -import com.github.damontecres.wholphin.data.ItemPlaybackRepository -import com.github.damontecres.wholphin.data.ServerRepository -import com.github.damontecres.wholphin.data.model.JellyfinUser -import com.github.damontecres.wholphin.data.model.JellyfinServer -import com.github.damontecres.wholphin.preferences.AppPreferences -import com.github.damontecres.wholphin.preferences.UserPreferences -import com.github.damontecres.wholphin.services.FavoriteWatchManager -import com.github.damontecres.wholphin.services.ImageUrlService -import com.github.damontecres.wholphin.ui.successQueryResult -import com.github.damontecres.wholphin.ui.successResponse -import io.mockk.coEvery -import io.mockk.coVerify -import io.mockk.every -import io.mockk.mockk -import io.mockk.mockkObject -import io.mockk.unmockkObject -import kotlinx.coroutines.test.runTest -import org.jellyfin.sdk.api.client.ApiClient -import org.jellyfin.sdk.api.client.extensions.itemsApi -import org.jellyfin.sdk.api.client.extensions.tvShowsApi -import org.jellyfin.sdk.api.client.extensions.userLibraryApi -import org.jellyfin.sdk.api.operations.ItemsApi -import org.jellyfin.sdk.api.operations.TvShowsApi -import org.jellyfin.sdk.api.operations.UserLibraryApi -import org.jellyfin.sdk.model.api.BaseItemDto -import org.jellyfin.sdk.model.api.BaseItemKind -import com.github.damontecres.wholphin.test.TestTracks -import org.jellyfin.sdk.model.api.MediaStreamType -import org.jellyfin.sdk.model.api.request.GetEpisodesRequest -import org.jellyfin.sdk.model.api.request.GetItemsRequest -import org.junit.Assert.* -import org.junit.After -import org.junit.Before -import org.junit.Rule -import org.junit.Test -import org.junit.rules.TemporaryFolder -import org.junit.runner.RunWith -import org.justinvisser.wolfskin.design.ShellPerson -import org.justinvisser.wolfskin.design.TitleConnection -import org.justinvisser.wolfskin.design.TitleState -import org.justinvisser.wolfskin.tv.read.TitleReadFacade -import org.robolectric.RobolectricTestRunner -import org.robolectric.annotation.Config -import org.robolectric.RuntimeEnvironment -import java.util.UUID - -/** SDK replies stay in-process; disk reload and identity isolation exercise the real facade. */ -@RunWith(RobolectricTestRunner::class) -@Config(sdk = [34], application = Application::class) -class TitleReadFacadeTest { - @get:Rule val directory = TemporaryFolder() - private val library = mockk() - private val items = mockk() - private val shows = mockk() - private val api = mockk() - private val playback = mockk() - private val repository = mockk() - private val preferences = UserPreferences(AppPreferences.getDefaultInstance(), null) - private lateinit var facade: TitleReadFacade - private val firstId = UUID.fromString("00000000-0000-0000-0000-000000000001") - private val secondId = UUID.fromString("00000000-0000-0000-0000-000000000002") - private val seriesId = UUID.fromString("00000000-0000-0000-0000-000000000003") - private val seasonId = UUID.fromString("00000000-0000-0000-0000-000000000004") - private val sourceId = UUID.fromString("00000000-0000-0000-0000-000000000005").toString().replace("-", "") - - @Before fun setup() { - // BaseItem formats runtime using application resources; no Hilt/network application is started. - val app = mockk { - every { resources } returns RuntimeEnvironment.getApplication().resources - } - mockkObject(WholphinApplication.Companion) - every { WholphinApplication.instance } returns app - every { api.userLibraryApi } returns library - every { api.itemsApi } returns items - every { api.tvShowsApi } returns shows - every { repository.currentServer } returns null - every { repository.currentUser } returns null - coEvery { playback.getSelectedTracks(any(), any(), any()) } returns null - val context = mockk { every { filesDir } returns directory.root } - facade = TitleReadFacade(api, mockk(relaxed = true), playback, repository, mockk(), context) - } - - @After fun teardown() { - unmockkObject(WholphinApplication.Companion) - } - - private fun file(id: UUID, kind: BaseItemKind = BaseItemKind.MOVIE): BaseItemDto { - val source = TestTracks.Builder().addVideo().addAudio().addSubtitle().buildMediaSourceInfo() - val streams = source.mediaStreams.orEmpty().map { stream -> - when (stream.type) { - MediaStreamType.VIDEO -> stream.copy(index = 0, displayTitle = "1080p") - MediaStreamType.AUDIO -> stream.copy(index = 3, displayTitle = "English", isDefault = true) - MediaStreamType.SUBTITLE -> stream.copy(index = 8, displayTitle = "Dutch") - else -> error("Unexpected track in the SDK fixture builder") - } - } - return BaseItemDto(id = id, name = "A real file", type = kind, runTimeTicks = 6_000_000_000, - mediaSources = listOf(source.copy(id = sourceId, name = "Original", container = "mkv", mediaStreams = streams))) - } - - @Test fun diskCopyPreservesFileAndNonContiguousStreamIndexesWithoutRatingsBeforeSignIn() = runTest { - coEvery { library.getItem(firstId) } returns successResponse(file(firstId)) - facade.read(firstId, null, preferences) - coEvery { library.getItem(any()) } throws java.io.IOException("offline") - val saved = facade.readSaved(firstId, preferences)!! - val screen = TitleState(saved, ShellPerson("justin", "Justin", "J", false)) {} - assertEquals("MKV", saved.versions.single().container) - assertEquals(3, screen.audio?.index) - assertEquals(listOf(8), saved.versions.single().subtitles.map { it.index }) - assertEquals(TitleConnection.SignedOut, saved.connection) - assertTrue(saved.item.ratings.isEmpty()) - assertEquals(firstId.toString(), saved.watchTarget.id) - } - - @Test fun diskCopiesNeverCrossViewerIdentity() = runTest { - val userA = mockk { every { id } returns firstId } - val userB = mockk { every { id } returns secondId } - every { repository.currentUser } returns userA - coEvery { library.getItem(firstId) } returns successResponse(file(firstId)) - facade.read(firstId, null, preferences) - every { repository.currentUser } returns userB - assertNull(facade.readSaved(firstId, preferences)) - every { repository.currentUser } returns userA - assertEquals("A real file", facade.readSaved(firstId, preferences)?.item?.name) - } - - @Test fun personBiographyAndContinuousCreditsRemainReadableFromDiskWithoutAService() = runTest { - val actor = BaseItemDto(id = firstId, type = BaseItemKind.PERSON, name = "Actor", overview = "Actual biography") - coEvery { library.getItem(firstId) } returns successResponse(actor) - coEvery { items.getItems(any()) } returns successQueryResult(listOf(file(secondId))) - facade.readPerson(firstId, 0) - coEvery { library.getItem(any()) } throws java.io.IOException("offline") - coEvery { items.getItems(any()) } throws java.io.IOException("offline") - val saved = facade.readPersonSaved(firstId)!! - assertEquals("Actual biography", saved.person.biography) - assertEquals(secondId.toString(), saved.credits.single().id) - assertEquals("A real file", saved.credits.single().name) - } - - @Test fun personSavedCopiesNeverCrossServerOrViewerIdentity() = runTest { - val userA = mockk { every { id } returns firstId } - val userB = mockk { every { id } returns secondId } - val serverA = mockk { every { id } returns seriesId } - val serverB = mockk { every { id } returns seasonId } - every { repository.currentUser } returns userA - every { repository.currentServer } returns serverA - coEvery { library.getItem(firstId) } returns successResponse( - BaseItemDto(id = firstId, type = BaseItemKind.PERSON, name = "Saved actor", overview = "Private biography")) - coEvery { items.getItems(any()) } returns successQueryResult(listOf(file(secondId))) - facade.readPerson(firstId, 0) - every { repository.currentUser } returns userB - assertNull(facade.readPersonSaved(firstId)) - every { repository.currentUser } returns userA - every { repository.currentServer } returns serverB - assertNull(facade.readPersonSaved(firstId)) - every { repository.currentServer } returns serverA - val saved = requireNotNull(facade.readPersonSaved(firstId)) - assertEquals("Private biography", saved.person.biography) - assertEquals(secondId.toString(), saved.credits.single().id) - } - - @Test fun explicitEpisodeStaysThePlayAndWatchTargetAcrossDifferentSeasonSelection() = runTest { - val episode = file(firstId, BaseItemKind.EPISODE).copy(seriesId = seriesId, parentIndexNumber = 4, indexNumber = 9) - val other = file(secondId, BaseItemKind.EPISODE).copy(seriesId = seriesId, parentIndexNumber = 2, indexNumber = 1) - val series = BaseItemDto(id = seriesId, name = "Series", type = BaseItemKind.SERIES) - val secondSeason = BaseItemDto(id = seasonId, type = BaseItemKind.SEASON, indexNumber = 2) - coEvery { library.getItem(firstId) } returns successResponse(episode) - coEvery { library.getItem(seriesId) } returns successResponse(series) - coEvery { items.getItems(any()) } returns successQueryResult(listOf(secondSeason)) - coEvery { shows.getEpisodes(any()) } returns successQueryResult(listOf(other)) - val data = facade.read(firstId, 2, preferences) - assertEquals(seriesId.toString(), data.item.id) - assertEquals(firstId.toString(), data.playTarget?.id) - assertEquals(firstId.toString(), data.watchTarget.id) - assertEquals(listOf(secondId.toString()), data.episodes.map { it.id }) - assertEquals(listOf(2), data.seasonNumbers) - assertEquals(2, TitleState(data, ShellPerson("justin", "Justin", "J", false)) {}.season) - } - - @Test fun compactJellyfinSourceIdUsesTheSameVersionPersistenceKey() = runTest { - coEvery { library.getItem(firstId) } returns successResponse(file(firstId)) - coEvery { playback.savePlayVersion(any(), any()) } returns null - val data = facade.read(firstId, null, preferences) - facade.apply(org.justinvisser.wolfskin.design.TitleAction.Version(data.watchTarget, data.versions.single())) - coVerify(exactly = 1) { playback.savePlayVersion(firstId, UUID.fromString("00000000-0000-0000-0000-000000000005")) } - } - @Test fun subtitleOffDisablesPlaybackRatherThanRestoringThePreferredLanguage() = runTest { - coEvery { library.getItem(firstId) } returns successResponse(file(firstId)) - coEvery { playback.saveTrackSelection(any(), any(), any(), MediaStreamType.SUBTITLE) } returns - com.github.damontecres.wholphin.data.model.ItemPlayback(userId = 1, itemId = firstId) - val data = facade.read(firstId, null, preferences) - facade.apply(org.justinvisser.wolfskin.design.TitleAction.Track(data.watchTarget, data.versions.single(), audio = null, subtitle = -1)) - coVerify(exactly = 1) { playback.saveTrackSelection(any(), any(), com.github.damontecres.wholphin.data.model.TrackIndex.DISABLED, MediaStreamType.SUBTITLE) } - coVerify(exactly = 0) { playback.saveTrackSelection(any(), any(), com.github.damontecres.wholphin.data.model.TrackIndex.UNSPECIFIED, MediaStreamType.SUBTITLE) } - facade.apply(org.justinvisser.wolfskin.design.TitleAction.Track(data.watchTarget, data.versions.single(), audio = null, subtitle = 8)) - coVerify(exactly = 1) { playback.saveTrackSelection(any(), any(), 8, MediaStreamType.SUBTITLE) } - } -} diff --git a/app/src/test/java/org/justinvisser/wolfskin/tv/TitleTrailerTest.kt b/app/src/test/java/org/justinvisser/wolfskin/tv/TitleTrailerTest.kt deleted file mode 100644 index afa137ee..00000000 --- a/app/src/test/java/org/justinvisser/wolfskin/tv/TitleTrailerTest.kt +++ /dev/null @@ -1,51 +0,0 @@ -package org.justinvisser.wolfskin.tv - -import android.app.Application -import android.content.Context -import android.content.Intent -import android.content.pm.ActivityInfo -import android.content.pm.ResolveInfo -import android.net.Uri -import androidx.test.core.app.ApplicationProvider -import org.junit.Assert.* -import org.junit.Test -import org.junit.runner.RunWith -import org.robolectric.RobolectricTestRunner -import org.robolectric.Shadows.shadowOf -import org.robolectric.annotation.Config - -/** Browser handlers must never become a fallback for a missing YouTube app. */ -@RunWith(RobolectricTestRunner::class) -@Config(sdk = [34], application = Application::class) -class TitleTrailerTest { - private val context = ApplicationProvider.getApplicationContext() - private val url = "https://www.youtube.com/watch?v=abcdefghijk" - - @Test fun missingYoutubeHandlerStaysOnTheTitleEvenWhenABrowserExists() { - register(Intent(Intent.ACTION_VIEW, Uri.parse(url)), "test.browser") - assertFalse(TitleTrailer(context).open(url)) - assertNull(shadowOf(context as Application).nextStartedActivity) - } - - @Test fun installedYoutubeHandlerReceivesAnExplicitPackageAndNoBrowserUrl() { - register(Intent(Intent.ACTION_VIEW, Uri.parse("vnd.youtube:abcdefghijk")), "test.youtube") - assertTrue(TitleTrailer(context).open(url)) - val launched = shadowOf(context as Application).nextStartedActivity - assertEquals("test.youtube", launched.`package`) - assertEquals("vnd.youtube", launched.data?.scheme) - assertEquals("abcdefghijk", launched.data?.schemeSpecificPart) - } - - @Test fun nonYoutubeTrailerNeverOpensAGeneralViewHandler() { - register(Intent(Intent.ACTION_VIEW, Uri.parse("https://trailers.example/video")), "test.browser") - assertFalse(TitleTrailer(context).open("https://trailers.example/video")) - assertNull(shadowOf(context as Application).nextStartedActivity) - } - - private fun register(intent: Intent, name: String) { - val info = ResolveInfo().apply { - activityInfo = ActivityInfo().apply { packageName = name; this.name = "$name.Player"; exported = true } - } - shadowOf(context.packageManager).addResolveInfoForIntent(intent, info) - } -} diff --git a/app/src/test/resources/title-press-paths.json b/app/src/test/resources/title-press-paths.json deleted file mode 100644 index 14b28147..00000000 --- a/app/src/test/resources/title-press-paths.json +++ /dev/null @@ -1,92 +0,0 @@ -[ - { - "goal": "Round 3 · title page → nav", - "keys": [ - "OK", - "RIGHT", - "OK", - "UP" - ], - "presses": 4, - "note": "1 from the title page", - "start": "app launch: Who's watching with Justin focused (index.html:357)", - "replayed": "PASS", - "source": "index.html:2152-2174 PRESSES, replayed 2026-11-05", - "entryPresses": 3, - "title": "The Girl Who Leapt Through Time", - "end": "nav" - }, - { - "goal": "Round 3 · play Locke with version 2 (sample files)", - "keys": [ - "OK", - "DOWN", - "DOWN", - "DOWN", - "RIGHT", - "RIGHT", - "RIGHT", - "RIGHT", - "OK", - "RIGHT", - "OK", - "DOWN", - "OK", - "LEFT", - "OK" - ], - "presses": 15, - "note": "6 on the title page", - "start": "app launch: Who's watching with Justin focused (index.html:357)", - "replayed": "PASS", - "source": "index.html:2152-2174 PRESSES, replayed 2026-11-05", - "entryPresses": 9, - "title": "Locke", - "end": "play-version-2" - }, - { - "goal": "Round 3 · Locke → its first cast member’s page", - "keys": [ - "OK", - "DOWN", - "DOWN", - "DOWN", - "RIGHT", - "RIGHT", - "RIGHT", - "RIGHT", - "OK", - "DOWN", - "OK" - ], - "presses": 11, - "note": "2 on the title page: ↓ to Cast, OK", - "start": "app launch: Who's watching with Justin focused (index.html:357)", - "replayed": "PASS", - "source": "index.html:2152-2174 PRESSES, replayed 2026-11-05", - "entryPresses": 9, - "title": "Locke", - "end": "person-Tom Hardy" - }, - { - "goal": "Round 3 · switch person from a title page", - "keys": [ - "OK", - "RIGHT", - "OK", - "UP", - "LEFT", - "OK", - "RIGHT", - "OK" - ], - "presses": 8, - "note": "5 from the title page", - "start": "app launch: Who's watching with Justin focused (index.html:357)", - "replayed": "PASS", - "source": "index.html:2152-2174 PRESSES, replayed 2026-11-05", - "entryPresses": 3, - "title": "The Girl Who Leapt Through Time", - "end": "person-mindel" - } -] diff --git a/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/HomeDestination.kt b/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/HomeDestination.kt index e2ac7a91..579e92b8 100644 --- a/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/HomeDestination.kt +++ b/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/HomeDestination.kt @@ -84,7 +84,7 @@ class WolfskinHomeViewModel @Inject constructor( HomeAction.Discover -> openRoot(shell, "discover") HomeAction.Retry -> viewModelScope.launch { load(server, user, shell.person.key, retry = true) } is HomeAction.SeeAll -> if (action.row.target in shell.tabs) openRoot(shell, action.row.target!!) else seeAll.open(shell.person.key, action.row.id, action.row.title, action.row.allCards.map { it.libraryTitle() }, navigation) - is HomeAction.Details -> navigation.navigateTo(Destination.Wolfskin(titleRoute(action.title.id))) + is HomeAction.Details -> navigation.navigateTo(Destination.Wolfskin("title:${action.title.type}:${action.title.tmdbId ?: action.title.id}")) is HomeAction.Play -> viewModelScope.launch { if (!snapshot.jellyfinAvailable || shell.person.key != user.name.orEmpty().lowercase()) { showToast(RecoveryMessage.PlaybackUnavailable) diff --git a/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/ShellRouting.kt b/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/ShellRouting.kt index dffa611b..e69d1496 100644 --- a/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/ShellRouting.kt +++ b/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/ShellRouting.kt @@ -1,16 +1,13 @@ package org.justinvisser.wolfskin.tv import com.github.damontecres.wholphin.ui.nav.Destination -import org.jellyfin.sdk.model.api.BaseItemKind /** The rollout switch changes only intercepted screens; unrelated destinations always pass through. */ fun resolveUpstreamDestination(destination: Destination, wolfskinEnabled: Boolean, libraries: Map): Destination? = when (destination) { - is Destination.Home -> if (wolfskinEnabled) null else destination - is Destination.MediaItem -> if (wolfskinEnabled && destination.type in TITLE_KINDS) null else destination + is Destination.Home, is Destination.MediaItem -> if (wolfskinEnabled) null else destination is Destination.Wolfskin -> if (!wolfskinEnabled && destination.route in LIBRARY_ROUTES) libraries[destination.route] else null else -> destination } private val LIBRARY_ROUTES = setOf("movies", "shows", "anime") -private val TITLE_KINDS = setOf(BaseItemKind.MOVIE, BaseItemKind.SERIES, BaseItemKind.EPISODE, BaseItemKind.PERSON) diff --git a/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/TitleDestination.kt b/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/TitleDestination.kt deleted file mode 100644 index 913f51e7..00000000 --- a/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/TitleDestination.kt +++ /dev/null @@ -1,250 +0,0 @@ -package org.justinvisser.wolfskin.tv - -import android.content.Context -import android.net.Uri -import androidx.activity.compose.BackHandler -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier -import androidx.hilt.lifecycle.viewmodel.compose.hiltViewModel -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.github.damontecres.wholphin.BuildConfig -import com.github.damontecres.wholphin.preferences.UserPreferences -import com.github.damontecres.wholphin.services.NavigationManager -import com.github.damontecres.wholphin.ui.nav.Destination -import dagger.hilt.android.lifecycle.HiltViewModel -import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.Job -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock -import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext -import org.justinvisser.wolfskin.design.PersonState -import org.justinvisser.wolfskin.design.PersonSurface -import org.justinvisser.wolfskin.design.RecoveryMessage -import org.justinvisser.wolfskin.design.ShellPerson -import org.justinvisser.wolfskin.design.ShellState -import org.justinvisser.wolfskin.design.TitleAction -import org.justinvisser.wolfskin.design.TitleConnection -import org.justinvisser.wolfskin.design.TitleItem -import org.justinvisser.wolfskin.design.TitlePageData -import org.justinvisser.wolfskin.design.TitleReadStatus -import org.justinvisser.wolfskin.design.TitleState -import org.justinvisser.wolfskin.design.TitleSurface -import org.justinvisser.wolfskin.tv.read.TitleReadFacade -import java.util.UUID -import javax.inject.Inject - -/** Title and performer routes remain within the single existing Wolfskin destination subtype. */ -fun titleRoute(id: String): String = "title/${Uri.encode(id)}" -fun personRoute(id: String): String = "person/${Uri.encode(id)}" - -/** Each navigation entry owns its title focus and selections across nested person/title pages. */ -@HiltViewModel -class WolfskinTitleViewModel @Inject constructor( - @param:ApplicationContext private val context: Context, - private val facade: TitleReadFacade, - private val fixtureProvider: TitleFixtureProvider, - private val navigation: NavigationManager, -) : ViewModel() { - var title by mutableStateOf(null) - private set - var person by mutableStateOf(null) - private set - private var route = "" - private lateinit var viewer: ShellPerson - private lateinit var preferences: UserPreferences - private var fixture: TitleFixture? = null - private var personReadPending = false - private var personReadFinished = false - private var loadJob: Job? = null - private val saveMutex = Mutex() - private val fixtureSelections by lazy { context.getSharedPreferences("wolfskin-title-fixture", Context.MODE_PRIVATE) } - - /** Fixture reads are exclusively debug assets; real ids always use the authenticated Jellyfin facade. */ - fun load(destination: String, selected: ShellPerson, userPreferences: UserPreferences) { - if (route == destination && ::viewer.isInitialized && viewer.key == selected.key) return - route = destination - loadJob?.cancel() - person = null - fixture = null - personReadPending = false - personReadFinished = false - viewer = selected - preferences = userPreferences - val id = Uri.decode(destination.substringAfter('/')) - title = TitleState(TitlePageData(TitleItem(id, "", if (destination.startsWith("person/")) "person" else "movie"), status = TitleReadStatus.Loading), viewer, ::handle) - loadJob = viewModelScope.launch { - if (BuildConfig.DEBUG && id.toUuidOrNull() == null) { - val source = fixtureProvider.read() - fixture = source - if (destination.startsWith("person/")) { - val (actor, credits) = withContext(Dispatchers.IO) { source.person(id, selected.key) } - person = PersonState(actor, credits, ::handle) - } else { - val data = withContext(Dispatchers.IO) { source.title(id, selected.key) } - val key = "${viewer.key}:${data.item.id}" - val watchKey = "${viewer.key}:${data.watchTarget.id}" - title = TitleState(data.copy( - selectedVersion = fixtureSelections.getString("$key:version", null), - selectedAudio = if (fixtureSelections.contains("$key:audio")) fixtureSelections.getInt("$key:audio", -1) else null, - selectedSubtitle = fixtureSelections.getInt("$key:subtitle", -1), - watchTarget = data.watchTarget.copy(watched = fixtureSelections.getBoolean("$watchKey:watched", data.watchTarget.watched)), - hidden = fixtureSelections.getBoolean("$key:hidden", data.hidden), - ), viewer, ::handle) - } - } else if (destination.startsWith("person/")) readPerson(id) else readTitle(id) - } - } - - private suspend fun readTitle(id: String, retry: Boolean = false) { - val uuid = id.toUuidOrNull() ?: return - val current = title ?: return - try { - if (current.data.status != TitleReadStatus.Ready) facade.readSaved(uuid, preferences)?.let { current.update(it) } - val data = facade.read(uuid, current.takeIf { it.data.status == TitleReadStatus.Ready }?.season, preferences) - current.update(data) - } catch (exception: Exception) { - if (exception is CancellationException) throw exception - if (current.data.status == TitleReadStatus.Ready) { - if (current.data.episodesStatus == TitleReadStatus.Loading) current.restoreSeason() - } else current.update(current.data.copy(status = TitleReadStatus.Unavailable)) - if (current.data.status == TitleReadStatus.Ready || retry) current.toast = RecoveryMessage.StillUnreachable - } - } - - private suspend fun readPerson(id: String, retry: Boolean = false) { - if (personReadPending || personReadFinished) return - val uuid = id.toUuidOrNull() ?: return - val owner = viewer.key - personReadPending = true - try { - if (person == null) facade.readPersonSaved(uuid)?.let { saved -> - if (owner == viewer.key) person = newPerson(saved.person, saved.credits).apply { savedAt = saved.savedAt } - } - val start = if (person?.savedAt != null) 0 else person?.credits?.size ?: 0 - val result = facade.readPerson(uuid, start) - if (owner != viewer.key) return - val current = person - val credits = if (start == 0) result.credits else (current?.credits.orEmpty() + result.credits).distinctBy { it.id } - if (current == null) person = newPerson(result.person, credits) else current.update(result.person, credits) - personReadFinished = result.credits.size < 200 - } catch (exception: Exception) { - if (exception is CancellationException) throw exception - if (owner == viewer.key) { - person?.toast = RecoveryMessage.StillUnreachable - if (person == null) { - title?.update(title!!.data.copy(status = TitleReadStatus.Unavailable)) - if (retry) title?.toast = RecoveryMessage.StillUnreachable - } - } - } finally { if (owner == viewer.key) personReadPending = false } - } - - private fun newPerson(actor: org.justinvisser.wolfskin.design.TitlePerson, credits: List) = - PersonState(actor, credits, ::handle) { viewModelScope.launch { readPerson(actor.id) } } - - private fun handle(action: TitleAction) { - when (action) { - TitleAction.Pop -> navigation.goBack() - is TitleAction.Person -> navigation.navigateTo(action.person.id.toUuidOrNull()?.let { Destination.MediaItem(it, org.jellyfin.sdk.model.api.BaseItemKind.PERSON) } ?: Destination.Wolfskin(personRoute(action.person.id))) - is TitleAction.OpenTitle -> navigation.navigateTo(action.item.id.toUuidOrNull()?.let { Destination.MediaItem(it, when (action.item.kind) { - "movie" -> org.jellyfin.sdk.model.api.BaseItemKind.MOVIE - "episode" -> org.jellyfin.sdk.model.api.BaseItemKind.EPISODE - else -> org.jellyfin.sdk.model.api.BaseItemKind.SERIES - }) } ?: Destination.Wolfskin(titleRoute(action.item.id))) - is TitleAction.Play -> play(action.item.id.toUuidOrNull(), if (action.restart) 0 else action.item.resumeSeconds * 1000) - is TitleAction.Trailer -> if (action.url.startsWith("jellyfin:")) play(action.url.removePrefix("jellyfin:").toUuidOrNull(), 0) - else if (!TitleTrailer(context).open(action.url)) title?.toast = "No YouTube app is available to play this trailer." - is TitleAction.Version, is TitleAction.Track, is TitleAction.Watched -> savePlayback(action) - is TitleAction.Season -> { - loadJob?.cancel() - loadJob = viewModelScope.launch { - val current = title ?: return@launch - current.showSeasonLoading() - val source = fixture - if (source == null) readTitle(Uri.decode(route.substringAfter('/'))) - else { - val data = withContext(Dispatchers.IO) { source.title(Uri.decode(route.substringAfter('/')), viewer.key, action.number) } - current.update(data.copy(selectedVersion = current.versionId, selectedAudio = current.audioIndex, - selectedSubtitle = current.subtitleIndex, watchTarget = current.data.watchTarget.copy(watched = current.watched), hidden = current.data.hidden)) - } - } - } - TitleAction.Retry -> viewModelScope.launch { - if (fixture == null) { - if (route.startsWith("person/")) readPerson(Uri.decode(route.substringAfter('/')), retry = true) else readTitle(Uri.decode(route.substringAfter('/')), retry = true) - } - else title?.toast = RecoveryMessage.StillUnreachable - } - is TitleAction.Request, is TitleAction.Requests -> title?.toast = "Requests need this TV to be signed in to Conductarr." - is TitleAction.Hide -> if (fixture != null) fixtureSelections.edit().putBoolean("${viewer.key}:${action.item.id}:hidden", action.hidden).apply() - } - } - - private fun play(id: UUID?, position: Long) { - viewModelScope.launch { - try { - if (id == null) throw IllegalArgumentException("No Jellyfin playback identity") - facade.preparePlayback(id) - navigation.navigateTo(Destination.Playback(id, position)) - } catch (exception: Exception) { - if (exception is CancellationException) throw exception - title?.toast = RecoveryMessage.PlaybackUnavailable - } - } - } - - private fun savePlayback(action: TitleAction) { - val current = title ?: return - if (fixture != null) { - val edits = fixtureSelections.edit() - when (action) { - is TitleAction.Version -> edits.putString("${viewer.key}:${action.item.id}:version", action.version.id) - is TitleAction.Track -> { - action.audio?.let { edits.putInt("${viewer.key}:${action.item.id}:audio", it) } - edits.putInt("${viewer.key}:${action.item.id}:subtitle", action.subtitle) - } - is TitleAction.Watched -> edits.putBoolean("${viewer.key}:${action.item.id}:watched", action.watched) - else -> Unit - } - edits.apply() - current.confirmPlayback(action) - return - } - viewModelScope.launch { - saveMutex.withLock { - try { facade.apply(action); current.confirmPlayback(action) } - catch (exception: Exception) { - if (exception is CancellationException) throw exception - current.rejectPlayback(action) - current.toast = "Couldn’t save that change. Try again." - } - } - } - } -} - -/** The screen's own Back handler closes its sheet before delegating a navigation pop. */ -@Composable -fun TitleDestination(route: String, shell: ShellState, preferences: UserPreferences, modifier: Modifier = Modifier, viewModel: WolfskinTitleViewModel = hiltViewModel()) { - LaunchedEffect(route, shell.person.key) { viewModel.load(route, shell.person, preferences) } - val title = viewModel.title?.takeIf { it.person.key == shell.person.key } - LaunchedEffect(title?.data?.status) { - if (title?.data?.status == TitleReadStatus.Ready) shell.navFocused = false - } - val person = viewModel.person.takeIf { title != null } - BackHandler(enabled = title != null) { - title?.back(shell) - } - if (person != null && route.startsWith("person/")) PersonSurface(person, shell, modifier) - else if (title != null) TitleSurface(title, shell, modifier) -} - -private fun String.toUuidOrNull(): UUID? = try { UUID.fromString(this) } catch (_: IllegalArgumentException) { null } diff --git a/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/TitleFixture.kt b/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/TitleFixture.kt deleted file mode 100644 index 3e9709aa..00000000 --- a/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/TitleFixture.kt +++ /dev/null @@ -1,144 +0,0 @@ -package org.justinvisser.wolfskin.tv - -import android.content.Context -import com.github.damontecres.wholphin.BuildConfig -import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import javax.inject.Inject -import javax.inject.Singleton -import org.json.JSONArray -import org.json.JSONObject -import org.justinvisser.wolfskin.design.ShellPerson -import org.justinvisser.wolfskin.design.TitleConnection -import org.justinvisser.wolfskin.design.TitleItem -import org.justinvisser.wolfskin.design.TitlePageData -import org.justinvisser.wolfskin.design.TitlePerson -import org.justinvisser.wolfskin.design.LibraryRating -import org.justinvisser.wolfskin.design.TitleTrack -import org.justinvisser.wolfskin.design.TitleVersion -import java.util.Locale - -/** The locked prototype is projected only by debug callers and offline JVM captures. */ -class TitleFixture(private val fixture: JSONObject) { - private val profiles = fixture.getJSONArray("profiles").objects() - private val cast = fixture.getJSONObject("cast") - private val availableArt = fixture.getJSONArray("availableArt").let { array -> (0 until array.length()).map { array.getString(it) }.toSet() } - val people: List = profiles.map { ShellPerson(it.getString("key"), it.getString("name"), it.getString("initial"), it.getJSONObject("destinations").has("Anime")) } - private val all = profiles.flatMap { profile -> listOf("movies", "shows", "anime", "discover").flatMap { profile.getJSONArray(it).objects() } }.distinctBy { key(it) } - private val pool = profiles.flatMap { it.getJSONArray("discover").objects() }.distinctBy { key(it) } - - /** Each viewer gets their own ownership, resume target and episode watch identity. */ - fun title(id: String, person: String, season: Int? = null): TitlePageData { - val profile = profiles.first { it.getString("key") == person } - val library = listOf("movies", "shows", "anime").flatMap { profile.getJSONArray(it).objects() } - val episodes = listOf("resume", "nextUp").flatMap { profile.getJSONArray(it).objects() } - val source = (all + episodes).first { it.getString("id") == id || key(it) == id || it.getString("title") == id } - val selectedEpisode = source.takeIf { it.getString("type") == "episode" } - val container = if (selectedEpisode != null) library.first { it.getString("title") == selectedEpisode.getString("seriesTitle") } else source - val own = library.firstOrNull { key(it) == key(container) } - val item = item(own ?: container, person) - val play = selectedEpisode ?: episodes.firstOrNull { it.optString("seriesTitle") == container.getString("title") } - ?: own?.takeIf { it.optDouble("progress") > 0 } - val target = play?.let { item(it, person) } ?: item.takeIf { it.held && it.kind == "movie" } - val selectedSeason = season ?: play?.optInt("seasonNumber")?.takeIf { it > 0 } ?: 1 - val related = (pool + library).filter { key(it) != key(container) && overlap(it, container) > 0 } - .sortedByDescending { overlap(it, container) }.distinctBy { key(it) }.take(16).map { item(it, person) } - val castMembers = cast.optJSONArray(key(container))?.objects().orEmpty().map { member -> - TitlePerson(member.getString("name"), member.getString("name"), member.optString("character"), art(member.optString("img").takeIf { it.isNotEmpty() }?.let { "assets/cast/$it" })) - } - return TitlePageData(item, play?.let { item(it, person) }, selectedEpisode?.let { item(it, person) } ?: item, - versions = target?.let { versions(it) }.orEmpty(), - trailerUrl = if (item.held && key(container) in TRAILERS) "fixture:trailer" else null, - cast = castMembers, related = related, episodes = episodes.filter { it.optString("seriesTitle") == container.getString("title") && it.optInt("seasonNumber") == selectedSeason }.map { item(it, person) }, - connection = TitleConnection.SignedIn, pick = container.optString("source") == "materialized_personal_recommendation", selectedSeason = selectedSeason) - } - - /** Only real household credits are retained; prototype filler is never promoted to filmography. */ - fun person(name: String, viewer: String): Pair> { - val credits = all.mapNotNull { title -> - val actor = cast.optJSONArray(key(title))?.objects()?.firstOrNull { it.getString("name") == name } ?: return@mapNotNull null - item(title, viewer).copy(character = actor.optString("character")) - }.sortedWith(compareByDescending { it.year ?: 0 }.thenBy { it.name.replace(Regex("^(The|A|An) "), "") }) - val actor = cast.keys().asSequence().flatMap { cast.getJSONArray(it).objects() }.first { it.getString("name") == name } - return TitlePerson(name, name, portrait = art(actor.optString("img").takeIf { it.isNotEmpty() }?.let { "assets/cast/$it" })) to credits - } - - private fun item(source: JSONObject, person: String): TitleItem { - val owners = profiles.filter { profile -> listOf("movies", "shows", "anime").any { bucket -> profile.getJSONArray(bucket).objects().any { key(it) == key(source) } } } - val held = source.optString("type") == "episode" || owners.any { it.getString("key") == person } - return TitleItem( - source.getString("id"), source.getString("title"), source.getString("type"), source.optInt("year").takeIf { it > 0 }, - source.optLong("runtimeSeconds"), source.optInt("seasonCount"), source.optString("overview"), - source.optJSONArray("genres")?.let { values -> (0 until values.length()).map { values.getString(it) } }.orEmpty(), - art(source.optString("poster")), art(source.optString("backdrop")), held, source.optBoolean("played"), source.optDouble("resumeSeconds").toLong(), - seriesName = source.optString("seriesTitle").takeIf { it.isNotEmpty() }, season = source.optInt("seasonNumber"), episode = source.optInt("episodeNumber"), - ratings = ratings(source), otherOwners = owners.filter { it.getString("key") != person }.map { it.getString("name") }, - isPosterBackdrop = source.optJSONObject("artwork")?.optString("backdropKind") == "poster_crop", - ) - } - - private fun art(path: String?): String? = path?.takeIf { it in availableArt }?.let { "file:///android_asset/wolfskin-titles/$it" } - - private fun ratings(item: JSONObject): List { - val episode = item.optString("type") == "episode" - if (episode) { - val series = all.firstOrNull { it.optString("title") == item.optString("seriesTitle") } - val base = series?.let { ratings(it) }.orEmpty() - val score = item.optDouble("communityRating", Double.NaN) - return if (score in 0.0..10.0) base.filter { it.source != "tmdb" } + LibraryRating("tmdb", score, episode = true) else base - } - val ratings = item.optJSONObject("ratings") ?: JSONObject().apply { - if (!item.isNull("criticRating")) put("rtCritics", item.getDouble("criticRating")) - if (!item.isNull("communityRating")) put("tmdb", item.getDouble("communityRating")) - } - return buildList { - if (!ratings.isNull("rtCritics")) add(LibraryRating("rtCritics", ratings.getDouble("rtCritics"), ratings.optString("rtCriticsLabel").takeIf { it.isNotEmpty() })) - if (!ratings.isNull("rtAudience")) add(LibraryRating("rtAudience", ratings.getDouble("rtAudience"), ratings.optString("rtAudienceLabel").takeIf { it.isNotEmpty() })) - if (item.optString("type") == "movie" && (!ratings.has("imdbVotes") || ratings.optInt("imdbVotes") > 0) && !ratings.isNull("imdb")) add(LibraryRating("imdb", ratings.getDouble("imdb"))) - if (isEmpty() && (!ratings.has("tmdbVotes") || ratings.optInt("tmdbVotes") > 0) && !ratings.isNull("tmdb")) add(LibraryRating("tmdb", ratings.getDouble("tmdb"))) - }.filter { it.score in 0.0..if (it.source.startsWith("rt")) 100.0 else 10.0 } - } - - private fun versions(item: TitleItem): List { - val subtitles = listOf(TitleTrack(2, "English"), TitleTrack(3, "English SDH"), TitleTrack(4, "Dutch")) - fun version(id: String, name: String, video: String, bitrate: Double, container: String, audio: List) = - TitleVersion(id, name, video, "$bitrate Mbps", String.format(Locale.US, "%.1f GB", bitrate * item.runtimeSeconds / 8000), container, audio, subtitles) - val standardAudio = listOf(TitleTrack(0, "English · AC3 5.1", true), TitleTrack(1, "English · AAC 2.0")) - return if (item.name == "Locke") listOf( - version("v1", "2160p · HDR10 · Remux", "2160p HEVC Main 10 · HDR10", 58.4, "MKV", listOf(TitleTrack(0, "English · TrueHD 7.1", true), TitleTrack(1, "English · AC3 5.1"))), - version("v2", "1080p · SDR", "1080p H.264 High · SDR", 9.8, "MP4", standardAudio), - ) else listOf(version("v1", "1080p · SDR", "1080p H.264 High · SDR", 8.2, "MKV", standardAudio)) - } - - private fun key(item: JSONObject): String = "${item.getString("type")}:${item.optLong("tmdbId")}" - private fun overlap(first: JSONObject, second: JSONObject): Int { - fun genres(item: JSONObject): Set = item.optJSONArray("genres")?.let { array -> (0 until array.length()).flatMap { - when (val genre = array.getString(it)) { - "Sci-Fi & Fantasy" -> listOf("Science Fiction", "Fantasy") - "Action & Adventure" -> listOf("Action", "Adventure") - "Sci-Fi" -> listOf("Science Fiction") - else -> listOf(genre) - } - }.toSet() }.orEmpty() - return genres(first).intersect(genres(second)).size - } - - companion object { - private val TRAILERS = setOf("movie:14069", "movie:210479", "movie:318917", "movie:42994", "movie:123431", "tv:83867", "tv:76479", "tv:1215", "tv:1437", "tv:67070", "movie:1930", "movie:21469", "movie:76203", "tv:60948") - } -} - -/** Every title entry shares one parsed, read-only debug fixture; release callers cannot load it. */ -@Singleton -class TitleFixtureProvider @Inject constructor(@param:ApplicationContext private val context: Context) { - private val fixture by lazy { - TitleFixture(context.assets.open("wolfskin-titles.json").bufferedReader().use { JSONObject(it.readText()) }) - } - suspend fun read(): TitleFixture = withContext(Dispatchers.IO) { - check(BuildConfig.DEBUG) { "Title fixtures are debug-only" } - fixture - } -} - -private fun JSONArray.objects(): List = List(length()) { getJSONObject(it) } diff --git a/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/TitleTrailer.kt b/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/TitleTrailer.kt deleted file mode 100644 index 0dce1f9f..00000000 --- a/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/TitleTrailer.kt +++ /dev/null @@ -1,33 +0,0 @@ -package org.justinvisser.wolfskin.tv - -import android.content.ActivityNotFoundException -import android.content.Context -import android.content.Intent -import android.content.pm.PackageManager -import android.net.Uri - -/** Only an installed app that handles the YouTube scheme may receive a remote trailer. */ -class TitleTrailer(private val context: Context) { - /** A missing handler leaves the title in place rather than falling back to a browser. */ - fun open(url: String): Boolean { - val source = Uri.parse(url) - val video = when (source.host?.lowercase()) { - "youtu.be" -> source.pathSegments.firstOrNull() - "youtube.com", "www.youtube.com", "m.youtube.com" -> source.getQueryParameter("v") - ?: source.pathSegments.takeIf { it.firstOrNull() in setOf("shorts", "embed") }?.getOrNull(1) - else -> null - } ?: return false - val intent = Intent(Intent.ACTION_VIEW, Uri.parse("vnd.youtube:$video")).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - val handler = context.packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY) - .firstOrNull { it.activityInfo.exported } ?: return false - intent.setPackage(handler.activityInfo.packageName) - return try { - context.startActivity(intent) - true - } catch (_: ActivityNotFoundException) { - false - } catch (_: SecurityException) { - false - } - } -} diff --git a/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/WolfskinApp.kt b/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/WolfskinApp.kt index 63e29f9b..6efd6932 100644 --- a/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/WolfskinApp.kt +++ b/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/WolfskinApp.kt @@ -41,7 +41,6 @@ import javax.inject.Singleton import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.launch -import org.jellyfin.sdk.model.serializer.toUUIDOrNull import kotlinx.coroutines.withContext import org.justinvisser.wolfskin.design.PeopleStatus import org.justinvisser.wolfskin.design.SettingsList @@ -125,7 +124,7 @@ class WolfskinShellViewModel @Inject constructor( is ShellAction.Person -> selectPerson(action.person, server, user) ShellAction.RetryPeople -> viewModelScope.launch { load(server, user) } ShellAction.RetryRequests -> refreshRequests(retry = true) - is ShellAction.RequestTitle -> navigation.navigateTo(Destination.Wolfskin(titleRoute("${action.request.mediaType}:${action.request.tmdbId}"))) + is ShellAction.RequestTitle -> navigation.navigateTo(Destination.Wolfskin("request-title/${action.request.mediaType}/${action.request.tmdbId}")) } } @@ -203,7 +202,6 @@ fun WolfskinApp( val route = when (destination) { is Destination.Home -> "home" is Destination.Wolfskin -> destination.route - is Destination.MediaItem -> if (destination.type == org.jellyfin.sdk.model.api.BaseItemKind.PERSON) personRoute(destination.itemId.toString()) else titleRoute(destination.itemId.toString()) else -> "pushed" } LaunchedEffect(destination) { if (!destination.fullScreen) state.enterDestination(route) } @@ -212,23 +210,16 @@ fun WolfskinApp( } else { BackHandler { state.key(org.justinvisser.wolfskin.design.ShellKey.Back) } val upstream = resolveUpstreamDestination(destination, WolfskinScreenPreference.enabled, viewModel.libraryDestinations) - if (upstream == null && (route.startsWith("title/") || route.startsWith("person/"))) { - val jellyfinIdentity = destination is Destination.MediaItem || android.net.Uri.decode(route.substringAfter('/')).toUUIDOrNull() != null - if (jellyfinIdentity && state.person.key != viewModel.signedInPerson) { - ShellSurface(state, handlesContentKeys = false) { ShellPlaceholder("Sign in as ${state.person.name} to open their Jellyfin library", it) } - } else TitleDestination(route, state, preferences) - } else { - ShellSurface(state, handlesContentKeys = upstream == null, - overlay = { if (route == "discover" || route.startsWith("discover-")) DiscoverOverlay(discover) }) { contentModifier -> - when { - (upstream != null || destination is Destination.Home || route in LIBRARY_DESTINATIONS) && state.person.key != viewModel.signedInPerson -> ShellPlaceholder("Sign in as ${state.person.name} to open their Jellyfin library", contentModifier) - upstream != null -> DestinationContent(upstream, preferences, viewModel::clearBackdrop, contentModifier) - destination is Destination.Home -> HomeDestination(state, server, user, contentModifier) - route in LIBRARY_DESTINATIONS || route.startsWith("seeall/") -> - WolfskinLibraryContent(androidx.compose.ui.platform.LocalContext.current, route, state, user, "${server.id}:${user.id}", viewModel.libraries, navigationManager, viewModel.seeAll, contentModifier) - destination is Destination.Wolfskin -> DestinationContent(destination, preferences, viewModel::clearBackdrop, contentModifier) - else -> ShellPlaceholder(route, contentModifier) - } + ShellSurface(state, handlesContentKeys = upstream == null, + overlay = { if (route == "discover" || route.startsWith("discover-")) DiscoverOverlay(discover) }) { contentModifier -> + when { + (upstream != null || destination is Destination.Home || route in LIBRARY_DESTINATIONS) && state.person.key != viewModel.signedInPerson -> ShellPlaceholder("Sign in as ${state.person.name} to open their Jellyfin library", contentModifier) + upstream != null -> DestinationContent(upstream, preferences, viewModel::clearBackdrop, contentModifier) + destination is Destination.Home -> HomeDestination(state, server, user, contentModifier) + route in LIBRARY_DESTINATIONS || route.startsWith("seeall/") || route.startsWith("library-title/") -> + WolfskinLibraryContent(androidx.compose.ui.platform.LocalContext.current, route, state, user, "${server.id}:${user.id}", viewModel.libraries, navigationManager, viewModel.seeAll, contentModifier) + destination is Destination.Wolfskin -> DestinationContent(destination, preferences, viewModel::clearBackdrop, contentModifier) + else -> ShellPlaceholder(route, contentModifier) } } } @@ -246,6 +237,7 @@ fun WolfskinDestinationContent(route: String, modifier: Modifier = Modifier) { when { route == "settings" -> SettingsList(LocalShellState.current, modifier) route == "discover" || route.startsWith("discover-") -> DiscoverScreen(LocalDiscoverState.current, modifier) + route.startsWith("request-title/") -> ShellPlaceholder("Title: ${LocalShellState.current.requests.focused?.title.orEmpty()} (title slice integration pending)", modifier) else -> ShellPlaceholder(route, modifier) } } diff --git a/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/WolfskinLibrary.kt b/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/WolfskinLibrary.kt index 0a9a56e5..583bdb02 100644 --- a/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/WolfskinLibrary.kt +++ b/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/WolfskinLibrary.kt @@ -19,8 +19,6 @@ import org.justinvisser.wolfskin.design.* import org.justinvisser.wolfskin.tv.read.LibraryReadFacade import org.justinvisser.wolfskin.tv.read.LibrarySnapshotStore import org.justinvisser.wolfskin.conductarr.FileCacheStore -import org.jellyfin.sdk.model.api.BaseItemKind -import org.jellyfin.sdk.model.serializer.toUUIDOrNull /** Other shelves register the complete per-type list, not the visible twenty-card window. */ @Singleton @@ -30,7 +28,7 @@ class WolfskinSeeAllLists @Inject constructor() { fun open(person: String, key: String, title: String, items: List, navigation: NavigationManager, loadNextPage: (suspend (Int) -> LibraryPage)? = null) { val identity = "$person/$key" val grid = LibraryGridState(title, items, catalogue = true, - onTitle = { navigation.navigateTo(libraryTitleDestination(it)) }) + onTitle = { navigation.navigateTo(Destination.Wolfskin("library-title/${it.id}")) }) if (loadNextPage != null) grid.pagination = LibraryPagination(grid, loadNextPage) lists[identity] = grid navigation.navigateTo(Destination.Wolfskin("seeall/$identity")) @@ -59,10 +57,14 @@ fun WolfskinLibraryContent( } } val snapshots = remember(context) { LibrarySnapshotStore(FileCacheStore(File(context.filesDir, "wolfskin-library-cache"))) } + if (route.startsWith("library-title/")) { + ShellPlaceholder("Title destination: ${route.substringAfter("library-title/")}", modifier) + return + } val grid = remember(shell.person.key, route, view) { view.library ?: if (route.startsWith("seeall/")) seeAll.get(route.substringAfter("seeall/")) else LibraryGridState( title = route.replaceFirstChar { it.uppercase() }, items = emptyList(), - onTitle = { navigation.navigateTo(libraryTitleDestination(it)) }, + onTitle = { navigation.navigateTo(Destination.Wolfskin("library-title/${it.id}")) }, onDiscover = { shell.enterDestination("discover"); navigation.replace(Destination.Wolfskin("discover")) }, onRecover = { view.library?.let { it.refreshRevision++ } }, ).also { it.status = LibraryStatus.Loading; view.library = it } @@ -93,7 +95,3 @@ fun WolfskinLibraryContent( } val LIBRARY_DESTINATIONS = setOf("movies", "shows", "anime") - -private fun libraryTitleDestination(title: LibraryTitle): Destination = - title.id.toUUIDOrNull()?.let { Destination.MediaItem(it, if (title.type == "movie") BaseItemKind.MOVIE else BaseItemKind.SERIES) } - ?: Destination.Wolfskin(titleRoute(title.id)) diff --git a/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/read/TitleReadFacade.kt b/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/read/TitleReadFacade.kt deleted file mode 100644 index bdad22a5..00000000 --- a/app/src/wolfskin/java/org/justinvisser/wolfskin/tv/read/TitleReadFacade.kt +++ /dev/null @@ -1,186 +0,0 @@ -package org.justinvisser.wolfskin.tv.read - -import android.content.Context -import com.github.damontecres.wholphin.data.ItemPlaybackRepository -import com.github.damontecres.wholphin.data.ServerRepository -import com.github.damontecres.wholphin.data.model.BaseItem -import com.github.damontecres.wholphin.data.model.TrackIndex -import com.github.damontecres.wholphin.preferences.UserPreferences -import com.github.damontecres.wholphin.services.FavoriteWatchManager -import com.github.damontecres.wholphin.services.ImageUrlService -import dagger.hilt.android.qualifiers.ApplicationContext -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import kotlinx.serialization.builtins.ListSerializer -import kotlinx.serialization.json.Json -import org.jellyfin.sdk.api.client.ApiClient -import org.jellyfin.sdk.api.client.extensions.itemsApi -import org.jellyfin.sdk.api.client.extensions.tvShowsApi -import org.jellyfin.sdk.api.client.extensions.userLibraryApi -import org.jellyfin.sdk.model.api.BaseItemDto -import org.jellyfin.sdk.model.api.BaseItemKind -import org.jellyfin.sdk.model.api.ImageType -import org.jellyfin.sdk.model.api.ItemFields -import org.jellyfin.sdk.model.api.ItemSortBy -import org.jellyfin.sdk.model.api.MediaStreamType -import org.jellyfin.sdk.model.api.request.GetEpisodesRequest -import org.jellyfin.sdk.model.api.request.GetItemsRequest -import org.jellyfin.sdk.model.api.request.GetNextUpRequest -import org.jellyfin.sdk.model.serializer.toUUIDOrNull -import org.json.JSONObject -import org.justinvisser.wolfskin.design.TitleAction -import org.justinvisser.wolfskin.design.TitleConnection -import org.justinvisser.wolfskin.design.TitleItem -import org.justinvisser.wolfskin.design.TitlePageData -import org.justinvisser.wolfskin.design.TitlePerson -import org.justinvisser.wolfskin.design.TitleTrack -import org.justinvisser.wolfskin.design.TitleVersion -import java.io.File -import java.util.Locale -import java.util.UUID -import javax.inject.Inject - -data class PersonRead(val person: TitlePerson, val credits: List, val savedAt: String? = null) - -/** Jellyfin SDK changes are confined to this boundary; title UI sees immutable screen data only. */ -class TitleReadFacade @Inject constructor( - private val api: ApiClient, - private val images: ImageUrlService, - private val playback: ItemPlaybackRepository, - private val repository: ServerRepository, - private val watched: FavoriteWatchManager, - @param:ApplicationContext private val context: Context, -) { - private val json = Json { ignoreUnknownKeys = true } - private val fields = listOf(ItemFields.PROVIDER_IDS, ItemFields.MEDIA_SOURCES, ItemFields.MEDIA_STREAMS, ItemFields.OVERVIEW, ItemFields.PEOPLE, ItemFields.PARENT_ID) - - /** A disk copy is decoded before any network read; ownership is isolated by server and user. */ - suspend fun readSaved(id: UUID, preferences: UserPreferences): TitlePageData? = withContext(Dispatchers.IO) { - val file = cacheFile(id) - if (!file.exists()) return@withContext null - try { - val saved = JSONObject(file.readText()) - val rows = json.decodeFromString(ListSerializer(BaseItemDto.serializer()), saved.getString("items")) - val numbers = saved.getJSONArray("seasonNumbers").let { array -> List(array.length()) { array.getInt(it) } } - build(rows, numbers, saved.optInt("selectedSeason"), saved.getString("watch"), saved.optString("target").takeIf { it.isNotEmpty() }, preferences) - .copy(savedAt = savedTime(file), trailerUrl = saved.optString("trailer").takeIf { it.isNotEmpty() }) - } catch (_: java.io.IOException) { null } catch (_: IllegalArgumentException) { null } catch (_: org.json.JSONException) { null } - } - - /** An episode opens its series with that exact episode as both play and watched target. */ - suspend fun read(id: UUID, season: Int?, preferences: UserPreferences): TitlePageData = withContext(Dispatchers.IO) { - val file = cacheFile(id) - val opened = api.userLibraryApi.getItem(id).content - val series = if (opened.type == BaseItemKind.EPISODE && opened.seriesId != null) api.userLibraryApi.getItem(opened.seriesId!!).content else opened - val seasons = if (series.type == BaseItemKind.SERIES) api.itemsApi.getItems(GetItemsRequest(parentId = series.id, includeItemTypes = listOf(BaseItemKind.SEASON), recursive = false, sortBy = listOf(ItemSortBy.INDEX_NUMBER))).content.items.orEmpty() else emptyList() - val next = if (opened.type == BaseItemKind.EPISODE || opened.type == BaseItemKind.MOVIE) opened else { - api.tvShowsApi.getNextUp(GetNextUpRequest(seriesId = series.id, userId = repository.currentUser?.id, limit = 1, fields = fields, enableResumable = true)).content.items.firstOrNull()?.let { api.userLibraryApi.getItem(it.id).content } - } - val selectedNumber = season ?: next?.parentIndexNumber ?: seasons.firstOrNull()?.indexNumber - val selected = seasons.firstOrNull { it.indexNumber == selectedNumber } ?: seasons.firstOrNull() - val episodes = selected?.let { api.tvShowsApi.getEpisodes(GetEpisodesRequest(seriesId = series.id, seasonId = it.id, fields = fields)).content.items.orEmpty() }.orEmpty() - val target = next ?: episodes.firstOrNull { it.type == BaseItemKind.EPISODE } - val rows = (listOf(series, opened) + listOfNotNull(target) + episodes).distinctBy { it.id } - val numbers = seasons.mapNotNull { it.indexNumber } - val result = build(rows, numbers, selected?.indexNumber, opened.id.toString(), target?.id?.toString(), preferences) - val localTrailer = if (result.trailerUrl == null && (series.localTrailerCount ?: 0) > 0) api.userLibraryApi.getLocalTrailers(series.id).content.firstOrNull()?.id?.toString() else null - val trailer = result.trailerUrl ?: localTrailer?.let { "jellyfin:$it" } - val saved = JSONObject().put("items", json.encodeToString(ListSerializer(BaseItemDto.serializer()), rows)) - .put("seasonNumbers", org.json.JSONArray(numbers)).put("selectedSeason", selected?.indexNumber).put("watch", opened.id.toString()) - .put("target", target?.id?.toString().orEmpty()).put("trailer", trailer.orEmpty()) - file.parentFile?.mkdirs() - try { file.writeText(saved.toString()) } catch (_: java.io.IOException) { /* Playback remains available when the disk cannot save a copy. */ } - result.copy(trailerUrl = trailer) - } - - /** A failed reachability read leaves navigation on the title instead of opening a dead player. */ - suspend fun preparePlayback(id: UUID) { api.userLibraryApi.getItem(id) } - - /** Track selection uses the same repository consumed by the upstream player. */ - suspend fun apply(action: TitleAction) = withContext(Dispatchers.IO) { - when (action) { - is TitleAction.Version -> playback.savePlayVersion( - UUID.fromString(action.item.id), - requireNotNull(action.version.id.toUUIDOrNull()) { "Invalid Jellyfin media source identifier" }, - ) - is TitleAction.Track -> { - val id = UUID.fromString(action.item.id) - val item = BaseItem(api.userLibraryApi.getItem(id).content) - var choice = repository.currentUser?.let { playback.itemPlaybackDao.getItem(it, id) } - action.audio?.let { choice = playback.saveTrackSelection(item, choice, it, MediaStreamType.AUDIO) } - playback.saveTrackSelection(item, choice, if (action.subtitle == -1) TrackIndex.DISABLED else action.subtitle, MediaStreamType.SUBTITLE) - } - is TitleAction.Watched -> watched.setWatched(UUID.fromString(action.item.id), action.watched) - else -> Unit - } - Unit - } - - /** A person keeps the same server/user-scoped last good copy as a title. */ - suspend fun readPersonSaved(id: UUID): PersonRead? = withContext(Dispatchers.IO) { - val file = personCacheFile(id) - if (!file.exists()) return@withContext null - try { - val rows = json.decodeFromString(ListSerializer(BaseItemDto.serializer()), file.readText()) - personData(id, rows.first(), rows.drop(1)).copy(savedAt = savedTime(file)) - } catch (_: java.io.IOException) { null } catch (_: IllegalArgumentException) { null } - } - - /** Held performer credits are read continuously; a signed-out TV never falls back to Seerr. */ - suspend fun readPerson(id: UUID, start: Int): PersonRead = withContext(Dispatchers.IO) { - val file = personCacheFile(id) - val previous = if (start > 0 && file.exists()) { - try { json.decodeFromString(ListSerializer(BaseItemDto.serializer()), file.readText()) } - catch (_: java.io.IOException) { emptyList() } catch (_: IllegalArgumentException) { emptyList() } - } else emptyList() - val person = previous.firstOrNull() ?: api.userLibraryApi.getItem(id).content - val credits = api.itemsApi.getItems(GetItemsRequest(personIds = listOf(id), recursive = true, - includeItemTypes = listOf(BaseItemKind.MOVIE, BaseItemKind.SERIES), fields = fields, startIndex = start, limit = 200, - sortBy = listOf(ItemSortBy.PRODUCTION_YEAR, ItemSortBy.SORT_NAME))).content.items.orEmpty() - val rows = listOf(person) + (previous.drop(1) + credits).distinctBy { it.id } - file.parentFile?.mkdirs() - try { file.writeText(json.encodeToString(ListSerializer(BaseItemDto.serializer()), rows)) } - catch (_: java.io.IOException) { /* The readable grid does not disappear when saving fails. */ } - personData(id, person, credits) - } - - private fun personData(id: UUID, person: BaseItemDto, credits: List): PersonRead = - PersonRead(TitlePerson(id.toString(), person.name.orEmpty(), portrait = images.getItemImageUrl(id, ImageType.PRIMARY, maxWidth = 240, maxHeight = 240), biography = person.overview.orEmpty()), - credits.map { credit -> mapItem(credit).copy(character = credit.people.orEmpty().firstOrNull { it.id == id }?.role) }) - - private suspend fun build(rows: List, seasonNumbers: List, selectedSeason: Int?, watchId: String, targetId: String?, preferences: UserPreferences): TitlePageData { - val item = rows.first() - val target = rows.firstOrNull { it.id.toString() == targetId } - val chosen = target?.let { playback.getSelectedTracks(it.id, BaseItem(it), preferences) } - val versions = target?.mediaSources.orEmpty().map { source -> - val streams = source.mediaStreams.orEmpty() - TitleVersion(source.id.orEmpty(), source.name ?: source.path ?: source.id.orEmpty(), streams.firstOrNull { it.type == MediaStreamType.VIDEO }?.displayTitle.orEmpty(), - source.bitrate?.let { String.format(Locale.getDefault(), "%.1f Mbps", it / 1_000_000.0) }.orEmpty(), - source.size?.let { String.format(Locale.getDefault(), "%.1f GB", it / 1_000_000_000.0) }.orEmpty(), source.container.orEmpty().uppercase(), - streams.filter { it.type == MediaStreamType.AUDIO }.map { TitleTrack(it.index, it.displayTitle ?: it.language ?: it.codec.orEmpty(), it.isDefault) }, - streams.filter { it.type == MediaStreamType.SUBTITLE }.map { TitleTrack(it.index, it.displayTitle ?: it.language ?: it.codec.orEmpty(), it.isDefault) }) - } - return TitlePageData(mapItem(item).copy(seasons = seasonNumbers.size), target?.takeIf { it.type == BaseItemKind.EPISODE || (it.userData?.playbackPositionTicks ?: 0) > 0 }?.let { mapItem(it) }, - rows.first { it.id.toString() == watchId }.let { mapItem(it) }, versions, chosen?.source?.id, chosen?.audioStream?.stream?.index, - if (chosen?.subtitlesDisabled == true) -1 else chosen?.subtitleStream?.stream?.index ?: -1, - item.remoteTrailers.orEmpty().firstNotNullOfOrNull { it.url }, - cast = item.people.orEmpty().filter { it.type.toString().equals("Actor", true) }.map { person -> - TitlePerson(person.id.toString(), person.name.orEmpty(), person.role.orEmpty(), person.primaryImageTag?.let { images.getItemImageUrl(person.id, ImageType.PRIMARY, maxWidth = 200, maxHeight = 200, tag = it) }) - }, - episodes = rows.filter { it.type == BaseItemKind.EPISODE && it.parentIndexNumber == selectedSeason }.map { mapItem(it) }, - connection = TitleConnection.SignedOut, seasonNumbers = seasonNumbers, selectedSeason = selectedSeason) - } - - private fun mapItem(item: BaseItemDto): TitleItem = TitleItem( - item.id.toString(), item.name.orEmpty(), when (item.type) { BaseItemKind.MOVIE -> "movie"; BaseItemKind.EPISODE -> "episode"; else -> "tv" }, - item.productionYear, (item.runTimeTicks ?: 0) / 10_000_000, overview = item.overview.orEmpty(), genres = item.genres.orEmpty(), - poster = item.imageTags?.get(ImageType.PRIMARY)?.let { images.getItemImageUrl(item.id, ImageType.PRIMARY, maxWidth = 256, maxHeight = 384, tag = it) }, - backdrop = item.backdropImageTags?.firstOrNull()?.let { images.getItemImageUrl(item.id, ImageType.BACKDROP, maxWidth = 1280, maxHeight = 720, tag = it) }, - held = true, watched = item.userData?.played == true, resumeSeconds = (item.userData?.playbackPositionTicks ?: 0) / 10_000_000, - seriesId = item.seriesId?.toString(), seriesName = item.seriesName, season = item.parentIndexNumber ?: 0, episode = item.indexNumber ?: 0, - ) - - private fun cacheFile(id: UUID): File = File(context.filesDir, "wolfskin-title/${repository.currentServer?.id}/${repository.currentUser?.id}/$id.json") - private fun personCacheFile(id: UUID): File = File(cacheFile(id).parentFile, "person-$id.json") - private fun savedTime(file: File): String = java.text.SimpleDateFormat("HH:mm", Locale.getDefault()).format(java.util.Date(file.lastModified())) -} diff --git a/docker/README.md b/docker/README.md index cc822873..928fece8 100644 --- a/docker/README.md +++ b/docker/README.md @@ -59,9 +59,9 @@ cover the Wolfskin nav. The independent `:wolfskin-design` module owns the shell components, fixed person colours, focus policy, per-person root-view memory, palette and motion. Its `tokens.json` is the copied approved TV-spec source, retaining the locked prototype -SHA and provenance. `shell-tokens.json` adds shared shell/grid/sheet measurements; -`title-tokens.json`, `home-tokens.json` and `discover-tokens.json` add their screen -measurements from the same locked prototype. Generate Kotlin, CSS and the checksum manifest together: +SHA and provenance. `shell-tokens.json` adds shared shell, grid and sheet measurements; +`home-tokens.json` and `discover-tokens.json` add their screen geometry from that +same locked prototype. Generate the committed Kotlin, CSS and checksum manifest together: ```sh python3 wolfskin-design/generate_tokens.py @@ -297,10 +297,10 @@ uv run --with cairosvg==2.9.1 python wolfskin-design/generate_request_marks.py ``` `RequestsCaptureTest` writes `st-081`…`st-086`, `st-088` and `st-111` at 1920×1080, -density 2.0. Title selection opens the shared native title destination by media -type and TMDB identity. Back restores the exact Coming-in row and expansion; -the temporary `request-title/...` placeholder is removed. TV sign-in, release -and device deployment remain separate. +density 2.0. Title selection currently uses an explicitly labelled +`request-title/...` destination until the independent title screen is integrated; +this slice does not claim to implement title pages, TV sign-in, release or device +deployment. ## Libraries and See all @@ -331,10 +331,8 @@ Home/Discover shelves open a full list through The optional suspend page provider returns `LibraryPage(items, hasMore)` using the generated Conductarr client. The grid reads within ten cards of its end, deduplicates title identities, and pauses on Try again or Show more rather than looping. -Title activation opens `title/{id}` through `Destination.Wolfskin` for prototype -identities, or the existing typed media destination for real Jellyfin identities. -Movies, series, episodes and people use the native title family; collections and -music keep their upstream destinations. +Title activation pushes the explicitly named `library-title/{id}` destination for +the title-screen implementation; this slice does not implement title pages. `LibraryCaptureTest` renders the sixteen approved library/See all states offline. `LibraryKeysTest` reads the approved JSON path and reaches Spirited Away in exactly @@ -342,65 +340,6 @@ music keep their upstream destinations. failure/retry, stale copies, and person/server isolation. Library captures are written to `build/wolfskin-captures/library/`; Discover's independent captures use `discover/`. -## Title pages and people - -`TitleSurface` owns the film/series/episode header, season chips, episode tiles, -cast and related shelves. `PersonSurface` owns the real biography and continuous -six-column filmography. Both reuse the shell/nav/back ladder, `LibraryPoster`, -the adaptive `LibraryRatingPlate`, shared captions and the single bounded -`WolfskinImages` loader. Image requests use exact slot sizes, RGB565 for opaque -posters, no crossfade, four concurrent reads and next-row prefetch. The fixed -title backdrop remains visible behind deep rows; only off-screen row images -leave composition. - -The options row preserves complete labels beyond the copy-column measure. -Version choices close after selection; Audio and subtitles stays open, including -an explicit Off choice. Real source IDs use the Jellyfin SDK UUID parser, and -stream indexes remain the server's indexes rather than positions in a list. -Selections persist through the same playback repository as the upstream player. -Marking a whole series asks first; an explicit episode remains the exact play and -watched target even while another season is selected. Nested person/title visits -retain their entry's focus and selection state. -Hardware and remote Back share the sheet/picker/request-overlay precedence, then -pop a pushed title/person from content **or** nav. Initial loading has no content -target: Down stays in nav, while Back can still leave the title. A missing rating -set emits no layout node, so it cannot reserve an invisible extra facts gap. - -`TitleReadFacade` confines SDK reads, server/user-scoped last-good disk copies, -person credits and playback mutations to one boundary. Cached content appears -before refresh. Production ratings stay hidden until Conductarr sign-in exists. -Debug-only `wolfskin-titles.json` and local `wolfskin-titles/assets/` project the -locked household fixture, including portraits; release never packages them. -Those synthetic IDs are not invented Jellyfin playback IDs. Real held-title -playback uses the existing player; debug catalogue identities cannot play a file. - -Held trailers use Jellyfin remote/local trailer data. YouTube URLs target an -installed YouTube handler such as SmartTube, never a browser. No handler leaves -the title visible with a calm message. Titles nobody holds have no Trailer -button until Conductarr's trailer field exists. Conductarr sign-in and request -submission/receipt workflows belong to their separate slices; title pages do not -pretend those operations succeeded or fall back to Seerr. - -`TitleCaptureTest` writes the 34 approved title/person/options frames plus native -text weights, colours, line boxes and bounds at 1920×1080, density 2.0. The approved -typeface ruling keeps platform Roboto, not the browser's DejaVu Sans: no per-title -compensation and no wrapping-parity claim. Explicit CSS line boxes constrain title -headers, sheets, cast and poster captions without changing shared type tokens. -Fractional stack placement rounds only the accumulated position, preventing a -one-pixel-per-row drift. Focused controls share the canonical lift shadow. -`TitleKeysTest` replays real Android keys, including modal Back/hold, nearest-row -entry, remembered columns, long-sheet visibility and full media-table geometry. -`TitleAsyncFocusTest` delays title and person replies through the real destination -and view-model, then exercises content focus and hardware Back. Subtitles Off -maps to the player's explicit disabled sentinel, not its unspecified default. - -`TitleLaunchKeysTest` starts at Who's watching and replays the full 4/8/15/11 -sequences through the real Home hero/shelves and title/person surfaces. -`title-press-paths.json` supplies every event; no prefix is skipped or padded. -The shorter 1/5/6/2 title-entry replays remain as focused regressions. SDK cache, -exact-episode, track-index, identity, locale-layout and trailer-handler tests -run offline with in-process service replies and local art. - ## Offline states and recovery Owned screens share `RecoveryToast`: the warning glyph, 760 px maximum width, @@ -444,13 +383,7 @@ Production Conductarr TV sign-in/provider wiring remains outside these state components: release Discover is signed out and release Requests is unavailable. The generated client's identity-scoped disk cache is the Conductarr cache boundary; no Seerr fallback, live-test server, handwritten HTTP or offline request queue is added. -Title and person surfaces publish saved timestamps through the same per-person -`RememberedView` partition and nav Saved indicator. Their timed notices render -the shared `RecoveryToast`; failed Try again and playback use `RecoveryMessage` -without transport details. A selected-person mismatch never renders the former -person's title/person projection. Title and performer disk copies remain isolated -by both server and authenticated user; native retry and cache-isolation regressions -exercise these boundaries without a live service. +Title-family state integration and captures follow its independent title-screen merge. ## Toolchain and disk use diff --git a/wolfskin-design/build.gradle.kts b/wolfskin-design/build.gradle.kts index d1275edb..5db509aa 100644 --- a/wolfskin-design/build.gradle.kts +++ b/wolfskin-design/build.gradle.kts @@ -30,7 +30,7 @@ val cacheRobolectricSdk by tasks.registering(Copy::class) { } val checkTokenDrift by tasks.registering { - inputs.files(fileTree(projectDir) { include("tokens.json", "shell-tokens.json", "title-tokens.json", "home-tokens.json", "discover-tokens.json", "generate_tokens.py", "tokens.css", "tokens.sha256", "src/main/java/**/WolfskinTokens.kt") }) + inputs.files(fileTree(projectDir) { include("tokens.json", "shell-tokens.json", "home-tokens.json", "discover-tokens.json", "generate_tokens.py", "tokens.css", "tokens.sha256", "src/main/java/**/WolfskinTokens.kt") }) doLast { file("tokens.sha256").readLines().forEach { line -> val (expected, name) = line.split(" ", limit = 2) diff --git a/wolfskin-design/generate_tokens.py b/wolfskin-design/generate_tokens.py index 51a49b20..a8cd6db6 100755 --- a/wolfskin-design/generate_tokens.py +++ b/wolfskin-design/generate_tokens.py @@ -86,14 +86,6 @@ def render_tokens(tokens: dict) -> tuple[str, str]: elif isinstance(token.get("dp"), dict): for suffix, dimension in token["dp"].items(): lines.append(f" val {name}{suffix[0].upper() + suffix[1:]} = {number(dimension)}.dp") - if kind == "card": - lines.append(f" const val {name}Slots = {token['fullSlotsPerRow']}") - elif group_name == "image" and isinstance(token.get("px"), list): - for suffix, dimension in zip(("Width", "Height"), token["px"]): - lines.append(f" const val {name}{suffix} = {int(dimension)}") - elif group_name == "image" and isinstance(value, dict): - for suffix, count in value.items(): - lines.append(f" const val {name}{suffix[0].upper() + suffix[1:]} = {int(count)}") elif isinstance(value, (float, int)) and not isinstance(value, bool): lines.append(f" const val {name} = {number(value)}f") elif kind in ("gradient", "filter", "rule") and isinstance(value, str): @@ -113,12 +105,11 @@ def main() -> None: arguments = parser.parse_args() tokens = json.loads((ROOT / "tokens.json").read_text()) tokens.update(json.loads((ROOT / "shell-tokens.json").read_text())) - tokens.update(json.loads((ROOT / "title-tokens.json").read_text())) tokens.update(json.loads((ROOT / "home-tokens.json").read_text())) tokens.update(json.loads((ROOT / "discover-tokens.json").read_text())) kotlin, css = render_tokens(tokens) outputs = {str(KOTLIN): kotlin, "tokens.css": css} - inputs = ["tokens.json", "shell-tokens.json", "title-tokens.json", "home-tokens.json", "discover-tokens.json", "generate_tokens.py"] + inputs = ["tokens.json", "shell-tokens.json", "home-tokens.json", "discover-tokens.json", "generate_tokens.py"] checksums = {name: hashlib.sha256((ROOT / name).read_bytes()).hexdigest() for name in inputs} checksums.update({name: hashlib.sha256(content.encode()).hexdigest() for name, content in outputs.items()}) outputs["tokens.sha256"] = "".join(f"{checksum} {name}\n" for name, checksum in sorted(checksums.items())) diff --git a/wolfskin-design/shell-tokens.json b/wolfskin-design/shell-tokens.json index e66ac6ec..4fbc4f44 100644 --- a/wolfskin-design/shell-tokens.json +++ b/wolfskin-design/shell-tokens.json @@ -369,12 +369,9 @@ "chipIcon": {"$type":"dimension","px":26,"dp":13,"source":"index.html:185"}, "captionWidth": {"$type":"dimension","px":640,"dp":320,"source":"index.html:151"}, "captionSeparatorOpacity": {"$type":"number","$value":0.4,"source":"index.html:1207; spec 4.4"}, - "captionFactsGap": {"$type":"dimension","px":18,"dp":9,"source":"index.html:154"}, - "badgeIcon": {"$type":"dimension","px":28,"dp":14,"source":"index.html:142"}, "plateTop": {"$type":"dimension","px":14,"dp":7,"source":"index.html:162"}, "plateSide": {"$type":"dimension","px":16,"dp":8,"source":"index.html:162"}, "plateBottom": {"$type":"dimension","px":46,"dp":23,"source":"index.html:162"}, - "plateInlineDescent": {"$type":"dimension","px":6.6,"dp":3.3,"source":"index.html:156,162 inline-flex baseline strut; proto-104 rplate 100.2px minus 14+33.6+46"}, "plateFloor": {"$type":"typography","px":24,"sp":12,"weight":700,"$value":{"fontWeight":700},"source":"index.html:802"}, "plateStep": {"$type":"number","$value":0.25,"source":"spec 4.8"}, "plateGapEm": {"$type":"number","$value":0.64,"source":"index.html:164"}, diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/Caption.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/Caption.kt index 5f9a0742..31a0487e 100644 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/Caption.kt +++ b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/Caption.kt @@ -9,13 +9,12 @@ import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.text.style.TextOverflow + +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.style.TextOverflow import androidx.tv.material3.Text -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.ui.draw.clipToBounds -import androidx.compose.ui.layout.Layout -import androidx.compose.ui.unit.constrainHeight /** Captions fade without moving the reserved band under the focused poster. */ @Composable @@ -26,47 +25,32 @@ fun Caption(title: String, facts: String, visible: Boolean, modifier: Modifier = LaunchedEffect(alpha, visible) { alpha.animateTo(if (visible) 1f else 0f, tween(WolfskinTokens.Motion.fast, easing = CubicBezierEasing(.25f, .1f, .25f, 1f))) } - Column(modifier.graphicsLayer { this.alpha = alpha.value }) { - Text(title, color = WolfskinTokens.Color.fg, style = titleStyle, modifier = Modifier.exactLineBox(titleStyle), maxLines = 1, overflow = titleOverflow) - CaptionFacts(facts, accentFirstFact, accentLastFact, factsStyle) - } -} - -/** CSS flex facts: only coloured role/ownership spans shrink; ordinary facts and dots keep their width. */ -@Composable -private fun CaptionFacts(facts: String, accentFirst: Boolean, accentLast: Boolean, style: TextStyle) { - val parts = remember(facts) { facts.split(" · ") } - val muted = WolfskinTokens.Color.muted - val colour = WolfskinTokens.Color.accentText - Layout( - content = { - parts.forEachIndexed { index, part -> - val accented = (index == 0 && accentFirst) || (index == parts.lastIndex && accentLast) - Text(part, color = if (accented) colour else muted, style = style, modifier = Modifier.exactLineBox(style), maxLines = 1, overflow = TextOverflow.Clip) - if (index != parts.lastIndex) Text("·", color = muted.copy(alpha = muted.alpha * WolfskinTokens.Library.captionSeparatorOpacity), style = style, modifier = Modifier.exactLineBox(style)) + val styledFacts = remember(facts, accentLastFact, accentFirstFact) { + buildAnnotatedString { + val separator = " · " + append(facts) + if (accentFirstFact) { + val end = facts.indexOf(separator).takeIf { it >= 0 } ?: facts.length + addStyle(SpanStyle(color = WolfskinTokens.Color.accentText), 0, end) + } + if (accentLastFact) { + val suffix = facts.lastIndexOf(separator).takeIf { it >= 0 }?.plus(separator.length) ?: facts.length + if (suffix < facts.length) addStyle(SpanStyle(color = WolfskinTokens.Color.accentText), suffix, facts.length) + } + var start = facts.indexOf(separator) + if (start >= 0) { + val muted = WolfskinTokens.Color.muted + val separatorStyle = SpanStyle(color = muted.copy(alpha = muted.alpha * WolfskinTokens.Library.captionSeparatorOpacity)) + val dotOffset = separator.indexOf('·') + while (start >= 0) { + addStyle(separatorStyle, start + dotOffset, start + dotOffset + 1) + start = facts.indexOf(separator, start + separator.length) + } } - }, - modifier = Modifier.fillMaxWidth().clipToBounds(), - ) { children, constraints -> - val gap = WolfskinTokens.Library.captionFactsGap.roundToPx() - val basis = IntArray(children.size) - var fixed = gap * (children.size - 1).coerceAtLeast(0) - var flexible = 0 - fun shrinks(index: Int) = (index == 0 && accentFirst) || (index == children.lastIndex && accentLast) - children.forEachIndexed { index, child -> - val width = child.maxIntrinsicWidth(constraints.maxHeight) - basis[index] = width - if (shrinks(index)) flexible += width else fixed += width - } - val available = (constraints.maxWidth - fixed).coerceAtLeast(0) - val ratio = if (flexible > available) available.toFloat() / flexible else 1f - val measured = children.mapIndexed { index, child -> - val width = if (shrinks(index)) (basis[index] * ratio).toInt() else basis[index] - child.measure(constraints.copy(minWidth = 0, maxWidth = width, minHeight = 0)) - } - layout(constraints.maxWidth, constraints.constrainHeight(measured.maxOfOrNull { it.height } ?: 0)) { - var x = 0 - measured.forEach { child -> child.placeRelative(x, 0); x += child.width + gap } } } + Column(modifier.graphicsLayer { this.alpha = alpha.value }) { + Text(title, modifier = Modifier.exactLineBox(titleStyle), color = WolfskinTokens.Color.fg, style = titleStyle, maxLines = 1, overflow = titleOverflow) + Text(styledFacts, modifier = Modifier.exactLineBox(factsStyle), color = WolfskinTokens.Color.muted, style = factsStyle, maxLines = 1) + } } diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/CssLineBox.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/CssLineBox.kt deleted file mode 100644 index 4f1d281a..00000000 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/CssLineBox.kt +++ /dev/null @@ -1,68 +0,0 @@ -package org.justinvisser.wolfskin.design - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier -import androidx.compose.ui.layout.FirstBaseline -import androidx.compose.ui.layout.LastBaseline -import androidx.compose.ui.layout.Layout -import androidx.compose.ui.layout.LayoutModifier -import androidx.compose.ui.layout.Measurable -import androidx.compose.ui.layout.MeasureScope -import androidx.compose.ui.layout.ParentDataModifier -import androidx.compose.ui.unit.Constraints -import androidx.compose.ui.unit.Density -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.TextUnit -import kotlin.math.roundToInt - -internal data class CssLineBox(val lineHeight: TextUnit, val top: Dp, val bottom: Dp) : LayoutModifier, ParentDataModifier { - override fun Density.modifyParentData(parentData: Any?): Any = parentData ?: this@CssLineBox - fun Density.exactHeight(height: Int): Float { - val margins = top.toPx() + bottom.toPx() - return ((height - margins) / lineHeight.toPx()).roundToInt().coerceAtLeast(1) * lineHeight.toPx() + margins - } - override fun MeasureScope.measure(measurable: Measurable, constraints: Constraints) = with(measurable.measure(constraints.copy(minHeight = 0))) { - val line = lineHeight.toPx() - val lines = ((this[LastBaseline] - this[FirstBaseline]) / line).roundToInt().coerceAtLeast(0) + 1 - val textHeight = lines * line - val offset = top.toPx() + (textHeight - height) / 2f - layout(width, (textHeight + top.toPx() + bottom.toPx()).roundToInt()) { - placeRelative(0, offset.roundToInt()) - } - } -} - -private class CssColumnHeight : ParentDataModifier { - var pixels = 0f - override fun Density.modifyParentData(parentData: Any?): Any = parentData ?: this@CssColumnHeight -} - -/** Fractional line heights accumulate before rounding, rather than adding a rounded pixel per row. */ -@Composable -internal fun CssColumn(modifier: Modifier = Modifier, gap: Dp = WolfskinTokens.Shell.zero, content: @Composable () -> Unit) { - val exact = remember { CssColumnHeight() } - Layout(content, modifier.then(exact)) { children, constraints -> - val measured = Array(children.size) { children[it].measure(constraints.copy(minWidth = 0, minHeight = 0)) } - fun height(index: Int): Float = when (val data = children[index].parentData) { - is CssLineBox -> with(data) { exactHeight(measured[index].height) } - is CssColumnHeight -> data.pixels - else -> measured[index].height.toFloat() - } - val space = gap.toPx() - var total = 0f - var width = constraints.minWidth - for (index in measured.indices) { - total += height(index) + if (index == measured.lastIndex) 0f else space - width = maxOf(width, measured[index].width) - } - exact.pixels = total - layout(width.coerceIn(constraints.minWidth, constraints.maxWidth), total.roundToInt().coerceIn(constraints.minHeight, constraints.maxHeight)) { - var y = 0f - for (index in measured.indices) { - measured[index].placeRelative(0, y.roundToInt()) - y += height(index) + space - } - } - } -} diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/Glyph.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/Glyph.kt index 5a9227d3..3682a759 100644 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/Glyph.kt +++ b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/Glyph.kt @@ -6,24 +6,25 @@ import androidx.compose.ui.graphics.Color import androidx.compose.ui.res.painterResource import androidx.tv.material3.Icon -/** Shared glyph geometry comes from the locked prototype, never a platform icon font. */ +/** Shell glyph geometry is copied from the locked prototype, not a platform icon font. */ @Composable fun Glyph(name: String, color: Color, modifier: Modifier = Modifier) { val resource = when (name) { "gear" -> R.drawable.wolfskin_gear "requests" -> R.drawable.wolfskin_tray "interface" -> R.drawable.wolfskin_grid - "play", "playback" -> R.drawable.wolfskin_play - "tv", "nextup" -> R.drawable.wolfskin_tv - "users", "profile" -> R.drawable.wolfskin_users + "playback" -> R.drawable.wolfskin_play + "nextup" -> R.drawable.wolfskin_tv + "profile" -> R.drawable.wolfskin_users "about" -> R.drawable.wolfskin_info - "sparkle", "seerr" -> R.drawable.wolfskin_sparkle + "seerr" -> R.drawable.wolfskin_sparkle "advanced" -> R.drawable.wolfskin_sort "alert" -> R.drawable.wolfskin_alert "wifi" -> R.drawable.wolfskin_wifi "clock" -> R.drawable.wolfskin_clock "plus" -> R.drawable.wolfskin_plus "check" -> R.drawable.wolfskin_check + "clock" -> R.drawable.wolfskin_clock "hide" -> R.drawable.wolfskin_hide "undo" -> R.drawable.wolfskin_undo "left" -> R.drawable.wolfskin_left @@ -31,12 +32,6 @@ fun Glyph(name: String, color: Color, modifier: Modifier = Modifier) { "film" -> R.drawable.wolfskin_film "eye" -> R.drawable.wolfskin_eye "down" -> R.drawable.wolfskin_down - "restart" -> R.drawable.title_restart - "version" -> R.drawable.title_version - "tracks" -> R.drawable.title_tracks - "eyeoff" -> R.drawable.title_eyeoff - "trailer" -> R.drawable.title_trailer - "more" -> R.drawable.title_more else -> R.drawable.wolfskin_right } Icon(painterResource(resource), contentDescription = null, modifier = modifier, tint = color) diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/LibraryGridState.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/LibraryGridState.kt index bd36f97f..1a1f9a7a 100644 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/LibraryGridState.kt +++ b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/LibraryGridState.kt @@ -5,41 +5,26 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.compose.runtime.derivedStateOf import java.util.Locale -import androidx.compose.runtime.Immutable private val leadingArticle = Regex("^(the|a|an)\\s+", RegexOption.IGNORE_CASE) -/** Art-only card data shared without per-card adapter allocations. */ -@Immutable -interface PosterContent { - val id: String - val posterTitle: String - val posterIsMovie: Boolean - val poster: String? - val ratings: List - val progress: Float - val badge: String? -} - /** Immutable title facts cross the provider boundary without SDK objects. */ data class LibraryTitle( - override val id: String, + val id: String, val title: String, val type: String, val year: Int? = null, val runtimeSeconds: Long? = null, val seasons: Int? = null, - override val poster: String? = null, + val poster: String? = null, val played: Boolean = false, - override val progress: Float = 0f, + val progress: Float = 0f, val addedAt: String = "", - override val ratings: List = emptyList(), + val ratings: List = emptyList(), val availability: String = "", - override val badge: String? = null, + val badge: String? = null, val tmdbId: String? = null, -) : PosterContent { - override val posterTitle: String get() = title - override val posterIsMovie: Boolean get() = type == "movie" +) { val sortName: String = title.replace(leadingArticle, "").lowercase(Locale.ROOT) val catalogueKey: String = "$type:${tmdbId ?: id}" val letter: Char = sortName.firstOrNull()?.uppercaseChar()?.takeIf { it in 'A'..'Z' } ?: '#' @@ -55,8 +40,7 @@ data class LibraryTitle( } /** Ordered rating entries are formatted after the active TV locale is known. */ -@Immutable -data class LibraryRating(val source: String, val score: Double, val label: String? = null, val episode: Boolean = false) { +data class LibraryRating(val source: String, val score: Double, val label: String? = null) { fun formatted(locale: Locale = Locale.getDefault()): String = if (source.startsWith("rt")) "${score.toInt()}%" else String.format(locale, "%.1f", score) } diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/LibraryPoster.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/LibraryPoster.kt index 27374461..f6435e63 100644 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/LibraryPoster.kt +++ b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/LibraryPoster.kt @@ -1,5 +1,7 @@ package org.justinvisser.wolfskin.design +import androidx.compose.animation.core.animateFloatAsState +import androidx.compose.animation.core.tween import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.border @@ -8,42 +10,43 @@ import androidx.compose.foundation.shape.CircleShape import androidx.compose.runtime.* import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Brush +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.graphics.ColorMatrix import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.layout.ContentScale -import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.testTag -import coil3.compose.AsyncImage +import androidx.compose.ui.text.rememberTextMeasurer +import androidx.compose.ui.unit.TextUnit +import androidx.compose.ui.unit.sp +import androidx.tv.material3.Text import org.justinvisser.wolfskin.design.WolfskinTokens.Color as C import org.justinvisser.wolfskin.design.WolfskinTokens.Library as L /** Poster slots use exact requests and share the shell's draw-only focus treatment. */ @Composable fun LibraryPoster( - title: PosterContent, + title: LibraryTitle, focused: Boolean, ratingsVisible: Boolean, catalogue: Boolean, modifier: Modifier = Modifier, offlineArt: ((String) -> ImageBitmap?)? = null, ) { - val poster = title.poster TitleCard(focused, modifier.testTag("poster-${title.id}")) { - val bitmap = remember(poster, offlineArt) { poster?.let { offlineArt?.invoke(it) } } - if (bitmap != null) Image(bitmap, title.posterTitle, Modifier.fillMaxSize(), contentScale = ContentScale.Crop) - else if (poster != null && offlineArt == null) { - var ready by remember(poster) { mutableStateOf(false) } - if (!ready) MediaArtworkFallback(title.posterTitle, title.posterIsMovie) - val context = LocalContext.current - val request = remember(poster, context) { WolfskinImages.request(context, poster, WolfskinTokens.Image.posterRequestWidth, WolfskinTokens.Image.posterRequestHeight, true) } - AsyncImage(request, title.posterTitle, imageLoader = WolfskinImages.loader(context), modifier = Modifier.fillMaxSize(), contentScale = ContentScale.Crop, - onSuccess = { ready = true }, onError = { ready = false }) - } else MediaArtworkFallback(title.posterTitle, title.posterIsMovie) + val bitmap = remember(title.poster) { title.poster?.let { offlineArt?.invoke(it) } } + if (bitmap != null) Image(bitmap, title.title, Modifier.fillMaxSize(), contentScale = ContentScale.Crop) + else if (offlineArt == null) TitleArtwork(title.title, title.type, title.poster, + WolfskinTokens.Card.posterW, WolfskinTokens.Card.posterH, Modifier.fillMaxSize()) + else TitleArtwork(title.title, title.type, null, WolfskinTokens.Card.posterW, WolfskinTokens.Card.posterH, Modifier.fillMaxSize()) if (title.ratings.isNotEmpty()) LibraryRatingPlate(title.ratings, visible = ratingsVisible) - val progress = title.progress - if (progress > 0f && progress < 1f) { + if (title.progress > 0f && title.progress < 1f) { Box(Modifier.align(Alignment.BottomCenter).padding(horizontal = WolfskinTokens.Layout.captionOffset, vertical = WolfskinTokens.Layout.navItemGap) .fillMaxWidth().height(WolfskinTokens.Layout.progressBar).background(C.progressTrack, CircleShape)) { - Box(Modifier.fillMaxHeight().fillMaxWidth(progress).background(C.accent, CircleShape)) + Box(Modifier.fillMaxHeight().fillMaxWidth(title.progress).background(C.accent, CircleShape)) } } if (catalogue && title.badge != null) { @@ -51,7 +54,7 @@ fun LibraryPoster( val color = if (title.badge == "failed") C.fail else C.accent Box(Modifier.align(Alignment.BottomEnd).padding(WolfskinTokens.Layout.badgeInset) .size(WolfskinTokens.Layout.badge).background(if (held) C.ok else C.badgeRest, CircleShape) - .then(if (held) Modifier else Modifier.border(L.badgeRing, color, CircleShape)), contentAlignment = Alignment.Center) { + .border(if (held) WolfskinTokens.Shell.zero else L.badgeRing, color, CircleShape), contentAlignment = Alignment.Center) { Glyph(if (held) "check" else if (title.badge == "failed") "alert" else "clock", if (held) C.onFocus else color, Modifier.size(L.badgeIcon)) } @@ -60,3 +63,45 @@ fun LibraryPoster( } +/** A measured prefix stays on one line, shrinking only to the approved type floor. */ +@Composable +fun LibraryRatingPlate(ratings: List, modifier: Modifier = Modifier, visible: Boolean = true) { + val measurer = rememberTextMeasurer() + val density = LocalDensity.current + val available = with(density) { (WolfskinTokens.Card.posterW - L.plateSide * 2).toPx() } + val formatted = ratings.map { it.formatted() } + fun width(count: Int, size: TextUnit): Float = (0 until count).sumOf { index -> + val labelWidth = measurer.measure(formatted[index], WolfskinTokens.Type.ratingPlate.copy(fontSize = size)).size.width + val pixels = with(density) { size.toPx() } + (labelWidth + pixels * (if (ratings[index].source in listOf("imdb", "tmdb")) L.wordmarkRatio else 1f) + pixels * L.markGapEm + if (index > 0) pixels * L.plateGapEm else 0f).toDouble() + }.toFloat() + var size = WolfskinTokens.Type.ratingPlate.fontSize + var count = ratings.size + while (size > L.plateFloor.fontSize && width(count, size) > available) size = (size.value - L.plateStep).coerceAtLeast(L.plateFloor.fontSize.value).sp + while (count > 1 && width(count, size) > available) count-- + val alpha by animateFloatAsState(if (visible) 1f else 0f, tween(WolfskinTokens.Motion.base), label = "library-plate") + Row(modifier.fillMaxWidth().graphicsLayer { this.alpha = alpha }.background(Brush.verticalGradient( + 0f to C.bg.copy(alpha = L.plateOpacity), L.plateMidStop to C.bg.copy(alpha = L.plateMidOpacity), 1f to Color.Transparent)) + .padding(start = L.plateSide, end = L.plateSide, top = L.plateTop, bottom = L.plateBottom), + horizontalArrangement = Arrangement.spacedBy(with(density) { (size.toPx() * L.plateGapEm).toDp() }), verticalAlignment = Alignment.CenterVertically) { + repeat(count) { index -> + val rating = ratings[index] + val mark = when (rating.source) { + "rtCritics" -> if (rating.label == "Rotten") R.drawable.ic_rotten_tomatoes_rotten else R.drawable.ic_rotten_tomatoes_fresh + "rtAudience" -> if (rating.label == "Spilled") R.drawable.ic_rt_spilled else R.drawable.ic_rt_upright + "imdb" -> R.drawable.ic_rating_imdb + else -> R.drawable.ic_rating_tmdb + } + val markHeight = with(density) { size.toDp() } + val unknownCritic = rating.source == "rtCritics" && rating.label != "Fresh" && rating.label != "Certified Fresh" && rating.label != "Rotten" + val desaturated = remember { ColorFilter.colorMatrix(ColorMatrix().apply { setToSaturation(0f) }) } + Row(horizontalArrangement = Arrangement.spacedBy(markHeight * L.markGapEm), verticalAlignment = Alignment.CenterVertically) { + Image(androidx.compose.ui.res.painterResource(mark), rating.source, + Modifier.size(markHeight * if (rating.source in listOf("imdb", "tmdb")) L.wordmarkRatio else 1f, markHeight) + .graphicsLayer { this.alpha = if (unknownCritic) L.unknownCriticOpacity else 1f }, + colorFilter = if (unknownCritic) desaturated else null) + Text(formatted[index], color = C.fg, style = WolfskinTokens.Type.ratingPlate.copy(fontSize = size), maxLines = 1, softWrap = false) + } + } + } +} diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/NavBar.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/NavBar.kt index 9042e3fe..970feb56 100644 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/NavBar.kt +++ b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/NavBar.kt @@ -7,12 +7,12 @@ import androidx.compose.animation.core.tween import androidx.compose.animation.core.spring import androidx.compose.foundation.Canvas import androidx.compose.foundation.background +import androidx.compose.foundation.clickable import androidx.compose.foundation.border -import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height @@ -33,9 +33,9 @@ import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.unit.Dp import androidx.tv.material3.Text import org.justinvisser.wolfskin.design.WolfskinTokens.Color as C +import org.justinvisser.wolfskin.design.WolfskinTokens.Home as H import org.justinvisser.wolfskin.design.WolfskinTokens.Layout as L import org.justinvisser.wolfskin.design.WolfskinTokens.Shell as S -import org.justinvisser.wolfskin.design.WolfskinTokens.SavedIndicator as V /** Blob bounds retain their measurement while their draw coordinates spring between targets. */ data class NavBox(val left: Dp, val top: Dp, val width: Dp, val height: Dp) @@ -101,11 +101,10 @@ fun NavBar(state: ShellState, scrolled: Boolean, modifier: Modifier = Modifier) } } state.navSavedAt?.let { time -> - Row(Modifier.align(Alignment.TopEnd) - .offset(x = -(L.safeSide + L.navAvatar + L.navItemGap), y = S.navItemTop + (L.navAvatar - V.height) / 2) - .height(V.height).border(V.border, C.warn.copy(alpha = V.borderOpacity), RoundedCornerShape(WolfskinTokens.Radius.button)) - .padding(horizontal = V.side + V.border), horizontalArrangement = Arrangement.spacedBy(V.gap), verticalAlignment = Alignment.CenterVertically) { - Glyph("wifi", C.warn, Modifier.size(V.icon)) + Row(Modifier.align(Alignment.TopEnd).offset(-L.safeSide - L.navAvatar - L.navItemGap, S.navItemTop + (L.navItemHeight - H.savedHeight) / 2) + .height(H.savedHeight).border(H.hairline, C.warn.copy(alpha = .5f), RoundedCornerShape(H.savedRadius)) + .padding(horizontal = H.savedPadding + H.hairline), verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(H.savedGap)) { + Glyph("wifi", C.warn, Modifier.size(H.savedIcon)) Text("Saved $time", color = C.warn, style = WolfskinTokens.Type.caption) } } diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/PersonPage.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/PersonPage.kt deleted file mode 100644 index 011a1d70..00000000 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/PersonPage.kt +++ /dev/null @@ -1,158 +0,0 @@ -package org.justinvisser.wolfskin.design - -import androidx.compose.foundation.background -import androidx.compose.foundation.focusable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.offset -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.foundation.gestures.animateScrollBy -import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.input.key.KeyEventType -import androidx.compose.ui.input.key.onPreviewKeyEvent -import androidx.compose.ui.input.key.type -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.platform.testTag -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.semantics.stateDescription -import androidx.tv.material3.Text -import org.justinvisser.wolfskin.design.WolfskinTokens.Color as C -import org.justinvisser.wolfskin.design.WolfskinTokens.Layout as L -import org.justinvisser.wolfskin.design.WolfskinTokens.Title as D - -/** Filmography retains a real credit key and requests more credits before focus reaches the tail. */ -class PersonState(initialPerson: TitlePerson, initialCredits: List, private val onAction: (TitleAction) -> Unit, private val onReadMore: () -> Unit = {}) { - var person by mutableStateOf(initialPerson) - private set - var credits by mutableStateOf(initialCredits) - var savedAt by mutableStateOf(null) - var toast by mutableStateOf(null) - fun update(actor: TitlePerson, titles: List, saved: String? = null) { - person = actor; credits = titles; savedAt = saved - index = index.coerceAtMost((credits.size - 1).coerceAtLeast(0)) - } - var index by mutableStateOf(0) - private var armed: String? = null - - /** Pointer activation and remote key-up open the same selected credit. */ - fun click(position: Int) { index = position; onAction(TitleAction.OpenTitle(credits[index])) } - - /** The first grid row exits upward into the existing shell nav. */ - fun key(key: ShellKey, down: Boolean, repeat: Int, shell: ShellState): Boolean { - if (credits.isEmpty()) { - if (down && key == ShellKey.Back) onAction(TitleAction.Pop) - else if (down && key == ShellKey.Up) shell.focusNav(shell.currentTab) - return true - } - val columns = WolfskinTokens.Behaviour.gridColumns.toInt() - if (key == ShellKey.Ok) { - if (repeat > 0) return true - if (down) armed = credits[index].id else { if (armed == credits[index].id) click(index); armed = null } - return true - } - if (!down) return true - armed = null - when (key) { - ShellKey.Back -> onAction(TitleAction.Pop) - ShellKey.Up -> if (index < columns) shell.focusNav(shell.currentTab) else index -= columns - ShellKey.Down -> if (index / columns < credits.lastIndex / columns) index = (index + columns).coerceAtMost(credits.lastIndex) - ShellKey.Left -> if (index % columns > 0) index-- - ShellKey.Right -> if (index % columns < columns - 1 && index < credits.lastIndex) index++ - else -> Unit - } - if (index >= credits.size - WolfskinTokens.Behaviour.nextPageCards.toInt()) onReadMore() - return true - } -} - -/** Portrait, biography and the full continuous grid use the shell's remembered frame. */ -@Composable -fun PersonSurface(state: PersonState, shell: ShellState, modifier: Modifier = Modifier) { - val view = shell.view - LaunchedEffect(view, state.savedAt) { view.savedAt = state.savedAt } - val owner = androidx.compose.runtime.remember(shell) { { shell.navFocused = false } } - LaunchedEffect(state) { shell.navFocused = false } - Box(modifier.fillMaxSize().background(C.bg)) { - androidx.compose.runtime.CompositionLocalProvider(LocalTitleFocusOwner provides owner) { - ShellSurface(shell, handlesContentKeys = false) { PersonPage(state, shell, it) } - } - if (!shell.pickerVisible) TitleNotice(state.toast, Modifier.align(Alignment.TopEnd)) { state.toast = null } - } -} - -@Composable -private fun PersonPage(state: PersonState, shell: ShellState, modifier: Modifier = Modifier) { - val density = LocalDensity.current - val list = shell.view.listState - var wheelPending by remember { mutableStateOf(false) } - val columns = WolfskinTokens.Behaviour.gridColumns.toInt() - LaunchedEffect(state.index / columns, shell.navFocused) { - val target = if (shell.navFocused || state.index < columns) 0f - else with(density) { (L.row_phead + L.row_gh + D.gridHeight * (state.index / columns) - L.pinnedLine).toPx() } - val first = list.firstVisibleItemIndex - val before = when (first) { - 0 -> WolfskinTokens.Shell.zero - 1 -> L.row_phead - else -> L.row_phead + L.row_gh + D.gridHeight * (first - 2) - } - val current = with(density) { before.toPx() } + list.firstVisibleItemScrollOffset - if (target != current) list.animateScrollBy(target - current, titleFrameScrollSpec) - } - Box(modifier.testTag("person-page").semantics { stateDescription = "${state.person.id}:${state.index}" } - .titleWheel { wheelPending = true; shell.navFocused = false } - .onPreviewKeyEvent { event -> - val key = readShellKey(event) - if (key != null && key != ShellKey.Back && event.type == KeyEventType.KeyDown && wheelPending) { - val visible = list.layoutInfo.visibleItemsInfo.firstOrNull { it.index >= 2 && it.key != "end-padding" && it.offset + it.size > with(density) { L.pinnedLine.roundToPx() } } - state.index = ((visible?.index?.minus(2) ?: 0) * columns).coerceAtMost((state.credits.size - 1).coerceAtLeast(0)) - wheelPending = false - if (key != ShellKey.Ok) return@onPreviewKeyEvent true - } - key?.let { state.key(it, event.type == KeyEventType.KeyDown, event.nativeKeyEvent.repeatCount, shell) } ?: false - }.focusable()) { - LazyColumn(state = list, modifier = Modifier.fillMaxSize()) { - item(key = "person-header", contentType = "header") { - Box(Modifier.height(L.row_phead)) { - Row(Modifier.offset(L.safeSide, D.personTop), horizontalArrangement = Arrangement.spacedBy(D.personGap), verticalAlignment = Alignment.CenterVertically) { - PersonPortrait(state.person, Modifier.size(L.personPortrait).clip(CircleShape), true) - Column(Modifier.width(L.contentWidth - L.personPortrait - D.personGap)) { - Text(state.person.name, color = C.fg, style = TitleTextStyles.screenTitle, modifier = Modifier.padding(bottom = D.personNameBottom)) - Text("Acting · ${state.credits.size} credit${if (state.credits.size == 1) "" else "s"} among this household’s titles", color = C.muted, style = TitleTextStyles.body) - if (state.person.biography.isNotBlank()) Text(state.person.biography, color = C.dim, style = TitleTextStyles.caption, maxLines = 3) - } - } - } - } - item(key = "filmography", contentType = "header") { - Text("Filmography", color = C.fg, style = TitleTextStyles.rowHeading, modifier = Modifier.height(L.row_gh).padding(start = L.safeSide, top = D.gridHeadingTop)) - } - itemsIndexed(state.credits.chunked(columns), key = { _, row -> row.first().id }, contentType = { _, _ -> "grid" }) { rowIndex, row -> - Row(Modifier.height(D.gridHeight).padding(horizontal = L.safeSide), horizontalArrangement = Arrangement.spacedBy(WolfskinTokens.Card.posterGap)) { - row.forEachIndexed { column, item -> - val index = rowIndex * columns + column - TitlePoster(item, index == state.index && !shell.navFocused, Modifier.width(WolfskinTokens.Card.posterW), catalogue = true, onFocus = { state.index = index }) { state.click(index) } - } - } - } - item(key = "end-padding", contentType = "spacer") { Spacer(Modifier.height(WolfskinTokens.Shell.stageHeight - L.pinnedLine - D.gridHeight)) } - } - } -} diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/ShellSurface.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/ShellSurface.kt index 5eca15da..708d1e3c 100644 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/ShellSurface.kt +++ b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/ShellSurface.kt @@ -9,6 +9,8 @@ import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.remember @@ -32,20 +34,17 @@ import androidx.tv.material3.Text import org.justinvisser.wolfskin.design.WolfskinTokens.Color as C import org.justinvisser.wolfskin.design.WolfskinTokens.Layout as L -/** Screens and the shell interpret the same Android directional and activation keys. */ -fun readShellKey(event: KeyEvent): ShellKey? = when (event.key) { - Key.DirectionUp -> ShellKey.Up - Key.DirectionDown -> ShellKey.Down - Key.DirectionLeft -> ShellKey.Left - Key.DirectionRight -> ShellKey.Right - Key.DirectionCenter, Key.Enter, Key.NumPadEnter -> ShellKey.Ok - Key.Back, Key.Escape -> ShellKey.Back - else -> null -} - /** Map Android key events once, preserving repeat count and key-up semantics. */ fun ShellState.handleKey(event: KeyEvent): Boolean { - val key = readShellKey(event) ?: return false + val key = when (event.key) { + Key.DirectionUp -> ShellKey.Up + Key.DirectionDown -> ShellKey.Down + Key.DirectionLeft -> ShellKey.Left + Key.DirectionRight -> ShellKey.Right + Key.DirectionCenter, Key.Enter, Key.NumPadEnter -> ShellKey.Ok + Key.Back, Key.Escape -> ShellKey.Back + else -> return false + } return this.key(key, event.type == KeyEventType.KeyDown, event.nativeKeyEvent.repeatCount) } diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/SourceRatings.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/SourceRatings.kt deleted file mode 100644 index 018e4a4b..00000000 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/SourceRatings.kt +++ /dev/null @@ -1,107 +0,0 @@ -package org.justinvisser.wolfskin.design - -import androidx.compose.foundation.Image -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.BoxWithConstraints -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.runtime.getValue -import androidx.compose.animation.core.animateFloatAsState -import androidx.compose.animation.core.tween -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.graphics.ColorMatrix -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.platform.testTag -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.rememberTextMeasurer -import androidx.compose.ui.unit.TextUnit -import androidx.compose.ui.unit.TextUnitType -import androidx.tv.material3.Text -import java.util.Locale -import org.justinvisser.wolfskin.design.WolfskinTokens.Color as C -import org.justinvisser.wolfskin.design.WolfskinTokens.Title as D -import org.justinvisser.wolfskin.design.WolfskinTokens.Library as P - -/** A full facts-line set never shrinks or waits for focused-card dwell. */ -@Composable -fun TitleRatings(ratings: List, modifier: Modifier = Modifier, style: TextStyle = WolfskinTokens.Type.ratingPlate, plate: Boolean = false) { - if (ratings.isEmpty()) return - val density = LocalDensity.current - val markHeight = with(density) { style.fontSize.toDp() } - val lineHeight = style.fontSize * (WolfskinTokens.Type.ratingPlate.lineHeight.value / WolfskinTokens.Type.ratingPlate.fontSize.value) - val textStyle = if (style.lineHeight == lineHeight) style else style.copy(lineHeight = lineHeight) - val numberStyle = remember(textStyle) { textStyle.copy(fontFeatureSettings = "tnum", fontWeight = FontWeight.Bold) } - val gap = if (plate) with(density) { (style.fontSize * P.plateGapEm).toDp() } else D.ratingGap - val markGap = if (plate) with(density) { (style.fontSize * P.markGapEm).toDp() } else D.ratingMarkGap - Row(modifier, horizontalArrangement = Arrangement.spacedBy(gap), verticalAlignment = Alignment.CenterVertically) { - ratings.forEach { rating -> - Row(horizontalArrangement = Arrangement.spacedBy(markGap), verticalAlignment = Alignment.CenterVertically) { - val resource = when (rating.source) { - "rtCritics" -> if (rating.label == "Rotten") R.drawable.ic_rotten_tomatoes_rotten else R.drawable.ic_rotten_tomatoes_fresh - "rtAudience" -> if (rating.label == "Spilled") R.drawable.ic_rt_spilled else R.drawable.ic_rt_upright - "imdb" -> R.drawable.ic_rating_imdb - else -> R.drawable.ic_rating_tmdb - } - val unknownCritic = rating.source == "rtCritics" && rating.label != "Fresh" && rating.label != "Certified Fresh" && rating.label != "Rotten" - val desaturated = if (unknownCritic) remember { ColorFilter.colorMatrix(ColorMatrix().apply { setToSaturation(0f) }) } else null - Image(painterResource(resource), rating.source, Modifier.size(markHeight * if (rating.source == "imdb" || rating.source == "tmdb") P.wordmarkRatio else 1f, markHeight), - alpha = if (unknownCritic) P.unknownCriticOpacity else 1f, colorFilter = desaturated) - if (rating.episode) Text("Ep", color = C.muted, style = textStyle.copy(fontWeight = WolfskinTokens.Type.label.fontWeight), modifier = Modifier.exactLineBox(textStyle)) - Text(rating.formatted(), color = C.fg, style = numberStyle, modifier = Modifier.exactLineBox(numberStyle), maxLines = 1) - } - } - } -} - -/** The plate keeps a prefix of the title set, shrinking to the caption floor before dropping its tail. */ -@Composable -fun LibraryRatingPlate(ratings: List, modifier: Modifier = Modifier, visible: Boolean = true) { - if (ratings.isEmpty()) return - val measurer = rememberTextMeasurer() - val density = LocalDensity.current - val alpha by animateFloatAsState(if (visible) 1f else 0f, tween(WolfskinTokens.Motion.base), label = "rating-plate") - BoxWithConstraints(modifier.fillMaxWidth().graphicsLayer { this.alpha = alpha } - .background(Brush.verticalGradient(0f to C.bg.copy(alpha = P.plateOpacity), P.plateMidStop to C.bg.copy(alpha = P.plateMidOpacity), 1f to C.bg.copy(alpha = 0f))) - .testTag("rating-plate").padding(horizontal = P.plateSide)) { - val width = with(density) { maxWidth.toPx() } - val fit = remember(ratings, width, density, Locale.getDefault()) { - var size = WolfskinTokens.Type.ratingPlate.fontSize.value - var count = ratings.size - val numbers = ratings.map { it.formatted() } - fun measured(): Float { - val fontSize = TextUnit(size, TextUnitType.Sp) - val style = WolfskinTokens.Type.ratingPlate.copy(fontSize = fontSize, fontFeatureSettings = "tnum") - val markGap = with(density) { (fontSize * P.markGapEm).toPx() } - val entryGap = with(density) { (fontSize * P.plateGapEm).toPx() } - var total = 0f - for (index in 0 until count) { - val rating = ratings[index] - total += measurer.measure(numbers[index], style, maxLines = 1).size.width - total += with(density) { fontSize.toPx() } * if (rating.source == "imdb" || rating.source == "tmdb") P.wordmarkRatio else 1f - total += markGap - if (rating.episode) total += measurer.measure("Ep", style.copy(fontWeight = WolfskinTokens.Type.label.fontWeight), maxLines = 1).size.width + markGap - if (index > 0) total += entryGap - } - return total - } - while (size > P.plateFloor.fontSize.value && measured() > width) size = (size - P.plateStep).coerceAtLeast(P.plateFloor.fontSize.value) - while (count > 1 && measured() > width) count-- - count to size - } - val fontSize = TextUnit(fit.second, TextUnitType.Sp) - val style = WolfskinTokens.Type.ratingPlate.copy(fontSize = fontSize, - lineHeight = WolfskinTokens.Type.ratingPlate.lineHeight * (fit.second / WolfskinTokens.Type.ratingPlate.fontSize.value)) - TitleRatings(ratings.take(fit.first), modifier = Modifier.exactLineBox(style, top = P.plateTop, bottom = P.plateBottom + P.plateInlineDescent), style = style, plate = true) - } -} diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TextLineBox.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TextLineBox.kt index b21c4dcb..15315f17 100644 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TextLineBox.kt +++ b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TextLineBox.kt @@ -1,10 +1,26 @@ package org.justinvisser.wolfskin.design import androidx.compose.ui.Modifier +import androidx.compose.ui.layout.AlignmentLine +import androidx.compose.ui.layout.FirstBaseline +import androidx.compose.ui.layout.LastBaseline +import androidx.compose.ui.layout.layout import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.unit.Dp -import androidx.compose.ui.unit.TextUnit +import androidx.compose.ui.text.style.LineHeightStyle +import androidx.compose.ui.unit.constrainHeight +import kotlin.math.roundToInt -/** Explicit CSS leading and margins share one fractional layout engine across Wolfskin screens. */ -fun Modifier.exactLineBox(style: TextStyle, top: Dp = WolfskinTokens.Shell.zero, bottom: Dp = WolfskinTokens.Shell.zero): Modifier = - if (style.lineHeight == TextUnit.Unspecified) this else then(CssLineBox(style.lineHeight, top, bottom)) +/** Android's intrinsic paragraph minimum must not enlarge an explicitly untrimmed CSS line box. */ +fun Modifier.exactLineBox(style: TextStyle): Modifier { + if (style.lineHeightStyle?.trim != LineHeightStyle.Trim.None) return this + return layout { measurable, constraints -> + val placeable = measurable.measure(constraints.copy(minHeight = 0)) + val lineHeight = style.lineHeight.toPx() + val first = placeable[FirstBaseline] + val last = placeable[LastBaseline] + val lines = if (first == AlignmentLine.Unspecified || last == AlignmentLine.Unspecified) 1 + else ((last - first) / lineHeight).roundToInt() + 1 + val height = constraints.constrainHeight((lineHeight * lines).roundToInt()) + layout(placeable.width, height) { placeable.placeRelative(0, (height - placeable.height) / 2) } + } +} diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleArtwork.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleArtwork.kt index 1ea37eb4..cfc66a2f 100644 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleArtwork.kt +++ b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleArtwork.kt @@ -1,176 +1,87 @@ package org.justinvisser.wolfskin.design -import androidx.compose.foundation.Image import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.offset -import androidx.compose.foundation.layout.size -import androidx.compose.runtime.Composable import androidx.compose.foundation.layout.padding -import androidx.compose.runtime.compositionLocalOf +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.requiredSize +import androidx.compose.foundation.layout.wrapContentSize +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.runtime.Composable import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.blur import androidx.compose.ui.draw.clip -import androidx.compose.ui.draw.drawWithCache -import androidx.compose.ui.draw.dropShadow -import androidx.compose.ui.graphics.shadow.Shadow -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.layout.layout -import androidx.compose.ui.unit.DpOffset -import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.graphics.ColorMatrix -import androidx.compose.ui.graphics.ShaderBrush -import androidx.compose.ui.graphics.toArgb import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.ui.geometry.Offset -import androidx.compose.ui.unit.Dp import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.ImageBitmap +import androidx.compose.ui.graphics.ColorFilter +import androidx.compose.ui.graphics.ColorMatrix +import androidx.compose.ui.graphics.graphicsLayer import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.Dp import androidx.tv.material3.Text import coil3.compose.AsyncImage import org.justinvisser.wolfskin.design.WolfskinTokens.Color as C -import org.justinvisser.wolfskin.design.WolfskinTokens.Layout as L -import org.justinvisser.wolfskin.design.WolfskinTokens.Title as D +import org.justinvisser.wolfskin.design.WolfskinTokens.Home as H -/** Local decoded fixture art keeps screenshot tests deterministic and completely offline. */ -val LocalTitleBitmaps = compositionLocalOf> { emptyMap() } - -/** Decode at the slot size, with no crossfade or oversized poster allocations. */ +/** Exact decode dimensions and no crossfade keep card focus independent of image work. */ @Composable -fun TitleArtwork(path: String?, width: Int, height: Int, modifier: Modifier = Modifier, poster: Boolean = false, colorFilter: ColorFilter? = null, onError: () -> Unit = {}) { - val bitmap = LocalTitleBitmaps.current[path] - if (bitmap != null) Image(bitmap, null, modifier, contentScale = ContentScale.Crop, colorFilter = colorFilter) - else if (path != null) { - val context = LocalContext.current - val request = remember(context, path, width, height, poster) { - WolfskinImages.request(context, path, width, height, poster) - } - AsyncImage(model = request, imageLoader = WolfskinImages.loader(context), - contentDescription = null, modifier = modifier, contentScale = ContentScale.Crop, colorFilter = colorFilter, onError = { onError() }) +private fun SlotImage(source: String, width: Dp, height: Dp, modifier: Modifier = Modifier, poster: Boolean = false, colorFilter: ColorFilter? = null, onError: () -> Unit = {}) { + val context = LocalContext.current + val request = remember(context, source, width, height, poster) { + WolfskinImages.request(context, source, (width.value * 2).toInt(), (height.value * 2).toInt(), poster) } + AsyncImage(request, imageLoader = WolfskinImages.loader(context), contentDescription = null, modifier = modifier, contentScale = ContentScale.Crop, colorFilter = colorFilter, onError = { onError() }) } -/** Initials follow the same title-hashed hue as the locked art fallback. */ +/** Poster-only landscapes use the upright one-sheet over a dimmed wash of the same image. */ @Composable -fun PersonPortrait(person: TitlePerson, modifier: Modifier = Modifier, large: Boolean = false) { - val initials = remember(person.name) { person.name.split(Regex("\\s+")).filter { it.isNotEmpty() }.take(2).joinToString("") { it.take(1) }.uppercase() } - val size = if (large) (L.personPortrait.value * 2).toInt() else WolfskinTokens.Image.castRequestWidth - Box(modifier.titleFallbackBackground(person.name, D.personFallbackGradient), contentAlignment = Alignment.Center) { - Text(initials, color = D.initialsColor, style = if (large) D.personInitialSize else D.initialSize, textAlign = TextAlign.Center) - if (person.portrait != null) TitleArtwork(person.portrait, size, size, Modifier.fillMaxSize()) +fun TitleArtwork(title: String, type: String, poster: String?, width: Dp, height: Dp, modifier: Modifier = Modifier, + backdrop: String? = null, posterOnly: Boolean = false, landscape: Boolean = false, hero: Boolean = false) { + val source = if (landscape) backdrop ?: poster else poster + val failed = remember(source) { androidx.compose.runtime.mutableStateOf(false) } + val missing = source == null || failed.value + val density = LocalDensity.current + val fallback = if (missing && !hero) remember(title, width, height, density) { + val hue = title.fold(0) { hash, character -> (hash * 31 + character.code) % 360 }.toFloat() + val radians = Math.toRadians(160.0) + val directionX = kotlin.math.sin(radians).toFloat() + val directionY = -kotlin.math.cos(radians).toFloat() + val size = with(density) { Offset(width.toPx(), height.toPx()) } + val extent = size.x * directionX + size.y * directionY + val center = size / 2f + val offset = Offset(directionX * extent / 2f, directionY * extent / 2f) + Brush.linearGradient(listOf(Color.hsl(hue, .22f, .22f), Color.hsl(hue, .26f, .10f)), center - offset, center + offset) + } else null + Box(modifier.then(if (fallback != null) Modifier.background(fallback) else Modifier.background(C.surface2))) { + if (!missing) { + if (landscape && (posterOnly || backdrop == null) && poster != null) { + val wash = remember(hero) { + val matrix = ColorMatrix().apply { setToSaturation(if (hero) 1.2f else 1f) } + val brightness = if (hero) .55f else .5f + for (index in 0 until 15) matrix.values[index] *= brightness + ColorFilter.colorMatrix(matrix) + } + val inset = if (hero) H.heroWashInset else H.cardWashInset + val washModifier = Modifier.wrapContentSize(Alignment.Center, unbounded = true) + .requiredSize(width + inset * 2, height + inset * 2) + .blur(if (hero) H.heroBlur else H.cardBlur) + .graphicsLayer { if (hero) { scaleX = 1.1f; scaleY = 1.1f } } + SlotImage(poster, width, height, washModifier, colorFilter = wash, onError = { failed.value = true }) + val sheetHeight = if (hero) WolfskinTokens.Layout.heroSheetHeight else height - H.cardSheetInset + val sheetWidth = if (hero) WolfskinTokens.Layout.heroSheetWidth else sheetHeight * (2f / 3f) + val sheetModifier = if (hero) Modifier.align(Alignment.TopEnd).offset(-H.heroSheetRight, H.heroSheetTop) else Modifier.offset(H.cardSheetLeft, H.cardSheetTop) + SlotImage(poster, sheetWidth, sheetHeight, sheetModifier.size(sheetWidth, sheetHeight).clip(RoundedCornerShape(if (hero) WolfskinTokens.Radius.heroSheet else WolfskinTokens.Radius.cardSheet)), poster = true, onError = { failed.value = true }) + } else SlotImage(source, if (hero) WolfskinTokens.Card.posterW * 5 else width, if (hero) WolfskinTokens.Card.posterW * 5 * (9f / 16f) else height, Modifier.fillMaxSize(), poster = !landscape, onError = { failed.value = true }) + } else if (!hero) { + Glyph(if (type == "movie") "film" else "nextup", C.fg.copy(alpha = .45f), Modifier.offset(H.cardPadding, H.cardPadding).size(H.artGlyph)) + if (!landscape) Text(title, color = C.fg, style = WolfskinTokens.Type.button, maxLines = 4, modifier = Modifier.align(Alignment.BottomStart).padding(H.cardPadding)) + } else HomeAmbient(Modifier.fillMaxSize()) } } - -/** The original gradient is parsed once so stops stay derived from the canonical token. */ -@Composable -fun TitleBackdrop(item: TitleItem, modifier: Modifier = Modifier) { - val horizontal = remember { - val stops = Regex("rgb\\(7 7 10 / ([.\\d]+)\\) (\\d+)%").findAll(WolfskinTokens.Gradient.detailScrim).take(3) - .map { it.groupValues[2].toFloat() / 100 to C.bg.copy(alpha = it.groupValues[1].toFloat()) }.toList() - Brush.horizontalGradient(*stops.toTypedArray()) - } - val vertical = remember { - val token = WolfskinTokens.Gradient.detailScrim.substringAfter("linear-gradient(0deg,") - val stops = mutableListOf(1f to C.bg) - Regex("rgb\\(7 7 10 / ([.\\d]+)\\) (\\d+)%").findAll(token).forEach { - stops.add(1f - it.groupValues[2].toFloat() / 100 to C.bg.copy(alpha = it.groupValues[1].toFloat())) - } - Brush.verticalGradient(*stops.sortedBy { it.first }.toTypedArray()) - } - Box(modifier.titleAmbientBackground()) { - if (item.backdrop != null && !item.isPosterBackdrop) { - TitleArtwork(item.backdrop, WolfskinTokens.Image.heroRequestWidth, WolfskinTokens.Image.heroRequestHeight, Modifier.fillMaxSize()) - } else if (item.poster != null) { - val filter = remember { - val token = WolfskinTokens.Gradient.heroAmbientFilter - Regex("blur\\(([\\d.]+)px\\).*saturate\\(([\\d.]+)\\).*brightness\\(([\\d.]+)\\)").find(token)!!.groupValues - } - val colorFilter = remember { - val matrix = ColorMatrix().apply { setToSaturation(filter[2].toFloat()) } - for (index in 0 until 15) matrix.values[index] *= filter[3].toFloat() - ColorFilter.colorMatrix(matrix) - } - TitleArtwork(item.poster, WolfskinTokens.Image.heroRequestWidth, WolfskinTokens.Image.heroRequestHeight, - Modifier.fillMaxSize().artOverscan(D.ambientInset).graphicsLayer { scaleX = D.ambientScale; scaleY = D.ambientScale } - .blur(Dp(filter[1].toFloat() / 2)), colorFilter = colorFilter) - val posterShape = remember { RoundedCornerShape(WolfskinTokens.Radius.heroSheet) } - val posterShadow = remember { Shadow(radius = D.posterShadowRadius, offset = DpOffset.Zero.copy(y = D.posterShadowY), color = Color.Black.copy(alpha = D.posterShadowOpacity)) } - TitleArtwork(item.poster, (L.heroSheetWidth.value * 2).toInt(), (L.heroSheetHeight.value * 2).toInt(), - Modifier.offset(WolfskinTokens.Shell.stageWidth - L.heroSheetWidth - D.heroSheetRight, D.heroSheetTop) - .size(L.heroSheetWidth, L.heroSheetHeight).dropShadow(posterShape, posterShadow).clip(posterShape)) - } - Box(Modifier.fillMaxSize().background(horizontal)) - Box(Modifier.fillMaxSize().background(vertical)) - } -} - -/** Library, related and person posters share the exact locked missing-art treatment. */ -@Composable -internal fun MediaArtworkFallback(name: String, movie: Boolean, showTitle: Boolean = true) { - Box(Modifier.fillMaxSize().titleFallbackBackground(name, D.cardFallbackGradient)) { - Glyph(if (movie) "film" else "tv", D.fallbackGlyphColor, Modifier.offset(D.fallbackInset, D.fallbackInset).size(D.fallbackGlyph)) - if (showTitle) Text(name, color = C.fg, style = D.fallbackTitle, maxLines = 4, overflow = TextOverflow.Ellipsis, - modifier = Modifier.align(Alignment.BottomStart).padding(D.fallbackInset)) - } -} - -/** Episode tiles use their backdrop, or the prototype's blurred poster and small one-sheet. */ -@Composable -fun TitleTileArtwork(item: TitleItem) { - Box(Modifier.fillMaxSize()) { - MediaArtworkFallback(item.seriesName ?: item.name, item.kind == "movie", showTitle = false) - if (item.isPosterBackdrop && item.poster != null) { - val filter = remember { ColorFilter.colorMatrix(ColorMatrix().apply { - for (index in 0 until 15) values[index] *= D.tileAmbientBrightness - }) } - TitleArtwork(item.poster, WolfskinTokens.Image.tileRequestWidth, WolfskinTokens.Image.tileRequestHeight, Modifier.fillMaxSize().artOverscan(D.tileAmbientInset).blur(D.tileAmbientBlur), colorFilter = filter) - val height = WolfskinTokens.Card.tileH - D.tileSheetInset * 2 - val shape = remember { RoundedCornerShape(D.tileSheetRadius) } - val shadow = remember { Shadow(radius = D.tileShadowRadius, offset = DpOffset.Zero.copy(y = D.tileShadowY), color = Color.Black.copy(alpha = D.tileShadowOpacity)) } - TitleArtwork(item.poster, (height.value * 2 * 2 / 3).toInt(), (height.value * 2).toInt(), - Modifier.offset(D.tileSheetLeft, D.tileSheetInset).size(height * (2f / 3), height).dropShadow(shape, shadow).clip(shape), poster = true) - } else TitleArtwork(item.backdrop, WolfskinTokens.Image.tileRequestWidth, WolfskinTokens.Image.tileRequestHeight, Modifier.fillMaxSize()) - } -} - -private fun Modifier.artOverscan(inset: Dp): Modifier = layout { measurable, constraints -> - val pixels = inset.roundToPx() - val width = constraints.maxWidth + pixels * 2 - val height = constraints.maxHeight + pixels * 2 - val placeable = measurable.measure(constraints.copy(minWidth = width, maxWidth = width, minHeight = height, maxHeight = height)) - layout(constraints.maxWidth, constraints.maxHeight) { placeable.place(-pixels, -pixels) } -} - -private fun Modifier.titleFallbackBackground(name: String, token: String): Modifier = drawWithCache { - var hue = 0 - name.forEach { hue = (hue * 31 + it.code) % 360 } - val values = Regex("([\\d.]+)%").findAll(token).map { it.groupValues[1].toFloat() / 100 }.toList() - val angle = Math.toRadians(Regex("(\\d+)deg").find(token)!!.groupValues[1].toDouble()) - val dx = kotlin.math.sin(angle).toFloat() - val dy = -kotlin.math.cos(angle).toFloat() - val half = (kotlin.math.abs(size.width * dx) + kotlin.math.abs(size.height * dy)) / 2 - val vector = Offset(dx * half, dy * half) - val middle = Offset(size.width / 2, size.height / 2) - val brush = Brush.linearGradient(listOf(Color.hsl(hue.toFloat(), values[0], values[1]), Color.hsl(hue.toFloat(), values[2], values[3])), - start = middle - vector, end = middle + vector) - onDrawBehind { drawRect(brush) } -} - -private fun Modifier.titleAmbientBackground(): Modifier = drawWithCache { - val values = Regex("([\\d.]+)%").findAll(D.heroAmbientBackground).map { it.groupValues[1].toFloat() / 100 }.toList() - val shader = android.graphics.RadialGradient(0f, 0f, 1f, intArrayOf(C.surface3.toArgb(), C.bg.toArgb()), null, android.graphics.Shader.TileMode.CLAMP) - shader.setLocalMatrix(android.graphics.Matrix().apply { - setScale(size.width * values[0], size.height * values[1]) - postTranslate(size.width * values[2], size.height * values[3]) - }) - val brush = ShaderBrush(shader) - onDrawBehind { drawRect(brush) } -} diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleControl.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleControl.kt deleted file mode 100644 index 4346eae2..00000000 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleControl.kt +++ /dev/null @@ -1,59 +0,0 @@ -package org.justinvisser.wolfskin.design - -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.platform.testTag -import androidx.compose.ui.semantics.Role -import androidx.compose.ui.semantics.contentDescription -import androidx.compose.ui.semantics.role -import androidx.compose.ui.semantics.selected -import androidx.compose.ui.semantics.semantics -import androidx.tv.material3.Text -import org.justinvisser.wolfskin.design.WolfskinTokens.Color as C -import org.justinvisser.wolfskin.design.WolfskinTokens.Layout as L -import org.justinvisser.wolfskin.design.WolfskinTokens.Title as D - -/** Compact title controls reserve captions beneath the whole row, not inside an expanding button. */ -@Composable -fun TitleControl(option: TitleOption, focused: Boolean, modifier: Modifier = Modifier, onFocus: (() -> Unit)? = null, overArtwork: Boolean = true, onClick: () -> Unit) { - val focusOwner = LocalTitleFocusOwner.current - val background = if (option.primary) C.fg else if (overArtwork) { - if (focused) C.titleButtonSecondaryFocused else C.titleButtonSecondary - } else if (focused) C.buttonSecondaryFocused else C.buttonSecondary - val foreground = if (option.primary) C.onFocus else C.fg - val shape = RoundedCornerShape(WolfskinTokens.Radius.button) - val dimensions = if (option.icon) Modifier.size(L.iconButton) else Modifier.height(L.buttonHeight).padding(horizontal = L.buttonPaddingX) - Row(modifier.testTag("title-option-${option.id}").titlePointerFocus(onFocus).focusScale(focused, WolfskinTokens.Focus.scaleControl) - .semantics { if (option.icon) contentDescription = option.label; role = Role.Button; selected = option.on } - .focusRing(focused, WolfskinTokens.Radius.button, WolfskinTokens.Focus.ringButtonGap, WolfskinTokens.Focus.ringButtonRing, C.accent, FocusLift.Button) - .background(background, shape) - .then(if (option.on && !focused) Modifier.border(D.radioBorder, C.accent, shape) else Modifier) - .clickable { focusOwner?.invoke(); onClick() }.then(dimensions), - horizontalArrangement = Arrangement.spacedBy(D.iconGap, Alignment.CenterHorizontally), verticalAlignment = Alignment.CenterVertically) { - if (option.glyph.isNotEmpty()) Glyph(option.glyph, foreground, Modifier.size(if (option.icon) D.iconSize else L.buttonIcon)) - if (!option.icon) Text(option.label, color = foreground, style = WolfskinTokens.Type.button, maxLines = 1) - } -} - - -/** A radio remains visibly selected independently of the inverse focused row. */ -@Composable -fun TitleRadio(selected: Boolean, focused: Boolean) { - val color = if (focused) C.onFocus else C.fg - Box(Modifier.size(D.radioSize).background(if (selected) C.accent else androidx.compose.ui.graphics.Color.Transparent, CircleShape) - .then(if (focused || !selected) Modifier.border(D.radioBorder, color.copy(alpha = if (focused) .5f else .35f), CircleShape) else Modifier), contentAlignment = Alignment.Center) { - if (selected) Box(Modifier.size(D.radioDot).background(C.onFocus, CircleShape)) - } -} diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleHeader.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleHeader.kt deleted file mode 100644 index 6b31174e..00000000 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleHeader.kt +++ /dev/null @@ -1,117 +0,0 @@ -package org.justinvisser.wolfskin.design - -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.boundsInRoot -import androidx.compose.ui.platform.testTag -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.heightIn -import androidx.compose.foundation.layout.offset -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.layout.wrapContentWidth -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.text.buildAnnotatedString -import androidx.compose.ui.text.SpanStyle -import androidx.compose.ui.text.withStyle -import androidx.compose.ui.text.style.TextOverflow -import androidx.tv.material3.Text -import org.justinvisser.wolfskin.design.WolfskinTokens.Color as C -import org.justinvisser.wolfskin.design.WolfskinTokens.Layout as L -import org.justinvisser.wolfskin.design.WolfskinTokens.Title as D - -/** Film, series and episode share one copy block and one fixed options-caption band. */ -@Composable -fun TitleHeader(state: TitleState, active: Boolean, modifier: Modifier = Modifier) { - if (state.data.status == TitleReadStatus.Loading) { TitleHeaderSkeleton(modifier); return } - val item = state.data.item - val type = if (item.kind == "movie") "Movie" else "Series" - CssColumn(modifier.offset(L.safeSide, L.detailCopyTop + D.lineLift).width(L.detailCopyWidth)) { - Row(Modifier.exactLineBox(TitleTextStyles.dLine, bottom = D.lineGap), horizontalArrangement = Arrangement.spacedBy(L.navItemGap), verticalAlignment = Alignment.CenterVertically) { - Glyph(if (item.held) "check" else "sparkle", C.accentText, Modifier.size(D.lineIcon)) - Text(buildString { - append("$type · ${if (item.held) "In your library" else "Not in your library"}") - if (item.held && state.watched) append(" · Watched") - if (!item.held && item.otherOwners.isNotEmpty()) append(" · In ${item.otherOwners.joinToString(" and ")}’s library") - if (state.data.hidden) append(" · Hidden from your picks") - }, color = C.accentText, style = TitleTextStyles.dLine) - } - Text(item.name, color = C.fg, style = TitleTextStyles.displayDetail, maxLines = 2, overflow = TextOverflow.Ellipsis, modifier = Modifier.exactLineBox(TitleTextStyles.displayDetail, bottom = D.titleBottom).testTag("title-heading")) - Row(Modifier.padding(bottom = D.factsBottom).height(D.factsHeight).testTag("title-facts"), horizontalArrangement = Arrangement.spacedBy(D.factsGap), verticalAlignment = Alignment.CenterVertically) { - item.year?.let { Text(it.toString(), color = C.muted, style = TitleTextStyles.body, modifier = Modifier.exactLineBox(TitleTextStyles.body)) } - if (item.kind == "movie" && item.runtimeSeconds > 0) Text(item.runtime, color = C.muted, style = TitleTextStyles.body, modifier = Modifier.exactLineBox(TitleTextStyles.body)) - if (item.kind == "tv" && item.seasons > 0) Text("${item.seasons} season${if (item.seasons == 1) "" else "s"}", color = C.muted, style = TitleTextStyles.body, modifier = Modifier.exactLineBox(TitleTextStyles.body)) - if (state.data.connection != TitleConnection.SignedOut) TitleRatings(item.ratings) - if (item.genres.isNotEmpty()) Text(item.genres.take(3).joinToString(", "), color = C.muted, style = TitleTextStyles.body, modifier = Modifier.exactLineBox(TitleTextStyles.body)) - } - state.data.requestedStage?.let { stage -> - val color = when (stage) { "Ready" -> C.ok; "Failed" -> C.fail; "Downloading", "Almost ready" -> C.accent; else -> C.muted } - Row(Modifier.exactLineBox(TitleTextStyles.dLine, bottom = D.lineGap), horizontalArrangement = Arrangement.spacedBy(L.navItemGap), verticalAlignment = Alignment.CenterVertically) { - Glyph(titleStageGlyph(stage), color, Modifier.size(D.lineIcon)) - Text(stage, color = color, style = TitleTextStyles.label) - Text("for you · by ${state.data.requestActor.orEmpty()}", color = C.muted, style = TitleTextStyles.dLine) - } - } - Text(item.overview, color = C.muted, style = TitleTextStyles.body, maxLines = 3, overflow = TextOverflow.Ellipsis, modifier = Modifier.exactLineBox(TitleTextStyles.body, bottom = D.overviewGap).testTag("title-overview")) - if (!item.held && state.data.connection != TitleConnection.SignedIn) { - Text(if (state.data.connection == TitleConnection.SignedOut) "Requests need this TV to be signed in to Conductarr." else "Requests need Conductarr, and it can’t be reached right now.", - color = C.warn, style = TitleTextStyles.body, modifier = Modifier.exactLineBox(TitleTextStyles.body, bottom = D.overviewGap)) - } - state.data.playTarget?.let { target -> - Row(Modifier.exactLineBox(TitleTextStyles.progress, top = D.progressLift, bottom = D.progressBottom).testTag("title-progress"), horizontalArrangement = Arrangement.spacedBy(D.progressGap), verticalAlignment = Alignment.CenterVertically) { - if (target.resumeSeconds > 0) { - Box(Modifier.size(D.progressWidth, L.progressBar).background(C.progressTrack, RoundedCornerShape(WolfskinTokens.Radius.progress))) { - val fraction = if (target.runtimeSeconds > 0) (target.resumeSeconds.toFloat() / target.runtimeSeconds).coerceIn(0f, 1f) else 0f - Box(Modifier.fillMaxWidth(fraction).fillMaxHeight().background(C.accent)) - } - Text((if (target.kind == "episode") "${target.episodeLabel} · " else "") + "${((target.runtimeSeconds - target.resumeSeconds + 30) / 60).coerceAtLeast(1)} min left", color = C.muted, style = TitleTextStyles.progress) - } else if (target.kind == "episode") Text("Up next: ${target.episodeLabel} · ${target.name}", color = C.muted, style = TitleTextStyles.progress) - if (state.data.connection != TitleConnection.SignedOut) TitleRatings(target.ratings, style = TitleTextStyles.progress) - } - } - Row(Modifier.wrapContentWidth(Alignment.Start, unbounded = true).testTag("title-actions"), horizontalArrangement = Arrangement.spacedBy(L.buttonGap)) { - state.options.forEachIndexed { index, option -> TitleControl(option, active && state.column == index, - Modifier.onGloballyPositioned { state.recordCenter("header", index, it.boundsInRoot().center.x) }, - onFocus = { state.focus("header", index) }) { state.click("header", index) } } - } - if (state.options.any { it.icon }) { - val option = state.options.getOrNull(state.column)?.takeIf { active && it.icon } - Text(buildAnnotatedString { - if (option != null) { - withStyle(SpanStyle(color = C.fg, fontWeight = WolfskinTokens.Type.label.fontWeight)) { append(option.label) } - if (option.note.isNotEmpty()) append(" · ${option.note}") - } - }, color = C.muted, style = D.iconCaption, modifier = Modifier.padding(top = D.captionTop).height(L.iconCaptionLine)) - } - } -} - -/** A no-copy load has no focusable content and never draws a spinner. */ -@Composable -fun TitleHeaderSkeleton(modifier: Modifier = Modifier) { - Column(modifier.offset(L.safeSide, L.detailCopyTop)) { - Box(Modifier.size(D.skeletonKickerWidth, D.skeletonKickerHeight).background(C.surface, RoundedCornerShape(WolfskinTokens.Radius.cardSheet))) - Spacer(Modifier.height(D.skeletonTitleGap)) - Box(Modifier.size(D.skeletonTitleWidth, D.skeletonTitleHeight).background(C.surface, RoundedCornerShape(WolfskinTokens.Radius.card))) - Spacer(Modifier.height(D.skeletonFactsGap)) - Box(Modifier.size(D.skeletonFactsWidth, D.skeletonKickerHeight).background(C.surface, RoundedCornerShape(WolfskinTokens.Radius.cardSheet))) - Spacer(Modifier.height(D.skeletonOverviewGap)) - Box(Modifier.size(D.skeletonOverviewWidth, D.skeletonOverviewHeight).background(C.surface, RoundedCornerShape(WolfskinTokens.Radius.card))) - Spacer(Modifier.height(D.overviewGap)) - Row(horizontalArrangement = Arrangement.spacedBy(L.buttonGap)) { - Box(Modifier.size(D.skeletonPlayWidth, L.buttonHeight).background(C.surface, RoundedCornerShape(WolfskinTokens.Radius.button))) - repeat(2) { Box(Modifier.size(L.iconButton).background(C.surface, RoundedCornerShape(WolfskinTokens.Radius.button))) } - } - } -} diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleModel.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleModel.kt deleted file mode 100644 index 052627dc..00000000 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleModel.kt +++ /dev/null @@ -1,112 +0,0 @@ -package org.justinvisser.wolfskin.design - -import androidx.compose.runtime.Immutable - -/** Screen data is independent of Jellyfin and Conductarr wire objects. */ -@Immutable -data class TitleItem( - override val id: String, - val name: String, - val kind: String, - val year: Int? = null, - val runtimeSeconds: Long = 0, - val seasons: Int = 0, - val overview: String = "", - val genres: List = emptyList(), - override val poster: String? = null, - val backdrop: String? = null, - val held: Boolean = false, - val watched: Boolean = false, - val resumeSeconds: Long = 0, - val seriesId: String? = null, - val seriesName: String? = null, - val season: Int = 0, - val episode: Int = 0, - override val ratings: List = emptyList(), - val character: String? = null, - val otherOwners: List = emptyList(), - val isPosterBackdrop: Boolean = false, -) : PosterContent { - override val posterTitle: String get() = name - override val posterIsMovie: Boolean get() = kind == "movie" - override val progress: Float get() = if (runtimeSeconds > 0) resumeSeconds.toFloat() / runtimeSeconds else 0f - override val badge: String? get() = if (held) "held" else null - val episodeLabel: String get() = "S$season E$episode" - val runtime: String get() { - val minutes = (runtimeSeconds + 30) / 60 - return if (minutes >= 60) "${minutes / 60}h ${minutes % 60}m" else "${minutes}m" - } -} - -/** A cast identity can open a performer page without borrowing a title's identity. */ -@Immutable -data class TitlePerson(val id: String, val name: String, val character: String = "", val portrait: String? = null, val biography: String = "") - -/** Stream indexes remain the server's indexes, including non-contiguous track lists. */ -@Immutable -data class TitleTrack(val index: Int, val label: String, val isDefault: Boolean = false) - -/** Playback options describe the actual play target, not a season or recommendation stub. */ -@Immutable -data class TitleVersion( - val id: String, - val name: String, - val video: String, - val bitrate: String, - val size: String, - val container: String, - val audio: List, - val subtitles: List, -) - -enum class TitleReadStatus { Ready, Loading, Unavailable } -enum class TitleConnection { SignedIn, SignedOut, Offline } -enum class TitleSheet { Version, Tracks, MediaInfo, ConfirmWatched, HiddenReceipt } - -/** A title read includes related titles and the selected season; reads happen outside composition. */ -@Immutable -data class TitlePageData( - val item: TitleItem, - val playTarget: TitleItem? = null, - val watchTarget: TitleItem = item, - val versions: List = emptyList(), - val selectedVersion: String? = null, - val selectedAudio: Int? = null, - val selectedSubtitle: Int = -1, - val trailerUrl: String? = null, - val cast: List = emptyList(), - val castStatus: TitleReadStatus = TitleReadStatus.Ready, - val related: List = emptyList(), - val episodes: List = emptyList(), - val status: TitleReadStatus = TitleReadStatus.Ready, - val connection: TitleConnection = TitleConnection.SignedOut, - val requestedStage: String? = null, - val requestActor: String? = null, - val hidden: Boolean = false, - val pick: Boolean = false, - val savedAt: String? = null, - val seasonNumbers: List = List(item.seasons) { it + 1 }, - val selectedSeason: Int? = null, - val episodesStatus: TitleReadStatus = TitleReadStatus.Ready, -) - -/** Effects are handled by the app's authenticated facade and navigation layer. */ -sealed interface TitleAction { - data class Play(val item: TitleItem, val restart: Boolean = false) : TitleAction - data class Version(val item: TitleItem, val version: TitleVersion) : TitleAction - data class Track(val item: TitleItem, val version: TitleVersion, val audio: Int?, val subtitle: Int) : TitleAction - data class Watched(val item: TitleItem, val watched: Boolean) : TitleAction - data class Trailer(val url: String) : TitleAction - data class Person(val person: TitlePerson) : TitleAction - data class OpenTitle(val item: TitleItem) : TitleAction - data class Season(val number: Int) : TitleAction - data class Request(val item: TitleItem, val forSomeoneElse: Boolean) : TitleAction - data class Hide(val item: TitleItem, val hidden: Boolean) : TitleAction - data class Requests(val item: TitleItem) : TitleAction - data object Retry : TitleAction - data object Pop : TitleAction -} - -/** The options row distinguishes compact icons from labelled primary and secondary pills. */ -@Immutable -data class TitleOption(val id: String, val label: String, val glyph: String, val note: String = "", val primary: Boolean = false, val icon: Boolean = true, val on: Boolean = false) diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleOptionsSheet.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleOptionsSheet.kt deleted file mode 100644 index 3a87dcdd..00000000 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleOptionsSheet.kt +++ /dev/null @@ -1,170 +0,0 @@ -package org.justinvisser.wolfskin.design - -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.focusable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusRequester -import androidx.compose.ui.input.key.KeyEventType -import androidx.compose.ui.input.key.onPreviewKeyEvent -import androidx.compose.ui.input.key.type -import androidx.compose.ui.platform.testTag -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.semantics.stateDescription -import androidx.tv.material3.Text -import androidx.compose.ui.draw.dropShadow -import androidx.compose.ui.graphics.RectangleShape -import androidx.compose.ui.graphics.Color -import androidx.compose.ui.graphics.shadow.Shadow -import androidx.compose.ui.unit.DpOffset -import androidx.compose.ui.layout.layout -import org.justinvisser.wolfskin.design.WolfskinTokens.Color as C -import org.justinvisser.wolfskin.design.WolfskinTokens.Layout as L -import org.justinvisser.wolfskin.design.WolfskinTokens.Title as D - -/** Sheets sit above navigation and consume pointer and key input across the entire scrim. */ -@Composable -fun TitleOptionsSheet(state: TitleState, shell: ShellState) { - val focus = remember { FocusRequester() } - LaunchedEffect(state.sheet) { focus.requestFocus() } - val shadow = remember { Shadow(radius = D.sheetShadowRadius, offset = DpOffset.Zero.copy(x = D.sheetShadowX), color = Color.Black.copy(alpha = D.sheetShadowOpacity)) } - Box(Modifier.fillMaxSize().background(C.sheetScrim).clickable { } - .testTag("title-sheet").semantics { stateDescription = "${state.sheet}:${state.sheetIndex}" } - .focusRequester(focus).onPreviewKeyEvent { event -> - val key = readShellKey(event) - key != null && state.key(key, event.type == KeyEventType.KeyDown, event.nativeKeyEvent.repeatCount, shell) - }.focusable()) { - CssColumn(Modifier.align(Alignment.TopEnd).width(L.sheetWidth).fillMaxHeight().dropShadow(RectangleShape, shadow).background(C.surface) - .verticalScroll(rememberScrollState()).padding(horizontal = D.sheetPaddingSide, vertical = D.sheetPaddingTop), - gap = if (state.sheet == TitleSheet.Tracks) D.trackGap else if (state.sheet == TitleSheet.MediaInfo) D.infoGap else D.sheetGap) { - when (state.sheet) { - TitleSheet.Version -> VersionChoices(state) - TitleSheet.Tracks -> TrackChoices(state) - TitleSheet.MediaInfo -> MediaInformation(state) - TitleSheet.ConfirmWatched -> WatchedConfirmation(state) - TitleSheet.HiddenReceipt -> HiddenReceipt(state) - null -> Unit - } - } - } -} - -@Composable -private fun VersionChoices(state: TitleState) { - Text("Version", color = C.fg, style = TitleTextStyles.sheetTitle, modifier = Modifier.exactLineBox(TitleTextStyles.sheetTitle)) - SheetSubtitle("${state.target?.name ?: state.data.item.name} · ${state.data.versions.size} files") - state.data.versions.forEachIndexed { index, version -> - PlaybackChoice(version.name, listOf(version.video, version.bitrate, version.size).filter { it.isNotBlank() }.joinToString(" · "), version == state.version, state.sheetIndex == index, { state.sheetIndex = index }) { state.clickSheet(index) } - } - Text("Remembered for ${state.person.name} on this title.", color = C.dim, style = TitleTextStyles.caption, modifier = Modifier.exactLineBox(TitleTextStyles.caption)) -} - -@Composable -private fun TrackChoices(state: TitleState) { - val version = state.version ?: return - Text("Audio and subtitles", color = C.fg, style = TitleTextStyles.sheetTitle, modifier = Modifier.exactLineBox(TitleTextStyles.sheetTitle)) - SheetSubtitle("${state.target?.let { if (it.kind == "episode") "${it.seriesName} · ${it.episodeLabel}" else it.name } ?: state.data.item.name} · ${version.name}") - Text("Audio", color = C.dim, style = TitleTextStyles.label, modifier = Modifier.exactLineBox(TitleTextStyles.label, top = D.sheetLabelTop)) - version.audio.forEachIndexed { index, track -> - PlaybackChoice(track.label, null, track.index == state.audio?.index, state.sheetIndex == index, { state.sheetIndex = index }) { state.clickSheet(index) } - } - Text("Subtitles", color = C.dim, style = TitleTextStyles.label, modifier = Modifier.exactLineBox(TitleTextStyles.label, top = D.sheetLabelTop)) - val start = version.audio.size - PlaybackChoice("Off", null, state.subtitleIndex == -1, state.sheetIndex == start, { state.sheetIndex = start }) { state.clickSheet(start) } - version.subtitles.forEachIndexed { index, track -> - val position = start + index + 1 - PlaybackChoice(track.label, null, track.index == state.subtitleIndex, state.sheetIndex == position, { state.sheetIndex = position }) { state.clickSheet(position) } - } - val done = start + version.subtitles.size + 1 - TitleControl(TitleOption("done", "Done", "", primary = true, icon = false), state.sheetIndex == done, Modifier.padding(top = D.sheetButtonTop).sheetFocused(state.sheetIndex == done), onFocus = { state.sheetIndex = done }) { state.clickSheet(done) } -} - -@Composable -private fun PlaybackChoice(label: String, why: String?, selected: Boolean, focused: Boolean, onFocus: () -> Unit, onClick: () -> Unit) { - val foreground = if (focused) C.onFocus else C.fg - val sizing = if (why == null) Modifier.height(D.trackHeight) else Modifier.padding(vertical = D.versionRowVertical) - Row(Modifier.fillMaxWidth().sheetFocused(focused).titlePointerFocus(onFocus).focusScale(focused, WolfskinTokens.Focus.scaleRow) - .background(if (focused) C.fg else C.listRowRest, RoundedCornerShape(WolfskinTokens.Radius.listRow)) - .clickable(onClick = onClick).then(sizing).padding(horizontal = D.sheetRowSide), - horizontalArrangement = Arrangement.spacedBy(D.personGap), verticalAlignment = Alignment.CenterVertically) { - CssColumn(Modifier.weight(1f)) { - Text(label, color = foreground, style = TitleTextStyles.listTitle, modifier = Modifier.exactLineBox(TitleTextStyles.listTitle)) - if (why != null) Text(why, color = foreground.copy(alpha = .8f), style = TitleTextStyles.caption, modifier = Modifier.exactLineBox(TitleTextStyles.caption)) - } - TitleRadio(selected, focused) - } -} - -@Composable -private fun MediaInformation(state: TitleState) { - val version = state.version ?: return - Text("Media info", color = C.fg, style = TitleTextStyles.sheetTitle, modifier = Modifier.exactLineBox(TitleTextStyles.sheetTitle)) - SheetSubtitle(state.target?.let { if (it.kind == "episode") "${it.seriesName} · ${it.episodeLabel}" else it.name } ?: state.data.item.name) - MediaInfoSection("General", listOf("Container" to version.container, "Size" to version.size.ifEmpty { "not known" }, "Bitrate" to version.bitrate, "Runtime" to (state.target?.runtime ?: "not known"))) - MediaInfoSection("Video", listOf("Stream" to version.video)) - MediaInfoSection("Audio", version.audio.mapIndexed { index, track -> "Track ${index + 1}" to (track.label + if (track.isDefault) " (default)" else "") }) - MediaInfoSection("Subtitles", version.subtitles.mapIndexed { index, track -> "Track ${index + 1}" to track.label }) - TitleControl(TitleOption("close", "Close", "", primary = true, icon = false), true, Modifier.padding(top = D.sheetButtonTop).sheetFocused(true), onFocus = { state.sheetIndex = 0 }) { state.clickSheet(0) } -} - -@Composable -private fun MediaInfoSection(label: String, values: List>) { - Text(label, color = C.dim, style = TitleTextStyles.label, modifier = Modifier.exactLineBox(TitleTextStyles.label, top = D.sheetLabelTop)) - CssColumn(gap = D.infoRowGap) { values.forEach { (name, value) -> - Row(Modifier.fillMaxWidth().exactLineBox(TitleTextStyles.caption), horizontalArrangement = Arrangement.spacedBy(D.infoColumnGap)) { - Text(name, color = C.dim, style = TitleTextStyles.infoKey, modifier = Modifier.width(D.infoLabelWidth)) - Text(value, color = C.fg, style = TitleTextStyles.caption) - } - } } -} - -@Composable -private fun WatchedConfirmation(state: TitleState) { - val verb = if (state.watched) "unwatched" else "watched" - Text("Mark the whole series as $verb?", color = C.fg, style = TitleTextStyles.sheetTitle, modifier = Modifier.exactLineBox(TitleTextStyles.sheetTitle)) - SheetSubtitle("Every episode of ${state.data.item.name} changes for ${state.person.name}.") - Row(Modifier.padding(top = D.sheetButtonTop), horizontalArrangement = Arrangement.spacedBy(L.buttonGap)) { - TitleControl(TitleOption("confirm", "Mark as $verb", "", primary = true, icon = false), state.sheetIndex == 0, Modifier.sheetFocused(state.sheetIndex == 0), onFocus = { state.sheetIndex = 0 }) { state.clickSheet(0) } - TitleControl(TitleOption("cancel", "Cancel", "", icon = false), state.sheetIndex == 1, Modifier.sheetFocused(state.sheetIndex == 1), onFocus = { state.sheetIndex = 1 }, overArtwork = false) { state.clickSheet(1) } - } -} - -@Composable -private fun SheetSubtitle(text: String) { - Text(text, color = C.muted, style = TitleTextStyles.body, modifier = Modifier.exactLineBox(TitleTextStyles.body, top = D.sheetSubLift, bottom = D.sheetSubBottom)) -} - -@Composable -private fun HiddenReceipt(state: TitleState) { - Column(Modifier.fillMaxWidth().background(C.listRowRest, RoundedCornerShape(WolfskinTokens.Radius.panel)).padding(horizontal = D.receiptSide, vertical = D.receiptTop), - verticalArrangement = Arrangement.spacedBy(D.receiptGap)) { - Row(horizontalArrangement = Arrangement.spacedBy(D.iconGap), verticalAlignment = Alignment.CenterVertically) { - Glyph("check", C.fg, Modifier.size(D.receiptIcon)) - Text("Hidden from your picks", color = C.fg, style = TitleTextStyles.receiptTitle) - } - Text("${state.data.item.name} leaves every row of ${state.person.name}’s picks. It waits under Hidden picks at the end of Discover.", color = C.muted, style = TitleTextStyles.body) - } - Row(Modifier.padding(top = D.sheetButtonTop), horizontalArrangement = Arrangement.spacedBy(L.buttonGap)) { - TitleControl(TitleOption("undo", "Undo", "", primary = true, icon = false), state.sheetIndex == 0, Modifier.sheetFocused(state.sheetIndex == 0), onFocus = { state.sheetIndex = 0 }) { state.clickSheet(0) } - TitleControl(TitleOption("done", "Done", "", icon = false), state.sheetIndex == 1, Modifier.sheetFocused(state.sheetIndex == 1), onFocus = { state.sheetIndex = 1 }, overArtwork = false) { state.clickSheet(1) } - } -} diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitlePage.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitlePage.kt deleted file mode 100644 index 85f847f5..00000000 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitlePage.kt +++ /dev/null @@ -1,209 +0,0 @@ -package org.justinvisser.wolfskin.design - -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.boundsInRoot -import androidx.compose.foundation.background -import androidx.compose.foundation.border -import androidx.compose.foundation.clickable -import androidx.compose.foundation.focusable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.offset -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.width -import kotlinx.coroutines.delay -import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.derivedStateOf -import androidx.compose.runtime.getValue -import androidx.compose.runtime.remember -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue -import androidx.compose.foundation.gestures.animateScrollBy -import androidx.compose.animation.core.tween -import androidx.compose.animation.core.CubicBezierEasing -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.Modifier -import androidx.compose.ui.Alignment -import androidx.compose.ui.focus.FocusRequester -import androidx.compose.ui.focus.focusRequester -import androidx.compose.ui.input.key.KeyEventType -import androidx.compose.ui.input.key.onPreviewKeyEvent -import androidx.compose.ui.input.key.type -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.platform.testTag -import androidx.compose.ui.semantics.semantics -import androidx.compose.ui.semantics.stateDescription -import androidx.compose.ui.unit.Dp -import androidx.tv.material3.Text -import org.justinvisser.wolfskin.design.WolfskinTokens.Color as C -import org.justinvisser.wolfskin.design.WolfskinTokens.Layout as L -import org.justinvisser.wolfskin.design.WolfskinTokens.Title as D - -/** The shared shell remains authoritative; title sheets overlay it and trap all input. */ -@Composable -fun TitleSurface(state: TitleState, shell: ShellState, modifier: Modifier = Modifier) { - val view = shell.view - LaunchedEffect(view, state.data.savedAt) { view.savedAt = state.data.savedAt } - Box(modifier.fillMaxSize().onPreviewKeyEvent { event -> - // No content target exists during an initial load; nav Down must not enter a skeleton. - if (state.data.status != TitleReadStatus.Loading || shell.pickerVisible || shell.requestsVisible) false - else when (readShellKey(event)) { - ShellKey.Down -> true - ShellKey.Back -> { - if (event.type == KeyEventType.KeyDown && event.nativeKeyEvent.repeatCount == 0) state.back(shell) - true - } - else -> false - } - }) { - val focusOwner = remember(shell) { { shell.navFocused = false } } - androidx.compose.runtime.CompositionLocalProvider(LocalTitleFocusOwner provides focusOwner) { - ShellSurface(shell, handlesContentKeys = false) { TitlePage(state, shell, it) } - } - if (!shell.pickerVisible && state.sheet != null) TitleOptionsSheet(state, shell) - if (!shell.pickerVisible) TitleNotice(state.toast, Modifier.align(Alignment.TopEnd)) { state.toast = null } - } -} - -/** Playback and person reads share one calm, timed notice above the persistent nav. */ -@Composable -internal fun TitleNotice(message: String?, modifier: Modifier = Modifier, onDismiss: () -> Unit) { - LaunchedEffect(message) { - if (message != null) { delay(WolfskinTokens.Motion.toast.toLong()); onDismiss() } - } - if (message != null) RecoveryToast(message, modifier) -} - -/** One keyed vertical frame renders the exact header, season, cast and related order. */ -@Composable -fun TitlePage(state: TitleState, shell: ShellState, modifier: Modifier = Modifier) { - val density = LocalDensity.current - val list = shell.view.listState - var wheelPending by remember { mutableStateOf(false) } - val focus = remember { FocusRequester() } - LaunchedEffect(state.sheet, shell.navFocused, shell.pickerVisible) { - if (state.sheet == null && !shell.navFocused && !shell.pickerVisible) focus.requestFocus() - } - val displayedRows = remember(state.data) { - buildList { - add("header") - if (state.data.status != TitleReadStatus.Ready) return@buildList - if (state.data.item.held && state.data.item.kind == "tv" && state.data.item.seasons > 0) { - add("seasons") - if (state.data.episodesStatus == TitleReadStatus.Loading || state.data.episodes.isNotEmpty()) add("episodes") - } - if (state.data.castStatus == TitleReadStatus.Loading || state.data.cast.isNotEmpty()) add("cast") - if (state.data.related.isNotEmpty()) add("related") - } - } - val rowOffsets = remember(displayedRows, density) { - FloatArray(displayedRows.size + 1).apply { - displayedRows.forEachIndexed { index, row -> this[index + 1] = this[index] + with(density) { titleRowHeight(row).toPx() } } - } - } - val position by remember(list, rowOffsets) { derivedStateOf { - rowOffsets[list.firstVisibleItemIndex.coerceAtMost(rowOffsets.lastIndex)] + list.firstVisibleItemScrollOffset - } } - LaunchedEffect(state.row, shell.navFocused, state.data.status, displayedRows) { - if (state.data.status == TitleReadStatus.Loading) shell.focusNav(shell.currentTab) - val index = if (shell.navFocused) 0 else displayedRows.indexOf(state.row).coerceAtLeast(0) - val y = rowOffsets[index] - val height = with(density) { titleRowHeight(state.row).toPx() } - val target = if (index == 0 || (y < with(density) { L.windowAhead.toPx() } && y + height <= with(density) { (WolfskinTokens.Shell.stageHeight - L.safeTopPicker).toPx() })) 0f - else y - with(density) { L.pinnedLine.toPx() } - if (target != position) list.animateScrollBy(target - position, titleFrameScrollSpec) - } - val dim by remember(rowOffsets, list) { derivedStateOf { (position / D.dimScrollPx).coerceAtMost(D.dimMaximum) } } - val lastVisible by remember(list) { derivedStateOf { list.layoutInfo.visibleItemsInfo.lastOrNull()?.index ?: -1 } } - val nextArtRow = remember(displayedRows, lastVisible) { if (lastVisible < 0) null else displayedRows.drop(lastVisible + 1).firstOrNull { it == "cast" || it == "episodes" || it == "related" } } - TitleRowPrefetch(state.data, nextArtRow) - Box(modifier.focusRequester(focus).testTag("title-page").semantics { stateDescription = "${state.data.item.id}:${state.row}:${state.column}:${state.sheet}" } - .titleWheel { if (state.data.status == TitleReadStatus.Ready) { wheelPending = true; shell.navFocused = false } } - .onPreviewKeyEvent { event -> - val key = readShellKey(event) - if (key != null && key != ShellKey.Back && event.type == KeyEventType.KeyDown && wheelPending) { - val visible = list.layoutInfo.visibleItemsInfo.firstOrNull { - it.key in state.rows && it.offset + it.size > with(density) { L.pinnedLine.roundToPx() } - }?.key as? String ?: "header" - state.focus(visible, state.columns[visible] ?: 0) - wheelPending = false - if (key != ShellKey.Ok) return@onPreviewKeyEvent true - } - key != null && state.key(key, event.type == KeyEventType.KeyDown, event.nativeKeyEvent.repeatCount, shell) - }.focusable()) { - // This remains visible behind the scrolled rows; it is not an off-screen header image. - TitleBackdrop(state.data.item, Modifier.fillMaxSize()) - Box(Modifier.fillMaxSize().graphicsLayer { alpha = dim }.background(C.bg)) - if (state.data.status == TitleReadStatus.Unavailable) TitleReadError(state) - else LazyColumn(state = list, modifier = Modifier.fillMaxSize()) { - displayedRows.forEach { id -> item(key = id, contentType = if (id == "header") "header" else if (id == "seasons") "chips" else "shelf") { - val active = state.row == id && !shell.navFocused && state.sheet == null - when (id) { - "header" -> Box(Modifier.height(L.row_dhead)) { TitleHeader(state, active) } - "seasons" -> TitleSeasons(state, active) - "episodes" -> TitleMediaShelf(state, true, active) - "cast" -> TitleCast(state, active) - "related" -> TitleMediaShelf(state, false, active) - } - } } - item(key = "end-padding", contentType = "spacer") { - Spacer(Modifier.height((WolfskinTokens.Shell.stageHeight - L.pinnedLine - titleRowHeight(displayedRows.last())).coerceAtLeast(D.minimumEndPadding))) - } - } - } -} - -private fun titleRowHeight(row: String): Dp = when (row) { - "header" -> L.row_dhead - "seasons" -> L.row_chips - "episodes" -> L.rowHeadingBand + WolfskinTokens.Card.tileH + L.rowGapAfter - "cast" -> D.castHeight - else -> L.rowHeadingBand + WolfskinTokens.Card.posterH + WolfskinTokens.Card.posterCaptionBand + L.rowGapAfter -} - -@Composable -private fun TitleSeasons(state: TitleState, active: Boolean) { - val focusOwner = LocalTitleFocusOwner.current - androidx.compose.foundation.lazy.LazyRow(Modifier.height(L.row_chips).padding(top = D.chipTop), contentPadding = androidx.compose.foundation.layout.PaddingValues(horizontal = L.safeSide), horizontalArrangement = Arrangement.spacedBy(D.chipGap)) { - items(state.data.seasonNumbers.size, key = { "season-${state.data.seasonNumbers[it]}" }, contentType = { "chip" }) { index -> - val number = state.data.seasonNumbers[index] - val focused = active && state.column == index - val selected = state.season == number - val shape = RoundedCornerShape(WolfskinTokens.Radius.chip) - Box(Modifier.height(D.chipHeight).titlePointerFocus { state.focus("seasons", index) }.focusScale(focused, WolfskinTokens.Focus.scaleControl) - .onGloballyPositioned { state.recordCenter("seasons", index, it.boundsInRoot().center.x) } - .background(if (focused) C.fg else if (selected) C.accentSoft else C.chipRest, shape) - .then(if (selected && !focused) Modifier.border(D.chipBorder, C.accent, shape) else Modifier) - .clickable { focusOwner?.invoke(); state.click("seasons", index) }.padding(horizontal = D.chipPadding), contentAlignment = Alignment.Center) { - Text("Season $number", color = if (focused) C.onFocus else if (selected) C.accentText else C.fg, style = WolfskinTokens.Type.label) - } - } - } -} - -@Composable -private fun TitleReadError(state: TitleState) { - Column(Modifier.offset(L.safeSide, D.errorTop).width(L.stateWidth) - .background(C.surface, RoundedCornerShape(WolfskinTokens.Radius.panel)) - .border(WolfskinTokens.SavedIndicator.border, C.border, RoundedCornerShape(WolfskinTokens.Radius.panel)) - .padding(WolfskinTokens.SavedIndicator.border) - .padding(horizontal = D.errorSide, vertical = D.errorVertical)) { - Row(Modifier.padding(bottom = D.errorHeadingBottom), horizontalArrangement = Arrangement.spacedBy(D.iconGap), verticalAlignment = Alignment.CenterVertically) { - Glyph("alert", C.warn, Modifier.size(D.receiptIcon)) - Text(if (state.data.item.kind == "person") "This person can’t be read" else "This title can’t be read", color = C.fg, style = TitleTextStyles.errorTitle) - } - Text("${if (state.data.connection == TitleConnection.SignedOut) "Jellyfin" else "Conductarr"} didn’t answer, and this TV has no saved copy of the page yet.", color = C.muted, style = TitleTextStyles.body, modifier = Modifier.padding(bottom = D.errorBodyBottom)) - Row(horizontalArrangement = Arrangement.spacedBy(L.buttonGap)) { state.options.forEachIndexed { index, option -> TitleControl(option, state.column == index, onFocus = { state.focus("header", index) }, overArtwork = false) { state.click("header", index) } } } - } -} - -internal val titleFrameScrollSpec = tween(WolfskinTokens.Motion.scroll, easing = CubicBezierEasing(.33f, 1f, .68f, 1f)) diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitlePointer.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitlePointer.kt deleted file mode 100644 index ab763b8a..00000000 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitlePointer.kt +++ /dev/null @@ -1,41 +0,0 @@ -package org.justinvisser.wolfskin.design - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.compositionLocalOf -import androidx.compose.runtime.getValue -import androidx.compose.runtime.rememberUpdatedState -import androidx.compose.ui.Modifier -import androidx.compose.ui.input.pointer.PointerEventType -import androidx.compose.ui.input.pointer.pointerInput - -/** Pointing at owned content exits nav focus through the same shell state as a remote Down. */ -val LocalTitleFocusOwner = compositionLocalOf<(() -> Unit)?> { null } - -/** Hover changes logical focus without activating a button or arming an OK press. */ -@Composable -fun Modifier.titlePointerFocus(onFocus: (() -> Unit)?): Modifier { - if (onFocus == null) return this - val latest by rememberUpdatedState(onFocus) - val owner = LocalTitleFocusOwner.current - return pointerInput(owner) { - awaitPointerEventScope { - while (true) { - val event = awaitPointerEvent() - if (event.type == PointerEventType.Enter) { owner?.invoke(); latest() } - } - } - } -} - -/** Observe wheel input without consuming the frame's native scroll gesture. */ -@Composable -fun Modifier.titleWheel(onScroll: () -> Unit): Modifier { - val latest by rememberUpdatedState(onScroll) - return pointerInput(Unit) { - awaitPointerEventScope { - while (true) { - if (awaitPointerEvent().type == PointerEventType.Scroll) latest() - } - } - } -} diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitlePrefetch.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitlePrefetch.kt deleted file mode 100644 index 641fead0..00000000 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitlePrefetch.kt +++ /dev/null @@ -1,32 +0,0 @@ -package org.justinvisser.wolfskin.design - -import androidx.compose.runtime.Composable -import androidx.compose.runtime.DisposableEffect -import androidx.compose.ui.platform.LocalContext -import coil3.request.Disposable - -/** Read the next hidden art row into the bounded loader, cancelling work when the window changes. */ -@Composable -internal fun TitleRowPrefetch(data: TitlePageData, row: String?) { - val context = LocalContext.current - if (row == null || data.status != TitleReadStatus.Ready) return - if (LocalTitleBitmaps.current.isNotEmpty()) return - val loader = WolfskinImages.loader(context) - DisposableEffect(loader, context, row, data.cast, data.episodes, data.related) { - val requests = ArrayList() - fun queue(path: String?, width: Int, height: Int, poster: Boolean = false) { - if (path != null) requests.add(loader.enqueue(WolfskinImages.request(context, path, width, height, poster))) - } - when (row) { - "cast" -> for (index in 0 until minOf(data.cast.size, WolfskinTokens.Card.personSlots)) - queue(data.cast[index].portrait, WolfskinTokens.Image.castRequestWidth, WolfskinTokens.Image.castRequestHeight) - "episodes" -> for (index in 0 until minOf(data.episodes.size, WolfskinTokens.Card.tileSlots)) { - val item = data.episodes[index] - queue(if (item.isPosterBackdrop) item.poster else item.backdrop, WolfskinTokens.Image.tileRequestWidth, WolfskinTokens.Image.tileRequestHeight) - } - "related" -> for (index in 0 until minOf(data.related.size, WolfskinTokens.Card.posterSlots)) - queue(data.related[index].poster, WolfskinTokens.Image.posterRequestWidth, WolfskinTokens.Image.posterRequestHeight, true) - } - onDispose { requests.forEach { it.dispose() } } - } -} diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleSheetFocus.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleSheetFocus.kt deleted file mode 100644 index d6c46049..00000000 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleSheetFocus.kt +++ /dev/null @@ -1,16 +0,0 @@ -package org.justinvisser.wolfskin.design - -import androidx.compose.foundation.relocation.BringIntoViewRequester -import androidx.compose.foundation.relocation.bringIntoViewRequester -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.runtime.remember -import androidx.compose.ui.Modifier - -/** Logical remote focus must reveal its row even though Android focus stays on the modal owner. */ -@Composable -internal fun Modifier.sheetFocused(focused: Boolean): Modifier { - val request = remember { BringIntoViewRequester() } - LaunchedEffect(focused) { if (focused) request.bringIntoView() } - return bringIntoViewRequester(request) -} diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleShelf.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleShelf.kt deleted file mode 100644 index dcfaadc7..00000000 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleShelf.kt +++ /dev/null @@ -1,166 +0,0 @@ -package org.justinvisser.wolfskin.design - -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.animation.core.tween -import androidx.compose.animation.core.CubicBezierEasing -import androidx.compose.foundation.gestures.animateScrollBy -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.foundation.layout.fillMaxHeight -import androidx.compose.foundation.background -import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.PaddingValues -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.offset -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.width -import androidx.compose.foundation.layout.wrapContentWidth -import androidx.compose.foundation.lazy.LazyRow -import androidx.compose.foundation.lazy.LazyListState -import androidx.compose.ui.layout.onGloballyPositioned -import androidx.compose.ui.layout.boundsInRoot -import androidx.compose.foundation.lazy.itemsIndexed -import androidx.compose.foundation.lazy.rememberLazyListState -import androidx.compose.foundation.shape.CircleShape -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.Brush -import androidx.compose.ui.platform.testTag -import androidx.compose.ui.text.style.TextAlign -import androidx.compose.ui.text.style.TextOverflow -import androidx.compose.ui.zIndex -import androidx.tv.material3.Text -import org.justinvisser.wolfskin.design.WolfskinTokens.Color as C -import org.justinvisser.wolfskin.design.WolfskinTokens.Layout as L -import org.justinvisser.wolfskin.design.WolfskinTokens.Title as D - -/** Cast occupies the first shelf after films, and follows season episodes on series. */ -@Composable -fun TitleCast(state: TitleState, active: Boolean) { - val track = rememberLazyListState() - val focusOwner = LocalTitleFocusOwner.current - val pitch = with(LocalDensity.current) { WolfskinTokens.Card.personPitch.toPx() } - LaunchedEffect(state.column, active) { if (active) track.keepColumnInWindow(state.column, WolfskinTokens.Card.personSlots, pitch) } - Column(Modifier.height(D.castHeight)) { - Text("Cast", color = C.fg, style = WolfskinTokens.Type.rowHeading, modifier = Modifier.padding(start = L.safeSide).height(L.rowHeadingBand)) - LazyRow(state = track, contentPadding = PaddingValues(horizontal = L.safeSide), horizontalArrangement = Arrangement.spacedBy(WolfskinTokens.Card.personGap)) { - if (state.data.castStatus == TitleReadStatus.Loading) { - items(WolfskinTokens.Card.personSlots, key = { "cast-skeleton-$it" }, contentType = { "skeleton" }) { - Box(Modifier.size(L.castCircle).background(C.surface, CircleShape)) - } - } else itemsIndexed(state.data.cast, key = { _, person -> person.id }, contentType = { _, _ -> "person" }) { index, person -> - val focused = active && state.column == index - Box(Modifier.size(WolfskinTokens.Card.personW, WolfskinTokens.Card.personH).zIndex(if (focused) 1f else 0f) - .onGloballyPositioned { state.recordCenter("cast", index, it.boundsInRoot().center.x) } - .titlePointerFocus { state.focus("cast", index) }.focusScale(focused, WolfskinTokens.Focus.scaleCard).clickable { focusOwner?.invoke(); state.click("cast", index) }.testTag("title-cast-${person.id}")) { - PersonPortrait(person, Modifier.size(L.castCircle).focusRing(focused, L.castCircle / 2, WolfskinTokens.Focus.ringCardGap, WolfskinTokens.Focus.ringCardRing, C.accent).clip(CircleShape)) - Column(Modifier.offset(x = -D.castNameSide, y = D.castNameTop).wrapContentWidth(Alignment.Start, unbounded = true).width(L.castCircle + D.castNameSide * 2), horizontalAlignment = Alignment.CenterHorizontally) { - Text(person.name, color = C.fg, style = TitleTextStyles.castName, modifier = Modifier.exactLineBox(TitleTextStyles.castName), maxLines = 1, overflow = TextOverflow.Ellipsis, textAlign = TextAlign.Center) - Text(person.character, color = C.muted, style = TitleTextStyles.caption, modifier = Modifier.exactLineBox(TitleTextStyles.caption), maxLines = 1, overflow = TextOverflow.Ellipsis, textAlign = TextAlign.Center) - } - } - } - } - } -} - -/** Episode and related shelves are lazy, keyed and keep their focused card above adjacent art. */ -@Composable -fun TitleMediaShelf(state: TitleState, episodes: Boolean, active: Boolean) { - val titles = if (episodes) state.data.episodes else state.data.related - val id = if (episodes) "episodes" else "related" - val width = if (episodes) WolfskinTokens.Card.tileW else WolfskinTokens.Card.posterW - val height = if (episodes) WolfskinTokens.Card.tileH else WolfskinTokens.Card.posterH - val track = rememberLazyListState() - val visible = if (episodes) WolfskinTokens.Card.tileSlots else WolfskinTokens.Card.posterSlots - val pitch = with(LocalDensity.current) { (if (episodes) WolfskinTokens.Card.tilePitch else WolfskinTokens.Card.posterPitch).toPx() } - LaunchedEffect(state.column, active) { if (active) track.keepColumnInWindow(state.column, visible, pitch) } - Column(Modifier.height(L.rowHeadingBand + height + L.rowGapAfter + if (episodes) WolfskinTokens.Shell.zero else WolfskinTokens.Card.posterCaptionBand)) { - Text(if (episodes) "Season ${state.season}" else "More like this", color = C.fg, style = WolfskinTokens.Type.rowHeading, modifier = Modifier.padding(start = L.safeSide).height(L.rowHeadingBand)) - LazyRow(state = track, contentPadding = PaddingValues(horizontal = L.safeSide), horizontalArrangement = Arrangement.spacedBy(WolfskinTokens.Card.posterGap)) { - if (episodes && state.data.episodesStatus == TitleReadStatus.Loading) { - items(visible, key = { "episode-skeleton-$it" }, contentType = { "skeleton" }) { - Box(Modifier.size(width, height).background(C.surface, RoundedCornerShape(WolfskinTokens.Radius.card))) - } - } else itemsIndexed(titles, key = { _, item -> item.id }, contentType = { _, _ -> if (episodes) "tile" else "poster" }) { index, item -> - TitlePoster(item, active && state.column == index, Modifier.width(width) - .onGloballyPositioned { state.recordCenter(id, index, it.boundsInRoot().center.x) }, - episodes, state.data.connection != TitleConnection.SignedOut, onFocus = { state.focus(id, index) }) { state.click(id, index) } - } - } - } -} - -/** Posters draw art at rest, with facts only in the reserved focused-caption band. */ -@Composable -fun TitlePoster(item: TitleItem, focused: Boolean, modifier: Modifier = Modifier, tile: Boolean = false, ratingsVisible: Boolean = true, catalogue: Boolean = false, onFocus: (() -> Unit)? = null, onClick: () -> Unit) { - val focusOwner = LocalTitleFocusOwner.current - Column(modifier.zIndex(if (focused) 1f else 0f)) { - if (!tile) { - val bitmaps = LocalTitleBitmaps.current - val offlineArt = androidx.compose.runtime.remember(bitmaps) { if (bitmaps.isEmpty()) null else { path: String -> bitmaps[path] } } - LibraryPoster(item, focused, focused && ratingsVisible, catalogue = catalogue, - modifier = Modifier.titlePointerFocus(onFocus).clickable { focusOwner?.invoke(); onClick() }, offlineArt = offlineArt) - } else Box(Modifier.size(WolfskinTokens.Card.tileW, WolfskinTokens.Card.tileH).titlePointerFocus(onFocus).focusScale(focused, WolfskinTokens.Focus.scaleCard) - .focusRing(focused, WolfskinTokens.Radius.card, WolfskinTokens.Focus.ringCardGap, WolfskinTokens.Focus.ringCardRing, C.accent) - .clip(RoundedCornerShape(WolfskinTokens.Radius.card)).background(C.surface2).clickable { focusOwner?.invoke(); onClick() }) { - TitleTileArtwork(item) - Column(Modifier.align(Alignment.BottomStart).fillMaxWidth().background(Brush.verticalGradient(listOf(C.bg.copy(alpha = 0f), C.bg.copy(alpha = D.cardOverlayOpacity)))) - .padding(start = D.tileOverlaySide, end = D.tileOverlaySide, top = D.tileOverlayTop, bottom = D.tileOverlayBottom)) { - Text(item.seriesName ?: item.name, color = C.fg, style = WolfskinTokens.Type.button, maxLines = 1, overflow = TextOverflow.Ellipsis) - Text("${item.episodeLabel} · ${item.name}", color = C.muted, style = WolfskinTokens.Type.caption, maxLines = 1, overflow = TextOverflow.Ellipsis) - } - val progress = item.progress - if (progress > 0f && progress < 1f) { - Box(Modifier.align(Alignment.BottomCenter).padding(start = D.cardProgressInset, end = D.cardProgressInset, bottom = D.tileProgressBottom) - .fillMaxWidth().height(L.progressBar).clip(RoundedCornerShape(WolfskinTokens.Radius.progress)).background(C.progressTrack)) { - Box(Modifier.fillMaxWidth(progress).fillMaxHeight().background(C.accent)) - } - } - androidx.compose.animation.AnimatedVisibility(focused && ratingsVisible, enter = fadeIn(tween(WolfskinTokens.Motion.base)), exit = fadeOut(tween(WolfskinTokens.Motion.base))) { - LibraryRatingPlate(item.ratings, Modifier.fillMaxWidth()) - } - } - if (!tile) { - val availability = androidx.compose.runtime.remember(item, catalogue) { - if (catalogue) { - if (item.held) "In your library" else item.otherOwners.takeIf { it.isNotEmpty() }?.let { "In ${it.joinToString(" and ")}’s library" } - } else if (item.watched) "Watched" - else if (item.resumeSeconds > 0) "${((item.runtimeSeconds - item.resumeSeconds + 30) / 60).coerceAtLeast(1)} min left" - else null - } - val facts = androidx.compose.runtime.remember(item, availability) { - listOfNotNull(item.character?.takeIf { it.isNotBlank() }?.let { "as $it" }, item.year?.toString(), - if (item.kind == "movie") { if (item.runtimeSeconds > 0) item.runtime else "Movie" } else if (item.seasons > 0) "${item.seasons} season${if (item.seasons == 1) "" else "s"}" else "Series", - availability).joinToString(" · ") - } - Box(Modifier.height(WolfskinTokens.Card.posterCaptionBand)) { - Caption(item.name, facts, focused, Modifier.offset(y = L.captionOffset).wrapContentWidth(Alignment.Start, unbounded = true).width(D.captionWidth), - accentLastFact = availability != null, accentFirstFact = !item.character.isNullOrBlank()) - } - } - } -} - -/** Keep a full lookahead card, but do not recenter a row when reversing direction. */ -private suspend fun LazyListState.keepColumnInWindow(column: Int, slots: Int, pitch: Float) { - val first = firstVisibleItemIndex - val next = when { - column < first -> column - column >= first + slots - 1 -> (column - slots + 2).coerceAtLeast(0) - else -> first - } - if (next != first) animateScrollBy((next - first) * pitch - firstVisibleItemScrollOffset, titleTrackScrollSpec) -} - -private val titleTrackScrollSpec = tween(WolfskinTokens.Motion.base, easing = CubicBezierEasing(.25f, .1f, .25f, 1f)) diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleSlotArtwork.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleSlotArtwork.kt deleted file mode 100644 index 242e0e6b..00000000 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleSlotArtwork.kt +++ /dev/null @@ -1,60 +0,0 @@ -package org.justinvisser.wolfskin.design - -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box -import androidx.compose.foundation.layout.fillMaxSize -import androidx.compose.foundation.layout.offset -import androidx.compose.foundation.layout.requiredSize -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.layout.wrapContentSize -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.draw.blur -import androidx.compose.ui.draw.clip -import androidx.compose.ui.graphics.ColorFilter -import androidx.compose.ui.graphics.ColorMatrix -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.unit.Dp -import org.justinvisser.wolfskin.design.WolfskinTokens.Color as C -import org.justinvisser.wolfskin.design.WolfskinTokens.Home as H - -/** Slot dimensions adapt to the shared exact-pixel artwork request, never another image loader. */ -@Composable -private fun SlotImage(source: String, width: Dp, height: Dp, modifier: Modifier = Modifier, poster: Boolean = false, colorFilter: ColorFilter? = null, onError: () -> Unit = {}) { - TitleArtwork(source, (width.value * 2).toInt(), (height.value * 2).toInt(), modifier, poster, colorFilter, onError) -} - -/** Poster-only landscapes retain the upright one-sheet above the same dimmed image wash. */ -@Composable -fun TitleArtwork(title: String, type: String, poster: String?, width: Dp, height: Dp, modifier: Modifier = Modifier, - backdrop: String? = null, posterOnly: Boolean = false, landscape: Boolean = false, hero: Boolean = false) { - val source = if (landscape) backdrop ?: poster else poster - val failed = remember(source) { androidx.compose.runtime.mutableStateOf(false) } - val missing = source == null || failed.value - Box(modifier.background(C.surface2)) { - if (!missing) { - if (landscape && (posterOnly || backdrop == null) && poster != null) { - val wash = remember(hero) { - val matrix = ColorMatrix().apply { setToSaturation(if (hero) 1.2f else 1f) } - val brightness = if (hero) .55f else .5f - for (index in 0 until 15) matrix.values[index] *= brightness - ColorFilter.colorMatrix(matrix) - } - val inset = if (hero) H.heroWashInset else H.cardWashInset - val washModifier = Modifier.wrapContentSize(Alignment.Center, unbounded = true) - .requiredSize(width + inset * 2, height + inset * 2) - .blur(if (hero) H.heroBlur else H.cardBlur) - .graphicsLayer { if (hero) { scaleX = 1.1f; scaleY = 1.1f } } - SlotImage(poster, width, height, washModifier, colorFilter = wash, onError = { failed.value = true }) - val sheetHeight = if (hero) WolfskinTokens.Layout.heroSheetHeight else height - H.cardSheetInset - val sheetWidth = if (hero) WolfskinTokens.Layout.heroSheetWidth else sheetHeight * (2f / 3f) - val sheetModifier = if (hero) Modifier.align(Alignment.TopEnd).offset(-H.heroSheetRight, H.heroSheetTop) else Modifier.offset(H.cardSheetLeft, H.cardSheetTop) - SlotImage(poster, sheetWidth, sheetHeight, sheetModifier.size(sheetWidth, sheetHeight).clip(RoundedCornerShape(if (hero) WolfskinTokens.Radius.heroSheet else WolfskinTokens.Radius.cardSheet)), poster = true, onError = { failed.value = true }) - } else SlotImage(source, if (hero) WolfskinTokens.Card.posterW * 5 else width, if (hero) WolfskinTokens.Card.posterW * 5 * (9f / 16f) else height, Modifier.fillMaxSize(), poster = !landscape, onError = { failed.value = true }) - } else if (!hero) MediaArtworkFallback(title, type == "movie", showTitle = !landscape) - else HomeAmbient(Modifier.fillMaxSize()) - } -} diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleState.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleState.kt deleted file mode 100644 index c122ec9f..00000000 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleState.kt +++ /dev/null @@ -1,291 +0,0 @@ -package org.justinvisser.wolfskin.design - -import androidx.compose.runtime.getValue -import androidx.compose.runtime.derivedStateOf -import androidx.compose.runtime.mutableStateMapOf -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.setValue - -/** One focus controller drives the drawn screen and Android key-event replays. */ -class TitleState( - initial: TitlePageData, - val person: ShellPerson, - private val onAction: (TitleAction) -> Unit, -) { - var data by mutableStateOf(initial) - private set - var row by mutableStateOf("header") - var column by mutableStateOf(0) - val columns = mutableStateMapOf() - private val centers = HashMap>() - fun recordCenter(row: String, index: Int, x: Float) { centers.getOrPut(row) { HashMap() }[index] = x } - fun showSeasonLoading() { if (data.episodesStatus != TitleReadStatus.Loading) data = data.copy(episodesStatus = TitleReadStatus.Loading) } - fun restoreSeason() { season = data.selectedSeason ?: season; data = data.copy(episodesStatus = TitleReadStatus.Ready) } - var sheet by mutableStateOf(null) - private set - var sheetIndex by mutableStateOf(0) - var season by mutableStateOf(initial.selectedSeason ?: initial.playTarget?.season?.takeIf { it in initial.seasonNumbers } ?: initial.seasonNumbers.firstOrNull() ?: 1) - var versionId by mutableStateOf(initial.selectedVersion) - var audioIndex by mutableStateOf(initial.selectedAudio) - var subtitleIndex by mutableStateOf(initial.selectedSubtitle) - var watched by mutableStateOf(initial.watchTarget.watched) - var toast by mutableStateOf(null) - private var armedCard: String? = null - private var okHeld = false - val target: TitleItem? get() = data.playTarget ?: data.item.takeIf { it.kind == "movie" && it.held } - val version: TitleVersion? get() = data.versions.firstOrNull { it.id == versionId } ?: data.versions.firstOrNull() - val audio: TitleTrack? get() = version?.audio?.firstOrNull { it.index == audioIndex } ?: version?.audio?.firstOrNull { it.isDefault } ?: version?.audio?.firstOrNull() - val subtitle: TitleTrack? get() = version?.subtitles?.firstOrNull { it.index == subtitleIndex } - val rows: List by derivedStateOf { buildList { - add("header") - if (data.status != TitleReadStatus.Ready) return@buildList - if (data.item.held && data.item.kind == "tv" && data.item.seasons > 0) { - add("seasons") - if (data.episodesStatus == TitleReadStatus.Ready && data.episodes.isNotEmpty()) add("episodes") - } - if (data.castStatus == TitleReadStatus.Ready && data.cast.isNotEmpty()) add("cast") - if (data.related.isNotEmpty()) add("related") - } } - val options: List by derivedStateOf { titleOptions(this) } - - /** Refresh keeps the selected row and file when they still exist. */ - fun update(value: TitlePageData) { - val wasLoading = data.status == TitleReadStatus.Loading - val pendingWatched = watched != data.watchTarget.watched - val pendingVersion = versionId != data.selectedVersion - val pendingAudio = audioIndex != data.selectedAudio - val pendingSubtitle = subtitleIndex != data.selectedSubtitle - data = value - if (wasLoading || season !in value.seasonNumbers) season = value.selectedSeason ?: value.playTarget?.season?.takeIf { it in value.seasonNumbers } ?: value.seasonNumbers.firstOrNull() ?: 1 - if (!pendingWatched) watched = value.watchTarget.watched - if (!pendingVersion) versionId = value.selectedVersion - if (!pendingAudio) audioIndex = value.selectedAudio - if (!pendingSubtitle) subtitleIndex = value.selectedSubtitle - if (row !in rows) { row = "header"; column = 0 } - column = column.coerceAtMost(rowSize(row).minus(1).coerceAtLeast(0)) - } - - /** Pointer focus and D-pad use the same row memory. */ - fun focus(targetRow: String, targetColumn: Int) { - columns[row] = column - row = targetRow - column = targetColumn - columns[row] = column - } - /** Pointer clicks activate the same state transition as a completed remote press. */ - fun click(targetRow: String, targetColumn: Int) { - focus(targetRow, targetColumn) - activate() - } - - - /** Keep the last confirmed selections separate from immediate, optimistic UI feedback. */ - fun confirmPlayback(action: TitleAction) { - data = when (action) { - is TitleAction.Version -> data.copy(selectedVersion = action.version.id, selectedAudio = null, selectedSubtitle = -1) - is TitleAction.Track -> data.copy(selectedVersion = action.version.id, selectedAudio = action.audio, selectedSubtitle = action.subtitle) - is TitleAction.Watched -> data.copy(watchTarget = data.watchTarget.copy(watched = action.watched)) - else -> data - } - } - - /** A failed older write cannot undo a newer selection still waiting to save. */ - fun rejectPlayback(action: TitleAction) { - when (action) { - is TitleAction.Version -> if (versionId == action.version.id) { - versionId = data.selectedVersion; audioIndex = data.selectedAudio; subtitleIndex = data.selectedSubtitle - } - is TitleAction.Track -> if (audioIndex == action.audio && subtitleIndex == action.subtitle) { - audioIndex = data.selectedAudio; subtitleIndex = data.selectedSubtitle - } - is TitleAction.Watched -> if (watched == action.watched) watched = data.watchTarget.watched - else -> Unit - } - } - - /** Key-up can only activate the same card that armed the first key-down. */ - fun key(key: ShellKey, down: Boolean, repeat: Int, shell: ShellState): Boolean { - if (key == ShellKey.Ok) { - if (!down) { - okHeld = false - val card = "$row:$column" - if (armedCard == card && sheet == null && !shell.navFocused) activate() - armedCard = null - return true - } - if (repeat > 0 || okHeld) return true - okHeld = true - if (sheet == null && (row == "cast" || row == "related" || row == "episodes")) { - armedCard = "$row:$column" - return true - } - } else { - if (!down) return true - armedCard = null - } - if (sheet != null) { sheetKey(key); return true } - when (key) { - ShellKey.Back -> back(shell) - ShellKey.Up -> if (row == "header") { shell.focusNav(shell.currentTab) } else moveRow(-1) - ShellKey.Down -> moveRow(1) - ShellKey.Left -> focus(row, (column - 1).coerceAtLeast(0)) - ShellKey.Right -> focus(row, (column + 1).coerceAtMost((rowSize(row) - 1).coerceAtLeast(0))) - ShellKey.Ok -> activate() - } - return true - } - - /** Sheets and shell overlays close first; a pushed title/person pops from content or nav. */ - fun back(shell: ShellState) { - when { - sheet != null -> sheet = null - shell.pickerVisible || shell.requestsVisible -> shell.key(ShellKey.Back) - else -> onAction(TitleAction.Pop) - } - } - - /** Pointer selection stays inside the modal's row order. */ - fun clickSheet(index: Int) { sheetIndex = index; sheetKey(ShellKey.Ok) } - - private fun moveRow(delta: Int) { - val index = (rows.indexOf(row) + delta).coerceIn(0, rows.lastIndex) - val next = rows[index] - val x = centers[row]?.get(column) - val nearest = if (x != null) centers[next]?.entries?.minByOrNull { kotlin.math.abs(it.value - x) }?.key else null - focus(next, (columns[next] ?: nearest ?: column).coerceAtMost((rowSize(next) - 1).coerceAtLeast(0))) - } - - private fun rowSize(id: String): Int = when (id) { - "header" -> options.size - "seasons" -> data.seasonNumbers.size - "episodes" -> data.episodes.size - "cast" -> data.cast.size - "related" -> data.related.size - else -> 0 - } - - private fun activate() { - when (row) { - "cast" -> data.cast.getOrNull(column)?.let { onAction(TitleAction.Person(it)) } - "related" -> data.related.getOrNull(column)?.let { onAction(TitleAction.OpenTitle(it)) } - "episodes" -> data.episodes.getOrNull(column)?.let { onAction(TitleAction.OpenTitle(it)) } - "seasons" -> { season = data.seasonNumbers[column]; onAction(TitleAction.Season(season)) } - "header" -> options.getOrNull(column)?.let { activateOption(it.id) } - } - } - - private fun activateOption(id: String) { - when (id) { - "play", "restart" -> target?.let { onAction(TitleAction.Play(it, id == "restart")) } - "version" -> { sheetIndex = data.versions.indexOf(version).coerceAtLeast(0); sheet = TitleSheet.Version } - "tracks" -> { sheetIndex = 0; sheet = TitleSheet.Tracks } - "more" -> { sheetIndex = 0; sheet = TitleSheet.MediaInfo } - "watched" -> if (data.watchTarget.kind == "tv") { sheetIndex = 0; sheet = TitleSheet.ConfirmWatched } else toggleWatched() - "trailer" -> data.trailerUrl?.let { onAction(TitleAction.Trailer(it)) } - "seasons" -> focus("seasons", data.seasonNumbers.indexOf(season).coerceAtLeast(0)) - "retry" -> onAction(TitleAction.Retry) - "back" -> onAction(TitleAction.Pop) - "request", "other", "add" -> onAction(TitleAction.Request(data.item, id != "request")) - "status" -> onAction(TitleAction.Requests(data.item)) - "hide", "unhide" -> { - val hidden = id == "hide" - data = data.copy(hidden = hidden) - onAction(TitleAction.Hide(data.item, hidden)) - if (hidden) { sheetIndex = 0; sheet = TitleSheet.HiddenReceipt } else toast = "Back in your picks." - } - } - } - - private fun toggleWatched() { - watched = !watched - onAction(TitleAction.Watched(data.watchTarget, watched)) - } - - private fun sheetKey(key: ShellKey) { - if (key == ShellKey.Back) { sheet = null; return } - val current = version - val size = when (sheet) { - TitleSheet.Version -> data.versions.size - TitleSheet.Tracks -> (current?.audio?.size ?: 0) + (current?.subtitles?.size ?: 0) + 2 - TitleSheet.ConfirmWatched, TitleSheet.HiddenReceipt -> 2 - else -> 1 - } - when (key) { - ShellKey.Up, ShellKey.Left -> sheetIndex = (sheetIndex - 1).coerceAtLeast(0) - ShellKey.Down, ShellKey.Right -> sheetIndex = (sheetIndex + 1).coerceAtMost(size - 1) - ShellKey.Ok -> when (sheet) { - TitleSheet.Version -> { - val selected = data.versions[sheetIndex] - versionId = selected.id - audioIndex = null - subtitleIndex = -1 - target?.let { onAction(TitleAction.Version(it, selected)) } - sheet = null - } - TitleSheet.Tracks -> if (current != null) selectTrack(current) - TitleSheet.ConfirmWatched -> { if (sheetIndex == 0) toggleWatched(); sheet = null } - TitleSheet.HiddenReceipt -> { - sheet = null - if (sheetIndex == 0) { - data = data.copy(hidden = false) - onAction(TitleAction.Hide(data.item, false)) - } else onAction(TitleAction.Pop) - } - else -> sheet = null - } - } - } - - private fun selectTrack(current: TitleVersion) { - when { - sheetIndex < current.audio.size -> audioIndex = current.audio[sheetIndex].index - sheetIndex == current.audio.size -> subtitleIndex = -1 - sheetIndex <= current.audio.size + current.subtitles.size -> subtitleIndex = current.subtitles[sheetIndex - current.audio.size - 1].index - else -> { sheet = null; return } - } - target?.let { onAction(TitleAction.Track(it, current, audio?.index, subtitleIndex)) } - } -} - -/** Button order follows the file, resume, ownership and authentication facts, never synthetic availability. */ -fun titleOptions(state: TitleState): List = buildList { - val data = state.data - val item = data.item - val target = state.target - if (data.status != TitleReadStatus.Ready) { - if (data.status == TitleReadStatus.Unavailable) { - add(TitleOption("retry", "Try again", "", primary = true, icon = false)) - add(TitleOption("back", "Back", "", icon = false)) - } - return@buildList - } - if (item.held) { - if (target != null) { - val verb = if (target.resumeSeconds > 0) "Resume" else "Play" - add(TitleOption("play", verb + if (target.kind == "episode") " ${target.episodeLabel}" else "", "play", primary = true, icon = false)) - if (target.resumeSeconds > 0) add(TitleOption("restart", "Restart", "restart", "play from the beginning")) - if (data.versions.size > 1) add(TitleOption("version", "Version", "version", state.version?.name.orEmpty())) - add(TitleOption("tracks", "Audio and subtitles", "tracks", "${state.audio?.label.orEmpty()} · subtitles ${state.subtitle?.label ?: "off"}")) - } - val series = data.watchTarget.kind == "tv" - add(TitleOption("watched", "Mark ${if (series) "series " else ""}as ${if (state.watched) "unwatched" else "watched"}", if (state.watched) "eye" else "eyeoff", if (data.watchTarget.kind == "episode") data.watchTarget.episodeLabel else "", on = state.watched)) - if (data.trailerUrl != null) add(TitleOption("trailer", "Play trailer", "trailer")) - if (target != null) add(TitleOption("more", "More", "more", "Media info")) - if (item.kind == "tv" && item.seasons > 0) add(TitleOption("seasons", "Seasons", "tv", icon = false)) - if (data.connection == TitleConnection.SignedIn) add(TitleOption("add", "Add for someone", "users", icon = false)) - } else if (data.connection != TitleConnection.SignedIn) { - add(TitleOption("retry", "Try again", "wifi", primary = true, icon = false)) - } else { - add(TitleOption(if (data.requestedStage == null) "request" else "status", data.requestedStage?.let { "Requested · $it" } ?: "Request", data.requestedStage?.let(::titleStageGlyph) ?: "plus", primary = true, icon = false)) - add(TitleOption("other", "For someone else", "users", icon = false)) - if (data.hidden) add(TitleOption("unhide", "Show again", "undo", icon = false)) - else if (data.pick) add(TitleOption("hide", "Not interested", "eyeoff", icon = false)) - } -} - -internal fun titleStageGlyph(stage: String): String = when (stage) { - "Ready" -> "check" - "Failed" -> "alert" - "Downloading", "Almost ready" -> "download" - else -> "clock" -} diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleTextStyles.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleTextStyles.kt deleted file mode 100644 index 69465238..00000000 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/TitleTextStyles.kt +++ /dev/null @@ -1,25 +0,0 @@ -package org.justinvisser.wolfskin.design - -import androidx.compose.ui.text.TextStyle -import androidx.compose.ui.text.style.LineHeightStyle - -/** Explicit styles retain CSS leading without changing shared nav or library typography. */ -internal object TitleTextStyles { - private val lineBoxes = LineHeightStyle(LineHeightStyle.Alignment.Center, LineHeightStyle.Trim.None) - private fun TextStyle.withLineBoxes() = copy(lineHeightStyle = lineBoxes) - - val displayDetail = WolfskinTokens.Type.displayDetail.withLineBoxes() - val dLine = WolfskinTokens.Title.dLine.withLineBoxes() - val progress = WolfskinTokens.Title.dLine.withLineBoxes() - val castName = WolfskinTokens.Title.castName.withLineBoxes() - val body = WolfskinTokens.Type.body.withLineBoxes() - val caption = WolfskinTokens.Type.caption.withLineBoxes() - val label = WolfskinTokens.Type.label.withLineBoxes() - val sheetTitle = WolfskinTokens.Type.sheetTitle.withLineBoxes() - val listTitle = WolfskinTokens.Type.listTitle.withLineBoxes() - val screenTitle = WolfskinTokens.Type.screenTitle.withLineBoxes() - val rowHeading = WolfskinTokens.Type.rowHeading.withLineBoxes() - val errorTitle = WolfskinTokens.Title.errorTitle.withLineBoxes() - val receiptTitle = WolfskinTokens.Title.receiptTitle.withLineBoxes() - val infoKey = WolfskinTokens.Title.infoKey.withLineBoxes() -} diff --git a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/WolfskinTokens.kt b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/WolfskinTokens.kt index 9cf06f03..77fc5766 100644 --- a/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/WolfskinTokens.kt +++ b/wolfskin-design/src/main/java/org/justinvisser/wolfskin/design/WolfskinTokens.kt @@ -166,31 +166,26 @@ object WolfskinTokens { val posterGap = 12.0.dp val posterPitch = 140.0.dp val posterCaptionBand = 38.0.dp - const val posterSlots = 6 val tileW = 208.0.dp val tileH = 117.0.dp val tileGap = 12.0.dp val tilePitch = 220.0.dp val tileCaptionBand = 0.0.dp - const val tileSlots = 4 val wideW = 280.0.dp val wideH = 157.5.dp val wideGap = 12.0.dp val widePitch = 292.0.dp val wideCaptionBand = 0.0.dp - const val wideSlots = 3 val entryW = 128.0.dp val entryH = 72.0.dp val entryGap = 12.0.dp val entryPitch = 140.0.dp val entryCaptionBand = 0.0.dp - const val entrySlots = 6 val personW = 100.0.dp val personH = 145.0.dp val personGap = 14.0.dp val personPitch = 114.0.dp val personCaptionBand = 0.0.dp - const val personSlots = 7 } object Focus { const val scaleCard = 1.08f @@ -217,20 +212,8 @@ object WolfskinTokens { const val reducedMotion = "all transitions instant" } object Image { - const val posterRequestWidth = 256 - const val posterRequestHeight = 384 - const val tileRequestWidth = 416 - const val tileRequestHeight = 234 - const val wideRequestWidth = 560 - const val wideRequestHeight = 315 - const val heroRequestWidth = 1280 - const val heroRequestHeight = 720 - const val castRequestWidth = 200 - const val castRequestHeight = 200 const val memoryCacheMB = 64.0f const val diskCacheMB = 128.0f - const val concurrentReadsCatalogue = 2 - const val concurrentReadsImage = 4 } object Behaviour { const val rowLimit = 20.0f @@ -354,12 +337,9 @@ object WolfskinTokens { val chipIcon = 13.0.dp val captionWidth = 320.0.dp const val captionSeparatorOpacity = 0.4f - val captionFactsGap = 9.0.dp - val badgeIcon = 14.0.dp val plateTop = 7.0.dp val plateSide = 8.0.dp val plateBottom = 23.0.dp - val plateInlineDescent = 3.3.dp val plateFloor = TextStyle(fontSize = 12.0.sp, fontWeight = FontWeight.Bold, lineHeight = 15.600000000000001.sp, letterSpacing = 0.0.em) const val plateStep = 0.25f const val plateGapEm = 0.64f @@ -386,6 +366,7 @@ object WolfskinTokens { val tailPadding = 10.0.dp val tailGap = 5.0.dp val badgeRing = 1.5.dp + val badgeIcon = 14.0.dp val seeAllGap = 4.0.dp val tailDescription = TextStyle(fontSize = 12.0.sp, fontWeight = FontWeight(500), lineHeight = 15.600000000000001.sp, letterSpacing = 0.0.em) val headerSubtitle = TextStyle(fontSize = 15.0.sp, fontWeight = FontWeight(400), lineHeight = 19.5.sp, letterSpacing = 0.0.em) @@ -414,134 +395,6 @@ object WolfskinTokens { val sheetX = -15.0.dp const val sheetOpacity = 0.5f } - object Title { - val lineGap = 11.0.dp - val lineLift = -2.0.dp - val overviewGap = 17.0.dp - val factsGap = 11.0.dp - val factsBottom = 7.0.dp - val factsHeight = 19.0.dp - val titleBottom = 8.0.dp - val iconGap = 7.0.dp - val iconSize = 16.0.dp - val captionTop = 8.0.dp - val progressWidth = 160.0.dp - val progressBottom = 15.0.dp - val progressGap = 9.0.dp - val progressLift = -7.0.dp - val castHeight = 197.0.dp - val castNameTop = 108.0.dp - val castNameSide = 6.0.dp - val personTop = 85.0.dp - val personGap = 24.0.dp - val personNameBottom = 5.0.dp - val personNoteBottom = 3.0.dp - val captionWidth = 320.0.dp - val sheetPaddingTop = 40.0.dp - val sheetPaddingSide = 32.0.dp - val sheetGap = 9.0.dp - val sheetSubLift = -4.0.dp - val sheetSubBottom = 7.0.dp - val sheetLabelTop = 4.0.dp - val sheetButtonTop = 6.0.dp - val sheetRowSide = 13.0.dp - val versionRowVertical = 10.0.dp - val trackHeight = 42.0.dp - val trackGap = 6.0.dp - val radioSize = 20.0.dp - val radioDot = 8.0.dp - val radioBorder = 1.5.dp - val infoGap = 7.0.dp - val infoLabelWidth = 100.0.dp - val infoRowGap = 3.0.dp - val infoColumnGap = 10.0.dp - val infoKey = TextStyle(fontSize = 12.0.sp, fontWeight = FontWeight.Bold, lineHeight = 15.600000000000001.sp, letterSpacing = 0.0.em) - val gridHeight = 244.0.dp - val minimumEndPadding = 40.0.dp - val ratingGap = 10.0.dp - val ratingMarkGap = 4.0.dp - val initialSize = TextStyle(fontSize = 32.0.sp, fontWeight = FontWeight(800), lineHeight = 41.6.sp, letterSpacing = 0.0.em) - val personInitialSize = TextStyle(fontSize = 48.0.sp, fontWeight = FontWeight(800), lineHeight = 62.400000000000006.sp, letterSpacing = 0.0.em) - const val fallbackHue = 260.0f - val skeletonKickerWidth = 210.0.dp - val skeletonKickerHeight = 17.0.dp - val skeletonTitleGap = 13.0.dp - val skeletonFactsGap = 12.0.dp - val skeletonOverviewGap = 15.0.dp - val skeletonTitleWidth = 380.0.dp - val skeletonTitleHeight = 46.0.dp - val skeletonFactsWidth = 280.0.dp - val skeletonOverviewWidth = 490.0.dp - val skeletonOverviewHeight = 55.0.dp - val skeletonPlayWidth = 110.0.dp - val dLine = TextStyle(fontSize = 13.0.sp, fontWeight = FontWeight(400), lineHeight = 16.900000000000002.sp, letterSpacing = 0.0.em) - val iconCaption = TextStyle(fontSize = 13.0.sp, fontWeight = FontWeight(400), lineHeight = 16.900000000000002.sp, letterSpacing = 0.0.em) - val lineIcon = 14.0.dp - val chipHeight = 34.0.dp - val chipPadding = 14.0.dp - val chipGap = 8.0.dp - val chipTop = 8.0.dp - val chipBorder = 1.0.dp - val heroSheetRight = 90.0.dp - val heroSheetTop = 75.0.dp - val gridHeadingTop = 12.0.dp - val castName = TextStyle(fontSize = 13.0.sp, fontWeight = FontWeight.Bold, lineHeight = 16.900000000000002.sp, letterSpacing = 0.0.em) - val receiptSide = 15.0.dp - val receiptTop = 14.0.dp - val receiptGap = 5.0.dp - val receiptIcon = 18.0.dp - val receiptTitle = TextStyle(fontSize = 18.0.sp, fontWeight = FontWeight.Bold, lineHeight = 23.400000000000002.sp, letterSpacing = 0.0.em) - val toastMaxWidth = 380.0.dp - val toastSide = 14.0.dp - val toastTop = 11.0.dp - const val heroAmbientBackground = "radial-gradient(120% 90% at 70% 20%,var(--surface3),var(--bg))" - const val dimScrollPx = 1400.0f - const val dimMaximum = 0.7f - val errorTop = 85.0.dp - val errorSide = 20.0.dp - val errorVertical = 17.0.dp - val errorHeadingBottom = 4.0.dp - val errorBodyBottom = 12.0.dp - val errorTitle = TextStyle(fontSize = 18.0.sp, fontWeight = FontWeight.Bold, lineHeight = 23.400000000000002.sp, letterSpacing = 0.0.em) - val fallbackGlyph = 22.0.dp - val fallbackInset = 11.0.dp - val tileSheetInset = 9.0.dp - val tileSheetLeft = 11.0.dp - val tileSheetRadius = 5.0.dp - val tileAmbientBlur = 13.0.dp - val tileAmbientInset = 15.0.dp - val tileShadowRadius = 15.0.dp - val tileShadowY = 5.0.dp - const val tileShadowOpacity = 0.5f - const val tileAmbientBrightness = 0.5f - const val cardFallbackGradient = "linear-gradient(160deg,hsl(var(--h) 22% 22%),hsl(var(--h) 26% 10%))" - const val personFallbackGradient = "linear-gradient(160deg,hsl(var(--h) 24% 30%),hsl(var(--h) 26% 14%))" - val initialsColor = ComposeColor(0xD1FFFFFF) - val fallbackGlyphColor = ComposeColor(0x73FFFFFF) - val fallbackTitle = TextStyle(fontSize = 14.0.sp, fontWeight = FontWeight.Bold, lineHeight = 16.099999999999998.sp, letterSpacing = 0.0.em) - val tileOverlayTop = 27.0.dp - val tileOverlaySide = 11.0.dp - val tileOverlayBottom = 9.0.dp - const val cardOverlayOpacity = 0.92f - val cardProgressInset = 9.0.dp - val tileProgressBottom = 5.0.dp - val ambientInset = 40.0.dp - const val ambientScale = 1.1f - val posterShadowRadius = 40.0.dp - val posterShadowY = 15.0.dp - const val posterShadowOpacity = 0.6f - val sheetShadowRadius = 40.0.dp - val sheetShadowX = -15.0.dp - const val sheetShadowOpacity = 0.5f - } - object SavedIndicator { - val height = 26.0.dp - val side = 10.0.dp - val gap = 5.0.dp - val icon = 14.0.dp - val border = 1.0.dp - const val borderOpacity = 0.5f - } object Home { val kickerGap = 6.0.dp val kickerBottom = 5.0.dp diff --git a/wolfskin-design/src/main/res/drawable/title_eyeoff.xml b/wolfskin-design/src/main/res/drawable/title_eyeoff.xml deleted file mode 100644 index 2e70993e..00000000 --- a/wolfskin-design/src/main/res/drawable/title_eyeoff.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/wolfskin-design/src/main/res/drawable/title_more.xml b/wolfskin-design/src/main/res/drawable/title_more.xml deleted file mode 100644 index 5a0c05ff..00000000 --- a/wolfskin-design/src/main/res/drawable/title_more.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/wolfskin-design/src/main/res/drawable/title_restart.xml b/wolfskin-design/src/main/res/drawable/title_restart.xml deleted file mode 100644 index 56b12c0e..00000000 --- a/wolfskin-design/src/main/res/drawable/title_restart.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/wolfskin-design/src/main/res/drawable/title_tracks.xml b/wolfskin-design/src/main/res/drawable/title_tracks.xml deleted file mode 100644 index 2bd8d4ea..00000000 --- a/wolfskin-design/src/main/res/drawable/title_tracks.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/wolfskin-design/src/main/res/drawable/title_trailer.xml b/wolfskin-design/src/main/res/drawable/title_trailer.xml deleted file mode 100644 index b81fba2c..00000000 --- a/wolfskin-design/src/main/res/drawable/title_trailer.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/wolfskin-design/src/main/res/drawable/title_version.xml b/wolfskin-design/src/main/res/drawable/title_version.xml deleted file mode 100644 index 2d6a9570..00000000 --- a/wolfskin-design/src/main/res/drawable/title_version.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/wolfskin-design/src/test/java/org/justinvisser/wolfskin/design/RequestsKeysTest.kt b/wolfskin-design/src/test/java/org/justinvisser/wolfskin/design/RequestsKeysTest.kt index 780a6575..1020f57d 100644 --- a/wolfskin-design/src/test/java/org/justinvisser/wolfskin/design/RequestsKeysTest.kt +++ b/wolfskin-design/src/test/java/org/justinvisser/wolfskin/design/RequestsKeysTest.kt @@ -61,7 +61,7 @@ class RequestsKeysTest { @Test fun readinessWindowAndTitleRoundTripPreserveRequest() { lateinit var state: ShellState - state = sheet { action -> if (action is ShellAction.RequestTitle) state.enterDestination("title/${action.request.mediaType}:${action.request.tmdbId}") } + state = sheet { action -> if (action is ShellAction.RequestTitle) state.enterDestination("request-title/${action.request.tmdbId}") } mount(state) send(Key.DirectionDown, Key.DirectionRight) rule.onNodeWithText("Download · Downloading").assertExists() @@ -76,7 +76,7 @@ class RequestsKeysTest { assertEquals("x6", state.requests.focusedId) send(Key.DirectionCenter) assertFalse(state.requestsVisible) - assertTrue(state.route.startsWith("title/")) + assertTrue(state.route.startsWith("request-title/")) send(Key.Back) rule.onNodeWithTag("coming-row-x6").assertExists() assertEquals("x6", state.requests.focusedId) @@ -123,7 +123,7 @@ class RequestsKeysTest { @Test fun selectingARootAfterARequestTitleDiscardsTheSheetReturnLink() { lateinit var state: ShellState - state = sheet { action -> if (action is ShellAction.RequestTitle) state.enterDestination("title/${action.request.mediaType}:${action.request.tmdbId}") } + state = sheet { action -> if (action is ShellAction.RequestTitle) state.enterDestination("request-title/${action.request.tmdbId}") } mount(state) send(Key.DirectionCenter, Key.DirectionUp, Key.DirectionCenter) assertEquals("home", state.route) diff --git a/wolfskin-design/title-tokens.json b/wolfskin-design/title-tokens.json deleted file mode 100644 index 9f7ad2e6..00000000 --- a/wolfskin-design/title-tokens.json +++ /dev/null @@ -1,130 +0,0 @@ -{ - "title": { - "lineGap": {"dp": 11, "px": 22, "source": "index.html:214"}, - "lineLift": {"dp": -2, "px": -4, "source": "index.html:214"}, - "overviewGap": {"dp": 17, "px": 34, "source": "index.html:216"}, - "factsGap": {"dp": 11, "px": 22, "source": "index.html:104"}, - "factsBottom": {"dp": 7, "px": 14, "source": "index.html:104"}, - "factsHeight": {"dp": 19, "px": 38, "source": "index.html:104 .h-meta minimum height"}, - "titleBottom": {"dp": 8, "px": 16, "source": "index.html:103"}, - "iconGap": {"dp": 7, "px": 14, "source": "index.html:108"}, - "iconSize": {"dp": 16, "px": 32, "source": "index.html:275"}, - "captionTop": {"dp": 8, "px": 16, "source": "index.html:281"}, - "progressWidth": {"dp": 160, "px": 320, "source": "index.html:218"}, - "progressBottom": {"dp": 15, "px": 30, "source": "index.html:217"}, - "progressGap": {"dp": 9, "px": 18, "source": "index.html:217"}, - "progressLift": {"dp": -7, "px": -14, "source": "index.html:217"}, - "castHeight": {"dp": 197, "px": 394, "source": "index.html:1018"}, - "castNameTop": {"dp": 108, "px": 216, "source": "index.html:289"}, - "castNameSide": {"dp": 6, "px": 12, "source": "index.html:289"}, - "personTop": {"dp": 85, "px": 170, "source": "index.html:293"}, - "personGap": {"dp": 24, "px": 48, "source": "index.html:293"}, - "personNameBottom": {"dp": 5, "px": 10, "source": "index.html:296"}, - "personNoteBottom": {"dp": 3, "px": 6, "source": "index.html:297"}, - "captionWidth": {"dp": 320, "px": 640, "source": "index.html:1242"}, - "sheetPaddingTop": {"dp": 40, "px": 80, "source": "index.html:227"}, - "sheetPaddingSide": {"dp": 32, "px": 64, "source": "index.html:227"}, - "sheetGap": {"dp": 9, "px": 18, "source": "index.html:227"}, - "sheetSubLift": {"dp": -4, "px": -8, "source": "index.html:229"}, - "sheetSubBottom": {"dp": 7, "px": 14, "source": "index.html:229"}, - "sheetLabelTop": {"dp": 4, "px": 8, "source": "index.html:230"}, - "sheetButtonTop": {"dp": 6, "px": 12, "source": "index.html:241 .sheet .btn margin-top"}, - "sheetRowSide": {"dp": 13, "px": 26, "source": "index.html:231"}, - "versionRowVertical": {"dp": 10, "px": 20, "source": "index.html:1936"}, - "trackHeight": {"dp": 42, "px": 84, "source": "index.html:1941"}, - "trackGap": {"dp": 6, "px": 12, "source": "index.html:1941"}, - "radioSize": {"dp": 20, "px": 40, "source": "index.html:234"}, - "radioDot": {"dp": 8, "px": 16, "source": "index.html:236"}, - "radioBorder": {"dp": 1.5, "px": 3, "source": "index.html:234"}, - "infoGap": {"dp": 7, "px": 14, "source": "index.html:1948"}, - "infoLabelWidth": {"dp": 100, "px": 200, "source": "index.html:318"}, - "infoRowGap": {"dp": 3, "px": 6, "source": "index.html:318"}, - "infoColumnGap": {"dp": 10, "px": 20, "source": "index.html:318"}, - "infoKey": {"$type": "typography", "sp": 12, "px": 24, "weight": 650, "$value": {"fontWeight": 650}, "source": "index.html:319"}, - "gridHeight": {"dp": 244, "px": 488, "source": "index.html:1019"}, - "minimumEndPadding": {"dp": 40, "px": 80, "source": "index.html:1042"}, - "ratingGap": {"dp": 10, "px": 20, "source": "index.html:156"}, - "ratingMarkGap": {"dp": 4, "px": 8, "source": "index.html:157"}, - "initialSize": {"$type": "typography", "sp": 32, "px": 64, "weight": 800, "$value": {"fontWeight": 800}, "source": "index.html:288"}, - "personInitialSize": {"$type": "typography", "sp": 48, "px": 96, "weight": 800, "$value": {"fontWeight": 800}, "source": "index.html:1317"}, - "fallbackHue": {"$value": 260, "source": "index.html:130"}, - "skeletonKickerWidth": {"dp": 210, "px": 420, "source": "index.html:1322"}, - "skeletonKickerHeight": {"dp": 17, "px": 34, "source": "index.html:1322"}, - "skeletonTitleGap": {"dp": 13, "px": 26, "source": "index.html:1322"}, - "skeletonFactsGap": {"dp": 12, "px": 24, "source": "index.html:1322"}, - "skeletonOverviewGap": {"dp": 15, "px": 30, "source": "index.html:1322"}, - "skeletonTitleWidth": {"dp": 380, "px": 760, "source": "index.html:1322"}, - "skeletonTitleHeight": {"dp": 46, "px": 92, "source": "index.html:1322"}, - "skeletonFactsWidth": {"dp": 280, "px": 560, "source": "index.html:1322"}, - "skeletonOverviewWidth": {"dp": 490, "px": 980, "source": "index.html:1322"}, - "skeletonOverviewHeight": {"dp": 55, "px": 110, "source": "index.html:1322"}, - "skeletonPlayWidth": {"dp": 110, "px": 220, "source": "index.html:1322"}, - "dLine": {"$type": "typography", "sp": 13, "px": 26, "weight": 400, "$value": {"fontWeight": 400}, "source": "index.html:214"}, - "iconCaption": {"$type": "typography", "sp": 13, "px": 26, "weight": 400, "$value": {"fontWeight": 400}, "source": "index.html:281"}, - "lineIcon": {"dp": 14, "px": 28, "source": "index.html:215"}, - "chipHeight": {"dp": 34, "px": 68, "source": "index.html:185"}, - "chipPadding": {"dp": 14, "px": 28, "source": "index.html:185"}, - "chipGap": {"dp": 8, "px": 16, "source": "index.html:184"}, - "chipTop": {"dp": 8, "px": 16, "source": "index.html:184"}, - "chipBorder": {"dp": 1, "px": 2, "source": "index.html:188"}, - "heroSheetRight": {"dp": 90, "px": 180, "source": "index.html:97"}, - "heroSheetTop": {"dp": 75, "px": 150, "source": "index.html:97"}, - "gridHeadingTop": {"dp": 12, "px": 24, "source": "index.html:1312"}, - "castName": {"$type": "typography", "sp": 13, "px": 26, "weight": 700, "$value": {"fontWeight": 700}, "source": "index.html:290"}, - "receiptSide": {"dp": 15, "px": 30, "source": "index.html:243"}, - "receiptTop": {"dp": 14, "px": 28, "source": "index.html:243"}, - "receiptGap": {"dp": 5, "px": 10, "source": "index.html:243"}, - "receiptIcon": {"dp": 18, "px": 36, "source": "index.html:245"}, - "receiptTitle": {"$type": "typography", "sp": 18, "px": 36, "weight": 700, "$value": {"fontWeight": 700}, "source": "index.html:244"}, - "toastMaxWidth": {"dp": 380, "px": 760, "source": "index.html:270"}, - "toastSide": {"dp": 14, "px": 28, "source": "index.html:270"}, - "toastTop": {"dp": 11, "px": 22, "source": "index.html:270"}, - "heroAmbientBackground": {"$type": "gradient", "$value": "radial-gradient(120% 90% at 70% 20%,var(--surface3),var(--bg))", "source": "index.html:94"}, - "dimScrollPx": {"$value": 1400, "source": "index.html:1541"}, - "dimMaximum": {"$value": 0.7, "source": "index.html:1541"}, - "errorTop": {"dp": 85, "px": 170, "source": "index.html:1457,194"}, - "errorSide": {"dp": 20, "px": 40, "source": "index.html:194"}, - "errorVertical": {"dp": 17, "px": 34, "source": "index.html:194"}, - "errorHeadingBottom": {"dp": 4, "px": 8, "source": "index.html:195"}, - "errorBodyBottom": {"dp": 12, "px": 24, "source": "index.html:198"}, - "errorTitle": {"$type": "typography", "sp": 18, "px": 36, "weight": 700, "$value": {"fontWeight": 700}, "source": "index.html:195"}, - "fallbackGlyph": {"dp": 22, "px": 44, "source": "index.html:131"}, - "fallbackInset": {"dp": 11, "px": 22, "source": "index.html:130-131"}, - "tileSheetInset": {"dp": 9, "px": 18, "source": "index.html:128"}, - "tileSheetLeft": {"dp": 11, "px": 22, "source": "index.html:128"}, - "tileSheetRadius": {"dp": 5, "px": 10, "source": "index.html:128"}, - "tileAmbientBlur": {"dp": 13, "px": 26, "source": "index.html:129"}, - "tileAmbientInset": {"dp": 15, "px": 30, "source": "index.html:129"}, - "tileShadowRadius": {"dp": 15, "px": 30, "source": "index.html:128"}, - "tileShadowY": {"dp": 5, "px": 10, "source": "index.html:128"}, - "tileShadowOpacity": {"$value": 0.5, "source": "index.html:128"}, - "tileAmbientBrightness": {"$value": 0.5, "source": "index.html:129"}, - "cardFallbackGradient": {"$type": "gradient", "$value": "linear-gradient(160deg,hsl(var(--h) 22% 22%),hsl(var(--h) 26% 10%))", "source": "index.html:130"}, - "personFallbackGradient": {"$type": "gradient", "$value": "linear-gradient(160deg,hsl(var(--h) 24% 30%),hsl(var(--h) 26% 14%))", "source": "index.html:288"}, - "initialsColor": {"$type": "color", "$value": "#ffffffd1", "source": "index.html:288"}, - "fallbackGlyphColor": {"$type": "color", "$value": "#ffffff73", "source": "index.html:131"}, - "fallbackTitle": {"$type": "typography", "sp": 14, "px": 28, "weight": 700, "lineHeight": 1.15, "$value": {"fontWeight": 700}, "source": "index.html:132"}, - "tileOverlayTop": {"dp": 27, "px": 54, "source": "index.html:135"}, - "tileOverlaySide": {"dp": 11, "px": 22, "source": "index.html:135"}, - "tileOverlayBottom": {"dp": 9, "px": 18, "source": "index.html:135"}, - "cardOverlayOpacity": {"$value": 0.92, "source": "index.html:135"}, - "cardProgressInset": {"dp": 9, "px": 18, "source": "index.html:138"}, - "tileProgressBottom": {"dp": 5, "px": 10, "source": "index.html:140"}, - "ambientInset": {"dp": 40, "px": 80, "source": "index.html:96"}, - "ambientScale": {"$value": 1.1, "source": "index.html:96"}, - "posterShadowRadius": {"dp": 40, "px": 80, "source": "index.html:97"}, - "posterShadowY": {"dp": 15, "px": 30, "source": "index.html:97"}, - "posterShadowOpacity": {"$value": 0.6, "source": "index.html:97"}, - "sheetShadowRadius": {"dp": 40, "px": 80, "source": "index.html:227"}, - "sheetShadowX": {"dp": -15, "px": -30, "source": "index.html:227"}, - "sheetShadowOpacity": {"$value": 0.5, "source": "index.html:227"} - }, - "savedIndicator": { - "height": {"dp": 26, "px": 52, "source": "index.html:87"}, - "side": {"dp": 10, "px": 20, "source": "index.html:87"}, - "gap": {"dp": 5, "px": 10, "source": "index.html:87"}, - "icon": {"dp": 14, "px": 28, "source": "index.html:88"}, - "border": {"dp": 1, "px": 2, "source": "index.html:87"}, - "borderOpacity": {"$value": 0.5, "source": "index.html:87"} - } -} diff --git a/wolfskin-design/tokens.css b/wolfskin-design/tokens.css index 4d3f3488..4eb2ef47 100644 --- a/wolfskin-design/tokens.css +++ b/wolfskin-design/tokens.css @@ -222,12 +222,9 @@ --library-chipTop: 16.0px; --library-chipIcon: 26.0px; --library-captionWidth: 640.0px; - --library-captionFactsGap: 18.0px; - --library-badgeIcon: 28.0px; --library-plateTop: 14.0px; --library-plateSide: 16.0px; --library-plateBottom: 46.0px; - --library-plateInlineDescent: 6.6px; --library-plateFloor: 24.0px; --library-railWidth: 52.0px; --library-railLetterHeight: 30.0px; @@ -246,6 +243,7 @@ --library-tailPadding: 20.0px; --library-tailGap: 10.0px; --library-badgeRing: 3.0px; + --library-badgeIcon: 28.0px; --library-seeAllGap: 8.0px; --library-tailDescription: 24.0px; --library-headerSubtitle: 30.0px; @@ -259,120 +257,6 @@ --lift-heroY: 30.0px; --lift-sheetBlur: 80.0px; --lift-sheetX: -30.0px; - --title-lineGap: 22.0px; - --title-lineLift: -4.0px; - --title-overviewGap: 34.0px; - --title-factsGap: 22.0px; - --title-factsBottom: 14.0px; - --title-factsHeight: 38.0px; - --title-titleBottom: 16.0px; - --title-iconGap: 14.0px; - --title-iconSize: 32.0px; - --title-captionTop: 16.0px; - --title-progressWidth: 320.0px; - --title-progressBottom: 30.0px; - --title-progressGap: 18.0px; - --title-progressLift: -14.0px; - --title-castHeight: 394.0px; - --title-castNameTop: 216.0px; - --title-castNameSide: 12.0px; - --title-personTop: 170.0px; - --title-personGap: 48.0px; - --title-personNameBottom: 10.0px; - --title-personNoteBottom: 6.0px; - --title-captionWidth: 640.0px; - --title-sheetPaddingTop: 80.0px; - --title-sheetPaddingSide: 64.0px; - --title-sheetGap: 18.0px; - --title-sheetSubLift: -8.0px; - --title-sheetSubBottom: 14.0px; - --title-sheetLabelTop: 8.0px; - --title-sheetButtonTop: 12.0px; - --title-sheetRowSide: 26.0px; - --title-versionRowVertical: 20.0px; - --title-trackHeight: 84.0px; - --title-trackGap: 12.0px; - --title-radioSize: 40.0px; - --title-radioDot: 16.0px; - --title-radioBorder: 3.0px; - --title-infoGap: 14.0px; - --title-infoLabelWidth: 200.0px; - --title-infoRowGap: 6.0px; - --title-infoColumnGap: 20.0px; - --title-infoKey: 24.0px; - --title-gridHeight: 488.0px; - --title-minimumEndPadding: 80.0px; - --title-ratingGap: 20.0px; - --title-ratingMarkGap: 8.0px; - --title-initialSize: 64.0px; - --title-personInitialSize: 96.0px; - --title-skeletonKickerWidth: 420.0px; - --title-skeletonKickerHeight: 34.0px; - --title-skeletonTitleGap: 26.0px; - --title-skeletonFactsGap: 24.0px; - --title-skeletonOverviewGap: 30.0px; - --title-skeletonTitleWidth: 760.0px; - --title-skeletonTitleHeight: 92.0px; - --title-skeletonFactsWidth: 560.0px; - --title-skeletonOverviewWidth: 980.0px; - --title-skeletonOverviewHeight: 110.0px; - --title-skeletonPlayWidth: 220.0px; - --title-dLine: 26.0px; - --title-iconCaption: 26.0px; - --title-lineIcon: 28.0px; - --title-chipHeight: 68.0px; - --title-chipPadding: 28.0px; - --title-chipGap: 16.0px; - --title-chipTop: 16.0px; - --title-chipBorder: 2.0px; - --title-heroSheetRight: 180.0px; - --title-heroSheetTop: 150.0px; - --title-gridHeadingTop: 24.0px; - --title-castName: 26.0px; - --title-receiptSide: 30.0px; - --title-receiptTop: 28.0px; - --title-receiptGap: 10.0px; - --title-receiptIcon: 36.0px; - --title-receiptTitle: 36.0px; - --title-toastMaxWidth: 760.0px; - --title-toastSide: 28.0px; - --title-toastTop: 22.0px; - --title-heroAmbientBackground: radial-gradient(120% 90% at 70% 20%,var(--surface3),var(--bg)); - --title-errorTop: 170.0px; - --title-errorSide: 40.0px; - --title-errorVertical: 34.0px; - --title-errorHeadingBottom: 8.0px; - --title-errorBodyBottom: 24.0px; - --title-errorTitle: 36.0px; - --title-fallbackGlyph: 44.0px; - --title-fallbackInset: 22.0px; - --title-tileSheetInset: 18.0px; - --title-tileSheetLeft: 22.0px; - --title-tileSheetRadius: 10.0px; - --title-tileAmbientBlur: 26.0px; - --title-tileAmbientInset: 30.0px; - --title-tileShadowRadius: 30.0px; - --title-tileShadowY: 10.0px; - --title-cardFallbackGradient: linear-gradient(160deg,hsl(var(--h) 22% 22%),hsl(var(--h) 26% 10%)); - --title-personFallbackGradient: linear-gradient(160deg,hsl(var(--h) 24% 30%),hsl(var(--h) 26% 14%)); - --title-initialsColor: #ffffffd1; - --title-fallbackGlyphColor: #ffffff73; - --title-fallbackTitle: 28.0px; - --title-tileOverlayTop: 54.0px; - --title-tileOverlaySide: 22.0px; - --title-tileOverlayBottom: 18.0px; - --title-cardProgressInset: 18.0px; - --title-tileProgressBottom: 10.0px; - --title-ambientInset: 80.0px; - --title-posterShadowRadius: 80.0px; - --title-posterShadowY: 30.0px; - --title-sheetShadowRadius: 80.0px; - --title-sheetShadowX: -30.0px; - --savedIndicator-height: 52.0px; - --savedIndicator-side: 20.0px; - --savedIndicator-gap: 10.0px; - --savedIndicator-icon: 28.0px; - --savedIndicator-border: 2.0px; --home-kickerGap: 12.0px; --home-kickerBottom: 10.0px; --home-titleBottom: 16.0px; diff --git a/wolfskin-design/tokens.sha256 b/wolfskin-design/tokens.sha256 index ba5f6201..d3bc9970 100644 --- a/wolfskin-design/tokens.sha256 +++ b/wolfskin-design/tokens.sha256 @@ -1,8 +1,7 @@ 1f22175c1ce3987c4efa14d573601641a61e1a915e2c464c943b6c400356adb4 discover-tokens.json -85109c394255f6120a621fbefe8e58df82832974ccd6a6a975a61567f641ea2a generate_tokens.py +a934faf6ce6972371455b51c18be7278e4f3d9daf6e1c32e230542a09ddb94c6 generate_tokens.py 25985087986a46f00e2819917d0421ff2b437ec21c54f6ce6412b84c0eb05302 home-tokens.json -be3af0ddcb0d67abef0805d19d7a33cdb55428bcace656b50f0a38935f212028 shell-tokens.json -1c805ae8eacbca1c63fbf91e19d7f9fea6c27b54e709e91f6bd46720d5048a41 src/main/java/org/justinvisser/wolfskin/design/WolfskinTokens.kt -7ed093cc63b0fd6f47fe951da5df26ee7258865b8d0a51345a408ab64f037de0 title-tokens.json -3b14b60264e1f97c02be3e57d0c0bd9477e982044ee944c8c8a5b71e939fa8fb tokens.css +1dcf1136efaf0eb0cda4ab93266abe32d68325c63d7a967d7edb66f6ccd64f29 shell-tokens.json +9bf7d34cd27f4156d7adc10911f0b28a5d77e41a1adc1618ee0dd7b302c86ca3 src/main/java/org/justinvisser/wolfskin/design/WolfskinTokens.kt +22c2a522d892e0751c8bc1bad7364cc3c2e19d3b73cc523dbaa8087d54727b6c tokens.css 5b939f1f3eb90b428008fda75720f6e3a4e844c486668931db3d52bffb987b53 tokens.json