An ATproto social media client -- with an independent Appview.

Merge main into the Web PR (#230)

* Update to RN 71.1.0 (#100)

* Update to RN 71

* Adds missing lint plugin

* Add missing native changes

* Bump @atproto/api@0.0.7 (#112)

* Image not loading on swipe (#114)

* Adds prefetching to images

* Adds image prefetch

* bugfix for images not showing on swipe

* Fixes prefetch bug

* Update src/view/com/util/PostEmbeds.tsx

---------

Co-authored-by: Paul Frazee <pfrazee@gmail.com>

* Fixes to session management (#117)

* Update session-management to solve incorrectly dropped sessions

* Reset the nav on account switch

* Reset the feed on me.load()

* Update tests to reflect new account-switching behavior

* Increase max image resolutions and sizes (#118)

* Slightly increase the hitslop for post controls

* Fix character counter color in dark mode

* Update login to use new session.create api, which enables email login (close #93) (#119)

* Replaces the alert with dropdown for profile image and banner (#123)

* replaces the alert with dropdown for profile image and banner

* lint

* Fix to ordering of images in the embed grid (#121)

* Add explicit link-embed controls to the composer (#120)

* Add explicit link-embed controls

* Update the target rez/size of link embed thumbs

* Remove the alert before publishing without a link card

* [Draft] Fixes image failing on reupload issue (#128)

* Fixes image failing on reupload issue

* Use tmp folder instead of documents

* lint

* Image performance improvements (#126)

* Switch out most images for FastImage

* Add image loading placeholders

* Fix tests

* Collection of fixes to list rendering (#127)

* Fix bug that caused endless spinners in profile feeds

* Bundle fetches of suggested actors into one update

* Fixes to suggested follow rendering

* Fix missing replacement of flex:1 to height:100

* Fixes to navigation swipes (#129)

* Nav swipe: increase the distance traveled in response to gesture movement.

This causes swipes to feel faster and more responsive.

* Fix: fully clamp the swipe against the edge

* Improve the performance of swipes by skipping the interaction manager

* Adds dark mode to the edit screen (#130)

* Adds dark mode to edit screen

* lint

* lint

* lint

* Reduce render cost of post controls and improve perceived responsiveness (#132)

* Move post control animations into conditional render and increase perceived responsiveness

* Remove log

* Adds dark mode to the dropdown (#131)

* Adds dark mode to the bottom sheet

* Make background button lighter (like before)

* lint

* Fix bug in lightbox rendering (#133)

* Fix layout in onboarding to not overflow the footer

* Configure feed FlatList (removeClippedSubviews=true) to improve scroll performance (#136)

* Disable like/repost animations to see if theyre causing #135 (#137)

* Composer: mention tagging now works in middle of text (close #105) (#139)

* Implement account deletion (#141)

* Fix photo & camera permission management (#140)

* Check photo & camera perms and alert the user if not available (close #64)

- Adds perms checks with a prompt to update settings if needed
- Moves initial access of photos in the composer so that the initial prompt
occurs at an intuitive time.

* Add react-native-permissions test mock

* Fix issue causing multiple access requests

* Use longer var names

* Update podfile.lock

* Lint fix

* Move photo perm request in composer to the gallery btn instead of when the carousel is opened

* Adds more tracking all around the app (#142)

* Adds more tracking all around the app

* more events

* lint

* using better analytics naming

* missed file

* more fixes

* Calculate image aspect ratio on load (#146)

* Calculate image aspect ratio on load

* Move aspect ratio bounds to constants

* Adds detox testing and instructions (#147)

* Adds detox testing and instructions

* lint

* lint

* Error cleanup (close #79) (#148)

* Avoid surfacing errors to the user when it's not critical

* Remove now-unused GetAssertionsView

* Apply cleanError() consistently

* Give a better error message for Upstream Failures (http status 502)

* Hide errors in notifications because they're not useful

* More e2e tests (create account) (#150)

* Adds respots under the 'post' tab under profile (#158)

* Adds dark mode to delete account screen (#159)

* 87 dark mode edit profile (#162)

* Adds dark mode to delete account screen

* Adds one more missed darkmode

* more fixes

* Remove fallback gradient on external links without thumbs (#164)

* Remove fallback gradient on external links without thumbs

* Remove fallback gradient on external links without thumbs in the composer preview

* Fix refresh behavior around a series of models (repost, graph, vote) (#163)

* Fix refresh behavior around a series of models (repost, graph, vote)

* Fix cursor behavior in reposted-by view

* Fixes issue where retrying on image upload fails (#166)

* Fixes issue where retrying on image upload fails

* Lint, longer test time

* Longer waitfor time in tests

* even longer timeout

* longer timeout

* missed file

* Update src/view/com/composer/ComposePost.tsx

Co-authored-by: Paul Frazee <pfrazee@gmail.com>

* Update src/view/com/composer/ComposePost.tsx

Co-authored-by: Paul Frazee <pfrazee@gmail.com>

---------

Co-authored-by: Paul Frazee <pfrazee@gmail.com>

* 154 cached image profile (#167)

* Fixes issue where retrying on image upload fails

* Lint, longer test time

* Longer waitfor time in tests

* even longer timeout

* longer timeout

* missed file

* Fixes image cache error on second try for profile screen

* lint

* lint

* lint

* Refactor session management to use a new "Agent" API (#165)

* Add the atp-agent implementation (temporarily in this repo)

* Rewrite all session & API management to use the new atp-agent

* Update tests for the atp-agent refactor

* Refactor management of session-related state. Includes:
- More careful management of when state is cleared or fetched
- Debug logging to help trace future issues
- Clearer APIs overall

* Bubble session-expiration events to the user and display a toast to explain

* Switch to the new @atproto/api@0.1.0

* Minor aesthetic cleanup in SessionModel

* Wire up ReportAccount and ReportPost (#168)

* Fixes embeds for youtube channels (#169)

* Bump app ios version to 1.1 (needed after app store submission)

* Fix potential issues with promise guards when an error occurs (#170)

* Refactor models to use bundleAsync and lock regions (#171)

* Fix to an edge case with feed re-ordering for threads (#172)

* 151 fix youtube channel embed (#173)

* Fixes embeds for youtube channels

* Tests for youtube extract meta

* lint

* Add 'doesnt use non-exempt encryption' to ios config

* Rework the search UI and add (#174)

* Add search tab and move icon to footer

* Remove subtitles from view header

* Remove unused code

* Clean up UI of search screen

* Search: give better user feedback to UI state and add a cancel button

* Add WhoToFollow section to search

* Add a temporary SuggestedPosts solution using the patented 'bsky team algo'

* Trigger reload of suggested content in search on open

* Wait five min between reloading discovery content

* Reduce weight of solid search icon in footer

* Fix lint

* Fix tests

* 151 feat youtube embed iframe (#176)

* youtube embed iframe temp commit

* Fixes styling and code cleanup

* lint

* Now clicking between the pause and settings button doesn't trigger the parent

* use modest branding (less yt logos)

* Stop playing the video once there's a navigation event

* Make sure the iframe is unmounted on any navigation event

* fixes tests

* lint

* Add scroll-to-top for all screens (#177)

* Adds hardcoded suggested list (#178)

* Adds hardcoded suggested list

* Update suggested-actors-view to support page sizes smaller than the hardcoded list

---------

Co-authored-by: Paul Frazee <pfrazee@gmail.com>

* more robust centering of the play button (#181)

Co-authored-by: Aryan Goharzad <arrygoo@gmail.com>

* Bundle of UI modifications (#175)

* Adjust visual balance of SuggestedPosts and WhoToFollow

* Fix bug in the discovery load trigger

* Adjust search header aesthetic and have it scroll away

* More visual balance tweaks on the search page

* Even more visual balance tweaks on the search page

* Hide the footer on scroll in search

* Ditch the composer prompt buttons in the home feed

* Center the view header title

* Hide header on scroll on the home feed

* Fix e2e tests

* Fix home feed positioning (closes #189) (#195)

* Fix home feed positioning for floating header

* Fix positioning of errors in home feed

* Fix lint

* Don't show new-content notification for reposts (close #179) (#197)

* Show the splash screen during session resumption (close #186) (#199)

* Fix to suggested follows: chunk the hardcoded fetches to 25 at a time (close #196) (#198)

* UI updates to the floating action button (#201)

* Update FAB to use a plus icon and not drop shadow

* Update FAB positioning to be more consistent in different shell modes

* Animate the FAB's repositioning

* Remove the 'loading' placeholder from images as it degraded feed perf (#202)

* Remove the 'loading' placeholder from images as it degraded feed perf

* Remove references

* Fix RN bug that causes home feed not to load more; also fix home feed load view. (#208)

RN has a bug where rendering a flatlist with an empty array appears to break its
virtual list windowing behaviors. See https://stackoverflow.com/a/67873596

* Only give the loading spinner on the home feed during PTR (#207)

(cherry picked from commit b7a5da12fdfacef74873b5cf6d75f20d259bde0e)

* Implement our own lifecycle tracking to ensure it never fires while the app is backgrounded (close #193) (#211)

* Push notification fixes (#210)

* Fix to when screen analytics events are firing

* Fix: dont trigger update state when backgrounded

* Small fix to notifee API usage

* Fix: properly load notification info for push card

* Add feedback link to main menu (close #191) (#212)

* Add "follows you" information and sync follow state between views (#215)

* Bump @atproto/api@0.1.2 and update API usage

* Add 'follows you' pill to profile header (close #110)

* Add 'follows you' to followers and follows (close #103)

* Update reposted-by and liked-by views to use the same components as followers and following

* Create a local follows cache MyFollowsModel to keep views in sync (close #205)

* Add incremental hydration to the MyFollows model

* Fix tests

* Update deps

* Fix lint

* Fix to paginated fetches

* Fix reference

* Fix potential state-desync issue

* Fixes to notifications (#216)

* Improve push-notification for follows

* Refresh notifications on screen open (close #214)

* Avoid showing loader more than needed in post threads

* Refactor notification polling to handle view-state more effectively

* Delete a bunch of tests taht werent adding value

* Remove the accounts integration test; we'll use the e2e test instead

* Load latest in notifications when the screen is open rather than full refresh

* Randomize hard-coded suggested follows (#226)

* Ensure follows are loaded before filtering hardcoded suggestions

* Randomize hard-coded suggested profiles (close #219)

* Sanitizes posts on publish and render (#217)

* Sanatizes posts on publish and render

* lint

* lint and added sanitize to thread view as well

* adjusts indices based on replaced text

* Woops, fixes a bug

* bugfix + cleanup

* comment

* lint

* move sanitize text to later in the flow

* undo changes to compose post

* Add RichText library building upon the sanitizePost library method

* Add lodash.clonedeep dep

* Switch to RichText processing on record load & render

* Fix lint

---------

Co-authored-by: Paul Frazee <pfrazee@gmail.com>

* A group of notifications fixes (#227)

* Fix: don't group together notifications that can't visually be grouped (close #221)

* Mark all notifications read on PTR

* Small optimization: useCallback and useMemo in posts feed

* Add loading spinner to footer of notifications (close #222)

* Fix to scrolling to posts within a thread (#228)

* Fix: render the entire thread at start so that scrollToIndex works always (close #270)

* Visual fixes to thread 'load more'

* A few small perf improvements to thread rendering

* Fix lint

* 1.2

* Remove unused logger lib

* Remove state-mock

* Type fixes

* Reorganize the folder structure for lib and switch to typescript path aliases

* Move build-flags into lib

* Move to the state path alias

* Add view path alias

* Fix lint

* iOS build fixes

* Wrap analytics in native/web splitter and re-enable in all view code

* Add web version of react-native-webview

* Add web split for version number

* Fix BlurView import for web

* Add web split for fastimage

* Create web split for permissions lib

* Fix for web high priority images

---------

Co-authored-by: Aryan Goharzad <arrygoo@gmail.com>

authored by

Paul Frazee
Paul Frazee
Aryan Goharzad
and committed by
GitHub
f2833473 7916b26a

+8493 -7547
+85
.detoxrc.js
··· 1 + /** @type {Detox.DetoxConfig} */ 2 + module.exports = { 3 + testRunner: { 4 + args: { 5 + $0: 'jest', 6 + config: 'e2e/jest.config.js', 7 + }, 8 + jest: { 9 + setupTimeout: 120000, 10 + }, 11 + }, 12 + apps: { 13 + 'ios.debug': { 14 + type: 'ios.app', 15 + binaryPath: 'ios/build/Build/Products/Debug-iphonesimulator/app.app', 16 + build: 17 + 'xcodebuild -workspace ios/app.xcworkspace -scheme app -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build', 18 + }, 19 + 'ios.release': { 20 + type: 'ios.app', 21 + binaryPath: 'ios/build/Build/Products/Release-iphonesimulator/app.app', 22 + build: 23 + 'xcodebuild -workspace ios/app.xcworkspace -scheme app -configuration Release -sdk iphonesimulator -derivedDataPath ios/build', 24 + }, 25 + 'android.debug': { 26 + type: 'android.apk', 27 + binaryPath: 'android/app/build/outputs/apk/debug/app-debug.apk', 28 + build: 29 + 'cd android ; ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug ; cd -', 30 + reversePorts: [8081], 31 + }, 32 + 'android.release': { 33 + type: 'android.apk', 34 + binaryPath: 'android/app/build/outputs/apk/release/app-release.apk', 35 + build: 36 + 'cd android ; ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release ; cd -', 37 + }, 38 + }, 39 + devices: { 40 + simulator: { 41 + type: 'ios.simulator', 42 + device: { 43 + type: 'iPhone 14', 44 + }, 45 + }, 46 + attached: { 47 + type: 'android.attached', 48 + device: { 49 + adbName: '.*', 50 + }, 51 + }, 52 + emulator: { 53 + type: 'android.emulator', 54 + device: { 55 + avdName: 'Pixel_3a_API_30_x86', 56 + }, 57 + }, 58 + }, 59 + configurations: { 60 + 'ios.sim.debug': { 61 + device: 'simulator', 62 + app: 'ios.debug', 63 + }, 64 + 'ios.sim.release': { 65 + device: 'simulator', 66 + app: 'ios.release', 67 + }, 68 + 'android.att.debug': { 69 + device: 'attached', 70 + app: 'android.debug', 71 + }, 72 + 'android.att.release': { 73 + device: 'attached', 74 + app: 'android.release', 75 + }, 76 + 'android.emu.debug': { 77 + device: 'emulator', 78 + app: 'android.debug', 79 + }, 80 + 'android.emu.release': { 81 + device: 'emulator', 82 + app: 'android.release', 83 + }, 84 + }, 85 + }
+1 -1
.eslintrc.js
··· 2 2 root: true, 3 3 extends: '@react-native-community', 4 4 parser: '@typescript-eslint/parser', 5 - plugins: ['@typescript-eslint'], 5 + plugins: ['@typescript-eslint', 'detox'], 6 6 ignorePatterns: [ 7 7 '**/__mocks__/*.ts', 8 8 'src/third-party',
+2 -2
.github/workflows/lint.yml
··· 11 11 runs-on: ubuntu-latest 12 12 steps: 13 13 - name: Check out Git repository 14 - uses: actions/checkout@v2 14 + uses: actions/checkout@v3 15 15 - name: Yarn install 16 16 run: yarn 17 17 - name: Lint Reporter ··· 30 30 with: 31 31 node-version: 18 32 32 - name: Check out Git repository 33 - uses: actions/checkout@v2 33 + uses: actions/checkout@v3 34 34 - name: Yarn install 35 35 run: yarn 36 36 - name: Run tests
+2 -1
.gitignore
··· 62 62 63 63 # Testing 64 64 coverage/ 65 - junit.xml 65 + junit.xml 66 + artifacts
+16 -11
README.md
··· 1 - # Social App 2 - 3 - In-progress social app. 4 - 5 - Uses: 6 - 7 - - [React Native](https://reactnative.dev) 8 - - [React Native for Web](https://necolas.github.io/react-native-web/) 9 - - [React Navigation](https://reactnative.dev/docs/navigation#react-navigation) 10 - - [MobX](https://mobx.js.org/README.html) 11 - - [Async Storage](https://github.com/react-native-async-storage/async-storage) 1 + # Bluesky 12 2 13 3 ## Build instructions 14 4 15 5 - Setup your environment [using the react native instructions](https://reactnative.dev/docs/environment-setup). 6 + - Setup your environment [for e2e testing using detox](https://wix.github.io/Detox/docs/introduction/getting-started): 7 + - yarn global add detox-cli 8 + - brew tap wix/brew 9 + - brew install applesimutils 16 10 - After initial setup: 17 11 - `cd ios ; pod install` 18 12 - Start the dev servers ··· 33 27 - For some reason, the typescript compiler chokes on platform-specific files (e.g. `foo.native.ts`) but only when compiling for Web thus far. Therefore we always have one version of the file which doesn't use a platform specifier, and that should bee the Web version. ([More info](https://stackoverflow.com/questions/44001050/platform-specific-import-component-in-react-native-with-typescript).) 34 28 35 29 ## Various notes 30 + 31 + ### Debugging 32 + 33 + - Note that since 0.70, debugging using the old debugger (which shows up using CMD+D) doesn't work anymore. Follow the instructions below to debug the code: https://reactnative.dev/docs/next/hermes#debugging-js-on-hermes-using-google-chromes-devtools 34 + 35 + ### Running E2E Tests 36 + 37 + - Make sure you've setup your environment following above 38 + - Make sure Metro and the dev server are running 39 + - Run `yarn e2e` 40 + - Find the artifacts in the `artifact` folder 36 41 37 42 ### Polyfills 38 43
+67
__mocks__/react-native-svg.js
··· 1 + // @flow 2 + 3 + // https://github.com/FormidableLabs/react-native-svg-mock 4 + import React from 'react' 5 + 6 + const createComponent = function (name) { 7 + return class extends React.Component { 8 + // overwrite the displayName, since this is a class created dynamically 9 + static displayName = name 10 + 11 + render() { 12 + return React.createElement(name, this.props, this.props.children) 13 + } 14 + } 15 + } 16 + 17 + // Mock all react-native-svg exports 18 + // from https://github.com/magicismight/react-native-svg/blob/master/index.js 19 + const Svg = createComponent('Svg') 20 + const Circle = createComponent('Circle') 21 + const Ellipse = createComponent('Ellipse') 22 + const G = createComponent('G') 23 + const Text = createComponent('Text') 24 + const TextPath = createComponent('TextPath') 25 + const TSpan = createComponent('TSpan') 26 + const Path = createComponent('Path') 27 + const Polygon = createComponent('Polygon') 28 + const Polyline = createComponent('Polyline') 29 + const Line = createComponent('Line') 30 + const Rect = createComponent('Rect') 31 + const Use = createComponent('Use') 32 + const Image = createComponent('Image') 33 + const Symbol = createComponent('Symbol') 34 + const Defs = createComponent('Defs') 35 + const LinearGradient = createComponent('LinearGradient') 36 + const RadialGradient = createComponent('RadialGradient') 37 + const Stop = createComponent('Stop') 38 + const ClipPath = createComponent('ClipPath') 39 + const Pattern = createComponent('Pattern') 40 + const Mask = createComponent('Mask') 41 + 42 + export { 43 + Svg, 44 + Circle, 45 + Ellipse, 46 + G, 47 + Text, 48 + TextPath, 49 + TSpan, 50 + Path, 51 + Polygon, 52 + Polyline, 53 + Line, 54 + Rect, 55 + Use, 56 + Image, 57 + Symbol, 58 + Defs, 59 + LinearGradient, 60 + RadialGradient, 61 + Stop, 62 + ClipPath, 63 + Pattern, 64 + Mask, 65 + } 66 + 67 + export default Svg
-856
__mocks__/state-mock.ts
··· 1 - import {LogModel} from './../src/state/models/log' 2 - import {LRUMap} from 'lru_map' 3 - import {RootStoreModel} from './../src/state/models/root-store' 4 - import {NavigationTabModel} from './../src/state/models/navigation' 5 - import {SessionModel} from '../src/state/models/session' 6 - import {NavigationModel} from '../src/state/models/navigation' 7 - import {ShellUiModel} from '../src/state/models/shell-ui' 8 - import {MeModel} from '../src/state/models/me' 9 - import {OnboardModel} from '../src/state/models/onboard' 10 - import {ProfilesViewModel} from '../src/state/models/profiles-view' 11 - import {LinkMetasViewModel} from '../src/state/models/link-metas-view' 12 - import {FeedModel} from '../src/state/models/feed-view' 13 - import {NotificationsViewModel} from '../src/state/models/notifications-view' 14 - import {ProfileViewModel} from '../src/state/models/profile-view' 15 - import {ProfileUiModel, Sections} from '../src/state/models/profile-ui' 16 - import {SessionServiceClient} from '@atproto/api' 17 - import {UserAutocompleteViewModel} from '../src/state/models/user-autocomplete-view' 18 - import {UserLocalPhotosModel} from '../src/state/models/user-local-photos' 19 - import {SuggestedActorsViewModel} from '../src/state/models/suggested-actors-view' 20 - import {UserFollowersViewModel} from '../src/state/models/user-followers-view' 21 - import {UserFollowsViewModel} from '../src/state/models/user-follows-view' 22 - import {NotificationsViewItemModel} from './../src/state/models/notifications-view' 23 - import { 24 - PostThreadViewModel, 25 - PostThreadViewPostModel, 26 - } from '../src/state/models/post-thread-view' 27 - import {FeedItemModel} from '../src/state/models/feed-view' 28 - import {RepostedByViewModel} from '../src/state/models/reposted-by-view' 29 - import {VotesViewModel} from '../src/state/models/votes-view' 30 - 31 - export const mockedProfileStore = { 32 - isLoading: false, 33 - isRefreshing: false, 34 - hasLoaded: true, 35 - error: '', 36 - params: { 37 - actor: '', 38 - }, 39 - did: 'test did', 40 - handle: 'testhandle', 41 - declaration: { 42 - cid: '', 43 - actorType: '', 44 - }, 45 - creator: 'test did', 46 - displayName: '', 47 - description: '', 48 - avatar: '', 49 - banner: '', 50 - followersCount: 0, 51 - followsCount: 0, 52 - membersCount: 0, 53 - postsCount: 0, 54 - myState: { 55 - follow: '', 56 - member: '', 57 - }, 58 - rootStore: {} as RootStoreModel, 59 - hasContent: true, 60 - hasError: false, 61 - isEmpty: false, 62 - isUser: true, 63 - isScene: false, 64 - setup: jest.fn().mockResolvedValue({aborted: false}), 65 - refresh: jest.fn().mockResolvedValue({}), 66 - toggleFollowing: jest.fn().mockResolvedValue({}), 67 - updateProfile: jest.fn(), 68 - // unknown required because of the missing private methods: _xLoading, _xIdle, _load, _replaceAll 69 - } as unknown as ProfileViewModel 70 - 71 - export const mockedFeedItemStore = { 72 - _reactKey: 'item-1', 73 - _isThreadParent: false, 74 - _isThreadChildElided: false, 75 - _isThreadChild: false, 76 - _hideParent: false, 77 - _isRenderingAsThread: false, 78 - post: { 79 - uri: 'testuri', 80 - cid: 'test cid', 81 - author: { 82 - did: 'test did', 83 - handle: 'test.handle', 84 - displayName: 'test name', 85 - declaration: {cid: '', actorType: ''}, 86 - }, 87 - record: { 88 - $type: 'app.bsky.feed.post', 89 - createdAt: '2022-12-29T16:39:57.919Z', 90 - text: 'Sup', 91 - }, 92 - replyCount: 0, 93 - repostCount: 0, 94 - upvoteCount: 0, 95 - downvoteCount: 0, 96 - indexedAt: '2022-12-29T16:39:57.919Z', 97 - viewer: {}, 98 - }, 99 - postRecord: { 100 - $type: 'app.bsky.feed.post', 101 - text: 'test text', 102 - createdAt: '1', 103 - reply: { 104 - root: { 105 - uri: 'testuri', 106 - cid: 'tes cid', 107 - }, 108 - parent: { 109 - uri: 'testuri', 110 - cid: 'tes cid', 111 - }, 112 - }, 113 - }, 114 - rootStore: {} as RootStoreModel, 115 - copy: jest.fn(), 116 - toggleUpvote: jest.fn().mockResolvedValue({}), 117 - toggleDownvote: jest.fn(), 118 - toggleRepost: jest.fn().mockResolvedValue({}), 119 - delete: jest.fn().mockResolvedValue({}), 120 - reasonRepost: { 121 - by: { 122 - did: 'test did', 123 - handle: 'test.handle', 124 - declaration: {cid: '', actorType: ''}, 125 - }, 126 - indexedAt: '', 127 - }, 128 - reasonTrend: { 129 - by: { 130 - did: 'test did', 131 - handle: 'test.handle', 132 - declaration: {cid: '', actorType: ''}, 133 - }, 134 - indexedAt: '', 135 - }, 136 - reply: { 137 - parent: { 138 - author: { 139 - did: 'test did', 140 - handle: 'test.handle', 141 - displayName: 'test name', 142 - declaration: {cid: '', actorType: ''}, 143 - }, 144 - cid: '', 145 - downvoteCount: 0, 146 - indexedAt: '2023-01-10T11:17:46.945Z', 147 - record: {}, 148 - replyCount: 1, 149 - repostCount: 0, 150 - upvoteCount: 0, 151 - uri: 'testuri', 152 - viewer: {}, 153 - }, 154 - root: { 155 - author: { 156 - did: 'test did', 157 - handle: 'test.handle', 158 - displayName: 'test name', 159 - declaration: {cid: '', actorType: ''}, 160 - }, 161 - cid: '', 162 - downvoteCount: 0, 163 - indexedAt: '2023-01-10T11:17:46.739Z', 164 - record: {}, 165 - replyCount: 1, 166 - repostCount: 0, 167 - upvoteCount: 1, 168 - uri: 'testuri', 169 - viewer: {}, 170 - }, 171 - }, 172 - } as FeedItemModel 173 - 174 - export const mockedFeedStore = { 175 - isLoading: false, 176 - isRefreshing: false, 177 - hasNewLatest: false, 178 - hasLoaded: true, 179 - error: '', 180 - hasMore: true, 181 - params: { 182 - actor: '', 183 - limit: 1, 184 - before: '', 185 - }, 186 - feed: [], 187 - rootStore: {} as RootStoreModel, 188 - feedType: 'home', 189 - hasContent: true, 190 - hasError: false, 191 - isEmpty: false, 192 - nonReplyFeed: [ 193 - { 194 - _reactKey: 'item-1', 195 - post: { 196 - author: { 197 - handle: 'handle.test', 198 - displayName: 'test name', 199 - avatar: '', 200 - }, 201 - cid: 'bafyreihkwjoy2vbfqld2lp3tv4ce6yfr354sqgp32qoplrudso4gyyjiwe', 202 - downvoteCount: 0, 203 - indexedAt: '2022-12-29T16:35:55.270Z', 204 - record: { 205 - $type: 'app.bsky.feed.post', 206 - createdAt: '2022-12-29T16:39:57.919Z', 207 - text: 'Sup', 208 - }, 209 - replyCount: 0, 210 - repostCount: 0, 211 - upvoteCount: 0, 212 - uri: 'at://did:plc:wcizmlgv3rdslk64t6q4silu/app.bsky.feed.post/3jkzce5kfvn2h', 213 - viewer: { 214 - handle: 'handle.test', 215 - displayName: 'test name', 216 - avatar: '', 217 - }, 218 - }, 219 - reason: undefined, 220 - reply: undefined, 221 - }, 222 - ], 223 - setHasNewLatest: jest.fn(), 224 - setup: jest.fn().mockResolvedValue({}), 225 - refresh: jest.fn().mockResolvedValue({}), 226 - loadMore: jest.fn().mockResolvedValue({}), 227 - loadLatest: jest.fn(), 228 - update: jest.fn(), 229 - checkForLatest: jest.fn().mockRejectedValue('Error checking for latest'), 230 - registerListeners: jest.fn().mockReturnValue(jest.fn()), 231 - // unknown required because of the missing private methods: _xLoading, _xIdle, _pendingWork, _initialLoad, _loadLatest, _loadMore, _update, _replaceAll, _appendAll, _prependAll, _updateAll, _getFeed, loadMoreCursor, pollCursor, _loadPromise, _updatePromise, _loadLatestPromise, _loadMorePromise 232 - } as unknown as FeedModel 233 - 234 - export const mockedPostThreadViewPostStore = { 235 - _reactKey: 'item-1', 236 - _depth: 0, 237 - _isHighlightedPost: false, 238 - _hasMore: false, 239 - postRecord: { 240 - text: 'test text', 241 - createdAt: '', 242 - reply: { 243 - root: { 244 - uri: 'testuri', 245 - cid: 'tes cid', 246 - }, 247 - parent: { 248 - uri: 'testuri', 249 - cid: 'tes cid', 250 - }, 251 - }, 252 - }, 253 - post: { 254 - uri: 'testuri', 255 - cid: 'testcid', 256 - record: {}, 257 - author: { 258 - did: 'test did', 259 - handle: 'test.handle', 260 - declaration: {cid: '', actorType: ''}, 261 - viewer: { 262 - muted: true, 263 - }, 264 - }, 265 - replyCount: 0, 266 - repostCount: 0, 267 - upvoteCount: 0, 268 - downvoteCount: 0, 269 - indexedAt: '', 270 - viewer: { 271 - repost: '', 272 - upvote: '', 273 - downvote: '', 274 - }, 275 - }, 276 - rootStore: {} as RootStoreModel, 277 - assignTreeModels: jest.fn(), 278 - toggleRepost: jest.fn().mockRejectedValue({}), 279 - toggleUpvote: jest.fn().mockRejectedValue({}), 280 - toggleDownvote: jest.fn(), 281 - delete: jest.fn(), 282 - } as PostThreadViewPostModel 283 - 284 - export const mockedPostThreadViewStore = { 285 - isLoading: false, 286 - isRefreshing: false, 287 - hasLoaded: false, 288 - error: '', 289 - notFound: false, 290 - resolvedUri: 'testuri', 291 - params: { 292 - uri: 'testuri', 293 - }, 294 - thread: mockedPostThreadViewPostStore, 295 - hasContent: true, 296 - hasError: false, 297 - setup: jest.fn(), 298 - refresh: jest.fn().mockResolvedValue({}), 299 - update: jest.fn(), 300 - // unknown required because of the missing private methods: _xLoading, _xIdle, _resolveUri, _load, _replaceAll 301 - } as unknown as PostThreadViewModel 302 - 303 - export const mockedNotificationsViewItemStore = { 304 - _reactKey: 'item-1', 305 - uri: 'testuri', 306 - cid: '', 307 - author: { 308 - did: 'test did', 309 - handle: 'test.handle', 310 - declaration: {cid: '', actorType: ''}, 311 - }, 312 - rootStore: {} as RootStoreModel, 313 - copy: jest.fn(), 314 - reason: 'test reason', 315 - isRead: true, 316 - indexedAt: '', 317 - isUpvote: true, 318 - isRepost: false, 319 - isTrend: false, 320 - isMention: false, 321 - isReply: false, 322 - isFollow: false, 323 - isAssertion: false, 324 - needsAdditionalData: false, 325 - isInvite: false, 326 - subjectUri: 'testuri', 327 - toSupportedRecord: jest.fn().mockReturnValue({ 328 - text: 'test text', 329 - createdAt: '', 330 - }), 331 - fetchAdditionalData: jest.fn(), 332 - toNotifeeOpts: jest.fn(), 333 - } as NotificationsViewItemModel 334 - 335 - export const mockedNotificationsStore = { 336 - isLoading: false, 337 - isRefreshing: false, 338 - hasLoaded: true, 339 - error: '', 340 - params: { 341 - limit: 1, 342 - before: '', 343 - }, 344 - hasMore: true, 345 - notifications: [mockedNotificationsViewItemStore], 346 - rootStore: {} as RootStoreModel, 347 - hasContent: true, 348 - hasError: false, 349 - isEmpty: false, 350 - setup: jest.fn().mockResolvedValue({aborted: false}), 351 - refresh: jest.fn().mockResolvedValue({}), 352 - loadMore: jest.fn().mockResolvedValue({}), 353 - update: jest.fn().mockResolvedValue(null), 354 - updateReadState: jest.fn(), 355 - // unknown required because of the missing private methods: _xLoading, _xIdle, _pendingWork, _initialLoad, _loadMore, _update, _replaceAll, _appendAll, _updateAll, loadMoreCursor, _loadPromise, _updatePromise, _loadLatestPromise, _loadMorePromise 356 - } as unknown as NotificationsViewModel 357 - 358 - export const mockedSessionStore = { 359 - serialize: jest.fn(), 360 - hydrate: jest.fn(), 361 - data: { 362 - service: '', 363 - refreshJwt: '', 364 - accessJwt: '', 365 - handle: '', 366 - did: 'test did', 367 - }, 368 - online: false, 369 - attemptingConnect: false, 370 - rootStore: {} as RootStoreModel, 371 - hasSession: true, 372 - clear: jest.fn(), 373 - setState: jest.fn(), 374 - setOnline: jest.fn(), 375 - updateAuthTokens: jest.fn(), 376 - connect: jest.fn(), 377 - describeService: jest.fn().mockResolvedValue({ 378 - availableUserDomains: ['test'], 379 - links: { 380 - termsOfService: 'https://testTermsOfService', 381 - privacyPolicy: 'https://testPrivacyPolicy', 382 - }, 383 - }), 384 - login: jest.fn(), 385 - createAccount: jest.fn(), 386 - logout: jest.fn(), 387 - 388 - // unknown required because of the missing private methods: _connectPromise, configureApi & _connect 389 - } as unknown as SessionModel 390 - 391 - export const mockedNavigationTabStore = { 392 - serialize: jest.fn(), 393 - hydrate: jest.fn(), 394 - id: '0', 395 - history: [ 396 - { 397 - url: '', 398 - ts: 0, 399 - title: '', 400 - id: '0', 401 - }, 402 - ], 403 - index: 0, 404 - isNewTab: false, 405 - current: { 406 - url: '', 407 - ts: 0, 408 - title: '', 409 - id: '0', 410 - }, 411 - canGoBack: false, 412 - canGoForward: false, 413 - backTen: [ 414 - { 415 - url: '', 416 - title: '', 417 - index: 0, 418 - id: '0', 419 - }, 420 - ], 421 - forwardTen: [ 422 - { 423 - url: '', 424 - title: '', 425 - index: 0, 426 - id: '0', 427 - }, 428 - ], 429 - navigate: jest.fn(), 430 - refresh: jest.fn().mockResolvedValue({}), 431 - goBack: jest.fn(), 432 - fixedTabReset: jest.fn(), 433 - goForward: jest.fn(), 434 - goToIndex: jest.fn(), 435 - setTitle: jest.fn(), 436 - setIsNewTab: jest.fn(), 437 - fixedTabPurpose: 0, 438 - getBackList: () => [ 439 - { 440 - url: '/', 441 - title: '', 442 - index: 1, 443 - id: '1', 444 - }, 445 - ], 446 - getForwardList: jest.fn(), 447 - } as NavigationTabModel 448 - 449 - export const mockedNavigationStore = { 450 - serialize: jest.fn(), 451 - hydrate: jest.fn(), 452 - tabs: [mockedNavigationTabStore], 453 - tabIndex: 0, 454 - clear: jest.fn(), 455 - tab: mockedNavigationTabStore, 456 - tabCount: 1, 457 - isCurrentScreen: jest.fn(), 458 - navigate: jest.fn(), 459 - refresh: jest.fn().mockResolvedValue({}), 460 - setTitle: jest.fn(), 461 - handleLink: jest.fn(), 462 - switchTo: jest.fn(), 463 - setActiveTab: jest.fn(), 464 - closeTab: jest.fn(), 465 - newTab: jest.fn(), 466 - } as NavigationModel 467 - 468 - export const mockedShellStore = { 469 - serialize: jest.fn(), 470 - hydrate: jest.fn(), 471 - minimalShellMode: false, 472 - isMainMenuOpen: false, 473 - isModalActive: false, 474 - activeModal: undefined, 475 - isLightboxActive: false, 476 - activeLightbox: undefined, 477 - isComposerActive: false, 478 - composerOpts: undefined, 479 - darkMode: false, 480 - setDarkMode: jest.fn(), 481 - setMainMenuOpen: jest.fn(), 482 - setMinimalShellMode: jest.fn(), 483 - openModal: jest.fn(), 484 - closeModal: jest.fn(), 485 - closeComposer: jest.fn(), 486 - closeLightbox: jest.fn(), 487 - openComposer: jest.fn(), 488 - openLightbox: jest.fn(), 489 - } as ShellUiModel 490 - 491 - export const mockedMeStore = { 492 - serialize: jest.fn(), 493 - hydrate: jest.fn(), 494 - did: 'test did', 495 - handle: 'test', 496 - displayName: 'test', 497 - description: 'test', 498 - avatar: '', 499 - notificationCount: 0, 500 - rootStore: {} as RootStoreModel, 501 - mainFeed: mockedFeedStore, 502 - notifications: mockedNotificationsStore, 503 - clear: jest.fn(), 504 - load: jest.fn(), 505 - clearNotificationCount: jest.fn(), 506 - fetchNotifications: jest.fn(), 507 - bgFetchNotifications: jest.fn(), 508 - refreshMemberships: jest.fn(), 509 - } as MeModel 510 - 511 - export const mockedOnboardStore = { 512 - serialize: jest.fn(), 513 - hydrate: jest.fn(), 514 - isOnboarding: false, 515 - stage: '', 516 - start: jest.fn(), 517 - stop: jest.fn(), 518 - next: jest.fn(), 519 - } as OnboardModel 520 - 521 - export const mockedProfilesStore = { 522 - hydrate: jest.fn(), 523 - serialize: jest.fn(), 524 - cache: new LRUMap(100), 525 - rootStore: {} as RootStoreModel, 526 - getProfile: jest.fn().mockResolvedValue({data: {}}), 527 - overwrite: jest.fn(), 528 - } as ProfilesViewModel 529 - 530 - export const mockedLinkMetasStore = { 531 - hydrate: jest.fn(), 532 - serialize: jest.fn(), 533 - cache: new LRUMap(100), 534 - rootStore: {} as RootStoreModel, 535 - getLinkMeta: jest.fn(), 536 - } as LinkMetasViewModel 537 - 538 - export const mockedLogStore = { 539 - entries: [], 540 - serialize: jest.fn(), 541 - hydrate: jest.fn(), 542 - debug: jest.fn(), 543 - warn: jest.fn(), 544 - error: jest.fn(), 545 - // unknown required because of the missing private methods: add 546 - } as unknown as LogModel 547 - 548 - export const mockedRootStore = { 549 - api: { 550 - com: {}, 551 - app: { 552 - bsky: { 553 - actor: { 554 - searchTypeahead: jest.fn().mockResolvedValue({data: {users: []}}), 555 - }, 556 - graph: { 557 - getFollows: jest.fn().mockResolvedValue({data: {follows: []}}), 558 - getFollowers: jest.fn().mockResolvedValue({}), 559 - getMembers: jest.fn().mockResolvedValue({}), 560 - }, 561 - }, 562 - }, 563 - } as unknown as SessionServiceClient, 564 - resolveName: jest.fn(), 565 - serialize: jest.fn(), 566 - hydrate: jest.fn(), 567 - fetchStateUpdate: jest.fn(), 568 - clearAll: jest.fn(), 569 - onPostDeleted: jest.fn(), 570 - emitPostDeleted: jest.fn(), 571 - initBgFetch: jest.fn(), 572 - onBgFetch: jest.fn(), 573 - onBgFetchTimeout: jest.fn(), 574 - session: mockedSessionStore, 575 - nav: mockedNavigationStore, 576 - shell: mockedShellStore, 577 - me: mockedMeStore, 578 - onboard: mockedOnboardStore, 579 - profiles: mockedProfilesStore, 580 - linkMetas: mockedLinkMetasStore, 581 - log: mockedLogStore, 582 - } as RootStoreModel 583 - 584 - export const mockedProfileUiStore = { 585 - profile: mockedProfileStore, 586 - feed: mockedFeedStore, 587 - selectedViewIndex: 0, 588 - rootStore: mockedRootStore, 589 - params: { 590 - user: 'test user', 591 - }, 592 - currentView: mockedFeedStore, 593 - isInitialLoading: false, 594 - isRefreshing: false, 595 - isUser: true, 596 - isScene: false, 597 - selectorItems: [Sections.Posts, Sections.PostsWithReplies], 598 - selectedView: Sections.Posts, 599 - setSelectedViewIndex: jest.fn(), 600 - setup: jest.fn().mockResolvedValue({aborted: false}), 601 - update: jest.fn(), 602 - refresh: jest.fn().mockResolvedValue({}), 603 - loadMore: jest.fn(), 604 - } as ProfileUiModel 605 - 606 - export const mockedAutocompleteViewStore = { 607 - isLoading: false, 608 - isActive: true, 609 - prefix: '', 610 - follows: [ 611 - { 612 - did: 'test did', 613 - declaration: { 614 - cid: '', 615 - actorType: 'app.bsky.system.actorUser', 616 - }, 617 - handle: '', 618 - displayName: '', 619 - createdAt: '', 620 - indexedAt: '', 621 - }, 622 - ], 623 - searchRes: [ 624 - { 625 - did: 'test did', 626 - declaration: { 627 - cid: '', 628 - actorType: 'app.bsky.system.actorUser', 629 - }, 630 - handle: '', 631 - displayName: '', 632 - }, 633 - ], 634 - knownHandles: new Set<string>(), 635 - suggestions: [ 636 - { 637 - handle: 'handle.test', 638 - displayName: 'Test Display', 639 - }, 640 - { 641 - handle: 'handle2.test', 642 - displayName: 'Test Display 2', 643 - }, 644 - ], 645 - rootStore: {} as RootStoreModel, 646 - setup: jest.fn(), 647 - setActive: jest.fn(), 648 - setPrefix: jest.fn(), 649 - // unknown required because of the missing private methods: _searchPromise, _getFollows , _search 650 - } as unknown as UserAutocompleteViewModel 651 - 652 - export const mockedLocalPhotosStore = { 653 - photos: { 654 - node: { 655 - type: '', 656 - group_name: '', 657 - image: { 658 - filename: '', 659 - extension: '', 660 - uri: '', 661 - height: 1000, 662 - width: 1000, 663 - fileSize: null, 664 - playableDuration: 0, 665 - }, 666 - timestamp: 1672847197, 667 - location: null, 668 - }, 669 - }, 670 - rootStore: {} as RootStoreModel, 671 - setup: jest.fn(), 672 - // unknown required because of the missing private methods: _getPhotos 673 - } as unknown as UserLocalPhotosModel 674 - 675 - export const mockedSuggestedActorsStore = { 676 - isLoading: false, 677 - isRefreshing: false, 678 - hasLoaded: false, 679 - error: '', 680 - suggestions: [ 681 - { 682 - did: '1', 683 - declaration: { 684 - cid: '', 685 - actorType: 'app.bsky.system.actorUser', 686 - }, 687 - handle: 'handle1.test', 688 - displayName: 'test name 1', 689 - description: 'desc', 690 - indexedAt: '', 691 - _reactKey: '1', 692 - }, 693 - { 694 - did: '2', 695 - declaration: { 696 - cid: '', 697 - actorType: 'app.bsky.system.actorUser', 698 - }, 699 - handle: '', 700 - displayName: 'handle2.test', 701 - description: 'desc', 702 - indexedAt: '', 703 - _reactKey: '2', 704 - }, 705 - ], 706 - rootStore: {} as RootStoreModel, 707 - hasContent: true, 708 - hasError: false, 709 - isEmpty: false, 710 - setup: jest.fn().mockResolvedValue(null), 711 - refresh: jest.fn().mockResolvedValue({}), 712 - // unknown required because of the missing private methods: _xLoading, _xIdle, _fetch, _appendAll, _append 713 - } as unknown as SuggestedActorsViewModel 714 - 715 - export const mockedUserFollowersStore = { 716 - isLoading: false, 717 - isRefreshing: false, 718 - hasLoaded: false, 719 - error: '', 720 - params: { 721 - user: 'test user', 722 - }, 723 - subject: { 724 - did: 'test did', 725 - handle: '', 726 - declaration: {cid: '', actorType: ''}, 727 - }, 728 - followers: [ 729 - { 730 - did: 'test did', 731 - declaration: {cid: '', actorType: ''}, 732 - handle: 'testhandle', 733 - displayName: 'test name', 734 - indexedAt: '', 735 - _reactKey: '1', 736 - }, 737 - { 738 - did: 'test did2', 739 - declaration: {cid: '', actorType: ''}, 740 - handle: 'testhandle2', 741 - displayName: 'test name 2', 742 - indexedAt: '', 743 - _reactKey: '2', 744 - }, 745 - ], 746 - rootStore: {} as RootStoreModel, 747 - hasContent: true, 748 - hasError: false, 749 - isEmpty: false, 750 - setup: jest.fn(), 751 - refresh: jest.fn().mockResolvedValue({}), 752 - loadMore: jest.fn(), 753 - // unknown required because of the missing private methods: _xIdle, _xLoading, _fetch, _replaceAll, _append 754 - } as unknown as UserFollowersViewModel 755 - 756 - export const mockedUserFollowsStore = { 757 - isLoading: false, 758 - isRefreshing: false, 759 - hasLoaded: false, 760 - error: '', 761 - params: { 762 - user: 'test user', 763 - }, 764 - subject: { 765 - did: 'test did', 766 - handle: '', 767 - declaration: {cid: '', actorType: ''}, 768 - }, 769 - follows: [ 770 - { 771 - did: 'test did', 772 - declaration: {cid: '', actorType: ''}, 773 - handle: 'testhandle', 774 - displayName: 'test name', 775 - indexedAt: '', 776 - _reactKey: '1', 777 - }, 778 - { 779 - did: 'test did2', 780 - declaration: {cid: '', actorType: ''}, 781 - handle: 'testhandle2', 782 - displayName: 'test name 2', 783 - indexedAt: '', 784 - _reactKey: '2', 785 - }, 786 - ], 787 - rootStore: {} as RootStoreModel, 788 - hasContent: true, 789 - hasError: false, 790 - isEmpty: false, 791 - setup: jest.fn(), 792 - refresh: jest.fn().mockResolvedValue({}), 793 - loadMore: jest.fn(), 794 - // unknown required because of the missing private methods: _xIdle, _xLoading, _fetch, _replaceAll, _append 795 - } as unknown as UserFollowsViewModel 796 - 797 - export const mockedRepostedByViewStore = { 798 - isLoading: false, 799 - isRefreshing: false, 800 - hasLoaded: false, 801 - error: '', 802 - resolvedUri: '', 803 - params: { 804 - uri: 'testuri', 805 - }, 806 - uri: '', 807 - repostedBy: [ 808 - { 809 - _reactKey: '', 810 - did: '', 811 - handle: '', 812 - displayName: '', 813 - declaration: {cid: '', actorType: ''}, 814 - indexedAt: '', 815 - }, 816 - ], 817 - hasContent: false, 818 - hasError: false, 819 - isEmpty: false, 820 - setup: jest.fn().mockResolvedValue({}), 821 - refresh: jest.fn().mockResolvedValue({}), 822 - loadMore: jest.fn().mockResolvedValue({}), 823 - // unknown required because of the missing private methods: _xIdle, _xLoading, _resolveUri, _fetch, _refresh, _replaceAll, _append 824 - } as unknown as RepostedByViewModel 825 - 826 - export const mockedVotesViewStore = { 827 - isLoading: false, 828 - isRefreshing: false, 829 - hasLoaded: false, 830 - error: '', 831 - resolvedUri: '', 832 - params: { 833 - uri: 'testuri', 834 - }, 835 - uri: '', 836 - votes: [ 837 - { 838 - _reactKey: '', 839 - direction: 'up', 840 - indexedAt: '', 841 - createdAt: '', 842 - actor: { 843 - did: '', 844 - handle: '', 845 - declaration: {cid: '', actorType: ''}, 846 - }, 847 - }, 848 - ], 849 - hasContent: false, 850 - hasError: false, 851 - isEmpty: false, 852 - setup: jest.fn(), 853 - refresh: jest.fn().mockResolvedValue({}), 854 - loadMore: jest.fn().mockResolvedValue({}), 855 - // unknown required because of the missing private methods: _xIdle, _xLoading, _resolveUri, _fetch, _replaceAll, _append 856 - } as unknown as VotesViewModel
-241
__tests__/accounts.test.tsx
··· 1 - import React from 'react' 2 - import {MobileShell} from '../src/view/shell/mobile' 3 - import {cleanup, fireEvent, render, waitFor} from '../jest/test-utils' 4 - import {createServer, TestPDS} from '../jest/test-pds' 5 - import {RootStoreModel, setupState} from '../src/state' 6 - 7 - const WAIT_OPTS = {timeout: 5e3} 8 - 9 - describe('Account flows', () => { 10 - let pds: TestPDS | undefined 11 - let rootStore: RootStoreModel | undefined 12 - beforeAll(async () => { 13 - jest.useFakeTimers() 14 - pds = await createServer() 15 - rootStore = await setupState(pds.pdsUrl) 16 - }) 17 - 18 - afterAll(async () => { 19 - jest.clearAllMocks() 20 - cleanup() 21 - await pds?.close() 22 - }) 23 - 24 - it('renders initial screen', () => { 25 - const {getByTestId} = render(<MobileShell />, rootStore) 26 - const signUpScreen = getByTestId('signinOrCreateAccount') 27 - 28 - expect(signUpScreen).toBeTruthy() 29 - }) 30 - 31 - it('completes signin to the server', async () => { 32 - const {getByTestId} = render(<MobileShell />, rootStore) 33 - 34 - // move to signin view 35 - fireEvent.press(getByTestId('signInButton')) 36 - expect(getByTestId('signIn')).toBeTruthy() 37 - expect(getByTestId('loginForm')).toBeTruthy() 38 - 39 - // input the target server 40 - expect(getByTestId('loginSelectServiceButton')).toBeTruthy() 41 - fireEvent.press(getByTestId('loginSelectServiceButton')) 42 - expect(getByTestId('serverInputModal')).toBeTruthy() 43 - fireEvent.changeText( 44 - getByTestId('customServerTextInput'), 45 - pds?.pdsUrl || '', 46 - ) 47 - fireEvent.press(getByTestId('customServerSelectBtn')) 48 - await waitFor(() => { 49 - expect(getByTestId('loginUsernameInput')).toBeTruthy() 50 - }, WAIT_OPTS) 51 - 52 - // enter username & pass 53 - fireEvent.changeText(getByTestId('loginUsernameInput'), 'alice') 54 - fireEvent.changeText(getByTestId('loginPasswordInput'), 'hunter2') 55 - await waitFor(() => { 56 - expect(getByTestId('loginNextButton')).toBeTruthy() 57 - }, WAIT_OPTS) 58 - fireEvent.press(getByTestId('loginNextButton')) 59 - 60 - // signed in 61 - await waitFor(() => { 62 - expect(getByTestId('homeFeed')).toBeTruthy() 63 - expect(rootStore?.me?.displayName).toBe('Alice') 64 - expect(rootStore?.me?.handle).toBe('alice.test') 65 - expect(rootStore?.session.accounts.length).toBe(1) 66 - }, WAIT_OPTS) 67 - expect(rootStore?.me?.displayName).toBe('Alice') 68 - expect(rootStore?.me?.handle).toBe('alice.test') 69 - expect(rootStore?.session.accounts.length).toBe(1) 70 - }) 71 - 72 - it('opens the login screen when "add account" is pressed', async () => { 73 - const {getByTestId, getAllByTestId} = render(<MobileShell />, rootStore) 74 - await waitFor(() => expect(getByTestId('homeFeed')).toBeTruthy(), WAIT_OPTS) 75 - 76 - // open side menu 77 - fireEvent.press(getAllByTestId('viewHeaderBackOrMenuBtn')[0]) 78 - await waitFor(() => expect(getByTestId('menuView')).toBeTruthy(), WAIT_OPTS) 79 - 80 - // nav to settings 81 - fireEvent.press(getByTestId('menuItemButton-Settings')) 82 - await waitFor( 83 - () => expect(getByTestId('settingsScreen')).toBeTruthy(), 84 - WAIT_OPTS, 85 - ) 86 - 87 - // press '+ new account' in switcher 88 - fireEvent.press(getByTestId('switchToNewAccountBtn')) 89 - await waitFor( 90 - () => expect(getByTestId('signinOrCreateAccount')).toBeTruthy(), 91 - WAIT_OPTS, 92 - ) 93 - }) 94 - 95 - it('shows the "choose account" form when a previous session has been created', async () => { 96 - const {getByTestId} = render(<MobileShell />, rootStore) 97 - 98 - // move to signin view 99 - fireEvent.press(getByTestId('signInButton')) 100 - expect(getByTestId('signIn')).toBeTruthy() 101 - expect(getByTestId('chooseAccountForm')).toBeTruthy() 102 - }) 103 - 104 - it('logs directly into the account due to still possessing session tokens', async () => { 105 - const {getByTestId} = render(<MobileShell />, rootStore) 106 - 107 - // move to signin view 108 - fireEvent.press(getByTestId('signInButton')) 109 - expect(getByTestId('signIn')).toBeTruthy() 110 - expect(getByTestId('chooseAccountForm')).toBeTruthy() 111 - 112 - // select the previous account 113 - fireEvent.press(getByTestId('chooseAccountBtn-alice.test')) 114 - 115 - // signs in immediately 116 - await waitFor(() => { 117 - expect(getByTestId('homeFeed')).toBeTruthy() 118 - expect(rootStore?.me?.displayName).toBe('Alice') 119 - expect(rootStore?.me?.handle).toBe('alice.test') 120 - expect(rootStore?.session.accounts.length).toBe(1) 121 - }, WAIT_OPTS) 122 - expect(rootStore?.me?.displayName).toBe('Alice') 123 - expect(rootStore?.me?.handle).toBe('alice.test') 124 - expect(rootStore?.session.accounts.length).toBe(1) 125 - }) 126 - 127 - it('logs into a second account via the switcher', async () => { 128 - const {getByTestId, getAllByTestId} = render(<MobileShell />, rootStore) 129 - await waitFor(() => expect(getByTestId('homeFeed')).toBeTruthy(), WAIT_OPTS) 130 - 131 - // open side menu 132 - fireEvent.press(getAllByTestId('viewHeaderBackOrMenuBtn')[0]) 133 - await waitFor(() => expect(getByTestId('menuView')).toBeTruthy(), WAIT_OPTS) 134 - 135 - // nav to settings 136 - fireEvent.press(getByTestId('menuItemButton-Settings')) 137 - await waitFor( 138 - () => expect(getByTestId('settingsScreen')).toBeTruthy(), 139 - WAIT_OPTS, 140 - ) 141 - 142 - // press '+ new account' in switcher 143 - fireEvent.press(getByTestId('switchToNewAccountBtn')) 144 - await waitFor( 145 - () => expect(getByTestId('signinOrCreateAccount')).toBeTruthy(), 146 - WAIT_OPTS, 147 - ) 148 - 149 - // move to signin view 150 - fireEvent.press(getByTestId('signInButton')) 151 - expect(getByTestId('signIn')).toBeTruthy() 152 - expect(getByTestId('chooseAccountForm')).toBeTruthy() 153 - 154 - // select a new account 155 - fireEvent.press(getByTestId('chooseNewAccountBtn')) 156 - expect(getByTestId('loginForm')).toBeTruthy() 157 - 158 - // input the target server 159 - expect(getByTestId('loginSelectServiceButton')).toBeTruthy() 160 - fireEvent.press(getByTestId('loginSelectServiceButton')) 161 - expect(getByTestId('serverInputModal')).toBeTruthy() 162 - fireEvent.changeText( 163 - getByTestId('customServerTextInput'), 164 - pds?.pdsUrl || '', 165 - ) 166 - fireEvent.press(getByTestId('customServerSelectBtn')) 167 - await waitFor( 168 - () => expect(getByTestId('loginUsernameInput')).toBeTruthy(), 169 - WAIT_OPTS, 170 - ) 171 - 172 - // enter username & pass 173 - fireEvent.changeText(getByTestId('loginUsernameInput'), 'bob') 174 - fireEvent.changeText(getByTestId('loginPasswordInput'), 'hunter2') 175 - await waitFor( 176 - () => expect(getByTestId('loginNextButton')).toBeTruthy(), 177 - WAIT_OPTS, 178 - ) 179 - fireEvent.press(getByTestId('loginNextButton')) 180 - 181 - // signed in 182 - await waitFor(() => { 183 - expect(getByTestId('settingsScreen')).toBeTruthy() // we go back to settings in this situation 184 - expect(rootStore?.me?.displayName).toBe('Bob') 185 - expect(rootStore?.me?.handle).toBe('bob.test') 186 - expect(rootStore?.session.accounts.length).toBe(2) 187 - }, WAIT_OPTS) 188 - expect(rootStore?.me?.displayName).toBe('Bob') 189 - expect(rootStore?.me?.handle).toBe('bob.test') 190 - expect(rootStore?.session.accounts.length).toBe(2) 191 - }) 192 - 193 - it('can instantly switch between accounts', async () => { 194 - const {getByTestId} = render(<MobileShell />, rootStore) 195 - await waitFor( 196 - () => expect(getByTestId('settingsScreen')).toBeTruthy(), 197 - WAIT_OPTS, 198 - ) 199 - 200 - // select the alice account 201 - fireEvent.press(getByTestId('switchToAccountBtn-alice.test')) 202 - 203 - // swapped account 204 - await waitFor(() => { 205 - expect(rootStore?.me?.displayName).toBe('Alice') 206 - expect(rootStore?.me?.handle).toBe('alice.test') 207 - expect(rootStore?.session.accounts.length).toBe(2) 208 - }, WAIT_OPTS) 209 - expect(rootStore?.me?.displayName).toBe('Alice') 210 - expect(rootStore?.me?.handle).toBe('alice.test') 211 - expect(rootStore?.session.accounts.length).toBe(2) 212 - }) 213 - 214 - it('will prompt for a password if you sign out', async () => { 215 - const {getByTestId} = render(<MobileShell />, rootStore) 216 - await waitFor( 217 - () => expect(getByTestId('settingsScreen')).toBeTruthy(), 218 - WAIT_OPTS, 219 - ) 220 - 221 - // press the sign out button 222 - fireEvent.press(getByTestId('signOutBtn')) 223 - 224 - // in the logged out state 225 - await waitFor( 226 - () => expect(getByTestId('signinOrCreateAccount')).toBeTruthy(), 227 - WAIT_OPTS, 228 - ) 229 - 230 - // move to signin view 231 - fireEvent.press(getByTestId('signInButton')) 232 - expect(getByTestId('signIn')).toBeTruthy() 233 - expect(getByTestId('chooseAccountForm')).toBeTruthy() 234 - 235 - // select an existing account 236 - fireEvent.press(getByTestId('chooseAccountBtn-alice.test')) 237 - 238 - // goes to login screen instead of straight back to settings 239 - expect(getByTestId('loginForm')).toBeTruthy() 240 - }) 241 - })
+63
__tests__/lib/__mocks__/youtubeChannelHtml.ts
··· 1 + export const youtubeChannelHtml = ` 2 + 3 + <!DOCTYPE html><html style="font-size: 10px;font-family: Roboto, Arial, sans-serif;" lang="en" dark system-icons typography typography-spacing darker-dark-theme darker-dark-theme-deprecate><head><meta http-equiv="origin-trial" content="AlgsH67ctYlMR3JYAxEnGfvsoFo41AMqAg6wRHHXOpWAfD54ZCfTPBclxnFT4Gc8IUX4pq6Xfo0esDuOt+WH3wIAAABteyJvcmlnaW4iOiJodHRwczovL3lvdXR1YmUuY29tOjQ0MyIsImZlYXR1cmUiOiJQcml2YWN5U2FuZGJveEFkc0FQSXMiLCJleHBpcnkiOjE2ODA2NTI3OTksImlzU3ViZG9tYWluIjp0cnVlfQ=="/><script nonce="nopnosk9VoEiau3Xtg_3uQ">var ytcfg={d:function(){return window.yt&&yt.config_||ytcfg.data_||(ytcfg.data_={})},get:function(k,o){return k in ytcfg.d()?ytcfg.d()[k]:o},set:function(){var a=arguments;if(a.length>1)ytcfg.d()[a[0]]=a[1];else for(var k in a[0])ytcfg.d()[k]=a[0][k]}}; 4 + window.ytcfg.set('EMERGENCY_BASE_URL', '\/error_204?t\x3djserror\x26level\x3dERROR\x26client.name\x3d1\x26client.version\x3d2.20230201.01.00');</script><script nonce="nopnosk9VoEiau3Xtg_3uQ">(function(){window.yterr=window.yterr||true;window.unhandledErrorMessages={};window.unhandledErrorCount=0; 5 + window.onerror=function(msg,url,line,columnNumber,error){var err;if(error)err=error;else{err=new Error;err.stack="";err.message=msg;err.fileName=url;err.lineNumber=line;if(!isNaN(columnNumber))err["columnNumber"]=columnNumber}var message=String(err.message);if(!err.message||message in window.unhandledErrorMessages||window.unhandledErrorCount>=5)return;window.unhandledErrorCount+=1;window.unhandledErrorMessages[message]=true;var img=new Image;window.emergencyTimeoutImg=img;img.onload=img.onerror=function(){delete window.emergencyTimeoutImg}; 6 + var combinedLineAndColumn=err.lineNumber;if(!isNaN(err["columnNumber"]))combinedLineAndColumn+=":"+err["columnNumber"];var stack=err.stack||"";var values={"msg":message,"type":err.name,"client.params":"unhandled window error","file":err.fileName,"line":combinedLineAndColumn,"stack":stack.substr(0,500)};var thirdPartyScript=!err.fileName||err.fileName==="<anonymous>"||stack.indexOf("extension://")>=0;var replaced=stack.replace(/https:\/\/www.youtube.com\//g,"");if(replaced.match(/https?:\/\/[^/]+\//))thirdPartyScript= 7 + true;else if(stack.indexOf("trapProp")>=0&&stack.indexOf("trapChain")>=0)thirdPartyScript=true;else if(message.indexOf("redefine non-configurable")>=0)thirdPartyScript=true;var baseUrl=window["ytcfg"].get("EMERGENCY_BASE_URL","https://www.youtube.com/error_204?t=jserror&level=ERROR");var unsupported=message.indexOf("window.customElements is undefined")>=0;if(thirdPartyScript||unsupported)baseUrl=baseUrl.replace("level=ERROR","level=WARNING");var parts=[baseUrl];for(var key in values){var value=values[key]; 8 + if(value)parts.push(key+"="+encodeURIComponent(value))}img.src=parts.join("&")}; 9 + (function(){function _getExtendedNativePrototype(tag){var p=this._nativePrototypes[tag];if(!p){p=Object.create(this.getNativePrototype(tag));var p$=Object.getOwnPropertyNames(window["Polymer"].Base);for(var i=0,n=void 0;i<p$.length&&(n=p$[i]);i++)if(!window["Polymer"].BaseDescriptors[n])try{p[n]=window["Polymer"].Base[n]}catch(e){throw new Error("Error while copying property: "+n+". Tag is "+tag);}try{Object.defineProperties(p,window["Polymer"].BaseDescriptors)}catch(e$0){throw new Error("Polymer define property failed for "+ 10 + Object.keys(p));}this._nativePrototypes[tag]=p}return p}function handlePolymerError(msg){window.onerror(msg,window.location.href,0,0,new Error(Array.prototype.join.call(arguments,",")))}var origPolymer=window["Polymer"];var newPolymer=function(config){if(!origPolymer._ytIntercepted&&window["Polymer"].Base){origPolymer._ytIntercepted=true;window["Polymer"].Base._getExtendedNativePrototype=_getExtendedNativePrototype;window["Polymer"].Base._error=handlePolymerError;window["Polymer"].Base._warn=handlePolymerError}return origPolymer.apply(this, 11 + arguments)};var origDescriptor=Object.getOwnPropertyDescriptor(window,"Polymer");Object.defineProperty(window,"Polymer",{set:function(p){if(origDescriptor&&origDescriptor.set&&origDescriptor.get){origDescriptor.set(p);origPolymer=origDescriptor.get()}else origPolymer=p;if(typeof origPolymer==="function")Object.defineProperty(window,"Polymer",{value:origPolymer,configurable:true,enumerable:true,writable:true})},get:function(){return typeof origPolymer==="function"?newPolymer:origPolymer},configurable:true, 12 + enumerable:true})})();}).call(this); 13 + </script><script nonce="nopnosk9VoEiau3Xtg_3uQ">window.Polymer=window.Polymer||{};window.Polymer.legacyOptimizations=true;window.Polymer.setPassiveTouchGestures=true;window.ShadyDOM={force:true,preferPerformance:true,noPatch:true}; 14 + window.polymerSkipLoadingFontRoboto = true;window.ShadyCSS = {disableRuntime: true};</script><link rel="shortcut icon" href="https://www.youtube.com/s/desktop/156c3d3d/img/favicon.ico" type="image/x-icon"><link rel="icon" href="https://www.youtube.com/s/desktop/156c3d3d/img/favicon_32x32.png" sizes="32x32"><link rel="icon" href="https://www.youtube.com/s/desktop/156c3d3d/img/favicon_48x48.png" sizes="48x48"><link rel="icon" href="https://www.youtube.com/s/desktop/156c3d3d/img/favicon_96x96.png" sizes="96x96"><link rel="icon" href="https://www.youtube.com/s/desktop/156c3d3d/img/favicon_144x144.png" sizes="144x144"><script nonce="nopnosk9VoEiau3Xtg_3uQ">var ytcsi={gt:function(n){n=(n||"")+"data_";return ytcsi[n]||(ytcsi[n]={tick:{},info:{}})},now:window.performance&&window.performance.timing&&window.performance.now&&window.performance.timing.navigationStart?function(){return window.performance.timing.navigationStart+window.performance.now()}:function(){return(new Date).getTime()},tick:function(l,t,n){var ticks=ytcsi.gt(n).tick;var v=t||ytcsi.now();if(ticks[l]){ticks["_"+l]=ticks["_"+l]||[ticks[l]];ticks["_"+l].push(v)}ticks[l]=v},info:function(k, 15 + v,n){ytcsi.gt(n).info[k]=v},setStart:function(t,n){ytcsi.tick("_start",t,n)}}; 16 + (function(w,d){ytcsi.setStart(w.performance?w.performance.timing.responseStart:null);var isPrerender=(d.visibilityState||d.webkitVisibilityState)=="prerender";var vName=!d.visibilityState&&d.webkitVisibilityState?"webkitvisibilitychange":"visibilitychange";if(isPrerender){var startTick=function(){ytcsi.setStart();d.removeEventListener(vName,startTick)};d.addEventListener(vName,startTick,false)}if(d.addEventListener)d.addEventListener(vName,function(){ytcsi.tick("vc")},false);function isGecko(){if(!w.navigator)return false; 17 + try{if(w.navigator.userAgentData&&w.navigator.userAgentData.brands&&w.navigator.userAgentData.brands.length){var brands=w.navigator.userAgentData.brands;for(var i=0;i<brands.length;i++)if(brands[i]&&brands[i].brand==="Firefox")return true;return false}}catch(e){setTimeout(function(){throw e;})}if(!w.navigator.userAgent)return false;var ua=w.navigator.userAgent;return ua.indexOf("Gecko")>0&&ua.toLowerCase().indexOf("webkit")<0&&ua.indexOf("Edge")<0&&ua.indexOf("Trident")<0&&ua.indexOf("MSIE")<0}if(isGecko()){var isHidden= 18 + (d.visibilityState||d.webkitVisibilityState)=="hidden";if(isHidden)ytcsi.tick("vc")}var slt=function(el,t){setTimeout(function(){var n=ytcsi.now();el.loadTime=n;if(el.slt)el.slt()},t)};w.__ytRIL=function(el){if(!el.getAttribute("data-thumb"))if(w.requestAnimationFrame)w.requestAnimationFrame(function(){slt(el,0)});else slt(el,16)}})(window,document); 19 + </script><link rel="preload" href="https://i.ytimg.com/generate_204" as="fetch"><link as="script" rel="preload" href="https://www.youtube.com/s/desktop/156c3d3d/jsbin/desktop_polymer.vflset/desktop_polymer.js" nonce="nopnosk9VoEiau3Xtg_3uQ"><script src="https://www.youtube.com/s/desktop/156c3d3d/jsbin/web-animations-next-lite.min.vflset/web-animations-next-lite.min.js" nonce="nopnosk9VoEiau3Xtg_3uQ"></script><script src="https://www.youtube.com/s/desktop/156c3d3d/jsbin/custom-elements-es5-adapter.vflset/custom-elements-es5-adapter.js" nonce="nopnosk9VoEiau3Xtg_3uQ"></script><script src="https://www.youtube.com/s/desktop/156c3d3d/jsbin/webcomponents-sd.vflset/webcomponents-sd.js" nonce="nopnosk9VoEiau3Xtg_3uQ"></script><script src="https://www.youtube.com/s/desktop/156c3d3d/jsbin/intersection-observer.min.vflset/intersection-observer.min.js" nonce="nopnosk9VoEiau3Xtg_3uQ"></script><script nonce="nopnosk9VoEiau3Xtg_3uQ">if (window.ytcsi) {window.ytcsi.tick('lpcs', null, '');}</script><script nonce="nopnosk9VoEiau3Xtg_3uQ">(function() {window.ytplayer={}; 20 + ytcfg.set({"CLIENT_CANARY_STATE":"none","DEVICE":"cbr\u003dChrome\u0026cbrand\u003dapple\u0026cbrver\u003d109.0.0.0\u0026ceng\u003dWebKit\u0026cengver\u003d537.36\u0026cos\u003dMacintosh\u0026cosver\u003d10_15_7\u0026cplatform\u003dDESKTOP\u0026cyear\u003d2013","DISABLE_YT_IMG_DELAY_LOADING":false,"ELEMENT_POOL_DEFAULT_CAP":75,"EVENT_ID":"h8LiY6bbOsKD6QK505eQCA","EXPERIMENT_FLAGS":{"H5_enable_full_pacf_logging":true,"H5_use_async_logging":true,"allow_skip_networkless":true,"autoescape_tempdata_url":true,"background_thread_flush_logs_due_to_batch_limit":true,"browse_next_continuations_migration_playlist":true,"c3_watch_page_component":true,"cache_utc_offset_minutes_in_pref_cookie":true,"cancel_pending_navs":true,"check_user_lact_at_prompt_shown_time_on_web":true,"clear_user_partitioned_ls":true,"client_respect_autoplay_switch_button_renderer":true,"cold_missing_history":true,"csi_on_gel":true,"decorate_autoplay_renderer":true,"defer_menus":true,"defer_overlays":true,"defer_rendering_outside_visible_area":true,"deprecate_csi_has_info":true,"deprecate_pair_servlet_enabled":true,"deprecate_two_way_binding_child":true,"deprecate_two_way_binding_parent":true,"desktop_add_to_playlist_renderer_dialog_popup":true,"desktop_adjust_touch_target":true,"desktop_animate_miniplayer":true,"desktop_client_release":true,"desktop_delay_player_resizing":true,"desktop_enable_dmpanel_click_drag_scroll":true,"desktop_enable_dmpanel_scroll":true,"desktop_enable_dmpanel_wheel_scroll":true,"desktop_image_cta_no_background":true,"desktop_keyboard_capture_keydown_killswitch":true,"desktop_log_img_click_location":true,"desktop_mix_use_sampled_color_for_bottom_bar":true,"desktop_mix_use_sampled_color_for_bottom_bar_search":true,"desktop_mix_use_sampled_color_for_bottom_bar_watch_next":true,"desktop_notification_high_priority_ignore_push":true,"desktop_notification_set_title_bar":true,"desktop_persistent_menu":true,"desktop_search_prominent_thumbs":true,"desktop_sparkles_light_cta_button":true,"desktop_swipeable_guide":true,"desktop_themeable_vulcan":true,"desktop_touch_gestures_usage_log":true,"desktop_use_new_history_manager":true,"disable_child_node_auto_formatted_strings":true,"disable_dependency_injection":true,"disable_exif_rotation_for_image_posts":true,"disable_features_for_supex":true,"disable_legacy_desktop_remote_queue":true,"disable_open_in_new_window_on_discovery_ads_search_desktop":true,"disable_pacf_logging_for_memory_limited_tv":true,"disable_simple_mixed_direction_formatted_strings":true,"disable_thumbnail_preloading":true,"embeds_web_enable_replace_unload_w_pagehide":true,"embeds_web_nwl_disable_nocookie":true,"enable_audio_pivot_back_nav_button":true,"enable_button_behavior_reuse":true,"enable_call_to_action_clarification_renderer_bottom_section_conditions":true,"enable_client_sli_logging":true,"enable_client_streamz_web":true,"enable_commerce_action_request_sequencing":true,"enable_desktop_amsterdam_info_panels":true,"enable_docked_chat_messages":true,"enable_gel_log_commands":true,"enable_get_account_switcher_endpoint_on_webfe":true,"enable_handles_account_menu_switcher":true,"enable_handles_in_mention_suggest_posts":true,"enable_handoff_location_2fa_on_mweb":true,"enable_header_channel_handler_ui":true,"enable_hlp_client_icon_pick":true,"enable_image_poll_post_creation":true,"enable_inline_preview_controls":true,"enable_inline_shorts_on_wn":true,"enable_madison_search_migration":true,"enable_masthead_quartile_ping_fix":true,"enable_memberships_and_purchases":true,"enable_mentions_in_reposts":true,"enable_microformat_data":true,"enable_mixed_direction_formatted_strings":true,"enable_multi_image_post_creation":true,"enable_names_handles_account_switcher":true,"enable_offer_suppression":true,"enable_on_yt_command_executor_command_to_navigate":true,"enable_poll_choice_border_on_web":true,"enable_polymer_resin":true,"enable_polymer_resin_migration":true,"enable_post_cct_links":true,"enable_post_scheduling":true,"enable_premium_voluntary_pause":true,"enable_programmed_playlist_color_sample":true,"enable_programmed_playlist_redesign":true,"enable_purchase_activity_in_paid_memberships":true,"enable_reel_watch_sequence":true,"enable_rendererstamper_listener_cleanup":true,"enable_rta_manager":true,"enable_seedless_shorts_url":true,"enable_server_stitched_dai":true,"enable_service_ajax_csn":true,"enable_servlet_errors_streamz":true,"enable_servlet_streamz":true,"enable_sfv_audio_pivot_url":true,"enable_shorts_on_library":true,"enable_shorts_singleton_channel_web":true,"enable_signals":true,"enable_skip_ad_guidance_prompt":true,"enable_skippable_ads_for_unplugged_ad_pod":true,"enable_smearing_expansion_dai":true,"enable_squiffle_gif_handles_landing_page":true,"enable_streamline_repost_flow":true,"enable_structured_description_shorts_web_mweb":true,"enable_tectonic_ad_ux_for_halftime":true,"enable_third_party_info":true,"enable_topsoil_wta_for_halftime_live_infra":true,"enable_unavailable_videos_watch_page":true,"enable_unified_show_page_web_client":true,"enable_watch_next_pause_autoplay_lact":true,"enable_web_ketchup_hero_animation":true,"enable_web_poster_hover_animation":true,"enable_web_shorts_audio_pivot":true,"enable_yoodle":true,"enable_ypc_spinners":true,"enable_ytc_refunds_submit_form_signal_action":true,"enable_ytc_self_serve_refunds":true,"endpoint_handler_logging_cleanup_killswitch":true,"export_networkless_options":true,"external_fullscreen":true,"external_fullscreen_with_edu":true,"fill_single_video_with_notify_to_lasr":true,"gcf_config_store_enabled":true,"gfeedback_for_signed_out_users_enabled":true,"global_spacebar_pause":true,"gpa_sparkles_ten_percent_layer":true,"h5_companion_enable_adcpn_macro_substitution_for_click_pings":true,"h5_inplayer_enable_adcpn_macro_substitution_for_click_pings":true,"hide_endpoint_overflow_on_ytd_display_ad_renderer":true,"html5_control_flow_include_trigger_logging_in_tmp_logs":true,"html5_enable_ads_client_monitoring_log_tv":true,"html5_enable_single_video_vod_ivar_on_pacf":true,"html5_log_trigger_events_with_debug_data":true,"html5_recognize_predict_start_cue_point":true,"html5_server_stitched_dai_group":true,"html5_web_enable_halftime_preroll":true,"il_use_view_model_logging_context":true,"include_autoplay_count_in_playlists":true,"is_browser_support_for_webcam_streaming":true,"is_part_of_any_user_engagement_experiment":true,"json_condensed_response":true,"kevlar_app_shortcuts":true,"kevlar_appbehavior_attach_startup_tasks":true,"kevlar_append_toggled_engagement_panels_top":true,"kevlar_appshell_service_worker":true,"kevlar_autofocus_menu_on_keyboard_nav":true,"kevlar_autonav_popup_filtering":true,"kevlar_av_eliminate_polling":true,"kevlar_background_color_update":true,"kevlar_cache_cold_load_response":true,"kevlar_cache_on_ttl_player":true,"kevlar_cache_on_ttl_search":true,"kevlar_calculate_grid_collapsible":true,"kevlar_cancel_scheduled_comment_jobs_on_navigate":true,"kevlar_center_search_results":true,"kevlar_channel_creation_form_resolver":true,"kevlar_channel_trailer_multi_attach":true,"kevlar_chapters_list_view_seek_by_chapter":true,"kevlar_clear_duplicate_pref_cookie":true,"kevlar_clear_non_displayable_url_params":true,"kevlar_client_side_screens":true,"kevlar_command_handler":true,"kevlar_command_handler_clicks":true,"kevlar_command_handler_formatted_string":true,"kevlar_command_url":true,"kevlar_decorate_endpoint_with_onesie_config":true,"kevlar_delay_watch_initial_data":true,"kevlar_disable_background_prefetch":true,"kevlar_disable_pending_command":true,"kevlar_downloads_on_home":true,"kevlar_dragdrop_fast_scroll":true,"kevlar_dropdown_fix":true,"kevlar_droppable_prefetchable_requests":true,"kevlar_early_popup_close":true,"kevlar_enable_download_upsell_type_a":true,"kevlar_enable_editable_playlists":true,"kevlar_enable_reorderable_playlists":true,"kevlar_enable_shorts_prefetch_in_sequence":true,"kevlar_enable_shorts_response_chunking":true,"kevlar_enable_slis":true,"kevlar_enable_up_arrow":true,"kevlar_enable_upsell_on_video_menu":true,"kevlar_enable_ybp_op_for_shoptube":true,"kevlar_exit_fullscreen_leaving_watch":true,"kevlar_fix_playlist_continuation":true,"kevlar_flexible_menu":true,"kevlar_fluid_touch_scroll":true,"kevlar_frontend_queue_recover":true,"kevlar_gel_error_routing":true,"kevlar_guide_refresh":true,"kevlar_help_use_locale":true,"kevlar_hide_playlist_playback_status":true,"kevlar_hide_pp_url_param":true,"kevlar_hide_time_continue_url_param":true,"kevlar_home_shorts_grid_alignment":true,"kevlar_home_skeleton":true,"kevlar_home_skeleton_hide_later":true,"kevlar_js_fixes":true,"kevlar_keyboard_button_focus":true,"kevlar_larger_three_dot_tap":true,"kevlar_lazy_list_resume_for_autofill":true,"kevlar_live_report_menu_item":true,"kevlar_local_innertube_response":true,"kevlar_macro_markers_keyboard_shortcut":true,"kevlar_masthead_store":true,"kevlar_mealbar_above_player":true,"kevlar_miniplayer":true,"kevlar_miniplayer_expand_top":true,"kevlar_miniplayer_play_pause_on_scrim":true,"kevlar_miniplayer_queue_user_activation":true,"kevlar_mix_handle_first_endpoint_different":true,"kevlar_modern_sd":true,"kevlar_network_banner":true,"kevlar_next_cold_on_auth_change_detected":true,"kevlar_nitrate_driven_tooltips":true,"kevlar_no_autoscroll_on_playlist_hover":true,"kevlar_op_infra":true,"kevlar_op_warm_pages":true,"kevlar_pandown_polyfill":true,"kevlar_passive_event_listeners":true,"kevlar_playback_associated_queue":true,"kevlar_player_cached_load_config":true,"kevlar_player_check_ad_state_on_stop":true,"kevlar_player_load_player_no_op":true,"kevlar_player_new_bootstrap_adoption":true,"kevlar_player_playlist_use_local_index":true,"kevlar_player_watch_endpoint_navigation":true,"kevlar_playlist_drag_handles":true,"kevlar_playlist_responsive":true,"kevlar_playlist_use_x_close_button":true,"kevlar_prefetch":true,"kevlar_prevent_polymer_dynamic_font_load":true,"kevlar_queue_use_update_api":true,"kevlar_refresh_gesture":true,"kevlar_refresh_on_theme_change":true,"kevlar_rendererstamper_event_listener":true,"kevlar_replace_short_to_short_history_state":true,"kevlar_request_sequencing":true,"kevlar_resolve_command_for_confirm_dialog":true,"kevlar_resolve_playlist_endpoint_as_watch_endpoint":true,"kevlar_response_command_processor_page":true,"kevlar_scroll_chips_on_touch":true,"kevlar_scrollbar_rework":true,"kevlar_service_command_check":true,"kevlar_set_internal_player_size":true,"kevlar_shell_for_downloads_page":true,"kevlar_should_maintain_stable_list":true,"kevlar_smart_downloads":true,"kevlar_smart_downloads_setting":true,"kevlar_startup_lifecycle":true,"kevlar_structured_description_content_inline":true,"kevlar_system_icons":true,"kevlar_tabs_gesture":true,"kevlar_text_inline_expander_formatted_snippet":true,"kevlar_three_dot_ink":true,"kevlar_thumbnail_fluid":true,"kevlar_toast_manager":true,"kevlar_topbar_logo_fallback_home":true,"kevlar_touch_feedback":true,"kevlar_touch_feedback_lockups":true,"kevlar_touch_gesture_ves":true,"kevlar_transcript_engagement_panel":true,"kevlar_tuner_run_default_comments_delay":true,"kevlar_tuner_should_defer_detach":true,"kevlar_typography_spacing_update":true,"kevlar_typography_update":true,"kevlar_unavailable_video_error_ui_client":true,"kevlar_unified_errors_init":true,"kevlar_use_response_ttl_to_invalidate_cache":true,"kevlar_use_vimio_behavior":true,"kevlar_use_ytd_player":true,"kevlar_variable_youtube_sans":true,"kevlar_vimio_use_shared_monitor":true,"kevlar_voice_logging_fix":true,"kevlar_voice_search":true,"kevlar_watch_cinematics":true,"kevlar_watch_color_update":true,"kevlar_watch_comments_ep_disable_theater":true,"kevlar_watch_drag_handles":true,"kevlar_watch_flexy_autonav_manager":true,"kevlar_watch_flexy_use_controller":true,"kevlar_watch_focus_on_engagement_panels":true,"kevlar_watch_gesture_pandown":true,"kevlar_watch_hide_comments_teaser":true,"kevlar_watch_hide_comments_while_panel_open":true,"kevlar_watch_js_panel_height":true,"kevlar_watch_metadata_refresh":true,"kevlar_watch_metadata_refresh_attached_subscribe":true,"kevlar_watch_metadata_refresh_clickable_description":true,"kevlar_watch_metadata_refresh_compact_view_count":true,"kevlar_watch_metadata_refresh_description_info_dedicated_line":true,"kevlar_watch_metadata_refresh_description_inline_expander":true,"kevlar_watch_metadata_refresh_description_primary_color":true,"kevlar_watch_metadata_refresh_for_live_killswitch":true,"kevlar_watch_metadata_refresh_full_width_description":true,"kevlar_watch_metadata_refresh_left_aligned_video_actions":true,"kevlar_watch_metadata_refresh_lower_case_video_actions":true,"kevlar_watch_metadata_refresh_narrower_item_wrap":true,"kevlar_watch_metadata_refresh_relative_date":true,"kevlar_watch_metadata_refresh_top_aligned_actions":true,"kevlar_watch_modern_metapanel":true,"kevlar_watch_modern_panels":true,"kevlar_watch_panel_height_matches_player":true,"kevlar_woffle":true,"kevlar_woffle_fallback_image":true,"kevlar_ytb_live_badges":true,"killswitch_toggle_button_behavior_resolve_command":true,"live_chat_banner_expansion_fix":true,"live_chat_collapse_merch_banner":true,"live_chat_enable_qna_banner_overflow_menu_actions":true,"live_chat_enable_qna_channel":true,"live_chat_increased_min_height":true,"live_chat_over_playlist":true,"live_chat_use_new_emoji_picker":true,"log_errors_through_nwl_on_retry":true,"log_heartbeat_with_lifecycles":true,"log_vis_on_tab_change":true,"log_web_endpoint_to_layer":true,"mdx_enable_privacy_disclosure_ui":true,"mdx_load_cast_api_bootstrap_script":true,"migrate_events_to_ts":true,"music_on_main_handle_playlist_edit_video_added_result_data":true,"mweb_actions_command_handler":true,"mweb_command_handler":true,"mweb_disable_set_autonav_state_in_player":true,"mweb_enable_consistency_service":true,"mweb_enable_hlp":true,"mweb_logo_use_home_page_ve":true,"mweb_navigate_to_watch_with_op":true,"networkless_gel":true,"networkless_logging":true,"no_sub_count_on_sub_button":true,"nwl_send_fast_on_unload":true,"nwl_send_from_memory_when_online":true,"offline_error_handling":true,"pageid_as_header_web":true,"parse_query_data_from_url":true,"pause_ad_video_on_desktop_engagement_panel_click":true,"pdg_enable_flow_logging_for_super_chat":true,"pdg_enable_flow_logging_for_super_stickers":true,"player_allow_autonav_after_playlist":true,"player_bootstrap_method":true,"player_doubletap_to_seek":true,"player_enable_playback_playlist_change":true,"player_endscreen_ellipsis_fix":true,"polymer_bad_build_labels":true,"polymer_task_manager_proxied_promise":true,"polymer_verifiy_app_state":true,"polymer_video_renderer_defer_menu":true,"polymer_warm_thumbnail_preload":true,"polymer_ytdi_enable_global_injector":true,"problem_walkthrough_sd":true,"qoe_send_and_write":true,"record_app_crashed_web":true,"reload_without_polymer_innertube":true,"remove_web_comment_id_cache":true,"remove_yt_simple_endpoint_from_desktop_display_ad_title":true,"rich_grid_mini_mode":true,"rich_grid_watch_meta_side":true,"rich_grid_watch_show_watch_next":true,"scheduler_use_raf_by_default":true,"search_ui_enable_pve_buy_button":true,"search_ui_official_cards_enable_paid_virtual_event_buy_button":true,"searchbox_reporting":true,"serve_pdp_at_canonical_url":true,"service_worker_enabled":true,"service_worker_push_enabled":true,"service_worker_push_home_page_prompt":true,"service_worker_push_watch_page_prompt":true,"service_worker_subscribe_with_vapid_key":true,"should_clear_video_data_on_player_cued_unstarted":true,"show_civ_reminder_on_web":true,"skip_invalid_ytcsi_ticks":true,"skip_ls_gel_retry":true,"skip_setting_info_in_csi_data_object":true,"sponsorships_gifting_enable_announcements":true,"sponsorships_gifting_enable_opt_in":true,"sponsorships_gifting_enable_purchase":true,"start_client_gcf":true,"start_client_gcf_for_player":true,"super_sticker_emoji_picker_category_button_icon_filled":true,"suppress_error_204_logging":true,"track_webfe_innertube_auth_mismatch":true,"transport_use_scheduler":true,"use_ads_engagement_panel_desktop_footer_cta":true,"use_better_post_dismissals":true,"use_border_and_grid_wrapping_on_desktop_panel_tiles":true,"use_new_in_memory_storage":true,"use_new_nwl_initialization":true,"use_new_nwl_saw":true,"use_new_nwl_stw":true,"use_new_nwl_wts":true,"use_on_click_for_desktop_companion":true,"use_player_abuse_bg_library":true,"use_profilepage_event_label_in_carousel_playbacks":true,"use_request_time_ms_header":true,"use_rta_manager_for_async":true,"use_session_based_sampling":true,"use_shared_nsm":true,"use_shared_nsm_and_keep_yt_online_updated":true,"use_source_element_if_present_for_actions":true,"use_ts_visibilitylogger":true,"use_watch_fragments2":true,"verify_ads_itag_early":true,"vss_final_ping_send_and_write":true,"vss_playback_use_send_and_write":true,"warm_load_nav_start_web":true,"warm_op_csn_cleanup":true,"web_always_load_chat_support":true,"web_amsterdam_playlists":true,"web_amsterdam_post_mvp_playlists":true,"web_animated_like":true,"web_animated_like_lazy_load":true,"web_api_url":true,"web_appshell_purge_trigger":true,"web_appshell_refresh_trigger":true,"web_autonav_allow_off_by_default":true,"web_button_rework":true,"web_darker_dark_theme":true,"web_darker_dark_theme_deprecate":true,"web_dedupe_ve_grafting":true,"web_defer_shorts_ui":true,"web_defer_shorts_ui_phase2":true,"web_deprecate_service_ajax_map_dependency":true,"web_enable_history_cache_map":true,"web_enable_video_preview_migration":true,"web_enable_voz_audio_feedback":true,"web_engagement_panel_show_description":true,"web_ep_chevron_tap_target_size":true,"web_filled_subscribed_button":true,"web_forward_command_on_pbj":true,"web_gel_timeout_cap":true,"web_guide_ui_refresh":true,"web_hide_autonav_headline":true,"web_hide_autonav_keyline":true,"web_inline_player_enabled":true,"web_kevlar_enable_adaptive_signals":true,"web_log_memory_total_kbytes":true,"web_log_player_watch_next_ticks":true,"web_log_reels_ticks":true,"web_modern_ads":true,"web_modern_buttons":true,"web_modern_buttons_bl_survey":true,"web_modern_chips":true,"web_modern_dialogs":true,"web_modern_playlists":true,"web_modern_subscribe":true,"web_move_autoplay_video_under_chip":true,"web_moved_super_title_link":true,"web_one_platform_error_handling":true,"web_player_autonav_toggle_always_listen":true,"web_player_autonav_use_server_provided_state":true,"web_player_decouple_autonav":true,"web_player_enable_early_warning_snackbar":true,"web_player_enable_ipp":true,"web_player_enable_premium_hbr_in_h5_api":true,"web_player_enable_premium_hbr_playback_cap":true,"web_player_entities_middleware":true,"web_player_move_autonav_toggle":true,"web_player_mutable_event_label":true,"web_player_should_honor_include_asr_setting":true,"web_player_small_hbp_settings_menu":true,"web_player_touch_mode_improvements":true,"web_player_use_new_api_for_quality_pullback":true,"web_player_watch_next_response":true,"web_prefetch_preload_video":true,"web_prs_testing_mode_killswitch":true,"web_repeating_chapters":true,"web_replace_thumbnail_with_image":true,"web_rounded_containers":true,"web_rounded_thumbnails":true,"web_segmented_like_dislike_button":true,"web_sheets_ui_refresh":true,"web_shorts_early_player_load":true,"web_shorts_progress_bar":true,"web_shorts_shelf_on_search":true,"web_shorts_skip_loading_same_index":true,"web_snackbar_ui_refresh":true,"web_structured_description_show_more":true,"web_use_cache_for_image_fallback":true,"web_yt_config_context":true,"woffle_clean_up_after_entity_migration":true,"woffle_orchestration":true,"your_data_entrypoint":true,"yt_network_manager_component_to_lib_killswitch":true,"ytidb_clear_embedded_player":true,"ytidb_fetch_datasync_ids_for_data_cleanup":true,"H5_async_logging_delay_ms":30000.0,"addto_ajax_log_warning_fraction":0.1,"autoplay_pause_by_lact_sampling_fraction":0.0,"browse_ajax_log_warning_fraction":1.0,"cinematic_watch_effect_opacity":0.4,"kevlar_tuner_clamp_device_pixel_ratio":2.0,"kevlar_tuner_thumbnail_factor":1.0,"kevlar_unified_player_logging_threshold":1.0,"log_window_onerror_fraction":0.1,"polymer_report_client_url_requested_rate":0.001,"polymer_report_missing_web_navigation_endpoint_rate":0.001,"prefetch_coordinator_error_logging_sampling_rate":1.0,"tv_pacf_logging_sample_rate":0.01,"web_shorts_error_logging_threshold":0.001,"web_shorts_intersection_observer_threshold_override":0.0,"web_system_health_fraction":0.01,"ytidb_transaction_ended_event_rate_limit":0.02,"ytidb_transaction_ended_event_rate_limit_session":0.2,"ytidb_transaction_ended_event_rate_limit_transaction":0.1,"autoplay_pause_by_lact_sec":0,"autoplay_time":8000,"autoplay_time_for_fullscreen":3000,"autoplay_time_for_music_content":3000,"botguard_async_snapshot_timeout_ms":3000,"check_navigator_accuracy_timeout_ms":0,"cinematic_watch_css_filter_blur_strength":40,"cinematic_watch_fade_out_duration":500,"client_streamz_web_flush_count":100,"client_streamz_web_flush_interval_seconds":60,"desktop_search_suggestion_tap_target":0,"external_fullscreen_button_click_threshold":2,"external_fullscreen_button_shown_threshold":10,"get_async_timeout_ms":60000,"high_priority_flyout_frequency":3,"initial_gel_batch_timeout":2000,"kevlar_mini_guide_width_threshold":791,"kevlar_persistent_guide_width_threshold":1312,"kevlar_time_caching_end_threshold":15,"kevlar_time_caching_start_threshold":15,"kevlar_tooltip_impression_cap":2,"kevlar_tuner_default_comments_delay":1000,"kevlar_tuner_scheduler_soft_state_timer_ms":800,"kevlar_tuner_visibility_time_between_jobs_ms":100,"kevlar_watch_flexy_metadata_height":136,"kevlar_watch_metadata_refresh_description_lines":3,"live_chat_chunk_rendering":0,"log_web_meta_interval_ms":0,"max_duration_to_consider_mouseover_as_hover":600000,"max_prefetch_window_sec_for_livestream_optimization":10,"min_mouse_still_duration":100,"min_prefetch_offset_sec_for_livestream_optimization":20,"minimum_duration_to_consider_mouseover_as_hover":500,"mweb_history_manager_cache_size":100,"network_polling_interval":30000,"pbj_navigate_limit":-1,"polymer_log_prop_change_observer_percent":0,"post_type_icons_rearrange":1,"prefetch_comments_ms_after_video":0,"prefetch_coordinator_command_timeout_ms":60000,"prefetch_coordinator_max_inflight_requests":1,"rich_grid_watch_open_animation_duration":0,"send_config_hash_timer":0,"service_worker_push_logged_out_prompt_watches":-1,"service_worker_push_prompt_cap":-1,"service_worker_push_prompt_delay_microseconds":3888000000000,"shorts_inline_player_triggering_delay":500,"user_engagement_experiments_rate_limit_ms":86400000,"user_mention_suggestions_edu_impression_cap":10,"visibility_time_between_jobs_ms":100,"watch_next_pause_autoplay_lact_sec":4500,"web_emulated_idle_callback_delay":0,"web_foreground_heartbeat_interval_ms":28000,"web_gel_debounce_ms":10000,"web_home_feed_reload_delay":1440,"web_inline_player_triggering_delay":1000,"web_logging_max_batch":150,"web_player_caption_language_preference_stickiness_duration":0,"web_search_inline_player_triggering_delay":1000,"web_shorts_inline_playback_preview_ms":0,"web_shorts_scrubber_threshold_sec":0,"web_shorts_shelf_fixed_position":9,"web_smoothness_test_duration_ms":0,"web_smoothness_test_method":0,"yoodle_end_time_utc":0,"yoodle_start_time_utc":0,"ytidb_remake_db_retries":3,"ytidb_reopen_db_retries":3,"WebClientReleaseProcessCritical__youtube_web_client_version_override":"","debug_forced_internalcountrycode":"","desktop_search_bigger_thumbs_style":"DEFAULT","desktop_search_prominent_thumbs_style":"DEFAULT","desktop_searchbar_style":"default","embeds_web_synth_ch_headers_banned_urls_regex":"","kevlar_duplicate_pref_cookie_domain_override":"","kevlar_link_capturing_mode":"","live_chat_unicode_emoji_json_url":"https://www.gstatic.com/youtube/img/emojis/emojis-svg-9.json","polymer_task_manager_status":"production","service_worker_push_force_notification_prompt_tag":"1","service_worker_scope":"/","web_client_version_override":"","web_modern_subscribe_style":"filled","web_searchbar_style":"rounded_corner_borders_light_btn","web_shorts_expanded_overlay_type":"GLOBAL","web_shorts_overlay_vertical_orientation":"bottom","yoodle_base_url":"","yoodle_webp_base_url":"","conditional_lab_ids":[],"guide_business_info_countries":["KR"],"guide_legal_footer_enabled_countries":["NL","ES"],"kevlar_command_handler_command_banlist":[],"kevlar_page_service_url_prefix_carveouts":[],"web_op_signal_type_banlist":[]},"GAPI_HINT_PARAMS":"m;/_/scs/abc-static/_/js/k\u003dgapi.gapi.en.3R2S2iMRC9o.O/d\u003d1/rs\u003dAHpOoo8-ukmJKpOYaCGRb909wNTowBRXFA/m\u003d__features__","GAPI_HOST":"https://apis.google.com","GAPI_LOCALE":"en_US","GL":"CA","GOOGLE_FEEDBACK_PRODUCT_ID":"59","GOOGLE_FEEDBACK_PRODUCT_DATA":{"polymer":"active","polymer2":"active","accept_language":"en-CA,en;q\u003d0.9,fa-IR;q\u003d0.8,fa;q\u003d0.7,en-GB;q\u003d0.6,en-US;q\u003d0.5"},"HL":"en","HTML_DIR":"ltr","HTML_LANG":"en","ID_TOKEN":"QUFFLUhqa0FldldtOVRsbjVWQ3ZGek1Gb3dhSFU5RHJWQXw\u003d","INNERTUBE_API_KEY":"AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8","INNERTUBE_API_VERSION":"v1","INNERTUBE_CLIENT_NAME":"WEB","INNERTUBE_CLIENT_VERSION":"2.20230201.01.00","INNERTUBE_CONTEXT":{"client":{"hl":"en","gl":"CA","remoteHost":"74.12.195.102","deviceMake":"Apple","deviceModel":"","visitorData":"CgtWLUUwMFpXMzdWQSiHhYufBg%3D%3D","userAgent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36,gzip(gfe)","clientName":"WEB","clientVersion":"2.20230201.01.00","osName":"Macintosh","osVersion":"10_15_7","originalUrl":"https://www.youtube.com/@penguinz0","screenPixelDensity":2,"platform":"DESKTOP","clientFormFactor":"UNKNOWN_FORM_FACTOR","configInfo":{"appInstallData":"CIeFi58GEOSg_hIQh92uBRDyov4SEMzfrgUQieiuBRDX5K4FEOqi_hIQlPiuBRCjgK8FEIuArwUQ4tSuBRDM9a4FELiLrgUQ-6P-EhC41K4FEILdrgUQ_u6uBRDa6a4FEOf3rgUQtpz-EhCO-64FEKLsrgUQ-sWuBRCJ_K4FEO2j_hIQkfj8Eg%3D%3D"},"screenDensityFloat":2.0,"userInterfaceTheme":"USER_INTERFACE_THEME_DARK","timeZone":"America/Toronto","browserName":"Chrome","browserVersion":"109.0.0.0","acceptHeader":"text/html,application/xhtml+xml,application/xml;q\u003d0.9,image/avif,image/webp,image/apng,*/*;q\u003d0.8,application/signed-exchange;v\u003db3;q\u003d0.9","deviceExperimentId":"ChxOekUzTnpRMk1ESXdOVGN5TkRVMU5UTTBNdz09EIeFi58GGIfs7ZwG"},"user":{"lockedSafetyMode":false},"request":{"useSsl":true},"clickTracking":{"clickTrackingParams":"IhMI5rq8pq2E/QIVwkFaCh256QWC"}},"INNERTUBE_CONTEXT_CLIENT_NAME":1,"INNERTUBE_CONTEXT_CLIENT_VERSION":"2.20230201.01.00","INNERTUBE_CONTEXT_GL":"CA","INNERTUBE_CONTEXT_HL":"en","LATEST_ECATCHER_SERVICE_TRACKING_PARAMS":{"client.name":"WEB"},"LOGGED_IN":true,"PAGE_BUILD_LABEL":"youtube.desktop.web_20230201_01_RC00","PAGE_CL":506236239,"scheduler":{"useRaf":true,"timeout":20},"SERVER_NAME":"WebFE","SESSION_INDEX":"0","SIGNIN_URL":"https://accounts.google.com/ServiceLogin?service\u003dyoutube\u0026uilel\u003d3\u0026passive\u003dtrue\u0026continue\u003dhttps%3A%2F%2Fwww.youtube.com%2Fsignin%3Faction_handle_signin%3Dtrue%26app%3Ddesktop%26hl%3Den%26next%3Dhttps%253A%252F%252Fwww.youtube.com%252F%2540penguinz0%26feature%3D__FEATURE__\u0026hl\u003den\u0026authuser\u003d0","VISITOR_DATA":"CgtWLUUwMFpXMzdWQSiHhYufBg%3D%3D","WEB_PLAYER_CONTEXT_CONFIGS":{"WEB_PLAYER_CONTEXT_CONFIG_ID_KEVLAR_WATCH":{"transparentBackground":true,"showMiniplayerButton":true,"externalFullscreen":true,"showMiniplayerUiWhenMinimized":true,"rootElementId":"movie_player","jsUrl":"/s/player/97ea7458/player_ias.vflset/en_US/base.js","cssUrl":"/s/player/97ea7458/www-player.css","contextId":"WEB_PLAYER_CONTEXT_CONFIG_ID_KEVLAR_WATCH","eventLabel":"detailpage","contentRegion":"CA","hl":"en_US","hostLanguage":"en","playerStyle":"desktop-polymer","innertubeApiKey":"AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8","innertubeApiVersion":"v1","innertubeContextClientVersion":"2.20230201.01.00","device":{"brand":"apple","model":"","browser":"Chrome","browserVersion":"109.0.0.0","os":"Macintosh","osVersion":"10_15_7","platform":"DESKTOP","interfaceName":"WEB","interfaceVersion":"2.20230201.01.00","deviceYear":2013},"serializedExperimentIds":"23983296,23986016,24004644,24007246,24080738,24135310,24169501,24219381,24255163,24282011,24396645,24415864,24416291,24416441,24433679,24437577,24439361,24441240,24449113,24449639,24450366,24451032,24454357,24454498,24457577,24457884,24460376,24463912,24469897","serializedExperimentFlags":"H5_async_logging_delay_ms\u003d30000.0\u0026H5_enable_full_pacf_logging\u003dtrue\u0026H5_use_async_logging\u003dtrue\u0026ad_pod_disable_companion_persist_ads_quality\u003dtrue\u0026addto_ajax_log_warning_fraction\u003d0.1\u0026align_ad_to_video_player_lifecycle_for_bulleit\u003dtrue\u0026allow_live_autoplay\u003dtrue\u0026allow_poltergust_autoplay\u003dtrue\u0026allow_skip_networkless\u003dtrue\u0026autoplay_time\u003d8000\u0026autoplay_time_for_fullscreen\u003d3000\u0026autoplay_time_for_music_content\u003d3000\u0026background_thread_flush_logs_due_to_batch_limit\u003dtrue\u0026bg_vm_reinit_threshold\u003d7200000\u0026blocked_packages_for_sps\u003d[]\u0026botguard_async_snapshot_timeout_ms\u003d3000\u0026check_ad_ui_status_for_mweb_safari\u003dtrue\u0026check_navigator_accuracy_timeout_ms\u003d0\u0026clear_user_partitioned_ls\u003dtrue\u0026client_respect_autoplay_switch_button_renderer\u003dtrue\u0026csi_on_gel\u003dtrue\u0026dash_manifest_version\u003d5\u0026debug_bandaid_hostname\u003d\u0026debug_sherlog_username\u003d\u0026delay_ads_gvi_call_on_bulleit_living_room_ms\u003d0\u0026deprecate_csi_has_info\u003dtrue\u0026deprecate_pair_servlet_enabled\u003dtrue\u0026deprecate_two_way_binding_child\u003dtrue\u0026deprecate_two_way_binding_parent\u003dtrue\u0026desktop_image_cta_no_background\u003dtrue\u0026desktop_log_img_click_location\u003dtrue\u0026desktop_player_button_tooltip_with_shortcut\u003dtrue\u0026desktop_sparkles_light_cta_button\u003dtrue\u0026disable_channel_id_check_for_suspended_channels\u003dtrue\u0026disable_child_node_auto_formatted_strings\u003dtrue\u0026disable_defer_admodule_on_advertiser_video\u003dtrue\u0026disable_features_for_supex\u003dtrue\u0026disable_legacy_desktop_remote_queue\u003dtrue\u0026disable_mdx_connection_in_mdx_module_for_music_web\u003dtrue\u0026disable_new_pause_state3\u003dtrue\u0026disable_pacf_logging_for_memory_limited_tv\u003dtrue\u0026disable_rounding_ad_notify\u003dtrue\u0026disable_simple_mixed_direction_formatted_strings\u003dtrue\u0026disable_ssdai_on_errors\u003dtrue\u0026disable_tabbing_before_flyout_ad_elements_appear\u003dtrue\u0026disable_thumbnail_preloading\u003dtrue\u0026embeds_enable_allow_watch_again_endscreen_for_eligible_shorts\u003dtrue\u0026embeds_enable_embed_module\u003dtrue\u0026embeds_enable_shorts_branded_ui\u003dtrue\u0026embeds_enable_shorts_links_for_eligible_shorts\u003dtrue\u0026embeds_web_enable_gws_wh_rel_off\u003dtrue\u0026embeds_web_enable_info_panel_preview\u003dtrue\u0026embeds_web_enable_load_player_from_page_show\u003dtrue\u0026embeds_web_enable_logging_event_handlers\u003dtrue\u0026embeds_web_enable_pem_domain_fix_for_ad_requests\u003dtrue\u0026embeds_web_enable_replace_unload_w_pagehide\u003dtrue\u0026embeds_web_enable_ve_conversion_logging_tracking_no_allow_list\u003dtrue\u0026embeds_web_enable_video_data_refactoring_break_down_and_move_methods\u003dtrue\u0026embeds_web_enable_video_data_refactoring_like_button_renderer\u003dtrue\u0026embeds_web_hide_unfilled_more_videos_suggestions\u003dtrue\u0026embeds_web_lite_mode\u003d1\u0026embeds_web_nwl_disable_nocookie\u003dtrue\u0026embeds_web_synth_ch_headers_banned_urls_regex\u003d\u0026enable_ad_cpn_macro_substitution_for_click_pings\u003dtrue\u0026enable_cast_for_web_unplugged\u003dtrue\u0026enable_cast_on_music_web\u003dtrue\u0026enable_client_page_id_header_for_first_party_pings\u003dtrue\u0026enable_client_sli_logging\u003dtrue\u0026enable_discrete_live_precise_embargos\u003dtrue\u0026enable_error_corrections_infocard\u003dtrue\u0026enable_error_corrections_infocard_web_client\u003dtrue\u0026enable_error_corrections_infocard_web_client_check\u003dtrue\u0026enable_error_corrections_infocards_icon_web\u003dtrue\u0026enable_eviction_protection_for_bulleit\u003dtrue\u0026enable_gel_log_commands\u003dtrue\u0026enable_handles_account_menu_switcher\u003dtrue\u0026enable_inline_preview_controls\u003dtrue\u0026enable_live_premiere_web_player_indicator\u003dtrue\u0026enable_lr_home_infeed_ads_inline_playback_progress_pings\u003dtrue\u0026enable_macro_substitution_on_html5\u003dtrue\u0026enable_mixed_direction_formatted_strings\u003dtrue\u0026enable_mweb_livestream_ui_update\u003dtrue\u0026enable_new_paid_product_placement\u003dtrue\u0026enable_post_ad_perception_survey_fix_on_tvhtml5\u003dtrue\u0026enable_post_ad_perception_survey_in_tvhtml5\u003dtrue\u0026enable_precise_embargos\u003dtrue\u0026enable_server_stitched_dai\u003dtrue\u0026enable_shorts_player\u003dtrue\u0026enable_skip_ad_guidance_prompt\u003dtrue\u0026enable_skippable_ads_for_unplugged_ad_pod\u003dtrue\u0026enable_smearing_expansion_dai\u003dtrue\u0026enable_tectonic_ad_ux_for_halftime\u003dtrue\u0026enable_third_party_info\u003dtrue\u0026enable_topsoil_wta_for_halftime_live_infra\u003dtrue\u0026enable_web_media_session_metadata_fix\u003dtrue\u0026error_message_for_gsuite_network_restrictions\u003dtrue\u0026export_networkless_options\u003dtrue\u0026external_fullscreen_with_edu\u003dtrue\u0026fast_autonav_in_background\u003dtrue\u0026fetch_att_independently\u003dtrue\u0026fill_single_video_with_notify_to_lasr\u003dtrue\u0026filter_vp9_for_csdai\u003dtrue\u0026fix_ads_tracking_for_swf_config_deprecation_mweb\u003dtrue\u0026gcf_config_store_enabled\u003dtrue\u0026gpa_sparkles_ten_percent_layer\u003dtrue\u0026gvi_channel_client_screen\u003dtrue\u0026h5_companion_enable_adcpn_macro_substitution_for_click_pings\u003dtrue\u0026h5_inplayer_enable_adcpn_macro_substitution_for_click_pings\u003dtrue\u0026hfr_dropped_framerate_fallback_threshold\u003d0\u0026hide_endpoint_overflow_on_ytd_display_ad_renderer\u003dtrue\u0026hls_use_new_codecs_string_api\u003dtrue\u0026html5_ad_timeout_ms\u003d0\u0026html5_ads_preroll_lock_timeout_delay_ms\u003d15000\u0026html5_allow_discontiguous_slices\u003dtrue\u0026html5_allow_video_keyframe_without_audio\u003dtrue\u0026html5_append_init_while_paused\u003dtrue\u0026html5_apply_ustreamer_cap_per_video_id\u003dtrue\u0026html5_att_oauth\u003dtrue\u0026html5_attach_num_random_bytes_to_bandaid\u003d0\u0026html5_attach_po_token_to_bandaid\u003dtrue\u0026html5_autonav_cap_idle_secs\u003d0\u0026html5_autonav_quality_cap\u003d720\u0026html5_autoplay_default_quality_cap\u003d0\u0026html5_block_pip_safari_delay\u003d0\u0026html5_bmff_new_fourcc_check\u003dtrue\u0026html5_cap_quality_for_tv_hfr\u003dtrue\u0026html5_change_player_mode_order_for_logging\u003dtrue\u0026html5_clamp_cuepoints_to_min\u003dtrue\u0026html5_cobalt_max_size_for_immed_job\u003d0\u0026html5_cobalt_min_processor_cnt_to_offload_algo\u003d0\u0026html5_cobalt_override_quic\u003d0\u0026html5_consume_media_bytes_slice_infos\u003dtrue\u0026html5_control_flow_include_trigger_logging_in_tmp_logs\u003dtrue\u0026html5_create_manifest_from_protos\u003dtrue\u0026html5_de_dupe_content_video_loads_in_lifecycle_api\u003dtrue\u0026html5_deadzone_multiplier\u003d1.0\u0026html5_debug_data_log_probability\u003d0.1\u0026html5_decode_to_texture_cap\u003dtrue\u0026html5_decoder_freeze_timeout_delay_ms\u003d0\u0026html5_default_ad_gain\u003d0.5\u0026html5_default_quality_cap\u003d0\u0026html5_defer_ad_module_ms\u003d0\u0026html5_defer_fetch_att_ms\u003d1000\u0026html5_defer_modules_delay_time_millis\u003d0\u0026html5_delay_initial_loading\u003dtrue\u0026html5_delay_retries_for_host_timeout\u003dtrue\u0026html5_delayed_retry_count\u003d1\u0026html5_delayed_retry_delay_ms\u003d5000\u0026html5_deprecate_video_tag_pool\u003dtrue\u0026html5_desktop_vr180_allow_panning\u003dtrue\u0026html5_desync_cue_range_threshold\u003d0\u0026html5_df_downgrade_thresh\u003d0.2\u0026html5_disable_connection_issue_event\u003dtrue\u0026html5_disable_csi_for_bulleit\u003dtrue\u0026html5_disable_move_pssh_to_moov\u003dtrue\u0026html5_disable_non_contiguous\u003dtrue\u0026html5_displayed_frame_rate_downgrade_threshold\u003d45\u0026html5_drm_check_all_key_error_states\u003dtrue\u0026html5_drm_cpi_license_key\u003dtrue\u0026html5_early_read_chunk\u003dtrue\u0026html5_enable_ac3\u003dtrue\u0026html5_enable_ads_client_monitoring_log_tv\u003dtrue\u0026html5_enable_atv_offline\u003dtrue\u0026html5_enable_client_hints_override\u003dtrue\u0026html5_enable_eac3\u003dtrue\u0026html5_enable_embedded_player_visibility_signals\u003dtrue\u0026html5_enable_non_notify_composite_vod_lsar_pacf\u003dtrue\u0026html5_enable_single_video_vod_ivar_on_pacf\u003dtrue\u0026html5_enable_tvos_dash\u003dtrue\u0026html5_enable_tvos_encrypted_vp9\u003dtrue\u0026html5_enable_widevine_for_alc\u003dtrue\u0026html5_enable_widevine_for_fast_linear\u003dtrue\u0026html5_encourage_array_coalescing\u003dtrue\u0026html5_exile_on_drm_fatal\u003dtrue\u0026html5_fill_isTypeSupported_capability_cache_earlier\u003dtrue\u0026html5_fludd_suspend\u003dtrue\u0026html5_flush_segment_index_on_error\u003dtrue\u0026html5_flush_vss_with_rti_and_rtn\u003dtrue\u0026html5_gapless_ended_transition_buffer_ms\u003d200\u0026html5_gapless_preloading\u003dtrue\u0026html5_generate_session_po_token\u003dtrue\u0026html5_gl_fps_threshold\u003d0\u0026html5_halt_ssdai_fetch_on_predict_start\u003dtrue\u0026html5_hdcp_probing_stream_url\u003d\u0026html5_heartbeat_set_ended\u003dtrue\u0026html5_hfr_quality_cap\u003d0\u0026html5_high_res_logging_percent\u003d0.01\u0026html5_idle_rate_limit_ms\u003d0\u0026html5_ignore_media_element_event_loadeddata\u003dtrue\u0026html5_innertube_heartbeats_for_fairplay\u003dtrue\u0026html5_innertube_heartbeats_for_playready\u003dtrue\u0026html5_innertube_heartbeats_for_widevine\u003dtrue\u0026html5_ios4_seek_above_zero\u003dtrue\u0026html5_ios7_force_play_on_stall\u003dtrue\u0026html5_ios_force_seek_to_zero_on_stop\u003dtrue\u0026html5_jumbo_mobile_subsegment_readahead_target\u003d3.0\u0026html5_jumbo_ull_nonstreaming_mffa_ms\u003d4000\u0026html5_jumbo_ull_subsegment_readahead_target\u003d1.3\u0026html5_license_constraint_delay\u003d5000\u0026html5_live_abr_head_miss_fraction\u003d0.0\u0026html5_live_abr_repredict_fraction\u003d0.0\u0026html5_live_byterate_factor_for_readahead\u003d1.3\u0026html5_live_low_latency_bandwidth_window\u003d0.0\u0026html5_live_normal_latency_bandwidth_window\u003d0.0\u0026html5_live_partial_response_resumable\u003dtrue\u0026html5_live_quality_cap\u003d0\u0026html5_live_ultra_low_latency_bandwidth_window\u003d0.0\u0026html5_log_audio_abr\u003dtrue\u0026html5_log_experiment_id_from_player_response_to_ctmp\u003d\u0026html5_log_first_ssdai_requests_killswitch\u003dtrue\u0026html5_log_offline_playback_started_event\u003dtrue\u0026html5_log_readahead_on_playback_start\u003dtrue\u0026html5_log_rebuffer_events\u003d5\u0026html5_log_server_url_param\u003dtrue\u0026html5_log_trigger_events_with_debug_data\u003dtrue\u0026html5_long_rebuffer_jiggle_cmt_delay_ms\u003d0\u0026html5_long_rebuffer_new_elem_shorts_delay_ms\u003d0\u0026html5_long_rebuffer_threshold_ms\u003d30000\u0026html5_manifestless_seg_drift_limit_secs\u003d0\u0026html5_manifestless_unplugged\u003dtrue\u0026html5_manifestless_vp9_otf\u003dtrue\u0026html5_max_drift_per_track_secs\u003d0.0\u0026html5_max_headm_for_streaming_xhr\u003d0\u0026html5_max_live_dvr_window_plus_margin_secs\u003d46800.0\u0026html5_max_readbehind_secs\u003d0\u0026html5_max_redirect_response_length\u003d8192\u0026html5_max_selectable_quality_ordinal\u003d0\u0026html5_maximum_readahead_seconds\u003d0.0\u0026html5_media_fullscreen\u003dtrue\u0026html5_mfl_extend_max_request_time\u003dtrue\u0026html5_min_readbehind_cap_secs\u003d60\u0026html5_min_readbehind_secs\u003d0\u0026html5_min_selectable_quality_ordinal\u003d0\u0026html5_min_startup_buffered_ad_media_duration_secs\u003d1.2\u0026html5_min_startup_buffered_media_duration_secs\u003d1.2\u0026html5_minimum_readahead_seconds\u003d0.0\u0026html5_new_min_startup_smooth_logic\u003dtrue\u0026html5_no_placeholder_rollbacks\u003dtrue\u0026html5_non_network_rebuffer_duration_ms\u003d0\u0026html5_non_onesie_attach_po_token\u003dtrue\u0026html5_not_register_disposables_when_core_listens\u003dtrue\u0026html5_offline_failure_retry_limit\u003d2\u0026html5_onesie_cast\u003dtrue\u0026html5_onesie_defer_content_loader_ms\u003d0\u0026html5_onesie_disable_js_cleartext_compression\u003dtrue\u0026html5_onesie_enable_server_side_badwidth_estimation\u003dtrue\u0026html5_onesie_host_racing_cap_ms\u003d0\u0026html5_onesie_ignore_innertube_api_key\u003dtrue\u0026html5_onesie_live_ttl_secs\u003d8\u0026html5_onesie_media_bytes\u003dtrue\u0026html5_onesie_nonzero_playback_start\u003dtrue\u0026html5_onesie_notify_cuepoint_manager_on_completion\u003dtrue\u0026html5_onesie_prefer_trusted_host\u003dtrue\u0026html5_onesie_prewarm_cooldown_ms\u003d0\u0026html5_onesie_prewarm_interval_ms\u003d0\u0026html5_onesie_prewarm_max_lact_ms\u003d0\u0026html5_onesie_redirector_timeout_ms\u003d0\u0026html5_onesie_request_timeout_ms\u003d1000\u0026html5_onesie_sticky_server_side\u003dtrue\u0026html5_pause_on_nonforeground_platform_errors\u003dtrue\u0026html5_peak_shave\u003dtrue\u0026html5_per_format_loudness_fix\u003dtrue\u0026html5_perf_cap_override_sticky\u003dtrue\u0026html5_performance_cap_floor\u003d360\u0026html5_performance_impact_profiling_timer_ms\u003d0\u0026html5_perserve_av1_perf_cap\u003dtrue\u0026html5_photos_use_vp9_otf\u003dtrue\u0026html5_platform_minimum_readahead_seconds\u003d0.0\u0026html5_platform_whitelisted_for_frame_accurate_seeks\u003dtrue\u0026html5_player_autonav_logging\u003dtrue\u0026html5_player_dynamic_bottom_gradient\u003dtrue\u0026html5_player_min_build_cl\u003d-1\u0026html5_player_preload_ad_fix\u003dtrue\u0026html5_post_interrupt_readahead\u003d20\u0026html5_prefer_server_bwe3\u003dtrue\u0026html5_preload_wait_time_secs\u003d0.0\u0026html5_probe_primary_delay_base_ms\u003d0\u0026html5_process_all_encrypted_events\u003dtrue\u0026html5_query_sw_secure_crypto_for_android\u003dtrue\u0026html5_random_playback_cap\u003d0\u0026html5_readahead_ratelimit\u003d3000\u0026html5_recognize_predict_start_cue_point\u003dtrue\u0026html5_reduce_istypesupported_calls\u003dtrue\u0026html5_remove_command_triggered_companions\u003dtrue\u0026html5_remove_not_servable_check_killswitch\u003dtrue\u0026html5_rename_apbs\u003dtrue\u0026html5_report_fatal_drm_restricted_error_killswitch\u003dtrue\u0026html5_report_slow_ads_as_error\u003dtrue\u0026html5_request_only_hdr_or_sdr_keys\u003dtrue\u0026html5_request_sizing_multiplier\u003d0.8\u0026html5_require_hdr_capability\u003dtrue\u0026html5_reset_media_stream_on_unresumable_slices\u003dtrue\u0026html5_resource_bad_status_delay_scaling\u003d1.5\u0026html5_restrict_streaming_xhr_on_sqless_requests\u003dtrue\u0026html5_safari_desktop_eme_min_version\u003d0\u0026html5_seek_jiggle_cmt_delay_ms\u003d8000\u0026html5_seek_new_elem_delay_ms\u003d12000\u0026html5_seek_new_elem_shorts_delay_ms\u003d0\u0026html5_seek_over_discontinuities_delay_ms\u003d0\u0026html5_seek_set_cmt_delay_ms\u003d2000\u0026html5_seek_timeout_delay_ms\u003d20000\u0026html5_selectable_formats_early_exit\u003dtrue\u0026html5_server_stitched_dai_decorated_url_retry_limit\u003d5\u0026html5_server_stitched_dai_group\u003dtrue\u0026html5_session_po_token_interval_time_ms\u003d900000\u0026html5_set_ended_in_pfx_live\u003dtrue\u0026html5_simplify_streaming_xhr\u003dtrue\u0026html5_skip_oob_start_seconds\u003dtrue\u0026html5_skip_slow_ad_delay_ms\u003d15000\u0026html5_skip_sub_quantum_discontinuity_secs\u003d0.0\u0026html5_slow_start_no_media_source_delay_ms\u003d0\u0026html5_slow_start_timeout_delay_ms\u003d20000\u0026html5_ssdai_adfetch_dynamic_timeout_ms\u003d0\u0026html5_ssdai_enable_new_seek_logic\u003dtrue\u0026html5_ssdai_flush_vss\u003dtrue\u0026html5_ssdai_vss_player_state_change\u003dtrue\u0026html5_start_seconds_reorder\u003dtrue\u0026html5_stateful_audio_min_adjustment_value\u003d0\u0026html5_static_abr_resolution_shelf\u003d0\u0026html5_store_xhr_headers_readable\u003dtrue\u0026html5_stream_metadata\u003dtrue\u0026html5_streaming_init_requests_sizes\u003d0\u0026html5_streaming_xhr_check_for_null_response\u003dtrue\u0026html5_subsegment_readahead_load_speed_check_interval\u003d0.5\u0026html5_subsegment_readahead_min_buffer_health_secs\u003d0.25\u0026html5_subsegment_readahead_min_buffer_health_secs_on_timeout\u003d0.1\u0026html5_subsegment_readahead_min_load_speed\u003d1.5\u0026html5_subsegment_readahead_seek_latency_fudge\u003d0.5\u0026html5_subsegment_readahead_target_buffer_health_secs\u003d0.5\u0026html5_subsegment_readahead_timeout_secs\u003d2.0\u0026html5_suspend_loader\u003dtrue\u0026html5_track_termination_during_request\u003dtrue\u0026html5_ugc_live_audio_51\u003dtrue\u0026html5_ugc_vod_audio_51\u003dtrue\u0026html5_ultra_high_res_logging_percent\u003d0.0\u0026html5_unreported_seek_reseek_delay_ms\u003d0\u0026html5_unrestricted_layer_high_res_logging_percent\u003d0.0\u0026html5_update_constraint\u003dtrue\u0026html5_use_post_for_media\u003dtrue\u0026html5_varispeed_playback_rate\u003dtrue\u0026html5_video_tbd_min_kb\u003d0\u0026html5_viewport_undersend_maximum\u003d0.0\u0026html5_watchdog_for_zero_seek\u003dtrue\u0026html5_web_enable_halftime_preroll\u003dtrue\u0026html5_webpo_idle_priority_job\u003dtrue\u0026html5_woffle_resume\u003dtrue\u0026html5_workaround_delay_trigger\u003dtrue\u0026html5_xhr_clean_up_multi_slice_facade\u003dtrue\u0026html5_ytvlr_enable_single_select_survey\u003dtrue\u0026il_use_view_model_logging_context\u003dtrue\u0026initial_gel_batch_timeout\u003d2000\u0026injected_license_handler_error_code\u003d0\u0026injected_license_handler_license_status\u003d0\u0026json_condensed_response\u003dtrue\u0026kevlar_command_handler_command_banlist\u003d[]\u0026kevlar_dropdown_fix\u003dtrue\u0026kevlar_gel_error_routing\u003dtrue\u0026kevlar_miniplayer\u003dtrue\u0026kevlar_miniplayer_expand_top\u003dtrue\u0026kevlar_miniplayer_play_pause_on_scrim\u003dtrue\u0026kevlar_playback_associated_queue\u003dtrue\u0026kevlar_queue_use_update_api\u003dtrue\u0026kevlar_smart_downloads\u003dtrue\u0026kevlar_smart_downloads_setting\u003dtrue\u0026kevlar_vimio_use_shared_monitor\u003dtrue\u0026kevlar_woffle\u003dtrue\u0026live_chunk_readahead\u003d3\u0026live_fresca_v2\u003dtrue\u0026log_errors_through_nwl_on_retry\u003dtrue\u0026log_heartbeat_with_lifecycles\u003dtrue\u0026log_web_endpoint_to_layer\u003dtrue\u0026log_window_onerror_fraction\u003d0.1\u0026manifestless_post_live\u003dtrue\u0026manifestless_post_live_ufph\u003dtrue\u0026max_prefetch_window_sec_for_livestream_optimization\u003d10\u0026max_resolution_for_white_noise\u003d360\u0026mdx_enable_privacy_disclosure_ui\u003dtrue\u0026mdx_load_cast_api_bootstrap_script\u003dtrue\u0026migrate_events_to_ts\u003dtrue\u0026min_prefetch_offset_sec_for_livestream_optimization\u003d20\u0026music_enable_shared_audio_tier_logic\u003dtrue\u0026mweb_c3_endscreen\u003dtrue\u0026mweb_enable_custom_control_shared\u003dtrue\u0026mweb_enable_skippables_on_jio_phone\u003dtrue\u0026mweb_muted_autoplay_animation\u003dshrink\u0026mweb_native_control_in_faux_fullscreen_shared\u003dtrue\u0026network_polling_interval\u003d30000\u0026networkless_gel\u003dtrue\u0026networkless_logging\u003dtrue\u0026new_codecs_string_api_uses_legacy_style\u003dtrue\u0026nwl_send_fast_on_unload\u003dtrue\u0026nwl_send_from_memory_when_online\u003dtrue\u0026offline_error_handling\u003dtrue\u0026pageid_as_header_web\u003dtrue\u0026parse_query_data_from_url\u003dtrue\u0026player_ads_set_adformat_on_client\u003dtrue\u0026player_allow_autonav_after_playlist\u003dtrue\u0026player_bootstrap_method\u003dtrue\u0026player_defer_caption_display\u003d1000\u0026player_destroy_old_version\u003dtrue\u0026player_doubletap_to_seek\u003dtrue\u0026player_enable_playback_playlist_change\u003dtrue\u0026player_endscreen_ellipsis_fix\u003dtrue\u0026player_underlay_min_player_width\u003d768.0\u0026player_underlay_video_width_fraction\u003d0.6\u0026player_web_canary_stage\u003d0\u0026playready_first_play_expiration\u003d-1\u0026polymer_bad_build_labels\u003dtrue\u0026polymer_log_prop_change_observer_percent\u003d0\u0026polymer_verifiy_app_state\u003dtrue\u0026preskip_button_style_ads_backend\u003dcountdown_next_to_thumbnail\u0026qoe_nwl_downloads\u003dtrue\u0026qoe_send_and_write\u003dtrue\u0026record_app_crashed_web\u003dtrue\u0026replace_playability_retriever_in_watch\u003dtrue\u0026scheduler_use_raf_by_default\u003dtrue\u0026self_podding_header_string_template\u003dself_podding_interstitial_message\u0026self_podding_highlight_non_default_button\u003dtrue\u0026self_podding_midroll_choice_string_template\u003dself_podding_midroll_choice\u0026send_config_hash_timer\u003d0\u0026set_interstitial_advertisers_question_text\u003dtrue\u0026short_start_time_prefer_publish_in_watch_log\u003dtrue\u0026should_clear_video_data_on_player_cued_unstarted\u003dtrue\u0026skip_inline_muted_license_service_check\u003dtrue\u0026skip_invalid_ytcsi_ticks\u003dtrue\u0026skip_ls_gel_retry\u003dtrue\u0026skip_setting_info_in_csi_data_object\u003dtrue\u0026start_client_gcf\u003dtrue\u0026start_client_gcf_for_player\u003dtrue\u0026streaming_data_emergency_itag_blacklist\u003d[]\u0026suppress_error_204_logging\u003dtrue\u0026transport_use_scheduler\u003dtrue\u0026tv_pacf_logging_sample_rate\u003d0.01\u0026tvhtml5_unplugged_preload_cache_size\u003d5\u0026uncover_ad_badge_on_RTL_tiny_window\u003dtrue\u0026unplugged_dai_live_chunk_readahead\u003d3\u0026unplugged_tvhtml5_video_preload_on_focus_delay_ms\u003d0\u0026use_inlined_player_rpc\u003dtrue\u0026use_new_in_memory_storage\u003dtrue\u0026use_new_nwl_initialization\u003dtrue\u0026use_new_nwl_saw\u003dtrue\u0026use_new_nwl_stw\u003dtrue\u0026use_new_nwl_wts\u003dtrue\u0026use_player_abuse_bg_library\u003dtrue\u0026use_profilepage_event_label_in_carousel_playbacks\u003dtrue\u0026use_request_time_ms_header\u003dtrue\u0026use_session_based_sampling\u003dtrue\u0026use_shared_nsm\u003dtrue\u0026use_shared_nsm_and_keep_yt_online_updated\u003dtrue\u0026use_ts_visibilitylogger\u003dtrue\u0026variable_buffer_timeout_ms\u003d0\u0026verify_ads_itag_early\u003dtrue\u0026vp9_drm_live\u003dtrue\u0026vss_final_ping_send_and_write\u003dtrue\u0026vss_pings_using_networkless\u003dtrue\u0026vss_playback_use_send_and_write\u003dtrue\u0026web_api_url\u003dtrue\u0026web_cinematic_watch_settings\u003dtrue\u0026web_client_version_override\u003d\u0026web_dedupe_ve_grafting\u003dtrue\u0026web_deprecate_service_ajax_map_dependency\u003dtrue\u0026web_enable_voz_audio_feedback\u003dtrue\u0026web_foreground_heartbeat_interval_ms\u003d28000\u0026web_forward_command_on_pbj\u003dtrue\u0026web_gel_debounce_ms\u003d10000\u0026web_gel_timeout_cap\u003dtrue\u0026web_key_moments_markers\u003dtrue\u0026web_log_memory_total_kbytes\u003dtrue\u0026web_logging_max_batch\u003d150\u0026web_modern_ads\u003dtrue\u0026web_modern_buttons\u003dtrue\u0026web_modern_buttons_bl_survey\u003dtrue\u0026web_modern_subscribe\u003dtrue\u0026web_modern_subscribe_style\u003dfilled\u0026web_new_autonav_countdown\u003dtrue\u0026web_one_platform_error_handling\u003dtrue\u0026web_op_signal_type_banlist\u003d[]\u0026web_playback_associated_log_ctt\u003dtrue\u0026web_playback_associated_ve\u003dtrue\u0026web_player_api_logging_fraction\u003d0.01\u0026web_player_autonav_toggle_always_listen\u003dtrue\u0026web_player_autonav_use_server_provided_state\u003dtrue\u0026web_player_caption_language_preference_stickiness_duration\u003d0\u0026web_player_decouple_autonav\u003dtrue\u0026web_player_enable_early_warning_snackbar\u003dtrue\u0026web_player_enable_premium_hbr_in_h5_api\u003dtrue\u0026web_player_enable_premium_hbr_playback_cap\u003dtrue\u0026web_player_fine_scrubbing\u003dtrue\u0026web_player_gvi_wexit_adunit\u003dtrue\u0026web_player_gvi_wexit_all_player_styles\u003dtrue\u0026web_player_gvi_wexit_living_room_bedrock\u003dtrue\u0026web_player_gvi_wexit_living_room_kids\u003dtrue\u0026web_player_gvi_wexit_living_room_other\u003dtrue\u0026web_player_gvi_wexit_living_room_pangea\u003dtrue\u0026web_player_gvi_wexit_living_room_simply\u003dtrue\u0026web_player_gvi_wexit_living_room_unplugged\u003dtrue\u0026web_player_innertube_playlist_update\u003dtrue\u0026web_player_ipp_canary_type_for_logging\u003d\u0026web_player_live_monitor_env\u003dtrue\u0026web_player_move_autonav_toggle\u003dtrue\u0026web_player_music_visualizer_treatment\u003dfake\u0026web_player_mutable_event_label\u003dtrue\u0026web_player_nitrate_promo_tooltip\u003dtrue\u0026web_player_no_force_gvi\u003dtrue\u0026web_player_response_playback_tracking_parsing\u003dtrue\u0026web_player_seek_chapters_by_shortcut\u003dtrue\u0026web_player_sentinel_is_uniplayer\u003dtrue\u0026web_player_should_honor_include_asr_setting\u003dtrue\u0026web_player_show_music_in_this_video_graphic\u003dvideo_thumbnail\u0026web_player_small_hbp_settings_menu\u003dtrue\u0026web_player_ss_dai_ad_fetching_timeout_ms\u003d15000\u0026web_player_ss_media_time_offset\u003dtrue\u0026web_player_ss_timeout_skip_ads\u003dtrue\u0026web_player_ssdai_all_acpns_aids_logging_killswitch\u003dtrue\u0026web_player_touch_mode_improvements\u003dtrue\u0026web_player_transfer_timeout_threshold_ms\u003d10800000\u0026web_player_unset_default_csn_killswitch\u003dtrue\u0026web_player_use_cinematic_label_2\u003dtrue\u0026web_player_use_new_api_for_quality_pullback\u003dtrue\u0026web_player_vss_pageid_header\u003dtrue\u0026web_player_watch_next_response\u003dtrue\u0026web_player_watch_next_response_parsing\u003dtrue\u0026web_prefetch_preload_video\u003dtrue\u0026web_repeating_chapters\u003dtrue\u0026web_rounded_containers\u003dtrue\u0026web_rounded_thumbnails\u003dtrue\u0026web_settings_menu_icons\u003dtrue\u0026web_smoothness_test_duration_ms\u003d0\u0026web_smoothness_test_method\u003d0\u0026web_yt_config_context\u003dtrue\u0026woffle_clean_up_after_entity_migration\u003dtrue\u0026woffle_orchestration\u003dtrue\u0026ytidb_clear_embedded_player\u003dtrue\u0026ytidb_fetch_datasync_ids_for_data_cleanup\u003dtrue\u0026ytidb_remake_db_retries\u003d3\u0026ytidb_reopen_db_retries\u003d3\u0026ytidb_transaction_ended_event_rate_limit\u003d0.02\u0026ytidb_transaction_ended_event_rate_limit_session\u003d0.2\u0026ytidb_transaction_ended_event_rate_limit_transaction\u003d0.1","cspNonce":"nopnosk9VoEiau3Xtg_3uQ","canaryState":"none","enableCsiLogging":true,"csiPageType":"watch","authorizedUserIndex":0,"datasyncId":"106384449314396247844||","allowWoffleManagement":true,"cinematicSettingsAvailable":true},"WEB_PLAYER_CONTEXT_CONFIG_ID_KEVLAR_CHANNEL_TRAILER":{"rootElementId":"c4-player","jsUrl":"/s/player/97ea7458/player_ias.vflset/en_US/base.js","cssUrl":"/s/player/97ea7458/www-player.css","contextId":"WEB_PLAYER_CONTEXT_CONFIG_ID_KEVLAR_CHANNEL_TRAILER","eventLabel":"profilepage","contentRegion":"CA","hl":"en_US","hostLanguage":"en","playerStyle":"desktop-polymer","innertubeApiKey":"AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8","innertubeApiVersion":"v1","innertubeContextClientVersion":"2.20230201.01.00","device":{"brand":"apple","model":"","browser":"Chrome","browserVersion":"109.0.0.0","os":"Macintosh","osVersion":"10_15_7","platform":"DESKTOP","interfaceName":"WEB","interfaceVersion":"2.20230201.01.00","deviceYear":2013},"serializedExperimentIds":"23983296,23986016,24004644,24007246,24080738,24135310,24169501,24219381,24255163,24282011,24396645,24415864,24416291,24416441,24433679,24437577,24439361,24441240,24449113,24449639,24450366,24451032,24454357,24454498,24457577,24457884,24460376,24463912,24469897","serializedExperimentFlags":"H5_async_logging_delay_ms\u003d30000.0\u0026H5_enable_full_pacf_logging\u003dtrue\u0026H5_use_async_logging\u003dtrue\u0026ad_pod_disable_companion_persist_ads_quality\u003dtrue\u0026addto_ajax_log_warning_fraction\u003d0.1\u0026align_ad_to_video_player_lifecycle_for_bulleit\u003dtrue\u0026allow_live_autoplay\u003dtrue\u0026allow_poltergust_autoplay\u003dtrue\u0026allow_skip_networkless\u003dtrue\u0026autoplay_time\u003d8000\u0026autoplay_time_for_fullscreen\u003d3000\u0026autoplay_time_for_music_content\u003d3000\u0026background_thread_flush_logs_due_to_batch_limit\u003dtrue\u0026bg_vm_reinit_threshold\u003d7200000\u0026blocked_packages_for_sps\u003d[]\u0026botguard_async_snapshot_timeout_ms\u003d3000\u0026check_ad_ui_status_for_mweb_safari\u003dtrue\u0026check_navigator_accuracy_timeout_ms\u003d0\u0026clear_user_partitioned_ls\u003dtrue\u0026client_respect_autoplay_switch_button_renderer\u003dtrue\u0026csi_on_gel\u003dtrue\u0026dash_manifest_version\u003d5\u0026debug_bandaid_hostname\u003d\u0026debug_sherlog_username\u003d\u0026delay_ads_gvi_call_on_bulleit_living_room_ms\u003d0\u0026deprecate_csi_has_info\u003dtrue\u0026deprecate_pair_servlet_enabled\u003dtrue\u0026deprecate_two_way_binding_child\u003dtrue\u0026deprecate_two_way_binding_parent\u003dtrue\u0026desktop_image_cta_no_background\u003dtrue\u0026desktop_log_img_click_location\u003dtrue\u0026desktop_player_button_tooltip_with_shortcut\u003dtrue\u0026desktop_sparkles_light_cta_button\u003dtrue\u0026disable_channel_id_check_for_suspended_channels\u003dtrue\u0026disable_child_node_auto_formatted_strings\u003dtrue\u0026disable_defer_admodule_on_advertiser_video\u003dtrue\u0026disable_features_for_supex\u003dtrue\u0026disable_legacy_desktop_remote_queue\u003dtrue\u0026disable_mdx_connection_in_mdx_module_for_music_web\u003dtrue\u0026disable_new_pause_state3\u003dtrue\u0026disable_pacf_logging_for_memory_limited_tv\u003dtrue\u0026disable_rounding_ad_notify\u003dtrue\u0026disable_simple_mixed_direction_formatted_strings\u003dtrue\u0026disable_ssdai_on_errors\u003dtrue\u0026disable_tabbing_before_flyout_ad_elements_appear\u003dtrue\u0026disable_thumbnail_preloading\u003dtrue\u0026embeds_enable_allow_watch_again_endscreen_for_eligible_shorts\u003dtrue\u0026embeds_enable_embed_module\u003dtrue\u0026embeds_enable_shorts_branded_ui\u003dtrue\u0026embeds_enable_shorts_links_for_eligible_shorts\u003dtrue\u0026embeds_web_enable_gws_wh_rel_off\u003dtrue\u0026embeds_web_enable_info_panel_preview\u003dtrue\u0026embeds_web_enable_load_player_from_page_show\u003dtrue\u0026embeds_web_enable_logging_event_handlers\u003dtrue\u0026embeds_web_enable_pem_domain_fix_for_ad_requests\u003dtrue\u0026embeds_web_enable_replace_unload_w_pagehide\u003dtrue\u0026embeds_web_enable_ve_conversion_logging_tracking_no_allow_list\u003dtrue\u0026embeds_web_enable_video_data_refactoring_break_down_and_move_methods\u003dtrue\u0026embeds_web_enable_video_data_refactoring_like_button_renderer\u003dtrue\u0026embeds_web_hide_unfilled_more_videos_suggestions\u003dtrue\u0026embeds_web_lite_mode\u003d1\u0026embeds_web_nwl_disable_nocookie\u003dtrue\u0026embeds_web_synth_ch_headers_banned_urls_regex\u003d\u0026enable_ad_cpn_macro_substitution_for_click_pings\u003dtrue\u0026enable_cast_for_web_unplugged\u003dtrue\u0026enable_cast_on_music_web\u003dtrue\u0026enable_client_page_id_header_for_first_party_pings\u003dtrue\u0026enable_client_sli_logging\u003dtrue\u0026enable_discrete_live_precise_embargos\u003dtrue\u0026enable_error_corrections_infocard\u003dtrue\u0026enable_error_corrections_infocard_web_client\u003dtrue\u0026enable_error_corrections_infocard_web_client_check\u003dtrue\u0026enable_error_corrections_infocards_icon_web\u003dtrue\u0026enable_eviction_protection_for_bulleit\u003dtrue\u0026enable_gel_log_commands\u003dtrue\u0026enable_handles_account_menu_switcher\u003dtrue\u0026enable_inline_preview_controls\u003dtrue\u0026enable_live_premiere_web_player_indicator\u003dtrue\u0026enable_lr_home_infeed_ads_inline_playback_progress_pings\u003dtrue\u0026enable_macro_substitution_on_html5\u003dtrue\u0026enable_mixed_direction_formatted_strings\u003dtrue\u0026enable_mweb_livestream_ui_update\u003dtrue\u0026enable_new_paid_product_placement\u003dtrue\u0026enable_post_ad_perception_survey_fix_on_tvhtml5\u003dtrue\u0026enable_post_ad_perception_survey_in_tvhtml5\u003dtrue\u0026enable_precise_embargos\u003dtrue\u0026enable_server_stitched_dai\u003dtrue\u0026enable_shorts_player\u003dtrue\u0026enable_skip_ad_guidance_prompt\u003dtrue\u0026enable_skippable_ads_for_unplugged_ad_pod\u003dtrue\u0026enable_smearing_expansion_dai\u003dtrue\u0026enable_tectonic_ad_ux_for_halftime\u003dtrue\u0026enable_third_party_info\u003dtrue\u0026enable_topsoil_wta_for_halftime_live_infra\u003dtrue\u0026enable_web_media_session_metadata_fix\u003dtrue\u0026error_message_for_gsuite_network_restrictions\u003dtrue\u0026export_networkless_options\u003dtrue\u0026external_fullscreen_with_edu\u003dtrue\u0026fast_autonav_in_background\u003dtrue\u0026fetch_att_independently\u003dtrue\u0026fill_single_video_with_notify_to_lasr\u003dtrue\u0026filter_vp9_for_csdai\u003dtrue\u0026fix_ads_tracking_for_swf_config_deprecation_mweb\u003dtrue\u0026gcf_config_store_enabled\u003dtrue\u0026gpa_sparkles_ten_percent_layer\u003dtrue\u0026gvi_channel_client_screen\u003dtrue\u0026h5_companion_enable_adcpn_macro_substitution_for_click_pings\u003dtrue\u0026h5_inplayer_enable_adcpn_macro_substitution_for_click_pings\u003dtrue\u0026hfr_dropped_framerate_fallback_threshold\u003d0\u0026hide_endpoint_overflow_on_ytd_display_ad_renderer\u003dtrue\u0026hls_use_new_codecs_string_api\u003dtrue\u0026html5_ad_timeout_ms\u003d0\u0026html5_ads_preroll_lock_timeout_delay_ms\u003d15000\u0026html5_allow_discontiguous_slices\u003dtrue\u0026html5_allow_video_keyframe_without_audio\u003dtrue\u0026html5_append_init_while_paused\u003dtrue\u0026html5_apply_ustreamer_cap_per_video_id\u003dtrue\u0026html5_att_oauth\u003dtrue\u0026html5_attach_num_random_bytes_to_bandaid\u003d0\u0026html5_attach_po_token_to_bandaid\u003dtrue\u0026html5_autonav_cap_idle_secs\u003d0\u0026html5_autonav_quality_cap\u003d720\u0026html5_autoplay_default_quality_cap\u003d0\u0026html5_block_pip_safari_delay\u003d0\u0026html5_bmff_new_fourcc_check\u003dtrue\u0026html5_cap_quality_for_tv_hfr\u003dtrue\u0026html5_change_player_mode_order_for_logging\u003dtrue\u0026html5_clamp_cuepoints_to_min\u003dtrue\u0026html5_cobalt_max_size_for_immed_job\u003d0\u0026html5_cobalt_min_processor_cnt_to_offload_algo\u003d0\u0026html5_cobalt_override_quic\u003d0\u0026html5_consume_media_bytes_slice_infos\u003dtrue\u0026html5_control_flow_include_trigger_logging_in_tmp_logs\u003dtrue\u0026html5_create_manifest_from_protos\u003dtrue\u0026html5_de_dupe_content_video_loads_in_lifecycle_api\u003dtrue\u0026html5_deadzone_multiplier\u003d1.0\u0026html5_debug_data_log_probability\u003d0.1\u0026html5_decode_to_texture_cap\u003dtrue\u0026html5_decoder_freeze_timeout_delay_ms\u003d0\u0026html5_default_ad_gain\u003d0.5\u0026html5_default_quality_cap\u003d0\u0026html5_defer_ad_module_ms\u003d0\u0026html5_defer_fetch_att_ms\u003d1000\u0026html5_defer_modules_delay_time_millis\u003d0\u0026html5_delay_initial_loading\u003dtrue\u0026html5_delay_retries_for_host_timeout\u003dtrue\u0026html5_delayed_retry_count\u003d1\u0026html5_delayed_retry_delay_ms\u003d5000\u0026html5_deprecate_video_tag_pool\u003dtrue\u0026html5_desktop_vr180_allow_panning\u003dtrue\u0026html5_desync_cue_range_threshold\u003d0\u0026html5_df_downgrade_thresh\u003d0.2\u0026html5_disable_connection_issue_event\u003dtrue\u0026html5_disable_csi_for_bulleit\u003dtrue\u0026html5_disable_move_pssh_to_moov\u003dtrue\u0026html5_disable_non_contiguous\u003dtrue\u0026html5_displayed_frame_rate_downgrade_threshold\u003d45\u0026html5_drm_check_all_key_error_states\u003dtrue\u0026html5_drm_cpi_license_key\u003dtrue\u0026html5_early_read_chunk\u003dtrue\u0026html5_enable_ac3\u003dtrue\u0026html5_enable_ads_client_monitoring_log_tv\u003dtrue\u0026html5_enable_atv_offline\u003dtrue\u0026html5_enable_client_hints_override\u003dtrue\u0026html5_enable_eac3\u003dtrue\u0026html5_enable_embedded_player_visibility_signals\u003dtrue\u0026html5_enable_non_notify_composite_vod_lsar_pacf\u003dtrue\u0026html5_enable_single_video_vod_ivar_on_pacf\u003dtrue\u0026html5_enable_tvos_dash\u003dtrue\u0026html5_enable_tvos_encrypted_vp9\u003dtrue\u0026html5_enable_widevine_for_alc\u003dtrue\u0026html5_enable_widevine_for_fast_linear\u003dtrue\u0026html5_encourage_array_coalescing\u003dtrue\u0026html5_exile_on_drm_fatal\u003dtrue\u0026html5_fill_isTypeSupported_capability_cache_earlier\u003dtrue\u0026html5_fludd_suspend\u003dtrue\u0026html5_flush_segment_index_on_error\u003dtrue\u0026html5_flush_vss_with_rti_and_rtn\u003dtrue\u0026html5_gapless_ended_transition_buffer_ms\u003d200\u0026html5_gapless_preloading\u003dtrue\u0026html5_generate_session_po_token\u003dtrue\u0026html5_gl_fps_threshold\u003d0\u0026html5_halt_ssdai_fetch_on_predict_start\u003dtrue\u0026html5_hdcp_probing_stream_url\u003d\u0026html5_heartbeat_set_ended\u003dtrue\u0026html5_hfr_quality_cap\u003d0\u0026html5_high_res_logging_percent\u003d0.01\u0026html5_idle_rate_limit_ms\u003d0\u0026html5_ignore_media_element_event_loadeddata\u003dtrue\u0026html5_innertube_heartbeats_for_fairplay\u003dtrue\u0026html5_innertube_heartbeats_for_playready\u003dtrue\u0026html5_innertube_heartbeats_for_widevine\u003dtrue\u0026html5_ios4_seek_above_zero\u003dtrue\u0026html5_ios7_force_play_on_stall\u003dtrue\u0026html5_ios_force_seek_to_zero_on_stop\u003dtrue\u0026html5_jumbo_mobile_subsegment_readahead_target\u003d3.0\u0026html5_jumbo_ull_nonstreaming_mffa_ms\u003d4000\u0026html5_jumbo_ull_subsegment_readahead_target\u003d1.3\u0026html5_license_constraint_delay\u003d5000\u0026html5_live_abr_head_miss_fraction\u003d0.0\u0026html5_live_abr_repredict_fraction\u003d0.0\u0026html5_live_byterate_factor_for_readahead\u003d1.3\u0026html5_live_low_latency_bandwidth_window\u003d0.0\u0026html5_live_normal_latency_bandwidth_window\u003d0.0\u0026html5_live_partial_response_resumable\u003dtrue\u0026html5_live_quality_cap\u003d0\u0026html5_live_ultra_low_latency_bandwidth_window\u003d0.0\u0026html5_log_audio_abr\u003dtrue\u0026html5_log_experiment_id_from_player_response_to_ctmp\u003d\u0026html5_log_first_ssdai_requests_killswitch\u003dtrue\u0026html5_log_offline_playback_started_event\u003dtrue\u0026html5_log_readahead_on_playback_start\u003dtrue\u0026html5_log_rebuffer_events\u003d5\u0026html5_log_server_url_param\u003dtrue\u0026html5_log_trigger_events_with_debug_data\u003dtrue\u0026html5_long_rebuffer_jiggle_cmt_delay_ms\u003d0\u0026html5_long_rebuffer_new_elem_shorts_delay_ms\u003d0\u0026html5_long_rebuffer_threshold_ms\u003d30000\u0026html5_manifestless_seg_drift_limit_secs\u003d0\u0026html5_manifestless_unplugged\u003dtrue\u0026html5_manifestless_vp9_otf\u003dtrue\u0026html5_max_drift_per_track_secs\u003d0.0\u0026html5_max_headm_for_streaming_xhr\u003d0\u0026html5_max_live_dvr_window_plus_margin_secs\u003d46800.0\u0026html5_max_readbehind_secs\u003d0\u0026html5_max_redirect_response_length\u003d8192\u0026html5_max_selectable_quality_ordinal\u003d0\u0026html5_maximum_readahead_seconds\u003d0.0\u0026html5_media_fullscreen\u003dtrue\u0026html5_mfl_extend_max_request_time\u003dtrue\u0026html5_min_readbehind_cap_secs\u003d60\u0026html5_min_readbehind_secs\u003d0\u0026html5_min_selectable_quality_ordinal\u003d0\u0026html5_min_startup_buffered_ad_media_duration_secs\u003d1.2\u0026html5_min_startup_buffered_media_duration_secs\u003d1.2\u0026html5_minimum_readahead_seconds\u003d0.0\u0026html5_new_min_startup_smooth_logic\u003dtrue\u0026html5_no_placeholder_rollbacks\u003dtrue\u0026html5_non_network_rebuffer_duration_ms\u003d0\u0026html5_non_onesie_attach_po_token\u003dtrue\u0026html5_not_register_disposables_when_core_listens\u003dtrue\u0026html5_offline_failure_retry_limit\u003d2\u0026html5_onesie_cast\u003dtrue\u0026html5_onesie_defer_content_loader_ms\u003d0\u0026html5_onesie_disable_js_cleartext_compression\u003dtrue\u0026html5_onesie_enable_server_side_badwidth_estimation\u003dtrue\u0026html5_onesie_host_racing_cap_ms\u003d0\u0026html5_onesie_ignore_innertube_api_key\u003dtrue\u0026html5_onesie_live_ttl_secs\u003d8\u0026html5_onesie_media_bytes\u003dtrue\u0026html5_onesie_nonzero_playback_start\u003dtrue\u0026html5_onesie_notify_cuepoint_manager_on_completion\u003dtrue\u0026html5_onesie_prefer_trusted_host\u003dtrue\u0026html5_onesie_prewarm_cooldown_ms\u003d0\u0026html5_onesie_prewarm_interval_ms\u003d0\u0026html5_onesie_prewarm_max_lact_ms\u003d0\u0026html5_onesie_redirector_timeout_ms\u003d0\u0026html5_onesie_request_timeout_ms\u003d1000\u0026html5_onesie_sticky_server_side\u003dtrue\u0026html5_pause_on_nonforeground_platform_errors\u003dtrue\u0026html5_peak_shave\u003dtrue\u0026html5_per_format_loudness_fix\u003dtrue\u0026html5_perf_cap_override_sticky\u003dtrue\u0026html5_performance_cap_floor\u003d360\u0026html5_performance_impact_profiling_timer_ms\u003d0\u0026html5_perserve_av1_perf_cap\u003dtrue\u0026html5_photos_use_vp9_otf\u003dtrue\u0026html5_platform_minimum_readahead_seconds\u003d0.0\u0026html5_platform_whitelisted_for_frame_accurate_seeks\u003dtrue\u0026html5_player_autonav_logging\u003dtrue\u0026html5_player_dynamic_bottom_gradient\u003dtrue\u0026html5_player_min_build_cl\u003d-1\u0026html5_player_preload_ad_fix\u003dtrue\u0026html5_post_interrupt_readahead\u003d20\u0026html5_prefer_server_bwe3\u003dtrue\u0026html5_preload_wait_time_secs\u003d0.0\u0026html5_probe_primary_delay_base_ms\u003d0\u0026html5_process_all_encrypted_events\u003dtrue\u0026html5_query_sw_secure_crypto_for_android\u003dtrue\u0026html5_random_playback_cap\u003d0\u0026html5_readahead_ratelimit\u003d3000\u0026html5_recognize_predict_start_cue_point\u003dtrue\u0026html5_reduce_istypesupported_calls\u003dtrue\u0026html5_remove_command_triggered_companions\u003dtrue\u0026html5_remove_not_servable_check_killswitch\u003dtrue\u0026html5_rename_apbs\u003dtrue\u0026html5_report_fatal_drm_restricted_error_killswitch\u003dtrue\u0026html5_report_slow_ads_as_error\u003dtrue\u0026html5_request_only_hdr_or_sdr_keys\u003dtrue\u0026html5_request_sizing_multiplier\u003d0.8\u0026html5_require_hdr_capability\u003dtrue\u0026html5_reset_media_stream_on_unresumable_slices\u003dtrue\u0026html5_resource_bad_status_delay_scaling\u003d1.5\u0026html5_restrict_streaming_xhr_on_sqless_requests\u003dtrue\u0026html5_safari_desktop_eme_min_version\u003d0\u0026html5_seek_jiggle_cmt_delay_ms\u003d8000\u0026html5_seek_new_elem_delay_ms\u003d12000\u0026html5_seek_new_elem_shorts_delay_ms\u003d0\u0026html5_seek_over_discontinuities_delay_ms\u003d0\u0026html5_seek_set_cmt_delay_ms\u003d2000\u0026html5_seek_timeout_delay_ms\u003d20000\u0026html5_selectable_formats_early_exit\u003dtrue\u0026html5_server_stitched_dai_decorated_url_retry_limit\u003d5\u0026html5_server_stitched_dai_group\u003dtrue\u0026html5_session_po_token_interval_time_ms\u003d900000\u0026html5_set_ended_in_pfx_live\u003dtrue\u0026html5_simplify_streaming_xhr\u003dtrue\u0026html5_skip_oob_start_seconds\u003dtrue\u0026html5_skip_slow_ad_delay_ms\u003d15000\u0026html5_skip_sub_quantum_discontinuity_secs\u003d0.0\u0026html5_slow_start_no_media_source_delay_ms\u003d0\u0026html5_slow_start_timeout_delay_ms\u003d20000\u0026html5_ssdai_adfetch_dynamic_timeout_ms\u003d0\u0026html5_ssdai_enable_new_seek_logic\u003dtrue\u0026html5_ssdai_flush_vss\u003dtrue\u0026html5_ssdai_vss_player_state_change\u003dtrue\u0026html5_start_seconds_reorder\u003dtrue\u0026html5_stateful_audio_min_adjustment_value\u003d0\u0026html5_static_abr_resolution_shelf\u003d0\u0026html5_store_xhr_headers_readable\u003dtrue\u0026html5_stream_metadata\u003dtrue\u0026html5_streaming_init_requests_sizes\u003d0\u0026html5_streaming_xhr_check_for_null_response\u003dtrue\u0026html5_subsegment_readahead_load_speed_check_interval\u003d0.5\u0026html5_subsegment_readahead_min_buffer_health_secs\u003d0.25\u0026html5_subsegment_readahead_min_buffer_health_secs_on_timeout\u003d0.1\u0026html5_subsegment_readahead_min_load_speed\u003d1.5\u0026html5_subsegment_readahead_seek_latency_fudge\u003d0.5\u0026html5_subsegment_readahead_target_buffer_health_secs\u003d0.5\u0026html5_subsegment_readahead_timeout_secs\u003d2.0\u0026html5_suspend_loader\u003dtrue\u0026html5_track_termination_during_request\u003dtrue\u0026html5_ugc_live_audio_51\u003dtrue\u0026html5_ugc_vod_audio_51\u003dtrue\u0026html5_ultra_high_res_logging_percent\u003d0.0\u0026html5_unreported_seek_reseek_delay_ms\u003d0\u0026html5_unrestricted_layer_high_res_logging_percent\u003d0.0\u0026html5_update_constraint\u003dtrue\u0026html5_use_post_for_media\u003dtrue\u0026html5_varispeed_playback_rate\u003dtrue\u0026html5_video_tbd_min_kb\u003d0\u0026html5_viewport_undersend_maximum\u003d0.0\u0026html5_watchdog_for_zero_seek\u003dtrue\u0026html5_web_enable_halftime_preroll\u003dtrue\u0026html5_webpo_idle_priority_job\u003dtrue\u0026html5_woffle_resume\u003dtrue\u0026html5_workaround_delay_trigger\u003dtrue\u0026html5_xhr_clean_up_multi_slice_facade\u003dtrue\u0026html5_ytvlr_enable_single_select_survey\u003dtrue\u0026il_use_view_model_logging_context\u003dtrue\u0026initial_gel_batch_timeout\u003d2000\u0026injected_license_handler_error_code\u003d0\u0026injected_license_handler_license_status\u003d0\u0026json_condensed_response\u003dtrue\u0026kevlar_command_handler_command_banlist\u003d[]\u0026kevlar_dropdown_fix\u003dtrue\u0026kevlar_gel_error_routing\u003dtrue\u0026kevlar_miniplayer\u003dtrue\u0026kevlar_miniplayer_expand_top\u003dtrue\u0026kevlar_miniplayer_play_pause_on_scrim\u003dtrue\u0026kevlar_playback_associated_queue\u003dtrue\u0026kevlar_queue_use_update_api\u003dtrue\u0026kevlar_smart_downloads\u003dtrue\u0026kevlar_smart_downloads_setting\u003dtrue\u0026kevlar_vimio_use_shared_monitor\u003dtrue\u0026kevlar_woffle\u003dtrue\u0026live_chunk_readahead\u003d3\u0026live_fresca_v2\u003dtrue\u0026log_errors_through_nwl_on_retry\u003dtrue\u0026log_heartbeat_with_lifecycles\u003dtrue\u0026log_web_endpoint_to_layer\u003dtrue\u0026log_window_onerror_fraction\u003d0.1\u0026manifestless_post_live\u003dtrue\u0026manifestless_post_live_ufph\u003dtrue\u0026max_prefetch_window_sec_for_livestream_optimization\u003d10\u0026max_resolution_for_white_noise\u003d360\u0026mdx_enable_privacy_disclosure_ui\u003dtrue\u0026mdx_load_cast_api_bootstrap_script\u003dtrue\u0026migrate_events_to_ts\u003dtrue\u0026min_prefetch_offset_sec_for_livestream_optimization\u003d20\u0026music_enable_shared_audio_tier_logic\u003dtrue\u0026mweb_c3_endscreen\u003dtrue\u0026mweb_enable_custom_control_shared\u003dtrue\u0026mweb_enable_skippables_on_jio_phone\u003dtrue\u0026mweb_muted_autoplay_animation\u003dshrink\u0026mweb_native_control_in_faux_fullscreen_shared\u003dtrue\u0026network_polling_interval\u003d30000\u0026networkless_gel\u003dtrue\u0026networkless_logging\u003dtrue\u0026new_codecs_string_api_uses_legacy_style\u003dtrue\u0026nwl_send_fast_on_unload\u003dtrue\u0026nwl_send_from_memory_when_online\u003dtrue\u0026offline_error_handling\u003dtrue\u0026pageid_as_header_web\u003dtrue\u0026parse_query_data_from_url\u003dtrue\u0026player_ads_set_adformat_on_client\u003dtrue\u0026player_allow_autonav_after_playlist\u003dtrue\u0026player_bootstrap_method\u003dtrue\u0026player_defer_caption_display\u003d1000\u0026player_destroy_old_version\u003dtrue\u0026player_doubletap_to_seek\u003dtrue\u0026player_enable_playback_playlist_change\u003dtrue\u0026player_endscreen_ellipsis_fix\u003dtrue\u0026player_underlay_min_player_width\u003d768.0\u0026player_underlay_video_width_fraction\u003d0.6\u0026player_web_canary_stage\u003d0\u0026playready_first_play_expiration\u003d-1\u0026polymer_bad_build_labels\u003dtrue\u0026polymer_log_prop_change_observer_percent\u003d0\u0026polymer_verifiy_app_state\u003dtrue\u0026preskip_button_style_ads_backend\u003dcountdown_next_to_thumbnail\u0026qoe_nwl_downloads\u003dtrue\u0026qoe_send_and_write\u003dtrue\u0026record_app_crashed_web\u003dtrue\u0026replace_playability_retriever_in_watch\u003dtrue\u0026scheduler_use_raf_by_default\u003dtrue\u0026self_podding_header_string_template\u003dself_podding_interstitial_message\u0026self_podding_highlight_non_default_button\u003dtrue\u0026self_podding_midroll_choice_string_template\u003dself_podding_midroll_choice\u0026send_config_hash_timer\u003d0\u0026set_interstitial_advertisers_question_text\u003dtrue\u0026short_start_time_prefer_publish_in_watch_log\u003dtrue\u0026should_clear_video_data_on_player_cued_unstarted\u003dtrue\u0026skip_inline_muted_license_service_check\u003dtrue\u0026skip_invalid_ytcsi_ticks\u003dtrue\u0026skip_ls_gel_retry\u003dtrue\u0026skip_setting_info_in_csi_data_object\u003dtrue\u0026start_client_gcf\u003dtrue\u0026start_client_gcf_for_player\u003dtrue\u0026streaming_data_emergency_itag_blacklist\u003d[]\u0026suppress_error_204_logging\u003dtrue\u0026transport_use_scheduler\u003dtrue\u0026tv_pacf_logging_sample_rate\u003d0.01\u0026tvhtml5_unplugged_preload_cache_size\u003d5\u0026uncover_ad_badge_on_RTL_tiny_window\u003dtrue\u0026unplugged_dai_live_chunk_readahead\u003d3\u0026unplugged_tvhtml5_video_preload_on_focus_delay_ms\u003d0\u0026use_inlined_player_rpc\u003dtrue\u0026use_new_in_memory_storage\u003dtrue\u0026use_new_nwl_initialization\u003dtrue\u0026use_new_nwl_saw\u003dtrue\u0026use_new_nwl_stw\u003dtrue\u0026use_new_nwl_wts\u003dtrue\u0026use_player_abuse_bg_library\u003dtrue\u0026use_profilepage_event_label_in_carousel_playbacks\u003dtrue\u0026use_request_time_ms_header\u003dtrue\u0026use_session_based_sampling\u003dtrue\u0026use_shared_nsm\u003dtrue\u0026use_shared_nsm_and_keep_yt_online_updated\u003dtrue\u0026use_ts_visibilitylogger\u003dtrue\u0026variable_buffer_timeout_ms\u003d0\u0026verify_ads_itag_early\u003dtrue\u0026vp9_drm_live\u003dtrue\u0026vss_final_ping_send_and_write\u003dtrue\u0026vss_pings_using_networkless\u003dtrue\u0026vss_playback_use_send_and_write\u003dtrue\u0026web_api_url\u003dtrue\u0026web_cinematic_watch_settings\u003dtrue\u0026web_client_version_override\u003d\u0026web_dedupe_ve_grafting\u003dtrue\u0026web_deprecate_service_ajax_map_dependency\u003dtrue\u0026web_enable_voz_audio_feedback\u003dtrue\u0026web_foreground_heartbeat_interval_ms\u003d28000\u0026web_forward_command_on_pbj\u003dtrue\u0026web_gel_debounce_ms\u003d10000\u0026web_gel_timeout_cap\u003dtrue\u0026web_key_moments_markers\u003dtrue\u0026web_log_memory_total_kbytes\u003dtrue\u0026web_logging_max_batch\u003d150\u0026web_modern_ads\u003dtrue\u0026web_modern_buttons\u003dtrue\u0026web_modern_buttons_bl_survey\u003dtrue\u0026web_modern_subscribe\u003dtrue\u0026web_modern_subscribe_style\u003dfilled\u0026web_new_autonav_countdown\u003dtrue\u0026web_one_platform_error_handling\u003dtrue\u0026web_op_signal_type_banlist\u003d[]\u0026web_playback_associated_log_ctt\u003dtrue\u0026web_playback_associated_ve\u003dtrue\u0026web_player_api_logging_fraction\u003d0.01\u0026web_player_autonav_toggle_always_listen\u003dtrue\u0026web_player_autonav_use_server_provided_state\u003dtrue\u0026web_player_caption_language_preference_stickiness_duration\u003d0\u0026web_player_decouple_autonav\u003dtrue\u0026web_player_enable_early_warning_snackbar\u003dtrue\u0026web_player_enable_premium_hbr_in_h5_api\u003dtrue\u0026web_player_enable_premium_hbr_playback_cap\u003dtrue\u0026web_player_fine_scrubbing\u003dtrue\u0026web_player_gvi_wexit_adunit\u003dtrue\u0026web_player_gvi_wexit_all_player_styles\u003dtrue\u0026web_player_gvi_wexit_living_room_bedrock\u003dtrue\u0026web_player_gvi_wexit_living_room_kids\u003dtrue\u0026web_player_gvi_wexit_living_room_other\u003dtrue\u0026web_player_gvi_wexit_living_room_pangea\u003dtrue\u0026web_player_gvi_wexit_living_room_simply\u003dtrue\u0026web_player_gvi_wexit_living_room_unplugged\u003dtrue\u0026web_player_innertube_playlist_update\u003dtrue\u0026web_player_ipp_canary_type_for_logging\u003d\u0026web_player_live_monitor_env\u003dtrue\u0026web_player_move_autonav_toggle\u003dtrue\u0026web_player_music_visualizer_treatment\u003dfake\u0026web_player_mutable_event_label\u003dtrue\u0026web_player_nitrate_promo_tooltip\u003dtrue\u0026web_player_no_force_gvi\u003dtrue\u0026web_player_response_playback_tracking_parsing\u003dtrue\u0026web_player_seek_chapters_by_shortcut\u003dtrue\u0026web_player_sentinel_is_uniplayer\u003dtrue\u0026web_player_should_honor_include_asr_setting\u003dtrue\u0026web_player_show_music_in_this_video_graphic\u003dvideo_thumbnail\u0026web_player_small_hbp_settings_menu\u003dtrue\u0026web_player_ss_dai_ad_fetching_timeout_ms\u003d15000\u0026web_player_ss_media_time_offset\u003dtrue\u0026web_player_ss_timeout_skip_ads\u003dtrue\u0026web_player_ssdai_all_acpns_aids_logging_killswitch\u003dtrue\u0026web_player_touch_mode_improvements\u003dtrue\u0026web_player_transfer_timeout_threshold_ms\u003d10800000\u0026web_player_unset_default_csn_killswitch\u003dtrue\u0026web_player_use_cinematic_label_2\u003dtrue\u0026web_player_use_new_api_for_quality_pullback\u003dtrue\u0026web_player_vss_pageid_header\u003dtrue\u0026web_player_watch_next_response\u003dtrue\u0026web_player_watch_next_response_parsing\u003dtrue\u0026web_prefetch_preload_video\u003dtrue\u0026web_repeating_chapters\u003dtrue\u0026web_rounded_containers\u003dtrue\u0026web_rounded_thumbnails\u003dtrue\u0026web_settings_menu_icons\u003dtrue\u0026web_smoothness_test_duration_ms\u003d0\u0026web_smoothness_test_method\u003d0\u0026web_yt_config_context\u003dtrue\u0026woffle_clean_up_after_entity_migration\u003dtrue\u0026woffle_orchestration\u003dtrue\u0026ytidb_clear_embedded_player\u003dtrue\u0026ytidb_fetch_datasync_ids_for_data_cleanup\u003dtrue\u0026ytidb_remake_db_retries\u003d3\u0026ytidb_reopen_db_retries\u003d3\u0026ytidb_transaction_ended_event_rate_limit\u003d0.02\u0026ytidb_transaction_ended_event_rate_limit_session\u003d0.2\u0026ytidb_transaction_ended_event_rate_limit_transaction\u003d0.1","cspNonce":"nopnosk9VoEiau3Xtg_3uQ","canaryState":"none","enableCsiLogging":true,"csiPageType":"channels","authorizedUserIndex":0,"datasyncId":"106384449314396247844||"},"WEB_PLAYER_CONTEXT_CONFIG_ID_KEVLAR_PLAYLIST_OVERVIEW":{"rootElementId":"c4-player","jsUrl":"/s/player/97ea7458/player_ias.vflset/en_US/base.js","cssUrl":"/s/player/97ea7458/www-player.css","contextId":"WEB_PLAYER_CONTEXT_CONFIG_ID_KEVLAR_PLAYLIST_OVERVIEW","eventLabel":"playlistoverview","contentRegion":"CA","hl":"en_US","hostLanguage":"en","playerStyle":"desktop-polymer","innertubeApiKey":"AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8","innertubeApiVersion":"v1","innertubeContextClientVersion":"2.20230201.01.00","device":{"brand":"apple","model":"","browser":"Chrome","browserVersion":"109.0.0.0","os":"Macintosh","osVersion":"10_15_7","platform":"DESKTOP","interfaceName":"WEB","interfaceVersion":"2.20230201.01.00","deviceYear":2013},"serializedExperimentIds":"23983296,23986016,24004644,24007246,24080738,24135310,24169501,24219381,24255163,24282011,24396645,24415864,24416291,24416441,24433679,24437577,24439361,24441240,24449113,24449639,24450366,24451032,24454357,24454498,24457577,24457884,24460376,24463912,24469897","serializedExperimentFlags":"H5_async_logging_delay_ms\u003d30000.0\u0026H5_enable_full_pacf_logging\u003dtrue\u0026H5_use_async_logging\u003dtrue\u0026ad_pod_disable_companion_persist_ads_quality\u003dtrue\u0026addto_ajax_log_warning_fraction\u003d0.1\u0026align_ad_to_video_player_lifecycle_for_bulleit\u003dtrue\u0026allow_live_autoplay\u003dtrue\u0026allow_poltergust_autoplay\u003dtrue\u0026allow_skip_networkless\u003dtrue\u0026autoplay_time\u003d8000\u0026autoplay_time_for_fullscreen\u003d3000\u0026autoplay_time_for_music_content\u003d3000\u0026background_thread_flush_logs_due_to_batch_limit\u003dtrue\u0026bg_vm_reinit_threshold\u003d7200000\u0026blocked_packages_for_sps\u003d[]\u0026botguard_async_snapshot_timeout_ms\u003d3000\u0026check_ad_ui_status_for_mweb_safari\u003dtrue\u0026check_navigator_accuracy_timeout_ms\u003d0\u0026clear_user_partitioned_ls\u003dtrue\u0026client_respect_autoplay_switch_button_renderer\u003dtrue\u0026csi_on_gel\u003dtrue\u0026dash_manifest_version\u003d5\u0026debug_bandaid_hostname\u003d\u0026debug_sherlog_username\u003d\u0026delay_ads_gvi_call_on_bulleit_living_room_ms\u003d0\u0026deprecate_csi_has_info\u003dtrue\u0026deprecate_pair_servlet_enabled\u003dtrue\u0026deprecate_two_way_binding_child\u003dtrue\u0026deprecate_two_way_binding_parent\u003dtrue\u0026desktop_image_cta_no_background\u003dtrue\u0026desktop_log_img_click_location\u003dtrue\u0026desktop_player_button_tooltip_with_shortcut\u003dtrue\u0026desktop_sparkles_light_cta_button\u003dtrue\u0026disable_channel_id_check_for_suspended_channels\u003dtrue\u0026disable_child_node_auto_formatted_strings\u003dtrue\u0026disable_defer_admodule_on_advertiser_video\u003dtrue\u0026disable_features_for_supex\u003dtrue\u0026disable_legacy_desktop_remote_queue\u003dtrue\u0026disable_mdx_connection_in_mdx_module_for_music_web\u003dtrue\u0026disable_new_pause_state3\u003dtrue\u0026disable_pacf_logging_for_memory_limited_tv\u003dtrue\u0026disable_rounding_ad_notify\u003dtrue\u0026disable_simple_mixed_direction_formatted_strings\u003dtrue\u0026disable_ssdai_on_errors\u003dtrue\u0026disable_tabbing_before_flyout_ad_elements_appear\u003dtrue\u0026disable_thumbnail_preloading\u003dtrue\u0026embeds_enable_allow_watch_again_endscreen_for_eligible_shorts\u003dtrue\u0026embeds_enable_embed_module\u003dtrue\u0026embeds_enable_shorts_branded_ui\u003dtrue\u0026embeds_enable_shorts_links_for_eligible_shorts\u003dtrue\u0026embeds_web_enable_gws_wh_rel_off\u003dtrue\u0026embeds_web_enable_info_panel_preview\u003dtrue\u0026embeds_web_enable_load_player_from_page_show\u003dtrue\u0026embeds_web_enable_logging_event_handlers\u003dtrue\u0026embeds_web_enable_pem_domain_fix_for_ad_requests\u003dtrue\u0026embeds_web_enable_replace_unload_w_pagehide\u003dtrue\u0026embeds_web_enable_ve_conversion_logging_tracking_no_allow_list\u003dtrue\u0026embeds_web_enable_video_data_refactoring_break_down_and_move_methods\u003dtrue\u0026embeds_web_enable_video_data_refactoring_like_button_renderer\u003dtrue\u0026embeds_web_hide_unfilled_more_videos_suggestions\u003dtrue\u0026embeds_web_lite_mode\u003d1\u0026embeds_web_nwl_disable_nocookie\u003dtrue\u0026embeds_web_synth_ch_headers_banned_urls_regex\u003d\u0026enable_ad_cpn_macro_substitution_for_click_pings\u003dtrue\u0026enable_cast_for_web_unplugged\u003dtrue\u0026enable_cast_on_music_web\u003dtrue\u0026enable_client_page_id_header_for_first_party_pings\u003dtrue\u0026enable_client_sli_logging\u003dtrue\u0026enable_discrete_live_precise_embargos\u003dtrue\u0026enable_error_corrections_infocard\u003dtrue\u0026enable_error_corrections_infocard_web_client\u003dtrue\u0026enable_error_corrections_infocard_web_client_check\u003dtrue\u0026enable_error_corrections_infocards_icon_web\u003dtrue\u0026enable_eviction_protection_for_bulleit\u003dtrue\u0026enable_gel_log_commands\u003dtrue\u0026enable_handles_account_menu_switcher\u003dtrue\u0026enable_inline_preview_controls\u003dtrue\u0026enable_live_premiere_web_player_indicator\u003dtrue\u0026enable_lr_home_infeed_ads_inline_playback_progress_pings\u003dtrue\u0026enable_macro_substitution_on_html5\u003dtrue\u0026enable_mixed_direction_formatted_strings\u003dtrue\u0026enable_mweb_livestream_ui_update\u003dtrue\u0026enable_new_paid_product_placement\u003dtrue\u0026enable_post_ad_perception_survey_fix_on_tvhtml5\u003dtrue\u0026enable_post_ad_perception_survey_in_tvhtml5\u003dtrue\u0026enable_precise_embargos\u003dtrue\u0026enable_server_stitched_dai\u003dtrue\u0026enable_shorts_player\u003dtrue\u0026enable_skip_ad_guidance_prompt\u003dtrue\u0026enable_skippable_ads_for_unplugged_ad_pod\u003dtrue\u0026enable_smearing_expansion_dai\u003dtrue\u0026enable_tectonic_ad_ux_for_halftime\u003dtrue\u0026enable_third_party_info\u003dtrue\u0026enable_topsoil_wta_for_halftime_live_infra\u003dtrue\u0026enable_web_media_session_metadata_fix\u003dtrue\u0026error_message_for_gsuite_network_restrictions\u003dtrue\u0026export_networkless_options\u003dtrue\u0026external_fullscreen_with_edu\u003dtrue\u0026fast_autonav_in_background\u003dtrue\u0026fetch_att_independently\u003dtrue\u0026fill_single_video_with_notify_to_lasr\u003dtrue\u0026filter_vp9_for_csdai\u003dtrue\u0026fix_ads_tracking_for_swf_config_deprecation_mweb\u003dtrue\u0026gcf_config_store_enabled\u003dtrue\u0026gpa_sparkles_ten_percent_layer\u003dtrue\u0026gvi_channel_client_screen\u003dtrue\u0026h5_companion_enable_adcpn_macro_substitution_for_click_pings\u003dtrue\u0026h5_inplayer_enable_adcpn_macro_substitution_for_click_pings\u003dtrue\u0026hfr_dropped_framerate_fallback_threshold\u003d0\u0026hide_endpoint_overflow_on_ytd_display_ad_renderer\u003dtrue\u0026hls_use_new_codecs_string_api\u003dtrue\u0026html5_ad_timeout_ms\u003d0\u0026html5_ads_preroll_lock_timeout_delay_ms\u003d15000\u0026html5_allow_discontiguous_slices\u003dtrue\u0026html5_allow_video_keyframe_without_audio\u003dtrue\u0026html5_append_init_while_paused\u003dtrue\u0026html5_apply_ustreamer_cap_per_video_id\u003dtrue\u0026html5_att_oauth\u003dtrue\u0026html5_attach_num_random_bytes_to_bandaid\u003d0\u0026html5_attach_po_token_to_bandaid\u003dtrue\u0026html5_autonav_cap_idle_secs\u003d0\u0026html5_autonav_quality_cap\u003d720\u0026html5_autoplay_default_quality_cap\u003d0\u0026html5_block_pip_safari_delay\u003d0\u0026html5_bmff_new_fourcc_check\u003dtrue\u0026html5_cap_quality_for_tv_hfr\u003dtrue\u0026html5_change_player_mode_order_for_logging\u003dtrue\u0026html5_clamp_cuepoints_to_min\u003dtrue\u0026html5_cobalt_max_size_for_immed_job\u003d0\u0026html5_cobalt_min_processor_cnt_to_offload_algo\u003d0\u0026html5_cobalt_override_quic\u003d0\u0026html5_consume_media_bytes_slice_infos\u003dtrue\u0026html5_control_flow_include_trigger_logging_in_tmp_logs\u003dtrue\u0026html5_create_manifest_from_protos\u003dtrue\u0026html5_de_dupe_content_video_loads_in_lifecycle_api\u003dtrue\u0026html5_deadzone_multiplier\u003d1.0\u0026html5_debug_data_log_probability\u003d0.1\u0026html5_decode_to_texture_cap\u003dtrue\u0026html5_decoder_freeze_timeout_delay_ms\u003d0\u0026html5_default_ad_gain\u003d0.5\u0026html5_default_quality_cap\u003d0\u0026html5_defer_ad_module_ms\u003d0\u0026html5_defer_fetch_att_ms\u003d1000\u0026html5_defer_modules_delay_time_millis\u003d0\u0026html5_delay_initial_loading\u003dtrue\u0026html5_delay_retries_for_host_timeout\u003dtrue\u0026html5_delayed_retry_count\u003d1\u0026html5_delayed_retry_delay_ms\u003d5000\u0026html5_deprecate_video_tag_pool\u003dtrue\u0026html5_desktop_vr180_allow_panning\u003dtrue\u0026html5_desync_cue_range_threshold\u003d0\u0026html5_df_downgrade_thresh\u003d0.2\u0026html5_disable_connection_issue_event\u003dtrue\u0026html5_disable_csi_for_bulleit\u003dtrue\u0026html5_disable_move_pssh_to_moov\u003dtrue\u0026html5_disable_non_contiguous\u003dtrue\u0026html5_displayed_frame_rate_downgrade_threshold\u003d45\u0026html5_drm_check_all_key_error_states\u003dtrue\u0026html5_drm_cpi_license_key\u003dtrue\u0026html5_early_read_chunk\u003dtrue\u0026html5_enable_ac3\u003dtrue\u0026html5_enable_ads_client_monitoring_log_tv\u003dtrue\u0026html5_enable_atv_offline\u003dtrue\u0026html5_enable_client_hints_override\u003dtrue\u0026html5_enable_eac3\u003dtrue\u0026html5_enable_embedded_player_visibility_signals\u003dtrue\u0026html5_enable_non_notify_composite_vod_lsar_pacf\u003dtrue\u0026html5_enable_single_video_vod_ivar_on_pacf\u003dtrue\u0026html5_enable_tvos_dash\u003dtrue\u0026html5_enable_tvos_encrypted_vp9\u003dtrue\u0026html5_enable_widevine_for_alc\u003dtrue\u0026html5_enable_widevine_for_fast_linear\u003dtrue\u0026html5_encourage_array_coalescing\u003dtrue\u0026html5_exile_on_drm_fatal\u003dtrue\u0026html5_fill_isTypeSupported_capability_cache_earlier\u003dtrue\u0026html5_fludd_suspend\u003dtrue\u0026html5_flush_segment_index_on_error\u003dtrue\u0026html5_flush_vss_with_rti_and_rtn\u003dtrue\u0026html5_gapless_ended_transition_buffer_ms\u003d200\u0026html5_gapless_preloading\u003dtrue\u0026html5_generate_session_po_token\u003dtrue\u0026html5_gl_fps_threshold\u003d0\u0026html5_halt_ssdai_fetch_on_predict_start\u003dtrue\u0026html5_hdcp_probing_stream_url\u003d\u0026html5_heartbeat_set_ended\u003dtrue\u0026html5_hfr_quality_cap\u003d0\u0026html5_high_res_logging_percent\u003d0.01\u0026html5_idle_rate_limit_ms\u003d0\u0026html5_ignore_media_element_event_loadeddata\u003dtrue\u0026html5_innertube_heartbeats_for_fairplay\u003dtrue\u0026html5_innertube_heartbeats_for_playready\u003dtrue\u0026html5_innertube_heartbeats_for_widevine\u003dtrue\u0026html5_ios4_seek_above_zero\u003dtrue\u0026html5_ios7_force_play_on_stall\u003dtrue\u0026html5_ios_force_seek_to_zero_on_stop\u003dtrue\u0026html5_jumbo_mobile_subsegment_readahead_target\u003d3.0\u0026html5_jumbo_ull_nonstreaming_mffa_ms\u003d4000\u0026html5_jumbo_ull_subsegment_readahead_target\u003d1.3\u0026html5_license_constraint_delay\u003d5000\u0026html5_live_abr_head_miss_fraction\u003d0.0\u0026html5_live_abr_repredict_fraction\u003d0.0\u0026html5_live_byterate_factor_for_readahead\u003d1.3\u0026html5_live_low_latency_bandwidth_window\u003d0.0\u0026html5_live_normal_latency_bandwidth_window\u003d0.0\u0026html5_live_partial_response_resumable\u003dtrue\u0026html5_live_quality_cap\u003d0\u0026html5_live_ultra_low_latency_bandwidth_window\u003d0.0\u0026html5_log_audio_abr\u003dtrue\u0026html5_log_experiment_id_from_player_response_to_ctmp\u003d\u0026html5_log_first_ssdai_requests_killswitch\u003dtrue\u0026html5_log_offline_playback_started_event\u003dtrue\u0026html5_log_readahead_on_playback_start\u003dtrue\u0026html5_log_rebuffer_events\u003d5\u0026html5_log_server_url_param\u003dtrue\u0026html5_log_trigger_events_with_debug_data\u003dtrue\u0026html5_long_rebuffer_jiggle_cmt_delay_ms\u003d0\u0026html5_long_rebuffer_new_elem_shorts_delay_ms\u003d0\u0026html5_long_rebuffer_threshold_ms\u003d30000\u0026html5_manifestless_seg_drift_limit_secs\u003d0\u0026html5_manifestless_unplugged\u003dtrue\u0026html5_manifestless_vp9_otf\u003dtrue\u0026html5_max_drift_per_track_secs\u003d0.0\u0026html5_max_headm_for_streaming_xhr\u003d0\u0026html5_max_live_dvr_window_plus_margin_secs\u003d46800.0\u0026html5_max_readbehind_secs\u003d0\u0026html5_max_redirect_response_length\u003d8192\u0026html5_max_selectable_quality_ordinal\u003d0\u0026html5_maximum_readahead_seconds\u003d0.0\u0026html5_media_fullscreen\u003dtrue\u0026html5_mfl_extend_max_request_time\u003dtrue\u0026html5_min_readbehind_cap_secs\u003d60\u0026html5_min_readbehind_secs\u003d0\u0026html5_min_selectable_quality_ordinal\u003d0\u0026html5_min_startup_buffered_ad_media_duration_secs\u003d1.2\u0026html5_min_startup_buffered_media_duration_secs\u003d1.2\u0026html5_minimum_readahead_seconds\u003d0.0\u0026html5_new_min_startup_smooth_logic\u003dtrue\u0026html5_no_placeholder_rollbacks\u003dtrue\u0026html5_non_network_rebuffer_duration_ms\u003d0\u0026html5_non_onesie_attach_po_token\u003dtrue\u0026html5_not_register_disposables_when_core_listens\u003dtrue\u0026html5_offline_failure_retry_limit\u003d2\u0026html5_onesie_cast\u003dtrue\u0026html5_onesie_defer_content_loader_ms\u003d0\u0026html5_onesie_disable_js_cleartext_compression\u003dtrue\u0026html5_onesie_enable_server_side_badwidth_estimation\u003dtrue\u0026html5_onesie_host_racing_cap_ms\u003d0\u0026html5_onesie_ignore_innertube_api_key\u003dtrue\u0026html5_onesie_live_ttl_secs\u003d8\u0026html5_onesie_media_bytes\u003dtrue\u0026html5_onesie_nonzero_playback_start\u003dtrue\u0026html5_onesie_notify_cuepoint_manager_on_completion\u003dtrue\u0026html5_onesie_prefer_trusted_host\u003dtrue\u0026html5_onesie_prewarm_cooldown_ms\u003d0\u0026html5_onesie_prewarm_interval_ms\u003d0\u0026html5_onesie_prewarm_max_lact_ms\u003d0\u0026html5_onesie_redirector_timeout_ms\u003d0\u0026html5_onesie_request_timeout_ms\u003d1000\u0026html5_onesie_sticky_server_side\u003dtrue\u0026html5_pause_on_nonforeground_platform_errors\u003dtrue\u0026html5_peak_shave\u003dtrue\u0026html5_per_format_loudness_fix\u003dtrue\u0026html5_perf_cap_override_sticky\u003dtrue\u0026html5_performance_cap_floor\u003d360\u0026html5_performance_impact_profiling_timer_ms\u003d0\u0026html5_perserve_av1_perf_cap\u003dtrue\u0026html5_photos_use_vp9_otf\u003dtrue\u0026html5_platform_minimum_readahead_seconds\u003d0.0\u0026html5_platform_whitelisted_for_frame_accurate_seeks\u003dtrue\u0026html5_player_autonav_logging\u003dtrue\u0026html5_player_dynamic_bottom_gradient\u003dtrue\u0026html5_player_min_build_cl\u003d-1\u0026html5_player_preload_ad_fix\u003dtrue\u0026html5_post_interrupt_readahead\u003d20\u0026html5_prefer_server_bwe3\u003dtrue\u0026html5_preload_wait_time_secs\u003d0.0\u0026html5_probe_primary_delay_base_ms\u003d0\u0026html5_process_all_encrypted_events\u003dtrue\u0026html5_query_sw_secure_crypto_for_android\u003dtrue\u0026html5_random_playback_cap\u003d0\u0026html5_readahead_ratelimit\u003d3000\u0026html5_recognize_predict_start_cue_point\u003dtrue\u0026html5_reduce_istypesupported_calls\u003dtrue\u0026html5_remove_command_triggered_companions\u003dtrue\u0026html5_remove_not_servable_check_killswitch\u003dtrue\u0026html5_rename_apbs\u003dtrue\u0026html5_report_fatal_drm_restricted_error_killswitch\u003dtrue\u0026html5_report_slow_ads_as_error\u003dtrue\u0026html5_request_only_hdr_or_sdr_keys\u003dtrue\u0026html5_request_sizing_multiplier\u003d0.8\u0026html5_require_hdr_capability\u003dtrue\u0026html5_reset_media_stream_on_unresumable_slices\u003dtrue\u0026html5_resource_bad_status_delay_scaling\u003d1.5\u0026html5_restrict_streaming_xhr_on_sqless_requests\u003dtrue\u0026html5_safari_desktop_eme_min_version\u003d0\u0026html5_seek_jiggle_cmt_delay_ms\u003d8000\u0026html5_seek_new_elem_delay_ms\u003d12000\u0026html5_seek_new_elem_shorts_delay_ms\u003d0\u0026html5_seek_over_discontinuities_delay_ms\u003d0\u0026html5_seek_set_cmt_delay_ms\u003d2000\u0026html5_seek_timeout_delay_ms\u003d20000\u0026html5_selectable_formats_early_exit\u003dtrue\u0026html5_server_stitched_dai_decorated_url_retry_limit\u003d5\u0026html5_server_stitched_dai_group\u003dtrue\u0026html5_session_po_token_interval_time_ms\u003d900000\u0026html5_set_ended_in_pfx_live\u003dtrue\u0026html5_simplify_streaming_xhr\u003dtrue\u0026html5_skip_oob_start_seconds\u003dtrue\u0026html5_skip_slow_ad_delay_ms\u003d15000\u0026html5_skip_sub_quantum_discontinuity_secs\u003d0.0\u0026html5_slow_start_no_media_source_delay_ms\u003d0\u0026html5_slow_start_timeout_delay_ms\u003d20000\u0026html5_ssdai_adfetch_dynamic_timeout_ms\u003d0\u0026html5_ssdai_enable_new_seek_logic\u003dtrue\u0026html5_ssdai_flush_vss\u003dtrue\u0026html5_ssdai_vss_player_state_change\u003dtrue\u0026html5_start_seconds_reorder\u003dtrue\u0026html5_stateful_audio_min_adjustment_value\u003d0\u0026html5_static_abr_resolution_shelf\u003d0\u0026html5_store_xhr_headers_readable\u003dtrue\u0026html5_stream_metadata\u003dtrue\u0026html5_streaming_init_requests_sizes\u003d0\u0026html5_streaming_xhr_check_for_null_response\u003dtrue\u0026html5_subsegment_readahead_load_speed_check_interval\u003d0.5\u0026html5_subsegment_readahead_min_buffer_health_secs\u003d0.25\u0026html5_subsegment_readahead_min_buffer_health_secs_on_timeout\u003d0.1\u0026html5_subsegment_readahead_min_load_speed\u003d1.5\u0026html5_subsegment_readahead_seek_latency_fudge\u003d0.5\u0026html5_subsegment_readahead_target_buffer_health_secs\u003d0.5\u0026html5_subsegment_readahead_timeout_secs\u003d2.0\u0026html5_suspend_loader\u003dtrue\u0026html5_track_termination_during_request\u003dtrue\u0026html5_ugc_live_audio_51\u003dtrue\u0026html5_ugc_vod_audio_51\u003dtrue\u0026html5_ultra_high_res_logging_percent\u003d0.0\u0026html5_unreported_seek_reseek_delay_ms\u003d0\u0026html5_unrestricted_layer_high_res_logging_percent\u003d0.0\u0026html5_update_constraint\u003dtrue\u0026html5_use_post_for_media\u003dtrue\u0026html5_varispeed_playback_rate\u003dtrue\u0026html5_video_tbd_min_kb\u003d0\u0026html5_viewport_undersend_maximum\u003d0.0\u0026html5_watchdog_for_zero_seek\u003dtrue\u0026html5_web_enable_halftime_preroll\u003dtrue\u0026html5_webpo_idle_priority_job\u003dtrue\u0026html5_woffle_resume\u003dtrue\u0026html5_workaround_delay_trigger\u003dtrue\u0026html5_xhr_clean_up_multi_slice_facade\u003dtrue\u0026html5_ytvlr_enable_single_select_survey\u003dtrue\u0026il_use_view_model_logging_context\u003dtrue\u0026initial_gel_batch_timeout\u003d2000\u0026injected_license_handler_error_code\u003d0\u0026injected_license_handler_license_status\u003d0\u0026json_condensed_response\u003dtrue\u0026kevlar_command_handler_command_banlist\u003d[]\u0026kevlar_dropdown_fix\u003dtrue\u0026kevlar_gel_error_routing\u003dtrue\u0026kevlar_miniplayer\u003dtrue\u0026kevlar_miniplayer_expand_top\u003dtrue\u0026kevlar_miniplayer_play_pause_on_scrim\u003dtrue\u0026kevlar_playback_associated_queue\u003dtrue\u0026kevlar_queue_use_update_api\u003dtrue\u0026kevlar_smart_downloads\u003dtrue\u0026kevlar_smart_downloads_setting\u003dtrue\u0026kevlar_vimio_use_shared_monitor\u003dtrue\u0026kevlar_woffle\u003dtrue\u0026live_chunk_readahead\u003d3\u0026live_fresca_v2\u003dtrue\u0026log_errors_through_nwl_on_retry\u003dtrue\u0026log_heartbeat_with_lifecycles\u003dtrue\u0026log_web_endpoint_to_layer\u003dtrue\u0026log_window_onerror_fraction\u003d0.1\u0026manifestless_post_live\u003dtrue\u0026manifestless_post_live_ufph\u003dtrue\u0026max_prefetch_window_sec_for_livestream_optimization\u003d10\u0026max_resolution_for_white_noise\u003d360\u0026mdx_enable_privacy_disclosure_ui\u003dtrue\u0026mdx_load_cast_api_bootstrap_script\u003dtrue\u0026migrate_events_to_ts\u003dtrue\u0026min_prefetch_offset_sec_for_livestream_optimization\u003d20\u0026music_enable_shared_audio_tier_logic\u003dtrue\u0026mweb_c3_endscreen\u003dtrue\u0026mweb_enable_custom_control_shared\u003dtrue\u0026mweb_enable_skippables_on_jio_phone\u003dtrue\u0026mweb_muted_autoplay_animation\u003dshrink\u0026mweb_native_control_in_faux_fullscreen_shared\u003dtrue\u0026network_polling_interval\u003d30000\u0026networkless_gel\u003dtrue\u0026networkless_logging\u003dtrue\u0026new_codecs_string_api_uses_legacy_style\u003dtrue\u0026nwl_send_fast_on_unload\u003dtrue\u0026nwl_send_from_memory_when_online\u003dtrue\u0026offline_error_handling\u003dtrue\u0026pageid_as_header_web\u003dtrue\u0026parse_query_data_from_url\u003dtrue\u0026player_ads_set_adformat_on_client\u003dtrue\u0026player_allow_autonav_after_playlist\u003dtrue\u0026player_bootstrap_method\u003dtrue\u0026player_defer_caption_display\u003d1000\u0026player_destroy_old_version\u003dtrue\u0026player_doubletap_to_seek\u003dtrue\u0026player_enable_playback_playlist_change\u003dtrue\u0026player_endscreen_ellipsis_fix\u003dtrue\u0026player_underlay_min_player_width\u003d768.0\u0026player_underlay_video_width_fraction\u003d0.6\u0026player_web_canary_stage\u003d0\u0026playready_first_play_expiration\u003d-1\u0026polymer_bad_build_labels\u003dtrue\u0026polymer_log_prop_change_observer_percent\u003d0\u0026polymer_verifiy_app_state\u003dtrue\u0026preskip_button_style_ads_backend\u003dcountdown_next_to_thumbnail\u0026qoe_nwl_downloads\u003dtrue\u0026qoe_send_and_write\u003dtrue\u0026record_app_crashed_web\u003dtrue\u0026replace_playability_retriever_in_watch\u003dtrue\u0026scheduler_use_raf_by_default\u003dtrue\u0026self_podding_header_string_template\u003dself_podding_interstitial_message\u0026self_podding_highlight_non_default_button\u003dtrue\u0026self_podding_midroll_choice_string_template\u003dself_podding_midroll_choice\u0026send_config_hash_timer\u003d0\u0026set_interstitial_advertisers_question_text\u003dtrue\u0026short_start_time_prefer_publish_in_watch_log\u003dtrue\u0026should_clear_video_data_on_player_cued_unstarted\u003dtrue\u0026skip_inline_muted_license_service_check\u003dtrue\u0026skip_invalid_ytcsi_ticks\u003dtrue\u0026skip_ls_gel_retry\u003dtrue\u0026skip_setting_info_in_csi_data_object\u003dtrue\u0026start_client_gcf\u003dtrue\u0026start_client_gcf_for_player\u003dtrue\u0026streaming_data_emergency_itag_blacklist\u003d[]\u0026suppress_error_204_logging\u003dtrue\u0026transport_use_scheduler\u003dtrue\u0026tv_pacf_logging_sample_rate\u003d0.01\u0026tvhtml5_unplugged_preload_cache_size\u003d5\u0026uncover_ad_badge_on_RTL_tiny_window\u003dtrue\u0026unplugged_dai_live_chunk_readahead\u003d3\u0026unplugged_tvhtml5_video_preload_on_focus_delay_ms\u003d0\u0026use_inlined_player_rpc\u003dtrue\u0026use_new_in_memory_storage\u003dtrue\u0026use_new_nwl_initialization\u003dtrue\u0026use_new_nwl_saw\u003dtrue\u0026use_new_nwl_stw\u003dtrue\u0026use_new_nwl_wts\u003dtrue\u0026use_player_abuse_bg_library\u003dtrue\u0026use_profilepage_event_label_in_carousel_playbacks\u003dtrue\u0026use_request_time_ms_header\u003dtrue\u0026use_session_based_sampling\u003dtrue\u0026use_shared_nsm\u003dtrue\u0026use_shared_nsm_and_keep_yt_online_updated\u003dtrue\u0026use_ts_visibilitylogger\u003dtrue\u0026variable_buffer_timeout_ms\u003d0\u0026verify_ads_itag_early\u003dtrue\u0026vp9_drm_live\u003dtrue\u0026vss_final_ping_send_and_write\u003dtrue\u0026vss_pings_using_networkless\u003dtrue\u0026vss_playback_use_send_and_write\u003dtrue\u0026web_api_url\u003dtrue\u0026web_cinematic_watch_settings\u003dtrue\u0026web_client_version_override\u003d\u0026web_dedupe_ve_grafting\u003dtrue\u0026web_deprecate_service_ajax_map_dependency\u003dtrue\u0026web_enable_voz_audio_feedback\u003dtrue\u0026web_foreground_heartbeat_interval_ms\u003d28000\u0026web_forward_command_on_pbj\u003dtrue\u0026web_gel_debounce_ms\u003d10000\u0026web_gel_timeout_cap\u003dtrue\u0026web_key_moments_markers\u003dtrue\u0026web_log_memory_total_kbytes\u003dtrue\u0026web_logging_max_batch\u003d150\u0026web_modern_ads\u003dtrue\u0026web_modern_buttons\u003dtrue\u0026web_modern_buttons_bl_survey\u003dtrue\u0026web_modern_subscribe\u003dtrue\u0026web_modern_subscribe_style\u003dfilled\u0026web_new_autonav_countdown\u003dtrue\u0026web_one_platform_error_handling\u003dtrue\u0026web_op_signal_type_banlist\u003d[]\u0026web_playback_associated_log_ctt\u003dtrue\u0026web_playback_associated_ve\u003dtrue\u0026web_player_api_logging_fraction\u003d0.01\u0026web_player_autonav_toggle_always_listen\u003dtrue\u0026web_player_autonav_use_server_provided_state\u003dtrue\u0026web_player_caption_language_preference_stickiness_duration\u003d0\u0026web_player_decouple_autonav\u003dtrue\u0026web_player_enable_early_warning_snackbar\u003dtrue\u0026web_player_enable_premium_hbr_in_h5_api\u003dtrue\u0026web_player_enable_premium_hbr_playback_cap\u003dtrue\u0026web_player_fine_scrubbing\u003dtrue\u0026web_player_gvi_wexit_adunit\u003dtrue\u0026web_player_gvi_wexit_all_player_styles\u003dtrue\u0026web_player_gvi_wexit_living_room_bedrock\u003dtrue\u0026web_player_gvi_wexit_living_room_kids\u003dtrue\u0026web_player_gvi_wexit_living_room_other\u003dtrue\u0026web_player_gvi_wexit_living_room_pangea\u003dtrue\u0026web_player_gvi_wexit_living_room_simply\u003dtrue\u0026web_player_gvi_wexit_living_room_unplugged\u003dtrue\u0026web_player_innertube_playlist_update\u003dtrue\u0026web_player_ipp_canary_type_for_logging\u003d\u0026web_player_live_monitor_env\u003dtrue\u0026web_player_move_autonav_toggle\u003dtrue\u0026web_player_music_visualizer_treatment\u003dfake\u0026web_player_mutable_event_label\u003dtrue\u0026web_player_nitrate_promo_tooltip\u003dtrue\u0026web_player_no_force_gvi\u003dtrue\u0026web_player_response_playback_tracking_parsing\u003dtrue\u0026web_player_seek_chapters_by_shortcut\u003dtrue\u0026web_player_sentinel_is_uniplayer\u003dtrue\u0026web_player_should_honor_include_asr_setting\u003dtrue\u0026web_player_show_music_in_this_video_graphic\u003dvideo_thumbnail\u0026web_player_small_hbp_settings_menu\u003dtrue\u0026web_player_ss_dai_ad_fetching_timeout_ms\u003d15000\u0026web_player_ss_media_time_offset\u003dtrue\u0026web_player_ss_timeout_skip_ads\u003dtrue\u0026web_player_ssdai_all_acpns_aids_logging_killswitch\u003dtrue\u0026web_player_touch_mode_improvements\u003dtrue\u0026web_player_transfer_timeout_threshold_ms\u003d10800000\u0026web_player_unset_default_csn_killswitch\u003dtrue\u0026web_player_use_cinematic_label_2\u003dtrue\u0026web_player_use_new_api_for_quality_pullback\u003dtrue\u0026web_player_vss_pageid_header\u003dtrue\u0026web_player_watch_next_response\u003dtrue\u0026web_player_watch_next_response_parsing\u003dtrue\u0026web_prefetch_preload_video\u003dtrue\u0026web_repeating_chapters\u003dtrue\u0026web_rounded_containers\u003dtrue\u0026web_rounded_thumbnails\u003dtrue\u0026web_settings_menu_icons\u003dtrue\u0026web_smoothness_test_duration_ms\u003d0\u0026web_smoothness_test_method\u003d0\u0026web_yt_config_context\u003dtrue\u0026woffle_clean_up_after_entity_migration\u003dtrue\u0026woffle_orchestration\u003dtrue\u0026ytidb_clear_embedded_player\u003dtrue\u0026ytidb_fetch_datasync_ids_for_data_cleanup\u003dtrue\u0026ytidb_remake_db_retries\u003d3\u0026ytidb_reopen_db_retries\u003d3\u0026ytidb_transaction_ended_event_rate_limit\u003d0.02\u0026ytidb_transaction_ended_event_rate_limit_session\u003d0.2\u0026ytidb_transaction_ended_event_rate_limit_transaction\u003d0.1","disableSharing":true,"hideInfo":true,"disableWatchLater":true,"cspNonce":"nopnosk9VoEiau3Xtg_3uQ","canaryState":"none","enableCsiLogging":true,"csiPageType":"playlist_overview","authorizedUserIndex":0,"datasyncId":"106384449314396247844||"},"WEB_PLAYER_CONTEXT_CONFIG_ID_KEVLAR_VERTICAL_LANDING_PAGE_PROMO":{"rootElementId":"ytd-default-promo-panel-renderer-inline-playback-renderer","jsUrl":"/s/player/97ea7458/player_ias.vflset/en_US/base.js","cssUrl":"/s/player/97ea7458/www-player.css","contextId":"WEB_PLAYER_CONTEXT_CONFIG_ID_KEVLAR_VERTICAL_LANDING_PAGE_PROMO","eventLabel":"profilepage","contentRegion":"CA","hl":"en_US","hostLanguage":"en","playerStyle":"desktop-polymer","innertubeApiKey":"AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8","innertubeApiVersion":"v1","innertubeContextClientVersion":"2.20230201.01.00","controlsType":0,"disableRelatedVideos":true,"annotationsLoadPolicy":3,"device":{"brand":"apple","model":"","browser":"Chrome","browserVersion":"109.0.0.0","os":"Macintosh","osVersion":"10_15_7","platform":"DESKTOP","interfaceName":"WEB","interfaceVersion":"2.20230201.01.00","deviceYear":2013},"serializedExperimentIds":"23983296,23986016,24004644,24007246,24080738,24135310,24169501,24219381,24255163,24282011,24396645,24415864,24416291,24416441,24433679,24437577,24439361,24441240,24449113,24449639,24450366,24451032,24454357,24454498,24457577,24457884,24460376,24463912,24469897","serializedExperimentFlags":"H5_async_logging_delay_ms\u003d30000.0\u0026H5_enable_full_pacf_logging\u003dtrue\u0026H5_use_async_logging\u003dtrue\u0026ad_pod_disable_companion_persist_ads_quality\u003dtrue\u0026addto_ajax_log_warning_fraction\u003d0.1\u0026align_ad_to_video_player_lifecycle_for_bulleit\u003dtrue\u0026allow_live_autoplay\u003dtrue\u0026allow_poltergust_autoplay\u003dtrue\u0026allow_skip_networkless\u003dtrue\u0026autoplay_time\u003d8000\u0026autoplay_time_for_fullscreen\u003d3000\u0026autoplay_time_for_music_content\u003d3000\u0026background_thread_flush_logs_due_to_batch_limit\u003dtrue\u0026bg_vm_reinit_threshold\u003d7200000\u0026blocked_packages_for_sps\u003d[]\u0026botguard_async_snapshot_timeout_ms\u003d3000\u0026check_ad_ui_status_for_mweb_safari\u003dtrue\u0026check_navigator_accuracy_timeout_ms\u003d0\u0026clear_user_partitioned_ls\u003dtrue\u0026client_respect_autoplay_switch_button_renderer\u003dtrue\u0026csi_on_gel\u003dtrue\u0026dash_manifest_version\u003d5\u0026debug_bandaid_hostname\u003d\u0026debug_sherlog_username\u003d\u0026delay_ads_gvi_call_on_bulleit_living_room_ms\u003d0\u0026deprecate_csi_has_info\u003dtrue\u0026deprecate_pair_servlet_enabled\u003dtrue\u0026deprecate_two_way_binding_child\u003dtrue\u0026deprecate_two_way_binding_parent\u003dtrue\u0026desktop_image_cta_no_background\u003dtrue\u0026desktop_log_img_click_location\u003dtrue\u0026desktop_player_button_tooltip_with_shortcut\u003dtrue\u0026desktop_sparkles_light_cta_button\u003dtrue\u0026disable_channel_id_check_for_suspended_channels\u003dtrue\u0026disable_child_node_auto_formatted_strings\u003dtrue\u0026disable_defer_admodule_on_advertiser_video\u003dtrue\u0026disable_features_for_supex\u003dtrue\u0026disable_legacy_desktop_remote_queue\u003dtrue\u0026disable_mdx_connection_in_mdx_module_for_music_web\u003dtrue\u0026disable_new_pause_state3\u003dtrue\u0026disable_pacf_logging_for_memory_limited_tv\u003dtrue\u0026disable_rounding_ad_notify\u003dtrue\u0026disable_simple_mixed_direction_formatted_strings\u003dtrue\u0026disable_ssdai_on_errors\u003dtrue\u0026disable_tabbing_before_flyout_ad_elements_appear\u003dtrue\u0026disable_thumbnail_preloading\u003dtrue\u0026embeds_enable_allow_watch_again_endscreen_for_eligible_shorts\u003dtrue\u0026embeds_enable_embed_module\u003dtrue\u0026embeds_enable_shorts_branded_ui\u003dtrue\u0026embeds_enable_shorts_links_for_eligible_shorts\u003dtrue\u0026embeds_web_enable_gws_wh_rel_off\u003dtrue\u0026embeds_web_enable_info_panel_preview\u003dtrue\u0026embeds_web_enable_load_player_from_page_show\u003dtrue\u0026embeds_web_enable_logging_event_handlers\u003dtrue\u0026embeds_web_enable_pem_domain_fix_for_ad_requests\u003dtrue\u0026embeds_web_enable_replace_unload_w_pagehide\u003dtrue\u0026embeds_web_enable_ve_conversion_logging_tracking_no_allow_list\u003dtrue\u0026embeds_web_enable_video_data_refactoring_break_down_and_move_methods\u003dtrue\u0026embeds_web_enable_video_data_refactoring_like_button_renderer\u003dtrue\u0026embeds_web_hide_unfilled_more_videos_suggestions\u003dtrue\u0026embeds_web_lite_mode\u003d1\u0026embeds_web_nwl_disable_nocookie\u003dtrue\u0026embeds_web_synth_ch_headers_banned_urls_regex\u003d\u0026enable_ad_cpn_macro_substitution_for_click_pings\u003dtrue\u0026enable_cast_for_web_unplugged\u003dtrue\u0026enable_cast_on_music_web\u003dtrue\u0026enable_client_page_id_header_for_first_party_pings\u003dtrue\u0026enable_client_sli_logging\u003dtrue\u0026enable_discrete_live_precise_embargos\u003dtrue\u0026enable_error_corrections_infocard\u003dtrue\u0026enable_error_corrections_infocard_web_client\u003dtrue\u0026enable_error_corrections_infocard_web_client_check\u003dtrue\u0026enable_error_corrections_infocards_icon_web\u003dtrue\u0026enable_eviction_protection_for_bulleit\u003dtrue\u0026enable_gel_log_commands\u003dtrue\u0026enable_handles_account_menu_switcher\u003dtrue\u0026enable_inline_preview_controls\u003dtrue\u0026enable_live_premiere_web_player_indicator\u003dtrue\u0026enable_lr_home_infeed_ads_inline_playback_progress_pings\u003dtrue\u0026enable_macro_substitution_on_html5\u003dtrue\u0026enable_mixed_direction_formatted_strings\u003dtrue\u0026enable_mweb_livestream_ui_update\u003dtrue\u0026enable_new_paid_product_placement\u003dtrue\u0026enable_post_ad_perception_survey_fix_on_tvhtml5\u003dtrue\u0026enable_post_ad_perception_survey_in_tvhtml5\u003dtrue\u0026enable_precise_embargos\u003dtrue\u0026enable_server_stitched_dai\u003dtrue\u0026enable_shorts_player\u003dtrue\u0026enable_skip_ad_guidance_prompt\u003dtrue\u0026enable_skippable_ads_for_unplugged_ad_pod\u003dtrue\u0026enable_smearing_expansion_dai\u003dtrue\u0026enable_tectonic_ad_ux_for_halftime\u003dtrue\u0026enable_third_party_info\u003dtrue\u0026enable_topsoil_wta_for_halftime_live_infra\u003dtrue\u0026enable_web_media_session_metadata_fix\u003dtrue\u0026error_message_for_gsuite_network_restrictions\u003dtrue\u0026export_networkless_options\u003dtrue\u0026external_fullscreen_with_edu\u003dtrue\u0026fast_autonav_in_background\u003dtrue\u0026fetch_att_independently\u003dtrue\u0026fill_single_video_with_notify_to_lasr\u003dtrue\u0026filter_vp9_for_csdai\u003dtrue\u0026fix_ads_tracking_for_swf_config_deprecation_mweb\u003dtrue\u0026gcf_config_store_enabled\u003dtrue\u0026gpa_sparkles_ten_percent_layer\u003dtrue\u0026gvi_channel_client_screen\u003dtrue\u0026h5_companion_enable_adcpn_macro_substitution_for_click_pings\u003dtrue\u0026h5_inplayer_enable_adcpn_macro_substitution_for_click_pings\u003dtrue\u0026hfr_dropped_framerate_fallback_threshold\u003d0\u0026hide_endpoint_overflow_on_ytd_display_ad_renderer\u003dtrue\u0026hls_use_new_codecs_string_api\u003dtrue\u0026html5_ad_timeout_ms\u003d0\u0026html5_ads_preroll_lock_timeout_delay_ms\u003d15000\u0026html5_allow_discontiguous_slices\u003dtrue\u0026html5_allow_video_keyframe_without_audio\u003dtrue\u0026html5_append_init_while_paused\u003dtrue\u0026html5_apply_ustreamer_cap_per_video_id\u003dtrue\u0026html5_att_oauth\u003dtrue\u0026html5_attach_num_random_bytes_to_bandaid\u003d0\u0026html5_attach_po_token_to_bandaid\u003dtrue\u0026html5_autonav_cap_idle_secs\u003d0\u0026html5_autonav_quality_cap\u003d720\u0026html5_autoplay_default_quality_cap\u003d0\u0026html5_block_pip_safari_delay\u003d0\u0026html5_bmff_new_fourcc_check\u003dtrue\u0026html5_cap_quality_for_tv_hfr\u003dtrue\u0026html5_change_player_mode_order_for_logging\u003dtrue\u0026html5_clamp_cuepoints_to_min\u003dtrue\u0026html5_cobalt_max_size_for_immed_job\u003d0\u0026html5_cobalt_min_processor_cnt_to_offload_algo\u003d0\u0026html5_cobalt_override_quic\u003d0\u0026html5_consume_media_bytes_slice_infos\u003dtrue\u0026html5_control_flow_include_trigger_logging_in_tmp_logs\u003dtrue\u0026html5_create_manifest_from_protos\u003dtrue\u0026html5_de_dupe_content_video_loads_in_lifecycle_api\u003dtrue\u0026html5_deadzone_multiplier\u003d1.0\u0026html5_debug_data_log_probability\u003d0.1\u0026html5_decode_to_texture_cap\u003dtrue\u0026html5_decoder_freeze_timeout_delay_ms\u003d0\u0026html5_default_ad_gain\u003d0.5\u0026html5_default_quality_cap\u003d0\u0026html5_defer_ad_module_ms\u003d0\u0026html5_defer_fetch_att_ms\u003d1000\u0026html5_defer_modules_delay_time_millis\u003d0\u0026html5_delay_initial_loading\u003dtrue\u0026html5_delay_retries_for_host_timeout\u003dtrue\u0026html5_delayed_retry_count\u003d1\u0026html5_delayed_retry_delay_ms\u003d5000\u0026html5_deprecate_video_tag_pool\u003dtrue\u0026html5_desktop_vr180_allow_panning\u003dtrue\u0026html5_desync_cue_range_threshold\u003d0\u0026html5_df_downgrade_thresh\u003d0.2\u0026html5_disable_connection_issue_event\u003dtrue\u0026html5_disable_csi_for_bulleit\u003dtrue\u0026html5_disable_move_pssh_to_moov\u003dtrue\u0026html5_disable_non_contiguous\u003dtrue\u0026html5_displayed_frame_rate_downgrade_threshold\u003d45\u0026html5_drm_check_all_key_error_states\u003dtrue\u0026html5_drm_cpi_license_key\u003dtrue\u0026html5_early_read_chunk\u003dtrue\u0026html5_enable_ac3\u003dtrue\u0026html5_enable_ads_client_monitoring_log_tv\u003dtrue\u0026html5_enable_atv_offline\u003dtrue\u0026html5_enable_client_hints_override\u003dtrue\u0026html5_enable_eac3\u003dtrue\u0026html5_enable_embedded_player_visibility_signals\u003dtrue\u0026html5_enable_non_notify_composite_vod_lsar_pacf\u003dtrue\u0026html5_enable_single_video_vod_ivar_on_pacf\u003dtrue\u0026html5_enable_tvos_dash\u003dtrue\u0026html5_enable_tvos_encrypted_vp9\u003dtrue\u0026html5_enable_widevine_for_alc\u003dtrue\u0026html5_enable_widevine_for_fast_linear\u003dtrue\u0026html5_encourage_array_coalescing\u003dtrue\u0026html5_exile_on_drm_fatal\u003dtrue\u0026html5_fill_isTypeSupported_capability_cache_earlier\u003dtrue\u0026html5_fludd_suspend\u003dtrue\u0026html5_flush_segment_index_on_error\u003dtrue\u0026html5_flush_vss_with_rti_and_rtn\u003dtrue\u0026html5_gapless_ended_transition_buffer_ms\u003d200\u0026html5_gapless_preloading\u003dtrue\u0026html5_generate_session_po_token\u003dtrue\u0026html5_gl_fps_threshold\u003d0\u0026html5_halt_ssdai_fetch_on_predict_start\u003dtrue\u0026html5_hdcp_probing_stream_url\u003d\u0026html5_heartbeat_set_ended\u003dtrue\u0026html5_hfr_quality_cap\u003d0\u0026html5_high_res_logging_percent\u003d0.01\u0026html5_idle_rate_limit_ms\u003d0\u0026html5_ignore_media_element_event_loadeddata\u003dtrue\u0026html5_innertube_heartbeats_for_fairplay\u003dtrue\u0026html5_innertube_heartbeats_for_playready\u003dtrue\u0026html5_innertube_heartbeats_for_widevine\u003dtrue\u0026html5_ios4_seek_above_zero\u003dtrue\u0026html5_ios7_force_play_on_stall\u003dtrue\u0026html5_ios_force_seek_to_zero_on_stop\u003dtrue\u0026html5_jumbo_mobile_subsegment_readahead_target\u003d3.0\u0026html5_jumbo_ull_nonstreaming_mffa_ms\u003d4000\u0026html5_jumbo_ull_subsegment_readahead_target\u003d1.3\u0026html5_license_constraint_delay\u003d5000\u0026html5_live_abr_head_miss_fraction\u003d0.0\u0026html5_live_abr_repredict_fraction\u003d0.0\u0026html5_live_byterate_factor_for_readahead\u003d1.3\u0026html5_live_low_latency_bandwidth_window\u003d0.0\u0026html5_live_normal_latency_bandwidth_window\u003d0.0\u0026html5_live_partial_response_resumable\u003dtrue\u0026html5_live_quality_cap\u003d0\u0026html5_live_ultra_low_latency_bandwidth_window\u003d0.0\u0026html5_log_audio_abr\u003dtrue\u0026html5_log_experiment_id_from_player_response_to_ctmp\u003d\u0026html5_log_first_ssdai_requests_killswitch\u003dtrue\u0026html5_log_offline_playback_started_event\u003dtrue\u0026html5_log_readahead_on_playback_start\u003dtrue\u0026html5_log_rebuffer_events\u003d5\u0026html5_log_server_url_param\u003dtrue\u0026html5_log_trigger_events_with_debug_data\u003dtrue\u0026html5_long_rebuffer_jiggle_cmt_delay_ms\u003d0\u0026html5_long_rebuffer_new_elem_shorts_delay_ms\u003d0\u0026html5_long_rebuffer_threshold_ms\u003d30000\u0026html5_manifestless_seg_drift_limit_secs\u003d0\u0026html5_manifestless_unplugged\u003dtrue\u0026html5_manifestless_vp9_otf\u003dtrue\u0026html5_max_drift_per_track_secs\u003d0.0\u0026html5_max_headm_for_streaming_xhr\u003d0\u0026html5_max_live_dvr_window_plus_margin_secs\u003d46800.0\u0026html5_max_readbehind_secs\u003d0\u0026html5_max_redirect_response_length\u003d8192\u0026html5_max_selectable_quality_ordinal\u003d0\u0026html5_maximum_readahead_seconds\u003d0.0\u0026html5_media_fullscreen\u003dtrue\u0026html5_mfl_extend_max_request_time\u003dtrue\u0026html5_min_readbehind_cap_secs\u003d60\u0026html5_min_readbehind_secs\u003d0\u0026html5_min_selectable_quality_ordinal\u003d0\u0026html5_min_startup_buffered_ad_media_duration_secs\u003d1.2\u0026html5_min_startup_buffered_media_duration_secs\u003d1.2\u0026html5_minimum_readahead_seconds\u003d0.0\u0026html5_new_min_startup_smooth_logic\u003dtrue\u0026html5_no_placeholder_rollbacks\u003dtrue\u0026html5_non_network_rebuffer_duration_ms\u003d0\u0026html5_non_onesie_attach_po_token\u003dtrue\u0026html5_not_register_disposables_when_core_listens\u003dtrue\u0026html5_offline_failure_retry_limit\u003d2\u0026html5_onesie_cast\u003dtrue\u0026html5_onesie_defer_content_loader_ms\u003d0\u0026html5_onesie_disable_js_cleartext_compression\u003dtrue\u0026html5_onesie_enable_server_side_badwidth_estimation\u003dtrue\u0026html5_onesie_host_racing_cap_ms\u003d0\u0026html5_onesie_ignore_innertube_api_key\u003dtrue\u0026html5_onesie_live_ttl_secs\u003d8\u0026html5_onesie_media_bytes\u003dtrue\u0026html5_onesie_nonzero_playback_start\u003dtrue\u0026html5_onesie_notify_cuepoint_manager_on_completion\u003dtrue\u0026html5_onesie_prefer_trusted_host\u003dtrue\u0026html5_onesie_prewarm_cooldown_ms\u003d0\u0026html5_onesie_prewarm_interval_ms\u003d0\u0026html5_onesie_prewarm_max_lact_ms\u003d0\u0026html5_onesie_redirector_timeout_ms\u003d0\u0026html5_onesie_request_timeout_ms\u003d1000\u0026html5_onesie_sticky_server_side\u003dtrue\u0026html5_pause_on_nonforeground_platform_errors\u003dtrue\u0026html5_peak_shave\u003dtrue\u0026html5_per_format_loudness_fix\u003dtrue\u0026html5_perf_cap_override_sticky\u003dtrue\u0026html5_performance_cap_floor\u003d360\u0026html5_performance_impact_profiling_timer_ms\u003d0\u0026html5_perserve_av1_perf_cap\u003dtrue\u0026html5_photos_use_vp9_otf\u003dtrue\u0026html5_platform_minimum_readahead_seconds\u003d0.0\u0026html5_platform_whitelisted_for_frame_accurate_seeks\u003dtrue\u0026html5_player_autonav_logging\u003dtrue\u0026html5_player_dynamic_bottom_gradient\u003dtrue\u0026html5_player_min_build_cl\u003d-1\u0026html5_player_preload_ad_fix\u003dtrue\u0026html5_post_interrupt_readahead\u003d20\u0026html5_prefer_server_bwe3\u003dtrue\u0026html5_preload_wait_time_secs\u003d0.0\u0026html5_probe_primary_delay_base_ms\u003d0\u0026html5_process_all_encrypted_events\u003dtrue\u0026html5_query_sw_secure_crypto_for_android\u003dtrue\u0026html5_random_playback_cap\u003d0\u0026html5_readahead_ratelimit\u003d3000\u0026html5_recognize_predict_start_cue_point\u003dtrue\u0026html5_reduce_istypesupported_calls\u003dtrue\u0026html5_remove_command_triggered_companions\u003dtrue\u0026html5_remove_not_servable_check_killswitch\u003dtrue\u0026html5_rename_apbs\u003dtrue\u0026html5_report_fatal_drm_restricted_error_killswitch\u003dtrue\u0026html5_report_slow_ads_as_error\u003dtrue\u0026html5_request_only_hdr_or_sdr_keys\u003dtrue\u0026html5_request_sizing_multiplier\u003d0.8\u0026html5_require_hdr_capability\u003dtrue\u0026html5_reset_media_stream_on_unresumable_slices\u003dtrue\u0026html5_resource_bad_status_delay_scaling\u003d1.5\u0026html5_restrict_streaming_xhr_on_sqless_requests\u003dtrue\u0026html5_safari_desktop_eme_min_version\u003d0\u0026html5_seek_jiggle_cmt_delay_ms\u003d8000\u0026html5_seek_new_elem_delay_ms\u003d12000\u0026html5_seek_new_elem_shorts_delay_ms\u003d0\u0026html5_seek_over_discontinuities_delay_ms\u003d0\u0026html5_seek_set_cmt_delay_ms\u003d2000\u0026html5_seek_timeout_delay_ms\u003d20000\u0026html5_selectable_formats_early_exit\u003dtrue\u0026html5_server_stitched_dai_decorated_url_retry_limit\u003d5\u0026html5_server_stitched_dai_group\u003dtrue\u0026html5_session_po_token_interval_time_ms\u003d900000\u0026html5_set_ended_in_pfx_live\u003dtrue\u0026html5_simplify_streaming_xhr\u003dtrue\u0026html5_skip_oob_start_seconds\u003dtrue\u0026html5_skip_slow_ad_delay_ms\u003d15000\u0026html5_skip_sub_quantum_discontinuity_secs\u003d0.0\u0026html5_slow_start_no_media_source_delay_ms\u003d0\u0026html5_slow_start_timeout_delay_ms\u003d20000\u0026html5_ssdai_adfetch_dynamic_timeout_ms\u003d0\u0026html5_ssdai_enable_new_seek_logic\u003dtrue\u0026html5_ssdai_flush_vss\u003dtrue\u0026html5_ssdai_vss_player_state_change\u003dtrue\u0026html5_start_seconds_reorder\u003dtrue\u0026html5_stateful_audio_min_adjustment_value\u003d0\u0026html5_static_abr_resolution_shelf\u003d0\u0026html5_store_xhr_headers_readable\u003dtrue\u0026html5_stream_metadata\u003dtrue\u0026html5_streaming_init_requests_sizes\u003d0\u0026html5_streaming_xhr_check_for_null_response\u003dtrue\u0026html5_subsegment_readahead_load_speed_check_interval\u003d0.5\u0026html5_subsegment_readahead_min_buffer_health_secs\u003d0.25\u0026html5_subsegment_readahead_min_buffer_health_secs_on_timeout\u003d0.1\u0026html5_subsegment_readahead_min_load_speed\u003d1.5\u0026html5_subsegment_readahead_seek_latency_fudge\u003d0.5\u0026html5_subsegment_readahead_target_buffer_health_secs\u003d0.5\u0026html5_subsegment_readahead_timeout_secs\u003d2.0\u0026html5_suspend_loader\u003dtrue\u0026html5_track_termination_during_request\u003dtrue\u0026html5_ugc_live_audio_51\u003dtrue\u0026html5_ugc_vod_audio_51\u003dtrue\u0026html5_ultra_high_res_logging_percent\u003d0.0\u0026html5_unreported_seek_reseek_delay_ms\u003d0\u0026html5_unrestricted_layer_high_res_logging_percent\u003d0.0\u0026html5_update_constraint\u003dtrue\u0026html5_use_post_for_media\u003dtrue\u0026html5_varispeed_playback_rate\u003dtrue\u0026html5_video_tbd_min_kb\u003d0\u0026html5_viewport_undersend_maximum\u003d0.0\u0026html5_watchdog_for_zero_seek\u003dtrue\u0026html5_web_enable_halftime_preroll\u003dtrue\u0026html5_webpo_idle_priority_job\u003dtrue\u0026html5_woffle_resume\u003dtrue\u0026html5_workaround_delay_trigger\u003dtrue\u0026html5_xhr_clean_up_multi_slice_facade\u003dtrue\u0026html5_ytvlr_enable_single_select_survey\u003dtrue\u0026il_use_view_model_logging_context\u003dtrue\u0026initial_gel_batch_timeout\u003d2000\u0026injected_license_handler_error_code\u003d0\u0026injected_license_handler_license_status\u003d0\u0026json_condensed_response\u003dtrue\u0026kevlar_command_handler_command_banlist\u003d[]\u0026kevlar_dropdown_fix\u003dtrue\u0026kevlar_gel_error_routing\u003dtrue\u0026kevlar_miniplayer\u003dtrue\u0026kevlar_miniplayer_expand_top\u003dtrue\u0026kevlar_miniplayer_play_pause_on_scrim\u003dtrue\u0026kevlar_playback_associated_queue\u003dtrue\u0026kevlar_queue_use_update_api\u003dtrue\u0026kevlar_smart_downloads\u003dtrue\u0026kevlar_smart_downloads_setting\u003dtrue\u0026kevlar_vimio_use_shared_monitor\u003dtrue\u0026kevlar_woffle\u003dtrue\u0026live_chunk_readahead\u003d3\u0026live_fresca_v2\u003dtrue\u0026log_errors_through_nwl_on_retry\u003dtrue\u0026log_heartbeat_with_lifecycles\u003dtrue\u0026log_web_endpoint_to_layer\u003dtrue\u0026log_window_onerror_fraction\u003d0.1\u0026manifestless_post_live\u003dtrue\u0026manifestless_post_live_ufph\u003dtrue\u0026max_prefetch_window_sec_for_livestream_optimization\u003d10\u0026max_resolution_for_white_noise\u003d360\u0026mdx_enable_privacy_disclosure_ui\u003dtrue\u0026mdx_load_cast_api_bootstrap_script\u003dtrue\u0026migrate_events_to_ts\u003dtrue\u0026min_prefetch_offset_sec_for_livestream_optimization\u003d20\u0026music_enable_shared_audio_tier_logic\u003dtrue\u0026mweb_c3_endscreen\u003dtrue\u0026mweb_enable_custom_control_shared\u003dtrue\u0026mweb_enable_skippables_on_jio_phone\u003dtrue\u0026mweb_muted_autoplay_animation\u003dshrink\u0026mweb_native_control_in_faux_fullscreen_shared\u003dtrue\u0026network_polling_interval\u003d30000\u0026networkless_gel\u003dtrue\u0026networkless_logging\u003dtrue\u0026new_codecs_string_api_uses_legacy_style\u003dtrue\u0026nwl_send_fast_on_unload\u003dtrue\u0026nwl_send_from_memory_when_online\u003dtrue\u0026offline_error_handling\u003dtrue\u0026pageid_as_header_web\u003dtrue\u0026parse_query_data_from_url\u003dtrue\u0026player_ads_set_adformat_on_client\u003dtrue\u0026player_allow_autonav_after_playlist\u003dtrue\u0026player_bootstrap_method\u003dtrue\u0026player_defer_caption_display\u003d1000\u0026player_destroy_old_version\u003dtrue\u0026player_doubletap_to_seek\u003dtrue\u0026player_enable_playback_playlist_change\u003dtrue\u0026player_endscreen_ellipsis_fix\u003dtrue\u0026player_underlay_min_player_width\u003d768.0\u0026player_underlay_video_width_fraction\u003d0.6\u0026player_web_canary_stage\u003d0\u0026playready_first_play_expiration\u003d-1\u0026polymer_bad_build_labels\u003dtrue\u0026polymer_log_prop_change_observer_percent\u003d0\u0026polymer_verifiy_app_state\u003dtrue\u0026preskip_button_style_ads_backend\u003dcountdown_next_to_thumbnail\u0026qoe_nwl_downloads\u003dtrue\u0026qoe_send_and_write\u003dtrue\u0026record_app_crashed_web\u003dtrue\u0026replace_playability_retriever_in_watch\u003dtrue\u0026scheduler_use_raf_by_default\u003dtrue\u0026self_podding_header_string_template\u003dself_podding_interstitial_message\u0026self_podding_highlight_non_default_button\u003dtrue\u0026self_podding_midroll_choice_string_template\u003dself_podding_midroll_choice\u0026send_config_hash_timer\u003d0\u0026set_interstitial_advertisers_question_text\u003dtrue\u0026short_start_time_prefer_publish_in_watch_log\u003dtrue\u0026should_clear_video_data_on_player_cued_unstarted\u003dtrue\u0026skip_inline_muted_license_service_check\u003dtrue\u0026skip_invalid_ytcsi_ticks\u003dtrue\u0026skip_ls_gel_retry\u003dtrue\u0026skip_setting_info_in_csi_data_object\u003dtrue\u0026start_client_gcf\u003dtrue\u0026start_client_gcf_for_player\u003dtrue\u0026streaming_data_emergency_itag_blacklist\u003d[]\u0026suppress_error_204_logging\u003dtrue\u0026transport_use_scheduler\u003dtrue\u0026tv_pacf_logging_sample_rate\u003d0.01\u0026tvhtml5_unplugged_preload_cache_size\u003d5\u0026uncover_ad_badge_on_RTL_tiny_window\u003dtrue\u0026unplugged_dai_live_chunk_readahead\u003d3\u0026unplugged_tvhtml5_video_preload_on_focus_delay_ms\u003d0\u0026use_inlined_player_rpc\u003dtrue\u0026use_new_in_memory_storage\u003dtrue\u0026use_new_nwl_initialization\u003dtrue\u0026use_new_nwl_saw\u003dtrue\u0026use_new_nwl_stw\u003dtrue\u0026use_new_nwl_wts\u003dtrue\u0026use_player_abuse_bg_library\u003dtrue\u0026use_profilepage_event_label_in_carousel_playbacks\u003dtrue\u0026use_request_time_ms_header\u003dtrue\u0026use_session_based_sampling\u003dtrue\u0026use_shared_nsm\u003dtrue\u0026use_shared_nsm_and_keep_yt_online_updated\u003dtrue\u0026use_ts_visibilitylogger\u003dtrue\u0026variable_buffer_timeout_ms\u003d0\u0026verify_ads_itag_early\u003dtrue\u0026vp9_drm_live\u003dtrue\u0026vss_final_ping_send_and_write\u003dtrue\u0026vss_pings_using_networkless\u003dtrue\u0026vss_playback_use_send_and_write\u003dtrue\u0026web_api_url\u003dtrue\u0026web_cinematic_watch_settings\u003dtrue\u0026web_client_version_override\u003d\u0026web_dedupe_ve_grafting\u003dtrue\u0026web_deprecate_service_ajax_map_dependency\u003dtrue\u0026web_enable_voz_audio_feedback\u003dtrue\u0026web_foreground_heartbeat_interval_ms\u003d28000\u0026web_forward_command_on_pbj\u003dtrue\u0026web_gel_debounce_ms\u003d10000\u0026web_gel_timeout_cap\u003dtrue\u0026web_key_moments_markers\u003dtrue\u0026web_log_memory_total_kbytes\u003dtrue\u0026web_logging_max_batch\u003d150\u0026web_modern_ads\u003dtrue\u0026web_modern_buttons\u003dtrue\u0026web_modern_buttons_bl_survey\u003dtrue\u0026web_modern_subscribe\u003dtrue\u0026web_modern_subscribe_style\u003dfilled\u0026web_new_autonav_countdown\u003dtrue\u0026web_one_platform_error_handling\u003dtrue\u0026web_op_signal_type_banlist\u003d[]\u0026web_playback_associated_log_ctt\u003dtrue\u0026web_playback_associated_ve\u003dtrue\u0026web_player_api_logging_fraction\u003d0.01\u0026web_player_autonav_toggle_always_listen\u003dtrue\u0026web_player_autonav_use_server_provided_state\u003dtrue\u0026web_player_caption_language_preference_stickiness_duration\u003d0\u0026web_player_decouple_autonav\u003dtrue\u0026web_player_enable_early_warning_snackbar\u003dtrue\u0026web_player_enable_premium_hbr_in_h5_api\u003dtrue\u0026web_player_enable_premium_hbr_playback_cap\u003dtrue\u0026web_player_fine_scrubbing\u003dtrue\u0026web_player_gvi_wexit_adunit\u003dtrue\u0026web_player_gvi_wexit_all_player_styles\u003dtrue\u0026web_player_gvi_wexit_living_room_bedrock\u003dtrue\u0026web_player_gvi_wexit_living_room_kids\u003dtrue\u0026web_player_gvi_wexit_living_room_other\u003dtrue\u0026web_player_gvi_wexit_living_room_pangea\u003dtrue\u0026web_player_gvi_wexit_living_room_simply\u003dtrue\u0026web_player_gvi_wexit_living_room_unplugged\u003dtrue\u0026web_player_innertube_playlist_update\u003dtrue\u0026web_player_ipp_canary_type_for_logging\u003d\u0026web_player_live_monitor_env\u003dtrue\u0026web_player_move_autonav_toggle\u003dtrue\u0026web_player_music_visualizer_treatment\u003dfake\u0026web_player_mutable_event_label\u003dtrue\u0026web_player_nitrate_promo_tooltip\u003dtrue\u0026web_player_no_force_gvi\u003dtrue\u0026web_player_response_playback_tracking_parsing\u003dtrue\u0026web_player_seek_chapters_by_shortcut\u003dtrue\u0026web_player_sentinel_is_uniplayer\u003dtrue\u0026web_player_should_honor_include_asr_setting\u003dtrue\u0026web_player_show_music_in_this_video_graphic\u003dvideo_thumbnail\u0026web_player_small_hbp_settings_menu\u003dtrue\u0026web_player_ss_dai_ad_fetching_timeout_ms\u003d15000\u0026web_player_ss_media_time_offset\u003dtrue\u0026web_player_ss_timeout_skip_ads\u003dtrue\u0026web_player_ssdai_all_acpns_aids_logging_killswitch\u003dtrue\u0026web_player_touch_mode_improvements\u003dtrue\u0026web_player_transfer_timeout_threshold_ms\u003d10800000\u0026web_player_unset_default_csn_killswitch\u003dtrue\u0026web_player_use_cinematic_label_2\u003dtrue\u0026web_player_use_new_api_for_quality_pullback\u003dtrue\u0026web_player_vss_pageid_header\u003dtrue\u0026web_player_watch_next_response\u003dtrue\u0026web_player_watch_next_response_parsing\u003dtrue\u0026web_prefetch_preload_video\u003dtrue\u0026web_repeating_chapters\u003dtrue\u0026web_rounded_containers\u003dtrue\u0026web_rounded_thumbnails\u003dtrue\u0026web_settings_menu_icons\u003dtrue\u0026web_smoothness_test_duration_ms\u003d0\u0026web_smoothness_test_method\u003d0\u0026web_yt_config_context\u003dtrue\u0026woffle_clean_up_after_entity_migration\u003dtrue\u0026woffle_orchestration\u003dtrue\u0026ytidb_clear_embedded_player\u003dtrue\u0026ytidb_fetch_datasync_ids_for_data_cleanup\u003dtrue\u0026ytidb_remake_db_retries\u003d3\u0026ytidb_reopen_db_retries\u003d3\u0026ytidb_transaction_ended_event_rate_limit\u003d0.02\u0026ytidb_transaction_ended_event_rate_limit_session\u003d0.2\u0026ytidb_transaction_ended_event_rate_limit_transaction\u003d0.1","hideInfo":true,"startMuted":true,"enableMutedAutoplay":true,"cspNonce":"nopnosk9VoEiau3Xtg_3uQ","canaryState":"none","enableCsiLogging":true,"csiPageType":"channels","authorizedUserIndex":0,"datasyncId":"106384449314396247844||"},"WEB_PLAYER_CONTEXT_CONFIG_ID_KEVLAR_SHORTS":{"rootElementId":"shorts-player","jsUrl":"/s/player/97ea7458/player_ias.vflset/en_US/base.js","cssUrl":"/s/player/97ea7458/www-player.css","contextId":"WEB_PLAYER_CONTEXT_CONFIG_ID_KEVLAR_SHORTS","eventLabel":"shortspage","contentRegion":"CA","hl":"en_US","hostLanguage":"en","playerStyle":"desktop-polymer","innertubeApiKey":"AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8","innertubeApiVersion":"v1","innertubeContextClientVersion":"2.20230201.01.00","controlsType":0,"disableKeyboardControls":true,"disableRelatedVideos":true,"annotationsLoadPolicy":3,"device":{"brand":"apple","model":"","browser":"Chrome","browserVersion":"109.0.0.0","os":"Macintosh","osVersion":"10_15_7","platform":"DESKTOP","interfaceName":"WEB","interfaceVersion":"2.20230201.01.00","deviceYear":2013},"serializedExperimentIds":"23983296,23986016,24004644,24007246,24080738,24135310,24169501,24219381,24255163,24282011,24396645,24415864,24416291,24416441,24433679,24437577,24439361,24441240,24449113,24449639,24450366,24451032,24454357,24454498,24457577,24457884,24460376,24463912,24469897","serializedExperimentFlags":"H5_async_logging_delay_ms\u003d30000.0\u0026H5_enable_full_pacf_logging\u003dtrue\u0026H5_use_async_logging\u003dtrue\u0026ad_pod_disable_companion_persist_ads_quality\u003dtrue\u0026addto_ajax_log_warning_fraction\u003d0.1\u0026align_ad_to_video_player_lifecycle_for_bulleit\u003dtrue\u0026allow_live_autoplay\u003dtrue\u0026allow_poltergust_autoplay\u003dtrue\u0026allow_skip_networkless\u003dtrue\u0026autoplay_time\u003d8000\u0026autoplay_time_for_fullscreen\u003d3000\u0026autoplay_time_for_music_content\u003d3000\u0026background_thread_flush_logs_due_to_batch_limit\u003dtrue\u0026bg_vm_reinit_threshold\u003d7200000\u0026blocked_packages_for_sps\u003d[]\u0026botguard_async_snapshot_timeout_ms\u003d3000\u0026check_ad_ui_status_for_mweb_safari\u003dtrue\u0026check_navigator_accuracy_timeout_ms\u003d0\u0026clear_user_partitioned_ls\u003dtrue\u0026client_respect_autoplay_switch_button_renderer\u003dtrue\u0026csi_on_gel\u003dtrue\u0026dash_manifest_version\u003d5\u0026debug_bandaid_hostname\u003d\u0026debug_sherlog_username\u003d\u0026delay_ads_gvi_call_on_bulleit_living_room_ms\u003d0\u0026deprecate_csi_has_info\u003dtrue\u0026deprecate_pair_servlet_enabled\u003dtrue\u0026deprecate_two_way_binding_child\u003dtrue\u0026deprecate_two_way_binding_parent\u003dtrue\u0026desktop_image_cta_no_background\u003dtrue\u0026desktop_log_img_click_location\u003dtrue\u0026desktop_player_button_tooltip_with_shortcut\u003dtrue\u0026desktop_sparkles_light_cta_button\u003dtrue\u0026disable_channel_id_check_for_suspended_channels\u003dtrue\u0026disable_child_node_auto_formatted_strings\u003dtrue\u0026disable_defer_admodule_on_advertiser_video\u003dtrue\u0026disable_features_for_supex\u003dtrue\u0026disable_legacy_desktop_remote_queue\u003dtrue\u0026disable_mdx_connection_in_mdx_module_for_music_web\u003dtrue\u0026disable_new_pause_state3\u003dtrue\u0026disable_pacf_logging_for_memory_limited_tv\u003dtrue\u0026disable_rounding_ad_notify\u003dtrue\u0026disable_simple_mixed_direction_formatted_strings\u003dtrue\u0026disable_ssdai_on_errors\u003dtrue\u0026disable_tabbing_before_flyout_ad_elements_appear\u003dtrue\u0026disable_thumbnail_preloading\u003dtrue\u0026embeds_enable_allow_watch_again_endscreen_for_eligible_shorts\u003dtrue\u0026embeds_enable_embed_module\u003dtrue\u0026embeds_enable_shorts_branded_ui\u003dtrue\u0026embeds_enable_shorts_links_for_eligible_shorts\u003dtrue\u0026embeds_web_enable_gws_wh_rel_off\u003dtrue\u0026embeds_web_enable_info_panel_preview\u003dtrue\u0026embeds_web_enable_load_player_from_page_show\u003dtrue\u0026embeds_web_enable_logging_event_handlers\u003dtrue\u0026embeds_web_enable_pem_domain_fix_for_ad_requests\u003dtrue\u0026embeds_web_enable_replace_unload_w_pagehide\u003dtrue\u0026embeds_web_enable_ve_conversion_logging_tracking_no_allow_list\u003dtrue\u0026embeds_web_enable_video_data_refactoring_break_down_and_move_methods\u003dtrue\u0026embeds_web_enable_video_data_refactoring_like_button_renderer\u003dtrue\u0026embeds_web_hide_unfilled_more_videos_suggestions\u003dtrue\u0026embeds_web_lite_mode\u003d1\u0026embeds_web_nwl_disable_nocookie\u003dtrue\u0026embeds_web_synth_ch_headers_banned_urls_regex\u003d\u0026enable_ad_cpn_macro_substitution_for_click_pings\u003dtrue\u0026enable_cast_for_web_unplugged\u003dtrue\u0026enable_cast_on_music_web\u003dtrue\u0026enable_client_page_id_header_for_first_party_pings\u003dtrue\u0026enable_client_sli_logging\u003dtrue\u0026enable_discrete_live_precise_embargos\u003dtrue\u0026enable_error_corrections_infocard\u003dtrue\u0026enable_error_corrections_infocard_web_client\u003dtrue\u0026enable_error_corrections_infocard_web_client_check\u003dtrue\u0026enable_error_corrections_infocards_icon_web\u003dtrue\u0026enable_eviction_protection_for_bulleit\u003dtrue\u0026enable_gel_log_commands\u003dtrue\u0026enable_handles_account_menu_switcher\u003dtrue\u0026enable_inline_preview_controls\u003dtrue\u0026enable_live_premiere_web_player_indicator\u003dtrue\u0026enable_lr_home_infeed_ads_inline_playback_progress_pings\u003dtrue\u0026enable_macro_substitution_on_html5\u003dtrue\u0026enable_mixed_direction_formatted_strings\u003dtrue\u0026enable_mweb_livestream_ui_update\u003dtrue\u0026enable_new_paid_product_placement\u003dtrue\u0026enable_post_ad_perception_survey_fix_on_tvhtml5\u003dtrue\u0026enable_post_ad_perception_survey_in_tvhtml5\u003dtrue\u0026enable_precise_embargos\u003dtrue\u0026enable_server_stitched_dai\u003dtrue\u0026enable_shorts_player\u003dtrue\u0026enable_skip_ad_guidance_prompt\u003dtrue\u0026enable_skippable_ads_for_unplugged_ad_pod\u003dtrue\u0026enable_smearing_expansion_dai\u003dtrue\u0026enable_tectonic_ad_ux_for_halftime\u003dtrue\u0026enable_third_party_info\u003dtrue\u0026enable_topsoil_wta_for_halftime_live_infra\u003dtrue\u0026enable_web_media_session_metadata_fix\u003dtrue\u0026error_message_for_gsuite_network_restrictions\u003dtrue\u0026export_networkless_options\u003dtrue\u0026external_fullscreen_with_edu\u003dtrue\u0026fast_autonav_in_background\u003dtrue\u0026fetch_att_independently\u003dtrue\u0026fill_single_video_with_notify_to_lasr\u003dtrue\u0026filter_vp9_for_csdai\u003dtrue\u0026fix_ads_tracking_for_swf_config_deprecation_mweb\u003dtrue\u0026gcf_config_store_enabled\u003dtrue\u0026gpa_sparkles_ten_percent_layer\u003dtrue\u0026gvi_channel_client_screen\u003dtrue\u0026h5_companion_enable_adcpn_macro_substitution_for_click_pings\u003dtrue\u0026h5_inplayer_enable_adcpn_macro_substitution_for_click_pings\u003dtrue\u0026hfr_dropped_framerate_fallback_threshold\u003d0\u0026hide_endpoint_overflow_on_ytd_display_ad_renderer\u003dtrue\u0026hls_use_new_codecs_string_api\u003dtrue\u0026html5_ad_timeout_ms\u003d0\u0026html5_ads_preroll_lock_timeout_delay_ms\u003d15000\u0026html5_allow_discontiguous_slices\u003dtrue\u0026html5_allow_video_keyframe_without_audio\u003dtrue\u0026html5_append_init_while_paused\u003dtrue\u0026html5_apply_ustreamer_cap_per_video_id\u003dtrue\u0026html5_att_oauth\u003dtrue\u0026html5_attach_num_random_bytes_to_bandaid\u003d0\u0026html5_attach_po_token_to_bandaid\u003dtrue\u0026html5_autonav_cap_idle_secs\u003d0\u0026html5_autonav_quality_cap\u003d720\u0026html5_autoplay_default_quality_cap\u003d0\u0026html5_block_pip_safari_delay\u003d0\u0026html5_bmff_new_fourcc_check\u003dtrue\u0026html5_cap_quality_for_tv_hfr\u003dtrue\u0026html5_change_player_mode_order_for_logging\u003dtrue\u0026html5_clamp_cuepoints_to_min\u003dtrue\u0026html5_cobalt_max_size_for_immed_job\u003d0\u0026html5_cobalt_min_processor_cnt_to_offload_algo\u003d0\u0026html5_cobalt_override_quic\u003d0\u0026html5_consume_media_bytes_slice_infos\u003dtrue\u0026html5_control_flow_include_trigger_logging_in_tmp_logs\u003dtrue\u0026html5_create_manifest_from_protos\u003dtrue\u0026html5_de_dupe_content_video_loads_in_lifecycle_api\u003dtrue\u0026html5_deadzone_multiplier\u003d1.0\u0026html5_debug_data_log_probability\u003d0.1\u0026html5_decode_to_texture_cap\u003dtrue\u0026html5_decoder_freeze_timeout_delay_ms\u003d0\u0026html5_default_ad_gain\u003d0.5\u0026html5_default_quality_cap\u003d0\u0026html5_defer_ad_module_ms\u003d0\u0026html5_defer_fetch_att_ms\u003d1000\u0026html5_defer_modules_delay_time_millis\u003d0\u0026html5_delay_initial_loading\u003dtrue\u0026html5_delay_retries_for_host_timeout\u003dtrue\u0026html5_delayed_retry_count\u003d1\u0026html5_delayed_retry_delay_ms\u003d5000\u0026html5_deprecate_video_tag_pool\u003dtrue\u0026html5_desktop_vr180_allow_panning\u003dtrue\u0026html5_desync_cue_range_threshold\u003d0\u0026html5_df_downgrade_thresh\u003d0.2\u0026html5_disable_connection_issue_event\u003dtrue\u0026html5_disable_csi_for_bulleit\u003dtrue\u0026html5_disable_move_pssh_to_moov\u003dtrue\u0026html5_disable_non_contiguous\u003dtrue\u0026html5_displayed_frame_rate_downgrade_threshold\u003d45\u0026html5_drm_check_all_key_error_states\u003dtrue\u0026html5_drm_cpi_license_key\u003dtrue\u0026html5_early_read_chunk\u003dtrue\u0026html5_enable_ac3\u003dtrue\u0026html5_enable_ads_client_monitoring_log_tv\u003dtrue\u0026html5_enable_atv_offline\u003dtrue\u0026html5_enable_client_hints_override\u003dtrue\u0026html5_enable_eac3\u003dtrue\u0026html5_enable_embedded_player_visibility_signals\u003dtrue\u0026html5_enable_non_notify_composite_vod_lsar_pacf\u003dtrue\u0026html5_enable_single_video_vod_ivar_on_pacf\u003dtrue\u0026html5_enable_tvos_dash\u003dtrue\u0026html5_enable_tvos_encrypted_vp9\u003dtrue\u0026html5_enable_widevine_for_alc\u003dtrue\u0026html5_enable_widevine_for_fast_linear\u003dtrue\u0026html5_encourage_array_coalescing\u003dtrue\u0026html5_exile_on_drm_fatal\u003dtrue\u0026html5_fill_isTypeSupported_capability_cache_earlier\u003dtrue\u0026html5_fludd_suspend\u003dtrue\u0026html5_flush_segment_index_on_error\u003dtrue\u0026html5_flush_vss_with_rti_and_rtn\u003dtrue\u0026html5_gapless_ended_transition_buffer_ms\u003d200\u0026html5_gapless_preloading\u003dtrue\u0026html5_generate_session_po_token\u003dtrue\u0026html5_gl_fps_threshold\u003d0\u0026html5_halt_ssdai_fetch_on_predict_start\u003dtrue\u0026html5_hdcp_probing_stream_url\u003d\u0026html5_heartbeat_set_ended\u003dtrue\u0026html5_hfr_quality_cap\u003d0\u0026html5_high_res_logging_percent\u003d0.01\u0026html5_idle_rate_limit_ms\u003d0\u0026html5_ignore_media_element_event_loadeddata\u003dtrue\u0026html5_innertube_heartbeats_for_fairplay\u003dtrue\u0026html5_innertube_heartbeats_for_playready\u003dtrue\u0026html5_innertube_heartbeats_for_widevine\u003dtrue\u0026html5_ios4_seek_above_zero\u003dtrue\u0026html5_ios7_force_play_on_stall\u003dtrue\u0026html5_ios_force_seek_to_zero_on_stop\u003dtrue\u0026html5_jumbo_mobile_subsegment_readahead_target\u003d3.0\u0026html5_jumbo_ull_nonstreaming_mffa_ms\u003d4000\u0026html5_jumbo_ull_subsegment_readahead_target\u003d1.3\u0026html5_license_constraint_delay\u003d5000\u0026html5_live_abr_head_miss_fraction\u003d0.0\u0026html5_live_abr_repredict_fraction\u003d0.0\u0026html5_live_byterate_factor_for_readahead\u003d1.3\u0026html5_live_low_latency_bandwidth_window\u003d0.0\u0026html5_live_normal_latency_bandwidth_window\u003d0.0\u0026html5_live_partial_response_resumable\u003dtrue\u0026html5_live_quality_cap\u003d0\u0026html5_live_ultra_low_latency_bandwidth_window\u003d0.0\u0026html5_log_audio_abr\u003dtrue\u0026html5_log_experiment_id_from_player_response_to_ctmp\u003d\u0026html5_log_first_ssdai_requests_killswitch\u003dtrue\u0026html5_log_offline_playback_started_event\u003dtrue\u0026html5_log_readahead_on_playback_start\u003dtrue\u0026html5_log_rebuffer_events\u003d5\u0026html5_log_server_url_param\u003dtrue\u0026html5_log_trigger_events_with_debug_data\u003dtrue\u0026html5_long_rebuffer_jiggle_cmt_delay_ms\u003d0\u0026html5_long_rebuffer_new_elem_shorts_delay_ms\u003d0\u0026html5_long_rebuffer_threshold_ms\u003d30000\u0026html5_manifestless_seg_drift_limit_secs\u003d0\u0026html5_manifestless_unplugged\u003dtrue\u0026html5_manifestless_vp9_otf\u003dtrue\u0026html5_max_drift_per_track_secs\u003d0.0\u0026html5_max_headm_for_streaming_xhr\u003d0\u0026html5_max_live_dvr_window_plus_margin_secs\u003d46800.0\u0026html5_max_readbehind_secs\u003d0\u0026html5_max_redirect_response_length\u003d8192\u0026html5_max_selectable_quality_ordinal\u003d0\u0026html5_maximum_readahead_seconds\u003d0.0\u0026html5_media_fullscreen\u003dtrue\u0026html5_mfl_extend_max_request_time\u003dtrue\u0026html5_min_readbehind_cap_secs\u003d60\u0026html5_min_readbehind_secs\u003d0\u0026html5_min_selectable_quality_ordinal\u003d0\u0026html5_min_startup_buffered_ad_media_duration_secs\u003d1.2\u0026html5_min_startup_buffered_media_duration_secs\u003d1.2\u0026html5_minimum_readahead_seconds\u003d0.0\u0026html5_new_min_startup_smooth_logic\u003dtrue\u0026html5_no_placeholder_rollbacks\u003dtrue\u0026html5_non_network_rebuffer_duration_ms\u003d0\u0026html5_non_onesie_attach_po_token\u003dtrue\u0026html5_not_register_disposables_when_core_listens\u003dtrue\u0026html5_offline_failure_retry_limit\u003d2\u0026html5_onesie_cast\u003dtrue\u0026html5_onesie_defer_content_loader_ms\u003d0\u0026html5_onesie_disable_js_cleartext_compression\u003dtrue\u0026html5_onesie_enable_server_side_badwidth_estimation\u003dtrue\u0026html5_onesie_host_racing_cap_ms\u003d0\u0026html5_onesie_ignore_innertube_api_key\u003dtrue\u0026html5_onesie_live_ttl_secs\u003d8\u0026html5_onesie_media_bytes\u003dtrue\u0026html5_onesie_nonzero_playback_start\u003dtrue\u0026html5_onesie_notify_cuepoint_manager_on_completion\u003dtrue\u0026html5_onesie_prefer_trusted_host\u003dtrue\u0026html5_onesie_prewarm_cooldown_ms\u003d0\u0026html5_onesie_prewarm_interval_ms\u003d0\u0026html5_onesie_prewarm_max_lact_ms\u003d0\u0026html5_onesie_redirector_timeout_ms\u003d0\u0026html5_onesie_request_timeout_ms\u003d1000\u0026html5_onesie_sticky_server_side\u003dtrue\u0026html5_pause_on_nonforeground_platform_errors\u003dtrue\u0026html5_peak_shave\u003dtrue\u0026html5_per_format_loudness_fix\u003dtrue\u0026html5_perf_cap_override_sticky\u003dtrue\u0026html5_performance_cap_floor\u003d360\u0026html5_performance_impact_profiling_timer_ms\u003d0\u0026html5_perserve_av1_perf_cap\u003dtrue\u0026html5_photos_use_vp9_otf\u003dtrue\u0026html5_platform_minimum_readahead_seconds\u003d0.0\u0026html5_platform_whitelisted_for_frame_accurate_seeks\u003dtrue\u0026html5_player_autonav_logging\u003dtrue\u0026html5_player_dynamic_bottom_gradient\u003dtrue\u0026html5_player_min_build_cl\u003d-1\u0026html5_player_preload_ad_fix\u003dtrue\u0026html5_post_interrupt_readahead\u003d20\u0026html5_prefer_server_bwe3\u003dtrue\u0026html5_preload_wait_time_secs\u003d0.0\u0026html5_probe_primary_delay_base_ms\u003d0\u0026html5_process_all_encrypted_events\u003dtrue\u0026html5_query_sw_secure_crypto_for_android\u003dtrue\u0026html5_random_playback_cap\u003d0\u0026html5_readahead_ratelimit\u003d3000\u0026html5_recognize_predict_start_cue_point\u003dtrue\u0026html5_reduce_istypesupported_calls\u003dtrue\u0026html5_remove_command_triggered_companions\u003dtrue\u0026html5_remove_not_servable_check_killswitch\u003dtrue\u0026html5_rename_apbs\u003dtrue\u0026html5_report_fatal_drm_restricted_error_killswitch\u003dtrue\u0026html5_report_slow_ads_as_error\u003dtrue\u0026html5_request_only_hdr_or_sdr_keys\u003dtrue\u0026html5_request_sizing_multiplier\u003d0.8\u0026html5_require_hdr_capability\u003dtrue\u0026html5_reset_media_stream_on_unresumable_slices\u003dtrue\u0026html5_resource_bad_status_delay_scaling\u003d1.5\u0026html5_restrict_streaming_xhr_on_sqless_requests\u003dtrue\u0026html5_safari_desktop_eme_min_version\u003d0\u0026html5_seek_jiggle_cmt_delay_ms\u003d8000\u0026html5_seek_new_elem_delay_ms\u003d12000\u0026html5_seek_new_elem_shorts_delay_ms\u003d0\u0026html5_seek_over_discontinuities_delay_ms\u003d0\u0026html5_seek_set_cmt_delay_ms\u003d2000\u0026html5_seek_timeout_delay_ms\u003d20000\u0026html5_selectable_formats_early_exit\u003dtrue\u0026html5_server_stitched_dai_decorated_url_retry_limit\u003d5\u0026html5_server_stitched_dai_group\u003dtrue\u0026html5_session_po_token_interval_time_ms\u003d900000\u0026html5_set_ended_in_pfx_live\u003dtrue\u0026html5_simplify_streaming_xhr\u003dtrue\u0026html5_skip_oob_start_seconds\u003dtrue\u0026html5_skip_slow_ad_delay_ms\u003d15000\u0026html5_skip_sub_quantum_discontinuity_secs\u003d0.0\u0026html5_slow_start_no_media_source_delay_ms\u003d0\u0026html5_slow_start_timeout_delay_ms\u003d20000\u0026html5_ssdai_adfetch_dynamic_timeout_ms\u003d0\u0026html5_ssdai_enable_new_seek_logic\u003dtrue\u0026html5_ssdai_flush_vss\u003dtrue\u0026html5_ssdai_vss_player_state_change\u003dtrue\u0026html5_start_seconds_reorder\u003dtrue\u0026html5_stateful_audio_min_adjustment_value\u003d0\u0026html5_static_abr_resolution_shelf\u003d0\u0026html5_store_xhr_headers_readable\u003dtrue\u0026html5_stream_metadata\u003dtrue\u0026html5_streaming_init_requests_sizes\u003d0\u0026html5_streaming_xhr_check_for_null_response\u003dtrue\u0026html5_subsegment_readahead_load_speed_check_interval\u003d0.5\u0026html5_subsegment_readahead_min_buffer_health_secs\u003d0.25\u0026html5_subsegment_readahead_min_buffer_health_secs_on_timeout\u003d0.1\u0026html5_subsegment_readahead_min_load_speed\u003d1.5\u0026html5_subsegment_readahead_seek_latency_fudge\u003d0.5\u0026html5_subsegment_readahead_target_buffer_health_secs\u003d0.5\u0026html5_subsegment_readahead_timeout_secs\u003d2.0\u0026html5_suspend_loader\u003dtrue\u0026html5_track_termination_during_request\u003dtrue\u0026html5_ugc_live_audio_51\u003dtrue\u0026html5_ugc_vod_audio_51\u003dtrue\u0026html5_ultra_high_res_logging_percent\u003d0.0\u0026html5_unreported_seek_reseek_delay_ms\u003d0\u0026html5_unrestricted_layer_high_res_logging_percent\u003d0.0\u0026html5_update_constraint\u003dtrue\u0026html5_use_post_for_media\u003dtrue\u0026html5_varispeed_playback_rate\u003dtrue\u0026html5_video_tbd_min_kb\u003d0\u0026html5_viewport_undersend_maximum\u003d0.0\u0026html5_watchdog_for_zero_seek\u003dtrue\u0026html5_web_enable_halftime_preroll\u003dtrue\u0026html5_webpo_idle_priority_job\u003dtrue\u0026html5_woffle_resume\u003dtrue\u0026html5_workaround_delay_trigger\u003dtrue\u0026html5_xhr_clean_up_multi_slice_facade\u003dtrue\u0026html5_ytvlr_enable_single_select_survey\u003dtrue\u0026il_use_view_model_logging_context\u003dtrue\u0026initial_gel_batch_timeout\u003d2000\u0026injected_license_handler_error_code\u003d0\u0026injected_license_handler_license_status\u003d0\u0026json_condensed_response\u003dtrue\u0026kevlar_command_handler_command_banlist\u003d[]\u0026kevlar_dropdown_fix\u003dtrue\u0026kevlar_gel_error_routing\u003dtrue\u0026kevlar_miniplayer\u003dtrue\u0026kevlar_miniplayer_expand_top\u003dtrue\u0026kevlar_miniplayer_play_pause_on_scrim\u003dtrue\u0026kevlar_playback_associated_queue\u003dtrue\u0026kevlar_queue_use_update_api\u003dtrue\u0026kevlar_smart_downloads\u003dtrue\u0026kevlar_smart_downloads_setting\u003dtrue\u0026kevlar_vimio_use_shared_monitor\u003dtrue\u0026kevlar_woffle\u003dtrue\u0026live_chunk_readahead\u003d3\u0026live_fresca_v2\u003dtrue\u0026log_errors_through_nwl_on_retry\u003dtrue\u0026log_heartbeat_with_lifecycles\u003dtrue\u0026log_web_endpoint_to_layer\u003dtrue\u0026log_window_onerror_fraction\u003d0.1\u0026manifestless_post_live\u003dtrue\u0026manifestless_post_live_ufph\u003dtrue\u0026max_prefetch_window_sec_for_livestream_optimization\u003d10\u0026max_resolution_for_white_noise\u003d360\u0026mdx_enable_privacy_disclosure_ui\u003dtrue\u0026mdx_load_cast_api_bootstrap_script\u003dtrue\u0026migrate_events_to_ts\u003dtrue\u0026min_prefetch_offset_sec_for_livestream_optimization\u003d20\u0026music_enable_shared_audio_tier_logic\u003dtrue\u0026mweb_c3_endscreen\u003dtrue\u0026mweb_enable_custom_control_shared\u003dtrue\u0026mweb_enable_skippables_on_jio_phone\u003dtrue\u0026mweb_muted_autoplay_animation\u003dshrink\u0026mweb_native_control_in_faux_fullscreen_shared\u003dtrue\u0026network_polling_interval\u003d30000\u0026networkless_gel\u003dtrue\u0026networkless_logging\u003dtrue\u0026new_codecs_string_api_uses_legacy_style\u003dtrue\u0026nwl_send_fast_on_unload\u003dtrue\u0026nwl_send_from_memory_when_online\u003dtrue\u0026offline_error_handling\u003dtrue\u0026pageid_as_header_web\u003dtrue\u0026parse_query_data_from_url\u003dtrue\u0026player_ads_set_adformat_on_client\u003dtrue\u0026player_allow_autonav_after_playlist\u003dtrue\u0026player_bootstrap_method\u003dtrue\u0026player_defer_caption_display\u003d1000\u0026player_destroy_old_version\u003dtrue\u0026player_doubletap_to_seek\u003dtrue\u0026player_enable_playback_playlist_change\u003dtrue\u0026player_endscreen_ellipsis_fix\u003dtrue\u0026player_underlay_min_player_width\u003d768.0\u0026player_underlay_video_width_fraction\u003d0.6\u0026player_web_canary_stage\u003d0\u0026playready_first_play_expiration\u003d-1\u0026polymer_bad_build_labels\u003dtrue\u0026polymer_log_prop_change_observer_percent\u003d0\u0026polymer_verifiy_app_state\u003dtrue\u0026preskip_button_style_ads_backend\u003dcountdown_next_to_thumbnail\u0026qoe_nwl_downloads\u003dtrue\u0026qoe_send_and_write\u003dtrue\u0026record_app_crashed_web\u003dtrue\u0026replace_playability_retriever_in_watch\u003dtrue\u0026scheduler_use_raf_by_default\u003dtrue\u0026self_podding_header_string_template\u003dself_podding_interstitial_message\u0026self_podding_highlight_non_default_button\u003dtrue\u0026self_podding_midroll_choice_string_template\u003dself_podding_midroll_choice\u0026send_config_hash_timer\u003d0\u0026set_interstitial_advertisers_question_text\u003dtrue\u0026short_start_time_prefer_publish_in_watch_log\u003dtrue\u0026should_clear_video_data_on_player_cued_unstarted\u003dtrue\u0026skip_inline_muted_license_service_check\u003dtrue\u0026skip_invalid_ytcsi_ticks\u003dtrue\u0026skip_ls_gel_retry\u003dtrue\u0026skip_setting_info_in_csi_data_object\u003dtrue\u0026start_client_gcf\u003dtrue\u0026start_client_gcf_for_player\u003dtrue\u0026streaming_data_emergency_itag_blacklist\u003d[]\u0026suppress_error_204_logging\u003dtrue\u0026transport_use_scheduler\u003dtrue\u0026tv_pacf_logging_sample_rate\u003d0.01\u0026tvhtml5_unplugged_preload_cache_size\u003d5\u0026uncover_ad_badge_on_RTL_tiny_window\u003dtrue\u0026unplugged_dai_live_chunk_readahead\u003d3\u0026unplugged_tvhtml5_video_preload_on_focus_delay_ms\u003d0\u0026use_inlined_player_rpc\u003dtrue\u0026use_new_in_memory_storage\u003dtrue\u0026use_new_nwl_initialization\u003dtrue\u0026use_new_nwl_saw\u003dtrue\u0026use_new_nwl_stw\u003dtrue\u0026use_new_nwl_wts\u003dtrue\u0026use_player_abuse_bg_library\u003dtrue\u0026use_profilepage_event_label_in_carousel_playbacks\u003dtrue\u0026use_request_time_ms_header\u003dtrue\u0026use_session_based_sampling\u003dtrue\u0026use_shared_nsm\u003dtrue\u0026use_shared_nsm_and_keep_yt_online_updated\u003dtrue\u0026use_ts_visibilitylogger\u003dtrue\u0026variable_buffer_timeout_ms\u003d0\u0026verify_ads_itag_early\u003dtrue\u0026vp9_drm_live\u003dtrue\u0026vss_final_ping_send_and_write\u003dtrue\u0026vss_pings_using_networkless\u003dtrue\u0026vss_playback_use_send_and_write\u003dtrue\u0026web_api_url\u003dtrue\u0026web_cinematic_watch_settings\u003dtrue\u0026web_client_version_override\u003d\u0026web_dedupe_ve_grafting\u003dtrue\u0026web_deprecate_service_ajax_map_dependency\u003dtrue\u0026web_enable_voz_audio_feedback\u003dtrue\u0026web_foreground_heartbeat_interval_ms\u003d28000\u0026web_forward_command_on_pbj\u003dtrue\u0026web_gel_debounce_ms\u003d10000\u0026web_gel_timeout_cap\u003dtrue\u0026web_key_moments_markers\u003dtrue\u0026web_log_memory_total_kbytes\u003dtrue\u0026web_logging_max_batch\u003d150\u0026web_modern_ads\u003dtrue\u0026web_modern_buttons\u003dtrue\u0026web_modern_buttons_bl_survey\u003dtrue\u0026web_modern_subscribe\u003dtrue\u0026web_modern_subscribe_style\u003dfilled\u0026web_new_autonav_countdown\u003dtrue\u0026web_one_platform_error_handling\u003dtrue\u0026web_op_signal_type_banlist\u003d[]\u0026web_playback_associated_log_ctt\u003dtrue\u0026web_playback_associated_ve\u003dtrue\u0026web_player_api_logging_fraction\u003d0.01\u0026web_player_autonav_toggle_always_listen\u003dtrue\u0026web_player_autonav_use_server_provided_state\u003dtrue\u0026web_player_caption_language_preference_stickiness_duration\u003d0\u0026web_player_decouple_autonav\u003dtrue\u0026web_player_enable_early_warning_snackbar\u003dtrue\u0026web_player_enable_premium_hbr_in_h5_api\u003dtrue\u0026web_player_enable_premium_hbr_playback_cap\u003dtrue\u0026web_player_fine_scrubbing\u003dtrue\u0026web_player_gvi_wexit_adunit\u003dtrue\u0026web_player_gvi_wexit_all_player_styles\u003dtrue\u0026web_player_gvi_wexit_living_room_bedrock\u003dtrue\u0026web_player_gvi_wexit_living_room_kids\u003dtrue\u0026web_player_gvi_wexit_living_room_other\u003dtrue\u0026web_player_gvi_wexit_living_room_pangea\u003dtrue\u0026web_player_gvi_wexit_living_room_simply\u003dtrue\u0026web_player_gvi_wexit_living_room_unplugged\u003dtrue\u0026web_player_innertube_playlist_update\u003dtrue\u0026web_player_ipp_canary_type_for_logging\u003d\u0026web_player_live_monitor_env\u003dtrue\u0026web_player_move_autonav_toggle\u003dtrue\u0026web_player_music_visualizer_treatment\u003dfake\u0026web_player_mutable_event_label\u003dtrue\u0026web_player_nitrate_promo_tooltip\u003dtrue\u0026web_player_no_force_gvi\u003dtrue\u0026web_player_response_playback_tracking_parsing\u003dtrue\u0026web_player_seek_chapters_by_shortcut\u003dtrue\u0026web_player_sentinel_is_uniplayer\u003dtrue\u0026web_player_should_honor_include_asr_setting\u003dtrue\u0026web_player_show_music_in_this_video_graphic\u003dvideo_thumbnail\u0026web_player_small_hbp_settings_menu\u003dtrue\u0026web_player_ss_dai_ad_fetching_timeout_ms\u003d15000\u0026web_player_ss_media_time_offset\u003dtrue\u0026web_player_ss_timeout_skip_ads\u003dtrue\u0026web_player_ssdai_all_acpns_aids_logging_killswitch\u003dtrue\u0026web_player_touch_mode_improvements\u003dtrue\u0026web_player_transfer_timeout_threshold_ms\u003d10800000\u0026web_player_unset_default_csn_killswitch\u003dtrue\u0026web_player_use_cinematic_label_2\u003dtrue\u0026web_player_use_new_api_for_quality_pullback\u003dtrue\u0026web_player_vss_pageid_header\u003dtrue\u0026web_player_watch_next_response\u003dtrue\u0026web_player_watch_next_response_parsing\u003dtrue\u0026web_prefetch_preload_video\u003dtrue\u0026web_repeating_chapters\u003dtrue\u0026web_rounded_containers\u003dtrue\u0026web_rounded_thumbnails\u003dtrue\u0026web_settings_menu_icons\u003dtrue\u0026web_smoothness_test_duration_ms\u003d0\u0026web_smoothness_test_method\u003d0\u0026web_yt_config_context\u003dtrue\u0026woffle_clean_up_after_entity_migration\u003dtrue\u0026woffle_orchestration\u003dtrue\u0026ytidb_clear_embedded_player\u003dtrue\u0026ytidb_fetch_datasync_ids_for_data_cleanup\u003dtrue\u0026ytidb_remake_db_retries\u003d3\u0026ytidb_reopen_db_retries\u003d3\u0026ytidb_transaction_ended_event_rate_limit\u003d0.02\u0026ytidb_transaction_ended_event_rate_limit_session\u003d0.2\u0026ytidb_transaction_ended_event_rate_limit_transaction\u003d0.1","hideInfo":true,"disableFullscreen":true,"cspNonce":"nopnosk9VoEiau3Xtg_3uQ","canaryState":"none","enableCsiLogging":true,"authorizedUserIndex":0,"datasyncId":"106384449314396247844||","storeUserVolume":true,"disableSeek":true,"disablePaidContentOverlay":true},"WEB_PLAYER_CONTEXT_CONFIG_ID_KEVLAR_SPONSORSHIPS_OFFER":{"rootElementId":"ytd-sponsorships-offer-with-video-renderer","jsUrl":"/s/player/97ea7458/player_ias.vflset/en_US/base.js","cssUrl":"/s/player/97ea7458/www-player.css","contextId":"WEB_PLAYER_CONTEXT_CONFIG_ID_KEVLAR_SPONSORSHIPS_OFFER","eventLabel":"sponsorshipsoffer","contentRegion":"CA","hl":"en_US","hostLanguage":"en","playerStyle":"desktop-polymer","innertubeApiKey":"AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8","innertubeApiVersion":"v1","innertubeContextClientVersion":"2.20230201.01.00","disableRelatedVideos":true,"annotationsLoadPolicy":3,"device":{"brand":"apple","model":"","browser":"Chrome","browserVersion":"109.0.0.0","os":"Macintosh","osVersion":"10_15_7","platform":"DESKTOP","interfaceName":"WEB","interfaceVersion":"2.20230201.01.00","deviceYear":2013},"serializedExperimentIds":"23983296,23986016,24004644,24007246,24080738,24135310,24169501,24219381,24255163,24282011,24396645,24415864,24416291,24416441,24433679,24437577,24439361,24441240,24449113,24449639,24450366,24451032,24454357,24454498,24457577,24457884,24460376,24463912,24469897","serializedExperimentFlags":"H5_async_logging_delay_ms\u003d30000.0\u0026H5_enable_full_pacf_logging\u003dtrue\u0026H5_use_async_logging\u003dtrue\u0026ad_pod_disable_companion_persist_ads_quality\u003dtrue\u0026addto_ajax_log_warning_fraction\u003d0.1\u0026align_ad_to_video_player_lifecycle_for_bulleit\u003dtrue\u0026allow_live_autoplay\u003dtrue\u0026allow_poltergust_autoplay\u003dtrue\u0026allow_skip_networkless\u003dtrue\u0026autoplay_time\u003d8000\u0026autoplay_time_for_fullscreen\u003d3000\u0026autoplay_time_for_music_content\u003d3000\u0026background_thread_flush_logs_due_to_batch_limit\u003dtrue\u0026bg_vm_reinit_threshold\u003d7200000\u0026blocked_packages_for_sps\u003d[]\u0026botguard_async_snapshot_timeout_ms\u003d3000\u0026check_ad_ui_status_for_mweb_safari\u003dtrue\u0026check_navigator_accuracy_timeout_ms\u003d0\u0026clear_user_partitioned_ls\u003dtrue\u0026client_respect_autoplay_switch_button_renderer\u003dtrue\u0026csi_on_gel\u003dtrue\u0026dash_manifest_version\u003d5\u0026debug_bandaid_hostname\u003d\u0026debug_sherlog_username\u003d\u0026delay_ads_gvi_call_on_bulleit_living_room_ms\u003d0\u0026deprecate_csi_has_info\u003dtrue\u0026deprecate_pair_servlet_enabled\u003dtrue\u0026deprecate_two_way_binding_child\u003dtrue\u0026deprecate_two_way_binding_parent\u003dtrue\u0026desktop_image_cta_no_background\u003dtrue\u0026desktop_log_img_click_location\u003dtrue\u0026desktop_player_button_tooltip_with_shortcut\u003dtrue\u0026desktop_sparkles_light_cta_button\u003dtrue\u0026disable_channel_id_check_for_suspended_channels\u003dtrue\u0026disable_child_node_auto_formatted_strings\u003dtrue\u0026disable_defer_admodule_on_advertiser_video\u003dtrue\u0026disable_features_for_supex\u003dtrue\u0026disable_legacy_desktop_remote_queue\u003dtrue\u0026disable_mdx_connection_in_mdx_module_for_music_web\u003dtrue\u0026disable_new_pause_state3\u003dtrue\u0026disable_pacf_logging_for_memory_limited_tv\u003dtrue\u0026disable_rounding_ad_notify\u003dtrue\u0026disable_simple_mixed_direction_formatted_strings\u003dtrue\u0026disable_ssdai_on_errors\u003dtrue\u0026disable_tabbing_before_flyout_ad_elements_appear\u003dtrue\u0026disable_thumbnail_preloading\u003dtrue\u0026embeds_enable_allow_watch_again_endscreen_for_eligible_shorts\u003dtrue\u0026embeds_enable_embed_module\u003dtrue\u0026embeds_enable_shorts_branded_ui\u003dtrue\u0026embeds_enable_shorts_links_for_eligible_shorts\u003dtrue\u0026embeds_web_enable_gws_wh_rel_off\u003dtrue\u0026embeds_web_enable_info_panel_preview\u003dtrue\u0026embeds_web_enable_load_player_from_page_show\u003dtrue\u0026embeds_web_enable_logging_event_handlers\u003dtrue\u0026embeds_web_enable_pem_domain_fix_for_ad_requests\u003dtrue\u0026embeds_web_enable_replace_unload_w_pagehide\u003dtrue\u0026embeds_web_enable_ve_conversion_logging_tracking_no_allow_list\u003dtrue\u0026embeds_web_enable_video_data_refactoring_break_down_and_move_methods\u003dtrue\u0026embeds_web_enable_video_data_refactoring_like_button_renderer\u003dtrue\u0026embeds_web_hide_unfilled_more_videos_suggestions\u003dtrue\u0026embeds_web_lite_mode\u003d1\u0026embeds_web_nwl_disable_nocookie\u003dtrue\u0026embeds_web_synth_ch_headers_banned_urls_regex\u003d\u0026enable_ad_cpn_macro_substitution_for_click_pings\u003dtrue\u0026enable_cast_for_web_unplugged\u003dtrue\u0026enable_cast_on_music_web\u003dtrue\u0026enable_client_page_id_header_for_first_party_pings\u003dtrue\u0026enable_client_sli_logging\u003dtrue\u0026enable_discrete_live_precise_embargos\u003dtrue\u0026enable_error_corrections_infocard\u003dtrue\u0026enable_error_corrections_infocard_web_client\u003dtrue\u0026enable_error_corrections_infocard_web_client_check\u003dtrue\u0026enable_error_corrections_infocards_icon_web\u003dtrue\u0026enable_eviction_protection_for_bulleit\u003dtrue\u0026enable_gel_log_commands\u003dtrue\u0026enable_handles_account_menu_switcher\u003dtrue\u0026enable_inline_preview_controls\u003dtrue\u0026enable_live_premiere_web_player_indicator\u003dtrue\u0026enable_lr_home_infeed_ads_inline_playback_progress_pings\u003dtrue\u0026enable_macro_substitution_on_html5\u003dtrue\u0026enable_mixed_direction_formatted_strings\u003dtrue\u0026enable_mweb_livestream_ui_update\u003dtrue\u0026enable_new_paid_product_placement\u003dtrue\u0026enable_post_ad_perception_survey_fix_on_tvhtml5\u003dtrue\u0026enable_post_ad_perception_survey_in_tvhtml5\u003dtrue\u0026enable_precise_embargos\u003dtrue\u0026enable_server_stitched_dai\u003dtrue\u0026enable_shorts_player\u003dtrue\u0026enable_skip_ad_guidance_prompt\u003dtrue\u0026enable_skippable_ads_for_unplugged_ad_pod\u003dtrue\u0026enable_smearing_expansion_dai\u003dtrue\u0026enable_tectonic_ad_ux_for_halftime\u003dtrue\u0026enable_third_party_info\u003dtrue\u0026enable_topsoil_wta_for_halftime_live_infra\u003dtrue\u0026enable_web_media_session_metadata_fix\u003dtrue\u0026error_message_for_gsuite_network_restrictions\u003dtrue\u0026export_networkless_options\u003dtrue\u0026external_fullscreen_with_edu\u003dtrue\u0026fast_autonav_in_background\u003dtrue\u0026fetch_att_independently\u003dtrue\u0026fill_single_video_with_notify_to_lasr\u003dtrue\u0026filter_vp9_for_csdai\u003dtrue\u0026fix_ads_tracking_for_swf_config_deprecation_mweb\u003dtrue\u0026gcf_config_store_enabled\u003dtrue\u0026gpa_sparkles_ten_percent_layer\u003dtrue\u0026gvi_channel_client_screen\u003dtrue\u0026h5_companion_enable_adcpn_macro_substitution_for_click_pings\u003dtrue\u0026h5_inplayer_enable_adcpn_macro_substitution_for_click_pings\u003dtrue\u0026hfr_dropped_framerate_fallback_threshold\u003d0\u0026hide_endpoint_overflow_on_ytd_display_ad_renderer\u003dtrue\u0026hls_use_new_codecs_string_api\u003dtrue\u0026html5_ad_timeout_ms\u003d0\u0026html5_ads_preroll_lock_timeout_delay_ms\u003d15000\u0026html5_allow_discontiguous_slices\u003dtrue\u0026html5_allow_video_keyframe_without_audio\u003dtrue\u0026html5_append_init_while_paused\u003dtrue\u0026html5_apply_ustreamer_cap_per_video_id\u003dtrue\u0026html5_att_oauth\u003dtrue\u0026html5_attach_num_random_bytes_to_bandaid\u003d0\u0026html5_attach_po_token_to_bandaid\u003dtrue\u0026html5_autonav_cap_idle_secs\u003d0\u0026html5_autonav_quality_cap\u003d720\u0026html5_autoplay_default_quality_cap\u003d0\u0026html5_block_pip_safari_delay\u003d0\u0026html5_bmff_new_fourcc_check\u003dtrue\u0026html5_cap_quality_for_tv_hfr\u003dtrue\u0026html5_change_player_mode_order_for_logging\u003dtrue\u0026html5_clamp_cuepoints_to_min\u003dtrue\u0026html5_cobalt_max_size_for_immed_job\u003d0\u0026html5_cobalt_min_processor_cnt_to_offload_algo\u003d0\u0026html5_cobalt_override_quic\u003d0\u0026html5_consume_media_bytes_slice_infos\u003dtrue\u0026html5_control_flow_include_trigger_logging_in_tmp_logs\u003dtrue\u0026html5_create_manifest_from_protos\u003dtrue\u0026html5_de_dupe_content_video_loads_in_lifecycle_api\u003dtrue\u0026html5_deadzone_multiplier\u003d1.0\u0026html5_debug_data_log_probability\u003d0.1\u0026html5_decode_to_texture_cap\u003dtrue\u0026html5_decoder_freeze_timeout_delay_ms\u003d0\u0026html5_default_ad_gain\u003d0.5\u0026html5_default_quality_cap\u003d0\u0026html5_defer_ad_module_ms\u003d0\u0026html5_defer_fetch_att_ms\u003d1000\u0026html5_defer_modules_delay_time_millis\u003d0\u0026html5_delay_initial_loading\u003dtrue\u0026html5_delay_retries_for_host_timeout\u003dtrue\u0026html5_delayed_retry_count\u003d1\u0026html5_delayed_retry_delay_ms\u003d5000\u0026html5_deprecate_video_tag_pool\u003dtrue\u0026html5_desktop_vr180_allow_panning\u003dtrue\u0026html5_desync_cue_range_threshold\u003d0\u0026html5_df_downgrade_thresh\u003d0.2\u0026html5_disable_connection_issue_event\u003dtrue\u0026html5_disable_csi_for_bulleit\u003dtrue\u0026html5_disable_move_pssh_to_moov\u003dtrue\u0026html5_disable_non_contiguous\u003dtrue\u0026html5_displayed_frame_rate_downgrade_threshold\u003d45\u0026html5_drm_check_all_key_error_states\u003dtrue\u0026html5_drm_cpi_license_key\u003dtrue\u0026html5_early_read_chunk\u003dtrue\u0026html5_enable_ac3\u003dtrue\u0026html5_enable_ads_client_monitoring_log_tv\u003dtrue\u0026html5_enable_atv_offline\u003dtrue\u0026html5_enable_client_hints_override\u003dtrue\u0026html5_enable_eac3\u003dtrue\u0026html5_enable_embedded_player_visibility_signals\u003dtrue\u0026html5_enable_non_notify_composite_vod_lsar_pacf\u003dtrue\u0026html5_enable_single_video_vod_ivar_on_pacf\u003dtrue\u0026html5_enable_tvos_dash\u003dtrue\u0026html5_enable_tvos_encrypted_vp9\u003dtrue\u0026html5_enable_widevine_for_alc\u003dtrue\u0026html5_enable_widevine_for_fast_linear\u003dtrue\u0026html5_encourage_array_coalescing\u003dtrue\u0026html5_exile_on_drm_fatal\u003dtrue\u0026html5_fill_isTypeSupported_capability_cache_earlier\u003dtrue\u0026html5_fludd_suspend\u003dtrue\u0026html5_flush_segment_index_on_error\u003dtrue\u0026html5_flush_vss_with_rti_and_rtn\u003dtrue\u0026html5_gapless_ended_transition_buffer_ms\u003d200\u0026html5_gapless_preloading\u003dtrue\u0026html5_generate_session_po_token\u003dtrue\u0026html5_gl_fps_threshold\u003d0\u0026html5_halt_ssdai_fetch_on_predict_start\u003dtrue\u0026html5_hdcp_probing_stream_url\u003d\u0026html5_heartbeat_set_ended\u003dtrue\u0026html5_hfr_quality_cap\u003d0\u0026html5_high_res_logging_percent\u003d0.01\u0026html5_idle_rate_limit_ms\u003d0\u0026html5_ignore_media_element_event_loadeddata\u003dtrue\u0026html5_innertube_heartbeats_for_fairplay\u003dtrue\u0026html5_innertube_heartbeats_for_playready\u003dtrue\u0026html5_innertube_heartbeats_for_widevine\u003dtrue\u0026html5_ios4_seek_above_zero\u003dtrue\u0026html5_ios7_force_play_on_stall\u003dtrue\u0026html5_ios_force_seek_to_zero_on_stop\u003dtrue\u0026html5_jumbo_mobile_subsegment_readahead_target\u003d3.0\u0026html5_jumbo_ull_nonstreaming_mffa_ms\u003d4000\u0026html5_jumbo_ull_subsegment_readahead_target\u003d1.3\u0026html5_license_constraint_delay\u003d5000\u0026html5_live_abr_head_miss_fraction\u003d0.0\u0026html5_live_abr_repredict_fraction\u003d0.0\u0026html5_live_byterate_factor_for_readahead\u003d1.3\u0026html5_live_low_latency_bandwidth_window\u003d0.0\u0026html5_live_normal_latency_bandwidth_window\u003d0.0\u0026html5_live_partial_response_resumable\u003dtrue\u0026html5_live_quality_cap\u003d0\u0026html5_live_ultra_low_latency_bandwidth_window\u003d0.0\u0026html5_log_audio_abr\u003dtrue\u0026html5_log_experiment_id_from_player_response_to_ctmp\u003d\u0026html5_log_first_ssdai_requests_killswitch\u003dtrue\u0026html5_log_offline_playback_started_event\u003dtrue\u0026html5_log_readahead_on_playback_start\u003dtrue\u0026html5_log_rebuffer_events\u003d5\u0026html5_log_server_url_param\u003dtrue\u0026html5_log_trigger_events_with_debug_data\u003dtrue\u0026html5_long_rebuffer_jiggle_cmt_delay_ms\u003d0\u0026html5_long_rebuffer_new_elem_shorts_delay_ms\u003d0\u0026html5_long_rebuffer_threshold_ms\u003d30000\u0026html5_manifestless_seg_drift_limit_secs\u003d0\u0026html5_manifestless_unplugged\u003dtrue\u0026html5_manifestless_vp9_otf\u003dtrue\u0026html5_max_drift_per_track_secs\u003d0.0\u0026html5_max_headm_for_streaming_xhr\u003d0\u0026html5_max_live_dvr_window_plus_margin_secs\u003d46800.0\u0026html5_max_readbehind_secs\u003d0\u0026html5_max_redirect_response_length\u003d8192\u0026html5_max_selectable_quality_ordinal\u003d0\u0026html5_maximum_readahead_seconds\u003d0.0\u0026html5_media_fullscreen\u003dtrue\u0026html5_mfl_extend_max_request_time\u003dtrue\u0026html5_min_readbehind_cap_secs\u003d60\u0026html5_min_readbehind_secs\u003d0\u0026html5_min_selectable_quality_ordinal\u003d0\u0026html5_min_startup_buffered_ad_media_duration_secs\u003d1.2\u0026html5_min_startup_buffered_media_duration_secs\u003d1.2\u0026html5_minimum_readahead_seconds\u003d0.0\u0026html5_new_min_startup_smooth_logic\u003dtrue\u0026html5_no_placeholder_rollbacks\u003dtrue\u0026html5_non_network_rebuffer_duration_ms\u003d0\u0026html5_non_onesie_attach_po_token\u003dtrue\u0026html5_not_register_disposables_when_core_listens\u003dtrue\u0026html5_offline_failure_retry_limit\u003d2\u0026html5_onesie_cast\u003dtrue\u0026html5_onesie_defer_content_loader_ms\u003d0\u0026html5_onesie_disable_js_cleartext_compression\u003dtrue\u0026html5_onesie_enable_server_side_badwidth_estimation\u003dtrue\u0026html5_onesie_host_racing_cap_ms\u003d0\u0026html5_onesie_ignore_innertube_api_key\u003dtrue\u0026html5_onesie_live_ttl_secs\u003d8\u0026html5_onesie_media_bytes\u003dtrue\u0026html5_onesie_nonzero_playback_start\u003dtrue\u0026html5_onesie_notify_cuepoint_manager_on_completion\u003dtrue\u0026html5_onesie_prefer_trusted_host\u003dtrue\u0026html5_onesie_prewarm_cooldown_ms\u003d0\u0026html5_onesie_prewarm_interval_ms\u003d0\u0026html5_onesie_prewarm_max_lact_ms\u003d0\u0026html5_onesie_redirector_timeout_ms\u003d0\u0026html5_onesie_request_timeout_ms\u003d1000\u0026html5_onesie_sticky_server_side\u003dtrue\u0026html5_pause_on_nonforeground_platform_errors\u003dtrue\u0026html5_peak_shave\u003dtrue\u0026html5_per_format_loudness_fix\u003dtrue\u0026html5_perf_cap_override_sticky\u003dtrue\u0026html5_performance_cap_floor\u003d360\u0026html5_performance_impact_profiling_timer_ms\u003d0\u0026html5_perserve_av1_perf_cap\u003dtrue\u0026html5_photos_use_vp9_otf\u003dtrue\u0026html5_platform_minimum_readahead_seconds\u003d0.0\u0026html5_platform_whitelisted_for_frame_accurate_seeks\u003dtrue\u0026html5_player_autonav_logging\u003dtrue\u0026html5_player_dynamic_bottom_gradient\u003dtrue\u0026html5_player_min_build_cl\u003d-1\u0026html5_player_preload_ad_fix\u003dtrue\u0026html5_post_interrupt_readahead\u003d20\u0026html5_prefer_server_bwe3\u003dtrue\u0026html5_preload_wait_time_secs\u003d0.0\u0026html5_probe_primary_delay_base_ms\u003d0\u0026html5_process_all_encrypted_events\u003dtrue\u0026html5_query_sw_secure_crypto_for_android\u003dtrue\u0026html5_random_playback_cap\u003d0\u0026html5_readahead_ratelimit\u003d3000\u0026html5_recognize_predict_start_cue_point\u003dtrue\u0026html5_reduce_istypesupported_calls\u003dtrue\u0026html5_remove_command_triggered_companions\u003dtrue\u0026html5_remove_not_servable_check_killswitch\u003dtrue\u0026html5_rename_apbs\u003dtrue\u0026html5_report_fatal_drm_restricted_error_killswitch\u003dtrue\u0026html5_report_slow_ads_as_error\u003dtrue\u0026html5_request_only_hdr_or_sdr_keys\u003dtrue\u0026html5_request_sizing_multiplier\u003d0.8\u0026html5_require_hdr_capability\u003dtrue\u0026html5_reset_media_stream_on_unresumable_slices\u003dtrue\u0026html5_resource_bad_status_delay_scaling\u003d1.5\u0026html5_restrict_streaming_xhr_on_sqless_requests\u003dtrue\u0026html5_safari_desktop_eme_min_version\u003d0\u0026html5_seek_jiggle_cmt_delay_ms\u003d8000\u0026html5_seek_new_elem_delay_ms\u003d12000\u0026html5_seek_new_elem_shorts_delay_ms\u003d0\u0026html5_seek_over_discontinuities_delay_ms\u003d0\u0026html5_seek_set_cmt_delay_ms\u003d2000\u0026html5_seek_timeout_delay_ms\u003d20000\u0026html5_selectable_formats_early_exit\u003dtrue\u0026html5_server_stitched_dai_decorated_url_retry_limit\u003d5\u0026html5_server_stitched_dai_group\u003dtrue\u0026html5_session_po_token_interval_time_ms\u003d900000\u0026html5_set_ended_in_pfx_live\u003dtrue\u0026html5_simplify_streaming_xhr\u003dtrue\u0026html5_skip_oob_start_seconds\u003dtrue\u0026html5_skip_slow_ad_delay_ms\u003d15000\u0026html5_skip_sub_quantum_discontinuity_secs\u003d0.0\u0026html5_slow_start_no_media_source_delay_ms\u003d0\u0026html5_slow_start_timeout_delay_ms\u003d20000\u0026html5_ssdai_adfetch_dynamic_timeout_ms\u003d0\u0026html5_ssdai_enable_new_seek_logic\u003dtrue\u0026html5_ssdai_flush_vss\u003dtrue\u0026html5_ssdai_vss_player_state_change\u003dtrue\u0026html5_start_seconds_reorder\u003dtrue\u0026html5_stateful_audio_min_adjustment_value\u003d0\u0026html5_static_abr_resolution_shelf\u003d0\u0026html5_store_xhr_headers_readable\u003dtrue\u0026html5_stream_metadata\u003dtrue\u0026html5_streaming_init_requests_sizes\u003d0\u0026html5_streaming_xhr_check_for_null_response\u003dtrue\u0026html5_subsegment_readahead_load_speed_check_interval\u003d0.5\u0026html5_subsegment_readahead_min_buffer_health_secs\u003d0.25\u0026html5_subsegment_readahead_min_buffer_health_secs_on_timeout\u003d0.1\u0026html5_subsegment_readahead_min_load_speed\u003d1.5\u0026html5_subsegment_readahead_seek_latency_fudge\u003d0.5\u0026html5_subsegment_readahead_target_buffer_health_secs\u003d0.5\u0026html5_subsegment_readahead_timeout_secs\u003d2.0\u0026html5_suspend_loader\u003dtrue\u0026html5_track_termination_during_request\u003dtrue\u0026html5_ugc_live_audio_51\u003dtrue\u0026html5_ugc_vod_audio_51\u003dtrue\u0026html5_ultra_high_res_logging_percent\u003d0.0\u0026html5_unreported_seek_reseek_delay_ms\u003d0\u0026html5_unrestricted_layer_high_res_logging_percent\u003d0.0\u0026html5_update_constraint\u003dtrue\u0026html5_use_post_for_media\u003dtrue\u0026html5_varispeed_playback_rate\u003dtrue\u0026html5_video_tbd_min_kb\u003d0\u0026html5_viewport_undersend_maximum\u003d0.0\u0026html5_watchdog_for_zero_seek\u003dtrue\u0026html5_web_enable_halftime_preroll\u003dtrue\u0026html5_webpo_idle_priority_job\u003dtrue\u0026html5_woffle_resume\u003dtrue\u0026html5_workaround_delay_trigger\u003dtrue\u0026html5_xhr_clean_up_multi_slice_facade\u003dtrue\u0026html5_ytvlr_enable_single_select_survey\u003dtrue\u0026il_use_view_model_logging_context\u003dtrue\u0026initial_gel_batch_timeout\u003d2000\u0026injected_license_handler_error_code\u003d0\u0026injected_license_handler_license_status\u003d0\u0026json_condensed_response\u003dtrue\u0026kevlar_command_handler_command_banlist\u003d[]\u0026kevlar_dropdown_fix\u003dtrue\u0026kevlar_gel_error_routing\u003dtrue\u0026kevlar_miniplayer\u003dtrue\u0026kevlar_miniplayer_expand_top\u003dtrue\u0026kevlar_miniplayer_play_pause_on_scrim\u003dtrue\u0026kevlar_playback_associated_queue\u003dtrue\u0026kevlar_queue_use_update_api\u003dtrue\u0026kevlar_smart_downloads\u003dtrue\u0026kevlar_smart_downloads_setting\u003dtrue\u0026kevlar_vimio_use_shared_monitor\u003dtrue\u0026kevlar_woffle\u003dtrue\u0026live_chunk_readahead\u003d3\u0026live_fresca_v2\u003dtrue\u0026log_errors_through_nwl_on_retry\u003dtrue\u0026log_heartbeat_with_lifecycles\u003dtrue\u0026log_web_endpoint_to_layer\u003dtrue\u0026log_window_onerror_fraction\u003d0.1\u0026manifestless_post_live\u003dtrue\u0026manifestless_post_live_ufph\u003dtrue\u0026max_prefetch_window_sec_for_livestream_optimization\u003d10\u0026max_resolution_for_white_noise\u003d360\u0026mdx_enable_privacy_disclosure_ui\u003dtrue\u0026mdx_load_cast_api_bootstrap_script\u003dtrue\u0026migrate_events_to_ts\u003dtrue\u0026min_prefetch_offset_sec_for_livestream_optimization\u003d20\u0026music_enable_shared_audio_tier_logic\u003dtrue\u0026mweb_c3_endscreen\u003dtrue\u0026mweb_enable_custom_control_shared\u003dtrue\u0026mweb_enable_skippables_on_jio_phone\u003dtrue\u0026mweb_muted_autoplay_animation\u003dshrink\u0026mweb_native_control_in_faux_fullscreen_shared\u003dtrue\u0026network_polling_interval\u003d30000\u0026networkless_gel\u003dtrue\u0026networkless_logging\u003dtrue\u0026new_codecs_string_api_uses_legacy_style\u003dtrue\u0026nwl_send_fast_on_unload\u003dtrue\u0026nwl_send_from_memory_when_online\u003dtrue\u0026offline_error_handling\u003dtrue\u0026pageid_as_header_web\u003dtrue\u0026parse_query_data_from_url\u003dtrue\u0026player_ads_set_adformat_on_client\u003dtrue\u0026player_allow_autonav_after_playlist\u003dtrue\u0026player_bootstrap_method\u003dtrue\u0026player_defer_caption_display\u003d1000\u0026player_destroy_old_version\u003dtrue\u0026player_doubletap_to_seek\u003dtrue\u0026player_enable_playback_playlist_change\u003dtrue\u0026player_endscreen_ellipsis_fix\u003dtrue\u0026player_underlay_min_player_width\u003d768.0\u0026player_underlay_video_width_fraction\u003d0.6\u0026player_web_canary_stage\u003d0\u0026playready_first_play_expiration\u003d-1\u0026polymer_bad_build_labels\u003dtrue\u0026polymer_log_prop_change_observer_percent\u003d0\u0026polymer_verifiy_app_state\u003dtrue\u0026preskip_button_style_ads_backend\u003dcountdown_next_to_thumbnail\u0026qoe_nwl_downloads\u003dtrue\u0026qoe_send_and_write\u003dtrue\u0026record_app_crashed_web\u003dtrue\u0026replace_playability_retriever_in_watch\u003dtrue\u0026scheduler_use_raf_by_default\u003dtrue\u0026self_podding_header_string_template\u003dself_podding_interstitial_message\u0026self_podding_highlight_non_default_button\u003dtrue\u0026self_podding_midroll_choice_string_template\u003dself_podding_midroll_choice\u0026send_config_hash_timer\u003d0\u0026set_interstitial_advertisers_question_text\u003dtrue\u0026short_start_time_prefer_publish_in_watch_log\u003dtrue\u0026should_clear_video_data_on_player_cued_unstarted\u003dtrue\u0026skip_inline_muted_license_service_check\u003dtrue\u0026skip_invalid_ytcsi_ticks\u003dtrue\u0026skip_ls_gel_retry\u003dtrue\u0026skip_setting_info_in_csi_data_object\u003dtrue\u0026start_client_gcf\u003dtrue\u0026start_client_gcf_for_player\u003dtrue\u0026streaming_data_emergency_itag_blacklist\u003d[]\u0026suppress_error_204_logging\u003dtrue\u0026transport_use_scheduler\u003dtrue\u0026tv_pacf_logging_sample_rate\u003d0.01\u0026tvhtml5_unplugged_preload_cache_size\u003d5\u0026uncover_ad_badge_on_RTL_tiny_window\u003dtrue\u0026unplugged_dai_live_chunk_readahead\u003d3\u0026unplugged_tvhtml5_video_preload_on_focus_delay_ms\u003d0\u0026use_inlined_player_rpc\u003dtrue\u0026use_new_in_memory_storage\u003dtrue\u0026use_new_nwl_initialization\u003dtrue\u0026use_new_nwl_saw\u003dtrue\u0026use_new_nwl_stw\u003dtrue\u0026use_new_nwl_wts\u003dtrue\u0026use_player_abuse_bg_library\u003dtrue\u0026use_profilepage_event_label_in_carousel_playbacks\u003dtrue\u0026use_request_time_ms_header\u003dtrue\u0026use_session_based_sampling\u003dtrue\u0026use_shared_nsm\u003dtrue\u0026use_shared_nsm_and_keep_yt_online_updated\u003dtrue\u0026use_ts_visibilitylogger\u003dtrue\u0026variable_buffer_timeout_ms\u003d0\u0026verify_ads_itag_early\u003dtrue\u0026vp9_drm_live\u003dtrue\u0026vss_final_ping_send_and_write\u003dtrue\u0026vss_pings_using_networkless\u003dtrue\u0026vss_playback_use_send_and_write\u003dtrue\u0026web_api_url\u003dtrue\u0026web_cinematic_watch_settings\u003dtrue\u0026web_client_version_override\u003d\u0026web_dedupe_ve_grafting\u003dtrue\u0026web_deprecate_service_ajax_map_dependency\u003dtrue\u0026web_enable_voz_audio_feedback\u003dtrue\u0026web_foreground_heartbeat_interval_ms\u003d28000\u0026web_forward_command_on_pbj\u003dtrue\u0026web_gel_debounce_ms\u003d10000\u0026web_gel_timeout_cap\u003dtrue\u0026web_key_moments_markers\u003dtrue\u0026web_log_memory_total_kbytes\u003dtrue\u0026web_logging_max_batch\u003d150\u0026web_modern_ads\u003dtrue\u0026web_modern_buttons\u003dtrue\u0026web_modern_buttons_bl_survey\u003dtrue\u0026web_modern_subscribe\u003dtrue\u0026web_modern_subscribe_style\u003dfilled\u0026web_new_autonav_countdown\u003dtrue\u0026web_one_platform_error_handling\u003dtrue\u0026web_op_signal_type_banlist\u003d[]\u0026web_playback_associated_log_ctt\u003dtrue\u0026web_playback_associated_ve\u003dtrue\u0026web_player_api_logging_fraction\u003d0.01\u0026web_player_autonav_toggle_always_listen\u003dtrue\u0026web_player_autonav_use_server_provided_state\u003dtrue\u0026web_player_caption_language_preference_stickiness_duration\u003d0\u0026web_player_decouple_autonav\u003dtrue\u0026web_player_enable_early_warning_snackbar\u003dtrue\u0026web_player_enable_premium_hbr_in_h5_api\u003dtrue\u0026web_player_enable_premium_hbr_playback_cap\u003dtrue\u0026web_player_fine_scrubbing\u003dtrue\u0026web_player_gvi_wexit_adunit\u003dtrue\u0026web_player_gvi_wexit_all_player_styles\u003dtrue\u0026web_player_gvi_wexit_living_room_bedrock\u003dtrue\u0026web_player_gvi_wexit_living_room_kids\u003dtrue\u0026web_player_gvi_wexit_living_room_other\u003dtrue\u0026web_player_gvi_wexit_living_room_pangea\u003dtrue\u0026web_player_gvi_wexit_living_room_simply\u003dtrue\u0026web_player_gvi_wexit_living_room_unplugged\u003dtrue\u0026web_player_innertube_playlist_update\u003dtrue\u0026web_player_ipp_canary_type_for_logging\u003d\u0026web_player_live_monitor_env\u003dtrue\u0026web_player_move_autonav_toggle\u003dtrue\u0026web_player_music_visualizer_treatment\u003dfake\u0026web_player_mutable_event_label\u003dtrue\u0026web_player_nitrate_promo_tooltip\u003dtrue\u0026web_player_no_force_gvi\u003dtrue\u0026web_player_response_playback_tracking_parsing\u003dtrue\u0026web_player_seek_chapters_by_shortcut\u003dtrue\u0026web_player_sentinel_is_uniplayer\u003dtrue\u0026web_player_should_honor_include_asr_setting\u003dtrue\u0026web_player_show_music_in_this_video_graphic\u003dvideo_thumbnail\u0026web_player_small_hbp_settings_menu\u003dtrue\u0026web_player_ss_dai_ad_fetching_timeout_ms\u003d15000\u0026web_player_ss_media_time_offset\u003dtrue\u0026web_player_ss_timeout_skip_ads\u003dtrue\u0026web_player_ssdai_all_acpns_aids_logging_killswitch\u003dtrue\u0026web_player_touch_mode_improvements\u003dtrue\u0026web_player_transfer_timeout_threshold_ms\u003d10800000\u0026web_player_unset_default_csn_killswitch\u003dtrue\u0026web_player_use_cinematic_label_2\u003dtrue\u0026web_player_use_new_api_for_quality_pullback\u003dtrue\u0026web_player_vss_pageid_header\u003dtrue\u0026web_player_watch_next_response\u003dtrue\u0026web_player_watch_next_response_parsing\u003dtrue\u0026web_prefetch_preload_video\u003dtrue\u0026web_repeating_chapters\u003dtrue\u0026web_rounded_containers\u003dtrue\u0026web_rounded_thumbnails\u003dtrue\u0026web_settings_menu_icons\u003dtrue\u0026web_smoothness_test_duration_ms\u003d0\u0026web_smoothness_test_method\u003d0\u0026web_yt_config_context\u003dtrue\u0026woffle_clean_up_after_entity_migration\u003dtrue\u0026woffle_orchestration\u003dtrue\u0026ytidb_clear_embedded_player\u003dtrue\u0026ytidb_fetch_datasync_ids_for_data_cleanup\u003dtrue\u0026ytidb_remake_db_retries\u003d3\u0026ytidb_reopen_db_retries\u003d3\u0026ytidb_transaction_ended_event_rate_limit\u003d0.02\u0026ytidb_transaction_ended_event_rate_limit_session\u003d0.2\u0026ytidb_transaction_ended_event_rate_limit_transaction\u003d0.1","disableFullscreen":true,"cspNonce":"nopnosk9VoEiau3Xtg_3uQ","canaryState":"none","authorizedUserIndex":0,"datasyncId":"106384449314396247844||"},"WEB_PLAYER_CONTEXT_CONFIG_ID_KEVLAR_INLINE_PREVIEW":{"rootElementId":"inline-preview-player","jsUrl":"/s/player/97ea7458/player_ias.vflset/en_US/base.js","cssUrl":"/s/player/97ea7458/www-player.css","contextId":"WEB_PLAYER_CONTEXT_CONFIG_ID_KEVLAR_INLINE_PREVIEW","eventLabel":"detailpage","contentRegion":"CA","hl":"en_US","hostLanguage":"en","playerStyle":"desktop-polymer","innertubeApiKey":"AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8","innertubeApiVersion":"v1","innertubeContextClientVersion":"2.20230201.01.00","disableKeyboardControls":true,"device":{"brand":"apple","model":"","browser":"Chrome","browserVersion":"109.0.0.0","os":"Macintosh","osVersion":"10_15_7","platform":"DESKTOP","interfaceName":"WEB","interfaceVersion":"2.20230201.01.00","deviceYear":2013},"serializedExperimentIds":"23983296,23986016,24004644,24007246,24080738,24135310,24169501,24219381,24255163,24282011,24396645,24415864,24416291,24416441,24433679,24437577,24439361,24441240,24449113,24449639,24450366,24451032,24454357,24454498,24457577,24457884,24460376,24463912,24469897","serializedExperimentFlags":"H5_async_logging_delay_ms\u003d30000.0\u0026H5_enable_full_pacf_logging\u003dtrue\u0026H5_use_async_logging\u003dtrue\u0026ad_pod_disable_companion_persist_ads_quality\u003dtrue\u0026addto_ajax_log_warning_fraction\u003d0.1\u0026align_ad_to_video_player_lifecycle_for_bulleit\u003dtrue\u0026allow_live_autoplay\u003dtrue\u0026allow_poltergust_autoplay\u003dtrue\u0026allow_skip_networkless\u003dtrue\u0026autoplay_time\u003d8000\u0026autoplay_time_for_fullscreen\u003d3000\u0026autoplay_time_for_music_content\u003d3000\u0026background_thread_flush_logs_due_to_batch_limit\u003dtrue\u0026bg_vm_reinit_threshold\u003d7200000\u0026blocked_packages_for_sps\u003d[]\u0026botguard_async_snapshot_timeout_ms\u003d3000\u0026check_ad_ui_status_for_mweb_safari\u003dtrue\u0026check_navigator_accuracy_timeout_ms\u003d0\u0026clear_user_partitioned_ls\u003dtrue\u0026client_respect_autoplay_switch_button_renderer\u003dtrue\u0026csi_on_gel\u003dtrue\u0026dash_manifest_version\u003d5\u0026debug_bandaid_hostname\u003d\u0026debug_sherlog_username\u003d\u0026delay_ads_gvi_call_on_bulleit_living_room_ms\u003d0\u0026deprecate_csi_has_info\u003dtrue\u0026deprecate_pair_servlet_enabled\u003dtrue\u0026deprecate_two_way_binding_child\u003dtrue\u0026deprecate_two_way_binding_parent\u003dtrue\u0026desktop_image_cta_no_background\u003dtrue\u0026desktop_log_img_click_location\u003dtrue\u0026desktop_player_button_tooltip_with_shortcut\u003dtrue\u0026desktop_sparkles_light_cta_button\u003dtrue\u0026disable_channel_id_check_for_suspended_channels\u003dtrue\u0026disable_child_node_auto_formatted_strings\u003dtrue\u0026disable_defer_admodule_on_advertiser_video\u003dtrue\u0026disable_features_for_supex\u003dtrue\u0026disable_legacy_desktop_remote_queue\u003dtrue\u0026disable_mdx_connection_in_mdx_module_for_music_web\u003dtrue\u0026disable_new_pause_state3\u003dtrue\u0026disable_pacf_logging_for_memory_limited_tv\u003dtrue\u0026disable_rounding_ad_notify\u003dtrue\u0026disable_simple_mixed_direction_formatted_strings\u003dtrue\u0026disable_ssdai_on_errors\u003dtrue\u0026disable_tabbing_before_flyout_ad_elements_appear\u003dtrue\u0026disable_thumbnail_preloading\u003dtrue\u0026embeds_enable_allow_watch_again_endscreen_for_eligible_shorts\u003dtrue\u0026embeds_enable_embed_module\u003dtrue\u0026embeds_enable_shorts_branded_ui\u003dtrue\u0026embeds_enable_shorts_links_for_eligible_shorts\u003dtrue\u0026embeds_web_enable_gws_wh_rel_off\u003dtrue\u0026embeds_web_enable_info_panel_preview\u003dtrue\u0026embeds_web_enable_load_player_from_page_show\u003dtrue\u0026embeds_web_enable_logging_event_handlers\u003dtrue\u0026embeds_web_enable_pem_domain_fix_for_ad_requests\u003dtrue\u0026embeds_web_enable_replace_unload_w_pagehide\u003dtrue\u0026embeds_web_enable_ve_conversion_logging_tracking_no_allow_list\u003dtrue\u0026embeds_web_enable_video_data_refactoring_break_down_and_move_methods\u003dtrue\u0026embeds_web_enable_video_data_refactoring_like_button_renderer\u003dtrue\u0026embeds_web_hide_unfilled_more_videos_suggestions\u003dtrue\u0026embeds_web_lite_mode\u003d1\u0026embeds_web_nwl_disable_nocookie\u003dtrue\u0026embeds_web_synth_ch_headers_banned_urls_regex\u003d\u0026enable_ad_cpn_macro_substitution_for_click_pings\u003dtrue\u0026enable_cast_for_web_unplugged\u003dtrue\u0026enable_cast_on_music_web\u003dtrue\u0026enable_client_page_id_header_for_first_party_pings\u003dtrue\u0026enable_client_sli_logging\u003dtrue\u0026enable_discrete_live_precise_embargos\u003dtrue\u0026enable_error_corrections_infocard\u003dtrue\u0026enable_error_corrections_infocard_web_client\u003dtrue\u0026enable_error_corrections_infocard_web_client_check\u003dtrue\u0026enable_error_corrections_infocards_icon_web\u003dtrue\u0026enable_eviction_protection_for_bulleit\u003dtrue\u0026enable_gel_log_commands\u003dtrue\u0026enable_handles_account_menu_switcher\u003dtrue\u0026enable_inline_preview_controls\u003dtrue\u0026enable_live_premiere_web_player_indicator\u003dtrue\u0026enable_lr_home_infeed_ads_inline_playback_progress_pings\u003dtrue\u0026enable_macro_substitution_on_html5\u003dtrue\u0026enable_mixed_direction_formatted_strings\u003dtrue\u0026enable_mweb_livestream_ui_update\u003dtrue\u0026enable_new_paid_product_placement\u003dtrue\u0026enable_post_ad_perception_survey_fix_on_tvhtml5\u003dtrue\u0026enable_post_ad_perception_survey_in_tvhtml5\u003dtrue\u0026enable_precise_embargos\u003dtrue\u0026enable_server_stitched_dai\u003dtrue\u0026enable_shorts_player\u003dtrue\u0026enable_skip_ad_guidance_prompt\u003dtrue\u0026enable_skippable_ads_for_unplugged_ad_pod\u003dtrue\u0026enable_smearing_expansion_dai\u003dtrue\u0026enable_tectonic_ad_ux_for_halftime\u003dtrue\u0026enable_third_party_info\u003dtrue\u0026enable_topsoil_wta_for_halftime_live_infra\u003dtrue\u0026enable_web_media_session_metadata_fix\u003dtrue\u0026error_message_for_gsuite_network_restrictions\u003dtrue\u0026export_networkless_options\u003dtrue\u0026external_fullscreen_with_edu\u003dtrue\u0026fast_autonav_in_background\u003dtrue\u0026fetch_att_independently\u003dtrue\u0026fill_single_video_with_notify_to_lasr\u003dtrue\u0026filter_vp9_for_csdai\u003dtrue\u0026fix_ads_tracking_for_swf_config_deprecation_mweb\u003dtrue\u0026gcf_config_store_enabled\u003dtrue\u0026gpa_sparkles_ten_percent_layer\u003dtrue\u0026gvi_channel_client_screen\u003dtrue\u0026h5_companion_enable_adcpn_macro_substitution_for_click_pings\u003dtrue\u0026h5_inplayer_enable_adcpn_macro_substitution_for_click_pings\u003dtrue\u0026hfr_dropped_framerate_fallback_threshold\u003d0\u0026hide_endpoint_overflow_on_ytd_display_ad_renderer\u003dtrue\u0026hls_use_new_codecs_string_api\u003dtrue\u0026html5_ad_timeout_ms\u003d0\u0026html5_ads_preroll_lock_timeout_delay_ms\u003d15000\u0026html5_allow_discontiguous_slices\u003dtrue\u0026html5_allow_video_keyframe_without_audio\u003dtrue\u0026html5_append_init_while_paused\u003dtrue\u0026html5_apply_ustreamer_cap_per_video_id\u003dtrue\u0026html5_att_oauth\u003dtrue\u0026html5_attach_num_random_bytes_to_bandaid\u003d0\u0026html5_attach_po_token_to_bandaid\u003dtrue\u0026html5_autonav_cap_idle_secs\u003d0\u0026html5_autonav_quality_cap\u003d720\u0026html5_autoplay_default_quality_cap\u003d0\u0026html5_block_pip_safari_delay\u003d0\u0026html5_bmff_new_fourcc_check\u003dtrue\u0026html5_cap_quality_for_tv_hfr\u003dtrue\u0026html5_change_player_mode_order_for_logging\u003dtrue\u0026html5_clamp_cuepoints_to_min\u003dtrue\u0026html5_cobalt_max_size_for_immed_job\u003d0\u0026html5_cobalt_min_processor_cnt_to_offload_algo\u003d0\u0026html5_cobalt_override_quic\u003d0\u0026html5_consume_media_bytes_slice_infos\u003dtrue\u0026html5_control_flow_include_trigger_logging_in_tmp_logs\u003dtrue\u0026html5_create_manifest_from_protos\u003dtrue\u0026html5_de_dupe_content_video_loads_in_lifecycle_api\u003dtrue\u0026html5_deadzone_multiplier\u003d1.0\u0026html5_debug_data_log_probability\u003d0.1\u0026html5_decode_to_texture_cap\u003dtrue\u0026html5_decoder_freeze_timeout_delay_ms\u003d0\u0026html5_default_ad_gain\u003d0.5\u0026html5_default_quality_cap\u003d0\u0026html5_defer_ad_module_ms\u003d0\u0026html5_defer_fetch_att_ms\u003d1000\u0026html5_defer_modules_delay_time_millis\u003d0\u0026html5_delay_initial_loading\u003dtrue\u0026html5_delay_retries_for_host_timeout\u003dtrue\u0026html5_delayed_retry_count\u003d1\u0026html5_delayed_retry_delay_ms\u003d5000\u0026html5_deprecate_video_tag_pool\u003dtrue\u0026html5_desktop_vr180_allow_panning\u003dtrue\u0026html5_desync_cue_range_threshold\u003d0\u0026html5_df_downgrade_thresh\u003d0.2\u0026html5_disable_connection_issue_event\u003dtrue\u0026html5_disable_csi_for_bulleit\u003dtrue\u0026html5_disable_move_pssh_to_moov\u003dtrue\u0026html5_disable_non_contiguous\u003dtrue\u0026html5_displayed_frame_rate_downgrade_threshold\u003d45\u0026html5_drm_check_all_key_error_states\u003dtrue\u0026html5_drm_cpi_license_key\u003dtrue\u0026html5_early_read_chunk\u003dtrue\u0026html5_enable_ac3\u003dtrue\u0026html5_enable_ads_client_monitoring_log_tv\u003dtrue\u0026html5_enable_atv_offline\u003dtrue\u0026html5_enable_client_hints_override\u003dtrue\u0026html5_enable_eac3\u003dtrue\u0026html5_enable_embedded_player_visibility_signals\u003dtrue\u0026html5_enable_non_notify_composite_vod_lsar_pacf\u003dtrue\u0026html5_enable_single_video_vod_ivar_on_pacf\u003dtrue\u0026html5_enable_tvos_dash\u003dtrue\u0026html5_enable_tvos_encrypted_vp9\u003dtrue\u0026html5_enable_widevine_for_alc\u003dtrue\u0026html5_enable_widevine_for_fast_linear\u003dtrue\u0026html5_encourage_array_coalescing\u003dtrue\u0026html5_exile_on_drm_fatal\u003dtrue\u0026html5_fill_isTypeSupported_capability_cache_earlier\u003dtrue\u0026html5_fludd_suspend\u003dtrue\u0026html5_flush_segment_index_on_error\u003dtrue\u0026html5_flush_vss_with_rti_and_rtn\u003dtrue\u0026html5_gapless_ended_transition_buffer_ms\u003d200\u0026html5_gapless_preloading\u003dtrue\u0026html5_generate_session_po_token\u003dtrue\u0026html5_gl_fps_threshold\u003d0\u0026html5_halt_ssdai_fetch_on_predict_start\u003dtrue\u0026html5_hdcp_probing_stream_url\u003d\u0026html5_heartbeat_set_ended\u003dtrue\u0026html5_hfr_quality_cap\u003d0\u0026html5_high_res_logging_percent\u003d0.01\u0026html5_idle_rate_limit_ms\u003d0\u0026html5_ignore_media_element_event_loadeddata\u003dtrue\u0026html5_innertube_heartbeats_for_fairplay\u003dtrue\u0026html5_innertube_heartbeats_for_playready\u003dtrue\u0026html5_innertube_heartbeats_for_widevine\u003dtrue\u0026html5_ios4_seek_above_zero\u003dtrue\u0026html5_ios7_force_play_on_stall\u003dtrue\u0026html5_ios_force_seek_to_zero_on_stop\u003dtrue\u0026html5_jumbo_mobile_subsegment_readahead_target\u003d3.0\u0026html5_jumbo_ull_nonstreaming_mffa_ms\u003d4000\u0026html5_jumbo_ull_subsegment_readahead_target\u003d1.3\u0026html5_license_constraint_delay\u003d5000\u0026html5_live_abr_head_miss_fraction\u003d0.0\u0026html5_live_abr_repredict_fraction\u003d0.0\u0026html5_live_byterate_factor_for_readahead\u003d1.3\u0026html5_live_low_latency_bandwidth_window\u003d0.0\u0026html5_live_normal_latency_bandwidth_window\u003d0.0\u0026html5_live_partial_response_resumable\u003dtrue\u0026html5_live_quality_cap\u003d0\u0026html5_live_ultra_low_latency_bandwidth_window\u003d0.0\u0026html5_log_audio_abr\u003dtrue\u0026html5_log_experiment_id_from_player_response_to_ctmp\u003d\u0026html5_log_first_ssdai_requests_killswitch\u003dtrue\u0026html5_log_offline_playback_started_event\u003dtrue\u0026html5_log_readahead_on_playback_start\u003dtrue\u0026html5_log_rebuffer_events\u003d5\u0026html5_log_server_url_param\u003dtrue\u0026html5_log_trigger_events_with_debug_data\u003dtrue\u0026html5_long_rebuffer_jiggle_cmt_delay_ms\u003d0\u0026html5_long_rebuffer_new_elem_shorts_delay_ms\u003d0\u0026html5_long_rebuffer_threshold_ms\u003d30000\u0026html5_manifestless_seg_drift_limit_secs\u003d0\u0026html5_manifestless_unplugged\u003dtrue\u0026html5_manifestless_vp9_otf\u003dtrue\u0026html5_max_drift_per_track_secs\u003d0.0\u0026html5_max_headm_for_streaming_xhr\u003d0\u0026html5_max_live_dvr_window_plus_margin_secs\u003d46800.0\u0026html5_max_readbehind_secs\u003d0\u0026html5_max_redirect_response_length\u003d8192\u0026html5_max_selectable_quality_ordinal\u003d0\u0026html5_maximum_readahead_seconds\u003d0.0\u0026html5_media_fullscreen\u003dtrue\u0026html5_mfl_extend_max_request_time\u003dtrue\u0026html5_min_readbehind_cap_secs\u003d60\u0026html5_min_readbehind_secs\u003d0\u0026html5_min_selectable_quality_ordinal\u003d0\u0026html5_min_startup_buffered_ad_media_duration_secs\u003d1.2\u0026html5_min_startup_buffered_media_duration_secs\u003d1.2\u0026html5_minimum_readahead_seconds\u003d0.0\u0026html5_new_min_startup_smooth_logic\u003dtrue\u0026html5_no_placeholder_rollbacks\u003dtrue\u0026html5_non_network_rebuffer_duration_ms\u003d0\u0026html5_non_onesie_attach_po_token\u003dtrue\u0026html5_not_register_disposables_when_core_listens\u003dtrue\u0026html5_offline_failure_retry_limit\u003d2\u0026html5_onesie_cast\u003dtrue\u0026html5_onesie_defer_content_loader_ms\u003d0\u0026html5_onesie_disable_js_cleartext_compression\u003dtrue\u0026html5_onesie_enable_server_side_badwidth_estimation\u003dtrue\u0026html5_onesie_host_racing_cap_ms\u003d0\u0026html5_onesie_ignore_innertube_api_key\u003dtrue\u0026html5_onesie_live_ttl_secs\u003d8\u0026html5_onesie_media_bytes\u003dtrue\u0026html5_onesie_nonzero_playback_start\u003dtrue\u0026html5_onesie_notify_cuepoint_manager_on_completion\u003dtrue\u0026html5_onesie_prefer_trusted_host\u003dtrue\u0026html5_onesie_prewarm_cooldown_ms\u003d0\u0026html5_onesie_prewarm_interval_ms\u003d0\u0026html5_onesie_prewarm_max_lact_ms\u003d0\u0026html5_onesie_redirector_timeout_ms\u003d0\u0026html5_onesie_request_timeout_ms\u003d1000\u0026html5_onesie_sticky_server_side\u003dtrue\u0026html5_pause_on_nonforeground_platform_errors\u003dtrue\u0026html5_peak_shave\u003dtrue\u0026html5_per_format_loudness_fix\u003dtrue\u0026html5_perf_cap_override_sticky\u003dtrue\u0026html5_performance_cap_floor\u003d360\u0026html5_performance_impact_profiling_timer_ms\u003d0\u0026html5_perserve_av1_perf_cap\u003dtrue\u0026html5_photos_use_vp9_otf\u003dtrue\u0026html5_platform_minimum_readahead_seconds\u003d0.0\u0026html5_platform_whitelisted_for_frame_accurate_seeks\u003dtrue\u0026html5_player_autonav_logging\u003dtrue\u0026html5_player_dynamic_bottom_gradient\u003dtrue\u0026html5_player_min_build_cl\u003d-1\u0026html5_player_preload_ad_fix\u003dtrue\u0026html5_post_interrupt_readahead\u003d20\u0026html5_prefer_server_bwe3\u003dtrue\u0026html5_preload_wait_time_secs\u003d0.0\u0026html5_probe_primary_delay_base_ms\u003d0\u0026html5_process_all_encrypted_events\u003dtrue\u0026html5_query_sw_secure_crypto_for_android\u003dtrue\u0026html5_random_playback_cap\u003d0\u0026html5_readahead_ratelimit\u003d3000\u0026html5_recognize_predict_start_cue_point\u003dtrue\u0026html5_reduce_istypesupported_calls\u003dtrue\u0026html5_remove_command_triggered_companions\u003dtrue\u0026html5_remove_not_servable_check_killswitch\u003dtrue\u0026html5_rename_apbs\u003dtrue\u0026html5_report_fatal_drm_restricted_error_killswitch\u003dtrue\u0026html5_report_slow_ads_as_error\u003dtrue\u0026html5_request_only_hdr_or_sdr_keys\u003dtrue\u0026html5_request_sizing_multiplier\u003d0.8\u0026html5_require_hdr_capability\u003dtrue\u0026html5_reset_media_stream_on_unresumable_slices\u003dtrue\u0026html5_resource_bad_status_delay_scaling\u003d1.5\u0026html5_restrict_streaming_xhr_on_sqless_requests\u003dtrue\u0026html5_safari_desktop_eme_min_version\u003d0\u0026html5_seek_jiggle_cmt_delay_ms\u003d8000\u0026html5_seek_new_elem_delay_ms\u003d12000\u0026html5_seek_new_elem_shorts_delay_ms\u003d0\u0026html5_seek_over_discontinuities_delay_ms\u003d0\u0026html5_seek_set_cmt_delay_ms\u003d2000\u0026html5_seek_timeout_delay_ms\u003d20000\u0026html5_selectable_formats_early_exit\u003dtrue\u0026html5_server_stitched_dai_decorated_url_retry_limit\u003d5\u0026html5_server_stitched_dai_group\u003dtrue\u0026html5_session_po_token_interval_time_ms\u003d900000\u0026html5_set_ended_in_pfx_live\u003dtrue\u0026html5_simplify_streaming_xhr\u003dtrue\u0026html5_skip_oob_start_seconds\u003dtrue\u0026html5_skip_slow_ad_delay_ms\u003d15000\u0026html5_skip_sub_quantum_discontinuity_secs\u003d0.0\u0026html5_slow_start_no_media_source_delay_ms\u003d0\u0026html5_slow_start_timeout_delay_ms\u003d20000\u0026html5_ssdai_adfetch_dynamic_timeout_ms\u003d0\u0026html5_ssdai_enable_new_seek_logic\u003dtrue\u0026html5_ssdai_flush_vss\u003dtrue\u0026html5_ssdai_vss_player_state_change\u003dtrue\u0026html5_start_seconds_reorder\u003dtrue\u0026html5_stateful_audio_min_adjustment_value\u003d0\u0026html5_static_abr_resolution_shelf\u003d0\u0026html5_store_xhr_headers_readable\u003dtrue\u0026html5_stream_metadata\u003dtrue\u0026html5_streaming_init_requests_sizes\u003d0\u0026html5_streaming_xhr_check_for_null_response\u003dtrue\u0026html5_subsegment_readahead_load_speed_check_interval\u003d0.5\u0026html5_subsegment_readahead_min_buffer_health_secs\u003d0.25\u0026html5_subsegment_readahead_min_buffer_health_secs_on_timeout\u003d0.1\u0026html5_subsegment_readahead_min_load_speed\u003d1.5\u0026html5_subsegment_readahead_seek_latency_fudge\u003d0.5\u0026html5_subsegment_readahead_target_buffer_health_secs\u003d0.5\u0026html5_subsegment_readahead_timeout_secs\u003d2.0\u0026html5_suspend_loader\u003dtrue\u0026html5_track_termination_during_request\u003dtrue\u0026html5_ugc_live_audio_51\u003dtrue\u0026html5_ugc_vod_audio_51\u003dtrue\u0026html5_ultra_high_res_logging_percent\u003d0.0\u0026html5_unreported_seek_reseek_delay_ms\u003d0\u0026html5_unrestricted_layer_high_res_logging_percent\u003d0.0\u0026html5_update_constraint\u003dtrue\u0026html5_use_post_for_media\u003dtrue\u0026html5_varispeed_playback_rate\u003dtrue\u0026html5_video_tbd_min_kb\u003d0\u0026html5_viewport_undersend_maximum\u003d0.0\u0026html5_watchdog_for_zero_seek\u003dtrue\u0026html5_web_enable_halftime_preroll\u003dtrue\u0026html5_webpo_idle_priority_job\u003dtrue\u0026html5_woffle_resume\u003dtrue\u0026html5_workaround_delay_trigger\u003dtrue\u0026html5_xhr_clean_up_multi_slice_facade\u003dtrue\u0026html5_ytvlr_enable_single_select_survey\u003dtrue\u0026il_use_view_model_logging_context\u003dtrue\u0026initial_gel_batch_timeout\u003d2000\u0026injected_license_handler_error_code\u003d0\u0026injected_license_handler_license_status\u003d0\u0026json_condensed_response\u003dtrue\u0026kevlar_command_handler_command_banlist\u003d[]\u0026kevlar_dropdown_fix\u003dtrue\u0026kevlar_gel_error_routing\u003dtrue\u0026kevlar_miniplayer\u003dtrue\u0026kevlar_miniplayer_expand_top\u003dtrue\u0026kevlar_miniplayer_play_pause_on_scrim\u003dtrue\u0026kevlar_playback_associated_queue\u003dtrue\u0026kevlar_queue_use_update_api\u003dtrue\u0026kevlar_smart_downloads\u003dtrue\u0026kevlar_smart_downloads_setting\u003dtrue\u0026kevlar_vimio_use_shared_monitor\u003dtrue\u0026kevlar_woffle\u003dtrue\u0026live_chunk_readahead\u003d3\u0026live_fresca_v2\u003dtrue\u0026log_errors_through_nwl_on_retry\u003dtrue\u0026log_heartbeat_with_lifecycles\u003dtrue\u0026log_web_endpoint_to_layer\u003dtrue\u0026log_window_onerror_fraction\u003d0.1\u0026manifestless_post_live\u003dtrue\u0026manifestless_post_live_ufph\u003dtrue\u0026max_prefetch_window_sec_for_livestream_optimization\u003d10\u0026max_resolution_for_white_noise\u003d360\u0026mdx_enable_privacy_disclosure_ui\u003dtrue\u0026mdx_load_cast_api_bootstrap_script\u003dtrue\u0026migrate_events_to_ts\u003dtrue\u0026min_prefetch_offset_sec_for_livestream_optimization\u003d20\u0026music_enable_shared_audio_tier_logic\u003dtrue\u0026mweb_c3_endscreen\u003dtrue\u0026mweb_enable_custom_control_shared\u003dtrue\u0026mweb_enable_skippables_on_jio_phone\u003dtrue\u0026mweb_muted_autoplay_animation\u003dshrink\u0026mweb_native_control_in_faux_fullscreen_shared\u003dtrue\u0026network_polling_interval\u003d30000\u0026networkless_gel\u003dtrue\u0026networkless_logging\u003dtrue\u0026new_codecs_string_api_uses_legacy_style\u003dtrue\u0026nwl_send_fast_on_unload\u003dtrue\u0026nwl_send_from_memory_when_online\u003dtrue\u0026offline_error_handling\u003dtrue\u0026pageid_as_header_web\u003dtrue\u0026parse_query_data_from_url\u003dtrue\u0026player_ads_set_adformat_on_client\u003dtrue\u0026player_allow_autonav_after_playlist\u003dtrue\u0026player_bootstrap_method\u003dtrue\u0026player_defer_caption_display\u003d1000\u0026player_destroy_old_version\u003dtrue\u0026player_doubletap_to_seek\u003dtrue\u0026player_enable_playback_playlist_change\u003dtrue\u0026player_endscreen_ellipsis_fix\u003dtrue\u0026player_underlay_min_player_width\u003d768.0\u0026player_underlay_video_width_fraction\u003d0.6\u0026player_web_canary_stage\u003d0\u0026playready_first_play_expiration\u003d-1\u0026polymer_bad_build_labels\u003dtrue\u0026polymer_log_prop_change_observer_percent\u003d0\u0026polymer_verifiy_app_state\u003dtrue\u0026preskip_button_style_ads_backend\u003dcountdown_next_to_thumbnail\u0026qoe_nwl_downloads\u003dtrue\u0026qoe_send_and_write\u003dtrue\u0026record_app_crashed_web\u003dtrue\u0026replace_playability_retriever_in_watch\u003dtrue\u0026scheduler_use_raf_by_default\u003dtrue\u0026self_podding_header_string_template\u003dself_podding_interstitial_message\u0026self_podding_highlight_non_default_button\u003dtrue\u0026self_podding_midroll_choice_string_template\u003dself_podding_midroll_choice\u0026send_config_hash_timer\u003d0\u0026set_interstitial_advertisers_question_text\u003dtrue\u0026short_start_time_prefer_publish_in_watch_log\u003dtrue\u0026should_clear_video_data_on_player_cued_unstarted\u003dtrue\u0026skip_inline_muted_license_service_check\u003dtrue\u0026skip_invalid_ytcsi_ticks\u003dtrue\u0026skip_ls_gel_retry\u003dtrue\u0026skip_setting_info_in_csi_data_object\u003dtrue\u0026start_client_gcf\u003dtrue\u0026start_client_gcf_for_player\u003dtrue\u0026streaming_data_emergency_itag_blacklist\u003d[]\u0026suppress_error_204_logging\u003dtrue\u0026transport_use_scheduler\u003dtrue\u0026tv_pacf_logging_sample_rate\u003d0.01\u0026tvhtml5_unplugged_preload_cache_size\u003d5\u0026uncover_ad_badge_on_RTL_tiny_window\u003dtrue\u0026unplugged_dai_live_chunk_readahead\u003d3\u0026unplugged_tvhtml5_video_preload_on_focus_delay_ms\u003d0\u0026use_inlined_player_rpc\u003dtrue\u0026use_new_in_memory_storage\u003dtrue\u0026use_new_nwl_initialization\u003dtrue\u0026use_new_nwl_saw\u003dtrue\u0026use_new_nwl_stw\u003dtrue\u0026use_new_nwl_wts\u003dtrue\u0026use_player_abuse_bg_library\u003dtrue\u0026use_profilepage_event_label_in_carousel_playbacks\u003dtrue\u0026use_request_time_ms_header\u003dtrue\u0026use_session_based_sampling\u003dtrue\u0026use_shared_nsm\u003dtrue\u0026use_shared_nsm_and_keep_yt_online_updated\u003dtrue\u0026use_ts_visibilitylogger\u003dtrue\u0026variable_buffer_timeout_ms\u003d0\u0026verify_ads_itag_early\u003dtrue\u0026vp9_drm_live\u003dtrue\u0026vss_final_ping_send_and_write\u003dtrue\u0026vss_pings_using_networkless\u003dtrue\u0026vss_playback_use_send_and_write\u003dtrue\u0026web_api_url\u003dtrue\u0026web_cinematic_watch_settings\u003dtrue\u0026web_client_version_override\u003d\u0026web_dedupe_ve_grafting\u003dtrue\u0026web_deprecate_service_ajax_map_dependency\u003dtrue\u0026web_enable_voz_audio_feedback\u003dtrue\u0026web_foreground_heartbeat_interval_ms\u003d28000\u0026web_forward_command_on_pbj\u003dtrue\u0026web_gel_debounce_ms\u003d10000\u0026web_gel_timeout_cap\u003dtrue\u0026web_key_moments_markers\u003dtrue\u0026web_log_memory_total_kbytes\u003dtrue\u0026web_logging_max_batch\u003d150\u0026web_modern_ads\u003dtrue\u0026web_modern_buttons\u003dtrue\u0026web_modern_buttons_bl_survey\u003dtrue\u0026web_modern_subscribe\u003dtrue\u0026web_modern_subscribe_style\u003dfilled\u0026web_new_autonav_countdown\u003dtrue\u0026web_one_platform_error_handling\u003dtrue\u0026web_op_signal_type_banlist\u003d[]\u0026web_playback_associated_log_ctt\u003dtrue\u0026web_playback_associated_ve\u003dtrue\u0026web_player_api_logging_fraction\u003d0.01\u0026web_player_autonav_toggle_always_listen\u003dtrue\u0026web_player_autonav_use_server_provided_state\u003dtrue\u0026web_player_caption_language_preference_stickiness_duration\u003d0\u0026web_player_decouple_autonav\u003dtrue\u0026web_player_enable_early_warning_snackbar\u003dtrue\u0026web_player_enable_premium_hbr_in_h5_api\u003dtrue\u0026web_player_enable_premium_hbr_playback_cap\u003dtrue\u0026web_player_fine_scrubbing\u003dtrue\u0026web_player_gvi_wexit_adunit\u003dtrue\u0026web_player_gvi_wexit_all_player_styles\u003dtrue\u0026web_player_gvi_wexit_living_room_bedrock\u003dtrue\u0026web_player_gvi_wexit_living_room_kids\u003dtrue\u0026web_player_gvi_wexit_living_room_other\u003dtrue\u0026web_player_gvi_wexit_living_room_pangea\u003dtrue\u0026web_player_gvi_wexit_living_room_simply\u003dtrue\u0026web_player_gvi_wexit_living_room_unplugged\u003dtrue\u0026web_player_innertube_playlist_update\u003dtrue\u0026web_player_ipp_canary_type_for_logging\u003d\u0026web_player_live_monitor_env\u003dtrue\u0026web_player_move_autonav_toggle\u003dtrue\u0026web_player_music_visualizer_treatment\u003dfake\u0026web_player_mutable_event_label\u003dtrue\u0026web_player_nitrate_promo_tooltip\u003dtrue\u0026web_player_no_force_gvi\u003dtrue\u0026web_player_response_playback_tracking_parsing\u003dtrue\u0026web_player_seek_chapters_by_shortcut\u003dtrue\u0026web_player_sentinel_is_uniplayer\u003dtrue\u0026web_player_should_honor_include_asr_setting\u003dtrue\u0026web_player_show_music_in_this_video_graphic\u003dvideo_thumbnail\u0026web_player_small_hbp_settings_menu\u003dtrue\u0026web_player_ss_dai_ad_fetching_timeout_ms\u003d15000\u0026web_player_ss_media_time_offset\u003dtrue\u0026web_player_ss_timeout_skip_ads\u003dtrue\u0026web_player_ssdai_all_acpns_aids_logging_killswitch\u003dtrue\u0026web_player_touch_mode_improvements\u003dtrue\u0026web_player_transfer_timeout_threshold_ms\u003d10800000\u0026web_player_unset_default_csn_killswitch\u003dtrue\u0026web_player_use_cinematic_label_2\u003dtrue\u0026web_player_use_new_api_for_quality_pullback\u003dtrue\u0026web_player_vss_pageid_header\u003dtrue\u0026web_player_watch_next_response\u003dtrue\u0026web_player_watch_next_response_parsing\u003dtrue\u0026web_prefetch_preload_video\u003dtrue\u0026web_repeating_chapters\u003dtrue\u0026web_rounded_containers\u003dtrue\u0026web_rounded_thumbnails\u003dtrue\u0026web_settings_menu_icons\u003dtrue\u0026web_smoothness_test_duration_ms\u003d0\u0026web_smoothness_test_method\u003d0\u0026web_yt_config_context\u003dtrue\u0026woffle_clean_up_after_entity_migration\u003dtrue\u0026woffle_orchestration\u003dtrue\u0026ytidb_clear_embedded_player\u003dtrue\u0026ytidb_fetch_datasync_ids_for_data_cleanup\u003dtrue\u0026ytidb_remake_db_retries\u003d3\u0026ytidb_reopen_db_retries\u003d3\u0026ytidb_transaction_ended_event_rate_limit\u003d0.02\u0026ytidb_transaction_ended_event_rate_limit_session\u003d0.2\u0026ytidb_transaction_ended_event_rate_limit_transaction\u003d0.1","disableFullscreen":true,"cspNonce":"nopnosk9VoEiau3Xtg_3uQ","canaryState":"none","enableCsiLogging":true,"csiPageType":"watch","authorizedUserIndex":0,"disableMdxCast":true,"datasyncId":"106384449314396247844||","showInlinePreviewUi":true},"WEB_PLAYER_CONTEXT_CONFIG_ID_HANDLES_CLAIMING":{"rootElementId":"ytd-handles-claiming-video-item-renderer","jsUrl":"/s/player/97ea7458/player_ias.vflset/en_US/base.js","cssUrl":"/s/player/97ea7458/www-player.css","contextId":"WEB_PLAYER_CONTEXT_CONFIG_ID_HANDLES_CLAIMING","eventLabel":"handlesclaiming","contentRegion":"CA","hl":"en_US","hostLanguage":"en","playerStyle":"desktop-polymer","innertubeApiKey":"AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8","innertubeApiVersion":"v1","innertubeContextClientVersion":"2.20230201.01.00","disableRelatedVideos":true,"device":{"brand":"apple","model":"","browser":"Chrome","browserVersion":"109.0.0.0","os":"Macintosh","osVersion":"10_15_7","platform":"DESKTOP","interfaceName":"WEB","interfaceVersion":"2.20230201.01.00","deviceYear":2013},"serializedExperimentIds":"23983296,23986016,24004644,24007246,24080738,24135310,24169501,24219381,24255163,24282011,24396645,24415864,24416291,24416441,24433679,24437577,24439361,24441240,24449113,24449639,24450366,24451032,24454357,24454498,24457577,24457884,24460376,24463912,24469897","serializedExperimentFlags":"H5_async_logging_delay_ms\u003d30000.0\u0026H5_enable_full_pacf_logging\u003dtrue\u0026H5_use_async_logging\u003dtrue\u0026ad_pod_disable_companion_persist_ads_quality\u003dtrue\u0026addto_ajax_log_warning_fraction\u003d0.1\u0026align_ad_to_video_player_lifecycle_for_bulleit\u003dtrue\u0026allow_live_autoplay\u003dtrue\u0026allow_poltergust_autoplay\u003dtrue\u0026allow_skip_networkless\u003dtrue\u0026autoplay_time\u003d8000\u0026autoplay_time_for_fullscreen\u003d3000\u0026autoplay_time_for_music_content\u003d3000\u0026background_thread_flush_logs_due_to_batch_limit\u003dtrue\u0026bg_vm_reinit_threshold\u003d7200000\u0026blocked_packages_for_sps\u003d[]\u0026botguard_async_snapshot_timeout_ms\u003d3000\u0026check_ad_ui_status_for_mweb_safari\u003dtrue\u0026check_navigator_accuracy_timeout_ms\u003d0\u0026clear_user_partitioned_ls\u003dtrue\u0026client_respect_autoplay_switch_button_renderer\u003dtrue\u0026csi_on_gel\u003dtrue\u0026dash_manifest_version\u003d5\u0026debug_bandaid_hostname\u003d\u0026debug_sherlog_username\u003d\u0026delay_ads_gvi_call_on_bulleit_living_room_ms\u003d0\u0026deprecate_csi_has_info\u003dtrue\u0026deprecate_pair_servlet_enabled\u003dtrue\u0026deprecate_two_way_binding_child\u003dtrue\u0026deprecate_two_way_binding_parent\u003dtrue\u0026desktop_image_cta_no_background\u003dtrue\u0026desktop_log_img_click_location\u003dtrue\u0026desktop_player_button_tooltip_with_shortcut\u003dtrue\u0026desktop_sparkles_light_cta_button\u003dtrue\u0026disable_channel_id_check_for_suspended_channels\u003dtrue\u0026disable_child_node_auto_formatted_strings\u003dtrue\u0026disable_defer_admodule_on_advertiser_video\u003dtrue\u0026disable_features_for_supex\u003dtrue\u0026disable_legacy_desktop_remote_queue\u003dtrue\u0026disable_mdx_connection_in_mdx_module_for_music_web\u003dtrue\u0026disable_new_pause_state3\u003dtrue\u0026disable_pacf_logging_for_memory_limited_tv\u003dtrue\u0026disable_rounding_ad_notify\u003dtrue\u0026disable_simple_mixed_direction_formatted_strings\u003dtrue\u0026disable_ssdai_on_errors\u003dtrue\u0026disable_tabbing_before_flyout_ad_elements_appear\u003dtrue\u0026disable_thumbnail_preloading\u003dtrue\u0026embeds_enable_allow_watch_again_endscreen_for_eligible_shorts\u003dtrue\u0026embeds_enable_embed_module\u003dtrue\u0026embeds_enable_shorts_branded_ui\u003dtrue\u0026embeds_enable_shorts_links_for_eligible_shorts\u003dtrue\u0026embeds_web_enable_gws_wh_rel_off\u003dtrue\u0026embeds_web_enable_info_panel_preview\u003dtrue\u0026embeds_web_enable_load_player_from_page_show\u003dtrue\u0026embeds_web_enable_logging_event_handlers\u003dtrue\u0026embeds_web_enable_pem_domain_fix_for_ad_requests\u003dtrue\u0026embeds_web_enable_replace_unload_w_pagehide\u003dtrue\u0026embeds_web_enable_ve_conversion_logging_tracking_no_allow_list\u003dtrue\u0026embeds_web_enable_video_data_refactoring_break_down_and_move_methods\u003dtrue\u0026embeds_web_enable_video_data_refactoring_like_button_renderer\u003dtrue\u0026embeds_web_hide_unfilled_more_videos_suggestions\u003dtrue\u0026embeds_web_lite_mode\u003d1\u0026embeds_web_nwl_disable_nocookie\u003dtrue\u0026embeds_web_synth_ch_headers_banned_urls_regex\u003d\u0026enable_ad_cpn_macro_substitution_for_click_pings\u003dtrue\u0026enable_cast_for_web_unplugged\u003dtrue\u0026enable_cast_on_music_web\u003dtrue\u0026enable_client_page_id_header_for_first_party_pings\u003dtrue\u0026enable_client_sli_logging\u003dtrue\u0026enable_discrete_live_precise_embargos\u003dtrue\u0026enable_error_corrections_infocard\u003dtrue\u0026enable_error_corrections_infocard_web_client\u003dtrue\u0026enable_error_corrections_infocard_web_client_check\u003dtrue\u0026enable_error_corrections_infocards_icon_web\u003dtrue\u0026enable_eviction_protection_for_bulleit\u003dtrue\u0026enable_gel_log_commands\u003dtrue\u0026enable_handles_account_menu_switcher\u003dtrue\u0026enable_inline_preview_controls\u003dtrue\u0026enable_live_premiere_web_player_indicator\u003dtrue\u0026enable_lr_home_infeed_ads_inline_playback_progress_pings\u003dtrue\u0026enable_macro_substitution_on_html5\u003dtrue\u0026enable_mixed_direction_formatted_strings\u003dtrue\u0026enable_mweb_livestream_ui_update\u003dtrue\u0026enable_new_paid_product_placement\u003dtrue\u0026enable_post_ad_perception_survey_fix_on_tvhtml5\u003dtrue\u0026enable_post_ad_perception_survey_in_tvhtml5\u003dtrue\u0026enable_precise_embargos\u003dtrue\u0026enable_server_stitched_dai\u003dtrue\u0026enable_shorts_player\u003dtrue\u0026enable_skip_ad_guidance_prompt\u003dtrue\u0026enable_skippable_ads_for_unplugged_ad_pod\u003dtrue\u0026enable_smearing_expansion_dai\u003dtrue\u0026enable_tectonic_ad_ux_for_halftime\u003dtrue\u0026enable_third_party_info\u003dtrue\u0026enable_topsoil_wta_for_halftime_live_infra\u003dtrue\u0026enable_web_media_session_metadata_fix\u003dtrue\u0026error_message_for_gsuite_network_restrictions\u003dtrue\u0026export_networkless_options\u003dtrue\u0026external_fullscreen_with_edu\u003dtrue\u0026fast_autonav_in_background\u003dtrue\u0026fetch_att_independently\u003dtrue\u0026fill_single_video_with_notify_to_lasr\u003dtrue\u0026filter_vp9_for_csdai\u003dtrue\u0026fix_ads_tracking_for_swf_config_deprecation_mweb\u003dtrue\u0026gcf_config_store_enabled\u003dtrue\u0026gpa_sparkles_ten_percent_layer\u003dtrue\u0026gvi_channel_client_screen\u003dtrue\u0026h5_companion_enable_adcpn_macro_substitution_for_click_pings\u003dtrue\u0026h5_inplayer_enable_adcpn_macro_substitution_for_click_pings\u003dtrue\u0026hfr_dropped_framerate_fallback_threshold\u003d0\u0026hide_endpoint_overflow_on_ytd_display_ad_renderer\u003dtrue\u0026hls_use_new_codecs_string_api\u003dtrue\u0026html5_ad_timeout_ms\u003d0\u0026html5_ads_preroll_lock_timeout_delay_ms\u003d15000\u0026html5_allow_discontiguous_slices\u003dtrue\u0026html5_allow_video_keyframe_without_audio\u003dtrue\u0026html5_append_init_while_paused\u003dtrue\u0026html5_apply_ustreamer_cap_per_video_id\u003dtrue\u0026html5_att_oauth\u003dtrue\u0026html5_attach_num_random_bytes_to_bandaid\u003d0\u0026html5_attach_po_token_to_bandaid\u003dtrue\u0026html5_autonav_cap_idle_secs\u003d0\u0026html5_autonav_quality_cap\u003d720\u0026html5_autoplay_default_quality_cap\u003d0\u0026html5_block_pip_safari_delay\u003d0\u0026html5_bmff_new_fourcc_check\u003dtrue\u0026html5_cap_quality_for_tv_hfr\u003dtrue\u0026html5_change_player_mode_order_for_logging\u003dtrue\u0026html5_clamp_cuepoints_to_min\u003dtrue\u0026html5_cobalt_max_size_for_immed_job\u003d0\u0026html5_cobalt_min_processor_cnt_to_offload_algo\u003d0\u0026html5_cobalt_override_quic\u003d0\u0026html5_consume_media_bytes_slice_infos\u003dtrue\u0026html5_control_flow_include_trigger_logging_in_tmp_logs\u003dtrue\u0026html5_create_manifest_from_protos\u003dtrue\u0026html5_de_dupe_content_video_loads_in_lifecycle_api\u003dtrue\u0026html5_deadzone_multiplier\u003d1.0\u0026html5_debug_data_log_probability\u003d0.1\u0026html5_decode_to_texture_cap\u003dtrue\u0026html5_decoder_freeze_timeout_delay_ms\u003d0\u0026html5_default_ad_gain\u003d0.5\u0026html5_default_quality_cap\u003d0\u0026html5_defer_ad_module_ms\u003d0\u0026html5_defer_fetch_att_ms\u003d1000\u0026html5_defer_modules_delay_time_millis\u003d0\u0026html5_delay_initial_loading\u003dtrue\u0026html5_delay_retries_for_host_timeout\u003dtrue\u0026html5_delayed_retry_count\u003d1\u0026html5_delayed_retry_delay_ms\u003d5000\u0026html5_deprecate_video_tag_pool\u003dtrue\u0026html5_desktop_vr180_allow_panning\u003dtrue\u0026html5_desync_cue_range_threshold\u003d0\u0026html5_df_downgrade_thresh\u003d0.2\u0026html5_disable_connection_issue_event\u003dtrue\u0026html5_disable_csi_for_bulleit\u003dtrue\u0026html5_disable_move_pssh_to_moov\u003dtrue\u0026html5_disable_non_contiguous\u003dtrue\u0026html5_displayed_frame_rate_downgrade_threshold\u003d45\u0026html5_drm_check_all_key_error_states\u003dtrue\u0026html5_drm_cpi_license_key\u003dtrue\u0026html5_early_read_chunk\u003dtrue\u0026html5_enable_ac3\u003dtrue\u0026html5_enable_ads_client_monitoring_log_tv\u003dtrue\u0026html5_enable_atv_offline\u003dtrue\u0026html5_enable_client_hints_override\u003dtrue\u0026html5_enable_eac3\u003dtrue\u0026html5_enable_embedded_player_visibility_signals\u003dtrue\u0026html5_enable_non_notify_composite_vod_lsar_pacf\u003dtrue\u0026html5_enable_single_video_vod_ivar_on_pacf\u003dtrue\u0026html5_enable_tvos_dash\u003dtrue\u0026html5_enable_tvos_encrypted_vp9\u003dtrue\u0026html5_enable_widevine_for_alc\u003dtrue\u0026html5_enable_widevine_for_fast_linear\u003dtrue\u0026html5_encourage_array_coalescing\u003dtrue\u0026html5_exile_on_drm_fatal\u003dtrue\u0026html5_fill_isTypeSupported_capability_cache_earlier\u003dtrue\u0026html5_fludd_suspend\u003dtrue\u0026html5_flush_segment_index_on_error\u003dtrue\u0026html5_flush_vss_with_rti_and_rtn\u003dtrue\u0026html5_gapless_ended_transition_buffer_ms\u003d200\u0026html5_gapless_preloading\u003dtrue\u0026html5_generate_session_po_token\u003dtrue\u0026html5_gl_fps_threshold\u003d0\u0026html5_halt_ssdai_fetch_on_predict_start\u003dtrue\u0026html5_hdcp_probing_stream_url\u003d\u0026html5_heartbeat_set_ended\u003dtrue\u0026html5_hfr_quality_cap\u003d0\u0026html5_high_res_logging_percent\u003d0.01\u0026html5_idle_rate_limit_ms\u003d0\u0026html5_ignore_media_element_event_loadeddata\u003dtrue\u0026html5_innertube_heartbeats_for_fairplay\u003dtrue\u0026html5_innertube_heartbeats_for_playready\u003dtrue\u0026html5_innertube_heartbeats_for_widevine\u003dtrue\u0026html5_ios4_seek_above_zero\u003dtrue\u0026html5_ios7_force_play_on_stall\u003dtrue\u0026html5_ios_force_seek_to_zero_on_stop\u003dtrue\u0026html5_jumbo_mobile_subsegment_readahead_target\u003d3.0\u0026html5_jumbo_ull_nonstreaming_mffa_ms\u003d4000\u0026html5_jumbo_ull_subsegment_readahead_target\u003d1.3\u0026html5_license_constraint_delay\u003d5000\u0026html5_live_abr_head_miss_fraction\u003d0.0\u0026html5_live_abr_repredict_fraction\u003d0.0\u0026html5_live_byterate_factor_for_readahead\u003d1.3\u0026html5_live_low_latency_bandwidth_window\u003d0.0\u0026html5_live_normal_latency_bandwidth_window\u003d0.0\u0026html5_live_partial_response_resumable\u003dtrue\u0026html5_live_quality_cap\u003d0\u0026html5_live_ultra_low_latency_bandwidth_window\u003d0.0\u0026html5_log_audio_abr\u003dtrue\u0026html5_log_experiment_id_from_player_response_to_ctmp\u003d\u0026html5_log_first_ssdai_requests_killswitch\u003dtrue\u0026html5_log_offline_playback_started_event\u003dtrue\u0026html5_log_readahead_on_playback_start\u003dtrue\u0026html5_log_rebuffer_events\u003d5\u0026html5_log_server_url_param\u003dtrue\u0026html5_log_trigger_events_with_debug_data\u003dtrue\u0026html5_long_rebuffer_jiggle_cmt_delay_ms\u003d0\u0026html5_long_rebuffer_new_elem_shorts_delay_ms\u003d0\u0026html5_long_rebuffer_threshold_ms\u003d30000\u0026html5_manifestless_seg_drift_limit_secs\u003d0\u0026html5_manifestless_unplugged\u003dtrue\u0026html5_manifestless_vp9_otf\u003dtrue\u0026html5_max_drift_per_track_secs\u003d0.0\u0026html5_max_headm_for_streaming_xhr\u003d0\u0026html5_max_live_dvr_window_plus_margin_secs\u003d46800.0\u0026html5_max_readbehind_secs\u003d0\u0026html5_max_redirect_response_length\u003d8192\u0026html5_max_selectable_quality_ordinal\u003d0\u0026html5_maximum_readahead_seconds\u003d0.0\u0026html5_media_fullscreen\u003dtrue\u0026html5_mfl_extend_max_request_time\u003dtrue\u0026html5_min_readbehind_cap_secs\u003d60\u0026html5_min_readbehind_secs\u003d0\u0026html5_min_selectable_quality_ordinal\u003d0\u0026html5_min_startup_buffered_ad_media_duration_secs\u003d1.2\u0026html5_min_startup_buffered_media_duration_secs\u003d1.2\u0026html5_minimum_readahead_seconds\u003d0.0\u0026html5_new_min_startup_smooth_logic\u003dtrue\u0026html5_no_placeholder_rollbacks\u003dtrue\u0026html5_non_network_rebuffer_duration_ms\u003d0\u0026html5_non_onesie_attach_po_token\u003dtrue\u0026html5_not_register_disposables_when_core_listens\u003dtrue\u0026html5_offline_failure_retry_limit\u003d2\u0026html5_onesie_cast\u003dtrue\u0026html5_onesie_defer_content_loader_ms\u003d0\u0026html5_onesie_disable_js_cleartext_compression\u003dtrue\u0026html5_onesie_enable_server_side_badwidth_estimation\u003dtrue\u0026html5_onesie_host_racing_cap_ms\u003d0\u0026html5_onesie_ignore_innertube_api_key\u003dtrue\u0026html5_onesie_live_ttl_secs\u003d8\u0026html5_onesie_media_bytes\u003dtrue\u0026html5_onesie_nonzero_playback_start\u003dtrue\u0026html5_onesie_notify_cuepoint_manager_on_completion\u003dtrue\u0026html5_onesie_prefer_trusted_host\u003dtrue\u0026html5_onesie_prewarm_cooldown_ms\u003d0\u0026html5_onesie_prewarm_interval_ms\u003d0\u0026html5_onesie_prewarm_max_lact_ms\u003d0\u0026html5_onesie_redirector_timeout_ms\u003d0\u0026html5_onesie_request_timeout_ms\u003d1000\u0026html5_onesie_sticky_server_side\u003dtrue\u0026html5_pause_on_nonforeground_platform_errors\u003dtrue\u0026html5_peak_shave\u003dtrue\u0026html5_per_format_loudness_fix\u003dtrue\u0026html5_perf_cap_override_sticky\u003dtrue\u0026html5_performance_cap_floor\u003d360\u0026html5_performance_impact_profiling_timer_ms\u003d0\u0026html5_perserve_av1_perf_cap\u003dtrue\u0026html5_photos_use_vp9_otf\u003dtrue\u0026html5_platform_minimum_readahead_seconds\u003d0.0\u0026html5_platform_whitelisted_for_frame_accurate_seeks\u003dtrue\u0026html5_player_autonav_logging\u003dtrue\u0026html5_player_dynamic_bottom_gradient\u003dtrue\u0026html5_player_min_build_cl\u003d-1\u0026html5_player_preload_ad_fix\u003dtrue\u0026html5_post_interrupt_readahead\u003d20\u0026html5_prefer_server_bwe3\u003dtrue\u0026html5_preload_wait_time_secs\u003d0.0\u0026html5_probe_primary_delay_base_ms\u003d0\u0026html5_process_all_encrypted_events\u003dtrue\u0026html5_query_sw_secure_crypto_for_android\u003dtrue\u0026html5_random_playback_cap\u003d0\u0026html5_readahead_ratelimit\u003d3000\u0026html5_recognize_predict_start_cue_point\u003dtrue\u0026html5_reduce_istypesupported_calls\u003dtrue\u0026html5_remove_command_triggered_companions\u003dtrue\u0026html5_remove_not_servable_check_killswitch\u003dtrue\u0026html5_rename_apbs\u003dtrue\u0026html5_report_fatal_drm_restricted_error_killswitch\u003dtrue\u0026html5_report_slow_ads_as_error\u003dtrue\u0026html5_request_only_hdr_or_sdr_keys\u003dtrue\u0026html5_request_sizing_multiplier\u003d0.8\u0026html5_require_hdr_capability\u003dtrue\u0026html5_reset_media_stream_on_unresumable_slices\u003dtrue\u0026html5_resource_bad_status_delay_scaling\u003d1.5\u0026html5_restrict_streaming_xhr_on_sqless_requests\u003dtrue\u0026html5_safari_desktop_eme_min_version\u003d0\u0026html5_seek_jiggle_cmt_delay_ms\u003d8000\u0026html5_seek_new_elem_delay_ms\u003d12000\u0026html5_seek_new_elem_shorts_delay_ms\u003d0\u0026html5_seek_over_discontinuities_delay_ms\u003d0\u0026html5_seek_set_cmt_delay_ms\u003d2000\u0026html5_seek_timeout_delay_ms\u003d20000\u0026html5_selectable_formats_early_exit\u003dtrue\u0026html5_server_stitched_dai_decorated_url_retry_limit\u003d5\u0026html5_server_stitched_dai_group\u003dtrue\u0026html5_session_po_token_interval_time_ms\u003d900000\u0026html5_set_ended_in_pfx_live\u003dtrue\u0026html5_simplify_streaming_xhr\u003dtrue\u0026html5_skip_oob_start_seconds\u003dtrue\u0026html5_skip_slow_ad_delay_ms\u003d15000\u0026html5_skip_sub_quantum_discontinuity_secs\u003d0.0\u0026html5_slow_start_no_media_source_delay_ms\u003d0\u0026html5_slow_start_timeout_delay_ms\u003d20000\u0026html5_ssdai_adfetch_dynamic_timeout_ms\u003d0\u0026html5_ssdai_enable_new_seek_logic\u003dtrue\u0026html5_ssdai_flush_vss\u003dtrue\u0026html5_ssdai_vss_player_state_change\u003dtrue\u0026html5_start_seconds_reorder\u003dtrue\u0026html5_stateful_audio_min_adjustment_value\u003d0\u0026html5_static_abr_resolution_shelf\u003d0\u0026html5_store_xhr_headers_readable\u003dtrue\u0026html5_stream_metadata\u003dtrue\u0026html5_streaming_init_requests_sizes\u003d0\u0026html5_streaming_xhr_check_for_null_response\u003dtrue\u0026html5_subsegment_readahead_load_speed_check_interval\u003d0.5\u0026html5_subsegment_readahead_min_buffer_health_secs\u003d0.25\u0026html5_subsegment_readahead_min_buffer_health_secs_on_timeout\u003d0.1\u0026html5_subsegment_readahead_min_load_speed\u003d1.5\u0026html5_subsegment_readahead_seek_latency_fudge\u003d0.5\u0026html5_subsegment_readahead_target_buffer_health_secs\u003d0.5\u0026html5_subsegment_readahead_timeout_secs\u003d2.0\u0026html5_suspend_loader\u003dtrue\u0026html5_track_termination_during_request\u003dtrue\u0026html5_ugc_live_audio_51\u003dtrue\u0026html5_ugc_vod_audio_51\u003dtrue\u0026html5_ultra_high_res_logging_percent\u003d0.0\u0026html5_unreported_seek_reseek_delay_ms\u003d0\u0026html5_unrestricted_layer_high_res_logging_percent\u003d0.0\u0026html5_update_constraint\u003dtrue\u0026html5_use_post_for_media\u003dtrue\u0026html5_varispeed_playback_rate\u003dtrue\u0026html5_video_tbd_min_kb\u003d0\u0026html5_viewport_undersend_maximum\u003d0.0\u0026html5_watchdog_for_zero_seek\u003dtrue\u0026html5_web_enable_halftime_preroll\u003dtrue\u0026html5_webpo_idle_priority_job\u003dtrue\u0026html5_woffle_resume\u003dtrue\u0026html5_workaround_delay_trigger\u003dtrue\u0026html5_xhr_clean_up_multi_slice_facade\u003dtrue\u0026html5_ytvlr_enable_single_select_survey\u003dtrue\u0026il_use_view_model_logging_context\u003dtrue\u0026initial_gel_batch_timeout\u003d2000\u0026injected_license_handler_error_code\u003d0\u0026injected_license_handler_license_status\u003d0\u0026json_condensed_response\u003dtrue\u0026kevlar_command_handler_command_banlist\u003d[]\u0026kevlar_dropdown_fix\u003dtrue\u0026kevlar_gel_error_routing\u003dtrue\u0026kevlar_miniplayer\u003dtrue\u0026kevlar_miniplayer_expand_top\u003dtrue\u0026kevlar_miniplayer_play_pause_on_scrim\u003dtrue\u0026kevlar_playback_associated_queue\u003dtrue\u0026kevlar_queue_use_update_api\u003dtrue\u0026kevlar_smart_downloads\u003dtrue\u0026kevlar_smart_downloads_setting\u003dtrue\u0026kevlar_vimio_use_shared_monitor\u003dtrue\u0026kevlar_woffle\u003dtrue\u0026live_chunk_readahead\u003d3\u0026live_fresca_v2\u003dtrue\u0026log_errors_through_nwl_on_retry\u003dtrue\u0026log_heartbeat_with_lifecycles\u003dtrue\u0026log_web_endpoint_to_layer\u003dtrue\u0026log_window_onerror_fraction\u003d0.1\u0026manifestless_post_live\u003dtrue\u0026manifestless_post_live_ufph\u003dtrue\u0026max_prefetch_window_sec_for_livestream_optimization\u003d10\u0026max_resolution_for_white_noise\u003d360\u0026mdx_enable_privacy_disclosure_ui\u003dtrue\u0026mdx_load_cast_api_bootstrap_script\u003dtrue\u0026migrate_events_to_ts\u003dtrue\u0026min_prefetch_offset_sec_for_livestream_optimization\u003d20\u0026music_enable_shared_audio_tier_logic\u003dtrue\u0026mweb_c3_endscreen\u003dtrue\u0026mweb_enable_custom_control_shared\u003dtrue\u0026mweb_enable_skippables_on_jio_phone\u003dtrue\u0026mweb_muted_autoplay_animation\u003dshrink\u0026mweb_native_control_in_faux_fullscreen_shared\u003dtrue\u0026network_polling_interval\u003d30000\u0026networkless_gel\u003dtrue\u0026networkless_logging\u003dtrue\u0026new_codecs_string_api_uses_legacy_style\u003dtrue\u0026nwl_send_fast_on_unload\u003dtrue\u0026nwl_send_from_memory_when_online\u003dtrue\u0026offline_error_handling\u003dtrue\u0026pageid_as_header_web\u003dtrue\u0026parse_query_data_from_url\u003dtrue\u0026player_ads_set_adformat_on_client\u003dtrue\u0026player_allow_autonav_after_playlist\u003dtrue\u0026player_bootstrap_method\u003dtrue\u0026player_defer_caption_display\u003d1000\u0026player_destroy_old_version\u003dtrue\u0026player_doubletap_to_seek\u003dtrue\u0026player_enable_playback_playlist_change\u003dtrue\u0026player_endscreen_ellipsis_fix\u003dtrue\u0026player_underlay_min_player_width\u003d768.0\u0026player_underlay_video_width_fraction\u003d0.6\u0026player_web_canary_stage\u003d0\u0026playready_first_play_expiration\u003d-1\u0026polymer_bad_build_labels\u003dtrue\u0026polymer_log_prop_change_observer_percent\u003d0\u0026polymer_verifiy_app_state\u003dtrue\u0026preskip_button_style_ads_backend\u003dcountdown_next_to_thumbnail\u0026qoe_nwl_downloads\u003dtrue\u0026qoe_send_and_write\u003dtrue\u0026record_app_crashed_web\u003dtrue\u0026replace_playability_retriever_in_watch\u003dtrue\u0026scheduler_use_raf_by_default\u003dtrue\u0026self_podding_header_string_template\u003dself_podding_interstitial_message\u0026self_podding_highlight_non_default_button\u003dtrue\u0026self_podding_midroll_choice_string_template\u003dself_podding_midroll_choice\u0026send_config_hash_timer\u003d0\u0026set_interstitial_advertisers_question_text\u003dtrue\u0026short_start_time_prefer_publish_in_watch_log\u003dtrue\u0026should_clear_video_data_on_player_cued_unstarted\u003dtrue\u0026skip_inline_muted_license_service_check\u003dtrue\u0026skip_invalid_ytcsi_ticks\u003dtrue\u0026skip_ls_gel_retry\u003dtrue\u0026skip_setting_info_in_csi_data_object\u003dtrue\u0026start_client_gcf\u003dtrue\u0026start_client_gcf_for_player\u003dtrue\u0026streaming_data_emergency_itag_blacklist\u003d[]\u0026suppress_error_204_logging\u003dtrue\u0026transport_use_scheduler\u003dtrue\u0026tv_pacf_logging_sample_rate\u003d0.01\u0026tvhtml5_unplugged_preload_cache_size\u003d5\u0026uncover_ad_badge_on_RTL_tiny_window\u003dtrue\u0026unplugged_dai_live_chunk_readahead\u003d3\u0026unplugged_tvhtml5_video_preload_on_focus_delay_ms\u003d0\u0026use_inlined_player_rpc\u003dtrue\u0026use_new_in_memory_storage\u003dtrue\u0026use_new_nwl_initialization\u003dtrue\u0026use_new_nwl_saw\u003dtrue\u0026use_new_nwl_stw\u003dtrue\u0026use_new_nwl_wts\u003dtrue\u0026use_player_abuse_bg_library\u003dtrue\u0026use_profilepage_event_label_in_carousel_playbacks\u003dtrue\u0026use_request_time_ms_header\u003dtrue\u0026use_session_based_sampling\u003dtrue\u0026use_shared_nsm\u003dtrue\u0026use_shared_nsm_and_keep_yt_online_updated\u003dtrue\u0026use_ts_visibilitylogger\u003dtrue\u0026variable_buffer_timeout_ms\u003d0\u0026verify_ads_itag_early\u003dtrue\u0026vp9_drm_live\u003dtrue\u0026vss_final_ping_send_and_write\u003dtrue\u0026vss_pings_using_networkless\u003dtrue\u0026vss_playback_use_send_and_write\u003dtrue\u0026web_api_url\u003dtrue\u0026web_cinematic_watch_settings\u003dtrue\u0026web_client_version_override\u003d\u0026web_dedupe_ve_grafting\u003dtrue\u0026web_deprecate_service_ajax_map_dependency\u003dtrue\u0026web_enable_voz_audio_feedback\u003dtrue\u0026web_foreground_heartbeat_interval_ms\u003d28000\u0026web_forward_command_on_pbj\u003dtrue\u0026web_gel_debounce_ms\u003d10000\u0026web_gel_timeout_cap\u003dtrue\u0026web_key_moments_markers\u003dtrue\u0026web_log_memory_total_kbytes\u003dtrue\u0026web_logging_max_batch\u003d150\u0026web_modern_ads\u003dtrue\u0026web_modern_buttons\u003dtrue\u0026web_modern_buttons_bl_survey\u003dtrue\u0026web_modern_subscribe\u003dtrue\u0026web_modern_subscribe_style\u003dfilled\u0026web_new_autonav_countdown\u003dtrue\u0026web_one_platform_error_handling\u003dtrue\u0026web_op_signal_type_banlist\u003d[]\u0026web_playback_associated_log_ctt\u003dtrue\u0026web_playback_associated_ve\u003dtrue\u0026web_player_api_logging_fraction\u003d0.01\u0026web_player_autonav_toggle_always_listen\u003dtrue\u0026web_player_autonav_use_server_provided_state\u003dtrue\u0026web_player_caption_language_preference_stickiness_duration\u003d0\u0026web_player_decouple_autonav\u003dtrue\u0026web_player_enable_early_warning_snackbar\u003dtrue\u0026web_player_enable_premium_hbr_in_h5_api\u003dtrue\u0026web_player_enable_premium_hbr_playback_cap\u003dtrue\u0026web_player_fine_scrubbing\u003dtrue\u0026web_player_gvi_wexit_adunit\u003dtrue\u0026web_player_gvi_wexit_all_player_styles\u003dtrue\u0026web_player_gvi_wexit_living_room_bedrock\u003dtrue\u0026web_player_gvi_wexit_living_room_kids\u003dtrue\u0026web_player_gvi_wexit_living_room_other\u003dtrue\u0026web_player_gvi_wexit_living_room_pangea\u003dtrue\u0026web_player_gvi_wexit_living_room_simply\u003dtrue\u0026web_player_gvi_wexit_living_room_unplugged\u003dtrue\u0026web_player_innertube_playlist_update\u003dtrue\u0026web_player_ipp_canary_type_for_logging\u003d\u0026web_player_live_monitor_env\u003dtrue\u0026web_player_move_autonav_toggle\u003dtrue\u0026web_player_music_visualizer_treatment\u003dfake\u0026web_player_mutable_event_label\u003dtrue\u0026web_player_nitrate_promo_tooltip\u003dtrue\u0026web_player_no_force_gvi\u003dtrue\u0026web_player_response_playback_tracking_parsing\u003dtrue\u0026web_player_seek_chapters_by_shortcut\u003dtrue\u0026web_player_sentinel_is_uniplayer\u003dtrue\u0026web_player_should_honor_include_asr_setting\u003dtrue\u0026web_player_show_music_in_this_video_graphic\u003dvideo_thumbnail\u0026web_player_small_hbp_settings_menu\u003dtrue\u0026web_player_ss_dai_ad_fetching_timeout_ms\u003d15000\u0026web_player_ss_media_time_offset\u003dtrue\u0026web_player_ss_timeout_skip_ads\u003dtrue\u0026web_player_ssdai_all_acpns_aids_logging_killswitch\u003dtrue\u0026web_player_touch_mode_improvements\u003dtrue\u0026web_player_transfer_timeout_threshold_ms\u003d10800000\u0026web_player_unset_default_csn_killswitch\u003dtrue\u0026web_player_use_cinematic_label_2\u003dtrue\u0026web_player_use_new_api_for_quality_pullback\u003dtrue\u0026web_player_vss_pageid_header\u003dtrue\u0026web_player_watch_next_response\u003dtrue\u0026web_player_watch_next_response_parsing\u003dtrue\u0026web_prefetch_preload_video\u003dtrue\u0026web_repeating_chapters\u003dtrue\u0026web_rounded_containers\u003dtrue\u0026web_rounded_thumbnails\u003dtrue\u0026web_settings_menu_icons\u003dtrue\u0026web_smoothness_test_duration_ms\u003d0\u0026web_smoothness_test_method\u003d0\u0026web_yt_config_context\u003dtrue\u0026woffle_clean_up_after_entity_migration\u003dtrue\u0026woffle_orchestration\u003dtrue\u0026ytidb_clear_embedded_player\u003dtrue\u0026ytidb_fetch_datasync_ids_for_data_cleanup\u003dtrue\u0026ytidb_remake_db_retries\u003d3\u0026ytidb_reopen_db_retries\u003d3\u0026ytidb_transaction_ended_event_rate_limit\u003d0.02\u0026ytidb_transaction_ended_event_rate_limit_session\u003d0.2\u0026ytidb_transaction_ended_event_rate_limit_transaction\u003d0.1","cspNonce":"nopnosk9VoEiau3Xtg_3uQ","canaryState":"none","authorizedUserIndex":0,"datasyncId":"106384449314396247844||"}},"XSRF_FIELD_NAME":"session_token","XSRF_TOKEN":"QUFFLUhqbFdNejRPcDhVMlNOdXRWSVQtUjFqX0VEanY5QXxBQ3Jtc0tsaGJneENWQWVZTGRmWkVtMHhWWWdBZWNvSmJKRTd2dXBsMV9lbzVNQVhRVUZyVS1hYktSN0ZZWGpSWDdSY25FRTVBSk1jeDFud2NlOFAwRUVxXzZ1UGlfWF81d1NDeDVqSjNaeVluaFRrNWxDMXpoWQ\u003d\u003d","YPC_MB_URL":"https://payments.youtube.com/payments/v4/js/integrator.js?ss\u003dmd","YTR_FAMILY_CREATION_URL":"https://families.google.com/webcreation?usegapi\u003d1","SERVER_VERSION":"prod","REUSE_COMPONENTS":true,"STAMPER_STABLE_LIST":true,"DATASYNC_ID":"106384449314396247844||","SERIALIZED_CLIENT_CONFIG_DATA":"CIiFi58GEOSg_hIQh92uBRDyov4SEMzfrgUQieiuBRDX5K4FEOqi_hIQlPiuBRCjgK8FEIuArwUQ4tSuBRDM9a4FELiLrgUQ-6P-EhC41K4FEILdrgUQ_u6uBRDa6a4FEOf3rgUQtpz-EhCO-64FEKLsrgUQ-sWuBRCJ_K4FEO2j_hIQkfj8Eg%3D%3D","LIVE_CHAT_BASE_TANGO_CONFIG":{"apiKey":"AIzaSyDZNkyC-AtROwMBpLfevIvqYk-Gfi8ZOeo","channelUri":"https://client-channel.google.com/client-channel/client","clientName":"yt-live-comments","requiresAuthToken":false,"senderUri":"https://clients4.google.com/invalidation/lcs/client","useNewTango":true},"FEXP_EXPERIMENTS":[23983296,23986016,24004644,24007246,24080738,24135310,24169501,24219381,24255163,24282011,24396645,24415864,24416291,24416441,24433679,24437577,24439361,24441240,24449113,24449639,24450366,24451032,24454357,24454498,24457577,24457884,24460376,24463912,24469897],"LIVE_CHAT_SEND_MESSAGE_ACTION":"live_chat/watch_page/send","ROOT_VE_TYPE":3611,"CLIENT_PROTOCOL":"h2","CLIENT_TRANSPORT":"quic","TIME_CREATED_MS":1675805320004,"BUTTON_REWORK":true,"LOGIN_INFO":"AFmmF2swRgIhAJlS_wc5KADLRNaMCPJS9LxFhe3IOgr3CtyzxZcMYDbgAiEA9KuEboLEz4GY26ymR5wQJP19ZxfifEsFJUeQzuvJrV4:QUQ3MjNmejhxUlF0X1RNOTlMYmc5VHN2RTlCUWx6ZzRsSXBMdC03MDRpcjhNMWV5cWk5UmRtd1lQNWxUUXF6anJRRzE3ZVlpVW5IaVJhZkJ3WWRFOU1OWlhmQ0lWYlg5WG1RMENNQi1hQzVNcFNUcEw4NHJERE4zNFFMSkZISkVxQmd1eW5nVmxQR0JHOVdDRlZGZmF0RmdudkZ6Q19FSmJpbUFiZV9QUHFSM3h6Q2NyWlpBWjhj","VALID_SESSION_TEMPDATA_DOMAINS":["www.youtube.com","studio.youtube.com","m.youtube.com"],"WORKER_PERFORMANCE_URL":{"privateDoNotAccessOrElseTrustedResourceUrlWrappedValue":"https://www.youtube.com/s/desktop/156c3d3d/jsbin/worker-performance.vflset/worker-performance.js"},"VISIBILITY_TIME_BETWEEN_JOBS_MS":100,"START_IN_THEATER_MODE":true,"START_IN_FULL_WINDOW_MODE":false,"SERVICE_WORKER_PROMPT_NOTIFICATIONS":true,"SBOX_LABELS":{"SUGGESTION_DISMISS_LABEL":"Remove","SUGGESTION_DISMISSED_LABEL":"Suggestion removed"},"ONE_PICK_URL":"","NO_EMPTY_DATA_IMG":true,"MENTIONS_EDU_HELP_LINK":"https://support.google.com/youtube/?p\u003dcreator_community","DEFERRED_DETACH":true,"RECAPTCHA_V3_SITEKEY":"6LedoOcUAAAAAHA4CFG9zRpaCNjYj33SYjzQ9cTy","PLAYER_JS_URL":"/s/player/97ea7458/player_ias.vflset/en_US/base.js","PLAYER_CSS_URL":"/s/player/97ea7458/www-player.css","LINK_GAL_DOMAIN":"https://accountlinking-pa-clients6.youtube.com","LINK_OIS_DOMAIN":"oauthintegrations-clients6.youtube.com","IS_TABLET":false,"LINK_API_KEY":"AIzaSyDophAQuyyiBr8h0nypEwXUKozH-BEswD0","DISABLE_WARM_LOADS":false,"RAW_COLD_CONFIG_GROUP":{"configData":"CIiFi58GEOqdrQUQ7bqtBRCM8q0FEJ79rQUQ94iuBRC4i64FEPWWrgUQxZquBRCnna4FEIahrgUQibGuBRCCta4FEIa1rgUQoLmuBRDYvK4FEPrFrgUQ5s2uBRCT0K4FEP3TrgUQuNSuBRDi1K4FEOTWrgUQoNquBRCC3a4FEIfdrgUQu96uBRDM364FEObgrgUQ5-GuBRCJ6K4FENrprgUQouyuBRDM7a4FEJHurgUQ_u6uBRCF8a4FEMz1rgUQ2PauBRDn964FEJT4rgUQ3PiuBRD4-K4FELT5rgUQ3vquBRDv-q4FEPP6rgUQ9fquBRCO-64FELL7rgUQzvuuBRCA_K4FEIn8rgUQrPyuBRCd_a4FENX9rgUQl_6uBRCLgK8FEKOArwUQ_ICvBRoyQUVULTZxYWpGdTlqdEx3bWVxWDdmR0FYczJPYnh0djhzdFJKWlR3OGhFYW4wcXJqQXciMkFFVC02cWFNSjlKczZnMmxfajE0dWpQTHBaeXgtN3lLZVhuTzZyN0w5ak80QnVuVGZ3KiRDQU1TRlEwUC10U3BBcVVCdWljVkRxeTYxZ3ljRTVpUkJBPT0%3D","mainAppColdConfig":{"iosSsoSafariFsiPromoEnabled":true,"iosTodayWidgetEnabled":false,"iosEnableDynamicFontSizing":false,"enableMobileAutoOffline":false,"androidEnablePip":false,"postsV2":false,"enableDetailedNetworkStatusReporting":false,"hourToReportNetworkStatus":0,"networkStatusReportingWindowSecs":0,"iosSearchviewRefactoryEnabled":false,"ngwFlexyEnabled":false,"iosWatchExpandTransitionWithoutSnapshot":false,"androidNgwUiEnabled":false,"androidThumbnailMonitorEnabled":false,"androidThumbnailMonitorCount":0,"androidThumbnailMonitorMinimumWidth":0,"enableGhostCards":false,"enableInlineMuted":false,"ngwFlexyMaxCropRatio":1.0,"androidRestoreBrowseContentsFromBackStack":false,"searchHintExp":"search_youtube"}},"RAW_HOT_CONFIG_GROUP":{"mainAppHotConfig":{"iosWatchExpandTransition":false,"iosEarlySetWatchTransition":false,"exposeConfigRefreshSetting":false,"iosEnableSearchButtonOnPlayerOverlay":false,"iosMinimumTooltipDurationMsecs":1000,"iosFreshHomeIntervalSecs":0,"iosFreshSubscriptionsIntervalSecs":0,"iosTodayWidgetRefreshIntervalSecs":28800,"iosFreshNotificationsInboxIntervalSecs":0,"signedOutNotificationsIosPrompt":true,"iosFreshFullRefresh":false},"loggingHotConfig":{"eventLoggingConfig":{"enabled":true,"maxAgeHours":720}}},"SERIALIZED_HOT_HASH_DATA":"CIiFi58GEhQxMDI1OTcwMDcwMzA2Mjc5ODg4OBiIhYufBiiU5PwSKJH4_BIonv_8Eijbk_0SKIWs_RIo4az9EijLrf0SKMay_RIoqrT9EijOwP0SKJnG_RIom8z9Eiil0P0SKPne_RIogPP9EijJ-f0SKKCA_hIo24D-Eijogv4SKMCD_hIoyYT-EijKh_4SKN-I_hIo74n-Eijxif4SKPiL_hIorZD-Eiiekf4SKIOV_hIo25b-EiiMmv4SKP6a_hIouJv-Eii8m_4SKLac_hIoi57-Eiionv4SKJ6f_hIo9p_-EiiJoP4SKOKg_hIo5KD-EiiCov4SKOqi_hIo8qL-Eiivo_4SKO2j_hIo-6P-EiifqP4SMjJBRVQtNnFhakZ1OWp0THdtZXFYN2ZHQVhzMk9ieHR2OHN0UkpaVHc4aEVhbjBxcmpBdzoyQUVULTZxYU1KOUpzNmcybF9qMTR1alBMcFp5eC03eUtlWG5PNnI3TDlqTzRCdW5UZndCKENBTVNHZzBOb3RmNkZiNF95Z0NxQVJVTDNjX0NES2liQW9ES0FZTWI%3D","SERIALIZED_COLD_HASH_DATA":"CIiFi58GEhQxMjI4NzI4MDY4OTgyMTA5NjgyNBiIhYufBjIyQUVULTZxYWpGdTlqdEx3bWVxWDdmR0FYczJPYnh0djhzdFJKWlR3OGhFYW4wcXJqQXc6MkFFVC02cWFNSjlKczZnMmxfajE0dWpQTHBaeXgtN3lLZVhuTzZyN0w5ak80QnVuVGZ3QiRDQU1TRlEwUC10U3BBcVVCdWljVkRxeTYxZ3ljRTVpUkJBPT0%3D","ZWIEBACK_PING_URLS":["https://www.google.com/pagead/lvz?evtid\u003dAC6ezLgEoRrXxVwQSBLpWVHo3kN7HsEXkDHAnpmgAtU_l34uVDFw-62KcaGd_Bc3E7keR6Hmw4JlOh2pJ-nW2b0gv56b2C7kEg\u0026req_ts\u003d1675805320\u0026pg\u003dMainAppBootstrap%3AUnclassified\u0026az\u003d1\u0026sigh\u003dAJT_Cif44eSFl96bBr8d1sp6-UepvgVe_A","https://www.google.ca/pagead/lvz?evtid\u003dAC6ezLgEoRrXxVwQSBLpWVHo3kN7HsEXkDHAnpmgAtU_l34uVDFw-62KcaGd_Bc3E7keR6Hmw4JlOh2pJ-nW2b0gv56b2C7kEg\u0026req_ts\u003d1675805320\u0026pg\u003dMainAppBootstrap%3AUnclassified\u0026az\u003d1\u0026sigh\u003dAJT_Cif44eSFl96bBr8d1sp6-UepvgVe_A"],"VOZ_API_KEY":"AIzaSyBU2xE_JHvB6wag3tMfhxXpg2Q_W8xnM-I","STS":19389,"SBOX_SETTINGS":{"HAS_ON_SCREEN_KEYBOARD":false,"IS_FUSION":false,"IS_POLYMER":true,"PSUGGEST_TOKEN":"jiJlkasl1Y49RWf4H81Ljw","REQUEST_DOMAIN":"ca","REQUEST_LANGUAGE":"en","SEND_VISITOR_DATA":false,"SEARCHBOX_BEHAVIOR_EXPERIMENT":"zero-prefix","SEARCHBOX_ENABLE_REFINEMENT_SUGGEST":true,"SEARCHBOX_TAP_TARGET_EXPERIMENT":0,"SEARCHBOX_ZERO_TYPING_SUGGEST_USE_REGULAR_SUGGEST":"always","SUGG_EXP_ID":"uqap13nintent2,ytpo.bo.me\u003d1,ytposo.bo.me\u003d1,ytpo.bo.ro.mi\u003d24456747,ytposo.bo.ro.mi\u003d24456747,cfro\u003d1,ytpo.bo.me\u003d0,ytposo.bo.me\u003d0,ytpo.bo.ro.mi\u003d24452979,ytposo.bo.ro.mi\u003d24452979","SEARCHBOX_HOST_OVERRIDE":"suggestqueries-clients6.youtube.com","HIDE_REMOVE_LINK":false},"SBOX_JS_URL":"https://www.youtube.com/s/desktop/156c3d3d/jsbin/www-searchbox.vflset/www-searchbox.js"}); window.ytcfg.obfuscatedData_ = [];var setMessage=function(msg){if(window.yt&&yt.setMsg)yt.setMsg(msg);else{window.ytcfg=window.ytcfg||{};ytcfg.msgs=msg}}; 21 + setMessage({"ADDED_TO_QUEUE":"Added to queue","ADD_TO_DROPDOWN_LABEL":"Save to...","AD_BADGE_TEXT":"Ad","AD_TITLE":"Ad: $title.","BACK_ALT_LABEL":"Back","BACK_ONLINE":"Back online","CANCEL":"Cancel","CAPTION_OFF_TOAST":"Subtitles/CC turned off","CAPTION_ON_TOAST":"Subtitles/CC turned on","CHECK_CONNECTION_OR_DOWNLOADS":"Please check your connection or watch your downloaded videos.","CLEAR":"Clear","CLOSE":"Close","CLOSED_CAPTIONS_DISABLED":"No captions are available for this video","COMMENT_LABEL":"Comment","CONNECT_TO_THE_INTERNET":"Connect to the internet","CONTINUE_WATCHING":"Continue watching","DELETE":"Delete","DELETED_PLAYLIST":"Playlist deleted from downloads.","DELETED_VIDEO":"Video deleted from downloads.","DELETE_ALL_DOWNLOADS_PROMPT":"Delete all downloads?","DELETE_FROM_DOWNLOADS":"Remove from downloads","DELETING_ALL":"Downloads are being deleted","DISLIKE_LABEL":"Dislike","DISMISS":"Dismiss","DOWNLOAD":"Download","DOWNLOADED":"Downloaded","DOWNLOADING":"Downloading","DOWNLOADING_PERCENT":"Downloading... $percent%","DOWNLOADS":"Downloads","DOWNLOADS_AVAILABILITY":"Downloads remain available as long as your device has an active internet connection at least once every 30 days.","DOWNLOADS_SETTINGS":"Downloads Settings","DOWNLOAD_EXPIRED":"Download expired","DOWNLOAD_PAUSED":"Download paused","DOWNLOAD_QUALITY":"Download Quality","DO_NOT_HAVE_DOWNLOADS":"You do not have any downloads","EDIT_AVATAR_LABEL":"Edit profile picture","EDU_GOT_IT":"Got It","END_OF_PLAYLIST":"End of playlist","ENTER_DATE_OR_EARLIER":"Enter $allowed_date or earlier","ENTER_DATE_OR_LATER":"Enter $allowed_date or later","FREEBIE_JOIN_MEMBERSHIP_EDU_TEXT":"This channel offers a membership which you can join for free with YouTube Premium","GO_TO_DOWNLOADS":"Go to downloads","GUIDE_ALT_LABEL":"Guide","HORIZONTAL_LIST_NEXT_LABEL":"Next","HORIZONTAL_LIST_PREVIOUS_LABEL":"Previous","IMAGE_HORIZONTAL_POSITION_LABEL":"The center of the preview is $x_percent% from the left and $y_percent% from the right.","IMAGE_VERTICAL_POSITION_LABEL":"The center of the preview is $x_percent% from the top and $y_percent% from the bottom.","INVALID_DATE_ERROR":"Invalid Date","JOIN_MEMBERSHIP_EDU_TEXT":"Get access to exclusive perks when you purchase a membership to this channel.","JOIN_MEMBERSHIP_EDU_TITLE":"Membership","KEEP_OPEN":"Keep this window open to continue","LIBRARY_GUIDE_ITEM_EDU_TEXT":"Find your history, playlists, purchases, and more","LIBRARY_GUIDE_ITEM_EDU_TITLE":"Check out your new Library","LIKE_LABEL":"Like","LOCAL_TIME_LABEL":"Local Time","LOGO_ALT_LABEL":"YouTube Home","MAIN_APP_WEB_COMMENT_TEASER_TOOLTIP":"Click here to read comments while watching the video.","MANAGE_MEMBERSHIP_EDU_TEXT":"Access your benefits and manage your membership from here.","MENTIONS_EDU_TEXT":"Go to the Help Center to see how mentions work on YouTube.","MENTIONS_EDU_TITLE":"Learn more","MINIPLAYER_CLOSE":"Close player","MINIPLAYER_COLLAPSE_LABEL":"Collapse","MINIPLAYER_EXPAND_LABEL":"Expand","NEXT_VIDEO_LABEL":"Next video","NO_ANGLE_BRACKET_LABEL":"Playlist title cannot contain \u003c or \u003e","NO_DOWNLOADS":"No downloads","NO_INTERNET_CONNECTION":"No internet connection","OFFLINE_CHECK_CONNECTION":"You\u0027re offline. Check your connection.","PAUSE_DOWNLOADING":"Pause downloading","PLAYER_LABEL_MUTE":"Mute (m)","PLAYER_LABEL_PAUSE":"Pause (k)","PLAYER_LABEL_PLAY":"Play (k)","PLAYER_LABEL_UNMUTE":"Unmute (m)","PLAYLIST_NEXT_VIDEO_TITLE":"Next: $video_title","PLAY_ALL":"Play all","PREPARING_TO_DOWNLOAD":"Preparing to download...","PREVIOUS_VIDEO_LABEL":"Previous video","QUEUE":"Queue","QUEUE_CLEARED":"{count,plural, \u003d1{1 video in the queue removed}other{# videos in the queue removed}}","QUEUE_CLEARED_UNPLURALIZED":"Queue cleared","QUEUE_CLOSE_MINIPLAYER_CONFIRM_BODY_TEXT":"Are you sure you want to close the player?","QUEUE_CLOSE_MINIPLAYER_CONFIRM_TITLE":"Queue will be cleared","QUEUE_RECOVER_BUTTON":"Restore","QUEUE_RECOVER_MESSAGE":"Recover queue","REACH_BOTTOM_OF_IMAGE_TEXT":"You have reached the bottom of the image","REACH_LEFT_OF_IMAGE_TEXT":"You have reached the left of the image","REACH_RIGHT_OF_IMAGE_TEXT":"You have reached the right of the image","REACH_TOP_OF_IMAGE_TEXT":"You have reached the top of the image","REMEMBER_MY_SETTINGS":"Remember my settings","REMEMBER_MY_SETTINGS_N_DAYS":"Remember my settings for $days_till_expired days.","REPOSITION_IMAGE_HORIZONTALLY_LABEL":"Use left and right arrow keys to reposition the preview","REPOSITION_IMAGE_VERTICALLY_LABEL":"Use up and down arrow keys to reposition the preview","REQUIRED_LABEL":"Required","RESUME_DOWNLOAD":"Resume download","RETRY":"Retry","SBOX_INAPPROPRIATE_ADDITIONAL":"Provide additional details (optional)","SBOX_INAPPROPRIATE_CANCEL":"Cancel","SBOX_INAPPROPRIATE_CATEGORY":"The selected predictions are:","SBOX_INAPPROPRIATE_DANGEROUS":"Dangerous and harmful activity","SBOX_INAPPROPRIATE_EXPLICIT":"Sexually explicit","SBOX_INAPPROPRIATE_HATEFUL":"Hateful","SBOX_INAPPROPRIATE_OTHER":"Other","SBOX_INAPPROPRIATE_PROMPT":"Report search predictions","SBOX_INAPPROPRIATE_REASON":"Reason (required)","SBOX_INAPPROPRIATE_REPORT":"Report","SBOX_INAPPROPRIATE_SUBMIT":"Submit","SBOX_INAPPROPRIATE_SUGGESTIONS":"Select predictions you would like to report:","SBOX_INAPPROPRIATE_TITLE":"Report search predictions","SBOX_INAPPROPRIATE_TOAST":"Thanks for your feedback!","SBOX_INAPPROPRIATE_VIOLENT":"Violent","SBOX_PLACEHOLDER":"Search","SBOX_VOICE_OVERLAY_PLACEHOLDER":"Listening...","SHARE_LABEL":"Share","SHARE_POST_EDU_TEXT":"Now you can share posts on YouTube","SHOW_LESS":"Show less","SHOW_MORE":"Show more","SIGN_IN_LABEL":"Sign in","SMART_DOWNLOADS":"Smart downloads","STORAGE_FULL":"Storage full","SUBSCRIBE_LABEL":"Subscribe","SUBS_FILTER_EDU_CHANNEL_TEXT":"Now showing new videos from this channel.","SUBS_FILTER_EDU_TEXT":"See new videos from each channel","SUBS_GUIDE_ITEM_EDU_TEXT":"See new videos from all of your subscriptions","TIMEZONE_FORMAT":"($utc_offset_text) $city_name","TRANSFER_FAILED":"Download failed","TRY_AGAIN_LATER":"Something went wrong. Please try again later.","TURN_OFF":"Turn off","TURN_ON":"Turn on","UNAVAILABLE_OFFLINE":"Unavailable offline","UNDO":"Undo","UNDO_ACTION":"Undo","UPDATED_TIME":"Updated $relative_time","UPDATE_SMART_DOWNLOADS_NOW":"Update now","UPDATING":"Updating...","UTC_OFFSET_FORMAT":"GMT$utc_offset","VIDEOS_DOWNLOADING":{"case1":"Downloading 1 video...","other":"Downloading # videos..."},"VIDEOS_DOWNLOADING_RATIO":"Downloading... $downloaded/$total","VIDEO_ACTION_MENU":"Action menu","VIEW_DOWNLOADS":"View","VIEW_FULL_PLAYLIST":"View full playlist","WAITING_FOR_INTERNET":"Waiting for internet connection...","WAITING_TO_DOWNLOAD":"Waiting to download...","YOU_ARE_OFFLINE":"You are offline","__lang__":"en"});})();ytcfg.set("initialInnerWidth",window.innerWidth);ytcfg.set("initialInnerHeight",window.innerHeight); 22 + </script><script nonce="nopnosk9VoEiau3Xtg_3uQ">if (window.ytcsi) {window.ytcsi.tick('lpcf', null, '');}</script><script src="https://www.youtube.com/s/desktop/156c3d3d/jsbin/scheduler.vflset/scheduler.js" nonce="nopnosk9VoEiau3Xtg_3uQ"></script><script src="https://www.youtube.com/s/desktop/156c3d3d/jsbin/www-i18n-constants-en_US.vflset/www-i18n-constants.js" nonce="nopnosk9VoEiau3Xtg_3uQ"></script><script src="https://www.youtube.com/s/desktop/156c3d3d/jsbin/www-tampering.vflset/www-tampering.js" nonce="nopnosk9VoEiau3Xtg_3uQ"></script><script src="https://www.youtube.com/s/desktop/156c3d3d/jsbin/spf.vflset/spf.js" nonce="nopnosk9VoEiau3Xtg_3uQ"></script><script nonce="nopnosk9VoEiau3Xtg_3uQ">if(window["_spf_state"])window["_spf_state"].config={"assume-all-json-requests-chunked":true}; 23 + </script><script src="https://www.youtube.com/s/desktop/156c3d3d/jsbin/network.vflset/network.js" nonce="nopnosk9VoEiau3Xtg_3uQ"></script><script nonce="nopnosk9VoEiau3Xtg_3uQ">if (window.ytcsi) {window.ytcsi.tick('csl', null, '');}</script><link rel="stylesheet" href="//fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&family=YouTube+Sans:wght@300..900&display=swap" nonce="EXDS35bkZefCv-NuBrYLQw"><script name="www-roboto" nonce="nopnosk9VoEiau3Xtg_3uQ">if (document.fonts && document.fonts.load) {document.fonts.load("400 10pt Roboto", ""); document.fonts.load("500 10pt Roboto", "");}</script><link rel="stylesheet" href="https://www.youtube.com/s/desktop/156c3d3d/cssbin/www-onepick-2x.css" nonce="EXDS35bkZefCv-NuBrYLQw"><link rel="stylesheet" href="https://www.youtube.com/s/_/ytmainappweb/_/ss/k=ytmainappweb.kevlar_base.blUb5Bj4eTY.L.B1.O/am=SA/d=0/br=1/rs=AGKMywGrhnWsvcr7HIYFgNRndqbf2eF8cg" nonce="EXDS35bkZefCv-NuBrYLQw"><style class="global_styles" nonce="EXDS35bkZefCv-NuBrYLQw">body{padding:0;margin:0;overflow-y:scroll}body.autoscroll{overflow-y:auto}body.no-scroll{overflow:hidden}body.no-y-scroll{overflow-y:hidden}.hidden{display:none}textarea{--paper-input-container-input_-_white-space:pre-wrap}.grecaptcha-badge{visibility:hidden}</style><style class="masthead_shell" nonce="EXDS35bkZefCv-NuBrYLQw">ytd-masthead.shell{background:hsla(0,0%,100%,.98);position:fixed;top:0;right:0;left:0;display:-ms-flex;display:-webkit-flex;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:flex;height:56px;-ms-flex-align:center;-webkit-align-items:center;-webkit-box-align:center;-moz-box-align:center;align-items:center}html[darker-dark-theme] ytd-masthead.shell{background-color:#fff!important}ytd-masthead.shell #menu-icon{margin-left:16px}ytd-app>ytd-masthead.chunked{position:fixed;top:0;width:100%}ytd-masthead.shell.dark,ytd-masthead.shell.theater{background:rgba(40,40,40,.98)}ytd-masthead.shell.full-window-mode{background:rgba(40,40,40,.98);opacity:0;-webkit-transform:translateY(calc(-100% - 5px));transform:translateY(calc(-100% - 5px))}html[darker-dark-theme] ytd-masthead.shell.dark,html[darker-dark-theme] ytd-masthead.shell.theater{background-color:#0f0f0f!important}html[darker-dark-theme] ytd-masthead.shell.full-window-mode{background-color:#0f0f0f!important}ytd-masthead.shell>:first-child{padding-left:16px}ytd-masthead.shell>:last-child{padding-right:16px}ytd-masthead #masthead-logo{display:-ms-flex;display:-webkit-flex;display:-webkit-box;display:-moz-box;display:-ms-flexbox;display:flex}ytd-masthead #masthead-logo #country-code{margin-right:2px}ytd-masthead.shell #yt-logo-red-svg,ytd-masthead.shell #yt-logo-red-updated-svg,ytd-masthead.shell #yt-logo-svg,ytd-masthead.shell #yt-logo-updated-svg{-webkit-align-self:center;-ms-flex-item-align:center;align-self:center;margin-left:8px;padding:0;color:#000}ytd-masthead.shell #a11y-skip-nav{display:none}ytd-masthead.shell svg{width:40px;height:40px;padding:8px;margin-right:8px;-moz-box-sizing:border-box;box-sizing:border-box;color:#606060;fill:currentColor}ytd-masthead .external-icon{width:24px;height:24px}ytd-masthead .yt-icons-ext{fill:currentColor;color:#606060}ytd-masthead.shell.dark .yt-icons-ext ytd-masthead.shell.theater .yt-icons-ext{fill:#fff}ytd-masthead svg#yt-logo-svg{width:80px}ytd-masthead svg#yt-logo-red-svg{width:106.4px}ytd-masthead svg#yt-logo-updated-svg{width:90px}ytd-masthead svg#yt-logo-red-updated-svg{width:97px}@media (max-width:656px){ytd-masthead.shell>:first-child{padding-left:8px}ytd-masthead.shell>:last-child{padding-right:8px}ytd-masthead.shell svg{margin-right:0}ytd-masthead #masthead-logo{-ms-flex:1 1 0.000000001px;-webkit-flex:1;-webkit-box-flex:1;-moz-box-flex:1;flex:1;-webkit-flex-basis:0.000000001px;-ms-flex-preferred-size:0.000000001px;flex-basis:0.000000001px}ytd-masthead.shell #yt-logo-red-svg,ytd-masthead.shell #yt-logo-svg{margin-left:4px}}@media (min-width:876px){ytd-masthead #masthead-logo{width:129px}}#masthead-skeleton-icons{display:-webkit-box;display:-webkit-flex;display:-moz-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-webkit-flex:1;-moz-box-flex:1;-ms-flex:1;flex:1;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-webkit-flex-direction:row;-moz-box-orient:horizontal;-moz-box-direction:normal;-ms-flex-direction:row;flex-direction:row;-webkit-box-pack:end;-webkit-justify-content:flex-end;-moz-box-pack:end;-ms-flex-pack:end;justify-content:flex-end}ytd-masthead.masthead-finish #masthead-skeleton-icons{display:none}.masthead-skeleton-icon{border-radius:50%;height:32px;width:32px;margin:0 8px;background-color:#e3e3e3}ytd-masthead.dark .masthead-skeleton-icon{background-color:#292929}</style><style class="masthead_custom_styles" is="custom-style" id="ext-styles" nonce="EXDS35bkZefCv-NuBrYLQw">ytd-masthead .yt-icons-ext{color:var(--yt-spec-icon-active-other)}ytd-masthead svg#yt-logo-red-svg #youtube-red-paths path,ytd-masthead svg#yt-logo-red-updated-svg #youtube-red-paths path,ytd-masthead svg#yt-logo-svg #youtube-paths path,ytd-masthead svg#yt-logo-updated-svg #youtube-paths path{fill:#282828}ytd-masthead.dark svg#yt-logo-red-svg #youtube-red-paths path,ytd-masthead.dark svg#yt-logo-red-updated-svg #youtube-red-paths path,ytd-masthead.dark svg#yt-logo-svg #youtube-paths path,ytd-masthead.dark svg#yt-logo-updated-svg #youtube-paths path,ytd-masthead.theater svg#yt-logo-red-svg #youtube-red-paths path,ytd-masthead.theater svg#yt-logo-svg #youtube-paths path{fill:#fff}</style><style class="searchbox" nonce="EXDS35bkZefCv-NuBrYLQw">#search-input.ytd-searchbox-spt input{-webkit-appearance:none;-webkit-font-smoothing:antialiased;background-color:transparent;border:none;box-shadow:none;color:inherit;font-family:Roboto,Noto,sans-serif;font-size:16px;font-weight:400;line-height:24px;margin-left:4px;max-width:100%;outline:none;text-align:inherit;width:100%;-ms-flex:1 1 0.000000001px;-webkit-flex:1;-webkit-box-flex:1;-moz-box-flex:1;flex:1;-webkit-flex-basis:0.000000001px;-ms-flex-preferred-size:0.000000001px;flex-basis:0.000000001px}#search-container.ytd-searchbox-spt{pointer-events:none;position:absolute;top:0;right:0;bottom:0;left:0}#search-input.ytd-searchbox-spt #search::-webkit-input-placeholder{color:#888}#search-input.ytd-searchbox-spt #search::-moz-input-placeholder{color:#888}#search-input.ytd-searchbox-spt #search:-ms-input-placeholder{color:#888}</style><style class="kevlar_global_styles" nonce="EXDS35bkZefCv-NuBrYLQw">html{background-color:#f9f9f9!important;-webkit-text-size-adjust:none}html[darker-dark-theme]{background-color:#fff!important}html[dark]{background-color:#181818!important}html[darker-dark-theme][dark]{background-color:#0f0f0f!important}#logo-red-icon-container.ytd-topbar-logo-renderer{width:86px}</style><meta name="theme-color" content="rgba(33, 33, 33, 0.98)"><link rel="search" type="application/opensearchdescription+xml" href="https://www.youtube.com/opensearch?locale=en_US" title="YouTube"><link rel="manifest" href="/manifest.webmanifest" crossorigin="use-credentials"></head><body dir="ltr"><script nonce="nopnosk9VoEiau3Xtg_3uQ">if (window.ytcsi) {window.ytcsi.tick('bs', null, '');}</script><script nonce="nopnosk9VoEiau3Xtg_3uQ">ytcfg.set('initialBodyClientWidth', document.body.clientWidth);</script><script nonce="nopnosk9VoEiau3Xtg_3uQ">if (window.ytcsi) {window.ytcsi.tick('ai', null, '');}</script><ytd-app><ytd-masthead id="masthead" logo-type="YOUTUBE_PREMIUM_LOGO" slot="masthead" class="shell dark"><div id="search-container" class="ytd-searchbox-spt" slot="search-container"></div><div id="search-input" class="ytd-searchbox-spt" slot="search-input"><input id="search" autocapitalize="none" autocomplete="off" autocorrect="off" hidden name="search_query" tabindex="0" type="text" spellcheck="false"></div><svg id="menu-icon" class="external-icon" preserveAspectRatio="xMidYMid meet"><g id="menu" class="yt-icons-ext" viewBox="0 0 24 24"><path d="M21,6H3V5h18V6z M21,11H3v1h18V11z M21,17H3v1h18V17z"/></g></svg><div id="masthead-logo" slot="masthead-logo"><a style="display: none;" href="/" title="YouTube"><svg id="yt-logo-updated-svg" class="external-icon" viewBox="0 0 90 20"><g id="yt-logo-updated" viewBox="0 0 90 20" preserveAspectRatio="xMidYMid meet"><g><path d="M27.9727 3.12324C27.6435 1.89323 26.6768 0.926623 25.4468 0.597366C23.2197 2.24288e-07 14.285 0 14.285 0C14.285 0 5.35042 2.24288e-07 3.12323 0.597366C1.89323 0.926623 0.926623 1.89323 0.597366 3.12324C2.24288e-07 5.35042 0 10 0 10C0 10 2.24288e-07 14.6496 0.597366 16.8768C0.926623 18.1068 1.89323 19.0734 3.12323 19.4026C5.35042 20 14.285 20 14.285 20C14.285 20 23.2197 20 25.4468 19.4026C26.6768 19.0734 27.6435 18.1068 27.9727 16.8768C28.5701 14.6496 28.5701 10 28.5701 10C28.5701 10 28.5677 5.35042 27.9727 3.12324Z" fill="#FF0000"/><path d="M11.4253 14.2854L18.8477 10.0004L11.4253 5.71533V14.2854Z" fill="white"/></g><g><g id="youtube-paths"><path d="M34.6024 13.0036L31.3945 1.41846H34.1932L35.3174 6.6701C35.6043 7.96361 35.8136 9.06662 35.95 9.97913H36.0323C36.1264 9.32532 36.3381 8.22937 36.665 6.68892L37.8291 1.41846H40.6278L37.3799 13.0036V18.561H34.6001V13.0036H34.6024Z"/><path d="M41.4697 18.1937C40.9053 17.8127 40.5031 17.22 40.2632 16.4157C40.0257 15.6114 39.9058 14.5437 39.9058 13.2078V11.3898C39.9058 10.0422 40.0422 8.95805 40.315 8.14196C40.5878 7.32588 41.0135 6.72851 41.592 6.35457C42.1706 5.98063 42.9302 5.79248 43.871 5.79248C44.7976 5.79248 45.5384 5.98298 46.0981 6.36398C46.6555 6.74497 47.0647 7.34234 47.3234 8.15137C47.5821 8.96275 47.7115 10.0422 47.7115 11.3898V13.2078C47.7115 14.5437 47.5845 15.6161 47.3329 16.4251C47.0812 17.2365 46.672 17.8292 46.1075 18.2031C45.5431 18.5771 44.7764 18.7652 43.8098 18.7652C42.8126 18.7675 42.0342 18.5747 41.4697 18.1937ZM44.6353 16.2323C44.7905 15.8231 44.8705 15.1575 44.8705 14.2309V10.3292C44.8705 9.43077 44.7929 8.77225 44.6353 8.35833C44.4777 7.94206 44.2026 7.7351 43.8074 7.7351C43.4265 7.7351 43.156 7.94206 43.0008 8.35833C42.8432 8.77461 42.7656 9.43077 42.7656 10.3292V14.2309C42.7656 15.1575 42.8408 15.8254 42.9914 16.2323C43.1419 16.6415 43.4123 16.8461 43.8074 16.8461C44.2026 16.8461 44.4777 16.6415 44.6353 16.2323Z"/><path d="M56.8154 18.5634H54.6094L54.3648 17.03H54.3037C53.7039 18.1871 52.8055 18.7656 51.6061 18.7656C50.7759 18.7656 50.1621 18.4928 49.767 17.9496C49.3719 17.4039 49.1743 16.5526 49.1743 15.3955V6.03751H51.9942V15.2308C51.9942 15.7906 52.0553 16.188 52.1776 16.4256C52.2999 16.6631 52.5045 16.783 52.7914 16.783C53.036 16.783 53.2712 16.7078 53.497 16.5573C53.7228 16.4067 53.8874 16.2162 53.9979 15.9858V6.03516H56.8154V18.5634Z"/><path d="M64.4755 3.68758H61.6768V18.5629H58.9181V3.68758H56.1194V1.42041H64.4755V3.68758Z"/><path d="M71.2768 18.5634H69.0708L68.8262 17.03H68.7651C68.1654 18.1871 67.267 18.7656 66.0675 18.7656C65.2373 18.7656 64.6235 18.4928 64.2284 17.9496C63.8333 17.4039 63.6357 16.5526 63.6357 15.3955V6.03751H66.4556V15.2308C66.4556 15.7906 66.5167 16.188 66.639 16.4256C66.7613 16.6631 66.9659 16.783 67.2529 16.783C67.4974 16.783 67.7326 16.7078 67.9584 16.5573C68.1842 16.4067 68.3488 16.2162 68.4593 15.9858V6.03516H71.2768V18.5634Z"/><path d="M80.609 8.0387C80.4373 7.24849 80.1621 6.67699 79.7812 6.32186C79.4002 5.96674 78.8757 5.79035 78.2078 5.79035C77.6904 5.79035 77.2059 5.93616 76.7567 6.23014C76.3075 6.52412 75.9594 6.90747 75.7148 7.38489H75.6937V0.785645H72.9773V18.5608H75.3056L75.5925 17.3755H75.6537C75.8724 17.7988 76.1993 18.1304 76.6344 18.3774C77.0695 18.622 77.554 18.7443 78.0855 18.7443C79.038 18.7443 79.7412 18.3045 80.1904 17.4272C80.6396 16.5476 80.8653 15.1765 80.8653 13.3092V11.3266C80.8653 9.92722 80.7783 8.82892 80.609 8.0387ZM78.0243 13.1492C78.0243 14.0617 77.9867 14.7767 77.9114 15.2941C77.8362 15.8115 77.7115 16.1808 77.5328 16.3971C77.3564 16.6158 77.1165 16.724 76.8178 16.724C76.585 16.724 76.371 16.6699 76.1734 16.5594C75.9759 16.4512 75.816 16.2866 75.6937 16.0702V8.96062C75.7877 8.6196 75.9524 8.34209 76.1852 8.12337C76.4157 7.90465 76.6697 7.79646 76.9401 7.79646C77.2271 7.79646 77.4481 7.90935 77.6034 8.13278C77.7609 8.35855 77.8691 8.73485 77.9303 9.26636C77.9914 9.79787 78.022 10.5528 78.022 11.5335V13.1492H78.0243Z"/><path d="M84.8657 13.8712C84.8657 14.6755 84.8892 15.2776 84.9363 15.6798C84.9833 16.0819 85.0821 16.3736 85.2326 16.5594C85.3831 16.7428 85.6136 16.8345 85.9264 16.8345C86.3474 16.8345 86.639 16.6699 86.7942 16.343C86.9518 16.0161 87.0365 15.4705 87.0506 14.7085L89.4824 14.8519C89.4965 14.9601 89.5035 15.1106 89.5035 15.3011C89.5035 16.4582 89.186 17.3237 88.5534 17.8952C87.9208 18.4667 87.0247 18.7536 85.8676 18.7536C84.4777 18.7536 83.504 18.3185 82.9466 17.446C82.3869 16.5735 82.1094 15.2259 82.1094 13.4008V11.2136C82.1094 9.33452 82.3987 7.96105 82.9772 7.09558C83.5558 6.2301 84.5459 5.79736 85.9499 5.79736C86.9165 5.79736 87.6597 5.97375 88.1771 6.32888C88.6945 6.684 89.059 7.23433 89.2707 7.98457C89.4824 8.7348 89.5882 9.76961 89.5882 11.0913V13.2362H84.8657V13.8712ZM85.2232 7.96811C85.0797 8.14449 84.9857 8.43377 84.9363 8.83593C84.8892 9.2381 84.8657 9.84722 84.8657 10.6657V11.5641H86.9283V10.6657C86.9283 9.86133 86.9001 9.25221 86.846 8.83593C86.7919 8.41966 86.6931 8.12803 86.5496 7.95635C86.4062 7.78702 86.1851 7.7 85.8864 7.7C85.5854 7.70235 85.3643 7.79172 85.2232 7.96811Z"/></g></g></g></svg></a><a style="display: none;" href="/" title="YouTube"><svg id="yt-logo-red-updated-svg" class="external-icon" viewBox="0 0 97 20" style="width: 97px;"><g id="yt-logo-red-updated" viewBox="0 0 97 20" preserveAspectRatio="xMidYMid meet"><g><path d="M27.9704 3.12324C27.6411 1.89323 26.6745 0.926623 25.4445 0.597366C23.2173 2.24288e-07 14.2827 0 14.2827 0C14.2827 0 5.34807 2.24288e-07 3.12088 0.597366C1.89323 0.926623 0.924271 1.89323 0.595014 3.12324C-2.8036e-07 5.35042 0 10 0 10C0 10 -1.57002e-06 14.6496 0.597364 16.8768C0.926621 18.1068 1.89323 19.0734 3.12324 19.4026C5.35042 20 14.285 20 14.285 20C14.285 20 23.2197 20 25.4468 19.4026C26.6769 19.0734 27.6435 18.1068 27.9727 16.8768C28.5701 14.6496 28.5701 10 28.5701 10C28.5701 10 28.5677 5.35042 27.9704 3.12324Z" fill="#FF0000"/><path d="M11.4275 14.2854L18.8475 10.0004L11.4275 5.71533V14.2854Z" fill="white"/></g><g id="youtube-red-paths"><path d="M40.0566 6.34524V7.03668C40.0566 10.4915 38.5255 12.5118 35.1742 12.5118H34.6638V18.5583H31.9263V1.42285H35.414C38.6078 1.42285 40.0566 2.7728 40.0566 6.34524ZM37.1779 6.59218C37.1779 4.09924 36.7287 3.50658 35.1765 3.50658H34.6662V10.4727H35.1365C36.6064 10.4727 37.1803 9.40968 37.1803 7.10253L37.1779 6.59218Z"/><path d="M46.5336 5.8345L46.3901 9.08238C45.2259 8.83779 44.264 9.02123 43.836 9.77382V18.5579H41.1196V6.0391H43.2857L43.5303 8.75312H43.6337C43.9183 6.77288 44.8379 5.771 46.0232 5.771C46.1949 5.7757 46.3666 5.79687 46.5336 5.8345Z"/><path d="M49.6567 13.2456V13.8782C49.6567 16.0842 49.779 16.8415 50.7198 16.8415C51.6182 16.8415 51.8228 16.1501 51.8439 14.7178L54.2734 14.8613C54.4568 17.5565 53.0481 18.763 50.6586 18.763C47.7588 18.763 46.9004 16.8627 46.9004 13.4126V11.223C46.9004 7.58707 47.8599 5.80908 50.7409 5.80908C53.6407 5.80908 54.3769 7.32131 54.3769 11.0984V13.2456H49.6567ZM49.6567 10.6703V11.5687H51.7193V10.675C51.7193 8.37258 51.5547 7.71172 50.6821 7.71172C49.8096 7.71172 49.6567 8.38669 49.6567 10.675V10.6703Z"/><path d="M68.4103 9.09902V18.5557H65.5928V9.30834C65.5928 8.28764 65.327 7.77729 64.7132 7.77729C64.2216 7.77729 63.7724 8.06186 63.4667 8.59338C63.4832 8.76271 63.4902 8.93439 63.4879 9.10373V18.5605H60.668V9.30834C60.668 8.28764 60.4022 7.77729 59.7884 7.77729C59.2969 7.77729 58.8665 8.06186 58.5631 8.57456V18.5628H55.7456V6.03929H57.9728L58.2221 7.63383H58.2621C58.8947 6.42969 59.9178 5.77588 61.1219 5.77588C62.3072 5.77588 62.9799 6.36854 63.288 7.43157C63.9418 6.34973 64.9225 5.77588 66.0443 5.77588C67.7564 5.77588 68.4103 7.00119 68.4103 9.09902Z"/><path d="M69.8191 2.8338C69.8191 1.4862 70.3106 1.09814 71.3501 1.09814C72.4132 1.09814 72.8812 1.54734 72.8812 2.8338C72.8812 4.22373 72.4108 4.57181 71.3501 4.57181C70.3106 4.56945 69.8191 4.22138 69.8191 2.8338ZM69.9837 6.03935H72.6789V18.5629H69.9837V6.03935Z"/><path d="M81.891 6.03955V18.5631H79.6849L79.4403 17.032H79.3792C78.7466 18.2573 77.827 18.7677 76.684 18.7677C75.0095 18.7677 74.2522 17.7046 74.2522 15.3975V6.0419H77.0697V15.2352C77.0697 16.3382 77.3002 16.7874 77.867 16.7874C78.3844 16.7663 78.8477 16.4582 79.0688 15.9902V6.0419H81.891V6.03955Z"/><path d="M96.1901 9.09893V18.5557H93.3726V9.30825C93.3726 8.28755 93.1068 7.7772 92.493 7.7772C92.0015 7.7772 91.5523 8.06177 91.2465 8.59329C91.263 8.76027 91.2701 8.9296 91.2677 9.09893V18.5557H88.4502V9.30825C88.4502 8.28755 88.1845 7.7772 87.5706 7.7772C87.0791 7.7772 86.6487 8.06177 86.3453 8.57447V18.5627H83.5278V6.0392H85.7527L85.9973 7.63139H86.0372C86.6699 6.42725 87.6929 5.77344 88.8971 5.77344C90.0824 5.77344 90.755 6.3661 91.0631 7.42913C91.7169 6.34729 92.6976 5.77344 93.8194 5.77344C95.541 5.77579 96.1901 7.0011 96.1901 9.09893Z"/><path d="M40.0566 6.34524V7.03668C40.0566 10.4915 38.5255 12.5118 35.1742 12.5118H34.6638V18.5583H31.9263V1.42285H35.414C38.6078 1.42285 40.0566 2.7728 40.0566 6.34524ZM37.1779 6.59218C37.1779 4.09924 36.7287 3.50658 35.1765 3.50658H34.6662V10.4727H35.1365C36.6064 10.4727 37.1803 9.40968 37.1803 7.10253L37.1779 6.59218Z"/></g></g></svg></a><span id="country-code"></span></div><div id="masthead-skeleton-icons" slot="masthead-skeleton"><div class="masthead-skeleton-icon"></div><div class="masthead-skeleton-icon"></div><div class="masthead-skeleton-icon"></div><div class="masthead-skeleton-icon"></div></div></ytd-masthead><a slot="guide-links-primary" href="https://www.youtube.com/about/" style="display: none;">About</a><a slot="guide-links-primary" href="https://www.youtube.com/about/press/" style="display: none;">Press</a><a slot="guide-links-primary" href="https://www.youtube.com/about/copyright/" style="display: none;">Copyright</a><a slot="guide-links-primary" href="/t/contact_us/" style="display: none;">Contact us</a><a slot="guide-links-primary" href="https://www.youtube.com/creators/" style="display: none;">Creators</a><a slot="guide-links-primary" href="https://www.youtube.com/ads/" style="display: none;">Advertise</a><a slot="guide-links-primary" href="https://developers.google.com/youtube" style="display: none;">Developers</a><a slot="guide-links-secondary" href="/t/terms" style="display: none;">Terms</a><a slot="guide-links-secondary" href="/t/privacy" style="display: none;">Privacy</a><a slot="guide-links-secondary" href="https://www.youtube.com/about/policies/" style="display: none;">Policy &amp; Safety</a><a slot="guide-links-secondary" href="https://www.youtube.com/howyoutubeworks?utm_campaign=ytgen&amp;utm_source=ythp&amp;utm_medium=LeftNav&amp;utm_content=txt&amp;u=https%3A%2F%2Fwww.youtube.com%2Fhowyoutubeworks%3Futm_source%3Dythp%26utm_medium%3DLeftNav%26utm_campaign%3Dytgen" style="display: none;">How YouTube works</a><a slot="guide-links-secondary" href="/new" style="display: none;">Test new features</a><div id="copyright" slot="copyright" style="display: none;"><div dir="ltr" style="display:inline">&copy; 2023 Google LLC</div></div></ytd-app><script nonce="nopnosk9VoEiau3Xtg_3uQ">if (window.ytcsi) {window.ytcsi.tick('nc_pj', null, '');}</script><script nonce="nopnosk9VoEiau3Xtg_3uQ">if (window.ytcsi) {window.ytcsi.tick('rsbe_dpj', null, '');}</script><script nonce="nopnosk9VoEiau3Xtg_3uQ">if (window.ytcsi) {window.ytcsi.tick('js_ld', null, '');}</script><script id="base-js" src="https://www.youtube.com/s/desktop/156c3d3d/jsbin/desktop_polymer.vflset/desktop_polymer.js" nonce="nopnosk9VoEiau3Xtg_3uQ"></script><script nonce="nopnosk9VoEiau3Xtg_3uQ">if (window.ytcsi) {window.ytcsi.tick('rsef_dpj', null, '');}</script><script nonce="nopnosk9VoEiau3Xtg_3uQ">if (window.ytcsi) {window.ytcsi.tick('rsae_dpj', null, '');}</script><script nonce="nopnosk9VoEiau3Xtg_3uQ">if (window.ytcsi) {window.ytcsi.tick('js_r', null, '');}</script><script nonce="nopnosk9VoEiau3Xtg_3uQ">if (window.ytcsi) {window.ytcsi.tick('ac', null, '');}</script><script nonce="nopnosk9VoEiau3Xtg_3uQ">var onPolymerReady = function(e) {window.removeEventListener('script-load-dpj', onPolymerReady);if (window.ytcsi) {window.ytcsi.tick('apr', null, '');}}; if (window.Polymer && Polymer.RenderStatus) {onPolymerReady();} else {window.addEventListener('script-load-dpj', onPolymerReady);}</script><script nonce="nopnosk9VoEiau3Xtg_3uQ">if (window.ytcsi) {window.ytcsi.tick('pdc', null, '');}</script><script nonce="nopnosk9VoEiau3Xtg_3uQ">var ytInitialData = {"responseContext":{"serviceTrackingParams":[{"service":"GFEEDBACK","params":[{"key":"route","value":"channel."},{"key":"is_casual","value":"false"},{"key":"is_owner","value":"false"},{"key":"is_monetization_enabled","value":"true"},{"key":"num_shelves","value":"6+"},{"key":"is_alc_surface","value":"false"},{"key":"browse_id","value":"UCq6VFHwMzcMXbuKyG7SQYIg"},{"key":"browse_id_prefix","value":""},{"key":"logged_in","value":"1"},{"key":"e","value":"1714252,23804281,23918597,23946420,23966208,23983296,23986016,23998056,24004644,24007246,24034168,24036948,24077241,24080738,24120819,24135310,24140247,24161116,24162920,24164186,24166867,24169501,24181174,24187043,24187377,24187920,24211178,24219381,24219713,24240251,24241378,24255163,24255543,24255545,24260378,24262346,24263796,24267564,24268142,24270757,24281897,24282011,24283015,24283093,24288047,24288664,24290971,24291857,24294555,24390675,24391541,24396645,24404640,24406313,24407191,24415864,24415866,24416291,24416441,24426636,24428900,24429094,24433679,24436009,24436595,24437577,24439361,24439483,24440132,24441240,24443834,24445230,24446866,24447185,24448384,24449113,24449639,24450200,24450367,24451032,24451434,24453129,24454357,24454498,24455643,24457195,24457577,24457884,24457969,24458839,24458983,24459943,24460376,24463477,24463912,24465101,24466458,24469897,45686551"}]},{"service":"GOOGLE_HELP","params":[{"key":"browse_id","value":"UCq6VFHwMzcMXbuKyG7SQYIg"},{"key":"browse_id_prefix","value":""}]},{"service":"CSI","params":[{"key":"c","value":"WEB"},{"key":"cver","value":"2.20230201.01.00"},{"key":"yt_li","value":"1"},{"key":"GetChannelPage_rid","value":"0x6df4b9bb86611832"}]},{"service":"GUIDED_HELP","params":[{"key":"logged_in","value":"1"}]},{"service":"ECATCHER","params":[{"key":"client.version","value":"2.20230201"},{"key":"client.name","value":"WEB"},{"key":"client.fexp","value":"24450200,24282011,24262346,24455643,24390675,24451032,24415866,24436009,24454498,24457195,1714252,24416291,24440132,24448384,24283093,24463477,24294555,24270757,24255545,24004644,24036948,24460376,23946420,24407191,24140247,24463912,24406313,24454357,24457577,24007246,24260378,23804281,24416441,23983296,24466458,24291857,24219713,23966208,24288047,24396645,23918597,24080738,24135310,24445230,24429094,24283015,24267564,24164186,24426636,24263796,24450367,24077241,24436595,24187377,24446866,24255163,23998056,24268142,24281897,24290971,24459943,24288664,24447185,24433679,24187043,24437577,24449113,24255543,24428900,24161116,24439361,24451434,24457969,24465101,24441240,24449639,24219381,24120819,24439483,24404640,24187920,24034168,23986016,24240251,24211178,24181174,45686551,24415864,24457884,24169501,24469897,24443834,24241378,24391541,24458839,24458983,24166867,24162920,24453129"}]}],"maxAgeSeconds":300,"mainAppWebResponseContext":{"datasyncId":"106384449314396247844||","loggedOut":false},"webResponseContextExtensionData":{"ytConfigData":{"visitorData":"CgtWLUUwMFpXMzdWQSiHhYufBg%3D%3D","sessionIndex":0,"rootVisualElementType":3611},"hasDecorated":true}},"contents":{"twoColumnBrowseResultsRenderer":{"tabs":[{"tabRenderer":{"endpoint":{"clickTrackingParams":"CCwQ8JMBGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0/featured","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","params":"EghmZWF0dXJlZPIGBAoCMgA%3D","canonicalBaseUrl":"/@penguinz0"}},"title":"Home","selected":true,"content":{"sectionListRenderer":{"contents":[{"itemSectionRenderer":{"contents":[{"shelfRenderer":{"title":{"runs":[{"text":"Videos","navigationEndpoint":{"clickTrackingParams":"CPQFENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0/videos?view=0\u0026sort=dd\u0026shelf_id=0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","params":"EgZ2aWRlb3MYAyAAcADyBgsKCToCCAGiAQIIAQ%3D%3D","canonicalBaseUrl":"/@penguinz0"}}}]},"endpoint":{"clickTrackingParams":"CPQFENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0/videos?view=0\u0026sort=dd\u0026shelf_id=0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","params":"EgZ2aWRlb3MYAyAAcADyBgsKCToCCAGiAQIIAQ%3D%3D","canonicalBaseUrl":"/@penguinz0"}},"content":{"horizontalListRenderer":{"items":[{"gridVideoRenderer":{"videoId":"1-kBDK0dx-c","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/1-kBDK0dx-c/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDaL521AtRNylEvmyNvD2qXgu-iOA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/1-kBDK0dx-c/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBrYOZxqPPW1fam8G-L43JJBxQlRA","width":196,"height":110},{"url":"https://i.ytimg.com/vi/1-kBDK0dx-c/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAiPOr0LCRYCfm6fkzB50hv9YYvGA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/1-kBDK0dx-c/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDatzO7m2e2BY-0paaqBeGldo8n4g","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"I'm Training for A Youtuber Boxing Match by penguinz0 2 hours ago 12 minutes, 1 second 168,142 views"}},"simpleText":"I'm Training for A Youtuber Boxing Match"},"publishedTimeText":{"simpleText":"2 hours ago"},"viewCountText":{"simpleText":"168,142 views"},"navigationEndpoint":{"clickTrackingParams":"CNEGEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1UyCmctaGlnaC1jcnZaGFVDcTZWRkh3TXpjTVhidUt5RzdTUVlJZ5oBBRDyOBhmqgEaVVVMRnE2VkZId016Y01YYnVLeUc3U1FZSWc=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=1-kBDK0dx-c","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"1-kBDK0dx-c","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr6---sn-cxaaj5o5q5-tt1el.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=d7e9010cad1dc7e7\u0026ip=74.12.195.102\u0026initcwndbps=1782500\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CNEGEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CNEGEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1VA54_36MqhwPTXAaoBGlVVTEZxNlZGSHdNemNNWGJ1S3lHN1NRWUln","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CNgGEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"168K views"}},"simpleText":"168K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CNcGEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CNcGEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"1-kBDK0dx-c","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CNcGEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["1-kBDK0dx-c"],"params":"CAQ%3D"}},"videoIds":["1-kBDK0dx-c"]}}]}},"trackingParams":"CNcGEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CNEGEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"1-kBDK0dx-c","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CNEGEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CNYGEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"1-kBDK0dx-c"}},"trackingParams":"CNYGEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CNUGENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"1-kBDK0dx-c","onAddCommand":{"clickTrackingParams":"CNUGENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"1-kBDK0dx-c","params":"CAI%3D"}}}},"trackingParams":"CNUGENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CNEGEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgsxLWtCREswZHgtYw%3D%3D","commands":[{"clickTrackingParams":"CNEGEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CNQGEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CNEGEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CNEGEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"12 minutes, 1 second"}},"simpleText":"12:01"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CNMGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"1-kBDK0dx-c","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CNMGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"1-kBDK0dx-c"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CNMGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CNIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CNIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"1-kBDK0dx-c","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CNIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["1-kBDK0dx-c"],"params":"CAQ%3D"}},"videoIds":["1-kBDK0dx-c"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CNIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/1-kBDK0dx-c/mqdefault_6s.webp?du=3000\u0026sqp=CIiCi58G\u0026rs=AOn4CLDq1dqDkZoP2ru5HvoYbTpYJRNXtw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"lwZts7Epq20","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/lwZts7Epq20/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBQmlfXpgrQqyeSaLbS3HGZ8M1yYg","width":168,"height":94},{"url":"https://i.ytimg.com/vi/lwZts7Epq20/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBeCN2AqR3p3Ftru-SRwrodt7wDpA","width":196,"height":110},{"url":"https://i.ytimg.com/vi/lwZts7Epq20/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBncBqNLL0Jd1fON8XdqJbh5rQWzg","width":246,"height":138},{"url":"https://i.ytimg.com/vi/lwZts7Epq20/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDbktdmb_JGCHzzfnVnJr1yWzrDmg","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"I Need To Rant About This by penguinz0 20 hours ago 7 minutes, 11 seconds 2,100,350 views"}},"simpleText":"I Need To Rant About This"},"publishedTimeText":{"simpleText":"20 hours ago"},"viewCountText":{"simpleText":"2,100,350 views"},"navigationEndpoint":{"clickTrackingParams":"CMkGEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1UyCmctaGlnaC1jcnZaGFVDcTZWRkh3TXpjTVhidUt5RzdTUVlJZ5oBBRDyOBhmqgEaVVVMRnE2VkZId016Y01YYnVLeUc3U1FZSWc=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=lwZts7Epq20","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"lwZts7Epq20","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr4---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=97066db3b129ab6d\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CMkGEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CMkGEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1VA7damibu2m4OXAaoBGlVVTEZxNlZGSHdNemNNWGJ1S3lHN1NRWUln","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CNAGEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2.1 million views"}},"simpleText":"2.1M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CM8GEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CM8GEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"lwZts7Epq20","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CM8GEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["lwZts7Epq20"],"params":"CAQ%3D"}},"videoIds":["lwZts7Epq20"]}}]}},"trackingParams":"CM8GEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CMkGEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"lwZts7Epq20","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CMkGEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CM4GEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"lwZts7Epq20"}},"trackingParams":"CM4GEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CM0GENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"lwZts7Epq20","onAddCommand":{"clickTrackingParams":"CM0GENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"lwZts7Epq20","params":"CAI%3D"}}}},"trackingParams":"CM0GENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CMkGEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgtsd1p0czdFcHEyMA%3D%3D","commands":[{"clickTrackingParams":"CMkGEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CMwGEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CMkGEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CMkGEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"7 minutes, 11 seconds"}},"simpleText":"7:11"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CMsGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"lwZts7Epq20","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CMsGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"lwZts7Epq20"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CMsGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CMoGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CMoGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"lwZts7Epq20","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CMoGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["lwZts7Epq20"],"params":"CAQ%3D"}},"videoIds":["lwZts7Epq20"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CMoGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/lwZts7Epq20/mqdefault_6s.webp?du=3000\u0026sqp=CJ7eip8G\u0026rs=AOn4CLAmRBUdm_8VqBeWZYl39-p8SwLqbw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"xXMURkp8mCo","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/xXMURkp8mCo/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLALCTtErCXiU7hWMeuHomrt96xHiw","width":168,"height":94},{"url":"https://i.ytimg.com/vi/xXMURkp8mCo/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCtucVPfv4JUKg_Wsm6xcsr0MlFkQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/xXMURkp8mCo/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDc1fNc9hHpGsWDM9pXI46J1WY9vg","width":246,"height":138},{"url":"https://i.ytimg.com/vi/xXMURkp8mCo/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLD6vNpjZm7uX3dUSVcaV3YAs8KELw","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Walmart Has A Huge Problem by penguinz0 1 day ago 8 minutes, 6 seconds 2,263,682 views"}},"simpleText":"Walmart Has A Huge Problem"},"publishedTimeText":{"simpleText":"1 day ago"},"viewCountText":{"simpleText":"2,263,682 views"},"navigationEndpoint":{"clickTrackingParams":"CMEGEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1UyCmctaGlnaC1jcnZaGFVDcTZWRkh3TXpjTVhidUt5RzdTUVlJZ5oBBRDyOBhmqgEaVVVMRnE2VkZId016Y01YYnVLeUc3U1FZSWc=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=xXMURkp8mCo","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"xXMURkp8mCo","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr7---sn-cxaaj5o5q5-tt1ez.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=c57314464a7c982a\u0026ip=74.12.195.102\u0026initcwndbps=1915000\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CMEGEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CMEGEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1VAqrDy0-SIxbnFAaoBGlVVTEZxNlZGSHdNemNNWGJ1S3lHN1NRWUln","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CMgGEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2.2 million views"}},"simpleText":"2.2M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CMcGEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CMcGEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"xXMURkp8mCo","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CMcGEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["xXMURkp8mCo"],"params":"CAQ%3D"}},"videoIds":["xXMURkp8mCo"]}}]}},"trackingParams":"CMcGEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CMEGEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"xXMURkp8mCo","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CMEGEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CMYGEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"xXMURkp8mCo"}},"trackingParams":"CMYGEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CMUGENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"xXMURkp8mCo","onAddCommand":{"clickTrackingParams":"CMUGENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"xXMURkp8mCo","params":"CAI%3D"}}}},"trackingParams":"CMUGENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CMEGEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgt4WE1VUmtwOG1Dbw%3D%3D","commands":[{"clickTrackingParams":"CMEGEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CMQGEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CMEGEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CMEGEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"8 minutes, 6 seconds"}},"simpleText":"8:06"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CMMGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"xXMURkp8mCo","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CMMGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"xXMURkp8mCo"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CMMGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CMIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CMIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"xXMURkp8mCo","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CMIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["xXMURkp8mCo"],"params":"CAQ%3D"}},"videoIds":["xXMURkp8mCo"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CMIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/xXMURkp8mCo/mqdefault_6s.webp?du=3000\u0026sqp=CNbWip8G\u0026rs=AOn4CLBKffah34E0Nv7f6x-AdZFj0aqXQg","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"NTvGLtIChLc","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/NTvGLtIChLc/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBdHiF3YfXZkRuTf2UsPUOjjTwN6A","width":168,"height":94},{"url":"https://i.ytimg.com/vi/NTvGLtIChLc/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAAsKf8FuIN-hqgRh4fjsNDh-BY1Q","width":196,"height":110},{"url":"https://i.ytimg.com/vi/NTvGLtIChLc/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCrzgepR5QDApEcyln9Eih1vxvHzA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/NTvGLtIChLc/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLD6SqV3akDoyGiyXw9KXnozKuunFg","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Most Evil Streamer Ever by penguinz0 1 day ago 8 minutes, 21 seconds 3,215,641 views"}},"simpleText":"Most Evil Streamer Ever"},"publishedTimeText":{"simpleText":"1 day ago"},"viewCountText":{"simpleText":"3,215,641 views"},"navigationEndpoint":{"clickTrackingParams":"CLkGEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1UyCmctaGlnaC1jcnZaGFVDcTZWRkh3TXpjTVhidUt5RzdTUVlJZ5oBBRDyOBhmqgEaVVVMRnE2VkZId016Y01YYnVLeUc3U1FZSWc=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=NTvGLtIChLc","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"NTvGLtIChLc","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr4---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=353bc62ed20284b7\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CLkGEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CLkGEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1VAt4mKkO3F8Z01qgEaVVVMRnE2VkZId016Y01YYnVLeUc3U1FZSWc=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CMAGEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"3.2 million views"}},"simpleText":"3.2M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CL8GEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CL8GEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"NTvGLtIChLc","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CL8GEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["NTvGLtIChLc"],"params":"CAQ%3D"}},"videoIds":["NTvGLtIChLc"]}}]}},"trackingParams":"CL8GEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CLkGEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"NTvGLtIChLc","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CLkGEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CL4GEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"NTvGLtIChLc"}},"trackingParams":"CL4GEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CL0GENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"NTvGLtIChLc","onAddCommand":{"clickTrackingParams":"CL0GENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"NTvGLtIChLc","params":"CAI%3D"}}}},"trackingParams":"CL0GENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CLkGEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtOVHZHTHRJQ2hMYw%3D%3D","commands":[{"clickTrackingParams":"CLkGEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CLwGEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CLkGEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CLkGEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"8 minutes, 21 seconds"}},"simpleText":"8:21"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CLsGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"NTvGLtIChLc","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CLsGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"NTvGLtIChLc"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CLsGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CLoGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CLoGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"NTvGLtIChLc","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CLoGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["NTvGLtIChLc"],"params":"CAQ%3D"}},"videoIds":["NTvGLtIChLc"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CLoGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/NTvGLtIChLc/mqdefault_6s.webp?du=3000\u0026sqp=CJ_oip8G\u0026rs=AOn4CLAlKU6KKVVkRIvwkwOljmn8_aeEbA","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"tnioGimSpX8","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/tnioGimSpX8/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCyoHdbW05zabyWOsubNyMCxJk_6A","width":168,"height":94},{"url":"https://i.ytimg.com/vi/tnioGimSpX8/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLA-2DP62SLnnHsqlQzlA9JbYo7RVg","width":196,"height":110},{"url":"https://i.ytimg.com/vi/tnioGimSpX8/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBNSis81ILGm89MPBX_bEIvaZATLQ","width":246,"height":138},{"url":"https://i.ytimg.com/vi/tnioGimSpX8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLADcUpuZNWw8QW4MZQnpnuNlD7-Mg","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Official Podcast #322: Charlie's Naughty Photo by penguinz0 2 days ago 1 hour, 16 minutes 178,955 views"}},"simpleText":"The Official Podcast #322: Charlie's Naughty Photo"},"publishedTimeText":{"simpleText":"2 days ago"},"viewCountText":{"simpleText":"178,955 views"},"navigationEndpoint":{"clickTrackingParams":"CLEGEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1UyCmctaGlnaC1jcnZaGFVDcTZWRkh3TXpjTVhidUt5RzdTUVlJZ5oBBRDyOBhmqgEaVVVMRnE2VkZId016Y01YYnVLeUc3U1FZSWc=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=tnioGimSpX8","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"tnioGimSpX8","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr2---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=b678a81a2992a57f\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CLEGEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CLEGEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1VA_8rKzKKDqry2AaoBGlVVTEZxNlZGSHdNemNNWGJ1S3lHN1NRWUln","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CLgGEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"178K views"}},"simpleText":"178K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CLcGEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CLcGEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"tnioGimSpX8","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CLcGEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["tnioGimSpX8"],"params":"CAQ%3D"}},"videoIds":["tnioGimSpX8"]}}]}},"trackingParams":"CLcGEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CLEGEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"tnioGimSpX8","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CLEGEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CLYGEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"tnioGimSpX8"}},"trackingParams":"CLYGEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CLUGENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"tnioGimSpX8","onAddCommand":{"clickTrackingParams":"CLUGENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"tnioGimSpX8","params":"CAI%3D"}}}},"trackingParams":"CLUGENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CLEGEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgt0bmlvR2ltU3BYOA%3D%3D","commands":[{"clickTrackingParams":"CLEGEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CLQGEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CLEGEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CLEGEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 hour, 16 minutes"}},"simpleText":"1:16:00"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CLMGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"tnioGimSpX8","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CLMGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"tnioGimSpX8"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CLMGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CLIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CLIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"tnioGimSpX8","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CLIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["tnioGimSpX8"],"params":"CAQ%3D"}},"videoIds":["tnioGimSpX8"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CLIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}]}},{"gridVideoRenderer":{"videoId":"iXE_udlBFEk","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/iXE_udlBFEk/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCnProJfHCiAJ0pi4jOToEea0lKFw","width":168,"height":94},{"url":"https://i.ytimg.com/vi/iXE_udlBFEk/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDeMAwoz-0o18tKDHGJ-SmNY3kgEA","width":196,"height":110},{"url":"https://i.ytimg.com/vi/iXE_udlBFEk/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBFQ-3msZj5QdHe8VxQ_dFS3hlliQ","width":246,"height":138},{"url":"https://i.ytimg.com/vi/iXE_udlBFEk/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDbqNO13bcuTcel9TJrqd19R8XuXg","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Netflix Gave Up by penguinz0 2 days ago 8 minutes, 11 seconds 3,366,529 views"}},"simpleText":"Netflix Gave Up"},"publishedTimeText":{"simpleText":"2 days ago"},"viewCountText":{"simpleText":"3,366,529 views"},"navigationEndpoint":{"clickTrackingParams":"CKkGEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1UyCmctaGlnaC1jcnZaGFVDcTZWRkh3TXpjTVhidUt5RzdTUVlJZ5oBBRDyOBhmqgEaVVVMRnE2VkZId016Y01YYnVLeUc3U1FZSWc=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=iXE_udlBFEk\u0026t=11s","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"iXE_udlBFEk","params":"uAIL","startTimeSeconds":11,"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr4---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=89713fb9d9411449\u0026ip=74.12.195.102\u0026osts=11\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CKkGEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CKkGEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1VAyaiEyp33z7iJAaoBGlVVTEZxNlZGSHdNemNNWGJ1S3lHN1NRWUln","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CLAGEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"3.3 million views"}},"simpleText":"3.3M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CK8GEP6YBBgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CK8GEP6YBBgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"iXE_udlBFEk","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CK8GEP6YBBgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["iXE_udlBFEk"],"params":"CAQ%3D"}},"videoIds":["iXE_udlBFEk"]}}]}},"trackingParams":"CK8GEP6YBBgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CKkGEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"iXE_udlBFEk","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CKkGEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CK4GEJSsCRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"iXE_udlBFEk"}},"trackingParams":"CK4GEJSsCRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CK0GENGqBRgLIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"iXE_udlBFEk","onAddCommand":{"clickTrackingParams":"CK0GENGqBRgLIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"iXE_udlBFEk","params":"CAI%3D"}}}},"trackingParams":"CK0GENGqBRgLIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CKkGEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtpWEVfdWRsQkZFaw%3D%3D","commands":[{"clickTrackingParams":"CKkGEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CKwGEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CKkGEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CKkGEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayResumePlaybackRenderer":{"percentDurationWatched":10}},{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"8 minutes, 11 seconds"}},"simpleText":"8:11"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CKsGEPnnAxgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"iXE_udlBFEk","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CKsGEPnnAxgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"iXE_udlBFEk"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CKsGEPnnAxgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CKoGEMfsBBgEIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CKoGEMfsBBgEIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"iXE_udlBFEk","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CKoGEMfsBBgEIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["iXE_udlBFEk"],"params":"CAQ%3D"}},"videoIds":["iXE_udlBFEk"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CKoGEMfsBBgEIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/iXE_udlBFEk/mqdefault_6s.webp?du=3000\u0026sqp=COLiip8G\u0026rs=AOn4CLBn-wHBF2uQ36QTRnYapmd-9AgjVA","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"_5h8EtyCXjI","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/_5h8EtyCXjI/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCNI7pw0god-oYb8oJm92AkTQACJQ","width":168,"height":94},{"url":"https://i.ytimg.com/vi/_5h8EtyCXjI/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBAA0z-i69V2Qsuj3MElqDMzvNEdQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/_5h8EtyCXjI/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDAI5s8pnddsV7muz6Je8faF6O9pQ","width":246,"height":138},{"url":"https://i.ytimg.com/vi/_5h8EtyCXjI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCbNR5oQTuagpLKH5H_cTbSlsMeRw","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Huge Fake Game Scam by penguinz0 3 days ago 11 minutes, 55 seconds 2,868,812 views"}},"simpleText":"Huge Fake Game Scam"},"publishedTimeText":{"simpleText":"3 days ago"},"viewCountText":{"simpleText":"2,868,812 views"},"navigationEndpoint":{"clickTrackingParams":"CKEGEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1UyCmctaGlnaC1jcnZaGFVDcTZWRkh3TXpjTVhidUt5RzdTUVlJZ5oBBRDyOBhmqgEaVVVMRnE2VkZId016Y01YYnVLeUc3U1FZSWc=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=_5h8EtyCXjI","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"_5h8EtyCXjI","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr4---sn-cxaaj5o5q5-tt1ez.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=ff987c12dc825e32\u0026ip=74.12.195.102\u0026initcwndbps=1915000\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CKEGEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CKEGEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1VAsryJ5K2Cn8z_AaoBGlVVTEZxNlZGSHdNemNNWGJ1S3lHN1NRWUln","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CKgGEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2.8 million views"}},"simpleText":"2.8M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CKcGEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CKcGEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"_5h8EtyCXjI","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CKcGEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["_5h8EtyCXjI"],"params":"CAQ%3D"}},"videoIds":["_5h8EtyCXjI"]}}]}},"trackingParams":"CKcGEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CKEGEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"_5h8EtyCXjI","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CKEGEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CKYGEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"_5h8EtyCXjI"}},"trackingParams":"CKYGEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CKUGENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"_5h8EtyCXjI","onAddCommand":{"clickTrackingParams":"CKUGENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"_5h8EtyCXjI","params":"CAI%3D"}}}},"trackingParams":"CKUGENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CKEGEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtfNWg4RXR5Q1hqSQ%3D%3D","commands":[{"clickTrackingParams":"CKEGEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CKQGEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CKEGEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CKEGEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"11 minutes, 55 seconds"}},"simpleText":"11:55"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CKMGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"_5h8EtyCXjI","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CKMGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"_5h8EtyCXjI"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CKMGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CKIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CKIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"_5h8EtyCXjI","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CKIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["_5h8EtyCXjI"],"params":"CAQ%3D"}},"videoIds":["_5h8EtyCXjI"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CKIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/_5h8EtyCXjI/mqdefault_6s.webp?du=3000\u0026sqp=CMT1ip8G\u0026rs=AOn4CLAo_Jpp8u9Tn7PpinNC42Tw6bczfA","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"NbnVn5vmA2I","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/NbnVn5vmA2I/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLD5AQxPz21Ols-YvcXRK23kvA13yw","width":168,"height":94},{"url":"https://i.ytimg.com/vi/NbnVn5vmA2I/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBsz8DnoV4zPi-ZFyC9hdzYG7UluQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/NbnVn5vmA2I/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLA7AZPrts1-nBlmDOFuhtOuQdmPHQ","width":246,"height":138},{"url":"https://i.ytimg.com/vi/NbnVn5vmA2I/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBfsBI3dPH1JuaGLgnxf-TDvfkFSg","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"This Technology Will Scare You by penguinz0 3 days ago 11 minutes, 46 seconds 2,197,193 views"}},"simpleText":"This Technology Will Scare You"},"publishedTimeText":{"simpleText":"3 days ago"},"viewCountText":{"simpleText":"2,197,193 views"},"navigationEndpoint":{"clickTrackingParams":"CJkGEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1UyCmctaGlnaC1jcnZaGFVDcTZWRkh3TXpjTVhidUt5RzdTUVlJZ5oBBRDyOBhmqgEaVVVMRnE2VkZId016Y01YYnVLeUc3U1FZSWc=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=NbnVn5vmA2I","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"NbnVn5vmA2I","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr4---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=35b9d59f9be60362\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CJkGEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CJkGEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1VA4oaY3_mz9dw1qgEaVVVMRnE2VkZId016Y01YYnVLeUc3U1FZSWc=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CKAGEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2.1 million views"}},"simpleText":"2.1M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CJ8GEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CJ8GEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"NbnVn5vmA2I","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CJ8GEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["NbnVn5vmA2I"],"params":"CAQ%3D"}},"videoIds":["NbnVn5vmA2I"]}}]}},"trackingParams":"CJ8GEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CJkGEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"NbnVn5vmA2I","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CJkGEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CJ4GEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"NbnVn5vmA2I"}},"trackingParams":"CJ4GEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CJ0GENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"NbnVn5vmA2I","onAddCommand":{"clickTrackingParams":"CJ0GENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"NbnVn5vmA2I","params":"CAI%3D"}}}},"trackingParams":"CJ0GENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CJkGEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtOYm5WbjV2bUEySQ%3D%3D","commands":[{"clickTrackingParams":"CJkGEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CJwGEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CJkGEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CJkGEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"11 minutes, 46 seconds"}},"simpleText":"11:46"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CJsGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"NbnVn5vmA2I","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CJsGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"NbnVn5vmA2I"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CJsGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CJoGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CJoGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"NbnVn5vmA2I","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CJoGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["NbnVn5vmA2I"],"params":"CAQ%3D"}},"videoIds":["NbnVn5vmA2I"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CJoGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/NbnVn5vmA2I/mqdefault_6s.webp?du=3000\u0026sqp=CIiFi58G\u0026rs=AOn4CLBykJlqF2-xaS7IQTHqFZqDcmE9Ww","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"merbANJ7eV0","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/merbANJ7eV0/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBaJV3QdyOPZzRNdt8JEv1XfP2WdA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/merbANJ7eV0/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBjbi8sms0FmZxeY8If6rULslhuMA","width":196,"height":110},{"url":"https://i.ytimg.com/vi/merbANJ7eV0/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLChB1wSrYorv6FFjFbuXE_yWpjPXg","width":246,"height":138},{"url":"https://i.ytimg.com/vi/merbANJ7eV0/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLB8G6qD6Trjv5UJDLafIVelJH_0Fg","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"I've Been Silent About This for Too Long by penguinz0 4 days ago 8 minutes, 23 seconds 2,548,172 views"}},"simpleText":"I've Been Silent About This for Too Long"},"publishedTimeText":{"simpleText":"4 days ago"},"viewCountText":{"simpleText":"2,548,172 views"},"navigationEndpoint":{"clickTrackingParams":"CJEGEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1UyCmctaGlnaC1jcnZaGFVDcTZWRkh3TXpjTVhidUt5RzdTUVlJZ5oBBRDyOBhmqgEaVVVMRnE2VkZId016Y01YYnVLeUc3U1FZSWc=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=merbANJ7eV0","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"merbANJ7eV0","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr1---sn-cxaaj5o5q5-tt1ee.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=99eadb00d27b795d\u0026ip=74.12.195.102\u0026initcwndbps=1816250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CJEGEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CJEGEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1VA3fLtk43gtvWZAaoBGlVVTEZxNlZGSHdNemNNWGJ1S3lHN1NRWUln","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CJgGEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2.5 million views"}},"simpleText":"2.5M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CJcGEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CJcGEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"merbANJ7eV0","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CJcGEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["merbANJ7eV0"],"params":"CAQ%3D"}},"videoIds":["merbANJ7eV0"]}}]}},"trackingParams":"CJcGEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CJEGEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"merbANJ7eV0","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CJEGEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CJYGEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"merbANJ7eV0"}},"trackingParams":"CJYGEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CJUGENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"merbANJ7eV0","onAddCommand":{"clickTrackingParams":"CJUGENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"merbANJ7eV0","params":"CAI%3D"}}}},"trackingParams":"CJUGENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CJEGEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgttZXJiQU5KN2VWMA%3D%3D","commands":[{"clickTrackingParams":"CJEGEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CJQGEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CJEGEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CJEGEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"8 minutes, 23 seconds"}},"simpleText":"8:23"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CJMGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"merbANJ7eV0","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CJMGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"merbANJ7eV0"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CJMGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CJIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CJIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"merbANJ7eV0","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CJIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["merbANJ7eV0"],"params":"CAQ%3D"}},"videoIds":["merbANJ7eV0"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CJIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/merbANJ7eV0/mqdefault_6s.webp?du=3000\u0026sqp=CMjmip8G\u0026rs=AOn4CLDIHz2VTOjtmm_H3TJkZgUOfbr9fQ","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"VabiWw1deR8","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/VabiWw1deR8/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBswC6AjGxvJmCwTm7Q1CadiM63EA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/VabiWw1deR8/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBlcEDD7LrjHS9ezBmTtMD0ysShFA","width":196,"height":110},{"url":"https://i.ytimg.com/vi/VabiWw1deR8/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAgF83TkDq5TJn-p50OaMpa9wR9bA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/VabiWw1deR8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLA-8Gu9vBkud_SDKlEH24lhlRr42g","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Netflix Just Made the Worst Change Ever by penguinz0 4 days ago 8 minutes, 52 seconds 2,486,516 views"}},"simpleText":"Netflix Just Made the Worst Change Ever"},"publishedTimeText":{"simpleText":"4 days ago"},"viewCountText":{"simpleText":"2,486,516 views"},"navigationEndpoint":{"clickTrackingParams":"CIkGEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1UyCmctaGlnaC1jcnZaGFVDcTZWRkh3TXpjTVhidUt5RzdTUVlJZ5oBBRDyOBhmqgEaVVVMRnE2VkZId016Y01YYnVLeUc3U1FZSWc=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=VabiWw1deR8\u0026t=1s","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"VabiWw1deR8","params":"uAIB","startTimeSeconds":1,"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr2---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=55a6e25b0d5d791f\u0026ip=74.12.195.102\u0026osts=1\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CIkGEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CIkGEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1VAn_L16rDLuNNVqgEaVVVMRnE2VkZId016Y01YYnVLeUc3U1FZSWc=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CJAGEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2.4 million views"}},"simpleText":"2.4M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CI8GEP6YBBgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CI8GEP6YBBgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"VabiWw1deR8","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CI8GEP6YBBgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["VabiWw1deR8"],"params":"CAQ%3D"}},"videoIds":["VabiWw1deR8"]}}]}},"trackingParams":"CI8GEP6YBBgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CIkGEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"VabiWw1deR8","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CIkGEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CI4GEJSsCRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"VabiWw1deR8"}},"trackingParams":"CI4GEJSsCRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CI0GENGqBRgLIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"VabiWw1deR8","onAddCommand":{"clickTrackingParams":"CI0GENGqBRgLIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"VabiWw1deR8","params":"CAI%3D"}}}},"trackingParams":"CI0GENGqBRgLIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CIkGEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtWYWJpV3cxZGVSOA%3D%3D","commands":[{"clickTrackingParams":"CIkGEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CIwGEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CIkGEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CIkGEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayResumePlaybackRenderer":{"percentDurationWatched":10}},{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"8 minutes, 52 seconds"}},"simpleText":"8:52"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CIsGEPnnAxgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"VabiWw1deR8","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CIsGEPnnAxgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"VabiWw1deR8"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CIsGEPnnAxgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CIoGEMfsBBgEIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CIoGEMfsBBgEIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"VabiWw1deR8","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CIoGEMfsBBgEIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["VabiWw1deR8"],"params":"CAQ%3D"}},"videoIds":["VabiWw1deR8"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CIoGEMfsBBgEIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/VabiWw1deR8/mqdefault_6s.webp?du=3000\u0026sqp=CNXVip8G\u0026rs=AOn4CLARFffiAiYkbucq2VAQGbP7FIKwjg","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"H1YUjGh7-EE","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/H1YUjGh7-EE/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAc9FQiEr8jUV24CZzeANExyiO3bg","width":168,"height":94},{"url":"https://i.ytimg.com/vi/H1YUjGh7-EE/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBJvVOBGHhDNLGwFU1FEpWvy3jKzg","width":196,"height":110},{"url":"https://i.ytimg.com/vi/H1YUjGh7-EE/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLD74zZJyo2uhwRzvd2UM0MPF4HCSQ","width":246,"height":138},{"url":"https://i.ytimg.com/vi/H1YUjGh7-EE/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBv_ba6UXPJUMYn1dgdpn2wOHy6XQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"We Went Wild by penguinz0 5 days ago 57 minutes 851,332 views"}},"simpleText":"We Went Wild"},"publishedTimeText":{"simpleText":"5 days ago"},"viewCountText":{"simpleText":"851,332 views"},"navigationEndpoint":{"clickTrackingParams":"CIEGEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1UyCmctaGlnaC1jcnZaGFVDcTZWRkh3TXpjTVhidUt5RzdTUVlJZ5oBBRDyOBhmqgEaVVVMRnE2VkZId016Y01YYnVLeUc3U1FZSWc=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=H1YUjGh7-EE","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"H1YUjGh7-EE","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=1f56148c687bf841\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CIEGEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CIEGEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1VAwfDvw8aRhasfqgEaVVVMRnE2VkZId016Y01YYnVLeUc3U1FZSWc=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CIgGEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"851K views"}},"simpleText":"851K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CIcGEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CIcGEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"H1YUjGh7-EE","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CIcGEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["H1YUjGh7-EE"],"params":"CAQ%3D"}},"videoIds":["H1YUjGh7-EE"]}}]}},"trackingParams":"CIcGEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CIEGEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"H1YUjGh7-EE","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CIEGEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CIYGEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"H1YUjGh7-EE"}},"trackingParams":"CIYGEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CIUGENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"H1YUjGh7-EE","onAddCommand":{"clickTrackingParams":"CIUGENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"H1YUjGh7-EE","params":"CAI%3D"}}}},"trackingParams":"CIUGENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CIEGEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtIMVlVakdoNy1FRQ%3D%3D","commands":[{"clickTrackingParams":"CIEGEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CIQGEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CIEGEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CIEGEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"57 minutes, 14 seconds"}},"simpleText":"57:14"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CIMGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"H1YUjGh7-EE","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CIMGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"H1YUjGh7-EE"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CIMGEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CIIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CIIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"H1YUjGh7-EE","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CIIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["H1YUjGh7-EE"],"params":"CAQ%3D"}},"videoIds":["H1YUjGh7-EE"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CIIGEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/H1YUjGh7-EE/mqdefault_6s.webp?du=3000\u0026sqp=CJfiip8G\u0026rs=AOn4CLDh-1PXg_NlrA_FTarhrIoSq2sy9w","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"COZCHQkMsxM","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/COZCHQkMsxM/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLA1awY6jJ6oJetuxVczcF9mbVj9WQ","width":168,"height":94},{"url":"https://i.ytimg.com/vi/COZCHQkMsxM/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAnB6JGKaMt8BdZpNsda_Eu-W3y3w","width":196,"height":110},{"url":"https://i.ytimg.com/vi/COZCHQkMsxM/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDpvIEOLseve8EF5vbPOXinBh3KXA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/COZCHQkMsxM/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAX6sxUDg16kr_johKLU4hwtadCqQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Horrible Streamer Deepfake Situation by penguinz0 5 days ago 12 minutes, 13 seconds 3,348,336 views"}},"simpleText":"Horrible Streamer Deepfake Situation"},"publishedTimeText":{"simpleText":"5 days ago"},"viewCountText":{"simpleText":"3,348,336 views"},"navigationEndpoint":{"clickTrackingParams":"CPkFEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1UyCmctaGlnaC1jcnZaGFVDcTZWRkh3TXpjTVhidUt5RzdTUVlJZ5oBBRDyOBhmqgEaVVVMRnE2VkZId016Y01YYnVLeUc3U1FZSWc=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=COZCHQkMsxM\u0026t=6s","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"COZCHQkMsxM","params":"uAIG","startTimeSeconds":6,"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr1---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=08e6421d090cb313\u0026ip=74.12.195.102\u0026osts=6\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CPkFEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CPkFEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1VAk-ayyNDDkPMIqgEaVVVMRnE2VkZId016Y01YYnVLeUc3U1FZSWc=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CIAGEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"3.3 million views"}},"simpleText":"3.3M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CP8FEP6YBBgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CP8FEP6YBBgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"COZCHQkMsxM","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CP8FEP6YBBgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["COZCHQkMsxM"],"params":"CAQ%3D"}},"videoIds":["COZCHQkMsxM"]}}]}},"trackingParams":"CP8FEP6YBBgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CPkFEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"COZCHQkMsxM","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CPkFEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CP4FEJSsCRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"COZCHQkMsxM"}},"trackingParams":"CP4FEJSsCRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CP0FENGqBRgLIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"COZCHQkMsxM","onAddCommand":{"clickTrackingParams":"CP0FENGqBRgLIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"COZCHQkMsxM","params":"CAI%3D"}}}},"trackingParams":"CP0FENGqBRgLIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CPkFEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtDT1pDSFFrTXN4TQ%3D%3D","commands":[{"clickTrackingParams":"CPkFEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CPwFEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CPkFEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CPkFEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayResumePlaybackRenderer":{"percentDurationWatched":10}},{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"12 minutes, 13 seconds"}},"simpleText":"12:13"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CPsFEPnnAxgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"COZCHQkMsxM","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CPsFEPnnAxgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"COZCHQkMsxM"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CPsFEPnnAxgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CPoFEMfsBBgEIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CPoFEMfsBBgEIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"COZCHQkMsxM","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CPoFEMfsBBgEIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["COZCHQkMsxM"],"params":"CAQ%3D"}},"videoIds":["COZCHQkMsxM"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CPoFEMfsBBgEIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/COZCHQkMsxM/mqdefault_6s.webp?du=3000\u0026sqp=COnvip8G\u0026rs=AOn4CLDoHGVZpxNdAEy7YDdQwuxBmKY08w","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}}],"trackingParams":"CPYFEMY5IhMI-Mm_pq2E_QIVEIf_BB2wqAtV","visibleItemCount":4,"nextButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"CHEVRON_RIGHT"},"accessibility":{"label":"Next"},"trackingParams":"CPgFEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},"previousButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"CHEVRON_LEFT"},"accessibility":{"label":"Previous"},"trackingParams":"CPcFEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}}}},"trackingParams":"CPQFENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","playAllButton":{"buttonRenderer":{"style":"STYLE_TEXT","size":"SIZE_DEFAULT","isDisabled":false,"text":{"runs":[{"text":"Play all"}]},"icon":{"iconType":"PLAY_ALL"},"navigationEndpoint":{"clickTrackingParams":"CPUFEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=1-kBDK0dx-c\u0026list=UULFq6VFHwMzcMXbuKyG7SQYIg","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"1-kBDK0dx-c","playlistId":"UULFq6VFHwMzcMXbuKyG7SQYIg","loggingContext":{"vssLoggingContext":{"serializedContextData":"GhpVVUxGcTZWRkh3TXpjTVhidUt5RzdTUVlJZw%3D%3D"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr6---sn-cxaaj5o5q5-tt1el.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=d7e9010cad1dc7e7\u0026ip=74.12.195.102\u0026initcwndbps=1782500\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"trackingParams":"CPUFEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}}}}],"trackingParams":"CPMFELsvGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"itemSectionRenderer":{"contents":[{"shelfRenderer":{"title":{"runs":[{"text":"Slapping","navigationEndpoint":{"clickTrackingParams":"CI4FENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLRD7N-Zrj2DOt_DFJg7IaJJCaLpsLJEwz","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLRD7N-Zrj2DOt_DFJg7IaJJCaLpsLJEwz"}}}]},"endpoint":{"clickTrackingParams":"CI4FENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLRD7N-Zrj2DOt_DFJg7IaJJCaLpsLJEwz","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLRD7N-Zrj2DOt_DFJg7IaJJCaLpsLJEwz"}},"content":{"horizontalListRenderer":{"items":[{"gridVideoRenderer":{"videoId":"gXJ1_i2cJQk","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/gXJ1_i2cJQk/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDHSlhXIkVxC1S4Ltz0Hr69fo5HrA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/gXJ1_i2cJQk/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLD2HBKfD8718LdN_s1Rydh1wCxYzg","width":196,"height":110},{"url":"https://i.ytimg.com/vi/gXJ1_i2cJQk/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCvYLsSYlDiTUeXsWJkqP1bpfjrug","width":246,"height":138},{"url":"https://i.ytimg.com/vi/gXJ1_i2cJQk/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDOnB2KljrG0pifhBJs7UaeIcjVyQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Proud To Be An American by penguinz0 1 year ago 10 minutes, 52 seconds 1,481,499 views"}},"simpleText":"Proud To Be An American"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"1,481,499 views"},"navigationEndpoint":{"clickTrackingParams":"COsFEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRPdF9ERkpnN0lhSkpDYUxwc0xKRXd6","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=gXJ1_i2cJQk","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"gXJ1_i2cJQk","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr8---sn-cxaaj5o5q5-tt1es.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=817275fe2d9c2509\u0026ip=74.12.195.102\u0026initcwndbps=1656250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"COsFEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"COsFEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"COsFEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1VAicrw7OK_nbmBAaoBIlBMUkQ3Ti1acmoyRE90X0RGSmc3SWFKSkNhTHBzTEpFd3o=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CPIFEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.4 million views"}},"simpleText":"1.4M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CPEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CPEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"gXJ1_i2cJQk","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CPEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["gXJ1_i2cJQk"],"params":"CAQ%3D"}},"videoIds":["gXJ1_i2cJQk"]}}]}},"trackingParams":"CPEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"COsFEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"gXJ1_i2cJQk","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"COsFEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CPAFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"gXJ1_i2cJQk"}},"trackingParams":"CPAFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CO8FENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"gXJ1_i2cJQk","onAddCommand":{"clickTrackingParams":"CO8FENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"gXJ1_i2cJQk","params":"CAI%3D"}}}},"trackingParams":"CO8FENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"COsFEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtnWEoxX2kyY0pRaw%3D%3D","commands":[{"clickTrackingParams":"COsFEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CO4FEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"COsFEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"COsFEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"10 minutes, 52 seconds"}},"simpleText":"10:52"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CO0FEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"gXJ1_i2cJQk","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CO0FEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"gXJ1_i2cJQk"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CO0FEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"COwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"COwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"gXJ1_i2cJQk","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"COwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["gXJ1_i2cJQk"],"params":"CAQ%3D"}},"videoIds":["gXJ1_i2cJQk"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"COwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/gXJ1_i2cJQk/mqdefault_6s.webp?du=3000\u0026sqp=CNDkip8G\u0026rs=AOn4CLBSnBvqDBeoSrEagcEMCiQjBh9fPQ","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"bsgQw4N-xBE","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/bsgQw4N-xBE/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCk8A1Tf0yYzWoZ6yaotVBzBliggg","width":168,"height":94},{"url":"https://i.ytimg.com/vi/bsgQw4N-xBE/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAtzd4OUx8E82nY4KWiqc9dFeWt_Q","width":196,"height":110},{"url":"https://i.ytimg.com/vi/bsgQw4N-xBE/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBbiF_5cal2DMPik2lE5LcaUz10Zw","width":246,"height":138},{"url":"https://i.ytimg.com/vi/bsgQw4N-xBE/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLChQ5rqorRpRBQVwiWjrPFfPgWotw","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Welcome to America by penguinz0 1 year ago 6 minutes, 54 seconds 1,406,864 views"}},"simpleText":"Welcome to America"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"1,406,864 views"},"navigationEndpoint":{"clickTrackingParams":"COMFEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRPdF9ERkpnN0lhSkpDYUxwc0xKRXd6","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=bsgQw4N-xBE","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"bsgQw4N-xBE","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr4---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=6ec810c3837ec411\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"COMFEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"COMFEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"COMFEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1VAkYj7m7iYhORuqgEiUExSRDdOLVpyajJET3RfREZKZzdJYUpKQ2FMcHNMSkV3eg==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"COoFEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.4 million views"}},"simpleText":"1.4M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"COkFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"COkFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"bsgQw4N-xBE","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"COkFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["bsgQw4N-xBE"],"params":"CAQ%3D"}},"videoIds":["bsgQw4N-xBE"]}}]}},"trackingParams":"COkFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"COMFEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"bsgQw4N-xBE","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"COMFEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"COgFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"bsgQw4N-xBE"}},"trackingParams":"COgFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"COcFENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"bsgQw4N-xBE","onAddCommand":{"clickTrackingParams":"COcFENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"bsgQw4N-xBE","params":"CAI%3D"}}}},"trackingParams":"COcFENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"COMFEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgtic2dRdzROLXhCRQ%3D%3D","commands":[{"clickTrackingParams":"COMFEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"COYFEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"COMFEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"COMFEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"6 minutes, 54 seconds"}},"simpleText":"6:54"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"COUFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"bsgQw4N-xBE","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"COUFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"bsgQw4N-xBE"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"COUFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"COQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"COQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"bsgQw4N-xBE","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"COQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["bsgQw4N-xBE"],"params":"CAQ%3D"}},"videoIds":["bsgQw4N-xBE"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"COQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/bsgQw4N-xBE/mqdefault_6s.webp?du=3000\u0026sqp=CPWEi58G\u0026rs=AOn4CLC4YV73WNohNZPzd8uHAvV0-aPY5g","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"7YZH-5cHSgg","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/7YZH-5cHSgg/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAi1tLItECEBr9wonhzC0RCB-5JUQ","width":168,"height":94},{"url":"https://i.ytimg.com/vi/7YZH-5cHSgg/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAWGaKjK8ryAisY5xGSPAIL5Zw3dg","width":196,"height":110},{"url":"https://i.ytimg.com/vi/7YZH-5cHSgg/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAIxHbRqeUiEEYeS1tLJTzsWDdqfQ","width":246,"height":138},{"url":"https://i.ytimg.com/vi/7YZH-5cHSgg/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLA8j7lTqMB54HOjb6lYLgfGpBJZdw","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"This Is The Future of Slapping by penguinz0 1 year ago 7 minutes, 46 seconds 1,286,946 views"}},"simpleText":"This Is The Future of Slapping"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"1,286,946 views"},"navigationEndpoint":{"clickTrackingParams":"CNsFEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRPdF9ERkpnN0lhSkpDYUxwc0xKRXd6","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=7YZH-5cHSgg","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"7YZH-5cHSgg","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr1---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=ed8647fb97074a08\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CNsFEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CNsFEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CNsFEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1VAiJSduLn_kcPtAaoBIlBMUkQ3Ti1acmoyRE90X0RGSmc3SWFKSkNhTHBzTEpFd3o=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"COIFEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.2 million views"}},"simpleText":"1.2M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"COEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"COEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"7YZH-5cHSgg","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"COEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["7YZH-5cHSgg"],"params":"CAQ%3D"}},"videoIds":["7YZH-5cHSgg"]}}]}},"trackingParams":"COEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CNsFEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"7YZH-5cHSgg","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CNsFEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"COAFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"7YZH-5cHSgg"}},"trackingParams":"COAFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CN8FENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"7YZH-5cHSgg","onAddCommand":{"clickTrackingParams":"CN8FENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"7YZH-5cHSgg","params":"CAI%3D"}}}},"trackingParams":"CN8FENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CNsFEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs3WVpILTVjSFNnZw%3D%3D","commands":[{"clickTrackingParams":"CNsFEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CN4FEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CNsFEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CNsFEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"7 minutes, 46 seconds"}},"simpleText":"7:46"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CN0FEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"7YZH-5cHSgg","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CN0FEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"7YZH-5cHSgg"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CN0FEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CNwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CNwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"7YZH-5cHSgg","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CNwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["7YZH-5cHSgg"],"params":"CAQ%3D"}},"videoIds":["7YZH-5cHSgg"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CNwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/7YZH-5cHSgg/mqdefault_6s.webp?du=3000\u0026sqp=CPDtip8G\u0026rs=AOn4CLDlRoLPf1EHH85xGiHwjmg9kS-xxg","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"VRBD2N4-EW8","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/VRBD2N4-EW8/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDu3ump_y44uzRGXZCk4TI6RXg-oQ","width":168,"height":94},{"url":"https://i.ytimg.com/vi/VRBD2N4-EW8/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBIIeU3fcsCOtV8-gYQmDlYe4qZ1Q","width":196,"height":110},{"url":"https://i.ytimg.com/vi/VRBD2N4-EW8/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDfHnNektlxKCsB5yZHgySFKkORjQ","width":246,"height":138},{"url":"https://i.ytimg.com/vi/VRBD2N4-EW8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBPcudOJ0mkw1mw2mw6P65focNI3A","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Most American Thing I've Ever Seen by penguinz0 1 year ago 12 minutes, 14 seconds 2,493,795 views"}},"simpleText":"Most American Thing I've Ever Seen"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"2,493,795 views"},"navigationEndpoint":{"clickTrackingParams":"CNMFEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRPdF9ERkpnN0lhSkpDYUxwc0xKRXd6","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=VRBD2N4-EW8","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"VRBD2N4-EW8","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr1---sn-cxaaj5o5q5-tt1y.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=551043d8de3e116f\u0026ip=74.12.195.102\u0026initcwndbps=1702500\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CNMFEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CNMFEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CNMFEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1VA76L48Y37kIhVqgEiUExSRDdOLVpyajJET3RfREZKZzdJYUpKQ2FMcHNMSkV3eg==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CNoFEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2.4 million views"}},"simpleText":"2.4M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CNkFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CNkFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"VRBD2N4-EW8","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CNkFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["VRBD2N4-EW8"],"params":"CAQ%3D"}},"videoIds":["VRBD2N4-EW8"]}}]}},"trackingParams":"CNkFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CNMFEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"VRBD2N4-EW8","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CNMFEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CNgFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"VRBD2N4-EW8"}},"trackingParams":"CNgFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CNcFENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"VRBD2N4-EW8","onAddCommand":{"clickTrackingParams":"CNcFENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"VRBD2N4-EW8","params":"CAI%3D"}}}},"trackingParams":"CNcFENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CNMFEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtWUkJEMk40LUVXOA%3D%3D","commands":[{"clickTrackingParams":"CNMFEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CNYFEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CNMFEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CNMFEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"12 minutes, 14 seconds"}},"simpleText":"12:14"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CNUFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"VRBD2N4-EW8","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CNUFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"VRBD2N4-EW8"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CNUFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CNQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CNQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"VRBD2N4-EW8","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CNQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["VRBD2N4-EW8"],"params":"CAQ%3D"}},"videoIds":["VRBD2N4-EW8"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CNQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/VRBD2N4-EW8/mqdefault_6s.webp?du=3000\u0026sqp=CIngip8G\u0026rs=AOn4CLB4yJt89QrIwMYrKmjnvlRRfIbRQw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"8Ry90Meo-3E","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/8Ry90Meo-3E/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCQa2eI9Sc8dtgiVjqwN16Jdsa20Q","width":168,"height":94},{"url":"https://i.ytimg.com/vi/8Ry90Meo-3E/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAv8LRw7rpc_IHRmJdUOndum5MOWA","width":196,"height":110},{"url":"https://i.ytimg.com/vi/8Ry90Meo-3E/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCwCuNSZAEy4jufClEzKVtNHYJtww","width":246,"height":138},{"url":"https://i.ytimg.com/vi/8Ry90Meo-3E/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCUWw2Jmwc5Zr_UnwECxGnPtkiPfw","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Weeb Slap by penguinz0 1 year ago 7 minutes, 14 seconds 1,322,659 views"}},"simpleText":"Weeb Slap"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"1,322,659 views"},"navigationEndpoint":{"clickTrackingParams":"CMsFEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRPdF9ERkpnN0lhSkpDYUxwc0xKRXd6","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=8Ry90Meo-3E","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"8Ry90Meo-3E","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=f11cbdd0c7a8fb71\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CMsFEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CMsFEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CMsFEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1VA8fajvYy6r47xAaoBIlBMUkQ3Ti1acmoyRE90X0RGSmc3SWFKSkNhTHBzTEpFd3o=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CNIFEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.3 million views"}},"simpleText":"1.3M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CNEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CNEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"8Ry90Meo-3E","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CNEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["8Ry90Meo-3E"],"params":"CAQ%3D"}},"videoIds":["8Ry90Meo-3E"]}}]}},"trackingParams":"CNEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CMsFEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"8Ry90Meo-3E","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CMsFEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CNAFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"8Ry90Meo-3E"}},"trackingParams":"CNAFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CM8FENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"8Ry90Meo-3E","onAddCommand":{"clickTrackingParams":"CM8FENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"8Ry90Meo-3E","params":"CAI%3D"}}}},"trackingParams":"CM8FENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CMsFEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs4Unk5ME1lby0zRQ%3D%3D","commands":[{"clickTrackingParams":"CMsFEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CM4FEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CMsFEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CMsFEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"7 minutes, 14 seconds"}},"simpleText":"7:14"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CM0FEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"8Ry90Meo-3E","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CM0FEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"8Ry90Meo-3E"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CM0FEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CMwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CMwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"8Ry90Meo-3E","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CMwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["8Ry90Meo-3E"],"params":"CAQ%3D"}},"videoIds":["8Ry90Meo-3E"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CMwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/8Ry90Meo-3E/mqdefault_6s.webp?du=3000\u0026sqp=CNbXip8G\u0026rs=AOn4CLBjscF1N18hqDEcFT9gB1KDLnkcdw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"AD9hWFgpc7g","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/AD9hWFgpc7g/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAcEO4Kx99b9ucVNN-VAfTh3wrXIw","width":168,"height":94},{"url":"https://i.ytimg.com/vi/AD9hWFgpc7g/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDw7D-HAH_DE7LlG60X8jmPd8lICA","width":196,"height":110},{"url":"https://i.ytimg.com/vi/AD9hWFgpc7g/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAxBUBzxc_-TlMPEMywRCZesK-L4w","width":246,"height":138},{"url":"https://i.ytimg.com/vi/AD9hWFgpc7g/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBAnimj3vgBXuVb9bqF5iifjK-vgA","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Ass Slapping Is The Best Sport by penguinz0 1 year ago 5 minutes, 7 seconds 4,220,974 views"}},"simpleText":"Ass Slapping Is The Best Sport"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"4,220,974 views"},"navigationEndpoint":{"clickTrackingParams":"CMMFEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRPdF9ERkpnN0lhSkpDYUxwc0xKRXd6","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=AD9hWFgpc7g","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"AD9hWFgpc7g","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr7---sn-cxaaj5o5q5-tt1y.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=003f6158582973b8\u0026ip=74.12.195.102\u0026initcwndbps=1702500\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CMMFEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CMMFEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CMMFEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1VAuOelwYWr2B-qASJQTFJEN04tWnJqMkRPdF9ERkpnN0lhSkpDYUxwc0xKRXd6","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CMoFEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"4.2 million views"}},"simpleText":"4.2M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CMkFEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CMkFEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"AD9hWFgpc7g","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CMkFEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["AD9hWFgpc7g"],"params":"CAQ%3D"}},"videoIds":["AD9hWFgpc7g"]}}]}},"trackingParams":"CMkFEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CMMFEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"AD9hWFgpc7g","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CMMFEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CMgFEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"AD9hWFgpc7g"}},"trackingParams":"CMgFEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CMcFENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"AD9hWFgpc7g","onAddCommand":{"clickTrackingParams":"CMcFENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"AD9hWFgpc7g","params":"CAI%3D"}}}},"trackingParams":"CMcFENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CMMFEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtBRDloV0ZncGM3Zw%3D%3D","commands":[{"clickTrackingParams":"CMMFEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CMYFEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CMMFEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CMMFEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"5 minutes, 7 seconds"}},"simpleText":"5:07"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CMUFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"AD9hWFgpc7g","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CMUFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"AD9hWFgpc7g"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CMUFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CMQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CMQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"AD9hWFgpc7g","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CMQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["AD9hWFgpc7g"],"params":"CAQ%3D"}},"videoIds":["AD9hWFgpc7g"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CMQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}]}},{"gridVideoRenderer":{"videoId":"s-iOSMr17Yw","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/s-iOSMr17Yw/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBXXibaQdvVzEI3ccC6aR48KtaV_g","width":168,"height":94},{"url":"https://i.ytimg.com/vi/s-iOSMr17Yw/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBvxWGVALhn37QrHzIhBotb9v6q9Q","width":196,"height":110},{"url":"https://i.ytimg.com/vi/s-iOSMr17Yw/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAKIjgTKZ0ycib6o-URCWe8zAEG4g","width":246,"height":138},{"url":"https://i.ytimg.com/vi/s-iOSMr17Yw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAIyh4fgeWL7qc6vYHqYTDevljLsA","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"My New Favorite Slap Warrior by penguinz0 1 year ago 9 minutes, 8 seconds 5,884,521 views"}},"simpleText":"My New Favorite Slap Warrior"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"5,884,521 views"},"navigationEndpoint":{"clickTrackingParams":"CLsFEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRPdF9ERkpnN0lhSkpDYUxwc0xKRXd6","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=s-iOSMr17Yw","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"s-iOSMr17Yw","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr7---sn-cxaaj5o5q5-tt1y.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=b3e88e48caf5ed8c\u0026ip=74.12.195.102\u0026initcwndbps=1702500\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CLsFEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CLsFEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CLsFEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1VAjNvX14zJo_SzAaoBIlBMUkQ3Ti1acmoyRE90X0RGSmc3SWFKSkNhTHBzTEpFd3o=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CMIFEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"5.8 million views"}},"simpleText":"5.8M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CMEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CMEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"s-iOSMr17Yw","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CMEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["s-iOSMr17Yw"],"params":"CAQ%3D"}},"videoIds":["s-iOSMr17Yw"]}}]}},"trackingParams":"CMEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CLsFEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"s-iOSMr17Yw","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CLsFEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CMAFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"s-iOSMr17Yw"}},"trackingParams":"CMAFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CL8FENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"s-iOSMr17Yw","onAddCommand":{"clickTrackingParams":"CL8FENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"s-iOSMr17Yw","params":"CAI%3D"}}}},"trackingParams":"CL8FENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CLsFEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtzLWlPU01yMTdZdw%3D%3D","commands":[{"clickTrackingParams":"CLsFEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CL4FEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CLsFEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CLsFEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"9 minutes, 8 seconds"}},"simpleText":"9:08"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CL0FEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"s-iOSMr17Yw","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CL0FEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"s-iOSMr17Yw"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CL0FEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CLwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CLwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"s-iOSMr17Yw","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CLwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["s-iOSMr17Yw"],"params":"CAQ%3D"}},"videoIds":["s-iOSMr17Yw"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CLwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/s-iOSMr17Yw/mqdefault_6s.webp?du=3000\u0026sqp=CIjbip8G\u0026rs=AOn4CLByUMBv0_hDfstxuC7FbcsydCHUPw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"aUr_r9mEhTo","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/aUr_r9mEhTo/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDvNIvP_NiKbvSKL0tmf--490ztmg","width":168,"height":94},{"url":"https://i.ytimg.com/vi/aUr_r9mEhTo/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBuOJcAnRj6F3p5qKcs-aKlpNtGFQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/aUr_r9mEhTo/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDcxgewf8peyU3dZcI2YApRxRzrlA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/aUr_r9mEhTo/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCiZxOm411FXWddAYPnOQqb-fMPQQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"King of Slapping Knockouts by penguinz0 1 year ago 5 minutes, 42 seconds 1,186,850 views"}},"simpleText":"King of Slapping Knockouts"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"1,186,850 views"},"navigationEndpoint":{"clickTrackingParams":"CLMFEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRPdF9ERkpnN0lhSkpDYUxwc0xKRXd6","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=aUr_r9mEhTo","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"aUr_r9mEhTo","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr4---sn-cxaaj5o5q5-tt1r.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=694affafd984853a\u0026ip=74.12.195.102\u0026initcwndbps=1643750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CLMFEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CLMFEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CLMFEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1VAuoqSzP31v6VpqgEiUExSRDdOLVpyajJET3RfREZKZzdJYUpKQ2FMcHNMSkV3eg==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CLoFEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.1 million views"}},"simpleText":"1.1M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CLkFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CLkFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"aUr_r9mEhTo","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CLkFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["aUr_r9mEhTo"],"params":"CAQ%3D"}},"videoIds":["aUr_r9mEhTo"]}}]}},"trackingParams":"CLkFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CLMFEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"aUr_r9mEhTo","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CLMFEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CLgFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"aUr_r9mEhTo"}},"trackingParams":"CLgFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CLcFENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"aUr_r9mEhTo","onAddCommand":{"clickTrackingParams":"CLcFENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"aUr_r9mEhTo","params":"CAI%3D"}}}},"trackingParams":"CLcFENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CLMFEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgthVXJfcjltRWhUbw%3D%3D","commands":[{"clickTrackingParams":"CLMFEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CLYFEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CLMFEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CLMFEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"5 minutes, 42 seconds"}},"simpleText":"5:42"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CLUFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"aUr_r9mEhTo","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CLUFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"aUr_r9mEhTo"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CLUFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CLQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CLQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"aUr_r9mEhTo","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CLQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["aUr_r9mEhTo"],"params":"CAQ%3D"}},"videoIds":["aUr_r9mEhTo"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CLQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/aUr_r9mEhTo/mqdefault_6s.webp?du=3000\u0026sqp=CMDwip8G\u0026rs=AOn4CLAKLOyhLas3guaWJg-e3d0LiNDg8g","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"F7ZTCM5ahTA","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/F7ZTCM5ahTA/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBwplVGn3DiR4exmNri9tod98861g","width":168,"height":94},{"url":"https://i.ytimg.com/vi/F7ZTCM5ahTA/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLC7Zp1I7E4ozTDGpmLGDPBITjP8xA","width":196,"height":110},{"url":"https://i.ytimg.com/vi/F7ZTCM5ahTA/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDPiKrqhXfXF91hdpRnTT5Qp6pcIw","width":246,"height":138},{"url":"https://i.ytimg.com/vi/F7ZTCM5ahTA/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAj9nzr7ZiTdNOF8e2PHoYDWAbeLQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"A Slapping Titan Has Arrived by penguinz0 1 year ago 6 minutes, 15 seconds 3,009,395 views"}},"simpleText":"A Slapping Titan Has Arrived"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"3,009,395 views"},"navigationEndpoint":{"clickTrackingParams":"CKsFEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRPdF9ERkpnN0lhSkpDYUxwc0xKRXd6","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=F7ZTCM5ahTA","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"F7ZTCM5ahTA","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1ez.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=17b65308ce5a8530\u0026ip=74.12.195.102\u0026initcwndbps=1915000\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CKsFEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CKsFEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CKsFEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1VAsIrq8ozhlNsXqgEiUExSRDdOLVpyajJET3RfREZKZzdJYUpKQ2FMcHNMSkV3eg==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CLIFEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"3 million views"}},"simpleText":"3M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CLEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CLEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"F7ZTCM5ahTA","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CLEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["F7ZTCM5ahTA"],"params":"CAQ%3D"}},"videoIds":["F7ZTCM5ahTA"]}}]}},"trackingParams":"CLEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CKsFEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"F7ZTCM5ahTA","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CKsFEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CLAFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"F7ZTCM5ahTA"}},"trackingParams":"CLAFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CK8FENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"F7ZTCM5ahTA","onAddCommand":{"clickTrackingParams":"CK8FENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"F7ZTCM5ahTA","params":"CAI%3D"}}}},"trackingParams":"CK8FENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CKsFEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtGN1pUQ001YWhUQQ%3D%3D","commands":[{"clickTrackingParams":"CKsFEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CK4FEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CKsFEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CKsFEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"6 minutes, 15 seconds"}},"simpleText":"6:15"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CK0FEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"F7ZTCM5ahTA","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CK0FEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"F7ZTCM5ahTA"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CK0FEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CKwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CKwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"F7ZTCM5ahTA","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CKwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["F7ZTCM5ahTA"],"params":"CAQ%3D"}},"videoIds":["F7ZTCM5ahTA"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CKwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/F7ZTCM5ahTA/mqdefault_6s.webp?du=3000\u0026sqp=CMD6ip8G\u0026rs=AOn4CLA0858ma0bWkorpq6u4sT22CMuBrw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"FbZG25p8cXU","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/FbZG25p8cXU/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBKCHy6C4IkzOF4NK6NeFfFwJqDbQ","width":168,"height":94},{"url":"https://i.ytimg.com/vi/FbZG25p8cXU/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAewaH3M2sAYMikY4aeOZ2DvDSb7Q","width":196,"height":110},{"url":"https://i.ytimg.com/vi/FbZG25p8cXU/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCriPfcxIlyCfaaHuNDFXdUECrbBw","width":246,"height":138},{"url":"https://i.ytimg.com/vi/FbZG25p8cXU/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAJQ0HPADMYn41YnjyZe4iFxwe6fw","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Hardest Knockout Ever by penguinz0 1 year ago 4 minutes, 13 seconds 1,954,237 views"}},"simpleText":"Hardest Knockout Ever"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"1,954,237 views"},"navigationEndpoint":{"clickTrackingParams":"CKMFEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRPdF9ERkpnN0lhSkpDYUxwc0xKRXd6","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=FbZG25p8cXU","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"FbZG25p8cXU","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr4---sn-cxaaj5o5q5-tt1e6.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=15b646db9a7c7175\u0026ip=74.12.195.102\u0026initcwndbps=1521250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CKMFEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CKMFEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CKMFEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1VA9eLx07nbkdsVqgEiUExSRDdOLVpyajJET3RfREZKZzdJYUpKQ2FMcHNMSkV3eg==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CKoFEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.9 million views"}},"simpleText":"1.9M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CKkFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CKkFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"FbZG25p8cXU","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CKkFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["FbZG25p8cXU"],"params":"CAQ%3D"}},"videoIds":["FbZG25p8cXU"]}}]}},"trackingParams":"CKkFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CKMFEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"FbZG25p8cXU","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CKMFEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CKgFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"FbZG25p8cXU"}},"trackingParams":"CKgFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CKcFENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"FbZG25p8cXU","onAddCommand":{"clickTrackingParams":"CKcFENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"FbZG25p8cXU","params":"CAI%3D"}}}},"trackingParams":"CKcFENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CKMFEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtGYlpHMjVwOGNYVQ%3D%3D","commands":[{"clickTrackingParams":"CKMFEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CKYFEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CKMFEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CKMFEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"4 minutes, 13 seconds"}},"simpleText":"4:13"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CKUFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"FbZG25p8cXU","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CKUFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"FbZG25p8cXU"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CKUFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CKQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CKQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"FbZG25p8cXU","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CKQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["FbZG25p8cXU"],"params":"CAQ%3D"}},"videoIds":["FbZG25p8cXU"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CKQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/FbZG25p8cXU/mqdefault_6s.webp?du=3000\u0026sqp=COyEi58G\u0026rs=AOn4CLDp0ALravrxnVdTF5pl2NZG6nEj8w","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"38rCjYAjQJE","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/38rCjYAjQJE/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCdfYtuRKm5EKqgPaZ-2-zW-GsvtQ","width":168,"height":94},{"url":"https://i.ytimg.com/vi/38rCjYAjQJE/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLD_f8mpBxS_7mOLbc9HtwN8PfdyYQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/38rCjYAjQJE/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBJLZo2TuJFMHkWAO8rei5dm28EBA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/38rCjYAjQJE/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCFlIf_w_uxQU-F-Wz69ja0LaInBQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Slapping Monster Just Can't Lose by penguinz0 1 year ago 10 minutes, 15 seconds 1,398,261 views"}},"simpleText":"Slapping Monster Just Can't Lose"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"1,398,261 views"},"navigationEndpoint":{"clickTrackingParams":"CJsFEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRPdF9ERkpnN0lhSkpDYUxwc0xKRXd6","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=38rCjYAjQJE","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"38rCjYAjQJE","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr6---sn-cxaaj5o5q5-tt1r.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=dfcac28d80234091\u0026ip=74.12.195.102\u0026initcwndbps=1643750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CJsFEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CJsFEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CJsFEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1VAkYGNgdjRsOXfAaoBIlBMUkQ3Ti1acmoyRE90X0RGSmc3SWFKSkNhTHBzTEpFd3o=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CKIFEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.3 million views"}},"simpleText":"1.3M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CKEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CKEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"38rCjYAjQJE","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CKEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["38rCjYAjQJE"],"params":"CAQ%3D"}},"videoIds":["38rCjYAjQJE"]}}]}},"trackingParams":"CKEFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CJsFEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"38rCjYAjQJE","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CJsFEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CKAFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"38rCjYAjQJE"}},"trackingParams":"CKAFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CJ8FENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"38rCjYAjQJE","onAddCommand":{"clickTrackingParams":"CJ8FENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"38rCjYAjQJE","params":"CAI%3D"}}}},"trackingParams":"CJ8FENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CJsFEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgszOHJDallBalFKRQ%3D%3D","commands":[{"clickTrackingParams":"CJsFEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CJ4FEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CJsFEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CJsFEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"10 minutes, 15 seconds"}},"simpleText":"10:15"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CJ0FEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"38rCjYAjQJE","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CJ0FEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"38rCjYAjQJE"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CJ0FEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CJwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CJwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"38rCjYAjQJE","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CJwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["38rCjYAjQJE"],"params":"CAQ%3D"}},"videoIds":["38rCjYAjQJE"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CJwFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/38rCjYAjQJE/mqdefault_6s.webp?du=3000\u0026sqp=CNvhip8G\u0026rs=AOn4CLCUDVX0XM5CMUNnR_MEQm78Ys0WQw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"7rDKdwhJ-y0","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/7rDKdwhJ-y0/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCP4D2ibg-uIs9lviswmmctOG5n2A","width":168,"height":94},{"url":"https://i.ytimg.com/vi/7rDKdwhJ-y0/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBVy6UyMLeK9U_E3JOi-eKO8OaXSw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/7rDKdwhJ-y0/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLA4-oqm4U-HL62rVUGWh5HPkzTOLw","width":246,"height":138},{"url":"https://i.ytimg.com/vi/7rDKdwhJ-y0/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLC-WnsYZQRNpXp4qjOCWnsRClP6uQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The King Is Back by penguinz0 1 year ago 9 minutes, 31 seconds 2,832,984 views"}},"simpleText":"The King Is Back"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"2,832,984 views"},"navigationEndpoint":{"clickTrackingParams":"CJMFEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRPdF9ERkpnN0lhSkpDYUxwc0xKRXd6","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=7rDKdwhJ-y0","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"7rDKdwhJ-y0","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=eeb0ca770849fb2d\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CJMFEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CJMFEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CJMFEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1VArfanwvDOstjuAaoBIlBMUkQ3Ti1acmoyRE90X0RGSmc3SWFKSkNhTHBzTEpFd3o=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CJoFEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2.8 million views"}},"simpleText":"2.8M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CJkFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CJkFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"7rDKdwhJ-y0","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CJkFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["7rDKdwhJ-y0"],"params":"CAQ%3D"}},"videoIds":["7rDKdwhJ-y0"]}}]}},"trackingParams":"CJkFEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CJMFEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"7rDKdwhJ-y0","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CJMFEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CJgFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"7rDKdwhJ-y0"}},"trackingParams":"CJgFEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CJcFENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"7rDKdwhJ-y0","onAddCommand":{"clickTrackingParams":"CJcFENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"7rDKdwhJ-y0","params":"CAI%3D"}}}},"trackingParams":"CJcFENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CJMFEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs3ckRLZHdoSi15MA%3D%3D","commands":[{"clickTrackingParams":"CJMFEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CJYFEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CJMFEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CJMFEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"9 minutes, 31 seconds"}},"simpleText":"9:31"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CJUFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"7rDKdwhJ-y0","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CJUFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"7rDKdwhJ-y0"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CJUFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CJQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CJQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"7rDKdwhJ-y0","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CJQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["7rDKdwhJ-y0"],"params":"CAQ%3D"}},"videoIds":["7rDKdwhJ-y0"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CJQFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/7rDKdwhJ-y0/mqdefault_6s.webp?du=3000\u0026sqp=CP7iip8G\u0026rs=AOn4CLDgLC6HOzgWOivkp6vgUK-dWFjZUw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}}],"trackingParams":"CJAFEMY5IhMI-Mm_pq2E_QIVEIf_BB2wqAtV","visibleItemCount":4,"nextButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"CHEVRON_RIGHT"},"accessibility":{"label":"Next"},"trackingParams":"CJIFEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},"previousButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"CHEVRON_LEFT"},"accessibility":{"label":"Previous"},"trackingParams":"CJEFEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}}}},"trackingParams":"CI4FENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","playAllButton":{"buttonRenderer":{"style":"STYLE_TEXT","size":"SIZE_DEFAULT","isDisabled":false,"text":{"runs":[{"text":"Play all"}]},"icon":{"iconType":"PLAY_ALL"},"navigationEndpoint":{"clickTrackingParams":"CI8FEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=gXJ1_i2cJQk\u0026list=PLRD7N-Zrj2DOt_DFJg7IaJJCaLpsLJEwz","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"gXJ1_i2cJQk","playlistId":"PLRD7N-Zrj2DOt_DFJg7IaJJCaLpsLJEwz","loggingContext":{"vssLoggingContext":{"serializedContextData":"GiJQTFJEN04tWnJqMkRPdF9ERkpnN0lhSkpDYUxwc0xKRXd6"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr8---sn-cxaaj5o5q5-tt1es.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=817275fe2d9c2509\u0026ip=74.12.195.102\u0026initcwndbps=1656250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"trackingParams":"CI8FEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}}}}],"trackingParams":"CI0FELsvGAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"itemSectionRenderer":{"contents":[{"shelfRenderer":{"title":{"runs":[{"text":"Music","navigationEndpoint":{"clickTrackingParams":"CMAEENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLRD7N-Zrj2DNLqPJ4tFE9gk6Ek4FC3l7_","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLRD7N-Zrj2DNLqPJ4tFE9gk6Ek4FC3l7_"}}}]},"endpoint":{"clickTrackingParams":"CMAEENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLRD7N-Zrj2DNLqPJ4tFE9gk6Ek4FC3l7_","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLRD7N-Zrj2DNLqPJ4tFE9gk6Ek4FC3l7_"}},"content":{"horizontalListRenderer":{"items":[{"gridVideoRenderer":{"videoId":"BR_WkKvLjJ4","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/BR_WkKvLjJ4/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDJp5JQxeXxERp6Gu4NhOPQtDx3Uw","width":168,"height":94},{"url":"https://i.ytimg.com/vi/BR_WkKvLjJ4/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCvNdLI17K7tJpqigO8ikOsqCHSRg","width":196,"height":110},{"url":"https://i.ytimg.com/vi/BR_WkKvLjJ4/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLD0HoMyWwZwPD00Ej1MVf0hBHUe7g","width":246,"height":138},{"url":"https://i.ytimg.com/vi/BR_WkKvLjJ4/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCUGgqUmY3ANc6C1knaX26pMdD6xg","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Gentle Men - Here's to Us by penguinz0 1 year ago 4 minutes 1,411,816 views"}},"simpleText":"The Gentle Men - Here's to Us"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"1,411,816 views"},"navigationEndpoint":{"clickTrackingParams":"CIUFEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkROTHFQSjR0RkU5Z2s2RWs0RkMzbDdf","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=BR_WkKvLjJ4","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"BR_WkKvLjJ4","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr4---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=051fd690abcb8c9e\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CIUFEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CIUFEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CIUFEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1VAnpmu3orS9Y8FqgEiUExSRDdOLVpyajJETkxxUEo0dEZFOWdrNkVrNEZDM2w3Xw==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CIwFEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.4 million views"}},"simpleText":"1.4M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CIsFEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CIsFEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"BR_WkKvLjJ4","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CIsFEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["BR_WkKvLjJ4"],"params":"CAQ%3D"}},"videoIds":["BR_WkKvLjJ4"]}}]}},"trackingParams":"CIsFEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CIUFEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"BR_WkKvLjJ4","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CIUFEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CIoFEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"BR_WkKvLjJ4"}},"trackingParams":"CIoFEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CIkFENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"BR_WkKvLjJ4","onAddCommand":{"clickTrackingParams":"CIkFENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"BR_WkKvLjJ4","params":"CAI%3D"}}}},"trackingParams":"CIkFENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CIUFEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtCUl9Xa0t2TGpKNA%3D%3D","commands":[{"clickTrackingParams":"CIUFEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CIgFEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CIUFEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CIUFEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"4 minutes"}},"simpleText":"4:00"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CIcFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"BR_WkKvLjJ4","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CIcFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"BR_WkKvLjJ4"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CIcFEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CIYFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CIYFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"BR_WkKvLjJ4","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CIYFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["BR_WkKvLjJ4"],"params":"CAQ%3D"}},"videoIds":["BR_WkKvLjJ4"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CIYFEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}]}},{"gridVideoRenderer":{"videoId":"-yPaY2lbwTE","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/-yPaY2lbwTE/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCX2zPG-JtzwCWrVyvdgSaK4LpGSg","width":168,"height":94},{"url":"https://i.ytimg.com/vi/-yPaY2lbwTE/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLABCh84z8DqicIWX2qDwfu10u3Wlw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/-yPaY2lbwTE/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAZKZVy-V6NE31hqZBgHIlxfKxlXA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/-yPaY2lbwTE/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCBsG5CM8lwTsGRGOmPoKLY25slaw","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Gentle Men - Perfect Oblivion by penguinz0 1 year ago 3 minutes, 20 seconds 1,505,177 views"}},"simpleText":"The Gentle Men - Perfect Oblivion"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"1,505,177 views"},"navigationEndpoint":{"clickTrackingParams":"CP0EEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkROTHFQSjR0RkU5Z2s2RWs0RkMzbDdf","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=-yPaY2lbwTE","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"-yPaY2lbwTE","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr5---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=fb23da63695bc131\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CP0EEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CP0EEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CP0EEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1VAsYLvyrbM9pH7AaoBIlBMUkQ3Ti1acmoyRE5McVBKNHRGRTlnazZFazRGQzNsN18=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CIQFEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.5 million views"}},"simpleText":"1.5M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CIMFEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CIMFEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"-yPaY2lbwTE","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CIMFEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["-yPaY2lbwTE"],"params":"CAQ%3D"}},"videoIds":["-yPaY2lbwTE"]}}]}},"trackingParams":"CIMFEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CP0EEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"-yPaY2lbwTE","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CP0EEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CIIFEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"-yPaY2lbwTE"}},"trackingParams":"CIIFEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CIEFENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"-yPaY2lbwTE","onAddCommand":{"clickTrackingParams":"CIEFENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"-yPaY2lbwTE","params":"CAI%3D"}}}},"trackingParams":"CIEFENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CP0EEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgsteVBhWTJsYndURQ%3D%3D","commands":[{"clickTrackingParams":"CP0EEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CIAFEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CP0EEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CP0EEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"3 minutes, 20 seconds"}},"simpleText":"3:20"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CP8EEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"-yPaY2lbwTE","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CP8EEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"-yPaY2lbwTE"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CP8EEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CP4EEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CP4EEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"-yPaY2lbwTE","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CP4EEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["-yPaY2lbwTE"],"params":"CAQ%3D"}},"videoIds":["-yPaY2lbwTE"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CP4EEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}]}},{"gridVideoRenderer":{"videoId":"7hZS3N_FWPI","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/7hZS3N_FWPI/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLA171ED08CZTfluX2sHFXRlkpvuwA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/7hZS3N_FWPI/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAxBoTt8KorsTjEQOx7vmt6OZKnDA","width":196,"height":110},{"url":"https://i.ytimg.com/vi/7hZS3N_FWPI/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCnEPtEleiPtsHNeP0k3gvO6RisrA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/7hZS3N_FWPI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBpMRHC7ps9oTmhmpGLfQgUX9fqcA","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Gentle Men - Your Boyfriend Doesn't Scare Me ft. KMac2021 by penguinz0 1 year ago 4 minutes, 23 seconds 3,947,067 views"}},"simpleText":"The Gentle Men - Your Boyfriend Doesn't Scare Me ft. KMac2021"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"3,947,067 views"},"navigationEndpoint":{"clickTrackingParams":"CPUEEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkROTHFQSjR0RkU5Z2s2RWs0RkMzbDdf","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=7hZS3N_FWPI","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"7hZS3N_FWPI","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr8---sn-cxaaj5o5q5-tt1e6.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=ee1652dcdfc558f2\u0026ip=74.12.195.102\u0026initcwndbps=1521250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CPUEEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CPUEEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CPUEEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1VA8rGV_s3blIvuAaoBIlBMUkQ3Ti1acmoyRE5McVBKNHRGRTlnazZFazRGQzNsN18=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CPwEEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"3.9 million views"}},"simpleText":"3.9M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CPsEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CPsEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"7hZS3N_FWPI","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CPsEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["7hZS3N_FWPI"],"params":"CAQ%3D"}},"videoIds":["7hZS3N_FWPI"]}}]}},"trackingParams":"CPsEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CPUEEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"7hZS3N_FWPI","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CPUEEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CPoEEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"7hZS3N_FWPI"}},"trackingParams":"CPoEEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CPkEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"7hZS3N_FWPI","onAddCommand":{"clickTrackingParams":"CPkEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"7hZS3N_FWPI","params":"CAI%3D"}}}},"trackingParams":"CPkEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CPUEEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs3aFpTM05fRldQSQ%3D%3D","commands":[{"clickTrackingParams":"CPUEEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CPgEEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CPUEEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CPUEEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"4 minutes, 23 seconds"}},"simpleText":"4:23"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CPcEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"7hZS3N_FWPI","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CPcEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"7hZS3N_FWPI"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CPcEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CPYEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CPYEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"7hZS3N_FWPI","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CPYEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["7hZS3N_FWPI"],"params":"CAQ%3D"}},"videoIds":["7hZS3N_FWPI"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CPYEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}]}},{"gridVideoRenderer":{"videoId":"K9lUuVIBOJ0","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/K9lUuVIBOJ0/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBWdE906PezaCP90PKeN3-xZJg-Kg","width":168,"height":94},{"url":"https://i.ytimg.com/vi/K9lUuVIBOJ0/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAuqGorp2CjmpuVMKLVQ3oimTMsEg","width":196,"height":110},{"url":"https://i.ytimg.com/vi/K9lUuVIBOJ0/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBgGqbIZ0UhvdKhaVJLqe-7DGfZoA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/K9lUuVIBOJ0/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCfuKj_ntt8DWL-TqbbFAAAbh4CUQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Gentle Men - I Am Truth by penguinz0 2 years ago 3 minutes, 44 seconds 2,170,720 views"}},"simpleText":"The Gentle Men - I Am Truth"},"publishedTimeText":{"simpleText":"2 years ago"},"viewCountText":{"simpleText":"2,170,720 views"},"navigationEndpoint":{"clickTrackingParams":"CO0EEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkROTHFQSjR0RkU5Z2s2RWs0RkMzbDdf","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=K9lUuVIBOJ0","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"K9lUuVIBOJ0","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr7---sn-cxaaj5o5q5-tt1y.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=2bd954b95201389d\u0026ip=74.12.195.102\u0026initcwndbps=1702500\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CO0EEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CO0EEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CO0EEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1VAnfGEkJWX1ewrqgEiUExSRDdOLVpyajJETkxxUEo0dEZFOWdrNkVrNEZDM2w3Xw==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CPQEEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2.1 million views"}},"simpleText":"2.1M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CPMEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CPMEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"K9lUuVIBOJ0","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CPMEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["K9lUuVIBOJ0"],"params":"CAQ%3D"}},"videoIds":["K9lUuVIBOJ0"]}}]}},"trackingParams":"CPMEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CO0EEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"K9lUuVIBOJ0","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CO0EEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CPIEEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"K9lUuVIBOJ0"}},"trackingParams":"CPIEEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CPEEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"K9lUuVIBOJ0","onAddCommand":{"clickTrackingParams":"CPEEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"K9lUuVIBOJ0","params":"CAI%3D"}}}},"trackingParams":"CPEEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CO0EEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtLOWxVdVZJQk9KMA%3D%3D","commands":[{"clickTrackingParams":"CO0EEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CPAEEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CO0EEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CO0EEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"3 minutes, 44 seconds"}},"simpleText":"3:44"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CO8EEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"K9lUuVIBOJ0","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CO8EEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"K9lUuVIBOJ0"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CO8EEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CO4EEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CO4EEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"K9lUuVIBOJ0","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CO4EEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["K9lUuVIBOJ0"],"params":"CAQ%3D"}},"videoIds":["K9lUuVIBOJ0"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CO4EEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}]}},{"gridVideoRenderer":{"videoId":"gGj_D6oI4e8","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/gGj_D6oI4e8/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDgXCht2aq_YFudlgOXIPBILA4Xaw","width":168,"height":94},{"url":"https://i.ytimg.com/vi/gGj_D6oI4e8/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLA6AAZfCvWr2mxws7YZLqJgKuVoTQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/gGj_D6oI4e8/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCQPxCuKldKreP0QKrhhxwuD5KogA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/gGj_D6oI4e8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLA-OoOE9i18ylm6Wk7OQNdCMmvebg","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Gentle Men - 2004 Breakup by penguinz0 2 years ago 3 minutes, 32 seconds 3,730,705 views"}},"simpleText":"The Gentle Men - 2004 Breakup"},"publishedTimeText":{"simpleText":"2 years ago"},"viewCountText":{"simpleText":"3,730,705 views"},"navigationEndpoint":{"clickTrackingParams":"COUEEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkROTHFQSjR0RkU5Z2s2RWs0RkMzbDdf","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=gGj_D6oI4e8","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"gGj_D6oI4e8","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr4---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=8068ff0faa08e1ef\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"COUEEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"COUEEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"COUEEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1VA78Oj0Prhv7SAAaoBIlBMUkQ3Ti1acmoyRE5McVBKNHRGRTlnazZFazRGQzNsN18=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"COwEEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"3.7 million views"}},"simpleText":"3.7M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"COsEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"COsEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"gGj_D6oI4e8","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"COsEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["gGj_D6oI4e8"],"params":"CAQ%3D"}},"videoIds":["gGj_D6oI4e8"]}}]}},"trackingParams":"COsEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"COUEEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"gGj_D6oI4e8","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"COUEEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"COoEEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"gGj_D6oI4e8"}},"trackingParams":"COoEEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"COkEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"gGj_D6oI4e8","onAddCommand":{"clickTrackingParams":"COkEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"gGj_D6oI4e8","params":"CAI%3D"}}}},"trackingParams":"COkEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"COUEEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtnR2pfRDZvSTRlOA%3D%3D","commands":[{"clickTrackingParams":"COUEEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"COgEEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"COUEEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"COUEEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"3 minutes, 32 seconds"}},"simpleText":"3:32"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"COcEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"gGj_D6oI4e8","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"COcEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"gGj_D6oI4e8"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"COcEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"COYEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"COYEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"gGj_D6oI4e8","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"COYEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["gGj_D6oI4e8"],"params":"CAQ%3D"}},"videoIds":["gGj_D6oI4e8"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"COYEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}]}},{"gridVideoRenderer":{"videoId":"FOeBaPVwRsE","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/FOeBaPVwRsE/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDfWc35qhwOS3f1jJk_gWzZ-Sbkqg","width":168,"height":94},{"url":"https://i.ytimg.com/vi/FOeBaPVwRsE/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDolLvep_DGGZ9DS2VGLnyyDISyYw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/FOeBaPVwRsE/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDSMmZgonI7UKSDxs5zzX49jhE67w","width":246,"height":138},{"url":"https://i.ytimg.com/vi/FOeBaPVwRsE/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAcGRB0Wur5Kh95_DkE129DYqLZIw","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Gentle Men - Skynut by penguinz0 2 years ago 4 minutes, 20 seconds 6,518,660 views"}},"simpleText":"The Gentle Men - Skynut"},"publishedTimeText":{"simpleText":"2 years ago"},"viewCountText":{"simpleText":"6,518,660 views"},"navigationEndpoint":{"clickTrackingParams":"CN0EEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkROTHFQSjR0RkU5Z2s2RWs0RkMzbDdf","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=FOeBaPVwRsE","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"FOeBaPVwRsE","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr5---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=14e78168f57046c1\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CN0EEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CN0EEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CN0EEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1VAwY3Bq4-t4PMUqgEiUExSRDdOLVpyajJETkxxUEo0dEZFOWdrNkVrNEZDM2w3Xw==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"COQEEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"6.5 million views"}},"simpleText":"6.5M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"COMEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"COMEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"FOeBaPVwRsE","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"COMEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["FOeBaPVwRsE"],"params":"CAQ%3D"}},"videoIds":["FOeBaPVwRsE"]}}]}},"trackingParams":"COMEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CN0EEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"FOeBaPVwRsE","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CN0EEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"COIEEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"FOeBaPVwRsE"}},"trackingParams":"COIEEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"COEEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"FOeBaPVwRsE","onAddCommand":{"clickTrackingParams":"COEEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"FOeBaPVwRsE","params":"CAI%3D"}}}},"trackingParams":"COEEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CN0EEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtGT2VCYVBWd1JzRQ%3D%3D","commands":[{"clickTrackingParams":"CN0EEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"COAEEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CN0EEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CN0EEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"4 minutes, 20 seconds"}},"simpleText":"4:20"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CN8EEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"FOeBaPVwRsE","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CN8EEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"FOeBaPVwRsE"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CN8EEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CN4EEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CN4EEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"FOeBaPVwRsE","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CN4EEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["FOeBaPVwRsE"],"params":"CAQ%3D"}},"videoIds":["FOeBaPVwRsE"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CN4EEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}]}},{"gridVideoRenderer":{"videoId":"M7zwoO6zfVs","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/M7zwoO6zfVs/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBJ8ZWDtP42OvGLVcHtwRKKKpIfuQ","width":168,"height":94},{"url":"https://i.ytimg.com/vi/M7zwoO6zfVs/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAGk26MXJpRJsKC5zbpYUYTjFLyiw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/M7zwoO6zfVs/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCYQUqRUcsDcr7mUbFtKFlfNZqNqQ","width":246,"height":138},{"url":"https://i.ytimg.com/vi/M7zwoO6zfVs/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLA96atHSfkcIHiEkPHZ2rMfyHCESQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Gentle Men - Real To Me by penguinz0 2 years ago 4 minutes, 58 seconds 3,442,186 views"}},"simpleText":"The Gentle Men - Real To Me"},"publishedTimeText":{"simpleText":"2 years ago"},"viewCountText":{"simpleText":"3,442,186 views"},"navigationEndpoint":{"clickTrackingParams":"CNUEEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkROTHFQSjR0RkU5Z2s2RWs0RkMzbDdf","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=M7zwoO6zfVs","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"M7zwoO6zfVs","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr5---sn-cxaaj5o5q5-tt1ee.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=33bcf0a0eeb37d5b\u0026ip=74.12.195.102\u0026initcwndbps=1816250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CNUEEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CNUEEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CNUEEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1VA2_rN9Y6UvN4zqgEiUExSRDdOLVpyajJETkxxUEo0dEZFOWdrNkVrNEZDM2w3Xw==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CNwEEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"3.4 million views"}},"simpleText":"3.4M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CNsEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CNsEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"M7zwoO6zfVs","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CNsEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["M7zwoO6zfVs"],"params":"CAQ%3D"}},"videoIds":["M7zwoO6zfVs"]}}]}},"trackingParams":"CNsEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CNUEEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"M7zwoO6zfVs","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CNUEEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CNoEEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"M7zwoO6zfVs"}},"trackingParams":"CNoEEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CNkEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"M7zwoO6zfVs","onAddCommand":{"clickTrackingParams":"CNkEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"M7zwoO6zfVs","params":"CAI%3D"}}}},"trackingParams":"CNkEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CNUEEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtNN3p3b082emZWcw%3D%3D","commands":[{"clickTrackingParams":"CNUEEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CNgEEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CNUEEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CNUEEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"4 minutes, 58 seconds"}},"simpleText":"4:58"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CNcEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"M7zwoO6zfVs","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CNcEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"M7zwoO6zfVs"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CNcEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CNYEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CNYEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"M7zwoO6zfVs","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CNYEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["M7zwoO6zfVs"],"params":"CAQ%3D"}},"videoIds":["M7zwoO6zfVs"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CNYEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}]}},{"gridVideoRenderer":{"videoId":"u-R9p7wHai8","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/u-R9p7wHai8/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAnNZfE01tBNEsrXUoFosgkqvSlJA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/u-R9p7wHai8/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDH10cSaoqziLZ93caFUG3CknSyMQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/u-R9p7wHai8/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDGVtYkTNyM1WqPrFO6JwA4frBaiw","width":246,"height":138},{"url":"https://i.ytimg.com/vi/u-R9p7wHai8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLB5af9rzVLo7fFKpEFyl5utGFfcQQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Gentle Men - Obsession by penguinz0 2 years ago 3 minutes, 32 seconds 3,752,780 views"}},"simpleText":"The Gentle Men - Obsession"},"publishedTimeText":{"simpleText":"2 years ago"},"viewCountText":{"simpleText":"3,752,780 views"},"navigationEndpoint":{"clickTrackingParams":"CM0EEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkROTHFQSjR0RkU5Z2s2RWs0RkMzbDdf","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=u-R9p7wHai8","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"u-R9p7wHai8","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr2---sn-cxaaj5o5q5-tt1es.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=bbe47da7bc076a2f\u0026ip=74.12.195.102\u0026initcwndbps=1656250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CM0EEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CM0EEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CM0EEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1VAr9Sd4Pu0n_K7AaoBIlBMUkQ3Ti1acmoyRE5McVBKNHRGRTlnazZFazRGQzNsN18=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CNQEEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"3.7 million views"}},"simpleText":"3.7M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CNMEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CNMEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"u-R9p7wHai8","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CNMEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["u-R9p7wHai8"],"params":"CAQ%3D"}},"videoIds":["u-R9p7wHai8"]}}]}},"trackingParams":"CNMEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CM0EEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"u-R9p7wHai8","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CM0EEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CNIEEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"u-R9p7wHai8"}},"trackingParams":"CNIEEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CNEEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"u-R9p7wHai8","onAddCommand":{"clickTrackingParams":"CNEEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"u-R9p7wHai8","params":"CAI%3D"}}}},"trackingParams":"CNEEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CM0EEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgt1LVI5cDd3SGFpOA%3D%3D","commands":[{"clickTrackingParams":"CM0EEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CNAEEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CM0EEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CM0EEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"3 minutes, 32 seconds"}},"simpleText":"3:32"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CM8EEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"u-R9p7wHai8","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CM8EEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"u-R9p7wHai8"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CM8EEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CM4EEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CM4EEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"u-R9p7wHai8","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CM4EEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["u-R9p7wHai8"],"params":"CAQ%3D"}},"videoIds":["u-R9p7wHai8"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CM4EEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}]}},{"gridVideoRenderer":{"videoId":"4SiiRx7GDzI","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/4SiiRx7GDzI/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAloToOMkQ_UnRgPs_zWqedv-yKPg","width":168,"height":94},{"url":"https://i.ytimg.com/vi/4SiiRx7GDzI/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAEvv6oQGGVCun35xkEWhdDogP8gw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/4SiiRx7GDzI/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBW0CBaMNG4NQ10pf9hcMA1gN8lpg","width":246,"height":138},{"url":"https://i.ytimg.com/vi/4SiiRx7GDzI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLA7nF8QTKSirUwJSY97VQ31d3_nOw","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Gentle Men - 2019 Guy by penguinz0 3 years ago 3 minutes, 19 seconds 10,686,740 views"}},"simpleText":"The Gentle Men - 2019 Guy"},"publishedTimeText":{"simpleText":"3 years ago"},"viewCountText":{"simpleText":"10,686,740 views"},"navigationEndpoint":{"clickTrackingParams":"CMUEEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkROTHFQSjR0RkU5Z2s2RWs0RkMzbDdf","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=4SiiRx7GDzI","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"4SiiRx7GDzI","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=e128a2471ec60f32\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CMUEEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CMUEEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CMUEEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1VAsp6Y9vHIqJThAaoBIlBMUkQ3Ti1acmoyRE5McVBKNHRGRTlnazZFazRGQzNsN18=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CMwEEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"10 million views"}},"simpleText":"10M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CMsEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CMsEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"4SiiRx7GDzI","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CMsEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["4SiiRx7GDzI"],"params":"CAQ%3D"}},"videoIds":["4SiiRx7GDzI"]}}]}},"trackingParams":"CMsEEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CMUEEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"4SiiRx7GDzI","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CMUEEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CMoEEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"4SiiRx7GDzI"}},"trackingParams":"CMoEEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CMkEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"4SiiRx7GDzI","onAddCommand":{"clickTrackingParams":"CMkEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"4SiiRx7GDzI","params":"CAI%3D"}}}},"trackingParams":"CMkEENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CMUEEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs0U2lpUng3R0R6SQ%3D%3D","commands":[{"clickTrackingParams":"CMUEEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CMgEEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CMUEEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CMUEEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"3 minutes, 19 seconds"}},"simpleText":"3:19"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CMcEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"4SiiRx7GDzI","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CMcEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"4SiiRx7GDzI"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CMcEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CMYEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CMYEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"4SiiRx7GDzI","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CMYEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["4SiiRx7GDzI"],"params":"CAQ%3D"}},"videoIds":["4SiiRx7GDzI"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CMYEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}]}}],"trackingParams":"CMIEEMY5IhMI-Mm_pq2E_QIVEIf_BB2wqAtV","visibleItemCount":4,"nextButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"CHEVRON_RIGHT"},"accessibility":{"label":"Next"},"trackingParams":"CMQEEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},"previousButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"CHEVRON_LEFT"},"accessibility":{"label":"Previous"},"trackingParams":"CMMEEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}}}},"trackingParams":"CMAEENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","playAllButton":{"buttonRenderer":{"style":"STYLE_TEXT","size":"SIZE_DEFAULT","isDisabled":false,"text":{"runs":[{"text":"Play all"}]},"icon":{"iconType":"PLAY_ALL"},"navigationEndpoint":{"clickTrackingParams":"CMEEEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=BR_WkKvLjJ4\u0026list=PLRD7N-Zrj2DNLqPJ4tFE9gk6Ek4FC3l7_","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"BR_WkKvLjJ4","playlistId":"PLRD7N-Zrj2DNLqPJ4tFE9gk6Ek4FC3l7_","loggingContext":{"vssLoggingContext":{"serializedContextData":"GiJQTFJEN04tWnJqMkROTHFQSjR0RkU5Z2s2RWs0RkMzbDdf"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr4---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=051fd690abcb8c9e\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"trackingParams":"CMEEEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}}}}],"trackingParams":"CL8EELsvGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"itemSectionRenderer":{"contents":[{"shelfRenderer":{"title":{"runs":[{"text":"Tier List","navigationEndpoint":{"clickTrackingParams":"CNoDENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLRD7N-Zrj2DMUJAlXRGKpeEel-7isQjI1","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLRD7N-Zrj2DMUJAlXRGKpeEel-7isQjI1"}}}]},"endpoint":{"clickTrackingParams":"CNoDENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLRD7N-Zrj2DMUJAlXRGKpeEel-7isQjI1","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLRD7N-Zrj2DMUJAlXRGKpeEel-7isQjI1"}},"content":{"horizontalListRenderer":{"items":[{"gridVideoRenderer":{"videoId":"8HSwDqwGzrc","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/8HSwDqwGzrc/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBCd8h9gyf9sOcQzqM7US_Hx2sanA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/8HSwDqwGzrc/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDZ9WmtNDRqIA2YFVuHdK72uWCZPw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/8HSwDqwGzrc/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAJJ-y9nt_nvZKNIlxHSFXOz_gEVA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/8HSwDqwGzrc/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDCquPy7ryv7VnErwgTgRRyJbot-g","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Dipping Sauces Tier List by penguinz0 1 year ago 28 minutes 1,759,579 views"}},"simpleText":"Dipping Sauces Tier List"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"1,759,579 views"},"navigationEndpoint":{"clickTrackingParams":"CLcEEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNVUpBbFhSR0twZUVlbC03aXNRakkx","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=8HSwDqwGzrc","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"8HSwDqwGzrc","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr2---sn-cxaaj5o5q5-tt1ee.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=f074b00eac06ceb7\u0026ip=74.12.195.102\u0026initcwndbps=1816250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CLcEEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CLcEEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CLcEEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1VAt52b4OqBrLrwAaoBIlBMUkQ3Ti1acmoyRE1VSkFsWFJHS3BlRWVsLTdpc1FqSTE=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CL4EEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.7 million views"}},"simpleText":"1.7M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CL0EEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CL0EEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"8HSwDqwGzrc","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CL0EEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["8HSwDqwGzrc"],"params":"CAQ%3D"}},"videoIds":["8HSwDqwGzrc"]}}]}},"trackingParams":"CL0EEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CLcEEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"8HSwDqwGzrc","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CLcEEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CLwEEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"8HSwDqwGzrc"}},"trackingParams":"CLwEEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CLsEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"8HSwDqwGzrc","onAddCommand":{"clickTrackingParams":"CLsEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"8HSwDqwGzrc","params":"CAI%3D"}}}},"trackingParams":"CLsEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CLcEEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs4SFN3RHF3R3pyYw%3D%3D","commands":[{"clickTrackingParams":"CLcEEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CLoEEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CLcEEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CLcEEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"28 minutes, 51 seconds"}},"simpleText":"28:51"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CLkEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"8HSwDqwGzrc","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CLkEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"8HSwDqwGzrc"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CLkEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CLgEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CLgEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"8HSwDqwGzrc","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CLgEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["8HSwDqwGzrc"],"params":"CAQ%3D"}},"videoIds":["8HSwDqwGzrc"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CLgEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/8HSwDqwGzrc/mqdefault_6s.webp?du=3000\u0026sqp=CIzoip8G\u0026rs=AOn4CLAQGR7OfVrRz9iWcnrT3RFzKu54vw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"7ie1bpT4iLs","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/7ie1bpT4iLs/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDtoSVIbZwGbHP_pMvlAoNOE-eDCQ","width":168,"height":94},{"url":"https://i.ytimg.com/vi/7ie1bpT4iLs/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBOQtDLhyIt8922cBLtXb5258-Q8w","width":196,"height":110},{"url":"https://i.ytimg.com/vi/7ie1bpT4iLs/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBwXevmwusNFJHHNaeH6oXjw52uxg","width":246,"height":138},{"url":"https://i.ytimg.com/vi/7ie1bpT4iLs/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCFSuAkYg-sZL0zkvNmDr5oJrAcdA","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Star Wars Tier List by penguinz0 1 year ago 52 minutes 1,804,958 views"}},"simpleText":"Star Wars Tier List"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"1,804,958 views"},"navigationEndpoint":{"clickTrackingParams":"CK8EEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNVUpBbFhSR0twZUVlbC03aXNRakkx","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=7ie1bpT4iLs","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"7ie1bpT4iLs","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr1---sn-cxaaj5o5q5-tt1ee.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=ee27b56e94f888bb\u0026ip=74.12.195.102\u0026initcwndbps=1816250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CK8EEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CK8EEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CK8EEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1VAu5Hip-mt7ZPuAaoBIlBMUkQ3Ti1acmoyRE1VSkFsWFJHS3BlRWVsLTdpc1FqSTE=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CLYEEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.8 million views"}},"simpleText":"1.8M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CLUEEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CLUEEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"7ie1bpT4iLs","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CLUEEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["7ie1bpT4iLs"],"params":"CAQ%3D"}},"videoIds":["7ie1bpT4iLs"]}}]}},"trackingParams":"CLUEEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CK8EEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"7ie1bpT4iLs","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CK8EEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CLQEEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"7ie1bpT4iLs"}},"trackingParams":"CLQEEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CLMEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"7ie1bpT4iLs","onAddCommand":{"clickTrackingParams":"CLMEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"7ie1bpT4iLs","params":"CAI%3D"}}}},"trackingParams":"CLMEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CK8EEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs3aWUxYnBUNGlMcw%3D%3D","commands":[{"clickTrackingParams":"CK8EEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CLIEEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CK8EEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CK8EEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"52 minutes, 22 seconds"}},"simpleText":"52:22"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CLEEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"7ie1bpT4iLs","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CLEEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"7ie1bpT4iLs"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CLEEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CLAEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CLAEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"7ie1bpT4iLs","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CLAEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["7ie1bpT4iLs"],"params":"CAQ%3D"}},"videoIds":["7ie1bpT4iLs"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CLAEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/7ie1bpT4iLs/mqdefault_6s.webp?du=3000\u0026sqp=CPb5ip8G\u0026rs=AOn4CLDPJgLuuskMvop3Ksz5z1ivV7T02g","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"6D4KJHeCyKY","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/6D4KJHeCyKY/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLACKgYZDhkMydrv39-8m7kM26zh8w","width":168,"height":94},{"url":"https://i.ytimg.com/vi/6D4KJHeCyKY/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBDiRDzDou-oU50K-zyr0qz1TtFDA","width":196,"height":110},{"url":"https://i.ytimg.com/vi/6D4KJHeCyKY/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBjXC1qKiltEvDdTOeGC4859wquUg","width":246,"height":138},{"url":"https://i.ytimg.com/vi/6D4KJHeCyKY/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDw5D-rCSd5m4--fCT1UDK6MPWR0A","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Marvel Movie Tier List by penguinz0 1 year ago 53 minutes 2,693,370 views"}},"simpleText":"Marvel Movie Tier List"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"2,693,370 views"},"navigationEndpoint":{"clickTrackingParams":"CKcEEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNVUpBbFhSR0twZUVlbC03aXNRakkx","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=6D4KJHeCyKY","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"6D4KJHeCyKY","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr5---sn-cxaaj5o5q5-tt1r.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=e83e0a247782c8a6\u0026ip=74.12.195.102\u0026initcwndbps=1643750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CKcEEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CKcEEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CKcEEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1VAppGLvMfEgp_oAaoBIlBMUkQ3Ti1acmoyRE1VSkFsWFJHS3BlRWVsLTdpc1FqSTE=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CK4EEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2.6 million views"}},"simpleText":"2.6M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CK0EEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CK0EEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"6D4KJHeCyKY","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CK0EEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["6D4KJHeCyKY"],"params":"CAQ%3D"}},"videoIds":["6D4KJHeCyKY"]}}]}},"trackingParams":"CK0EEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CKcEEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"6D4KJHeCyKY","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CKcEEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CKwEEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"6D4KJHeCyKY"}},"trackingParams":"CKwEEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CKsEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"6D4KJHeCyKY","onAddCommand":{"clickTrackingParams":"CKsEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"6D4KJHeCyKY","params":"CAI%3D"}}}},"trackingParams":"CKsEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CKcEEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs2RDRLSkhlQ3lLWQ%3D%3D","commands":[{"clickTrackingParams":"CKcEEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CKoEEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CKcEEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CKcEEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"53 minutes, 38 seconds"}},"simpleText":"53:38"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CKkEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"6D4KJHeCyKY","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CKkEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"6D4KJHeCyKY"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CKkEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CKgEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CKgEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"6D4KJHeCyKY","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CKgEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["6D4KJHeCyKY"],"params":"CAQ%3D"}},"videoIds":["6D4KJHeCyKY"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CKgEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/6D4KJHeCyKY/mqdefault_6s.webp?du=3000\u0026sqp=CMDbip8G\u0026rs=AOn4CLDo0SEX2aZVyYslcm_r_uzg4aQkTQ","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"8G8x_genYBo","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/8G8x_genYBo/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDpAZl25Vjh8lND4UWEbur28MToyA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/8G8x_genYBo/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBmXxG3Ohdt6TDtVUI-7MY6cuiWFQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/8G8x_genYBo/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCtT3qctRJjR_OXB_bELRxit3Pfhg","width":246,"height":138},{"url":"https://i.ytimg.com/vi/8G8x_genYBo/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDAjVvGrh8KwHDxSm014JNkYz_Ytg","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Greek Gods Tier List by penguinz0 1 year ago 1 hour, 7 minutes 1,491,747 views"}},"simpleText":"Greek Gods Tier List"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"1,491,747 views"},"navigationEndpoint":{"clickTrackingParams":"CJ8EEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNVUpBbFhSR0twZUVlbC03aXNRakkx","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=8G8x_genYBo","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"8G8x_genYBo","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr7---sn-cxaaj5o5q5-tt1y.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=f06f31fe07a7601a\u0026ip=74.12.195.102\u0026initcwndbps=1702500\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CJ8EEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CJ8EEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CJ8EEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1VAmsCdveC_zLfwAaoBIlBMUkQ3Ti1acmoyRE1VSkFsWFJHS3BlRWVsLTdpc1FqSTE=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CKYEEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.4 million views"}},"simpleText":"1.4M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CKUEEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CKUEEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"8G8x_genYBo","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CKUEEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["8G8x_genYBo"],"params":"CAQ%3D"}},"videoIds":["8G8x_genYBo"]}}]}},"trackingParams":"CKUEEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CJ8EEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"8G8x_genYBo","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CJ8EEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CKQEEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"8G8x_genYBo"}},"trackingParams":"CKQEEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CKMEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"8G8x_genYBo","onAddCommand":{"clickTrackingParams":"CKMEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"8G8x_genYBo","params":"CAI%3D"}}}},"trackingParams":"CKMEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CJ8EEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs4Rzh4X2dlbllCbw%3D%3D","commands":[{"clickTrackingParams":"CJ8EEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CKIEEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CJ8EEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CJ8EEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 hour, 7 minutes, 2 seconds"}},"simpleText":"1:07:02"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CKEEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"8G8x_genYBo","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CKEEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"8G8x_genYBo"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CKEEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CKAEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CKAEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"8G8x_genYBo","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CKAEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["8G8x_genYBo"],"params":"CAQ%3D"}},"videoIds":["8G8x_genYBo"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CKAEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/8G8x_genYBo/mqdefault_6s.webp?du=3000\u0026sqp=CNKCi58G\u0026rs=AOn4CLBzzO_t_yemoEDy18bQhC-p-Z4V0A","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"-2NtqhkIg1c","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/-2NtqhkIg1c/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCsgTnaYCkBE_6RKMIxbe74LpWWAg","width":168,"height":94},{"url":"https://i.ytimg.com/vi/-2NtqhkIg1c/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBIAXfU8z9d3PGBfh29BFzl8Oy-3A","width":196,"height":110},{"url":"https://i.ytimg.com/vi/-2NtqhkIg1c/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCc6vi3lS9oKnMHMdxODQRJRT8Msg","width":246,"height":138},{"url":"https://i.ytimg.com/vi/-2NtqhkIg1c/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLB0TTFuyfMU2y1Seff46xNHRhPf9A","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Bad Celebrities Tier List by penguinz0 1 year ago 1 hour, 13 minutes 6,504,016 views"}},"simpleText":"Bad Celebrities Tier List"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"6,504,016 views"},"navigationEndpoint":{"clickTrackingParams":"CJcEEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNVUpBbFhSR0twZUVlbC03aXNRakkx","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=-2NtqhkIg1c","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"-2NtqhkIg1c","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr1---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=fb636daa19088357\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CJcEEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CJcEEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CJcEEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1VA14aiyKG127H7AaoBIlBMUkQ3Ti1acmoyRE1VSkFsWFJHS3BlRWVsLTdpc1FqSTE=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CJ4EEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"6.5 million views"}},"simpleText":"6.5M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CJ0EEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CJ0EEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"-2NtqhkIg1c","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CJ0EEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["-2NtqhkIg1c"],"params":"CAQ%3D"}},"videoIds":["-2NtqhkIg1c"]}}]}},"trackingParams":"CJ0EEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CJcEEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"-2NtqhkIg1c","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CJcEEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CJwEEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"-2NtqhkIg1c"}},"trackingParams":"CJwEEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CJsEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"-2NtqhkIg1c","onAddCommand":{"clickTrackingParams":"CJsEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"-2NtqhkIg1c","params":"CAI%3D"}}}},"trackingParams":"CJsEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CJcEEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgstMk50cWhrSWcxYw%3D%3D","commands":[{"clickTrackingParams":"CJcEEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CJoEEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CJcEEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CJcEEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 hour, 13 minutes, 1 second"}},"simpleText":"1:13:01"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CJkEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"-2NtqhkIg1c","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CJkEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"-2NtqhkIg1c"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CJkEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CJgEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CJgEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"-2NtqhkIg1c","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CJgEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["-2NtqhkIg1c"],"params":"CAQ%3D"}},"videoIds":["-2NtqhkIg1c"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CJgEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/-2NtqhkIg1c/mqdefault_6s.webp?du=3000\u0026sqp=CNaAi58G\u0026rs=AOn4CLBcIzjyHWZOIEmWJZsNrDn6jo1tYA","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"_B5ApwEP9y0","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/_B5ApwEP9y0/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLA9TFA4lgTZQQt-zkgHHGjQ1TZp4A","width":168,"height":94},{"url":"https://i.ytimg.com/vi/_B5ApwEP9y0/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBDyHEsD3IE0NleU2UUxHUrnNhubQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/_B5ApwEP9y0/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDAz2RhxF_WSTP_8IUcUYdshjhjpw","width":246,"height":138},{"url":"https://i.ytimg.com/vi/_B5ApwEP9y0/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCXMecNBfpHwW1JbU_Jq4Lfo8G6xA","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Ice Cream Tier List by penguinz0 1 year ago 28 minutes 2,005,031 views"}},"simpleText":"Ice Cream Tier List"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"2,005,031 views"},"navigationEndpoint":{"clickTrackingParams":"CI8EEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNVUpBbFhSR0twZUVlbC03aXNRakkx","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=_B5ApwEP9y0","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"_B5ApwEP9y0","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr7---sn-cxaaj5o5q5-tt1es.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=fc1e40a7010ff72d\u0026ip=74.12.195.102\u0026initcwndbps=1656250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CI8EEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CI8EEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CI8EEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1VAre6_iPCUkI_8AaoBIlBMUkQ3Ti1acmoyRE1VSkFsWFJHS3BlRWVsLTdpc1FqSTE=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CJYEEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2 million views"}},"simpleText":"2M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CJUEEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CJUEEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"_B5ApwEP9y0","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CJUEEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["_B5ApwEP9y0"],"params":"CAQ%3D"}},"videoIds":["_B5ApwEP9y0"]}}]}},"trackingParams":"CJUEEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CI8EEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"_B5ApwEP9y0","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CI8EEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CJQEEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"_B5ApwEP9y0"}},"trackingParams":"CJQEEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CJMEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"_B5ApwEP9y0","onAddCommand":{"clickTrackingParams":"CJMEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"_B5ApwEP9y0","params":"CAI%3D"}}}},"trackingParams":"CJMEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CI8EEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtfQjVBcHdFUDl5MA%3D%3D","commands":[{"clickTrackingParams":"CI8EEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CJIEEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CI8EEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CI8EEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"28 minutes, 50 seconds"}},"simpleText":"28:50"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CJEEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"_B5ApwEP9y0","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CJEEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"_B5ApwEP9y0"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CJEEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CJAEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CJAEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"_B5ApwEP9y0","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CJAEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["_B5ApwEP9y0"],"params":"CAQ%3D"}},"videoIds":["_B5ApwEP9y0"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CJAEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/_B5ApwEP9y0/mqdefault_6s.webp?du=3000\u0026sqp=CNvDip8G\u0026rs=AOn4CLA_qKpLDVEpCvXyZBq0KUk4DUYAAg","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"awaaCzI77rU","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/awaaCzI77rU/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDIy-CIV89Q6aXcY4dwshCRGKlPbQ","width":168,"height":94},{"url":"https://i.ytimg.com/vi/awaaCzI77rU/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCJ4g5DFt3S4hQchn8HScSxSrHG2Q","width":196,"height":110},{"url":"https://i.ytimg.com/vi/awaaCzI77rU/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCKdXRJ9h_7wQiKkbAP-WdbrmcXZg","width":246,"height":138},{"url":"https://i.ytimg.com/vi/awaaCzI77rU/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCqy9vV0pSvhj2gzLvvhoQO4uHHEQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Bible Characters Tier List by penguinz0 1 year ago 1 hour, 33 minutes 2,320,882 views"}},"simpleText":"Bible Characters Tier List"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"2,320,882 views"},"navigationEndpoint":{"clickTrackingParams":"CIcEEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNVUpBbFhSR0twZUVlbC03aXNRakkx","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=awaaCzI77rU","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"awaaCzI77rU","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr8---sn-cxaaj5o5q5-tt1e6.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=6b069a0b323beeb5\u0026ip=74.12.195.102\u0026initcwndbps=1521250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CIcEEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CIcEEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CIcEEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1VAtd3vkbPBpoNrqgEiUExSRDdOLVpyajJETVVKQWxYUkdLcGVFZWwtN2lzUWpJMQ==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CI4EEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2.3 million views"}},"simpleText":"2.3M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CI0EEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CI0EEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"awaaCzI77rU","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CI0EEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["awaaCzI77rU"],"params":"CAQ%3D"}},"videoIds":["awaaCzI77rU"]}}]}},"trackingParams":"CI0EEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CIcEEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"awaaCzI77rU","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CIcEEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CIwEEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"awaaCzI77rU"}},"trackingParams":"CIwEEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CIsEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"awaaCzI77rU","onAddCommand":{"clickTrackingParams":"CIsEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"awaaCzI77rU","params":"CAI%3D"}}}},"trackingParams":"CIsEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CIcEEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgthd2FhQ3pJNzdyVQ%3D%3D","commands":[{"clickTrackingParams":"CIcEEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CIoEEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CIcEEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CIcEEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 hour, 33 minutes, 10 seconds"}},"simpleText":"1:33:10"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CIkEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"awaaCzI77rU","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CIkEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"awaaCzI77rU"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CIkEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CIgEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CIgEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"awaaCzI77rU","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CIgEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["awaaCzI77rU"],"params":"CAQ%3D"}},"videoIds":["awaaCzI77rU"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CIgEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/awaaCzI77rU/mqdefault_6s.webp?du=3000\u0026sqp=COzdip8G\u0026rs=AOn4CLCEHg1DRmIoO6afiEMw2maaI2DOyg","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"yLPk2qVaJKo","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/yLPk2qVaJKo/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDssxphmKo_ay_cepb0ir5nXJaMWw","width":168,"height":94},{"url":"https://i.ytimg.com/vi/yLPk2qVaJKo/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAB79O57WM4lWTneItc0kscAD9SzA","width":196,"height":110},{"url":"https://i.ytimg.com/vi/yLPk2qVaJKo/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLD12RgsPfF0PCzNiOqDBNjLBpSclg","width":246,"height":138},{"url":"https://i.ytimg.com/vi/yLPk2qVaJKo/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDJuxi7-CIM-GO1qWUQtbzCFsqzag","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Every Cartoon Network Show Tier List by penguinz0 1 year ago 1 hour 2,057,058 views"}},"simpleText":"Every Cartoon Network Show Tier List"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"2,057,058 views"},"navigationEndpoint":{"clickTrackingParams":"CP8DEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNVUpBbFhSR0twZUVlbC03aXNRakkx","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=yLPk2qVaJKo","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"yLPk2qVaJKo","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr4---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=c8b3e4daa55a24aa\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CP8DEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CP8DEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CP8DEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1VAqsnoqqqb-dnIAaoBIlBMUkQ3Ti1acmoyRE1VSkFsWFJHS3BlRWVsLTdpc1FqSTE=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CIYEEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2 million views"}},"simpleText":"2M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CIUEEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CIUEEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"yLPk2qVaJKo","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CIUEEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["yLPk2qVaJKo"],"params":"CAQ%3D"}},"videoIds":["yLPk2qVaJKo"]}}]}},"trackingParams":"CIUEEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CP8DEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"yLPk2qVaJKo","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CP8DEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CIQEEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"yLPk2qVaJKo"}},"trackingParams":"CIQEEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CIMEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"yLPk2qVaJKo","onAddCommand":{"clickTrackingParams":"CIMEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"yLPk2qVaJKo","params":"CAI%3D"}}}},"trackingParams":"CIMEENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CP8DEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgt5TFBrMnFWYUpLbw%3D%3D","commands":[{"clickTrackingParams":"CP8DEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CIIEEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CP8DEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CP8DEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 hour, 46 seconds"}},"simpleText":"1:00:46"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CIEEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"yLPk2qVaJKo","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CIEEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"yLPk2qVaJKo"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CIEEEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CIAEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CIAEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"yLPk2qVaJKo","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CIAEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["yLPk2qVaJKo"],"params":"CAQ%3D"}},"videoIds":["yLPk2qVaJKo"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CIAEEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/yLPk2qVaJKo/mqdefault_6s.webp?du=3000\u0026sqp=COqEi58G\u0026rs=AOn4CLApbY85-4N8KZxRMrMzTjKyLIhGnA","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"4EPbQ14HoXk","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/4EPbQ14HoXk/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAI-WEQrapm6vX0m98XDPTizIlsiw","width":168,"height":94},{"url":"https://i.ytimg.com/vi/4EPbQ14HoXk/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBN1whrRNpPHd2wgzEgDjWml3zscQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/4EPbQ14HoXk/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBgaIn43OQHya10kFvu_HgMtKR6hw","width":246,"height":138},{"url":"https://i.ytimg.com/vi/4EPbQ14HoXk/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLA6KLZ7l_dFnlv7dKZnulY2941Etw","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Fast Food Tier List by penguinz0 1 year ago 1 hour, 15 minutes 2,970,632 views"}},"simpleText":"Fast Food Tier List"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"2,970,632 views"},"navigationEndpoint":{"clickTrackingParams":"CPcDEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNVUpBbFhSR0twZUVlbC03aXNRakkx","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=4EPbQ14HoXk","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"4EPbQ14HoXk","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=e043db435e07a179\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CPcDEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CPcDEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CPcDEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1VA-cKe8LXo9qHgAaoBIlBMUkQ3Ti1acmoyRE1VSkFsWFJHS3BlRWVsLTdpc1FqSTE=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CP4DEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2.9 million views"}},"simpleText":"2.9M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CP0DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CP0DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"4EPbQ14HoXk","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CP0DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["4EPbQ14HoXk"],"params":"CAQ%3D"}},"videoIds":["4EPbQ14HoXk"]}}]}},"trackingParams":"CP0DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CPcDEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"4EPbQ14HoXk","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CPcDEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CPwDEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"4EPbQ14HoXk"}},"trackingParams":"CPwDEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CPsDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"4EPbQ14HoXk","onAddCommand":{"clickTrackingParams":"CPsDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"4EPbQ14HoXk","params":"CAI%3D"}}}},"trackingParams":"CPsDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CPcDEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs0RVBiUTE0SG9Yaw%3D%3D","commands":[{"clickTrackingParams":"CPcDEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CPoDEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CPcDEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CPcDEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 hour, 15 minutes, 12 seconds"}},"simpleText":"1:15:12"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CPkDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"4EPbQ14HoXk","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CPkDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"4EPbQ14HoXk"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CPkDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CPgDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CPgDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"4EPbQ14HoXk","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CPgDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["4EPbQ14HoXk"],"params":"CAQ%3D"}},"videoIds":["4EPbQ14HoXk"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CPgDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/4EPbQ14HoXk/mqdefault_6s.webp?du=3000\u0026sqp=CNLkip8G\u0026rs=AOn4CLBLkgKqjQVRtPlbn3QN2XGkXnB8Tw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"7bQl_bVZd8s","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/7bQl_bVZd8s/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBtKMoKDs4_qDmZbTfMNjhKyKtEEA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/7bQl_bVZd8s/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDbrCalELdBoYXrnLgCnt8xbc-kYQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/7bQl_bVZd8s/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAugMg9TUHGMHaAdYxu4An_OPZoAA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/7bQl_bVZd8s/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLB09-zpW21msKDjfDdXRcMmH3DuRA","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"MrBeast Burger Tier List by penguinz0 1 year ago 26 minutes 4,621,409 views"}},"simpleText":"MrBeast Burger Tier List"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"4,621,409 views"},"navigationEndpoint":{"clickTrackingParams":"CO8DEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNVUpBbFhSR0twZUVlbC03aXNRakkx","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=7bQl_bVZd8s","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"7bQl_bVZd8s","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=edb425fdb55977cb\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CO8DEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CO8DEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CO8DEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1VAy-_lqtu_idrtAaoBIlBMUkQ3Ti1acmoyRE1VSkFsWFJHS3BlRWVsLTdpc1FqSTE=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CPYDEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"4.6 million views"}},"simpleText":"4.6M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CPUDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CPUDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"7bQl_bVZd8s","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CPUDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["7bQl_bVZd8s"],"params":"CAQ%3D"}},"videoIds":["7bQl_bVZd8s"]}}]}},"trackingParams":"CPUDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CO8DEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"7bQl_bVZd8s","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CO8DEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CPQDEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"7bQl_bVZd8s"}},"trackingParams":"CPQDEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CPMDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"7bQl_bVZd8s","onAddCommand":{"clickTrackingParams":"CPMDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"7bQl_bVZd8s","params":"CAI%3D"}}}},"trackingParams":"CPMDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CO8DEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs3YlFsX2JWWmQ4cw%3D%3D","commands":[{"clickTrackingParams":"CO8DEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CPIDEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CO8DEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CO8DEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"26 minutes, 10 seconds"}},"simpleText":"26:10"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CPEDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"7bQl_bVZd8s","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CPEDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"7bQl_bVZd8s"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CPEDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CPADEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CPADEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"7bQl_bVZd8s","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CPADEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["7bQl_bVZd8s"],"params":"CAQ%3D"}},"videoIds":["7bQl_bVZd8s"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CPADEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/7bQl_bVZd8s/mqdefault_6s.webp?du=3000\u0026sqp=CPT3ip8G\u0026rs=AOn4CLAQw9iCjUHBLr0T6yXrorxwdwAHGQ","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"8JhxAnENYdc","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/8JhxAnENYdc/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDc2tHS6a_SfDnm-9ds7ioNW7qO5A","width":168,"height":94},{"url":"https://i.ytimg.com/vi/8JhxAnENYdc/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBWbK_0mL8Lisk68h30YH-HTASYQg","width":196,"height":110},{"url":"https://i.ytimg.com/vi/8JhxAnENYdc/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLC0JU9ZNOzrjB8VNFuJC6y9oGSksQ","width":246,"height":138},{"url":"https://i.ytimg.com/vi/8JhxAnENYdc/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLB7IWt1_3XGTn9mhLRkX-qyXB503Q","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Blind Bottled Water Taste Tier List by penguinz0 1 year ago 28 minutes 988,318 views"}},"simpleText":"Blind Bottled Water Taste Tier List"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"988,318 views"},"navigationEndpoint":{"clickTrackingParams":"COcDEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNVUpBbFhSR0twZUVlbC03aXNRakkx","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=8JhxAnENYdc","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"8JhxAnENYdc","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr1---sn-cxaaj5o5q5-tt1ee.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=f0987102710d61d7\u0026ip=74.12.195.102\u0026initcwndbps=1816250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"COcDEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"COcDEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"COcDEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1VA18O1iKegnMzwAaoBIlBMUkQ3Ti1acmoyRE1VSkFsWFJHS3BlRWVsLTdpc1FqSTE=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CO4DEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"988K views"}},"simpleText":"988K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CO0DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CO0DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"8JhxAnENYdc","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CO0DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["8JhxAnENYdc"],"params":"CAQ%3D"}},"videoIds":["8JhxAnENYdc"]}}]}},"trackingParams":"CO0DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"COcDEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"8JhxAnENYdc","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"COcDEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"COwDEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"8JhxAnENYdc"}},"trackingParams":"COwDEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"COsDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"8JhxAnENYdc","onAddCommand":{"clickTrackingParams":"COsDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"8JhxAnENYdc","params":"CAI%3D"}}}},"trackingParams":"COsDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"COcDEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs4Smh4QW5FTllkYw%3D%3D","commands":[{"clickTrackingParams":"COcDEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"COoDEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"COcDEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"COcDEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"28 minutes, 42 seconds"}},"simpleText":"28:42"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"COkDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"8JhxAnENYdc","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"COkDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"8JhxAnENYdc"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"COkDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"COgDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"COgDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"8JhxAnENYdc","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"COgDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["8JhxAnENYdc"],"params":"CAQ%3D"}},"videoIds":["8JhxAnENYdc"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"COgDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/8JhxAnENYdc/mqdefault_6s.webp?du=3000\u0026sqp=CJ24ip8G\u0026rs=AOn4CLDStLauNoJhFSFPSR7wzl8XfsWwPQ","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"KMyKtPwqGV4","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/KMyKtPwqGV4/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAmH5Pr8RWoEefLTIq8H0e9JpEqIw","width":168,"height":94},{"url":"https://i.ytimg.com/vi/KMyKtPwqGV4/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAb_IHPvGTeMaczH5qKviY5VcRC6A","width":196,"height":110},{"url":"https://i.ytimg.com/vi/KMyKtPwqGV4/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBzXWHjzc2KnUMYFw6wYxbd4f8_mQ","width":246,"height":138},{"url":"https://i.ytimg.com/vi/KMyKtPwqGV4/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDt5RdMeUpCxiUp8pmTbShrrw6TdA","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Dhar Mann Tier List by penguinz0 1 year ago 11 minutes, 35 seconds 984,819 views"}},"simpleText":"Dhar Mann Tier List"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"984,819 views"},"navigationEndpoint":{"clickTrackingParams":"CN8DEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNVUpBbFhSR0twZUVlbC03aXNRakkx","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=KMyKtPwqGV4","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"KMyKtPwqGV4","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1ee.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=28cc8ab4fc2a195e\u0026ip=74.12.195.102\u0026initcwndbps=1816250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CN8DEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CN8DEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CN8DEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1VA3rKo4c_WouYoqgEiUExSRDdOLVpyajJETVVKQWxYUkdLcGVFZWwtN2lzUWpJMQ==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"COYDEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"984K views"}},"simpleText":"984K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"COUDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"COUDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"KMyKtPwqGV4","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"COUDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["KMyKtPwqGV4"],"params":"CAQ%3D"}},"videoIds":["KMyKtPwqGV4"]}}]}},"trackingParams":"COUDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CN8DEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"KMyKtPwqGV4","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CN8DEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"COQDEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"KMyKtPwqGV4"}},"trackingParams":"COQDEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"COMDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"KMyKtPwqGV4","onAddCommand":{"clickTrackingParams":"COMDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"KMyKtPwqGV4","params":"CAI%3D"}}}},"trackingParams":"COMDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CN8DEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtLTXlLdFB3cUdWNA%3D%3D","commands":[{"clickTrackingParams":"CN8DEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"COIDEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CN8DEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CN8DEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"11 minutes, 35 seconds"}},"simpleText":"11:35"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"COEDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"KMyKtPwqGV4","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"COEDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"KMyKtPwqGV4"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"COEDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"COADEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"COADEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"KMyKtPwqGV4","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"COADEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["KMyKtPwqGV4"],"params":"CAQ%3D"}},"videoIds":["KMyKtPwqGV4"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"COADEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/KMyKtPwqGV4/mqdefault_6s.webp?du=3000\u0026sqp=CMjtip8G\u0026rs=AOn4CLC7U8X5sYIxymPhNd3QkxNeefJ6oQ","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}}],"trackingParams":"CNwDEMY5IhMI-Mm_pq2E_QIVEIf_BB2wqAtV","visibleItemCount":4,"nextButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"CHEVRON_RIGHT"},"accessibility":{"label":"Next"},"trackingParams":"CN4DEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},"previousButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"CHEVRON_LEFT"},"accessibility":{"label":"Previous"},"trackingParams":"CN0DEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}}}},"trackingParams":"CNoDENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","playAllButton":{"buttonRenderer":{"style":"STYLE_TEXT","size":"SIZE_DEFAULT","isDisabled":false,"text":{"runs":[{"text":"Play all"}]},"icon":{"iconType":"PLAY_ALL"},"navigationEndpoint":{"clickTrackingParams":"CNsDEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=8HSwDqwGzrc\u0026list=PLRD7N-Zrj2DMUJAlXRGKpeEel-7isQjI1","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"8HSwDqwGzrc","playlistId":"PLRD7N-Zrj2DMUJAlXRGKpeEel-7isQjI1","loggingContext":{"vssLoggingContext":{"serializedContextData":"GiJQTFJEN04tWnJqMkRNVUpBbFhSR0twZUVlbC03aXNRakkx"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr2---sn-cxaaj5o5q5-tt1ee.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=f074b00eac06ceb7\u0026ip=74.12.195.102\u0026initcwndbps=1816250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"trackingParams":"CNsDEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}}}}],"trackingParams":"CNkDELsvGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"itemSectionRenderer":{"contents":[{"shelfRenderer":{"title":{"runs":[{"text":"Moist Meter","navigationEndpoint":{"clickTrackingParams":"CPQCENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLRD7N-Zrj2DMOLTG7t9E-vJo35BzeTwVG","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLRD7N-Zrj2DMOLTG7t9E-vJo35BzeTwVG"}}}]},"endpoint":{"clickTrackingParams":"CPQCENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLRD7N-Zrj2DMOLTG7t9E-vJo35BzeTwVG","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLRD7N-Zrj2DMOLTG7t9E-vJo35BzeTwVG"}},"content":{"horizontalListRenderer":{"items":[{"gridVideoRenderer":{"videoId":"nK_XkXHS1VI","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/nK_XkXHS1VI/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBFvYUcRo3SaHkaPHwZwGDWnAPPOQ","width":168,"height":94},{"url":"https://i.ytimg.com/vi/nK_XkXHS1VI/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBgA0K94FN1gGLPx_N5ZwRtxdqcfQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/nK_XkXHS1VI/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDgcQQWmZzObSbercWgFlGNhHZLIg","width":246,"height":138},{"url":"https://i.ytimg.com/vi/nK_XkXHS1VI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCY_CVXFVO0oQujoKa6CwDOwEt6jA","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Moist Meter | Dune by penguinz0 1 year ago 8 minutes, 29 seconds 1,401,452 views"}},"simpleText":"Moist Meter | Dune"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"1,401,452 views"},"navigationEndpoint":{"clickTrackingParams":"CNEDEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNT0xURzd0OUUtdkpvMzVCemVUd1ZH","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=nK_XkXHS1VI","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"nK_XkXHS1VI","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr5---sn-cxaaj5o5q5-tt1y.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=9cafd79171d2d552\u0026ip=74.12.195.102\u0026initcwndbps=1702500\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CNEDEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CNEDEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CNEDEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1VA0qrLjpfy9decAaoBIlBMUkQ3Ti1acmoyRE1PTFRHN3Q5RS12Sm8zNUJ6ZVR3Vkc=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CNgDEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.4 million views"}},"simpleText":"1.4M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CNcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CNcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"nK_XkXHS1VI","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CNcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["nK_XkXHS1VI"],"params":"CAQ%3D"}},"videoIds":["nK_XkXHS1VI"]}}]}},"trackingParams":"CNcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CNEDEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"nK_XkXHS1VI","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CNEDEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CNYDEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"nK_XkXHS1VI"}},"trackingParams":"CNYDEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CNUDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"nK_XkXHS1VI","onAddCommand":{"clickTrackingParams":"CNUDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"nK_XkXHS1VI","params":"CAI%3D"}}}},"trackingParams":"CNUDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CNEDEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtuS19Ya1hIUzFWSQ%3D%3D","commands":[{"clickTrackingParams":"CNEDEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CNQDEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CNEDEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CNEDEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"8 minutes, 29 seconds"}},"simpleText":"8:29"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CNMDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"nK_XkXHS1VI","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CNMDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"nK_XkXHS1VI"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CNMDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CNIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CNIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"nK_XkXHS1VI","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CNIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["nK_XkXHS1VI"],"params":"CAQ%3D"}},"videoIds":["nK_XkXHS1VI"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CNIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/nK_XkXHS1VI/mqdefault_6s.webp?du=3000\u0026sqp=CKjzip8G\u0026rs=AOn4CLAtzgfxEEkoNg-R0Se1cx29INCxDA","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"6Oh9Exf6rCs","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/6Oh9Exf6rCs/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAfzqMdMElNKb4ipA-sDVyaNtx1jw","width":168,"height":94},{"url":"https://i.ytimg.com/vi/6Oh9Exf6rCs/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDbRLRPbt2I9Oijs5a-PNXO3Un6HA","width":196,"height":110},{"url":"https://i.ytimg.com/vi/6Oh9Exf6rCs/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLC44zzxZjSjdCw-ZRZQyusYI3ddkA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/6Oh9Exf6rCs/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDMwGJfjwOqlbaAQxo6I0TUHBBIpQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Moist Meter | Halloween Kills by penguinz0 1 year ago 8 minutes, 30 seconds 743,630 views"}},"simpleText":"Moist Meter | Halloween Kills"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"743,630 views"},"navigationEndpoint":{"clickTrackingParams":"CMkDEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNT0xURzd0OUUtdkpvMzVCemVUd1ZH","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=6Oh9Exf6rCs","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"6Oh9Exf6rCs","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr6---sn-cxaaj5o5q5-tt1e6.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=e8e87d1317faac2b\u0026ip=74.12.195.102\u0026initcwndbps=1521250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CMkDEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CMkDEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CMkDEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1VAq9jqv7Gin_ToAaoBIlBMUkQ3Ti1acmoyRE1PTFRHN3Q5RS12Sm8zNUJ6ZVR3Vkc=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CNADEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"743K views"}},"simpleText":"743K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CM8DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CM8DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"6Oh9Exf6rCs","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CM8DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["6Oh9Exf6rCs"],"params":"CAQ%3D"}},"videoIds":["6Oh9Exf6rCs"]}}]}},"trackingParams":"CM8DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CMkDEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"6Oh9Exf6rCs","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CMkDEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CM4DEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"6Oh9Exf6rCs"}},"trackingParams":"CM4DEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CM0DENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"6Oh9Exf6rCs","onAddCommand":{"clickTrackingParams":"CM0DENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"6Oh9Exf6rCs","params":"CAI%3D"}}}},"trackingParams":"CM0DENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CMkDEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs2T2g5RXhmNnJDcw%3D%3D","commands":[{"clickTrackingParams":"CMkDEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CMwDEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CMkDEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CMkDEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"8 minutes, 30 seconds"}},"simpleText":"8:30"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CMsDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"6Oh9Exf6rCs","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CMsDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"6Oh9Exf6rCs"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CMsDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CMoDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CMoDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"6Oh9Exf6rCs","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CMoDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["6Oh9Exf6rCs"],"params":"CAQ%3D"}},"videoIds":["6Oh9Exf6rCs"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CMoDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/6Oh9Exf6rCs/mqdefault_6s.webp?du=3000\u0026sqp=CJT8ip8G\u0026rs=AOn4CLBQfCm_pBh_jEdNfMZDYNh9hM0kDw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"8L0fn22OYcY","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/8L0fn22OYcY/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCNIC6z42Am2qrUKgJU9e4vwSdg0g","width":168,"height":94},{"url":"https://i.ytimg.com/vi/8L0fn22OYcY/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCQ3frOVxyI_yJyrTD1hppQbkNMYw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/8L0fn22OYcY/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDiEKZc6ejkb1uxwdJd9bHLMuJ7fQ","width":246,"height":138},{"url":"https://i.ytimg.com/vi/8L0fn22OYcY/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAI1z-HdBWRmZvFoXKXocSgF6eR2A","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Moist Meter | No Time To Die by penguinz0 1 year ago 13 minutes, 19 seconds 828,957 views"}},"simpleText":"Moist Meter | No Time To Die"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"828,957 views"},"navigationEndpoint":{"clickTrackingParams":"CMEDEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNT0xURzd0OUUtdkpvMzVCemVUd1ZH","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=8L0fn22OYcY","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"8L0fn22OYcY","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr5---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=f0bd1f9f6d8e61c6\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CMEDEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CMEDEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CMEDEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1VAxsO57Pbzx97wAaoBIlBMUkQ3Ti1acmoyRE1PTFRHN3Q5RS12Sm8zNUJ6ZVR3Vkc=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CMgDEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"828K views"}},"simpleText":"828K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CMcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CMcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"8L0fn22OYcY","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CMcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["8L0fn22OYcY"],"params":"CAQ%3D"}},"videoIds":["8L0fn22OYcY"]}}]}},"trackingParams":"CMcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CMEDEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"8L0fn22OYcY","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CMEDEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CMYDEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"8L0fn22OYcY"}},"trackingParams":"CMYDEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CMUDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"8L0fn22OYcY","onAddCommand":{"clickTrackingParams":"CMUDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"8L0fn22OYcY","params":"CAI%3D"}}}},"trackingParams":"CMUDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CMEDEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs4TDBmbjIyT1ljWQ%3D%3D","commands":[{"clickTrackingParams":"CMEDEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CMQDEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CMEDEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CMEDEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"13 minutes, 19 seconds"}},"simpleText":"13:19"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CMMDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"8L0fn22OYcY","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CMMDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"8L0fn22OYcY"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CMMDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CMIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CMIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"8L0fn22OYcY","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CMIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["8L0fn22OYcY"],"params":"CAQ%3D"}},"videoIds":["8L0fn22OYcY"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CMIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/8L0fn22OYcY/mqdefault_6s.webp?du=3000\u0026sqp=CMrTip8G\u0026rs=AOn4CLCloZVtOlWIxbJnzOkZDrMr3pDC1g","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"RhqBoWD3ekI","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/RhqBoWD3ekI/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBl0vc2PQ2cPEfaHAyiT62XdKSv7Q","width":168,"height":94},{"url":"https://i.ytimg.com/vi/RhqBoWD3ekI/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBqq4nDnWq1kLm-BAXd5aX4rSEI-g","width":196,"height":110},{"url":"https://i.ytimg.com/vi/RhqBoWD3ekI/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAqrOJ_1UaAFF0iw5UW8-_nRS61hQ","width":246,"height":138},{"url":"https://i.ytimg.com/vi/RhqBoWD3ekI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBuss3C2b5a8UgH0s5kQdvIGQV3EA","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Moist Meter | Squid Game by penguinz0 1 year ago 5 minutes, 54 seconds 2,559,613 views"}},"simpleText":"Moist Meter | Squid Game"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"2,559,613 views"},"navigationEndpoint":{"clickTrackingParams":"CLkDEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNT0xURzd0OUUtdkpvMzVCemVUd1ZH","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=RhqBoWD3ekI","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"RhqBoWD3ekI","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr8---sn-cxaaj5o5q5-tt1e6.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=461a81a160f77a42\u0026ip=74.12.195.102\u0026initcwndbps=1521250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CLkDEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CLkDEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CLkDEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1VAwvTdh5a0oI1GqgEiUExSRDdOLVpyajJETU9MVEc3dDlFLXZKbzM1QnplVHdWRw==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CMADEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2.5 million views"}},"simpleText":"2.5M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CL8DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CL8DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"RhqBoWD3ekI","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CL8DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["RhqBoWD3ekI"],"params":"CAQ%3D"}},"videoIds":["RhqBoWD3ekI"]}}]}},"trackingParams":"CL8DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CLkDEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"RhqBoWD3ekI","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CLkDEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CL4DEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"RhqBoWD3ekI"}},"trackingParams":"CL4DEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CL0DENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"RhqBoWD3ekI","onAddCommand":{"clickTrackingParams":"CL0DENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"RhqBoWD3ekI","params":"CAI%3D"}}}},"trackingParams":"CL0DENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CLkDEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtSaHFCb1dEM2VrSQ%3D%3D","commands":[{"clickTrackingParams":"CLkDEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CLwDEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CLkDEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CLkDEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"5 minutes, 54 seconds"}},"simpleText":"5:54"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CLsDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"RhqBoWD3ekI","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CLsDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"RhqBoWD3ekI"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CLsDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CLoDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CLoDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"RhqBoWD3ekI","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CLoDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["RhqBoWD3ekI"],"params":"CAQ%3D"}},"videoIds":["RhqBoWD3ekI"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CLoDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/RhqBoWD3ekI/mqdefault_6s.webp?du=3000\u0026sqp=CMLmip8G\u0026rs=AOn4CLBz_1FtpkFrVZ6qFvrmeKQE6ki4Tw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"ijdpACdrMSM","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/ijdpACdrMSM/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBrQ0H5rOz7Xz06fq5ikwB3SnAjEA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/ijdpACdrMSM/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAaOce3LH9oRv8EX44G_qixY8u9ig","width":196,"height":110},{"url":"https://i.ytimg.com/vi/ijdpACdrMSM/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBaqJ0Hi9ZYheQstM0yy68eNQKWzw","width":246,"height":138},{"url":"https://i.ytimg.com/vi/ijdpACdrMSM/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLA2JUMUPCju-PTnpHPI_WlFu_81_Q","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Moist Meter | Venom: Let There Be Carnage by penguinz0 1 year ago 8 minutes, 11 seconds 1,117,755 views"}},"simpleText":"Moist Meter | Venom: Let There Be Carnage"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"1,117,755 views"},"navigationEndpoint":{"clickTrackingParams":"CLEDEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNT0xURzd0OUUtdkpvMzVCemVUd1ZH","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=ijdpACdrMSM","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"ijdpACdrMSM","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr4---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=8a376900276b3123\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CLEDEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CLEDEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CLEDEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1VAo-Ksu4Kg2puKAaoBIlBMUkQ3Ti1acmoyRE1PTFRHN3Q5RS12Sm8zNUJ6ZVR3Vkc=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CLgDEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.1 million views"}},"simpleText":"1.1M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CLcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CLcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"ijdpACdrMSM","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CLcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["ijdpACdrMSM"],"params":"CAQ%3D"}},"videoIds":["ijdpACdrMSM"]}}]}},"trackingParams":"CLcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CLEDEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"ijdpACdrMSM","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CLEDEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CLYDEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"ijdpACdrMSM"}},"trackingParams":"CLYDEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CLUDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"ijdpACdrMSM","onAddCommand":{"clickTrackingParams":"CLUDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"ijdpACdrMSM","params":"CAI%3D"}}}},"trackingParams":"CLUDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CLEDEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtpamRwQUNkck1TTQ%3D%3D","commands":[{"clickTrackingParams":"CLEDEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CLQDEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CLEDEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CLEDEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"8 minutes, 11 seconds"}},"simpleText":"8:11"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CLMDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"ijdpACdrMSM","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CLMDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"ijdpACdrMSM"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CLMDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CLIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CLIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"ijdpACdrMSM","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CLIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["ijdpACdrMSM"],"params":"CAQ%3D"}},"videoIds":["ijdpACdrMSM"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CLIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/ijdpACdrMSM/mqdefault_6s.webp?du=3000\u0026sqp=CJj-ip8G\u0026rs=AOn4CLBDRZ77kgUf9WrXeK7O54wmCHZilQ","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"9mVIyRQRous","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/9mVIyRQRous/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDWwIwxBbSK2kRWBqdgp3IIC6cnfw","width":168,"height":94},{"url":"https://i.ytimg.com/vi/9mVIyRQRous/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAQ8zVmVl5zEpZBSnXUCSpFGc6Rdg","width":196,"height":110},{"url":"https://i.ytimg.com/vi/9mVIyRQRous/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLB3D-LT6wiMzLEvwhBDrYiwqde2WQ","width":246,"height":138},{"url":"https://i.ytimg.com/vi/9mVIyRQRous/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCSgBALAq2H3_3VbPEX0DaL9rlW8A","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Moist Meter | Tokyo Revengers by penguinz0 1 year ago 9 minutes, 18 seconds 820,974 views"}},"simpleText":"Moist Meter | Tokyo Revengers"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"820,974 views"},"navigationEndpoint":{"clickTrackingParams":"CKkDEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNT0xURzd0OUUtdkpvMzVCemVUd1ZH","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=9mVIyRQRous","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"9mVIyRQRous","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr2---sn-cxaaj5o5q5-tt1e6.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=f66548c91411a2eb\u0026ip=74.12.195.102\u0026initcwndbps=1521250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CKkDEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CKkDEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CKkDEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1VA68XGoJGZ0rL2AaoBIlBMUkQ3Ti1acmoyRE1PTFRHN3Q5RS12Sm8zNUJ6ZVR3Vkc=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CLADEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"820K views"}},"simpleText":"820K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CK8DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CK8DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"9mVIyRQRous","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CK8DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["9mVIyRQRous"],"params":"CAQ%3D"}},"videoIds":["9mVIyRQRous"]}}]}},"trackingParams":"CK8DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CKkDEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"9mVIyRQRous","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CKkDEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CK4DEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"9mVIyRQRous"}},"trackingParams":"CK4DEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CK0DENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"9mVIyRQRous","onAddCommand":{"clickTrackingParams":"CK0DENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"9mVIyRQRous","params":"CAI%3D"}}}},"trackingParams":"CK0DENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CKkDEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs5bVZJeVJRUm91cw%3D%3D","commands":[{"clickTrackingParams":"CKkDEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CKwDEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CKkDEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CKkDEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"9 minutes, 18 seconds"}},"simpleText":"9:18"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CKsDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"9mVIyRQRous","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CKsDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"9mVIyRQRous"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CKsDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CKoDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CKoDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"9mVIyRQRous","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CKoDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["9mVIyRQRous"],"params":"CAQ%3D"}},"videoIds":["9mVIyRQRous"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CKoDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/9mVIyRQRous/mqdefault_6s.webp?du=3000\u0026sqp=CLH9ip8G\u0026rs=AOn4CLCHIWps-jMB95fS6KH2CdvKW-DXnw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"mmxL2yyRq5c","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/mmxL2yyRq5c/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCliDWJDgFHZUWdwN_AZ4EXaKM_Cg","width":168,"height":94},{"url":"https://i.ytimg.com/vi/mmxL2yyRq5c/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDXUAVrxkmbQCroGGimz1aI9D5nWg","width":196,"height":110},{"url":"https://i.ytimg.com/vi/mmxL2yyRq5c/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLD1wH6jJBrkA-4xS3WUZajlseneKA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/mmxL2yyRq5c/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCNl5ulsNMBiTJjgTj1iCfP9W326g","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Moist Meter | Deathloop by penguinz0 1 year ago 9 minutes, 4 seconds 832,538 views"}},"simpleText":"Moist Meter | Deathloop"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"832,538 views"},"navigationEndpoint":{"clickTrackingParams":"CKEDEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNT0xURzd0OUUtdkpvMzVCemVUd1ZH","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=mmxL2yyRq5c","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"mmxL2yyRq5c","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr5---sn-cxaaj5o5q5-tt1el.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=9a6c4bdb2c91ab97\u0026ip=74.12.195.102\u0026initcwndbps=1782500\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CKEDEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CKEDEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CKEDEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1VAl9fG5LL7kraaAaoBIlBMUkQ3Ti1acmoyRE1PTFRHN3Q5RS12Sm8zNUJ6ZVR3Vkc=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CKgDEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"832K views"}},"simpleText":"832K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CKcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CKcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"mmxL2yyRq5c","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CKcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["mmxL2yyRq5c"],"params":"CAQ%3D"}},"videoIds":["mmxL2yyRq5c"]}}]}},"trackingParams":"CKcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CKEDEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"mmxL2yyRq5c","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CKEDEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CKYDEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"mmxL2yyRq5c"}},"trackingParams":"CKYDEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CKUDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"mmxL2yyRq5c","onAddCommand":{"clickTrackingParams":"CKUDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"mmxL2yyRq5c","params":"CAI%3D"}}}},"trackingParams":"CKUDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CKEDEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgttbXhMMnl5UnE1Yw%3D%3D","commands":[{"clickTrackingParams":"CKEDEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CKQDEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CKEDEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CKEDEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"9 minutes, 4 seconds"}},"simpleText":"9:04"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CKMDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"mmxL2yyRq5c","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CKMDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"mmxL2yyRq5c"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CKMDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CKIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CKIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"mmxL2yyRq5c","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CKIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["mmxL2yyRq5c"],"params":"CAQ%3D"}},"videoIds":["mmxL2yyRq5c"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CKIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/mmxL2yyRq5c/mqdefault_6s.webp?du=3000\u0026sqp=CPXEip8G\u0026rs=AOn4CLCWcEPJakjSXsWOi6NRq38oq8qx7A","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"im80Ib1f30o","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/im80Ib1f30o/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDKL1QtszDEls5Zph661BV5rfmJuA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/im80Ib1f30o/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLB2nn8aBLLlEdLgKxkhbFtHyad1PQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/im80Ib1f30o/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDU-RZvVHqURIXi6pT1p7VkHNxJOw","width":246,"height":138},{"url":"https://i.ytimg.com/vi/im80Ib1f30o/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBzMpmxSRqgQu2n10wN_CtG9HaNtA","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Moist Meter | Shang-Chi and the Legend of the Ten Rings by penguinz0 1 year ago 7 minutes, 17 seconds 1,322,664 views"}},"simpleText":"Moist Meter | Shang-Chi and the Legend of the Ten Rings"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"1,322,664 views"},"navigationEndpoint":{"clickTrackingParams":"CJkDEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNT0xURzd0OUUtdkpvMzVCemVUd1ZH","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=im80Ib1f30o","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"im80Ib1f30o","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr6---sn-cxaaj5o5q5-tt1e6.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=8a6f3421bd5fdf4a\u0026ip=74.12.195.102\u0026initcwndbps=1521250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CJkDEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CJkDEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CJkDEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1VAyr7_6puEzbeKAaoBIlBMUkQ3Ti1acmoyRE1PTFRHN3Q5RS12Sm8zNUJ6ZVR3Vkc=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CKADEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.3 million views"}},"simpleText":"1.3M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CJ8DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CJ8DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"im80Ib1f30o","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CJ8DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["im80Ib1f30o"],"params":"CAQ%3D"}},"videoIds":["im80Ib1f30o"]}}]}},"trackingParams":"CJ8DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CJkDEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"im80Ib1f30o","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CJkDEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CJ4DEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"im80Ib1f30o"}},"trackingParams":"CJ4DEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CJ0DENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"im80Ib1f30o","onAddCommand":{"clickTrackingParams":"CJ0DENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"im80Ib1f30o","params":"CAI%3D"}}}},"trackingParams":"CJ0DENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CJkDEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtpbTgwSWIxZjMwbw%3D%3D","commands":[{"clickTrackingParams":"CJkDEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CJwDEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CJkDEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CJkDEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"7 minutes, 17 seconds"}},"simpleText":"7:17"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CJsDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"im80Ib1f30o","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CJsDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"im80Ib1f30o"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CJsDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CJoDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CJoDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"im80Ib1f30o","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CJoDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["im80Ib1f30o"],"params":"CAQ%3D"}},"videoIds":["im80Ib1f30o"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CJoDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/im80Ib1f30o/mqdefault_6s.webp?du=3000\u0026sqp=CMj9ip8G\u0026rs=AOn4CLA-8ZrDpuiyWfO7XAskNN8Pd_kDhw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"gXcoNoi-3kA","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/gXcoNoi-3kA/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAV0jJ3hz5CKQbqEBSAAM4O2IkwLQ","width":168,"height":94},{"url":"https://i.ytimg.com/vi/gXcoNoi-3kA/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAdz6bfdtMLzgjxrzcazCqBKJxtuA","width":196,"height":110},{"url":"https://i.ytimg.com/vi/gXcoNoi-3kA/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCPY5LeBKRrIoadNRSOP6anA45RNA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/gXcoNoi-3kA/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBruc8fxA83syV5SZ3dhLflAtw31Q","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Moist Meter | Psychonauts 2 by penguinz0 1 year ago 7 minutes, 36 seconds 700,602 views"}},"simpleText":"Moist Meter | Psychonauts 2"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"700,602 views"},"navigationEndpoint":{"clickTrackingParams":"CJEDEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNT0xURzd0OUUtdkpvMzVCemVUd1ZH","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=gXcoNoi-3kA","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"gXcoNoi-3kA","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr5---sn-cxaaj5o5q5-tt1ee.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=8177283688bede40\u0026ip=74.12.195.102\u0026initcwndbps=1816250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CJEDEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CJEDEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CJEDEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1VAwLz7xeiGyruBAaoBIlBMUkQ3Ti1acmoyRE1PTFRHN3Q5RS12Sm8zNUJ6ZVR3Vkc=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CJgDEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"700K views"}},"simpleText":"700K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CJcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CJcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"gXcoNoi-3kA","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CJcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["gXcoNoi-3kA"],"params":"CAQ%3D"}},"videoIds":["gXcoNoi-3kA"]}}]}},"trackingParams":"CJcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CJEDEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"gXcoNoi-3kA","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CJEDEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CJYDEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"gXcoNoi-3kA"}},"trackingParams":"CJYDEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CJUDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"gXcoNoi-3kA","onAddCommand":{"clickTrackingParams":"CJUDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"gXcoNoi-3kA","params":"CAI%3D"}}}},"trackingParams":"CJUDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CJEDEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtnWGNvTm9pLTNrQQ%3D%3D","commands":[{"clickTrackingParams":"CJEDEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CJQDEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CJEDEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CJEDEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"7 minutes, 36 seconds"}},"simpleText":"7:36"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CJMDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"gXcoNoi-3kA","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CJMDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"gXcoNoi-3kA"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CJMDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CJIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CJIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"gXcoNoi-3kA","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CJIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["gXcoNoi-3kA"],"params":"CAQ%3D"}},"videoIds":["gXcoNoi-3kA"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CJIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/gXcoNoi-3kA/mqdefault_6s.webp?du=3000\u0026sqp=COD-ip8G\u0026rs=AOn4CLBcuuWV_N4qG_eKL4OTi4j2jaTlhw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"EXeSbVaMkjA","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/EXeSbVaMkjA/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCPpvZ7lb2qRNhrnzEsRMuksG25qQ","width":168,"height":94},{"url":"https://i.ytimg.com/vi/EXeSbVaMkjA/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDCV5fMag432CQD88HwaI6V1weoxQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/EXeSbVaMkjA/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBKKQ0PflhiVXZ9noFyzB1iiejq4w","width":246,"height":138},{"url":"https://i.ytimg.com/vi/EXeSbVaMkjA/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAjTrCgd0tbZH1lcizQ0r3KRZWN6A","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Moist Meter | Free Guy by penguinz0 1 year ago 5 minutes, 27 seconds 1,374,917 views"}},"simpleText":"Moist Meter | Free Guy"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"1,374,917 views"},"navigationEndpoint":{"clickTrackingParams":"CIkDEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNT0xURzd0OUUtdkpvMzVCemVUd1ZH","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=EXeSbVaMkjA","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"EXeSbVaMkjA","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr5---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=1177926d568c9230\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CIkDEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CIkDEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CIkDEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1VAsKSytNXN5LsRqgEiUExSRDdOLVpyajJETU9MVEc3dDlFLXZKbzM1QnplVHdWRw==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CJADEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.3 million views"}},"simpleText":"1.3M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CI8DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CI8DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"EXeSbVaMkjA","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CI8DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["EXeSbVaMkjA"],"params":"CAQ%3D"}},"videoIds":["EXeSbVaMkjA"]}}]}},"trackingParams":"CI8DEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CIkDEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"EXeSbVaMkjA","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CIkDEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CI4DEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"EXeSbVaMkjA"}},"trackingParams":"CI4DEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CI0DENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"EXeSbVaMkjA","onAddCommand":{"clickTrackingParams":"CI0DENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"EXeSbVaMkjA","params":"CAI%3D"}}}},"trackingParams":"CI0DENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CIkDEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtFWGVTYlZhTWtqQQ%3D%3D","commands":[{"clickTrackingParams":"CIkDEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CIwDEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CIkDEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CIkDEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"5 minutes, 27 seconds"}},"simpleText":"5:27"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CIsDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"EXeSbVaMkjA","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CIsDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"EXeSbVaMkjA"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CIsDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CIoDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CIoDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"EXeSbVaMkjA","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CIoDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["EXeSbVaMkjA"],"params":"CAQ%3D"}},"videoIds":["EXeSbVaMkjA"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CIoDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/EXeSbVaMkjA/mqdefault_6s.webp?du=3000\u0026sqp=CKDfip8G\u0026rs=AOn4CLB3kLwI2K3bkxS7JC8UzdY7QFyKuQ","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"cdeFqNjGVUI","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/cdeFqNjGVUI/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBESUi57fM4AdDgU1pk2m8PclxUSA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/cdeFqNjGVUI/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLD6BJt2-RLoVWI1pOojHEfKrbw9zQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/cdeFqNjGVUI/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBhck7c2Pe_R9A912Oa9vVqtqmwEg","width":246,"height":138},{"url":"https://i.ytimg.com/vi/cdeFqNjGVUI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAHXvSgCIAo4wP-HDJGWJZysUJdPQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Moist Meter | The Suicide Squad by penguinz0 1 year ago 7 minutes, 34 seconds 1,595,199 views"}},"simpleText":"Moist Meter | The Suicide Squad"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"1,595,199 views"},"navigationEndpoint":{"clickTrackingParams":"CIEDEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNT0xURzd0OUUtdkpvMzVCemVUd1ZH","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=cdeFqNjGVUI","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"cdeFqNjGVUI","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=71d785a8d8c65542\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CIEDEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CIEDEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CIEDEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1VAwqqZxo214etxqgEiUExSRDdOLVpyajJETU9MVEc3dDlFLXZKbzM1QnplVHdWRw==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CIgDEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.5 million views"}},"simpleText":"1.5M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CIcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CIcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"cdeFqNjGVUI","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CIcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["cdeFqNjGVUI"],"params":"CAQ%3D"}},"videoIds":["cdeFqNjGVUI"]}}]}},"trackingParams":"CIcDEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CIEDEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"cdeFqNjGVUI","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CIEDEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CIYDEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"cdeFqNjGVUI"}},"trackingParams":"CIYDEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CIUDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"cdeFqNjGVUI","onAddCommand":{"clickTrackingParams":"CIUDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"cdeFqNjGVUI","params":"CAI%3D"}}}},"trackingParams":"CIUDENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CIEDEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtjZGVGcU5qR1ZVSQ%3D%3D","commands":[{"clickTrackingParams":"CIEDEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CIQDEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CIEDEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CIEDEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"7 minutes, 34 seconds"}},"simpleText":"7:34"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CIMDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"cdeFqNjGVUI","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CIMDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"cdeFqNjGVUI"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CIMDEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CIIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CIIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"cdeFqNjGVUI","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CIIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["cdeFqNjGVUI"],"params":"CAQ%3D"}},"videoIds":["cdeFqNjGVUI"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CIIDEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/cdeFqNjGVUI/mqdefault_6s.webp?du=3000\u0026sqp=CJqDi58G\u0026rs=AOn4CLDu_0gqBCJw2-s2fNGFy91BzXZhyw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"Rmdcm2vmH8A","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/Rmdcm2vmH8A/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCCTXJ6FTvWD8Sv7xqmLd-jIGTKRQ","width":168,"height":94},{"url":"https://i.ytimg.com/vi/Rmdcm2vmH8A/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLA06pRvrQUSiQl_kWsfhlxCaBEGIw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/Rmdcm2vmH8A/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLByms_M0sdSfRGDPCtoz536Au3nPg","width":246,"height":138},{"url":"https://i.ytimg.com/vi/Rmdcm2vmH8A/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDqKe_U1xDqEj2krNiC3kWguSx-VA","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Moist Meter | The Green Knight by penguinz0 1 year ago 9 minutes, 36 seconds 634,300 views"}},"simpleText":"Moist Meter | The Green Knight"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"634,300 views"},"navigationEndpoint":{"clickTrackingParams":"CPkCEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNT0xURzd0OUUtdkpvMzVCemVUd1ZH","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=Rmdcm2vmH8A","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"Rmdcm2vmH8A","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr8---sn-cxaaj5o5q5-tt1y.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=46675c9b6be61fc0\u0026ip=74.12.195.102\u0026initcwndbps=1702500\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CPkCEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CPkCEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CPkCEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1VAwL-Y37aT17NGqgEiUExSRDdOLVpyajJETU9MVEc3dDlFLXZKbzM1QnplVHdWRw==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CIADEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"634K views"}},"simpleText":"634K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CP8CEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CP8CEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"Rmdcm2vmH8A","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CP8CEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["Rmdcm2vmH8A"],"params":"CAQ%3D"}},"videoIds":["Rmdcm2vmH8A"]}}]}},"trackingParams":"CP8CEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CPkCEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"Rmdcm2vmH8A","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CPkCEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CP4CEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"Rmdcm2vmH8A"}},"trackingParams":"CP4CEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CP0CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"Rmdcm2vmH8A","onAddCommand":{"clickTrackingParams":"CP0CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"Rmdcm2vmH8A","params":"CAI%3D"}}}},"trackingParams":"CP0CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CPkCEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtSbWRjbTJ2bUg4QQ%3D%3D","commands":[{"clickTrackingParams":"CPkCEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CPwCEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CPkCEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CPkCEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"9 minutes, 36 seconds"}},"simpleText":"9:36"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CPsCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"Rmdcm2vmH8A","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CPsCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"Rmdcm2vmH8A"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CPsCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CPoCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CPoCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"Rmdcm2vmH8A","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CPoCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["Rmdcm2vmH8A"],"params":"CAQ%3D"}},"videoIds":["Rmdcm2vmH8A"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CPoCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/Rmdcm2vmH8A/mqdefault_6s.webp?du=3000\u0026sqp=CLDiip8G\u0026rs=AOn4CLC3q7BA4RZbhvk42gY5Zgn-VXeWUA","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}}],"trackingParams":"CPYCEMY5IhMI-Mm_pq2E_QIVEIf_BB2wqAtV","visibleItemCount":4,"nextButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"CHEVRON_RIGHT"},"accessibility":{"label":"Next"},"trackingParams":"CPgCEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},"previousButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"CHEVRON_LEFT"},"accessibility":{"label":"Previous"},"trackingParams":"CPcCEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}}}},"trackingParams":"CPQCENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","playAllButton":{"buttonRenderer":{"style":"STYLE_TEXT","size":"SIZE_DEFAULT","isDisabled":false,"text":{"runs":[{"text":"Play all"}]},"icon":{"iconType":"PLAY_ALL"},"navigationEndpoint":{"clickTrackingParams":"CPUCEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=nK_XkXHS1VI\u0026list=PLRD7N-Zrj2DMOLTG7t9E-vJo35BzeTwVG","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"nK_XkXHS1VI","playlistId":"PLRD7N-Zrj2DMOLTG7t9E-vJo35BzeTwVG","loggingContext":{"vssLoggingContext":{"serializedContextData":"GiJQTFJEN04tWnJqMkRNT0xURzd0OUUtdkpvMzVCemVUd1ZH"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr5---sn-cxaaj5o5q5-tt1y.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=9cafd79171d2d552\u0026ip=74.12.195.102\u0026initcwndbps=1702500\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"trackingParams":"CPUCEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}}}}],"trackingParams":"CPMCELsvGAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"itemSectionRenderer":{"contents":[{"shelfRenderer":{"title":{"runs":[{"text":"The Official Podcast","navigationEndpoint":{"clickTrackingParams":"CI4CENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLRD7N-Zrj2DMPlFktUo5BRduSyCxu8nZy","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLRD7N-Zrj2DMPlFktUo5BRduSyCxu8nZy"}}}]},"endpoint":{"clickTrackingParams":"CI4CENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLRD7N-Zrj2DMPlFktUo5BRduSyCxu8nZy","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLRD7N-Zrj2DMPlFktUo5BRduSyCxu8nZy"}},"content":{"horizontalListRenderer":{"items":[{"gridVideoRenderer":{"videoId":"WgQRzLWWalE","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/WgQRzLWWalE/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAVDvoN1_WvUyIRSKICO_XluTv7DA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/WgQRzLWWalE/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDG0hQE37Z2NYfbirGR3j-nqOEDGw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/WgQRzLWWalE/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBFbHyHkV74Y6mV53vFeONxK5qh6w","width":246,"height":138},{"url":"https://i.ytimg.com/vi/WgQRzLWWalE/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBwKtL68QfrxWtzMS0zI1iQUwYrww","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Official Podcast #231: Turkish Oil Wrestling with Josh Pillault by penguinz0 1 year ago 1 hour, 31 minutes 400,142 views"}},"simpleText":"The Official Podcast #231: Turkish Oil Wrestling with Josh Pillault"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"400,142 views"},"navigationEndpoint":{"clickTrackingParams":"COsCEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNUGxGa3RVbzVCUmR1U3lDeHU4blp5","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=WgQRzLWWalE","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"WgQRzLWWalE","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=5a0411ccb5966a51\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"COsCEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"COsCEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"COsCEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1VA0dTZrMu5hIJaqgEiUExSRDdOLVpyajJETVBsRmt0VW81QlJkdVN5Q3h1OG5aeQ==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CPICEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"400K views"}},"simpleText":"400K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CPECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CPECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"WgQRzLWWalE","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CPECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["WgQRzLWWalE"],"params":"CAQ%3D"}},"videoIds":["WgQRzLWWalE"]}}]}},"trackingParams":"CPECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"COsCEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"WgQRzLWWalE","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"COsCEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CPACEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"WgQRzLWWalE"}},"trackingParams":"CPACEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CO8CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"WgQRzLWWalE","onAddCommand":{"clickTrackingParams":"CO8CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"WgQRzLWWalE","params":"CAI%3D"}}}},"trackingParams":"CO8CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"COsCEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtXZ1FSekxXV2FsRQ%3D%3D","commands":[{"clickTrackingParams":"COsCEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CO4CEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"COsCEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"COsCEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 hour, 31 minutes, 57 seconds"}},"simpleText":"1:31:57"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CO0CEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"WgQRzLWWalE","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CO0CEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"WgQRzLWWalE"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CO0CEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"COwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"COwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"WgQRzLWWalE","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"COwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["WgQRzLWWalE"],"params":"CAQ%3D"}},"videoIds":["WgQRzLWWalE"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"COwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/WgQRzLWWalE/mqdefault_6s.webp?du=3000\u0026sqp=CKPwip8G\u0026rs=AOn4CLBYuViDPottFrVz-0816YuRSkccLQ","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"vtbTjuKdAn8","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/vtbTjuKdAn8/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBBR4gekH7Xm0w1ObKTyITuyZTTPQ","width":168,"height":94},{"url":"https://i.ytimg.com/vi/vtbTjuKdAn8/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCExB5TvYLrT3AtfDeRjBfBMhNdZw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/vtbTjuKdAn8/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCeHdNgf9o1CNe5N-dnIBeaK3vG4A","width":246,"height":138},{"url":"https://i.ytimg.com/vi/vtbTjuKdAn8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCH2_39mcHXAILTWNdSGkfHP8BHkA","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Official Podcast #230: E(ntering) D(at) P(rison) by penguinz0 1 year ago 1 hour, 17 minutes 786,966 views"}},"simpleText":"The Official Podcast #230: E(ntering) D(at) P(rison)"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"786,966 views"},"navigationEndpoint":{"clickTrackingParams":"COMCEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNUGxGa3RVbzVCUmR1U3lDeHU4blp5","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=vtbTjuKdAn8","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"vtbTjuKdAn8","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr5---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=bed6d38ee29d027f\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"COMCEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"COMCEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"COMCEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1VA_4T0lO7xtOu-AaoBIlBMUkQ3Ti1acmoyRE1QbEZrdFVvNUJSZHVTeUN4dThuWnk=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"COoCEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"786K views"}},"simpleText":"786K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"COkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"COkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"vtbTjuKdAn8","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"COkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["vtbTjuKdAn8"],"params":"CAQ%3D"}},"videoIds":["vtbTjuKdAn8"]}}]}},"trackingParams":"COkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"COMCEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"vtbTjuKdAn8","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"COMCEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"COgCEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"vtbTjuKdAn8"}},"trackingParams":"COgCEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"COcCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"vtbTjuKdAn8","onAddCommand":{"clickTrackingParams":"COcCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"vtbTjuKdAn8","params":"CAI%3D"}}}},"trackingParams":"COcCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"COMCEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgt2dGJUanVLZEFuOA%3D%3D","commands":[{"clickTrackingParams":"COMCEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"COYCEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"COMCEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"COMCEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 hour, 17 minutes, 10 seconds"}},"simpleText":"1:17:10"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"COUCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"vtbTjuKdAn8","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"COUCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"vtbTjuKdAn8"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"COUCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"COQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"COQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"vtbTjuKdAn8","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"COQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["vtbTjuKdAn8"],"params":"CAQ%3D"}},"videoIds":["vtbTjuKdAn8"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"COQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/vtbTjuKdAn8/mqdefault_6s.webp?du=3000\u0026sqp=CJn6ip8G\u0026rs=AOn4CLBvY4aHYoLAC6Ex62hcWmwxqHWExQ","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"6kplWHLQEVM","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/6kplWHLQEVM/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLD6bOGG5CGCjmwHXshghGcbrU1nDA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/6kplWHLQEVM/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCnE86EFuALE_ANonq-bvf7enMCLQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/6kplWHLQEVM/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLC3XmPgsv58JU4gEIy8Awo-GiHjHw","width":246,"height":138},{"url":"https://i.ytimg.com/vi/6kplWHLQEVM/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLABHWJ9dkx_0-uCykutQPtN7YEsTg","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Official Podcast #229: Jared Fogle vs Austin Jones by penguinz0 1 year ago 1 hour, 14 minutes 326,543 views"}},"simpleText":"The Official Podcast #229: Jared Fogle vs Austin Jones"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"326,543 views"},"navigationEndpoint":{"clickTrackingParams":"CNsCEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNUGxGa3RVbzVCUmR1U3lDeHU4blp5","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=6kplWHLQEVM","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"6kplWHLQEVM","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=ea4a655872d01153\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CNsCEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CNsCEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CNsCEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1VA06LAloermaXqAaoBIlBMUkQ3Ti1acmoyRE1QbEZrdFVvNUJSZHVTeUN4dThuWnk=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"COICEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"326K views"}},"simpleText":"326K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"COECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"COECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"6kplWHLQEVM","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"COECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["6kplWHLQEVM"],"params":"CAQ%3D"}},"videoIds":["6kplWHLQEVM"]}}]}},"trackingParams":"COECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CNsCEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"6kplWHLQEVM","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CNsCEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"COACEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"6kplWHLQEVM"}},"trackingParams":"COACEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CN8CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"6kplWHLQEVM","onAddCommand":{"clickTrackingParams":"CN8CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"6kplWHLQEVM","params":"CAI%3D"}}}},"trackingParams":"CN8CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CNsCEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs2a3BsV0hMUUVWTQ%3D%3D","commands":[{"clickTrackingParams":"CNsCEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CN4CEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CNsCEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CNsCEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 hour, 14 minutes, 2 seconds"}},"simpleText":"1:14:02"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CN0CEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"6kplWHLQEVM","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CN0CEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"6kplWHLQEVM"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CN0CEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CNwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CNwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"6kplWHLQEVM","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CNwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["6kplWHLQEVM"],"params":"CAQ%3D"}},"videoIds":["6kplWHLQEVM"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CNwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/6kplWHLQEVM/mqdefault_6s.webp?du=3000\u0026sqp=CICFi58G\u0026rs=AOn4CLDrispLQbtrJWxNZJlXq6jYtoS6DQ","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"GrchvHEL-D4","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/GrchvHEL-D4/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDq8duJY8nPFXs4gj_cgVQ7m11E-w","width":168,"height":94},{"url":"https://i.ytimg.com/vi/GrchvHEL-D4/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDFrVTJgOOtMbnSaaKKEM-aHtgVgg","width":196,"height":110},{"url":"https://i.ytimg.com/vi/GrchvHEL-D4/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLA3u46LpQOy4DJ4TGbIM3fhIqC9Uw","width":246,"height":138},{"url":"https://i.ytimg.com/vi/GrchvHEL-D4/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDkc4sfV36Y7J9OGj026Hr2-aZ4KQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Official Podcast #228: Farewell, Prince Phillip by penguinz0 1 year ago 1 hour, 13 minutes 285,724 views"}},"simpleText":"The Official Podcast #228: Farewell, Prince Phillip"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"285,724 views"},"navigationEndpoint":{"clickTrackingParams":"CNMCEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNUGxGa3RVbzVCUmR1U3lDeHU4blp5","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=GrchvHEL-D4","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"GrchvHEL-D4","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr8---sn-cxaaj5o5q5-tt1el.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=1ab721bc710bf83e\u0026ip=74.12.195.102\u0026initcwndbps=1782500\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CNMCEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CNMCEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CNMCEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1VAvvCviMe3yNsaqgEiUExSRDdOLVpyajJETVBsRmt0VW81QlJkdVN5Q3h1OG5aeQ==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CNoCEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"285K views"}},"simpleText":"285K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CNkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CNkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"GrchvHEL-D4","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CNkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["GrchvHEL-D4"],"params":"CAQ%3D"}},"videoIds":["GrchvHEL-D4"]}}]}},"trackingParams":"CNkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CNMCEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"GrchvHEL-D4","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CNMCEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CNgCEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"GrchvHEL-D4"}},"trackingParams":"CNgCEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CNcCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"GrchvHEL-D4","onAddCommand":{"clickTrackingParams":"CNcCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"GrchvHEL-D4","params":"CAI%3D"}}}},"trackingParams":"CNcCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CNMCEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtHcmNodkhFTC1ENA%3D%3D","commands":[{"clickTrackingParams":"CNMCEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CNYCEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CNMCEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CNMCEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 hour, 13 minutes, 47 seconds"}},"simpleText":"1:13:47"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CNUCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"GrchvHEL-D4","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CNUCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"GrchvHEL-D4"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CNUCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CNQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CNQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"GrchvHEL-D4","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CNQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["GrchvHEL-D4"],"params":"CAQ%3D"}},"videoIds":["GrchvHEL-D4"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CNQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/GrchvHEL-D4/mqdefault_6s.webp?du=3000\u0026sqp=CPrhip8G\u0026rs=AOn4CLA8Y-vu6u1Hj13pB7VyOQOIlJPz6A","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"t3BrEm1QdSE","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/t3BrEm1QdSE/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCH-VK3RB1O1Q7lqkmWQ1DfEJVCtw","width":168,"height":94},{"url":"https://i.ytimg.com/vi/t3BrEm1QdSE/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLC2G5tjC7sIrS550Gw2hpG68dwoNw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/t3BrEm1QdSE/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCAhg8AkV9xaPmuli_AiZamPjpSBg","width":246,"height":138},{"url":"https://i.ytimg.com/vi/t3BrEm1QdSE/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCJ-qIXb3fa225o06R_SGJ1mLcn4g","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Official Podcast #227: Godzilla vs Kong vs Cancel Culture by penguinz0 1 year ago 1 hour, 26 minutes 289,321 views"}},"simpleText":"The Official Podcast #227: Godzilla vs Kong vs Cancel Culture"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"289,321 views"},"navigationEndpoint":{"clickTrackingParams":"CMsCEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNUGxGa3RVbzVCUmR1U3lDeHU4blp5","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=t3BrEm1QdSE","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"t3BrEm1QdSE","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr2---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=b7706b126d507521\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CMsCEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CMsCEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CMsCEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1VAoerB6qbimri3AaoBIlBMUkQ3Ti1acmoyRE1QbEZrdFVvNUJSZHVTeUN4dThuWnk=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CNICEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"289K views"}},"simpleText":"289K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CNECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CNECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"t3BrEm1QdSE","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CNECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["t3BrEm1QdSE"],"params":"CAQ%3D"}},"videoIds":["t3BrEm1QdSE"]}}]}},"trackingParams":"CNECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CMsCEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"t3BrEm1QdSE","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CMsCEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CNACEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"t3BrEm1QdSE"}},"trackingParams":"CNACEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CM8CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"t3BrEm1QdSE","onAddCommand":{"clickTrackingParams":"CM8CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"t3BrEm1QdSE","params":"CAI%3D"}}}},"trackingParams":"CM8CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CMsCEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgt0M0JyRW0xUWRTRQ%3D%3D","commands":[{"clickTrackingParams":"CMsCEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CM4CEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CMsCEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CMsCEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 hour, 26 minutes, 3 seconds"}},"simpleText":"1:26:03"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CM0CEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"t3BrEm1QdSE","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CM0CEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"t3BrEm1QdSE"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CM0CEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CMwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CMwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"t3BrEm1QdSE","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CMwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["t3BrEm1QdSE"],"params":"CAQ%3D"}},"videoIds":["t3BrEm1QdSE"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CMwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/t3BrEm1QdSE/mqdefault_6s.webp?du=3000\u0026sqp=CL7cip8G\u0026rs=AOn4CLCACwZZm8fyEOJSCEnOoIlt6MiNbA","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"yEHNVhjUxwI","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/yEHNVhjUxwI/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLA2UgJmdGSl3sA0-J-qWtYcpI_sQw","width":168,"height":94},{"url":"https://i.ytimg.com/vi/yEHNVhjUxwI/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLA-kUeyCr7-dufZTvUp7uYrlnuYtw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/yEHNVhjUxwI/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDNwju8VlV0Pn84jcKRcY2RFdVXCg","width":246,"height":138},{"url":"https://i.ytimg.com/vi/yEHNVhjUxwI/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDFRMP34SO7KoqonY2AY_MRU5isGw","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Official Podcast #226: Down the Rabbit Hole with Fredrik Knudsen by penguinz0 1 year ago 2 hours, 8 minutes 644,861 views"}},"simpleText":"The Official Podcast #226: Down the Rabbit Hole with Fredrik Knudsen"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"644,861 views"},"navigationEndpoint":{"clickTrackingParams":"CMMCEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNUGxGa3RVbzVCUmR1U3lDeHU4blp5","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=yEHNVhjUxwI","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"yEHNVhjUxwI","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=c841cd5618d4c702\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CMMCEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CMMCEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CMMCEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1VAgo7TxuGq86DIAaoBIlBMUkQ3Ti1acmoyRE1QbEZrdFVvNUJSZHVTeUN4dThuWnk=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CMoCEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"644K views"}},"simpleText":"644K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CMkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CMkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"yEHNVhjUxwI","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CMkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["yEHNVhjUxwI"],"params":"CAQ%3D"}},"videoIds":["yEHNVhjUxwI"]}}]}},"trackingParams":"CMkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CMMCEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"yEHNVhjUxwI","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CMMCEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CMgCEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"yEHNVhjUxwI"}},"trackingParams":"CMgCEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CMcCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"yEHNVhjUxwI","onAddCommand":{"clickTrackingParams":"CMcCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"yEHNVhjUxwI","params":"CAI%3D"}}}},"trackingParams":"CMcCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CMMCEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgt5RUhOVmhqVXh3SQ%3D%3D","commands":[{"clickTrackingParams":"CMMCEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CMYCEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CMMCEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CMMCEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"2 hours, 8 minutes, 11 seconds"}},"simpleText":"2:08:11"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CMUCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"yEHNVhjUxwI","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CMUCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"yEHNVhjUxwI"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CMUCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CMQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CMQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"yEHNVhjUxwI","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CMQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["yEHNVhjUxwI"],"params":"CAQ%3D"}},"videoIds":["yEHNVhjUxwI"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CMQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/yEHNVhjUxwI/mqdefault_6s.webp?du=3000\u0026sqp=CPDLip8G\u0026rs=AOn4CLD5mSseyX98zjU3m1ZwKqp_ite5NQ","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"WVGiXGq8UJU","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/WVGiXGq8UJU/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLD9h3rqtkBu109HhGWzbZuwlYBfYg","width":168,"height":94},{"url":"https://i.ytimg.com/vi/WVGiXGq8UJU/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDO8znv9N2E_vSKxQ59_l02tGXsXA","width":196,"height":110},{"url":"https://i.ytimg.com/vi/WVGiXGq8UJU/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCyvZxg0jWCF0yI8CgmLr5KOffFbQ","width":246,"height":138},{"url":"https://i.ytimg.com/vi/WVGiXGq8UJU/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDxMQaEkGb0gqbUW8IVVBaYjVbZzQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Official Podcast #225: One of Us Is A Virgin by penguinz0 1 year ago 1 hour, 17 minutes 373,631 views"}},"simpleText":"The Official Podcast #225: One of Us Is A Virgin"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"373,631 views"},"navigationEndpoint":{"clickTrackingParams":"CLsCEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNUGxGa3RVbzVCUmR1U3lDeHU4blp5","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=WVGiXGq8UJU","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"WVGiXGq8UJU","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr1---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=5951a25c6abc5095\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CLsCEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CLsCEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CLsCEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1VAlaHx1cbL6KhZqgEiUExSRDdOLVpyajJETVBsRmt0VW81QlJkdVN5Q3h1OG5aeQ==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CMICEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"373K views"}},"simpleText":"373K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CMECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CMECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"WVGiXGq8UJU","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CMECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["WVGiXGq8UJU"],"params":"CAQ%3D"}},"videoIds":["WVGiXGq8UJU"]}}]}},"trackingParams":"CMECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CLsCEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"WVGiXGq8UJU","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CLsCEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CMACEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"WVGiXGq8UJU"}},"trackingParams":"CMACEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CL8CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"WVGiXGq8UJU","onAddCommand":{"clickTrackingParams":"CL8CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"WVGiXGq8UJU","params":"CAI%3D"}}}},"trackingParams":"CL8CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CLsCEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtXVkdpWEdxOFVKVQ%3D%3D","commands":[{"clickTrackingParams":"CLsCEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CL4CEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CLsCEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CLsCEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 hour, 17 minutes, 2 seconds"}},"simpleText":"1:17:02"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CL0CEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"WVGiXGq8UJU","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CL0CEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"WVGiXGq8UJU"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CL0CEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CLwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CLwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"WVGiXGq8UJU","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CLwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["WVGiXGq8UJU"],"params":"CAQ%3D"}},"videoIds":["WVGiXGq8UJU"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CLwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/WVGiXGq8UJU/mqdefault_6s.webp?du=3000\u0026sqp=CKu-ip8G\u0026rs=AOn4CLBJTjkzEuefO778WaeblY4evTi06A","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"xYjGID7cE5g","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/xYjGID7cE5g/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBFodeK8xh-td8FDompVx4OjrfJPw","width":168,"height":94},{"url":"https://i.ytimg.com/vi/xYjGID7cE5g/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLD2FhyCkKSJ9e1CuQ88x1KsjAZomA","width":196,"height":110},{"url":"https://i.ytimg.com/vi/xYjGID7cE5g/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCu11xw-ZC-Bd9rR0N6OHputz8iOA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/xYjGID7cE5g/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCfD81vg9nHYJc9QvvTflW9y1isZg","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Official Podcast #224: Kaya's Funeral by penguinz0 1 year ago 1 hour, 5 minutes 295,440 views"}},"simpleText":"The Official Podcast #224: Kaya's Funeral"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"295,440 views"},"navigationEndpoint":{"clickTrackingParams":"CLMCEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNUGxGa3RVbzVCUmR1U3lDeHU4blp5","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=xYjGID7cE5g","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"xYjGID7cE5g","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=c588c6203edc1398\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CLMCEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CLMCEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CLMCEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1VAmKfw9oPEscTFAaoBIlBMUkQ3Ti1acmoyRE1QbEZrdFVvNUJSZHVTeUN4dThuWnk=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CLoCEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"295K views"}},"simpleText":"295K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CLkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CLkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"xYjGID7cE5g","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CLkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["xYjGID7cE5g"],"params":"CAQ%3D"}},"videoIds":["xYjGID7cE5g"]}}]}},"trackingParams":"CLkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CLMCEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"xYjGID7cE5g","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CLMCEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CLgCEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"xYjGID7cE5g"}},"trackingParams":"CLgCEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CLcCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"xYjGID7cE5g","onAddCommand":{"clickTrackingParams":"CLcCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"xYjGID7cE5g","params":"CAI%3D"}}}},"trackingParams":"CLcCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CLMCEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgt4WWpHSUQ3Y0U1Zw%3D%3D","commands":[{"clickTrackingParams":"CLMCEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CLYCEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CLMCEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CLMCEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 hour, 5 minutes, 40 seconds"}},"simpleText":"1:05:40"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CLUCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"xYjGID7cE5g","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CLUCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"xYjGID7cE5g"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CLUCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CLQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CLQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"xYjGID7cE5g","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CLQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["xYjGID7cE5g"],"params":"CAQ%3D"}},"videoIds":["xYjGID7cE5g"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CLQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/xYjGID7cE5g/mqdefault_6s.webp?du=3000\u0026sqp=CMjpip8G\u0026rs=AOn4CLDU-U4wS5HxtWyLj9Pd_ZccQghNkA","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"45ZpXY9H61Q","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/45ZpXY9H61Q/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLD0AmA1gBxeF_fsIUF6MuJLKZRvLA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/45ZpXY9H61Q/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCGb5yRSifbxWkKzcJZDG9Kdm7iNw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/45ZpXY9H61Q/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBghlYtZQcIJnOWHeNps9fgslfYRA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/45ZpXY9H61Q/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLC6c-7Osl8EV7ZVM9xYoiZB_tynaw","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Official Podcast #223: Incels In Space by penguinz0 1 year ago 1 hour, 37 minutes 435,977 views"}},"simpleText":"The Official Podcast #223: Incels In Space"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"435,977 views"},"navigationEndpoint":{"clickTrackingParams":"CKsCEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNUGxGa3RVbzVCUmR1U3lDeHU4blp5","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=45ZpXY9H61Q","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"45ZpXY9H61Q","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr2---sn-cxaaj5o5q5-tt1el.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=e396695d8f47eb54\u0026ip=74.12.195.102\u0026initcwndbps=1782500\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CKsCEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CKsCEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CKsCEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1VA1Naf-tirmsvjAaoBIlBMUkQ3Ti1acmoyRE1QbEZrdFVvNUJSZHVTeUN4dThuWnk=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CLICEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"435K views"}},"simpleText":"435K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CLECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CLECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"45ZpXY9H61Q","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CLECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["45ZpXY9H61Q"],"params":"CAQ%3D"}},"videoIds":["45ZpXY9H61Q"]}}]}},"trackingParams":"CLECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CKsCEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"45ZpXY9H61Q","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CKsCEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CLACEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"45ZpXY9H61Q"}},"trackingParams":"CLACEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CK8CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"45ZpXY9H61Q","onAddCommand":{"clickTrackingParams":"CK8CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"45ZpXY9H61Q","params":"CAI%3D"}}}},"trackingParams":"CK8CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CKsCEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs0NVpwWFk5SDYxUQ%3D%3D","commands":[{"clickTrackingParams":"CKsCEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CK4CEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CKsCEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CKsCEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 hour, 37 minutes, 3 seconds"}},"simpleText":"1:37:03"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CK0CEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"45ZpXY9H61Q","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CK0CEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"45ZpXY9H61Q"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CK0CEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CKwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CKwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"45ZpXY9H61Q","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CKwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["45ZpXY9H61Q"],"params":"CAQ%3D"}},"videoIds":["45ZpXY9H61Q"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CKwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/45ZpXY9H61Q/mqdefault_6s.webp?du=3000\u0026sqp=CMDpip8G\u0026rs=AOn4CLATZ_fKdutiI1eQdCw9elKsedmuKw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"GaiElU2xNIA","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/GaiElU2xNIA/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCYjwDyRrlCBzZPOAPAuDVX28f7hg","width":168,"height":94},{"url":"https://i.ytimg.com/vi/GaiElU2xNIA/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLACgijuyxVO0a_SdmPG4ppsq6pqDQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/GaiElU2xNIA/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBonNbFEtyCo75Obs4XorC9c-X-Rw","width":246,"height":138},{"url":"https://i.ytimg.com/vi/GaiElU2xNIA/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCEVcAp0VcVo-QdxoRmhYC13NJ9WA","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Official Podcast #222: The Worst Hentai, Best Surprise by penguinz0 1 year ago 1 hour, 13 minutes 219,065 views"}},"simpleText":"The Official Podcast #222: The Worst Hentai, Best Surprise"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"219,065 views"},"navigationEndpoint":{"clickTrackingParams":"CKMCEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNUGxGa3RVbzVCUmR1U3lDeHU4blp5","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=GaiElU2xNIA","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"GaiElU2xNIA","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr1---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=19a884954db13480\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CKMCEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CKMCEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CKMCEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1VAgOnE7dSSodQZqgEiUExSRDdOLVpyajJETVBsRmt0VW81QlJkdVN5Q3h1OG5aeQ==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CKoCEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"219K views"}},"simpleText":"219K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CKkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CKkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"GaiElU2xNIA","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CKkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["GaiElU2xNIA"],"params":"CAQ%3D"}},"videoIds":["GaiElU2xNIA"]}}]}},"trackingParams":"CKkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CKMCEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"GaiElU2xNIA","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CKMCEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CKgCEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"GaiElU2xNIA"}},"trackingParams":"CKgCEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CKcCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"GaiElU2xNIA","onAddCommand":{"clickTrackingParams":"CKcCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"GaiElU2xNIA","params":"CAI%3D"}}}},"trackingParams":"CKcCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CKMCEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtHYWlFbFUyeE5JQQ%3D%3D","commands":[{"clickTrackingParams":"CKMCEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CKYCEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CKMCEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CKMCEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 hour, 13 minutes, 3 seconds"}},"simpleText":"1:13:03"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CKUCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"GaiElU2xNIA","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CKUCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"GaiElU2xNIA"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CKUCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CKQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CKQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"GaiElU2xNIA","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CKQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["GaiElU2xNIA"],"params":"CAQ%3D"}},"videoIds":["GaiElU2xNIA"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CKQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/GaiElU2xNIA/mqdefault_6s.webp?du=3000\u0026sqp=CKDcip8G\u0026rs=AOn4CLCxGDarbzBh1HUCfLEVIBGFYZheCw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"6S50AWezyOE","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/6S50AWezyOE/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLATxOurFSYXb_pe-JM_OkS82jBxVg","width":168,"height":94},{"url":"https://i.ytimg.com/vi/6S50AWezyOE/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAfD3aOgTgVBJEIy5vRZKhJMDaNpw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/6S50AWezyOE/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCGhBPRzizPrH_sbKYVgvneRU4otA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/6S50AWezyOE/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLD7DyB5S-6yMTlwyndd4DCg8biCcw","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Official Podcast #221: The Anthem of Failure by penguinz0 1 year ago 1 hour, 22 minutes 363,354 views"}},"simpleText":"The Official Podcast #221: The Anthem of Failure"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"363,354 views"},"navigationEndpoint":{"clickTrackingParams":"CJsCEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNUGxGa3RVbzVCUmR1U3lDeHU4blp5","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=6S50AWezyOE","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"6S50AWezyOE","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr4---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=e92e740167b3c8e1\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CJsCEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CJsCEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CJsCEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1VA4ZHPvZaAnZfpAaoBIlBMUkQ3Ti1acmoyRE1QbEZrdFVvNUJSZHVTeUN4dThuWnk=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CKICEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"363K views"}},"simpleText":"363K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CKECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CKECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"6S50AWezyOE","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CKECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["6S50AWezyOE"],"params":"CAQ%3D"}},"videoIds":["6S50AWezyOE"]}}]}},"trackingParams":"CKECEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CJsCEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"6S50AWezyOE","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CJsCEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CKACEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"6S50AWezyOE"}},"trackingParams":"CKACEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CJ8CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"6S50AWezyOE","onAddCommand":{"clickTrackingParams":"CJ8CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"6S50AWezyOE","params":"CAI%3D"}}}},"trackingParams":"CJ8CENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CJsCEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs2UzUwQVdlenlPRQ%3D%3D","commands":[{"clickTrackingParams":"CJsCEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CJ4CEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CJsCEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CJsCEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 hour, 22 minutes, 30 seconds"}},"simpleText":"1:22:30"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CJ0CEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"6S50AWezyOE","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CJ0CEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"6S50AWezyOE"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CJ0CEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CJwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CJwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"6S50AWezyOE","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CJwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["6S50AWezyOE"],"params":"CAQ%3D"}},"videoIds":["6S50AWezyOE"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CJwCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/6S50AWezyOE/mqdefault_6s.webp?du=3000\u0026sqp=CI7hip8G\u0026rs=AOn4CLA325jgLneZ6fynL8elJNXK3q3d8Q","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"revGXx6eHl0","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/revGXx6eHl0/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDvBlLBdWaA8y5ks5_K6HAh7lMeDg","width":168,"height":94},{"url":"https://i.ytimg.com/vi/revGXx6eHl0/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLB8wAfvZe2Ux8CP2pP2b-h9BYjM4g","width":196,"height":110},{"url":"https://i.ytimg.com/vi/revGXx6eHl0/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBfb2nopAGwmmmw4gUlXxMgTpHelw","width":246,"height":138},{"url":"https://i.ytimg.com/vi/revGXx6eHl0/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDcrv40OWDmeXEtAD929hChbztgcA","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Official Podcast #220: The Loneliest Valentine by penguinz0 1 year ago 1 hour, 2 minutes 237,053 views"}},"simpleText":"The Official Podcast #220: The Loneliest Valentine"},"publishedTimeText":{"simpleText":"1 year ago"},"viewCountText":{"simpleText":"237,053 views"},"navigationEndpoint":{"clickTrackingParams":"CJMCEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRNUGxGa3RVbzVCUmR1U3lDeHU4blp5","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=revGXx6eHl0","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"revGXx6eHl0","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr5---sn-cxaaj5o5q5-tt1es.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=adebc65f1e9e1e5d\u0026ip=74.12.195.102\u0026initcwndbps=1656250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CJMCEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CJMCEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CJMCEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1VA3bz49PHL8fWtAaoBIlBMUkQ3Ti1acmoyRE1QbEZrdFVvNUJSZHVTeUN4dThuWnk=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CJoCEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"237K views"}},"simpleText":"237K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CJkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CJkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"revGXx6eHl0","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CJkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["revGXx6eHl0"],"params":"CAQ%3D"}},"videoIds":["revGXx6eHl0"]}}]}},"trackingParams":"CJkCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CJMCEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"revGXx6eHl0","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CJMCEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CJgCEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"revGXx6eHl0"}},"trackingParams":"CJgCEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CJcCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"revGXx6eHl0","onAddCommand":{"clickTrackingParams":"CJcCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"revGXx6eHl0","params":"CAI%3D"}}}},"trackingParams":"CJcCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CJMCEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtyZXZHWHg2ZUhsMA%3D%3D","commands":[{"clickTrackingParams":"CJMCEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CJYCEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CJMCEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CJMCEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 hour, 2 minutes, 58 seconds"}},"simpleText":"1:02:58"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CJUCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"revGXx6eHl0","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CJUCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"revGXx6eHl0"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CJUCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CJQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CJQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"revGXx6eHl0","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CJQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["revGXx6eHl0"],"params":"CAQ%3D"}},"videoIds":["revGXx6eHl0"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CJQCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/revGXx6eHl0/mqdefault_6s.webp?du=3000\u0026sqp=CJ_2ip8G\u0026rs=AOn4CLBVND3FjE0Ef5ylDcrcqdjIss1l3Q","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}}],"trackingParams":"CJACEMY5IhMI-Mm_pq2E_QIVEIf_BB2wqAtV","visibleItemCount":4,"nextButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"CHEVRON_RIGHT"},"accessibility":{"label":"Next"},"trackingParams":"CJICEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},"previousButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"CHEVRON_LEFT"},"accessibility":{"label":"Previous"},"trackingParams":"CJECEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}}}},"trackingParams":"CI4CENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","playAllButton":{"buttonRenderer":{"style":"STYLE_TEXT","size":"SIZE_DEFAULT","isDisabled":false,"text":{"runs":[{"text":"Play all"}]},"icon":{"iconType":"PLAY_ALL"},"navigationEndpoint":{"clickTrackingParams":"CI8CEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=WgQRzLWWalE\u0026list=PLRD7N-Zrj2DMPlFktUo5BRduSyCxu8nZy","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"WgQRzLWWalE","playlistId":"PLRD7N-Zrj2DMPlFktUo5BRduSyCxu8nZy","loggingContext":{"vssLoggingContext":{"serializedContextData":"GiJQTFJEN04tWnJqMkRNUGxGa3RVbzVCUmR1U3lDeHU4blp5"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=5a0411ccb5966a51\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"trackingParams":"CI8CEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}}}}],"trackingParams":"CI0CELsvGAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"itemSectionRenderer":{"contents":[{"shelfRenderer":{"title":{"runs":[{"text":"The Real Series","navigationEndpoint":{"clickTrackingParams":"CKgBENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLRD7N-Zrj2DNE6S2AsY71GuuFgkRuzpWw","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLRD7N-Zrj2DNE6S2AsY71GuuFgkRuzpWw"}}}]},"endpoint":{"clickTrackingParams":"CKgBENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLRD7N-Zrj2DNE6S2AsY71GuuFgkRuzpWw","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLRD7N-Zrj2DNE6S2AsY71GuuFgkRuzpWw"}},"content":{"horizontalListRenderer":{"items":[{"gridVideoRenderer":{"videoId":"VelRmbqo8PQ","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/VelRmbqo8PQ/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLD5iRJHk_ni4_8DTqPVrwMCMVBw1Q","width":168,"height":94},{"url":"https://i.ytimg.com/vi/VelRmbqo8PQ/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBWOS_25drwHZbPY_6hTm5Oc_VLAg","width":196,"height":110},{"url":"https://i.ytimg.com/vi/VelRmbqo8PQ/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLC93PYDpHtJ9ygLSfz6kZTUoeX2rg","width":246,"height":138},{"url":"https://i.ytimg.com/vi/VelRmbqo8PQ/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCcz2VfnfKIVsYBB1zDJp4T0BE_3A","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Ignore Family Watch Football by penguinz0 2 years ago 2 minutes, 19 seconds 959,423 views"}},"simpleText":"Ignore Family Watch Football"},"publishedTimeText":{"simpleText":"2 years ago"},"viewCountText":{"simpleText":"959,423 views"},"navigationEndpoint":{"clickTrackingParams":"CIUCEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRORTZTMkFzWTcxR3V1RmdrUnV6cFd3","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=VelRmbqo8PQ","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"VelRmbqo8PQ","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr8---sn-cxaaj5o5q5-tt1ee.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=55e95199baa8f0f4\u0026ip=74.12.195.102\u0026initcwndbps=1816250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CIUCEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CIUCEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CIUCEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1VA9OGj1Zuz1PRVqgEiUExSRDdOLVpyajJETkU2UzJBc1k3MUd1dUZna1J1enBXdw==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CIwCEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"959K views"}},"simpleText":"959K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CIsCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CIsCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"VelRmbqo8PQ","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CIsCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["VelRmbqo8PQ"],"params":"CAQ%3D"}},"videoIds":["VelRmbqo8PQ"]}}]}},"trackingParams":"CIsCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CIUCEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"VelRmbqo8PQ","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CIUCEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CIoCEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"VelRmbqo8PQ"}},"trackingParams":"CIoCEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CIkCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"VelRmbqo8PQ","onAddCommand":{"clickTrackingParams":"CIkCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"VelRmbqo8PQ","params":"CAI%3D"}}}},"trackingParams":"CIkCENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CIUCEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtWZWxSbWJxbzhQUQ%3D%3D","commands":[{"clickTrackingParams":"CIUCEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CIgCEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CIUCEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CIUCEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"2 minutes, 19 seconds"}},"simpleText":"2:19"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CIcCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"VelRmbqo8PQ","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CIcCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"VelRmbqo8PQ"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CIcCEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CIYCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CIYCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"VelRmbqo8PQ","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CIYCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["VelRmbqo8PQ"],"params":"CAQ%3D"}},"videoIds":["VelRmbqo8PQ"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CIYCEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/VelRmbqo8PQ/mqdefault_6s.webp?du=3000\u0026sqp=CPSAi58G\u0026rs=AOn4CLBYZavGxPlr0ITkmaqFld5LVDzhVg","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"vPcDINtnBqg","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/vPcDINtnBqg/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLC2BRZV1EleSK07VtYvpdC6EGioqA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/vPcDINtnBqg/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDf9Ij-fLvDOqSAdUZyRHzm01IDQg","width":196,"height":110},{"url":"https://i.ytimg.com/vi/vPcDINtnBqg/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDEPVNewAo56j7oeNGhkpiBjTw22Q","width":246,"height":138},{"url":"https://i.ytimg.com/vi/vPcDINtnBqg/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDxJcIvUrzwSyQ0bUb8ZrIoaJxpxQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Getting A Chiseled Jawline Is Easy by penguinz0 2 years ago 1 minute, 55 seconds 2,478,615 views"}},"simpleText":"Getting A Chiseled Jawline Is Easy"},"publishedTimeText":{"simpleText":"2 years ago"},"viewCountText":{"simpleText":"2,478,615 views"},"navigationEndpoint":{"clickTrackingParams":"CP0BEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRORTZTMkFzWTcxR3V1RmdrUnV6cFd3","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=vPcDINtnBqg","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"vPcDINtnBqg","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr4---sn-cxaaj5o5q5-tt1e6.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=bcf70320db6706a8\u0026ip=74.12.195.102\u0026initcwndbps=1521250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CP0BEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CP0BEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CP0BEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1VAqI2c243kwPu8AaoBIlBMUkQ3Ti1acmoyRE5FNlMyQXNZNzFHdXVGZ2tSdXpwV3c=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CIQCEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2.4 million views"}},"simpleText":"2.4M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CIMCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CIMCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"vPcDINtnBqg","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CIMCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["vPcDINtnBqg"],"params":"CAQ%3D"}},"videoIds":["vPcDINtnBqg"]}}]}},"trackingParams":"CIMCEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CP0BEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"vPcDINtnBqg","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CP0BEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CIICEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"vPcDINtnBqg"}},"trackingParams":"CIICEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CIECENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"vPcDINtnBqg","onAddCommand":{"clickTrackingParams":"CIECENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"vPcDINtnBqg","params":"CAI%3D"}}}},"trackingParams":"CIECENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CP0BEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgt2UGNESU50bkJxZw%3D%3D","commands":[{"clickTrackingParams":"CP0BEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CIACEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CP0BEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CP0BEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 minute, 55 seconds"}},"simpleText":"1:55"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CP8BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"vPcDINtnBqg","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CP8BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"vPcDINtnBqg"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CP8BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CP4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CP4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"vPcDINtnBqg","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CP4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["vPcDINtnBqg"],"params":"CAQ%3D"}},"videoIds":["vPcDINtnBqg"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CP4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/vPcDINtnBqg/mqdefault_6s.webp?du=3000\u0026sqp=CKj8ip8G\u0026rs=AOn4CLBM02d2ePE71LOGBnzzdsJ0ureKRQ","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"lhODmU4c4kc","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/lhODmU4c4kc/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLD99lxQWURkYDKH7bGE88tmBd1tgA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/lhODmU4c4kc/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCYubHhtVLx2cJSFIFP_Re_08qtkQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/lhODmU4c4kc/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCIBDP3JbLsgdsuDmxO5V0kA6GUaQ","width":246,"height":138},{"url":"https://i.ytimg.com/vi/lhODmU4c4kc/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLB3e5ko0phcg78TWXnOtACCBIcL-w","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Germs Have Been Defeated by penguinz0 3 years ago 2 minutes, 2 seconds 1,728,041 views"}},"simpleText":"Germs Have Been Defeated"},"publishedTimeText":{"simpleText":"3 years ago"},"viewCountText":{"simpleText":"1,728,041 views"},"navigationEndpoint":{"clickTrackingParams":"CPUBEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRORTZTMkFzWTcxR3V1RmdrUnV6cFd3","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=lhODmU4c4kc","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"lhODmU4c4kc","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr8---sn-cxaaj5o5q5-tt1e6.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=961383994e1ce247\u0026ip=74.12.195.102\u0026initcwndbps=1521250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CPUBEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CPUBEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CPUBEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1VAx8Tz8JTz4ImWAaoBIlBMUkQ3Ti1acmoyRE5FNlMyQXNZNzFHdXVGZ2tSdXpwV3c=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CPwBEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.7 million views"}},"simpleText":"1.7M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CPsBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CPsBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"lhODmU4c4kc","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CPsBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["lhODmU4c4kc"],"params":"CAQ%3D"}},"videoIds":["lhODmU4c4kc"]}}]}},"trackingParams":"CPsBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CPUBEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"lhODmU4c4kc","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CPUBEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CPoBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"lhODmU4c4kc"}},"trackingParams":"CPoBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CPkBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"lhODmU4c4kc","onAddCommand":{"clickTrackingParams":"CPkBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"lhODmU4c4kc","params":"CAI%3D"}}}},"trackingParams":"CPkBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CPUBEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtsaE9EbVU0YzRrYw%3D%3D","commands":[{"clickTrackingParams":"CPUBEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CPgBEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CPUBEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CPUBEJQ1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"2 minutes, 2 seconds"}},"simpleText":"2:02"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CPcBEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"lhODmU4c4kc","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CPcBEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"lhODmU4c4kc"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CPcBEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CPYBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CPYBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"lhODmU4c4kc","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CPYBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["lhODmU4c4kc"],"params":"CAQ%3D"}},"videoIds":["lhODmU4c4kc"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CPYBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/lhODmU4c4kc/mqdefault_6s.webp?du=3000\u0026sqp=CIz-ip8G\u0026rs=AOn4CLDj_hLhqPgpSAAJcrVvF_WAKeT1Zw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"MT4osHskht8","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/MT4osHskht8/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCar-XGnjLJfvCLcXk6-kcA0DuthA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/MT4osHskht8/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBDFyhhqQdQ4HNBBmpGmmQaYyG_hQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/MT4osHskht8/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDGyKvjZnM_7qi3wXhO7EvCoFYU5w","width":246,"height":138},{"url":"https://i.ytimg.com/vi/MT4osHskht8/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCrhpqoMrGgoF47LRAqpV6XwImrcA","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Mopping Has Changed by penguinz0 3 years ago 2 minutes, 11 seconds 918,216 views"}},"simpleText":"Mopping Has Changed"},"publishedTimeText":{"simpleText":"3 years ago"},"viewCountText":{"simpleText":"918,216 views"},"navigationEndpoint":{"clickTrackingParams":"CO0BEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRORTZTMkFzWTcxR3V1RmdrUnV6cFd3","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=MT4osHskht8","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"MT4osHskht8","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr5---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=313e28b07b2486df\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CO0BEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CO0BEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CO0BEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1VA342S2YeWip8xqgEiUExSRDdOLVpyajJETkU2UzJBc1k3MUd1dUZna1J1enBXdw==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CPQBEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"918K views"}},"simpleText":"918K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CPMBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CPMBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"MT4osHskht8","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CPMBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["MT4osHskht8"],"params":"CAQ%3D"}},"videoIds":["MT4osHskht8"]}}]}},"trackingParams":"CPMBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CO0BEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"MT4osHskht8","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CO0BEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CPIBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"MT4osHskht8"}},"trackingParams":"CPIBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CPEBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"MT4osHskht8","onAddCommand":{"clickTrackingParams":"CPEBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"MT4osHskht8","params":"CAI%3D"}}}},"trackingParams":"CPEBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CO0BEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtNVDRvc0hza2h0OA%3D%3D","commands":[{"clickTrackingParams":"CO0BEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CPABEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CO0BEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CO0BEJQ1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"2 minutes, 11 seconds"}},"simpleText":"2:11"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CO8BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"MT4osHskht8","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CO8BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"MT4osHskht8"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CO8BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CO4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CO4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"MT4osHskht8","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CO4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["MT4osHskht8"],"params":"CAQ%3D"}},"videoIds":["MT4osHskht8"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CO4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/MT4osHskht8/mqdefault_6s.webp?du=3000\u0026sqp=CK7Aip8G\u0026rs=AOn4CLAG8I417soE_6PpRbshRekswbgN8Q","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"Xb67bjpgEJE","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/Xb67bjpgEJE/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAQcQhf6MtyHHLOWJ880XHlseS0fw","width":168,"height":94},{"url":"https://i.ytimg.com/vi/Xb67bjpgEJE/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDmVAmPfq8-Y_q3inbrrbH9sN2enw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/Xb67bjpgEJE/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBxUWBMI9i-bG6Mt2J1hMJTdTprdg","width":246,"height":138},{"url":"https://i.ytimg.com/vi/Xb67bjpgEJE/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBov9q6MR_AlNUQNB2a1su9A5COEw","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Weaponized Toilet Brush by penguinz0 3 years ago 1 minute, 48 seconds 1,039,617 views"}},"simpleText":"Weaponized Toilet Brush"},"publishedTimeText":{"simpleText":"3 years ago"},"viewCountText":{"simpleText":"1,039,617 views"},"navigationEndpoint":{"clickTrackingParams":"COUBEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRORTZTMkFzWTcxR3V1RmdrUnV6cFd3","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=Xb67bjpgEJE","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"Xb67bjpgEJE","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1ee.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=5dbebb6e3a601091\u0026ip=74.12.195.102\u0026initcwndbps=1816250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"COUBEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"COUBEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"COUBEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1VAkaGA0-Ptrt9dqgEiUExSRDdOLVpyajJETkU2UzJBc1k3MUd1dUZna1J1enBXdw==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"COwBEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1 million views"}},"simpleText":"1M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"COsBEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"COsBEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"Xb67bjpgEJE","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"COsBEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["Xb67bjpgEJE"],"params":"CAQ%3D"}},"videoIds":["Xb67bjpgEJE"]}}]}},"trackingParams":"COsBEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"COUBEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"Xb67bjpgEJE","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"COUBEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"COoBEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"Xb67bjpgEJE"}},"trackingParams":"COoBEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"COkBENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"Xb67bjpgEJE","onAddCommand":{"clickTrackingParams":"COkBENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"Xb67bjpgEJE","params":"CAI%3D"}}}},"trackingParams":"COkBENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"COUBEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtYYjY3YmpwZ0VKRQ%3D%3D","commands":[{"clickTrackingParams":"COUBEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"COgBEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"COUBEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"COUBEJQ1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 minute, 48 seconds"}},"simpleText":"1:48"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"COcBEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"Xb67bjpgEJE","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"COcBEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"Xb67bjpgEJE"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"COcBEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"COYBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"COYBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"Xb67bjpgEJE","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"COYBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["Xb67bjpgEJE"],"params":"CAQ%3D"}},"videoIds":["Xb67bjpgEJE"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"COYBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}]}},{"gridVideoRenderer":{"videoId":"C0_kBFaFVO4","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/C0_kBFaFVO4/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBUvtJlfpK1qFgR77qWryYWBUqg2g","width":168,"height":94},{"url":"https://i.ytimg.com/vi/C0_kBFaFVO4/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLB2siemEZ6HeUb35JsC9tL11jFm9w","width":196,"height":110},{"url":"https://i.ytimg.com/vi/C0_kBFaFVO4/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAvnntdX79KCfCRHPvypyUAoGRSlw","width":246,"height":138},{"url":"https://i.ytimg.com/vi/C0_kBFaFVO4/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDOoo14dox2zydXedTAoEv2lLfLAQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"A Mop For Redditors by penguinz0 3 years ago 2 minutes, 18 seconds 3,157,941 views"}},"simpleText":"A Mop For Redditors"},"publishedTimeText":{"simpleText":"3 years ago"},"viewCountText":{"simpleText":"3,157,941 views"},"navigationEndpoint":{"clickTrackingParams":"CN0BEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRORTZTMkFzWTcxR3V1RmdrUnV6cFd3","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=C0_kBFaFVO4","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"C0_kBFaFVO4","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr7---sn-cxaaj5o5q5-tt1el.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=0b4fe404568554ee\u0026ip=74.12.195.102\u0026initcwndbps=1782500\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CN0BEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CN0BEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CN0BEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1VA7qmVtMWA-acLqgEiUExSRDdOLVpyajJETkU2UzJBc1k3MUd1dUZna1J1enBXdw==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"COQBEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"3.1 million views"}},"simpleText":"3.1M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"COMBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"COMBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"C0_kBFaFVO4","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"COMBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["C0_kBFaFVO4"],"params":"CAQ%3D"}},"videoIds":["C0_kBFaFVO4"]}}]}},"trackingParams":"COMBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CN0BEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"C0_kBFaFVO4","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CN0BEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"COIBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"C0_kBFaFVO4"}},"trackingParams":"COIBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"COEBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"C0_kBFaFVO4","onAddCommand":{"clickTrackingParams":"COEBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"C0_kBFaFVO4","params":"CAI%3D"}}}},"trackingParams":"COEBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CN0BEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtDMF9rQkZhRlZPNA%3D%3D","commands":[{"clickTrackingParams":"CN0BEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"COABEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CN0BEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CN0BEJQ1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"2 minutes, 18 seconds"}},"simpleText":"2:18"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CN8BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"C0_kBFaFVO4","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CN8BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"C0_kBFaFVO4"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CN8BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CN4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CN4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"C0_kBFaFVO4","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CN4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["C0_kBFaFVO4"],"params":"CAQ%3D"}},"videoIds":["C0_kBFaFVO4"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CN4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/C0_kBFaFVO4/mqdefault_6s.webp?du=3000\u0026sqp=CJ6Ai58G\u0026rs=AOn4CLBDfbgr2-IINYQxxfgvv_Rw7Y7Xqw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"Kgl2wuGAnfU","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/Kgl2wuGAnfU/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLClVjDMzf5eQqn9Hn3kdMXsbfbbsQ","width":168,"height":94},{"url":"https://i.ytimg.com/vi/Kgl2wuGAnfU/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLA7scoX2OUok20FhWmJcGbsHl5pUA","width":196,"height":110},{"url":"https://i.ytimg.com/vi/Kgl2wuGAnfU/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDv94h1XH1nUNDsUL2Qm1BU0ZYrNw","width":246,"height":138},{"url":"https://i.ytimg.com/vi/Kgl2wuGAnfU/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLChJYMPEwg-Yzs8hga3WQNbYHIP0Q","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Jupiter Technology by penguinz0 3 years ago 1 minute, 32 seconds 649,534 views"}},"simpleText":"Jupiter Technology"},"publishedTimeText":{"simpleText":"3 years ago"},"viewCountText":{"simpleText":"649,534 views"},"navigationEndpoint":{"clickTrackingParams":"CNUBEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRORTZTMkFzWTcxR3V1RmdrUnV6cFd3","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=Kgl2wuGAnfU","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"Kgl2wuGAnfU","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr7---sn-cxaaj5o5q5-tt1el.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=2a0976c2e1809df5\u0026ip=74.12.195.102\u0026initcwndbps=1782500\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CNUBEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CNUBEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CNUBEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1VA9buCjK7Y3YQqqgEiUExSRDdOLVpyajJETkU2UzJBc1k3MUd1dUZna1J1enBXdw==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CNwBEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"649K views"}},"simpleText":"649K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CNsBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CNsBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"Kgl2wuGAnfU","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CNsBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["Kgl2wuGAnfU"],"params":"CAQ%3D"}},"videoIds":["Kgl2wuGAnfU"]}}]}},"trackingParams":"CNsBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CNUBEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"Kgl2wuGAnfU","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CNUBEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CNoBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"Kgl2wuGAnfU"}},"trackingParams":"CNoBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CNkBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"Kgl2wuGAnfU","onAddCommand":{"clickTrackingParams":"CNkBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"Kgl2wuGAnfU","params":"CAI%3D"}}}},"trackingParams":"CNkBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CNUBEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtLZ2wyd3VHQW5mVQ%3D%3D","commands":[{"clickTrackingParams":"CNUBEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CNgBEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CNUBEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CNUBEJQ1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 minute, 32 seconds"}},"simpleText":"1:32"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CNcBEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"Kgl2wuGAnfU","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CNcBEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"Kgl2wuGAnfU"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CNcBEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CNYBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CNYBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"Kgl2wuGAnfU","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CNYBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["Kgl2wuGAnfU"],"params":"CAQ%3D"}},"videoIds":["Kgl2wuGAnfU"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CNYBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/Kgl2wuGAnfU/mqdefault_6s.webp?du=3000\u0026sqp=CLnbip8G\u0026rs=AOn4CLDnvnE46Nf4qeSnEBToltoCQPJUvw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"67NiX6KrmR4","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/67NiX6KrmR4/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCRtDfNitOgGi8y29bSWTEC4-CoCg","width":168,"height":94},{"url":"https://i.ytimg.com/vi/67NiX6KrmR4/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCPc0Q_8HUQdNouszT8ly6Y92_j1A","width":196,"height":110},{"url":"https://i.ytimg.com/vi/67NiX6KrmR4/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCscjxx1rG0-hsnmqCKcPjfvKd3YA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/67NiX6KrmR4/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLARx_T-6foOKaCr_l88dfy9l-DlWA","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Nothing Fucking Sticks Pan by penguinz0 3 years ago 1 minute, 54 seconds 826,367 views"}},"simpleText":"The Nothing Fucking Sticks Pan"},"publishedTimeText":{"simpleText":"3 years ago"},"viewCountText":{"simpleText":"826,367 views"},"navigationEndpoint":{"clickTrackingParams":"CM0BEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRORTZTMkFzWTcxR3V1RmdrUnV6cFd3","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=67NiX6KrmR4","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"67NiX6KrmR4","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1el.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=ebb3625fa2ab991e\u0026ip=74.12.195.102\u0026initcwndbps=1782500\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CM0BEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CM0BEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CM0BEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1VAnrKulfrL2NnrAaoBIlBMUkQ3Ti1acmoyRE5FNlMyQXNZNzFHdXVGZ2tSdXpwV3c=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CNQBEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"826K views"}},"simpleText":"826K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CNMBEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CNMBEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"67NiX6KrmR4","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CNMBEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["67NiX6KrmR4"],"params":"CAQ%3D"}},"videoIds":["67NiX6KrmR4"]}}]}},"trackingParams":"CNMBEP6YBBgGIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CM0BEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"67NiX6KrmR4","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CM0BEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CNIBEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"67NiX6KrmR4"}},"trackingParams":"CNIBEJSsCRgIIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CNEBENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"67NiX6KrmR4","onAddCommand":{"clickTrackingParams":"CNEBENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"67NiX6KrmR4","params":"CAI%3D"}}}},"trackingParams":"CNEBENGqBRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CM0BEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs2N05pWDZLcm1SNA%3D%3D","commands":[{"clickTrackingParams":"CM0BEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CNABEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CM0BEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CM0BEJQ1GAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 minute, 54 seconds"}},"simpleText":"1:54"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CM8BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"67NiX6KrmR4","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CM8BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"67NiX6KrmR4"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CM8BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CM4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CM4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"67NiX6KrmR4","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CM4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["67NiX6KrmR4"],"params":"CAQ%3D"}},"videoIds":["67NiX6KrmR4"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CM4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}]}},{"gridVideoRenderer":{"videoId":"yACYQKSxs1k","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/yACYQKSxs1k/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCg3FmD2qy-uHC3OmjHFSUljdUoKw","width":168,"height":94},{"url":"https://i.ytimg.com/vi/yACYQKSxs1k/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBhwlSO4YsHTpI28W5IF6x3aXRrfw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/yACYQKSxs1k/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAcVDMMHZk5V38EkocT_Wc2cERJhQ","width":246,"height":138},{"url":"https://i.ytimg.com/vi/yACYQKSxs1k/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDESGrJ0U90ROV3Oui9pKVkS21r-w","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"The Ultimate Pump by penguinz0 4 years ago 1 minute, 38 seconds 810,528 views"}},"simpleText":"The Ultimate Pump"},"publishedTimeText":{"simpleText":"4 years ago"},"viewCountText":{"simpleText":"810,528 views"},"navigationEndpoint":{"clickTrackingParams":"CMUBEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRORTZTMkFzWTcxR3V1RmdrUnV6cFd3","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=yACYQKSxs1k","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"yACYQKSxs1k","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr2---sn-cxaaj5o5q5-tt1e6.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=c8009840a4b1b359\u0026ip=74.12.195.102\u0026initcwndbps=1521250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CMUBEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CMUBEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CMUBEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1VA2ebGpYqIpoDIAaoBIlBMUkQ3Ti1acmoyRE5FNlMyQXNZNzFHdXVGZ2tSdXpwV3c=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CMwBEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"810K views"}},"simpleText":"810K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CMsBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CMsBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"yACYQKSxs1k","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CMsBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["yACYQKSxs1k"],"params":"CAQ%3D"}},"videoIds":["yACYQKSxs1k"]}}]}},"trackingParams":"CMsBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CMUBEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"yACYQKSxs1k","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CMUBEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CMoBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"yACYQKSxs1k"}},"trackingParams":"CMoBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CMkBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"yACYQKSxs1k","onAddCommand":{"clickTrackingParams":"CMkBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"yACYQKSxs1k","params":"CAI%3D"}}}},"trackingParams":"CMkBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CMUBEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgt5QUNZUUtTeHMxaw%3D%3D","commands":[{"clickTrackingParams":"CMUBEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CMgBEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CMUBEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CMUBEJQ1GAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 minute, 38 seconds"}},"simpleText":"1:38"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CMcBEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"yACYQKSxs1k","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CMcBEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"yACYQKSxs1k"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CMcBEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CMYBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CMYBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"yACYQKSxs1k","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CMYBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["yACYQKSxs1k"],"params":"CAQ%3D"}},"videoIds":["yACYQKSxs1k"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CMYBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/yACYQKSxs1k/mqdefault_6s.webp?du=3000\u0026sqp=CMvZip8G\u0026rs=AOn4CLBAzCqLPHBQOWmMDcY4im9xqEcHRw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"VAnLKOlPmSA","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/VAnLKOlPmSA/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCxqkiN2ewxCU5Ypq3jnq1xcEwkAg","width":168,"height":94},{"url":"https://i.ytimg.com/vi/VAnLKOlPmSA/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCxKAbdDY57KS_jHsvXCL6l3jWiYw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/VAnLKOlPmSA/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDLbiGGlc8Jtiacqp8rGcr8MVV4Fw","width":246,"height":138},{"url":"https://i.ytimg.com/vi/VAnLKOlPmSA/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLBTBxqmxa9bakiosY3lVc9M4_XZLQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Device To Turn Humans Into Androids by penguinz0 4 years ago 1 minute, 5 seconds 566,401 views"}},"simpleText":"Device To Turn Humans Into Androids"},"publishedTimeText":{"simpleText":"4 years ago"},"viewCountText":{"simpleText":"566,401 views"},"navigationEndpoint":{"clickTrackingParams":"CL0BEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRORTZTMkFzWTcxR3V1RmdrUnV6cFd3","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=VAnLKOlPmSA","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"VAnLKOlPmSA","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr6---sn-cxaaj5o5q5-tt1el.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=5409cb28e94f9920\u0026ip=74.12.195.102\u0026initcwndbps=1782500\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CL0BEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CL0BEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CL0BEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1VAoLK-yo7l8oRUqgEiUExSRDdOLVpyajJETkU2UzJBc1k3MUd1dUZna1J1enBXdw==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CMQBEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"566K views"}},"simpleText":"566K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CMMBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CMMBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"VAnLKOlPmSA","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CMMBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["VAnLKOlPmSA"],"params":"CAQ%3D"}},"videoIds":["VAnLKOlPmSA"]}}]}},"trackingParams":"CMMBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CL0BEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"VAnLKOlPmSA","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CL0BEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CMIBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"VAnLKOlPmSA"}},"trackingParams":"CMIBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CMEBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"VAnLKOlPmSA","onAddCommand":{"clickTrackingParams":"CMEBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"VAnLKOlPmSA","params":"CAI%3D"}}}},"trackingParams":"CMEBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CL0BEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtWQW5MS09sUG1TQQ%3D%3D","commands":[{"clickTrackingParams":"CL0BEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CMABEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CL0BEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CL0BEJQ1GAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 minute, 5 seconds"}},"simpleText":"1:05"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CL8BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"VAnLKOlPmSA","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CL8BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"VAnLKOlPmSA"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CL8BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CL4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CL4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"VAnLKOlPmSA","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CL4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["VAnLKOlPmSA"],"params":"CAQ%3D"}},"videoIds":["VAnLKOlPmSA"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CL4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/VAnLKOlPmSA/mqdefault_6s.webp?du=3000\u0026sqp=CID-ip8G\u0026rs=AOn4CLB_3_IORLAgnKS_s_tlpxRHkHW8mw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"53BL4Lyqrg0","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/53BL4Lyqrg0/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLB82ti4pj7ZnzJm0_XgnuG3E6Pwjg","width":168,"height":94},{"url":"https://i.ytimg.com/vi/53BL4Lyqrg0/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBjEeXmpaHY1FkVIXBDAjL_1eU6MA","width":196,"height":110},{"url":"https://i.ytimg.com/vi/53BL4Lyqrg0/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCXWbOTpyUVpeWsIZawHRoZJcmHZg","width":246,"height":138},{"url":"https://i.ytimg.com/vi/53BL4Lyqrg0/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAaodDY-0SXl4eP7SHzCB4KiKLSug","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Almost Oxiclean by penguinz0 4 years ago 1 minute, 16 seconds 678,023 views"}},"simpleText":"Almost Oxiclean"},"publishedTimeText":{"simpleText":"4 years ago"},"viewCountText":{"simpleText":"678,023 views"},"navigationEndpoint":{"clickTrackingParams":"CLUBEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRORTZTMkFzWTcxR3V1RmdrUnV6cFd3","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=53BL4Lyqrg0","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"53BL4Lyqrg0","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr4---sn-cxaaj5o5q5-tt1y.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=e7704be0bcaaae0d\u0026ip=74.12.195.102\u0026initcwndbps=1702500\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CLUBEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CLUBEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CLUBEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1VAjdyq5Yv8krjnAaoBIlBMUkQ3Ti1acmoyRE5FNlMyQXNZNzFHdXVGZ2tSdXpwV3c=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CLwBEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"678K views"}},"simpleText":"678K views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CLsBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CLsBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"53BL4Lyqrg0","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CLsBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["53BL4Lyqrg0"],"params":"CAQ%3D"}},"videoIds":["53BL4Lyqrg0"]}}]}},"trackingParams":"CLsBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CLUBEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"53BL4Lyqrg0","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CLUBEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CLoBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"53BL4Lyqrg0"}},"trackingParams":"CLoBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CLkBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"53BL4Lyqrg0","onAddCommand":{"clickTrackingParams":"CLkBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"53BL4Lyqrg0","params":"CAI%3D"}}}},"trackingParams":"CLkBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CLUBEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs1M0JMNEx5cXJnMA%3D%3D","commands":[{"clickTrackingParams":"CLUBEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CLgBEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CLUBEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CLUBEJQ1GAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"1 minute, 16 seconds"}},"simpleText":"1:16"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CLcBEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"53BL4Lyqrg0","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CLcBEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"53BL4Lyqrg0"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CLcBEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CLYBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CLYBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"53BL4Lyqrg0","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CLYBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["53BL4Lyqrg0"],"params":"CAQ%3D"}},"videoIds":["53BL4Lyqrg0"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CLYBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/53BL4Lyqrg0/mqdefault_6s.webp?du=3000\u0026sqp=CM2Ei58G\u0026rs=AOn4CLBHXpBDpfW-nN0-Q6OFuZ8bqdZb_Q","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"L-D2aLGy7To","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/L-D2aLGy7To/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAvvD9M78Zidb4Dn09ooTODJ5pUAQ","width":168,"height":94},{"url":"https://i.ytimg.com/vi/L-D2aLGy7To/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAvgCrq3yqRqLzPMj853C91SulEYw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/L-D2aLGy7To/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAwUMEBUtQQB6l_KmBUVPJWLl9P_w","width":246,"height":138},{"url":"https://i.ytimg.com/vi/L-D2aLGy7To/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDJcEVo7qmxBc02biZ11HLMlELAkw","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Atomic Wallet by penguinz0 4 years ago 2 minutes, 8 seconds 3,464,076 views"}},"simpleText":"Atomic Wallet"},"publishedTimeText":{"simpleText":"4 years ago"},"viewCountText":{"simpleText":"3,464,076 views"},"navigationEndpoint":{"clickTrackingParams":"CK0BEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRORTZTMkFzWTcxR3V1RmdrUnV6cFd3","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=L-D2aLGy7To","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"L-D2aLGy7To","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr4---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=2fe0f668b1b2ed3a\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CK0BEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CK0BEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CK0BEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1VAutrLjYvNvfAvqgEiUExSRDdOLVpyajJETkU2UzJBc1k3MUd1dUZna1J1enBXdw==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CLQBEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"3.4 million views"}},"simpleText":"3.4M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CLMBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CLMBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"L-D2aLGy7To","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CLMBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["L-D2aLGy7To"],"params":"CAQ%3D"}},"videoIds":["L-D2aLGy7To"]}}]}},"trackingParams":"CLMBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CK0BEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"L-D2aLGy7To","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CK0BEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CLIBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"L-D2aLGy7To"}},"trackingParams":"CLIBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CLEBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"L-D2aLGy7To","onAddCommand":{"clickTrackingParams":"CLEBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"L-D2aLGy7To","params":"CAI%3D"}}}},"trackingParams":"CLEBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CK0BEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtMLUQyYUxHeTdUbw%3D%3D","commands":[{"clickTrackingParams":"CK0BEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CLABEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CK0BEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CK0BEJQ1GAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"2 minutes, 8 seconds"}},"simpleText":"2:08"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CK8BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"L-D2aLGy7To","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CK8BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"L-D2aLGy7To"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CK8BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CK4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CK4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"L-D2aLGy7To","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CK4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["L-D2aLGy7To"],"params":"CAQ%3D"}},"videoIds":["L-D2aLGy7To"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CK4BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/L-D2aLGy7To/mqdefault_6s.webp?du=3000\u0026sqp=CIj_ip8G\u0026rs=AOn4CLBYg6n0KokPjcxBUBoli6iODd5hFw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}}],"trackingParams":"CKoBEMY5IhMI-Mm_pq2E_QIVEIf_BB2wqAtV","visibleItemCount":4,"nextButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"CHEVRON_RIGHT"},"accessibility":{"label":"Next"},"trackingParams":"CKwBEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},"previousButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"CHEVRON_LEFT"},"accessibility":{"label":"Previous"},"trackingParams":"CKsBEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}}}},"trackingParams":"CKgBENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","playAllButton":{"buttonRenderer":{"style":"STYLE_TEXT","size":"SIZE_DEFAULT","isDisabled":false,"text":{"runs":[{"text":"Play all"}]},"icon":{"iconType":"PLAY_ALL"},"navigationEndpoint":{"clickTrackingParams":"CKkBEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=VelRmbqo8PQ\u0026list=PLRD7N-Zrj2DNE6S2AsY71GuuFgkRuzpWw","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"VelRmbqo8PQ","playlistId":"PLRD7N-Zrj2DNE6S2AsY71GuuFgkRuzpWw","loggingContext":{"vssLoggingContext":{"serializedContextData":"GiJQTFJEN04tWnJqMkRORTZTMkFzWTcxR3V1RmdrUnV6cFd3"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr8---sn-cxaaj5o5q5-tt1ee.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=55e95199baa8f0f4\u0026ip=74.12.195.102\u0026initcwndbps=1816250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"trackingParams":"CKkBEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}}}}],"trackingParams":"CKcBELsvGAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"itemSectionRenderer":{"contents":[{"shelfRenderer":{"title":{"runs":[{"text":"Series","navigationEndpoint":{"clickTrackingParams":"CJUBENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0/playlists?view=50\u0026sort=dd\u0026shelf_id=8","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","params":"EglwbGF5bGlzdHMYAyAycAg%3D","canonicalBaseUrl":"/@penguinz0"}}}]},"endpoint":{"clickTrackingParams":"CJUBENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0/playlists?view=50\u0026sort=dd\u0026shelf_id=8","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","params":"EglwbGF5bGlzdHMYAyAycAg%3D","canonicalBaseUrl":"/@penguinz0"}},"content":{"horizontalListRenderer":{"items":[{"gridPlaylistRenderer":{"playlistId":"PLRD7N-Zrj2DPqkTQmTUvgJWI8ZMGWRWw8","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/b3NBZjxgrDc/hqdefault.jpg?sqp=-oaymwEXCOADEI4CSFryq4qpAwkIARUAAIhCGAE=\u0026rs=AOn4CLDy244u2SU3Ixo6iMO74bb7E45NPw","width":480,"height":270}]},"title":{"runs":[{"text":"Forged In Fire","navigationEndpoint":{"clickTrackingParams":"CKUBEJY1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEGEPI4GJcB","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=b3NBZjxgrDc\u0026list=PLRD7N-Zrj2DPqkTQmTUvgJWI8ZMGWRWw8","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"b3NBZjxgrDc","playlistId":"PLRD7N-Zrj2DPqkTQmTUvgJWI8ZMGWRWw8","params":"OAI%3D","loggingContext":{"vssLoggingContext":{"serializedContextData":"GiJQTFJEN04tWnJqMkRQcWtUUW1UVXZnSldJOFpNR1dSV3c4"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr7---sn-cxaaj5o5q5-tt1r.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=6f7341663c60ac37\u0026ip=74.12.195.102\u0026initcwndbps=1643750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}}}]},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CKUBEJY1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"videoCountText":{"runs":[{"text":"6"},{"text":" videos"}]},"navigationEndpoint":{"clickTrackingParams":"CKUBEJY1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEGEPI4GJcB","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=b3NBZjxgrDc\u0026list=PLRD7N-Zrj2DPqkTQmTUvgJWI8ZMGWRWw8","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"b3NBZjxgrDc","playlistId":"PLRD7N-Zrj2DPqkTQmTUvgJWI8ZMGWRWw8","params":"OAI%3D","loggingContext":{"vssLoggingContext":{"serializedContextData":"GiJQTFJEN04tWnJqMkRQcWtUUW1UVXZnSldJOFpNR1dSV3c4"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr7---sn-cxaaj5o5q5-tt1r.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=6f7341663c60ac37\u0026ip=74.12.195.102\u0026initcwndbps=1643750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"videoCountShortText":{"simpleText":"6"},"trackingParams":"CKUBEJY1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","sidebarThumbnails":[{"thumbnails":[{"url":"https://i.ytimg.com/vi/q2exWoLhSbc/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/pX2GPLIHOpc/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/5GiBolhyjcQ/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/ZBNDJuofNwo/default.jpg","width":43,"height":20}]}],"thumbnailText":{"runs":[{"text":"6","bold":true},{"text":" videos"}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CKUBEJY1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"thumbnailRenderer":{"playlistVideoThumbnailRenderer":{"thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/b3NBZjxgrDc/hqdefault.jpg?sqp=-oaymwEXCOADEI4CSFryq4qpAwkIARUAAIhCGAE=\u0026rs=AOn4CLDy244u2SU3Ixo6iMO74bb7E45NPw","width":480,"height":270}]},"trackingParams":"CKYBEMvsCSITCPjJv6athP0CFRCH_wQdsKgLVQ=="}},"longBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CKUBEJY1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"thumbnailOverlays":[{"thumbnailOverlaySidePanelRenderer":{"text":{"simpleText":"6"},"icon":{"iconType":"PLAYLISTS"}}},{"thumbnailOverlayHoverTextRenderer":{"text":{"runs":[{"text":"Play all"}]},"icon":{"iconType":"PLAY_ALL"}}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"viewPlaylistText":{"runs":[{"text":"View full playlist","navigationEndpoint":{"clickTrackingParams":"CKUBEJY1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLRD7N-Zrj2DPqkTQmTUvgJWI8ZMGWRWw8","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLRD7N-Zrj2DPqkTQmTUvgJWI8ZMGWRWw8"}}}]}}},{"gridPlaylistRenderer":{"playlistId":"PLRD7N-Zrj2DOt_DFJg7IaJJCaLpsLJEwz","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/gXJ1_i2cJQk/hqdefault.jpg?sqp=-oaymwEXCOADEI4CSFryq4qpAwkIARUAAIhCGAE=\u0026rs=AOn4CLA6Ty4c_2KloFcMro-RjiqbRFXE1Q","width":480,"height":270}]},"title":{"runs":[{"text":"Slapping","navigationEndpoint":{"clickTrackingParams":"CKMBEJY1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEGEPI4GJcB","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=gXJ1_i2cJQk\u0026list=PLRD7N-Zrj2DOt_DFJg7IaJJCaLpsLJEwz","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"gXJ1_i2cJQk","playlistId":"PLRD7N-Zrj2DOt_DFJg7IaJJCaLpsLJEwz","params":"OAI%3D","loggingContext":{"vssLoggingContext":{"serializedContextData":"GiJQTFJEN04tWnJqMkRPdF9ERkpnN0lhSkpDYUxwc0xKRXd6"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr8---sn-cxaaj5o5q5-tt1es.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=817275fe2d9c2509\u0026ip=74.12.195.102\u0026initcwndbps=1656250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}}}]},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CKMBEJY1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"videoCountText":{"runs":[{"text":"39"},{"text":" videos"}]},"navigationEndpoint":{"clickTrackingParams":"CKMBEJY1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEGEPI4GJcB","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=gXJ1_i2cJQk\u0026list=PLRD7N-Zrj2DOt_DFJg7IaJJCaLpsLJEwz","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"gXJ1_i2cJQk","playlistId":"PLRD7N-Zrj2DOt_DFJg7IaJJCaLpsLJEwz","params":"OAI%3D","loggingContext":{"vssLoggingContext":{"serializedContextData":"GiJQTFJEN04tWnJqMkRPdF9ERkpnN0lhSkpDYUxwc0xKRXd6"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr8---sn-cxaaj5o5q5-tt1es.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=817275fe2d9c2509\u0026ip=74.12.195.102\u0026initcwndbps=1656250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"videoCountShortText":{"simpleText":"39"},"trackingParams":"CKMBEJY1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","sidebarThumbnails":[{"thumbnails":[{"url":"https://i.ytimg.com/vi/bsgQw4N-xBE/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/7YZH-5cHSgg/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/VRBD2N4-EW8/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/8Ry90Meo-3E/default.jpg","width":43,"height":20}]}],"thumbnailText":{"runs":[{"text":"39","bold":true},{"text":" videos"}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CKMBEJY1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"thumbnailRenderer":{"playlistVideoThumbnailRenderer":{"thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/gXJ1_i2cJQk/hqdefault.jpg?sqp=-oaymwEXCOADEI4CSFryq4qpAwkIARUAAIhCGAE=\u0026rs=AOn4CLA6Ty4c_2KloFcMro-RjiqbRFXE1Q","width":480,"height":270}]},"trackingParams":"CKQBEMvsCSITCPjJv6athP0CFRCH_wQdsKgLVQ=="}},"longBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CKMBEJY1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"thumbnailOverlays":[{"thumbnailOverlaySidePanelRenderer":{"text":{"simpleText":"39"},"icon":{"iconType":"PLAYLISTS"}}},{"thumbnailOverlayHoverTextRenderer":{"text":{"runs":[{"text":"Play all"}]},"icon":{"iconType":"PLAY_ALL"}}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"viewPlaylistText":{"runs":[{"text":"View full playlist","navigationEndpoint":{"clickTrackingParams":"CKMBEJY1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLRD7N-Zrj2DOt_DFJg7IaJJCaLpsLJEwz","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLRD7N-Zrj2DOt_DFJg7IaJJCaLpsLJEwz"}}}]}}},{"gridPlaylistRenderer":{"playlistId":"PLRD7N-Zrj2DMzuze3L7pDcz-qRtFKwDB0","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/WhJa5fZUfT8/hqdefault.jpg?sqp=-oaymwEXCOADEI4CSFryq4qpAwkIARUAAIhCGAE=\u0026rs=AOn4CLB3dA9e8GUDS8gLqiAGEFmZ1HXQWw","width":480,"height":270}]},"title":{"runs":[{"text":"Cooking","navigationEndpoint":{"clickTrackingParams":"CKEBEJY1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEGEPI4GJcB","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=WhJa5fZUfT8\u0026list=PLRD7N-Zrj2DMzuze3L7pDcz-qRtFKwDB0","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"WhJa5fZUfT8","playlistId":"PLRD7N-Zrj2DMzuze3L7pDcz-qRtFKwDB0","params":"OAI%3D","loggingContext":{"vssLoggingContext":{"serializedContextData":"GiJQTFJEN04tWnJqMkRNenV6ZTNMN3BEY3otcVJ0Rkt3REIw"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1e6.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=5a125ae5f6547d3f\u0026ip=74.12.195.102\u0026initcwndbps=1521250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}}}]},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CKEBEJY1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"videoCountText":{"runs":[{"text":"10"},{"text":" videos"}]},"navigationEndpoint":{"clickTrackingParams":"CKEBEJY1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEGEPI4GJcB","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=WhJa5fZUfT8\u0026list=PLRD7N-Zrj2DMzuze3L7pDcz-qRtFKwDB0","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"WhJa5fZUfT8","playlistId":"PLRD7N-Zrj2DMzuze3L7pDcz-qRtFKwDB0","params":"OAI%3D","loggingContext":{"vssLoggingContext":{"serializedContextData":"GiJQTFJEN04tWnJqMkRNenV6ZTNMN3BEY3otcVJ0Rkt3REIw"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1e6.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=5a125ae5f6547d3f\u0026ip=74.12.195.102\u0026initcwndbps=1521250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"videoCountShortText":{"simpleText":"10"},"trackingParams":"CKEBEJY1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","sidebarThumbnails":[{"thumbnails":[{"url":"https://i.ytimg.com/vi/EvwE0wyL7f0/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/_aktyXRudwk/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/84T80yAitjk/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/T3sAYuOsqbA/default.jpg","width":43,"height":20}]}],"thumbnailText":{"runs":[{"text":"10","bold":true},{"text":" videos"}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CKEBEJY1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"thumbnailRenderer":{"playlistVideoThumbnailRenderer":{"thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/WhJa5fZUfT8/hqdefault.jpg?sqp=-oaymwEXCOADEI4CSFryq4qpAwkIARUAAIhCGAE=\u0026rs=AOn4CLB3dA9e8GUDS8gLqiAGEFmZ1HXQWw","width":480,"height":270}]},"trackingParams":"CKIBEMvsCSITCPjJv6athP0CFRCH_wQdsKgLVQ=="}},"longBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CKEBEJY1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"thumbnailOverlays":[{"thumbnailOverlaySidePanelRenderer":{"text":{"simpleText":"10"},"icon":{"iconType":"PLAYLISTS"}}},{"thumbnailOverlayHoverTextRenderer":{"text":{"runs":[{"text":"Play all"}]},"icon":{"iconType":"PLAY_ALL"}}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"viewPlaylistText":{"runs":[{"text":"View full playlist","navigationEndpoint":{"clickTrackingParams":"CKEBEJY1GAIiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLRD7N-Zrj2DMzuze3L7pDcz-qRtFKwDB0","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLRD7N-Zrj2DMzuze3L7pDcz-qRtFKwDB0"}}}]}}},{"gridPlaylistRenderer":{"playlistId":"PLRD7N-Zrj2DNE6S2AsY71GuuFgkRuzpWw","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/VelRmbqo8PQ/hqdefault.jpg?sqp=-oaymwEXCOADEI4CSFryq4qpAwkIARUAAIhCGAE=\u0026rs=AOn4CLD0HgQssYz_VNLFMjm3HwvC1Ve1Vg","width":480,"height":270}]},"title":{"runs":[{"text":"The Real Series","navigationEndpoint":{"clickTrackingParams":"CJ8BEJY1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEGEPI4GJcB","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=VelRmbqo8PQ\u0026list=PLRD7N-Zrj2DNE6S2AsY71GuuFgkRuzpWw","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"VelRmbqo8PQ","playlistId":"PLRD7N-Zrj2DNE6S2AsY71GuuFgkRuzpWw","params":"OAI%3D","loggingContext":{"vssLoggingContext":{"serializedContextData":"GiJQTFJEN04tWnJqMkRORTZTMkFzWTcxR3V1RmdrUnV6cFd3"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr8---sn-cxaaj5o5q5-tt1ee.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=55e95199baa8f0f4\u0026ip=74.12.195.102\u0026initcwndbps=1816250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}}}]},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CJ8BEJY1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"videoCountText":{"runs":[{"text":"50"},{"text":" videos"}]},"navigationEndpoint":{"clickTrackingParams":"CJ8BEJY1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEGEPI4GJcB","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=VelRmbqo8PQ\u0026list=PLRD7N-Zrj2DNE6S2AsY71GuuFgkRuzpWw","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"VelRmbqo8PQ","playlistId":"PLRD7N-Zrj2DNE6S2AsY71GuuFgkRuzpWw","params":"OAI%3D","loggingContext":{"vssLoggingContext":{"serializedContextData":"GiJQTFJEN04tWnJqMkRORTZTMkFzWTcxR3V1RmdrUnV6cFd3"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr8---sn-cxaaj5o5q5-tt1ee.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=55e95199baa8f0f4\u0026ip=74.12.195.102\u0026initcwndbps=1816250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"videoCountShortText":{"simpleText":"50"},"trackingParams":"CJ8BEJY1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","sidebarThumbnails":[{"thumbnails":[{"url":"https://i.ytimg.com/vi/vPcDINtnBqg/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/lhODmU4c4kc/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/MT4osHskht8/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/Xb67bjpgEJE/default.jpg","width":43,"height":20}]}],"thumbnailText":{"runs":[{"text":"50","bold":true},{"text":" videos"}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CJ8BEJY1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"thumbnailRenderer":{"playlistVideoThumbnailRenderer":{"thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/VelRmbqo8PQ/hqdefault.jpg?sqp=-oaymwEXCOADEI4CSFryq4qpAwkIARUAAIhCGAE=\u0026rs=AOn4CLD0HgQssYz_VNLFMjm3HwvC1Ve1Vg","width":480,"height":270}]},"trackingParams":"CKABEMvsCSITCPjJv6athP0CFRCH_wQdsKgLVQ=="}},"longBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CJ8BEJY1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"thumbnailOverlays":[{"thumbnailOverlaySidePanelRenderer":{"text":{"simpleText":"50"},"icon":{"iconType":"PLAYLISTS"}}},{"thumbnailOverlayHoverTextRenderer":{"text":{"runs":[{"text":"Play all"}]},"icon":{"iconType":"PLAY_ALL"}}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"viewPlaylistText":{"runs":[{"text":"View full playlist","navigationEndpoint":{"clickTrackingParams":"CJ8BEJY1GAMiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLRD7N-Zrj2DNE6S2AsY71GuuFgkRuzpWw","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLRD7N-Zrj2DNE6S2AsY71GuuFgkRuzpWw"}}}]}}},{"gridPlaylistRenderer":{"playlistId":"PLF5985320EC05B0FD","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/0B2QzVZN6YA/hqdefault.jpg?sqp=-oaymwEXCOADEI4CSFryq4qpAwkIARUAAIhCGAE=\u0026rs=AOn4CLAERqQO4vZkCABuv-TqS3PrcAd32w","width":480,"height":270}]},"title":{"runs":[{"text":"Stories","navigationEndpoint":{"clickTrackingParams":"CJ0BEJY1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEGEPI4GJcB","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=0B2QzVZN6YA\u0026list=PLF5985320EC05B0FD","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"0B2QzVZN6YA","playlistId":"PLF5985320EC05B0FD","params":"OAI%3D","loggingContext":{"vssLoggingContext":{"serializedContextData":"GhJQTEY1OTg1MzIwRUMwNUIwRkQ%3D"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr8---sn-cxaaj5o5q5-tt1e6.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=d01d90cd564de980\u0026ip=74.12.195.102\u0026initcwndbps=1521250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}}}]},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CJ0BEJY1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"videoCountText":{"runs":[{"text":"87"},{"text":" videos"}]},"navigationEndpoint":{"clickTrackingParams":"CJ0BEJY1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEGEPI4GJcB","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=0B2QzVZN6YA\u0026list=PLF5985320EC05B0FD","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"0B2QzVZN6YA","playlistId":"PLF5985320EC05B0FD","params":"OAI%3D","loggingContext":{"vssLoggingContext":{"serializedContextData":"GhJQTEY1OTg1MzIwRUMwNUIwRkQ%3D"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr8---sn-cxaaj5o5q5-tt1e6.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=d01d90cd564de980\u0026ip=74.12.195.102\u0026initcwndbps=1521250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"videoCountShortText":{"simpleText":"87"},"trackingParams":"CJ0BEJY1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","sidebarThumbnails":[{"thumbnails":[{"url":"https://i.ytimg.com/vi/H4A8iou050c/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/2TrBxiulPyM/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/4nMR-cHjXWw/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/sIQjtcM63XE/default.jpg","width":43,"height":20}]}],"thumbnailText":{"runs":[{"text":"87","bold":true},{"text":" videos"}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CJ0BEJY1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"thumbnailRenderer":{"playlistVideoThumbnailRenderer":{"thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/0B2QzVZN6YA/hqdefault.jpg?sqp=-oaymwEXCOADEI4CSFryq4qpAwkIARUAAIhCGAE=\u0026rs=AOn4CLAERqQO4vZkCABuv-TqS3PrcAd32w","width":480,"height":270}]},"trackingParams":"CJ4BEMvsCSITCPjJv6athP0CFRCH_wQdsKgLVQ=="}},"longBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CJ0BEJY1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"thumbnailOverlays":[{"thumbnailOverlaySidePanelRenderer":{"text":{"simpleText":"87"},"icon":{"iconType":"PLAYLISTS"}}},{"thumbnailOverlayHoverTextRenderer":{"text":{"runs":[{"text":"Play all"}]},"icon":{"iconType":"PLAY_ALL"}}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"viewPlaylistText":{"runs":[{"text":"View full playlist","navigationEndpoint":{"clickTrackingParams":"CJ0BEJY1GAQiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLF5985320EC05B0FD","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLF5985320EC05B0FD"}}}]}}},{"gridPlaylistRenderer":{"playlistId":"PLRD7N-Zrj2DNrib0vUkSdWfSGFlzd3zua","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/k2GxGeToegg/hqdefault.jpg?sqp=-oaymwEXCOADEI4CSFryq4qpAwkIARUAAIhCGAE=\u0026rs=AOn4CLBROCD-u4HDP8lj6nE0OR0jj-l7hw","width":480,"height":270}]},"title":{"runs":[{"text":"Soulcalibur","navigationEndpoint":{"clickTrackingParams":"CJsBEJY1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEGEPI4GJcB","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=k2GxGeToegg\u0026list=PLRD7N-Zrj2DNrib0vUkSdWfSGFlzd3zua","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"k2GxGeToegg","playlistId":"PLRD7N-Zrj2DNrib0vUkSdWfSGFlzd3zua","params":"OAI%3D","loggingContext":{"vssLoggingContext":{"serializedContextData":"GiJQTFJEN04tWnJqMkROcmliMHZVa1NkV2ZTR0ZsemQzenVh"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr7---sn-cxaaj5o5q5-tt1r.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=9361b119e4e87a08\u0026ip=74.12.195.102\u0026initcwndbps=1643750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}}}]},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CJsBEJY1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"videoCountText":{"runs":[{"text":"23"},{"text":" videos"}]},"navigationEndpoint":{"clickTrackingParams":"CJsBEJY1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEGEPI4GJcB","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=k2GxGeToegg\u0026list=PLRD7N-Zrj2DNrib0vUkSdWfSGFlzd3zua","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"k2GxGeToegg","playlistId":"PLRD7N-Zrj2DNrib0vUkSdWfSGFlzd3zua","params":"OAI%3D","loggingContext":{"vssLoggingContext":{"serializedContextData":"GiJQTFJEN04tWnJqMkROcmliMHZVa1NkV2ZTR0ZsemQzenVh"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr7---sn-cxaaj5o5q5-tt1r.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=9361b119e4e87a08\u0026ip=74.12.195.102\u0026initcwndbps=1643750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"videoCountShortText":{"simpleText":"23"},"trackingParams":"CJsBEJY1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","sidebarThumbnails":[{"thumbnails":[{"url":"https://i.ytimg.com/vi/XPHz6_T3wvg/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/Jqvg_GTsi18/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/TrQZP-3ESto/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/-sggw1APizI/default.jpg","width":43,"height":20}]}],"thumbnailText":{"runs":[{"text":"23","bold":true},{"text":" videos"}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CJsBEJY1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"thumbnailRenderer":{"playlistVideoThumbnailRenderer":{"thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/k2GxGeToegg/hqdefault.jpg?sqp=-oaymwEXCOADEI4CSFryq4qpAwkIARUAAIhCGAE=\u0026rs=AOn4CLBROCD-u4HDP8lj6nE0OR0jj-l7hw","width":480,"height":270}]},"trackingParams":"CJwBEMvsCSITCPjJv6athP0CFRCH_wQdsKgLVQ=="}},"longBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CJsBEJY1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"thumbnailOverlays":[{"thumbnailOverlaySidePanelRenderer":{"text":{"simpleText":"23"},"icon":{"iconType":"PLAYLISTS"}}},{"thumbnailOverlayHoverTextRenderer":{"text":{"runs":[{"text":"Play all"}]},"icon":{"iconType":"PLAY_ALL"}}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"viewPlaylistText":{"runs":[{"text":"View full playlist","navigationEndpoint":{"clickTrackingParams":"CJsBEJY1GAUiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLRD7N-Zrj2DNrib0vUkSdWfSGFlzd3zua","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLRD7N-Zrj2DNrib0vUkSdWfSGFlzd3zua"}}}]}}},{"gridPlaylistRenderer":{"playlistId":"PLRD7N-Zrj2DN260UFzdCSp1TRg2LYMdYU","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/dsnqgOVTVnE/hqdefault.jpg?sqp=-oaymwEXCOADEI4CSFryq4qpAwkIARUAAIhCGAE=\u0026rs=AOn4CLDQ2qGe8Bp6JjiPTOT6w62ywqMx3w","width":480,"height":270}]},"title":{"runs":[{"text":"The Worst Things on the Internet","navigationEndpoint":{"clickTrackingParams":"CJkBEJY1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEGEPI4GJcB","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=dsnqgOVTVnE\u0026list=PLRD7N-Zrj2DN260UFzdCSp1TRg2LYMdYU","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"dsnqgOVTVnE","playlistId":"PLRD7N-Zrj2DN260UFzdCSp1TRg2LYMdYU","params":"OAI%3D","loggingContext":{"vssLoggingContext":{"serializedContextData":"GiJQTFJEN04tWnJqMkROMjYwVUZ6ZENTcDFUUmcyTFlNZFlV"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1ez.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=76c9ea80e5535671\u0026ip=74.12.195.102\u0026initcwndbps=1915000\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}}}]},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CJkBEJY1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"videoCountText":{"runs":[{"text":"59"},{"text":" videos"}]},"navigationEndpoint":{"clickTrackingParams":"CJkBEJY1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEGEPI4GJcB","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=dsnqgOVTVnE\u0026list=PLRD7N-Zrj2DN260UFzdCSp1TRg2LYMdYU","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"dsnqgOVTVnE","playlistId":"PLRD7N-Zrj2DN260UFzdCSp1TRg2LYMdYU","params":"OAI%3D","loggingContext":{"vssLoggingContext":{"serializedContextData":"GiJQTFJEN04tWnJqMkROMjYwVUZ6ZENTcDFUUmcyTFlNZFlV"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1ez.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=76c9ea80e5535671\u0026ip=74.12.195.102\u0026initcwndbps=1915000\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"videoCountShortText":{"simpleText":"59"},"trackingParams":"CJkBEJY1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","sidebarThumbnails":[{"thumbnails":[{"url":"https://i.ytimg.com/vi/LVxKufQlnno/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/MnMSJ-Hc8_4/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/NPSamNJ_KHo/default.jpg","width":43,"height":20}]},{"thumbnails":[{"url":"https://i.ytimg.com/vi/cthlXGXjI6w/default.jpg","width":43,"height":20}]}],"thumbnailText":{"runs":[{"text":"59","bold":true},{"text":" videos"}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CJkBEJY1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"thumbnailRenderer":{"playlistVideoThumbnailRenderer":{"thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/dsnqgOVTVnE/hqdefault.jpg?sqp=-oaymwEXCOADEI4CSFryq4qpAwkIARUAAIhCGAE=\u0026rs=AOn4CLDQ2qGe8Bp6JjiPTOT6w62ywqMx3w","width":480,"height":270}]},"trackingParams":"CJoBEMvsCSITCPjJv6athP0CFRCH_wQdsKgLVQ=="}},"longBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CJkBEJY1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"thumbnailOverlays":[{"thumbnailOverlaySidePanelRenderer":{"text":{"simpleText":"59"},"icon":{"iconType":"PLAYLISTS"}}},{"thumbnailOverlayHoverTextRenderer":{"text":{"runs":[{"text":"Play all"}]},"icon":{"iconType":"PLAY_ALL"}}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"viewPlaylistText":{"runs":[{"text":"View full playlist","navigationEndpoint":{"clickTrackingParams":"CJkBEJY1GAYiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaA==","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLRD7N-Zrj2DN260UFzdCSp1TRg2LYMdYU","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLRD7N-Zrj2DN260UFzdCSp1TRg2LYMdYU"}}}]}}}],"trackingParams":"CJYBEMY5IhMI-Mm_pq2E_QIVEIf_BB2wqAtV","visibleItemCount":4,"nextButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"CHEVRON_RIGHT"},"accessibility":{"label":"Next"},"trackingParams":"CJgBEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},"previousButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"CHEVRON_LEFT"},"accessibility":{"label":"Previous"},"trackingParams":"CJcBEPBbIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}}}},"trackingParams":"CJUBENwcGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}}],"trackingParams":"CJQBELsvGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"itemSectionRenderer":{"contents":[{"shelfRenderer":{"title":{"runs":[{"text":"Among Us","navigationEndpoint":{"clickTrackingParams":"CC8Q3BwYACITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLRD7N-Zrj2DOVj2PuSW46elwqeQuiCiYV","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLRD7N-Zrj2DOVj2PuSW46elwqeQuiCiYV"}}}]},"endpoint":{"clickTrackingParams":"CC8Q3BwYACITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"url":"/playlist?list=PLRD7N-Zrj2DOVj2PuSW46elwqeQuiCiYV","webPageType":"WEB_PAGE_TYPE_PLAYLIST","rootVe":5754,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"VLPLRD7N-Zrj2DOVj2PuSW46elwqeQuiCiYV"}},"content":{"horizontalListRenderer":{"items":[{"gridVideoRenderer":{"videoId":"5Kp4obnli9A","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/5Kp4obnli9A/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAC2mu7rlnNy30StJNcdPL_JIc1zA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/5Kp4obnli9A/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCTdv7CEGxsgWWV05SimcrUs246Nw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/5Kp4obnli9A/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDmKBdafDT1gKq00j0up8s7A5zkHQ","width":246,"height":138},{"url":"https://i.ytimg.com/vi/5Kp4obnli9A/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLA6ATh8SAONq61ttRqaYslbfgnxRA","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"RIP Among Us by penguinz0 2 years ago 11 minutes, 55 seconds 1,577,546 views"}},"simpleText":"RIP Among Us"},"publishedTimeText":{"simpleText":"2 years ago"},"viewCountText":{"simpleText":"1,577,546 views"},"navigationEndpoint":{"clickTrackingParams":"CIwBEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRPVmoyUHVTVzQ2ZWx3cWVRdWlDaVlW","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=5Kp4obnli9A","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"5Kp4obnli9A","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr5---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=e4aa78a1b9e58bd0\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CIwBEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CIwBEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CIwBEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1VA0JeWz5uUntXkAaoBIlBMUkQ3Ti1acmoyRE9WajJQdVNXNDZlbHdxZVF1aUNpWVY=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CJMBEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.5 million views"}},"simpleText":"1.5M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CJIBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CJIBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"5Kp4obnli9A","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CJIBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["5Kp4obnli9A"],"params":"CAQ%3D"}},"videoIds":["5Kp4obnli9A"]}}]}},"trackingParams":"CJIBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CIwBEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"5Kp4obnli9A","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CIwBEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CJEBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"5Kp4obnli9A"}},"trackingParams":"CJEBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CJABENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"5Kp4obnli9A","onAddCommand":{"clickTrackingParams":"CJABENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"5Kp4obnli9A","params":"CAI%3D"}}}},"trackingParams":"CJABENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CIwBEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgs1S3A0b2JubGk5QQ%3D%3D","commands":[{"clickTrackingParams":"CIwBEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CI8BEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CIwBEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CIwBEJQ1GAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"11 minutes, 55 seconds"}},"simpleText":"11:55"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CI4BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"5Kp4obnli9A","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CI4BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"5Kp4obnli9A"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CI4BEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CI0BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CI0BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"5Kp4obnli9A","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CI0BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["5Kp4obnli9A"],"params":"CAQ%3D"}},"videoIds":["5Kp4obnli9A"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CI0BEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/5Kp4obnli9A/mqdefault_6s.webp?du=3000\u0026sqp=CIDoip8G\u0026rs=AOn4CLDY_6S8J07YC5Xv90vVSeMEVc6LDA","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"0TJOQkn0cE0","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/0TJOQkn0cE0/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBRJ3Z0GRAb192zuG4hZf7SsekTmQ","width":168,"height":94},{"url":"https://i.ytimg.com/vi/0TJOQkn0cE0/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLC5AtAWneQNHTBseIQnHqeDRlpHww","width":196,"height":110},{"url":"https://i.ytimg.com/vi/0TJOQkn0cE0/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLC_QC1ukrT4nRMKdahRtmEtalaFwA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/0TJOQkn0cE0/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDxO_1VvDhkegzh4lQnVLKZ1aLuiQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"I Almost Won A Huge Among Us Tournament by penguinz0 2 years ago 12 minutes, 11 seconds 1,378,301 views"}},"simpleText":"I Almost Won A Huge Among Us Tournament"},"publishedTimeText":{"simpleText":"2 years ago"},"viewCountText":{"simpleText":"1,378,301 views"},"navigationEndpoint":{"clickTrackingParams":"CIQBEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1UyBmctaGlnaFoYVUNxNlZGSHdNemNNWGJ1S3lHN1NRWUlnmgEFEPI4GGSqASJQTFJEN04tWnJqMkRPVmoyUHVTVzQ2ZWx3cWVRdWlDaVlW","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=0TJOQkn0cE0","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"0TJOQkn0cE0","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr4---sn-cxaaj5o5q5-tt1e6.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=d1324e4249f4704d\u0026ip=74.12.195.102\u0026initcwndbps=1521250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CIQBEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CIQBEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CIQBEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1VAzeDRz6TIk5nRAaoBIlBMUkQ3Ti1acmoyRE9WajJQdVNXNDZlbHdxZVF1aUNpWVY=","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CIsBEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.3 million views"}},"simpleText":"1.3M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CIoBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CIoBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"0TJOQkn0cE0","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CIoBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["0TJOQkn0cE0"],"params":"CAQ%3D"}},"videoIds":["0TJOQkn0cE0"]}}]}},"trackingParams":"CIoBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CIQBEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"0TJOQkn0cE0","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CIQBEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CIkBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"0TJOQkn0cE0"}},"trackingParams":"CIkBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CIgBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"0TJOQkn0cE0","onAddCommand":{"clickTrackingParams":"CIgBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"0TJOQkn0cE0","params":"CAI%3D"}}}},"trackingParams":"CIgBENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CIQBEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgswVEpPUWtuMGNFMA%3D%3D","commands":[{"clickTrackingParams":"CIQBEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CIcBEI5iIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CIQBEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","hasSeparator":true}}],"trackingParams":"CIQBEJQ1GAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"12 minutes, 11 seconds"}},"simpleText":"12:11"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CIYBEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"0TJOQkn0cE0","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CIYBEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"0TJOQkn0cE0"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CIYBEPnnAxgCIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CIUBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CIUBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"0TJOQkn0cE0","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CIUBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["0TJOQkn0cE0"],"params":"CAQ%3D"}},"videoIds":["0TJOQkn0cE0"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CIUBEMfsBBgDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/0TJOQkn0cE0/mqdefault_6s.webp?du=3000\u0026sqp=CI73ip8G\u0026rs=AOn4CLBYKoM6L67wOGIefMdvzNoEq9JkQw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"UcJFkbqdeLc","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/UcJFkbqdeLc/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLD0_V1_ShnMDcIlHcHH9w0KZrlV5w","width":168,"height":94},{"url":"https://i.ytimg.com/vi/UcJFkbqdeLc/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLB9-RnvIefUIHUbWb-oYMyLAH2vFQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/UcJFkbqdeLc/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAY6VbmancnZyM1v-bly8Qj133JPQ","width":246,"height":138},{"url":"https://i.ytimg.com/vi/UcJFkbqdeLc/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCm0P2SPq1VijTzNkuE6yPi3DJgsg","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Orang Strat Never Fails by penguinz0 2 years ago 8 minutes, 22 seconds 3,326,093 views"}},"simpleText":"Orang Strat Never Fails"},"publishedTimeText":{"simpleText":"2 years ago"},"viewCountText":{"simpleText":"3,326,093 views"},"navigationEndpoint":{"clickTrackingParams":"CHwQlDUYAiITCPjJv6athP0CFRCH_wQdsKgLVTIGZy1oaWdoWhhVQ3E2VkZId016Y01YYnVLeUc3U1FZSWeaAQUQ8jgYZKoBIlBMUkQ3Ti1acmoyRE9WajJQdVNXNDZlbHdxZVF1aUNpWVY=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=UcJFkbqdeLc","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"UcJFkbqdeLc","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr2---sn-cxaaj5o5q5-tt1el.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=51c24591ba9d78b7\u0026ip=74.12.195.102\u0026initcwndbps=1782500\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CHwQlDUYAiITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CHwQlDUYAiITCPjJv6athP0CFRCH_wQdsKgLVQ==","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CHwQlDUYAiITCPjJv6athP0CFRCH_wQdsKgLVUC38fXUm7KR4VGqASJQTFJEN04tWnJqMkRPVmoyUHVTVzQ2ZWx3cWVRdWlDaVlW","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CIMBEMc3IhMI-Mm_pq2E_QIVEIf_BB2wqAtVMgtvZmZsaW5lbGlzdA=="}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"3.3 million views"}},"simpleText":"3.3M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CIIBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CIIBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"UcJFkbqdeLc","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CIIBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["UcJFkbqdeLc"],"params":"CAQ%3D"}},"videoIds":["UcJFkbqdeLc"]}}]}},"trackingParams":"CIIBEP6YBBgHIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CHwQlDUYAiITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"UcJFkbqdeLc","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CHwQlDUYAiITCPjJv6athP0CFRCH_wQdsKgLVQ=="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CIEBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"UcJFkbqdeLc"}},"trackingParams":"CIEBEJSsCRgJIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CIABENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","offlineVideoEndpoint":{"videoId":"UcJFkbqdeLc","onAddCommand":{"clickTrackingParams":"CIABENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","getDownloadActionCommand":{"videoId":"UcJFkbqdeLc","params":"CAI%3D"}}}},"trackingParams":"CIABENGqBRgKIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CHwQlDUYAiITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtVY0pGa2JxZGVMYw%3D%3D","commands":[{"clickTrackingParams":"CHwQlDUYAiITCPjJv6athP0CFRCH_wQdsKgLVQ==","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CH8QjmIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CHwQlDUYAiITCPjJv6athP0CFRCH_wQdsKgLVQ==","hasSeparator":true}}],"trackingParams":"CHwQlDUYAiITCPjJv6athP0CFRCH_wQdsKgLVQ==","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"8 minutes, 22 seconds"}},"simpleText":"8:22"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CH4Q-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"UcJFkbqdeLc","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CH4Q-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"UcJFkbqdeLc"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CH4Q-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CH0Qx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CH0Qx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"UcJFkbqdeLc","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CH0Qx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["UcJFkbqdeLc"],"params":"CAQ%3D"}},"videoIds":["UcJFkbqdeLc"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CH0Qx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/UcJFkbqdeLc/mqdefault_6s.webp?du=3000\u0026sqp=CLyBi58G\u0026rs=AOn4CLDHa1E4CKbg9kVX9noxnLjSRqV9xg","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"DnTumOJkeqA","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/DnTumOJkeqA/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCfzl-fnZS204H7y5lWEp-BEk1yug","width":168,"height":94},{"url":"https://i.ytimg.com/vi/DnTumOJkeqA/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDuBTX0qoyY4IYh9K_IP5LQ0EnakQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/DnTumOJkeqA/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLA_3uKtu5O-FI3uVAAAiST4WsQ5yg","width":246,"height":138},{"url":"https://i.ytimg.com/vi/DnTumOJkeqA/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDQr4MthzPm8DiwDqRg_7EZiccicg","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"I'm Sorry Corpse by penguinz0 2 years ago 10 minutes, 48 seconds 2,090,185 views"}},"simpleText":"I'm Sorry Corpse"},"publishedTimeText":{"simpleText":"2 years ago"},"viewCountText":{"simpleText":"2,090,185 views"},"navigationEndpoint":{"clickTrackingParams":"CHQQlDUYAyITCPjJv6athP0CFRCH_wQdsKgLVTIGZy1oaWdoWhhVQ3E2VkZId016Y01YYnVLeUc3U1FZSWeaAQUQ8jgYZKoBIlBMUkQ3Ti1acmoyRE9WajJQdVNXNDZlbHdxZVF1aUNpWVY=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=DnTumOJkeqA","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"DnTumOJkeqA","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr7---sn-cxaaj5o5q5-tt1ez.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=0e74ee98e2647aa0\u0026ip=74.12.195.102\u0026initcwndbps=1915000\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CHQQlDUYAyITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CHQQlDUYAyITCPjJv6athP0CFRCH_wQdsKgLVQ==","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CHQQlDUYAyITCPjJv6athP0CFRCH_wQdsKgLVUCg9ZGTjtO7ug6qASJQTFJEN04tWnJqMkRPVmoyUHVTVzQ2ZWx3cWVRdWlDaVlW","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CHsQxzciEwj4yb-mrYT9AhUQh_8EHbCoC1UyC29mZmxpbmVsaXN0"}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2 million views"}},"simpleText":"2M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CHoQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CHoQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"DnTumOJkeqA","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CHoQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["DnTumOJkeqA"],"params":"CAQ%3D"}},"videoIds":["DnTumOJkeqA"]}}]}},"trackingParams":"CHoQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CHQQlDUYAyITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"DnTumOJkeqA","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CHQQlDUYAyITCPjJv6athP0CFRCH_wQdsKgLVQ=="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CHkQlKwJGAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"DnTumOJkeqA"}},"trackingParams":"CHkQlKwJGAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CHgQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","offlineVideoEndpoint":{"videoId":"DnTumOJkeqA","onAddCommand":{"clickTrackingParams":"CHgQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","getDownloadActionCommand":{"videoId":"DnTumOJkeqA","params":"CAI%3D"}}}},"trackingParams":"CHgQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CHQQlDUYAyITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtEblR1bU9Ka2VxQQ%3D%3D","commands":[{"clickTrackingParams":"CHQQlDUYAyITCPjJv6athP0CFRCH_wQdsKgLVQ==","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CHcQjmIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CHQQlDUYAyITCPjJv6athP0CFRCH_wQdsKgLVQ==","hasSeparator":true}}],"trackingParams":"CHQQlDUYAyITCPjJv6athP0CFRCH_wQdsKgLVQ==","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"10 minutes, 48 seconds"}},"simpleText":"10:48"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CHYQ-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"DnTumOJkeqA","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CHYQ-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"DnTumOJkeqA"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CHYQ-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CHUQx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CHUQx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"DnTumOJkeqA","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CHUQx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["DnTumOJkeqA"],"params":"CAQ%3D"}},"videoIds":["DnTumOJkeqA"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CHUQx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/DnTumOJkeqA/mqdefault_6s.webp?du=3000\u0026sqp=CICAi58G\u0026rs=AOn4CLAqwUzFY18v4t1z5zWsaUWHbwVcVw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"yGoDVD-lAkk","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/yGoDVD-lAkk/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLD7lfHrKvcnYERom8esWUo1qNeJ3Q","width":168,"height":94},{"url":"https://i.ytimg.com/vi/yGoDVD-lAkk/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLB2zQRCcy6bFUB-0M1oAz4MVeX0iw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/yGoDVD-lAkk/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAhV_9Jvx6ugXN7jak6OAuXUGlHTQ","width":246,"height":138},{"url":"https://i.ytimg.com/vi/yGoDVD-lAkk/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAvXwJDgtwd3O1pEMJu41CEKXa57g","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"My Most Impressive Impostor Win Yet by penguinz0 2 years ago 8 minutes, 33 seconds 1,768,334 views"}},"simpleText":"My Most Impressive Impostor Win Yet"},"publishedTimeText":{"simpleText":"2 years ago"},"viewCountText":{"simpleText":"1,768,334 views"},"navigationEndpoint":{"clickTrackingParams":"CGwQlDUYBCITCPjJv6athP0CFRCH_wQdsKgLVTIGZy1oaWdoWhhVQ3E2VkZId016Y01YYnVLeUc3U1FZSWeaAQUQ8jgYZKoBIlBMUkQ3Ti1acmoyRE9WajJQdVNXNDZlbHdxZVF1aUNpWVY=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=yGoDVD-lAkk","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"yGoDVD-lAkk","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr6---sn-cxaaj5o5q5-tt1ez.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=c86a03543fa50249\u0026ip=74.12.195.102\u0026initcwndbps=1915000\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CGwQlDUYBCITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CGwQlDUYBCITCPjJv6athP0CFRCH_wQdsKgLVQ==","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CGwQlDUYBCITCPjJv6athP0CFRCH_wQdsKgLVUDJhJT9w-qAtcgBqgEiUExSRDdOLVpyajJET1ZqMlB1U1c0NmVsd3FlUXVpQ2lZVg==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CHMQxzciEwj4yb-mrYT9AhUQh_8EHbCoC1UyC29mZmxpbmVsaXN0"}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.7 million views"}},"simpleText":"1.7M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CHIQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CHIQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"yGoDVD-lAkk","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CHIQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["yGoDVD-lAkk"],"params":"CAQ%3D"}},"videoIds":["yGoDVD-lAkk"]}}]}},"trackingParams":"CHIQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CGwQlDUYBCITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"yGoDVD-lAkk","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CGwQlDUYBCITCPjJv6athP0CFRCH_wQdsKgLVQ=="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CHEQlKwJGAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"yGoDVD-lAkk"}},"trackingParams":"CHEQlKwJGAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CHAQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","offlineVideoEndpoint":{"videoId":"yGoDVD-lAkk","onAddCommand":{"clickTrackingParams":"CHAQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","getDownloadActionCommand":{"videoId":"yGoDVD-lAkk","params":"CAI%3D"}}}},"trackingParams":"CHAQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CGwQlDUYBCITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgt5R29EVkQtbEFraw%3D%3D","commands":[{"clickTrackingParams":"CGwQlDUYBCITCPjJv6athP0CFRCH_wQdsKgLVQ==","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CG8QjmIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CGwQlDUYBCITCPjJv6athP0CFRCH_wQdsKgLVQ==","hasSeparator":true}}],"trackingParams":"CGwQlDUYBCITCPjJv6athP0CFRCH_wQdsKgLVQ==","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"8 minutes, 33 seconds"}},"simpleText":"8:33"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CG4Q-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"yGoDVD-lAkk","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CG4Q-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"yGoDVD-lAkk"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CG4Q-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CG0Qx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CG0Qx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"yGoDVD-lAkk","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CG0Qx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["yGoDVD-lAkk"],"params":"CAQ%3D"}},"videoIds":["yGoDVD-lAkk"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CG0Qx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/yGoDVD-lAkk/mqdefault_6s.webp?du=3000\u0026sqp=CK3aip8G\u0026rs=AOn4CLCcY5m1CgMMUviaWXSHHl8BGQx_bw","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"WWXq7LkUCAM","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/WWXq7LkUCAM/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLClxRWhRQ27rKRQYZqRKLGX4tWhIA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/WWXq7LkUCAM/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLA3Cnwy2-zflUoYiXdVSZH3ZecZtQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/WWXq7LkUCAM/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDxpaUKbmbg_rc_y8UrvsqHv0cLHQ","width":246,"height":138},{"url":"https://i.ytimg.com/vi/WWXq7LkUCAM/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLA9dxo52DUR1CYJSyQ5Om77uX1b4A","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Best Among Us Lobby by penguinz0 2 years ago 9 minutes, 1 second 1,945,342 views"}},"simpleText":"Best Among Us Lobby"},"publishedTimeText":{"simpleText":"2 years ago"},"viewCountText":{"simpleText":"1,945,342 views"},"navigationEndpoint":{"clickTrackingParams":"CGQQlDUYBSITCPjJv6athP0CFRCH_wQdsKgLVTIGZy1oaWdoWhhVQ3E2VkZId016Y01YYnVLeUc3U1FZSWeaAQUQ8jgYZKoBIlBMUkQ3Ti1acmoyRE9WajJQdVNXNDZlbHdxZVF1aUNpWVY=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=WWXq7LkUCAM","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"WWXq7LkUCAM","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr4---sn-cxaaj5o5q5-tt1e6.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=5965eaecb9140803\u0026ip=74.12.195.102\u0026initcwndbps=1521250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CGQQlDUYBSITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CGQQlDUYBSITCPjJv6athP0CFRCH_wQdsKgLVQ==","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CGQQlDUYBSITCPjJv6athP0CFRCH_wQdsKgLVUCDkNDIy936slmqASJQTFJEN04tWnJqMkRPVmoyUHVTVzQ2ZWx3cWVRdWlDaVlW","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CGsQxzciEwj4yb-mrYT9AhUQh_8EHbCoC1UyC29mZmxpbmVsaXN0"}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.9 million views"}},"simpleText":"1.9M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CGoQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CGoQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"WWXq7LkUCAM","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CGoQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["WWXq7LkUCAM"],"params":"CAQ%3D"}},"videoIds":["WWXq7LkUCAM"]}}]}},"trackingParams":"CGoQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CGQQlDUYBSITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"WWXq7LkUCAM","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CGQQlDUYBSITCPjJv6athP0CFRCH_wQdsKgLVQ=="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CGkQlKwJGAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"WWXq7LkUCAM"}},"trackingParams":"CGkQlKwJGAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CGgQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","offlineVideoEndpoint":{"videoId":"WWXq7LkUCAM","onAddCommand":{"clickTrackingParams":"CGgQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","getDownloadActionCommand":{"videoId":"WWXq7LkUCAM","params":"CAI%3D"}}}},"trackingParams":"CGgQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CGQQlDUYBSITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtXV1hxN0xrVUNBTQ%3D%3D","commands":[{"clickTrackingParams":"CGQQlDUYBSITCPjJv6athP0CFRCH_wQdsKgLVQ==","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CGcQjmIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CGQQlDUYBSITCPjJv6athP0CFRCH_wQdsKgLVQ==","hasSeparator":true}}],"trackingParams":"CGQQlDUYBSITCPjJv6athP0CFRCH_wQdsKgLVQ==","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"9 minutes, 1 second"}},"simpleText":"9:01"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CGYQ-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"WWXq7LkUCAM","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CGYQ-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"WWXq7LkUCAM"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CGYQ-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CGUQx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CGUQx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"WWXq7LkUCAM","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CGUQx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["WWXq7LkUCAM"],"params":"CAQ%3D"}},"videoIds":["WWXq7LkUCAM"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CGUQx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/WWXq7LkUCAM/mqdefault_6s.webp?du=3000\u0026sqp=CKOBi58G\u0026rs=AOn4CLB_u3fhEWhsy8JBeTO56zM9eI1HzQ","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"g_MxqMylxJw","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/g_MxqMylxJw/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCdH9A4K_KlrL5cvW1X1WTHEzrlFA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/g_MxqMylxJw/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLA0netP6jXIhQwR4H4J4eQg5FEFeQ","width":196,"height":110},{"url":"https://i.ytimg.com/vi/g_MxqMylxJw/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDZ3ikhwCPlVxqtPACkjfZn5Nrlpg","width":246,"height":138},{"url":"https://i.ytimg.com/vi/g_MxqMylxJw/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLCcYu4TQfmnFvIPF03Yw3dhr_-wOQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"I Ruined Anime Club by penguinz0 2 years ago 9 minutes, 13 seconds 1,740,563 views"}},"simpleText":"I Ruined Anime Club"},"publishedTimeText":{"simpleText":"2 years ago"},"viewCountText":{"simpleText":"1,740,563 views"},"navigationEndpoint":{"clickTrackingParams":"CFwQlDUYBiITCPjJv6athP0CFRCH_wQdsKgLVTIGZy1oaWdoWhhVQ3E2VkZId016Y01YYnVLeUc3U1FZSWeaAQUQ8jgYZKoBIlBMUkQ3Ti1acmoyRE9WajJQdVNXNDZlbHdxZVF1aUNpWVY=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=g_MxqMylxJw","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"g_MxqMylxJw","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr5---sn-cxaaj5o5q5-tt1e6.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=83f331a8cca5c49c\u0026ip=74.12.195.102\u0026initcwndbps=1521250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CFwQlDUYBiITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CFwQlDUYBiITCPjJv6athP0CFRCH_wQdsKgLVQ==","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CFwQlDUYBiITCPjJv6athP0CFRCH_wQdsKgLVUCciZfljLXM-YMBqgEiUExSRDdOLVpyajJET1ZqMlB1U1c0NmVsd3FlUXVpQ2lZVg==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CGMQxzciEwj4yb-mrYT9AhUQh_8EHbCoC1UyC29mZmxpbmVsaXN0"}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.7 million views"}},"simpleText":"1.7M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CGIQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CGIQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"g_MxqMylxJw","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CGIQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["g_MxqMylxJw"],"params":"CAQ%3D"}},"videoIds":["g_MxqMylxJw"]}}]}},"trackingParams":"CGIQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CFwQlDUYBiITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"g_MxqMylxJw","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CFwQlDUYBiITCPjJv6athP0CFRCH_wQdsKgLVQ=="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CGEQlKwJGAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"g_MxqMylxJw"}},"trackingParams":"CGEQlKwJGAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CGAQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","offlineVideoEndpoint":{"videoId":"g_MxqMylxJw","onAddCommand":{"clickTrackingParams":"CGAQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","getDownloadActionCommand":{"videoId":"g_MxqMylxJw","params":"CAI%3D"}}}},"trackingParams":"CGAQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CFwQlDUYBiITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtnX014cU15bHhKdw%3D%3D","commands":[{"clickTrackingParams":"CFwQlDUYBiITCPjJv6athP0CFRCH_wQdsKgLVQ==","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CF8QjmIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CFwQlDUYBiITCPjJv6athP0CFRCH_wQdsKgLVQ==","hasSeparator":true}}],"trackingParams":"CFwQlDUYBiITCPjJv6athP0CFRCH_wQdsKgLVQ==","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"9 minutes, 13 seconds"}},"simpleText":"9:13"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CF4Q-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"g_MxqMylxJw","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CF4Q-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"g_MxqMylxJw"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CF4Q-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CF0Qx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CF0Qx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"g_MxqMylxJw","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CF0Qx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["g_MxqMylxJw"],"params":"CAQ%3D"}},"videoIds":["g_MxqMylxJw"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CF0Qx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/g_MxqMylxJw/mqdefault_6s.webp?du=3000\u0026sqp=CJToip8G\u0026rs=AOn4CLCMAzAPis7tcr0pDySUHst6-sdWhA","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"vGvoSZ0Hx0E","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/vGvoSZ0Hx0E/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBs5P8DY_md5VHhQhj568CebKS-YQ","width":168,"height":94},{"url":"https://i.ytimg.com/vi/vGvoSZ0Hx0E/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLCRmtHUKDfnC1XOEqC90A6ubYG__A","width":196,"height":110},{"url":"https://i.ytimg.com/vi/vGvoSZ0Hx0E/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDhI28jJZpf_Mmr_ju5HCOlo36wuA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/vGvoSZ0Hx0E/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLD4gGsGK9tbBUhgJJt_xGTAXgn1cQ","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Angriest Man In Among Us by penguinz0 2 years ago 8 minutes, 49 seconds 2,719,139 views"}},"simpleText":"Angriest Man In Among Us"},"publishedTimeText":{"simpleText":"2 years ago"},"viewCountText":{"simpleText":"2,719,139 views"},"navigationEndpoint":{"clickTrackingParams":"CFQQlDUYByITCPjJv6athP0CFRCH_wQdsKgLVTIGZy1oaWdoWhhVQ3E2VkZId016Y01YYnVLeUc3U1FZSWeaAQUQ8jgYZKoBIlBMUkQ3Ti1acmoyRE9WajJQdVNXNDZlbHdxZVF1aUNpWVY=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=vGvoSZ0Hx0E","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"vGvoSZ0Hx0E","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr5---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=bc6be8499d07c741\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CFQQlDUYByITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CFQQlDUYByITCPjJv6athP0CFRCH_wQdsKgLVQ==","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CFQQlDUYByITCPjJv6athP0CFRCH_wQdsKgLVUDBjp_omYn6tbwBqgEiUExSRDdOLVpyajJET1ZqMlB1U1c0NmVsd3FlUXVpQ2lZVg==","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CFsQxzciEwj4yb-mrYT9AhUQh_8EHbCoC1UyC29mZmxpbmVsaXN0"}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2.7 million views"}},"simpleText":"2.7M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CFoQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CFoQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"vGvoSZ0Hx0E","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CFoQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["vGvoSZ0Hx0E"],"params":"CAQ%3D"}},"videoIds":["vGvoSZ0Hx0E"]}}]}},"trackingParams":"CFoQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CFQQlDUYByITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"vGvoSZ0Hx0E","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CFQQlDUYByITCPjJv6athP0CFRCH_wQdsKgLVQ=="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CFkQlKwJGAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"vGvoSZ0Hx0E"}},"trackingParams":"CFkQlKwJGAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CFgQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","offlineVideoEndpoint":{"videoId":"vGvoSZ0Hx0E","onAddCommand":{"clickTrackingParams":"CFgQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","getDownloadActionCommand":{"videoId":"vGvoSZ0Hx0E","params":"CAI%3D"}}}},"trackingParams":"CFgQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CFQQlDUYByITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"Cgt2R3ZvU1owSHgwRQ%3D%3D","commands":[{"clickTrackingParams":"CFQQlDUYByITCPjJv6athP0CFRCH_wQdsKgLVQ==","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CFcQjmIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CFQQlDUYByITCPjJv6athP0CFRCH_wQdsKgLVQ==","hasSeparator":true}}],"trackingParams":"CFQQlDUYByITCPjJv6athP0CFRCH_wQdsKgLVQ==","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"8 minutes, 49 seconds"}},"simpleText":"8:49"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CFYQ-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"vGvoSZ0Hx0E","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CFYQ-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"vGvoSZ0Hx0E"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CFYQ-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CFUQx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CFUQx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"vGvoSZ0Hx0E","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CFUQx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["vGvoSZ0Hx0E"],"params":"CAQ%3D"}},"videoIds":["vGvoSZ0Hx0E"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CFUQx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/vGvoSZ0Hx0E/mqdefault_6s.webp?du=3000\u0026sqp=CI77ip8G\u0026rs=AOn4CLB0-czKyNumN6tzMSrXjquPHBUPcA","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"ZPf8G2urut4","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/ZPf8G2urut4/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDFOSsC_tej0QP1h-3exQG9CqbmNA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/ZPf8G2urut4/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAivduTOVZZGJE6avcPmi97T4MX9Q","width":196,"height":110},{"url":"https://i.ytimg.com/vi/ZPf8G2urut4/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAwY08XooBfCYFZ24cI3X_dOKZDPA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/ZPf8G2urut4/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDIdEtxHQNOyTervLFDvHbThkdImA","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"Unbeatable Impostor by penguinz0 2 years ago 14 minutes, 38 seconds 2,884,538 views"}},"simpleText":"Unbeatable Impostor"},"publishedTimeText":{"simpleText":"2 years ago"},"viewCountText":{"simpleText":"2,884,538 views"},"navigationEndpoint":{"clickTrackingParams":"CEwQlDUYCCITCPjJv6athP0CFRCH_wQdsKgLVTIGZy1oaWdoWhhVQ3E2VkZId016Y01YYnVLeUc3U1FZSWeaAQUQ8jgYZKoBIlBMUkQ3Ti1acmoyRE9WajJQdVNXNDZlbHdxZVF1aUNpWVY=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=ZPf8G2urut4","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"ZPf8G2urut4","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr3---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=64f7fc1b6babbade\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CEwQlDUYCCITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CEwQlDUYCCITCPjJv6athP0CFRCH_wQdsKgLVQ==","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CEwQlDUYCCITCPjJv6athP0CFRCH_wQdsKgLVUDe9a7dtoP_-2SqASJQTFJEN04tWnJqMkRPVmoyUHVTVzQ2ZWx3cWVRdWlDaVlW","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CFMQxzciEwj4yb-mrYT9AhUQh_8EHbCoC1UyC29mZmxpbmVsaXN0"}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2.8 million views"}},"simpleText":"2.8M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CFIQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CFIQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"ZPf8G2urut4","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CFIQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["ZPf8G2urut4"],"params":"CAQ%3D"}},"videoIds":["ZPf8G2urut4"]}}]}},"trackingParams":"CFIQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CEwQlDUYCCITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"ZPf8G2urut4","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CEwQlDUYCCITCPjJv6athP0CFRCH_wQdsKgLVQ=="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CFEQlKwJGAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"ZPf8G2urut4"}},"trackingParams":"CFEQlKwJGAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CFAQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","offlineVideoEndpoint":{"videoId":"ZPf8G2urut4","onAddCommand":{"clickTrackingParams":"CFAQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","getDownloadActionCommand":{"videoId":"ZPf8G2urut4","params":"CAI%3D"}}}},"trackingParams":"CFAQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CEwQlDUYCCITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtaUGY4RzJ1cnV0NA%3D%3D","commands":[{"clickTrackingParams":"CEwQlDUYCCITCPjJv6athP0CFRCH_wQdsKgLVQ==","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CE8QjmIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CEwQlDUYCCITCPjJv6athP0CFRCH_wQdsKgLVQ==","hasSeparator":true}}],"trackingParams":"CEwQlDUYCCITCPjJv6athP0CFRCH_wQdsKgLVQ==","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"14 minutes, 38 seconds"}},"simpleText":"14:38"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CE4Q-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"ZPf8G2urut4","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CE4Q-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"ZPf8G2urut4"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CE4Q-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CE0Qx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CE0Qx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"ZPf8G2urut4","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CE0Qx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["ZPf8G2urut4"],"params":"CAQ%3D"}},"videoIds":["ZPf8G2urut4"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CE0Qx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/ZPf8G2urut4/mqdefault_6s.webp?du=3000\u0026sqp=CNb1ip8G\u0026rs=AOn4CLAqB95mH0y-whqshGEF8qPrkBP87g","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"AeynuykcTo0","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/AeynuykcTo0/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBI3Q0wAn4R7Qq6SOE4GXntr-ZPxA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/AeynuykcTo0/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLB-XNhIh1MCcP_ov6ECl1HFdnaW_Q","width":196,"height":110},{"url":"https://i.ytimg.com/vi/AeynuykcTo0/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDjssIR5hKiJ0bx4p3Uc3GkPq_n2Q","width":246,"height":138},{"url":"https://i.ytimg.com/vi/AeynuykcTo0/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLDtsjepVOuiZhk3TppcEs4nDH5olA","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"I'm Too Powerful For Public Lobbies by penguinz0 2 years ago 9 minutes, 35 seconds 2,116,005 views"}},"simpleText":"I'm Too Powerful For Public Lobbies"},"publishedTimeText":{"simpleText":"2 years ago"},"viewCountText":{"simpleText":"2,116,005 views"},"navigationEndpoint":{"clickTrackingParams":"CEQQlDUYCSITCPjJv6athP0CFRCH_wQdsKgLVTIGZy1oaWdoWhhVQ3E2VkZId016Y01YYnVLeUc3U1FZSWeaAQUQ8jgYZKoBIlBMUkQ3Ti1acmoyRE9WajJQdVNXNDZlbHdxZVF1aUNpWVY=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=AeynuykcTo0","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"AeynuykcTo0","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr4---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=01eca7bb291c4e8d\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CEQQlDUYCSITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CEQQlDUYCSITCPjJv6athP0CFRCH_wQdsKgLVQ==","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CEQQlDUYCSITCPjJv6athP0CFRCH_wQdsKgLVUCNnfHIsvep9gGqASJQTFJEN04tWnJqMkRPVmoyUHVTVzQ2ZWx3cWVRdWlDaVlW","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CEsQxzciEwj4yb-mrYT9AhUQh_8EHbCoC1UyC29mZmxpbmVsaXN0"}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2.1 million views"}},"simpleText":"2.1M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CEoQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CEoQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"AeynuykcTo0","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CEoQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["AeynuykcTo0"],"params":"CAQ%3D"}},"videoIds":["AeynuykcTo0"]}}]}},"trackingParams":"CEoQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CEQQlDUYCSITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"AeynuykcTo0","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CEQQlDUYCSITCPjJv6athP0CFRCH_wQdsKgLVQ=="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CEkQlKwJGAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"AeynuykcTo0"}},"trackingParams":"CEkQlKwJGAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CEgQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","offlineVideoEndpoint":{"videoId":"AeynuykcTo0","onAddCommand":{"clickTrackingParams":"CEgQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","getDownloadActionCommand":{"videoId":"AeynuykcTo0","params":"CAI%3D"}}}},"trackingParams":"CEgQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CEQQlDUYCSITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtBZXludXlrY1RvMA%3D%3D","commands":[{"clickTrackingParams":"CEQQlDUYCSITCPjJv6athP0CFRCH_wQdsKgLVQ==","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CEcQjmIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CEQQlDUYCSITCPjJv6athP0CFRCH_wQdsKgLVQ==","hasSeparator":true}}],"trackingParams":"CEQQlDUYCSITCPjJv6athP0CFRCH_wQdsKgLVQ==","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"9 minutes, 35 seconds"}},"simpleText":"9:35"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CEYQ-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"AeynuykcTo0","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CEYQ-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"AeynuykcTo0"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CEYQ-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CEUQx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CEUQx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"AeynuykcTo0","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CEUQx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["AeynuykcTo0"],"params":"CAQ%3D"}},"videoIds":["AeynuykcTo0"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CEUQx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/AeynuykcTo0/mqdefault_6s.webp?du=3000\u0026sqp=COX9ip8G\u0026rs=AOn4CLBPq27CTFg8AzRlEfwdQFnKUssYvg","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"VIkYfi38T54","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/VIkYfi38T54/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLBmSRn3Wg5MWlKaWyuZAWWdaxLYTQ","width":168,"height":94},{"url":"https://i.ytimg.com/vi/VIkYfi38T54/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLA63O3hgbtgelboYDtnTUtF4ScTiw","width":196,"height":110},{"url":"https://i.ytimg.com/vi/VIkYfi38T54/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLD1_h-NjvN_ctppRIsspLJi4PTk0w","width":246,"height":138},{"url":"https://i.ytimg.com/vi/VIkYfi38T54/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAyHHbfwErxGgj9xVUzB0KcTxpSMg","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"100% Winrate Impostor Strat by penguinz0 2 years ago 9 minutes, 39 seconds 2,323,637 views"}},"simpleText":"100% Winrate Impostor Strat"},"publishedTimeText":{"simpleText":"2 years ago"},"viewCountText":{"simpleText":"2,323,637 views"},"navigationEndpoint":{"clickTrackingParams":"CDwQlDUYCiITCPjJv6athP0CFRCH_wQdsKgLVTIGZy1oaWdoWhhVQ3E2VkZId016Y01YYnVLeUc3U1FZSWeaAQUQ8jgYZKoBIlBMUkQ3Ti1acmoyRE9WajJQdVNXNDZlbHdxZVF1aUNpWVY=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=VIkYfi38T54","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"VIkYfi38T54","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr5---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=5489187e2dfc4f9e\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CDwQlDUYCiITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CDwQlDUYCiITCPjJv6athP0CFRCH_wQdsKgLVQ==","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CDwQlDUYCiITCPjJv6athP0CFRCH_wQdsKgLVUCen_Hv4o_GxFSqASJQTFJEN04tWnJqMkRPVmoyUHVTVzQ2ZWx3cWVRdWlDaVlW","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CEMQxzciEwj4yb-mrYT9AhUQh_8EHbCoC1UyC29mZmxpbmVsaXN0"}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"2.3 million views"}},"simpleText":"2.3M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CEIQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CEIQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"VIkYfi38T54","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CEIQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["VIkYfi38T54"],"params":"CAQ%3D"}},"videoIds":["VIkYfi38T54"]}}]}},"trackingParams":"CEIQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CDwQlDUYCiITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"VIkYfi38T54","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CDwQlDUYCiITCPjJv6athP0CFRCH_wQdsKgLVQ=="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CEEQlKwJGAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"VIkYfi38T54"}},"trackingParams":"CEEQlKwJGAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CEAQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","offlineVideoEndpoint":{"videoId":"VIkYfi38T54","onAddCommand":{"clickTrackingParams":"CEAQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","getDownloadActionCommand":{"videoId":"VIkYfi38T54","params":"CAI%3D"}}}},"trackingParams":"CEAQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CDwQlDUYCiITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtWSWtZZmkzOFQ1NA%3D%3D","commands":[{"clickTrackingParams":"CDwQlDUYCiITCPjJv6athP0CFRCH_wQdsKgLVQ==","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CD8QjmIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CDwQlDUYCiITCPjJv6athP0CFRCH_wQdsKgLVQ==","hasSeparator":true}}],"trackingParams":"CDwQlDUYCiITCPjJv6athP0CFRCH_wQdsKgLVQ==","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"9 minutes, 39 seconds"}},"simpleText":"9:39"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CD4Q-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"VIkYfi38T54","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CD4Q-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"VIkYfi38T54"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CD4Q-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CD0Qx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CD0Qx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"VIkYfi38T54","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CD0Qx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["VIkYfi38T54"],"params":"CAQ%3D"}},"videoIds":["VIkYfi38T54"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CD0Qx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/VIkYfi38T54/mqdefault_6s.webp?du=3000\u0026sqp=CIrDip8G\u0026rs=AOn4CLAyPXtubeexvvXJLg2dLgrDfwVw6w","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}},{"gridVideoRenderer":{"videoId":"R46eiHZnouk","thumbnail":{"thumbnails":[{"url":"https://i.ytimg.com/vi/R46eiHZnouk/hqdefault.jpg?sqp=-oaymwEbCKgBEF5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLAhyPupqaLa6Wpy-s7KcHHeQPhKJA","width":168,"height":94},{"url":"https://i.ytimg.com/vi/R46eiHZnouk/hqdefault.jpg?sqp=-oaymwEbCMQBEG5IVfKriqkDDggBFQAAiEIYAXABwAEG\u0026rs=AOn4CLDCnv1v_ujwlLwPx0x-W0Taz0p2zA","width":196,"height":110},{"url":"https://i.ytimg.com/vi/R46eiHZnouk/hqdefault.jpg?sqp=-oaymwEcCPYBEIoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLChaICzfXzw_R1o9CmdxzXf6lO0KA","width":246,"height":138},{"url":"https://i.ytimg.com/vi/R46eiHZnouk/hqdefault.jpg?sqp=-oaymwEcCNACELwBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==\u0026rs=AOn4CLAvLg939XdHzSW_ObmvLbItvk8IWw","width":336,"height":188}]},"title":{"accessibility":{"accessibilityData":{"label":"I Helped A Man Get Laid In Among Us by penguinz0 2 years ago 10 minutes, 23 seconds 1,861,654 views"}},"simpleText":"I Helped A Man Get Laid In Among Us"},"publishedTimeText":{"simpleText":"2 years ago"},"viewCountText":{"simpleText":"1,861,654 views"},"navigationEndpoint":{"clickTrackingParams":"CDQQlDUYCyITCPjJv6athP0CFRCH_wQdsKgLVTIGZy1oaWdoWhhVQ3E2VkZId016Y01YYnVLeUc3U1FZSWeaAQUQ8jgYZKoBIlBMUkQ3Ti1acmoyRE9WajJQdVNXNDZlbHdxZVF1aUNpWVY=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=R46eiHZnouk","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"R46eiHZnouk","watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr5---sn-cxaaj5o5q5-tt1es.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=478e9e887667a2e9\u0026ip=74.12.195.102\u0026initcwndbps=1656250\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"shortBylineText":{"runs":[{"text":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CDQQlDUYCyITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}}}]},"ownerBadges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CDQQlDUYCyITCPjJv6athP0CFRCH_wQdsKgLVQ==","accessibilityData":{"label":"Verified"}}}],"trackingParams":"CDQQlDUYCyITCPjJv6athP0CFRCH_wQdsKgLVUDpxZ6zh9Gnx0eqASJQTFJEN04tWnJqMkRPVmoyUHVTVzQ2ZWx3cWVRdWlDaVlW","offlineability":{"offlineabilityRenderer":{"offlineable":true,"formats":[{"name":{"runs":[{"text":"Full HD (1080p)"}]},"formatType":"HD_1080"},{"name":{"runs":[{"text":"High (720p)"}]},"formatType":"HD"},{"name":{"runs":[{"text":"Medium (360p)"}]},"formatType":"SD"},{"name":{"runs":[{"text":"Low (144p)"}]},"formatType":"LD"}],"clickTrackingParams":"CDsQxzciEwj4yb-mrYT9AhUQh_8EHbCoC1UyC29mZmxpbmVsaXN0"}},"shortViewCountText":{"accessibility":{"accessibilityData":{"label":"1.8 million views"}},"simpleText":"1.8M views"},"menu":{"menuRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Add to queue"}]},"icon":{"iconType":"ADD_TO_QUEUE_TAIL"},"serviceEndpoint":{"clickTrackingParams":"CDoQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CDoQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"R46eiHZnouk","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CDoQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["R46eiHZnouk"],"params":"CAQ%3D"}},"videoIds":["R46eiHZnouk"]}}]}},"trackingParams":"CDoQ_pgEGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to Watch later"}]},"icon":{"iconType":"WATCH_LATER"},"serviceEndpoint":{"clickTrackingParams":"CDQQlDUYCyITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"R46eiHZnouk","action":"ACTION_ADD_VIDEO"}]}},"trackingParams":"CDQQlDUYCyITCPjJv6athP0CFRCH_wQdsKgLVQ=="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Save to playlist"}]},"icon":{"iconType":"PLAYLIST_ADD"},"serviceEndpoint":{"clickTrackingParams":"CDkQlKwJGAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/get_add_to_playlist"}},"addToPlaylistServiceEndpoint":{"videoId":"R46eiHZnouk"}},"trackingParams":"CDkQlKwJGAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemDownloadRenderer":{"serviceEndpoint":{"clickTrackingParams":"CDgQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","offlineVideoEndpoint":{"videoId":"R46eiHZnouk","onAddCommand":{"clickTrackingParams":"CDgQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","getDownloadActionCommand":{"videoId":"R46eiHZnouk","params":"CAI%3D"}}}},"trackingParams":"CDgQ0aoFGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Share"}]},"icon":{"iconType":"SHARE"},"serviceEndpoint":{"clickTrackingParams":"CDQQlDUYCyITCPjJv6athP0CFRCH_wQdsKgLVQ==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/share/get_share_panel"}},"shareEntityServiceEndpoint":{"serializedShareEntity":"CgtSNDZlaUhabm91aw%3D%3D","commands":[{"clickTrackingParams":"CDQQlDUYCyITCPjJv6athP0CFRCH_wQdsKgLVQ==","openPopupAction":{"popup":{"unifiedSharePanelRenderer":{"trackingParams":"CDcQjmIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","showLoadingSpinner":true}},"popupType":"DIALOG","beReused":true}}]}},"trackingParams":"CDQQlDUYCyITCPjJv6athP0CFRCH_wQdsKgLVQ==","hasSeparator":true}}],"trackingParams":"CDQQlDUYCyITCPjJv6athP0CFRCH_wQdsKgLVQ==","accessibility":{"accessibilityData":{"label":"Action menu"}}}},"thumbnailOverlays":[{"thumbnailOverlayTimeStatusRenderer":{"text":{"accessibility":{"accessibilityData":{"label":"10 minutes, 23 seconds"}},"simpleText":"10:23"},"style":"DEFAULT"}},{"thumbnailOverlayToggleButtonRenderer":{"isToggled":false,"untoggledIcon":{"iconType":"WATCH_LATER"},"toggledIcon":{"iconType":"CHECK"},"untoggledTooltip":"Watch later","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CDYQ-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"addedVideoId":"R46eiHZnouk","action":"ACTION_ADD_VIDEO"}]}},"toggledServiceEndpoint":{"clickTrackingParams":"CDYQ-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/browse/edit_playlist"}},"playlistEditEndpoint":{"playlistId":"WL","actions":[{"action":"ACTION_REMOVE_VIDEO_BY_VIDEO_ID","removedVideoId":"R46eiHZnouk"}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Watch later"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CDYQ-ecDGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"thumbnailOverlayToggleButtonRenderer":{"untoggledIcon":{"iconType":"ADD_TO_QUEUE_TAIL"},"toggledIcon":{"iconType":"PLAYLIST_ADD_CHECK"},"untoggledTooltip":"Add to queue","toggledTooltip":"Added","untoggledServiceEndpoint":{"clickTrackingParams":"CDUQx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CDUQx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","addToPlaylistCommand":{"openMiniplayer":true,"videoId":"R46eiHZnouk","listType":"PLAYLIST_EDIT_LIST_TYPE_QUEUE","onCreateListCommand":{"clickTrackingParams":"CDUQx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/playlist/create"}},"createPlaylistServiceEndpoint":{"videoIds":["R46eiHZnouk"],"params":"CAQ%3D"}},"videoIds":["R46eiHZnouk"]}}]}},"untoggledAccessibility":{"accessibilityData":{"label":"Add to queue"}},"toggledAccessibility":{"accessibilityData":{"label":"Added"}},"trackingParams":"CDUQx-wEGAMiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"thumbnailOverlayNowPlayingRenderer":{"text":{"runs":[{"text":"Now playing"}]}}}],"richThumbnail":{"movingThumbnailRenderer":{"movingThumbnailDetails":{"thumbnails":[{"url":"https://i.ytimg.com/an_webp/R46eiHZnouk/mqdefault_6s.webp?du=3000\u0026sqp=CLvFip8G\u0026rs=AOn4CLD5rrKP1yo3et8J3N5wfZGIYWxUYA","width":320,"height":180}],"logAsMovingThumbnail":true},"enableHoveredLogging":true,"enableOverlay":true}}}}],"trackingParams":"CDEQxjkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","visibleItemCount":4,"nextButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"CHEVRON_RIGHT"},"accessibility":{"label":"Next"},"trackingParams":"CDMQ8FsiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},"previousButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"CHEVRON_LEFT"},"accessibility":{"label":"Previous"},"trackingParams":"CDIQ8FsiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}}}},"trackingParams":"CC8Q3BwYACITCPjJv6athP0CFRCH_wQdsKgLVQ==","playAllButton":{"buttonRenderer":{"style":"STYLE_TEXT","size":"SIZE_DEFAULT","isDisabled":false,"text":{"runs":[{"text":"Play all"}]},"icon":{"iconType":"PLAY_ALL"},"navigationEndpoint":{"clickTrackingParams":"CDAQ8FsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/watch?v=5Kp4obnli9A\u0026list=PLRD7N-Zrj2DOVj2PuSW46elwqeQuiCiYV","webPageType":"WEB_PAGE_TYPE_WATCH","rootVe":3832}},"watchEndpoint":{"videoId":"5Kp4obnli9A","playlistId":"PLRD7N-Zrj2DOVj2PuSW46elwqeQuiCiYV","loggingContext":{"vssLoggingContext":{"serializedContextData":"GiJQTFJEN04tWnJqMkRPVmoyUHVTVzQ2ZWx3cWVRdWlDaVlW"}},"watchEndpointSupportedOnesieConfig":{"html5PlaybackOnesieConfig":{"commonConfig":{"url":"https://rr5---sn-cxaaj5o5q5-tt1ed.googlevideo.com/initplayback?source=youtube\u0026oeis=1\u0026c=WEB\u0026oad=3200\u0026ovd=3200\u0026oaad=11000\u0026oavd=11000\u0026ocs=700\u0026oewis=1\u0026oputc=1\u0026ofpcc=1\u0026msp=1\u0026odepv=1\u0026id=e4aa78a1b9e58bd0\u0026ip=74.12.195.102\u0026initcwndbps=1693750\u0026mt=1675804896\u0026oweuc=\u0026pxtags=Cg4KAnR4EggyNDQxNjQ0MQ\u0026rxtags=Cg4KAnR4EggyNDQxNjQzNg%2CCg4KAnR4EggyNDQxNjQzNw%2CCg4KAnR4EggyNDQxNjQzOA%2CCg4KAnR4EggyNDQxNjQzOQ%2CCg4KAnR4EggyNDQxNjQ0MA%2CCg4KAnR4EggyNDQxNjQ0MQ%2CCg4KAnR4EggyNDQxNjQ0Mg"}}}}},"trackingParams":"CDAQ8FsiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}}}}],"trackingParams":"CC4Quy8YCCITCPjJv6athP0CFRCH_wQdsKgLVQ=="}}],"trackingParams":"CC0Qui8iEwj4yb-mrYT9AhUQh_8EHbCoC1U=","targetId":"browse-feedUCq6VFHwMzcMXbuKyG7SQYIgfeatured","disablePullToRefresh":true}},"trackingParams":"CCwQ8JMBGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"tabRenderer":{"endpoint":{"clickTrackingParams":"CCsQ8JMBGAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0/videos","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","params":"EgZ2aWRlb3PyBgQKAjoA","canonicalBaseUrl":"/@penguinz0"}},"title":"Videos","trackingParams":"CCsQ8JMBGAgiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"tabRenderer":{"endpoint":{"clickTrackingParams":"CCoQ8JMBGAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0/streams","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","params":"EgdzdHJlYW1z8gYECgJ6AA%3D%3D","canonicalBaseUrl":"/@penguinz0"}},"title":"Live","trackingParams":"CCoQ8JMBGAkiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"tabRenderer":{"endpoint":{"clickTrackingParams":"CCkQ8JMBGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0/playlists","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","params":"EglwbGF5bGlzdHPyBgQKAkIA","canonicalBaseUrl":"/@penguinz0"}},"title":"Playlists","trackingParams":"CCkQ8JMBGAoiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"tabRenderer":{"endpoint":{"clickTrackingParams":"CCgQ8JMBGAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0/community","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","params":"Egljb21tdW5pdHnyBgQKAkoA","canonicalBaseUrl":"/@penguinz0"}},"title":"Community","trackingParams":"CCgQ8JMBGAsiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"tabRenderer":{"endpoint":{"clickTrackingParams":"CCcQ8JMBGAwiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0/channels","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","params":"EghjaGFubmVsc_IGBAoCUgA%3D","canonicalBaseUrl":"/@penguinz0"}},"title":"Channels","trackingParams":"CCcQ8JMBGAwiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"tabRenderer":{"endpoint":{"clickTrackingParams":"CCYQ8JMBGA0iEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0/about","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","params":"EgVhYm91dPIGBAoCEgA%3D","canonicalBaseUrl":"/@penguinz0"}},"title":"About","trackingParams":"CCYQ8JMBGA0iEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},{"expandableTabRenderer":{"endpoint":{"clickTrackingParams":"CAAQhGciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0/search","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","params":"EgZzZWFyY2jyBgQKAloA","canonicalBaseUrl":"/@penguinz0"}},"title":"Search","selected":false}}]}},"header":{"c4TabbedHeaderRenderer":{"channelId":"UCq6VFHwMzcMXbuKyG7SQYIg","title":"penguinz0","navigationEndpoint":{"clickTrackingParams":"CBYQ8DsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","canonicalBaseUrl":"/@penguinz0"}},"avatar":{"thumbnails":[{"url":"https://yt3.googleusercontent.com/ytc/AL5GRJWOhJOuUC6C2b7gP-5D2q6ypXbcOOckyAE1En4RUQ=s48-c-k-c0x00ffffff-no-rj","width":48,"height":48},{"url":"https://yt3.googleusercontent.com/ytc/AL5GRJWOhJOuUC6C2b7gP-5D2q6ypXbcOOckyAE1En4RUQ=s88-c-k-c0x00ffffff-no-rj","width":88,"height":88},{"url":"https://yt3.googleusercontent.com/ytc/AL5GRJWOhJOuUC6C2b7gP-5D2q6ypXbcOOckyAE1En4RUQ=s176-c-k-c0x00ffffff-no-rj","width":176,"height":176}]},"banner":{"thumbnails":[{"url":"https://yt3.googleusercontent.com/xdDjxTYkAK7yHew1lRZAdilfQQjQD5W67BeqtUzVVb_48RLJcFF3rQlpRlZG_7J6eXjnRJ4A=w1060-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj","width":1060,"height":175},{"url":"https://yt3.googleusercontent.com/xdDjxTYkAK7yHew1lRZAdilfQQjQD5W67BeqtUzVVb_48RLJcFF3rQlpRlZG_7J6eXjnRJ4A=w1138-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj","width":1138,"height":188},{"url":"https://yt3.googleusercontent.com/xdDjxTYkAK7yHew1lRZAdilfQQjQD5W67BeqtUzVVb_48RLJcFF3rQlpRlZG_7J6eXjnRJ4A=w1707-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj","width":1707,"height":283},{"url":"https://yt3.googleusercontent.com/xdDjxTYkAK7yHew1lRZAdilfQQjQD5W67BeqtUzVVb_48RLJcFF3rQlpRlZG_7J6eXjnRJ4A=w2120-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj","width":2120,"height":351},{"url":"https://yt3.googleusercontent.com/xdDjxTYkAK7yHew1lRZAdilfQQjQD5W67BeqtUzVVb_48RLJcFF3rQlpRlZG_7J6eXjnRJ4A=w2276-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj","width":2276,"height":377},{"url":"https://yt3.googleusercontent.com/xdDjxTYkAK7yHew1lRZAdilfQQjQD5W67BeqtUzVVb_48RLJcFF3rQlpRlZG_7J6eXjnRJ4A=w2560-fcrop64=1,00005a57ffffa5a8-k-c0xffffffff-no-nd-rj","width":2560,"height":424}]},"badges":[{"metadataBadgeRenderer":{"icon":{"iconType":"CHECK_CIRCLE_THICK"},"style":"BADGE_STYLE_TYPE_VERIFIED","tooltip":"Verified","trackingParams":"CBYQ8DsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"label":"Verified"}}}],"headerLinks":{"channelHeaderLinksRenderer":{"primaryLinks":[{"navigationEndpoint":{"clickTrackingParams":"CBYQ8DsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"https://www.youtube.com/redirect?event=channel_banner\u0026redir_token=QUFFLUhqbVpxczhZakFRYkVkOEFVRkdVOGwxeDhtVjJuUXxBQ3Jtc0tsZUlpMVVEUE1uQ2lScHJmNDV4ZjJqcllkMnN2YjJGT3dpTV9tSzNfbE53aWNEVjJ4SE5nd0ZNaGlFQnNNWDUxcXBRWkJaUGRQQnpnNTlJRXNKV3Q1T1JQLThlb0NVakJGMElaZVZ4Z3lYWENNN21LOA\u0026q=https%3A%2F%2Fwww.twitch.tv%2Fmoistcr1tikal","webPageType":"WEB_PAGE_TYPE_UNKNOWN","rootVe":83769}},"urlEndpoint":{"url":"https://www.youtube.com/redirect?event=channel_banner\u0026redir_token=QUFFLUhqbVpxczhZakFRYkVkOEFVRkdVOGwxeDhtVjJuUXxBQ3Jtc0tsZUlpMVVEUE1uQ2lScHJmNDV4ZjJqcllkMnN2YjJGT3dpTV9tSzNfbE53aWNEVjJ4SE5nd0ZNaGlFQnNNWDUxcXBRWkJaUGRQQnpnNTlJRXNKV3Q1T1JQLThlb0NVakJGMElaZVZ4Z3lYWENNN21LOA\u0026q=https%3A%2F%2Fwww.twitch.tv%2Fmoistcr1tikal","target":"TARGET_NEW_WINDOW","nofollow":true}},"icon":{"thumbnails":[{"url":"https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcRzCd7DjdKtgt5cyRzTrrTcYAgmlk-Og3EXAnC5WZZEuPuRNT4gNc6bLQgP9oRHywCV-5Oosa3EwFTFBqYMWllwuSMuLWaAJMza2sl--w2xkNQo"}]},"title":{"simpleText":"Twitch"}}],"secondaryLinks":[{"navigationEndpoint":{"clickTrackingParams":"CBYQ8DsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"https://www.youtube.com/redirect?event=channel_banner\u0026redir_token=QUFFLUhqbXNEcnJnVGVacm51WWdSRW02eW5xQzNId2ZJd3xBQ3Jtc0tsWGdQLWdwbEJJOTh0YVRnNGxNNTZPVDVpVTNrMkJaYml2NkRRNS1kOFdpU2NkRDBqS1AwR2JjanQtdFBscEZ3SnpHWmN0VWhmTlltY2xPSVRvM0tnTFFyNkU1eUNxSE9rOFlQME1Qb3gyd2RzRlBhaw\u0026q=https%3A%2F%2Ftwitter.com%2FMoistCr1TiKaL","webPageType":"WEB_PAGE_TYPE_UNKNOWN","rootVe":83769}},"urlEndpoint":{"url":"https://www.youtube.com/redirect?event=channel_banner\u0026redir_token=QUFFLUhqbXNEcnJnVGVacm51WWdSRW02eW5xQzNId2ZJd3xBQ3Jtc0tsWGdQLWdwbEJJOTh0YVRnNGxNNTZPVDVpVTNrMkJaYml2NkRRNS1kOFdpU2NkRDBqS1AwR2JjanQtdFBscEZ3SnpHWmN0VWhmTlltY2xPSVRvM0tnTFFyNkU1eUNxSE9rOFlQME1Qb3gyd2RzRlBhaw\u0026q=https%3A%2F%2Ftwitter.com%2FMoistCr1TiKaL","target":"TARGET_NEW_WINDOW","nofollow":true}},"icon":{"thumbnails":[{"url":"https://encrypted-tbn0.gstatic.com/favicon-tbn?q=tbn:ANd9GcR3iqklaOtk_2Tks6Fp78jzdlSWb2dc3v92FHhyc99Yz7tDHOkg62CoNEO1Mden-xjYCq7TQLjXfILWh8tjYFDXosrGXktdMY1GIadRgIMCdg"}]},"title":{"simpleText":"Twitter"}},{"navigationEndpoint":{"clickTrackingParams":"CBYQ8DsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"https://www.youtube.com/redirect?event=channel_banner\u0026redir_token=QUFFLUhqbTFCWmI2UHlrcU9XcHhENmVOaDJZbnVmbjJwZ3xBQ3Jtc0tsWHRWR2hkUTQ1Rzk1eXEwQ2ZfeUFPRWxPaGpJZ01aRU1DbDFtSDRXNjRjRm42RVA3S2ViYnVOQXhRSHZld3oyYWVvMGJBN3dTQjBidk90b1dZdU9xMmFUSHJtNVVzS3F1XzdJdTJkMm93a1NLSEhqNA\u0026q=https%3A%2F%2Fwww.instagram.com%2Fbigmoistcr1tikal%2F%3Fhl%3Den","webPageType":"WEB_PAGE_TYPE_UNKNOWN","rootVe":83769}},"urlEndpoint":{"url":"https://www.youtube.com/redirect?event=channel_banner\u0026redir_token=QUFFLUhqbTFCWmI2UHlrcU9XcHhENmVOaDJZbnVmbjJwZ3xBQ3Jtc0tsWHRWR2hkUTQ1Rzk1eXEwQ2ZfeUFPRWxPaGpJZ01aRU1DbDFtSDRXNjRjRm42RVA3S2ViYnVOQXhRSHZld3oyYWVvMGJBN3dTQjBidk90b1dZdU9xMmFUSHJtNVVzS3F1XzdJdTJkMm93a1NLSEhqNA\u0026q=https%3A%2F%2Fwww.instagram.com%2Fbigmoistcr1tikal%2F%3Fhl%3Den","target":"TARGET_NEW_WINDOW","nofollow":true}},"icon":{"thumbnails":[{"url":"https://encrypted-tbn3.gstatic.com/favicon-tbn?q=tbn:ANd9GcRfYQ4UPLA7AtItHycwuYVII6FrTKnGAJQDzjpPy0P1oY2HKJF_cYMJ_wjxTX_6xAJW6b18QHN2JGUSyDUyOkwHbE_qkNpRbxdNTJteROXvtHE7UC8_mg"}]},"title":{"simpleText":"Instagram"}},{"navigationEndpoint":{"clickTrackingParams":"CBYQ8DsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"https://www.youtube.com/redirect?event=channel_banner\u0026redir_token=QUFFLUhqbkplU0Q5TmtKTzZUWHVEN0RjUzR6TEJsNUJxZ3xBQ3Jtc0trVkJUVHlSMzkzVEdxTW5RUjVZa2NPN2hXLVlfa0I0eW1oV05vRDVmS1NoR01ENUFaZFhBY01pLXBaU25EelVmWUZIR1NLc2oyNE1RVlZuaExPSnBaNFZmOEJjdnhjWFBXVnZUak9aMG5XdU9uZ2FpUQ\u0026q=https%3A%2F%2Fmoistglobal.com%2F","webPageType":"WEB_PAGE_TYPE_UNKNOWN","rootVe":83769}},"urlEndpoint":{"url":"https://www.youtube.com/redirect?event=channel_banner\u0026redir_token=QUFFLUhqbkplU0Q5TmtKTzZUWHVEN0RjUzR6TEJsNUJxZ3xBQ3Jtc0trVkJUVHlSMzkzVEdxTW5RUjVZa2NPN2hXLVlfa0I0eW1oV05vRDVmS1NoR01ENUFaZFhBY01pLXBaU25EelVmWUZIR1NLc2oyNE1RVlZuaExPSnBaNFZmOEJjdnhjWFBXVnZUak9aMG5XdU9uZ2FpUQ\u0026q=https%3A%2F%2Fmoistglobal.com%2F","target":"TARGET_NEW_WINDOW","nofollow":true}},"icon":{"thumbnails":[{"url":"https://encrypted-tbn0.gstatic.com/favicon-tbn?q=tbn:ANd9GcRS4lbEeovJCVMIr-_8_1DXWXeKn81_9xhn76BmT5QZir-6PCxlioOBdAMsyKpW3UUWUewISEV4ibLXanaCijfZ8vrQmIN5Br0ywtsruzTb5Jw9raw"}]},"title":{"simpleText":"Merch "}}]}},"subscribeButton":{"subscribeButtonRenderer":{"buttonText":{"runs":[{"text":"Subscribed"}]},"subscribed":true,"enabled":true,"type":"FREE","channelId":"UCq6VFHwMzcMXbuKyG7SQYIg","showPreferences":true,"subscribedButtonText":{"runs":[{"text":"Subscribed"}]},"unsubscribedButtonText":{"runs":[{"text":"Subscribe"}]},"trackingParams":"CBcQmysiEwj4yb-mrYT9AhUQh_8EHbCoC1UyCWNoYW5uZWxzNA==","unsubscribeButtonText":{"runs":[{"text":"Unsubscribe"}]},"subscribeAccessibility":{"accessibilityData":{"label":"Subscribe to penguinz0."}},"unsubscribeAccessibility":{"accessibilityData":{"label":"Unsubscribe from penguinz0."}},"notificationPreferenceButton":{"subscriptionNotificationToggleButtonRenderer":{"states":[{"stateId":2,"nextStateId":2,"state":{"buttonRenderer":{"style":"STYLE_TEXT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"NOTIFICATIONS_ACTIVE"},"accessibility":{"label":"Current setting is all notifications. Tap to change your notification setting for penguinz0"},"trackingParams":"CCUQ8FsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"accessibilityData":{"label":"Current setting is all notifications. Tap to change your notification setting for penguinz0"}}}}},{"stateId":3,"nextStateId":3,"state":{"buttonRenderer":{"style":"STYLE_TEXT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"NOTIFICATIONS_NONE"},"accessibility":{"label":"Current setting is personalized notifications. Tap to change your notification setting for penguinz0"},"trackingParams":"CCQQ8FsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"accessibilityData":{"label":"Current setting is personalized notifications. Tap to change your notification setting for penguinz0"}}}}},{"stateId":0,"nextStateId":0,"state":{"buttonRenderer":{"style":"STYLE_TEXT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"NOTIFICATIONS_OFF"},"accessibility":{"label":"Current setting is receive no notifications. Tap to change your notification setting for penguinz0"},"trackingParams":"CCMQ8FsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"accessibilityData":{"label":"Current setting is receive no notifications. Tap to change your notification setting for penguinz0"}}}}}],"currentStateId":3,"trackingParams":"CBsQl_kBIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","command":{"clickTrackingParams":"CBsQl_kBIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandExecutorCommand":{"commands":[{"clickTrackingParams":"CBsQl_kBIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","openPopupAction":{"popup":{"menuPopupRenderer":{"items":[{"menuServiceItemRenderer":{"text":{"simpleText":"All"},"icon":{"iconType":"NOTIFICATIONS_ACTIVE"},"serviceEndpoint":{"clickTrackingParams":"CCIQ67UEGAQiEwj4yb-mrYT9AhUQh_8EHbCoC1UyHFBSRUZFUkVOQ0VfQUxMX05PVElGSUNBVElPTlM=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/notification/modify_channel_preference"}},"modifyChannelNotificationPreferenceEndpoint":{"params":"ChhVQ3E2VkZId016Y01YYnVLeUc3U1FZSWcSAggCGAAgBFIICgIIAhIAGAA%3D"}},"trackingParams":"CCIQ67UEGAQiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","isSelected":false}},{"menuServiceItemRenderer":{"text":{"simpleText":"Personalized"},"icon":{"iconType":"NOTIFICATIONS_NONE"},"serviceEndpoint":{"clickTrackingParams":"CCEQ7LUEGAUiEwj4yb-mrYT9AhUQh_8EHbCoC1UyElBSRUZFUkVOQ0VfREVGQVVMVA==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/notification/modify_channel_preference"}},"modifyChannelNotificationPreferenceEndpoint":{"params":"ChhVQ3E2VkZId016Y01YYnVLeUc3U1FZSWcSAggBGAAgBFIICgIIAhIAGAA%3D"}},"trackingParams":"CCEQ7LUEGAUiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","isSelected":true}},{"menuServiceItemRenderer":{"text":{"simpleText":"None"},"icon":{"iconType":"NOTIFICATIONS_OFF"},"serviceEndpoint":{"clickTrackingParams":"CCAQ7bUEGAYiEwj4yb-mrYT9AhUQh_8EHbCoC1UyG1BSRUZFUkVOQ0VfTk9fTk9USUZJQ0FUSU9OUw==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/notification/modify_channel_preference"}},"modifyChannelNotificationPreferenceEndpoint":{"params":"ChhVQ3E2VkZId016Y01YYnVLeUc3U1FZSWcSAggDGAAgBFIICgIIAhIAGAA%3D"}},"trackingParams":"CCAQ7bUEGAYiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","isSelected":false}},{"menuServiceItemRenderer":{"text":{"runs":[{"text":"Unsubscribe"}]},"icon":{"iconType":"PERSON_MINUS"},"serviceEndpoint":{"clickTrackingParams":"CBwQ24sKGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CBwQ24sKGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"confirmDialogRenderer":{"trackingParams":"CB0QxjgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","dialogMessages":[{"runs":[{"text":"Unsubscribe from "},{"text":"penguinz0"},{"text":"?"}]}],"confirmButton":{"buttonRenderer":{"style":"STYLE_BLUE_TEXT","size":"SIZE_DEFAULT","isDisabled":false,"text":{"runs":[{"text":"Unsubscribe"}]},"serviceEndpoint":{"clickTrackingParams":"CB8Q8FsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/subscription/unsubscribe"}},"unsubscribeEndpoint":{"channelIds":["UCq6VFHwMzcMXbuKyG7SQYIg"],"params":"CgIIAhgA"}},"accessibility":{"label":"Unsubscribe"},"trackingParams":"CB8Q8FsiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},"cancelButton":{"buttonRenderer":{"style":"STYLE_TEXT","size":"SIZE_DEFAULT","isDisabled":false,"text":{"runs":[{"text":"Cancel"}]},"accessibility":{"label":"Cancel"},"trackingParams":"CB4Q8FsiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},"primaryIsCancel":false}},"popupType":"DIALOG"}}]}},"trackingParams":"CBwQ24sKGAciEwj4yb-mrYT9AhUQh_8EHbCoC1U="}}]}},"popupType":"DROPDOWN"}}]}},"targetId":"notification-bell","secondaryIcon":{"iconType":"EXPAND_MORE"}}},"subscribedEntityKey":"EhhVQ3E2VkZId016Y01YYnVLeUc3U1FZSWcgMygB","onSubscribeEndpoints":[{"clickTrackingParams":"CBcQmysiEwj4yb-mrYT9AhUQh_8EHbCoC1UyCWNoYW5uZWxzNA==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/subscription/subscribe"}},"subscribeEndpoint":{"channelIds":["UCq6VFHwMzcMXbuKyG7SQYIg"],"params":"EgIIAhgA"}}],"onUnsubscribeEndpoints":[{"clickTrackingParams":"CBcQmysiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CBcQmysiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"confirmDialogRenderer":{"trackingParams":"CBgQxjgiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","dialogMessages":[{"runs":[{"text":"Unsubscribe from "},{"text":"penguinz0"},{"text":"?"}]}],"confirmButton":{"buttonRenderer":{"style":"STYLE_BLUE_TEXT","size":"SIZE_DEFAULT","isDisabled":false,"text":{"runs":[{"text":"Unsubscribe"}]},"serviceEndpoint":{"clickTrackingParams":"CBoQ8FsiEwj4yb-mrYT9AhUQh_8EHbCoC1UyCWNoYW5uZWxzNA==","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/subscription/unsubscribe"}},"unsubscribeEndpoint":{"channelIds":["UCq6VFHwMzcMXbuKyG7SQYIg"],"params":"CgIIAhgA"}},"accessibility":{"label":"Unsubscribe"},"trackingParams":"CBoQ8FsiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},"cancelButton":{"buttonRenderer":{"style":"STYLE_TEXT","size":"SIZE_DEFAULT","isDisabled":false,"text":{"runs":[{"text":"Cancel"}]},"accessibility":{"label":"Cancel"},"trackingParams":"CBkQ8FsiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},"primaryIsCancel":false}},"popupType":"DIALOG"}}]}}]}},"subscriberCountText":{"accessibility":{"accessibilityData":{"label":"12.2 million subscribers"}},"simpleText":"12.2M subscribers"},"tvBanner":{"thumbnails":[{"url":"https://yt3.googleusercontent.com/xdDjxTYkAK7yHew1lRZAdilfQQjQD5W67BeqtUzVVb_48RLJcFF3rQlpRlZG_7J6eXjnRJ4A=w320-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj","width":320,"height":180},{"url":"https://yt3.googleusercontent.com/xdDjxTYkAK7yHew1lRZAdilfQQjQD5W67BeqtUzVVb_48RLJcFF3rQlpRlZG_7J6eXjnRJ4A=w854-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj","width":854,"height":480},{"url":"https://yt3.googleusercontent.com/xdDjxTYkAK7yHew1lRZAdilfQQjQD5W67BeqtUzVVb_48RLJcFF3rQlpRlZG_7J6eXjnRJ4A=w1280-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj","width":1280,"height":720},{"url":"https://yt3.googleusercontent.com/xdDjxTYkAK7yHew1lRZAdilfQQjQD5W67BeqtUzVVb_48RLJcFF3rQlpRlZG_7J6eXjnRJ4A=w1920-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj","width":1920,"height":1080},{"url":"https://yt3.googleusercontent.com/xdDjxTYkAK7yHew1lRZAdilfQQjQD5W67BeqtUzVVb_48RLJcFF3rQlpRlZG_7J6eXjnRJ4A=w2120-fcrop64=1,00000000ffffffff-k-c0xffffffff-no-nd-rj","width":2120,"height":1192}]},"mobileBanner":{"thumbnails":[{"url":"https://yt3.googleusercontent.com/xdDjxTYkAK7yHew1lRZAdilfQQjQD5W67BeqtUzVVb_48RLJcFF3rQlpRlZG_7J6eXjnRJ4A=w320-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj","width":320,"height":88},{"url":"https://yt3.googleusercontent.com/xdDjxTYkAK7yHew1lRZAdilfQQjQD5W67BeqtUzVVb_48RLJcFF3rQlpRlZG_7J6eXjnRJ4A=w640-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj","width":640,"height":175},{"url":"https://yt3.googleusercontent.com/xdDjxTYkAK7yHew1lRZAdilfQQjQD5W67BeqtUzVVb_48RLJcFF3rQlpRlZG_7J6eXjnRJ4A=w960-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj","width":960,"height":263},{"url":"https://yt3.googleusercontent.com/xdDjxTYkAK7yHew1lRZAdilfQQjQD5W67BeqtUzVVb_48RLJcFF3rQlpRlZG_7J6eXjnRJ4A=w1280-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj","width":1280,"height":351},{"url":"https://yt3.googleusercontent.com/xdDjxTYkAK7yHew1lRZAdilfQQjQD5W67BeqtUzVVb_48RLJcFF3rQlpRlZG_7J6eXjnRJ4A=w1440-fcrop64=1,32b75a57cd48a5a8-k-c0xffffffff-no-nd-rj","width":1440,"height":395}]},"trackingParams":"CBYQ8DsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","channelHandleText":{"runs":[{"text":"@penguinz0"}]},"videosCountText":{"runs":[{"text":"4.3K"},{"text":" videos"}]}}},"metadata":{"channelMetadataRenderer":{"title":"penguinz0","description":"Clips channel: https://www.youtube.com/channel/UC4EQHfzIbkL_Skit_iKt1aA\n\nTwitter: https://twitter.com/MoistCr1TiKaL\n\nInstagram: https://www.instagram.com/bigmoistcr1tikal/?hl=en\n\nTwitch: https://www.twitch.tv/moistcr1tikal\n\nSnapchat: Hugecharles\n\nTik Tok: Hugecharles\n\nI don't have any other public accounts.","rssUrl":"https://www.youtube.com/feeds/videos.xml?channel_id=UCq6VFHwMzcMXbuKyG7SQYIg","externalId":"UCq6VFHwMzcMXbuKyG7SQYIg","doubleclickTrackingUsername":"penguinz0","keywords":"Cr1TiKaL Gears of War Call Duty Battlefield Bad Company Fun Tactics","ownerUrls":["http://www.youtube.com/@penguinz0"],"avatar":{"thumbnails":[{"url":"https://yt3.googleusercontent.com/ytc/AL5GRJWOhJOuUC6C2b7gP-5D2q6ypXbcOOckyAE1En4RUQ=s900-c-k-c0x00ffffff-no-rj","width":900,"height":900}]},"channelUrl":"https://www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg","isFamilySafe":true,"availableCountryCodes":["UA","BY","YE","LS","MG","PN","DE","TF","GM","CI","MH","ME","EH","PR","MC","VE","FJ","KH","VU","VA","ZA","PF","SE","CN","CC","NP","TO","FM","KG","RE","GP","GD","KZ","AF","EC","LU","RU","FK","SC","IL","MK","SB","BJ","IO","MU","GH","PK","CZ","TM","DO","SI","GE","GY","ID","BG","IE","KP","ML","NR","NU","PH","UG","BB","LC","BZ","SJ","GA","GT","AG","ES","EE","CA","CG","TC","GN","KR","VI","GL","SS","HM","TV","LV","BV","AZ","BT","RS","GB","MA","GG","MN","FI","CR","DZ","TJ","PL","AL","GF","GQ","MF","AS","NE","NL","UY","SK","TT","MX","IT","SR","AI","ET","CU","HU","MO","ST","TK","NZ","LT","ER","TD","TW","LB","ZM","CM","KY","LR","AO","PY","BM","MV","SA","NF","NO","SH","IR","AQ","WF","NA","HK","LY","IN","CY","KE","DM","MS","MT","KM","OM","TN","BS","MD","GI","MY","GS","PW","LA","WS","TL","AE","JP","SL","SO","BH","SG","JO","CH","AR","AU","BQ","HR","TG","JM","PE","BR","TR","SX","BO","LI","HT","DK","RW","UZ","PG","PS","NG","SV","MR","RO","IM","NC","HN","JE","IQ","AX","BF","TZ","MZ","AT","BE","GR","SD","AW","CF","CV","SN","DJ","PA","AM","BL","MP","ZW","MM","EG","CO","FR","BD","SZ","BN","CL","GU","BA","MW","YT","SY","CK","LK","QA","NI","CW","US","GW","KW","IS","BI","VN","AD","CD","KN","VG","BW","KI","TH","VC","SM","MQ","UM","CX","PT","PM","FO"],"androidDeepLink":"android-app://com.google.android.youtube/http/www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg","androidAppindexingLink":"android-app://com.google.android.youtube/http/www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg","iosAppindexingLink":"ios-app://544007664/vnd.youtube/www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg","vanityChannelUrl":"http://www.youtube.com/@penguinz0"}},"trackingParams":"CAAQhGciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","topbar":{"desktopTopbarRenderer":{"logo":{"topbarLogoRenderer":{"iconImage":{"iconType":"YOUTUBE_PREMIUM_LOGO"},"tooltipText":{"runs":[{"text":"YouTube Home"}]},"endpoint":{"clickTrackingParams":"CBUQsV4iEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/","webPageType":"WEB_PAGE_TYPE_BROWSE","rootVe":3854,"apiUrl":"/youtubei/v1/browse"}},"browseEndpoint":{"browseId":"FEwhat_to_watch"}},"trackingParams":"CBUQsV4iEwj4yb-mrYT9AhUQh_8EHbCoC1U=","overrideEntityKey":"EgZ0b3BiYXIg9QEoAQ%3D%3D"}},"searchbox":{"fusionSearchboxRenderer":{"icon":{"iconType":"SEARCH"},"placeholderText":{"runs":[{"text":"Search"}]},"config":{"webSearchboxConfig":{"requestLanguage":"en","requestDomain":"ca","hasOnscreenKeyboard":false,"focusSearchbox":true}},"trackingParams":"CBMQ7VAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","searchEndpoint":{"clickTrackingParams":"CBMQ7VAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/results?search_query=","webPageType":"WEB_PAGE_TYPE_SEARCH","rootVe":4724}},"searchEndpoint":{"query":""}},"clearButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"CLOSE"},"trackingParams":"CBQQ8FsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibilityData":{"accessibilityData":{"label":"Clear search query"}}}}}},"trackingParams":"CAEQq6wBIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","countryCode":"CA","topbarButtons":[{"topbarMenuButtonRenderer":{"icon":{"iconType":"VIDEO_CALL"},"menuRenderer":{"multiPageMenuRenderer":{"sections":[{"multiPageMenuSectionRenderer":{"items":[{"compactLinkRenderer":{"icon":{"iconType":"CREATION_UPLOAD"},"title":{"runs":[{"text":"Upload video"}]},"navigationEndpoint":{"clickTrackingParams":"CBIQ898CGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"/upload","webPageType":"WEB_PAGE_TYPE_UNKNOWN","rootVe":83769}},"uploadEndpoint":{"hack":true}},"trackingParams":"CBIQ898CGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","style":"COMPACT_LINK_STYLE_TYPE_CREATION_MENU"}},{"compactLinkRenderer":{"icon":{"iconType":"CREATION_LIVE"},"title":{"runs":[{"text":"Go live"}]},"navigationEndpoint":{"clickTrackingParams":"CBEQ9N8CGAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"url":"https://studio.youtube.com/channel/UC/livestreaming","webPageType":"WEB_PAGE_TYPE_UNKNOWN","rootVe":83769}},"signalNavigationEndpoint":{"signal":"LIVE_CONTROL_ROOM"}},"trackingParams":"CBEQ9N8CGAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","style":"COMPACT_LINK_STYLE_TYPE_CREATION_MENU"}}],"trackingParams":"CBAQ968BGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}}],"trackingParams":"CA8Q_6sBIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","style":"MULTI_PAGE_MENU_STYLE_TYPE_CREATION"}},"trackingParams":"CA4Q_qsBGAAiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Create"}},"tooltip":"Create","style":"STYLE_DEFAULT"}},{"notificationTopbarButtonRenderer":{"icon":{"iconType":"NOTIFICATIONS"},"menuRequest":{"clickTrackingParams":"CAwQovoBGAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/notification/get_notification_menu"}},"signalServiceEndpoint":{"signal":"GET_NOTIFICATIONS_MENU","actions":[{"clickTrackingParams":"CAwQovoBGAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"multiPageMenuRenderer":{"trackingParams":"CA0Q_6sBIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","style":"MULTI_PAGE_MENU_STYLE_TYPE_NOTIFICATIONS","showLoadingSpinner":true}},"popupType":"DROPDOWN","beReused":true}}]}},"style":"NOTIFICATION_BUTTON_STYLE_TYPE_DEFAULT","trackingParams":"CAwQovoBGAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Notifications"}},"tooltip":"Notifications","updateUnseenCountEndpoint":{"clickTrackingParams":"CAwQovoBGAEiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/notification/get_unseen_count"}},"signalServiceEndpoint":{"signal":"GET_UNSEEN_NOTIFICATION_COUNT"}},"notificationCount":0,"handlerDatas":["NOTIFICATION_ACTION_UPDATE_UNSEEN_COUNT"]}},{"topbarMenuButtonRenderer":{"avatar":{"thumbnails":[{"url":"https://yt3.googleusercontent.com/yti/AHXOFjXb9s6xiCwV3J8aT05yXIWp65fq_Dqeljvsz4NaIdc=s88-c-k-c0x00ffffff-no-rj-mo","width":88,"height":88}],"accessibility":{"accessibilityData":{"label":"Avatar image"}}},"menuRequest":{"clickTrackingParams":"CAoQ_qsBGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true,"apiUrl":"/youtubei/v1/account/account_menu"}},"signalServiceEndpoint":{"signal":"GET_ACCOUNT_MENU","actions":[{"clickTrackingParams":"CAoQ_qsBGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","openPopupAction":{"popup":{"multiPageMenuRenderer":{"trackingParams":"CAsQ_6sBIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","style":"MULTI_PAGE_MENU_STYLE_TYPE_ACCOUNT","showLoadingSpinner":true}},"popupType":"DROPDOWN","beReused":true}}]}},"trackingParams":"CAoQ_qsBGAIiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","accessibility":{"accessibilityData":{"label":"Account profile photo that opens list of alternate accounts"}},"tooltip":"Account profile photo that opens list of alternate accounts"}}],"hotkeyDialog":{"hotkeyDialogRenderer":{"title":{"runs":[{"text":"Keyboard shortcuts"}]},"sections":[{"hotkeyDialogSectionRenderer":{"title":{"runs":[{"text":"Playback"}]},"options":[{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Toggle play/pause"}]},"hotkey":"k"}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Rewind 10 seconds"}]},"hotkey":"j"}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Fast forward 10 seconds"}]},"hotkey":"l"}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Previous video"}]},"hotkey":"P (SHIFT+p)"}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Next video"}]},"hotkey":"N (SHIFT+n)"}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Previous frame (while paused)"}]},"hotkey":",","hotkeyAccessibilityLabel":{"accessibilityData":{"label":"Comma"}}}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Next frame (while paused)"}]},"hotkey":".","hotkeyAccessibilityLabel":{"accessibilityData":{"label":"Period"}}}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Decrease playback rate"}]},"hotkey":"\u003c (SHIFT+,)","hotkeyAccessibilityLabel":{"accessibilityData":{"label":"Less than or SHIFT + comma"}}}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Increase playback rate"}]},"hotkey":"\u003e (SHIFT+.)","hotkeyAccessibilityLabel":{"accessibilityData":{"label":"Greater than or SHIFT + period"}}}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Seek to specific point in the video (7 advances to 70% of duration)"}]},"hotkey":"0..9"}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Seek to previous chapter"}]},"hotkey":"OPTION + ←"}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Seek to next chapter"}]},"hotkey":"OPTION + →"}}]}},{"hotkeyDialogSectionRenderer":{"title":{"runs":[{"text":"General"}]},"options":[{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Toggle full screen"}]},"hotkey":"f"}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Toggle theater mode"}]},"hotkey":"t"}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Toggle miniplayer"}]},"hotkey":"i"}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Close miniplayer or current dialog"}]},"hotkey":"ESCAPE"}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Toggle mute"}]},"hotkey":"m"}}]}},{"hotkeyDialogSectionRenderer":{"title":{"runs":[{"text":"Subtitles and closed captions"}]},"options":[{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"If the video supports captions, toggle captions ON/OFF"}]},"hotkey":"c"}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Rotate through different text opacity levels"}]},"hotkey":"o"}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Rotate through different window opacity levels"}]},"hotkey":"w"}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Rotate through font sizes (increasing)"}]},"hotkey":"+"}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Rotate through font sizes (decreasing)"}]},"hotkey":"-","hotkeyAccessibilityLabel":{"accessibilityData":{"label":"Minus"}}}}]}},{"hotkeyDialogSectionRenderer":{"title":{"runs":[{"text":"Spherical Videos"}]},"options":[{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Pan up"}]},"hotkey":"w"}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Pan left"}]},"hotkey":"a"}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Pan down"}]},"hotkey":"s"}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Pan right"}]},"hotkey":"d"}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Zoom in"}]},"hotkey":"+ on numpad or ]","hotkeyAccessibilityLabel":{"accessibilityData":{"label":"Plus on number pad or right bracket"}}}},{"hotkeyDialogSectionOptionRenderer":{"label":{"runs":[{"text":"Zoom out"}]},"hotkey":"- on numpad or [","hotkeyAccessibilityLabel":{"accessibilityData":{"label":"Minus on number pad or left bracket"}}}}]}}],"dismissButton":{"buttonRenderer":{"style":"STYLE_BLUE_TEXT","size":"SIZE_DEFAULT","isDisabled":false,"text":{"runs":[{"text":"Dismiss"}]},"trackingParams":"CAkQ8FsiEwj4yb-mrYT9AhUQh_8EHbCoC1U="}},"trackingParams":"CAgQteYDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV"}},"backButton":{"buttonRenderer":{"trackingParams":"CAcQvIYDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","command":{"clickTrackingParams":"CAcQvIYDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CAcQvIYDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","signalAction":{"signal":"HISTORY_BACK"}}]}}}},"forwardButton":{"buttonRenderer":{"trackingParams":"CAYQvYYDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","command":{"clickTrackingParams":"CAYQvYYDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CAYQvYYDIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","signalAction":{"signal":"HISTORY_FORWARD"}}]}}}},"a11ySkipNavigationButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"text":{"runs":[{"text":"Skip navigation"}]},"trackingParams":"CAUQ8FsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","command":{"clickTrackingParams":"CAUQ8FsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CAUQ8FsiEwj4yb-mrYT9AhUQh_8EHbCoC1U=","signalAction":{"signal":"SKIP_NAVIGATION"}}]}}}},"voiceSearchButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"serviceEndpoint":{"clickTrackingParams":"CAIQ7a8FIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","commandMetadata":{"webCommandMetadata":{"sendPost":true}},"signalServiceEndpoint":{"signal":"CLIENT_SIGNAL","actions":[{"clickTrackingParams":"CAIQ7a8FIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","openPopupAction":{"popup":{"voiceSearchDialogRenderer":{"placeholderHeader":{"runs":[{"text":"Listening..."}]},"promptHeader":{"runs":[{"text":"Didn't hear that. Try again."}]},"exampleQuery1":{"runs":[{"text":"\"Play Dua Lipa\""}]},"exampleQuery2":{"runs":[{"text":"\"Show me my subscriptions\""}]},"promptMicrophoneLabel":{"runs":[{"text":"Tap microphone to try again"}]},"loadingHeader":{"runs":[{"text":"Working..."}]},"connectionErrorHeader":{"runs":[{"text":"No connection"}]},"connectionErrorMicrophoneLabel":{"runs":[{"text":"Check your connection and try again"}]},"permissionsHeader":{"runs":[{"text":"Waiting for permission"}]},"permissionsSubtext":{"runs":[{"text":"Allow microphone access to search with voice"}]},"disabledHeader":{"runs":[{"text":"Search with your voice"}]},"disabledSubtext":{"runs":[{"text":"To search by voice, go to your browser settings and allow access to microphone"}]},"microphoneButtonAriaLabel":{"runs":[{"text":"Cancel"}]},"exitButton":{"buttonRenderer":{"style":"STYLE_DEFAULT","size":"SIZE_DEFAULT","isDisabled":false,"icon":{"iconType":"CLOSE"},"trackingParams":"CAQQ0LEFIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","accessibilityData":{"accessibilityData":{"label":"Cancel"}}}},"trackingParams":"CAMQ7q8FIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","microphoneOffPromptHeader":{"runs":[{"text":"Microphone off. Try again."}]}}},"popupType":"TOP_ALIGNED_DIALOG"}}]}},"icon":{"iconType":"MICROPHONE_ON"},"tooltip":"Search with your voice","trackingParams":"CAIQ7a8FIhMI-Mm_pq2E_QIVEIf_BB2wqAtV","accessibilityData":{"accessibilityData":{"label":"Search with your voice"}}}}}},"microformat":{"microformatDataRenderer":{"urlCanonical":"https://www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg","title":"penguinz0","description":"Clips channel: https://www.youtube.com/channel/UC4EQHfzIbkL_Skit_iKt1aA Twitter: https://twitter.com/MoistCr1TiKaL Instagram: https://www.instagram.com/bigmo...","thumbnail":{"thumbnails":[{"url":"https://yt3.googleusercontent.com/ytc/AL5GRJWOhJOuUC6C2b7gP-5D2q6ypXbcOOckyAE1En4RUQ=s200-c-k-c0x00ffffff-no-rj?days_since_epoch=19395","width":200,"height":200}]},"siteName":"YouTube","appName":"YouTube","androidPackage":"com.google.android.youtube","iosAppStoreId":"544007664","iosAppArguments":"https://www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg","ogType":"yt-fb-app:channel","urlApplinksWeb":"https://www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg?feature=applinks","urlApplinksIos":"vnd.youtube://www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg?feature=applinks","urlApplinksAndroid":"vnd.youtube://www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg?feature=applinks","urlTwitterIos":"vnd.youtube://www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg?feature=twitter-deep-link","urlTwitterAndroid":"vnd.youtube://www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg?feature=twitter-deep-link","twitterCardType":"summary","twitterSiteHandle":"@YouTube","schemaDotOrgType":"http://schema.org/http://schema.org/YoutubeChannelV2","noindex":false,"unlisted":false,"familySafe":true,"tags":["Cr1TiKaL","Gears","of","War","Call","Duty","Battlefield","Bad","Company","Fun","Tactics"],"availableCountries":["UA","BY","YE","LS","MG","PN","DE","TF","GM","CI","MH","ME","EH","PR","MC","VE","FJ","KH","VU","VA","ZA","PF","SE","CN","CC","NP","TO","FM","KG","RE","GP","GD","KZ","AF","EC","LU","RU","FK","SC","IL","MK","SB","BJ","IO","MU","GH","PK","CZ","TM","DO","SI","GE","GY","ID","BG","IE","KP","ML","NR","NU","PH","UG","BB","LC","BZ","SJ","GA","GT","AG","ES","EE","CA","CG","TC","GN","KR","VI","GL","SS","HM","TV","LV","BV","AZ","BT","RS","GB","MA","GG","MN","FI","CR","DZ","TJ","PL","AL","GF","GQ","MF","AS","NE","NL","UY","SK","TT","MX","IT","SR","AI","ET","CU","HU","MO","ST","TK","NZ","LT","ER","TD","TW","LB","ZM","CM","KY","LR","AO","PY","BM","MV","SA","NF","NO","SH","IR","AQ","WF","NA","HK","LY","IN","CY","KE","DM","MS","MT","KM","OM","TN","BS","MD","GI","MY","GS","PW","LA","WS","TL","AE","JP","SL","SO","BH","SG","JO","CH","AR","AU","BQ","HR","TG","JM","PE","BR","TR","SX","BO","LI","HT","DK","RW","UZ","PG","PS","NG","SV","MR","RO","IM","NC","HN","JE","IQ","AX","BF","TZ","MZ","AT","BE","GR","SD","AW","CF","CV","SN","DJ","PA","AM","BL","MP","ZW","MM","EG","CO","FR","BD","SZ","BN","CL","GU","BA","MW","YT","SY","CK","LK","QA","NI","CW","US","GW","KW","IS","BI","VN","AD","CD","KN","VG","BW","KI","TH","VC","SM","MQ","UM","CX","PT","PM","FO"],"linkAlternates":[{"hrefUrl":"https://m.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg"},{"hrefUrl":"android-app://com.google.android.youtube/http/youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg"},{"hrefUrl":"ios-app://544007664/http/youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg"}]}},"onResponseReceivedActions":[{"clickTrackingParams":"CAAQhGciEwj4yb-mrYT9AhUQh_8EHbCoC1U=","resetChannelUnreadCountCommand":{"channelId":"UCq6VFHwMzcMXbuKyG7SQYIg"}}],"frameworkUpdates":{"entityBatchUpdate":{"mutations":[{"entityKey":"EhhVQ3E2VkZId016Y01YYnVLeUc3U1FZSWcgMygB","type":"ENTITY_MUTATION_TYPE_REPLACE","payload":{"subscriptionStateEntity":{"key":"EhhVQ3E2VkZId016Y01YYnVLeUc3U1FZSWcgMygB","subscribed":true}}}],"timestamp":{"seconds":"1675805320","nanos":178353730}}}};</script><script nonce="nopnosk9VoEiau3Xtg_3uQ">if (window.ytcsi) {window.ytcsi.tick('pdr', null, '');}</script><link rel="canonical" href="https://www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg"><link rel="alternate" media="handheld" href="https://m.youtube.com/@penguinz0"><link rel="alternate" media="only screen and (max-width: 640px)" href="https://m.youtube.com/@penguinz0"><title>penguinz0 - YouTube</title><meta name="description" content="Clips channel: https://www.youtube.com/channel/UC4EQHfzIbkL_Skit_iKt1aATwitter: https://twitter.com/MoistCr1TiKaLInstagram: https://www.instagram.com/..."><meta name="keywords" content="Cr1TiKaL Gears of War Call Duty Battlefield Bad Company Fun Tactics"><link rel="alternate" type="application/rss+xml" title="RSS" href="https://www.youtube.com/feeds/videos.xml?channel_id=UCq6VFHwMzcMXbuKyG7SQYIg"><meta property="og:title" content="penguinz0"><link rel="image_src" href="https://yt3.googleusercontent.com/ytc/AL5GRJWOhJOuUC6C2b7gP-5D2q6ypXbcOOckyAE1En4RUQ=s900-c-k-c0x00ffffff-no-rj"><meta property="og:site_name" content="YouTube"><meta property="og:url" content="https://www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg"><meta property="og:image" content="https://yt3.googleusercontent.com/ytc/AL5GRJWOhJOuUC6C2b7gP-5D2q6ypXbcOOckyAE1En4RUQ=s900-c-k-c0x00ffffff-no-rj"><meta property="og:image:width" content="900"><meta property="og:image:height" content="900"><meta property="og:description" content="Clips channel: https://www.youtube.com/channel/UC4EQHfzIbkL_Skit_iKt1aA 24 + 25 + Twitter: https://twitter.com/MoistCr1TiKaL 26 + 27 + Instagram: https://www.instagram.com/bigmoistcr1tikal/?hl=en 28 + 29 + Twitch: https://www.twitch.tv/moistcr1tikal 30 + 31 + Snapchat: Hugecharles 32 + 33 + Tik Tok: Hugecharles 34 + 35 + I don&#39;t have any other public accounts."><meta property="al:ios:app_store_id" content="544007664"><meta property="al:ios:app_name" content="YouTube"><meta property="al:ios:url" content="vnd.youtube://www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg"><meta property="al:android:url" content="https://www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg?feature=applinks"><meta property="al:android:app_name" content="YouTube"><meta property="al:android:package" content="com.google.android.youtube"><meta property="al:web:url" content="https://www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg?feature=applinks"><meta property="og:type" content="profile"><meta property="og:video:tag" content="Cr1TiKaL"><meta property="og:video:tag" content="Gears"><meta property="og:video:tag" content="of"><meta property="og:video:tag" content="War"><meta property="og:video:tag" content="Call"><meta property="og:video:tag" content="Duty"><meta property="og:video:tag" content="Battlefield"><meta property="og:video:tag" content="Bad"><meta property="og:video:tag" content="Company"><meta property="og:video:tag" content="Fun"><meta property="og:video:tag" content="Tactics"><meta property="fb:app_id" content="87741124305"><meta name="twitter:card" content="summary"><meta name="twitter:site" content="@youtube"><meta name="twitter:url" content="https://www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg"><meta name="twitter:title" content="penguinz0"><meta name="twitter:description" content="Clips channel: https://www.youtube.com/channel/UC4EQHfzIbkL_Skit_iKt1aA 36 + 37 + Twitter: https://twitter.com/MoistCr1TiKaL 38 + 39 + Instagram: https://www.instagram.com/bigmoistcr1tikal/?hl=en 40 + 41 + Twitch: https://www.twitch.tv/moistcr1tikal 42 + 43 + Snapchat: Hugecharles 44 + 45 + Tik Tok: Hugecharles 46 + 47 + I don&#39;t have any other public accounts."><meta name="twitter:image" content="https://yt3.googleusercontent.com/ytc/AL5GRJWOhJOuUC6C2b7gP-5D2q6ypXbcOOckyAE1En4RUQ=s900-c-k-c0x00ffffff-no-rj"><meta name="twitter:app:name:iphone" content="YouTube"><meta name="twitter:app:id:iphone" content="544007664"><meta name="twitter:app:name:ipad" content="YouTube"><meta name="twitter:app:id:ipad" content="544007664"><meta name="twitter:app:url:iphone" content="vnd.youtube://www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg"><meta name="twitter:app:url:ipad" content="vnd.youtube://www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg"><meta name="twitter:app:name:googleplay" content="YouTube"><meta name="twitter:app:id:googleplay" content="com.google.android.youtube"><meta name="twitter:app:url:googleplay" content="https://www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg"><link itemprop="url" href="https://www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg"><meta itemprop="name" content="penguinz0"><meta itemprop="description" content="Clips channel: https://www.youtube.com/channel/UC4EQHfzIbkL_Skit_iKt1aA 48 + 49 + Twitter: https://twitter.com/MoistCr1TiKaL 50 + 51 + Instagram: https://www.instagram.com/bigmoistcr1tikal/?hl=en 52 + 53 + Twitch: https://www.twitch.tv/moistcr1tikal 54 + 55 + Snapchat: Hugecharles 56 + 57 + Tik Tok: Hugecharles 58 + 59 + I don&#39;t have any other public accounts."><meta itemprop="paid" content="false"><meta itemprop="channelId" content="UCq6VFHwMzcMXbuKyG7SQYIg"><span itemprop="author" itemscope itemtype="http://schema.org/Person"><link itemprop="url" href="https://www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg"><link itemprop="name" content="penguinz0"></span><script type="application/ld+json" nonce="nopnosk9VoEiau3Xtg_3uQ">{"@context": "http://schema.org", "@type": "BreadcrumbList", "itemListElement": [{"@type": "ListItem", "position": 1, "item": {"@id": "https:\/\/www.youtube.com\/channel\/UCq6VFHwMzcMXbuKyG7SQYIg", "name": "penguinz0"}}]}</script><link itemprop="thumbnailUrl" href="https://yt3.googleusercontent.com/ytc/AL5GRJWOhJOuUC6C2b7gP-5D2q6ypXbcOOckyAE1En4RUQ=s900-c-k-c0x00ffffff-no-rj"><span itemprop="thumbnail" itemscope itemtype="http://schema.org/ImageObject"><link itemprop="url" href="https://yt3.googleusercontent.com/ytc/AL5GRJWOhJOuUC6C2b7gP-5D2q6ypXbcOOckyAE1En4RUQ=s900-c-k-c0x00ffffff-no-rj"><meta itemprop="width" content="900"><meta itemprop="height" content="900"></span><meta itemprop="isFamilyFriendly" content="true"><meta itemprop="regionsAllowed" content="UA,BY,YE,LS,MG,PN,DE,TF,GM,CI,MH,ME,EH,PR,MC,VE,FJ,KH,VU,VA,ZA,PF,SE,CN,CC,NP,TO,FM,KG,RE,GP,GD,KZ,AF,EC,LU,RU,FK,SC,IL,MK,SB,BJ,IO,MU,GH,PK,CZ,TM,DO,SI,GE,GY,ID,BG,IE,KP,ML,NR,NU,PH,UG,BB,LC,BZ,SJ,GA,GT,AG,ES,EE,CA,CG,TC,GN,KR,VI,GL,SS,HM,TV,LV,BV,AZ,BT,RS,GB,MA,GG,MN,FI,CR,DZ,TJ,PL,AL,GF,GQ,MF,AS,NE,NL,UY,SK,TT,MX,IT,SR,AI,ET,CU,HU,MO,ST,TK,NZ,LT,ER,TD,TW,LB,ZM,CM,KY,LR,AO,PY,BM,MV,SA,NF,NO,SH,IR,AQ,WF,NA,HK,LY,IN,CY,KE,DM,MS,MT,KM,OM,TN,BS,MD,GI,MY,GS,PW,LA,WS,TL,AE,JP,SL,SO,BH,SG,JO,CH,AR,AU,BQ,HR,TG,JM,PE,BR,TR,SX,BO,LI,HT,DK,RW,UZ,PG,PS,NG,SV,MR,RO,IM,NC,HN,JE,IQ,AX,BF,TZ,MZ,AT,BE,GR,SD,AW,CF,CV,SN,DJ,PA,AM,BL,MP,ZW,MM,EG,CO,FR,BD,SZ,BN,CL,GU,BA,MW,YT,SY,CK,LK,QA,NI,CW,US,GW,KW,IS,BI,VN,AD,CD,KN,VG,BW,KI,TH,VC,SM,MQ,UM,CX,PT,PM,FO"><link rel="alternate" href="android-app://com.google.android.youtube/http/www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg"><link rel="alternate" href="ios-app://544007664/vnd.youtube/www.youtube.com/channel/UCq6VFHwMzcMXbuKyG7SQYIg"><script nonce="nopnosk9VoEiau3Xtg_3uQ">(function serverContract() {window['ytPageType'] = "channel";window['ytCommand'] = {"clickTrackingParams":"IhMI7Zu-pq2E_QIV2K_lBx1N8wNfMghleHRlcm5hbA==","commandMetadata":{"webCommandMetadata":{"url":"/@penguinz0","webPageType":"WEB_PAGE_TYPE_CHANNEL","rootVe":3611,"apiUrl":"/youtubei/v1/browse"},"resolveUrlCommandMetadata":{"isVanityUrl":true}},"browseEndpoint":{"browseId":"UCq6VFHwMzcMXbuKyG7SQYIg","params":"EgC4AQDyBgQKAjIA"}};window['ytUrl'] = '\/@penguinz0';var a=window;(function(e){var c=window;c.getInitialCommand=function(){return e};c.loadInitialCommand&&c.loadInitialCommand(c.getInitialCommand())})(a.ytCommand); 60 + (function(e,c,l,f,g,h,k){var d=window;d.getInitialData=function(){var b=window;b.ytcsi&&b.ytcsi.tick("pr",null,"");b={page:e,endpoint:c,response:l};f&&(b.playerResponse=f);g&&(b.reelWatchSequenceResponse=g);k&&(b.url=k);h&&(b.previousCsn=h);return b};d.loadInitialData&&d.loadInitialData(d.getInitialData())})(a.ytPageType,a.ytCommand,a.ytInitialData,a.ytInitialPlayerResponse,a.ytInitialReelWatchSequenceResponse,a.ytPreviousCsn,a.ytUrl); 61 + })();</script><link rel="stylesheet" href="https://www.youtube.com/s/desktop/156c3d3d/cssbin/www-main-desktop-watch-page-skeleton-2x.css" name="www-main-desktop-watch-page-skeleton" nonce="EXDS35bkZefCv-NuBrYLQw"><div id="watch-page-skeleton" rounded-container class="watch-skeletonhidden"><div id="container"><div id="related"><div class="autoplay skeleton-light-border-bottom"><div id="upnext" class="skeleton-bg-color"></div><div class="video-skeleton"><div class="video-details"><div class="thumbnail skeleton-bg-color"></div><div class="details flex-1"><div class="video-title text-shell skeleton-bg-color"></div><div class="video-meta text-shell skeleton-bg-color"></div></div></div></div></div><div class="video-skeleton"><div class="video-details"><div class="thumbnail skeleton-bg-color"></div><div class="details flex-1"><div class="video-title text-shell skeleton-bg-color"></div><div class="video-meta text-shell skeleton-bg-color"></div></div></div></div><div class="video-skeleton"><div class="video-details"><div class="thumbnail skeleton-bg-color"></div><div class="details flex-1"><div class="video-title text-shell skeleton-bg-color"></div><div class="video-meta text-shell skeleton-bg-color"></div></div></div></div><div class="video-skeleton"><div class="video-details"><div class="thumbnail skeleton-bg-color"></div><div class="details flex-1"><div class="video-title text-shell skeleton-bg-color"></div><div class="video-meta text-shell skeleton-bg-color"></div></div></div></div><div class="video-skeleton"><div class="video-details"><div class="thumbnail skeleton-bg-color"></div><div class="details flex-1"><div class="video-title text-shell skeleton-bg-color"></div><div class="video-meta text-shell skeleton-bg-color"></div></div></div></div><div class="video-skeleton"><div class="video-details"><div class="thumbnail skeleton-bg-color"></div><div class="details flex-1"><div class="video-title text-shell skeleton-bg-color"></div><div class="video-meta text-shell skeleton-bg-color"></div></div></div></div><div class="video-skeleton"><div class="video-details"><div class="thumbnail skeleton-bg-color"></div><div class="details flex-1"><div class="video-title text-shell skeleton-bg-color"></div><div class="video-meta text-shell skeleton-bg-color"></div></div></div></div><div class="video-skeleton"><div class="video-details"><div class="thumbnail skeleton-bg-color"></div><div class="details flex-1"><div class="video-title text-shell skeleton-bg-color"></div><div class="video-meta text-shell skeleton-bg-color"></div></div></div></div><div class="video-skeleton"><div class="video-details"><div class="thumbnail skeleton-bg-color"></div><div class="details flex-1"><div class="video-title text-shell skeleton-bg-color"></div><div class="video-meta text-shell skeleton-bg-color"></div></div></div></div><div class="video-skeleton"><div class="video-details"><div class="thumbnail skeleton-bg-color"></div><div class="details flex-1"><div class="video-title text-shell skeleton-bg-color"></div><div class="video-meta text-shell skeleton-bg-color"></div></div></div></div></div><div id="info-container"><div id="primary-info" class="skeleton-light-border-bottom"><div id="title" class="text-shell skeleton-bg-color"></div><div id="info"><div id="count" class="text-shell skeleton-bg-color"></div><div class="flex-1"></div><div id="menu"><div class="menu-button skeleton-bg-color"></div><div class="menu-button skeleton-bg-color"></div><div class="menu-button skeleton-bg-color"></div><div class="menu-button skeleton-bg-color"></div><div class="menu-button skeleton-bg-color"></div></div></div></div><div id="secondary-info" class="skeleton-light-border-bottom"><div id="top-row"><div id="video-owner" class="flex-1"><div id="channel-icon" class="skeleton-bg-color"></div><div id="upload-info" class="flex-1"><div id="owner-name" class="text-shell skeleton-bg-color"></div><div id="published-date" class="text-shell skeleton-bg-color"></div></div></div><div id="subscribe-button" class="skeleton-bg-color"></div></div></div></div></div></div><script nonce="nopnosk9VoEiau3Xtg_3uQ">if (window.ytcsi) {window.ytcsi.tick('gcc', null, '');}</script><script nonce="nopnosk9VoEiau3Xtg_3uQ">ytcfg.set({"CSI_SERVICE_NAME": 'youtube', "TIMING_INFO": {}})</script><script nonce="nopnosk9VoEiau3Xtg_3uQ">if (window.ytcsi) {window.ytcsi.info('st', 341.0 , '');}</script></body></html> 62 + 63 + `
+47
__tests__/lib/async/bundle.test.ts
··· 1 + import {bundleAsync} from '../../../src/lib/async/bundle' 2 + 3 + describe('bundle', () => { 4 + it('bundles multiple simultaneous calls into one execution', async () => { 5 + let calls = 0 6 + const fn = bundleAsync(async () => { 7 + calls++ 8 + await new Promise(r => setTimeout(r, 1)) 9 + return 'hello' 10 + }) 11 + const [res1, res2, res3] = await Promise.all([fn(), fn(), fn()]) 12 + expect(calls).toEqual(1) 13 + expect(res1).toEqual('hello') 14 + expect(res2).toEqual('hello') 15 + expect(res3).toEqual('hello') 16 + }) 17 + it('does not bundle non-simultaneous calls', async () => { 18 + let calls = 0 19 + const fn = bundleAsync(async () => { 20 + calls++ 21 + await new Promise(r => setTimeout(r, 1)) 22 + return 'hello' 23 + }) 24 + const res1 = await fn() 25 + const res2 = await fn() 26 + const res3 = await fn() 27 + expect(calls).toEqual(3) 28 + expect(res1).toEqual('hello') 29 + expect(res2).toEqual('hello') 30 + expect(res3).toEqual('hello') 31 + }) 32 + it('is not affected by rejections', async () => { 33 + let calls = 0 34 + const fn = bundleAsync(async () => { 35 + calls++ 36 + await new Promise(r => setTimeout(r, 1)) 37 + throw new Error() 38 + }) 39 + const res1 = await fn().catch(() => 'reject') 40 + const res2 = await fn().catch(() => 'reject') 41 + const res3 = await fn().catch(() => 'reject') 42 + expect(calls).toEqual(3) 43 + expect(res1).toEqual('reject') 44 + expect(res2).toEqual('reject') 45 + expect(res3).toEqual('reject') 46 + }) 47 + })
+1 -1
__tests__/lib/errors.test.ts
··· 1 - import {isNetworkError} from '../../src/lib/errors' 1 + import {isNetworkError} from '../../src/lib/strings/errors' 2 2 3 3 describe('isNetworkError', () => { 4 4 const inputs = [
+15 -1
__tests__/lib/extractHtmlMeta.test.ts
··· 1 - import {extractHtmlMeta} from '../../src/lib/extractHtmlMeta' 1 + import {extractHtmlMeta} from '../../src/lib/link-meta/html' 2 2 import {exampleComHtml} from './__mocks__/exampleComHtml' 3 3 import {youtubeHTML} from './__mocks__/youtubeHtml' 4 4 import {tiktokHtml} from './__mocks__/tiktokHtml' 5 + import {youtubeChannelHtml} from './__mocks__/youtubeChannelHtml' 5 6 6 7 describe('extractHtmlMeta', () => { 7 8 const cases = [ ··· 77 78 description: 78 79 'Stunning HD Video ( 1080p ) of Patagonian Nature with Relaxing Native American Shamanic Music. HD footage used from ', 79 80 image: 'https://i.ytimg.com/vi/x6UITRjhijI/sddefault.jpg', 81 + } 82 + const output = extractHtmlMeta({html: input, hostname: 'youtube.com'}) 83 + expect(output).toEqual(expectedOutput) 84 + }) 85 + 86 + it('extracts avatar from a youtube channel', () => { 87 + const input = youtubeChannelHtml 88 + const expectedOutput = { 89 + title: 'penguinz0', 90 + description: 91 + 'Clips channel: https://www.youtube.com/channel/UC4EQHfzIbkL_Skit_iKt1aA\n\nTwitter: https://twitter.com/MoistCr1TiKaL\n\nInstagram: https://www.instagram.com/bigmoistcr1tikal/?hl=en\n\nTwitch: https://www.twitch.tv/moistcr1tikal\n\nSnapchat: Hugecharles\n\nTik Tok: Hugecharles\n\nI don&#39;t have any other public accounts.', 92 + image: 93 + 'https://yt3.googleusercontent.com/ytc/AL5GRJWOhJOuUC6C2b7gP-5D2q6ypXbcOOckyAE1En4RUQ=s176-c-k-c0x00ffffff-no-rj', 80 94 } 81 95 const output = extractHtmlMeta({html: input, hostname: 'youtube.com'}) 82 96 expect(output).toEqual(expectedOutput)
+27 -2
__tests__/lib/images.test.ts
··· 78 78 }) 79 79 80 80 it('should return undefined for unsupported file type', async () => { 81 + const mockedFetch = RNFetchBlob.fetch as jest.Mock 82 + mockedFetch.mockResolvedValueOnce({ 83 + path: jest.fn().mockReturnValue('file://downloaded-image'), 84 + flush: jest.fn(), 85 + }) 86 + 81 87 const opts: DownloadAndResizeOpts = { 82 - uri: 'https://example.com/image.bmp', 88 + uri: 'https://example.com/image', 83 89 width: 100, 84 90 height: 100, 85 91 maxSize: 500000, ··· 88 94 } 89 95 90 96 const result = await downloadAndResize(opts) 91 - expect(result).toBeUndefined() 97 + expect(result).toEqual(mockResizedImage) 98 + expect(RNFetchBlob.config).toHaveBeenCalledWith({ 99 + fileCache: true, 100 + appendExt: 'jpeg', 101 + }) 102 + expect(RNFetchBlob.fetch).toHaveBeenCalledWith( 103 + 'GET', 104 + 'https://example.com/image', 105 + ) 106 + expect(ImageResizer.createResizedImage).toHaveBeenCalledWith( 107 + 'file://downloaded-image', 108 + 100, 109 + 100, 110 + 'JPEG', 111 + 100, 112 + undefined, 113 + undefined, 114 + undefined, 115 + {mode: 'cover'}, 116 + ) 92 117 }) 93 118 })
+36 -9
__tests__/lib/string.test.ts
··· 1 1 import { 2 - extractEntities, 3 - detectLinkables, 4 - pluralize, 2 + getYoutubeVideoId, 5 3 makeRecordUri, 6 - ago, 7 - makeValidHandle, 8 - createFullHandle, 9 - enforceLen, 10 - cleanError, 11 4 toNiceDomain, 12 5 toShortUrl, 13 6 toShareUrl, 14 - } from '../../src/lib/strings' 7 + } from '../../src/lib/strings/url-helpers' 8 + import {pluralize, enforceLen} from '../../src/lib/strings/helpers' 9 + import {ago} from '../../src/lib/strings/time' 10 + import { 11 + extractEntities, 12 + detectLinkables, 13 + } from '../../src/lib/strings/rich-text-detection' 14 + import {makeValidHandle, createFullHandle} from '../../src/lib/strings/handles' 15 + import {cleanError} from '../../src/lib/strings/errors' 15 16 16 17 describe('extractEntities', () => { 17 18 const knownHandles = new Set(['handle.com', 'full123.test-of-chars']) ··· 487 488 } 488 489 }) 489 490 }) 491 + 492 + describe('getYoutubeVideoId', () => { 493 + it(' should return undefined for invalid youtube links', () => { 494 + expect(getYoutubeVideoId('')).toBeUndefined() 495 + expect(getYoutubeVideoId('https://www.google.com')).toBeUndefined() 496 + expect(getYoutubeVideoId('https://www.youtube.com')).toBeUndefined() 497 + expect( 498 + getYoutubeVideoId('https://www.youtube.com/channelName'), 499 + ).toBeUndefined() 500 + expect( 501 + getYoutubeVideoId('https://www.youtube.com/channel/channelName'), 502 + ).toBeUndefined() 503 + }) 504 + 505 + it('getYoutubeVideoId should return video id for valid youtube links', () => { 506 + expect(getYoutubeVideoId('https://www.youtube.com/watch?v=videoId')).toBe( 507 + 'videoId', 508 + ) 509 + expect( 510 + getYoutubeVideoId( 511 + 'https://www.youtube.com/watch?v=videoId&feature=share', 512 + ), 513 + ).toBe('videoId') 514 + expect(getYoutubeVideoId('https://youtu.be/videoId')).toBe('videoId') 515 + }) 516 + })
+84
__tests__/lib/strings/mention-manip.test.ts
··· 1 + import { 2 + getMentionAt, 3 + insertMentionAt, 4 + } from '../../../src/lib/strings/mention-manip' 5 + 6 + describe('getMentionAt', () => { 7 + type Case = [string, number, string | undefined] 8 + const cases: Case[] = [ 9 + ['hello @alice goodbye', 0, undefined], 10 + ['hello @alice goodbye', 1, undefined], 11 + ['hello @alice goodbye', 2, undefined], 12 + ['hello @alice goodbye', 3, undefined], 13 + ['hello @alice goodbye', 4, undefined], 14 + ['hello @alice goodbye', 5, undefined], 15 + ['hello @alice goodbye', 6, 'alice'], 16 + ['hello @alice goodbye', 7, 'alice'], 17 + ['hello @alice goodbye', 8, 'alice'], 18 + ['hello @alice goodbye', 9, 'alice'], 19 + ['hello @alice goodbye', 10, 'alice'], 20 + ['hello @alice goodbye', 11, 'alice'], 21 + ['hello @alice goodbye', 12, 'alice'], 22 + ['hello @alice goodbye', 13, undefined], 23 + ['hello @alice goodbye', 14, undefined], 24 + ['@alice', 0, 'alice'], 25 + ['@alice hello', 0, 'alice'], 26 + ['@alice hello', 1, 'alice'], 27 + ['@alice hello', 2, 'alice'], 28 + ['@alice hello', 3, 'alice'], 29 + ['@alice hello', 4, 'alice'], 30 + ['@alice hello', 5, 'alice'], 31 + ['@alice hello', 6, 'alice'], 32 + ['@alice hello', 7, undefined], 33 + ['alice@alice', 0, undefined], 34 + ['alice@alice', 6, undefined], 35 + ] 36 + 37 + it.each(cases)( 38 + 'given input string %p and cursor position %p, returns %p', 39 + (str, cursorPos, expected) => { 40 + const output = getMentionAt(str, cursorPos) 41 + expect(output?.value).toEqual(expected) 42 + }, 43 + ) 44 + }) 45 + 46 + describe('insertMentionAt', () => { 47 + type Case = [string, number, string] 48 + const cases: Case[] = [ 49 + ['hello @alice goodbye', 0, 'hello @alice goodbye'], 50 + ['hello @alice goodbye', 1, 'hello @alice goodbye'], 51 + ['hello @alice goodbye', 2, 'hello @alice goodbye'], 52 + ['hello @alice goodbye', 3, 'hello @alice goodbye'], 53 + ['hello @alice goodbye', 4, 'hello @alice goodbye'], 54 + ['hello @alice goodbye', 5, 'hello @alice goodbye'], 55 + ['hello @alice goodbye', 6, 'hello @alice.com goodbye'], 56 + ['hello @alice goodbye', 7, 'hello @alice.com goodbye'], 57 + ['hello @alice goodbye', 8, 'hello @alice.com goodbye'], 58 + ['hello @alice goodbye', 9, 'hello @alice.com goodbye'], 59 + ['hello @alice goodbye', 10, 'hello @alice.com goodbye'], 60 + ['hello @alice goodbye', 11, 'hello @alice.com goodbye'], 61 + ['hello @alice goodbye', 12, 'hello @alice.com goodbye'], 62 + ['hello @alice goodbye', 13, 'hello @alice goodbye'], 63 + ['hello @alice goodbye', 14, 'hello @alice goodbye'], 64 + ['@alice', 0, '@alice.com '], 65 + ['@alice hello', 0, '@alice.com hello'], 66 + ['@alice hello', 1, '@alice.com hello'], 67 + ['@alice hello', 2, '@alice.com hello'], 68 + ['@alice hello', 3, '@alice.com hello'], 69 + ['@alice hello', 4, '@alice.com hello'], 70 + ['@alice hello', 5, '@alice.com hello'], 71 + ['@alice hello', 6, '@alice.com hello'], 72 + ['@alice hello', 7, '@alice hello'], 73 + ['alice@alice', 0, 'alice@alice'], 74 + ['alice@alice', 6, 'alice@alice'], 75 + ] 76 + 77 + it.each(cases)( 78 + 'given input string %p and cursor position %p, returns %p', 79 + (str, cursorPos, expected) => { 80 + const output = insertMentionAt(str, cursorPos, 'alice.com') 81 + expect(output).toEqual(expected) 82 + }, 83 + ) 84 + })
+123
__tests__/lib/strings/rich-text-sanitize.ts
··· 1 + import {AppBskyFeedPost} from '@atproto/api' 2 + type Entity = AppBskyFeedPost.Entity 3 + import {RichText} from '../../../src/lib/strings/rich-text' 4 + import {removeExcessNewlines} from '../../../src/lib/strings/rich-text-sanitize' 5 + 6 + describe('removeExcessNewlines', () => { 7 + it('removes more than two consecutive new lines', () => { 8 + const input = new RichText( 9 + 'test\n\n\n\n\ntest\n\n\n\n\n\n\ntest\n\n\n\n\n\n\ntest\n\n\n\n\n\n\ntest', 10 + ) 11 + const output = removeExcessNewlines(input) 12 + expect(output.text).toEqual('test\n\ntest\n\ntest\n\ntest\n\ntest') 13 + }) 14 + 15 + it('removes more than two consecutive new lines with spaces', () => { 16 + const input = new RichText( 17 + 'test\n\n\n\n\ntest\n \n \n \n \n\n\ntest\n\n\n\n\n\n\ntest\n\n\n\n\n \n\ntest', 18 + ) 19 + const output = removeExcessNewlines(input) 20 + expect(output.text).toEqual('test\n\ntest\n\ntest\n\ntest\n\ntest') 21 + }) 22 + 23 + it('returns original string if there are no consecutive new lines', () => { 24 + const input = new RichText('test\n\ntest\n\ntest\n\ntest\n\ntest') 25 + const output = removeExcessNewlines(input) 26 + expect(output.text).toEqual(input.text) 27 + }) 28 + 29 + it('returns original string if there are no new lines', () => { 30 + const input = new RichText('test test test test test') 31 + const output = removeExcessNewlines(input) 32 + expect(output.text).toEqual(input.text) 33 + }) 34 + 35 + it('returns empty string if input is empty', () => { 36 + const input = new RichText('') 37 + const output = removeExcessNewlines(input) 38 + expect(output.text).toEqual('') 39 + }) 40 + 41 + it('works with different types of new line characters', () => { 42 + const input = new RichText( 43 + 'test\r\ntest\n\rtest\rtest\n\n\n\ntest\n\r \n \n \n \n\n\ntest', 44 + ) 45 + const output = removeExcessNewlines(input) 46 + expect(output.text).toEqual('test\r\ntest\n\rtest\rtest\n\ntest\n\ntest') 47 + }) 48 + 49 + it('removes more than two consecutive new lines with zero width space', () => { 50 + const input = new RichText( 51 + 'test\n\n\n\n\ntest\n\u200B\u200B\n\n\n\ntest\n \u200B\u200B \n\n\n\ntest\n\n\n\n\n\n\ntest', 52 + ) 53 + const output = removeExcessNewlines(input) 54 + expect(output.text).toEqual('test\n\ntest\n\ntest\n\ntest\n\ntest') 55 + }) 56 + 57 + it('removes more than two consecutive new lines with zero width non-joiner', () => { 58 + const input = new RichText( 59 + 'test\n\n\n\n\ntest\n\u200C\u200C\n\n\n\ntest\n \u200C\u200C \n\n\n\ntest\n\n\n\n\n\n\ntest', 60 + ) 61 + const output = removeExcessNewlines(input) 62 + expect(output.text).toEqual('test\n\ntest\n\ntest\n\ntest\n\ntest') 63 + }) 64 + 65 + it('removes more than two consecutive new lines with zero width joiner', () => { 66 + const input = new RichText( 67 + 'test\n\n\n\n\ntest\n\u200D\u200D\n\n\n\ntest\n \u200D\u200D \n\n\n\ntest\n\n\n\n\n\n\ntest', 68 + ) 69 + const output = removeExcessNewlines(input) 70 + expect(output.text).toEqual('test\n\ntest\n\ntest\n\ntest\n\ntest') 71 + }) 72 + 73 + it('removes more than two consecutive new lines with soft hyphen', () => { 74 + const input = new RichText( 75 + 'test\n\n\n\n\ntest\n\u00AD\u00AD\n\n\n\ntest\n \u00AD\u00AD \n\n\n\ntest\n\n\n\n\n\n\ntest', 76 + ) 77 + const output = removeExcessNewlines(input) 78 + expect(output.text).toEqual('test\n\ntest\n\ntest\n\ntest\n\ntest') 79 + }) 80 + 81 + it('removes more than two consecutive new lines with word joiner', () => { 82 + const input = new RichText( 83 + 'test\n\n\n\n\ntest\n\u2060\u2060\n\n\n\ntest\n \u2060\u2060 \n\n\n\ntest\n\n\n\n\n\n\ntest', 84 + ) 85 + const output = removeExcessNewlines(input) 86 + expect(output.text).toEqual('test\n\ntest\n\ntest\n\ntest\n\ntest') 87 + }) 88 + }) 89 + 90 + describe('removeExcessNewlines w/entities', () => { 91 + it('preserves entities as expected', () => { 92 + const input = new RichText( 93 + 'test\n\n\n\n\ntest\n\n\n\n\n\n\ntest\n\n\n\n\n\n\ntest\n\n\n\n\n\n\ntest', 94 + [ 95 + {index: {start: 0, end: 13}, type: '', value: ''}, 96 + {index: {start: 13, end: 24}, type: '', value: ''}, 97 + {index: {start: 9, end: 15}, type: '', value: ''}, 98 + {index: {start: 4, end: 9}, type: '', value: ''}, 99 + ], 100 + ) 101 + const output = removeExcessNewlines(input) 102 + expect(entToStr(input.text, input.entities?.[0])).toEqual( 103 + 'test\n\n\n\n\ntest', 104 + ) 105 + expect(entToStr(input.text, input.entities?.[1])).toEqual( 106 + '\n\n\n\n\n\n\ntest', 107 + ) 108 + expect(entToStr(input.text, input.entities?.[2])).toEqual('test\n\n') 109 + expect(entToStr(input.text, input.entities?.[3])).toEqual('\n\n\n\n\n') 110 + expect(output.text).toEqual('test\n\ntest\n\ntest\n\ntest\n\ntest') 111 + expect(entToStr(output.text, output.entities?.[0])).toEqual('test\n\ntest') 112 + expect(entToStr(output.text, output.entities?.[1])).toEqual('test') 113 + expect(entToStr(output.text, output.entities?.[2])).toEqual('test') 114 + expect(output.entities?.[3]).toEqual(undefined) 115 + }) 116 + }) 117 + 118 + function entToStr(str: string, ent?: Entity) { 119 + if (!ent) { 120 + return '' 121 + } 122 + return str.slice(ent.index.start, ent.index.end) 123 + }
+123
__tests__/lib/strings/rich-text.ts
··· 1 + import {RichText} from '../../../src/lib/strings/rich-text' 2 + 3 + describe('richText.insert', () => { 4 + const input = new RichText('hello world', [ 5 + {index: {start: 2, end: 7}, type: '', value: ''}, 6 + ]) 7 + 8 + it('correctly adjusts entities (scenario A - before)', () => { 9 + const output = input.clone().insert(0, 'test') 10 + expect(output.text).toEqual('testhello world') 11 + expect(output.entities?.[0].index.start).toEqual(6) 12 + expect(output.entities?.[0].index.end).toEqual(11) 13 + expect( 14 + output.text.slice( 15 + output.entities?.[0].index.start, 16 + output.entities?.[0].index.end, 17 + ), 18 + ).toEqual('llo w') 19 + }) 20 + 21 + it('correctly adjusts entities (scenario B - inner)', () => { 22 + const output = input.clone().insert(4, 'test') 23 + expect(output.text).toEqual('helltesto world') 24 + expect(output.entities?.[0].index.start).toEqual(2) 25 + expect(output.entities?.[0].index.end).toEqual(11) 26 + expect( 27 + output.text.slice( 28 + output.entities?.[0].index.start, 29 + output.entities?.[0].index.end, 30 + ), 31 + ).toEqual('lltesto w') 32 + }) 33 + 34 + it('correctly adjusts entities (scenario C - after)', () => { 35 + const output = input.clone().insert(8, 'test') 36 + expect(output.text).toEqual('hello wotestrld') 37 + expect(output.entities?.[0].index.start).toEqual(2) 38 + expect(output.entities?.[0].index.end).toEqual(7) 39 + expect( 40 + output.text.slice( 41 + output.entities?.[0].index.start, 42 + output.entities?.[0].index.end, 43 + ), 44 + ).toEqual('llo w') 45 + }) 46 + }) 47 + 48 + describe('richText.delete', () => { 49 + const input = new RichText('hello world', [ 50 + {index: {start: 2, end: 7}, type: '', value: ''}, 51 + ]) 52 + 53 + it('correctly adjusts entities (scenario A - entirely outer)', () => { 54 + const output = input.clone().delete(0, 9) 55 + expect(output.text).toEqual('ld') 56 + expect(output.entities?.length).toEqual(0) 57 + }) 58 + 59 + it('correctly adjusts entities (scenario B - entirely after)', () => { 60 + const output = input.clone().delete(7, 11) 61 + expect(output.text).toEqual('hello w') 62 + expect(output.entities?.[0].index.start).toEqual(2) 63 + expect(output.entities?.[0].index.end).toEqual(7) 64 + expect( 65 + output.text.slice( 66 + output.entities?.[0].index.start, 67 + output.entities?.[0].index.end, 68 + ), 69 + ).toEqual('llo w') 70 + }) 71 + 72 + it('correctly adjusts entities (scenario C - partially after)', () => { 73 + const output = input.clone().delete(4, 11) 74 + expect(output.text).toEqual('hell') 75 + expect(output.entities?.[0].index.start).toEqual(2) 76 + expect(output.entities?.[0].index.end).toEqual(4) 77 + expect( 78 + output.text.slice( 79 + output.entities?.[0].index.start, 80 + output.entities?.[0].index.end, 81 + ), 82 + ).toEqual('ll') 83 + }) 84 + 85 + it('correctly adjusts entities (scenario D - entirely inner)', () => { 86 + const output = input.clone().delete(3, 5) 87 + expect(output.text).toEqual('hel world') 88 + expect(output.entities?.[0].index.start).toEqual(2) 89 + expect(output.entities?.[0].index.end).toEqual(5) 90 + expect( 91 + output.text.slice( 92 + output.entities?.[0].index.start, 93 + output.entities?.[0].index.end, 94 + ), 95 + ).toEqual('l w') 96 + }) 97 + 98 + it('correctly adjusts entities (scenario E - partially before)', () => { 99 + const output = input.clone().delete(1, 5) 100 + expect(output.text).toEqual('h world') 101 + expect(output.entities?.[0].index.start).toEqual(1) 102 + expect(output.entities?.[0].index.end).toEqual(3) 103 + expect( 104 + output.text.slice( 105 + output.entities?.[0].index.start, 106 + output.entities?.[0].index.end, 107 + ), 108 + ).toEqual(' w') 109 + }) 110 + 111 + it('correctly adjusts entities (scenario F - entirely before)', () => { 112 + const output = input.clone().delete(0, 2) 113 + expect(output.text).toEqual('llo world') 114 + expect(output.entities?.[0].index.start).toEqual(0) 115 + expect(output.entities?.[0].index.end).toEqual(5) 116 + expect( 117 + output.text.slice( 118 + output.entities?.[0].index.start, 119 + output.entities?.[0].index.end, 120 + ), 121 + ).toEqual('llo w') 122 + }) 123 + })
-153
__tests__/state/models/log.test.ts
··· 1 - import {LogModel} from '../../../src/state/models/log' 2 - 3 - describe('LogModel', () => { 4 - let logModel: LogModel 5 - 6 - beforeEach(() => { 7 - logModel = new LogModel() 8 - jest.spyOn(console, 'debug') 9 - }) 10 - 11 - afterAll(() => { 12 - jest.clearAllMocks() 13 - }) 14 - 15 - it('should call a log method and add a log entry to the entries array', () => { 16 - logModel.debug('Test log') 17 - expect(logModel.entries.length).toEqual(1) 18 - expect(logModel.entries[0]).toEqual({ 19 - id: logModel.entries[0].id, 20 - type: 'debug', 21 - summary: 'Test log', 22 - details: undefined, 23 - ts: logModel.entries[0].ts, 24 - }) 25 - 26 - logModel.warn('Test log') 27 - expect(logModel.entries.length).toEqual(2) 28 - expect(logModel.entries[1]).toEqual({ 29 - id: logModel.entries[1].id, 30 - type: 'warn', 31 - summary: 'Test log', 32 - details: undefined, 33 - ts: logModel.entries[1].ts, 34 - }) 35 - 36 - logModel.error('Test log') 37 - expect(logModel.entries.length).toEqual(3) 38 - expect(logModel.entries[2]).toEqual({ 39 - id: logModel.entries[2].id, 40 - type: 'error', 41 - summary: 'Test log', 42 - details: undefined, 43 - ts: logModel.entries[2].ts, 44 - }) 45 - }) 46 - 47 - it('should call the console.debug after calling the debug method', () => { 48 - logModel.debug('Test log') 49 - expect(console.debug).toHaveBeenCalledWith('Test log', '') 50 - }) 51 - 52 - it('should call the serialize method', () => { 53 - logModel.debug('Test log') 54 - expect(logModel.serialize()).toEqual({ 55 - entries: [ 56 - { 57 - id: logModel.entries[0].id, 58 - type: 'debug', 59 - summary: 'Test log', 60 - details: undefined, 61 - ts: logModel.entries[0].ts, 62 - }, 63 - ], 64 - }) 65 - }) 66 - 67 - it('should call the hydrate method with valid properties', () => { 68 - logModel.hydrate({ 69 - entries: [ 70 - { 71 - id: '123', 72 - type: 'debug', 73 - summary: 'Test log', 74 - details: undefined, 75 - ts: 123, 76 - }, 77 - ], 78 - }) 79 - expect(logModel.entries).toEqual([ 80 - { 81 - id: '123', 82 - type: 'debug', 83 - summary: 'Test log', 84 - details: undefined, 85 - ts: 123, 86 - }, 87 - ]) 88 - }) 89 - 90 - it('should call the hydrate method with invalid properties', () => { 91 - logModel.hydrate({ 92 - entries: [ 93 - { 94 - id: '123', 95 - type: 'debug', 96 - summary: 'Test log', 97 - details: undefined, 98 - ts: 123, 99 - }, 100 - { 101 - summary: 'Invalid entry', 102 - }, 103 - ], 104 - }) 105 - expect(logModel.entries).toEqual([ 106 - { 107 - id: '123', 108 - type: 'debug', 109 - summary: 'Test log', 110 - details: undefined, 111 - ts: 123, 112 - }, 113 - ]) 114 - }) 115 - 116 - it('should stringify the details if it is not a string', () => { 117 - logModel.debug('Test log', {details: 'test'}) 118 - expect(logModel.entries[0].details).toEqual('{\n "details": "test"\n}') 119 - }) 120 - 121 - it('should stringify the details object if it is of a specific error', () => { 122 - class TestError extends Error { 123 - constructor() { 124 - super() 125 - this.name = 'TestError' 126 - } 127 - } 128 - const error = new TestError() 129 - logModel.error('Test error log', error) 130 - expect(logModel.entries[0].details).toEqual('TestError') 131 - 132 - class XRPCInvalidResponseErrorMock { 133 - validationError = {toString: () => 'validationError'} 134 - lexiconNsid = 'test' 135 - } 136 - const xrpcInvalidResponseError = new XRPCInvalidResponseErrorMock() 137 - logModel.error('Test error log', xrpcInvalidResponseError) 138 - expect(logModel.entries[1].details).toEqual( 139 - '{\n "validationError": {},\n "lexiconNsid": "test"\n}', 140 - ) 141 - 142 - class XRPCErrorMock { 143 - status = 'status' 144 - error = 'error' 145 - message = 'message' 146 - } 147 - const xrpcError = new XRPCErrorMock() 148 - logModel.error('Test error log', xrpcError) 149 - expect(logModel.entries[2].details).toEqual( 150 - '{\n "status": "status",\n "error": "error",\n "message": "message"\n}', 151 - ) 152 - }) 153 - })
-180
__tests__/state/models/me.test.ts
··· 1 - import {RootStoreModel} from '../../../src/state/models/root-store' 2 - import {MeModel} from '../../../src/state/models/me' 3 - import {NotificationsViewModel} from './../../../src/state/models/notifications-view' 4 - import {sessionClient, SessionServiceClient} from '@atproto/api' 5 - import {DEFAULT_SERVICE} from './../../../src/state/index' 6 - 7 - describe('MeModel', () => { 8 - let rootStore: RootStoreModel 9 - let meModel: MeModel 10 - 11 - beforeEach(() => { 12 - const api = sessionClient.service(DEFAULT_SERVICE) as SessionServiceClient 13 - rootStore = new RootStoreModel(api) 14 - meModel = new MeModel(rootStore) 15 - }) 16 - 17 - afterAll(() => { 18 - jest.clearAllMocks() 19 - }) 20 - 21 - it('should clear() correctly', () => { 22 - meModel.did = '123' 23 - meModel.handle = 'handle' 24 - meModel.displayName = 'John Doe' 25 - meModel.description = 'description' 26 - meModel.avatar = 'avatar' 27 - meModel.notificationCount = 1 28 - meModel.clear() 29 - expect(meModel.did).toEqual('') 30 - expect(meModel.handle).toEqual('') 31 - expect(meModel.displayName).toEqual('') 32 - expect(meModel.description).toEqual('') 33 - expect(meModel.avatar).toEqual('') 34 - expect(meModel.notificationCount).toEqual(0) 35 - }) 36 - 37 - it('should hydrate() successfully with valid properties', () => { 38 - meModel.hydrate({ 39 - did: '123', 40 - handle: 'handle', 41 - displayName: 'John Doe', 42 - description: 'description', 43 - avatar: 'avatar', 44 - }) 45 - expect(meModel.did).toEqual('123') 46 - expect(meModel.handle).toEqual('handle') 47 - expect(meModel.displayName).toEqual('John Doe') 48 - expect(meModel.description).toEqual('description') 49 - expect(meModel.avatar).toEqual('avatar') 50 - }) 51 - 52 - it('should not hydrate() with invalid properties', () => { 53 - meModel.hydrate({ 54 - did: '', 55 - handle: 'handle', 56 - displayName: 'John Doe', 57 - description: 'description', 58 - avatar: 'avatar', 59 - }) 60 - expect(meModel.did).toEqual('') 61 - expect(meModel.handle).toEqual('') 62 - expect(meModel.displayName).toEqual('') 63 - expect(meModel.description).toEqual('') 64 - expect(meModel.avatar).toEqual('') 65 - 66 - meModel.hydrate({ 67 - did: '123', 68 - displayName: 'John Doe', 69 - description: 'description', 70 - avatar: 'avatar', 71 - }) 72 - expect(meModel.did).toEqual('') 73 - expect(meModel.handle).toEqual('') 74 - expect(meModel.displayName).toEqual('') 75 - expect(meModel.description).toEqual('') 76 - expect(meModel.avatar).toEqual('') 77 - }) 78 - 79 - it('should load() successfully', async () => { 80 - jest 81 - .spyOn(rootStore.api.app.bsky.actor, 'getProfile') 82 - .mockImplementationOnce((): Promise<any> => { 83 - return Promise.resolve({ 84 - data: { 85 - displayName: 'John Doe', 86 - description: 'description', 87 - avatar: 'avatar', 88 - }, 89 - }) 90 - }) 91 - rootStore.session.data = { 92 - did: '123', 93 - handle: 'handle', 94 - service: 'test service', 95 - accessJwt: 'test token', 96 - refreshJwt: 'test token', 97 - } 98 - await meModel.load() 99 - expect(meModel.did).toEqual('123') 100 - expect(meModel.handle).toEqual('handle') 101 - expect(meModel.displayName).toEqual('John Doe') 102 - expect(meModel.description).toEqual('description') 103 - expect(meModel.avatar).toEqual('avatar') 104 - }) 105 - 106 - it('should load() successfully without profile data', async () => { 107 - jest 108 - .spyOn(rootStore.api.app.bsky.actor, 'getProfile') 109 - .mockImplementationOnce((): Promise<any> => { 110 - return Promise.resolve({ 111 - data: null, 112 - }) 113 - }) 114 - rootStore.session.data = { 115 - did: '123', 116 - handle: 'handle', 117 - service: 'test service', 118 - accessJwt: 'test token', 119 - refreshJwt: 'test token', 120 - } 121 - await meModel.load() 122 - expect(meModel.did).toEqual('123') 123 - expect(meModel.handle).toEqual('handle') 124 - expect(meModel.displayName).toEqual('') 125 - expect(meModel.description).toEqual('') 126 - expect(meModel.avatar).toEqual('') 127 - }) 128 - 129 - it('should load() to nothing when no session', async () => { 130 - rootStore.session.data = null 131 - await meModel.load() 132 - expect(meModel.did).toEqual('') 133 - expect(meModel.handle).toEqual('') 134 - expect(meModel.displayName).toEqual('') 135 - expect(meModel.description).toEqual('') 136 - expect(meModel.avatar).toEqual('') 137 - expect(meModel.notificationCount).toEqual(0) 138 - }) 139 - 140 - it('should serialize() key information', () => { 141 - meModel.did = '123' 142 - meModel.handle = 'handle' 143 - meModel.displayName = 'John Doe' 144 - meModel.description = 'description' 145 - meModel.avatar = 'avatar' 146 - 147 - expect(meModel.serialize()).toEqual({ 148 - did: '123', 149 - handle: 'handle', 150 - displayName: 'John Doe', 151 - description: 'description', 152 - avatar: 'avatar', 153 - }) 154 - }) 155 - 156 - it('should clearNotificationCount() successfully', () => { 157 - meModel.clearNotificationCount() 158 - expect(meModel.notificationCount).toBe(0) 159 - }) 160 - 161 - it('should update notifs count with fetchStateUpdate()', async () => { 162 - meModel.notifications = { 163 - refresh: jest.fn().mockResolvedValue({}), 164 - } as unknown as NotificationsViewModel 165 - 166 - jest 167 - .spyOn(rootStore.api.app.bsky.notification, 'getCount') 168 - .mockImplementationOnce((): Promise<any> => { 169 - return Promise.resolve({ 170 - data: { 171 - count: 1, 172 - }, 173 - }) 174 - }) 175 - 176 - await meModel.fetchNotifications() 177 - expect(meModel.notificationCount).toBe(1) 178 - expect(meModel.notifications.refresh).toHaveBeenCalled() 179 - }) 180 - })
+54 -48
__tests__/state/models/navigation.test.ts
··· 1 + import {RootStoreModel} from './../../../src/state/models/root-store' 1 2 import {NavigationModel} from './../../../src/state/models/navigation' 2 - import * as flags from '../../../src/build-flags' 3 + import * as flags from '../../../src/lib/build-flags' 4 + import AtpAgent from '@atproto/api' 5 + import {DEFAULT_SERVICE} from '../../../src/state' 3 6 4 7 describe('NavigationModel', () => { 5 8 let model: NavigationModel 9 + let rootStore: RootStoreModel 6 10 7 11 beforeEach(() => { 8 - model = new NavigationModel() 12 + rootStore = new RootStoreModel(new AtpAgent({service: DEFAULT_SERVICE})) 13 + model = new NavigationModel(rootStore) 9 14 model.setTitle('0-0', 'title') 10 15 }) 11 16 ··· 15 20 16 21 it('should clear() to the correct base state', async () => { 17 22 await model.clear() 18 - expect(model.tabCount).toBe(2) 23 + expect(model.tabCount).toBe(3) 19 24 expect(model.tab).toEqual({ 20 25 fixedTabPurpose: 0, 21 26 history: [ ··· 64 69 }) 65 70 66 71 it('should call the tabCount getter', () => { 67 - expect(model.tabCount).toBe(2) 72 + expect(model.tabCount).toBe(3) 68 73 }) 69 74 70 75 describe('tabs not enabled', () => { ··· 87 92 it('should not change the active tab', () => { 88 93 // @ts-expect-error 89 94 flags.TABS_ENABLED = false 90 - model.setActiveTab(2) 95 + model.setActiveTab(3) 91 96 expect(model.tabIndex).toBe(0) 92 97 }) 93 98 ··· 95 100 // @ts-expect-error 96 101 flags.TABS_ENABLED = false 97 102 model.closeTab(0) 98 - expect(model.tabCount).toBe(2) 103 + expect(model.tabCount).toBe(3) 99 104 }) 100 105 }) 101 106 102 - describe('tabs enabled', () => { 103 - jest.mock('../../../src/build-flags', () => ({ 104 - TABS_ENABLED: true, 105 - })) 107 + // TODO restore when tabs get re-enabled 108 + // describe('tabs enabled', () => { 109 + // jest.mock('../../../src/build-flags', () => ({ 110 + // TABS_ENABLED: true, 111 + // })) 106 112 107 - afterAll(() => { 108 - jest.clearAllMocks() 109 - }) 113 + // afterAll(() => { 114 + // jest.clearAllMocks() 115 + // }) 110 116 111 - it('should create new tabs', () => { 112 - // @ts-expect-error 113 - flags.TABS_ENABLED = true 117 + // it('should create new tabs', () => { 118 + // // @ts-expect-error 119 + // flags.TABS_ENABLED = true 114 120 115 - model.newTab('testurl', 'title') 116 - expect(model.tab.isNewTab).toBe(true) 117 - expect(model.tabIndex).toBe(2) 118 - }) 121 + // model.newTab('testurl', 'title') 122 + // expect(model.tab.isNewTab).toBe(true) 123 + // expect(model.tabIndex).toBe(2) 124 + // }) 119 125 120 - it('should change the current tab', () => { 121 - // @ts-expect-error 122 - flags.TABS_ENABLED = true 126 + // it('should change the current tab', () => { 127 + // // @ts-expect-error 128 + // flags.TABS_ENABLED = true 123 129 124 - model.setActiveTab(0) 125 - expect(model.tabIndex).toBe(0) 126 - }) 130 + // model.setActiveTab(0) 131 + // expect(model.tabIndex).toBe(0) 132 + // }) 127 133 128 - it('should close tabs', () => { 129 - // @ts-expect-error 130 - flags.TABS_ENABLED = true 134 + // it('should close tabs', () => { 135 + // // @ts-expect-error 136 + // flags.TABS_ENABLED = true 131 137 132 - model.closeTab(0) 133 - expect(model.tabs).toEqual([ 134 - { 135 - fixedTabPurpose: 1, 136 - history: [ 137 - { 138 - id: expect.anything(), 139 - ts: expect.anything(), 140 - url: '/notifications', 141 - }, 142 - ], 143 - id: expect.anything(), 144 - index: 0, 145 - isNewTab: false, 146 - }, 147 - ]) 148 - expect(model.tabIndex).toBe(0) 149 - }) 150 - }) 138 + // model.closeTab(0) 139 + // expect(model.tabs).toEqual([ 140 + // { 141 + // fixedTabPurpose: 1, 142 + // history: [ 143 + // { 144 + // id: expect.anything(), 145 + // ts: expect.anything(), 146 + // url: '/notifications', 147 + // }, 148 + // ], 149 + // id: expect.anything(), 150 + // index: 0, 151 + // isNewTab: false, 152 + // }, 153 + // ]) 154 + // expect(model.tabIndex).toBe(0) 155 + // }) 156 + // }) 151 157 })
-59
__tests__/state/models/root-store.test.ts
··· 1 - import {RootStoreModel} from '../../../src/state/models/root-store' 2 - import {setupState} from '../../../src/state' 3 - 4 - describe('rootStore', () => { 5 - let rootStore: RootStoreModel 6 - 7 - beforeAll(() => { 8 - jest.useFakeTimers() 9 - }) 10 - 11 - beforeEach(async () => { 12 - rootStore = await setupState() 13 - }) 14 - 15 - afterAll(() => { 16 - jest.clearAllMocks() 17 - }) 18 - 19 - it('should call the clearAll() resets state correctly', () => { 20 - rootStore.clearAll() 21 - 22 - expect(rootStore.session.data).toEqual(null) 23 - expect(rootStore.nav.tabs).toEqual([ 24 - { 25 - fixedTabPurpose: 0, 26 - history: [ 27 - { 28 - id: expect.anything(), 29 - ts: expect.anything(), 30 - url: '/', 31 - }, 32 - ], 33 - id: expect.anything(), 34 - index: 0, 35 - isNewTab: false, 36 - }, 37 - { 38 - fixedTabPurpose: 1, 39 - history: [ 40 - { 41 - id: expect.anything(), 42 - ts: expect.anything(), 43 - url: '/notifications', 44 - }, 45 - ], 46 - id: expect.anything(), 47 - index: 0, 48 - isNewTab: false, 49 - }, 50 - ]) 51 - expect(rootStore.nav.tabIndex).toEqual(0) 52 - expect(rootStore.me.did).toEqual('') 53 - expect(rootStore.me.handle).toEqual('') 54 - expect(rootStore.me.displayName).toEqual('') 55 - expect(rootStore.me.description).toEqual('') 56 - expect(rootStore.me.avatar).toEqual('') 57 - expect(rootStore.me.notificationCount).toEqual(0) 58 - }) 59 - })
-61
__tests__/state/models/shell-ui.test.ts
··· 1 - import { 2 - ConfirmModal, 3 - ImagesLightbox, 4 - ShellUiModel, 5 - } from './../../../src/state/models/shell-ui' 6 - 7 - describe('ShellUiModel', () => { 8 - let model: ShellUiModel 9 - 10 - beforeEach(() => { 11 - model = new ShellUiModel() 12 - }) 13 - 14 - afterAll(() => { 15 - jest.clearAllMocks() 16 - }) 17 - 18 - it('should call the openModal & closeModal method', () => { 19 - const m = new ConfirmModal('Test Modal', 'Look good?', () => {}) 20 - model.openModal(m) 21 - expect(model.isModalActive).toEqual(true) 22 - expect(model.activeModal).toEqual(m) 23 - 24 - model.closeModal() 25 - expect(model.isModalActive).toEqual(false) 26 - expect(model.activeModal).toBeUndefined() 27 - }) 28 - 29 - it('should call the openLightbox & closeLightbox method', () => { 30 - const lt = new ImagesLightbox(['uri'], 0) 31 - model.openLightbox(lt) 32 - expect(model.isLightboxActive).toEqual(true) 33 - expect(model.activeLightbox).toEqual(lt) 34 - 35 - model.closeLightbox() 36 - expect(model.isLightboxActive).toEqual(false) 37 - expect(model.activeLightbox).toBeUndefined() 38 - }) 39 - 40 - it('should call the openComposer & closeComposer method', () => { 41 - const composer = { 42 - replyTo: { 43 - uri: 'uri', 44 - cid: 'cid', 45 - text: 'text', 46 - author: { 47 - handle: 'handle', 48 - displayName: 'name', 49 - }, 50 - }, 51 - onPost: jest.fn(), 52 - } 53 - model.openComposer(composer) 54 - expect(model.isComposerActive).toEqual(true) 55 - expect(model.composerOpts).toEqual(composer) 56 - 57 - model.closeComposer() 58 - expect(model.isComposerActive).toEqual(false) 59 - expect(model.composerOpts).toBeUndefined() 60 - }) 61 - })
-43
__tests__/view/com/composer/Autocomplete.test.tsx
··· 1 - import React from 'react' 2 - import {Autocomplete} from '../../../../src/view/com/composer/Autocomplete' 3 - import {cleanup, fireEvent, render} from '../../../../jest/test-utils' 4 - 5 - describe('Autocomplete', () => { 6 - const onSelectMock = jest.fn() 7 - const mockedProps = { 8 - active: true, 9 - items: [ 10 - { 11 - handle: 'handle.test', 12 - displayName: 'Test Display', 13 - }, 14 - { 15 - handle: 'handle2.test', 16 - displayName: 'Test Display 2', 17 - }, 18 - ], 19 - onSelect: onSelectMock, 20 - } 21 - 22 - afterAll(() => { 23 - jest.clearAllMocks() 24 - cleanup() 25 - }) 26 - 27 - it('renders a button for each user', async () => { 28 - const {findAllByTestId} = render(<Autocomplete {...mockedProps} />) 29 - const autocompleteButton = await findAllByTestId('autocompleteButton') 30 - expect(autocompleteButton.length).toBe(2) 31 - }) 32 - 33 - it('triggers onSelect by pressing the button', async () => { 34 - const {findAllByTestId} = render(<Autocomplete {...mockedProps} />) 35 - const autocompleteButton = await findAllByTestId('autocompleteButton') 36 - 37 - fireEvent.press(autocompleteButton[0]) 38 - expect(onSelectMock).toHaveBeenCalledWith('handle.test') 39 - 40 - fireEvent.press(autocompleteButton[1]) 41 - expect(onSelectMock).toHaveBeenCalledWith('handle2.test') 42 - }) 43 - })
-118
__tests__/view/com/composer/ComposePost.test.tsx
··· 1 - import React from 'react' 2 - import {ComposePost} from '../../../../src/view/com/composer/ComposePost' 3 - import {cleanup, fireEvent, render, waitFor} from '../../../../jest/test-utils' 4 - import * as apilib from '../../../../src/state/lib/api' 5 - import { 6 - mockedAutocompleteViewStore, 7 - mockedRootStore, 8 - } from '../../../../__mocks__/state-mock' 9 - import Toast from 'react-native-root-toast' 10 - 11 - describe('ComposePost', () => { 12 - const mockedProps = { 13 - replyTo: { 14 - uri: 'testUri', 15 - cid: 'testCid', 16 - text: 'testText', 17 - author: { 18 - handle: 'test.handle', 19 - displayName: 'test name', 20 - avatar: '', 21 - }, 22 - }, 23 - onPost: jest.fn(), 24 - onClose: jest.fn(), 25 - } 26 - 27 - afterAll(() => { 28 - jest.clearAllMocks() 29 - cleanup() 30 - }) 31 - 32 - it('renders post composer', async () => { 33 - const {findByTestId} = render(<ComposePost {...mockedProps} />) 34 - const composePostView = await findByTestId('composePostView') 35 - expect(composePostView).toBeTruthy() 36 - }) 37 - 38 - it('closes composer', async () => { 39 - const {findByTestId} = render(<ComposePost {...mockedProps} />) 40 - const composerCancelButton = await findByTestId('composerCancelButton') 41 - fireEvent.press(composerCancelButton) 42 - expect(mockedProps.onClose).toHaveBeenCalled() 43 - }) 44 - 45 - it('changes text and publishes post', async () => { 46 - const postSpy = jest.spyOn(apilib, 'post').mockResolvedValue({ 47 - uri: '', 48 - cid: '', 49 - }) 50 - const toastSpy = jest.spyOn(Toast, 'show') 51 - 52 - const wrapper = render(<ComposePost {...mockedProps} />) 53 - 54 - const composerTextInput = await wrapper.findByTestId('composerTextInput') 55 - fireEvent.changeText(composerTextInput, 'testing publish') 56 - 57 - const composerPublishButton = await wrapper.findByTestId( 58 - 'composerPublishButton', 59 - ) 60 - fireEvent.press(composerPublishButton) 61 - 62 - expect(postSpy).toHaveBeenCalledWith( 63 - mockedRootStore, 64 - 'testing publish', 65 - 'testUri', 66 - undefined, 67 - [], 68 - new Set<string>(), 69 - expect.anything(), 70 - ) 71 - 72 - // Waits for request to be resolved 73 - await waitFor(() => { 74 - expect(mockedProps.onPost).toHaveBeenCalled() 75 - expect(mockedProps.onClose).toHaveBeenCalled() 76 - expect(toastSpy).toHaveBeenCalledWith('Your reply has been published', { 77 - animation: true, 78 - duration: 3500, 79 - hideOnPress: true, 80 - position: 50, 81 - shadow: true, 82 - }) 83 - }) 84 - }) 85 - 86 - it('selects autocomplete item', async () => { 87 - jest 88 - .spyOn(React, 'useMemo') 89 - .mockReturnValueOnce(mockedAutocompleteViewStore) 90 - 91 - const {findAllByTestId} = render(<ComposePost {...mockedProps} />) 92 - const autocompleteButton = await findAllByTestId('autocompleteButton') 93 - 94 - fireEvent.press(autocompleteButton[0]) 95 - expect(mockedAutocompleteViewStore.setActive).toHaveBeenCalledWith(false) 96 - }) 97 - 98 - it('selects photos', async () => { 99 - const {findByTestId, queryByTestId} = render( 100 - <ComposePost {...mockedProps} />, 101 - ) 102 - let photoCarouselPickerView = queryByTestId('photoCarouselPickerView') 103 - expect(photoCarouselPickerView).toBeFalsy() 104 - 105 - const composerSelectPhotosButton = await findByTestId( 106 - 'composerSelectPhotosButton', 107 - ) 108 - fireEvent.press(composerSelectPhotosButton) 109 - 110 - photoCarouselPickerView = await findByTestId('photoCarouselPickerView') 111 - expect(photoCarouselPickerView).toBeTruthy() 112 - 113 - fireEvent.press(composerSelectPhotosButton) 114 - 115 - photoCarouselPickerView = queryByTestId('photoCarouselPickerView') 116 - expect(photoCarouselPickerView).toBeFalsy() 117 - }) 118 - })
-70
__tests__/view/com/composer/SelectedPhoto.test.tsx
··· 1 - import React from 'react' 2 - import {SelectedPhoto} from '../../../../src/view/com/composer/SelectedPhoto' 3 - import {cleanup, fireEvent, render} from '../../../../jest/test-utils' 4 - 5 - describe('SelectedPhoto', () => { 6 - const mockedProps = { 7 - selectedPhotos: ['mock-uri', 'mock-uri-2'], 8 - onSelectPhotos: jest.fn(), 9 - } 10 - 11 - afterAll(() => { 12 - jest.clearAllMocks() 13 - cleanup() 14 - }) 15 - 16 - it('has no photos to render', () => { 17 - const {queryByTestId} = render( 18 - <SelectedPhoto selectedPhotos={[]} onSelectPhotos={jest.fn()} />, 19 - ) 20 - const selectedPhotosView = queryByTestId('selectedPhotosView') 21 - expect(selectedPhotosView).toBeNull() 22 - 23 - const selectedPhotoImage = queryByTestId('selectedPhotoImage') 24 - expect(selectedPhotoImage).toBeNull() 25 - }) 26 - 27 - it('has 1 photos to render', async () => { 28 - const {findByTestId} = render( 29 - <SelectedPhoto 30 - selectedPhotos={['mock-uri']} 31 - onSelectPhotos={jest.fn()} 32 - />, 33 - ) 34 - const selectedPhotosView = await findByTestId('selectedPhotosView') 35 - expect(selectedPhotosView).toBeTruthy() 36 - 37 - const selectedPhotoImage = await findByTestId('selectedPhotoImage') 38 - expect(selectedPhotoImage).toBeTruthy() 39 - // @ts-expect-error 40 - expect(selectedPhotoImage).toHaveStyle({width: 250}) 41 - }) 42 - 43 - it('has 2 photos to render', async () => { 44 - const {findAllByTestId} = render(<SelectedPhoto {...mockedProps} />) 45 - const selectedPhotoImage = await findAllByTestId('selectedPhotoImage') 46 - expect(selectedPhotoImage[0]).toBeTruthy() 47 - // @ts-expect-error 48 - expect(selectedPhotoImage[0]).toHaveStyle({width: 175}) 49 - }) 50 - 51 - it('has 3 photos to render', async () => { 52 - const {findAllByTestId} = render( 53 - <SelectedPhoto 54 - selectedPhotos={['mock-uri', 'mock-uri-2', 'mock-uri-3']} 55 - onSelectPhotos={jest.fn()} 56 - />, 57 - ) 58 - const selectedPhotoImage = await findAllByTestId('selectedPhotoImage') 59 - expect(selectedPhotoImage[0]).toBeTruthy() 60 - // @ts-expect-error 61 - expect(selectedPhotoImage[0]).toHaveStyle({width: 85}) 62 - }) 63 - 64 - it('removes a photo', async () => { 65 - const {findAllByTestId} = render(<SelectedPhoto {...mockedProps} />) 66 - const removePhotoButton = await findAllByTestId('removePhotoButton') 67 - fireEvent.press(removePhotoButton[0]) 68 - expect(mockedProps.onSelectPhotos).toHaveBeenCalledWith(['mock-uri-2']) 69 - }) 70 - })
-58
__tests__/view/com/login/CreateAccount.test.tsx
··· 1 - import React from 'react' 2 - import {Keyboard} from 'react-native' 3 - import {CreateAccount} from '../../../../src/view/com/login/CreateAccount' 4 - import {cleanup, fireEvent, render} from '../../../../jest/test-utils' 5 - import { 6 - mockedSessionStore, 7 - mockedShellStore, 8 - } from '../../../../__mocks__/state-mock' 9 - 10 - describe('CreateAccount', () => { 11 - const mockedProps = { 12 - onPressBack: jest.fn(), 13 - } 14 - afterAll(() => { 15 - jest.clearAllMocks() 16 - cleanup() 17 - }) 18 - 19 - it('renders form and creates new account', async () => { 20 - const {findByTestId} = render(<CreateAccount {...mockedProps} />) 21 - 22 - const registerEmailInput = await findByTestId('registerEmailInput') 23 - expect(registerEmailInput).toBeTruthy() 24 - fireEvent.changeText(registerEmailInput, 'test@email.com') 25 - 26 - const registerHandleInput = await findByTestId('registerHandleInput') 27 - expect(registerHandleInput).toBeTruthy() 28 - fireEvent.changeText(registerHandleInput, 'test.handle') 29 - 30 - const registerPasswordInput = await findByTestId('registerPasswordInput') 31 - expect(registerPasswordInput).toBeTruthy() 32 - fireEvent.changeText(registerPasswordInput, 'testpass') 33 - 34 - const registerIs13Input = await findByTestId('registerIs13Input') 35 - expect(registerIs13Input).toBeTruthy() 36 - fireEvent.press(registerIs13Input) 37 - 38 - const createAccountButton = await findByTestId('createAccountButton') 39 - expect(createAccountButton).toBeTruthy() 40 - fireEvent.press(createAccountButton) 41 - 42 - expect(mockedSessionStore.createAccount).toHaveBeenCalled() 43 - }) 44 - 45 - it('renders and selects service', async () => { 46 - const keyboardSpy = jest.spyOn(Keyboard, 'dismiss') 47 - const {findByTestId} = render(<CreateAccount {...mockedProps} />) 48 - 49 - const registerSelectServiceButton = await findByTestId( 50 - 'registerSelectServiceButton', 51 - ) 52 - expect(registerSelectServiceButton).toBeTruthy() 53 - fireEvent.press(registerSelectServiceButton) 54 - 55 - expect(mockedShellStore.openModal).toHaveBeenCalled() 56 - expect(keyboardSpy).toHaveBeenCalled() 57 - }) 58 - })
-110
__tests__/view/com/profile/ProfileHeader.test.tsx
··· 1 - import React from 'react' 2 - import {cleanup, fireEvent, render} from '../../../../jest/test-utils' 3 - import {ProfileViewModel} from '../../../../src/state/models/profile-view' 4 - import {ProfileHeader} from '../../../../src/view/com/profile/ProfileHeader' 5 - import { 6 - mockedNavigationStore, 7 - mockedProfileStore, 8 - mockedShellStore, 9 - } from '../../../../__mocks__/state-mock' 10 - 11 - describe('ProfileHeader', () => { 12 - const mockedProps = { 13 - view: mockedProfileStore, 14 - onRefreshAll: jest.fn(), 15 - } 16 - afterAll(() => { 17 - jest.clearAllMocks() 18 - cleanup() 19 - }) 20 - 21 - it('renders ErrorMessage on error', async () => { 22 - const {findByTestId} = render( 23 - <ProfileHeader 24 - {...{ 25 - view: { 26 - ...mockedProfileStore, 27 - hasError: true, 28 - } as ProfileViewModel, 29 - onRefreshAll: jest.fn(), 30 - }} 31 - />, 32 - ) 33 - 34 - const profileHeaderHasError = await findByTestId('profileHeaderHasError') 35 - expect(profileHeaderHasError).toBeTruthy() 36 - }) 37 - 38 - it('presses and opens edit profile', async () => { 39 - const {findByTestId} = render(<ProfileHeader {...mockedProps} />) 40 - 41 - const profileHeaderEditProfileButton = await findByTestId( 42 - 'profileHeaderEditProfileButton', 43 - ) 44 - expect(profileHeaderEditProfileButton).toBeTruthy() 45 - fireEvent.press(profileHeaderEditProfileButton) 46 - 47 - expect(mockedShellStore.openModal).toHaveBeenCalled() 48 - }) 49 - 50 - it('presses and opens followers page', async () => { 51 - const {findByTestId} = render(<ProfileHeader {...mockedProps} />) 52 - 53 - const profileHeaderFollowersButton = await findByTestId( 54 - 'profileHeaderFollowersButton', 55 - ) 56 - expect(profileHeaderFollowersButton).toBeTruthy() 57 - fireEvent.press(profileHeaderFollowersButton) 58 - 59 - expect(mockedNavigationStore.navigate).toHaveBeenCalledWith( 60 - '/profile/testhandle/followers', 61 - ) 62 - }) 63 - 64 - // TODO - this will only pass if the profile has an avatar image set 65 - // it('presses and opens avatar modal', async () => { 66 - // const {findByTestId} = render(<ProfileHeader {...mockedProps} />) 67 - 68 - // const profileHeaderAviButton = await findByTestId('profileHeaderAviButton') 69 - // expect(profileHeaderAviButton).toBeTruthy() 70 - // fireEvent.press(profileHeaderAviButton) 71 - 72 - // expect(mockedShellStore.openLightbox).toHaveBeenCalled() 73 - // }) 74 - 75 - it('presses and opens follows page', async () => { 76 - const {findByTestId} = render(<ProfileHeader {...mockedProps} />) 77 - 78 - const profileHeaderFollowsButton = await findByTestId( 79 - 'profileHeaderFollowsButton', 80 - ) 81 - expect(profileHeaderFollowsButton).toBeTruthy() 82 - fireEvent.press(profileHeaderFollowsButton) 83 - 84 - expect(mockedNavigationStore.navigate).toHaveBeenCalledWith( 85 - '/profile/testhandle/follows', 86 - ) 87 - }) 88 - 89 - it('toggles following', async () => { 90 - const {findByTestId} = render( 91 - <ProfileHeader 92 - {...{ 93 - view: { 94 - ...mockedProfileStore, 95 - did: 'test did 2', 96 - } as ProfileViewModel, 97 - onRefreshAll: jest.fn(), 98 - }} 99 - />, 100 - ) 101 - 102 - const profileHeaderToggleFollowButton = await findByTestId( 103 - 'profileHeaderToggleFollowButton', 104 - ) 105 - expect(profileHeaderToggleFollowButton).toBeTruthy() 106 - fireEvent.press(profileHeaderToggleFollowButton) 107 - 108 - expect(mockedProps.view.toggleFollowing).toHaveBeenCalled() 109 - }) 110 - })
-17
__tests__/view/lib/useAnimatedValue.test.tsx
··· 1 - import {renderHook} from '../../../jest/test-utils' 2 - import {useAnimatedValue} from '../../../src/view/lib/hooks/useAnimatedValue' 3 - 4 - describe('useAnimatedValue', () => { 5 - it('creates an Animated.Value with the initial value passed to the hook', () => { 6 - const {result} = renderHook(() => useAnimatedValue(10)) 7 - // @ts-expect-error 8 - expect(result.current.__getValue()).toEqual(10) 9 - }) 10 - 11 - it('returns the same Animated.Value instance on subsequent renders', () => { 12 - const {result, rerender} = renderHook(() => useAnimatedValue(10)) 13 - const firstValue = result.current 14 - rerender({}) 15 - expect(result.current).toBe(firstValue) 16 - }) 17 - })
-49
__tests__/view/lib/useOnMainScroll.test.tsx
··· 1 - import React from 'react' 2 - import {fireEvent, render} from '../../../jest/test-utils' 3 - import {Home} from '../../../src/view/screens/Home' 4 - import {mockedRootStore, mockedShellStore} from '../../../__mocks__/state-mock' 5 - 6 - describe('useOnMainScroll', () => { 7 - const mockedProps = { 8 - navIdx: '0-0', 9 - params: {}, 10 - visible: true, 11 - } 12 - 13 - it('toggles minimalShellMode to true', () => { 14 - jest.useFakeTimers() 15 - const {getByTestId} = render(<Home {...mockedProps} />) 16 - 17 - fireEvent.scroll(getByTestId('homeFeed'), { 18 - nativeEvent: { 19 - contentOffset: {y: 20}, 20 - contentSize: {height: 100}, 21 - layoutMeasurement: {height: 50}, 22 - }, 23 - }) 24 - 25 - expect(mockedRootStore.shell.setMinimalShellMode).toHaveBeenCalledWith(true) 26 - }) 27 - 28 - it('toggles minimalShellMode to false', () => { 29 - jest.useFakeTimers() 30 - const {getByTestId} = render(<Home {...mockedProps} />, { 31 - ...mockedRootStore, 32 - shell: { 33 - ...mockedShellStore, 34 - minimalShellMode: true, 35 - }, 36 - }) 37 - 38 - fireEvent.scroll(getByTestId('homeFeed'), { 39 - nativeEvent: { 40 - contentOffset: {y: 0}, 41 - contentSize: {height: 100}, 42 - layoutMeasurement: {height: 50}, 43 - }, 44 - }) 45 - expect(mockedRootStore.shell.setMinimalShellMode).toHaveBeenCalledWith( 46 - false, 47 - ) 48 - }) 49 - })
-37
__tests__/view/screens/Login.test.tsx
··· 1 - import React from 'react' 2 - import {Login} from '../../../src/view/screens/Login' 3 - import {cleanup, fireEvent, render} from '../../../jest/test-utils' 4 - 5 - describe('Login', () => { 6 - afterAll(() => { 7 - jest.clearAllMocks() 8 - cleanup() 9 - }) 10 - 11 - it('renders initial screen', () => { 12 - const {getByTestId} = render(<Login />) 13 - const signUpScreen = getByTestId('signinOrCreateAccount') 14 - 15 - expect(signUpScreen).toBeTruthy() 16 - }) 17 - 18 - it('renders Signin screen', () => { 19 - const {getByTestId} = render(<Login />) 20 - const signInButton = getByTestId('signInButton') 21 - 22 - fireEvent.press(signInButton) 23 - 24 - const signInScreen = getByTestId('signIn') 25 - expect(signInScreen).toBeTruthy() 26 - }) 27 - 28 - it('renders CreateAccount screen', () => { 29 - const {getByTestId} = render(<Login />) 30 - const createAccountButton = getByTestId('createAccountButton') 31 - 32 - fireEvent.press(createAccountButton) 33 - 34 - const createAccountScreen = getByTestId('createAccount') 35 - expect(createAccountScreen).toBeTruthy() 36 - }) 37 - })
-21
__tests__/view/screens/NotFound.test.tsx
··· 1 - import React from 'react' 2 - import {NotFound} from '../../../src/view/screens/NotFound' 3 - import {cleanup, fireEvent, render} from '../../../jest/test-utils' 4 - import {mockedNavigationStore} from '../../../__mocks__/state-mock' 5 - 6 - describe('NotFound', () => { 7 - afterAll(() => { 8 - jest.clearAllMocks() 9 - cleanup() 10 - }) 11 - 12 - it('navigates home', async () => { 13 - const navigationSpy = jest.spyOn(mockedNavigationStore, 'navigate') 14 - const {getByTestId} = render(<NotFound />) 15 - const navigateHomeButton = getByTestId('navigateHomeButton') 16 - 17 - fireEvent.press(navigateHomeButton) 18 - 19 - expect(navigationSpy).toHaveBeenCalledWith('/') 20 - }) 21 - })
-30
__tests__/view/screens/Search.test.tsx
··· 1 - import React from 'react' 2 - import {Search} from '../../../src/view/screens/Search' 3 - import {cleanup, fireEvent, render} from '../../../jest/test-utils' 4 - 5 - describe('Search', () => { 6 - jest.useFakeTimers() 7 - const mockedProps = { 8 - navIdx: '0-0', 9 - params: { 10 - name: 'test name', 11 - }, 12 - visible: true, 13 - } 14 - 15 - afterAll(() => { 16 - jest.clearAllMocks() 17 - cleanup() 18 - }) 19 - 20 - it('renders with query', async () => { 21 - const {findByTestId} = render(<Search {...mockedProps} />) 22 - const searchTextInput = await findByTestId('searchTextInput') 23 - 24 - expect(searchTextInput).toBeTruthy() 25 - fireEvent.changeText(searchTextInput, 'test') 26 - 27 - const searchScrollView = await findByTestId('searchScrollView') 28 - expect(searchScrollView).toBeTruthy() 29 - }) 30 - })
-57
__tests__/view/shell/mobile/Menu.test.tsx
··· 1 - import React from 'react' 2 - import {Menu} from '../../../../src/view/shell/mobile/Menu' 3 - import {cleanup, fireEvent, render} from '../../../../jest/test-utils' 4 - import {mockedNavigationStore} from '../../../../__mocks__/state-mock' 5 - 6 - describe('Menu', () => { 7 - const onCloseMock = jest.fn() 8 - 9 - const mockedProps = { 10 - visible: true, 11 - onClose: onCloseMock, 12 - } 13 - 14 - afterAll(() => { 15 - jest.clearAllMocks() 16 - cleanup() 17 - }) 18 - 19 - it('renders menu', () => { 20 - const {getByTestId} = render(<Menu {...mockedProps} />) 21 - 22 - const menuView = getByTestId('menuView') 23 - 24 - expect(menuView).toBeTruthy() 25 - }) 26 - 27 - it('presses profile card button', () => { 28 - const {getByTestId} = render(<Menu {...mockedProps} />) 29 - 30 - const profileCardButton = getByTestId('profileCardButton') 31 - fireEvent.press(profileCardButton) 32 - 33 - expect(onCloseMock).toHaveBeenCalled() 34 - expect(mockedNavigationStore.switchTo).toHaveBeenCalledWith(0, true) 35 - }) 36 - 37 - it('presses search button', () => { 38 - const {getByTestId} = render(<Menu {...mockedProps} />) 39 - 40 - const searchBtn = getByTestId('searchBtn') 41 - fireEvent.press(searchBtn) 42 - 43 - expect(onCloseMock).toHaveBeenCalled() 44 - expect(mockedNavigationStore.switchTo).toHaveBeenCalledWith(0, true) 45 - expect(mockedNavigationStore.navigate).toHaveBeenCalledWith('/search') 46 - }) 47 - 48 - it("presses notifications menu item' button", () => { 49 - const {getByTestId} = render(<Menu {...mockedProps} />) 50 - 51 - const menuItemButton = getByTestId('menuItemButton-Notifications') 52 - fireEvent.press(menuItemButton) 53 - 54 - expect(onCloseMock).toHaveBeenCalled() 55 - expect(mockedNavigationStore.switchTo).toHaveBeenCalledWith(1, true) 56 - }) 57 - })
-100
__tests__/view/shell/mobile/TabsSelector.test.tsx
··· 1 - import React from 'react' 2 - import {Animated} from 'react-native' 3 - import {TabsSelector} from '../../../../src/view/shell/mobile/TabsSelector' 4 - import {cleanup, fireEvent, render} from '../../../../jest/test-utils' 5 - import {mockedNavigationStore} from '../../../../__mocks__/state-mock' 6 - 7 - describe('TabsSelector', () => { 8 - const onCloseMock = jest.fn() 9 - 10 - const mockedProps = { 11 - active: true, 12 - tabMenuInterp: new Animated.Value(0), 13 - onClose: onCloseMock, 14 - } 15 - 16 - afterAll(() => { 17 - jest.clearAllMocks() 18 - cleanup() 19 - }) 20 - 21 - it('renders tabs selector', () => { 22 - const {getByTestId} = render(<TabsSelector {...mockedProps} />) 23 - 24 - const tabsSelectorView = getByTestId('tabsSelectorView') 25 - 26 - expect(tabsSelectorView).toBeTruthy() 27 - }) 28 - 29 - it('renders nothing if inactive', () => { 30 - const {getByTestId} = render( 31 - <TabsSelector {...{...mockedProps, active: false}} />, 32 - ) 33 - 34 - const emptyView = getByTestId('emptyView') 35 - 36 - expect(emptyView).toBeTruthy() 37 - }) 38 - 39 - // TODO - this throws currently, but the tabs selector isnt being used atm so I just disabled -prf 40 - // it('presses share button', () => { 41 - // const shareSpy = jest.spyOn(Share, 'share') 42 - // const {getByTestId} = render(<TabsSelector {...mockedProps} />) 43 - 44 - // const shareButton = getByTestId('shareButton') 45 - // fireEvent.press(shareButton) 46 - 47 - // expect(onCloseMock).toHaveBeenCalled() 48 - // expect(shareSpy).toHaveBeenCalledWith({url: 'https://bsky.app/'}) 49 - // }) 50 - 51 - it('presses clone button', () => { 52 - const {getByTestId} = render(<TabsSelector {...mockedProps} />) 53 - 54 - const cloneButton = getByTestId('cloneButton') 55 - fireEvent.press(cloneButton) 56 - 57 - expect(onCloseMock).toHaveBeenCalled() 58 - expect(mockedNavigationStore.newTab).toHaveBeenCalled() 59 - }) 60 - 61 - it('presses new tab button', () => { 62 - const {getByTestId} = render(<TabsSelector {...mockedProps} />) 63 - 64 - const newTabButton = getByTestId('newTabButton') 65 - fireEvent.press(newTabButton) 66 - 67 - expect(onCloseMock).toHaveBeenCalled() 68 - expect(mockedNavigationStore.newTab).toHaveBeenCalledWith('/') 69 - }) 70 - 71 - it('presses change tab button', () => { 72 - const {getAllByTestId} = render(<TabsSelector {...mockedProps} />) 73 - 74 - const changeTabButton = getAllByTestId('changeTabButton') 75 - fireEvent.press(changeTabButton[0]) 76 - 77 - expect(onCloseMock).toHaveBeenCalled() 78 - expect(mockedNavigationStore.newTab).toHaveBeenCalledWith('/') 79 - }) 80 - 81 - it('presses close tab button', () => { 82 - const {getAllByTestId} = render(<TabsSelector {...mockedProps} />) 83 - 84 - const closeTabButton = getAllByTestId('closeTabButton') 85 - fireEvent.press(closeTabButton[0]) 86 - 87 - expect(onCloseMock).toHaveBeenCalled() 88 - expect(mockedNavigationStore.setActiveTab).toHaveBeenCalledWith(0) 89 - }) 90 - 91 - it('presses swipes to close the tab', () => { 92 - const {getByTestId} = render(<TabsSelector {...mockedProps} />) 93 - 94 - const tabsSwipable = getByTestId('tabsSwipable') 95 - fireEvent(tabsSwipable, 'swipeableRightOpen') 96 - 97 - expect(onCloseMock).toHaveBeenCalled() 98 - expect(mockedNavigationStore.setActiveTab).toHaveBeenCalledWith(0) 99 - }) 100 - })
+2 -2
android/app/build.gradle
··· 14 14 // The root of your project, i.e. where "package.json" lives. Default is '..' 15 15 // root = file("../") 16 16 // The folder where the react-native NPM package is. Default is ../node_modules/react-native 17 - // reactNativeDir = file("../node-modules/react-native") 17 + // reactNativeDir = file("../node_modules/react-native") 18 18 // The folder where the react-native Codegen package is. Default is ../node_modules/react-native-codegen 19 - // codegenDir = file("../node-modules/react-native-codegen") 19 + // codegenDir = file("../node_modules/react-native-codegen") 20 20 // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js 21 21 // cliFile = file("../node_modules/react-native/cli.js") 22 22 /* Variants */
+11
babel.config.js
··· 14 14 verbose: false, 15 15 }, 16 16 ], 17 + [ 18 + 'module-resolver', 19 + { 20 + alias: { 21 + // This needs to be mirrored in tsconfig.json 22 + lib: './src/lib', 23 + state: './src/state', 24 + view: './src/view', 25 + }, 26 + }, 27 + ], 17 28 'react-native-reanimated/plugin', // NOTE: this plugin MUST be last 18 29 ], 19 30 }
+12
e2e/jest.config.js
··· 1 + /** @type {import('@jest/types').Config.InitialOptions} */ 2 + module.exports = { 3 + rootDir: '..', 4 + testMatch: ['<rootDir>/e2e/**/*.test.js'], 5 + testTimeout: 120000, 6 + maxWorkers: 1, 7 + globalSetup: 'detox/runners/jest/globalSetup', 8 + globalTeardown: 'detox/runners/jest/globalTeardown', 9 + reporters: ['detox/runners/jest/reporter'], 10 + testEnvironment: 'detox/runners/jest/testEnvironment', 11 + verbose: true, 12 + }
+77
e2e/tests/happyPath.test.js
··· 1 + /* eslint-env detox/detox */ 2 + 3 + describe('Example', () => { 4 + async function grantAccessToUserWithValidCredentials( 5 + username, 6 + {takeScreenshots} = {takeScreenshots: false}, 7 + ) { 8 + await element(by.id('signInButton')).tap() 9 + if (takeScreenshots) { 10 + await device.takeScreenshot('1- opened sign-in screen') 11 + } 12 + await element(by.id('loginSelectServiceButton')).tap() 13 + if (takeScreenshots) { 14 + await device.takeScreenshot('2- opened service selector') 15 + } 16 + await element(by.id('localDevServerButton')).tap() 17 + if (takeScreenshots) { 18 + await device.takeScreenshot('3- selected local dev server') 19 + } 20 + await element(by.id('loginUsernameInput')).typeText(username) 21 + await element(by.id('loginPasswordInput')).typeText('hunter2') 22 + if (takeScreenshots) { 23 + await device.takeScreenshot('4- entered username and password') 24 + } 25 + await element(by.id('loginNextButton')).tap() 26 + } 27 + 28 + beforeEach(async () => { 29 + await device.uninstallApp() 30 + await device.installApp() 31 + await device.launchApp({permissions: {notifications: 'YES'}}) 32 + }) 33 + 34 + it('As Alice, I can login', async () => { 35 + await expect(element(by.id('signInButton'))).toBeVisible() 36 + await grantAccessToUserWithValidCredentials('alice', { 37 + takeScreenshots: true, 38 + }) 39 + await device.takeScreenshot('5- opened home screen') 40 + }) 41 + 42 + it('As Alice, I can login, and post a text', async () => { 43 + await grantAccessToUserWithValidCredentials('alice') 44 + await element(by.id('composeFAB')).tap() 45 + await device.takeScreenshot('1- opened composer') 46 + await element(by.id('composerTextInput')).typeText( 47 + 'Greetings earthlings, I come in peace... and to run some tests.', 48 + ) 49 + await device.takeScreenshot('2- entered text') 50 + await element(by.id('composerPublishButton')).tap() 51 + await device.takeScreenshot('3- opened general section') 52 + await expect(element(by.id('composeFAB'))).toBeVisible() 53 + }) 54 + 55 + it('I can create a new account', async () => { 56 + await element(by.id('createAccountButton')).tap() 57 + await device.takeScreenshot('1- opened create account screen') 58 + await element(by.id('registerSelectServiceButton')).tap() 59 + await device.takeScreenshot('2- opened service selector') 60 + await element(by.id('localDevServerButton')).tap() 61 + await device.takeScreenshot('3- selected local dev server') 62 + await element(by.id('registerEmailInput')).typeText('example@test.com') 63 + await element(by.id('registerPasswordInput')).typeText('hunter2') 64 + await element(by.id('registerHandleInput')).typeText('e2e-test') 65 + await element(by.id('registerIs13Input')).tap() 66 + await device.takeScreenshot('4- entered account details') 67 + await element(by.id('createAccountButton')).tap() 68 + await expect(element(by.id('onboardFeatureExplainerSkipBtn'))).toBeVisible() 69 + await expect(element(by.id('onboardFeatureExplainerNextBtn'))).toBeVisible() 70 + await device.takeScreenshot('5- onboard feature explainer') 71 + await element(by.id('onboardFeatureExplainerSkipBtn')).tap() 72 + await expect(element(by.id('onboardFollowsSkipBtn'))).toBeVisible() 73 + await expect(element(by.id('onboardFollowsNextBtn'))).toBeVisible() 74 + await device.takeScreenshot('6- onboard follows recommender') 75 + await element(by.id('onboardFollowsSkipBtn')).tap() 76 + }) 77 + })
+25
ios/Podfile
··· 4 4 platform :ios, min_ios_version_supported 5 5 prepare_react_native_project! 6 6 7 + # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set. 8 + # because `react-native-flipper` depends on (FlipperKit,...) that will be excluded 9 + # 10 + # To fix this you can also exclude `react-native-flipper` using a `react-native.config.js` 11 + # ```js 12 + # module.exports = { 13 + # dependencies: { 14 + # ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}), 15 + # ``` 7 16 flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled 8 17 9 18 linkage = ENV['USE_FRAMEWORKS'] ··· 35 44 :app_path => "#{Pod::Config.instance.installation_root}/.." 36 45 ) 37 46 47 + # react-native-permissions settings 48 + permissions_path = '../node_modules/react-native-permissions/ios' 49 + pod 'Permission-Camera', :path => "#{permissions_path}/Camera" 50 + pod 'Permission-PhotoLibrary', :path => "#{permissions_path}/PhotoLibrary" 51 + 38 52 target 'appTests' do 39 53 inherit! :complete 40 54 # Pods for testing 41 55 end 42 56 43 57 post_install do |installer| 58 + # Temporary fix until CocoaPods 1.12.0 is released. 59 + # https://github.com/CocoaPods/CocoaPods/issues/11402#issuecomment-1201464693 60 + installer.pods_project.targets.each do |target| 61 + if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle" 62 + target.build_configurations.each do |config| 63 + config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO' 64 + end 65 + end 66 + end 67 + 68 + 44 69 react_native_post_install( 45 70 installer, 46 71 # Set `mac_catalyst_enabled` to `true` in order to apply patches
+306 -253
ios/Podfile.lock
··· 3 3 - BVLinearGradient (2.6.2): 4 4 - React-Core 5 5 - DoubleConversion (1.1.6) 6 - - FBLazyVector (0.71.0) 7 - - FBReactNativeSpec (0.71.0): 6 + - FBLazyVector (0.71.1) 7 + - FBReactNativeSpec (0.71.1): 8 8 - RCT-Folly (= 2021.07.22.00) 9 - - RCTRequired (= 0.71.0) 10 - - RCTTypeSafety (= 0.71.0) 11 - - React-Core (= 0.71.0) 12 - - React-jsi (= 0.71.0) 13 - - ReactCommon/turbomodule/core (= 0.71.0) 9 + - RCTRequired (= 0.71.1) 10 + - RCTTypeSafety (= 0.71.1) 11 + - React-Core (= 0.71.1) 12 + - React-jsi (= 0.71.1) 13 + - ReactCommon/turbomodule/core (= 0.71.1) 14 14 - fmt (6.2.1) 15 15 - glog (0.3.5) 16 - - hermes-engine (0.71.0): 17 - - hermes-engine/Pre-built (= 0.71.0) 18 - - hermes-engine/Pre-built (0.71.0) 16 + - hermes-engine (0.71.1): 17 + - hermes-engine/Pre-built (= 0.71.1) 18 + - hermes-engine/Pre-built (0.71.1) 19 19 - libevent (2.1.12) 20 + - libwebp (1.2.4): 21 + - libwebp/demux (= 1.2.4) 22 + - libwebp/mux (= 1.2.4) 23 + - libwebp/webp (= 1.2.4) 24 + - libwebp/demux (1.2.4): 25 + - libwebp/webp 26 + - libwebp/mux (1.2.4): 27 + - libwebp/demux 28 + - libwebp/webp (1.2.4) 29 + - Permission-Camera (3.6.1): 30 + - RNPermissions 31 + - Permission-PhotoLibrary (3.6.1): 32 + - RNPermissions 20 33 - RCT-Folly (2021.07.22.00): 21 34 - boost 22 35 - DoubleConversion ··· 34 47 - fmt (~> 6.2.1) 35 48 - glog 36 49 - libevent 37 - - RCTRequired (0.71.0) 38 - - RCTTypeSafety (0.71.0): 39 - - FBLazyVector (= 0.71.0) 40 - - RCTRequired (= 0.71.0) 41 - - React-Core (= 0.71.0) 42 - - React (0.71.0): 43 - - React-Core (= 0.71.0) 44 - - React-Core/DevSupport (= 0.71.0) 45 - - React-Core/RCTWebSocket (= 0.71.0) 46 - - React-RCTActionSheet (= 0.71.0) 47 - - React-RCTAnimation (= 0.71.0) 48 - - React-RCTBlob (= 0.71.0) 49 - - React-RCTImage (= 0.71.0) 50 - - React-RCTLinking (= 0.71.0) 51 - - React-RCTNetwork (= 0.71.0) 52 - - React-RCTSettings (= 0.71.0) 53 - - React-RCTText (= 0.71.0) 54 - - React-RCTVibration (= 0.71.0) 55 - - React-callinvoker (0.71.0) 56 - - React-Codegen (0.71.0): 50 + - RCTRequired (0.71.1) 51 + - RCTTypeSafety (0.71.1): 52 + - FBLazyVector (= 0.71.1) 53 + - RCTRequired (= 0.71.1) 54 + - React-Core (= 0.71.1) 55 + - React (0.71.1): 56 + - React-Core (= 0.71.1) 57 + - React-Core/DevSupport (= 0.71.1) 58 + - React-Core/RCTWebSocket (= 0.71.1) 59 + - React-RCTActionSheet (= 0.71.1) 60 + - React-RCTAnimation (= 0.71.1) 61 + - React-RCTBlob (= 0.71.1) 62 + - React-RCTImage (= 0.71.1) 63 + - React-RCTLinking (= 0.71.1) 64 + - React-RCTNetwork (= 0.71.1) 65 + - React-RCTSettings (= 0.71.1) 66 + - React-RCTText (= 0.71.1) 67 + - React-RCTVibration (= 0.71.1) 68 + - React-callinvoker (0.71.1) 69 + - React-Codegen (0.71.1): 57 70 - FBReactNativeSpec 58 71 - hermes-engine 59 72 - RCT-Folly ··· 64 77 - React-jsiexecutor 65 78 - ReactCommon/turbomodule/bridging 66 79 - ReactCommon/turbomodule/core 67 - - React-Core (0.71.0): 80 + - React-Core (0.71.1): 68 81 - glog 69 82 - RCT-Folly (= 2021.07.22.00) 70 - - React-Core/Default (= 0.71.0) 71 - - React-cxxreact (= 0.71.0) 72 - - React-jsi (= 0.71.0) 73 - - React-jsiexecutor (= 0.71.0) 74 - - React-perflogger (= 0.71.0) 83 + - React-Core/Default (= 0.71.1) 84 + - React-cxxreact (= 0.71.1) 85 + - React-jsi (= 0.71.1) 86 + - React-jsiexecutor (= 0.71.1) 87 + - React-perflogger (= 0.71.1) 75 88 - Yoga 76 - - React-Core/CoreModulesHeaders (0.71.0): 89 + - React-Core/CoreModulesHeaders (0.71.1): 77 90 - glog 78 91 - RCT-Folly (= 2021.07.22.00) 79 92 - React-Core/Default 80 - - React-cxxreact (= 0.71.0) 81 - - React-jsi (= 0.71.0) 82 - - React-jsiexecutor (= 0.71.0) 83 - - React-perflogger (= 0.71.0) 93 + - React-cxxreact (= 0.71.1) 94 + - React-jsi (= 0.71.1) 95 + - React-jsiexecutor (= 0.71.1) 96 + - React-perflogger (= 0.71.1) 84 97 - Yoga 85 - - React-Core/Default (0.71.0): 98 + - React-Core/Default (0.71.1): 86 99 - glog 87 100 - RCT-Folly (= 2021.07.22.00) 88 - - React-cxxreact (= 0.71.0) 89 - - React-jsi (= 0.71.0) 90 - - React-jsiexecutor (= 0.71.0) 91 - - React-perflogger (= 0.71.0) 101 + - React-cxxreact (= 0.71.1) 102 + - React-jsi (= 0.71.1) 103 + - React-jsiexecutor (= 0.71.1) 104 + - React-perflogger (= 0.71.1) 92 105 - Yoga 93 - - React-Core/DevSupport (0.71.0): 106 + - React-Core/DevSupport (0.71.1): 94 107 - glog 95 108 - RCT-Folly (= 2021.07.22.00) 96 - - React-Core/Default (= 0.71.0) 97 - - React-Core/RCTWebSocket (= 0.71.0) 98 - - React-cxxreact (= 0.71.0) 99 - - React-jsi (= 0.71.0) 100 - - React-jsiexecutor (= 0.71.0) 101 - - React-jsinspector (= 0.71.0) 102 - - React-perflogger (= 0.71.0) 109 + - React-Core/Default (= 0.71.1) 110 + - React-Core/RCTWebSocket (= 0.71.1) 111 + - React-cxxreact (= 0.71.1) 112 + - React-jsi (= 0.71.1) 113 + - React-jsiexecutor (= 0.71.1) 114 + - React-jsinspector (= 0.71.1) 115 + - React-perflogger (= 0.71.1) 103 116 - Yoga 104 - - React-Core/RCTActionSheetHeaders (0.71.0): 117 + - React-Core/RCTActionSheetHeaders (0.71.1): 105 118 - glog 106 119 - RCT-Folly (= 2021.07.22.00) 107 120 - React-Core/Default 108 - - React-cxxreact (= 0.71.0) 109 - - React-jsi (= 0.71.0) 110 - - React-jsiexecutor (= 0.71.0) 111 - - React-perflogger (= 0.71.0) 121 + - React-cxxreact (= 0.71.1) 122 + - React-jsi (= 0.71.1) 123 + - React-jsiexecutor (= 0.71.1) 124 + - React-perflogger (= 0.71.1) 112 125 - Yoga 113 - - React-Core/RCTAnimationHeaders (0.71.0): 126 + - React-Core/RCTAnimationHeaders (0.71.1): 114 127 - glog 115 128 - RCT-Folly (= 2021.07.22.00) 116 129 - React-Core/Default 117 - - React-cxxreact (= 0.71.0) 118 - - React-jsi (= 0.71.0) 119 - - React-jsiexecutor (= 0.71.0) 120 - - React-perflogger (= 0.71.0) 130 + - React-cxxreact (= 0.71.1) 131 + - React-jsi (= 0.71.1) 132 + - React-jsiexecutor (= 0.71.1) 133 + - React-perflogger (= 0.71.1) 121 134 - Yoga 122 - - React-Core/RCTBlobHeaders (0.71.0): 135 + - React-Core/RCTBlobHeaders (0.71.1): 123 136 - glog 124 137 - RCT-Folly (= 2021.07.22.00) 125 138 - React-Core/Default 126 - - React-cxxreact (= 0.71.0) 127 - - React-jsi (= 0.71.0) 128 - - React-jsiexecutor (= 0.71.0) 129 - - React-perflogger (= 0.71.0) 139 + - React-cxxreact (= 0.71.1) 140 + - React-jsi (= 0.71.1) 141 + - React-jsiexecutor (= 0.71.1) 142 + - React-perflogger (= 0.71.1) 130 143 - Yoga 131 - - React-Core/RCTImageHeaders (0.71.0): 144 + - React-Core/RCTImageHeaders (0.71.1): 132 145 - glog 133 146 - RCT-Folly (= 2021.07.22.00) 134 147 - React-Core/Default 135 - - React-cxxreact (= 0.71.0) 136 - - React-jsi (= 0.71.0) 137 - - React-jsiexecutor (= 0.71.0) 138 - - React-perflogger (= 0.71.0) 148 + - React-cxxreact (= 0.71.1) 149 + - React-jsi (= 0.71.1) 150 + - React-jsiexecutor (= 0.71.1) 151 + - React-perflogger (= 0.71.1) 139 152 - Yoga 140 - - React-Core/RCTLinkingHeaders (0.71.0): 153 + - React-Core/RCTLinkingHeaders (0.71.1): 141 154 - glog 142 155 - RCT-Folly (= 2021.07.22.00) 143 156 - React-Core/Default 144 - - React-cxxreact (= 0.71.0) 145 - - React-jsi (= 0.71.0) 146 - - React-jsiexecutor (= 0.71.0) 147 - - React-perflogger (= 0.71.0) 157 + - React-cxxreact (= 0.71.1) 158 + - React-jsi (= 0.71.1) 159 + - React-jsiexecutor (= 0.71.1) 160 + - React-perflogger (= 0.71.1) 148 161 - Yoga 149 - - React-Core/RCTNetworkHeaders (0.71.0): 162 + - React-Core/RCTNetworkHeaders (0.71.1): 150 163 - glog 151 164 - RCT-Folly (= 2021.07.22.00) 152 165 - React-Core/Default 153 - - React-cxxreact (= 0.71.0) 154 - - React-jsi (= 0.71.0) 155 - - React-jsiexecutor (= 0.71.0) 156 - - React-perflogger (= 0.71.0) 166 + - React-cxxreact (= 0.71.1) 167 + - React-jsi (= 0.71.1) 168 + - React-jsiexecutor (= 0.71.1) 169 + - React-perflogger (= 0.71.1) 157 170 - Yoga 158 - - React-Core/RCTSettingsHeaders (0.71.0): 171 + - React-Core/RCTSettingsHeaders (0.71.1): 159 172 - glog 160 173 - RCT-Folly (= 2021.07.22.00) 161 174 - React-Core/Default 162 - - React-cxxreact (= 0.71.0) 163 - - React-jsi (= 0.71.0) 164 - - React-jsiexecutor (= 0.71.0) 165 - - React-perflogger (= 0.71.0) 175 + - React-cxxreact (= 0.71.1) 176 + - React-jsi (= 0.71.1) 177 + - React-jsiexecutor (= 0.71.1) 178 + - React-perflogger (= 0.71.1) 166 179 - Yoga 167 - - React-Core/RCTTextHeaders (0.71.0): 180 + - React-Core/RCTTextHeaders (0.71.1): 168 181 - glog 169 182 - RCT-Folly (= 2021.07.22.00) 170 183 - React-Core/Default 171 - - React-cxxreact (= 0.71.0) 172 - - React-jsi (= 0.71.0) 173 - - React-jsiexecutor (= 0.71.0) 174 - - React-perflogger (= 0.71.0) 184 + - React-cxxreact (= 0.71.1) 185 + - React-jsi (= 0.71.1) 186 + - React-jsiexecutor (= 0.71.1) 187 + - React-perflogger (= 0.71.1) 175 188 - Yoga 176 - - React-Core/RCTVibrationHeaders (0.71.0): 189 + - React-Core/RCTVibrationHeaders (0.71.1): 177 190 - glog 178 191 - RCT-Folly (= 2021.07.22.00) 179 192 - React-Core/Default 180 - - React-cxxreact (= 0.71.0) 181 - - React-jsi (= 0.71.0) 182 - - React-jsiexecutor (= 0.71.0) 183 - - React-perflogger (= 0.71.0) 193 + - React-cxxreact (= 0.71.1) 194 + - React-jsi (= 0.71.1) 195 + - React-jsiexecutor (= 0.71.1) 196 + - React-perflogger (= 0.71.1) 184 197 - Yoga 185 - - React-Core/RCTWebSocket (0.71.0): 198 + - React-Core/RCTWebSocket (0.71.1): 186 199 - glog 187 200 - RCT-Folly (= 2021.07.22.00) 188 - - React-Core/Default (= 0.71.0) 189 - - React-cxxreact (= 0.71.0) 190 - - React-jsi (= 0.71.0) 191 - - React-jsiexecutor (= 0.71.0) 192 - - React-perflogger (= 0.71.0) 201 + - React-Core/Default (= 0.71.1) 202 + - React-cxxreact (= 0.71.1) 203 + - React-jsi (= 0.71.1) 204 + - React-jsiexecutor (= 0.71.1) 205 + - React-perflogger (= 0.71.1) 193 206 - Yoga 194 - - React-CoreModules (0.71.0): 207 + - React-CoreModules (0.71.1): 195 208 - RCT-Folly (= 2021.07.22.00) 196 - - RCTTypeSafety (= 0.71.0) 197 - - React-Codegen (= 0.71.0) 198 - - React-Core/CoreModulesHeaders (= 0.71.0) 199 - - React-jsi (= 0.71.0) 200 - - React-RCTImage (= 0.71.0) 201 - - ReactCommon/turbomodule/core (= 0.71.0) 202 - - React-cxxreact (0.71.0): 209 + - RCTTypeSafety (= 0.71.1) 210 + - React-Codegen (= 0.71.1) 211 + - React-Core/CoreModulesHeaders (= 0.71.1) 212 + - React-jsi (= 0.71.1) 213 + - React-RCTImage (= 0.71.1) 214 + - ReactCommon/turbomodule/core (= 0.71.1) 215 + - React-cxxreact (0.71.1): 203 216 - boost (= 1.76.0) 204 217 - DoubleConversion 205 218 - glog 206 219 - RCT-Folly (= 2021.07.22.00) 207 - - React-callinvoker (= 0.71.0) 208 - - React-jsi (= 0.71.0) 209 - - React-jsinspector (= 0.71.0) 210 - - React-logger (= 0.71.0) 211 - - React-perflogger (= 0.71.0) 212 - - React-runtimeexecutor (= 0.71.0) 213 - - React-hermes (0.71.0): 220 + - React-callinvoker (= 0.71.1) 221 + - React-jsi (= 0.71.1) 222 + - React-jsinspector (= 0.71.1) 223 + - React-logger (= 0.71.1) 224 + - React-perflogger (= 0.71.1) 225 + - React-runtimeexecutor (= 0.71.1) 226 + - React-hermes (0.71.1): 214 227 - DoubleConversion 215 228 - glog 216 229 - hermes-engine 217 230 - RCT-Folly (= 2021.07.22.00) 218 231 - RCT-Folly/Futures (= 2021.07.22.00) 219 - - React-cxxreact (= 0.71.0) 220 - - React-jsiexecutor (= 0.71.0) 221 - - React-jsinspector (= 0.71.0) 222 - - React-perflogger (= 0.71.0) 223 - - React-jsi (0.71.0): 232 + - React-cxxreact (= 0.71.1) 233 + - React-jsiexecutor (= 0.71.1) 234 + - React-jsinspector (= 0.71.1) 235 + - React-perflogger (= 0.71.1) 236 + - React-jsi (0.71.1): 224 237 - boost (= 1.76.0) 225 238 - DoubleConversion 226 239 - glog 227 240 - hermes-engine 228 241 - RCT-Folly (= 2021.07.22.00) 229 - - React-jsiexecutor (0.71.0): 242 + - React-jsiexecutor (0.71.1): 230 243 - DoubleConversion 231 244 - glog 232 245 - RCT-Folly (= 2021.07.22.00) 233 - - React-cxxreact (= 0.71.0) 234 - - React-jsi (= 0.71.0) 235 - - React-perflogger (= 0.71.0) 236 - - React-jsinspector (0.71.0) 237 - - React-logger (0.71.0): 246 + - React-cxxreact (= 0.71.1) 247 + - React-jsi (= 0.71.1) 248 + - React-perflogger (= 0.71.1) 249 + - React-jsinspector (0.71.1) 250 + - React-logger (0.71.1): 238 251 - glog 239 252 - react-native-blur (4.3.0): 240 253 - React-Core 241 - - react-native-cameraroll (5.2.2): 254 + - react-native-cameraroll (5.2.4): 242 255 - React-Core 243 - - react-native-image-resizer (3.0.4): 256 + - react-native-image-resizer (3.0.5): 244 257 - React-Core 245 - - react-native-pager-view (6.1.2): 258 + - react-native-pager-view (6.1.4): 246 259 - React-Core 247 - - react-native-paste-input (0.6.0): 260 + - react-native-paste-input (0.6.2): 248 261 - React-Core 249 262 - Swime (= 3.0.6) 250 - - react-native-safe-area-context (4.4.1): 263 + - react-native-safe-area-context (4.5.0): 251 264 - RCT-Folly 252 265 - RCTRequired 253 266 - RCTTypeSafety ··· 257 270 - React-Core 258 271 - react-native-version-number (0.3.6): 259 272 - React 260 - - React-perflogger (0.71.0) 261 - - React-RCTActionSheet (0.71.0): 262 - - React-Core/RCTActionSheetHeaders (= 0.71.0) 263 - - React-RCTAnimation (0.71.0): 273 + - react-native-webview (11.26.1): 274 + - React-Core 275 + - React-perflogger (0.71.1) 276 + - React-RCTActionSheet (0.71.1): 277 + - React-Core/RCTActionSheetHeaders (= 0.71.1) 278 + - React-RCTAnimation (0.71.1): 264 279 - RCT-Folly (= 2021.07.22.00) 265 - - RCTTypeSafety (= 0.71.0) 266 - - React-Codegen (= 0.71.0) 267 - - React-Core/RCTAnimationHeaders (= 0.71.0) 268 - - React-jsi (= 0.71.0) 269 - - ReactCommon/turbomodule/core (= 0.71.0) 270 - - React-RCTAppDelegate (0.71.0): 280 + - RCTTypeSafety (= 0.71.1) 281 + - React-Codegen (= 0.71.1) 282 + - React-Core/RCTAnimationHeaders (= 0.71.1) 283 + - React-jsi (= 0.71.1) 284 + - ReactCommon/turbomodule/core (= 0.71.1) 285 + - React-RCTAppDelegate (0.71.1): 271 286 - RCT-Folly 272 287 - RCTRequired 273 288 - RCTTypeSafety 274 289 - React-Core 275 290 - ReactCommon/turbomodule/core 276 - - React-RCTBlob (0.71.0): 291 + - React-RCTBlob (0.71.1): 277 292 - RCT-Folly (= 2021.07.22.00) 278 - - React-Codegen (= 0.71.0) 279 - - React-Core/RCTBlobHeaders (= 0.71.0) 280 - - React-Core/RCTWebSocket (= 0.71.0) 281 - - React-jsi (= 0.71.0) 282 - - React-RCTNetwork (= 0.71.0) 283 - - ReactCommon/turbomodule/core (= 0.71.0) 284 - - React-RCTImage (0.71.0): 293 + - React-Codegen (= 0.71.1) 294 + - React-Core/RCTBlobHeaders (= 0.71.1) 295 + - React-Core/RCTWebSocket (= 0.71.1) 296 + - React-jsi (= 0.71.1) 297 + - React-RCTNetwork (= 0.71.1) 298 + - ReactCommon/turbomodule/core (= 0.71.1) 299 + - React-RCTImage (0.71.1): 285 300 - RCT-Folly (= 2021.07.22.00) 286 - - RCTTypeSafety (= 0.71.0) 287 - - React-Codegen (= 0.71.0) 288 - - React-Core/RCTImageHeaders (= 0.71.0) 289 - - React-jsi (= 0.71.0) 290 - - React-RCTNetwork (= 0.71.0) 291 - - ReactCommon/turbomodule/core (= 0.71.0) 292 - - React-RCTLinking (0.71.0): 293 - - React-Codegen (= 0.71.0) 294 - - React-Core/RCTLinkingHeaders (= 0.71.0) 295 - - React-jsi (= 0.71.0) 296 - - ReactCommon/turbomodule/core (= 0.71.0) 297 - - React-RCTNetwork (0.71.0): 301 + - RCTTypeSafety (= 0.71.1) 302 + - React-Codegen (= 0.71.1) 303 + - React-Core/RCTImageHeaders (= 0.71.1) 304 + - React-jsi (= 0.71.1) 305 + - React-RCTNetwork (= 0.71.1) 306 + - ReactCommon/turbomodule/core (= 0.71.1) 307 + - React-RCTLinking (0.71.1): 308 + - React-Codegen (= 0.71.1) 309 + - React-Core/RCTLinkingHeaders (= 0.71.1) 310 + - React-jsi (= 0.71.1) 311 + - ReactCommon/turbomodule/core (= 0.71.1) 312 + - React-RCTNetwork (0.71.1): 298 313 - RCT-Folly (= 2021.07.22.00) 299 - - RCTTypeSafety (= 0.71.0) 300 - - React-Codegen (= 0.71.0) 301 - - React-Core/RCTNetworkHeaders (= 0.71.0) 302 - - React-jsi (= 0.71.0) 303 - - ReactCommon/turbomodule/core (= 0.71.0) 304 - - React-RCTSettings (0.71.0): 314 + - RCTTypeSafety (= 0.71.1) 315 + - React-Codegen (= 0.71.1) 316 + - React-Core/RCTNetworkHeaders (= 0.71.1) 317 + - React-jsi (= 0.71.1) 318 + - ReactCommon/turbomodule/core (= 0.71.1) 319 + - React-RCTSettings (0.71.1): 305 320 - RCT-Folly (= 2021.07.22.00) 306 - - RCTTypeSafety (= 0.71.0) 307 - - React-Codegen (= 0.71.0) 308 - - React-Core/RCTSettingsHeaders (= 0.71.0) 309 - - React-jsi (= 0.71.0) 310 - - ReactCommon/turbomodule/core (= 0.71.0) 311 - - React-RCTText (0.71.0): 312 - - React-Core/RCTTextHeaders (= 0.71.0) 313 - - React-RCTVibration (0.71.0): 321 + - RCTTypeSafety (= 0.71.1) 322 + - React-Codegen (= 0.71.1) 323 + - React-Core/RCTSettingsHeaders (= 0.71.1) 324 + - React-jsi (= 0.71.1) 325 + - ReactCommon/turbomodule/core (= 0.71.1) 326 + - React-RCTText (0.71.1): 327 + - React-Core/RCTTextHeaders (= 0.71.1) 328 + - React-RCTVibration (0.71.1): 314 329 - RCT-Folly (= 2021.07.22.00) 315 - - React-Codegen (= 0.71.0) 316 - - React-Core/RCTVibrationHeaders (= 0.71.0) 317 - - React-jsi (= 0.71.0) 318 - - ReactCommon/turbomodule/core (= 0.71.0) 319 - - React-runtimeexecutor (0.71.0): 320 - - React-jsi (= 0.71.0) 321 - - ReactCommon/turbomodule/bridging (0.71.0): 330 + - React-Codegen (= 0.71.1) 331 + - React-Core/RCTVibrationHeaders (= 0.71.1) 332 + - React-jsi (= 0.71.1) 333 + - ReactCommon/turbomodule/core (= 0.71.1) 334 + - React-runtimeexecutor (0.71.1): 335 + - React-jsi (= 0.71.1) 336 + - ReactCommon/turbomodule/bridging (0.71.1): 322 337 - DoubleConversion 323 338 - glog 324 339 - RCT-Folly (= 2021.07.22.00) 325 - - React-callinvoker (= 0.71.0) 326 - - React-Core (= 0.71.0) 327 - - React-cxxreact (= 0.71.0) 328 - - React-jsi (= 0.71.0) 329 - - React-logger (= 0.71.0) 330 - - React-perflogger (= 0.71.0) 331 - - ReactCommon/turbomodule/core (0.71.0): 340 + - React-callinvoker (= 0.71.1) 341 + - React-Core (= 0.71.1) 342 + - React-cxxreact (= 0.71.1) 343 + - React-jsi (= 0.71.1) 344 + - React-logger (= 0.71.1) 345 + - React-perflogger (= 0.71.1) 346 + - ReactCommon/turbomodule/core (0.71.1): 332 347 - DoubleConversion 333 348 - glog 334 349 - RCT-Folly (= 2021.07.22.00) 335 - - React-callinvoker (= 0.71.0) 336 - - React-Core (= 0.71.0) 337 - - React-cxxreact (= 0.71.0) 338 - - React-jsi (= 0.71.0) 339 - - React-logger (= 0.71.0) 340 - - React-perflogger (= 0.71.0) 350 + - React-callinvoker (= 0.71.1) 351 + - React-Core (= 0.71.1) 352 + - React-cxxreact (= 0.71.1) 353 + - React-jsi (= 0.71.1) 354 + - React-logger (= 0.71.1) 355 + - React-perflogger (= 0.71.1) 341 356 - rn-fetch-blob (0.12.0): 342 357 - React-Core 343 358 - RNBackgroundFetch (4.1.8): ··· 346 361 - React-Core 347 362 - RNCClipboard (1.11.1): 348 363 - React-Core 364 + - RNFastImage (8.6.3): 365 + - React-Core 366 + - SDWebImage (~> 5.11.1) 367 + - SDWebImageWebPCoder (~> 0.8.4) 349 368 - RNFS (2.20.0): 350 369 - React-Core 351 - - RNGestureHandler (2.8.0): 370 + - RNGestureHandler (2.9.0): 352 371 - React-Core 353 372 - RNImageCropPicker (0.38.1): 354 373 - React-Core ··· 361 380 - TOCropViewController 362 381 - RNInAppBrowser (3.7.0): 363 382 - React-Core 364 - - RNNotifee (7.4.0): 383 + - RNNotifee (7.5.0): 365 384 - React-Core 366 - - RNNotifee/NotifeeCore (= 7.4.0) 367 - - RNNotifee/NotifeeCore (7.4.0): 385 + - RNNotifee/NotifeeCore (= 7.5.0) 386 + - RNNotifee/NotifeeCore (7.5.0): 387 + - React-Core 388 + - RNPermissions (3.6.1): 368 389 - React-Core 369 390 - RNReactNativeHapticFeedback (1.14.0): 370 391 - React-Core 371 - - RNReanimated (2.13.0): 392 + - RNReanimated (2.14.4): 372 393 - DoubleConversion 373 394 - FBLazyVector 374 395 - FBReactNativeSpec ··· 395 416 - React-RCTText 396 417 - ReactCommon/turbomodule/core 397 418 - Yoga 398 - - RNScreens (3.18.2): 419 + - RNScreens (3.20.0): 399 420 - React-Core 400 421 - React-RCTImage 401 - - RNSVG (12.5.0): 422 + - RNSVG (12.5.1): 402 423 - React-Core 403 - - segment-analytics-react-native (2.10.1): 424 + - SDWebImage (5.11.1): 425 + - SDWebImage/Core (= 5.11.1) 426 + - SDWebImage/Core (5.11.1) 427 + - SDWebImageWebPCoder (0.8.5): 428 + - libwebp (~> 1.0) 429 + - SDWebImage/Core (~> 5.10) 430 + - segment-analytics-react-native (2.13.0): 404 431 - React-Core 405 432 - sovran-react-native 406 433 - sovran-react-native (0.4.5): ··· 418 445 - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) 419 446 - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) 420 447 - libevent (~> 2.1.12) 448 + - Permission-Camera (from `../node_modules/react-native-permissions/ios/Camera`) 449 + - Permission-PhotoLibrary (from `../node_modules/react-native-permissions/ios/PhotoLibrary`) 421 450 - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) 422 451 - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) 423 452 - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) ··· 441 470 - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) 442 471 - react-native-splash-screen (from `../node_modules/react-native-splash-screen`) 443 472 - react-native-version-number (from `../node_modules/react-native-version-number`) 473 + - react-native-webview (from `../node_modules/react-native-webview`) 444 474 - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) 445 475 - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) 446 476 - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) ··· 458 488 - RNBackgroundFetch (from `../node_modules/react-native-background-fetch`) 459 489 - "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)" 460 490 - "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)" 491 + - RNFastImage (from `../node_modules/react-native-fast-image`) 461 492 - RNFS (from `../node_modules/react-native-fs`) 462 493 - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) 463 494 - RNImageCropPicker (from `../node_modules/react-native-image-crop-picker`) 464 495 - RNInAppBrowser (from `../node_modules/react-native-inappbrowser-reborn`) 465 496 - "RNNotifee (from `../node_modules/@notifee/react-native`)" 497 + - RNPermissions (from `../node_modules/react-native-permissions`) 466 498 - RNReactNativeHapticFeedback (from `../node_modules/react-native-haptic-feedback`) 467 499 - RNReanimated (from `../node_modules/react-native-reanimated`) 468 500 - RNScreens (from `../node_modules/react-native-screens`) ··· 475 507 trunk: 476 508 - fmt 477 509 - libevent 510 + - libwebp 511 + - SDWebImage 512 + - SDWebImageWebPCoder 478 513 - Swime 479 514 - TOCropViewController 480 515 ··· 493 528 :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" 494 529 hermes-engine: 495 530 :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" 531 + Permission-Camera: 532 + :path: "../node_modules/react-native-permissions/ios/Camera" 533 + Permission-PhotoLibrary: 534 + :path: "../node_modules/react-native-permissions/ios/PhotoLibrary" 496 535 RCT-Folly: 497 536 :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" 498 537 RCTRequired: ··· 537 576 :path: "../node_modules/react-native-splash-screen" 538 577 react-native-version-number: 539 578 :path: "../node_modules/react-native-version-number" 579 + react-native-webview: 580 + :path: "../node_modules/react-native-webview" 540 581 React-perflogger: 541 582 :path: "../node_modules/react-native/ReactCommon/reactperflogger" 542 583 React-RCTActionSheet: ··· 571 612 :path: "../node_modules/@react-native-async-storage/async-storage" 572 613 RNCClipboard: 573 614 :path: "../node_modules/@react-native-clipboard/clipboard" 615 + RNFastImage: 616 + :path: "../node_modules/react-native-fast-image" 574 617 RNFS: 575 618 :path: "../node_modules/react-native-fs" 576 619 RNGestureHandler: ··· 581 624 :path: "../node_modules/react-native-inappbrowser-reborn" 582 625 RNNotifee: 583 626 :path: "../node_modules/@notifee/react-native" 627 + RNPermissions: 628 + :path: "../node_modules/react-native-permissions" 584 629 RNReactNativeHapticFeedback: 585 630 :path: "../node_modules/react-native-haptic-feedback" 586 631 RNReanimated: ··· 597 642 :path: "../node_modules/react-native/ReactCommon/yoga" 598 643 599 644 SPEC CHECKSUMS: 600 - boost: a7c83b31436843459a1961bfd74b96033dc77234 645 + boost: 57d2868c099736d80fcd648bf211b4431e51a558 601 646 BVLinearGradient: 34a999fda29036898a09c6a6b728b0b4189e1a44 602 - DoubleConversion: 831926d9b8bf8166fd87886c4abab286c2422662 603 - FBLazyVector: 61839cba7a48c570b7ac3e1cd8a4d0948382202f 604 - FBReactNativeSpec: 5a14398ccf5e27c1ca2d7109eb920594ce93c10d 647 + DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 648 + FBLazyVector: ad72713385db5289b19f1ead07e8e4aa26dcb01d 649 + FBReactNativeSpec: df2602c11e33d310433496e28a48b4b2be652a61 605 650 fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 606 - glog: 476ee3e89abb49e07f822b48323c51c57124b572 607 - hermes-engine: f6e715aa6c8bd38de6c13bc85e07b0a337edaa89 651 + glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b 652 + hermes-engine: 922ccd744f50d9bfde09e9677bf0f3b562ea5fb9 608 653 libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 654 + libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef 655 + Permission-Camera: bf6791b17c7f614b6826019fcfdcc286d3a107f6 656 + Permission-PhotoLibrary: 5b34ca67279f7201ae109cef36f9806a6596002d 609 657 RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 610 - RCTRequired: dea3e4163184ea57c50288c15c32c1529265c58f 611 - RCTTypeSafety: a0834ab89159a346731e8aae55ad6e2cce61c327 612 - React: d877d055ff2137ca0325a4babdef3411e11f3cb7 613 - React-callinvoker: 77bd2701eee3acac154b11ec219e68d5a1f780ad 614 - React-Codegen: bccc516adc1551ccfe04b0de27e345d38829b204 615 - React-Core: 4035f59e5bec8f3053583c6108d99c7516deb760 616 - React-CoreModules: b6a1f76423fea57a03e0d7a2f79d3b55cf193f2c 617 - React-cxxreact: fe5f6ec8ae875bebc71309d1e8ef89bb966d61a6 618 - React-hermes: 3c8ea5e8f402db2a08b57051206d7f2ba9c75565 619 - React-jsi: dbf0f82c93bfd828fa05c50f2ee74dc81f711050 620 - React-jsiexecutor: 060dd495f1e2af3d87216f7ca8a94c55ec885b4f 621 - React-jsinspector: 5061fcbec93fd672183dfb39cc2f65e55a0835db 622 - React-logger: a6c0b3a807a8e81f6d7fea2e72660766f55daa50 658 + RCTRequired: fd4d923b964658aa0c4091a32c8b2004c6d9e3a6 659 + RCTTypeSafety: c276d85975bde3d8448907235c70bf0da257adfd 660 + React: e481a67971af1ce9639c9f746b753dd0e84ca108 661 + React-callinvoker: 1051c04a94fa9d243786b86380606bad701a3b31 662 + React-Codegen: 14b1e716d361d5ad95e0ce1a338f3fa0733a98b5 663 + React-Core: 698fc3baecb80d511d987475a16d036cec6d287f 664 + React-CoreModules: 59245305f41ff0adfeac334acc0594dea4585a7c 665 + React-cxxreact: 49accd2954b0f532805dbcd1918fa6962f32f247 666 + React-hermes: d068733294581a085e95b6024e8d951b005e26d3 667 + React-jsi: 122b9bce14f4c6c7cb58f28f87912cfe091885fa 668 + React-jsiexecutor: 60cf272aababc5212410e4249d17cea14fc36caa 669 + React-jsinspector: ff56004b0c974b688a6548c156d5830ad751ae07 670 + React-logger: 60a0b5f8bed667ecf9e24fecca1f30d125de6d75 623 671 react-native-blur: 50c9feabacbc5f49b61337ebc32192c6be7ec3c3 624 - react-native-cameraroll: 71d68167beb6fc7216aa564abb6d86f1d666a2c6 625 - react-native-image-resizer: 794abf75ec13ed1f0dbb1f134e27504ea65e9e66 626 - react-native-pager-view: 54bed894cecebe28cede54c01038d9d1e122de43 627 - react-native-paste-input: 5182843692fd2ec72be50f241a38a49796e225d7 628 - react-native-safe-area-context: 99b24a0c5acd0d5dcac2b1a7f18c49ea317be99a 672 + react-native-cameraroll: cb752fda6d5268f1646b4390bd5be1f27706b9a0 673 + react-native-image-resizer: 00ceb0e05586c7aadf061eea676957a6c2ec60fa 674 + react-native-pager-view: b58cb9e9f42f64e50cab3040815772c1d119a2e2 675 + react-native-paste-input: 3392800944a47c00dddbff23c31c281482209679 676 + react-native-safe-area-context: 39c2d8be3328df5d437ac1700f4f3a4f75716acc 629 677 react-native-splash-screen: 4312f786b13a81b5169ef346d76d33bc0c6dc457 630 678 react-native-version-number: b415bbec6a13f2df62bf978e85bc0d699462f37f 631 - React-perflogger: e5fc4149e9bbb972b8520277f3b23141faa47a36 632 - React-RCTActionSheet: 991de88216bf03ab9bb1d213d73c62ecbe64ade7 633 - React-RCTAnimation: b74e3d1bf5280891a573e447b487fa1db0713b5b 634 - React-RCTAppDelegate: f52667f2dbc510f87b7988c5204e8764d50bf0c1 635 - React-RCTBlob: 6762787c01d5d8d18efed03764b0d58d3b79595a 636 - React-RCTImage: 9ed7eba8dd192a49def2cad2ecaedee7e7e315b4 637 - React-RCTLinking: 0b58eed9af0645a161b80bf412b6b721e4585c66 638 - React-RCTNetwork: dc075b0eea00d8a98c928f011d9bc2458acc7092 639 - React-RCTSettings: 30fb3f498cfaf8a4bb47334ff9ffbe318ef78766 640 - React-RCTText: a631564e84a227fe24bae7c04446f36faea7fcf5 641 - React-RCTVibration: 55c91eccdbd435d7634efbe847086944389475b0 642 - React-runtimeexecutor: ac80782d9d76ba2b0f709f4de0c427fe33c352dc 643 - ReactCommon: 20e38a9be5fe1341b5e422220877cc94034776ba 679 + react-native-webview: 9f111dfbcfc826084d6c507f569e5e03342ee1c1 680 + React-perflogger: ec8eef2a8f03ecfa6361c2c5fb9197ef4a29cc85 681 + React-RCTActionSheet: a0c023b86cf4c862fa9c4eb0f6f91fbe878fb2de 682 + React-RCTAnimation: 168d53718c74153947c0109f55900faa64d79439 683 + React-RCTAppDelegate: a8efbab128b34aa07a9491c85a41401210b1bec5 684 + React-RCTBlob: 9bcbfc893bfda9f6b2eb016329d38c0f6366d31a 685 + React-RCTImage: 3fcd4570b4b0f1ac2f4b4b6308dba33ce66c5b50 686 + React-RCTLinking: 1edb8e1bb3fc39bf9e13c63d6aaaa3f0c3d18683 687 + React-RCTNetwork: 500a79e0e0f67678077df727fabba87a55c043e1 688 + React-RCTSettings: cc4414eb84ad756d619076c3999fecbf12896d6f 689 + React-RCTText: 2a34261f3da6e34f47a62154def657546ebfa5e1 690 + React-RCTVibration: 49d531ec8498e0afa2c9b22c2205784372e3d4f3 691 + React-runtimeexecutor: 311feb67600774723fe10eb8801d3138cae9ad67 692 + ReactCommon: 03be76588338a27a88d103b35c3c44a3fd43d136 644 693 rn-fetch-blob: f065bb7ab7fb48dd002629f8bdcb0336602d3cba 645 694 RNBackgroundFetch: 8e16176ff415daac743a6eb57afc8e9e14dbe623 646 695 RNCAsyncStorage: 8616bd5a58af409453ea4e1b246521bb76578d60 647 696 RNCClipboard: 2834e1c4af68697089cdd455ee4a4cdd198fa7dd 697 + RNFastImage: 5c9c9fed9c076e521b3f509fe79e790418a544e8 648 698 RNFS: 4ac0f0ea233904cb798630b3c077808c06931688 649 - RNGestureHandler: 62232ba8f562f7dea5ba1b3383494eb5bf97a4d3 699 + RNGestureHandler: 071d7a9ad81e8b83fe7663b303d132406a7d8f39 650 700 RNImageCropPicker: 648356d68fbf9911a1016b3e3723885d28373eda 651 701 RNInAppBrowser: e36d6935517101ccba0e875bac8ad7b0cb655364 652 - RNNotifee: da8dcf09f079ea22f46e239d7c406e10d4525a5f 702 + RNNotifee: 053c0ace9c73634709a0214fd9c436a5777a562f 703 + RNPermissions: dcdb7b99796bbeda6975a6e79ad519c41b251b1c 653 704 RNReactNativeHapticFeedback: 1e3efeca9628ff9876ee7cdd9edec1b336913f8c 654 - RNReanimated: d8d9d3d3801bda5e35e85cdffc871577d044dc2e 655 - RNScreens: 34cc502acf1b916c582c60003dc3089fa01dc66d 656 - RNSVG: 6adc5c52d2488a476248413064b7f2832e639057 657 - segment-analytics-react-native: cb097e393c3560a0d4cfd877044293e37b0050d9 705 + RNReanimated: cc5e3aa479cb9170bcccf8204291a6950a3be128 706 + RNScreens: 218801c16a2782546d30bd2026bb625c0302d70f 707 + RNSVG: d7d7bc8229af3842c9cfc3a723c815a52cdd1105 708 + SDWebImage: a7f831e1a65eb5e285e3fb046a23fcfbf08e696d 709 + SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d 710 + segment-analytics-react-native: bd1f13ea95bad2313a9c7130da032af0e9a6da60 658 711 sovran-react-native: fd3dc8f1a4b14acdc4ad25fc6b4ac4f52a2a2a15 659 712 Swime: d7b2c277503b6cea317774aedc2dce05613f8b0b 660 713 TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863 661 - Yoga: c618b544ff8bd8865cdca602f00cbcdb92fd6d31 714 + Yoga: 921eb014669cf9c718ada68b08d362517d564e0c 662 715 663 - PODFILE CHECKSUM: 0975a639c66f07f4d49706dd0bf7c3aa4dc833cf 716 + PODFILE CHECKSUM: 95c7fde1130d862b561348cca2b3fb7f9bd84bfb 664 717 665 718 COCOAPODS: 1.11.3
+1
ios/app/AppDelegate.mm
··· 21 21 [[TSBackgroundFetch sharedInstance] didFinishLaunching]; 22 22 23 23 self.moduleName = @"xyz.blueskyweb.app"; 24 + self.initialProps = @{}; 24 25 return [super application:application didFinishLaunchingWithOptions:launchOptions]; 25 26 } 26 27
+3 -1
ios/app/Info.plist
··· 21 21 <key>CFBundlePackageType</key> 22 22 <string>APPL</string> 23 23 <key>CFBundleShortVersionString</key> 24 - <string>1.0</string> 24 + <string>1.2</string> 25 25 <key>CFBundleSignature</key> 26 26 <string>????</string> 27 27 <key>CFBundleURLTypes</key> ··· 39 39 </array> 40 40 <key>CFBundleVersion</key> 41 41 <string>1</string> 42 + <key>ITSAppUsesNonExemptEncryption</key> 43 + <false/> 42 44 <key>LSRequiresIPhoneOS</key> 43 45 <true/> 44 46 <key>NSAppTransportSecurity</key>
+15 -2
jest/jestSetup.js
··· 1 1 /* global jest */ 2 + import {configure} from '@testing-library/react-native' 3 + import 'react-native-gesture-handler/jestSetup' 4 + 5 + configure({asyncUtilTimeout: 20000}) 2 6 3 - import 'react-native-gesture-handler/jestSetup' 4 7 jest.mock('@react-native-async-storage/async-storage', () => 5 8 require('@react-native-async-storage/async-storage/jest/async-storage-mock'), 6 9 ) 7 - jest.mock('react-native/Libraries/EventEmitter/NativeEventEmitter') 10 + jest.mock('react-native/Libraries/EventEmitter/NativeEventEmitter', () => { 11 + const {EventEmitter} = require('events') 12 + return { 13 + __esModule: true, 14 + default: EventEmitter, 15 + } 16 + }) 8 17 9 18 // Silence the warning: Animated: `useNativeDriver` is not supported 10 19 jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper') ··· 55 64 flush: jest.fn(), 56 65 }), 57 66 })) 67 + 68 + jest.mock('react-native-permissions', () => 69 + require('react-native-permissions/mock'), 70 + )
+17 -15
jest/test-pds.ts
··· 8 8 ServerConfig as PDSServerConfig, 9 9 } from '@atproto/pds' 10 10 import * as plc from '@atproto/plc' 11 - import AtpApi, {ServiceClient} from '@atproto/api' 11 + import AtpAgent from '@atproto/api' 12 12 13 13 export interface TestUser { 14 14 email: string ··· 16 16 declarationCid: string 17 17 handle: string 18 18 password: string 19 - api: ServiceClient 19 + agent: AtpAgent 20 20 } 21 21 22 22 export interface TestUsers { ··· 87 87 dbPostgresUrl: process.env.DB_POSTGRES_URL, 88 88 blobstoreLocation: `${blobstoreLoc}/blobs`, 89 89 blobstoreTmp: `${blobstoreLoc}/tmp`, 90 + maxSubscriptionBuffer: 200, 91 + repoBackfillLimitMs: 1e3 * 60 * 60, 90 92 }) 91 93 92 94 const db = PDSDatabase.memory() ··· 112 114 async function genMockData(pdsUrl: string): Promise<TestUsers> { 113 115 const date = dateGen() 114 116 115 - const clients = { 116 - loggedout: AtpApi.service(pdsUrl), 117 - alice: AtpApi.service(pdsUrl), 118 - bob: AtpApi.service(pdsUrl), 119 - carla: AtpApi.service(pdsUrl), 117 + const agents = { 118 + loggedout: new AtpAgent({service: pdsUrl}), 119 + alice: new AtpAgent({service: pdsUrl}), 120 + bob: new AtpAgent({service: pdsUrl}), 121 + carla: new AtpAgent({service: pdsUrl}), 120 122 } 121 123 const users: TestUser[] = [ 122 124 { ··· 125 127 declarationCid: '', 126 128 handle: 'alice.test', 127 129 password: 'hunter2', 128 - api: clients.alice, 130 + agent: agents.alice, 129 131 }, 130 132 { 131 133 email: 'bob@test.com', ··· 133 135 declarationCid: '', 134 136 handle: 'bob.test', 135 137 password: 'hunter2', 136 - api: clients.bob, 138 + agent: agents.bob, 137 139 }, 138 140 { 139 141 email: 'carla@test.com', ··· 141 143 declarationCid: '', 142 144 handle: 'carla.test', 143 145 password: 'hunter2', 144 - api: clients.carla, 146 + agent: agents.carla, 145 147 }, 146 148 ] 147 149 const alice = users[0] ··· 150 152 151 153 let _i = 1 152 154 for (const user of users) { 153 - const res = await clients.loggedout.com.atproto.account.create({ 155 + const res = await agents.loggedout.api.com.atproto.account.create({ 154 156 email: user.email, 155 157 handle: user.handle, 156 158 password: user.password, 157 159 }) 158 - user.api.setHeader('Authorization', `Bearer ${res.data.accessJwt}`) 159 - const {data: profile} = await user.api.app.bsky.actor.getProfile({ 160 + user.agent.api.setHeader('Authorization', `Bearer ${res.data.accessJwt}`) 161 + const {data: profile} = await user.agent.api.app.bsky.actor.getProfile({ 160 162 actor: user.handle, 161 163 }) 162 164 user.did = res.data.did 163 165 user.declarationCid = profile.declaration.cid 164 - await user.api.app.bsky.actor.profile.create( 166 + await user.agent.api.app.bsky.actor.profile.create( 165 167 {did: user.did}, 166 168 { 167 169 displayName: ucfirst(user.handle).slice(0, -5), ··· 172 174 173 175 // everybody follows everybody 174 176 const follow = async (author: TestUser, subject: TestUser) => { 175 - await author.api.app.bsky.graph.follow.create( 177 + await author.agent.api.app.bsky.graph.follow.create( 176 178 {did: author.did}, 177 179 { 178 180 subject: {
+4 -6
jest/test-utils.tsx
··· 3 3 import {GestureHandlerRootView} from 'react-native-gesture-handler' 4 4 import {RootSiblingParent} from 'react-native-root-siblings' 5 5 import {SafeAreaProvider} from 'react-native-safe-area-context' 6 - import {RootStoreProvider} from '../src/state' 7 - import {ThemeProvider} from '../src/view/lib/ThemeContext' 8 - import {mockedRootStore} from '../__mocks__/state-mock' 6 + import {RootStoreProvider, RootStoreModel} from '../src/state' 7 + import {ThemeProvider} from '../src/lib/ThemeContext' 9 8 10 - const customRender = (ui: any, rootStore?: any) => 9 + const customRender = (ui: any, rootStore: RootStoreModel) => 11 10 render( 12 11 // eslint-disable-next-line react-native/no-inline-styles 13 12 <GestureHandlerRootView style={{flex: 1}}> 14 13 <RootSiblingParent> 15 - <RootStoreProvider 16 - value={rootStore != null ? rootStore : mockedRootStore}> 14 + <RootStoreProvider value={rootStore}> 17 15 <ThemeProvider theme="light"> 18 16 <SafeAreaProvider>{ui}</SafeAreaProvider> 19 17 </ThemeProvider>
+32 -13
package.json
··· 1 1 { 2 2 "name": "bsky.app", 3 - "version": "0.0.1", 3 + "version": "1.2.0", 4 4 "private": true, 5 5 "scripts": { 6 6 "android": "react-native run-android", ··· 8 8 "web": "webpack-dev-server --config ./web/webpack.config.js -d inline-source-map --hot --color", 9 9 "start": "react-native start", 10 10 "clean-cache": "rm -rf node_modules/.cache/babel-loader/*", 11 - "test": "jest --forceExit", 11 + "test": "jest --forceExit --testTimeout=20000 --bail", 12 12 "test-watch": "jest --watchAll", 13 13 "test-ci": "jest --ci --forceExit --reporters=default --reporters=jest-junit", 14 14 "test-coverage": "jest --coverage", 15 - "lint": "eslint . --ext .js,.jsx,.ts,.tsx" 15 + "lint": "eslint . --ext .js,.jsx,.ts,.tsx", 16 + "e2e": "detox test --configuration ios.sim.debug --take-screenshots all" 16 17 }, 17 18 "dependencies": { 18 - "@atproto/api": "^0.0.6", 19 + "@atproto/api": "^0.1.2", 19 20 "@atproto/lexicon": "^0.0.4", 20 - "@atproto/xrpc": "^0.0.3", 21 + "@atproto/xrpc": "^0.0.4", 21 22 "@bam.tech/react-native-image-resizer": "^3.0.4", 22 23 "@fortawesome/fontawesome-svg-core": "^6.1.1", 23 24 "@fortawesome/free-regular-svg-icons": "^6.1.1", ··· 34 35 "@segment/analytics-react-native": "^2.10.1", 35 36 "@segment/sovran-react-native": "^0.4.5", 36 37 "@zxing/text-encoding": "^0.9.0", 38 + "await-lock": "^2.2.2", 37 39 "base64-js": "^1.5.1", 38 40 "email-validator": "^2.0.4", 39 41 "he": "^1.2.0", 40 42 "lodash.chunk": "^4.2.0", 43 + "lodash.clonedeep": "^4.5.0", 44 + "lodash.isequal": "^4.5.0", 41 45 "lodash.omit": "^4.5.0", 46 + "lodash.shuffle": "^4.2.0", 42 47 "lru_map": "^0.4.1", 43 48 "mobx": "^6.6.1", 44 49 "mobx-react-lite": "^3.4.0", 50 + "normalize-url": "^8.0.0", 45 51 "react": "18.2.0", 46 52 "react-avatar-editor": "^13.0.0", 47 53 "react-circular-progressbar": "^2.1.0", 48 54 "react-dom": "^18.2.0", 49 - "react-native": "0.71.0", 55 + "react-native": "0.71.1", 50 56 "react-native-appstate-hook": "^1.0.6", 51 57 "react-native-background-fetch": "^4.1.8", 58 + "react-native-fast-image": "^8.6.3", 52 59 "react-native-fs": "^2.20.0", 53 60 "react-native-gesture-handler": "^2.5.0", 54 61 "react-native-haptic-feedback": "^1.14.0", ··· 56 63 "react-native-inappbrowser-reborn": "^3.6.3", 57 64 "react-native-linear-gradient": "^2.6.2", 58 65 "react-native-pager-view": "^6.0.2", 66 + "react-native-permissions": "^3.6.1", 59 67 "react-native-progress": "^5.0.0", 60 68 "react-native-reanimated": "^2.9.1", 61 69 "react-native-root-siblings": "^4.1.1", ··· 66 74 "react-native-svg": "^12.4.0", 67 75 "react-native-tab-view": "^3.3.0", 68 76 "react-native-url-polyfill": "^1.3.0", 77 + "react-native-uuid": "^2.0.1", 69 78 "react-native-version-number": "^0.3.6", 70 79 "react-native-web": "^0.18.11", 71 80 "react-native-web-linear-gradient": "^1.1.2", 81 + "react-native-web-webview": "^1.0.2", 82 + "react-native-webview": "^11.26.1", 83 + "react-native-youtube-iframe": "^2.2.2", 72 84 "rn-fetch-blob": "^0.12.0", 73 85 "tlds": "^1.234.0", 74 86 "zod": "^3.20.2" 75 87 }, 76 88 "devDependencies": { 77 - "@atproto/pds": "^0.0.1", 78 - "@babel/core": "^7.12.9", 79 - "@babel/preset-env": "^7.14.0", 80 - "@babel/runtime": "^7.12.5", 89 + "@atproto/pds": "^0.0.3", 90 + "@babel/core": "^7.20.0", 91 + "@babel/preset-env": "^7.20.0", 92 + "@babel/runtime": "^7.20.0", 81 93 "@react-native-community/eslint-config": "^3.0.0", 82 94 "@testing-library/jest-native": "^5.3.3", 83 95 "@testing-library/react-native": "^11.5.0", ··· 85 97 "@types/he": "^1.1.2", 86 98 "@types/jest": "^26.0.23", 87 99 "@types/lodash.chunk": "^4.2.7", 100 + "@types/lodash.clonedeep": "^4.5.7", 101 + "@types/lodash.isequal": "^4.5.6", 88 102 "@types/lodash.omit": "^4.5.7", 103 + "@types/lodash.shuffle": "^4.2.7", 89 104 "@types/react-avatar-editor": "^13.0.0", 90 105 "@types/react-native": "^0.67.3", 91 106 "@types/react-test-renderer": "^17.0.1", ··· 95 110 "babel-loader": "^9.1.2", 96 111 "babel-plugin-module-resolver": "^5.0.0", 97 112 "babel-plugin-react-native-web": "^0.18.12", 113 + "detox": "^20.1.2", 98 114 "eslint": "^8.19.0", 115 + "eslint-plugin-detox": "^1.0.0", 116 + "eslint-plugin-ft-flow": "^2.0.3", 99 117 "html-webpack-plugin": "^5.5.0", 100 118 "jest": "^29.2.1", 101 119 "jest-junit": "^15.0.0", 102 - "metro-react-native-babel-preset": "0.73.5", 120 + "metro-react-native-babel-preset": "^0.73.7", 103 121 "prettier": "^2.8.3", 104 122 "react-native-dotenv": "^3.3.1", 105 123 "react-scripts": "^5.0.1", ··· 131 149 "node" 132 150 ], 133 151 "transformIgnorePatterns": [ 134 - "node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|rollbar-react-native|@fortawesome|@react-native|@react-navigation)" 152 + "node_modules/(?!(jest-)?react-native|react-clone-referenced-element|@react-native-community|rollbar-react-native|@fortawesome|@react-native|@react-navigation|normalize-url)" 135 153 ], 136 154 "modulePathIgnorePatterns": [ 137 - "__tests__/.*/__mocks__" 155 + "__tests__/.*/__mocks__", 156 + "e2e/.*" 138 157 ], 139 158 "coveragePathIgnorePatterns": [ 140 159 "<rootDir>/node_modules/",
+17 -30
src/App.native.tsx
··· 6 6 import SplashScreen from 'react-native-splash-screen' 7 7 import {SafeAreaProvider} from 'react-native-safe-area-context' 8 8 import {observer} from 'mobx-react-lite' 9 - import { 10 - createClient, 11 - SegmentClient, 12 - AnalyticsProvider, 13 - } from '@segment/analytics-react-native' 14 - import {ThemeProvider} from './view/lib/ThemeContext' 9 + import {ThemeProvider} from 'lib/ThemeContext' 15 10 import * as view from './view/index' 16 11 import {RootStoreModel, setupState, RootStoreProvider} from './state' 17 12 import {MobileShell} from './view/shell/mobile' 18 - import {s} from './view/lib/styles' 19 - import notifee, {EventType} from '@notifee/react-native' 13 + import {s} from 'lib/styles' 14 + import * as notifee from 'lib/notifee' 15 + import * as analytics from 'lib/analytics' 16 + import * as Toast from './view/com/util/Toast' 20 17 21 18 const App = observer(() => { 22 19 const [rootStore, setRootStore] = useState<RootStoreModel | undefined>( 23 20 undefined, 24 21 ) 25 - const [segment, setSegment] = useState<SegmentClient | undefined>(undefined) 26 22 27 23 // init 28 24 useEffect(() => { 29 25 view.setup() 30 - setSegment( 31 - createClient({ 32 - writeKey: '8I6DsgfiSLuoONyaunGoiQM7A6y2ybdI', 33 - trackAppLifecycleEvents: true, 34 - }), 35 - ) 36 26 setupState().then(store => { 37 27 setRootStore(store) 28 + analytics.init(store) 29 + notifee.init(store) 38 30 SplashScreen.hide() 39 31 Linking.getInitialURL().then((url: string | null) => { 40 32 if (url) { ··· 44 36 Linking.addEventListener('url', ({url}) => { 45 37 store.nav.handleLink(url) 46 38 }) 47 - notifee.onForegroundEvent(async ({type}: {type: EventType}) => { 48 - store.log.debug('Notifee foreground event', {type}) 49 - if (type === EventType.PRESS) { 50 - store.log.debug('User pressed a notifee, opening notifications') 51 - store.nav.switchTo(1, true) 52 - } 39 + store.onSessionDropped(() => { 40 + Toast.show('Sorry! Your session expired. Please log in again.') 53 41 }) 54 42 }) 55 43 }, []) ··· 58 46 if (!rootStore) { 59 47 return null 60 48 } 61 - 62 49 return ( 63 50 <GestureHandlerRootView style={s.h100pct}> 64 - <RootSiblingParent> 65 - <AnalyticsProvider client={segment}> 66 - <RootStoreProvider value={rootStore}> 67 - <ThemeProvider theme={rootStore.shell.darkMode ? 'dark' : 'light'}> 51 + <ThemeProvider theme={rootStore.shell.darkMode ? 'dark' : 'light'}> 52 + <RootSiblingParent> 53 + <analytics.Provider> 54 + <RootStoreProvider value={rootStore}> 68 55 <SafeAreaProvider> 69 56 <MobileShell /> 70 57 </SafeAreaProvider> 71 - </ThemeProvider> 72 - </RootStoreProvider> 73 - </AnalyticsProvider> 74 - </RootSiblingParent> 58 + </RootStoreProvider> 59 + </analytics.Provider> 60 + </RootSiblingParent> 61 + </ThemeProvider> 75 62 </GestureHandlerRootView> 76 63 ) 77 64 })
src/build-flags.ts src/lib/build-flags.ts
+74
src/lib/analytics.tsx
··· 1 + import React from 'react' 2 + import {AppState, AppStateStatus} from 'react-native' 3 + import {createClient, AnalyticsProvider} from '@segment/analytics-react-native' 4 + import {RootStoreModel, AppInfo} from 'state/models/root-store' 5 + 6 + const segmentClient = createClient({ 7 + writeKey: '8I6DsgfiSLuoONyaunGoiQM7A6y2ybdI', 8 + trackAppLifecycleEvents: false, 9 + }) 10 + 11 + export {useAnalytics} from '@segment/analytics-react-native' 12 + 13 + export function init(store: RootStoreModel) { 14 + // NOTE 15 + // this method is a copy of segment's own lifecycle event tracking 16 + // we handle it manually to ensure that it never fires while the app is backgrounded 17 + // -prf 18 + segmentClient.onContextLoaded(() => { 19 + if (AppState.currentState !== 'active') { 20 + store.log.debug('Prevented a metrics ping while the app was backgrounded') 21 + return 22 + } 23 + const context = segmentClient.context.get() 24 + if (typeof context?.app === 'undefined') { 25 + store.log.debug('Aborted metrics ping due to unavailable context') 26 + return 27 + } 28 + 29 + const oldAppInfo = store.appInfo 30 + const newAppInfo = context.app as AppInfo 31 + store.setAppInfo(newAppInfo) 32 + store.log.debug('Recording app info', {new: newAppInfo, old: oldAppInfo}) 33 + 34 + if (typeof oldAppInfo === 'undefined') { 35 + segmentClient.track('Application Installed', { 36 + version: newAppInfo.version, 37 + build: newAppInfo.build, 38 + }) 39 + } else if (newAppInfo.version !== oldAppInfo.version) { 40 + segmentClient.track('Application Updated', { 41 + version: newAppInfo.version, 42 + build: newAppInfo.build, 43 + previous_version: oldAppInfo.version, 44 + previous_build: oldAppInfo.build, 45 + }) 46 + } 47 + segmentClient.track('Application Opened', { 48 + from_background: false, 49 + version: newAppInfo.version, 50 + build: newAppInfo.build, 51 + }) 52 + }) 53 + 54 + let lastState: AppStateStatus = AppState.currentState 55 + AppState.addEventListener('change', (state: AppStateStatus) => { 56 + if (state === 'active' && lastState !== 'active') { 57 + const context = segmentClient.context.get() 58 + segmentClient.track('Application Opened', { 59 + from_background: true, 60 + version: context?.app?.version, 61 + build: context?.app?.build, 62 + }) 63 + } else if (state !== 'active' && lastState === 'active') { 64 + segmentClient.track('Application Backgrounded') 65 + } 66 + lastState = state 67 + }) 68 + } 69 + 70 + export function Provider({children}: React.PropsWithChildren<{}>) { 71 + return ( 72 + <AnalyticsProvider client={segmentClient}>{children}</AnalyticsProvider> 73 + ) 74 + }
+16
src/lib/analytics.web.tsx
··· 1 + // TODO 2 + import React from 'react' 3 + import {RootStoreModel} from 'state/models/root-store' 4 + 5 + export function useAnalytics() { 6 + return { 7 + screen(_name: string) {}, 8 + track(_name: string, _opts: any) {}, 9 + } 10 + } 11 + 12 + export function init(_store: RootStoreModel) {} 13 + 14 + export function Provider({children}: React.PropsWithChildren<{}>) { 15 + return children 16 + }
+4
src/lib/app-info.ts
··· 1 + import VersionNumber from 'react-native-version-number' 2 + 3 + export const appVersion = VersionNumber.appVersion 4 + export const buildVersion = VersionNumber.buildVersion
+3
src/lib/app-info.web.ts
··· 1 + // TODO 2 + export const appVersion = 'TODO' 3 + export const buildVersion = 'TODO'
+5
src/lib/assets.native.ts
··· 1 + import {ImageRequireSource} from 'react-native' 2 + 3 + export const DEF_AVATAR: ImageRequireSource = require('../../public/img/default-avatar.jpg') 4 + export const TABS_EXPLAINER: ImageRequireSource = require('../../public/img/tabs-explainer.jpg') 5 + export const CLOUD_SPLASH: ImageRequireSource = require('../../public/img/cloud-splash.png')
+10
src/lib/assets.ts
··· 1 + import {ImageRequireSource} from 'react-native' 2 + 3 + // @ts-ignore we need to pretend -prf 4 + export const DEF_AVATAR: ImageRequireSource = {uri: '/img/default-avatar.jpg'} 5 + // @ts-ignore we need to pretend -prf 6 + export const TABS_EXPLAINER: ImageRequireSource = { 7 + uri: '/img/tabs-explainer.jpg', 8 + } 9 + // @ts-ignore we need to pretend -prf 10 + export const CLOUD_SPLASH: ImageRequireSource = {uri: '/img/cloud-splash.png'}
+24
src/lib/async/bundle.ts
··· 1 + type BundledFn<Args extends readonly unknown[], Res> = ( 2 + ...args: Args 3 + ) => Promise<Res> 4 + 5 + /** 6 + * A helper which ensures that multiple calls to an async function 7 + * only produces one in-flight request at a time. 8 + */ 9 + export function bundleAsync<Args extends readonly unknown[], Res>( 10 + fn: BundledFn<Args, Res>, 11 + ): BundledFn<Args, Res> { 12 + let promise: Promise<Res> | undefined 13 + return async (...args) => { 14 + if (promise) { 15 + return promise 16 + } 17 + promise = fn(...args) 18 + try { 19 + return await promise 20 + } finally { 21 + promise = undefined 22 + } 23 + } 24 + }
+65
src/lib/constants.ts
··· 1 + export const FEEDBACK_FORM_URL = 2 + 'https://docs.google.com/forms/d/e/1FAIpQLSdavFRXTdB6tRobaFrRR2A1gv3b-IBHwQkBmNZTRpoqmcrPrQ/viewform?usp=sf_link' 3 + 4 + export const MAX_DISPLAY_NAME = 64 5 + export const MAX_DESCRIPTION = 256 6 + 7 + export const PROD_SUGGESTED_FOLLOWS = [ 8 + 'john', 9 + 'visakanv', 10 + 'saz', 11 + 'steph', 12 + 'ratzlaff', 13 + 'beth', 14 + 'weisser', 15 + 'katherine', 16 + 'annagat', 17 + 'josh', 18 + 'lurkshark', 19 + 'amir', 20 + 'amyxzh', 21 + 'danielle', 22 + 'jack-frazee', 23 + 'vibes', 24 + 'cat', 25 + 'yuriy', 26 + 'alvinreyes', 27 + 'skoot', 28 + 'patricia', 29 + 'ara4n', 30 + 'case', 31 + 'armand', 32 + 'ivan', 33 + 'nicholas', 34 + 'kelsey', 35 + 'ericlee', 36 + 'emily', 37 + 'jake', 38 + 'jennijuju', 39 + 'ian5v', 40 + 'bnewbold', 41 + 'chris', 42 + 'mtclai', 43 + 'willscott', 44 + 'michael', 45 + 'kwkroeger', 46 + 'broox', 47 + 'iamrosewang', 48 + 'jack-morrison', 49 + 'pwang', 50 + 'martin', 51 + 'jack', 52 + 'dan', 53 + 'why', 54 + 'divy', 55 + 'jay', 56 + 'paul', 57 + ].map(handle => `${handle}.bsky.social`) 58 + 59 + export const STAGING_SUGGESTED_FOLLOWS = ['arcalinea', 'paul', 'paul2'].map( 60 + handle => `${handle}.staging.bsky.dev`, 61 + ) 62 + 63 + export const DEV_SUGGESTED_FOLLOWS = ['alice', 'bob', 'carla'].map( 64 + handle => `${handle}.test`, 65 + )
-4
src/lib/errors.ts
··· 1 - export function isNetworkError(e: unknown) { 2 - const str = String(e) 3 - return str.includes('Abort') || str.includes('Network request failed') 4 - }
+23 -9
src/lib/images.ts
··· 2 2 import ImageResizer from '@bam.tech/react-native-image-resizer' 3 3 import {Share} from 'react-native' 4 4 import RNFS from 'react-native-fs' 5 - 6 - import * as Toast from '../view/com/util/Toast' 5 + import uuid from 'react-native-uuid' 6 + import * as Toast from 'view/com/util/Toast' 7 7 8 8 export interface DownloadAndResizeOpts { 9 9 uri: string ··· 23 23 } 24 24 25 25 export async function downloadAndResize(opts: DownloadAndResizeOpts) { 26 - let appendExt 26 + let appendExt = 'jpeg' 27 27 try { 28 28 const urip = new URL(opts.uri) 29 29 const ext = urip.pathname.split('.').pop() 30 - if (ext === 'jpg' || ext === 'jpeg') { 31 - appendExt = 'jpeg' 32 - } else if (ext === 'png') { 30 + if (ext === 'png') { 33 31 appendExt = 'png' 34 - } else { 35 - return 36 32 } 37 33 } catch (e: any) { 38 34 console.error('Invalid URI', opts.uri, e) ··· 109 105 if (img.size < maxSize) { 110 106 return img 111 107 } 112 - return await resize(origUri, { 108 + const resizedImage = await resize(origUri, { 113 109 width: img.width, 114 110 height: img.height, 115 111 mode: 'stretch', 116 112 maxSize, 117 113 }) 114 + const finalImageMovedPath = await moveToPremanantPath(resizedImage.path) 115 + const finalImg = { 116 + ...resizedImage, 117 + path: finalImageMovedPath, 118 + } 119 + return finalImg 118 120 } 119 121 120 122 export interface Dim { ··· 150 152 } 151 153 RNFS.unlink(imagePath) 152 154 } 155 + 156 + export const moveToPremanantPath = async (path: string) => { 157 + /* 158 + Since this package stores images in a temp directory, we need to move the file to a permanent location. 159 + Relevant: IOS bug when trying to open a second time: 160 + https://github.com/ivpusic/react-native-image-crop-picker/issues/1199 161 + */ 162 + const filename = uuid.v4() 163 + const destinationPath = `${RNFS.TemporaryDirectoryPath}/${filename}` 164 + RNFS.moveFile(path, destinationPath) 165 + return destinationPath 166 + }
+2 -3
src/lib/images.web.ts
··· 1 - import {Share} from 'react-native' 2 - 3 - import * as Toast from '../view/com/util/Toast' 1 + // import {Share} from 'react-native' 2 + // import * as Toast from 'view/com/util/Toast' 4 3 5 4 export interface DownloadAndResizeOpts { 6 5 uri: string
+74
src/lib/notifee.ts
··· 1 + import notifee, {EventType} from '@notifee/react-native' 2 + import {AppBskyEmbedImages} from '@atproto/api' 3 + import {RootStoreModel} from 'state/models/root-store' 4 + import {TabPurpose} from 'state/models/navigation' 5 + import {NotificationsViewItemModel} from 'state/models/notifications-view' 6 + import {enforceLen} from 'lib/strings/helpers' 7 + 8 + export function init(store: RootStoreModel) { 9 + store.onUnreadNotifications(count => notifee.setBadgeCount(count)) 10 + store.onPushNotification(displayNotificationFromModel) 11 + store.onSessionLoaded(() => { 12 + // request notifications permission once the user has logged in 13 + notifee.requestPermission() 14 + }) 15 + notifee.onForegroundEvent(async ({type}: {type: EventType}) => { 16 + store.log.debug('Notifee foreground event', {type}) 17 + if (type === EventType.PRESS) { 18 + store.log.debug('User pressed a notifee, opening notifications') 19 + store.nav.switchTo(TabPurpose.Notifs, true) 20 + } 21 + }) 22 + notifee.onBackgroundEvent(async _e => {}) // notifee requires this but we handle it with onForegroundEvent 23 + } 24 + 25 + export function displayNotification( 26 + title: string, 27 + body?: string, 28 + image?: string, 29 + ) { 30 + const opts: {title: string; body?: string; ios?: any} = {title} 31 + if (body) { 32 + opts.body = enforceLen(body, 70, true) 33 + } 34 + if (image) { 35 + opts.ios = { 36 + attachments: [{url: image}], 37 + } 38 + } 39 + return notifee.displayNotification(opts) 40 + } 41 + 42 + export function displayNotificationFromModel( 43 + notif: NotificationsViewItemModel, 44 + ) { 45 + let author = notif.author.displayName || notif.author.handle 46 + let title: string 47 + let body: string = '' 48 + if (notif.isUpvote) { 49 + title = `${author} liked your post` 50 + body = notif.additionalPost?.thread?.postRecord?.text || '' 51 + } else if (notif.isRepost) { 52 + title = `${author} reposted your post` 53 + body = notif.additionalPost?.thread?.postRecord?.text || '' 54 + } else if (notif.isMention) { 55 + title = `${author} mentioned you` 56 + body = notif.additionalPost?.thread?.postRecord?.text || '' 57 + } else if (notif.isReply) { 58 + title = `${author} replied to your post` 59 + body = notif.additionalPost?.thread?.postRecord?.text || '' 60 + } else if (notif.isFollow) { 61 + title = 'New follower!' 62 + body = `${author} has followed you` 63 + } else { 64 + return 65 + } 66 + let image 67 + if ( 68 + AppBskyEmbedImages.isPresented(notif.additionalPost?.thread?.post.embed) && 69 + notif.additionalPost?.thread?.post.embed.images[0]?.thumb 70 + ) { 71 + image = notif.additionalPost.thread.post.embed.images[0].thumb 72 + } 73 + return displayNotification(title, body, image) 74 + }
+61
src/lib/permissions.ts
··· 1 + import {Alert} from 'react-native' 2 + import { 3 + check, 4 + openSettings, 5 + Permission, 6 + PermissionStatus, 7 + PERMISSIONS, 8 + RESULTS, 9 + } from 'react-native-permissions' 10 + 11 + export const PHOTO_LIBRARY = PERMISSIONS.IOS.PHOTO_LIBRARY 12 + export const CAMERA = PERMISSIONS.IOS.CAMERA 13 + 14 + /** 15 + * Returns `true` if the user has granted permission or hasn't made 16 + * a decision yet. Returns `false` if unavailable or not granted. 17 + */ 18 + export async function hasAccess(perm: Permission): Promise<boolean> { 19 + const status = await check(perm) 20 + return isntANo(status) 21 + } 22 + 23 + export async function requestAccessIfNeeded( 24 + perm: Permission, 25 + ): Promise<boolean> { 26 + if (await hasAccess(perm)) { 27 + return true 28 + } 29 + let permDescription 30 + if (perm === PHOTO_LIBRARY) { 31 + permDescription = 'photo library' 32 + } else if (perm === CAMERA) { 33 + permDescription = 'camera' 34 + } else { 35 + return false 36 + } 37 + Alert.alert( 38 + 'Permission needed', 39 + `Bluesky does not have permission to access your ${permDescription}.`, 40 + [ 41 + { 42 + text: 'Cancel', 43 + style: 'cancel', 44 + }, 45 + {text: 'Open Settings', onPress: () => openSettings()}, 46 + ], 47 + ) 48 + return false 49 + } 50 + 51 + export async function requestPhotoAccessIfNeeded() { 52 + return requestAccessIfNeeded(PHOTO_LIBRARY) 53 + } 54 + 55 + export async function requestCameraAccessIfNeeded() { 56 + return requestAccessIfNeeded(CAMERA) 57 + } 58 + 59 + function isntANo(status: PermissionStatus): boolean { 60 + return status !== RESULTS.UNAVAILABLE && status !== RESULTS.BLOCKED 61 + }
+22
src/lib/permissions.web.ts
··· 1 + /* 2 + At the moment, Web doesn't have any equivalence for these. 3 + */ 4 + 5 + export const PHOTO_LIBRARY = '' 6 + export const CAMERA = '' 7 + 8 + export async function hasAccess(_perm: any): Promise<boolean> { 9 + return true 10 + } 11 + 12 + export async function requestAccessIfNeeded(_perm: any): Promise<boolean> { 13 + return true 14 + } 15 + 16 + export async function requestPhotoAccessIfNeeded() { 17 + return requestAccessIfNeeded(PHOTO_LIBRARY) 18 + } 19 + 20 + export async function requestCameraAccessIfNeeded() { 21 + return requestAccessIfNeeded(CAMERA) 22 + }
-267
src/lib/strings.ts
··· 1 - import {AtUri} from '../third-party/uri' 2 - import {AppBskyFeedPost} from '@atproto/api' 3 - type Entity = AppBskyFeedPost.Entity 4 - import {PROD_SERVICE} from '../state' 5 - import {isNetworkError} from './errors' 6 - import TLDs from 'tlds' 7 - 8 - export const MAX_DISPLAY_NAME = 64 9 - export const MAX_DESCRIPTION = 256 10 - 11 - export function pluralize(n: number, base: string, plural?: string): string { 12 - if (n === 1) { 13 - return base 14 - } 15 - if (plural) { 16 - return plural 17 - } 18 - return base + 's' 19 - } 20 - 21 - export function makeRecordUri( 22 - didOrName: string, 23 - collection: string, 24 - rkey: string, 25 - ) { 26 - const urip = new AtUri('at://host/') 27 - urip.host = didOrName 28 - urip.collection = collection 29 - urip.rkey = rkey 30 - return urip.toString() 31 - } 32 - 33 - const MINUTE = 60 34 - const HOUR = MINUTE * 60 35 - const DAY = HOUR * 24 36 - const MONTH = DAY * 30 37 - const YEAR = DAY * 365 38 - export function ago(date: number | string | Date): string { 39 - let ts: number 40 - if (typeof date === 'string') { 41 - ts = Number(new Date(date)) 42 - } else if (date instanceof Date) { 43 - ts = Number(date) 44 - } else { 45 - ts = date 46 - } 47 - const diffSeconds = Math.floor((Date.now() - ts) / 1e3) 48 - if (diffSeconds < MINUTE) { 49 - return `${diffSeconds}s` 50 - } else if (diffSeconds < HOUR) { 51 - return `${Math.floor(diffSeconds / MINUTE)}m` 52 - } else if (diffSeconds < DAY) { 53 - return `${Math.floor(diffSeconds / HOUR)}h` 54 - } else if (diffSeconds < MONTH) { 55 - return `${Math.floor(diffSeconds / DAY)}d` 56 - } else if (diffSeconds < YEAR) { 57 - return `${Math.floor(diffSeconds / MONTH)}mo` 58 - } else { 59 - return new Date(ts).toLocaleDateString() 60 - } 61 - } 62 - 63 - export function isValidDomain(str: string): boolean { 64 - return !!TLDs.find(tld => { 65 - let i = str.lastIndexOf(tld) 66 - if (i === -1) { 67 - return false 68 - } 69 - return str.charAt(i - 1) === '.' && i === str.length - tld.length 70 - }) 71 - } 72 - 73 - export function extractEntities( 74 - text: string, 75 - knownHandles?: Set<string>, 76 - ): Entity[] | undefined { 77 - let match 78 - let ents: Entity[] = [] 79 - { 80 - // mentions 81 - const re = /(^|\s|\()(@)([a-zA-Z0-9.-]+)(\b)/g 82 - while ((match = re.exec(text))) { 83 - if (knownHandles && !knownHandles.has(match[3])) { 84 - continue // not a known handle 85 - } else if (!match[3].includes('.')) { 86 - continue // probably not a handle 87 - } 88 - const start = text.indexOf(match[3], match.index) - 1 89 - ents.push({ 90 - type: 'mention', 91 - value: match[3], 92 - index: {start, end: start + match[3].length + 1}, 93 - }) 94 - } 95 - } 96 - { 97 - // links 98 - const re = 99 - /(^|\s|\()((https?:\/\/[\S]+)|((?<domain>[a-z][a-z0-9]*(\.[a-z0-9]+)+)[\S]*))/gim 100 - while ((match = re.exec(text))) { 101 - let value = match[2] 102 - if (!value.startsWith('http')) { 103 - const domain = match.groups?.domain 104 - if (!domain || !isValidDomain(domain)) { 105 - continue 106 - } 107 - value = `https://${value}` 108 - } 109 - const start = text.indexOf(match[2], match.index) 110 - const index = {start, end: start + match[2].length} 111 - // strip ending puncuation 112 - if (/[.,;!?]$/.test(value)) { 113 - value = value.slice(0, -1) 114 - index.end-- 115 - } 116 - if (/[)]$/.test(value) && !value.includes('(')) { 117 - value = value.slice(0, -1) 118 - index.end-- 119 - } 120 - ents.push({ 121 - type: 'link', 122 - value, 123 - index, 124 - }) 125 - } 126 - } 127 - return ents.length > 0 ? ents : undefined 128 - } 129 - 130 - interface DetectedLink { 131 - link: string 132 - } 133 - type DetectedLinkable = string | DetectedLink 134 - export function detectLinkables(text: string): DetectedLinkable[] { 135 - const re = 136 - /((^|\s|\()@[a-z0-9.-]*)|((^|\s|\()https?:\/\/[\S]+)|((^|\s|\()(?<domain>[a-z][a-z0-9]*(\.[a-z0-9]+)+)[\S]*)/gi 137 - const segments = [] 138 - let match 139 - let start = 0 140 - while ((match = re.exec(text))) { 141 - let matchIndex = match.index 142 - let matchValue = match[0] 143 - 144 - if (match.groups?.domain && !isValidDomain(match.groups?.domain)) { 145 - continue 146 - } 147 - 148 - if (/\s|\(/.test(matchValue)) { 149 - // HACK 150 - // skip the starting space 151 - // we have to do this because RN doesnt support negative lookaheads 152 - // -prf 153 - matchIndex++ 154 - matchValue = matchValue.slice(1) 155 - } 156 - 157 - // strip ending puncuation 158 - if (/[.,;!?]$/.test(matchValue)) { 159 - matchValue = matchValue.slice(0, -1) 160 - } 161 - if (/[)]$/.test(matchValue) && !matchValue.includes('(')) { 162 - matchValue = matchValue.slice(0, -1) 163 - } 164 - 165 - if (start !== matchIndex) { 166 - segments.push(text.slice(start, matchIndex)) 167 - } 168 - segments.push({link: matchValue}) 169 - start = matchIndex + matchValue.length 170 - } 171 - if (start < text.length) { 172 - segments.push(text.slice(start)) 173 - } 174 - return segments 175 - } 176 - 177 - export function makeValidHandle(str: string): string { 178 - if (str.length > 20) { 179 - str = str.slice(0, 20) 180 - } 181 - str = str.toLowerCase() 182 - return str.replace(/^[^a-z]+/g, '').replace(/[^a-z0-9-]/g, '') 183 - } 184 - 185 - export function createFullHandle(name: string, domain: string): string { 186 - name = (name || '').replace(/[.]+$/, '') 187 - domain = (domain || '').replace(/^[.]+/, '') 188 - return `${name}.${domain}` 189 - } 190 - 191 - export function enforceLen(str: string, len: number, ellipsis = false): string { 192 - str = str || '' 193 - if (str.length > len) { 194 - return str.slice(0, len) + (ellipsis ? '...' : '') 195 - } 196 - return str 197 - } 198 - 199 - export function cleanError(str: any): string { 200 - if (!str) { 201 - return str 202 - } 203 - if (typeof str !== 'string') { 204 - str = str.toString() 205 - } 206 - if (isNetworkError(str)) { 207 - return 'Unable to connect. Please check your internet connection and try again.' 208 - } 209 - if (str.startsWith('Error: ')) { 210 - return str.slice('Error: '.length) 211 - } 212 - return str 213 - } 214 - 215 - export function toNiceDomain(url: string): string { 216 - try { 217 - const urlp = new URL(url) 218 - if (`https://${urlp.host}` === PROD_SERVICE) { 219 - return 'Bluesky Social' 220 - } 221 - return urlp.host 222 - } catch (e) { 223 - return url 224 - } 225 - } 226 - 227 - export function toShortUrl(url: string): string { 228 - try { 229 - const urlp = new URL(url) 230 - const shortened = 231 - urlp.host + 232 - (urlp.pathname === '/' ? '' : urlp.pathname) + 233 - urlp.search + 234 - urlp.hash 235 - if (shortened.length > 30) { 236 - return shortened.slice(0, 27) + '...' 237 - } 238 - return shortened 239 - } catch (e) { 240 - return url 241 - } 242 - } 243 - 244 - export function toShareUrl(url: string): string { 245 - if (!url.startsWith('https')) { 246 - const urlp = new URL('https://bsky.app') 247 - urlp.pathname = url 248 - url = urlp.toString() 249 - } 250 - return url 251 - } 252 - 253 - export function isBskyAppUrl(url: string): boolean { 254 - return url.startsWith('https://bsky.app/') 255 - } 256 - 257 - export function convertBskyAppUrlIfNeeded(url: string): string { 258 - if (isBskyAppUrl(url)) { 259 - try { 260 - const urlp = new URL(url) 261 - return urlp.pathname 262 - } catch (e) { 263 - console.error('Unexpected error in convertBskyAppUrlIfNeeded()', e) 264 - } 265 - } 266 - return url 267 - }
+23
src/lib/strings/errors.ts
··· 1 + export function cleanError(str: any): string { 2 + if (!str) { 3 + return '' 4 + } 5 + if (typeof str !== 'string') { 6 + str = str.toString() 7 + } 8 + if (isNetworkError(str)) { 9 + return 'Unable to connect. Please check your internet connection and try again.' 10 + } 11 + if (str.includes('Upstream Failure')) { 12 + return 'The server appears to be experiencing issues. Please try again in a few moments.' 13 + } 14 + if (str.startsWith('Error: ')) { 15 + return str.slice('Error: '.length) 16 + } 17 + return str 18 + } 19 + 20 + export function isNetworkError(e: unknown) { 21 + const str = String(e) 22 + return str.includes('Abort') || str.includes('Network request failed') 23 + }
+13
src/lib/strings/handles.ts
··· 1 + export function makeValidHandle(str: string): string { 2 + if (str.length > 20) { 3 + str = str.slice(0, 20) 4 + } 5 + str = str.toLowerCase() 6 + return str.replace(/^[^a-z]+/g, '').replace(/[^a-z0-9-]/g, '') 7 + } 8 + 9 + export function createFullHandle(name: string, domain: string): string { 10 + name = (name || '').replace(/[.]+$/, '') 11 + domain = (domain || '').replace(/^[.]+/, '') 12 + return `${name}.${domain}` 13 + }
+17
src/lib/strings/helpers.ts
··· 1 + export function pluralize(n: number, base: string, plural?: string): string { 2 + if (n === 1) { 3 + return base 4 + } 5 + if (plural) { 6 + return plural 7 + } 8 + return base + 's' 9 + } 10 + 11 + export function enforceLen(str: string, len: number, ellipsis = false): string { 12 + str = str || '' 13 + if (str.length > len) { 14 + return str.slice(0, len) + (ellipsis ? '...' : '') 15 + } 16 + return str 17 + }
+37
src/lib/strings/mention-manip.ts
··· 1 + interface FoundMention { 2 + value: string 3 + index: number 4 + } 5 + 6 + export function getMentionAt( 7 + text: string, 8 + cursorPos: number, 9 + ): FoundMention | undefined { 10 + let re = /(^|\s)@([a-z0-9.]*)/gi 11 + let match 12 + while ((match = re.exec(text))) { 13 + const spaceOffset = match[1].length 14 + const index = match.index + spaceOffset 15 + if ( 16 + cursorPos >= index && 17 + cursorPos <= index + match[0].length - spaceOffset 18 + ) { 19 + return {value: match[2], index} 20 + } 21 + } 22 + return undefined 23 + } 24 + 25 + export function insertMentionAt( 26 + text: string, 27 + cursorPos: number, 28 + mention: string, 29 + ) { 30 + const target = getMentionAt(text, cursorPos) 31 + if (target) { 32 + return `${text.slice(0, target.index)}@${mention} ${text.slice( 33 + target.index + target.value.length + 1, // add 1 to include the "@" 34 + )}` 35 + } 36 + return text 37 + }
+107
src/lib/strings/rich-text-detection.ts
··· 1 + import {AppBskyFeedPost} from '@atproto/api' 2 + type Entity = AppBskyFeedPost.Entity 3 + import {isValidDomain} from './url-helpers' 4 + 5 + export function extractEntities( 6 + text: string, 7 + knownHandles?: Set<string>, 8 + ): Entity[] | undefined { 9 + let match 10 + let ents: Entity[] = [] 11 + { 12 + // mentions 13 + const re = /(^|\s|\()(@)([a-zA-Z0-9.-]+)(\b)/g 14 + while ((match = re.exec(text))) { 15 + if (knownHandles && !knownHandles.has(match[3])) { 16 + continue // not a known handle 17 + } else if (!match[3].includes('.')) { 18 + continue // probably not a handle 19 + } 20 + const start = text.indexOf(match[3], match.index) - 1 21 + ents.push({ 22 + type: 'mention', 23 + value: match[3], 24 + index: {start, end: start + match[3].length + 1}, 25 + }) 26 + } 27 + } 28 + { 29 + // links 30 + const re = 31 + /(^|\s|\()((https?:\/\/[\S]+)|((?<domain>[a-z][a-z0-9]*(\.[a-z0-9]+)+)[\S]*))/gim 32 + while ((match = re.exec(text))) { 33 + let value = match[2] 34 + if (!value.startsWith('http')) { 35 + const domain = match.groups?.domain 36 + if (!domain || !isValidDomain(domain)) { 37 + continue 38 + } 39 + value = `https://${value}` 40 + } 41 + const start = text.indexOf(match[2], match.index) 42 + const index = {start, end: start + match[2].length} 43 + // strip ending puncuation 44 + if (/[.,;!?]$/.test(value)) { 45 + value = value.slice(0, -1) 46 + index.end-- 47 + } 48 + if (/[)]$/.test(value) && !value.includes('(')) { 49 + value = value.slice(0, -1) 50 + index.end-- 51 + } 52 + ents.push({ 53 + type: 'link', 54 + value, 55 + index, 56 + }) 57 + } 58 + } 59 + return ents.length > 0 ? ents : undefined 60 + } 61 + 62 + interface DetectedLink { 63 + link: string 64 + } 65 + type DetectedLinkable = string | DetectedLink 66 + export function detectLinkables(text: string): DetectedLinkable[] { 67 + const re = 68 + /((^|\s|\()@[a-z0-9.-]*)|((^|\s|\()https?:\/\/[\S]+)|((^|\s|\()(?<domain>[a-z][a-z0-9]*(\.[a-z0-9]+)+)[\S]*)/gi 69 + const segments = [] 70 + let match 71 + let start = 0 72 + while ((match = re.exec(text))) { 73 + let matchIndex = match.index 74 + let matchValue = match[0] 75 + 76 + if (match.groups?.domain && !isValidDomain(match.groups?.domain)) { 77 + continue 78 + } 79 + 80 + if (/\s|\(/.test(matchValue)) { 81 + // HACK 82 + // skip the starting space 83 + // we have to do this because RN doesnt support negative lookaheads 84 + // -prf 85 + matchIndex++ 86 + matchValue = matchValue.slice(1) 87 + } 88 + 89 + // strip ending puncuation 90 + if (/[.,;!?]$/.test(matchValue)) { 91 + matchValue = matchValue.slice(0, -1) 92 + } 93 + if (/[)]$/.test(matchValue) && !matchValue.includes('(')) { 94 + matchValue = matchValue.slice(0, -1) 95 + } 96 + 97 + if (start !== matchIndex) { 98 + segments.push(text.slice(start, matchIndex)) 99 + } 100 + segments.push({link: matchValue}) 101 + start = matchIndex + matchValue.length 102 + } 103 + if (start < text.length) { 104 + segments.push(text.slice(start)) 105 + } 106 + return segments 107 + }
+32
src/lib/strings/rich-text-sanitize.ts
··· 1 + import {RichText} from './rich-text' 2 + 3 + const EXCESS_SPACE_RE = /[\r\n]([\u00AD\u2060\u200D\u200C\u200B\s]*[\r\n]){2,}/ 4 + const REPLACEMENT_STR = '\n\n' 5 + 6 + export function removeExcessNewlines(richText: RichText): RichText { 7 + return clean(richText, EXCESS_SPACE_RE, REPLACEMENT_STR) 8 + } 9 + 10 + // TODO: check on whether this works correctly with multi-byte codepoints 11 + export function clean( 12 + richText: RichText, 13 + targetRegexp: RegExp, 14 + replacementString: string, 15 + ): RichText { 16 + richText = richText.clone() 17 + 18 + let match = richText.text.match(targetRegexp) 19 + while (match && typeof match.index !== 'undefined') { 20 + const oldText = richText.text 21 + const removeStartIndex = match.index 22 + const removeEndIndex = removeStartIndex + match[0].length 23 + richText.delete(removeStartIndex, removeEndIndex) 24 + if (richText.text === oldText) { 25 + break // sanity check 26 + } 27 + richText.insert(removeStartIndex, replacementString) 28 + match = richText.text.match(targetRegexp) 29 + } 30 + 31 + return richText 32 + }
+216
src/lib/strings/rich-text.ts
··· 1 + /* 2 + = Rich Text Manipulation 3 + 4 + When we sanitize rich text, we have to update the entity indices as the 5 + text is modified. This can be modeled as inserts() and deletes() of the 6 + rich text string. The possible scenarios are outlined below, along with 7 + their expected behaviors. 8 + 9 + NOTE: Slices are start inclusive, end exclusive 10 + 11 + == richTextInsert() 12 + 13 + Target string: 14 + 15 + 0 1 2 3 4 5 6 7 8 910 // string indices 16 + h e l l o w o r l d // string value 17 + ^-------^ // target slice {start: 2, end: 7} 18 + 19 + Scenarios: 20 + 21 + A: ^ // insert "test" at 0 22 + B: ^ // insert "test" at 4 23 + C: ^ // insert "test" at 8 24 + 25 + A = before -> move both by num added 26 + B = inner -> move end by num added 27 + C = after -> noop 28 + 29 + Results: 30 + 31 + A: 0 1 2 3 4 5 6 7 8 910 // string indices 32 + t e s t h e l l o w // string value 33 + ^-------^ // target slice {start: 6, end: 11} 34 + 35 + B: 0 1 2 3 4 5 6 7 8 910 // string indices 36 + h e l l t e s t o w // string value 37 + ^---------------^ // target slice {start: 2, end: 11} 38 + 39 + C: 0 1 2 3 4 5 6 7 8 910 // string indices 40 + h e l l o w o t e s // string value 41 + ^-------^ // target slice {start: 2, end: 7} 42 + 43 + == richTextDelete() 44 + 45 + Target string: 46 + 47 + 0 1 2 3 4 5 6 7 8 910 // string indices 48 + h e l l o w o r l d // string value 49 + ^-------^ // target slice {start: 2, end: 7} 50 + 51 + Scenarios: 52 + 53 + A: ^---------------^ // remove slice {start: 0, end: 9} 54 + B: ^-----^ // remove slice {start: 7, end: 11} 55 + C: ^-----------^ // remove slice {start: 4, end: 11} 56 + D: ^-^ // remove slice {start: 3, end: 5} 57 + E: ^-----^ // remove slice {start: 1, end: 5} 58 + F: ^-^ // remove slice {start: 0, end: 2} 59 + 60 + A = entirely outer -> delete slice 61 + B = entirely after -> noop 62 + C = partially after -> move end to remove-start 63 + D = entirely inner -> move end by num removed 64 + E = partially before -> move start to remove-start index, move end by num removed 65 + F = entirely before -> move both by num removed 66 + 67 + Results: 68 + 69 + A: 0 1 2 3 4 5 6 7 8 910 // string indices 70 + l d // string value 71 + // target slice (deleted) 72 + 73 + B: 0 1 2 3 4 5 6 7 8 910 // string indices 74 + h e l l o w // string value 75 + ^-------^ // target slice {start: 2, end: 7} 76 + 77 + C: 0 1 2 3 4 5 6 7 8 910 // string indices 78 + h e l l // string value 79 + ^-^ // target slice {start: 2, end: 4} 80 + 81 + D: 0 1 2 3 4 5 6 7 8 910 // string indices 82 + h e l w o r l d // string value 83 + ^---^ // target slice {start: 2, end: 5} 84 + 85 + E: 0 1 2 3 4 5 6 7 8 910 // string indices 86 + h w o r l d // string value 87 + ^-^ // target slice {start: 1, end: 3} 88 + 89 + F: 0 1 2 3 4 5 6 7 8 910 // string indices 90 + l l o w o r l d // string value 91 + ^-------^ // target slice {start: 0, end: 5} 92 + */ 93 + 94 + import cloneDeep from 'lodash.clonedeep' 95 + import {AppBskyFeedPost} from '@atproto/api' 96 + import {removeExcessNewlines} from './rich-text-sanitize' 97 + 98 + export type Entity = AppBskyFeedPost.Entity 99 + export interface RichTextOpts { 100 + cleanNewlines?: boolean 101 + } 102 + 103 + export class RichText { 104 + constructor( 105 + public text: string, 106 + public entities?: Entity[], 107 + opts?: RichTextOpts, 108 + ) { 109 + if (opts?.cleanNewlines) { 110 + removeExcessNewlines(this).copyInto(this) 111 + } 112 + } 113 + 114 + clone() { 115 + return new RichText(this.text, cloneDeep(this.entities)) 116 + } 117 + 118 + copyInto(target: RichText) { 119 + target.text = this.text 120 + target.entities = cloneDeep(this.entities) 121 + } 122 + 123 + insert(insertIndex: number, insertText: string) { 124 + this.text = 125 + this.text.slice(0, insertIndex) + 126 + insertText + 127 + this.text.slice(insertIndex) 128 + 129 + if (!this.entities?.length) { 130 + return this 131 + } 132 + 133 + const numCharsAdded = insertText.length 134 + for (const ent of this.entities) { 135 + // see comment at top of file for labels of each scenario 136 + // scenario A (before) 137 + if (insertIndex <= ent.index.start) { 138 + // move both by num added 139 + ent.index.start += numCharsAdded 140 + ent.index.end += numCharsAdded 141 + } 142 + // scenario B (inner) 143 + else if (insertIndex >= ent.index.start && insertIndex < ent.index.end) { 144 + // move end by num added 145 + ent.index.end += numCharsAdded 146 + } 147 + // scenario C (after) 148 + // noop 149 + } 150 + return this 151 + } 152 + 153 + delete(removeStartIndex: number, removeEndIndex: number) { 154 + this.text = 155 + this.text.slice(0, removeStartIndex) + this.text.slice(removeEndIndex) 156 + 157 + if (!this.entities?.length) { 158 + return this 159 + } 160 + 161 + const numCharsRemoved = removeEndIndex - removeStartIndex 162 + for (const ent of this.entities) { 163 + // see comment at top of file for labels of each scenario 164 + // scenario A (entirely outer) 165 + if ( 166 + removeStartIndex <= ent.index.start && 167 + removeEndIndex >= ent.index.end 168 + ) { 169 + // delete slice (will get removed in final pass) 170 + ent.index.start = 0 171 + ent.index.end = 0 172 + } 173 + // scenario B (entirely after) 174 + else if (removeStartIndex > ent.index.end) { 175 + // noop 176 + } 177 + // scenario C (partially after) 178 + else if ( 179 + removeStartIndex > ent.index.start && 180 + removeStartIndex <= ent.index.end && 181 + removeEndIndex > ent.index.end 182 + ) { 183 + // move end to remove start 184 + ent.index.end = removeStartIndex 185 + } 186 + // scenario D (entirely inner) 187 + else if ( 188 + removeStartIndex >= ent.index.start && 189 + removeEndIndex <= ent.index.end 190 + ) { 191 + // move end by num removed 192 + ent.index.end -= numCharsRemoved 193 + } 194 + // scenario E (partially before) 195 + else if ( 196 + removeStartIndex < ent.index.start && 197 + removeEndIndex >= ent.index.start && 198 + removeEndIndex <= ent.index.end 199 + ) { 200 + // move start to remove-start index, move end by num removed 201 + ent.index.start = removeStartIndex 202 + ent.index.end -= numCharsRemoved 203 + } 204 + // scenario F (entirely before) 205 + else if (removeEndIndex < ent.index.start) { 206 + // move both by num removed 207 + ent.index.start -= numCharsRemoved 208 + ent.index.end -= numCharsRemoved 209 + } 210 + } 211 + 212 + // filter out any entities that were made irrelevant 213 + this.entities = this.entities.filter(ent => ent.index.start < ent.index.end) 214 + return this 215 + } 216 + }
+29
src/lib/strings/time.ts
··· 1 + const MINUTE = 60 2 + const HOUR = MINUTE * 60 3 + const DAY = HOUR * 24 4 + const MONTH = DAY * 30 5 + const YEAR = DAY * 365 6 + export function ago(date: number | string | Date): string { 7 + let ts: number 8 + if (typeof date === 'string') { 9 + ts = Number(new Date(date)) 10 + } else if (date instanceof Date) { 11 + ts = Number(date) 12 + } else { 13 + ts = date 14 + } 15 + const diffSeconds = Math.floor((Date.now() - ts) / 1e3) 16 + if (diffSeconds < MINUTE) { 17 + return `${diffSeconds}s` 18 + } else if (diffSeconds < HOUR) { 19 + return `${Math.floor(diffSeconds / MINUTE)}m` 20 + } else if (diffSeconds < DAY) { 21 + return `${Math.floor(diffSeconds / HOUR)}h` 22 + } else if (diffSeconds < MONTH) { 23 + return `${Math.floor(diffSeconds / DAY)}d` 24 + } else if (diffSeconds < YEAR) { 25 + return `${Math.floor(diffSeconds / MONTH)}mo` 26 + } else { 27 + return new Date(ts).toLocaleDateString() 28 + } 29 + }
+108
src/lib/strings/url-helpers.ts
··· 1 + import {AtUri} from '../../third-party/uri' 2 + import {PROD_SERVICE} from 'state/index' 3 + import TLDs from 'tlds' 4 + 5 + export function isValidDomain(str: string): boolean { 6 + return !!TLDs.find(tld => { 7 + let i = str.lastIndexOf(tld) 8 + if (i === -1) { 9 + return false 10 + } 11 + return str.charAt(i - 1) === '.' && i === str.length - tld.length 12 + }) 13 + } 14 + 15 + export function makeRecordUri( 16 + didOrName: string, 17 + collection: string, 18 + rkey: string, 19 + ) { 20 + const urip = new AtUri('at://host/') 21 + urip.host = didOrName 22 + urip.collection = collection 23 + urip.rkey = rkey 24 + return urip.toString() 25 + } 26 + 27 + export function toNiceDomain(url: string): string { 28 + try { 29 + const urlp = new URL(url) 30 + if (`https://${urlp.host}` === PROD_SERVICE) { 31 + return 'Bluesky Social' 32 + } 33 + return urlp.host 34 + } catch (e) { 35 + return url 36 + } 37 + } 38 + 39 + export function toShortUrl(url: string): string { 40 + try { 41 + const urlp = new URL(url) 42 + const shortened = 43 + urlp.host + 44 + (urlp.pathname === '/' ? '' : urlp.pathname) + 45 + urlp.search + 46 + urlp.hash 47 + if (shortened.length > 30) { 48 + return shortened.slice(0, 27) + '...' 49 + } 50 + return shortened 51 + } catch (e) { 52 + return url 53 + } 54 + } 55 + 56 + export function toShareUrl(url: string): string { 57 + if (!url.startsWith('https')) { 58 + const urlp = new URL('https://bsky.app') 59 + urlp.pathname = url 60 + url = urlp.toString() 61 + } 62 + return url 63 + } 64 + 65 + export function isBskyAppUrl(url: string): boolean { 66 + return url.startsWith('https://bsky.app/') 67 + } 68 + 69 + export function convertBskyAppUrlIfNeeded(url: string): string { 70 + if (isBskyAppUrl(url)) { 71 + try { 72 + const urlp = new URL(url) 73 + return urlp.pathname 74 + } catch (e) { 75 + console.error('Unexpected error in convertBskyAppUrlIfNeeded()', e) 76 + } 77 + } 78 + return url 79 + } 80 + 81 + export function getYoutubeVideoId(link: string): string | undefined { 82 + let url 83 + try { 84 + url = new URL(link) 85 + } catch (e) { 86 + return undefined 87 + } 88 + 89 + if ( 90 + url.hostname !== 'www.youtube.com' && 91 + url.hostname !== 'youtube.com' && 92 + url.hostname !== 'youtu.be' 93 + ) { 94 + return undefined 95 + } 96 + if (url.hostname === 'youtu.be') { 97 + const videoId = url.pathname.split('/')[1] 98 + if (!videoId) { 99 + return undefined 100 + } 101 + return videoId 102 + } 103 + const videoId = url.searchParams.get('v') as string 104 + if (!videoId) { 105 + return undefined 106 + } 107 + return videoId 108 + }
+14 -26
src/state/index.ts
··· 1 1 import {autorun} from 'mobx' 2 - import {Platform} from 'react-native' 3 - import {sessionClient as AtpApi, SessionServiceClient} from '@atproto/api' 2 + import {AppState, Platform} from 'react-native' 3 + import {AtpAgent} from '@atproto/api' 4 4 import {RootStoreModel} from './models/root-store' 5 - import * as apiPolyfill from './lib/api-polyfill' 6 - import * as storage from './lib/storage' 5 + import * as apiPolyfill from 'lib/api/api-polyfill' 6 + import * as storage from 'lib/storage' 7 7 8 8 export const LOCAL_DEV_SERVICE = 9 9 Platform.OS === 'ios' ? 'http://localhost:2583' : 'http://10.0.2.2:2583' ··· 19 19 20 20 apiPolyfill.doPolyfill() 21 21 22 - const api = AtpApi.service(serviceUri) as SessionServiceClient 23 - rootStore = new RootStoreModel(api) 22 + rootStore = new RootStoreModel(new AtpAgent({service: serviceUri})) 24 23 try { 25 24 data = (await storage.load(ROOT_STATE_STORAGE_KEY)) || {} 26 25 rootStore.log.debug('Initial hydrate', {hasSession: !!data.session}) ··· 28 27 } catch (e: any) { 29 28 rootStore.log.error('Failed to load state from storage', e) 30 29 } 31 - 32 - rootStore.session 33 - .connect() 34 - .then(() => { 35 - rootStore.log.debug('Session connected') 36 - return rootStore.fetchStateUpdate() 37 - }) 38 - .catch((e: any) => { 39 - rootStore.log.warn('Failed initial connect', e) 40 - }) 41 - // @ts-ignore .on() is correct -prf 42 - api.sessionManager.on('session', () => { 43 - if (!api.sessionManager.session && rootStore.session.hasSession) { 44 - // reset session 45 - rootStore.session.clear() 46 - } else if (api.sessionManager.session) { 47 - rootStore.session.updateAuthTokens(api.sessionManager.session) 48 - } 49 - }) 30 + rootStore.attemptSessionResumption() 50 31 51 32 // track changes & save to storage 52 33 autorun(() => { ··· 56 37 57 38 // periodic state fetch 58 39 setInterval(() => { 59 - rootStore.fetchStateUpdate() 40 + // NOTE 41 + // this must ONLY occur when the app is active, as the bg-fetch handler 42 + // will wake up the thread and cause this interval to fire, which in 43 + // turn schedules a bunch of work at a poor time 44 + // -prf 45 + if (AppState.currentState === 'active') { 46 + rootStore.updateSessionState() 47 + } 60 48 }, STATE_FETCH_INTERVAL) 61 49 62 50 return rootStore
+2 -2
src/state/lib/api-polyfill.ts src/lib/api/api-polyfill.ts
··· 1 - import {sessionClient as AtpApi} from '@atproto/api' 1 + import AtpAgent from '@atproto/api' 2 2 import RNFS from 'react-native-fs' 3 3 4 4 const TIMEOUT = 10e3 // 10s 5 5 6 6 export function doPolyfill() { 7 - AtpApi.xrpc.fetch = fetchHandler 7 + AtpAgent.configure({fetch: fetchHandler}) 8 8 } 9 9 10 10 interface FetchHandlerResponse {
src/state/lib/api-polyfill.web.ts src/lib/api/api-polyfill.web.ts
+23 -12
src/state/lib/api.ts src/lib/api/index.ts
··· 1 - /** 2 - * The environment is a place where services and shared dependencies between 3 - * models live. They are made available to every model via dependency injection. 4 - */ 5 - 6 - // import {ReactNativeStore} from './auth' 7 1 import {AppBskyEmbedImages, AppBskyEmbedExternal} from '@atproto/api' 8 2 import {AtUri} from '../../third-party/uri' 9 - import {RootStoreModel} from '../models/root-store' 10 - import {extractEntities} from '../../lib/strings' 11 - import {isNetworkError} from '../../lib/errors' 12 - import {LinkMeta} from '../../lib/link-meta' 13 - import {Image} from '../../lib/images' 3 + import {RootStoreModel} from 'state/models/root-store' 4 + import {extractEntities} from 'lib/strings/rich-text-detection' 5 + import {isNetworkError} from 'lib/strings/errors' 6 + import {LinkMeta} from '../link-meta/link-meta' 7 + import {Image} from '../images' 8 + import {RichText} from '../strings/rich-text' 14 9 15 10 export interface ExternalEmbedDraft { 16 11 uri: string ··· 19 14 localThumb?: Image 20 15 } 21 16 17 + export async function resolveName(store: RootStoreModel, didOrHandle: string) { 18 + if (!didOrHandle) { 19 + throw new Error('Invalid handle: ""') 20 + } 21 + if (didOrHandle.startsWith('did:')) { 22 + return didOrHandle 23 + } 24 + const res = await store.api.com.atproto.handle.resolve({ 25 + handle: didOrHandle, 26 + }) 27 + return res.data.did 28 + } 29 + 22 30 export async function post( 23 31 store: RootStoreModel, 24 - text: string, 32 + rawText: string, 25 33 replyTo?: string, 26 34 extLink?: ExternalEmbedDraft, 27 35 images?: string[], ··· 30 38 ) { 31 39 let embed: AppBskyEmbedImages.Main | AppBskyEmbedExternal.Main | undefined 32 40 let reply 41 + const text = new RichText(rawText, undefined, { 42 + cleanNewlines: true, 43 + }).text.trim() 33 44 34 45 onStateChange?.('Processing...') 35 46 const entities = extractEntities(text, knownHandles)
+1 -1
src/state/lib/bg-scheduler.ts src/lib/bg-scheduler.ts
··· 4 4 5 5 export function configure( 6 6 handler: (taskId: string) => Promise<void>, 7 - timeoutHandler: (taskId: string) => Promise<void>, 7 + timeoutHandler: (taskId: string) => void, 8 8 ): Promise<BackgroundFetchStatus> { 9 9 return BackgroundFetch.configure( 10 10 {minimumFetchInterval: 15},
src/state/lib/bg-scheduler.web.ts src/lib/bg-scheduler.web.ts
src/state/lib/storage.ts src/lib/storage.ts
src/state/lib/type-guards.ts src/lib/type-guards.ts
+178 -165
src/state/models/feed-view.ts
··· 5 5 AppBskyFeedPost, 6 6 AppBskyFeedGetAuthorFeed as GetAuthorFeed, 7 7 } from '@atproto/api' 8 + import AwaitLock from 'await-lock' 9 + import {bundleAsync} from 'lib/async/bundle' 8 10 type FeedViewPost = AppBskyFeedFeedViewPost.Main 9 11 type ReasonRepost = AppBskyFeedFeedViewPost.ReasonRepost 10 12 type PostView = AppBskyFeedPost.View 11 13 import {AtUri} from '../../third-party/uri' 12 14 import {RootStoreModel} from './root-store' 13 - import * as apilib from '../lib/api' 14 - import {cleanError} from '../../lib/strings' 15 + import * as apilib from 'lib/api/index' 16 + import {cleanError} from 'lib/strings/errors' 17 + import {RichText} from 'lib/strings/rich-text' 15 18 16 19 const PAGE_SIZE = 30 17 20 ··· 37 40 reply?: FeedViewPost['reply'] 38 41 replyParent?: FeedItemModel 39 42 reason?: FeedViewPost['reason'] 43 + richText?: RichText 40 44 41 45 constructor( 42 46 public rootStore: RootStoreModel, ··· 49 53 const valid = AppBskyFeedPost.validateRecord(this.post.record) 50 54 if (valid.success) { 51 55 this.postRecord = this.post.record 56 + this.richText = new RichText( 57 + this.postRecord.text, 58 + this.postRecord.entities, 59 + {cleanNewlines: true}, 60 + ) 52 61 } else { 53 62 rootStore.log.warn( 54 63 'Received an invalid app.bsky.feed.post record', ··· 187 196 hasMore = true 188 197 loadMoreCursor: string | undefined 189 198 pollCursor: string | undefined 190 - _loadPromise: Promise<void> | undefined 191 - _loadMorePromise: Promise<void> | undefined 192 - _loadLatestPromise: Promise<void> | undefined 193 - _updatePromise: Promise<void> | undefined 199 + 200 + // used to linearize async modifications to state 201 + private lock = new AwaitLock() 194 202 195 203 // data 196 204 feed: FeedItemModel[] = [] ··· 206 214 rootStore: false, 207 215 params: false, 208 216 loadMoreCursor: false, 209 - _loadPromise: false, 210 - _loadMorePromise: false, 211 - _loadLatestPromise: false, 212 - _updatePromise: false, 213 217 }, 214 218 {autoBind: true}, 215 219 ) ··· 229 233 } 230 234 231 235 get nonReplyFeed() { 232 - return this.feed.filter( 233 - item => 236 + const nonReplyFeed = this.feed.filter(item => { 237 + const params = this.params as GetAuthorFeed.QueryParams 238 + const isRepost = 239 + item.reply && 240 + (item?.reasonRepost?.by?.handle === params.author || 241 + item?.reasonRepost?.by?.did === params.author) 242 + 243 + return ( 234 244 !item.reply || // not a reply 245 + isRepost || 235 246 ((item._isThreadParent || // but allow if it's a thread by the user 236 247 item._isThreadChild) && 237 - item.reply?.root.author.did === item.post.author.did), 238 - ) 248 + item.reply?.root.author.did === item.post.author.did) 249 + ) 250 + }) 251 + return nonReplyFeed 239 252 } 240 253 241 254 setHasNewLatest(v: boolean) { ··· 246 259 // = 247 260 248 261 /** 262 + * Nuke all data 263 + */ 264 + clear() { 265 + this.rootStore.log.debug('FeedModel:clear') 266 + this.isLoading = false 267 + this.isRefreshing = false 268 + this.hasNewLatest = false 269 + this.hasLoaded = false 270 + this.error = '' 271 + this.hasMore = true 272 + this.loadMoreCursor = undefined 273 + this.pollCursor = undefined 274 + this.feed = [] 275 + } 276 + 277 + /** 249 278 * Load for first render 250 279 */ 251 - async setup(isRefreshing = false) { 280 + setup = bundleAsync(async (isRefreshing: boolean = false) => { 281 + this.rootStore.log.debug('FeedModel:setup', {isRefreshing}) 252 282 if (isRefreshing) { 253 283 this.isRefreshing = true // set optimistically for UI 254 284 } 255 - if (this._loadPromise) { 256 - return this._loadPromise 285 + await this.lock.acquireAsync() 286 + try { 287 + this.setHasNewLatest(false) 288 + this._xLoading(isRefreshing) 289 + try { 290 + const res = await this._getFeed({limit: PAGE_SIZE}) 291 + await this._replaceAll(res) 292 + this._xIdle() 293 + } catch (e: any) { 294 + this._xIdle(e) 295 + } 296 + } finally { 297 + this.lock.release() 257 298 } 258 - await this._pendingWork() 259 - this.setHasNewLatest(false) 260 - this._loadPromise = this._initialLoad(isRefreshing) 261 - await this._loadPromise 262 - this._loadPromise = undefined 263 - } 299 + }) 264 300 265 301 /** 266 302 * Register any event listeners. Returns a cleanup function. ··· 280 316 /** 281 317 * Load more posts to the end of the feed 282 318 */ 283 - async loadMore() { 284 - if (this._loadMorePromise) { 285 - return this._loadMorePromise 319 + loadMore = bundleAsync(async () => { 320 + await this.lock.acquireAsync() 321 + try { 322 + if (!this.hasMore || this.hasError) { 323 + return 324 + } 325 + this._xLoading() 326 + try { 327 + const res = await this._getFeed({ 328 + before: this.loadMoreCursor, 329 + limit: PAGE_SIZE, 330 + }) 331 + await this._appendAll(res) 332 + this._xIdle() 333 + } catch (e: any) { 334 + this._xIdle() // don't bubble the error to the user 335 + this.rootStore.log.error('FeedView: Failed to load more', { 336 + params: this.params, 337 + e, 338 + }) 339 + } 340 + } finally { 341 + this.lock.release() 286 342 } 287 - await this._pendingWork() 288 - this._loadMorePromise = this._loadMore() 289 - await this._loadMorePromise 290 - this._loadMorePromise = undefined 291 - } 343 + }) 292 344 293 345 /** 294 346 * Load more posts to the start of the feed 295 347 */ 296 - async loadLatest() { 297 - if (this._loadLatestPromise) { 298 - return this._loadLatestPromise 348 + loadLatest = bundleAsync(async () => { 349 + await this.lock.acquireAsync() 350 + try { 351 + this.setHasNewLatest(false) 352 + this._xLoading() 353 + try { 354 + const res = await this._getFeed({limit: PAGE_SIZE}) 355 + await this._prependAll(res) 356 + this._xIdle() 357 + } catch (e: any) { 358 + this._xIdle() // don't bubble the error to the user 359 + this.rootStore.log.error('FeedView: Failed to load latest', { 360 + params: this.params, 361 + e, 362 + }) 363 + } 364 + } finally { 365 + this.lock.release() 299 366 } 300 - await this._pendingWork() 301 - this.setHasNewLatest(false) 302 - this._loadLatestPromise = this._loadLatest() 303 - await this._loadLatestPromise 304 - this._loadLatestPromise = undefined 305 - } 367 + }) 306 368 307 369 /** 308 370 * Update content in-place 309 371 */ 310 - async update() { 311 - if (this._updatePromise) { 312 - return this._updatePromise 372 + update = bundleAsync(async () => { 373 + await this.lock.acquireAsync() 374 + try { 375 + if (!this.feed.length) { 376 + return 377 + } 378 + this._xLoading() 379 + let numToFetch = this.feed.length 380 + let cursor 381 + try { 382 + do { 383 + const res: GetTimeline.Response = await this._getFeed({ 384 + before: cursor, 385 + limit: Math.min(numToFetch, 100), 386 + }) 387 + if (res.data.feed.length === 0) { 388 + break // sanity check 389 + } 390 + this._updateAll(res) 391 + numToFetch -= res.data.feed.length 392 + cursor = res.data.cursor 393 + } while (cursor && numToFetch > 0) 394 + this._xIdle() 395 + } catch (e: any) { 396 + this._xIdle() // don't bubble the error to the user 397 + this.rootStore.log.error('FeedView: Failed to update', { 398 + params: this.params, 399 + e, 400 + }) 401 + } 402 + } finally { 403 + this.lock.release() 313 404 } 314 - await this._pendingWork() 315 - this._updatePromise = this._update() 316 - await this._updatePromise 317 - this._updatePromise = undefined 318 - } 405 + }) 319 406 320 407 /** 321 408 * Check if new posts are available ··· 324 411 if (this.hasNewLatest) { 325 412 return 326 413 } 327 - await this._pendingWork() 328 414 const res = await this._getFeed({limit: 1}) 329 415 const currentLatestUri = this.pollCursor 330 - const receivedLatestUri = res.data.feed[0] 331 - ? res.data.feed[0].post.uri 332 - : undefined 333 - const hasNewLatest = Boolean( 334 - receivedLatestUri && 335 - (this.feed.length === 0 || receivedLatestUri !== currentLatestUri), 336 - ) 337 - this.setHasNewLatest(hasNewLatest) 416 + const item = res.data.feed[0] 417 + if (!item) { 418 + return 419 + } 420 + if (AppBskyFeedFeedViewPost.isReasonRepost(item.reason)) { 421 + if (item.reason.by.did === this.rootStore.me.did) { 422 + return // ignore reposts by the user 423 + } 424 + } 425 + this.setHasNewLatest(item.post.uri !== currentLatestUri) 338 426 } 339 427 340 428 /** ··· 363 451 this.isLoading = false 364 452 this.isRefreshing = false 365 453 this.hasLoaded = true 366 - this.error = err ? cleanError(err.toString()) : '' 454 + this.error = cleanError(err) 367 455 if (err) { 368 456 this.rootStore.log.error('Posts feed request failed', err) 369 457 } 370 458 } 371 459 372 - // loader functions 460 + // helper functions 373 461 // = 374 462 375 - private async _pendingWork() { 376 - if (this._loadPromise) { 377 - await this._loadPromise 378 - } 379 - if (this._loadMorePromise) { 380 - await this._loadMorePromise 381 - } 382 - if (this._loadLatestPromise) { 383 - await this._loadLatestPromise 384 - } 385 - if (this._updatePromise) { 386 - await this._updatePromise 387 - } 388 - } 389 - 390 - private async _initialLoad(isRefreshing = false) { 391 - this._xLoading(isRefreshing) 392 - try { 393 - const res = await this._getFeed({limit: PAGE_SIZE}) 394 - await this._replaceAll(res) 395 - this._xIdle() 396 - } catch (e: any) { 397 - this._xIdle(e) 398 - } 399 - } 400 - 401 - private async _loadLatest() { 402 - this._xLoading() 403 - try { 404 - const res = await this._getFeed({limit: PAGE_SIZE}) 405 - await this._prependAll(res) 406 - this._xIdle() 407 - } catch (e: any) { 408 - this._xIdle(e) 409 - } 410 - } 411 - 412 - private async _loadMore() { 413 - if (!this.hasMore || this.hasError) { 414 - return 415 - } 416 - this._xLoading() 417 - try { 418 - const res = await this._getFeed({ 419 - before: this.loadMoreCursor, 420 - limit: PAGE_SIZE, 421 - }) 422 - await this._appendAll(res) 423 - this._xIdle() 424 - } catch (e: any) { 425 - this._xIdle(e) 426 - } 427 - } 428 - 429 - private async _update() { 430 - if (!this.feed.length) { 431 - return 432 - } 433 - this._xLoading() 434 - let numToFetch = this.feed.length 435 - let cursor 436 - try { 437 - do { 438 - const res: GetTimeline.Response = await this._getFeed({ 439 - before: cursor, 440 - limit: Math.min(numToFetch, 100), 441 - }) 442 - if (res.data.feed.length === 0) { 443 - break // sanity check 444 - } 445 - this._updateAll(res) 446 - numToFetch -= res.data.feed.length 447 - cursor = res.data.cursor 448 - } while (cursor && numToFetch > 0) 449 - this._xIdle() 450 - } catch (e: any) { 451 - this._xIdle(e) 452 - } 453 - } 454 - 455 463 private async _replaceAll( 456 464 res: GetTimeline.Response | GetAuthorFeed.Response, 457 465 ) { ··· 570 578 reorg.unshift(item) 571 579 } 572 580 573 - // phase two: identify the positions of the threads 574 - let activeSlice = -1 575 - let threadSlices: Slice[] = [] 576 - for (let i = 0; i < reorg.length; i++) { 577 - const item = reorg[i] as FeedViewPostWithThreadMeta 578 - if (activeSlice === -1) { 579 - if (item._isThreadParent) { 580 - activeSlice = i 581 - } 582 - } else { 583 - if (!item._isThreadChild) { 584 - threadSlices.push({index: activeSlice, length: i - activeSlice}) 585 - if (item._isThreadParent) { 586 - activeSlice = i 587 - } else { 588 - activeSlice = -1 589 - } 590 - } 591 - } 592 - } 593 - if (activeSlice !== -1) { 594 - threadSlices.push({index: activeSlice, length: reorg.length - activeSlice}) 595 - } 596 - 597 - // phase three: reorder the feed so that the timestamp of the 581 + // phase two: reorder the feed so that the timestamp of the 598 582 // last post in a thread establishes its ordering 583 + let threadSlices: Slice[] = identifyThreadSlices(reorg) 599 584 for (const slice of threadSlices) { 600 585 const removed: FeedViewPostWithThreadMeta[] = reorg.splice( 601 586 slice.index, ··· 610 595 slice.index = newIndex 611 596 } 612 597 613 - // phase four: compress any threads that are longer than 3 posts 598 + // phase three: compress any threads that are longer than 3 posts 614 599 let removedCount = 0 600 + // phase 2 moved posts around, so we need to re-identify the slice indices 601 + threadSlices = identifyThreadSlices(reorg) 615 602 for (const slice of threadSlices) { 616 603 if (slice.length > 3) { 617 604 reorg.splice(slice.index - removedCount + 1, slice.length - 3) ··· 624 611 } 625 612 626 613 return reorg 614 + } 615 + 616 + function identifyThreadSlices(feed: FeedViewPost[]): Slice[] { 617 + let activeSlice = -1 618 + let threadSlices: Slice[] = [] 619 + for (let i = 0; i < feed.length; i++) { 620 + const item = feed[i] as FeedViewPostWithThreadMeta 621 + if (activeSlice === -1) { 622 + if (item._isThreadParent) { 623 + activeSlice = i 624 + } 625 + } else { 626 + if (!item._isThreadChild) { 627 + threadSlices.push({index: activeSlice, length: i - activeSlice}) 628 + if (item._isThreadParent) { 629 + activeSlice = i 630 + } else { 631 + activeSlice = -1 632 + } 633 + } 634 + } 635 + } 636 + if (activeSlice !== -1) { 637 + threadSlices.push({index: activeSlice, length: feed.length - activeSlice}) 638 + } 639 + return threadSlices 627 640 } 628 641 629 642 // WARNING: mutates `feed`
-123
src/state/models/get-assertions-view.ts
··· 1 - import {makeAutoObservable} from 'mobx' 2 - import {AppBskyGraphGetAssertions as GetAssertions} from '@atproto/api' 3 - import {RootStoreModel} from './root-store' 4 - 5 - export type Assertion = GetAssertions.Assertion & { 6 - _reactKey: string 7 - } 8 - 9 - export class GetAssertionsView { 10 - // state 11 - isLoading = false 12 - isRefreshing = false 13 - hasLoaded = false 14 - error = '' 15 - params: GetAssertions.QueryParams 16 - 17 - // data 18 - assertions: Assertion[] = [] 19 - 20 - constructor( 21 - public rootStore: RootStoreModel, 22 - params: GetAssertions.QueryParams, 23 - ) { 24 - makeAutoObservable( 25 - this, 26 - { 27 - rootStore: false, 28 - params: false, 29 - }, 30 - {autoBind: true}, 31 - ) 32 - this.params = params 33 - } 34 - 35 - get hasContent() { 36 - return this.assertions.length > 0 37 - } 38 - 39 - get hasError() { 40 - return this.error !== '' 41 - } 42 - 43 - get isEmpty() { 44 - return this.hasLoaded && !this.hasContent 45 - } 46 - 47 - getBySubject(did: string) { 48 - return this.assertions.find(assertion => assertion.subject.did === did) 49 - } 50 - 51 - get confirmed() { 52 - return this.assertions.filter(assertion => !!assertion.confirmation) 53 - } 54 - 55 - get unconfirmed() { 56 - return this.assertions.filter(assertion => !assertion.confirmation) 57 - } 58 - 59 - // public api 60 - // = 61 - 62 - async setup() { 63 - await this._fetch() 64 - } 65 - 66 - async refresh() { 67 - await this._fetch(true) 68 - } 69 - 70 - async loadMore() { 71 - // TODO 72 - } 73 - 74 - // state transitions 75 - // = 76 - 77 - private _xLoading(isRefreshing = false) { 78 - this.isLoading = true 79 - this.isRefreshing = isRefreshing 80 - this.error = '' 81 - } 82 - 83 - private _xIdle(err?: any) { 84 - this.isLoading = false 85 - this.isRefreshing = false 86 - this.hasLoaded = true 87 - this.error = err ? err.toString() : '' 88 - if (err) { 89 - this.rootStore.log.error('Failed to fetch assertions', err) 90 - } 91 - } 92 - 93 - // loader functions 94 - // = 95 - 96 - private async _fetch(isRefreshing = false) { 97 - this._xLoading(isRefreshing) 98 - try { 99 - const res = await this.rootStore.api.app.bsky.graph.getAssertions( 100 - this.params, 101 - ) 102 - this._replaceAll(res) 103 - this._xIdle() 104 - } catch (e: any) { 105 - this._xIdle(e) 106 - } 107 - } 108 - 109 - private _replaceAll(res: GetAssertions.Response) { 110 - this.assertions.length = 0 111 - let counter = 0 112 - for (const item of res.data.assertions) { 113 - this._append({ 114 - _reactKey: `item-${counter++}`, 115 - ...item, 116 - }) 117 - } 118 - } 119 - 120 - private _append(item: Assertion) { 121 - this.assertions.push(item) 122 - } 123 - }
+1 -1
src/state/models/log.ts
··· 1 1 import {makeAutoObservable} from 'mobx' 2 2 import {XRPCError, XRPCInvalidResponseError} from '@atproto/xrpc' 3 - import {isObj, hasProp} from '../lib/type-guards' 3 + import {isObj, hasProp} from 'lib/type-guards' 4 4 5 5 interface LogEntry { 6 6 id: string
+14 -54
src/state/models/me.ts
··· 1 1 import {makeAutoObservable, runInAction} from 'mobx' 2 - import notifee from '@notifee/react-native' 3 2 import {RootStoreModel} from './root-store' 4 3 import {FeedModel} from './feed-view' 5 4 import {NotificationsViewModel} from './notifications-view' 6 - import {isObj, hasProp} from '../lib/type-guards' 7 - import {displayNotificationFromModel} from '../../view/lib/notifee' 5 + import {MyFollowsModel} from './my-follows' 6 + import {isObj, hasProp} from 'lib/type-guards' 8 7 9 8 export class MeModel { 10 9 did: string = '' ··· 12 11 displayName: string = '' 13 12 description: string = '' 14 13 avatar: string = '' 15 - notificationCount: number = 0 16 14 mainFeed: FeedModel 17 15 notifications: NotificationsViewModel 16 + follows: MyFollowsModel 18 17 19 18 constructor(public rootStore: RootStoreModel) { 20 19 makeAutoObservable( ··· 26 25 algorithm: 'reverse-chronological', 27 26 }) 28 27 this.notifications = new NotificationsViewModel(this.rootStore, {}) 28 + this.follows = new MyFollowsModel(this.rootStore) 29 29 } 30 30 31 31 clear() { 32 + this.mainFeed.clear() 33 + this.notifications.clear() 32 34 this.did = '' 33 35 this.handle = '' 34 36 this.displayName = '' 35 37 this.description = '' 36 38 this.avatar = '' 37 - this.notificationCount = 0 38 39 } 39 40 40 41 serialize(): unknown { ··· 77 78 78 79 async load() { 79 80 const sess = this.rootStore.session 80 - if (sess.hasSession && sess.data) { 81 - this.did = sess.data.did || '' 82 - this.handle = sess.data.handle 81 + this.rootStore.log.debug('MeModel:load', {hasSession: sess.hasSession}) 82 + if (sess.hasSession) { 83 + this.did = sess.currentSession?.did || '' 84 + this.handle = sess.currentSession?.handle || '' 83 85 const profile = await this.rootStore.api.app.bsky.actor.getProfile({ 84 86 actor: this.did, 85 87 }) ··· 94 96 this.avatar = '' 95 97 } 96 98 }) 97 - this.mainFeed = new FeedModel(this.rootStore, 'home', { 98 - algorithm: 'reverse-chronological', 99 - }) 100 - this.notifications = new NotificationsViewModel(this.rootStore, {}) 101 99 await Promise.all([ 102 100 this.mainFeed.setup().catch(e => { 103 101 this.rootStore.log.error('Failed to setup main feed model', e) ··· 105 103 this.notifications.setup().catch(e => { 106 104 this.rootStore.log.error('Failed to setup notifications model', e) 107 105 }), 106 + this.follows.fetch().catch(e => { 107 + this.rootStore.log.error('Failed to load my follows', e) 108 + }), 108 109 ]) 109 - 110 - // request notifications permission once the user has logged in 111 - notifee.requestPermission() 110 + this.rootStore.emitSessionLoaded() 112 111 } else { 113 112 this.clear() 114 - } 115 - } 116 - 117 - clearNotificationCount() { 118 - this.notificationCount = 0 119 - notifee.setBadgeCount(0) 120 - } 121 - 122 - async fetchNotifications() { 123 - const res = await this.rootStore.api.app.bsky.notification.getCount() 124 - runInAction(() => { 125 - const newNotifications = this.notificationCount !== res.data.count 126 - this.notificationCount = res.data.count 127 - notifee.setBadgeCount(this.notificationCount) 128 - if (newNotifications) { 129 - this.notifications.refresh() 130 - } 131 - }) 132 - } 133 - 134 - async bgFetchNotifications() { 135 - const res = await this.rootStore.api.app.bsky.notification.getCount() 136 - // NOTE we don't update this.notificationCount to avoid repaints during bg 137 - // this means `newNotifications` may not be accurate, so we rely on 138 - // `mostRecent` to determine if there really is a new notif to show -prf 139 - const newNotifications = this.notificationCount !== res.data.count 140 - notifee.setBadgeCount(res.data.count) 141 - this.rootStore.log.debug( 142 - `Background fetch received unread count = ${res.data.count}`, 143 - ) 144 - if (newNotifications) { 145 - this.rootStore.log.debug( 146 - 'Background fetch detected potentially a new notification', 147 - ) 148 - const mostRecent = await this.notifications.getNewMostRecent() 149 - if (mostRecent) { 150 - this.rootStore.log.debug('Got the notification, triggering a push') 151 - displayNotificationFromModel(mostRecent) 152 - } 153 113 } 154 114 } 155 115 }
+109
src/state/models/my-follows.ts
··· 1 + import {makeAutoObservable, runInAction} from 'mobx' 2 + import {FollowRecord, AppBskyActorProfile, AppBskyActorRef} from '@atproto/api' 3 + import {RootStoreModel} from './root-store' 4 + import {bundleAsync} from 'lib/async/bundle' 5 + 6 + const CACHE_TTL = 1000 * 60 * 60 // hourly 7 + type FollowsListResponse = Awaited<ReturnType<FollowRecord['list']>> 8 + type FollowsListResponseRecord = FollowsListResponse['records'][0] 9 + type Profile = 10 + | AppBskyActorProfile.ViewBasic 11 + | AppBskyActorProfile.View 12 + | AppBskyActorRef.WithInfo 13 + 14 + /** 15 + * This model is used to maintain a synced local cache of the user's 16 + * follows. It should be periodically refreshed and updated any time 17 + * the user makes a change to their follows. 18 + */ 19 + export class MyFollowsModel { 20 + // data 21 + followDidToRecordMap: Record<string, string> = {} 22 + lastSync = 0 23 + 24 + constructor(public rootStore: RootStoreModel) { 25 + makeAutoObservable( 26 + this, 27 + { 28 + rootStore: false, 29 + }, 30 + {autoBind: true}, 31 + ) 32 + } 33 + 34 + // public api 35 + // = 36 + 37 + fetchIfNeeded = bundleAsync(async () => { 38 + if ( 39 + Object.keys(this.followDidToRecordMap).length === 0 || 40 + Date.now() - this.lastSync > CACHE_TTL 41 + ) { 42 + return await this.fetch() 43 + } 44 + }) 45 + 46 + fetch = bundleAsync(async () => { 47 + this.rootStore.log.debug('MyFollowsModel:fetch running full fetch') 48 + let before 49 + let records: FollowsListResponseRecord[] = [] 50 + do { 51 + const res: FollowsListResponse = 52 + await this.rootStore.api.app.bsky.graph.follow.list({ 53 + user: this.rootStore.me.did, 54 + before, 55 + }) 56 + records = records.concat(res.records) 57 + before = res.cursor 58 + } while (typeof before !== 'undefined') 59 + runInAction(() => { 60 + this.followDidToRecordMap = {} 61 + for (const record of records) { 62 + this.followDidToRecordMap[record.value.subject.did] = record.uri 63 + } 64 + this.lastSync = Date.now() 65 + }) 66 + }) 67 + 68 + isFollowing(did: string) { 69 + return !!this.followDidToRecordMap[did] 70 + } 71 + 72 + getFollowUri(did: string): string { 73 + const v = this.followDidToRecordMap[did] 74 + if (!v) { 75 + throw new Error('Not a followed user') 76 + } 77 + return v 78 + } 79 + 80 + addFollow(did: string, recordUri: string) { 81 + this.followDidToRecordMap[did] = recordUri 82 + } 83 + 84 + removeFollow(did: string) { 85 + delete this.followDidToRecordMap[did] 86 + } 87 + 88 + /** 89 + * Use this to incrementally update the cache as views provide information 90 + */ 91 + hydrate(did: string, recordUri: string | undefined) { 92 + if (recordUri) { 93 + this.followDidToRecordMap[did] = recordUri 94 + } else { 95 + delete this.followDidToRecordMap[did] 96 + } 97 + } 98 + 99 + /** 100 + * Use this to incrementally update the cache as views provide information 101 + */ 102 + hydrateProfiles(profiles: Profile[]) { 103 + for (const profile of profiles) { 104 + if (profile.viewer) { 105 + this.hydrate(profile.did, profile.viewer.following) 106 + } 107 + } 108 + } 109 + }
+39 -16
src/state/models/navigation.ts
··· 1 + import {RootStoreModel} from './root-store' 1 2 import {makeAutoObservable} from 'mobx' 2 - import {TABS_ENABLED} from '../../build-flags' 3 + import {TABS_ENABLED} from 'lib/build-flags' 4 + import {segmentClient} from 'lib/analytics' 3 5 4 6 let __id = 0 5 7 function genId() { ··· 11 13 // we've since decided to pause that idea and do something more traditional 12 14 // until we're fully sure what that is, the tabs are being repurposed into a fixed topology 13 15 // - Tab 0: The "Default" tab 14 - // - Tab 1: The "Notifications" tab 16 + // - Tab 1: The "Search" tab 17 + // - Tab 2: The "Notifications" tab 15 18 // These tabs always retain the first item in their history. 16 - // The default tab is used for basically everything except notifications. 17 19 // -prf 18 20 export enum TabPurpose { 19 21 Default = 0, 20 - Notifs = 1, 22 + Search = 1, 23 + Notifs = 2, 24 + } 25 + 26 + export const TabPurposeMainPath: Record<TabPurpose, string> = { 27 + [TabPurpose.Default]: '/', 28 + [TabPurpose.Search]: '/search', 29 + [TabPurpose.Notifs]: '/notifications', 21 30 } 22 31 23 32 interface HistoryItem { ··· 36 45 isNewTab = false 37 46 38 47 constructor(public fixedTabPurpose: TabPurpose) { 39 - if (fixedTabPurpose === TabPurpose.Notifs) { 40 - this.history = [{url: '/notifications', ts: Date.now(), id: genId()}] 41 - } else { 42 - this.history = [{url: '/', ts: Date.now(), id: genId()}] 43 - } 48 + this.history = [ 49 + {url: TabPurposeMainPath[fixedTabPurpose], ts: Date.now(), id: genId()}, 50 + ] 44 51 makeAutoObservable(this, { 45 52 serialize: false, 46 53 hydrate: false, ··· 96 103 // = 97 104 98 105 navigate(url: string, title?: string) { 106 + try { 107 + const path = url.split('/')[1] 108 + segmentClient.track('Navigation', { 109 + path, 110 + }) 111 + } catch (error) {} 112 + 99 113 if (this.current?.url === url) { 100 114 this.refresh() 101 115 } else { ··· 104 118 } 105 119 // TEMP ensure the tab has its purpose's main view -prf 106 120 if (this.history.length < 1) { 107 - const fixedUrl = 108 - this.fixedTabPurpose === TabPurpose.Notifs ? '/notifications' : '/' 121 + const fixedUrl = TabPurposeMainPath[this.fixedTabPurpose] 109 122 this.history.push({url: fixedUrl, ts: Date.now(), id: genId()}) 110 123 } 111 124 this.history.push({url, title, ts: Date.now(), id: genId()}) ··· 211 224 export class NavigationModel { 212 225 tabs: NavigationTabModel[] = [ 213 226 new NavigationTabModel(TabPurpose.Default), 227 + new NavigationTabModel(TabPurpose.Search), 214 228 new NavigationTabModel(TabPurpose.Notifs), 215 229 ] 216 230 tabIndex = 0 217 231 218 - constructor() { 232 + constructor(public rootStore: RootStoreModel) { 219 233 makeAutoObservable(this, { 234 + rootStore: false, 220 235 serialize: false, 221 236 hydrate: false, 222 237 }) ··· 225 240 clear() { 226 241 this.tabs = [ 227 242 new NavigationTabModel(TabPurpose.Default), 243 + new NavigationTabModel(TabPurpose.Search), 228 244 new NavigationTabModel(TabPurpose.Notifs), 229 245 ] 230 246 this.tabIndex = 0 ··· 249 265 // = 250 266 251 267 navigate(url: string, title?: string) { 268 + this.rootStore.emitNavigation() 252 269 this.tab.navigate(url, title) 253 270 } 254 271 ··· 286 303 // fixed tab helper function 287 304 // -prf 288 305 switchTo(purpose: TabPurpose, reset: boolean) { 289 - if (purpose === TabPurpose.Notifs) { 290 - this.tabIndex = 1 291 - } else { 292 - this.tabIndex = 0 306 + this.rootStore.emitNavigation() 307 + switch (purpose) { 308 + case TabPurpose.Notifs: 309 + this.tabIndex = 2 310 + break 311 + case TabPurpose.Search: 312 + this.tabIndex = 1 313 + break 314 + default: 315 + this.tabIndex = 0 293 316 } 294 317 if (reset) { 295 318 this.tab.fixedTabReset()
+204 -130
src/state/models/notifications-view.ts
··· 8 8 AppBskyGraphAssertion, 9 9 AppBskyGraphFollow, 10 10 } from '@atproto/api' 11 + import AwaitLock from 'await-lock' 12 + import {bundleAsync} from 'lib/async/bundle' 11 13 import {RootStoreModel} from './root-store' 12 14 import {PostThreadViewModel} from './post-thread-view' 13 - import {cleanError} from '../../lib/strings' 15 + import {cleanError} from 'lib/strings/errors' 14 16 15 - const UNGROUPABLE_REASONS = ['assertion'] 17 + const GROUPABLE_REASONS = ['vote', 'repost', 'follow'] 16 18 const PAGE_SIZE = 30 17 19 const MS_1HR = 1e3 * 60 * 60 18 20 const MS_2DAY = MS_1HR * 48 ··· 190 192 params: ListNotifications.QueryParams 191 193 hasMore = true 192 194 loadMoreCursor?: string 193 - _loadPromise: Promise<void> | undefined 194 - _loadMorePromise: Promise<void> | undefined 195 - _updatePromise: Promise<void> | undefined 195 + 196 + // used to linearize async modifications to state 197 + private lock = new AwaitLock() 196 198 197 199 // data 198 200 notifications: NotificationsViewItemModel[] = [] 201 + unreadCount = 0 199 202 200 203 // this is used to help trigger push notifications 201 - mostRecentNotification: NotificationsViewItemModel | undefined 204 + mostRecentNotificationUri: string | undefined 202 205 203 206 constructor( 204 207 public rootStore: RootStoreModel, ··· 209 212 { 210 213 rootStore: false, 211 214 params: false, 212 - mostRecentNotification: false, 213 - _loadPromise: false, 214 - _loadMorePromise: false, 215 - _updatePromise: false, 215 + mostRecentNotificationUri: false, 216 216 }, 217 217 {autoBind: true}, 218 218 ) ··· 235 235 // = 236 236 237 237 /** 238 + * Nuke all data 239 + */ 240 + clear() { 241 + this.rootStore.log.debug('NotificationsModel:clear') 242 + this.isLoading = false 243 + this.isRefreshing = false 244 + this.hasLoaded = false 245 + this.error = '' 246 + this.hasMore = true 247 + this.loadMoreCursor = undefined 248 + this.notifications = [] 249 + this.unreadCount = 0 250 + this.rootStore.emitUnreadNotifications(0) 251 + this.mostRecentNotificationUri = undefined 252 + } 253 + 254 + /** 238 255 * Load for first render 239 256 */ 240 - async setup(isRefreshing = false) { 257 + setup = bundleAsync(async (isRefreshing: boolean = false) => { 258 + this.rootStore.log.debug('NotificationsModel:setup', {isRefreshing}) 241 259 if (isRefreshing) { 242 260 this.isRefreshing = true // set optimistically for UI 243 261 } 244 - if (this._loadPromise) { 245 - return this._loadPromise 262 + await this.lock.acquireAsync() 263 + try { 264 + this._xLoading(isRefreshing) 265 + try { 266 + const params = Object.assign({}, this.params, { 267 + limit: PAGE_SIZE, 268 + }) 269 + const res = await this.rootStore.api.app.bsky.notification.list(params) 270 + await this._replaceAll(res) 271 + this._xIdle() 272 + } catch (e: any) { 273 + this._xIdle(e) 274 + } 275 + } finally { 276 + this.lock.release() 246 277 } 247 - await this._pendingWork() 248 - this._loadPromise = this._initialLoad(isRefreshing) 249 - await this._loadPromise 250 - this._loadPromise = undefined 251 - } 278 + }) 252 279 253 280 /** 254 281 * Reset and load ··· 260 287 /** 261 288 * Load more posts to the end of the notifications 262 289 */ 263 - async loadMore() { 264 - if (this._loadMorePromise) { 265 - return this._loadMorePromise 290 + loadMore = bundleAsync(async () => { 291 + if (!this.hasMore) { 292 + return 293 + } 294 + this.lock.acquireAsync() 295 + try { 296 + this._xLoading() 297 + try { 298 + const params = Object.assign({}, this.params, { 299 + limit: PAGE_SIZE, 300 + before: this.loadMoreCursor, 301 + }) 302 + const res = await this.rootStore.api.app.bsky.notification.list(params) 303 + await this._appendAll(res) 304 + this._xIdle() 305 + } catch (e: any) { 306 + this._xIdle() // don't bubble the error to the user 307 + this.rootStore.log.error('NotificationsView: Failed to load more', { 308 + params: this.params, 309 + e, 310 + }) 311 + } 312 + } finally { 313 + this.lock.release() 266 314 } 267 - await this._pendingWork() 268 - this._loadMorePromise = this._loadMore() 269 - await this._loadMorePromise 270 - this._loadMorePromise = undefined 271 - } 315 + }) 316 + 317 + /** 318 + * Load more posts at the start of the notifications 319 + */ 320 + loadLatest = bundleAsync(async () => { 321 + if (this.notifications.length === 0 || this.unreadCount > PAGE_SIZE) { 322 + return this.refresh() 323 + } 324 + this.lock.acquireAsync() 325 + try { 326 + this._xLoading() 327 + try { 328 + const res = await this.rootStore.api.app.bsky.notification.list({ 329 + limit: PAGE_SIZE, 330 + }) 331 + await this._prependAll(res) 332 + this._xIdle() 333 + } catch (e: any) { 334 + this._xIdle() // don't bubble the error to the user 335 + this.rootStore.log.error('NotificationsView: Failed to load latest', { 336 + params: this.params, 337 + e, 338 + }) 339 + } 340 + } finally { 341 + this.lock.release() 342 + } 343 + }) 272 344 273 345 /** 274 346 * Update content in-place 275 347 */ 276 - async update() { 277 - if (this._updatePromise) { 278 - return this._updatePromise 348 + update = bundleAsync(async () => { 349 + await this.lock.acquireAsync() 350 + try { 351 + if (!this.notifications.length) { 352 + return 353 + } 354 + this._xLoading() 355 + let numToFetch = this.notifications.length 356 + let cursor 357 + try { 358 + do { 359 + const res: ListNotifications.Response = 360 + await this.rootStore.api.app.bsky.notification.list({ 361 + before: cursor, 362 + limit: Math.min(numToFetch, 100), 363 + }) 364 + if (res.data.notifications.length === 0) { 365 + break // sanity check 366 + } 367 + this._updateAll(res) 368 + numToFetch -= res.data.notifications.length 369 + cursor = res.data.cursor 370 + } while (cursor && numToFetch > 0) 371 + this._xIdle() 372 + } catch (e: any) { 373 + this._xIdle() // don't bubble the error to the user 374 + this.rootStore.log.error('NotificationsView: Failed to update', { 375 + params: this.params, 376 + e, 377 + }) 378 + } 379 + } finally { 380 + this.lock.release() 279 381 } 280 - await this._pendingWork() 281 - this._updatePromise = this._update() 282 - await this._updatePromise 283 - this._updatePromise = undefined 284 - } 382 + }) 383 + 384 + // unread notification apis 385 + // = 386 + 387 + /** 388 + * Get the current number of unread notifications 389 + * returns true if the number changed 390 + */ 391 + loadUnreadCount = bundleAsync(async () => { 392 + const old = this.unreadCount 393 + const res = await this.rootStore.api.app.bsky.notification.getCount() 394 + runInAction(() => { 395 + this.unreadCount = res.data.count 396 + }) 397 + this.rootStore.emitUnreadNotifications(this.unreadCount) 398 + return this.unreadCount !== old 399 + }) 285 400 286 401 /** 287 402 * Update read/unread state 288 403 */ 289 - async updateReadState() { 404 + async markAllRead() { 290 405 try { 406 + this.unreadCount = 0 407 + this.rootStore.emitUnreadNotifications(0) 291 408 await this.rootStore.api.app.bsky.notification.updateSeen({ 292 409 seenAt: new Date().toISOString(), 293 410 }) 294 - this.rootStore.me.clearNotificationCount() 295 411 } catch (e: any) { 296 412 this.rootStore.log.warn('Failed to update notifications read state', e) 297 413 } 298 414 } 299 415 300 416 async getNewMostRecent(): Promise<NotificationsViewItemModel | undefined> { 301 - let old = this.mostRecentNotification 302 - const res = await this.rootStore.api.app.bsky.notification.list({limit: 1}) 303 - if ( 304 - !res.data.notifications[0] || 305 - old?.uri === res.data.notifications[0].uri 306 - ) { 417 + let old = this.mostRecentNotificationUri 418 + const res = await this.rootStore.api.app.bsky.notification.list({ 419 + limit: 1, 420 + }) 421 + if (!res.data.notifications[0] || old === res.data.notifications[0].uri) { 307 422 return 308 423 } 309 - this.mostRecentNotification = new NotificationsViewItemModel( 424 + this.mostRecentNotificationUri = res.data.notifications[0].uri 425 + const notif = new NotificationsViewItemModel( 310 426 this.rootStore, 311 427 'mostRecent', 312 428 res.data.notifications[0], 313 429 ) 314 - await this.mostRecentNotification.fetchAdditionalData() 315 - return this.mostRecentNotification 430 + await notif.fetchAdditionalData() 431 + return notif 316 432 } 317 433 318 434 // state transitions ··· 329 445 this.isRefreshing = false 330 446 this.hasLoaded = true 331 447 this.error = cleanError(err) 332 - this.error = err ? cleanError(err) : '' 333 448 if (err) { 334 449 this.rootStore.log.error('Failed to fetch notifications', err) 335 450 } 336 451 } 337 452 338 - // loader functions 453 + // helper functions 339 454 // = 340 455 341 - private async _pendingWork() { 342 - if (this._loadPromise) { 343 - await this._loadPromise 344 - } 345 - if (this._loadMorePromise) { 346 - await this._loadMorePromise 347 - } 348 - if (this._updatePromise) { 349 - await this._updatePromise 350 - } 351 - } 352 - 353 - private async _initialLoad(isRefreshing = false) { 354 - this._xLoading(isRefreshing) 355 - try { 356 - const params = Object.assign({}, this.params, { 357 - limit: PAGE_SIZE, 358 - }) 359 - const res = await this.rootStore.api.app.bsky.notification.list(params) 360 - await this._replaceAll(res) 361 - this._xIdle() 362 - } catch (e: any) { 363 - this._xIdle(e) 364 - } 365 - } 366 - 367 - private async _loadMore() { 368 - if (!this.hasMore) { 369 - return 370 - } 371 - this._xLoading() 372 - try { 373 - const params = Object.assign({}, this.params, { 374 - limit: PAGE_SIZE, 375 - before: this.loadMoreCursor, 376 - }) 377 - const res = await this.rootStore.api.app.bsky.notification.list(params) 378 - await this._appendAll(res) 379 - this._xIdle() 380 - } catch (e: any) { 381 - this._xIdle(e) 382 - } 383 - } 384 - 385 - private async _update() { 386 - if (!this.notifications.length) { 387 - return 388 - } 389 - this._xLoading() 390 - let numToFetch = this.notifications.length 391 - let cursor 392 - try { 393 - do { 394 - const res: ListNotifications.Response = 395 - await this.rootStore.api.app.bsky.notification.list({ 396 - before: cursor, 397 - limit: Math.min(numToFetch, 100), 398 - }) 399 - if (res.data.notifications.length === 0) { 400 - break // sanity check 401 - } 402 - this._updateAll(res) 403 - numToFetch -= res.data.notifications.length 404 - cursor = res.data.cursor 405 - } while (cursor && numToFetch > 0) 406 - this._xIdle() 407 - } catch (e: any) { 408 - this._xIdle(e) 409 - } 410 - } 411 - 412 456 private async _replaceAll(res: ListNotifications.Response) { 413 457 if (res.data.notifications[0]) { 414 - this.mostRecentNotification = new NotificationsViewItemModel( 415 - this.rootStore, 416 - 'mostRecent', 417 - res.data.notifications[0], 418 - ) 458 + this.mostRecentNotificationUri = res.data.notifications[0].uri 419 459 } 420 460 return this._appendAll(res, true) 421 461 } ··· 451 491 }) 452 492 } 453 493 494 + private async _prependAll(res: ListNotifications.Response) { 495 + const promises = [] 496 + const itemModels: NotificationsViewItemModel[] = [] 497 + const dedupedNotifs = res.data.notifications.filter( 498 + n1 => 499 + !this.notifications.find( 500 + n2 => isEq(n1, n2) || n2.additional?.find(n3 => isEq(n1, n3)), 501 + ), 502 + ) 503 + for (const item of groupNotifications(dedupedNotifs)) { 504 + const itemModel = new NotificationsViewItemModel( 505 + this.rootStore, 506 + `item-${_idCounter++}`, 507 + item, 508 + ) 509 + if (itemModel.needsAdditionalData) { 510 + promises.push(itemModel.fetchAdditionalData()) 511 + } 512 + itemModels.push(itemModel) 513 + } 514 + await Promise.all(promises).catch(e => { 515 + this.rootStore.log.error( 516 + 'Uncaught failure during notifications-view _prependAll()', 517 + e, 518 + ) 519 + }) 520 + runInAction(() => { 521 + this.notifications = itemModels.concat(this.notifications) 522 + }) 523 + } 524 + 454 525 private _updateAll(res: ListNotifications.Response) { 455 526 for (const item of res.data.notifications) { 456 - const existingItem = this.notifications.find( 457 - // this find function has a key subtlety- the indexedAt comparison 458 - // the reason for this is reposts: they set the URI of the original post, not of the repost record 459 - // the indexedAt time will be for the repost however, so we use that to help us 460 - item2 => item.uri === item2.uri && item.indexedAt === item2.indexedAt, 461 - ) 527 + const existingItem = this.notifications.find(item2 => isEq(item, item2)) 462 528 if (existingItem) { 463 529 existingItem.copy(item, true) 464 530 } ··· 473 539 for (const item of items) { 474 540 const ts = +new Date(item.indexedAt) 475 541 let grouped = false 476 - if (!UNGROUPABLE_REASONS.includes(item.reason)) { 542 + if (GROUPABLE_REASONS.includes(item.reason)) { 477 543 for (const item2 of items2) { 478 544 const ts2 = +new Date(item2.indexedAt) 479 545 if ( ··· 495 561 } 496 562 return items2 497 563 } 564 + 565 + type N = ListNotifications.Notification | NotificationsViewItemModel 566 + function isEq(a: N, b: N) { 567 + // this function has a key subtlety- the indexedAt comparison 568 + // the reason for this is reposts: they set the URI of the original post, not of the repost record 569 + // the indexedAt time will be for the repost however, so we use that to help us 570 + return a.uri === b.uri && a.indexedAt === b.indexedAt 571 + }
+1 -1
src/state/models/onboard.ts
··· 1 1 import {makeAutoObservable} from 'mobx' 2 - import {isObj, hasProp} from '../lib/type-guards' 2 + import {isObj, hasProp} from 'lib/type-guards' 3 3 4 4 export const OnboardStage = { 5 5 Explainers: 'explainers',
+24 -15
src/state/models/post-thread-view.ts
··· 5 5 } from '@atproto/api' 6 6 import {AtUri} from '../../third-party/uri' 7 7 import {RootStoreModel} from './root-store' 8 - import * as apilib from '../lib/api' 8 + import * as apilib from 'lib/api/index' 9 + import {cleanError} from 'lib/strings/errors' 10 + import {RichText} from 'lib/strings/rich-text' 9 11 10 12 function* reactKeyGenerator(): Generator<string> { 11 13 let counter = 0 ··· 26 28 postRecord?: FeedPost.Record 27 29 parent?: PostThreadViewPostModel | GetPostThread.NotFoundPost 28 30 replies?: (PostThreadViewPostModel | GetPostThread.NotFoundPost)[] 31 + richText?: RichText 29 32 30 33 constructor( 31 34 public rootStore: RootStoreModel, ··· 38 41 const valid = FeedPost.validateRecord(this.post.record) 39 42 if (valid.success) { 40 43 this.postRecord = this.post.record 44 + this.richText = new RichText( 45 + this.postRecord.text, 46 + this.postRecord.entities, 47 + {cleanNewlines: true}, 48 + ) 41 49 } else { 42 50 rootStore.log.warn( 43 51 'Received an invalid app.bsky.feed.post record', ··· 276 284 this.isLoading = false 277 285 this.isRefreshing = false 278 286 this.hasLoaded = true 279 - this.error = err ? err.toString() : '' 287 + this.error = cleanError(err) 280 288 if (err) { 281 289 this.rootStore.log.error('Failed to fetch post thread', err) 282 290 } ··· 290 298 const urip = new AtUri(this.params.uri) 291 299 if (!urip.host.startsWith('did:')) { 292 300 try { 293 - urip.host = await this.rootStore.resolveName(urip.host) 301 + urip.host = await apilib.resolveName(this.rootStore, urip.host) 294 302 } catch (e: any) { 295 303 this.error = e.toString() 296 304 } ··· 314 322 } 315 323 316 324 private _replaceAll(res: GetPostThread.Response) { 317 - // sortThread(res.data.thread) TODO needed? 325 + sortThread(res.data.thread) 318 326 const keyGen = reactKeyGenerator() 319 327 const thread = new PostThreadViewPostModel( 320 328 this.rootStore, ··· 330 338 } 331 339 } 332 340 333 - /* 334 - TODO needed? 341 + type MaybePost = 342 + | GetPostThread.ThreadViewPost 343 + | GetPostThread.NotFoundPost 344 + | {[k: string]: unknown; $type: string} 335 345 function sortThread(post: MaybePost) { 336 346 if (post.notFound) { 337 347 return 338 348 } 339 - post = post as GetPostThread.Post 349 + post = post as GetPostThread.ThreadViewPost 340 350 if (post.replies) { 341 351 post.replies.sort((a: MaybePost, b: MaybePost) => { 342 - post = post as GetPostThread.Post 352 + post = post as GetPostThread.ThreadViewPost 343 353 if (a.notFound) { 344 354 return 1 345 355 } 346 356 if (b.notFound) { 347 357 return -1 348 358 } 349 - a = a as GetPostThread.Post 350 - b = b as GetPostThread.Post 351 - const aIsByOp = a.author.did === post.author.did 352 - const bIsByOp = b.author.did === post.author.did 359 + a = a as GetPostThread.ThreadViewPost 360 + b = b as GetPostThread.ThreadViewPost 361 + const aIsByOp = a.post.author.did === post.post.author.did 362 + const bIsByOp = b.post.author.did === post.post.author.did 353 363 if (aIsByOp && bIsByOp) { 354 - return a.indexedAt.localeCompare(b.indexedAt) // oldest 364 + return a.post.indexedAt.localeCompare(b.post.indexedAt) // oldest 355 365 } else if (aIsByOp) { 356 366 return -1 // op's own reply 357 367 } else if (bIsByOp) { 358 368 return 1 // op's own reply 359 369 } 360 - return b.indexedAt.localeCompare(a.indexedAt) // newest 370 + return b.post.indexedAt.localeCompare(a.post.indexedAt) // newest 361 371 }) 362 372 post.replies.forEach(reply => sortThread(reply)) 363 373 } 364 374 } 365 - */
+1 -2
src/state/models/post.ts
··· 2 2 import {AppBskyFeedPost as Post} from '@atproto/api' 3 3 import {AtUri} from '../../third-party/uri' 4 4 import {RootStoreModel} from './root-store' 5 - import {cleanError} from '../../lib/strings' 5 + import {cleanError} from 'lib/strings/errors' 6 6 7 7 type RemoveIndex<T> = { 8 8 [P in keyof T as string extends P ··· 67 67 this.isLoading = false 68 68 this.hasLoaded = true 69 69 this.error = cleanError(err) 70 - this.error = err ? cleanError(err) : '' 71 70 if (err) { 72 71 this.rootStore.log.error('Failed to fetch post', err) 73 72 }
+41 -21
src/state/models/profile-view.ts
··· 1 1 import {makeAutoObservable, runInAction} from 'mobx' 2 - import {Image as PickedImage} from '../../view/com/util/images/image-crop-picker/ImageCropPicker' 2 + import {PickedMedia} from 'view/com/util/images/image-crop-picker/ImageCropPicker' 3 3 import { 4 4 AppBskyActorGetProfile as GetProfile, 5 5 AppBskyActorProfile as Profile, 6 6 AppBskySystemDeclRef, 7 - AppBskyFeedPost, 8 7 } from '@atproto/api' 9 8 type DeclRef = AppBskySystemDeclRef.Main 10 - type Entity = AppBskyFeedPost.Entity 11 - import {extractEntities} from '../../lib/strings' 9 + import {extractEntities} from 'lib/strings/rich-text-detection' 12 10 import {RootStoreModel} from './root-store' 13 - import * as apilib from '../lib/api' 11 + import * as apilib from 'lib/api/index' 12 + import {cleanError} from 'lib/strings/errors' 13 + import {RichText} from 'lib/strings/rich-text' 14 14 15 15 export const ACTOR_TYPE_USER = 'app.bsky.system.actorUser' 16 16 17 - export class ProfileViewMyStateModel { 18 - follow?: string 17 + export class ProfileViewViewerModel { 19 18 muted?: boolean 19 + following?: string 20 + followedBy?: string 20 21 21 22 constructor() { 22 23 makeAutoObservable(this) ··· 46 47 followersCount: number = 0 47 48 followsCount: number = 0 48 49 postsCount: number = 0 49 - myState = new ProfileViewMyStateModel() 50 + viewer = new ProfileViewViewerModel() 50 51 51 52 // added data 52 - descriptionEntities?: Entity[] 53 + descriptionRichText?: RichText 53 54 54 55 constructor( 55 56 public rootStore: RootStoreModel, ··· 97 98 if (!this.rootStore.me.did) { 98 99 throw new Error('Not logged in') 99 100 } 100 - if (this.myState.follow) { 101 - await apilib.unfollow(this.rootStore, this.myState.follow) 101 + 102 + const follows = this.rootStore.me.follows 103 + const followUri = follows.isFollowing(this.did) 104 + ? follows.getFollowUri(this.did) 105 + : undefined 106 + 107 + // guard against this view getting out of sync with the follows cache 108 + if (followUri !== this.viewer.following) { 109 + this.viewer.following = followUri 110 + return 111 + } 112 + 113 + if (followUri) { 114 + await apilib.unfollow(this.rootStore, followUri) 102 115 runInAction(() => { 103 116 this.followersCount-- 104 - this.myState.follow = undefined 117 + this.viewer.following = undefined 118 + this.rootStore.me.follows.removeFollow(this.did) 105 119 }) 106 120 } else { 107 121 const res = await apilib.follow( ··· 111 125 ) 112 126 runInAction(() => { 113 127 this.followersCount++ 114 - this.myState.follow = res.uri 128 + this.viewer.following = res.uri 129 + this.rootStore.me.follows.addFollow(this.did, res.uri) 115 130 }) 116 131 } 117 132 } 118 133 119 134 async updateProfile( 120 135 updates: Profile.Record, 121 - newUserAvatar: PickedImage | undefined, 122 - newUserBanner: PickedImage | undefined, 136 + newUserAvatar: PickedMedia | undefined, 137 + newUserBanner: PickedMedia | undefined, 123 138 ) { 124 139 if (newUserAvatar) { 125 140 const res = await this.rootStore.api.com.atproto.blob.upload( ··· 152 167 153 168 async muteAccount() { 154 169 await this.rootStore.api.app.bsky.graph.mute({user: this.did}) 155 - this.myState.muted = true 170 + this.viewer.muted = true 156 171 await this.refresh() 157 172 } 158 173 159 174 async unmuteAccount() { 160 175 await this.rootStore.api.app.bsky.graph.unmute({user: this.did}) 161 - this.myState.muted = false 176 + this.viewer.muted = false 162 177 await this.refresh() 163 178 } 164 179 ··· 175 190 this.isLoading = false 176 191 this.isRefreshing = false 177 192 this.hasLoaded = true 178 - this.error = err ? err.toString() : '' 193 + this.error = cleanError(err) 179 194 if (err) { 180 195 this.rootStore.log.error('Failed to fetch profile', err) 181 196 } ··· 210 225 this.followersCount = res.data.followersCount 211 226 this.followsCount = res.data.followsCount 212 227 this.postsCount = res.data.postsCount 213 - if (res.data.myState) { 214 - Object.assign(this.myState, res.data.myState) 228 + if (res.data.viewer) { 229 + Object.assign(this.viewer, res.data.viewer) 230 + this.rootStore.me.follows.hydrate(this.did, res.data.viewer.following) 215 231 } 216 - this.descriptionEntities = extractEntities(this.description || '') 232 + this.descriptionRichText = new RichText( 233 + this.description || '', 234 + extractEntities(this.description || ''), 235 + {cleanNewlines: true}, 236 + ) 217 237 } 218 238 }
+3 -1
src/state/models/profiles-view.ts
··· 31 31 } 32 32 } 33 33 try { 34 - const promise = this.rootStore.api.app.bsky.actor.getProfile({actor: did}) 34 + const promise = this.rootStore.api.app.bsky.actor.getProfile({ 35 + actor: did, 36 + }) 35 37 this.cache.set(did, promise) 36 38 const res = await promise 37 39 this.cache.set(did, res)
+36 -33
src/state/models/reposted-by-view.ts
··· 1 1 import {makeAutoObservable, runInAction} from 'mobx' 2 2 import {AtUri} from '../../third-party/uri' 3 - import {AppBskyFeedGetRepostedBy as GetRepostedBy} from '@atproto/api' 3 + import { 4 + AppBskyFeedGetRepostedBy as GetRepostedBy, 5 + AppBskyActorRef as ActorRef, 6 + } from '@atproto/api' 4 7 import {RootStoreModel} from './root-store' 8 + import {bundleAsync} from 'lib/async/bundle' 9 + import {cleanError} from 'lib/strings/errors' 10 + import * as apilib from 'lib/api/index' 5 11 6 12 const PAGE_SIZE = 30 7 13 8 - export type RepostedByItem = GetRepostedBy.RepostedBy 14 + export type RepostedByItem = ActorRef.WithInfo 9 15 10 16 export class RepostedByViewModel { 11 17 // state ··· 17 23 params: GetRepostedBy.QueryParams 18 24 hasMore = true 19 25 loadMoreCursor?: string 20 - private _loadMorePromise: Promise<void> | undefined 21 26 22 27 // data 23 28 uri: string = '' ··· 57 62 return this.loadMore(true) 58 63 } 59 64 60 - async loadMore(isRefreshing = false) { 61 - if (this._loadMorePromise) { 62 - return this._loadMorePromise 65 + loadMore = bundleAsync(async (replace: boolean = false) => { 66 + this._xLoading(replace) 67 + try { 68 + if (!this.resolvedUri) { 69 + await this._resolveUri() 70 + } 71 + const params = Object.assign({}, this.params, { 72 + uri: this.resolvedUri, 73 + limit: PAGE_SIZE, 74 + before: replace ? undefined : this.loadMoreCursor, 75 + }) 76 + const res = await this.rootStore.api.app.bsky.feed.getRepostedBy(params) 77 + if (replace) { 78 + this._replaceAll(res) 79 + } else { 80 + this._appendAll(res) 81 + } 82 + this._xIdle() 83 + } catch (e: any) { 84 + this._xIdle(e) 63 85 } 64 - if (!this.resolvedUri) { 65 - await this._resolveUri() 66 - } 67 - this._loadMorePromise = this._loadMore(isRefreshing) 68 - await this._loadMorePromise 69 - this._loadMorePromise = undefined 70 - } 86 + }) 71 87 72 88 // state transitions 73 89 // = ··· 82 98 this.isLoading = false 83 99 this.isRefreshing = false 84 100 this.hasLoaded = true 85 - this.error = err ? err.toString() : '' 101 + this.error = cleanError(err) 86 102 if (err) { 87 103 this.rootStore.log.error('Failed to fetch reposted by view', err) 88 104 } 89 105 } 90 106 91 - // loader functions 107 + // helper functions 92 108 // = 93 109 94 110 private async _resolveUri() { 95 111 const urip = new AtUri(this.params.uri) 96 112 if (!urip.host.startsWith('did:')) { 97 113 try { 98 - urip.host = await this.rootStore.resolveName(urip.host) 114 + urip.host = await apilib.resolveName(this.rootStore, urip.host) 99 115 } catch (e: any) { 100 116 this.error = e.toString() 101 117 } ··· 105 121 }) 106 122 } 107 123 108 - private async _loadMore(isRefreshing = false) { 109 - this._xLoading(isRefreshing) 110 - try { 111 - const params = Object.assign({}, this.params, { 112 - uri: this.resolvedUri, 113 - limit: PAGE_SIZE, 114 - before: this.loadMoreCursor, 115 - }) 116 - if (this.isRefreshing) { 117 - this.repostedBy = [] 118 - } 119 - const res = await this.rootStore.api.app.bsky.feed.getRepostedBy(params) 120 - await this._appendAll(res) 121 - this._xIdle() 122 - } catch (e: any) { 123 - this._xIdle(e) 124 - } 124 + private _replaceAll(res: GetRepostedBy.Response) { 125 + this.repostedBy = [] 126 + this._appendAll(res) 125 127 } 126 128 127 129 private _appendAll(res: GetRepostedBy.Response) { 128 130 this.loadMoreCursor = res.data.cursor 129 131 this.hasMore = !!this.loadMoreCursor 130 132 this.repostedBy = this.repostedBy.concat(res.data.repostedBy) 133 + this.rootStore.me.follows.hydrateProfiles(res.data.repostedBy) 131 134 } 132 135 }
+162 -36
src/state/models/root-store.ts
··· 3 3 */ 4 4 5 5 import {makeAutoObservable} from 'mobx' 6 - import {sessionClient as AtpApi, SessionServiceClient} from '@atproto/api' 6 + import {AtpAgent} from '@atproto/api' 7 7 import {createContext, useContext} from 'react' 8 8 import {DeviceEventEmitter, EmitterSubscription} from 'react-native' 9 - import * as BgScheduler from '../lib/bg-scheduler' 10 - import {isObj, hasProp} from '../lib/type-guards' 9 + import * as BgScheduler from 'lib/bg-scheduler' 10 + import {z} from 'zod' 11 + import {isObj, hasProp} from 'lib/type-guards' 11 12 import {LogModel} from './log' 12 13 import {SessionModel} from './session' 13 14 import {NavigationModel} from './navigation' 14 15 import {ShellUiModel} from './shell-ui' 15 16 import {ProfilesViewModel} from './profiles-view' 16 17 import {LinkMetasViewModel} from './link-metas-view' 18 + import {NotificationsViewItemModel} from './notifications-view' 17 19 import {MeModel} from './me' 18 20 import {OnboardModel} from './onboard' 19 - import {isNetworkError} from '../../lib/errors' 21 + 22 + export const appInfo = z.object({ 23 + build: z.string(), 24 + name: z.string(), 25 + namespace: z.string(), 26 + version: z.string(), 27 + }) 28 + export type AppInfo = z.infer<typeof appInfo> 20 29 21 30 export class RootStoreModel { 31 + agent: AtpAgent 32 + appInfo?: AppInfo 22 33 log = new LogModel() 23 34 session = new SessionModel(this) 24 - nav = new NavigationModel() 25 - shell = new ShellUiModel() 35 + nav = new NavigationModel(this) 36 + shell = new ShellUiModel(this) 26 37 me = new MeModel(this) 27 38 onboard = new OnboardModel() 28 39 profiles = new ProfilesViewModel(this) 29 40 linkMetas = new LinkMetasViewModel(this) 30 41 31 - constructor(public api: SessionServiceClient) { 42 + constructor(agent: AtpAgent) { 43 + this.agent = agent 32 44 makeAutoObservable(this, { 33 45 api: false, 34 - resolveName: false, 35 46 serialize: false, 36 47 hydrate: false, 37 48 }) 38 49 this.initBgFetch() 39 50 } 40 51 41 - async resolveName(didOrHandle: string) { 42 - if (!didOrHandle) { 43 - throw new Error('Invalid handle: ""') 44 - } 45 - if (didOrHandle.startsWith('did:')) { 46 - return didOrHandle 47 - } 48 - const res = await this.api.com.atproto.handle.resolve({handle: didOrHandle}) 49 - return res.data.did 52 + get api() { 53 + return this.agent.api 50 54 } 51 55 52 - async fetchStateUpdate() { 53 - if (!this.session.hasSession) { 54 - return 55 - } 56 - try { 57 - if (!this.session.online) { 58 - await this.session.connect() 59 - } 60 - await this.me.fetchNotifications() 61 - } catch (e: any) { 62 - if (isNetworkError(e)) { 63 - this.session.setOnline(false) // connection lost 64 - } 65 - this.log.error('Failed to fetch latest state', e) 66 - } 56 + setAppInfo(info: AppInfo) { 57 + this.appInfo = info 67 58 } 68 59 69 60 serialize(): unknown { 70 61 return { 62 + appInfo: this.appInfo, 71 63 log: this.log.serialize(), 72 64 session: this.session.serialize(), 73 65 me: this.me.serialize(), ··· 79 71 80 72 hydrate(v: unknown) { 81 73 if (isObj(v)) { 74 + if (hasProp(v, 'appInfo')) { 75 + const appInfoParsed = appInfo.safeParse(v.appInfo) 76 + if (appInfoParsed.success) { 77 + this.setAppInfo(appInfoParsed.data) 78 + } 79 + } 82 80 if (hasProp(v, 'log')) { 83 81 this.log.hydrate(v.log) 84 82 } ··· 100 98 } 101 99 } 102 100 103 - clearAll() { 101 + /** 102 + * Called during init to resume any stored session. 103 + */ 104 + async attemptSessionResumption() { 105 + this.log.debug('RootStoreModel:attemptSessionResumption') 106 + try { 107 + await this.session.attemptSessionResumption() 108 + this.log.debug('Session initialized', { 109 + hasSession: this.session.hasSession, 110 + }) 111 + this.updateSessionState() 112 + } catch (e: any) { 113 + this.log.warn('Failed to initialize session', e) 114 + } 115 + } 116 + 117 + /** 118 + * Called by the session model. Refreshes session-oriented state. 119 + */ 120 + async handleSessionChange(agent: AtpAgent) { 121 + this.log.debug('RootStoreModel:handleSessionChange') 122 + this.agent = agent 123 + this.nav.clear() 124 + this.me.clear() 125 + await this.me.load() 126 + } 127 + 128 + /** 129 + * Called by the session model. Handles session drops by informing the user. 130 + */ 131 + async handleSessionDrop() { 132 + this.log.debug('RootStoreModel:handleSessionDrop') 133 + this.nav.clear() 134 + this.me.clear() 135 + this.emitSessionDropped() 136 + } 137 + 138 + /** 139 + * Clears all session-oriented state. 140 + */ 141 + clearAllSessionState() { 142 + this.log.debug('RootStoreModel:clearAllSessionState') 104 143 this.session.clear() 105 144 this.nav.clear() 106 145 this.me.clear() 107 146 } 108 147 148 + /** 149 + * Periodic poll for new session state. 150 + */ 151 + async updateSessionState() { 152 + if (!this.session.hasSession) { 153 + return 154 + } 155 + try { 156 + await this.me.follows.fetchIfNeeded() 157 + } catch (e: any) { 158 + this.log.error('Failed to fetch latest state', e) 159 + } 160 + } 161 + 162 + // global event bus 163 + // = 164 + // - some events need to be passed around between views and models 165 + // in order to keep state in sync; these methods are for that 166 + 167 + // a post was deleted by the local user 109 168 onPostDeleted(handler: (uri: string) => void): EmitterSubscription { 110 169 return DeviceEventEmitter.addListener('post-deleted', handler) 111 170 } 112 - 113 171 emitPostDeleted(uri: string) { 114 172 DeviceEventEmitter.emit('post-deleted', uri) 115 173 } 116 174 175 + // the session has started and been fully hydrated 176 + onSessionLoaded(handler: () => void): EmitterSubscription { 177 + return DeviceEventEmitter.addListener('session-loaded', handler) 178 + } 179 + emitSessionLoaded() { 180 + DeviceEventEmitter.emit('session-loaded') 181 + } 182 + 183 + // the session was dropped due to bad/expired refresh tokens 184 + onSessionDropped(handler: () => void): EmitterSubscription { 185 + return DeviceEventEmitter.addListener('session-dropped', handler) 186 + } 187 + emitSessionDropped() { 188 + DeviceEventEmitter.emit('session-dropped') 189 + } 190 + 191 + // the current screen has changed 192 + onNavigation(handler: () => void): EmitterSubscription { 193 + return DeviceEventEmitter.addListener('navigation', handler) 194 + } 195 + emitNavigation() { 196 + DeviceEventEmitter.emit('navigation') 197 + } 198 + 199 + // a "soft reset" typically means scrolling to top and loading latest 200 + // but it can depend on the screen 201 + onScreenSoftReset(handler: () => void): EmitterSubscription { 202 + return DeviceEventEmitter.addListener('screen-soft-reset', handler) 203 + } 204 + emitScreenSoftReset() { 205 + DeviceEventEmitter.emit('screen-soft-reset') 206 + } 207 + 208 + // the unread notifications count has changed 209 + onUnreadNotifications(handler: (count: number) => void): EmitterSubscription { 210 + return DeviceEventEmitter.addListener('unread-notifications', handler) 211 + } 212 + emitUnreadNotifications(count: number) { 213 + DeviceEventEmitter.emit('unread-notifications', count) 214 + } 215 + 216 + // a notification has been queued for push 217 + onPushNotification( 218 + handler: (notif: NotificationsViewItemModel) => void, 219 + ): EmitterSubscription { 220 + return DeviceEventEmitter.addListener('push-notification', handler) 221 + } 222 + emitPushNotification(notif: NotificationsViewItemModel) { 223 + DeviceEventEmitter.emit('push-notification', notif) 224 + } 225 + 117 226 // background fetch 118 227 // = 119 228 // - we use this to poll for unread notifications, which is not "ideal" behavior but ··· 135 244 async onBgFetch(taskId: string) { 136 245 this.log.debug(`Background fetch fired for task ${taskId}`) 137 246 if (this.session.hasSession) { 138 - await this.me.bgFetchNotifications() 247 + const res = await this.api.app.bsky.notification.getCount() 248 + const hasNewNotifs = this.me.notifications.unreadCount !== res.data.count 249 + this.emitUnreadNotifications(res.data.count) 250 + this.log.debug( 251 + `Background fetch received unread count = ${res.data.count}`, 252 + ) 253 + if (hasNewNotifs) { 254 + this.log.debug( 255 + 'Background fetch detected potentially a new notification', 256 + ) 257 + const mostRecent = await this.me.notifications.getNewMostRecent() 258 + if (mostRecent) { 259 + this.log.debug('Got the notification, triggering a push') 260 + this.emitPushNotification(mostRecent) 261 + } 262 + } 139 263 } 140 264 BgScheduler.finish(taskId) 141 265 } ··· 146 270 } 147 271 } 148 272 149 - const throwawayInst = new RootStoreModel(AtpApi.service('http://localhost')) // this will be replaced by the loader, we just need to supply a value at init 273 + const throwawayInst = new RootStoreModel( 274 + new AtpAgent({service: 'http://localhost'}), 275 + ) // this will be replaced by the loader, we just need to supply a value at init 150 276 const RootStoreContext = createContext<RootStoreModel>(throwawayInst) 151 277 export const RootStoreProvider = RootStoreContext.Provider 152 278 export const useStores = () => useContext(RootStoreContext)
+200 -214
src/state/models/session.ts
··· 1 - import {makeAutoObservable, runInAction} from 'mobx' 1 + import {makeAutoObservable} from 'mobx' 2 2 import { 3 - sessionClient as AtpApi, 4 - Session, 5 - SessionServiceClient, 3 + AtpAgent, 4 + AtpSessionEvent, 5 + AtpSessionData, 6 6 ComAtprotoServerGetAccountsConfig as GetAccountsConfig, 7 7 } from '@atproto/api' 8 - import {isObj, hasProp} from '../lib/type-guards' 8 + import normalizeUrl from 'normalize-url' 9 + import {isObj, hasProp} from 'lib/type-guards' 9 10 import {z} from 'zod' 10 11 import {RootStoreModel} from './root-store' 11 - import {isNetworkError} from '../../lib/errors' 12 12 13 13 export type ServiceDescription = GetAccountsConfig.OutputSchema 14 14 15 - export const sessionData = z.object({ 15 + export const activeSession = z.object({ 16 16 service: z.string(), 17 - refreshJwt: z.string(), 18 - accessJwt: z.string(), 19 - handle: z.string(), 20 17 did: z.string(), 21 18 }) 22 - export type SessionData = z.infer<typeof sessionData> 19 + export type ActiveSession = z.infer<typeof activeSession> 23 20 24 21 export const accountData = z.object({ 25 22 service: z.string(), ··· 32 29 }) 33 30 export type AccountData = z.infer<typeof accountData> 34 31 32 + interface AdditionalAccountData { 33 + displayName?: string 34 + aviUrl?: string 35 + } 36 + 35 37 export class SessionModel { 36 38 /** 37 - * Current session data 39 + * Currently-active session 38 40 */ 39 - data: SessionData | null = null 41 + data: ActiveSession | null = null 40 42 /** 41 - * A listing of the currently & previous sessions, used for account switching 43 + * A listing of the currently & previous sessions 42 44 */ 43 45 accounts: AccountData[] = [] 44 - online = false 45 - attemptingConnect = false 46 - private _connectPromise: Promise<boolean> | undefined 46 + /** 47 + * Flag to indicate if we're doing our initial-load session resumption 48 + */ 49 + isResumingSession = false 47 50 48 51 constructor(public rootStore: RootStoreModel) { 49 52 makeAutoObservable(this, { ··· 53 56 }) 54 57 } 55 58 59 + get currentSession() { 60 + if (!this.data) { 61 + return undefined 62 + } 63 + const {did, service} = this.data 64 + return this.accounts.find( 65 + account => 66 + normalizeUrl(account.service) === normalizeUrl(service) && 67 + account.did === did && 68 + !!account.accessJwt && 69 + !!account.refreshJwt, 70 + ) 71 + } 72 + 56 73 get hasSession() { 57 - return this.data !== null 74 + return !!this.currentSession && !!this.rootStore.agent.session 58 75 } 59 76 60 77 get hasAccounts() { ··· 75 92 hydrate(v: unknown) { 76 93 this.accounts = [] 77 94 if (isObj(v)) { 78 - if (hasProp(v, 'data') && sessionData.safeParse(v.data)) { 79 - this.data = v.data as SessionData 95 + if (hasProp(v, 'data') && activeSession.safeParse(v.data)) { 96 + this.data = v.data as ActiveSession 80 97 } 81 98 if (hasProp(v, 'accounts') && Array.isArray(v.accounts)) { 82 99 for (const account of v.accounts) { ··· 90 107 91 108 clear() { 92 109 this.data = null 93 - this.setOnline(false) 94 110 } 95 111 96 - setState(data: SessionData) { 97 - this.data = data 98 - } 99 - 100 - setOnline(online: boolean, attemptingConnect?: boolean) { 101 - this.online = online 102 - if (typeof attemptingConnect === 'boolean') { 103 - this.attemptingConnect = attemptingConnect 112 + /** 113 + * Attempts to resume the previous session loaded from storage 114 + */ 115 + async attemptSessionResumption() { 116 + const sess = this.currentSession 117 + if (sess) { 118 + this.rootStore.log.debug( 119 + 'SessionModel:attemptSessionResumption found stored session', 120 + ) 121 + this.isResumingSession = true 122 + try { 123 + return await this.resumeSession(sess) 124 + } finally { 125 + this.isResumingSession = false 126 + } 127 + } else { 128 + this.rootStore.log.debug( 129 + 'SessionModel:attemptSessionResumption has no session to resume', 130 + ) 104 131 } 105 132 } 106 133 107 - updateAuthTokens(session: Session) { 108 - if (this.data) { 109 - this.setState({ 110 - ...this.data, 111 - accessJwt: session.accessJwt, 112 - refreshJwt: session.refreshJwt, 113 - }) 134 + /** 135 + * Sets the active session 136 + */ 137 + setActiveSession(agent: AtpAgent, did: string) { 138 + this.rootStore.log.debug('SessionModel:setActiveSession') 139 + this.data = { 140 + service: agent.service.toString(), 141 + did, 114 142 } 143 + this.rootStore.handleSessionChange(agent) 115 144 } 116 145 117 146 /** 118 - * Sets up the XRPC API, must be called before connecting to a service 147 + * Upserts a session into the accounts 119 148 */ 120 - private configureApi(): boolean { 121 - if (!this.data) { 122 - return false 123 - } 124 - 125 - try { 126 - const serviceUri = new URL(this.data.service) 127 - this.rootStore.api.xrpc.uri = serviceUri 128 - } catch (e: any) { 129 - this.rootStore.log.error( 130 - `Invalid service URL: ${this.data.service}. Resetting session.`, 131 - e, 132 - ) 133 - this.clear() 134 - return false 135 - } 136 - 137 - this.rootStore.api.sessionManager.set({ 138 - refreshJwt: this.data.refreshJwt, 139 - accessJwt: this.data.accessJwt, 149 + private persistSession( 150 + service: string, 151 + did: string, 152 + event: AtpSessionEvent, 153 + session?: AtpSessionData, 154 + addedInfo?: AdditionalAccountData, 155 + ) { 156 + this.rootStore.log.debug('SessionModel:persistSession', { 157 + service, 158 + did, 159 + event, 160 + hasSession: !!session, 140 161 }) 141 - return true 142 - } 143 162 144 - /** 145 - * Upserts the current session into the accounts 146 - */ 147 - private addSessionToAccounts() { 148 - if (!this.data) { 149 - return 150 - } 163 + // upsert the account in our listing 151 164 const existingAccount = this.accounts.find( 152 - acc => acc.service === this.data?.service && acc.did === this.data.did, 165 + account => account.service === service && account.did === did, 153 166 ) 154 167 const newAccount = { 155 - service: this.data.service, 156 - refreshJwt: this.data.refreshJwt, 157 - accessJwt: this.data.accessJwt, 158 - handle: this.data.handle, 159 - did: this.data.did, 160 - displayName: this.rootStore.me.displayName, 161 - aviUrl: this.rootStore.me.avatar, 168 + service, 169 + did, 170 + refreshJwt: session?.refreshJwt, 171 + accessJwt: session?.accessJwt, 172 + handle: session?.handle || existingAccount?.handle || '', 173 + displayName: addedInfo 174 + ? addedInfo.displayName 175 + : existingAccount?.displayName || '', 176 + aviUrl: addedInfo ? addedInfo.aviUrl : existingAccount?.aviUrl || '', 162 177 } 163 178 if (!existingAccount) { 164 179 this.accounts.push(newAccount) 165 180 } else { 166 - this.accounts = this.accounts 167 - .filter( 168 - acc => 169 - !(acc.service === this.data?.service && acc.did === this.data.did), 170 - ) 171 - .concat([newAccount]) 181 + this.accounts = [ 182 + newAccount, 183 + ...this.accounts.filter( 184 + account => !(account.service === service && account.did === did), 185 + ), 186 + ] 187 + } 188 + 189 + // if the session expired, fire an event to let the user know 190 + if (event === 'expired') { 191 + this.rootStore.handleSessionDrop() 172 192 } 173 193 } 174 194 175 195 /** 176 196 * Clears any session tokens from the accounts; used on logout. 177 197 */ 178 - private clearSessionTokensFromAccounts() { 198 + private clearSessionTokens() { 199 + this.rootStore.log.debug('SessionModel:clearSessionTokens') 179 200 this.accounts = this.accounts.map(acct => ({ 180 201 service: acct.service, 181 202 handle: acct.handle, ··· 186 207 } 187 208 188 209 /** 189 - * Fetches the current session from the service, if possible. 190 - * Requires an existing session (.data) to be populated with access tokens. 210 + * Fetches additional information about an account on load. 191 211 */ 192 - async connect(): Promise<boolean> { 193 - if (this._connectPromise) { 194 - return this._connectPromise 212 + private async loadAccountInfo(agent: AtpAgent, did: string) { 213 + const res = await agent.api.app.bsky.actor 214 + .getProfile({actor: did}) 215 + .catch(_e => undefined) 216 + if (res) { 217 + return { 218 + dispayName: res.data.displayName, 219 + aviUrl: res.data.avatar, 220 + } 195 221 } 196 - this._connectPromise = this._connect() 197 - const res = await this._connectPromise 198 - this._connectPromise = undefined 199 - return res 200 222 } 201 223 202 - private async _connect(): Promise<boolean> { 203 - this.attemptingConnect = true 204 - if (!this.configureApi()) { 224 + /** 225 + * Helper to fetch the accounts config settings from an account. 226 + */ 227 + async describeService(service: string): Promise<ServiceDescription> { 228 + const agent = new AtpAgent({service}) 229 + const res = await agent.api.com.atproto.server.getAccountsConfig({}) 230 + return res.data 231 + } 232 + 233 + /** 234 + * Attempt to resume a session that we still have access tokens for. 235 + */ 236 + async resumeSession(account: AccountData): Promise<boolean> { 237 + this.rootStore.log.debug('SessionModel:resumeSession') 238 + if (!(account.accessJwt && account.refreshJwt && account.service)) { 239 + this.rootStore.log.debug( 240 + 'SessionModel:resumeSession aborted due to lack of access tokens', 241 + ) 205 242 return false 206 243 } 207 244 245 + const agent = new AtpAgent({ 246 + service: account.service, 247 + persistSession: (evt: AtpSessionEvent, sess?: AtpSessionData) => { 248 + this.persistSession(account.service, account.did, evt, sess) 249 + }, 250 + }) 251 + 208 252 try { 209 - const sess = await this.rootStore.api.com.atproto.session.get() 210 - if (sess.success && this.data && this.data.did === sess.data.did) { 211 - this.setOnline(true, false) 212 - if (this.rootStore.me.did !== sess.data.did) { 213 - this.rootStore.me.clear() 214 - } 215 - this.rootStore.me 216 - .load() 217 - .catch(e => { 218 - this.rootStore.log.error( 219 - 'Failed to fetch local user information', 220 - e, 221 - ) 222 - }) 223 - .then(() => { 224 - this.addSessionToAccounts() 225 - }) 226 - return true // success 227 - } 253 + await agent.resumeSession({ 254 + accessJwt: account.accessJwt, 255 + refreshJwt: account.refreshJwt, 256 + did: account.did, 257 + handle: account.handle, 258 + }) 259 + const addedInfo = await this.loadAccountInfo(agent, account.did) 260 + this.persistSession( 261 + account.service, 262 + account.did, 263 + 'create', 264 + agent.session, 265 + addedInfo, 266 + ) 267 + this.rootStore.log.debug('SessionModel:resumeSession succeeded') 228 268 } catch (e: any) { 229 - if (isNetworkError(e)) { 230 - this.setOnline(false, false) // connection issue 231 - return false 232 - } else { 233 - this.clear() // invalid session cached 234 - } 269 + this.rootStore.log.debug('SessionModel:resumeSession failed', { 270 + error: e.toString(), 271 + }) 272 + return false 235 273 } 236 274 237 - this.setOnline(false, false) 238 - return false 239 - } 240 - 241 - /** 242 - * Helper to fetch the accounts config settings from an account. 243 - */ 244 - async describeService(service: string): Promise<ServiceDescription> { 245 - const api = AtpApi.service(service) as SessionServiceClient 246 - const res = await api.com.atproto.server.getAccountsConfig({}) 247 - return res.data 275 + this.setActiveSession(agent, account.did) 276 + return true 248 277 } 249 278 250 279 /** ··· 252 281 */ 253 282 async login({ 254 283 service, 255 - handle, 284 + identifier, 256 285 password, 257 286 }: { 258 287 service: string 259 - handle: string 288 + identifier: string 260 289 password: string 261 290 }) { 262 - const api = AtpApi.service(service) as SessionServiceClient 263 - const res = await api.com.atproto.session.create({handle, password}) 264 - if (res.data.accessJwt && res.data.refreshJwt) { 265 - this.setState({ 266 - service: service, 267 - accessJwt: res.data.accessJwt, 268 - refreshJwt: res.data.refreshJwt, 269 - handle: res.data.handle, 270 - did: res.data.did, 271 - }) 272 - this.configureApi() 273 - this.setOnline(true, false) 274 - this.rootStore.me 275 - .load() 276 - .catch(e => { 277 - this.rootStore.log.error('Failed to fetch local user information', e) 278 - }) 279 - .then(() => { 280 - this.addSessionToAccounts() 281 - }) 282 - } 283 - } 284 - 285 - /** 286 - * Attempt to resume a session that we still have access tokens for. 287 - */ 288 - async resumeSession(account: AccountData): Promise<boolean> { 289 - if (!(account.accessJwt && account.refreshJwt && account.service)) { 290 - return false 291 + this.rootStore.log.debug('SessionModel:login') 292 + const agent = new AtpAgent({service}) 293 + await agent.login({identifier, password}) 294 + if (!agent.session) { 295 + throw new Error('Failed to establish session') 291 296 } 292 297 293 - // test that the session is good 294 - const api = AtpApi.service(account.service) 295 - api.sessionManager.set({ 296 - refreshJwt: account.refreshJwt, 297 - accessJwt: account.accessJwt, 298 - }) 299 - try { 300 - const sess = await api.com.atproto.session.get() 301 - if ( 302 - !sess.success || 303 - sess.data.did !== account.did || 304 - !api.sessionManager.session 305 - ) { 306 - return false 307 - } 298 + const did = agent.session.did 299 + const addedInfo = await this.loadAccountInfo(agent, did) 308 300 309 - // copy over the access tokens, as they may have refreshed during the .get() above 310 - runInAction(() => { 311 - account.refreshJwt = api.sessionManager.session?.refreshJwt 312 - account.accessJwt = api.sessionManager.session?.accessJwt 313 - }) 314 - } catch (_e) { 315 - return false 316 - } 301 + this.persistSession(service, did, 'create', agent.session, addedInfo) 302 + agent.setPersistSessionHandler( 303 + (evt: AtpSessionEvent, sess?: AtpSessionData) => { 304 + this.persistSession(service, did, evt, sess) 305 + }, 306 + ) 317 307 318 - // session is good, connect 319 - this.setState({ 320 - service: account.service, 321 - accessJwt: account.accessJwt, 322 - refreshJwt: account.refreshJwt, 323 - handle: account.handle, 324 - did: account.did, 325 - }) 326 - return this.connect() 308 + this.setActiveSession(agent, did) 309 + this.rootStore.log.debug('SessionModel:login succeeded') 327 310 } 328 311 329 312 async createAccount({ ··· 339 322 handle: string 340 323 inviteCode?: string 341 324 }) { 342 - const api = AtpApi.service(service) as SessionServiceClient 343 - const res = await api.com.atproto.account.create({ 325 + this.rootStore.log.debug('SessionModel:createAccount') 326 + const agent = new AtpAgent({service}) 327 + await agent.createAccount({ 344 328 handle, 345 329 password, 346 330 email, 347 331 inviteCode, 348 332 }) 349 - if (res.data.accessJwt && res.data.refreshJwt) { 350 - this.setState({ 351 - service: service, 352 - accessJwt: res.data.accessJwt, 353 - refreshJwt: res.data.refreshJwt, 354 - handle: res.data.handle, 355 - did: res.data.did, 356 - }) 357 - this.rootStore.onboard.start() 358 - this.configureApi() 359 - this.rootStore.me 360 - .load() 361 - .catch(e => { 362 - this.rootStore.log.error('Failed to fetch local user information', e) 363 - }) 364 - .then(() => { 365 - this.addSessionToAccounts() 366 - }) 333 + if (!agent.session) { 334 + throw new Error('Failed to establish session') 367 335 } 336 + 337 + const did = agent.session.did 338 + const addedInfo = await this.loadAccountInfo(agent, did) 339 + 340 + this.persistSession(service, did, 'create', agent.session, addedInfo) 341 + agent.setPersistSessionHandler( 342 + (evt: AtpSessionEvent, sess?: AtpSessionData) => { 343 + this.persistSession(service, did, evt, sess) 344 + }, 345 + ) 346 + 347 + this.setActiveSession(agent, did) 348 + this.rootStore.onboard.start() 349 + this.rootStore.log.debug('SessionModel:createAccount succeeded') 368 350 } 369 351 370 352 /** 371 353 * Close all sessions across all accounts. 372 354 */ 373 355 async logout() { 356 + this.rootStore.log.debug('SessionModel:logout') 357 + // TODO 358 + // need to evaluate why deleting the session has caused errors at times 359 + // -prf 374 360 /*if (this.hasSession) { 375 361 this.rootStore.api.com.atproto.session.delete().catch((e: any) => { 376 362 this.rootStore.log.warn( ··· 379 365 ) 380 366 }) 381 367 }*/ 382 - this.clearSessionTokensFromAccounts() 383 - this.rootStore.clearAll() 368 + this.clearSessionTokens() 369 + this.rootStore.clearAllSessionState() 384 370 } 385 371 }
+23 -7
src/state/models/shell-ui.ts
··· 1 + import {RootStoreModel} from './root-store' 1 2 import {makeAutoObservable} from 'mobx' 2 3 import {ProfileViewModel} from './profile-view' 3 - import {isObj, hasProp} from '../lib/type-guards' 4 - import {PickedMedia} from '../../view/com/util/images/image-crop-picker/types' 4 + import {isObj, hasProp} from 'lib/type-guards' 5 + import {PickedMedia} from 'view/com/util/images/image-crop-picker/types' 5 6 6 7 export class ConfirmModal { 7 8 name = 'confirm' ··· 40 41 export class ReportPostModal { 41 42 name = 'report-post' 42 43 43 - constructor(public postUrl: string) { 44 + constructor(public postUri: string, public postCid: string) { 44 45 makeAutoObservable(this) 45 46 } 46 47 } ··· 59 60 constructor( 60 61 public uri: string, 61 62 public onSelect: (img?: PickedMedia) => void, 62 - ) { 63 + ) {} 64 + } 65 + 66 + export class DeleteAccountModal { 67 + name = 'delete-account' 68 + 69 + constructor() { 63 70 makeAutoObservable(this) 64 71 } 65 72 } ··· 111 118 | ReportPostModal 112 119 | ReportAccountModal 113 120 | CropImageModal 121 + | DeleteAccountModal 114 122 | undefined 115 123 isLightboxActive = false 116 124 activeLightbox: ProfileImageLightbox | ImagesLightbox | undefined 117 125 isComposerActive = false 118 126 composerOpts: ComposerOpts | undefined 119 127 120 - constructor() { 121 - makeAutoObservable(this, {serialize: false, hydrate: false}) 128 + constructor(public rootStore: RootStoreModel) { 129 + makeAutoObservable(this, { 130 + serialize: false, 131 + rootStore: false, 132 + hydrate: false, 133 + }) 122 134 } 123 135 124 136 serialize(): unknown { ··· 154 166 | ServerInputModal 155 167 | ReportPostModal 156 168 | ReportAccountModal 157 - | CropImageModal, 169 + | CropImageModal 170 + | DeleteAccountModal, 158 171 ) { 172 + this.rootStore.emitNavigation() 159 173 this.isModalActive = true 160 174 this.activeModal = modal 161 175 } ··· 166 180 } 167 181 168 182 openLightbox(lightbox: ProfileImageLightbox | ImagesLightbox) { 183 + this.rootStore.emitNavigation() 169 184 this.isLightboxActive = true 170 185 this.activeLightbox = lightbox 171 186 } ··· 176 191 } 177 192 178 193 openComposer(opts: ComposerOpts) { 194 + this.rootStore.emitNavigation() 179 195 this.isComposerActive = true 180 196 this.composerOpts = opts 181 197 }
+118 -55
src/state/models/suggested-actors-view.ts
··· 1 - import {makeAutoObservable} from 'mobx' 2 - import {AppBskyActorGetSuggestions as GetSuggestions} from '@atproto/api' 1 + import {makeAutoObservable, runInAction} from 'mobx' 2 + import {AppBskyActorProfile as Profile} from '@atproto/api' 3 + import shuffle from 'lodash.shuffle' 3 4 import {RootStoreModel} from './root-store' 5 + import {cleanError} from 'lib/strings/errors' 6 + import {bundleAsync} from 'lib/async/bundle' 7 + import { 8 + DEV_SUGGESTED_FOLLOWS, 9 + PROD_SUGGESTED_FOLLOWS, 10 + STAGING_SUGGESTED_FOLLOWS, 11 + } from 'lib/constants' 4 12 5 13 const PAGE_SIZE = 30 6 14 7 - export type SuggestedActor = GetSuggestions.Actor 15 + export type SuggestedActor = Profile.ViewBasic | Profile.View 16 + 17 + const getSuggestionList = ({serviceUrl}: {serviceUrl: string}) => { 18 + if (serviceUrl.includes('localhost')) { 19 + return DEV_SUGGESTED_FOLLOWS 20 + } else if (serviceUrl.includes('staging')) { 21 + return STAGING_SUGGESTED_FOLLOWS 22 + } else { 23 + return PROD_SUGGESTED_FOLLOWS 24 + } 25 + } 8 26 9 27 export class SuggestedActorsViewModel { 10 28 // state 29 + pageSize = PAGE_SIZE 11 30 isLoading = false 12 31 isRefreshing = false 13 32 hasLoaded = false 14 33 error = '' 15 34 hasMore = true 16 35 loadMoreCursor?: string 17 - private _loadMorePromise: Promise<void> | undefined 36 + 37 + private hardCodedSuggestions: SuggestedActor[] | undefined 18 38 19 39 // data 20 40 suggestions: SuggestedActor[] = [] 21 41 22 - constructor(public rootStore: RootStoreModel) { 42 + constructor(public rootStore: RootStoreModel, opts?: {pageSize?: number}) { 43 + if (opts?.pageSize) { 44 + this.pageSize = opts.pageSize 45 + } 23 46 makeAutoObservable( 24 47 this, 25 48 { ··· 48 71 return this.loadMore(true) 49 72 } 50 73 51 - async loadMore(isRefreshing = false) { 52 - if (this._loadMorePromise) { 53 - return this._loadMorePromise 74 + loadMore = bundleAsync(async (replace: boolean = false) => { 75 + if (!replace && !this.hasMore) { 76 + return 77 + } 78 + if (replace) { 79 + this.hardCodedSuggestions = undefined 80 + } 81 + this._xLoading(replace) 82 + try { 83 + let items: SuggestedActor[] = this.suggestions 84 + if (replace) { 85 + items = [] 86 + this.loadMoreCursor = undefined 87 + } 88 + let res 89 + do { 90 + await this.fetchHardcodedSuggestions() 91 + if (this.hardCodedSuggestions && this.hardCodedSuggestions.length > 0) { 92 + // pull from the hard-coded suggestions 93 + const newItems = this.hardCodedSuggestions.splice(0, this.pageSize) 94 + items = items.concat(newItems) 95 + this.hasMore = true 96 + this.loadMoreCursor = undefined 97 + } else { 98 + // pull from the PDS' algo 99 + res = await this.rootStore.api.app.bsky.actor.getSuggestions({ 100 + limit: this.pageSize, 101 + cursor: this.loadMoreCursor, 102 + }) 103 + this.loadMoreCursor = res.data.cursor 104 + this.hasMore = !!this.loadMoreCursor 105 + items = items.concat( 106 + res.data.actors.filter( 107 + actor => !items.find(i => i.did === actor.did), 108 + ), 109 + ) 110 + } 111 + } while (items.length < this.pageSize && this.hasMore) 112 + runInAction(() => { 113 + this.suggestions = items 114 + }) 115 + this._xIdle() 116 + } catch (e: any) { 117 + this._xIdle(e) 118 + } 119 + }) 120 + 121 + private async fetchHardcodedSuggestions() { 122 + if (this.hardCodedSuggestions) { 123 + return 124 + } 125 + await this.rootStore.me.follows.fetchIfNeeded() 126 + try { 127 + // clone the array so we can mutate it 128 + const actors = [ 129 + ...getSuggestionList({ 130 + serviceUrl: this.rootStore.session.currentSession?.service || '', 131 + }), 132 + ] 133 + 134 + // fetch the profiles in chunks of 25 (the limit allowed by `getProfiles`) 135 + let profiles: Profile.View[] = [] 136 + do { 137 + const res = await this.rootStore.api.app.bsky.actor.getProfiles({ 138 + actors: actors.splice(0, 25), 139 + }) 140 + profiles = profiles.concat(res.data.profiles) 141 + } while (actors.length) 142 + 143 + runInAction(() => { 144 + profiles = profiles.filter(profile => { 145 + if (this.rootStore.me.follows.isFollowing(profile.did)) { 146 + return false 147 + } 148 + if (profile.did === this.rootStore.me.did) { 149 + return false 150 + } 151 + return true 152 + }) 153 + this.hardCodedSuggestions = shuffle(profiles) 154 + }) 155 + } catch (e) { 156 + this.rootStore.log.error( 157 + 'Failed to getProfiles() for suggested follows', 158 + {e}, 159 + ) 160 + runInAction(() => { 161 + this.hardCodedSuggestions = [] 162 + }) 54 163 } 55 - this._loadMorePromise = this._loadMore(isRefreshing) 56 - await this._loadMorePromise 57 - this._loadMorePromise = undefined 58 164 } 59 165 60 166 // state transitions ··· 70 176 this.isLoading = false 71 177 this.isRefreshing = false 72 178 this.hasLoaded = true 73 - this.error = err ? err.toString() : '' 179 + this.error = cleanError(err) 74 180 if (err) { 75 181 this.rootStore.log.error('Failed to fetch suggested actors', err) 76 182 } 77 - } 78 - 79 - // loader functions 80 - // = 81 - 82 - private async _loadMore(isRefreshing = false) { 83 - if (!this.hasMore) { 84 - return 85 - } 86 - this._xLoading(isRefreshing) 87 - try { 88 - if (this.isRefreshing) { 89 - this.suggestions = [] 90 - } 91 - let res 92 - let totalAdded = 0 93 - do { 94 - res = await this.rootStore.api.app.bsky.actor.getSuggestions({ 95 - limit: PAGE_SIZE, 96 - cursor: this.loadMoreCursor, 97 - }) 98 - totalAdded += await this._appendAll(res) 99 - } while (totalAdded < PAGE_SIZE && this.hasMore) 100 - this._xIdle() 101 - } catch (e: any) { 102 - this._xIdle(e) 103 - } 104 - } 105 - 106 - private async _appendAll(res: GetSuggestions.Response) { 107 - this.loadMoreCursor = res.data.cursor 108 - this.hasMore = !!this.loadMoreCursor 109 - const newSuggestions = res.data.actors.filter(actor => { 110 - if (actor.did === this.rootStore.me.did) { 111 - return false // skip self 112 - } 113 - if (actor.myState?.follow) { 114 - return false // skip already-followed users 115 - } 116 - return true 117 - }) 118 - this.suggestions = this.suggestions.concat(newSuggestions) 119 - return newSuggestions.length 120 183 } 121 184 }
+148
src/state/models/suggested-posts-view.ts
··· 1 + import {makeAutoObservable, runInAction} from 'mobx' 2 + import { 3 + AppBskyFeedFeedViewPost, 4 + AppBskyFeedGetAuthorFeed as GetAuthorFeed, 5 + } from '@atproto/api' 6 + type ReasonRepost = AppBskyFeedFeedViewPost.ReasonRepost 7 + import {RootStoreModel} from './root-store' 8 + import {FeedItemModel} from './feed-view' 9 + import {cleanError} from 'lib/strings/errors' 10 + 11 + const TEAM_HANDLES = [ 12 + 'jay.bsky.social', 13 + 'paul.bsky.social', 14 + 'dan.bsky.social', 15 + 'divy.bsky.social', 16 + 'why.bsky.social', 17 + 'iamrosewang.bsky.social', 18 + ] 19 + 20 + export class SuggestedPostsView { 21 + // state 22 + isLoading = false 23 + hasLoaded = false 24 + error = '' 25 + 26 + // data 27 + posts: FeedItemModel[] = [] 28 + 29 + constructor(public rootStore: RootStoreModel) { 30 + makeAutoObservable( 31 + this, 32 + { 33 + rootStore: false, 34 + }, 35 + {autoBind: true}, 36 + ) 37 + } 38 + 39 + get hasContent() { 40 + return this.posts.length > 0 41 + } 42 + 43 + get hasError() { 44 + return this.error !== '' 45 + } 46 + 47 + get isEmpty() { 48 + return this.hasLoaded && !this.hasContent 49 + } 50 + 51 + // public api 52 + // = 53 + 54 + async setup() { 55 + this._xLoading() 56 + try { 57 + const responses = await Promise.all( 58 + TEAM_HANDLES.map(handle => 59 + this.rootStore.api.app.bsky.feed 60 + .getAuthorFeed({author: handle, limit: 10}) 61 + .catch(_err => ({success: false, headers: {}, data: {feed: []}})), 62 + ), 63 + ) 64 + runInAction(() => { 65 + this.posts = mergeAndFilterResponses(this.rootStore, responses) 66 + }) 67 + this._xIdle() 68 + } catch (e: any) { 69 + this.rootStore.log.error('SuggestedPostsView: Failed to load posts', { 70 + e, 71 + }) 72 + this._xIdle() // dont bubble to the user 73 + } 74 + } 75 + 76 + // state transitions 77 + // = 78 + 79 + private _xLoading() { 80 + this.isLoading = true 81 + this.error = '' 82 + } 83 + 84 + private _xIdle(err?: any) { 85 + this.isLoading = false 86 + this.hasLoaded = true 87 + this.error = cleanError(err) 88 + if (err) { 89 + this.rootStore.log.error('Failed to fetch suggested posts', err) 90 + } 91 + } 92 + } 93 + 94 + function mergeAndFilterResponses( 95 + store: RootStoreModel, 96 + responses: GetAuthorFeed.Response[], 97 + ): FeedItemModel[] { 98 + let posts: AppBskyFeedFeedViewPost.Main[] = [] 99 + 100 + // merge into one array 101 + for (const res of responses) { 102 + if (res.success) { 103 + posts = posts.concat(res.data.feed) 104 + } 105 + } 106 + 107 + // filter down to reposts of other users 108 + const now = Date.now() 109 + const uris = new Set() 110 + posts = posts.filter(p => { 111 + if (isARepostOfSomeoneElse(p) && isRecentEnough(now, p)) { 112 + if (uris.has(p.post.uri)) { 113 + return false 114 + } 115 + uris.add(p.post.uri) 116 + return true 117 + } 118 + return false 119 + }) 120 + 121 + // sort by index time 122 + posts.sort((a, b) => { 123 + return ( 124 + Number(new Date(b.post.indexedAt)) - Number(new Date(a.post.indexedAt)) 125 + ) 126 + }) 127 + 128 + // hydrate into models and strip the reasons to hide that these are reposts 129 + return posts.map((post, i) => { 130 + delete post.reason 131 + return new FeedItemModel(store, `post-${i}`, post) 132 + }) 133 + } 134 + 135 + function isARepostOfSomeoneElse(post: AppBskyFeedFeedViewPost.Main): boolean { 136 + return ( 137 + post.reason?.$type === 'app.bsky.feed.feedViewPost#reasonRepost' && 138 + post.post.author.did !== (post.reason as ReasonRepost).by.did 139 + ) 140 + } 141 + 142 + const THREE_DAYS = 3 * 24 * 60 * 60 * 1000 143 + function isRecentEnough( 144 + now: number, 145 + post: AppBskyFeedFeedViewPost.Main, 146 + ): boolean { 147 + return now - Number(new Date(post.post.indexedAt)) < THREE_DAYS 148 + }
+18 -16
src/state/models/user-autocomplete-view.ts
··· 1 1 import {makeAutoObservable, runInAction} from 'mobx' 2 - import { 3 - AppBskyGraphGetFollows as GetFollows, 4 - AppBskyActorSearchTypeahead as SearchTypeahead, 5 - } from '@atproto/api' 2 + import {AppBskyActorRef} from '@atproto/api' 3 + import AwaitLock from 'await-lock' 6 4 import {RootStoreModel} from './root-store' 7 5 8 6 export class UserAutocompleteViewModel { ··· 10 8 isLoading = false 11 9 isActive = false 12 10 prefix = '' 13 - _searchPromise: Promise<any> | undefined 11 + lock = new AwaitLock() 14 12 15 13 // data 16 - follows: GetFollows.Follow[] = [] 17 - searchRes: SearchTypeahead.User[] = [] 14 + follows: AppBskyActorRef.WithInfo[] = [] 15 + searchRes: AppBskyActorRef.WithInfo[] = [] 18 16 knownHandles: Set<string> = new Set() 19 17 20 18 constructor(public rootStore: RootStoreModel) { ··· 58 56 } 59 57 60 58 async setPrefix(prefix: string) { 61 - const origPrefix = prefix 62 - this.prefix = prefix.trim() 63 - if (this.prefix) { 64 - await this._searchPromise 65 - if (this.prefix !== origPrefix) { 66 - return // another prefix was set before we got our chance 59 + const origPrefix = prefix.trim() 60 + this.prefix = origPrefix 61 + await this.lock.acquireAsync() 62 + try { 63 + if (this.prefix) { 64 + if (this.prefix !== origPrefix) { 65 + return // another prefix was set before we got our chance 66 + } 67 + await this._search() 68 + } else { 69 + this.searchRes = [] 67 70 } 68 - this._searchPromise = this._search() 69 - } else { 70 - this.searchRes = [] 71 + } finally { 72 + this.lock.release() 71 73 } 72 74 } 73 75
+30 -31
src/state/models/user-followers-view.ts
··· 4 4 AppBskyActorRef as ActorRef, 5 5 } from '@atproto/api' 6 6 import {RootStoreModel} from './root-store' 7 + import {cleanError} from 'lib/strings/errors' 8 + import {bundleAsync} from 'lib/async/bundle' 7 9 8 10 const PAGE_SIZE = 30 9 11 10 - export type FollowerItem = GetFollowers.Follower 12 + export type FollowerItem = ActorRef.WithInfo 11 13 12 14 export class UserFollowersViewModel { 13 15 // state ··· 18 20 params: GetFollowers.QueryParams 19 21 hasMore = true 20 22 loadMoreCursor?: string 21 - private _loadMorePromise: Promise<void> | undefined 22 23 23 24 // data 24 25 subject: ActorRef.WithInfo = { ··· 62 63 return this.loadMore(true) 63 64 } 64 65 65 - async loadMore(isRefreshing = false) { 66 - if (this._loadMorePromise) { 67 - return this._loadMorePromise 66 + loadMore = bundleAsync(async (replace: boolean = false) => { 67 + if (!replace && !this.hasMore) { 68 + return 68 69 } 69 - this._loadMorePromise = this._loadMore(isRefreshing) 70 - await this._loadMorePromise 71 - this._loadMorePromise = undefined 72 - } 70 + this._xLoading(replace) 71 + try { 72 + const params = Object.assign({}, this.params, { 73 + limit: PAGE_SIZE, 74 + before: replace ? undefined : this.loadMoreCursor, 75 + }) 76 + const res = await this.rootStore.api.app.bsky.graph.getFollowers(params) 77 + if (replace) { 78 + this._replaceAll(res) 79 + } else { 80 + this._appendAll(res) 81 + } 82 + this._xIdle() 83 + } catch (e: any) { 84 + this._xIdle(e) 85 + } 86 + }) 73 87 74 88 // state transitions 75 89 // = ··· 84 98 this.isLoading = false 85 99 this.isRefreshing = false 86 100 this.hasLoaded = true 87 - this.error = err ? err.toString() : '' 101 + this.error = cleanError(err) 88 102 if (err) { 89 103 this.rootStore.log.error('Failed to fetch user followers', err) 90 104 } 91 105 } 92 106 93 - // loader functions 107 + // helper functions 94 108 // = 95 109 96 - private async _loadMore(isRefreshing = false) { 97 - if (!this.hasMore) { 98 - return 99 - } 100 - this._xLoading(isRefreshing) 101 - try { 102 - const params = Object.assign({}, this.params, { 103 - limit: PAGE_SIZE, 104 - before: this.loadMoreCursor, 105 - }) 106 - if (this.isRefreshing) { 107 - this.followers = [] 108 - } 109 - const res = await this.rootStore.api.app.bsky.graph.getFollowers(params) 110 - await this._appendAll(res) 111 - this._xIdle() 112 - } catch (e: any) { 113 - this._xIdle(e) 114 - } 110 + private _replaceAll(res: GetFollowers.Response) { 111 + this.followers = [] 112 + this._appendAll(res) 115 113 } 116 114 117 - private async _appendAll(res: GetFollowers.Response) { 115 + private _appendAll(res: GetFollowers.Response) { 118 116 this.loadMoreCursor = res.data.cursor 119 117 this.hasMore = !!this.loadMoreCursor 120 118 this.followers = this.followers.concat(res.data.followers) 119 + this.rootStore.me.follows.hydrateProfiles(res.data.followers) 121 120 } 122 121 }
+30 -31
src/state/models/user-follows-view.ts
··· 4 4 AppBskyActorRef as ActorRef, 5 5 } from '@atproto/api' 6 6 import {RootStoreModel} from './root-store' 7 + import {cleanError} from 'lib/strings/errors' 8 + import {bundleAsync} from 'lib/async/bundle' 7 9 8 10 const PAGE_SIZE = 30 9 11 10 - export type FollowItem = GetFollows.Follow 12 + export type FollowItem = ActorRef.WithInfo 11 13 12 14 export class UserFollowsViewModel { 13 15 // state ··· 18 20 params: GetFollows.QueryParams 19 21 hasMore = true 20 22 loadMoreCursor?: string 21 - private _loadMorePromise: Promise<void> | undefined 22 23 23 24 // data 24 25 subject: ActorRef.WithInfo = { ··· 62 63 return this.loadMore(true) 63 64 } 64 65 65 - async loadMore(isRefreshing = false) { 66 - if (this._loadMorePromise) { 67 - return this._loadMorePromise 66 + loadMore = bundleAsync(async (replace: boolean = false) => { 67 + if (!replace && !this.hasMore) { 68 + return 68 69 } 69 - this._loadMorePromise = this._loadMore(isRefreshing) 70 - await this._loadMorePromise 71 - this._loadMorePromise = undefined 72 - } 70 + this._xLoading(replace) 71 + try { 72 + const params = Object.assign({}, this.params, { 73 + limit: PAGE_SIZE, 74 + before: replace ? undefined : this.loadMoreCursor, 75 + }) 76 + const res = await this.rootStore.api.app.bsky.graph.getFollows(params) 77 + if (replace) { 78 + this._replaceAll(res) 79 + } else { 80 + this._appendAll(res) 81 + } 82 + this._xIdle() 83 + } catch (e: any) { 84 + this._xIdle(e) 85 + } 86 + }) 73 87 74 88 // state transitions 75 89 // = ··· 84 98 this.isLoading = false 85 99 this.isRefreshing = false 86 100 this.hasLoaded = true 87 - this.error = err ? err.toString() : '' 101 + this.error = cleanError(err) 88 102 if (err) { 89 103 this.rootStore.log.error('Failed to fetch user follows', err) 90 104 } 91 105 } 92 106 93 - // loader functions 107 + // helper functions 94 108 // = 95 109 96 - private async _loadMore(isRefreshing = false) { 97 - if (!this.hasMore) { 98 - return 99 - } 100 - this._xLoading(isRefreshing) 101 - try { 102 - const params = Object.assign({}, this.params, { 103 - limit: PAGE_SIZE, 104 - before: this.loadMoreCursor, 105 - }) 106 - if (this.isRefreshing) { 107 - this.follows = [] 108 - } 109 - const res = await this.rootStore.api.app.bsky.graph.getFollows(params) 110 - await this._appendAll(res) 111 - this._xIdle() 112 - } catch (e: any) { 113 - this._xIdle(e) 114 - } 110 + private _replaceAll(res: GetFollows.Response) { 111 + this.follows = [] 112 + this._appendAll(res) 115 113 } 116 114 117 - private async _appendAll(res: GetFollows.Response) { 115 + private _appendAll(res: GetFollows.Response) { 118 116 this.loadMoreCursor = res.data.cursor 119 117 this.hasMore = !!this.loadMoreCursor 120 118 this.follows = this.follows.concat(res.data.follows) 119 + this.rootStore.me.follows.hydrateProfiles(res.data.follows) 121 120 } 122 121 }
+32 -30
src/state/models/votes-view.ts
··· 2 2 import {AtUri} from '../../third-party/uri' 3 3 import {AppBskyFeedGetVotes as GetVotes} from '@atproto/api' 4 4 import {RootStoreModel} from './root-store' 5 + import {cleanError} from 'lib/strings/errors' 6 + import {bundleAsync} from 'lib/async/bundle' 7 + import * as apilib from 'lib/api/index' 5 8 6 9 const PAGE_SIZE = 30 7 10 ··· 17 20 params: GetVotes.QueryParams 18 21 hasMore = true 19 22 loadMoreCursor?: string 20 - private _loadMorePromise: Promise<void> | undefined 21 23 22 24 // data 23 25 uri: string = '' ··· 54 56 return this.loadMore(true) 55 57 } 56 58 57 - async loadMore(isRefreshing = false) { 58 - if (this._loadMorePromise) { 59 - return this._loadMorePromise 59 + loadMore = bundleAsync(async (replace: boolean = false) => { 60 + if (!replace && !this.hasMore) { 61 + return 60 62 } 61 - if (!this.resolvedUri) { 62 - await this._resolveUri() 63 + this._xLoading(replace) 64 + try { 65 + if (!this.resolvedUri) { 66 + await this._resolveUri() 67 + } 68 + const params = Object.assign({}, this.params, { 69 + uri: this.resolvedUri, 70 + limit: PAGE_SIZE, 71 + before: replace ? undefined : this.loadMoreCursor, 72 + }) 73 + const res = await this.rootStore.api.app.bsky.feed.getVotes(params) 74 + if (replace) { 75 + this._replaceAll(res) 76 + } else { 77 + this._appendAll(res) 78 + } 79 + this._xIdle() 80 + } catch (e: any) { 81 + this._xIdle(e) 63 82 } 64 - this._loadMorePromise = this._loadMore(isRefreshing) 65 - await this._loadMorePromise 66 - this._loadMorePromise = undefined 67 - } 83 + }) 68 84 69 85 // state transitions 70 86 // = ··· 79 95 this.isLoading = false 80 96 this.isRefreshing = false 81 97 this.hasLoaded = true 82 - this.error = err ? err.toString() : '' 98 + this.error = cleanError(err) 83 99 if (err) { 84 100 this.rootStore.log.error('Failed to fetch votes', err) 85 101 } 86 102 } 87 103 88 - // loader functions 104 + // helper functions 89 105 // = 90 106 91 107 private async _resolveUri() { 92 108 const urip = new AtUri(this.params.uri) 93 109 if (!urip.host.startsWith('did:')) { 94 110 try { 95 - urip.host = await this.rootStore.resolveName(urip.host) 111 + urip.host = await apilib.resolveName(this.rootStore, urip.host) 96 112 } catch (e: any) { 97 113 this.error = e.toString() 98 114 } ··· 102 118 }) 103 119 } 104 120 105 - private async _loadMore(isRefreshing = false) { 106 - this._xLoading(isRefreshing) 107 - try { 108 - const params = Object.assign({}, this.params, { 109 - uri: this.resolvedUri, 110 - limit: PAGE_SIZE, 111 - before: this.loadMoreCursor, 112 - }) 113 - if (this.isRefreshing) { 114 - this.votes = [] 115 - } 116 - const res = await this.rootStore.api.app.bsky.feed.getVotes(params) 117 - this._appendAll(res) 118 - this._xIdle() 119 - } catch (e: any) { 120 - this._xIdle(e) 121 - } 121 + private _replaceAll(res: GetVotes.Response) { 122 + this.votes = [] 123 + this._appendAll(res) 122 124 } 123 125 124 126 private _appendAll(res: GetVotes.Response) {
+2 -2
src/view/com/composer/Autocomplete.tsx
··· 5 5 StyleSheet, 6 6 useWindowDimensions, 7 7 } from 'react-native' 8 - import {useAnimatedValue} from '../../lib/hooks/useAnimatedValue' 8 + import {useAnimatedValue} from 'lib/hooks/useAnimatedValue' 9 + import {usePalette} from 'lib/hooks/usePalette' 9 10 import {Text} from '../util/text/Text' 10 - import {usePalette} from '../../lib/hooks/usePalette' 11 11 12 12 interface AutocompleteItem { 13 13 handle: string
+84 -57
src/view/com/composer/ComposePost.tsx
··· 3 3 import { 4 4 ActivityIndicator, 5 5 KeyboardAvoidingView, 6 + NativeSyntheticEvent, 6 7 Platform, 7 8 SafeAreaView, 8 9 ScrollView, 9 10 StyleSheet, 11 + TextInputSelectionChangeEventData, 10 12 TouchableOpacity, 11 13 TouchableWithoutFeedback, 12 14 View, ··· 16 18 FontAwesomeIcon, 17 19 FontAwesomeIconStyle, 18 20 } from '@fortawesome/react-native-fontawesome' 19 - // import {useAnalytics} from '@segment/analytics-react-native' TODO 20 - import {UserAutocompleteViewModel} from '../../../state/models/user-autocomplete-view' 21 + import {useAnalytics} from 'lib/analytics' 22 + import _isEqual from 'lodash.isequal' 23 + import {UserAutocompleteViewModel} from 'state/models/user-autocomplete-view' 21 24 import {Autocomplete} from './Autocomplete' 22 25 import {ExternalEmbed} from './ExternalEmbed' 23 26 import {Text} from '../util/text/Text' ··· 26 29 import {CharProgress} from './char-progress/CharProgress' 27 30 import {TextLink} from '../util/Link' 28 31 import {UserAvatar} from '../util/UserAvatar' 29 - import {useStores} from '../../../state' 30 - import * as apilib from '../../../state/lib/api' 31 - import {ComposerOpts} from '../../../state/models/shell-ui' 32 - import {s, colors, gradients} from '../../lib/styles' 33 - import { 34 - detectLinkables, 35 - extractEntities, 36 - cleanError, 37 - } from '../../../lib/strings' 38 - import {getLinkMeta} from '../../../lib/link-meta' 39 - import {downloadAndResize} from '../../../lib/images' 32 + import {useStores} from 'state/index' 33 + import * as apilib from 'lib/api/index' 34 + import {ComposerOpts} from 'state/models/shell-ui' 35 + import {s, colors, gradients} from 'lib/styles' 36 + import {cleanError} from 'lib/strings/errors' 37 + import {detectLinkables, extractEntities} from 'lib/strings/rich-text-detection' 38 + import {getLinkMeta} from 'lib/link-meta/link-meta' 39 + import {downloadAndResize} from 'lib/images' 40 40 import {PhotoCarouselPicker, cropPhoto} from './photos/PhotoCarouselPicker' 41 + import {getMentionAt, insertMentionAt} from 'lib/strings/mention-manip' 41 42 import {SelectedPhoto} from './SelectedPhoto' 42 - import {usePalette} from '../../lib/hooks/usePalette' 43 + import {usePalette} from 'lib/hooks/usePalette' 43 44 44 45 const MAX_TEXT_LENGTH = 256 45 46 const HITSLOP = {left: 10, top: 10, right: 10, bottom: 10} 47 + 48 + interface Selection { 49 + start: number 50 + end: number 51 + } 46 52 47 53 export const ComposePost = observer(function ComposePost({ 48 54 replyTo, ··· 55 61 onPost?: ComposerOpts['onPost'] 56 62 onClose: () => void 57 63 }) { 58 - // const {track} = useAnalytics() TODO 64 + const {track, screen} = useAnalytics() 59 65 const pal = usePalette('default') 60 66 const store = useStores() 61 67 const textInput = useRef<TextInputRef>(null) 68 + const textInputSelection = useRef<Selection>({start: 0, end: 0}) 62 69 const [isProcessing, setIsProcessing] = useState(false) 63 70 const [processingState, setProcessingState] = useState('') 64 71 const [error, setError] = useState('') ··· 66 73 const [extLink, setExtLink] = useState<apilib.ExternalEmbedDraft | undefined>( 67 74 undefined, 68 75 ) 69 - const [attemptedExtLinks, setAttemptedExtLinks] = useState<string[]>([]) 76 + const [suggestedExtLinks, setSuggestedExtLinks] = useState<Set<string>>( 77 + new Set(), 78 + ) 70 79 const [isSelectingPhotos, setIsSelectingPhotos] = useState( 71 80 imagesOpen || false, 72 81 ) ··· 117 126 if (extLink.isLoading && extLink.meta?.image && !extLink.localThumb) { 118 127 downloadAndResize({ 119 128 uri: extLink.meta.image, 120 - width: 250, 121 - height: 250, 129 + width: 2000, 130 + height: 2000, 122 131 mode: 'contain', 123 - maxSize: 100000, 132 + maxSize: 1000000, 124 133 timeout: 15e3, 125 134 }) 126 135 .catch(() => undefined) ··· 166 175 textInput.current?.focus() 167 176 } 168 177 const onPressSelectPhotos = () => { 178 + track('ComposePost:SelectPhotos') 169 179 if (isSelectingPhotos) { 170 180 setIsSelectingPhotos(false) 171 181 } else if (selectedPhotos.length < 4) { ··· 173 183 } 174 184 } 175 185 const onSelectPhotos = (photos: string[]) => { 186 + track('ComposePost:SelectPhotos:Done') 176 187 setSelectedPhotos(photos) 177 188 if (photos.length >= 4) { 178 189 setIsSelectingPhotos(false) 179 190 } 180 191 } 192 + const onPressAddLinkCard = (uri: string) => { 193 + setExtLink({uri, isLoading: true}) 194 + } 181 195 const onChangeText = (newText: string) => { 182 196 setText(newText) 183 197 184 - const prefix = extractTextAutocompletePrefix(newText) 185 - if (typeof prefix === 'string') { 198 + const prefix = getMentionAt(newText, textInputSelection.current?.start || 0) 199 + if (prefix) { 186 200 autocompleteView.setActive(true) 187 - autocompleteView.setPrefix(prefix) 201 + autocompleteView.setPrefix(prefix.value) 188 202 } else { 189 203 autocompleteView.setActive(false) 190 204 } 191 205 192 - if (!extLink && /\s$/.test(newText)) { 193 - const ents = extractEntities(newText) 194 - const entLink = ents 195 - ?.filter( 196 - ent => ent.type === 'link' && !attemptedExtLinks.includes(ent.value), 197 - ) 198 - .pop() // use last 199 - if (entLink) { 200 - setExtLink({ 201 - uri: entLink.value, 202 - isLoading: true, 203 - }) 204 - setAttemptedExtLinks([...attemptedExtLinks, entLink.value]) 206 + if (!extLink) { 207 + const ents = extractEntities(newText)?.filter(ent => ent.type === 'link') 208 + const set = new Set(ents ? ents.map(e => e.value) : []) 209 + if (!_isEqual(set, suggestedExtLinks)) { 210 + setSuggestedExtLinks(set) 205 211 } 206 212 } 207 213 } ··· 218 224 onSelectPhotos([...selectedPhotos, finalImgPath]) 219 225 } 220 226 } 227 + const onSelectionChange = ( 228 + evt: NativeSyntheticEvent<TextInputSelectionChangeEventData>, 229 + ) => { 230 + // NOTE we track the input selection using a ref to avoid excessive renders -prf 231 + textInputSelection.current = evt.nativeEvent.selection 232 + } 233 + const onSelectAutocompleteItem = (item: string) => { 234 + setText(insertMentionAt(text, textInputSelection.current?.start || 0, item)) 235 + autocompleteView.setActive(false) 236 + } 221 237 const onPressCancel = () => hackfixOnClose() 222 238 const onPressPublish = async () => { 223 239 if (isProcessing) { ··· 242 258 autocompleteView.knownHandles, 243 259 setProcessingState, 244 260 ) 245 - // TODO 246 - // track('Create Post', { 247 - // imageCount: selectedPhotos.length, 248 - // }) 261 + track('Create Post', { 262 + imageCount: selectedPhotos.length, 263 + }) 249 264 } catch (e: any) { 265 + setExtLink({ 266 + ...extLink, 267 + isLoading: true, 268 + localThumb: undefined, 269 + } as apilib.ExternalEmbedDraft) 250 270 setError(cleanError(e.message)) 251 271 setIsProcessing(false) 252 272 return ··· 255 275 onPost?.() 256 276 hackfixOnClose() 257 277 Toast.show(`Your ${replyTo ? 'reply' : 'post'} has been published`) 258 - } 259 - const onSelectAutocompleteItem = (item: string) => { 260 - setText(replaceTextAutocompletePrefix(text, item)) 261 - autocompleteView.setActive(false) 262 278 } 263 279 264 280 const canPost = text.length <= MAX_TEXT_LENGTH ··· 386 402 innerRef={textInput} 387 403 onChangeText={(str: string) => onChangeText(str)} 388 404 onPaste={onPaste} 405 + onSelectionChange={onSelectionChange} 389 406 placeholder={selectTextInputPlaceholder} 390 407 style={[ 391 408 pal.text, ··· 406 423 /> 407 424 )} 408 425 </ScrollView> 409 - {isSelectingPhotos && selectedPhotos.length < 4 && ( 426 + {isSelectingPhotos && selectedPhotos.length < 4 ? ( 410 427 <PhotoCarouselPicker 411 428 selectedPhotos={selectedPhotos} 412 429 onSelectPhotos={onSelectPhotos} 413 430 /> 414 - )} 431 + ) : !extLink && 432 + selectedPhotos.length === 0 && 433 + suggestedExtLinks.size > 0 ? ( 434 + <View style={s.mb5}> 435 + {Array.from(suggestedExtLinks).map(url => ( 436 + <TouchableOpacity 437 + key={`suggested-${url}`} 438 + style={[pal.borderDark, styles.addExtLinkBtn]} 439 + onPress={() => onPressAddLinkCard(url)}> 440 + <Text> 441 + Add link card: <Text style={pal.link}>{url}</Text> 442 + </Text> 443 + </TouchableOpacity> 444 + ))} 445 + </View> 446 + ) : null} 415 447 <View style={[pal.border, styles.bottomBar]}> 416 448 <TouchableOpacity 417 449 testID="composerSelectPhotosButton" ··· 441 473 </KeyboardAvoidingView> 442 474 ) 443 475 }) 444 - 445 - const atPrefixRegex = /@([a-z0-9.]*)$/i 446 - function extractTextAutocompletePrefix(text: string) { 447 - const match = atPrefixRegex.exec(text) 448 - if (match) { 449 - return match[1] 450 - } 451 - return undefined 452 - } 453 - function replaceTextAutocompletePrefix(text: string, item: string) { 454 - return text.replace(atPrefixRegex, `@${item} `) 455 - } 456 476 457 477 const styles = StyleSheet.create({ 458 478 outer: { ··· 531 551 flex: 1, 532 552 paddingLeft: 13, 533 553 paddingRight: 8, 554 + }, 555 + addExtLinkBtn: { 556 + borderWidth: 1, 557 + borderRadius: 24, 558 + paddingHorizontal: 16, 559 + paddingVertical: 12, 560 + marginBottom: 4, 534 561 }, 535 562 bottomBar: { 536 563 flexDirection: 'row',
+12 -30
src/view/com/composer/ExternalEmbed.tsx
··· 7 7 } from 'react-native' 8 8 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 9 9 import {BlurView} from '../util/BlurView' 10 - import LinearGradient from 'react-native-linear-gradient' 11 10 import {AutoSizedImage} from '../util/images/AutoSizedImage' 12 11 import {Text} from '../util/text/Text' 13 - import {s, gradients} from '../../lib/styles' 14 - import {usePalette} from '../../lib/hooks/usePalette' 15 - import {ExternalEmbedDraft} from '../../../state/lib/api' 12 + import {s} from 'lib/styles' 13 + import {usePalette} from 'lib/hooks/usePalette' 14 + import {ExternalEmbedDraft} from 'lib/api/index' 16 15 17 16 export const ExternalEmbed = ({ 18 17 link, ··· 30 29 <View style={[styles.outer, pal.view, pal.border]}> 31 30 {link.isLoading ? ( 32 31 <View 33 - style={[ 34 - styles.image, 35 - styles.imageFallback, 36 - {backgroundColor: pal.colors.backgroundLight}, 37 - ]}> 32 + style={[styles.image, {backgroundColor: pal.colors.backgroundLight}]}> 38 33 <ActivityIndicator size="large" style={styles.spinner} /> 39 34 </View> 40 35 ) : link.localThumb ? ( 41 - <AutoSizedImage 42 - uri={link.localThumb.path} 43 - containerStyle={styles.image} 44 - /> 45 - ) : ( 46 - <LinearGradient 47 - colors={[gradients.blueDark.start, gradients.blueDark.end]} 48 - start={{x: 0, y: 0}} 49 - end={{x: 1, y: 1}} 50 - style={[styles.image, styles.imageFallback]} 51 - /> 52 - )} 53 - <TouchableWithoutFeedback onPress={onRemove}> 54 - <BlurView style={styles.removeBtn} blurType="dark"> 55 - <FontAwesomeIcon size={18} icon="xmark" style={s.white} /> 56 - </BlurView> 57 - </TouchableWithoutFeedback> 36 + <AutoSizedImage uri={link.localThumb.path} style={styles.image} /> 37 + ) : undefined} 58 38 <View style={styles.inner}> 59 39 {!!link.meta?.title && ( 60 40 <Text type="sm-bold" numberOfLines={2} style={[pal.text]}> ··· 81 61 </Text> 82 62 )} 83 63 </View> 64 + <TouchableWithoutFeedback onPress={onRemove}> 65 + <BlurView style={styles.removeBtn} blurType="dark"> 66 + <FontAwesomeIcon size={18} icon="xmark" style={s.white} /> 67 + </BlurView> 68 + </TouchableWithoutFeedback> 84 69 </View> 85 70 ) 86 71 } ··· 98 83 borderTopLeftRadius: 6, 99 84 borderTopRightRadius: 6, 100 85 width: '100%', 101 - height: 200, 102 - }, 103 - imageFallback: { 104 - height: 160, 86 + maxHeight: 200, 105 87 }, 106 88 removeBtn: { 107 89 position: 'absolute',
+1 -1
src/view/com/composer/Prompt.tsx
··· 2 2 import {StyleSheet, TouchableOpacity, View} from 'react-native' 3 3 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 4 4 import {Text} from '../util/text/Text' 5 - import {usePalette} from '../../lib/hooks/usePalette' 5 + import {usePalette} from 'lib/hooks/usePalette' 6 6 7 7 export function ComposePrompt({ 8 8 text = "What's up?",
+3 -2
src/view/com/composer/SelectedPhoto.tsx
··· 1 1 import React, {useCallback} from 'react' 2 - import {Image, StyleSheet, TouchableOpacity, View} from 'react-native' 2 + import {StyleSheet, TouchableOpacity, View} from 'react-native' 3 3 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 4 - import {colors} from '../../lib/styles' 4 + import Image from 'view/com/util/images/Image' 5 + import {colors} from 'lib/styles' 5 6 6 7 export const SelectedPhoto = ({ 7 8 selectedPhotos,
+1 -1
src/view/com/composer/char-progress/CharProgress.tsx
··· 5 5 import ProgressCircle from 'react-native-progress/Circle' 6 6 // @ts-ignore no type definition -prf 7 7 import ProgressPie from 'react-native-progress/Pie' 8 - import {s, colors} from '../../../lib/styles' 8 + import {s, colors} from 'lib/styles' 9 9 10 10 const MAX_TEXT_LENGTH = 256 11 11 const DANGER_TEXT_LENGTH = MAX_TEXT_LENGTH
+1 -1
src/view/com/composer/char-progress/CharProgress.web.tsx
··· 1 1 import React from 'react' 2 2 import {View} from 'react-native' 3 3 import {Text} from '../../util/text/Text' 4 - import {s} from '../../../lib/styles' 4 + import {s} from 'lib/styles' 5 5 6 6 const MAX_TEXT_LENGTH = 256 7 7 const DANGER_TEXT_LENGTH = MAX_TEXT_LENGTH
+66 -46
src/view/com/composer/photos/PhotoCarouselPicker.tsx
··· 4 4 FontAwesomeIcon, 5 5 FontAwesomeIconStyle, 6 6 } from '@fortawesome/react-native-fontawesome' 7 + import {useAnalytics} from 'lib/analytics' 7 8 import { 8 9 openPicker, 9 10 openCamera, ··· 12 13 import { 13 14 UserLocalPhotosModel, 14 15 PhotoIdentifier, 15 - } from '../../../../state/models/user-local-photos' 16 - import {compressIfNeeded, scaleDownDimensions} from '../../../../lib/images' 17 - import {usePalette} from '../../../lib/hooks/usePalette' 18 - import {useStores, RootStoreModel} from '../../../../state' 16 + } from 'state/models/user-local-photos' 17 + import { 18 + compressIfNeeded, 19 + moveToPremanantPath, 20 + scaleDownDimensions, 21 + } from 'lib/images' 22 + import {usePalette} from 'lib/hooks/usePalette' 23 + import {useStores, RootStoreModel} from 'state/index' 24 + import { 25 + requestPhotoAccessIfNeeded, 26 + requestCameraAccessIfNeeded, 27 + } from 'lib/permissions' 19 28 20 - const MAX_WIDTH = 1000 21 - const MAX_HEIGHT = 1000 22 - const MAX_SIZE = 300000 29 + const MAX_WIDTH = 2000 30 + const MAX_HEIGHT = 2000 31 + const MAX_SIZE = 1000000 23 32 24 33 const IMAGE_PARAMS = { 25 - width: 1000, 26 - height: 1000, 34 + width: 2000, 35 + height: 2000, 27 36 freeStyleCropEnabled: true, 28 37 } 29 38 ··· 46 55 width, 47 56 height, 48 57 }) 58 + 49 59 const img = await compressIfNeeded(cropperRes, MAX_SIZE) 50 - return img.path 60 + const permanentPath = await moveToPremanantPath(img.path) 61 + return permanentPath 51 62 } 52 63 53 64 export const PhotoCarouselPicker = ({ ··· 57 68 selectedPhotos: string[] 58 69 onSelectPhotos: (v: string[]) => void 59 70 }) => { 71 + const {track} = useAnalytics() 60 72 const pal = usePalette('default') 61 73 const store = useStores() 62 - const [localPhotos, setLocalPhotos] = React.useState< 63 - UserLocalPhotosModel | undefined 64 - >(undefined) 74 + const [isSetup, setIsSetup] = React.useState<boolean>(false) 65 75 66 - // initial setup 76 + const localPhotos = React.useMemo<UserLocalPhotosModel>( 77 + () => new UserLocalPhotosModel(store), 78 + [store], 79 + ) 80 + 67 81 React.useEffect(() => { 68 - const photos = new UserLocalPhotosModel(store) 69 - photos.setup().then(() => { 70 - if (photos.photos) { 71 - setLocalPhotos(photos) 72 - } 82 + // initial setup 83 + localPhotos.setup().then(() => { 84 + setIsSetup(true) 73 85 }) 74 - }, [store]) 86 + }, [localPhotos]) 75 87 76 88 const handleOpenCamera = useCallback(async () => { 77 89 try { 90 + if (!(await requestCameraAccessIfNeeded())) { 91 + return 92 + } 78 93 const cameraRes = await openCamera(store, { 79 94 mediaType: 'photo', 80 95 ...IMAGE_PARAMS, ··· 89 104 90 105 const handleSelectPhoto = useCallback( 91 106 async (item: PhotoIdentifier) => { 107 + track('PhotoCarouselPicker:PhotoSelected') 92 108 try { 93 109 const imgPath = await cropPhoto( 94 110 store, ··· 102 118 store.log.warn('Error selecting photo', err) 103 119 } 104 120 }, 105 - [store, selectedPhotos, onSelectPhotos], 121 + [track, store, onSelectPhotos, selectedPhotos], 106 122 ) 107 123 108 - const handleOpenGallery = useCallback(() => { 109 - openPicker(store, { 124 + const handleOpenGallery = useCallback(async () => { 125 + track('PhotoCarouselPicker:GalleryOpened') 126 + if (!(await requestPhotoAccessIfNeeded())) { 127 + return 128 + } 129 + const items = await openPicker(store, { 110 130 multiple: true, 111 131 maxFiles: 4 - selectedPhotos.length, 112 132 mediaType: 'photo', 113 - }).then(async items => { 114 - const result = [] 115 - 116 - for (const image of items) { 117 - // choose target dimensions based on the original 118 - // this causes the photo cropper to start with the full image "selected" 119 - const {width, height} = scaleDownDimensions( 120 - {width: image.width, height: image.height}, 121 - {width: MAX_WIDTH, height: MAX_HEIGHT}, 122 - ) 123 - const cropperRes = await openCropper(store, { 124 - mediaType: 'photo', 125 - path: image.path, 126 - freeStyleCropEnabled: true, 127 - width, 128 - height, 129 - }) 130 - const finalImg = await compressIfNeeded(cropperRes, MAX_SIZE) 131 - result.push(finalImg.path) 132 - } 133 - onSelectPhotos([...selectedPhotos, ...result]) 134 133 }) 135 - }, [store, selectedPhotos, onSelectPhotos]) 134 + const result = [] 135 + 136 + for (const image of items) { 137 + // choose target dimensions based on the original 138 + // this causes the photo cropper to start with the full image "selected" 139 + const {width, height} = scaleDownDimensions( 140 + {width: image.width, height: image.height}, 141 + {width: MAX_WIDTH, height: MAX_HEIGHT}, 142 + ) 143 + const cropperRes = await openCropper(store, { 144 + mediaType: 'photo', 145 + path: image.path, 146 + ...IMAGE_PARAMS, 147 + width, 148 + height, 149 + }) 150 + const finalImg = await compressIfNeeded(cropperRes, MAX_SIZE) 151 + const permanentPath = await moveToPremanantPath(finalImg.path) 152 + result.push(permanentPath) 153 + } 154 + onSelectPhotos([...selectedPhotos, ...result]) 155 + }, [track, store, selectedPhotos, onSelectPhotos]) 136 156 137 157 return ( 138 158 <ScrollView ··· 161 181 size={24} 162 182 /> 163 183 </TouchableOpacity> 164 - {localPhotos != null && 184 + {isSetup && 165 185 localPhotos.photos.map((item: PhotoIdentifier, index: number) => ( 166 186 <TouchableOpacity 167 187 testID="openSelectPhotoButton"
+3 -3
src/view/com/composer/photos/PhotoCarouselPicker.web.tsx
··· 9 9 openCamera, 10 10 openCropper, 11 11 } from '../../util/images/image-crop-picker/ImageCropPicker' 12 - import {compressIfNeeded, scaleDownDimensions} from '../../../../lib/images' 13 - import {usePalette} from '../../../lib/hooks/usePalette' 14 - import {useStores, RootStoreModel} from '../../../../state' 12 + import {compressIfNeeded, scaleDownDimensions} from 'lib/images' 13 + import {usePalette} from 'lib/hooks/usePalette' 14 + import {useStores, RootStoreModel} from 'state/index' 15 15 16 16 const MAX_WIDTH = 1000 17 17 const MAX_HEIGHT = 1000
+12 -2
src/view/com/composer/text-input/TextInput.tsx
··· 1 1 import React from 'react' 2 - import {StyleProp, TextStyle} from 'react-native' 2 + import { 3 + NativeSyntheticEvent, 4 + StyleProp, 5 + TextInputSelectionChangeEventData, 6 + TextStyle, 7 + } from 'react-native' 3 8 import PasteInput, { 4 9 PastedFile, 5 10 PasteInputRef, 6 11 } from '@mattermost/react-native-paste-input' 7 - import {usePalette} from '../../../lib/hooks/usePalette' 12 + import {usePalette} from 'lib/hooks/usePalette' 8 13 9 14 export type TextInputRef = PasteInputRef 10 15 ··· 14 19 placeholder: string 15 20 style: StyleProp<TextStyle> 16 21 onChangeText: (str: string) => void 22 + onSelectionChange?: 23 + | ((e: NativeSyntheticEvent<TextInputSelectionChangeEventData>) => void) 24 + | undefined 17 25 onPaste: (err: string | undefined, uris: string[]) => void 18 26 } 19 27 ··· 23 31 placeholder, 24 32 style, 25 33 onChangeText, 34 + onSelectionChange, 26 35 onPaste, 27 36 children, 28 37 }: React.PropsWithChildren<TextInputProps>) { ··· 44 53 multiline 45 54 scrollEnabled 46 55 onChangeText={(str: string) => onChangeText(str)} 56 + onSelectionChange={onSelectionChange} 47 57 onPaste={onPasteInner} 48 58 placeholder={placeholder} 49 59 placeholderTextColor={pal.colors.textLight}
+9 -2
src/view/com/composer/text-input/TextInput.web.tsx
··· 1 1 import React from 'react' 2 2 import { 3 + NativeSyntheticEvent, 3 4 StyleProp, 4 5 StyleSheet, 5 6 TextInput as RNTextInput, 7 + TextInputSelectionChangeEventData, 6 8 TextStyle, 7 9 } from 'react-native' 8 - import {usePalette} from '../../../lib/hooks/usePalette' 9 - import {addStyle} from '../../../lib/addStyle' 10 + import {usePalette} from 'lib/hooks/usePalette' 11 + import {addStyle} from 'lib/styles' 10 12 11 13 export type TextInputRef = RNTextInput 12 14 ··· 16 18 placeholder: string 17 19 style: StyleProp<TextStyle> 18 20 onChangeText: (str: string) => void 21 + onSelectionChange?: 22 + | ((e: NativeSyntheticEvent<TextInputSelectionChangeEventData>) => void) 23 + | undefined 19 24 onPaste: (err: string | undefined, uris: string[]) => void 20 25 } 21 26 ··· 25 30 placeholder, 26 31 style, 27 32 onChangeText, 33 + onSelectionChange, 28 34 children, 29 35 }: React.PropsWithChildren<TextInputProps>) { 30 36 const pal = usePalette('default') ··· 36 42 multiline 37 43 scrollEnabled 38 44 onChangeText={(str: string) => onChangeText(str)} 45 + onSelectionChange={onSelectionChange} 39 46 placeholder={placeholder} 40 47 placeholderTextColor={pal.colors.textLight} 41 48 style={style}>
+5 -6
src/view/com/discover/LiteSuggestedFollows.tsx
··· 8 8 import LinearGradient from 'react-native-linear-gradient' 9 9 import {observer} from 'mobx-react-lite' 10 10 import _omit from 'lodash.omit' 11 - import {ErrorMessage} from '../util/error/ErrorMessage' 12 11 import {Link} from '../util/Link' 13 12 import {Text} from '../util/text/Text' 14 13 import {UserAvatar} from '../util/UserAvatar' 15 14 import * as Toast from '../util/Toast' 16 - import {useStores} from '../../../state' 17 - import * as apilib from '../../../state/lib/api' 15 + import {useStores} from 'state/index' 16 + import * as apilib from 'lib/api/index' 18 17 import { 19 18 SuggestedActorsViewModel, 20 19 SuggestedActor, 21 - } from '../../../state/models/suggested-actors-view' 22 - import {s, gradients} from '../../lib/styles' 23 - import {usePalette} from '../../lib/hooks/usePalette' 20 + } from 'state/models/suggested-actors-view' 21 + import {s, gradients} from 'lib/styles' 22 + import {usePalette} from 'lib/hooks/usePalette' 24 23 25 24 export const LiteSuggestedFollows = observer(() => { 26 25 const store = useStores()
+21 -187
src/view/com/discover/SuggestedFollows.tsx
··· 1 - import React, {useEffect, useState} from 'react' 2 - import { 3 - ActivityIndicator, 4 - StyleSheet, 5 - TouchableOpacity, 6 - View, 7 - } from 'react-native' 8 - import LinearGradient from 'react-native-linear-gradient' 9 - import { 10 - FontAwesomeIcon, 11 - FontAwesomeIconStyle, 12 - } from '@fortawesome/react-native-fontawesome' 13 - import {observer} from 'mobx-react-lite' 14 - import _omit from 'lodash.omit' 1 + import React from 'react' 2 + import {ActivityIndicator, StyleSheet, View} from 'react-native' 15 3 import {CenteredView, FlatList} from '../util/Views' 4 + import {observer} from 'mobx-react-lite' 16 5 import {ErrorScreen} from '../util/error/ErrorScreen' 17 - import {Link} from '../util/Link' 18 - import {Text} from '../util/text/Text' 19 - import {UserAvatar} from '../util/UserAvatar' 20 - import * as Toast from '../util/Toast' 21 - import {useStores} from '../../../state' 22 - import * as apilib from '../../../state/lib/api' 6 + import {ProfileCardWithFollowBtn} from '../profile/ProfileCard' 7 + import {useStores} from 'state/index' 23 8 import { 24 9 SuggestedActorsViewModel, 25 10 SuggestedActor, 26 - } from '../../../state/models/suggested-actors-view' 27 - import {s, gradients} from '../../lib/styles' 28 - import {usePalette} from '../../lib/hooks/usePalette' 11 + } from 'state/models/suggested-actors-view' 12 + import {s} from 'lib/styles' 13 + import {usePalette} from 'lib/hooks/usePalette' 29 14 30 15 export const SuggestedFollows = observer( 31 - ({ 32 - onNoSuggestions, 33 - asLinks, 34 - }: { 35 - onNoSuggestions?: () => void 36 - asLinks?: boolean 37 - }) => { 16 + ({onNoSuggestions}: {onNoSuggestions?: () => void}) => { 38 17 const pal = usePalette('default') 39 18 const store = useStores() 40 - const [follows, setFollows] = useState<Record<string, string>>({}) 41 19 42 - // Using default import (React.use...) instead of named import (use...) to be able to mock store's data in jest environment 43 20 const view = React.useMemo<SuggestedActorsViewModel>( 44 21 () => new SuggestedActorsViewModel(store), 45 22 [store], 46 23 ) 47 24 48 - useEffect(() => { 25 + React.useEffect(() => { 49 26 view 50 27 .loadMore() 51 28 .catch((err: any) => ··· 53 30 ) 54 31 }, [view, store.log]) 55 32 56 - useEffect(() => { 33 + React.useEffect(() => { 57 34 if (!view.isLoading && !view.hasError && !view.hasContent) { 58 35 onNoSuggestions?.() 59 36 } ··· 74 51 ) 75 52 } 76 53 77 - const onPressFollow = async (item: SuggestedActor) => { 78 - try { 79 - const res = await apilib.follow(store, item.did, item.declaration.cid) 80 - setFollows({[item.did]: res.uri, ...follows}) 81 - } catch (e: any) { 82 - store.log.error('Failed fo create follow', e) 83 - Toast.show('An issue occurred, please try again.') 84 - } 85 - } 86 - const onPressUnfollow = async (item: SuggestedActor) => { 87 - try { 88 - await apilib.unfollow(store, follows[item.did]) 89 - setFollows(_omit(follows, [item.did])) 90 - } catch (e: any) { 91 - store.log.error('Failed fo delete follow', e) 92 - Toast.show('An issue occurred, please try again.') 93 - } 94 - } 95 - 96 54 const renderItem = ({item}: {item: SuggestedActor}) => { 97 - if (asLinks) { 98 - return ( 99 - <Link 100 - href={`/profile/${item.handle}`} 101 - title={item.displayName || item.handle}> 102 - <User 103 - item={item} 104 - follow={follows[item.did]} 105 - onPressFollow={onPressFollow} 106 - onPressUnfollow={onPressUnfollow} 107 - /> 108 - </Link> 109 - ) 110 - } 111 55 return ( 112 - <User 113 - item={item} 114 - follow={follows[item.did]} 115 - onPressFollow={onPressFollow} 116 - onPressUnfollow={onPressUnfollow} 56 + <ProfileCardWithFollowBtn 57 + key={item.did} 58 + did={item.did} 59 + declarationCid={item.declaration.cid} 60 + handle={item.handle} 61 + displayName={item.displayName} 62 + avatar={item.avatar} 63 + description={item.description} 117 64 /> 118 65 ) 119 66 } ··· 146 93 </View> 147 94 )} 148 95 contentContainerStyle={s.contentContainer} 149 - style={s.flex1} 150 96 /> 151 97 </View> 152 98 )} ··· 155 101 }, 156 102 ) 157 103 158 - const User = ({ 159 - item, 160 - follow, 161 - onPressFollow, 162 - onPressUnfollow, 163 - }: { 164 - item: SuggestedActor 165 - follow: string | undefined 166 - onPressFollow: (item: SuggestedActor) => void 167 - onPressUnfollow: (item: SuggestedActor) => void 168 - }) => { 169 - const pal = usePalette('default') 170 - return ( 171 - <View style={[styles.actor, pal.view, pal.border]}> 172 - <View style={styles.actorMeta}> 173 - <View style={styles.actorAvi}> 174 - <UserAvatar 175 - size={40} 176 - displayName={item.displayName} 177 - handle={item.handle} 178 - avatar={item.avatar} 179 - /> 180 - </View> 181 - <View style={styles.actorContent}> 182 - <Text type="title-sm" style={pal.text} numberOfLines={1}> 183 - {item.displayName || item.handle} 184 - </Text> 185 - <Text style={pal.textLight} numberOfLines={1}> 186 - @{item.handle} 187 - </Text> 188 - </View> 189 - <View style={styles.actorBtn}> 190 - {follow ? ( 191 - <TouchableOpacity onPress={() => onPressUnfollow(item)}> 192 - <View style={[styles.btn, styles.secondaryBtn, pal.btn]}> 193 - <Text type="button" style={pal.text}> 194 - Unfollow 195 - </Text> 196 - </View> 197 - </TouchableOpacity> 198 - ) : ( 199 - <TouchableOpacity onPress={() => onPressFollow(item)}> 200 - <LinearGradient 201 - colors={[gradients.blueLight.start, gradients.blueLight.end]} 202 - start={{x: 0, y: 0}} 203 - end={{x: 1, y: 1}} 204 - style={[styles.btn, styles.gradientBtn]}> 205 - <FontAwesomeIcon 206 - icon="plus" 207 - style={[s.white as FontAwesomeIconStyle, s.mr5]} 208 - size={15} 209 - /> 210 - <Text style={[s.white, s.fw600, s.f15]}>Follow</Text> 211 - </LinearGradient> 212 - </TouchableOpacity> 213 - )} 214 - </View> 215 - </View> 216 - {item.description ? ( 217 - <View style={styles.actorDetails}> 218 - <Text style={pal.text} numberOfLines={4}> 219 - {item.description} 220 - </Text> 221 - </View> 222 - ) : undefined} 223 - </View> 224 - ) 225 - } 226 - 227 104 const styles = StyleSheet.create({ 228 105 container: { 229 - flex: 1, 106 + height: '100%', 230 107 }, 231 108 232 109 suggestionsContainer: { 233 - flex: 1, 110 + height: '100%', 234 111 }, 235 112 footer: { 236 113 height: 200, 237 114 paddingTop: 20, 238 - }, 239 - 240 - actor: { 241 - borderTopWidth: 1, 242 - }, 243 - actorMeta: { 244 - flexDirection: 'row', 245 - }, 246 - actorAvi: { 247 - width: 60, 248 - paddingLeft: 10, 249 - paddingTop: 10, 250 - paddingBottom: 10, 251 - }, 252 - actorContent: { 253 - flex: 1, 254 - paddingRight: 10, 255 - paddingTop: 10, 256 - }, 257 - actorBtn: { 258 - paddingRight: 10, 259 - paddingTop: 10, 260 - }, 261 - actorDetails: { 262 - paddingLeft: 60, 263 - paddingRight: 10, 264 - paddingBottom: 10, 265 - }, 266 - 267 - gradientBtn: { 268 - paddingHorizontal: 24, 269 - paddingVertical: 6, 270 - }, 271 - secondaryBtn: { 272 - paddingHorizontal: 14, 273 - }, 274 - btn: { 275 - flexDirection: 'row', 276 - alignItems: 'center', 277 - justifyContent: 'center', 278 - paddingVertical: 7, 279 - borderRadius: 50, 280 - marginLeft: 6, 281 115 }, 282 116 })
+66
src/view/com/discover/SuggestedPosts.tsx
··· 1 + import React from 'react' 2 + import {ActivityIndicator, StyleSheet, View} from 'react-native' 3 + import {observer} from 'mobx-react-lite' 4 + import {useStores} from 'state/index' 5 + import {SuggestedPostsView} from 'state/models/suggested-posts-view' 6 + import {s} from 'lib/styles' 7 + import {FeedItem as Post} from '../posts/FeedItem' 8 + import {Text} from '../util/text/Text' 9 + import {usePalette} from 'lib/hooks/usePalette' 10 + 11 + export const SuggestedPosts = observer(() => { 12 + const pal = usePalette('default') 13 + const store = useStores() 14 + const suggestedPostsView = React.useMemo<SuggestedPostsView>( 15 + () => new SuggestedPostsView(store), 16 + [store], 17 + ) 18 + 19 + React.useEffect(() => { 20 + if (!suggestedPostsView.hasLoaded) { 21 + suggestedPostsView.setup() 22 + } 23 + }, [store, suggestedPostsView]) 24 + 25 + return ( 26 + <> 27 + {(suggestedPostsView.hasContent || suggestedPostsView.isLoading) && ( 28 + <Text type="title" style={[styles.heading, pal.text]}> 29 + Recently, on Bluesky... 30 + </Text> 31 + )} 32 + {suggestedPostsView.hasContent && ( 33 + <> 34 + <View style={[pal.border, styles.bottomBorder]}> 35 + {suggestedPostsView.posts.map(item => ( 36 + <Post item={item} key={item._reactKey} /> 37 + ))} 38 + </View> 39 + </> 40 + )} 41 + {suggestedPostsView.isLoading && ( 42 + <View style={s.mt10}> 43 + <ActivityIndicator /> 44 + </View> 45 + )} 46 + </> 47 + ) 48 + }) 49 + 50 + const styles = StyleSheet.create({ 51 + heading: { 52 + fontWeight: 'bold', 53 + paddingHorizontal: 12, 54 + paddingTop: 16, 55 + paddingBottom: 8, 56 + }, 57 + 58 + bottomBorder: { 59 + borderBottomWidth: 1, 60 + }, 61 + 62 + loadMore: { 63 + paddingLeft: 12, 64 + paddingVertical: 10, 65 + }, 66 + })
+89
src/view/com/discover/WhoToFollow.tsx
··· 1 + import React from 'react' 2 + import { 3 + ActivityIndicator, 4 + StyleSheet, 5 + TouchableOpacity, 6 + View, 7 + } from 'react-native' 8 + import {observer} from 'mobx-react-lite' 9 + import {useStores} from 'state/index' 10 + import {SuggestedActorsViewModel} from 'state/models/suggested-actors-view' 11 + import {ProfileCardWithFollowBtn} from '../profile/ProfileCard' 12 + import {Text} from '../util/text/Text' 13 + import {s} from 'lib/styles' 14 + import {usePalette} from 'lib/hooks/usePalette' 15 + 16 + export const WhoToFollow = observer(() => { 17 + const pal = usePalette('default') 18 + const store = useStores() 19 + const suggestedActorsView = React.useMemo<SuggestedActorsViewModel>( 20 + () => new SuggestedActorsViewModel(store, {pageSize: 5}), 21 + [store], 22 + ) 23 + 24 + React.useEffect(() => { 25 + suggestedActorsView.loadMore(true) 26 + }, [store, suggestedActorsView]) 27 + 28 + const onPressLoadMoreSuggestedActors = () => { 29 + suggestedActorsView.loadMore() 30 + } 31 + return ( 32 + <> 33 + {(suggestedActorsView.hasContent || suggestedActorsView.isLoading) && ( 34 + <Text type="title" style={[styles.heading, pal.text]}> 35 + Who to follow 36 + </Text> 37 + )} 38 + {suggestedActorsView.hasContent && ( 39 + <> 40 + <View style={[pal.border, styles.bottomBorder]}> 41 + {suggestedActorsView.suggestions.map(item => ( 42 + <ProfileCardWithFollowBtn 43 + key={item.did} 44 + did={item.did} 45 + declarationCid={item.declaration.cid} 46 + handle={item.handle} 47 + displayName={item.displayName} 48 + avatar={item.avatar} 49 + description={item.description} 50 + /> 51 + ))} 52 + </View> 53 + {!suggestedActorsView.isLoading && suggestedActorsView.hasMore && ( 54 + <TouchableOpacity 55 + onPress={onPressLoadMoreSuggestedActors} 56 + style={styles.loadMore}> 57 + <Text type="lg" style={pal.link}> 58 + Show more 59 + </Text> 60 + </TouchableOpacity> 61 + )} 62 + </> 63 + )} 64 + {suggestedActorsView.isLoading && ( 65 + <View style={s.mt10}> 66 + <ActivityIndicator /> 67 + </View> 68 + )} 69 + </> 70 + ) 71 + }) 72 + 73 + const styles = StyleSheet.create({ 74 + heading: { 75 + fontWeight: 'bold', 76 + paddingHorizontal: 12, 77 + paddingTop: 16, 78 + paddingBottom: 8, 79 + }, 80 + 81 + bottomBorder: { 82 + borderBottomWidth: 1, 83 + }, 84 + 85 + loadMore: { 86 + paddingLeft: 16, 87 + paddingVertical: 12, 88 + }, 89 + })
+7 -5
src/view/com/lightbox/ImageViewing/index.tsx
··· 86 86 [toggleBarsVisible], 87 87 ) 88 88 89 + const onLayout = useCallback(() => { 90 + if (imageIndex) { 91 + imageList.current?.scrollToIndex({index: imageIndex, animated: false}) 92 + } 93 + }, [imageList, imageIndex]) 94 + 89 95 if (!visible) { 90 96 return null 91 97 } 92 98 93 99 return ( 94 - <View style={styles.screen}> 100 + <View style={styles.screen} onLayout={onLayout}> 95 101 <Modal /> 96 102 <View style={[styles.container, {opacity, backgroundColor}]}> 97 103 <Animated.View style={[styles.header, {transform: headerTransform}]}> ··· 108 114 data={images} 109 115 horizontal 110 116 pagingEnabled 111 - windowSize={2} 112 - initialNumToRender={1} 113 - maxToRenderPerBatch={1} 114 117 showsHorizontalScrollIndicator={false} 115 118 showsVerticalScrollIndicator={false} 116 - initialScrollIndex={imageIndex} 117 119 getItem={(_, index) => images[index]} 118 120 getItemCount={() => images.length} 119 121 getItemLayout={(_, index) => ({
+3 -3
src/view/com/lightbox/Lightbox.tsx
··· 2 2 import {View} from 'react-native' 3 3 import {observer} from 'mobx-react-lite' 4 4 import ImageView from './ImageViewing' 5 - import {useStores} from '../../../state' 6 - import * as models from '../../../state/models/shell-ui' 7 - import {saveImageModal} from '../../../lib/images' 5 + import {useStores} from 'state/index' 6 + import * as models from 'state/models/shell-ui' 7 + import {saveImageModal} from 'lib/images' 8 8 import {ImageSource} from './ImageViewing/@types' 9 9 10 10 export const Lightbox = observer(function Lightbox() {
+3 -3
src/view/com/lightbox/Lightbox.web.tsx
··· 8 8 } from 'react-native' 9 9 import {observer} from 'mobx-react-lite' 10 10 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 11 - import {useStores} from '../../../state' 12 - import * as models from '../../../state/models/shell-ui' 13 - import {colors} from '../../lib/styles' 11 + import {useStores} from 'state/index' 12 + import * as models from 'state/models/shell-ui' 13 + import {colors} from 'lib/styles' 14 14 15 15 interface Img { 16 16 uri: string
+16 -14
src/view/com/login/CreateAccount.tsx
··· 15 15 } from '@fortawesome/react-native-fontawesome' 16 16 import {ComAtprotoAccountCreate} from '@atproto/api' 17 17 import * as EmailValidator from 'email-validator' 18 - // import {useAnalytics} from '@segment/analytics-react-native' TODO 18 + import {useAnalytics} from 'lib/analytics' 19 19 import {LogoTextHero} from './Logo' 20 20 import {Picker} from '../util/Picker' 21 21 import {TextLink} from '../util/Link' 22 22 import {Text} from '../util/text/Text' 23 - import {s, colors} from '../../lib/styles' 24 - import { 25 - makeValidHandle, 26 - createFullHandle, 27 - toNiceDomain, 28 - } from '../../../lib/strings' 29 - import {useStores, DEFAULT_SERVICE} from '../../../state' 30 - import {ServiceDescription} from '../../../state/models/session' 31 - import {ServerInputModal} from '../../../state/models/shell-ui' 32 - import {usePalette} from '../../lib/hooks/usePalette' 23 + import {s, colors} from 'lib/styles' 24 + import {makeValidHandle, createFullHandle} from 'lib/strings/handles' 25 + import {toNiceDomain} from 'lib/strings/url-helpers' 26 + import {useStores, DEFAULT_SERVICE} from 'state/index' 27 + import {ServiceDescription} from 'state/models/session' 28 + import {ServerInputModal} from 'state/models/shell-ui' 29 + import {usePalette} from 'lib/hooks/usePalette' 30 + import {cleanError} from 'lib/strings/errors' 33 31 34 32 export const CreateAccount = ({onPressBack}: {onPressBack: () => void}) => { 35 - // const {track} = useAnalytics() TODO 33 + const {track, screen} = useAnalytics() 36 34 const pal = usePalette('default') 37 35 const store = useStores() 38 36 const [isProcessing, setIsProcessing] = useState<boolean>(false) ··· 48 46 const [password, setPassword] = useState<string>('') 49 47 const [handle, setHandle] = useState<string>('') 50 48 const [is13, setIs13] = useState<boolean>(false) 49 + 50 + useEffect(() => { 51 + screen('CreateAccount') 52 + }, [screen]) 51 53 52 54 useEffect(() => { 53 55 let aborted = false ··· 109 111 password, 110 112 inviteCode, 111 113 }) 112 - // track('Create Account') TODO 114 + track('Create Account') 113 115 } catch (e: any) { 114 116 let errMsg = e.toString() 115 117 if (e instanceof ComAtprotoAccountCreate.InvalidInviteCodeError) { ··· 118 120 } 119 121 store.log.error('Failed to create account', e) 120 122 setIsProcessing(false) 121 - setError(errMsg.replace(/^Error:/, '')) 123 + setError(cleanError(errMsg)) 122 124 } 123 125 } 124 126
+1 -1
src/view/com/login/Logo.tsx
··· 1 1 import React from 'react' 2 2 import {StyleSheet} from 'react-native' 3 3 import LinearGradient from 'react-native-linear-gradient' 4 - import {s, gradients} from '../../lib/styles' 4 + import {s, gradients} from 'lib/styles' 5 5 import {Text} from '../util/text/Text' 6 6 7 7 export const LogoTextHero = () => {
+65 -32
src/view/com/login/Signin.tsx
··· 13 13 FontAwesomeIconStyle, 14 14 } from '@fortawesome/react-native-fontawesome' 15 15 import * as EmailValidator from 'email-validator' 16 - import {sessionClient as AtpApi, SessionServiceClient} from '@atproto/api' 17 - // import {useAnalytics} from '@segment/analytics-react-native' TODO 16 + import AtpAgent from '@atproto/api' 17 + import {useAnalytics} from 'lib/analytics' 18 18 import {LogoTextHero} from './Logo' 19 19 import {Text} from '../util/text/Text' 20 20 import {UserAvatar} from '../util/UserAvatar' 21 - import {s, colors} from '../../lib/styles' 22 - import {createFullHandle, toNiceDomain} from '../../../lib/strings' 23 - import {useStores, RootStoreModel, DEFAULT_SERVICE} from '../../../state' 24 - import {ServiceDescription} from '../../../state/models/session' 25 - import {ServerInputModal} from '../../../state/models/shell-ui' 26 - import {AccountData} from '../../../state/models/session' 27 - import {isNetworkError} from '../../../lib/errors' 28 - import {usePalette} from '../../lib/hooks/usePalette' 21 + import {s, colors} from 'lib/styles' 22 + import {createFullHandle} from 'lib/strings/handles' 23 + import {toNiceDomain} from 'lib/strings/url-helpers' 24 + import {useStores, RootStoreModel, DEFAULT_SERVICE} from 'state/index' 25 + import {ServiceDescription} from 'state/models/session' 26 + import {ServerInputModal} from 'state/models/shell-ui' 27 + import {AccountData} from 'state/models/session' 28 + import {isNetworkError} from 'lib/strings/errors' 29 + import {usePalette} from 'lib/hooks/usePalette' 30 + import {cleanError} from 'lib/strings/errors' 29 31 30 32 enum Forms { 31 33 Login, ··· 38 40 export const Signin = ({onPressBack}: {onPressBack: () => void}) => { 39 41 const pal = usePalette('default') 40 42 const store = useStores() 43 + const {track} = useAnalytics() 41 44 const [error, setError] = useState<string>('') 42 45 const [retryDescribeTrigger, setRetryDescribeTrigger] = useState<any>({}) 43 46 const [serviceUrl, setServiceUrl] = useState<string>(DEFAULT_SERVICE) ··· 91 94 }, [store.session, store.log, serviceUrl, retryDescribeTrigger]) 92 95 93 96 const onPressRetryConnect = () => setRetryDescribeTrigger({}) 97 + const onPressForgotPassword = () => { 98 + track('Signin:PressedForgotPassword') 99 + setCurrentForm(Forms.ForgotPassword) 100 + } 94 101 95 102 return ( 96 103 <KeyboardAvoidingView testID="signIn" behavior="padding" style={[pal.view]}> ··· 104 111 setError={setError} 105 112 setServiceUrl={setServiceUrl} 106 113 onPressBack={onPressBack} 107 - onPressForgotPassword={gotoForm(Forms.ForgotPassword)} 114 + onPressForgotPassword={onPressForgotPassword} 108 115 onPressRetryConnect={onPressRetryConnect} 109 116 /> 110 117 ) : undefined} ··· 153 160 onSelectAccount: (account?: AccountData) => void 154 161 onPressBack: () => void 155 162 }) => { 156 - // const {track} = useAnalytics() TODO 163 + const {track, screen} = useAnalytics() 157 164 const pal = usePalette('default') 158 165 const [isProcessing, setIsProcessing] = React.useState(false) 159 166 167 + // React.useEffect(() => { 168 + screen('Choose Account') 169 + // }, [screen]) 170 + 160 171 const onTryAccount = async (account: AccountData) => { 161 172 if (account.accessJwt && account.refreshJwt) { 162 173 setIsProcessing(true) 163 174 if (await store.session.resumeSession(account)) { 164 - // track('Sign In', {resumedSession: true}) TODO 175 + track('Sign In', {resumedSession: true}) 165 176 setIsProcessing(false) 166 177 return 167 178 } ··· 261 272 onPressBack: () => void 262 273 onPressForgotPassword: () => void 263 274 }) => { 264 - // const {track} = useAnalytics() TODO 275 + const {track} = useAnalytics() 265 276 const pal = usePalette('default') 266 277 const [isProcessing, setIsProcessing] = useState<boolean>(false) 267 - const [handle, setHandle] = useState<string>(initialHandle) 278 + const [identifier, setIdentifier] = useState<string>(initialHandle) 268 279 const [password, setPassword] = useState<string>('') 269 280 270 281 const onPressSelectService = () => { 271 282 store.shell.openModal(new ServerInputModal(serviceUrl, setServiceUrl)) 272 283 Keyboard.dismiss() 284 + track('Signin:PressedSelectService') 273 285 } 274 286 275 287 const onPressNext = async () => { ··· 278 290 279 291 try { 280 292 // try to guess the handle if the user just gave their own username 281 - let fullHandle = handle 293 + let fullIdent = identifier 282 294 if ( 295 + !identifier.includes('@') && // not an email 283 296 serviceDescription && 284 297 serviceDescription.availableUserDomains.length > 0 285 298 ) { 286 299 let matched = false 287 300 for (const domain of serviceDescription.availableUserDomains) { 288 - if (fullHandle.endsWith(domain)) { 301 + if (fullIdent.endsWith(domain)) { 289 302 matched = true 290 303 } 291 304 } 292 305 if (!matched) { 293 - fullHandle = createFullHandle( 294 - handle, 306 + fullIdent = createFullHandle( 307 + identifier, 295 308 serviceDescription.availableUserDomains[0], 296 309 ) 297 310 } ··· 299 312 300 313 await store.session.login({ 301 314 service: serviceUrl, 302 - handle: fullHandle, 315 + identifier: fullIdent, 303 316 password, 304 317 }) 305 - // track('Sign In', {resumedSession: false}) TODO 318 + track('Sign In', {resumedSession: false}) 306 319 } catch (e: any) { 307 320 const errMsg = e.toString() 308 321 store.log.warn('Failed to login', e) ··· 314 327 'Unable to contact your service. Please check your Internet connection.', 315 328 ) 316 329 } else { 317 - setError(errMsg.replace(/^Error:/, '')) 330 + setError(cleanError(errMsg)) 318 331 } 319 332 } 320 333 } 321 334 322 - const isReady = !!serviceDescription && !!handle && !!password 335 + const isReady = !!serviceDescription && !!identifier && !!password 323 336 return ( 324 337 <View testID="loginForm"> 325 338 <LogoTextHero /> ··· 361 374 <TextInput 362 375 testID="loginUsernameInput" 363 376 style={[pal.text, styles.textInput]} 364 - placeholder="Username" 377 + placeholder="Username or email address" 365 378 placeholderTextColor={pal.colors.textLight} 366 379 autoCapitalize="none" 367 380 autoFocus 368 381 autoCorrect={false} 369 - value={handle} 370 - onChangeText={str => setHandle((str || '').toLowerCase())} 382 + value={identifier} 383 + onChangeText={str => setIdentifier((str || '').toLowerCase())} 371 384 editable={!isProcessing} 372 385 /> 373 386 </View> ··· 464 477 const pal = usePalette('default') 465 478 const [isProcessing, setIsProcessing] = useState<boolean>(false) 466 479 const [email, setEmail] = useState<string>('') 480 + const {screen} = useAnalytics() 481 + 482 + // useEffect(() => { 483 + screen('Signin:ForgotPassword') 484 + // }, [screen]) 467 485 468 486 const onPressSelectService = () => { 469 487 store.shell.openModal(new ServerInputModal(serviceUrl, setServiceUrl)) ··· 478 496 setIsProcessing(true) 479 497 480 498 try { 481 - const api = AtpApi.service(serviceUrl) as SessionServiceClient 482 - await api.com.atproto.account.requestPasswordReset({email}) 499 + const agent = new AtpAgent({service: serviceUrl}) 500 + await agent.api.com.atproto.account.requestPasswordReset({email}) 483 501 onEmailSent() 484 502 } catch (e: any) { 485 503 const errMsg = e.toString() ··· 490 508 'Unable to contact your service. Please check your Internet connection.', 491 509 ) 492 510 } else { 493 - setError(errMsg.replace(/^Error:/, '')) 511 + setError(cleanError(errMsg)) 494 512 } 495 513 } 496 514 } ··· 604 622 onPasswordSet: () => void 605 623 }) => { 606 624 const pal = usePalette('default') 625 + const {screen} = useAnalytics() 626 + 627 + // useEffect(() => { 628 + screen('Signin:SetNewPasswordForm') 629 + // }, [screen]) 630 + 607 631 const [isProcessing, setIsProcessing] = useState<boolean>(false) 608 632 const [resetCode, setResetCode] = useState<string>('') 609 633 const [password, setPassword] = useState<string>('') ··· 613 637 setIsProcessing(true) 614 638 615 639 try { 616 - const api = AtpApi.service(serviceUrl) as SessionServiceClient 617 - await api.com.atproto.account.resetPassword({token: resetCode, password}) 640 + const agent = new AtpAgent({service: serviceUrl}) 641 + await agent.api.com.atproto.account.resetPassword({ 642 + token: resetCode, 643 + password, 644 + }) 618 645 onPasswordSet() 619 646 } catch (e: any) { 620 647 const errMsg = e.toString() ··· 625 652 'Unable to contact your service. Please check your Internet connection.', 626 653 ) 627 654 } else { 628 - setError(errMsg.replace(/^Error:/, '')) 655 + setError(cleanError(errMsg)) 629 656 } 630 657 } 631 658 } ··· 726 753 } 727 754 728 755 const PasswordUpdatedForm = ({onPressNext}: {onPressNext: () => void}) => { 756 + const {screen} = useAnalytics() 757 + 758 + // useEffect(() => { 759 + screen('Signin:PasswordUpdatedForm') 760 + // }, [screen]) 761 + 729 762 const pal = usePalette('default') 730 763 return ( 731 764 <>
+4 -3
src/view/com/modals/Confirm.tsx
··· 7 7 } from 'react-native' 8 8 import LinearGradient from 'react-native-linear-gradient' 9 9 import {Text} from '../util/text/Text' 10 - import {useStores} from '../../../state' 11 - import {s, colors, gradients} from '../../lib/styles' 10 + import {useStores} from 'state/index' 11 + import {s, colors, gradients} from 'lib/styles' 12 12 import {ErrorMessage} from '../util/error/ErrorMessage' 13 + import {cleanError} from 'lib/strings/errors' 13 14 14 15 export const snapPoints = ['50%'] 15 16 ··· 33 34 store.shell.closeModal() 34 35 return 35 36 } catch (e: any) { 36 - setError(e.toString()) 37 + setError(cleanError(e)) 37 38 setIsProcessing(false) 38 39 } 39 40 }
+210
src/view/com/modals/DeleteAccount.tsx
··· 1 + import React from 'react' 2 + import { 3 + ActivityIndicator, 4 + StyleSheet, 5 + TouchableOpacity, 6 + View, 7 + } from 'react-native' 8 + import {BottomSheetTextInput} from '@gorhom/bottom-sheet' 9 + import LinearGradient from 'react-native-linear-gradient' 10 + import * as Toast from '../util/Toast' 11 + import {Text} from '../util/text/Text' 12 + import {useStores} from 'state/index' 13 + import {s, colors, gradients} from 'lib/styles' 14 + import {usePalette} from 'lib/hooks/usePalette' 15 + import {ErrorMessage} from '../util/error/ErrorMessage' 16 + import {cleanError} from 'lib/strings/errors' 17 + 18 + export const snapPoints = ['60%'] 19 + 20 + export function Component({}: {}) { 21 + const pal = usePalette('default') 22 + const store = useStores() 23 + const [isEmailSent, setIsEmailSent] = React.useState<boolean>(false) 24 + const [confirmCode, setConfirmCode] = React.useState<string>('') 25 + const [password, setPassword] = React.useState<string>('') 26 + const [isProcessing, setIsProcessing] = React.useState<boolean>(false) 27 + const [error, setError] = React.useState<string>('') 28 + const onPressSendEmail = async () => { 29 + setError('') 30 + setIsProcessing(true) 31 + try { 32 + await store.api.com.atproto.account.requestDelete() 33 + setIsEmailSent(true) 34 + } catch (e: any) { 35 + setError(cleanError(e)) 36 + } 37 + setIsProcessing(false) 38 + } 39 + const onPressConfirmDelete = async () => { 40 + setError('') 41 + setIsProcessing(true) 42 + try { 43 + await store.api.com.atproto.account.delete({ 44 + did: store.me.did, 45 + password, 46 + token: confirmCode, 47 + }) 48 + Toast.show('Your account has been deleted') 49 + store.nav.tab.fixedTabReset() 50 + store.session.clear() 51 + store.shell.closeModal() 52 + } catch (e: any) { 53 + setError(cleanError(e)) 54 + } 55 + setIsProcessing(false) 56 + } 57 + const onCancel = () => { 58 + store.shell.closeModal() 59 + } 60 + return ( 61 + <View 62 + style={[styles.container, {backgroundColor: pal.colors.backgroundLight}]}> 63 + <View style={[styles.innerContainer, pal.view]}> 64 + <Text type="title-xl" style={[styles.title, pal.text]}> 65 + Delete account 66 + </Text> 67 + {!isEmailSent ? ( 68 + <> 69 + <Text type="lg" style={[styles.description, pal.text]}> 70 + For security reasons, we'll need to send a confirmation code to 71 + your email. 72 + </Text> 73 + {error ? ( 74 + <View style={s.mt10}> 75 + <ErrorMessage message={error} /> 76 + </View> 77 + ) : undefined} 78 + {isProcessing ? ( 79 + <View style={[styles.btn, s.mt10]}> 80 + <ActivityIndicator /> 81 + </View> 82 + ) : ( 83 + <> 84 + <TouchableOpacity 85 + style={styles.mt20} 86 + onPress={onPressSendEmail}> 87 + <LinearGradient 88 + colors={[ 89 + gradients.blueLight.start, 90 + gradients.blueLight.end, 91 + ]} 92 + start={{x: 0, y: 0}} 93 + end={{x: 1, y: 1}} 94 + style={[styles.btn]}> 95 + <Text type="button-lg" style={[s.white, s.bold]}> 96 + Send email 97 + </Text> 98 + </LinearGradient> 99 + </TouchableOpacity> 100 + <TouchableOpacity 101 + style={[styles.btn, s.mt10]} 102 + onPress={onCancel}> 103 + <Text type="button-lg" style={pal.textLight}> 104 + Cancel 105 + </Text> 106 + </TouchableOpacity> 107 + </> 108 + )} 109 + </> 110 + ) : ( 111 + <> 112 + <Text type="lg" style={styles.description}> 113 + Check your inbox for an email with the confirmation code to enter 114 + below: 115 + </Text> 116 + <BottomSheetTextInput 117 + style={[styles.textInput, pal.borderDark, pal.text, styles.mb20]} 118 + placeholder="Confirmation code" 119 + placeholderTextColor={pal.textLight.color} 120 + value={confirmCode} 121 + onChangeText={setConfirmCode} 122 + /> 123 + <Text type="lg" style={styles.description}> 124 + Please enter your password as well: 125 + </Text> 126 + <BottomSheetTextInput 127 + style={[styles.textInput, pal.borderDark, pal.text]} 128 + placeholder="Password" 129 + placeholderTextColor={pal.textLight.color} 130 + secureTextEntry 131 + value={password} 132 + onChangeText={setPassword} 133 + /> 134 + {error ? ( 135 + <View style={styles.mt20}> 136 + <ErrorMessage message={error} /> 137 + </View> 138 + ) : undefined} 139 + {isProcessing ? ( 140 + <View style={[styles.btn, s.mt10]}> 141 + <ActivityIndicator /> 142 + </View> 143 + ) : ( 144 + <> 145 + <TouchableOpacity 146 + style={[styles.btn, styles.evilBtn, styles.mt20]} 147 + onPress={onPressConfirmDelete}> 148 + <Text type="button-lg" style={[s.white, s.bold]}> 149 + Delete my account 150 + </Text> 151 + </TouchableOpacity> 152 + <TouchableOpacity 153 + style={[styles.btn, s.mt10]} 154 + onPress={onCancel}> 155 + <Text type="button-lg" style={pal.textLight}> 156 + Cancel 157 + </Text> 158 + </TouchableOpacity> 159 + </> 160 + )} 161 + </> 162 + )} 163 + </View> 164 + </View> 165 + ) 166 + } 167 + 168 + const styles = StyleSheet.create({ 169 + container: { 170 + flex: 1, 171 + }, 172 + innerContainer: { 173 + paddingBottom: 20, 174 + }, 175 + title: { 176 + textAlign: 'center', 177 + marginTop: 12, 178 + marginBottom: 12, 179 + }, 180 + description: { 181 + textAlign: 'center', 182 + paddingHorizontal: 22, 183 + marginBottom: 10, 184 + }, 185 + mt20: { 186 + marginTop: 20, 187 + }, 188 + mb20: { 189 + marginBottom: 20, 190 + }, 191 + textInput: { 192 + borderWidth: 1, 193 + borderRadius: 6, 194 + paddingHorizontal: 16, 195 + paddingVertical: 12, 196 + fontSize: 20, 197 + marginHorizontal: 20, 198 + }, 199 + btn: { 200 + flexDirection: 'row', 201 + alignItems: 'center', 202 + justifyContent: 'center', 203 + borderRadius: 32, 204 + padding: 14, 205 + marginHorizontal: 20, 206 + }, 207 + evilBtn: { 208 + backgroundColor: colors.red4, 209 + }, 210 + })
+28 -23
src/view/com/modals/EditProfile.tsx
··· 11 11 import {PickedMedia} from '../util/images/image-crop-picker/ImageCropPicker' 12 12 import {Text} from '../util/text/Text' 13 13 import {ErrorMessage} from '../util/error/ErrorMessage' 14 - import {useStores} from '../../../state' 15 - import {ProfileViewModel} from '../../../state/models/profile-view' 16 - import {s, colors, gradients} from '../../lib/styles' 17 - import { 18 - enforceLen, 19 - MAX_DISPLAY_NAME, 20 - MAX_DESCRIPTION, 21 - } from '../../../lib/strings' 22 - import {isNetworkError} from '../../../lib/errors' 23 - import {compressIfNeeded} from '../../../lib/images' 14 + import {useStores} from 'state/index' 15 + import {ProfileViewModel} from 'state/models/profile-view' 16 + import {s, colors, gradients} from 'lib/styles' 17 + import {enforceLen} from 'lib/strings/helpers' 18 + import {MAX_DISPLAY_NAME, MAX_DESCRIPTION} from 'lib/constants' 19 + import {compressIfNeeded} from 'lib/images' 24 20 import {UserBanner} from '../util/UserBanner' 25 21 import {UserAvatar} from '../util/UserAvatar' 22 + import {usePalette} from 'lib/hooks/usePalette' 23 + import {useAnalytics} from 'lib/analytics' 24 + import {cleanError, isNetworkError} from 'lib/strings/errors' 26 25 27 26 export const snapPoints = ['80%'] 28 27 ··· 35 34 }) { 36 35 const store = useStores() 37 36 const [error, setError] = useState<string>('') 37 + const pal = usePalette('default') 38 + const {track} = useAnalytics() 39 + 38 40 const [isProcessing, setProcessing] = useState<boolean>(false) 39 41 const [displayName, setDisplayName] = useState<string>( 40 42 profileView.displayName || '', ··· 54 56 store.shell.closeModal() 55 57 } 56 58 const onSelectNewAvatar = async (img: PickedMedia) => { 59 + track('EditProfile:AvatarSelected') 57 60 try { 58 - const finalImg = await compressIfNeeded(img, 300000) 59 - setNewUserAvatar(finalImg) 61 + const finalImg = await compressIfNeeded(img, 1000000) 62 + setNewUserAvatar({mediaType: 'photo', ...finalImg}) 60 63 setUserAvatar(finalImg.path) 61 64 } catch (e: any) { 62 - setError(e.message || e.toString()) 65 + setError(cleanError(e)) 63 66 } 64 67 } 65 68 const onSelectNewBanner = async (img: PickedMedia) => { 69 + track('EditProfile:BannerSelected') 66 70 try { 67 - const finalImg = await compressIfNeeded(img, 500000) 68 - setNewUserBanner(finalImg) 71 + const finalImg = await compressIfNeeded(img, 1000000) 72 + setNewUserBanner({mediaType: 'photo', ...finalImg}) 69 73 setUserBanner(finalImg.path) 70 74 } catch (e: any) { 71 - setError(e.message || e.toString()) 75 + setError(cleanError(e)) 72 76 } 73 77 } 74 78 const onPressSave = async () => { 79 + track('EditProfile:Save') 75 80 setProcessing(true) 76 81 if (error) { 77 82 setError('') ··· 94 99 'Failed to save your profile. Check your internet connection and try again.', 95 100 ) 96 101 } else { 97 - setError(e.message) 102 + setError(cleanError(e)) 98 103 } 99 104 } 100 105 setProcessing(false) ··· 103 108 return ( 104 109 <View style={s.flex1}> 105 110 <ScrollView style={styles.inner}> 106 - <Text style={styles.title}>Edit my profile</Text> 111 + <Text style={[styles.title, pal.text]}>Edit my profile</Text> 107 112 <View style={styles.photos}> 108 113 <UserBanner 109 114 banner={userBanner} 110 115 onSelectNewBanner={onSelectNewBanner} 111 116 /> 112 - <View style={styles.avi}> 117 + <View style={[styles.avi, {borderColor: pal.colors.background}]}> 113 118 <UserAvatar 114 119 size={80} 115 120 avatar={userAvatar} ··· 127 132 <View> 128 133 <Text style={styles.label}>Display Name</Text> 129 134 <TextInput 130 - style={styles.textInput} 135 + style={[styles.textInput, pal.text]} 131 136 placeholder="e.g. Alice Roberts" 132 137 placeholderTextColor={colors.gray4} 133 138 value={displayName} ··· 135 140 /> 136 141 </View> 137 142 <View style={s.pb10}> 138 - <Text style={styles.label}>Description</Text> 143 + <Text style={[styles.label, pal.text]}>Description</Text> 139 144 <TextInput 140 - style={[styles.textArea]} 145 + style={[styles.textArea, pal.text]} 141 146 placeholder="e.g. Artist, dog-lover, and memelord." 142 147 placeholderTextColor={colors.gray4} 143 148 multiline ··· 162 167 )} 163 168 <TouchableOpacity style={s.mt5} onPress={onPressCancel}> 164 169 <View style={[styles.btn]}> 165 - <Text style={[s.black, s.bold]}>Cancel</Text> 170 + <Text style={[s.black, s.bold, pal.text]}>Cancel</Text> 166 171 </View> 167 172 </TouchableOpacity> 168 173 </ScrollView>
+28 -5
src/view/com/modals/Modal.tsx
··· 2 2 import {View} from 'react-native' 3 3 import {observer} from 'mobx-react-lite' 4 4 import BottomSheet from '@gorhom/bottom-sheet' 5 - import {useStores} from '../../../state' 5 + import {useStores} from 'state/index' 6 6 import {createCustomBackdrop} from '../util/BottomSheetCustomBackdrop' 7 7 8 - import * as models from '../../../state/models/shell-ui' 8 + import * as models from 'state/models/shell-ui' 9 9 10 10 import * as ConfirmModal from './Confirm' 11 11 import * as EditProfileModal from './EditProfile' 12 12 import * as ServerInputModal from './ServerInput' 13 13 import * as ReportPostModal from './ReportPost' 14 14 import * as ReportAccountModal from './ReportAccount' 15 + import * as DeleteAccountModal from './DeleteAccount' 16 + import {usePalette} from 'lib/hooks/usePalette' 17 + import {StyleSheet} from 'react-native' 15 18 16 19 const CLOSED_SNAPPOINTS = ['10%'] 17 20 18 21 export const Modal = observer(function Modal() { 19 22 const store = useStores() 20 23 const bottomSheetRef = useRef<BottomSheet>(null) 21 - 24 + const pal = usePalette('default') 22 25 const onBottomSheetChange = (snapPoint: number) => { 23 26 if (snapPoint === -1) { 24 27 store.shell.closeModal() ··· 62 65 ) 63 66 } else if (store.shell.activeModal?.name === 'report-post') { 64 67 snapPoints = ReportPostModal.snapPoints 65 - element = <ReportPostModal.Component /> 68 + element = ( 69 + <ReportPostModal.Component 70 + {...(store.shell.activeModal as models.ReportPostModal)} 71 + /> 72 + ) 66 73 } else if (store.shell.activeModal?.name === 'report-account') { 67 74 snapPoints = ReportAccountModal.snapPoints 68 - element = <ReportAccountModal.Component /> 75 + element = ( 76 + <ReportAccountModal.Component 77 + {...(store.shell.activeModal as models.ReportAccountModal)} 78 + /> 79 + ) 80 + } else if (store.shell.activeModal?.name === 'delete-account') { 81 + snapPoints = DeleteAccountModal.snapPoints 82 + element = <DeleteAccountModal.Component /> 69 83 } else { 70 84 element = <View /> 71 85 } ··· 80 94 backdropComponent={ 81 95 store.shell.isModalActive ? createCustomBackdrop(onClose) : undefined 82 96 } 97 + handleIndicatorStyle={{backgroundColor: pal.text.color}} 98 + handleStyle={[styles.handle, pal.view]} 83 99 onChange={onBottomSheetChange}> 84 100 {element} 85 101 </BottomSheet> 86 102 ) 87 103 }) 104 + 105 + const styles = StyleSheet.create({ 106 + handle: { 107 + borderTopLeftRadius: 10, 108 + borderTopRightRadius: 10, 109 + }, 110 + })
+13 -5
src/view/com/modals/Modal.web.tsx
··· 1 1 import React from 'react' 2 2 import {TouchableWithoutFeedback, StyleSheet, View} from 'react-native' 3 3 import {observer} from 'mobx-react-lite' 4 - import {useStores} from '../../../state' 5 - import {usePalette} from '../../lib/hooks/usePalette' 4 + import {useStores} from 'state/index' 5 + import {usePalette} from 'lib/hooks/usePalette' 6 6 7 - import * as models from '../../../state/models/shell-ui' 7 + import * as models from 'state/models/shell-ui' 8 8 9 9 import * as ConfirmModal from './Confirm' 10 10 import * as EditProfileModal from './EditProfile' ··· 48 48 /> 49 49 ) 50 50 } else if (store.shell.activeModal?.name === 'report-post') { 51 - element = <ReportPostModal.Component /> 51 + element = ( 52 + <ReportPostModal.Component 53 + {...(store.shell.activeModal as models.ReportPostModal)} 54 + /> 55 + ) 52 56 } else if (store.shell.activeModal?.name === 'report-account') { 53 - element = <ReportAccountModal.Component /> 57 + element = ( 58 + <ReportAccountModal.Component 59 + {...(store.shell.activeModal as models.ReportAccountModal)} 60 + /> 61 + ) 54 62 } else if (store.shell.activeModal?.name === 'crop-image') { 55 63 element = ( 56 64 <CropImageModal.Component
+25 -5
src/view/com/modals/ReportAccount.tsx
··· 5 5 TouchableOpacity, 6 6 View, 7 7 } from 'react-native' 8 + import {ComAtprotoReportReasonType} from '@atproto/api' 8 9 import LinearGradient from 'react-native-linear-gradient' 9 - import {useStores} from '../../../state' 10 - import {s, colors, gradients} from '../../lib/styles' 10 + import {useStores} from 'state/index' 11 + import {s, colors, gradients} from 'lib/styles' 11 12 import {RadioGroup, RadioGroupItem} from '../util/forms/RadioGroup' 12 13 import {Text} from '../util/text/Text' 14 + import * as Toast from '../util/Toast' 13 15 import {ErrorMessage} from '../util/error/ErrorMessage' 16 + import {cleanError} from 'lib/strings/errors' 14 17 15 18 const ITEMS: RadioGroupItem[] = [ 16 19 {key: 'spam', label: 'Spam or excessive repeat posts'}, ··· 20 23 21 24 export const snapPoints = ['50%'] 22 25 23 - export function Component() { 26 + export function Component({did}: {did: string}) { 24 27 const store = useStores() 25 28 const [isProcessing, setIsProcessing] = useState<boolean>(false) 26 29 const [error, setError] = useState<string>('') ··· 28 31 const onSelectIssue = (v: string) => setIssue(v) 29 32 const onPress = async () => { 30 33 setError('') 34 + if (!issue) { 35 + return 36 + } 31 37 setIsProcessing(true) 32 38 try { 33 - // TODO 39 + // NOTE: we should update the lexicon of reasontype to include more options -prf 40 + let reasonType = ComAtprotoReportReasonType.OTHER 41 + if (issue === 'spam') { 42 + reasonType = ComAtprotoReportReasonType.SPAM 43 + } 44 + const reason = ITEMS.find(item => item.key === issue)?.label || '' 45 + await store.api.com.atproto.report.create({ 46 + reasonType, 47 + reason, 48 + subject: { 49 + $type: 'com.atproto.repo.repoRef', 50 + did, 51 + }, 52 + }) 53 + Toast.show("Thank you for your report! We'll look into it promptly.") 34 54 store.shell.closeModal() 35 55 return 36 56 } catch (e: any) { 37 - setError(e.toString()) 57 + setError(cleanError(e)) 38 58 setIsProcessing(false) 39 59 } 40 60 }
+32 -5
src/view/com/modals/ReportPost.tsx
··· 5 5 TouchableOpacity, 6 6 View, 7 7 } from 'react-native' 8 + import {ComAtprotoReportReasonType} from '@atproto/api' 8 9 import LinearGradient from 'react-native-linear-gradient' 9 - import {useStores} from '../../../state' 10 - import {s, colors, gradients} from '../../lib/styles' 10 + import {useStores} from 'state/index' 11 + import {s, colors, gradients} from 'lib/styles' 11 12 import {RadioGroup, RadioGroupItem} from '../util/forms/RadioGroup' 12 13 import {Text} from '../util/text/Text' 14 + import * as Toast from '../util/Toast' 13 15 import {ErrorMessage} from '../util/error/ErrorMessage' 16 + import {cleanError} from 'lib/strings/errors' 14 17 15 18 const ITEMS: RadioGroupItem[] = [ 16 19 {key: 'spam', label: 'Spam or excessive repeat posts'}, ··· 21 24 22 25 export const snapPoints = ['50%'] 23 26 24 - export function Component() { 27 + export function Component({ 28 + postUri, 29 + postCid, 30 + }: { 31 + postUri: string 32 + postCid: string 33 + }) { 25 34 const store = useStores() 26 35 const [isProcessing, setIsProcessing] = useState<boolean>(false) 27 36 const [error, setError] = useState<string>('') ··· 29 38 const onSelectIssue = (v: string) => setIssue(v) 30 39 const onPress = async () => { 31 40 setError('') 41 + if (!issue) { 42 + return 43 + } 32 44 setIsProcessing(true) 33 45 try { 34 - // TODO 46 + // NOTE: we should update the lexicon of reasontype to include more options -prf 47 + let reasonType = ComAtprotoReportReasonType.OTHER 48 + if (issue === 'spam') { 49 + reasonType = ComAtprotoReportReasonType.SPAM 50 + } 51 + const reason = ITEMS.find(item => item.key === issue)?.label || '' 52 + await store.api.com.atproto.report.create({ 53 + reasonType, 54 + reason, 55 + subject: { 56 + $type: 'com.atproto.repo.recordRef', 57 + uri: postUri, 58 + cid: postCid, 59 + }, 60 + }) 61 + Toast.show("Thank you for your report! We'll look into it promptly.") 35 62 store.shell.closeModal() 36 63 return 37 64 } catch (e: any) { 38 - setError(e.toString()) 65 + setError(cleanError(e)) 39 66 setIsProcessing(false) 40 67 } 41 68 }
+5 -8
src/view/com/modals/ServerInput.tsx
··· 6 6 } from '@fortawesome/react-native-fontawesome' 7 7 import {ScrollView, TextInput} from './util' 8 8 import {Text} from '../util/text/Text' 9 - import {useStores} from '../../../state' 10 - import {s, colors} from '../../lib/styles' 11 - import { 12 - LOCAL_DEV_SERVICE, 13 - STAGING_SERVICE, 14 - PROD_SERVICE, 15 - } from '../../../state/index' 16 - import {LOGIN_INCLUDE_DEV_SERVERS} from '../../../build-flags' 9 + import {useStores} from 'state/index' 10 + import {s, colors} from 'lib/styles' 11 + import {LOCAL_DEV_SERVICE, STAGING_SERVICE, PROD_SERVICE} from 'state/index' 12 + import {LOGIN_INCLUDE_DEV_SERVERS} from 'lib/build-flags' 17 13 18 14 export const snapPoints = ['80%'] 19 15 ··· 37 33 {LOGIN_INCLUDE_DEV_SERVERS ? ( 38 34 <> 39 35 <TouchableOpacity 36 + testID="localDevServerButton" 40 37 style={styles.btn} 41 38 onPress={() => doSelect(LOCAL_DEV_SERVICE)}> 42 39 <Text style={styles.btnText}>Local dev server</Text>
+4 -4
src/view/com/modals/crop-image/CropImage.web.tsx
··· 5 5 import LinearGradient from 'react-native-linear-gradient' 6 6 import {Text} from '../../util/text/Text' 7 7 import {PickedMedia} from '../../util/images/image-crop-picker/types' 8 - import {s, gradients} from '../../../lib/styles' 9 - import {useStores} from '../../../../state' 10 - import {usePalette} from '../../../lib/hooks/usePalette' 11 - import {SquareIcon, RectWideIcon, RectTallIcon} from '../../../lib/icons' 8 + import {s, gradients} from 'lib/styles' 9 + import {useStores} from 'state/index' 10 + import {usePalette} from 'lib/hooks/usePalette' 11 + import {SquareIcon, RectWideIcon, RectTallIcon} from 'lib/icons' 12 12 13 13 enum AspectRatio { 14 14 Square = 'square',
+53 -29
src/view/com/notifications/Feed.tsx
··· 1 - import React from 'react' 1 + import React, {MutableRefObject} from 'react' 2 2 import {observer} from 'mobx-react-lite' 3 - import {StyleSheet, View} from 'react-native' 4 3 import {CenteredView, FlatList} from '../util/Views' 5 - import {NotificationsViewModel} from '../../../state/models/notifications-view' 4 + import {ActivityIndicator, StyleSheet, View} from 'react-native' 5 + import {NotificationsViewModel} from 'state/models/notifications-view' 6 6 import {FeedItem} from './FeedItem' 7 7 import {NotificationFeedLoadingPlaceholder} from '../util/LoadingPlaceholder' 8 8 import {ErrorMessage} from '../util/error/ErrorMessage' 9 9 import {EmptyState} from '../util/EmptyState' 10 - import {OnScrollCb} from '../../lib/hooks/useOnMainScroll' 11 - import {s} from '../../lib/styles' 10 + import {OnScrollCb} from 'lib/hooks/useOnMainScroll' 11 + import {s} from 'lib/styles' 12 12 13 13 const EMPTY_FEED_ITEM = {_reactKey: '__empty__'} 14 14 15 15 export const Feed = observer(function Feed({ 16 16 view, 17 + scrollElRef, 17 18 onPressTryAgain, 18 19 onScroll, 19 20 }: { 20 21 view: NotificationsViewModel 22 + scrollElRef?: MutableRefObject<FlatList<any> | null> 21 23 onPressTryAgain?: () => void 22 24 onScroll?: OnScrollCb 23 25 }) { 26 + const data = React.useMemo(() => { 27 + let feedItems 28 + if (view.hasLoaded) { 29 + if (view.isEmpty) { 30 + feedItems = [EMPTY_FEED_ITEM] 31 + } else { 32 + feedItems = view.notifications 33 + } 34 + } 35 + return feedItems 36 + }, [view.hasLoaded, view.isEmpty, view.notifications]) 37 + 38 + const onRefresh = React.useCallback(async () => { 39 + try { 40 + await view.refresh() 41 + await view.markAllRead() 42 + } catch (err) { 43 + view.rootStore.log.error('Failed to refresh notifications feed', err) 44 + } 45 + }, [view]) 46 + const onEndReached = React.useCallback(async () => { 47 + try { 48 + await view.loadMore() 49 + } catch (err) { 50 + view.rootStore.log.error('Failed to load more notifications', err) 51 + } 52 + }, [view]) 53 + 24 54 // TODO optimize renderItem or FeedItem, we're getting this notice from RN: -prf 25 55 // VirtualizedList: You have a large list that is slow to update - make sure your 26 56 // renderItem function renders components that follow React performance best practices 27 57 // like PureComponent, shouldComponentUpdate, etc 28 - const renderItem = ({item}: {item: any}) => { 58 + const renderItem = React.useCallback(({item}: {item: any}) => { 29 59 if (item === EMPTY_FEED_ITEM) { 30 60 return ( 31 61 <EmptyState ··· 36 66 ) 37 67 } 38 68 return <FeedItem item={item} /> 39 - } 40 - const onRefresh = () => { 41 - view 42 - .refresh() 43 - .catch(err => 44 - view.rootStore.log.error('Failed to refresh notifications feed', err), 45 - ) 46 - } 47 - const onEndReached = () => { 48 - view 49 - .loadMore() 50 - .catch(err => 51 - view.rootStore.log.error('Failed to load more notifications', err), 52 - ) 53 - } 54 - let data 55 - if (view.hasLoaded) { 56 - if (view.isEmpty) { 57 - data = [EMPTY_FEED_ITEM] 58 - } else { 59 - data = view.notifications 60 - } 61 - } 69 + }, []) 70 + 71 + const FeedFooter = React.useCallback( 72 + () => 73 + view.isLoading ? ( 74 + <View style={styles.feedFooter}> 75 + <ActivityIndicator /> 76 + </View> 77 + ) : ( 78 + <View /> 79 + ), 80 + [view], 81 + ) 82 + 62 83 return ( 63 84 <View style={s.h100pct}> 64 85 <CenteredView> ··· 72 93 </CenteredView> 73 94 {data && ( 74 95 <FlatList 96 + ref={scrollElRef} 75 97 data={data} 76 98 keyExtractor={item => item._reactKey} 77 99 renderItem={renderItem} 100 + ListFooterComponent={FeedFooter} 78 101 refreshing={view.isRefreshing} 79 102 onRefresh={onRefresh} 80 103 onEndReached={onEndReached} ··· 87 110 }) 88 111 89 112 const styles = StyleSheet.create({ 113 + feedFooter: {paddingTop: 20}, 90 114 emptyState: {paddingVertical: 40}, 91 115 })
+17 -12
src/view/com/notifications/FeedItem.tsx
··· 14 14 FontAwesomeIconStyle, 15 15 Props, 16 16 } from '@fortawesome/react-native-fontawesome' 17 - import {NotificationsViewItemModel} from '../../../state/models/notifications-view' 18 - import {PostThreadViewModel} from '../../../state/models/post-thread-view' 19 - import {s, colors} from '../../lib/styles' 20 - import {ago, pluralize} from '../../../lib/strings' 21 - import {HeartIconSolid} from '../../lib/icons' 17 + import {NotificationsViewItemModel} from 'state/models/notifications-view' 18 + import {PostThreadViewModel} from 'state/models/post-thread-view' 19 + import {s, colors} from 'lib/styles' 20 + import {ago} from 'lib/strings/time' 21 + import {pluralize} from 'lib/strings/helpers' 22 + import {HeartIconSolid} from 'lib/icons' 22 23 import {Text} from '../util/text/Text' 23 24 import {UserAvatar} from '../util/UserAvatar' 24 25 import {ImageHorzList} from '../util/images/ImageHorzList' 25 - import {ErrorMessage} from '../util/error/ErrorMessage' 26 26 import {Post} from '../post/Post' 27 27 import {Link} from '../util/Link' 28 - import {usePalette} from '../../lib/hooks/usePalette' 29 - import {useAnimatedValue} from '../../lib/hooks/useAnimatedValue' 28 + import {usePalette} from 'lib/hooks/usePalette' 29 + import {useAnimatedValue} from 'lib/hooks/useAnimatedValue' 30 30 31 31 const MAX_AUTHORS = 5 32 32 ··· 78 78 } 79 79 80 80 if (item.isReply || item.isMention) { 81 + if (item.additionalPost?.error) { 82 + // hide errors - it doesnt help the user to show them 83 + return <View /> 84 + } 81 85 return ( 82 86 <Link href={itemHref} title={itemTitle} noFeedback> 83 87 <Post ··· 347 351 additionalPost?: PostThreadViewModel 348 352 }) { 349 353 const pal = usePalette('default') 350 - if (!additionalPost || !additionalPost.thread?.postRecord) { 354 + if ( 355 + !additionalPost || 356 + !additionalPost.thread?.postRecord || 357 + additionalPost.error 358 + ) { 351 359 return <View /> 352 - } 353 - if (additionalPost.error) { 354 - return <ErrorMessage message={additionalPost.error} /> 355 360 } 356 361 const text = additionalPost.thread?.postRecord.text 357 362 const images = (
+10 -6
src/view/com/onboard/FeatureExplainer.tsx
··· 14 14 FontAwesomeIconStyle, 15 15 } from '@fortawesome/react-native-fontawesome' 16 16 import {Text} from '../util/text/Text' 17 - import {useStores} from '../../../state' 18 - import {s} from '../../lib/styles' 19 - import {TABS_EXPLAINER} from '../../lib/assets' 20 - import {TABS_ENABLED} from '../../../build-flags' 17 + import {useStores} from 'state/index' 18 + import {s} from 'lib/styles' 19 + import {TABS_EXPLAINER} from 'lib/assets' 20 + import {TABS_ENABLED} from 'lib/build-flags' 21 21 22 22 const ROUTES = TABS_ENABLED 23 23 ? [ ··· 127 127 <View /> 128 128 )} 129 129 <View style={styles.footer}> 130 - <TouchableOpacity onPress={onPressSkip}> 130 + <TouchableOpacity 131 + onPress={onPressSkip} 132 + testID="onboardFeatureExplainerSkipBtn"> 131 133 <Text style={[s.blue3, s.f18]}>Skip</Text> 132 134 </TouchableOpacity> 133 135 <View style={s.flex1} /> 134 - <TouchableOpacity onPress={onPressNext}> 136 + <TouchableOpacity 137 + onPress={onPressNext} 138 + testID="onboardFeatureExplainerNextBtn"> 135 139 <Text style={[s.blue3, s.f18]}>Next</Text> 136 140 </TouchableOpacity> 137 141 </View>
+4 -5
src/view/com/onboard/FeatureExplainer.web.tsx
··· 2 2 import { 3 3 Animated, 4 4 Image, 5 - SafeAreaView, 6 5 StyleSheet, 7 6 TouchableOpacity, 8 7 useWindowDimensions, ··· 15 14 } from '@fortawesome/react-native-fontawesome' 16 15 import {CenteredView} from '../util/Views.web' 17 16 import {Text} from '../util/text/Text' 18 - import {useStores} from '../../../state' 19 - import {s, colors} from '../../lib/styles' 20 - import {TABS_EXPLAINER} from '../../lib/assets' 21 - import {TABS_ENABLED} from '../../../build-flags' 17 + import {useStores} from 'state/index' 18 + import {s, colors} from 'lib/styles' 19 + import {TABS_EXPLAINER} from 'lib/assets' 20 + import {TABS_ENABLED} from 'lib/build-flags' 22 21 23 22 const ROUTES = TABS_ENABLED 24 23 ? [
+7 -5
src/view/com/onboard/Follows.tsx
··· 3 3 import {observer} from 'mobx-react-lite' 4 4 import {SuggestedFollows} from '../discover/SuggestedFollows' 5 5 import {Text} from '../util/text/Text' 6 - import {useStores} from '../../../state' 7 - import {s} from '../../lib/styles' 6 + import {useStores} from 'state/index' 7 + import {s} from 'lib/styles' 8 8 9 9 export const Follows = observer(() => { 10 10 const store = useStores() ··· 18 18 return ( 19 19 <SafeAreaView style={styles.container}> 20 20 <Text style={styles.title}>Suggested follows</Text> 21 - <SuggestedFollows onNoSuggestions={onNoSuggestions} /> 21 + <View style={s.flex1}> 22 + <SuggestedFollows onNoSuggestions={onNoSuggestions} /> 23 + </View> 22 24 <View style={styles.footer}> 23 - <TouchableOpacity onPress={onPressNext}> 25 + <TouchableOpacity onPress={onPressNext} testID="onboardFollowsSkipBtn"> 24 26 <Text style={[s.blue3, s.f18]}>Skip</Text> 25 27 </TouchableOpacity> 26 28 <View style={s.flex1} /> 27 - <TouchableOpacity onPress={onPressNext}> 29 + <TouchableOpacity onPress={onPressNext} testID="onboardFollowsNextBtn"> 28 30 <Text style={[s.blue3, s.f18]}>Next</Text> 29 31 </TouchableOpacity> 30 32 </View>
+3 -3
src/view/com/onboard/Follows.web.tsx
··· 1 1 import React from 'react' 2 - import {SafeAreaView, StyleSheet, TouchableOpacity, View} from 'react-native' 2 + import {SafeAreaView, StyleSheet, TouchableOpacity} from 'react-native' 3 3 import {observer} from 'mobx-react-lite' 4 4 import {SuggestedFollows} from '../discover/SuggestedFollows' 5 5 import {CenteredView} from '../util/Views.web' 6 6 import {Text} from '../util/text/Text' 7 - import {useStores} from '../../../state' 8 - import {s, colors} from '../../lib/styles' 7 + import {useStores} from 'state/index' 8 + import {s} from 'lib/styles' 9 9 10 10 export const Follows = observer(() => { 11 11 const store = useStores()
+12 -57
src/view/com/post-thread/PostRepostedBy.tsx
··· 5 5 import { 6 6 RepostedByViewModel, 7 7 RepostedByItem, 8 - } from '../../../state/models/reposted-by-view' 9 - import {UserAvatar} from '../util/UserAvatar' 8 + } from 'state/models/reposted-by-view' 9 + import {ProfileCardWithFollowBtn} from '../profile/ProfileCard' 10 10 import {ErrorMessage} from '../util/error/ErrorMessage' 11 - import {Link} from '../util/Link' 12 - import {Text} from '../util/text/Text' 13 - import {useStores} from '../../../state' 14 - import {s, colors} from '../../lib/styles' 11 + import {useStores} from 'state/index' 15 12 16 13 export const PostRepostedBy = observer(function PostRepostedBy({ 17 14 uri, ··· 62 59 // loaded 63 60 // = 64 61 const renderItem = ({item}: {item: RepostedByItem}) => ( 65 - <RepostedByItemCom item={item} /> 62 + <ProfileCardWithFollowBtn 63 + key={item.did} 64 + did={item.did} 65 + declarationCid={item.declaration.cid} 66 + handle={item.handle} 67 + displayName={item.displayName} 68 + avatar={item.avatar} 69 + isFollowedBy={!!item.viewer?.followedBy} 70 + /> 66 71 ) 67 72 return ( 68 73 <FlatList ··· 83 88 ) 84 89 }) 85 90 86 - const RepostedByItemCom = ({item}: {item: RepostedByItem}) => { 87 - return ( 88 - <Link 89 - style={styles.outer} 90 - href={`/profile/${item.handle}`} 91 - title={item.handle} 92 - noFeedback> 93 - <View style={styles.layout}> 94 - <View style={styles.layoutAvi}> 95 - <UserAvatar 96 - size={40} 97 - displayName={item.displayName} 98 - handle={item.handle} 99 - avatar={item.avatar} 100 - /> 101 - </View> 102 - <View style={styles.layoutContent}> 103 - <Text style={[s.f15, s.bold]}>{item.displayName || item.handle}</Text> 104 - <Text style={[s.f14, s.gray5]}>@{item.handle}</Text> 105 - </View> 106 - </View> 107 - </Link> 108 - ) 109 - } 110 - 111 91 const styles = StyleSheet.create({ 112 - outer: { 113 - marginTop: 1, 114 - backgroundColor: colors.white, 115 - }, 116 - layout: { 117 - flexDirection: 'row', 118 - }, 119 - layoutAvi: { 120 - width: 60, 121 - paddingLeft: 10, 122 - paddingTop: 10, 123 - paddingBottom: 10, 124 - }, 125 - avi: { 126 - width: 40, 127 - height: 40, 128 - borderRadius: 20, 129 - resizeMode: 'cover', 130 - }, 131 - layoutContent: { 132 - flex: 1, 133 - paddingRight: 10, 134 - paddingTop: 10, 135 - paddingBottom: 10, 136 - }, 137 92 footer: { 138 93 height: 200, 139 94 paddingTop: 20,
+37 -24
src/view/com/post-thread/PostThread.tsx
··· 1 1 import React, {useRef} from 'react' 2 2 import {observer} from 'mobx-react-lite' 3 - import {ActivityIndicator, View} from 'react-native' 3 + import {ActivityIndicator} from 'react-native' 4 4 import {CenteredView, FlatList} from '../util/Views' 5 5 import { 6 6 PostThreadViewModel, 7 7 PostThreadViewPostModel, 8 - } from '../../../state/models/post-thread-view' 8 + } from 'state/models/post-thread-view' 9 9 import {PostThreadItem} from './PostThreadItem' 10 10 import {ErrorMessage} from '../util/error/ErrorMessage' 11 - import {s} from '../../lib/styles' 11 + import {s} from 'lib/styles' 12 12 13 13 export const PostThread = observer(function PostThread({ 14 14 uri, ··· 18 18 view: PostThreadViewModel 19 19 }) { 20 20 const ref = useRef<FlatList>(null) 21 - const posts = view.thread ? Array.from(flattenThread(view.thread)) : [] 22 - const onRefresh = () => { 23 - view 24 - ?.refresh() 25 - .catch(err => 26 - view.rootStore.log.error('Failed to refresh posts thread', err), 27 - ) 28 - } 29 - const onLayout = () => { 21 + const [isRefreshing, setIsRefreshing] = React.useState(false) 22 + const posts = React.useMemo( 23 + () => (view.thread ? Array.from(flattenThread(view.thread)) : []), 24 + [view.thread], 25 + ) 26 + 27 + // events 28 + // = 29 + const onRefresh = React.useCallback(async () => { 30 + setIsRefreshing(true) 31 + try { 32 + view?.refresh() 33 + } catch (err) { 34 + view.rootStore.log.error('Failed to refresh posts thread', err) 35 + } 36 + setIsRefreshing(false) 37 + }, [view, setIsRefreshing]) 38 + const onLayout = React.useCallback(() => { 30 39 const index = posts.findIndex(post => post._isHighlightedPost) 31 40 if (index !== -1) { 32 41 ref.current?.scrollToIndex({ ··· 35 44 viewOffset: 40, 36 45 }) 37 46 } 38 - } 39 - const onScrollToIndexFailed = (info: { 40 - index: number 41 - highestMeasuredFrameIndex: number 42 - averageItemLength: number 43 - }) => { 44 - ref.current?.scrollToOffset({ 45 - animated: false, 46 - offset: info.averageItemLength * info.index, 47 - }) 48 - } 47 + }, [posts, ref]) 48 + const onScrollToIndexFailed = React.useCallback( 49 + (info: { 50 + index: number 51 + highestMeasuredFrameIndex: number 52 + averageItemLength: number 53 + }) => { 54 + ref.current?.scrollToOffset({ 55 + animated: false, 56 + offset: info.averageItemLength * info.index, 57 + }) 58 + }, 59 + [ref], 60 + ) 49 61 50 62 // loading 51 63 // = ··· 76 88 <FlatList 77 89 ref={ref} 78 90 data={posts} 91 + initialNumToRender={posts.length} 79 92 keyExtractor={item => item._reactKey} 80 93 renderItem={renderItem} 81 - refreshing={view.isRefreshing} 94 + refreshing={isRefreshing} 82 95 onRefresh={onRefresh} 83 96 onLayout={onLayout} 84 97 onScrollToIndexFailed={onScrollToIndexFailed}
+46 -30
src/view/com/post-thread/PostThreadItem.tsx
··· 1 - import React, {useMemo, useState} from 'react' 1 + import React from 'react' 2 2 import {observer} from 'mobx-react-lite' 3 3 import {StyleSheet, View} from 'react-native' 4 4 import Clipboard from '@react-native-clipboard/clipboard' ··· 7 7 FontAwesomeIcon, 8 8 FontAwesomeIconStyle, 9 9 } from '@fortawesome/react-native-fontawesome' 10 - import {PostThreadViewPostModel} from '../../../state/models/post-thread-view' 10 + import {PostThreadViewPostModel} from 'state/models/post-thread-view' 11 11 import {Link} from '../util/Link' 12 12 import {RichText} from '../util/text/RichText' 13 13 import {Text} from '../util/text/Text' 14 14 import {PostDropdownBtn} from '../util/forms/DropdownButton' 15 15 import * as Toast from '../util/Toast' 16 16 import {UserAvatar} from '../util/UserAvatar' 17 - import {s} from '../../lib/styles' 18 - import {ago, pluralize} from '../../../lib/strings' 19 - import {useStores} from '../../../state' 17 + import {s} from 'lib/styles' 18 + import {ago} from 'lib/strings/time' 19 + import {pluralize} from 'lib/strings/helpers' 20 + import {useStores} from 'state/index' 20 21 import {PostMeta} from '../util/PostMeta' 21 22 import {PostEmbeds} from '../util/PostEmbeds' 22 23 import {PostCtrls} from '../util/PostCtrls' 23 24 import {ErrorMessage} from '../util/error/ErrorMessage' 24 25 import {ComposePrompt} from '../composer/Prompt' 25 - import {usePalette} from '../../lib/hooks/usePalette' 26 + import {usePalette} from 'lib/hooks/usePalette' 26 27 27 28 const PARENT_REPLY_LINE_LENGTH = 8 28 29 ··· 35 36 }) { 36 37 const pal = usePalette('default') 37 38 const store = useStores() 38 - const [deleted, setDeleted] = useState(false) 39 + const [deleted, setDeleted] = React.useState(false) 39 40 const record = item.postRecord 40 41 const hasEngagement = item.post.upvoteCount || item.post.repostCount 41 42 42 - const itemHref = useMemo(() => { 43 + const itemUri = item.post.uri 44 + const itemCid = item.post.cid 45 + const itemHref = React.useMemo(() => { 43 46 const urip = new AtUri(item.post.uri) 44 47 return `/profile/${item.post.author.handle}/post/${urip.rkey}` 45 48 }, [item.post.uri, item.post.author.handle]) 46 49 const itemTitle = `Post by ${item.post.author.handle}` 47 50 const authorHref = `/profile/${item.post.author.handle}` 48 51 const authorTitle = item.post.author.handle 49 - const upvotesHref = useMemo(() => { 52 + const upvotesHref = React.useMemo(() => { 50 53 const urip = new AtUri(item.post.uri) 51 54 return `/profile/${item.post.author.handle}/post/${urip.rkey}/upvoted-by` 52 55 }, [item.post.uri, item.post.author.handle]) 53 56 const upvotesTitle = 'Likes on this post' 54 - const repostsHref = useMemo(() => { 57 + const repostsHref = React.useMemo(() => { 55 58 const urip = new AtUri(item.post.uri) 56 59 return `/profile/${item.post.author.handle}/post/${urip.rkey}/reposted-by` 57 60 }, [item.post.uri, item.post.author.handle]) 58 61 const repostsTitle = 'Reposts of this post' 59 62 60 - const onPressReply = () => { 63 + const onPressReply = React.useCallback(() => { 61 64 store.shell.openComposer({ 62 65 replyTo: { 63 66 uri: item.post.uri, ··· 71 74 }, 72 75 onPost: onPostReply, 73 76 }) 74 - } 75 - const onPressToggleRepost = () => { 76 - item 77 + }, [store, item, record, onPostReply]) 78 + const onPressToggleRepost = React.useCallback(() => { 79 + return item 77 80 .toggleRepost() 78 81 .catch(e => store.log.error('Failed to toggle repost', e)) 79 - } 80 - const onPressToggleUpvote = () => { 81 - item 82 + }, [item, store]) 83 + const onPressToggleUpvote = React.useCallback(() => { 84 + return item 82 85 .toggleUpvote() 83 86 .catch(e => store.log.error('Failed to toggle upvote', e)) 84 - } 85 - const onCopyPostText = () => { 87 + }, [item, store]) 88 + const onCopyPostText = React.useCallback(() => { 86 89 Clipboard.setString(record?.text || '') 87 90 Toast.show('Copied to clipboard') 88 - } 89 - const onDeletePost = () => { 91 + }, [record]) 92 + const onDeletePost = React.useCallback(() => { 90 93 item.delete().then( 91 94 () => { 92 95 setDeleted(true) ··· 97 100 Toast.show('Failed to delete post, please try again') 98 101 }, 99 102 ) 100 - } 103 + }, [item, store]) 101 104 102 105 if (!record) { 103 106 return <ErrorMessage message="Invalid or unsupported post record" /> ··· 154 157 <View style={s.flex1} /> 155 158 <PostDropdownBtn 156 159 style={styles.metaItem} 160 + itemUri={itemUri} 161 + itemCid={itemCid} 157 162 itemHref={itemHref} 158 163 itemTitle={itemTitle} 159 164 isAuthor={item.post.author.did === store.me.did} ··· 179 184 </View> 180 185 </View> 181 186 <View style={[s.pl10, s.pr10, s.pb10]}> 182 - {record.text ? ( 187 + {item.richText?.text ? ( 183 188 <View 184 189 style={[ 185 190 styles.postTextContainer, ··· 187 192 ]}> 188 193 <RichText 189 194 type="post-text-lg" 190 - text={record.text} 191 - entities={record.entities} 195 + richText={item.richText} 192 196 lineHeight={1.3} 193 197 /> 194 198 </View> ··· 233 237 <View style={[s.pl10, s.pb5]}> 234 238 <PostCtrls 235 239 big 240 + itemUri={itemUri} 241 + itemCid={itemCid} 236 242 itemHref={itemHref} 237 243 itemTitle={itemTitle} 238 244 isAuthor={item.post.author.did === store.me.did} ··· 301 307 <FontAwesomeIcon icon={['far', 'eye-slash']} style={s.mr2} /> 302 308 <Text type="sm">This post is by a muted account.</Text> 303 309 </View> 304 - ) : record.text ? ( 310 + ) : item.richText?.text ? ( 305 311 <View style={styles.postTextContainer}> 306 312 <RichText 307 313 type="post-text" 308 - text={record.text} 309 - entities={record.entities} 314 + richText={item.richText} 310 315 style={pal.text} 311 316 lineHeight={1.3} 312 317 /> ··· 314 319 ) : undefined} 315 320 <PostEmbeds embed={item.post.embed} style={s.mb10} /> 316 321 <PostCtrls 322 + itemUri={itemUri} 323 + itemCid={itemCid} 317 324 itemHref={itemHref} 318 325 itemTitle={itemTitle} 319 326 isAuthor={item.post.author.did === store.me.did} ··· 341 348 href={itemHref} 342 349 title={itemTitle} 343 350 noFeedback> 344 - <Text style={pal.link}>Load more</Text> 351 + <Text style={pal.link}>Continue thread...</Text> 352 + <FontAwesomeIcon 353 + icon="angle-right" 354 + style={pal.link as FontAwesomeIconStyle} 355 + size={18} 356 + /> 345 357 </Link> 346 358 ) : undefined} 347 359 </> ··· 433 445 marginRight: 10, 434 446 }, 435 447 loadMore: { 448 + flexDirection: 'row', 449 + justifyContent: 'space-between', 436 450 borderTopWidth: 1, 437 - paddingLeft: 28, 451 + paddingLeft: 80, 452 + paddingRight: 20, 438 453 paddingVertical: 10, 454 + marginBottom: 8, 439 455 }, 440 456 })
+14 -63
src/view/com/post-thread/PostVotedBy.tsx
··· 2 2 import {observer} from 'mobx-react-lite' 3 3 import {ActivityIndicator, StyleSheet, View} from 'react-native' 4 4 import {CenteredView, FlatList} from '../util/Views' 5 - import {VotesViewModel, VoteItem} from '../../../state/models/votes-view' 6 - import {Link} from '../util/Link' 7 - import {Text} from '../util/text/Text' 5 + import {VotesViewModel, VoteItem} from 'state/models/votes-view' 8 6 import {ErrorMessage} from '../util/error/ErrorMessage' 9 - import {UserAvatar} from '../util/UserAvatar' 10 - import {useStores} from '../../../state' 11 - import {s} from '../../lib/styles' 12 - import {usePalette} from '../../lib/hooks/usePalette' 7 + import {ProfileCardWithFollowBtn} from '../profile/ProfileCard' 8 + import {useStores} from 'state/index' 13 9 14 10 export const PostVotedBy = observer(function PostVotedBy({ 15 11 uri, ··· 57 53 58 54 // loaded 59 55 // = 60 - const renderItem = ({item}: {item: VoteItem}) => <LikedByItem item={item} /> 56 + const renderItem = ({item}: {item: VoteItem}) => ( 57 + <ProfileCardWithFollowBtn 58 + key={item.actor.did} 59 + did={item.actor.did} 60 + declarationCid={item.actor.declaration.cid} 61 + handle={item.actor.handle} 62 + displayName={item.actor.displayName} 63 + avatar={item.actor.avatar} 64 + isFollowedBy={!!item.actor.viewer?.followedBy} 65 + /> 66 + ) 61 67 return ( 62 68 <FlatList 63 69 data={view.votes} ··· 77 83 ) 78 84 }) 79 85 80 - const LikedByItem = ({item}: {item: VoteItem}) => { 81 - const pal = usePalette('default') 82 - 83 - return ( 84 - <Link 85 - style={[styles.outer, pal.view]} 86 - href={`/profile/${item.actor.handle}`} 87 - title={item.actor.handle} 88 - noFeedback> 89 - <View style={styles.layout}> 90 - <View style={styles.layoutAvi}> 91 - <UserAvatar 92 - size={40} 93 - displayName={item.actor.displayName} 94 - handle={item.actor.handle} 95 - avatar={item.actor.avatar} 96 - /> 97 - </View> 98 - <View style={styles.layoutContent}> 99 - <Text style={[s.f15, s.bold, pal.text]}> 100 - {item.actor.displayName || item.actor.handle} 101 - </Text> 102 - <Text style={[s.f14, s.gray5, pal.textLight]}> 103 - @{item.actor.handle} 104 - </Text> 105 - </View> 106 - </View> 107 - </Link> 108 - ) 109 - } 110 - 111 86 const styles = StyleSheet.create({ 112 - outer: { 113 - marginTop: 1, 114 - }, 115 - layout: { 116 - flexDirection: 'row', 117 - }, 118 - layoutAvi: { 119 - width: 60, 120 - paddingLeft: 10, 121 - paddingTop: 10, 122 - paddingBottom: 10, 123 - }, 124 - avi: { 125 - width: 40, 126 - height: 40, 127 - borderRadius: 20, 128 - resizeMode: 'cover', 129 - }, 130 - layoutContent: { 131 - flex: 1, 132 - paddingRight: 10, 133 - paddingTop: 10, 134 - paddingBottom: 10, 135 - }, 136 87 footer: { 137 88 height: 200, 138 89 paddingTop: 20,
+12 -9
src/view/com/post/Post.tsx
··· 10 10 import Clipboard from '@react-native-clipboard/clipboard' 11 11 import {AtUri} from '../../../third-party/uri' 12 12 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 13 - import {PostThreadViewModel} from '../../../state/models/post-thread-view' 13 + import {PostThreadViewModel} from 'state/models/post-thread-view' 14 14 import {Link} from '../util/Link' 15 15 import {UserInfoText} from '../util/UserInfoText' 16 16 import {PostMeta} from '../util/PostMeta' ··· 20 20 import {RichText} from '../util/text/RichText' 21 21 import * as Toast from '../util/Toast' 22 22 import {UserAvatar} from '../util/UserAvatar' 23 - import {useStores} from '../../../state' 24 - import {s, colors} from '../../lib/styles' 25 - import {usePalette} from '../../lib/hooks/usePalette' 23 + import {useStores} from 'state/index' 24 + import {s, colors} from 'lib/styles' 25 + import {usePalette} from 'lib/hooks/usePalette' 26 26 27 27 export const Post = observer(function Post({ 28 28 uri, ··· 80 80 const item = view.thread 81 81 const record = view.thread.postRecord 82 82 83 + const itemUri = item.post.uri 84 + const itemCid = item.post.cid 83 85 const itemUrip = new AtUri(item.post.uri) 84 86 const itemHref = `/profile/${item.post.author.handle}/post/${itemUrip.rkey}` 85 87 const itemTitle = `Post by ${item.post.author.handle}` ··· 105 107 }) 106 108 } 107 109 const onPressToggleRepost = () => { 108 - item 110 + return item 109 111 .toggleRepost() 110 112 .catch(e => store.log.error('Failed to toggle repost', e)) 111 113 } 112 114 const onPressToggleUpvote = () => { 113 - item 115 + return item 114 116 .toggleUpvote() 115 117 .catch(e => store.log.error('Failed to toggle upvote', e)) 116 118 } ··· 178 180 <FontAwesomeIcon icon={['far', 'eye-slash']} style={s.mr2} /> 179 181 <Text type="sm">This post is by a muted account.</Text> 180 182 </View> 181 - ) : record.text ? ( 183 + ) : item.richText?.text ? ( 182 184 <View style={styles.postTextContainer}> 183 185 <RichText 184 186 type="post-text" 185 - text={record.text} 186 - entities={record.entities} 187 + richText={item.richText} 187 188 lineHeight={1.3} 188 189 /> 189 190 </View> 190 191 ) : undefined} 191 192 <PostEmbeds embed={item.post.embed} style={s.mb10} /> 192 193 <PostCtrls 194 + itemUri={itemUri} 195 + itemCid={itemCid} 193 196 itemHref={itemHref} 194 197 itemTitle={itemTitle} 195 198 isAuthor={item.post.author.did === store.me.did}
+2 -2
src/view/com/post/PostText.tsx
··· 4 4 import {LoadingPlaceholder} from '../util/LoadingPlaceholder' 5 5 import {ErrorMessage} from '../util/error/ErrorMessage' 6 6 import {Text} from '../util/text/Text' 7 - import {PostModel} from '../../../state/models/post' 8 - import {useStores} from '../../../state' 7 + import {PostModel} from 'state/models/post' 8 + import {useStores} from 'state/index' 9 9 10 10 export const PostText = observer(function PostText({ 11 11 uri,
+2 -44
src/view/com/posts/ComposerPrompt.tsx
··· 1 - import React from 'react' 2 - import {StyleSheet, TouchableOpacity, View} from 'react-native' 3 - import {Text} from '../util/text/Text' 4 - import {usePalette} from '../../lib/hooks/usePalette' 5 - 6 - export function ComposerPrompt({ 7 - onPressCompose, 8 - }: { 1 + export function ComposerPrompt(_opts: { 9 2 onPressCompose: (imagesOpen?: boolean) => void 10 3 }) { 11 - const pal = usePalette('default') 12 - return ( 13 - <View style={[pal.view, pal.border, styles.container]}> 14 - <TouchableOpacity 15 - testID="composePromptButton" 16 - onPress={() => onPressCompose(false)} 17 - style={[styles.btn, {backgroundColor: pal.colors.backgroundLight}]}> 18 - <Text type="button" style={pal.text}> 19 - New post 20 - </Text> 21 - </TouchableOpacity> 22 - <TouchableOpacity 23 - onPress={() => onPressCompose(true)} 24 - style={[styles.btn, {backgroundColor: pal.colors.backgroundLight}]}> 25 - <Text type="button" style={pal.text}> 26 - Share photo 27 - </Text> 28 - </TouchableOpacity> 29 - </View> 30 - ) 4 + return null 31 5 } 32 - 33 - const styles = StyleSheet.create({ 34 - container: { 35 - paddingVertical: 12, 36 - paddingHorizontal: 16, 37 - flexDirection: 'row', 38 - alignItems: 'center', 39 - borderTopWidth: 1, 40 - }, 41 - btn: { 42 - paddingVertical: 6, 43 - paddingHorizontal: 14, 44 - borderRadius: 30, 45 - marginRight: 10, 46 - }, 47 - })
+2 -2
src/view/com/posts/ComposerPrompt.web.tsx
··· 1 1 import React from 'react' 2 2 import {StyleSheet, TouchableWithoutFeedback, View} from 'react-native' 3 3 import {Text} from '../util/text/Text' 4 - import {usePalette} from '../../lib/hooks/usePalette' 5 - import {s} from '../../lib/styles' 4 + import {usePalette} from 'lib/hooks/usePalette' 5 + import {s} from 'lib/styles' 6 6 7 7 export function ComposerPrompt({ 8 8 onPressCompose,
+99 -58
src/view/com/posts/Feed.tsx
··· 11 11 import {PostFeedLoadingPlaceholder} from '../util/LoadingPlaceholder' 12 12 import {EmptyState} from '../util/EmptyState' 13 13 import {ErrorMessage} from '../util/error/ErrorMessage' 14 - import {FeedModel} from '../../../state/models/feed-view' 14 + import {FeedModel} from 'state/models/feed-view' 15 15 import {FeedItem} from './FeedItem' 16 16 import {ComposerPrompt} from './ComposerPrompt' 17 - import {OnScrollCb} from '../../lib/hooks/useOnMainScroll' 18 - import {s} from '../../lib/styles' 17 + import {OnScrollCb} from 'lib/hooks/useOnMainScroll' 18 + import {s} from 'lib/styles' 19 + import {useAnalytics} from 'lib/analytics' 19 20 20 21 const COMPOSE_PROMPT_ITEM = {_reactKey: '__prompt__'} 21 22 const EMPTY_FEED_ITEM = {_reactKey: '__empty__'} 23 + const ERROR_FEED_ITEM = {_reactKey: '__error__'} 22 24 23 25 export const Feed = observer(function Feed({ 24 26 feed, 25 27 style, 26 28 scrollElRef, 27 - onPressCompose, 28 29 onPressTryAgain, 30 + onPressCompose, 29 31 onScroll, 30 32 testID, 33 + headerOffset = 0, 31 34 }: { 32 35 feed: FeedModel 33 36 style?: StyleProp<ViewStyle> 34 37 scrollElRef?: MutableRefObject<FlatList<any> | null> 35 - onPressCompose: (imagesOpen?: boolean) => void 36 38 onPressTryAgain?: () => void 39 + onPressCompose: (imagesOpen?: boolean) => void 37 40 onScroll?: OnScrollCb 38 41 testID?: string 42 + headerOffset?: number 39 43 }) { 44 + const {track} = useAnalytics() 45 + const [isRefreshing, setIsRefreshing] = React.useState(false) 46 + 47 + const data = React.useMemo(() => { 48 + let feedItems: any[] = [] 49 + if (feed.hasLoaded) { 50 + feedItems = feedItems.concat([COMPOSE_PROMPT_ITEM]) 51 + if (feed.hasError) { 52 + feedItems = feedItems.concat([ERROR_FEED_ITEM]) 53 + } 54 + if (feed.isEmpty) { 55 + feedItems = feedItems.concat([EMPTY_FEED_ITEM]) 56 + } else { 57 + feedItems = feedItems.concat(feed.feed) 58 + } 59 + } 60 + return feedItems 61 + }, [feed.hasError, feed.hasLoaded, feed.isEmpty, feed.feed]) 62 + 63 + // events 64 + // = 65 + 66 + const onRefresh = React.useCallback(async () => { 67 + track('Feed:onRefresh') 68 + setIsRefreshing(true) 69 + try { 70 + await feed.refresh() 71 + } catch (err) { 72 + feed.rootStore.log.error('Failed to refresh posts feed', err) 73 + } 74 + setIsRefreshing(false) 75 + }, [feed, track, setIsRefreshing]) 76 + const onEndReached = React.useCallback(async () => { 77 + track('Feed:onEndReached') 78 + try { 79 + await feed.loadMore() 80 + } catch (err) { 81 + feed.rootStore.log.error('Failed to load more posts', err) 82 + } 83 + }, [feed, track]) 84 + 85 + // rendering 86 + // = 87 + 40 88 // TODO optimize renderItem or FeedItem, we're getting this notice from RN: -prf 41 89 // VirtualizedList: You have a large list that is slow to update - make sure your 42 90 // renderItem function renders components that follow React performance best practices 43 91 // like PureComponent, shouldComponentUpdate, etc 44 - const renderItem = ({item}: {item: any}) => { 45 - if (item === COMPOSE_PROMPT_ITEM) { 46 - return <ComposerPrompt onPressCompose={onPressCompose} /> 47 - } else if (item === EMPTY_FEED_ITEM) { 48 - return ( 49 - <EmptyState 50 - icon="bars" 51 - message="This feed is empty!" 52 - style={styles.emptyState} 53 - /> 54 - ) 55 - } else { 56 - return <FeedItem item={item} /> 57 - } 58 - } 59 - const onRefresh = () => { 60 - feed 61 - .refresh() 62 - .catch(err => 63 - feed.rootStore.log.error('Failed to refresh posts feed', err), 64 - ) 65 - } 66 - const onEndReached = () => { 67 - feed 68 - .loadMore() 69 - .catch(err => feed.rootStore.log.error('Failed to load more posts', err)) 70 - } 71 - let data 72 - if (feed.hasLoaded) { 73 - if (feed.isEmpty) { 74 - data = [COMPOSE_PROMPT_ITEM, EMPTY_FEED_ITEM] 75 - } else { 76 - data = [COMPOSE_PROMPT_ITEM].concat(feed.feed) 77 - } 78 - } 79 - const FeedFooter = () => 80 - feed.isLoading ? ( 81 - <View style={styles.feedFooter}> 82 - <ActivityIndicator /> 83 - </View> 84 - ) : ( 85 - <View /> 86 - ) 87 - return ( 88 - <View testID={testID} style={style}> 89 - <CenteredView> 90 - {!data && <ComposerPrompt onPressCompose={onPressCompose} />} 91 - {feed.isLoading && !data && <PostFeedLoadingPlaceholder />} 92 - {feed.hasError && ( 92 + const renderItem = React.useCallback( 93 + ({item}: {item: any}) => { 94 + if (item === COMPOSE_PROMPT_ITEM) { 95 + return <ComposerPrompt onPressCompose={onPressCompose} /> 96 + } else if (item === EMPTY_FEED_ITEM) { 97 + return ( 98 + <EmptyState 99 + icon="bars" 100 + message="This feed is empty!" 101 + style={styles.emptyState} 102 + /> 103 + ) 104 + } else if (item === ERROR_FEED_ITEM) { 105 + return ( 93 106 <ErrorMessage 94 107 message={feed.error} 95 108 onPressTryAgain={onPressTryAgain} 96 109 /> 97 - )} 98 - </CenteredView> 99 - {feed.hasLoaded && data && ( 110 + ) 111 + } 112 + return <FeedItem item={item} /> 113 + }, 114 + [feed, onPressTryAgain, onPressCompose], 115 + ) 116 + 117 + const FeedFooter = React.useCallback( 118 + () => 119 + feed.isLoading ? ( 120 + <View style={styles.feedFooter}> 121 + <ActivityIndicator /> 122 + </View> 123 + ) : ( 124 + <View /> 125 + ), 126 + [feed], 127 + ) 128 + 129 + return ( 130 + <View testID={testID} style={style}> 131 + {feed.isLoading && data.length === 0 && ( 132 + <CenteredView style={{paddingTop: headerOffset}}> 133 + <PostFeedLoadingPlaceholder /> 134 + </CenteredView> 135 + )} 136 + {data.length > 0 && ( 100 137 <FlatList 101 138 ref={scrollElRef} 102 139 data={data} 103 140 keyExtractor={item => item._reactKey} 104 141 renderItem={renderItem} 105 142 ListFooterComponent={FeedFooter} 106 - refreshing={feed.isRefreshing} 143 + refreshing={isRefreshing} 107 144 contentContainerStyle={s.contentContainer} 108 145 onScroll={onScroll} 109 146 onRefresh={onRefresh} 110 147 onEndReached={onEndReached} 148 + removeClippedSubviews={true} 149 + contentInset={{top: headerOffset}} 150 + contentOffset={{x: 0, y: headerOffset * -1}} 151 + progressViewOffset={headerOffset} 111 152 /> 112 153 )} 113 154 </View>
+18 -9
src/view/com/posts/FeedItem.tsx
··· 8 8 FontAwesomeIcon, 9 9 FontAwesomeIconStyle, 10 10 } from '@fortawesome/react-native-fontawesome' 11 - import {FeedItemModel} from '../../../state/models/feed-view' 11 + import {FeedItemModel} from 'state/models/feed-view' 12 12 import {Link} from '../util/Link' 13 13 import {Text} from '../util/text/Text' 14 14 import {UserInfoText} from '../util/UserInfoText' ··· 18 18 import {RichText} from '../util/text/RichText' 19 19 import * as Toast from '../util/Toast' 20 20 import {UserAvatar} from '../util/UserAvatar' 21 - import {s} from '../../lib/styles' 22 - import {useStores} from '../../../state' 23 - import {usePalette} from '../../lib/hooks/usePalette' 21 + import {s} from 'lib/styles' 22 + import {useStores} from 'state/index' 23 + import {usePalette} from 'lib/hooks/usePalette' 24 + import {useAnalytics} from 'lib/analytics' 24 25 25 26 export const FeedItem = observer(function ({ 26 27 item, ··· 33 34 }) { 34 35 const store = useStores() 35 36 const pal = usePalette('default') 37 + const {track} = useAnalytics() 36 38 const [deleted, setDeleted] = useState(false) 37 39 const record = item.postRecord 40 + const itemUri = item.post.uri 41 + const itemCid = item.post.cid 38 42 const itemHref = useMemo(() => { 39 43 const urip = new AtUri(item.post.uri) 40 44 return `/profile/${item.post.author.handle}/post/${urip.rkey}` ··· 50 54 }, [record?.reply]) 51 55 52 56 const onPressReply = () => { 57 + track('FeedItem:PostReply') 53 58 store.shell.openComposer({ 54 59 replyTo: { 55 60 uri: item.post.uri, ··· 64 69 }) 65 70 } 66 71 const onPressToggleRepost = () => { 67 - item 72 + track('FeedItem:PostRepost') 73 + return item 68 74 .toggleRepost() 69 75 .catch(e => store.log.error('Failed to toggle repost', e)) 70 76 } 71 77 const onPressToggleUpvote = () => { 72 - item 78 + track('FeedItem:PostLike') 79 + return item 73 80 .toggleUpvote() 74 81 .catch(e => store.log.error('Failed to toggle upvote', e)) 75 82 } ··· 78 85 Toast.show('Copied to clipboard') 79 86 } 80 87 const onDeletePost = () => { 88 + track('FeedItem:PostDelete') 81 89 item.delete().then( 82 90 () => { 83 91 setDeleted(true) ··· 195 203 <FontAwesomeIcon icon={['far', 'eye-slash']} style={s.mr2} /> 196 204 <Text type="sm">This post is by a muted account.</Text> 197 205 </View> 198 - ) : record.text ? ( 206 + ) : item.richText?.text ? ( 199 207 <View style={styles.postTextContainer}> 200 208 <RichText 201 209 type="post-text" 202 - text={record.text} 203 - entities={record.entities} 210 + richText={item.richText} 204 211 lineHeight={1.3} 205 212 /> 206 213 </View> ··· 210 217 ) : null} 211 218 <PostCtrls 212 219 style={styles.ctrls} 220 + itemUri={itemUri} 221 + itemCid={itemCid} 213 222 itemHref={itemHref} 214 223 itemTitle={itemTitle} 215 224 isAuthor={item.post.author.did === store.me.did}
+119 -19
src/view/com/profile/ProfileCard.tsx
··· 1 1 import React from 'react' 2 2 import {StyleSheet, TouchableOpacity, View} from 'react-native' 3 + import {observer} from 'mobx-react-lite' 3 4 import {Link} from '../util/Link' 4 5 import {Text} from '../util/text/Text' 5 6 import {UserAvatar} from '../util/UserAvatar' 6 - import {s} from '../../lib/styles' 7 - import {usePalette} from '../../lib/hooks/usePalette' 7 + import * as Toast from '../util/Toast' 8 + import {s} from 'lib/styles' 9 + import {usePalette} from 'lib/hooks/usePalette' 10 + import {useStores} from 'state/index' 11 + import * as apilib from 'lib/api/index' 8 12 9 13 export function ProfileCard({ 10 14 handle, 11 15 displayName, 12 16 avatar, 17 + description, 18 + isFollowedBy, 13 19 renderButton, 14 - onPressButton, 15 20 }: { 16 21 handle: string 17 22 displayName?: string 18 23 avatar?: string 24 + description?: string 25 + isFollowedBy?: boolean 19 26 renderButton?: () => JSX.Element 20 - onPressButton?: () => void 21 27 }) { 22 28 const pal = usePalette('default') 23 29 return ( ··· 36 42 /> 37 43 </View> 38 44 <View style={styles.layoutContent}> 39 - <Text style={[s.bold, pal.text]} numberOfLines={1}> 45 + <Text type="lg" style={[s.bold, pal.text]} numberOfLines={1}> 40 46 {displayName || handle} 41 47 </Text> 42 - <Text type="sm" style={[pal.textLight]} numberOfLines={1}> 48 + <Text type="md" style={[pal.textLight]} numberOfLines={1}> 43 49 @{handle} 44 50 </Text> 51 + {isFollowedBy && ( 52 + <View style={s.flexRow}> 53 + <View style={[s.mt5, pal.btn, styles.pill]}> 54 + <Text type="xs">Follows You</Text> 55 + </View> 56 + </View> 57 + )} 45 58 </View> 46 59 {renderButton ? ( 47 - <View style={styles.layoutButton}> 48 - <TouchableOpacity 49 - onPress={onPressButton} 50 - style={[styles.btn, pal.btn]}> 51 - {renderButton()} 52 - </TouchableOpacity> 53 - </View> 60 + <View style={styles.layoutButton}>{renderButton()}</View> 54 61 ) : undefined} 55 62 </View> 63 + {description ? ( 64 + <View style={styles.details}> 65 + <Text style={pal.text} numberOfLines={4}> 66 + {description} 67 + </Text> 68 + </View> 69 + ) : undefined} 56 70 </Link> 57 71 ) 58 72 } 59 73 74 + export const ProfileCardWithFollowBtn = observer( 75 + ({ 76 + did, 77 + declarationCid, 78 + handle, 79 + displayName, 80 + avatar, 81 + description, 82 + isFollowedBy, 83 + }: { 84 + did: string 85 + declarationCid: string 86 + handle: string 87 + displayName?: string 88 + avatar?: string 89 + description?: string 90 + isFollowedBy?: boolean 91 + }) => { 92 + const store = useStores() 93 + const isMe = store.me.handle === handle 94 + const isFollowing = store.me.follows.isFollowing(did) 95 + const onToggleFollow = async () => { 96 + if (store.me.follows.isFollowing(did)) { 97 + try { 98 + await apilib.unfollow(store, store.me.follows.getFollowUri(did)) 99 + store.me.follows.removeFollow(did) 100 + } catch (e: any) { 101 + store.log.error('Failed fo delete follow', e) 102 + Toast.show('An issue occurred, please try again.') 103 + } 104 + } else { 105 + try { 106 + const res = await apilib.follow(store, did, declarationCid) 107 + store.me.follows.addFollow(did, res.uri) 108 + } catch (e: any) { 109 + store.log.error('Failed fo create follow', e) 110 + Toast.show('An issue occurred, please try again.') 111 + } 112 + } 113 + } 114 + return ( 115 + <ProfileCard 116 + handle={handle} 117 + displayName={displayName} 118 + avatar={avatar} 119 + description={description} 120 + isFollowedBy={isFollowedBy} 121 + renderButton={ 122 + isMe 123 + ? undefined 124 + : () => ( 125 + <FollowBtn isFollowing={isFollowing} onPress={onToggleFollow} /> 126 + ) 127 + } 128 + /> 129 + ) 130 + }, 131 + ) 132 + 133 + function FollowBtn({ 134 + isFollowing, 135 + onPress, 136 + }: { 137 + isFollowing: boolean 138 + onPress: () => void 139 + }) { 140 + const pal = usePalette('default') 141 + return ( 142 + <TouchableOpacity onPress={onPress}> 143 + <View style={[styles.btn, pal.btn]}> 144 + <Text type="button" style={[pal.text]}> 145 + {isFollowing ? 'Unfollow' : 'Follow'} 146 + </Text> 147 + </View> 148 + </TouchableOpacity> 149 + ) 150 + } 151 + 60 152 const styles = StyleSheet.create({ 61 153 outer: { 62 154 borderTopWidth: 1, 155 + paddingHorizontal: 6, 63 156 }, 64 157 layout: { 65 158 flexDirection: 'row', ··· 68 161 layoutAvi: { 69 162 width: 60, 70 163 paddingLeft: 10, 71 - paddingTop: 10, 164 + paddingTop: 8, 72 165 paddingBottom: 10, 73 166 }, 74 167 avi: { ··· 80 173 layoutContent: { 81 174 flex: 1, 82 175 paddingRight: 10, 83 - paddingTop: 12, 176 + paddingTop: 10, 84 177 paddingBottom: 10, 85 178 }, 86 179 layoutButton: { 87 180 paddingRight: 10, 88 181 }, 182 + details: { 183 + paddingLeft: 60, 184 + paddingRight: 10, 185 + paddingBottom: 10, 186 + }, 187 + pill: { 188 + borderRadius: 4, 189 + paddingHorizontal: 6, 190 + paddingVertical: 2, 191 + }, 89 192 btn: { 90 - flexDirection: 'row', 91 - alignItems: 'center', 92 - justifyContent: 'center', 93 193 paddingVertical: 7, 94 - paddingHorizontal: 14, 95 194 borderRadius: 50, 96 195 marginLeft: 6, 196 + paddingHorizontal: 14, 97 197 }, 98 198 })
+12 -56
src/view/com/profile/ProfileFollowers.tsx
··· 4 4 import { 5 5 UserFollowersViewModel, 6 6 FollowerItem, 7 - } from '../../../state/models/user-followers-view' 7 + } from 'state/models/user-followers-view' 8 8 import {CenteredView, FlatList} from '../util/Views' 9 - import {Link} from '../util/Link' 10 - import {Text} from '../util/text/Text' 11 9 import {ErrorMessage} from '../util/error/ErrorMessage' 12 - import {UserAvatar} from '../util/UserAvatar' 13 - import {useStores} from '../../../state' 14 - import {s} from '../../lib/styles' 15 - import {usePalette} from '../../lib/hooks/usePalette' 10 + import {ProfileCardWithFollowBtn} from './ProfileCard' 11 + import {useStores} from 'state/index' 16 12 17 13 export const ProfileFollowers = observer(function ProfileFollowers({ 18 14 name, ··· 63 59 // loaded 64 60 // = 65 61 const renderItem = ({item}: {item: FollowerItem}) => ( 66 - <User key={item.did} item={item} /> 62 + <ProfileCardWithFollowBtn 63 + key={item.did} 64 + did={item.did} 65 + declarationCid={item.declaration.cid} 66 + handle={item.handle} 67 + displayName={item.displayName} 68 + avatar={item.avatar} 69 + isFollowedBy={!!item.viewer?.followedBy} 70 + /> 67 71 ) 68 72 return ( 69 73 <FlatList ··· 84 88 ) 85 89 }) 86 90 87 - const User = ({item}: {item: FollowerItem}) => { 88 - const pal = usePalette('default') 89 - return ( 90 - <Link 91 - style={[styles.outer, pal.view, pal.border]} 92 - href={`/profile/${item.handle}`} 93 - title={item.handle} 94 - noFeedback> 95 - <View style={styles.layout}> 96 - <View style={styles.layoutAvi}> 97 - <UserAvatar 98 - size={40} 99 - displayName={item.displayName} 100 - handle={item.handle} 101 - avatar={item.avatar} 102 - /> 103 - </View> 104 - <View style={styles.layoutContent}> 105 - <Text style={[s.bold, pal.text]}> 106 - {item.displayName || item.handle} 107 - </Text> 108 - <Text type="sm" style={[pal.textLight]}> 109 - @{item.handle} 110 - </Text> 111 - </View> 112 - </View> 113 - </Link> 114 - ) 115 - } 116 - 117 91 const styles = StyleSheet.create({ 118 - outer: { 119 - borderTopWidth: 1, 120 - }, 121 - layout: { 122 - flexDirection: 'row', 123 - }, 124 - layoutAvi: { 125 - width: 60, 126 - paddingLeft: 10, 127 - paddingTop: 10, 128 - paddingBottom: 10, 129 - }, 130 - layoutContent: { 131 - flex: 1, 132 - paddingRight: 10, 133 - paddingTop: 10, 134 - paddingBottom: 10, 135 - }, 136 92 footer: { 137 93 height: 200, 138 94 paddingTop: 20,
+12 -63
src/view/com/profile/ProfileFollows.tsx
··· 2 2 import {observer} from 'mobx-react-lite' 3 3 import {ActivityIndicator, StyleSheet, View} from 'react-native' 4 4 import {CenteredView, FlatList} from '../util/Views' 5 - import { 6 - UserFollowsViewModel, 7 - FollowItem, 8 - } from '../../../state/models/user-follows-view' 9 - import {Link} from '../util/Link' 10 - import {Text} from '../util/text/Text' 5 + import {UserFollowsViewModel, FollowItem} from 'state/models/user-follows-view' 11 6 import {ErrorMessage} from '../util/error/ErrorMessage' 12 - import {UserAvatar} from '../util/UserAvatar' 13 - import {useStores} from '../../../state' 14 - import {s} from '../../lib/styles' 15 - import {usePalette} from '../../lib/hooks/usePalette' 7 + import {ProfileCardWithFollowBtn} from './ProfileCard' 8 + import {useStores} from 'state/index' 16 9 17 10 export const ProfileFollows = observer(function ProfileFollows({ 18 11 name, ··· 63 56 // loaded 64 57 // = 65 58 const renderItem = ({item}: {item: FollowItem}) => ( 66 - <User key={item.did} item={item} /> 59 + <ProfileCardWithFollowBtn 60 + key={item.did} 61 + did={item.did} 62 + declarationCid={item.declaration.cid} 63 + handle={item.handle} 64 + displayName={item.displayName} 65 + avatar={item.avatar} 66 + isFollowedBy={!!item.viewer?.followedBy} 67 + /> 67 68 ) 68 69 return ( 69 70 <FlatList ··· 84 85 ) 85 86 }) 86 87 87 - const User = ({item}: {item: FollowItem}) => { 88 - const pal = usePalette('default') 89 - return ( 90 - <Link 91 - style={[styles.outer, pal.view, pal.border]} 92 - href={`/profile/${item.handle}`} 93 - title={item.handle} 94 - noFeedback> 95 - <View style={styles.layout}> 96 - <View style={styles.layoutAvi}> 97 - <UserAvatar 98 - size={40} 99 - displayName={item.displayName} 100 - handle={item.handle} 101 - avatar={ 102 - item.avatar as 103 - | string 104 - | undefined /* HACK: type signature is wrong in the api */ 105 - } 106 - /> 107 - </View> 108 - <View style={styles.layoutContent}> 109 - <Text style={[s.bold, pal.text]}> 110 - {item.displayName || item.handle} 111 - </Text> 112 - <Text type="sm" style={[pal.textLight]}> 113 - @{item.handle} 114 - </Text> 115 - </View> 116 - </View> 117 - </Link> 118 - ) 119 - } 120 - 121 88 const styles = StyleSheet.create({ 122 - outer: { 123 - borderTopWidth: 1, 124 - }, 125 - layout: { 126 - flexDirection: 'row', 127 - }, 128 - layoutAvi: { 129 - width: 60, 130 - paddingLeft: 10, 131 - paddingTop: 10, 132 - paddingBottom: 10, 133 - }, 134 - layoutContent: { 135 - flex: 1, 136 - paddingRight: 10, 137 - paddingTop: 10, 138 - paddingBottom: 10, 139 - }, 140 89 footer: { 141 90 height: 200, 142 91 paddingTop: 20,
+39 -18
src/view/com/profile/ProfileHeader.tsx
··· 13 13 FontAwesomeIconStyle, 14 14 } from '@fortawesome/react-native-fontawesome' 15 15 import {BlurView} from '../util/BlurView' 16 - import {ProfileViewModel} from '../../../state/models/profile-view' 17 - import {useStores} from '../../../state' 16 + import {ProfileViewModel} from 'state/models/profile-view' 17 + import {useStores} from 'state/index' 18 18 import { 19 19 EditProfileModal, 20 20 ReportAccountModal, 21 21 ProfileImageLightbox, 22 - } from '../../../state/models/shell-ui' 23 - import {pluralize, toShareUrl} from '../../../lib/strings' 24 - import {s, gradients} from '../../lib/styles' 22 + } from 'state/models/shell-ui' 23 + import {pluralize} from 'lib/strings/helpers' 24 + import {toShareUrl} from 'lib/strings/url-helpers' 25 + import {s, gradients} from 'lib/styles' 25 26 import {DropdownButton, DropdownItem} from '../util/forms/DropdownButton' 26 27 import * as Toast from '../util/Toast' 27 28 import {LoadingPlaceholder} from '../util/LoadingPlaceholder' ··· 29 30 import {RichText} from '../util/text/RichText' 30 31 import {UserAvatar} from '../util/UserAvatar' 31 32 import {UserBanner} from '../util/UserBanner' 32 - import {usePalette} from '../../lib/hooks/usePalette' 33 + import {usePalette} from 'lib/hooks/usePalette' 34 + import {useAnalytics} from 'lib/analytics' 33 35 34 36 export const ProfileHeader = observer(function ProfileHeader({ 35 37 view, ··· 40 42 }) { 41 43 const pal = usePalette('default') 42 44 const store = useStores() 43 - 45 + const {track} = useAnalytics() 44 46 const onPressBack = () => { 45 47 store.nav.tab.goBack() 46 48 } ··· 53 55 view?.toggleFollowing().then( 54 56 () => { 55 57 Toast.show( 56 - `${view.myState.follow ? 'Following' : 'No longer following'} ${ 58 + `${view.viewer.following ? 'Following' : 'No longer following'} ${ 57 59 view.displayName || view.handle 58 60 }`, 59 61 ) ··· 62 64 ) 63 65 } 64 66 const onPressEditProfile = () => { 67 + track('ProfileHeader:EditProfileButtonClicked') 65 68 store.shell.openModal(new EditProfileModal(view, onRefreshAll)) 66 69 } 67 70 const onPressFollowers = () => { 71 + track('ProfileHeader:FollowersButtonClicked') 68 72 store.nav.navigate(`/profile/${view.handle}/followers`) 69 73 } 70 74 const onPressFollows = () => { 75 + track('ProfileHeader:FollowsButtonClicked') 71 76 store.nav.navigate(`/profile/${view.handle}/follows`) 72 77 } 73 78 const onPressShare = () => { 79 + track('ProfileHeader:ShareButtonClicked') 74 80 Share.share({url: toShareUrl(`/profile/${view.handle}`)}) 75 81 } 76 82 const onPressMuteAccount = async () => { 83 + track('ProfileHeader:MuteAccountButtonClicked') 77 84 try { 78 85 await view.muteAccount() 79 86 Toast.show('Account muted') ··· 83 90 } 84 91 } 85 92 const onPressUnmuteAccount = async () => { 93 + track('ProfileHeader:UnmuteAccountButtonClicked') 86 94 try { 87 95 await view.unmuteAccount() 88 96 Toast.show('Account unmuted') ··· 92 100 } 93 101 } 94 102 const onPressReportAccount = () => { 103 + track('ProfileHeader:ReportAccountButtonClicked') 95 104 store.shell.openModal(new ReportAccountModal(view.did)) 96 105 } 97 106 ··· 110 119 <LoadingPlaceholder width={100} height={31} style={styles.br50} /> 111 120 </View> 112 121 <View style={styles.displayNameLine}> 113 - <Text type="title-xl" style={[pal.text, styles.title]}> 122 + <Text type="title-2xl" style={[pal.text, styles.title]}> 114 123 {view.displayName || view.handle} 115 124 </Text> 116 125 </View> ··· 135 144 let dropdownItems: DropdownItem[] = [{label: 'Share', onPress: onPressShare}] 136 145 if (!isMe) { 137 146 dropdownItems.push({ 138 - label: view.myState.muted ? 'Unmute Account' : 'Mute Account', 139 - onPress: view.myState.muted ? onPressUnmuteAccount : onPressMuteAccount, 147 + label: view.viewer.muted ? 'Unmute Account' : 'Mute Account', 148 + onPress: view.viewer.muted ? onPressUnmuteAccount : onPressMuteAccount, 140 149 }) 141 150 dropdownItems.push({ 142 151 label: 'Report Account', ··· 159 168 </TouchableOpacity> 160 169 ) : ( 161 170 <> 162 - {view.myState.follow ? ( 171 + {store.me.follows.isFollowing(view.did) ? ( 163 172 <TouchableOpacity 164 173 onPress={onPressToggleFollow} 165 174 style={[styles.btn, styles.mainBtn, pal.btn]}> ··· 206 215 ) : undefined} 207 216 </View> 208 217 <View style={styles.displayNameLine}> 209 - <Text type="title-xl" style={[pal.text, styles.title]}> 218 + <Text type="title-2xl" style={[pal.text, styles.title]}> 210 219 {view.displayName || view.handle} 211 220 </Text> 212 221 </View> 213 222 <View style={styles.handleLine}> 223 + {view.viewer.followedBy ? ( 224 + <View style={[styles.pill, pal.btn, s.mr5]}> 225 + <Text type="xs" style={[pal.text]}> 226 + Follows you 227 + </Text> 228 + </View> 229 + ) : undefined} 214 230 <Text style={pal.textLight}>@{view.handle}</Text> 215 231 </View> 216 232 <View style={styles.metricsLine}> ··· 247 263 </Text> 248 264 </View> 249 265 </View> 250 - {view.description ? ( 266 + {view.descriptionRichText ? ( 251 267 <RichText 252 268 style={[styles.description, pal.text]} 253 269 numberOfLines={15} 254 - text={view.description} 255 - entities={view.descriptionEntities} 270 + richText={view.descriptionRichText} 256 271 /> 257 272 ) : undefined} 258 - {view.myState.muted ? ( 273 + {view.viewer.muted ? ( 259 274 <View style={[styles.detailLine, pal.btn, s.p5]}> 260 275 <FontAwesomeIcon 261 276 icon={['far', 'eye-slash']} 262 277 style={[pal.text, s.mr5]} 263 278 /> 264 279 <Text type="md" style={[s.mr2, pal.text]}> 265 - Account muted. 280 + Account muted 266 281 </Text> 267 282 </View> 268 283 ) : undefined} ··· 367 382 flexDirection: 'row', 368 383 alignItems: 'center', 369 384 marginBottom: 5, 385 + }, 386 + 387 + pill: { 388 + borderRadius: 4, 389 + paddingHorizontal: 6, 390 + paddingVertical: 2, 370 391 }, 371 392 372 393 br40: {borderRadius: 40},
+1 -1
src/view/com/util/BlurView.web.tsx
··· 1 1 import React from 'react' 2 2 import {StyleSheet, View, ViewProps} from 'react-native' 3 - import {addStyle} from '../../lib/addStyle' 3 + import {addStyle} from 'lib/styles' 4 4 5 5 type BlurViewProps = ViewProps & { 6 6 blurType?: 'dark' | 'light'
+2 -2
src/view/com/util/EmptyState.tsx
··· 6 6 FontAwesomeIconStyle, 7 7 } from '@fortawesome/react-native-fontawesome' 8 8 import {Text} from './text/Text' 9 - import {UserGroupIcon} from '../../lib/icons' 10 - import {usePalette} from '../../lib/hooks/usePalette' 9 + import {UserGroupIcon} from 'lib/icons' 10 + import {usePalette} from 'lib/hooks/usePalette' 11 11 12 12 export function EmptyState({ 13 13 icon,
+30 -25
src/view/com/util/FAB.tsx
··· 1 1 import React from 'react' 2 2 import {observer} from 'mobx-react-lite' 3 3 import { 4 + Animated, 4 5 GestureResponderEvent, 5 6 StyleSheet, 6 7 TouchableWithoutFeedback, 7 - View, 8 8 } from 'react-native' 9 9 import LinearGradient from 'react-native-linear-gradient' 10 10 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 11 11 import {IconProp} from '@fortawesome/fontawesome-svg-core' 12 - import {colors, gradients} from '../../lib/styles' 13 - import {useStores} from '../../../state' 12 + import {colors, gradients} from 'lib/styles' 13 + import {useAnimatedValue} from 'lib/hooks/useAnimatedValue' 14 + import {useStores} from 'state/index' 14 15 15 16 type OnPress = ((event: GestureResponderEvent) => void) | undefined 16 17 export const FAB = observer( 17 - ({icon, onPress}: {icon: IconProp; onPress: OnPress}) => { 18 + ({ 19 + testID, 20 + icon, 21 + onPress, 22 + }: { 23 + testID?: string 24 + icon: IconProp 25 + onPress: OnPress 26 + }) => { 18 27 const store = useStores() 28 + const interp = useAnimatedValue(0) 29 + React.useEffect(() => { 30 + Animated.timing(interp, { 31 + toValue: store.shell.minimalShellMode ? 1 : 0, 32 + duration: 100, 33 + useNativeDriver: true, 34 + isInteraction: false, 35 + }).start() 36 + }, [interp, store.shell.minimalShellMode]) 37 + const transform = { 38 + transform: [{translateY: Animated.multiply(interp, 60)}], 39 + } 19 40 return ( 20 - <TouchableWithoutFeedback onPress={onPress}> 21 - <View 22 - style={[ 23 - styles.outer, 24 - store.shell.minimalShellMode ? styles.lower : undefined, 25 - ]}> 41 + <TouchableWithoutFeedback testID={testID} onPress={onPress}> 42 + <Animated.View style={[styles.outer, transform]}> 26 43 <LinearGradient 27 44 colors={[gradients.blueLight.start, gradients.blueLight.end]} 28 45 start={{x: 0, y: 0}} 29 46 end={{x: 1, y: 1}} 30 47 style={styles.inner}> 31 - <FontAwesomeIcon 32 - size={24} 33 - icon={icon} 34 - color={colors.white} 35 - style={styles.icon} 36 - /> 48 + <FontAwesomeIcon size={24} icon={icon} color={colors.white} /> 37 49 </LinearGradient> 38 - </View> 50 + </Animated.View> 39 51 </TouchableWithoutFeedback> 40 52 ) 41 53 }, ··· 46 58 position: 'absolute', 47 59 zIndex: 1, 48 60 right: 22, 49 - bottom: 84, 61 + bottom: 94, 50 62 width: 60, 51 63 height: 60, 52 64 borderRadius: 30, 53 - shadowColor: '#000', 54 - shadowOpacity: 0.3, 55 - shadowOffset: {width: 0, height: 1}, 56 - }, 57 - lower: { 58 - bottom: 34, 59 65 }, 60 66 inner: { 61 67 width: 60, ··· 64 70 justifyContent: 'center', 65 71 alignItems: 'center', 66 72 }, 67 - icon: {}, 68 73 })
+10 -6
src/view/com/util/Link.tsx
··· 10 10 ViewStyle, 11 11 } from 'react-native' 12 12 import {Text} from './text/Text' 13 - import {TypographyVariant} from '../../lib/ThemeContext' 14 - import {useStores, RootStoreModel} from '../../../state' 15 - import {convertBskyAppUrlIfNeeded} from '../../../lib/strings' 13 + import {TypographyVariant} from 'lib/ThemeContext' 14 + import {useStores, RootStoreModel} from 'state/index' 15 + import {convertBskyAppUrlIfNeeded} from 'lib/strings/url-helpers' 16 16 17 17 export const Link = observer(function Link({ 18 18 style, ··· 22 22 noFeedback, 23 23 }: { 24 24 style?: StyleProp<ViewStyle> 25 - href: string 25 + href?: string 26 26 title?: string 27 27 children?: React.ReactNode 28 28 noFeedback?: boolean 29 29 }) { 30 30 const store = useStores() 31 31 const onPress = () => { 32 - handleLink(store, href, false) 32 + if (href) { 33 + handleLink(store, href, false) 34 + } 33 35 } 34 36 const onLongPress = () => { 35 - handleLink(store, href, true) 37 + if (href) { 38 + handleLink(store, href, true) 39 + } 36 40 } 37 41 if (noFeedback) { 38 42 return (
+2 -2
src/view/com/util/LoadLatestBtn.tsx
··· 4 4 import LinearGradient from 'react-native-linear-gradient' 5 5 import {useSafeAreaInsets} from 'react-native-safe-area-context' 6 6 import {Text} from './text/Text' 7 - import {colors, gradients} from '../../lib/styles' 7 + import {colors, gradients} from 'lib/styles' 8 8 import {clamp} from 'lodash' 9 - import {useStores} from '../../../state' 9 + import {useStores} from 'state/index' 10 10 11 11 const HITSLOP = {left: 20, top: 20, right: 20, bottom: 20} 12 12
+1 -1
src/view/com/util/LoadLatestBtn.web.tsx
··· 1 1 import React from 'react' 2 2 import {StyleSheet, TouchableOpacity} from 'react-native' 3 3 import {Text} from './text/Text' 4 - import {usePalette} from '../../lib/hooks/usePalette' 4 + import {usePalette} from 'lib/hooks/usePalette' 5 5 6 6 const HITSLOP = {left: 20, top: 20, right: 20, bottom: 20} 7 7
+4 -4
src/view/com/util/LoadingPlaceholder.tsx
··· 1 1 import React from 'react' 2 2 import {StyleSheet, StyleProp, View, ViewStyle} from 'react-native' 3 3 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 4 - import {HeartIcon} from '../../lib/icons' 5 - import {s} from '../../lib/styles' 6 - import {useTheme} from '../../lib/ThemeContext' 7 - import {usePalette} from '../../lib/hooks/usePalette' 4 + import {HeartIcon} from 'lib/icons' 5 + import {s} from 'lib/styles' 6 + import {useTheme} from 'lib/ThemeContext' 7 + import {usePalette} from 'lib/hooks/usePalette' 8 8 9 9 export function LoadingPlaceholder({ 10 10 width,
+1 -1
src/view/com/util/Picker.tsx
··· 16 16 } from '@fortawesome/react-native-fontawesome' 17 17 import RootSiblings from 'react-native-root-siblings' 18 18 import {Text} from './text/Text' 19 - import {colors} from '../../lib/styles' 19 + import {colors} from 'lib/styles' 20 20 21 21 interface PickerItem { 22 22 value: string
+122 -71
src/view/com/util/PostCtrls.tsx
··· 1 1 import React from 'react' 2 2 import { 3 - Animated, 4 3 StyleProp, 5 4 StyleSheet, 6 5 TouchableOpacity, ··· 12 11 FontAwesomeIconStyle, 13 12 } from '@fortawesome/react-native-fontawesome' 14 13 import ReactNativeHapticFeedback from 'react-native-haptic-feedback' 14 + // DISABLED see #135 15 + // import { 16 + // TriggerableAnimated, 17 + // TriggerableAnimatedRef, 18 + // } from './anim/TriggerableAnimated' 15 19 import {Text} from './text/Text' 16 20 import {PostDropdownBtn} from './forms/DropdownButton' 17 21 import { ··· 19 23 HeartIconSolid, 20 24 RepostIcon, 21 25 CommentBottomArrow, 22 - } from '../../lib/icons' 23 - import {s, colors} from '../../lib/styles' 24 - import {useTheme} from '../../lib/ThemeContext' 25 - import {useAnimatedValue} from '../../lib/hooks/useAnimatedValue' 26 + } from 'lib/icons' 27 + import {s, colors} from 'lib/styles' 28 + import {useTheme} from 'lib/ThemeContext' 26 29 27 30 interface PostCtrlsOpts { 31 + itemUri: string 32 + itemCid: string 28 33 itemHref: string 29 34 itemTitle: string 30 35 isAuthor: boolean ··· 36 41 isReposted: boolean 37 42 isUpvoted: boolean 38 43 onPressReply: () => void 39 - onPressToggleRepost: () => void 40 - onPressToggleUpvote: () => void 44 + onPressToggleRepost: () => Promise<void> 45 + onPressToggleUpvote: () => Promise<void> 41 46 onCopyPostText: () => void 42 47 onDeletePost: () => void 43 48 } 44 49 45 - const HITSLOP = {top: 2, left: 2, bottom: 2, right: 2} 50 + const HITSLOP = {top: 5, left: 5, bottom: 5, right: 5} 46 51 47 - export function PostCtrls(opts: PostCtrlsOpts) { 48 - const theme = useTheme() 49 - const defaultCtrlColor = React.useMemo( 50 - () => ({ 51 - color: theme.palette.default.postCtrl, 52 + // DISABLED see #135 53 + /* 54 + function ctrlAnimStart(interp: Animated.Value) { 55 + return Animated.sequence([ 56 + Animated.timing(interp, { 57 + toValue: 1, 58 + duration: 250, 59 + useNativeDriver: true, 52 60 }), 53 - [theme], 54 - ) 55 - const interp1 = useAnimatedValue(0) 56 - const interp2 = useAnimatedValue(0) 61 + Animated.delay(50), 62 + Animated.timing(interp, { 63 + toValue: 0, 64 + duration: 20, 65 + useNativeDriver: true, 66 + }), 67 + ]) 68 + } 57 69 58 - const anim1Style = { 70 + function ctrlAnimStyle(interp: Animated.Value) { 71 + return { 59 72 transform: [ 60 73 { 61 - scale: interp1.interpolate({ 62 - inputRange: [0, 1.0], 63 - outputRange: [1.0, 4.0], 64 - }), 65 - }, 66 - ], 67 - opacity: interp1.interpolate({ 68 - inputRange: [0, 1.0], 69 - outputRange: [1.0, 0.0], 70 - }), 71 - } 72 - const anim2Style = { 73 - transform: [ 74 - { 75 - scale: interp2.interpolate({ 74 + scale: interp.interpolate({ 76 75 inputRange: [0, 1.0], 77 76 outputRange: [1.0, 4.0], 78 77 }), 79 78 }, 80 79 ], 81 - opacity: interp2.interpolate({ 80 + opacity: interp.interpolate({ 82 81 inputRange: [0, 1.0], 83 82 outputRange: [1.0, 0.0], 84 83 }), 85 84 } 85 + } 86 + */ 86 87 88 + export function PostCtrls(opts: PostCtrlsOpts) { 89 + const theme = useTheme() 90 + const defaultCtrlColor = React.useMemo( 91 + () => ({ 92 + color: theme.palette.default.postCtrl, 93 + }), 94 + [theme], 95 + ) as StyleProp<ViewStyle> 96 + const [repostMod, setRepostMod] = React.useState<number>(0) 97 + const [likeMod, setLikeMod] = React.useState<number>(0) 98 + // DISABLED see #135 99 + // const repostRef = React.useRef<TriggerableAnimatedRef | null>(null) 100 + // const likeRef = React.useRef<TriggerableAnimatedRef | null>(null) 87 101 const onPressToggleRepostWrapper = () => { 88 102 if (!opts.isReposted) { 89 103 ReactNativeHapticFeedback.trigger('impactMedium') 90 - Animated.sequence([ 91 - Animated.timing(interp1, { 92 - toValue: 1, 93 - duration: 400, 94 - useNativeDriver: true, 95 - }), 96 - Animated.delay(100), 97 - Animated.timing(interp1, { 98 - toValue: 0, 99 - duration: 20, 100 - useNativeDriver: true, 101 - }), 102 - ]).start() 104 + setRepostMod(1) 105 + opts 106 + .onPressToggleRepost() 107 + .catch(_e => undefined) 108 + .then(() => setRepostMod(0)) 109 + // DISABLED see #135 110 + // repostRef.current?.trigger( 111 + // {start: ctrlAnimStart, style: ctrlAnimStyle}, 112 + // async () => { 113 + // await opts.onPressToggleRepost().catch(_e => undefined) 114 + // setRepostMod(0) 115 + // }, 116 + // ) 117 + } else { 118 + setRepostMod(-1) 119 + opts 120 + .onPressToggleRepost() 121 + .catch(_e => undefined) 122 + .then(() => setRepostMod(0)) 103 123 } 104 - opts.onPressToggleRepost() 105 124 } 106 125 const onPressToggleUpvoteWrapper = () => { 107 126 if (!opts.isUpvoted) { 108 127 ReactNativeHapticFeedback.trigger('impactMedium') 109 - Animated.sequence([ 110 - Animated.timing(interp2, { 111 - toValue: 1, 112 - duration: 400, 113 - useNativeDriver: true, 114 - }), 115 - Animated.delay(100), 116 - Animated.timing(interp2, { 117 - toValue: 0, 118 - duration: 20, 119 - useNativeDriver: true, 120 - }), 121 - ]).start() 128 + setLikeMod(1) 129 + opts 130 + .onPressToggleUpvote() 131 + .catch(_e => undefined) 132 + .then(() => setLikeMod(0)) 133 + // DISABLED see #135 134 + // likeRef.current?.trigger( 135 + // {start: ctrlAnimStart, style: ctrlAnimStyle}, 136 + // async () => { 137 + // await opts.onPressToggleUpvote().catch(_e => undefined) 138 + // setLikeMod(0) 139 + // }, 140 + // ) 141 + } else { 142 + setLikeMod(-1) 143 + opts 144 + .onPressToggleUpvote() 145 + .catch(_e => undefined) 146 + .then(() => setLikeMod(0)) 122 147 } 123 - opts.onPressToggleUpvote() 124 148 } 125 149 126 150 return ( ··· 147 171 hitSlop={HITSLOP} 148 172 onPress={onPressToggleRepostWrapper} 149 173 style={styles.ctrl}> 150 - <Animated.View style={anim1Style}> 174 + <RepostIcon 175 + style={ 176 + opts.isReposted || repostMod > 0 177 + ? (styles.ctrlIconReposted as StyleProp<ViewStyle>) 178 + : defaultCtrlColor 179 + } 180 + strokeWidth={2.4} 181 + size={opts.big ? 24 : 20} 182 + /> 183 + { 184 + undefined /*DISABLED see #135 <TriggerableAnimated ref={repostRef}> 151 185 <RepostIcon 152 186 style={ 153 187 (opts.isReposted ··· 157 191 strokeWidth={2.4} 158 192 size={opts.big ? 24 : 20} 159 193 /> 160 - </Animated.View> 194 + </TriggerableAnimated>*/ 195 + } 161 196 {typeof opts.repostCount !== 'undefined' ? ( 162 197 <Text 163 198 style={ 164 - opts.isReposted 199 + opts.isReposted || repostMod > 0 165 200 ? [s.bold, s.green3, s.f15, s.ml5] 166 201 : [defaultCtrlColor, s.f15, s.ml5] 167 202 }> 168 - {opts.repostCount} 203 + {opts.repostCount + repostMod} 169 204 </Text> 170 205 ) : undefined} 171 206 </TouchableOpacity> ··· 175 210 style={styles.ctrl} 176 211 hitSlop={HITSLOP} 177 212 onPress={onPressToggleUpvoteWrapper}> 178 - <Animated.View style={anim2Style}> 179 - {opts.isUpvoted ? ( 213 + {opts.isUpvoted || likeMod > 0 ? ( 214 + <HeartIconSolid 215 + style={styles.ctrlIconUpvoted as StyleProp<ViewStyle>} 216 + size={opts.big ? 22 : 16} 217 + /> 218 + ) : ( 219 + <HeartIcon 220 + style={[defaultCtrlColor, opts.big ? styles.mt1 : undefined]} 221 + strokeWidth={3} 222 + size={opts.big ? 20 : 16} 223 + /> 224 + )} 225 + { 226 + undefined /*DISABLED see #135 <TriggerableAnimated ref={likeRef}> 227 + {opts.isUpvoted || likeMod > 0 ? ( 180 228 <HeartIconSolid 181 229 style={styles.ctrlIconUpvoted as ViewStyle} 182 230 size={opts.big ? 22 : 16} ··· 191 239 size={opts.big ? 20 : 16} 192 240 /> 193 241 )} 194 - </Animated.View> 242 + </TriggerableAnimated>*/ 243 + } 195 244 {typeof opts.upvoteCount !== 'undefined' ? ( 196 245 <Text 197 246 style={ 198 - opts.isUpvoted 247 + opts.isUpvoted || likeMod > 0 199 248 ? [s.bold, s.red3, s.f15, s.ml5] 200 249 : [defaultCtrlColor, s.f15, s.ml5] 201 250 }> 202 - {opts.upvoteCount} 251 + {opts.upvoteCount + likeMod} 203 252 </Text> 204 253 ) : undefined} 205 254 </TouchableOpacity> ··· 208 257 {opts.big ? undefined : ( 209 258 <PostDropdownBtn 210 259 style={styles.ctrl} 260 + itemUri={opts.itemUri} 261 + itemCid={opts.itemCid} 211 262 itemHref={opts.itemHref} 212 263 itemTitle={opts.itemTitle} 213 264 isAuthor={opts.isAuthor}
-158
src/view/com/util/PostEmbeds.tsx
··· 1 - import React from 'react' 2 - import {StyleSheet, StyleProp, View, ViewStyle} from 'react-native' 3 - import {AppBskyEmbedImages, AppBskyEmbedExternal} from '@atproto/api' 4 - import LinearGradient from 'react-native-linear-gradient' 5 - import {Link} from '../util/Link' 6 - import {Text} from './text/Text' 7 - import {AutoSizedImage} from './images/AutoSizedImage' 8 - import {ImageLayoutGrid} from './images/ImageLayoutGrid' 9 - import {ImagesLightbox} from '../../../state/models/shell-ui' 10 - import {useStores} from '../../../state' 11 - import {usePalette} from '../../lib/hooks/usePalette' 12 - import {gradients} from '../../lib/styles' 13 - import {saveImageModal} from '../../../lib/images' 14 - 15 - type Embed = 16 - | AppBskyEmbedImages.Presented 17 - | AppBskyEmbedExternal.Presented 18 - | {$type: string; [k: string]: unknown} 19 - 20 - export function PostEmbeds({ 21 - embed, 22 - style, 23 - }: { 24 - embed?: Embed 25 - style?: StyleProp<ViewStyle> 26 - }) { 27 - const pal = usePalette('default') 28 - const store = useStores() 29 - if (AppBskyEmbedImages.isPresented(embed)) { 30 - if (embed.images.length > 0) { 31 - const uris = embed.images.map(img => img.fullsize) 32 - const openLightbox = (index: number) => { 33 - store.shell.openLightbox(new ImagesLightbox(uris, index)) 34 - } 35 - const onLongPress = (index: number) => { 36 - saveImageModal({uri: uris[index]}) 37 - } 38 - 39 - if (embed.images.length === 4) { 40 - return ( 41 - <View style={[styles.imagesContainer, style]}> 42 - <ImageLayoutGrid 43 - type="four" 44 - uris={embed.images.map(img => img.thumb)} 45 - onPress={openLightbox} 46 - onLongPress={onLongPress} 47 - /> 48 - </View> 49 - ) 50 - } else if (embed.images.length === 3) { 51 - return ( 52 - <View style={[styles.imagesContainer, style]}> 53 - <ImageLayoutGrid 54 - type="three" 55 - uris={embed.images.map(img => img.thumb)} 56 - onPress={openLightbox} 57 - onLongPress={onLongPress} 58 - /> 59 - </View> 60 - ) 61 - } else if (embed.images.length === 2) { 62 - return ( 63 - <View style={[styles.imagesContainer, style]}> 64 - <ImageLayoutGrid 65 - type="two" 66 - uris={embed.images.map(img => img.thumb)} 67 - onPress={openLightbox} 68 - onLongPress={onLongPress} 69 - /> 70 - </View> 71 - ) 72 - } else { 73 - return ( 74 - <View style={[styles.imagesContainer, style]}> 75 - <AutoSizedImage 76 - uri={embed.images[0].thumb} 77 - onPress={() => openLightbox(0)} 78 - onLongPress={() => onLongPress(0)} 79 - containerStyle={styles.singleImage} 80 - /> 81 - </View> 82 - ) 83 - } 84 - } 85 - } 86 - if (AppBskyEmbedExternal.isPresented(embed)) { 87 - const link = embed.external 88 - return ( 89 - <Link 90 - style={[styles.extOuter, pal.view, pal.border, style]} 91 - href={link.uri} 92 - noFeedback> 93 - {link.thumb ? ( 94 - <AutoSizedImage uri={link.thumb} containerStyle={styles.extImage} /> 95 - ) : ( 96 - <LinearGradient 97 - colors={[gradients.blueDark.start, gradients.blueDark.end]} 98 - start={{x: 0, y: 0}} 99 - end={{x: 1, y: 1}} 100 - style={[styles.extImage, styles.extImageFallback]} 101 - /> 102 - )} 103 - <View style={styles.extInner}> 104 - <Text type="md-bold" numberOfLines={2} style={[pal.text]}> 105 - {link.title || link.uri} 106 - </Text> 107 - <Text 108 - type="sm" 109 - numberOfLines={1} 110 - style={[pal.textLight, styles.extUri]}> 111 - {link.uri} 112 - </Text> 113 - {link.description ? ( 114 - <Text 115 - type="sm" 116 - numberOfLines={2} 117 - style={[pal.text, styles.extDescription]}> 118 - {link.description} 119 - </Text> 120 - ) : undefined} 121 - </View> 122 - </Link> 123 - ) 124 - } 125 - return <View /> 126 - } 127 - 128 - const styles = StyleSheet.create({ 129 - imagesContainer: { 130 - marginTop: 4, 131 - }, 132 - singleImage: { 133 - borderRadius: 8, 134 - }, 135 - extOuter: { 136 - borderWidth: 1, 137 - borderRadius: 8, 138 - marginTop: 4, 139 - }, 140 - extInner: { 141 - padding: 10, 142 - }, 143 - extImage: { 144 - borderTopLeftRadius: 6, 145 - borderTopRightRadius: 6, 146 - width: '100%', 147 - maxHeight: 200, 148 - }, 149 - extImageFallback: { 150 - height: 160, 151 - }, 152 - extUri: { 153 - marginTop: 2, 154 - }, 155 - extDescription: { 156 - marginTop: 4, 157 - }, 158 - })
+69
src/view/com/util/PostEmbeds/ExternalLinkEmbed.tsx
··· 1 + import React from 'react' 2 + import {Text} from '../text/Text' 3 + import {AutoSizedImage} from '../images/AutoSizedImage' 4 + import {StyleSheet, View} from 'react-native' 5 + import {usePalette} from 'lib/hooks/usePalette' 6 + import {PresentedExternal} from '@atproto/api/dist/client/types/app/bsky/embed/external' 7 + 8 + const ExternalLinkEmbed = ({ 9 + link, 10 + onImagePress, 11 + imageChild, 12 + }: { 13 + link: PresentedExternal 14 + onImagePress?: () => void 15 + imageChild?: React.ReactNode 16 + }) => { 17 + const pal = usePalette('default') 18 + return ( 19 + <> 20 + {link.thumb ? ( 21 + <AutoSizedImage 22 + uri={link.thumb} 23 + style={styles.extImage} 24 + onPress={onImagePress}> 25 + {imageChild} 26 + </AutoSizedImage> 27 + ) : undefined} 28 + <View style={styles.extInner}> 29 + <Text type="md-bold" numberOfLines={2} style={[pal.text]}> 30 + {link.title || link.uri} 31 + </Text> 32 + <Text 33 + type="sm" 34 + numberOfLines={1} 35 + style={[pal.textLight, styles.extUri]}> 36 + {link.uri} 37 + </Text> 38 + {link.description ? ( 39 + <Text 40 + type="sm" 41 + numberOfLines={2} 42 + style={[pal.text, styles.extDescription]}> 43 + {link.description} 44 + </Text> 45 + ) : undefined} 46 + </View> 47 + </> 48 + ) 49 + } 50 + 51 + const styles = StyleSheet.create({ 52 + extInner: { 53 + padding: 10, 54 + }, 55 + extImage: { 56 + borderTopLeftRadius: 6, 57 + borderTopRightRadius: 6, 58 + width: '100%', 59 + maxHeight: 200, 60 + }, 61 + extUri: { 62 + marginTop: 2, 63 + }, 64 + extDescription: { 65 + marginTop: 4, 66 + }, 67 + }) 68 + 69 + export default ExternalLinkEmbed
+119
src/view/com/util/PostEmbeds/YoutubeEmbed.tsx
··· 1 + import React, {useEffect} from 'react' 2 + import {useState} from 'react' 3 + import { 4 + View, 5 + StyleSheet, 6 + Pressable, 7 + TouchableWithoutFeedback, 8 + EmitterSubscription, 9 + } from 'react-native' 10 + import YoutubePlayer from 'react-native-youtube-iframe' 11 + import {usePalette} from 'lib/hooks/usePalette' 12 + import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 13 + import ExternalLinkEmbed from './ExternalLinkEmbed' 14 + import {PresentedExternal} from '@atproto/api/dist/client/types/app/bsky/embed/external' 15 + import {useStores} from 'state/index' 16 + 17 + const YoutubeEmbed = ({ 18 + link, 19 + videoId, 20 + }: { 21 + videoId: string 22 + link: PresentedExternal 23 + }) => { 24 + const store = useStores() 25 + const [displayVideoPlayer, setDisplayVideoPlayer] = useState(false) 26 + const [playerDimensions, setPlayerDimensions] = useState({ 27 + width: 0, 28 + height: 0, 29 + }) 30 + const pal = usePalette('default') 31 + const handlePlayButtonPressed = () => { 32 + setDisplayVideoPlayer(true) 33 + } 34 + const handleOnLayout = (event: { 35 + nativeEvent: {layout: {width: any; height: any}} 36 + }) => { 37 + setPlayerDimensions({ 38 + width: event.nativeEvent.layout.width, 39 + height: event.nativeEvent.layout.height, 40 + }) 41 + } 42 + useEffect(() => { 43 + let sub: EmitterSubscription 44 + if (displayVideoPlayer) { 45 + sub = store.onNavigation(() => { 46 + setDisplayVideoPlayer(false) 47 + }) 48 + } 49 + return () => sub && sub.remove() 50 + }, [displayVideoPlayer, store]) 51 + 52 + const imageChild = ( 53 + <Pressable onPress={handlePlayButtonPressed} style={styles.playButton}> 54 + <FontAwesomeIcon icon="play" size={24} color="white" /> 55 + </Pressable> 56 + ) 57 + 58 + if (!displayVideoPlayer) { 59 + return ( 60 + <View 61 + style={[styles.extOuter, pal.view, pal.border]} 62 + onLayout={handleOnLayout}> 63 + <ExternalLinkEmbed 64 + link={link} 65 + onImagePress={handlePlayButtonPressed} 66 + imageChild={imageChild} 67 + /> 68 + </View> 69 + ) 70 + } 71 + 72 + const height = (playerDimensions.width / 16) * 9 73 + const noop = () => {} 74 + 75 + return ( 76 + <TouchableWithoutFeedback onPress={noop}> 77 + <View> 78 + {/* Removing the outter View will make tap events propagate to parents */} 79 + <YoutubePlayer 80 + initialPlayerParams={{ 81 + modestbranding: true, 82 + }} 83 + webViewProps={{ 84 + startInLoadingState: true, 85 + }} 86 + height={height} 87 + videoId={videoId} 88 + webViewStyle={styles.webView} 89 + /> 90 + </View> 91 + </TouchableWithoutFeedback> 92 + ) 93 + } 94 + 95 + const styles = StyleSheet.create({ 96 + extOuter: { 97 + borderWidth: 1, 98 + borderRadius: 8, 99 + marginTop: 4, 100 + }, 101 + playButton: { 102 + position: 'absolute', 103 + alignSelf: 'center', 104 + alignItems: 'center', 105 + top: '44%', 106 + justifyContent: 'center', 107 + backgroundColor: 'black', 108 + padding: 10, 109 + borderRadius: 50, 110 + opacity: 0.8, 111 + }, 112 + webView: { 113 + alignItems: 'center', 114 + alignContent: 'center', 115 + justifyContent: 'center', 116 + }, 117 + }) 118 + 119 + export default YoutubeEmbed
+139
src/view/com/util/PostEmbeds/index.tsx
··· 1 + import React from 'react' 2 + import { 3 + StyleSheet, 4 + StyleProp, 5 + View, 6 + ViewStyle, 7 + Image as RNImage, 8 + } from 'react-native' 9 + import {AppBskyEmbedImages, AppBskyEmbedExternal} from '@atproto/api' 10 + import {Link} from '../Link' 11 + import {AutoSizedImage} from '../images/AutoSizedImage' 12 + import {ImageLayoutGrid} from '../images/ImageLayoutGrid' 13 + import {ImagesLightbox} from 'state/models/shell-ui' 14 + import {useStores} from 'state/index' 15 + import {usePalette} from 'lib/hooks/usePalette' 16 + import {saveImageModal} from 'lib/images' 17 + import YoutubeEmbed from './YoutubeEmbed' 18 + import ExternalLinkEmbed from './ExternalLinkEmbed' 19 + import {getYoutubeVideoId} from 'lib/strings/url-helpers' 20 + 21 + type Embed = 22 + | AppBskyEmbedImages.Presented 23 + | AppBskyEmbedExternal.Presented 24 + | {$type: string; [k: string]: unknown} 25 + 26 + export function PostEmbeds({ 27 + embed, 28 + style, 29 + }: { 30 + embed?: Embed 31 + style?: StyleProp<ViewStyle> 32 + }) { 33 + const pal = usePalette('default') 34 + const store = useStores() 35 + if (AppBskyEmbedImages.isPresented(embed)) { 36 + if (embed.images.length > 0) { 37 + const uris = embed.images.map(img => img.fullsize) 38 + const openLightbox = (index: number) => { 39 + store.shell.openLightbox(new ImagesLightbox(uris, index)) 40 + } 41 + const onLongPress = (index: number) => { 42 + saveImageModal({uri: uris[index]}) 43 + } 44 + const onPressIn = (index: number) => { 45 + const firstImageToShow = uris[index] 46 + RNImage.prefetch(firstImageToShow) 47 + uris.forEach(uri => { 48 + if (firstImageToShow !== uri) { 49 + // First image already prefeched above 50 + RNImage.prefetch(uri) 51 + } 52 + }) 53 + } 54 + 55 + if (embed.images.length === 4) { 56 + return ( 57 + <View style={[styles.imagesContainer, style]}> 58 + <ImageLayoutGrid 59 + type="four" 60 + uris={embed.images.map(img => img.thumb)} 61 + onPress={openLightbox} 62 + onLongPress={onLongPress} 63 + onPressIn={onPressIn} 64 + /> 65 + </View> 66 + ) 67 + } else if (embed.images.length === 3) { 68 + return ( 69 + <View style={[styles.imagesContainer, style]}> 70 + <ImageLayoutGrid 71 + type="three" 72 + uris={embed.images.map(img => img.thumb)} 73 + onPress={openLightbox} 74 + onLongPress={onLongPress} 75 + onPressIn={onPressIn} 76 + /> 77 + </View> 78 + ) 79 + } else if (embed.images.length === 2) { 80 + return ( 81 + <View style={[styles.imagesContainer, style]}> 82 + <ImageLayoutGrid 83 + type="two" 84 + uris={embed.images.map(img => img.thumb)} 85 + onPress={openLightbox} 86 + onLongPress={onLongPress} 87 + onPressIn={onPressIn} 88 + /> 89 + </View> 90 + ) 91 + } else { 92 + return ( 93 + <View style={[styles.imagesContainer, style]}> 94 + <AutoSizedImage 95 + uri={embed.images[0].thumb} 96 + onPress={() => openLightbox(0)} 97 + onLongPress={() => onLongPress(0)} 98 + onPressIn={() => onPressIn(0)} 99 + style={styles.singleImage} 100 + /> 101 + </View> 102 + ) 103 + } 104 + } 105 + } 106 + if (AppBskyEmbedExternal.isPresented(embed)) { 107 + const link = embed.external 108 + const youtubeVideoId = getYoutubeVideoId(link.uri) 109 + 110 + if (youtubeVideoId) { 111 + return <YoutubeEmbed videoId={youtubeVideoId} link={link} /> 112 + } 113 + 114 + return ( 115 + <Link 116 + style={[styles.extOuter, pal.view, pal.border, style]} 117 + href={link.uri} 118 + noFeedback> 119 + <ExternalLinkEmbed link={link} /> 120 + </Link> 121 + ) 122 + } 123 + return <View /> 124 + } 125 + 126 + const styles = StyleSheet.create({ 127 + imagesContainer: { 128 + marginTop: 4, 129 + }, 130 + singleImage: { 131 + borderRadius: 8, 132 + maxHeight: 500, 133 + }, 134 + extOuter: { 135 + borderWidth: 1, 136 + borderRadius: 8, 137 + marginTop: 4, 138 + }, 139 + })
+2 -2
src/view/com/util/PostMeta.tsx
··· 1 1 import React from 'react' 2 2 import {Platform, StyleSheet, View} from 'react-native' 3 3 import {Text} from './text/Text' 4 - import {ago} from '../../../lib/strings' 5 - import {usePalette} from '../../lib/hooks/usePalette' 4 + import {ago} from 'lib/strings/time' 5 + import {usePalette} from 'lib/hooks/usePalette' 6 6 7 7 interface PostMetaOpts { 8 8 authorHandle: string
+1 -1
src/view/com/util/Selector.tsx
··· 6 6 View, 7 7 } from 'react-native' 8 8 import {Text} from './text/Text' 9 - import {usePalette} from '../../lib/hooks/usePalette' 9 + import {usePalette} from 'lib/hooks/usePalette' 10 10 11 11 interface Layout { 12 12 x: number
+73 -42
src/view/com/util/UserAvatar.tsx
··· 1 - import React, {useCallback} from 'react' 2 - import {Alert, Image, StyleSheet, TouchableOpacity, View} from 'react-native' 1 + import React from 'react' 2 + import {StyleSheet, View} from 'react-native' 3 3 import Svg, {Circle, Text, Defs, LinearGradient, Stop} from 'react-native-svg' 4 4 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 5 + import {IconProp} from '@fortawesome/fontawesome-svg-core' 6 + import {HighPriorityImage} from 'view/com/util/images/Image' 5 7 import { 6 8 openCamera, 7 9 openCropper, 8 10 openPicker, 9 11 PickedMedia, 10 12 } from './images/image-crop-picker/ImageCropPicker' 11 - import {useStores} from '../../../state' 12 - import {colors, gradients} from '../../lib/styles' 13 + import { 14 + requestPhotoAccessIfNeeded, 15 + requestCameraAccessIfNeeded, 16 + } from 'lib/permissions' 17 + import {useStores} from 'state/index' 18 + import {colors, gradients} from 'lib/styles' 19 + import {DropdownButton} from './forms/DropdownButton' 20 + import {usePalette} from 'lib/hooks/usePalette' 13 21 14 22 export function UserAvatar({ 15 23 size, ··· 25 33 onSelectNewAvatar?: (img: PickedMedia) => void 26 34 }) { 27 35 const store = useStores() 36 + const pal = usePalette('default') 28 37 const initials = getInitials(displayName || handle) 29 38 30 - const handleEditAvatar = useCallback(() => { 31 - Alert.alert('Select upload method', '', [ 32 - { 33 - text: 'Take a new photo', 34 - onPress: () => { 35 - openCamera(store, { 36 - mediaType: 'photo', 37 - width: 1000, 38 - height: 1000, 39 - cropperCircleOverlay: true, 40 - }).then(onSelectNewAvatar) 41 - }, 42 - }, 43 - { 44 - text: 'Select from gallery', 45 - onPress: () => { 46 - openPicker(store, { 47 - mediaType: 'photo', 48 - }).then(async items => { 49 - await openCropper(store, { 50 - mediaType: 'photo', 51 - path: items[0].path, 52 - width: 1000, 53 - height: 1000, 54 - cropperCircleOverlay: true, 55 - }).then(onSelectNewAvatar) 56 - }) 57 - }, 58 - }, 59 - ]) 60 - }, [store, onSelectNewAvatar]) 61 - 62 39 const renderSvg = (svgSize: number, svgInitials: string) => ( 63 40 <Svg width={svgSize} height={svgSize} viewBox="0 0 100 100"> 64 41 <Defs> ··· 80 57 </Svg> 81 58 ) 82 59 60 + const dropdownItems = [ 61 + { 62 + label: 'Camera', 63 + icon: 'camera' as IconProp, 64 + onPress: async () => { 65 + if (!(await requestCameraAccessIfNeeded())) { 66 + return 67 + } 68 + onSelectNewAvatar?.( 69 + await openCamera(store, { 70 + mediaType: 'photo', 71 + width: 1000, 72 + height: 1000, 73 + cropperCircleOverlay: true, 74 + }), 75 + ) 76 + }, 77 + }, 78 + { 79 + label: 'Library', 80 + icon: 'image' as IconProp, 81 + onPress: async () => { 82 + if (!(await requestPhotoAccessIfNeeded())) { 83 + return 84 + } 85 + const items = await openPicker(store, { 86 + mediaType: 'photo', 87 + }) 88 + onSelectNewAvatar?.( 89 + await openCropper(store, { 90 + mediaType: 'photo', 91 + path: items[0].path, 92 + width: 1000, 93 + height: 1000, 94 + cropperCircleOverlay: true, 95 + }), 96 + ) 97 + }, 98 + }, 99 + // TODO: Remove avatar https://github.com/bluesky-social/social-app/issues/122 100 + // { 101 + // label: 'Remove', 102 + // icon: ['far', 'trash-can'], 103 + // onPress: () => { 104 + // // Remove avatar API call 105 + // }, 106 + // }, 107 + ] 83 108 // onSelectNewAvatar is only passed as prop on the EditProfile component 84 109 return onSelectNewAvatar ? ( 85 - <TouchableOpacity onPress={handleEditAvatar}> 110 + <DropdownButton 111 + type="bare" 112 + items={dropdownItems} 113 + openToRight 114 + rightOffset={-10} 115 + bottomOffset={-10} 116 + menuWidth={170}> 86 117 {avatar ? ( 87 - <Image 118 + <HighPriorityImage 88 119 style={{ 89 120 width: size, 90 121 height: size, ··· 95 126 ) : ( 96 127 renderSvg(size, initials) 97 128 )} 98 - <View style={styles.editButtonContainer}> 129 + <View style={[styles.editButtonContainer, pal.btn]}> 99 130 <FontAwesomeIcon 100 131 icon="camera" 101 132 size={12} 102 - style={{color: colors.white}} 133 + color={pal.text.color as string} 103 134 /> 104 135 </View> 105 - </TouchableOpacity> 136 + </DropdownButton> 106 137 ) : avatar ? ( 107 - <Image 138 + <HighPriorityImage 108 139 style={{width: size, height: size, borderRadius: Math.floor(size / 2)}} 109 140 resizeMode="stretch" 110 141 source={{uri: avatar}}
+65 -32
src/view/com/util/UserBanner.tsx
··· 1 - import React, {useCallback} from 'react' 2 - import {StyleSheet, View, TouchableOpacity, Alert, Image} from 'react-native' 1 + import React from 'react' 2 + import {StyleSheet, View} from 'react-native' 3 3 import Svg, {Rect, Defs, LinearGradient, Stop} from 'react-native-svg' 4 4 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 5 - import {colors, gradients} from '../../lib/styles' 5 + import {IconProp} from '@fortawesome/fontawesome-svg-core' 6 + import Image from 'view/com/util/images/Image' 7 + import {colors, gradients} from 'lib/styles' 6 8 import { 7 9 openCamera, 8 10 openCropper, 9 11 openPicker, 10 12 PickedMedia, 11 13 } from './images/image-crop-picker/ImageCropPicker' 12 - import {useStores} from '../../../state' 14 + import {useStores} from 'state/index' 15 + import { 16 + requestPhotoAccessIfNeeded, 17 + requestCameraAccessIfNeeded, 18 + } from 'lib/permissions' 19 + import {DropdownButton} from './forms/DropdownButton' 20 + import {usePalette} from 'lib/hooks/usePalette' 13 21 14 22 export function UserBanner({ 15 23 banner, ··· 19 27 onSelectNewBanner?: (img: PickedMedia) => void 20 28 }) { 21 29 const store = useStores() 22 - const handleEditBanner = useCallback(() => { 23 - Alert.alert('Select upload method', '', [ 24 - { 25 - text: 'Take a new photo', 26 - onPress: () => { 27 - openCamera(store, { 30 + const pal = usePalette('default') 31 + const dropdownItems = [ 32 + { 33 + label: 'Camera', 34 + icon: 'camera' as IconProp, 35 + onPress: async () => { 36 + if (!(await requestCameraAccessIfNeeded())) { 37 + return 38 + } 39 + onSelectNewBanner?.( 40 + await openCamera(store, { 28 41 mediaType: 'photo', 29 42 // compressImageMaxWidth: 3000, TODO needed? 30 43 width: 3000, 31 44 // compressImageMaxHeight: 1000, TODO needed? 32 45 height: 1000, 33 - }).then(onSelectNewBanner) 34 - }, 46 + }), 47 + ) 35 48 }, 36 - { 37 - text: 'Select from gallery', 38 - onPress: () => { 39 - openPicker(store, { 49 + }, 50 + { 51 + label: 'Library', 52 + icon: 'image' as IconProp, 53 + onPress: async () => { 54 + if (!(await requestPhotoAccessIfNeeded())) { 55 + return 56 + } 57 + const items = await openPicker(store, { 58 + mediaType: 'photo', 59 + }) 60 + onSelectNewBanner?.( 61 + await openCropper(store, { 40 62 mediaType: 'photo', 41 - }).then(async items => { 42 - await openCropper(store, { 43 - mediaType: 'photo', 44 - path: items[0].path, 45 - // compressImageMaxWidth: 3000, TODO needed? 46 - width: 3000, 47 - // compressImageMaxHeight: 1000, TODO needed? 48 - height: 1000, 49 - }).then(onSelectNewBanner) 50 - }) 51 - }, 63 + path: items[0].path, 64 + // compressImageMaxWidth: 3000, TODO needed? 65 + width: 3000, 66 + // compressImageMaxHeight: 1000, TODO needed? 67 + height: 1000, 68 + }), 69 + ) 52 70 }, 53 - ]) 54 - }, [store, onSelectNewBanner]) 71 + }, 72 + // TODO: Remove banner https://github.com/bluesky-social/social-app/issues/122 73 + // { 74 + // label: 'Remove', 75 + // icon: ['far', 'trash-can'], 76 + // onPress: () => { 77 + // // Remove banner api call 78 + // }, 79 + // }, 80 + ] 55 81 56 82 const renderSvg = () => ( 57 83 <Svg width="100%" height="150" viewBox="50 0 200 100"> ··· 72 98 73 99 // setUserBanner is only passed as prop on the EditProfile component 74 100 return onSelectNewBanner ? ( 75 - <TouchableOpacity onPress={handleEditBanner}> 101 + <DropdownButton 102 + type="bare" 103 + items={dropdownItems} 104 + openToRight 105 + rightOffset={-200} 106 + bottomOffset={-10} 107 + menuWidth={170}> 76 108 {banner ? ( 77 109 <Image style={styles.bannerImage} source={{uri: banner}} /> 78 110 ) : ( 79 111 renderSvg() 80 112 )} 81 - <View style={styles.editButtonContainer}> 113 + <View style={[styles.editButtonContainer, pal.btn]}> 82 114 <FontAwesomeIcon 83 115 icon="camera" 84 116 size={12} 85 117 style={{color: colors.white}} 118 + color={pal.text.color as string} 86 119 /> 87 120 </View> 88 - </TouchableOpacity> 121 + </DropdownButton> 89 122 ) : banner ? ( 90 123 <Image 91 124 style={styles.bannerImage}
+2 -2
src/view/com/util/UserInfoText.tsx
··· 4 4 import {Link} from './Link' 5 5 import {Text} from './text/Text' 6 6 import {LoadingPlaceholder} from './LoadingPlaceholder' 7 - import {useStores} from '../../../state' 8 - import {TypographyVariant} from '../../lib/ThemeContext' 7 + import {useStores} from 'state/index' 8 + import {TypographyVariant} from 'lib/ThemeContext' 9 9 10 10 export function UserInfoText({ 11 11 type = 'md',
+65 -87
src/view/com/util/ViewHeader.tsx
··· 1 1 import React from 'react' 2 2 import {observer} from 'mobx-react-lite' 3 - import { 4 - ActivityIndicator, 5 - StyleSheet, 6 - TouchableOpacity, 7 - View, 8 - } from 'react-native' 9 - import { 10 - FontAwesomeIcon, 11 - FontAwesomeIconStyle, 12 - } from '@fortawesome/react-native-fontawesome' 13 - import {CenteredView} from './Views' 3 + import {Animated, StyleSheet, TouchableOpacity, View} from 'react-native' 4 + import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 14 5 import {UserAvatar} from './UserAvatar' 15 6 import {Text} from './text/Text' 16 - import {MagnifyingGlassIcon} from '../../lib/icons' 17 - import {useStores} from '../../../state' 18 - import {usePalette} from '../../lib/hooks/usePalette' 19 - import {colors} from '../../lib/styles' 7 + import {useStores} from 'state/index' 8 + import {usePalette} from 'lib/hooks/usePalette' 9 + import {useAnimatedValue} from 'lib/hooks/useAnimatedValue' 10 + import {useAnalytics} from 'lib/analytics' 20 11 21 - const HITSLOP = {left: 10, top: 10, right: 10, bottom: 10} 22 12 const BACK_HITSLOP = {left: 10, top: 10, right: 30, bottom: 10} 23 13 24 14 export const ViewHeader = observer(function ViewHeader({ 25 15 title, 26 - subtitle, 27 16 canGoBack, 17 + hideOnScroll, 28 18 }: { 29 19 title: string 30 - subtitle?: string 31 20 canGoBack?: boolean 21 + hideOnScroll?: boolean 32 22 }) { 33 23 const pal = usePalette('default') 34 24 const store = useStores() 25 + const {track} = useAnalytics() 35 26 const onPressBack = () => { 36 27 store.nav.tab.goBack() 37 28 } 38 29 const onPressMenu = () => { 30 + track('ViewHeader:MenuButtonClicked') 39 31 store.shell.setMainMenuOpen(true) 40 32 } 41 - const onPressSearch = () => { 42 - store.nav.navigate('/search') 43 - } 44 - const onPressReconnect = () => { 45 - store.session.connect().catch(e => { 46 - store.log.warn('Failed to reconnect to server', e) 47 - }) 48 - } 49 33 if (typeof canGoBack === 'undefined') { 50 34 canGoBack = store.nav.tab.canGoBack 51 35 } 52 36 return ( 53 - <CenteredView style={[styles.header, pal.view]}> 37 + <Container hideOnScroll={hideOnScroll || false}> 54 38 <TouchableOpacity 55 39 testID="viewHeaderBackOrMenuBtn" 56 40 onPress={canGoBack ? onPressBack : onPressMenu} ··· 75 59 <Text type="title" style={[pal.text, styles.title]}> 76 60 {title} 77 61 </Text> 78 - {subtitle ? ( 79 - <Text 80 - type="title-sm" 81 - style={[styles.subtitle, pal.textLight]} 82 - numberOfLines={1}> 83 - {subtitle} 84 - </Text> 85 - ) : undefined} 86 62 </View> 87 - <TouchableOpacity 88 - onPress={onPressSearch} 89 - hitSlop={HITSLOP} 90 - style={styles.btn}> 91 - <MagnifyingGlassIcon size={21} strokeWidth={3} style={pal.text} /> 92 - </TouchableOpacity> 93 - {!store.session.online ? ( 94 - <TouchableOpacity style={styles.btn} onPress={onPressReconnect}> 95 - {store.session.attemptingConnect ? ( 96 - <ActivityIndicator /> 97 - ) : ( 98 - <> 99 - <FontAwesomeIcon 100 - icon="signal" 101 - style={pal.text as FontAwesomeIconStyle} 102 - size={16} 103 - /> 104 - <FontAwesomeIcon 105 - icon="x" 106 - style={[ 107 - styles.littleXIcon, 108 - {backgroundColor: pal.colors.background}, 109 - ]} 110 - size={8} 111 - /> 112 - </> 113 - )} 114 - </TouchableOpacity> 115 - ) : undefined} 116 - </CenteredView> 63 + <View style={canGoBack ? styles.backBtn : styles.backBtnWide} /> 64 + </Container> 117 65 ) 118 66 }) 119 67 68 + const Container = observer( 69 + ({ 70 + children, 71 + hideOnScroll, 72 + }: { 73 + children: React.ReactNode 74 + hideOnScroll: boolean 75 + }) => { 76 + const store = useStores() 77 + const pal = usePalette('default') 78 + const interp = useAnimatedValue(0) 79 + 80 + React.useEffect(() => { 81 + if (store.shell.minimalShellMode) { 82 + Animated.timing(interp, { 83 + toValue: 1, 84 + duration: 100, 85 + useNativeDriver: true, 86 + isInteraction: false, 87 + }).start() 88 + } else { 89 + Animated.timing(interp, { 90 + toValue: 0, 91 + duration: 100, 92 + useNativeDriver: true, 93 + isInteraction: false, 94 + }).start() 95 + } 96 + }, [interp, store.shell.minimalShellMode]) 97 + const transform = { 98 + transform: [{translateY: Animated.multiply(interp, -100)}], 99 + } 100 + 101 + if (!hideOnScroll) { 102 + return <View style={[styles.header, pal.view]}>{children}</View> 103 + } 104 + return ( 105 + <Animated.View 106 + style={[styles.header, pal.view, styles.headerFloating, transform]}> 107 + {children} 108 + </Animated.View> 109 + ) 110 + }, 111 + ) 112 + 120 113 const styles = StyleSheet.create({ 121 114 header: { 122 115 flexDirection: 'row', ··· 125 118 paddingTop: 6, 126 119 paddingBottom: 6, 127 120 }, 121 + headerFloating: { 122 + position: 'absolute', 123 + top: 0, 124 + width: '100%', 125 + }, 128 126 129 127 titleContainer: { 130 - flexDirection: 'row', 131 - alignItems: 'baseline', 128 + marginLeft: 'auto', 132 129 marginRight: 'auto', 130 + paddingRight: 10, 133 131 }, 134 132 title: { 135 133 fontWeight: 'bold', 136 134 }, 137 - subtitle: { 138 - marginLeft: 4, 139 - maxWidth: 200, 140 - fontWeight: 'normal', 141 - }, 142 135 143 136 backBtn: { 144 137 width: 30, ··· 151 144 }, 152 145 backIcon: { 153 146 marginTop: 6, 154 - }, 155 - btn: { 156 - flexDirection: 'row', 157 - alignItems: 'center', 158 - justifyContent: 'center', 159 - width: 36, 160 - height: 36, 161 - borderRadius: 20, 162 - marginLeft: 4, 163 - }, 164 - littleXIcon: { 165 - color: colors.red3, 166 - position: 'absolute', 167 - right: 7, 168 - bottom: 7, 169 147 }, 170 148 })
+5 -41
src/view/com/util/ViewHeader.web.tsx
··· 1 1 import React from 'react' 2 2 import {observer} from 'mobx-react-lite' 3 - import { 4 - ActivityIndicator, 5 - StyleSheet, 6 - TouchableOpacity, 7 - View, 8 - } from 'react-native' 9 - import { 10 - FontAwesomeIcon, 11 - FontAwesomeIconStyle, 12 - } from '@fortawesome/react-native-fontawesome' 3 + import {StyleSheet, TouchableOpacity, View} from 'react-native' 4 + import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 13 5 import {CenteredView} from './Views' 14 6 import {Text} from './text/Text' 15 - import {useStores} from '../../../state' 16 - import {usePalette} from '../../lib/hooks/usePalette' 17 - import {colors} from '../../lib/styles' 7 + import {useStores} from 'state/index' 8 + import {usePalette} from 'lib/hooks/usePalette' 9 + import {colors} from 'lib/styles' 18 10 19 11 const BACK_HITSLOP = {left: 10, top: 10, right: 30, bottom: 10} 20 12 ··· 31 23 const store = useStores() 32 24 const onPressBack = () => { 33 25 store.nav.tab.goBack() 34 - } 35 - const onPressReconnect = () => { 36 - store.session.connect().catch(e => { 37 - store.log.warn('Failed to reconnect to server', e) 38 - }) 39 26 } 40 27 if (typeof canGoBack === 'undefined') { 41 28 canGoBack = store.nav.tab.canGoBack ··· 76 63 </Text> 77 64 </View> 78 65 )} 79 - {!store.session.online ? ( 80 - <TouchableOpacity style={styles.btn} onPress={onPressReconnect}> 81 - {store.session.attemptingConnect ? ( 82 - <ActivityIndicator /> 83 - ) : ( 84 - <> 85 - <FontAwesomeIcon 86 - icon="signal" 87 - style={pal.text as FontAwesomeIconStyle} 88 - size={16} 89 - /> 90 - <FontAwesomeIcon 91 - icon="x" 92 - style={[ 93 - styles.littleXIcon, 94 - {backgroundColor: pal.colors.background}, 95 - ]} 96 - size={8} 97 - /> 98 - </> 99 - )} 100 - </TouchableOpacity> 101 - ) : undefined} 102 66 </CenteredView> 103 67 ) 104 68 })
+5 -4
src/view/com/util/ViewSelector.tsx
··· 3 3 import {Selector} from './Selector' 4 4 import {HorzSwipe} from './gestures/HorzSwipe' 5 5 import {FlatList} from './Views' 6 - import {useAnimatedValue} from '../../lib/hooks/useAnimatedValue' 7 - import {OnScrollCb} from '../../lib/hooks/useOnMainScroll' 8 - import {clamp} from '../../../lib/numbers' 9 - import {s} from '../../lib/styles' 6 + import {useAnimatedValue} from 'lib/hooks/useAnimatedValue' 7 + import {OnScrollCb} from 'lib/hooks/useOnMainScroll' 8 + import {clamp} from 'lib/numbers' 9 + import {s} from 'lib/styles' 10 10 11 11 const HEADER_ITEM = {_reactKey: '__header__'} 12 12 const SELECTOR_ITEM = {_reactKey: '__selector__'} ··· 101 101 onRefresh={onRefresh} 102 102 onEndReached={onEndReached} 103 103 contentContainerStyle={s.contentContainer} 104 + removeClippedSubviews={true} 104 105 /> 105 106 </HorzSwipe> 106 107 )
+2 -3
src/view/com/util/Views.web.tsx
··· 22 22 View, 23 23 ViewProps, 24 24 } from 'react-native' 25 - import {useTheme} from '../../lib/ThemeContext' 26 - import {addStyle} from '../../lib/addStyle' 27 - import {colors} from '../../lib/styles' 25 + import {useTheme} from 'lib/ThemeContext' 26 + import {addStyle, colors} from 'lib/styles' 28 27 29 28 export function CenteredView({ 30 29 style,
+73
src/view/com/util/anim/TriggerableAnimated.tsx
··· 1 + import React from 'react' 2 + import {Animated, StyleProp, View, ViewStyle} from 'react-native' 3 + import {useAnimatedValue} from 'lib/hooks/useAnimatedValue' 4 + 5 + type CreateAnimFn = (interp: Animated.Value) => Animated.CompositeAnimation 6 + type FinishCb = () => void 7 + 8 + interface TriggeredAnimation { 9 + start: CreateAnimFn 10 + style: ( 11 + interp: Animated.Value, 12 + ) => Animated.WithAnimatedValue<StyleProp<ViewStyle>> 13 + } 14 + 15 + export interface TriggerableAnimatedRef { 16 + trigger: (anim: TriggeredAnimation, onFinish?: FinishCb) => void 17 + } 18 + 19 + type TriggerableAnimatedProps = React.PropsWithChildren<{}> 20 + 21 + type PropsInner = TriggerableAnimatedProps & { 22 + anim: TriggeredAnimation 23 + onFinish: () => void 24 + } 25 + 26 + export const TriggerableAnimated = React.forwardRef< 27 + TriggerableAnimatedRef, 28 + TriggerableAnimatedProps 29 + >(({children, ...props}, ref) => { 30 + const [anim, setAnim] = React.useState<TriggeredAnimation | undefined>( 31 + undefined, 32 + ) 33 + const [finishCb, setFinishCb] = React.useState<FinishCb | undefined>( 34 + undefined, 35 + ) 36 + React.useImperativeHandle(ref, () => ({ 37 + trigger(v: TriggeredAnimation, cb?: FinishCb) { 38 + setFinishCb(() => cb) // note- wrap in function due to react behaviors around setstate 39 + setAnim(v) 40 + }, 41 + })) 42 + const onFinish = () => { 43 + finishCb?.() 44 + setAnim(undefined) 45 + setFinishCb(undefined) 46 + } 47 + return ( 48 + <View key="triggerable"> 49 + {anim ? ( 50 + <AnimatingView anim={anim} onFinish={onFinish} {...props}> 51 + {children} 52 + </AnimatingView> 53 + ) : ( 54 + children 55 + )} 56 + </View> 57 + ) 58 + }) 59 + 60 + function AnimatingView({ 61 + anim, 62 + onFinish, 63 + children, 64 + }: React.PropsWithChildren<PropsInner>) { 65 + const interp = useAnimatedValue(0) 66 + React.useEffect(() => { 67 + anim?.start(interp).start(() => { 68 + onFinish() 69 + }) 70 + }) 71 + const animStyle = anim?.style(interp) 72 + return <Animated.View style={animStyle}>{children}</Animated.View> 73 + }
+2 -2
src/view/com/util/error/ErrorMessage.tsx
··· 11 11 FontAwesomeIconStyle, 12 12 } from '@fortawesome/react-native-fontawesome' 13 13 import {Text} from '../text/Text' 14 - import {useTheme} from '../../../lib/ThemeContext' 15 - import {usePalette} from '../../../lib/hooks/usePalette' 14 + import {useTheme} from 'lib/ThemeContext' 15 + import {usePalette} from 'lib/hooks/usePalette' 16 16 17 17 export function ErrorMessage({ 18 18 message,
+3 -3
src/view/com/util/error/ErrorScreen.tsx
··· 5 5 FontAwesomeIconStyle, 6 6 } from '@fortawesome/react-native-fontawesome' 7 7 import {Text} from '../text/Text' 8 - import {colors} from '../../../lib/styles' 9 - import {useTheme} from '../../../lib/ThemeContext' 10 - import {usePalette} from '../../../lib/hooks/usePalette' 8 + import {colors} from 'lib/styles' 9 + import {useTheme} from 'lib/ThemeContext' 10 + import {usePalette} from 'lib/hooks/usePalette' 11 11 12 12 export function ErrorScreen({ 13 13 title,
+2 -2
src/view/com/util/forms/Button.tsx
··· 7 7 ViewStyle, 8 8 } from 'react-native' 9 9 import {Text} from '../text/Text' 10 - import {useTheme} from '../../../lib/ThemeContext' 11 - import {choose} from '../../../../lib/functions' 10 + import {useTheme} from 'lib/ThemeContext' 11 + import {choose} from 'lib/functions' 12 12 13 13 export type ButtonType = 14 14 | 'primary'
+83 -30
src/view/com/util/forms/DropdownButton.tsx
··· 13 13 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 14 14 import {Text} from '../text/Text' 15 15 import {Button, ButtonType} from './Button' 16 - import {colors} from '../../../lib/styles' 17 - import {toShareUrl} from '../../../../lib/strings' 18 - import {useStores} from '../../../../state' 19 - import {ReportPostModal, ConfirmModal} from '../../../../state/models/shell-ui' 20 - import {TABS_ENABLED} from '../../../../build-flags' 16 + import {colors} from 'lib/styles' 17 + import {toShareUrl} from 'lib/strings/url-helpers' 18 + import {useStores} from 'state/index' 19 + import {ReportPostModal, ConfirmModal} from 'state/models/shell-ui' 20 + import {TABS_ENABLED} from 'lib/build-flags' 21 + import {usePalette} from 'lib/hooks/usePalette' 22 + import {useTheme} from 'lib/ThemeContext' 21 23 22 24 const HITSLOP = {left: 10, top: 10, right: 10, bottom: 10} 23 25 ··· 36 38 label, 37 39 menuWidth, 38 40 children, 41 + openToRight = false, 42 + rightOffset = 0, 43 + bottomOffset = 0, 39 44 }: { 40 45 type?: DropdownButtonType 41 46 style?: StyleProp<ViewStyle> ··· 43 48 label?: string 44 49 menuWidth?: number 45 50 children?: React.ReactNode 51 + openToRight?: boolean 52 + rightOffset?: number 53 + bottomOffset?: number 46 54 }) { 47 55 const ref = useRef<TouchableOpacity>(null) 48 56 ··· 59 67 if (!menuWidth) { 60 68 menuWidth = 200 61 69 } 62 - createDropdownMenu( 63 - pageX + width - menuWidth, 64 - pageY + height, 65 - menuWidth, 66 - items, 67 - ) 70 + const newX = openToRight 71 + ? pageX + width + rightOffset 72 + : pageX + width - menuWidth 73 + const newY = pageY + height + bottomOffset 74 + createDropdownMenu(newX, newY, menuWidth, items) 68 75 }, 69 76 ) 70 77 } ··· 97 104 export function PostDropdownBtn({ 98 105 style, 99 106 children, 107 + itemUri, 108 + itemCid, 100 109 itemHref, 101 110 isAuthor, 102 111 onCopyPostText, ··· 104 113 }: { 105 114 style?: StyleProp<ViewStyle> 106 115 children?: React.ReactNode 116 + itemUri: string 117 + itemCid: string 107 118 itemHref: string 108 119 itemTitle: string 109 120 isAuthor: boolean ··· 140 151 icon: 'circle-exclamation', 141 152 label: 'Report post', 142 153 onPress() { 143 - store.shell.openModal(new ReportPostModal(itemHref)) 154 + store.shell.openModal(new ReportPostModal(itemUri, itemCid)) 144 155 }, 145 156 }, 146 157 isAuthor ··· 180 191 const onOuterPress = () => sibling.destroy() 181 192 const sibling = new RootSiblings( 182 193 ( 183 - <> 184 - <TouchableWithoutFeedback onPress={onOuterPress}> 185 - <View style={styles.bg} /> 186 - </TouchableWithoutFeedback> 187 - <View style={[styles.menu, {left: x, top: y, width}]}> 188 - {items.map((item, index) => ( 189 - <TouchableOpacity 190 - key={index} 191 - style={[styles.menuItem]} 192 - onPress={() => onPressItem(index)}> 193 - {item.icon && ( 194 - <FontAwesomeIcon style={styles.icon} icon={item.icon} /> 195 - )} 196 - <Text style={styles.label}>{item.label}</Text> 197 - </TouchableOpacity> 198 - ))} 199 - </View> 200 - </> 194 + <DropdownItems 195 + onOuterPress={onOuterPress} 196 + x={x} 197 + y={y} 198 + width={width} 199 + items={items} 200 + onPressItem={onPressItem} 201 + /> 201 202 ), 202 203 ) 203 204 return sibling ··· 241 242 fontSize: 18, 242 243 }, 243 244 }) 245 + type DropDownItemProps = { 246 + onOuterPress: () => void 247 + x: number 248 + y: number 249 + width: number 250 + items: DropdownItem[] 251 + onPressItem: (index: number) => void 252 + } 253 + 254 + const DropdownItems = ({ 255 + onOuterPress, 256 + x, 257 + y, 258 + width, 259 + items, 260 + onPressItem, 261 + }: DropDownItemProps) => { 262 + const pal = usePalette('default') 263 + const theme = useTheme() 264 + const dropDownBackgroundColor = 265 + theme.colorScheme === 'dark' ? pal.btn : pal.view 266 + 267 + return ( 268 + <> 269 + <TouchableWithoutFeedback onPress={onOuterPress}> 270 + <View style={[styles.bg]} /> 271 + </TouchableWithoutFeedback> 272 + <View 273 + style={[ 274 + styles.menu, 275 + {left: x, top: y, width}, 276 + dropDownBackgroundColor, 277 + ]}> 278 + {items.map((item, index) => ( 279 + <TouchableOpacity 280 + key={index} 281 + style={[styles.menuItem]} 282 + onPress={() => onPressItem(index)}> 283 + {item.icon && ( 284 + <FontAwesomeIcon 285 + style={styles.icon} 286 + icon={item.icon} 287 + color={pal.text.color as string} 288 + /> 289 + )} 290 + <Text style={[styles.label, pal.text]}>{item.label}</Text> 291 + </TouchableOpacity> 292 + ))} 293 + </View> 294 + </> 295 + ) 296 + }
+2 -2
src/view/com/util/forms/RadioButton.tsx
··· 2 2 import {StyleProp, StyleSheet, TextStyle, View, ViewStyle} from 'react-native' 3 3 import {Text} from '../text/Text' 4 4 import {Button, ButtonType} from './Button' 5 - import {useTheme} from '../../../lib/ThemeContext' 6 - import {choose} from '../../../../lib/functions' 5 + import {useTheme} from 'lib/ThemeContext' 6 + import {choose} from 'lib/functions' 7 7 8 8 export function RadioButton({ 9 9 type = 'default-light',
+1 -1
src/view/com/util/forms/RadioGroup.tsx
··· 2 2 import {View} from 'react-native' 3 3 import {RadioButton} from './RadioButton' 4 4 import {ButtonType} from './Button' 5 - import {s} from '../../../lib/styles' 5 + import {s} from 'lib/styles' 6 6 7 7 export interface RadioGroupItem { 8 8 label: string
+3 -3
src/view/com/util/forms/ToggleButton.tsx
··· 2 2 import {StyleProp, StyleSheet, TextStyle, View, ViewStyle} from 'react-native' 3 3 import {Text} from '../text/Text' 4 4 import {Button, ButtonType} from './Button' 5 - import {useTheme} from '../../../lib/ThemeContext' 6 - import {choose} from '../../../../lib/functions' 7 - import {colors} from '../../../lib/styles' 5 + import {useTheme} from 'lib/ThemeContext' 6 + import {choose} from 'lib/functions' 7 + import {colors} from 'lib/styles' 8 8 9 9 export function ToggleButton({ 10 10 type = 'default-light',
+4 -1
src/view/com/util/gestures/HorzSwipe.tsx
··· 9 9 View, 10 10 } from 'react-native' 11 11 import {clamp} from 'lodash' 12 - import {s} from '../../../lib/styles' 12 + import {s} from 'lib/styles' 13 13 14 14 interface Props { 15 15 panX: Animated.Value ··· 90 90 // swiping right 91 91 (diffX < 0 && !canSwipeRight) 92 92 ) { 93 + panX.setValue(0) 93 94 return 94 95 } 95 96 ··· 119 120 toValue: final, 120 121 duration: 100, 121 122 useNativeDriver, 123 + isInteraction: false, 122 124 }).start(() => { 123 125 onSwipeEnd?.(final) 124 126 panX.flattenOffset() ··· 130 132 toValue: 0, 131 133 duration: 100, 132 134 useNativeDriver, 135 + isInteraction: false, 133 136 }).start(() => { 134 137 panX.flattenOffset() 135 138 panX.setValue(0)
+1 -1
src/view/com/util/gestures/SwipeAndZoom.tsx
··· 9 9 View, 10 10 } from 'react-native' 11 11 import {clamp} from 'lodash' 12 - import {s} from '../../../lib/styles' 12 + import {s} from 'lib/styles' 13 13 14 14 export enum Dir { 15 15 None,
+36 -102
src/view/com/util/images/AutoSizedImage.tsx
··· 1 - import React, {useState, useEffect} from 'react' 2 - import { 3 - Image, 4 - ImageStyle, 5 - LayoutChangeEvent, 6 - StyleProp, 7 - StyleSheet, 8 - TouchableOpacity, 9 - View, 10 - ViewStyle, 11 - } from 'react-native' 12 - import {Text} from '../text/Text' 13 - import {useTheme} from '../../../lib/ThemeContext' 14 - import {usePalette} from '../../../lib/hooks/usePalette' 15 - import {DELAY_PRESS_IN} from './constants' 1 + import React from 'react' 2 + import {StyleProp, StyleSheet, TouchableOpacity, ViewStyle} from 'react-native' 3 + import Image, {OnLoadEvent} from 'view/com/util/images/Image' 4 + import {clamp} from 'lib/numbers' 16 5 17 - const MAX_HEIGHT = 300 18 - 19 - interface Dim { 20 - width: number 21 - height: number 22 - } 6 + export const DELAY_PRESS_IN = 500 7 + const MIN_ASPECT_RATIO = 0.33 // 1/3 8 + const MAX_ASPECT_RATIO = 5 // 5/1 23 9 24 10 export function AutoSizedImage({ 25 11 uri, 26 12 onPress, 27 13 onLongPress, 14 + onPressIn, 28 15 style, 29 - containerStyle, 16 + children = null, 30 17 }: { 31 18 uri: string 32 19 onPress?: () => void 33 20 onLongPress?: () => void 34 - style?: StyleProp<ImageStyle> 35 - containerStyle?: StyleProp<ViewStyle> 21 + onPressIn?: () => void 22 + style?: StyleProp<ViewStyle> 23 + children?: React.ReactNode 36 24 }) { 37 - const theme = useTheme() 38 - const errPal = usePalette('error') 39 - const [error, setError] = useState<string | undefined>('') 40 - const [imgInfo, setImgInfo] = useState<Dim | undefined>() 41 - const [containerInfo, setContainerInfo] = useState<Dim | undefined>() 42 - 43 - useEffect(() => { 44 - let aborted = false 45 - if (!imgInfo) { 46 - Image.getSize( 47 - uri, 48 - (width: number, height: number) => { 49 - if (!aborted) { 50 - setImgInfo({width, height}) 51 - } 52 - }, 53 - (err: any) => { 54 - if (!aborted) { 55 - setError(String(err)) 56 - } 57 - }, 58 - ) 59 - } 60 - return () => { 61 - aborted = true 62 - } 63 - }, [uri, imgInfo]) 64 - 65 - const onLayout = (evt: LayoutChangeEvent) => { 66 - setContainerInfo({ 67 - width: evt.nativeEvent.layout.width, 68 - height: evt.nativeEvent.layout.height, 69 - }) 70 - } 71 - 72 - let calculatedStyle: StyleProp<ImageStyle> | undefined 73 - if (imgInfo && containerInfo) { 74 - // imgInfo.height / imgInfo.width = x / containerInfo.width 75 - // x = imgInfo.height / imgInfo.width * containerInfo.width 76 - calculatedStyle = { 77 - height: Math.min( 78 - MAX_HEIGHT, 79 - (imgInfo.height / imgInfo.width) * containerInfo.width, 25 + const [aspectRatio, setAspectRatio] = React.useState<number>(1) 26 + const onLoad = (e: OnLoadEvent) => { 27 + setAspectRatio( 28 + clamp( 29 + e.nativeEvent.width / e.nativeEvent.height, 30 + MIN_ASPECT_RATIO, 31 + MAX_ASPECT_RATIO, 80 32 ), 81 - } 33 + ) 82 34 } 83 - 84 35 return ( 85 - <View style={style}> 86 - <TouchableOpacity 87 - onPress={onPress} 88 - onLongPress={onLongPress} 89 - delayPressIn={DELAY_PRESS_IN}> 90 - {error ? ( 91 - <View style={[styles.errorContainer, errPal.view, containerStyle]}> 92 - <Text style={errPal.text}>{error}</Text> 93 - </View> 94 - ) : calculatedStyle ? ( 95 - <View style={[styles.container, containerStyle]}> 96 - <Image style={calculatedStyle} source={{uri}} /> 97 - </View> 98 - ) : ( 99 - <View 100 - style={[ 101 - style, 102 - styles.placeholder, 103 - {backgroundColor: theme.palette.default.backgroundLight}, 104 - ]} 105 - onLayout={onLayout} 106 - /> 107 - )} 108 - </TouchableOpacity> 109 - </View> 36 + <TouchableOpacity 37 + onPress={onPress} 38 + onLongPress={onLongPress} 39 + onPressIn={onPressIn} 40 + delayPressIn={DELAY_PRESS_IN} 41 + style={[styles.container, style]}> 42 + <Image 43 + style={[styles.image, {aspectRatio}]} 44 + source={{uri}} 45 + onLoad={onLoad} 46 + /> 47 + {children} 48 + </TouchableOpacity> 110 49 ) 111 50 } 112 51 113 52 const styles = StyleSheet.create({ 114 - placeholder: { 115 - width: '100%', 116 - aspectRatio: 1, 117 - }, 118 - errorContainer: { 119 - paddingHorizontal: 12, 120 - paddingVertical: 8, 121 - }, 122 53 container: { 123 54 overflow: 'hidden', 55 + }, 56 + image: { 57 + width: '100%', 124 58 }, 125 59 })
+12
src/view/com/util/images/Image.tsx
··· 1 + import React from 'react' 2 + import FastImage, {FastImageProps, Source} from 'react-native-fast-image' 3 + export default FastImage 4 + export type {OnLoadEvent, ImageStyle, Source} from 'react-native-fast-image' 5 + 6 + export function HighPriorityImage({source, ...props}: FastImageProps) { 7 + const updatedSource = { 8 + uri: typeof source === 'object' && source ? source.uri : '', 9 + priority: FastImage.priority.high, 10 + } as Source 11 + return <FastImage source={updatedSource} {...props} /> 12 + }
+11
src/view/com/util/images/Image.web.tsx
··· 1 + import { 2 + Image, 3 + NativeSyntheticEvent, 4 + ImageLoadEventData, 5 + ImageSourcePropType, 6 + } from 'react-native' 7 + export default Image 8 + export const HighPriorityImage = Image 9 + export type OnLoadEvent = NativeSyntheticEvent<ImageLoadEventData> 10 + export type Source = ImageSourcePropType 11 + export type {ImageStyle} from 'react-native'
+1 -1
src/view/com/util/images/ImageHorzList.tsx
··· 1 1 import React from 'react' 2 2 import { 3 - Image, 4 3 StyleProp, 5 4 StyleSheet, 6 5 TouchableWithoutFeedback, 7 6 View, 8 7 ViewStyle, 9 8 } from 'react-native' 9 + import Image from 'view/com/util/images/Image' 10 10 11 11 export function ImageHorzList({ 12 12 uris,
+25 -11
src/view/com/util/images/ImageLayoutGrid.tsx
··· 1 1 import React from 'react' 2 2 import { 3 - Image, 4 - ImageStyle, 5 3 LayoutChangeEvent, 6 4 StyleProp, 7 5 StyleSheet, ··· 9 7 View, 10 8 ViewStyle, 11 9 } from 'react-native' 12 - import {DELAY_PRESS_IN} from './constants' 10 + import Image, {ImageStyle} from 'view/com/util/images/Image' 11 + 12 + export const DELAY_PRESS_IN = 500 13 13 14 14 interface Dim { 15 15 width: number ··· 23 23 uris, 24 24 onPress, 25 25 onLongPress, 26 + onPressIn, 26 27 style, 27 28 }: { 28 29 type: ImageLayoutGridType 29 30 uris: string[] 30 31 onPress?: (index: number) => void 31 32 onLongPress?: (index: number) => void 33 + onPressIn?: (index: number) => void 32 34 style?: StyleProp<ViewStyle> 33 35 }) { 34 36 const [containerInfo, setContainerInfo] = React.useState<Dim | undefined>() ··· 47 49 type={type} 48 50 uris={uris} 49 51 onPress={onPress} 52 + onPressIn={onPressIn} 50 53 onLongPress={onLongPress} 51 54 containerInfo={containerInfo} 52 55 /> ··· 60 63 uris, 61 64 onPress, 62 65 onLongPress, 66 + onPressIn, 63 67 containerInfo, 64 68 }: { 65 69 type: ImageLayoutGridType 66 70 uris: string[] 67 71 onPress?: (index: number) => void 68 72 onLongPress?: (index: number) => void 73 + onPressIn?: (index: number) => void 69 74 containerInfo: Dim 70 75 }) { 71 - const size1 = React.useMemo<ImageStyle>(() => { 76 + const size1 = React.useMemo<StyleProp<ImageStyle>>(() => { 72 77 if (type === 'three') { 73 78 const size = (containerInfo.width - 10) / 3 74 79 return {width: size, height: size, resizeMode: 'cover', borderRadius: 4} ··· 77 82 return {width: size, height: size, resizeMode: 'cover', borderRadius: 4} 78 83 } 79 84 }, [type, containerInfo]) 80 - const size2 = React.useMemo<ImageStyle>(() => { 85 + const size2 = React.useMemo<StyleProp<ImageStyle>>(() => { 81 86 if (type === 'three') { 82 87 const size = ((containerInfo.width - 10) / 3) * 2 + 5 83 88 return {width: size, height: size, resizeMode: 'cover', borderRadius: 4} ··· 93 98 <TouchableOpacity 94 99 delayPressIn={DELAY_PRESS_IN} 95 100 onPress={() => onPress?.(0)} 101 + onPressIn={() => onPressIn?.(0)} 96 102 onLongPress={() => onLongPress?.(0)}> 97 103 <Image source={{uri: uris[0]}} style={size1} /> 98 104 </TouchableOpacity> ··· 100 106 <TouchableOpacity 101 107 delayPressIn={DELAY_PRESS_IN} 102 108 onPress={() => onPress?.(1)} 109 + onPressIn={() => onPressIn?.(1)} 103 110 onLongPress={() => onLongPress?.(1)}> 104 111 <Image source={{uri: uris[1]}} style={size1} /> 105 112 </TouchableOpacity> ··· 112 119 <TouchableOpacity 113 120 delayPressIn={DELAY_PRESS_IN} 114 121 onPress={() => onPress?.(0)} 122 + onPressIn={() => onPressIn?.(0)} 115 123 onLongPress={() => onLongPress?.(0)}> 116 124 <Image source={{uri: uris[0]}} style={size2} /> 117 125 </TouchableOpacity> ··· 120 128 <TouchableOpacity 121 129 delayPressIn={DELAY_PRESS_IN} 122 130 onPress={() => onPress?.(1)} 131 + onPressIn={() => onPressIn?.(1)} 123 132 onLongPress={() => onLongPress?.(1)}> 124 133 <Image source={{uri: uris[1]}} style={size1} /> 125 134 </TouchableOpacity> ··· 127 136 <TouchableOpacity 128 137 delayPressIn={DELAY_PRESS_IN} 129 138 onPress={() => onPress?.(2)} 139 + onPressIn={() => onPressIn?.(2)} 130 140 onLongPress={() => onLongPress?.(2)}> 131 141 <Image source={{uri: uris[2]}} style={size1} /> 132 142 </TouchableOpacity> ··· 141 151 <TouchableOpacity 142 152 delayPressIn={DELAY_PRESS_IN} 143 153 onPress={() => onPress?.(0)} 154 + onPressIn={() => onPressIn?.(0)} 144 155 onLongPress={() => onLongPress?.(0)}> 145 156 <Image source={{uri: uris[0]}} style={size1} /> 146 157 </TouchableOpacity> 147 158 <View style={styles.hSpace} /> 148 159 <TouchableOpacity 149 160 delayPressIn={DELAY_PRESS_IN} 150 - onPress={() => onPress?.(1)} 151 - onLongPress={() => onLongPress?.(1)}> 152 - <Image source={{uri: uris[1]}} style={size1} /> 161 + onPress={() => onPress?.(2)} 162 + onPressIn={() => onPressIn?.(2)} 163 + onLongPress={() => onLongPress?.(2)}> 164 + <Image source={{uri: uris[2]}} style={size1} /> 153 165 </TouchableOpacity> 154 166 </View> 155 167 <View style={styles.wSpace} /> 156 168 <View> 157 169 <TouchableOpacity 158 170 delayPressIn={DELAY_PRESS_IN} 159 - onPress={() => onPress?.(2)} 160 - onLongPress={() => onLongPress?.(2)}> 161 - <Image source={{uri: uris[2]}} style={size1} /> 171 + onPress={() => onPress?.(1)} 172 + onPressIn={() => onPressIn?.(1)} 173 + onLongPress={() => onLongPress?.(1)}> 174 + <Image source={{uri: uris[1]}} style={size1} /> 162 175 </TouchableOpacity> 163 176 <View style={styles.hSpace} /> 164 177 <TouchableOpacity 165 178 delayPressIn={DELAY_PRESS_IN} 166 179 onPress={() => onPress?.(3)} 180 + onPressIn={() => onPressIn?.(3)} 167 181 onLongPress={() => onLongPress?.(3)}> 168 182 <Image source={{uri: uris[3]}} style={size1} /> 169 183 </TouchableOpacity>
-1
src/view/com/util/images/constants.ts
··· 1 - export const DELAY_PRESS_IN = 500
+1 -1
src/view/com/util/images/image-crop-picker/ImageCropPicker.tsx
··· 4 4 openCropper as openCropperFn, 5 5 ImageOrVideo, 6 6 } from 'react-native-image-crop-picker' 7 - import {RootStoreModel} from '../../../../../state' 7 + import {RootStoreModel} from 'state/index' 8 8 import {PickerOpts, CameraOpts, CropperOpts, PickedMedia} from './types' 9 9 export type {PickedMedia} from './types' 10 10
+6 -6
src/view/com/util/images/image-crop-picker/ImageCropPicker.web.tsx
··· 1 1 /// <reference lib="dom" /> 2 2 3 - import {CropImageModal} from '../../../../../state/models/shell-ui' 3 + import {CropImageModal} from 'state/models/shell-ui' 4 4 import {PickerOpts, CameraOpts, CropperOpts, PickedMedia} from './types' 5 5 export type {PickedMedia} from './types' 6 - import {RootStoreModel} from '../../../../../state' 6 + import {RootStoreModel} from 'state/index' 7 7 8 8 interface PickedFile { 9 9 uri: string ··· 31 31 32 32 export async function openCamera( 33 33 _store: RootStoreModel, 34 - opts: CameraOpts, 34 + _opts: CameraOpts, 35 35 ): Promise<PickedMedia> { 36 - const mediaType = opts.mediaType || 'photo' 36 + // const mediaType = opts.mediaType || 'photo' TODO 37 37 throw new Error('TODO') 38 38 } 39 39 40 40 export async function openCropper( 41 41 _store: RootStoreModel, 42 - opts: CropperOpts, 42 + _opts: CropperOpts, 43 43 ): Promise<PickedMedia> { 44 - const mediaType = opts.mediaType || 'photo' 44 + // const mediaType = opts.mediaType || 'photo' TODO 45 45 throw new Error('TODO') 46 46 } 47 47
+13 -15
src/view/com/util/text/RichText.tsx
··· 2 2 import {TextStyle, StyleProp} from 'react-native' 3 3 import {TextLink} from '../Link' 4 4 import {Text} from './Text' 5 - import {lh} from '../../../lib/styles' 6 - import {toShortUrl} from '../../../../lib/strings' 7 - import {useTheme, TypographyVariant} from '../../../lib/ThemeContext' 8 - import {usePalette} from '../../../lib/hooks/usePalette' 9 - 10 - type TextSlice = {start: number; end: number} 11 - type Entity = { 12 - index: TextSlice 13 - type: string 14 - value: string 15 - } 5 + import {lh} from 'lib/styles' 6 + import {toShortUrl} from 'lib/strings/url-helpers' 7 + import {RichText as RichTextObj, Entity} from 'lib/strings/rich-text' 8 + import {useTheme, TypographyVariant} from 'lib/ThemeContext' 9 + import {usePalette} from 'lib/hooks/usePalette' 16 10 17 11 export function RichText({ 18 12 type = 'md', 19 - text, 20 - entities, 13 + richText, 21 14 lineHeight = 1.2, 22 15 style, 23 16 numberOfLines, 24 17 }: { 25 18 type?: TypographyVariant 26 - text: string 27 - entities?: Entity[] 19 + richText?: RichTextObj 28 20 lineHeight?: number 29 21 style?: StyleProp<TextStyle> 30 22 numberOfLines?: number ··· 32 24 const theme = useTheme() 33 25 const pal = usePalette('default') 34 26 const lineHeightStyle = lh(theme, type, lineHeight) 27 + 28 + if (!richText) { 29 + return null 30 + } 31 + 32 + const {text, entities} = richText 35 33 if (!entities?.length) { 36 34 if (/^\p{Extended_Pictographic}+$/u.test(text) && text.length <= 5) { 37 35 style = {
+2 -2
src/view/com/util/text/Text.tsx
··· 1 1 import React from 'react' 2 2 import {Text as RNText, TextProps} from 'react-native' 3 - import {s} from '../../../lib/styles' 4 - import {useTheme, TypographyVariant} from '../../../lib/ThemeContext' 3 + import {s} from 'lib/styles' 4 + import {useTheme, TypographyVariant} from 'lib/ThemeContext' 5 5 6 6 export type CustomTextProps = TextProps & { 7 7 type?: TypographyVariant
+4
src/view/index.ts
··· 65 65 import {faTrashCan} from '@fortawesome/free-regular-svg-icons/faTrashCan' 66 66 import {faX} from '@fortawesome/free-solid-svg-icons/faX' 67 67 import {faXmark} from '@fortawesome/free-solid-svg-icons/faXmark' 68 + import {faPlay} from '@fortawesome/free-solid-svg-icons/faPlay' 69 + import {faPause} from '@fortawesome/free-solid-svg-icons/faPause' 68 70 69 71 export function setup() { 70 72 library.add( ··· 133 135 faTrashCan, 134 136 faX, 135 137 faXmark, 138 + faPlay, 139 + faPause, 136 140 ) 137 141 }
+2
src/view/lib/ThemeContext.tsx src/lib/ThemeContext.tsx
··· 53 53 | 'xs-medium' 54 54 | 'xs-bold' 55 55 | 'xs-heavy' 56 + | 'title-2xl' 56 57 | 'title-xl' 57 58 | 'title-lg' 58 59 | 'title' ··· 60 61 | 'post-text-lg' 61 62 | 'post-text' 62 63 | 'button' 64 + | 'button-lg' 63 65 | 'mono' 64 66 export type Typography = Record<TypographyVariant, TextStyle> 65 67
-11
src/view/lib/addStyle.ts
··· 1 - import {StyleProp} from 'react-native' 2 - 3 - export function addStyle<T>( 4 - base: StyleProp<T>, 5 - addedStyle: StyleProp<T>, 6 - ): StyleProp<T> { 7 - if (Array.isArray(base)) { 8 - return base.concat([addedStyle]) 9 - } 10 - return [base, addedStyle] 11 - }
-5
src/view/lib/assets.native.ts
··· 1 - import {ImageSourcePropType} from 'react-native' 2 - 3 - export const DEF_AVATAR: ImageSourcePropType = require('../../../public/img/default-avatar.jpg') 4 - export const TABS_EXPLAINER: ImageSourcePropType = require('../../../public/img/tabs-explainer.jpg') 5 - export const CLOUD_SPLASH: ImageSourcePropType = require('../../../public/img/cloud-splash.png')
-7
src/view/lib/assets.ts
··· 1 - import {ImageSourcePropType} from 'react-native' 2 - 3 - export const DEF_AVATAR: ImageSourcePropType = {uri: '/img/default-avatar.jpg'} 4 - export const TABS_EXPLAINER: ImageSourcePropType = { 5 - uri: '/img/tabs-explainer.jpg', 6 - } 7 - export const CLOUD_SPLASH: ImageSourcePropType = {uri: '/img/cloud-splash.png'}
src/view/lib/hooks/useAnimatedValue.ts src/lib/hooks/useAnimatedValue.ts
+1 -1
src/view/lib/hooks/useOnMainScroll.ts src/lib/hooks/useOnMainScroll.ts
··· 1 1 import {useState} from 'react' 2 2 import {NativeSyntheticEvent, NativeScrollEvent} from 'react-native' 3 - import {RootStoreModel} from '../../../state' 3 + import {RootStoreModel} from 'state/index' 4 4 5 5 export type OnScrollCb = ( 6 6 event: NativeSyntheticEvent<NativeScrollEvent>,
src/view/lib/hooks/usePalette.ts src/lib/hooks/usePalette.ts
src/view/lib/icons.tsx src/lib/icons.tsx
-54
src/view/lib/notifee.ts
··· 1 - import notifee from '@notifee/react-native' 2 - import {AppBskyEmbedImages} from '@atproto/api' 3 - import {NotificationsViewItemModel} from '../../state/models/notifications-view' 4 - import {enforceLen} from '../../lib/strings' 5 - 6 - export function displayNotification( 7 - title: string, 8 - body?: string, 9 - image?: string, 10 - ) { 11 - const opts: {title: string; body?: string; ios?: any} = {title} 12 - if (body) { 13 - opts.body = enforceLen(body, 70, true) 14 - } 15 - if (image) { 16 - opts.ios = { 17 - attachments: [{url: image}], 18 - } 19 - } 20 - return notifee.displayNotification(opts) 21 - } 22 - 23 - export function displayNotificationFromModel( 24 - notif: NotificationsViewItemModel, 25 - ) { 26 - let author = notif.author.displayName || notif.author.handle 27 - let title: string 28 - let body: string = '' 29 - if (notif.isUpvote) { 30 - title = `${author} liked your post` 31 - body = notif.additionalPost?.thread?.postRecord?.text || '' 32 - } else if (notif.isRepost) { 33 - title = `${author} reposted your post` 34 - body = notif.additionalPost?.thread?.postRecord?.text || '' 35 - } else if (notif.isMention) { 36 - title = `${author} mentioned you` 37 - body = notif.additionalPost?.thread?.postRecord?.text || '' 38 - } else if (notif.isReply) { 39 - title = `${author} replied to your post` 40 - body = notif.additionalPost?.thread?.postRecord?.text || '' 41 - } else if (notif.isFollow) { 42 - title = `${author} followed you` 43 - } else { 44 - return 45 - } 46 - let image 47 - if ( 48 - AppBskyEmbedImages.isPresented(notif.additionalPost?.thread?.post.embed) && 49 - notif.additionalPost?.thread?.post.embed.images[0]?.thumb 50 - ) { 51 - image = notif.additionalPost.thread.post.embed.images[0].thumb 52 - } 53 - return displayNotification(title, body, image) 54 - }
+11 -1
src/view/lib/styles.ts src/lib/styles.ts
··· 1 - import {StyleSheet, TextStyle} from 'react-native' 1 + import {StyleProp, StyleSheet, TextStyle} from 'react-native' 2 2 import {Theme, TypographyVariant} from './ThemeContext' 3 3 4 4 // 1 is lightest, 2 is light, 3 is mid, 4 is dark, 5 is darkest ··· 206 206 lineHeight: (theme.typography[type].fontSize || 16) * height, 207 207 } 208 208 } 209 + 210 + export function addStyle<T>( 211 + base: StyleProp<T>, 212 + addedStyle: StyleProp<T>, 213 + ): StyleProp<T> { 214 + if (Array.isArray(base)) { 215 + return base.concat([addedStyle]) 216 + } 217 + return [base, addedStyle] 218 + }
+13 -3
src/view/lib/themes.ts src/lib/themes.ts
··· 14 14 link: colors.blue3, 15 15 border: '#f0e9e9', 16 16 borderDark: '#e0d9d9', 17 - icon: colors.gray3, 17 + icon: colors.gray4, 18 18 19 19 // non-standard 20 20 textVeryLight: colors.gray4, ··· 208 208 fontWeight: '800', 209 209 }, 210 210 211 + 'title-2xl': { 212 + fontSize: 34, 213 + letterSpacing: 0.25, 214 + fontWeight: '500', 215 + }, 211 216 'title-xl': { 212 - fontSize: 34, 217 + fontSize: 28, 213 218 letterSpacing: 0.25, 214 219 fontWeight: '500', 215 220 }, ··· 237 242 letterSpacing: 0.4, 238 243 fontWeight: '400', 239 244 }, 245 + 'button-lg': { 246 + fontWeight: '500', 247 + fontSize: 18, 248 + letterSpacing: 0.5, 249 + }, 240 250 button: { 241 251 fontWeight: '500', 242 252 fontSize: 14, ··· 263 273 link: colors.blue3, 264 274 border: colors.gray6, 265 275 borderDark: colors.gray5, 266 - icon: colors.gray5, 276 + icon: colors.gray4, 267 277 268 278 // non-standard 269 279 textVeryLight: colors.gray4,
+1 -3
src/view/routes.ts
··· 1 - import React, {MutableRefObject} from 'react' 2 - import {FlatList} from 'react-native' 1 + import React from 'react' 3 2 import {IconProp} from '@fortawesome/fontawesome-svg-core' 4 3 import {Home} from './screens/Home' 5 4 import {Contacts} from './screens/Contacts' ··· 21 20 navIdx: string 22 21 params: Record<string, any> 23 22 visible: boolean 24 - scrollElRef?: MutableRefObject<FlatList<any> | null> 25 23 } 26 24 export type Route = [React.FC<ScreenParams>, string, IconProp, RegExp] 27 25 export type MatchResult = {
+3 -3
src/view/screens/Contacts.tsx
··· 4 4 import {ProfileFollows as ProfileFollowsComponent} from '../com/profile/ProfileFollows' 5 5 import {Selector} from '../com/util/Selector' 6 6 import {Text} from '../com/util/text/Text' 7 - import {colors} from '../lib/styles' 7 + import {colors} from 'lib/styles' 8 8 import {ScreenParams} from '../routes' 9 - import {useStores} from '../../state' 10 - import {useAnimatedValue} from '../lib/hooks/useAnimatedValue' 9 + import {useStores} from 'state/index' 10 + import {useAnimatedValue} from 'lib/hooks/useAnimatedValue' 11 11 12 12 export const Contacts = ({navIdx, visible}: ScreenParams) => { 13 13 const store = useStores()
+10 -5
src/view/screens/Debug.tsx
··· 1 1 import React from 'react' 2 2 import {ScrollView, View} from 'react-native' 3 3 import {ViewHeader} from '../com/util/ViewHeader' 4 - import {ThemeProvider} from '../lib/ThemeContext' 5 - import {PaletteColorName} from '../lib/ThemeContext' 6 - import {usePalette} from '../lib/hooks/usePalette' 7 - import {s} from '../lib/styles' 8 - import {displayNotification} from '../lib/notifee' 4 + import {ThemeProvider, PaletteColorName} from 'lib/ThemeContext' 5 + import {usePalette} from 'lib/hooks/usePalette' 6 + import {s} from 'lib/styles' 7 + import {displayNotification} from 'lib/notifee' 9 8 10 9 import {Text} from '../com/util/text/Text' 11 10 import {ViewSelector} from '../com/util/ViewSelector' ··· 284 283 'xs-heavy' lorem ipsum dolor 285 284 </Text> 286 285 286 + <Text type="title-2xl" style={[pal.text]}> 287 + 'title-2xl' lorem ipsum dolor 288 + </Text> 287 289 <Text type="title-xl" style={[pal.text]}> 288 290 'title-xl' lorem ipsum dolor 289 291 </Text> ··· 295 297 </Text> 296 298 <Text type="button" style={[pal.text]}> 297 299 Button 300 + </Text> 301 + <Text type="button-lg" style={[pal.text]}> 302 + Button-lg 298 303 </Text> 299 304 </View> 300 305 )
+38 -20
src/view/screens/Home.tsx
··· 1 1 import React, {useEffect} from 'react' 2 - import {View} from 'react-native' 2 + import {FlatList, View} from 'react-native' 3 3 import {observer} from 'mobx-react-lite' 4 4 import useAppState from 'react-native-appstate-hook' 5 5 import {ViewHeader} from '../com/util/ViewHeader' 6 6 import {Feed} from '../com/posts/Feed' 7 7 import {FAB} from '../com/util/FAB' 8 8 import {LoadLatestBtn} from '../com/util/LoadLatestBtn' 9 - import {useStores} from '../../state' 9 + import {useStores} from 'state/index' 10 10 import {ScreenParams} from '../routes' 11 - import {s} from '../lib/styles' 12 - import {useOnMainScroll} from '../lib/hooks/useOnMainScroll' 11 + import {s} from 'lib/styles' 12 + import {useOnMainScroll} from 'lib/hooks/useOnMainScroll' 13 + import {useAnalytics} from 'lib/analytics' 14 + 15 + const HEADER_HEIGHT = 42 13 16 14 - export const Home = observer(function Home({ 15 - navIdx, 16 - visible, 17 - scrollElRef, 18 - }: ScreenParams) { 17 + export const Home = observer(function Home({navIdx, visible}: ScreenParams) { 19 18 const store = useStores() 20 19 const onMainScroll = useOnMainScroll(store) 20 + const {screen, track} = useAnalytics() 21 + const scrollElRef = React.useRef<FlatList>(null) 21 22 const [wasVisible, setWasVisible] = React.useState<boolean>(false) 22 23 const {appState} = useAppState({ 23 24 onForeground: () => doPoll(true), ··· 31 32 if (store.me.mainFeed.isLoading) { 32 33 return 33 34 } 34 - store.log.debug('Polling home feed') 35 - store.me.mainFeed.checkForLatest().catch(e => { 36 - store.log.error('Failed to poll feed', e) 37 - }) 35 + store.log.debug('HomeScreen: Polling for new posts') 36 + store.me.mainFeed.checkForLatest() 38 37 }, 39 38 [appState, visible, store], 40 39 ) 41 40 41 + const scrollToTop = React.useCallback(() => { 42 + // NOTE: the feed is offset by the height of the collapsing header, 43 + // so we scroll to the negative of that height -prf 44 + scrollElRef.current?.scrollToOffset({offset: -HEADER_HEIGHT}) 45 + }, [scrollElRef]) 46 + 42 47 useEffect(() => { 48 + const softResetSub = store.onScreenSoftReset(scrollToTop) 43 49 const feedCleanup = store.me.mainFeed.registerListeners() 44 - const pollInterval = setInterval(() => doPoll(), 15e3) 50 + const pollInterval = setInterval(doPoll, 15e3) 45 51 const cleanup = () => { 46 52 clearInterval(pollInterval) 53 + softResetSub.remove() 47 54 feedCleanup() 48 55 } 49 56 57 + // guard to only continue when transitioning from !visible -> visible 58 + // TODO is this 100% needed? depends on if useEffect() is getting refired 59 + // for reasons other than `visible` changing -prf 50 60 if (!visible) { 51 61 setWasVisible(false) 52 62 return cleanup ··· 55 65 } 56 66 setWasVisible(true) 57 67 68 + // just became visible 69 + screen('Feed') 58 70 store.nav.setTitle(navIdx, 'Home') 59 - store.log.debug('Updating home feed') 71 + store.log.debug('HomeScreen: Updating feed') 60 72 if (store.me.mainFeed.hasContent) { 61 73 store.me.mainFeed.update() 62 74 } else { 63 75 store.me.mainFeed.setup() 64 76 } 65 77 return cleanup 66 - }, [visible, store, navIdx, doPoll, wasVisible]) 78 + }, [visible, store, store.me.mainFeed, navIdx, doPoll, wasVisible, scrollToTop, screen]) 67 79 68 80 const onPressCompose = (imagesOpen?: boolean) => { 81 + track('Home:ComposeButtonPressed') 69 82 store.shell.openComposer({imagesOpen}) 70 83 } 71 84 const onPressTryAgain = () => { ··· 73 86 } 74 87 const onPressLoadLatest = () => { 75 88 store.me.mainFeed.refresh() 76 - scrollElRef?.current?.scrollToOffset({offset: 0}) 89 + scrollToTop() 77 90 } 78 91 79 92 return ( 80 93 <View style={s.h100pct}> 81 - <ViewHeader title="Bluesky" subtitle="Private Beta" canGoBack={false} /> 82 94 <Feed 83 95 testID="homeFeed" 84 96 key="default" 85 97 feed={store.me.mainFeed} 86 98 scrollElRef={scrollElRef} 87 99 style={s.h100pct} 88 - onPressCompose={onPressCompose} 89 100 onPressTryAgain={onPressTryAgain} 101 + onPressCompose={onPressCompose} 90 102 onScroll={onMainScroll} 103 + headerOffset={HEADER_HEIGHT} 91 104 /> 105 + <ViewHeader title="Bluesky" canGoBack={false} hideOnScroll /> 92 106 {store.me.mainFeed.hasNewLatest && !store.me.mainFeed.isRefreshing && ( 93 107 <LoadLatestBtn onPress={onPressLoadLatest} /> 94 108 )} 95 - <FAB icon="pen-nib" onPress={() => onPressCompose(false)} /> 109 + <FAB 110 + testID="composeFAB" 111 + icon="plus" 112 + onPress={() => onPressCompose(false)} 113 + /> 96 114 </View> 97 115 ) 98 116 })
+4 -4
src/view/screens/Log.tsx
··· 3 3 import {observer} from 'mobx-react-lite' 4 4 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 5 5 import {ScrollView} from '../com/util/Views' 6 - import {useStores} from '../../state' 6 + import {useStores} from 'state/index' 7 7 import {ScreenParams} from '../routes' 8 - import {s} from '../lib/styles' 8 + import {s} from 'lib/styles' 9 9 import {ViewHeader} from '../com/util/ViewHeader' 10 10 import {Text} from '../com/util/text/Text' 11 - import {usePalette} from '../lib/hooks/usePalette' 12 - import {ago} from '../../lib/strings' 11 + import {usePalette} from 'lib/hooks/usePalette' 12 + import {ago} from 'lib/strings/time' 13 13 14 14 export const Log = observer(function Log({navIdx, visible}: ScreenParams) { 15 15 const pal = usePalette('default')
+28 -19
src/view/screens/Login.tsx
··· 1 - import React, {useState} from 'react' 2 - import { 3 - Image, 4 - SafeAreaView, 5 - StyleSheet, 6 - TouchableOpacity, 7 - View, 8 - } from 'react-native' 1 + import React, {useEffect, useState} from 'react' 2 + import {SafeAreaView, StyleSheet, TouchableOpacity, View} from 'react-native' 3 + import Image, {Source as ImageSource} from 'view/com/util/images/Image' 9 4 import {observer} from 'mobx-react-lite' 10 5 import {Signin} from '../com/login/Signin' 11 6 import {CreateAccount} from '../com/login/CreateAccount' 12 7 import {Text} from '../com/util/text/Text' 13 8 import {ErrorBoundary} from '../com/util/ErrorBoundary' 14 - import {colors} from '../lib/styles' 15 - import {usePalette} from '../lib/hooks/usePalette' 16 - import {CLOUD_SPLASH} from '../lib/assets' 9 + import {colors} from 'lib/styles' 10 + import {usePalette} from 'lib/hooks/usePalette' 11 + import {useStores} from 'state/index' 12 + import {CLOUD_SPLASH} from 'lib/assets' 13 + import {useAnalytics} from 'lib/analytics' 17 14 18 15 enum ScreenState { 19 16 S_SigninOrCreateAccount, ··· 28 25 onPressSignin: () => void 29 26 onPressCreateAccount: () => void 30 27 }) => { 28 + const {screen} = useAnalytics() 29 + 30 + useEffect(() => { 31 + screen('Login') 32 + }, [screen]) 33 + 31 34 const pal = usePalette('default') 32 35 return ( 33 36 <> ··· 57 60 58 61 export const Login = observer(() => { 59 62 const pal = usePalette('default') 63 + const store = useStores() 60 64 const [screenState, setScreenState] = useState<ScreenState>( 61 65 ScreenState.S_SigninOrCreateAccount, 62 66 ) 63 67 64 - if (screenState === ScreenState.S_SigninOrCreateAccount) { 68 + if ( 69 + store.session.isResumingSession || 70 + screenState === ScreenState.S_SigninOrCreateAccount 71 + ) { 65 72 return ( 66 73 <View style={styles.container}> 67 - <Image source={CLOUD_SPLASH} style={styles.bgImg} /> 74 + <Image source={CLOUD_SPLASH as ImageSource} style={styles.bgImg} /> 68 75 <SafeAreaView testID="noSessionView" style={styles.container}> 69 76 <ErrorBoundary> 70 - <SigninOrCreateAccount 71 - onPressSignin={() => setScreenState(ScreenState.S_Signin)} 72 - onPressCreateAccount={() => 73 - setScreenState(ScreenState.S_CreateAccount) 74 - } 75 - /> 77 + {!store.session.isResumingSession && ( 78 + <SigninOrCreateAccount 79 + onPressSignin={() => setScreenState(ScreenState.S_Signin)} 80 + onPressCreateAccount={() => 81 + setScreenState(ScreenState.S_CreateAccount) 82 + } 83 + /> 84 + )} 76 85 </ErrorBoundary> 77 86 </SafeAreaView> 78 87 </View>
+4 -10
src/view/screens/Login.web.tsx
··· 1 1 import React, {useState} from 'react' 2 - import { 3 - Image, 4 - SafeAreaView, 5 - StyleSheet, 6 - TouchableOpacity, 7 - View, 8 - } from 'react-native' 2 + import {SafeAreaView, StyleSheet, TouchableOpacity, View} from 'react-native' 9 3 import {observer} from 'mobx-react-lite' 10 4 import {CenteredView} from '../com/util/Views' 11 5 import {Signin} from '../com/login/Signin' 12 6 import {CreateAccount} from '../com/login/CreateAccount' 13 7 import {Text} from '../com/util/text/Text' 14 8 import {ErrorBoundary} from '../com/util/ErrorBoundary' 15 - import {colors} from '../lib/styles' 16 - import {usePalette} from '../lib/hooks/usePalette' 17 - import {CLOUD_SPLASH} from '../lib/assets' 9 + import {colors} from 'lib/styles' 10 + import {usePalette} from 'lib/hooks/usePalette' 18 11 19 12 enum ScreenState { 20 13 S_SigninOrCreateAccount, ··· 125 118 width: '100%', 126 119 height: '100%', 127 120 }, 121 + hero: {}, 128 122 heroText: { 129 123 backgroundColor: colors.white, 130 124 paddingTop: 10,
+1 -1
src/view/screens/NotFound.tsx
··· 2 2 import {Button, StyleSheet, View} from 'react-native' 3 3 import {ViewHeader} from '../com/util/ViewHeader' 4 4 import {Text} from '../com/util/text/Text' 5 - import {useStores} from '../../state' 5 + import {useStores} from 'state/index' 6 6 7 7 export const NotFound = () => { 8 8 const stores = useStores()
+63 -18
src/view/screens/Notifications.tsx
··· 1 1 import React, {useEffect} from 'react' 2 - import {View} from 'react-native' 2 + import {FlatList, View} from 'react-native' 3 + import useAppState from 'react-native-appstate-hook' 3 4 import {ViewHeader} from '../com/util/ViewHeader' 4 5 import {Feed} from '../com/notifications/Feed' 5 - import {useStores} from '../../state' 6 + import {useStores} from 'state/index' 6 7 import {ScreenParams} from '../routes' 7 - import {useOnMainScroll} from '../lib/hooks/useOnMainScroll' 8 - import {s} from '../lib/styles' 8 + import {useOnMainScroll} from 'lib/hooks/useOnMainScroll' 9 + import {s} from 'lib/styles' 10 + import {useAnalytics} from 'lib/analytics' 11 + 12 + const NOTIFICATIONS_POLL_INTERVAL = 15e3 9 13 10 14 export const Notifications = ({navIdx, visible}: ScreenParams) => { 11 15 const store = useStores() 12 16 const onMainScroll = useOnMainScroll(store) 17 + const scrollElRef = React.useRef<FlatList>(null) 18 + const {screen} = useAnalytics() 19 + const {appState} = useAppState({ 20 + onForeground: () => doPoll(true), 21 + }) 13 22 23 + // event handlers 24 + // = 25 + const onPressTryAgain = () => { 26 + store.me.notifications.refresh() 27 + } 28 + const scrollToTop = React.useCallback(() => { 29 + scrollElRef.current?.scrollToOffset({offset: 0}) 30 + }, [scrollElRef]) 31 + 32 + // periodic polling 33 + // = 34 + const doPoll = React.useCallback( 35 + async (isForegrounding = false) => { 36 + if (isForegrounding) { 37 + // app is foregrounding, refresh optimistically 38 + store.log.debug('NotificationsScreen: Refreshing on app foreground') 39 + await Promise.all([ 40 + store.me.notifications.loadUnreadCount(), 41 + store.me.notifications.refresh(), 42 + ]) 43 + } else if (appState === 'active') { 44 + // periodic poll, refresh if there are new notifs 45 + store.log.debug('NotificationsScreen: Polling for new notifications') 46 + const didChange = await store.me.notifications.loadUnreadCount() 47 + if (didChange) { 48 + store.log.debug('NotificationsScreen: Loading new notifications') 49 + await store.me.notifications.loadLatest() 50 + } 51 + } 52 + }, 53 + [appState, store], 54 + ) 55 + useEffect(() => { 56 + const pollInterval = setInterval(doPoll, NOTIFICATIONS_POLL_INTERVAL) 57 + return () => clearInterval(pollInterval) 58 + }, [doPoll]) 59 + 60 + // on-visible setup 61 + // = 14 62 useEffect(() => { 15 63 if (!visible) { 16 64 return 17 65 } 18 - store.log.debug('Updating notifications feed') 19 - store.me.notifications 20 - .update() 21 - .catch(e => { 22 - store.log.error('Error while updating notifications feed', e) 23 - }) 24 - .then(() => { 25 - store.me.notifications.updateReadState() 26 - }) 66 + store.log.debug('NotificationsScreen: Updating feed') 67 + const softResetSub = store.onScreenSoftReset(scrollToTop) 68 + store.me.notifications.update().then(() => { 69 + store.me.notifications.markAllRead() 70 + }) 71 + screen('Notifications') 27 72 store.nav.setTitle(navIdx, 'Notifications') 28 - }, [visible, store, navIdx]) 29 - 30 - const onPressTryAgain = () => { 31 - store.me.notifications.refresh() 32 - } 73 + return () => { 74 + softResetSub.remove() 75 + } 76 + }, [visible, store, navIdx, screen, scrollToTop]) 33 77 34 78 return ( 35 79 <View style={s.h100pct}> ··· 38 82 view={store.me.notifications} 39 83 onPressTryAgain={onPressTryAgain} 40 84 onScroll={onMainScroll} 85 + scrollElRef={scrollElRef} 41 86 /> 42 87 </View> 43 88 )
+2 -2
src/view/screens/Onboard.tsx
··· 3 3 import {observer} from 'mobx-react-lite' 4 4 import {FeatureExplainer} from '../com/onboard/FeatureExplainer' 5 5 import {Follows} from '../com/onboard/Follows' 6 - import {OnboardStage, OnboardStageOrder} from '../../state/models/onboard' 7 - import {useStores} from '../../state' 6 + import {OnboardStage, OnboardStageOrder} from 'state/models/onboard' 7 + import {useStores} from 'state/index' 8 8 9 9 export const Onboard = observer(() => { 10 10 const store = useStores()
+2 -2
src/view/screens/PostDownvotedBy.tsx
··· 3 3 import {ViewHeader} from '../com/util/ViewHeader' 4 4 import {PostVotedBy as PostLikedByComponent} from '../com/post-thread/PostVotedBy' 5 5 import {ScreenParams} from '../routes' 6 - import {useStores} from '../../state' 7 - import {makeRecordUri} from '../../lib/strings' 6 + import {useStores} from 'state/index' 7 + import {makeRecordUri} from 'lib/strings/url-helpers' 8 8 9 9 export const PostDownvotedBy = ({navIdx, visible, params}: ScreenParams) => { 10 10 const store = useStores()
+2 -2
src/view/screens/PostRepostedBy.tsx
··· 3 3 import {ViewHeader} from '../com/util/ViewHeader' 4 4 import {PostRepostedBy as PostRepostedByComponent} from '../com/post-thread/PostRepostedBy' 5 5 import {ScreenParams} from '../routes' 6 - import {useStores} from '../../state' 7 - import {makeRecordUri} from '../../lib/strings' 6 + import {useStores} from 'state/index' 7 + import {makeRecordUri} from 'lib/strings/url-helpers' 8 8 9 9 export const PostRepostedBy = ({navIdx, visible, params}: ScreenParams) => { 10 10 const store = useStores()
+6 -8
src/view/screens/PostThread.tsx
··· 1 - import React, {useEffect, useMemo, useState} from 'react' 1 + import React, {useEffect, useMemo} from 'react' 2 2 import {View} from 'react-native' 3 - import {makeRecordUri} from '../../lib/strings' 3 + import {makeRecordUri} from 'lib/strings/url-helpers' 4 4 import {ViewHeader} from '../com/util/ViewHeader' 5 5 import {PostThread as PostThreadComponent} from '../com/post-thread/PostThread' 6 - import {PostThreadViewModel} from '../../state/models/post-thread-view' 6 + import {PostThreadViewModel} from 'state/models/post-thread-view' 7 7 import {ScreenParams} from '../routes' 8 - import {useStores} from '../../state' 9 - import {s} from '../lib/styles' 8 + import {useStores} from 'state/index' 9 + import {s} from 'lib/styles' 10 10 11 11 export const PostThread = ({navIdx, visible, params}: ScreenParams) => { 12 12 const store = useStores() 13 13 const {name, rkey} = params 14 - const [viewSubtitle, setViewSubtitle] = useState<string>(`by ${name}`) 15 14 const uri = makeRecordUri(name, 'app.bsky.feed.post', rkey) 16 15 const view = useMemo<PostThreadViewModel>( 17 16 () => new PostThreadViewModel(store, {uri}), ··· 24 23 const setTitle = () => { 25 24 const author = view.thread?.post.author 26 25 const niceName = author?.handle || name 27 - setViewSubtitle(`by ${niceName}`) 28 26 store.nav.setTitle(navIdx, `Post by ${niceName}`) 29 27 } 30 28 if (!visible) { ··· 52 50 53 51 return ( 54 52 <View style={s.h100pct}> 55 - <ViewHeader title="Post" subtitle={viewSubtitle} /> 53 + <ViewHeader title="Post" /> 56 54 <View style={s.h100pct}> 57 55 <PostThreadComponent uri={uri} view={view} /> 58 56 </View>
+2 -2
src/view/screens/PostUpvotedBy.tsx
··· 3 3 import {ViewHeader} from '../com/util/ViewHeader' 4 4 import {PostVotedBy as PostLikedByComponent} from '../com/post-thread/PostVotedBy' 5 5 import {ScreenParams} from '../routes' 6 - import {useStores} from '../../state' 7 - import {makeRecordUri} from '../../lib/strings' 6 + import {useStores} from 'state/index' 7 + import {makeRecordUri} from 'lib/strings/url-helpers' 8 8 9 9 export const PostUpvotedBy = ({navIdx, visible, params}: ScreenParams) => { 10 10 const store = useStores()
+13 -6
src/view/screens/Profile.tsx
··· 4 4 import {ViewSelector} from '../com/util/ViewSelector' 5 5 import {CenteredView} from '../com/util/Views' 6 6 import {ScreenParams} from '../routes' 7 - import {ProfileUiModel, Sections} from '../../state/models/profile-ui' 8 - import {useStores} from '../../state' 7 + import {ProfileUiModel, Sections} from 'state/models/profile-ui' 8 + import {useStores} from 'state/index' 9 9 import {ProfileHeader} from '../com/profile/ProfileHeader' 10 10 import {FeedItem} from '../com/posts/FeedItem' 11 11 import {PostFeedLoadingPlaceholder} from '../com/util/LoadingPlaceholder' ··· 14 14 import {EmptyState} from '../com/util/EmptyState' 15 15 import {Text} from '../com/util/text/Text' 16 16 import {FAB} from '../com/util/FAB' 17 - import {s, colors} from '../lib/styles' 18 - import {useOnMainScroll} from '../lib/hooks/useOnMainScroll' 17 + import {s, colors} from 'lib/styles' 18 + import {useOnMainScroll} from 'lib/hooks/useOnMainScroll' 19 + import {useAnalytics} from 'lib/analytics' 19 20 20 21 const LOADING_ITEM = {_reactKey: '__loading__'} 21 22 const END_ITEM = {_reactKey: '__end__'} ··· 23 24 24 25 export const Profile = observer(({navIdx, visible, params}: ScreenParams) => { 25 26 const store = useStores() 27 + const {screen} = useAnalytics() 28 + 29 + useEffect(() => { 30 + screen('Profile') 31 + }, [screen]) 32 + 26 33 const onMainScroll = useOnMainScroll(store) 27 34 const [hasSetup, setHasSetup] = useState<boolean>(false) 28 35 const uiState = React.useMemo( ··· 128 135 } 129 136 if (!uiState.feed.hasMore) { 130 137 items = items.concat([END_ITEM]) 131 - } else { 138 + } else if (uiState.feed.isLoading) { 132 139 Footer = LoadingMoreFooter 133 140 } 134 141 renderItem = (item: any) => { ··· 184 191 ) : ( 185 192 <CenteredView>{renderHeader()}</CenteredView> 186 193 )} 187 - <FAB icon="pen-nib" onPress={onPressCompose} /> 194 + <FAB icon="plus" onPress={onPressCompose} /> 188 195 </View> 189 196 ) 190 197 })
+2 -2
src/view/screens/ProfileFollowers.tsx
··· 3 3 import {ViewHeader} from '../com/util/ViewHeader' 4 4 import {ProfileFollowers as ProfileFollowersComponent} from '../com/profile/ProfileFollowers' 5 5 import {ScreenParams} from '../routes' 6 - import {useStores} from '../../state' 6 + import {useStores} from 'state/index' 7 7 8 8 export const ProfileFollowers = ({navIdx, visible, params}: ScreenParams) => { 9 9 const store = useStores() ··· 18 18 19 19 return ( 20 20 <View> 21 - <ViewHeader title="Followers" subtitle={`of ${name}`} /> 21 + <ViewHeader title="Followers" /> 22 22 <ProfileFollowersComponent name={name} /> 23 23 </View> 24 24 )
+2 -2
src/view/screens/ProfileFollows.tsx
··· 3 3 import {ViewHeader} from '../com/util/ViewHeader' 4 4 import {ProfileFollows as ProfileFollowsComponent} from '../com/profile/ProfileFollows' 5 5 import {ScreenParams} from '../routes' 6 - import {useStores} from '../../state' 6 + import {useStores} from 'state/index' 7 7 8 8 export const ProfileFollows = ({navIdx, visible, params}: ScreenParams) => { 9 9 const store = useStores() ··· 18 18 19 19 return ( 20 20 <View> 21 - <ViewHeader title="Followed" subtitle={`by ${name}`} /> 21 + <ViewHeader title="Following" /> 22 22 <ProfileFollowsComponent name={name} /> 23 23 </View> 24 24 )
+158 -74
src/view/screens/Search.tsx
··· 1 - import React, {useEffect, useState, useMemo, useRef} from 'react' 1 + import React from 'react' 2 2 import { 3 3 Keyboard, 4 4 StyleSheet, 5 5 TextInput, 6 6 TouchableOpacity, 7 + TouchableWithoutFeedback, 7 8 View, 8 9 } from 'react-native' 9 - import {ViewHeader} from '../com/util/ViewHeader' 10 - import {CenteredView, ScrollView} from '../com/util/Views' 11 - import {SuggestedFollows} from '../com/discover/SuggestedFollows' 10 + import {ScrollView} from '../com/util/Views' 11 + import {observer} from 'mobx-react-lite' 12 12 import {UserAvatar} from '../com/util/UserAvatar' 13 13 import {Text} from '../com/util/text/Text' 14 14 import {ScreenParams} from '../routes' 15 - import {useStores} from '../../state' 16 - import {UserAutocompleteViewModel} from '../../state/models/user-autocomplete-view' 17 - import {s} from '../lib/styles' 18 - import {MagnifyingGlassIcon} from '../lib/icons' 19 - import {usePalette} from '../lib/hooks/usePalette' 15 + import {useStores} from 'state/index' 16 + import {UserAutocompleteViewModel} from 'state/models/user-autocomplete-view' 17 + import {s} from 'lib/styles' 18 + import {MagnifyingGlassIcon} from 'lib/icons' 19 + import {WhoToFollow} from '../com/discover/WhoToFollow' 20 + import {SuggestedPosts} from '../com/discover/SuggestedPosts' 21 + import {ProfileCard} from '../com/profile/ProfileCard' 22 + import {usePalette} from 'lib/hooks/usePalette' 23 + import {useOnMainScroll} from 'lib/hooks/useOnMainScroll' 24 + import {useAnalytics} from 'lib/analytics' 25 + 26 + const MENU_HITSLOP = {left: 10, top: 10, right: 30, bottom: 10} 27 + const FIVE_MIN = 5 * 60 * 1e3 20 28 21 - export const Search = ({navIdx, visible, params}: ScreenParams) => { 29 + export const Search = observer(({navIdx, visible, params}: ScreenParams) => { 22 30 const pal = usePalette('default') 23 31 const store = useStores() 24 - const textInput = useRef<TextInput>(null) 25 - const [query, setQuery] = useState<string>('') 26 - const autocompleteView = useMemo<UserAutocompleteViewModel>( 32 + const {track} = useAnalytics() 33 + const scrollElRef = React.useRef<ScrollView>(null) 34 + const onMainScroll = useOnMainScroll(store) 35 + const textInput = React.useRef<TextInput>(null) 36 + const [lastRenderTime, setRenderTime] = React.useState<number>(Date.now()) // used to trigger reloads 37 + const [isInputFocused, setIsInputFocused] = React.useState<boolean>(false) 38 + const [query, setQuery] = React.useState<string>('') 39 + const autocompleteView = React.useMemo<UserAutocompleteViewModel>( 27 40 () => new UserAutocompleteViewModel(store), 28 41 [store], 29 42 ) 30 43 const {name} = params 31 44 32 - useEffect(() => { 45 + const onSoftReset = () => { 46 + scrollElRef.current?.scrollTo({x: 0, y: 0}) 47 + } 48 + 49 + React.useEffect(() => { 50 + const softResetSub = store.onScreenSoftReset(onSoftReset) 51 + const cleanup = () => { 52 + softResetSub.remove() 53 + } 54 + 33 55 if (visible) { 56 + const now = Date.now() 57 + if (now - lastRenderTime > FIVE_MIN) { 58 + setRenderTime(Date.now()) // trigger reload of suggestions 59 + } 34 60 store.shell.setMinimalShellMode(false) 35 61 autocompleteView.setup() 36 62 store.nav.setTitle(navIdx, 'Search') 37 63 } 38 - }, [store, visible, name, navIdx, autocompleteView]) 64 + return cleanup 65 + }, [store, visible, name, navIdx, autocompleteView, lastRenderTime]) 66 + 67 + const onPressMenu = () => { 68 + track('ViewHeader:MenuButtonClicked') 69 + store.shell.setMainMenuOpen(true) 70 + } 39 71 40 72 const onChangeQuery = (text: string) => { 41 73 setQuery(text) ··· 46 78 autocompleteView.setActive(false) 47 79 } 48 80 } 49 - const onSelect = (handle: string) => { 50 - textInput.current?.blur() 51 - store.nav.navigate(`/profile/${handle}`) 81 + const onPressCancelSearch = () => { 82 + setQuery('') 83 + autocompleteView.setActive(false) 52 84 } 53 85 54 86 return ( 55 - <View style={[pal.view, styles.container]}> 56 - <ViewHeader title="Search" /> 57 - <CenteredView style={[pal.view, pal.border, styles.inputContainer]}> 58 - <MagnifyingGlassIcon style={[pal.text, styles.inputIcon]} /> 59 - <TextInput 60 - testID="searchTextInput" 61 - ref={textInput} 62 - placeholder="Type your query here..." 63 - placeholderTextColor={pal.colors.textLight} 64 - selectTextOnFocus 65 - returnKeyType="search" 66 - style={[pal.text, styles.input]} 67 - onChangeText={onChangeQuery} 68 - /> 69 - </CenteredView> 70 - <View style={styles.outputContainer}> 71 - {query ? ( 72 - <ScrollView testID="searchScrollView" onScroll={Keyboard.dismiss}> 73 - {autocompleteView.searchRes.map((item, i) => ( 74 - <TouchableOpacity 75 - key={i} 76 - style={[pal.view, pal.border, styles.searchResult]} 77 - onPress={() => onSelect(item.handle)}> 78 - <UserAvatar 79 - handle={item.handle} 80 - displayName={item.displayName} 81 - avatar={item.avatar} 82 - size={36} 83 - /> 84 - <View style={[s.ml10]}> 85 - <Text type="title-sm" style={pal.text}> 86 - {item.displayName || item.handle} 87 - </Text> 88 - <Text style={pal.textLight}>@{item.handle}</Text> 89 - </View> 87 + <TouchableWithoutFeedback onPress={Keyboard.dismiss}> 88 + <ScrollView 89 + ref={scrollElRef} 90 + testID="searchScrollView" 91 + style={[pal.view, styles.container]} 92 + onScroll={onMainScroll} 93 + scrollEventThrottle={100}> 94 + <View style={[pal.view, pal.border, styles.header]}> 95 + <TouchableOpacity 96 + testID="viewHeaderBackOrMenuBtn" 97 + onPress={onPressMenu} 98 + hitSlop={MENU_HITSLOP} 99 + style={styles.headerMenuBtn}> 100 + <UserAvatar 101 + size={30} 102 + handle={store.me.handle} 103 + displayName={store.me.displayName} 104 + avatar={store.me.avatar} 105 + /> 106 + </TouchableOpacity> 107 + <View 108 + style={[ 109 + {backgroundColor: pal.colors.backgroundLight}, 110 + styles.headerSearchContainer, 111 + ]}> 112 + <MagnifyingGlassIcon 113 + style={[pal.icon, styles.headerSearchIcon]} 114 + size={21} 115 + /> 116 + <TextInput 117 + testID="searchTextInput" 118 + ref={textInput} 119 + placeholder="Search" 120 + placeholderTextColor={pal.colors.textLight} 121 + selectTextOnFocus 122 + returnKeyType="search" 123 + value={query} 124 + style={[pal.text, styles.headerSearchInput]} 125 + onFocus={() => setIsInputFocused(true)} 126 + onBlur={() => setIsInputFocused(false)} 127 + onChangeText={onChangeQuery} 128 + /> 129 + </View> 130 + {query ? ( 131 + <View style={styles.headerCancelBtn}> 132 + <TouchableOpacity onPress={onPressCancelSearch}> 133 + <Text>Cancel</Text> 90 134 </TouchableOpacity> 135 + </View> 136 + ) : undefined} 137 + </View> 138 + {query && autocompleteView.searchRes.length ? ( 139 + <> 140 + {autocompleteView.searchRes.map(item => ( 141 + <ProfileCard 142 + key={item.did} 143 + handle={item.handle} 144 + displayName={item.displayName} 145 + avatar={item.avatar} 146 + /> 91 147 ))} 148 + </> 149 + ) : query && !autocompleteView.searchRes.length ? ( 150 + <View> 151 + <Text style={[pal.textLight, styles.searchPrompt]}> 152 + No results found for {autocompleteView.prefix} 153 + </Text> 154 + </View> 155 + ) : isInputFocused ? ( 156 + <View> 157 + <Text style={[pal.textLight, styles.searchPrompt]}> 158 + Search for users on the network 159 + </Text> 160 + </View> 161 + ) : ( 162 + <ScrollView onScroll={Keyboard.dismiss}> 163 + <WhoToFollow key={`wtf-${lastRenderTime}`} /> 164 + <SuggestedPosts key={`sp-${lastRenderTime}`} /> 92 165 <View style={s.footerSpacer} /> 93 166 </ScrollView> 94 - ) : ( 95 - <SuggestedFollows asLinks /> 96 167 )} 97 - </View> 98 - </View> 168 + <View style={s.footerSpacer} /> 169 + </ScrollView> 170 + </TouchableWithoutFeedback> 99 171 ) 100 - } 172 + }) 101 173 102 174 const styles = StyleSheet.create({ 103 175 container: { 104 176 flex: 1, 105 177 }, 106 178 107 - inputContainer: { 179 + header: { 108 180 flexDirection: 'row', 109 - paddingVertical: 16, 110 - paddingHorizontal: 16, 111 - borderTopWidth: 1, 181 + alignItems: 'center', 182 + paddingHorizontal: 12, 183 + paddingTop: 4, 184 + marginBottom: 14, 112 185 }, 113 - inputIcon: { 114 - marginRight: 10, 115 - alignSelf: 'center', 186 + headerMenuBtn: { 187 + width: 40, 188 + height: 30, 189 + marginLeft: 6, 116 190 }, 117 - input: { 191 + headerSearchContainer: { 118 192 flex: 1, 119 - fontSize: 16, 193 + flexDirection: 'row', 194 + alignItems: 'center', 195 + borderRadius: 30, 196 + paddingHorizontal: 12, 197 + paddingVertical: 8, 198 + }, 199 + headerSearchIcon: { 200 + marginRight: 6, 201 + alignSelf: 'center', 120 202 }, 121 - 122 - outputContainer: { 203 + headerSearchInput: { 123 204 flex: 1, 205 + fontSize: 17, 206 + }, 207 + headerCancelBtn: { 208 + width: 60, 209 + paddingLeft: 10, 124 210 }, 125 211 126 - searchResult: { 127 - flexDirection: 'row', 128 - borderTopWidth: 1, 129 - paddingVertical: 12, 130 - paddingHorizontal: 16, 212 + searchPrompt: { 213 + textAlign: 'center', 214 + paddingTop: 10, 131 215 }, 132 216 })
+34 -6
src/view/screens/Settings.tsx
··· 7 7 } from 'react-native' 8 8 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 9 9 import {observer} from 'mobx-react-lite' 10 - import {useStores} from '../../state' 10 + import * as AppInfo from 'lib/app-info' 11 + import {useStores} from 'state/index' 11 12 import {ScreenParams} from '../routes' 12 - import {s} from '../lib/styles' 13 + import {s} from 'lib/styles' 13 14 import {ScrollView} from '../com/util/Views' 14 15 import {ViewHeader} from '../com/util/ViewHeader' 15 16 import {Link} from '../com/util/Link' 16 17 import {Text} from '../com/util/text/Text' 17 18 import * as Toast from '../com/util/Toast' 18 19 import {UserAvatar} from '../com/util/UserAvatar' 19 - import {usePalette} from '../lib/hooks/usePalette' 20 - import {AccountData} from '../../state/models/session' 20 + import {usePalette} from 'lib/hooks/usePalette' 21 + import {AccountData} from 'state/models/session' 22 + import {useAnalytics} from 'lib/analytics' 23 + import {DeleteAccountModal} from 'state/models/shell-ui' 21 24 22 25 export const Settings = observer(function Settings({ 23 26 navIdx, ··· 25 28 }: ScreenParams) { 26 29 const pal = usePalette('default') 27 30 const store = useStores() 31 + const {screen, track} = useAnalytics() 28 32 const [isSwitching, setIsSwitching] = React.useState(false) 29 33 30 34 useEffect(() => { 35 + screen('Settings') 36 + }, [screen]) 37 + 38 + useEffect(() => { 31 39 if (!visible) { 32 40 return 33 41 } ··· 36 44 }, [visible, store, navIdx]) 37 45 38 46 const onPressSwitchAccount = async (acct: AccountData) => { 47 + track('Settings:SwitchAccountButtonClicked') 39 48 setIsSwitching(true) 40 49 if (await store.session.resumeSession(acct)) { 41 50 setIsSwitching(false) 51 + store.nav.tab.fixedTabReset() 42 52 Toast.show(`Signed in as ${acct.displayName || acct.handle}`) 43 53 return 44 54 } 45 55 setIsSwitching(false) 46 56 Toast.show('Sorry! We need you to enter your password.') 57 + store.nav.tab.fixedTabReset() 47 58 store.session.clear() 48 59 } 49 60 const onPressAddAccount = () => { 61 + track('Settings:AddAccountButtonClicked') 50 62 store.session.clear() 51 63 } 52 64 const onPressSignout = () => { 65 + track('Settings:SignOutButtonClicked') 53 66 store.session.logout() 67 + } 68 + const onPressDeleteAccount = () => { 69 + store.shell.openModal(new DeleteAccountModal()) 54 70 } 55 71 56 72 return ( ··· 143 159 </Text> 144 160 </View> 145 161 </TouchableOpacity> 162 + 146 163 <View style={styles.spacer} /> 147 164 <Text type="sm-medium" style={[s.mb5]}> 165 + Danger zone 166 + </Text> 167 + <TouchableOpacity 168 + style={[pal.view, s.p10, s.mb10]} 169 + onPress={onPressDeleteAccount}> 170 + <Text style={pal.textLight}>Delete my account</Text> 171 + </TouchableOpacity> 172 + <Text type="sm-medium" style={[s.mt10, s.mb5]}> 148 173 Developer tools 149 174 </Text> 150 175 <Link 151 176 style={[pal.view, s.p10, s.mb2]} 152 177 href="/sys/log" 153 178 title="System log"> 154 - <Text style={pal.link}>System log</Text> 179 + <Text style={pal.textLight}>System log</Text> 155 180 </Link> 156 181 <Link 157 182 style={[pal.view, s.p10, s.mb2]} 158 183 href="/sys/debug" 159 184 title="Debug tools"> 160 - <Text style={pal.link}>Storybook</Text> 185 + <Text style={pal.textLight}>Storybook</Text> 161 186 </Link> 187 + <Text type="sm" style={[s.mt10, pal.textLight]}> 188 + Build version {AppInfo.appVersion} ({AppInfo.buildVersion}) 189 + </Text> 162 190 <View style={s.footerSpacer} /> 163 191 </View> 164 192 </ScrollView>
+3 -3
src/view/shell/mobile/Composer.tsx
··· 2 2 import {observer} from 'mobx-react-lite' 3 3 import {Animated, Easing, Platform, StyleSheet, View} from 'react-native' 4 4 import {ComposePost} from '../../com/composer/ComposePost' 5 - import {ComposerOpts} from '../../../state/models/shell-ui' 6 - import {useAnimatedValue} from '../../lib/hooks/useAnimatedValue' 7 - import {usePalette} from '../../lib/hooks/usePalette' 5 + import {ComposerOpts} from 'state/models/shell-ui' 6 + import {useAnimatedValue} from 'lib/hooks/useAnimatedValue' 7 + import {usePalette} from 'lib/hooks/usePalette' 8 8 9 9 export const Composer = observer( 10 10 ({
+57 -20
src/view/shell/mobile/Menu.tsx
··· 1 1 import React from 'react' 2 2 import { 3 - ScrollView, 3 + Linking, 4 4 StyleProp, 5 5 StyleSheet, 6 6 TouchableOpacity, ··· 8 8 ViewStyle, 9 9 } from 'react-native' 10 10 import {observer} from 'mobx-react-lite' 11 - import VersionNumber from 'react-native-version-number' 12 - import {s, colors} from '../../lib/styles' 13 - import {useStores} from '../../../state' 11 + import { 12 + FontAwesomeIcon, 13 + FontAwesomeIconStyle, 14 + } from '@fortawesome/react-native-fontawesome' 15 + import {s, colors} from 'lib/styles' 16 + import {FEEDBACK_FORM_URL} from 'lib/constants' 17 + import {useStores} from 'state/index' 14 18 import { 15 19 HomeIcon, 16 20 BellIcon, 17 21 UserIcon, 18 22 CogIcon, 19 23 MagnifyingGlassIcon, 20 - } from '../../lib/icons' 24 + } from 'lib/icons' 25 + import {TabPurpose, TabPurposeMainPath} from 'state/models/navigation' 21 26 import {UserAvatar} from '../../com/util/UserAvatar' 22 27 import {Text} from '../../com/util/text/Text' 23 28 import {ToggleButton} from '../../com/util/forms/ToggleButton' 24 - import {usePalette} from '../../lib/hooks/usePalette' 29 + import {usePalette} from 'lib/hooks/usePalette' 30 + import {useAnalytics} from 'lib/analytics' 25 31 26 32 export const Menu = observer(({onClose}: {onClose: () => void}) => { 27 33 const pal = usePalette('default') 28 34 const store = useStores() 35 + const {track} = useAnalytics() 29 36 30 37 // events 31 38 // = 32 39 33 40 const onNavigate = (url: string) => { 41 + track('Menu:ItemClicked', {url}) 42 + 34 43 onClose() 35 - if (url === '/notifications') { 36 - store.nav.switchTo(1, true) 44 + if (url === TabPurposeMainPath[TabPurpose.Notifs]) { 45 + store.nav.switchTo(TabPurpose.Notifs, true) 46 + } else if (url === TabPurposeMainPath[TabPurpose.Search]) { 47 + store.nav.switchTo(TabPurpose.Search, true) 37 48 } else { 38 - store.nav.switchTo(0, true) 49 + store.nav.switchTo(TabPurpose.Default, true) 39 50 if (url !== '/') { 40 51 store.nav.navigate(url) 41 52 } 42 53 } 54 + } 55 + 56 + const onPressFeedback = () => { 57 + track('Menu:FeedbackClicked') 58 + Linking.openURL(FEEDBACK_FORM_URL) 43 59 } 44 60 45 61 // rendering ··· 83 99 </Text> 84 100 </TouchableOpacity> 85 101 ) 102 + 103 + const onDarkmodePress = () => { 104 + track('Menu:ItemClicked', {url: '/darkmode'}) 105 + store.shell.setDarkMode(!store.shell.darkMode) 106 + } 86 107 87 108 return ( 88 - <ScrollView testID="menuView" style={[styles.view, pal.view]}> 109 + <View 110 + testID="menuView" 111 + style={[ 112 + styles.view, 113 + pal.view, 114 + store.shell.minimalShellMode && styles.viewMinimalShell, 115 + ]}> 89 116 <TouchableOpacity 90 117 testID="profileCardButton" 91 118 onPress={() => onNavigate(`/profile/${store.me.handle}`)} ··· 132 159 icon={<BellIcon style={pal.text as StyleProp<ViewStyle>} size="28" />} 133 160 label="Notifications" 134 161 url="/notifications" 135 - count={store.me.notificationCount} 162 + count={store.me.notifications.unreadCount} 136 163 /> 137 164 <MenuItem 138 165 icon={ ··· 161 188 <ToggleButton 162 189 label="Dark mode" 163 190 isSelected={store.shell.darkMode} 164 - onPress={() => store.shell.setDarkMode(!store.shell.darkMode)} 191 + onPress={onDarkmodePress} 165 192 /> 166 193 </View> 194 + <View style={s.flex1} /> 167 195 <View style={styles.footer}> 168 - <Text style={[pal.textLight]}> 169 - Build version {VersionNumber.appVersion} ({VersionNumber.buildVersion} 170 - ) 171 - </Text> 196 + <MenuItem 197 + icon={ 198 + <FontAwesomeIcon 199 + style={pal.text as FontAwesomeIconStyle} 200 + size={24} 201 + icon={['far', 'message']} 202 + /> 203 + } 204 + label="Feedback" 205 + onPress={onPressFeedback} 206 + /> 172 207 </View> 173 - <View style={s.footerSpacer} /> 174 - </ScrollView> 208 + </View> 175 209 ) 176 210 }) 177 211 178 212 const styles = StyleSheet.create({ 179 213 view: { 180 214 flex: 1, 215 + paddingBottom: 90, 216 + }, 217 + viewMinimalShell: { 218 + paddingBottom: 50, 181 219 }, 182 220 section: { 183 221 paddingHorizontal: 10, ··· 254 292 }, 255 293 256 294 footer: { 257 - paddingHorizontal: 14, 258 - paddingVertical: 18, 295 + paddingHorizontal: 10, 259 296 }, 260 297 })
+4 -4
src/view/shell/mobile/TabsSelector.tsx
··· 12 12 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 13 13 import {Text} from '../../com/util/text/Text' 14 14 import Swipeable from 'react-native-gesture-handler/Swipeable' 15 - import {useStores} from '../../../state' 16 - import {s, colors} from '../../lib/styles' 17 - import {toShareUrl} from '../../../lib/strings' 15 + import {useStores} from 'state/index' 16 + import {s, colors} from 'lib/styles' 17 + import {toShareUrl} from 'lib/strings/url-helpers' 18 18 import {match} from '../../routes' 19 - import {useAnimatedValue} from '../../lib/hooks/useAnimatedValue' 19 + import {useAnimatedValue} from 'lib/hooks/useAnimatedValue' 20 20 21 21 const TAB_HEIGHT = 42 22 22
+87 -36
src/view/shell/mobile/index.tsx
··· 1 - import React, {useState, useEffect, useRef} from 'react' 1 + import React, {useState, useEffect} from 'react' 2 2 import {observer} from 'mobx-react-lite' 3 3 import { 4 4 Animated, 5 5 Easing, 6 - FlatList, 7 6 GestureResponderEvent, 8 7 StatusBar, 9 8 StyleSheet, ··· 12 11 useColorScheme, 13 12 useWindowDimensions, 14 13 View, 15 - ViewStyle, 16 14 } from 'react-native' 17 15 import {ScreenContainer, Screen} from 'react-native-screens' 18 16 import {useSafeAreaInsets} from 'react-native-safe-area-context' 19 17 import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome' 20 18 import {IconProp} from '@fortawesome/fontawesome-svg-core' 21 - import {TABS_ENABLED} from '../../../build-flags' 22 - import {useStores} from '../../../state' 23 - import {NavigationModel} from '../../../state/models/navigation' 19 + import {TABS_ENABLED} from 'lib/build-flags' 20 + import {useStores} from 'state/index' 21 + import { 22 + NavigationModel, 23 + TabPurpose, 24 + TabPurposeMainPath, 25 + } from 'state/models/navigation' 24 26 import {match, MatchResult} from '../../routes' 25 27 import {Login} from '../../screens/Login' 26 28 import {Menu} from './Menu' ··· 32 34 import {ErrorBoundary} from '../../com/util/ErrorBoundary' 33 35 import {TabsSelector} from './TabsSelector' 34 36 import {Composer} from './Composer' 35 - import {s, colors} from '../../lib/styles' 36 - import {clamp} from '../../../lib/numbers' 37 + import {s, colors} from 'lib/styles' 38 + import {clamp} from 'lib/numbers' 37 39 import { 38 40 GridIcon, 39 41 GridIconSolid, 40 42 HomeIcon, 41 43 HomeIconSolid, 44 + MagnifyingGlassIcon, 42 45 BellIcon, 43 46 BellIconSolid, 44 - } from '../../lib/icons' 45 - import {useAnimatedValue} from '../../lib/hooks/useAnimatedValue' 46 - import {useTheme} from '../../lib/ThemeContext' 47 - import {usePalette} from '../../lib/hooks/usePalette' 47 + } from 'lib/icons' 48 + import {useAnimatedValue} from 'lib/hooks/useAnimatedValue' 49 + import {useTheme} from 'lib/ThemeContext' 50 + import {usePalette} from 'lib/hooks/usePalette' 51 + import {useAnalytics} from 'lib/analytics' 48 52 49 53 const Btn = ({ 50 54 icon, ··· 59 63 | 'menu-solid' 60 64 | 'home' 61 65 | 'home-solid' 66 + | 'search' 67 + | 'search-solid' 62 68 | 'bell' 63 69 | 'bell-solid' 64 70 notificationCount?: number ··· 76 82 iconEl = <HomeIcon size={27} style={[styles.ctrlIcon, pal.text]} /> 77 83 } else if (icon === 'home-solid') { 78 84 iconEl = <HomeIconSolid size={27} style={[styles.ctrlIcon, pal.text]} /> 85 + } else if (icon === 'search') { 86 + iconEl = ( 87 + <MagnifyingGlassIcon 88 + size={28} 89 + style={[styles.ctrlIcon, pal.text, styles.bumpUpOnePixel]} 90 + /> 91 + ) 92 + } else if (icon === 'search-solid') { 93 + iconEl = ( 94 + <MagnifyingGlassIcon 95 + size={28} 96 + strokeWidth={3} 97 + style={[styles.ctrlIcon, pal.text, styles.bumpUpOnePixel]} 98 + /> 99 + ) 79 100 } else if (icon === 'bell') { 80 - const addedStyles = {position: 'relative', top: -1} as ViewStyle 81 101 iconEl = ( 82 - <BellIcon size={27} style={[styles.ctrlIcon, pal.text, addedStyles]} /> 102 + <BellIcon 103 + size={27} 104 + style={[styles.ctrlIcon, pal.text, styles.bumpUpOnePixel]} 105 + /> 83 106 ) 84 107 } else if (icon === 'bell-solid') { 85 - const addedStyles = {position: 'relative', top: -1} as ViewStyle 86 108 iconEl = ( 87 109 <BellIconSolid 88 110 size={27} 89 - style={[styles.ctrlIcon, pal.text, addedStyles]} 111 + style={[styles.ctrlIcon, pal.text, styles.bumpUpOnePixel]} 90 112 /> 91 113 ) 92 114 } else { 93 115 iconEl = ( 94 116 <FontAwesomeIcon 117 + icon={icon} 95 118 size={24} 96 - icon={icon} 97 119 style={[styles.ctrlIcon, pal.text]} 98 120 /> 99 121 ) ··· 125 147 const pal = usePalette('default') 126 148 const store = useStores() 127 149 const [isTabsSelectorActive, setTabsSelectorActive] = useState(false) 128 - const scrollElRef = useRef<FlatList>(null) 129 150 const winDim = useWindowDimensions() 130 151 const [menuSwipingDirection, setMenuSwipingDirection] = useState(0) 131 152 const swipeGestureInterp = useAnimatedValue(0) ··· 136 157 const colorScheme = useColorScheme() 137 158 const safeAreaInsets = useSafeAreaInsets() 138 159 const screenRenderDesc = constructScreenRenderDesc(store.nav) 160 + const {track} = useAnalytics() 139 161 140 162 const onPressHome = () => { 141 - if (store.shell.isMainMenuOpen) { 142 - store.shell.setMainMenuOpen(false) 163 + track('MobileShell:HomeButtonPressed') 164 + if (store.nav.tab.fixedTabPurpose === TabPurpose.Default) { 165 + if (!store.nav.tab.canGoBack) { 166 + store.emitScreenSoftReset() 167 + } else { 168 + store.nav.tab.fixedTabReset() 169 + } 170 + } else { 171 + store.nav.switchTo(TabPurpose.Default, false) 172 + if (store.nav.tab.index === 0) { 173 + store.nav.tab.fixedTabReset() 174 + } 143 175 } 144 - if (store.nav.tab.fixedTabPurpose === 0) { 145 - if (store.nav.tab.current.url === '/') { 146 - scrollElRef.current?.scrollToOffset({offset: 0}) 176 + } 177 + const onPressSearch = () => { 178 + track('MobileShell:SearchButtonPressed') 179 + if (store.nav.tab.fixedTabPurpose === TabPurpose.Search) { 180 + if (!store.nav.tab.canGoBack) { 181 + store.emitScreenSoftReset() 147 182 } else { 148 183 store.nav.tab.fixedTabReset() 149 184 } 150 185 } else { 151 - store.nav.switchTo(0, false) 186 + store.nav.switchTo(TabPurpose.Search, false) 152 187 if (store.nav.tab.index === 0) { 153 188 store.nav.tab.fixedTabReset() 154 189 } 155 190 } 156 191 } 157 192 const onPressNotifications = () => { 158 - if (store.shell.isMainMenuOpen) { 159 - store.shell.setMainMenuOpen(false) 160 - } 161 - if (store.nav.tab.fixedTabPurpose === 1) { 162 - store.nav.tab.fixedTabReset() 193 + track('MobileShell:NotificationsButtonPressed') 194 + if (store.nav.tab.fixedTabPurpose === TabPurpose.Notifs) { 195 + if (!store.nav.tab.canGoBack) { 196 + store.emitScreenSoftReset() 197 + } else { 198 + store.nav.tab.fixedTabReset() 199 + } 163 200 } else { 164 - store.nav.switchTo(1, false) 201 + store.nav.switchTo(TabPurpose.Notifs, false) 165 202 if (store.nav.tab.index === 0) { 166 203 store.nav.tab.fixedTabReset() 167 204 } ··· 178 215 toValue: 1, 179 216 duration: 100, 180 217 useNativeDriver: true, 218 + isInteraction: false, 181 219 }).start() 182 220 } else { 183 221 Animated.timing(minimalShellInterp, { 184 222 toValue: 0, 185 223 duration: 100, 186 224 useNativeDriver: true, 225 + isInteraction: false, 187 226 }).start() 188 227 } 189 228 }, [minimalShellInterp, store.shell.minimalShellMode]) ··· 343 382 ) 344 383 } 345 384 346 - const isAtHome = store.nav.tab.current.url === '/' 347 - const isAtNotifications = store.nav.tab.current.url === '/notifications' 385 + const isAtHome = 386 + store.nav.tab.current.url === TabPurposeMainPath[TabPurpose.Default] 387 + const isAtSearch = 388 + store.nav.tab.current.url === TabPurposeMainPath[TabPurpose.Search] 389 + const isAtNotifications = 390 + store.nav.tab.current.url === TabPurposeMainPath[TabPurpose.Notifs] 348 391 349 392 const screenBg = { 350 393 backgroundColor: theme.colorScheme === 'dark' ? colors.gray7 : colors.gray1, ··· 358 401 /> 359 402 <View style={[styles.innerContainer, {paddingTop: safeAreaInsets.top}]}> 360 403 <HorzSwipe 361 - distThresholdDivisor={1.5} 404 + distThresholdDivisor={2.5} 362 405 useNativeDriver 363 406 panX={swipeGestureInterp} 364 407 swipeEnabled ··· 405 448 params={params} 406 449 navIdx={navIdx} 407 450 visible={current} 408 - scrollElRef={current ? scrollElRef : undefined} 409 451 /> 410 452 </ErrorBoundary> 411 453 </Animated.View> ··· 454 496 onPress={onPressHome} 455 497 onLongPress={TABS_ENABLED ? doNewTab('/') : undefined} 456 498 /> 499 + <Btn 500 + icon={isAtSearch ? 'search-solid' : 'search'} 501 + onPress={onPressSearch} 502 + onLongPress={TABS_ENABLED ? doNewTab('/') : undefined} 503 + /> 457 504 {TABS_ENABLED ? ( 458 505 <Btn 459 506 icon={isTabsSelectorActive ? 'clone' : ['far', 'clone']} ··· 465 512 icon={isAtNotifications ? 'bell-solid' : 'bell'} 466 513 onPress={onPressNotifications} 467 514 onLongPress={TABS_ENABLED ? doNewTab('/notifications') : undefined} 468 - notificationCount={store.me.notificationCount} 515 + notificationCount={store.me.notifications.unreadCount} 469 516 /> 470 517 </Animated.View> 471 518 <Modal /> ··· 576 623 flexDirection: 'row', 577 624 borderTopWidth: 1, 578 625 paddingLeft: 5, 579 - paddingRight: 15, 626 + paddingRight: 25, 580 627 }, 581 628 ctrl: { 582 629 flex: 1, ··· 613 660 }, 614 661 inactive: { 615 662 color: colors.gray3, 663 + }, 664 + bumpUpOnePixel: { 665 + position: 'relative', 666 + top: -1, 616 667 }, 617 668 })
+2 -2
src/view/shell/web/Composer.tsx
··· 2 2 import {observer} from 'mobx-react-lite' 3 3 import {StyleSheet, View} from 'react-native' 4 4 import {ComposePost} from '../../com/composer/ComposePost' 5 - import {ComposerOpts} from '../../../state/models/shell-ui' 6 - import {usePalette} from '../../lib/hooks/usePalette' 5 + import {ComposerOpts} from 'state/models/shell-ui' 6 + import {usePalette} from 'lib/hooks/usePalette' 7 7 8 8 export const Composer = observer( 9 9 ({
+5 -5
src/view/shell/web/DesktopLeftColumn.tsx
··· 5 5 import {Link} from '../../com/util/Link' 6 6 import {Text} from '../../com/util/text/Text' 7 7 import {UserAvatar} from '../../com/util/UserAvatar' 8 - import {s, colors, gradients} from '../../lib/styles' 9 - import {useStores} from '../../../state' 10 - import {usePalette} from '../../lib/hooks/usePalette' 8 + import {s, colors, gradients} from 'lib/styles' 9 + import {useStores} from 'state/index' 10 + import {usePalette} from 'lib/hooks/usePalette' 11 11 import { 12 12 HomeIcon, 13 13 HomeIconSolid, ··· 15 15 BellIconSolid, 16 16 MagnifyingGlassIcon, 17 17 CogIcon, 18 - } from '../../lib/icons' 18 + } from 'lib/icons' 19 19 20 20 interface NavItemProps { 21 21 label: string ··· 97 97 <NavItem 98 98 href="/notifications" 99 99 label="Notifications" 100 - count={store.me.notificationCount} 100 + count={store.me.notifications.unreadCount} 101 101 icon={<BellIcon />} 102 102 iconFilled={<BellIconSolid />} 103 103 />
+3 -3
src/view/shell/web/DesktopRightColumn.tsx
··· 2 2 import {View, StyleSheet} from 'react-native' 3 3 import {Link} from '../../com/util/Link' 4 4 import {Text} from '../../com/util/text/Text' 5 - import {usePalette} from '../../lib/hooks/usePalette' 6 - import {MagnifyingGlassIcon} from '../../lib/icons' 5 + import {usePalette} from 'lib/hooks/usePalette' 6 + import {MagnifyingGlassIcon} from 'lib/icons' 7 7 import {LiteSuggestedFollows} from '../../com/discover/LiteSuggestedFollows' 8 - import {s} from '../../lib/styles' 8 + import {s} from 'lib/styles' 9 9 10 10 export const DesktopRightColumn: React.FC = () => { 11 11 const pal = usePalette('default')
+5 -3
src/view/shell/web/index.tsx
··· 1 1 import React from 'react' 2 2 import {observer} from 'mobx-react-lite' 3 3 import {View, StyleSheet} from 'react-native' 4 - import {useStores} from '../../../state' 4 + import {IconProp} from '@fortawesome/fontawesome-svg-core' 5 + import {useStores} from 'state/index' 6 + import {NavigationModel} from 'state/models/navigation' 5 7 import {match, MatchResult} from '../../routes' 6 8 import {DesktopLeftColumn} from './DesktopLeftColumn' 7 9 import {DesktopRightColumn} from './DesktopRightColumn' ··· 11 13 import {Lightbox} from '../../com/lightbox/Lightbox' 12 14 import {Modal} from '../../com/modals/Modal' 13 15 import {Composer} from './Composer' 14 - import {usePalette} from '../../lib/hooks/usePalette' 15 - import {s} from '../../lib/styles' 16 + import {usePalette} from 'lib/hooks/usePalette' 17 + import {s} from 'lib/styles' 16 18 17 19 export const WebShell: React.FC = observer(() => { 18 20 const pal = usePalette('default')
+8 -1
tsconfig.json
··· 1 1 { 2 - "extends": "@tsconfig/react-native/tsconfig.json" 2 + "extends": "@tsconfig/react-native/tsconfig.json", 3 + "compilerOptions": { 4 + "paths": { 5 + "lib/*": ["./src/lib/*"], 6 + "state/*": ["./src/state/*"], 7 + "view/*": ["./src/view/*"] 8 + } 9 + } 3 10 }
+16 -1
web/webpack.config.js
··· 44 44 }, 45 45 } 46 46 47 + const reactNativeWebWebviewConfiguration = { 48 + test: /postMock.html$/, 49 + use: { 50 + loader: 'file-loader', 51 + options: { 52 + name: '[name].[ext]', 53 + }, 54 + }, 55 + } 56 + 47 57 module.exports = { 48 58 mode: webpackEnv, 49 59 ··· 64 74 ], 65 75 66 76 module: { 67 - rules: [babelLoaderConfiguration, imageLoaderConfiguration], 77 + rules: [ 78 + babelLoaderConfiguration, 79 + imageLoaderConfiguration, 80 + reactNativeWebWebviewConfiguration, 81 + ], 68 82 }, 69 83 70 84 resolve: { 71 85 alias: { 72 86 'react-native$': 'react-native-web', 73 87 'react-native-linear-gradient': 'react-native-web-linear-gradient', 88 + 'react-native-webview': 'react-native-web-webview', 74 89 }, 75 90 extensions: [ 76 91 '.web.tsx',
+1832 -1499
yarn.lock
··· 2 2 # yarn lockfile v1 3 3 4 4 5 - "@ampproject/remapping@^2.1.0": 5 + "@ampproject/remapping@^2.2.0": 6 6 version "2.2.0" 7 7 resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" 8 8 integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== ··· 19 19 jsonpointer "^5.0.0" 20 20 leven "^3.1.0" 21 21 22 - "@atproto/api@^0.0.6": 23 - version "0.0.6" 24 - resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.0.6.tgz#4b4f0d46549e75ef8425bf3fdfb2b5f742395b5e" 25 - integrity sha512-yG5S+Mz+Z6K7qUTRVc3oAFWaoW92IeiB8yDT5rIxkrON/r3gez1LVnBOAU0dgeLFZ1mdRsF5pycX+zcleTYInQ== 22 + "@atproto/api@^0.1.2": 23 + version "0.1.2" 24 + resolved "https://registry.yarnpkg.com/@atproto/api/-/api-0.1.2.tgz#66102f9203ba499432bc5aeb30cd19313ab2e4fc" 25 + integrity sha512-lDcFGkrk0J7rkIPSie18xS7sO3IL6DsosX8GgoeqCNeVaDuphBRaFCcpBUWf0q4fHrpmdgghGo4ulefyKHTIFQ== 26 26 dependencies: 27 27 "@atproto/xrpc" "*" 28 28 typed-emitter "^2.1.0" ··· 90 90 resolved "https://registry.yarnpkg.com/@atproto/nsid/-/nsid-0.0.1.tgz#0cdc00cefe8f0b1385f352b9f57b3ad37fff09a4" 91 91 integrity sha512-t5M6/CzWBVYoBbIvfKDpqPj/+ZmyoK9ydZSStcTXosJ27XXwOPhz0VDUGKK2SM9G5Y7TPes8S5KTAU0UdVYFCw== 92 92 93 - "@atproto/pds@^0.0.1": 94 - version "0.0.1" 95 - resolved "https://registry.yarnpkg.com/@atproto/pds/-/pds-0.0.1.tgz#4492595cd0796a3dc4c10836cd121bb3b132f858" 96 - integrity sha512-8CaAIBzri05CN2gkMtXnUlNxCdUwaWp1qz4b9RXpMQ83Pk1+j3nw09fsml0kjlMCPcWokTF+iGJXrrTL3XVjOw== 93 + "@atproto/pds@^0.0.3": 94 + version "0.0.3" 95 + resolved "https://registry.yarnpkg.com/@atproto/pds/-/pds-0.0.3.tgz#118a1d51687664f085f8e1c19ae3ac1646dc69b2" 96 + integrity sha512-l5iGJNyQs73V/mQWkcg4NXNGbnfXfv+Yg3g8nqwtun409iAAeYZimA1Tt0JV/hyq+Oz3antG0VvLQQEtNVUpVQ== 97 97 dependencies: 98 - "@atproto/auth" "*" 99 98 "@atproto/common" "*" 100 99 "@atproto/crypto" "*" 101 100 "@atproto/did-resolver" "*" ··· 125 124 pino "^8.6.1" 126 125 pino-http "^8.2.1" 127 126 sharp "^0.31.2" 127 + typed-emitter "^2.1.0" 128 128 uint8arrays "3.0.0" 129 129 130 130 "@atproto/plc@*": ··· 181 181 mime-types "^2.1.35" 182 182 zod "^3.14.2" 183 183 184 - "@atproto/xrpc@*", "@atproto/xrpc@^0.0.3": 185 - version "0.0.3" 186 - resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.0.3.tgz#510028753d51dffd754ee4f96897b74bcba50bda" 187 - integrity sha512-dOxtUqUfXOalPhtc1jyIvzCasd+iXwt/Sp+QIAy5qOTCxF9IvXuJ9bNFY49NUPEWlagaRtL8glQhbR307GHcuA== 184 + "@atproto/xrpc@*", "@atproto/xrpc@^0.0.4": 185 + version "0.0.4" 186 + resolved "https://registry.yarnpkg.com/@atproto/xrpc/-/xrpc-0.0.4.tgz#d7dd45cdb21e29b9715ca30eb18320548f293413" 187 + integrity sha512-Hxh+GgZx21Zvlb2RMlSlJDd3r3GR0vAS6OOZPW2xzWiVHsetb9ZlFB6D0AeAPj2R+U2UUkmdUR8G3U/nkgnQFA== 188 188 dependencies: 189 189 "@atproto/lexicon" "*" 190 190 zod "^3.14.2" ··· 197 197 "@babel/highlight" "^7.18.6" 198 198 199 199 "@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.1", "@babel/compat-data@^7.20.5": 200 - version "7.20.10" 201 - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.10.tgz#9d92fa81b87542fff50e848ed585b4212c1d34ec" 202 - integrity sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg== 200 + version "7.21.0" 201 + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.21.0.tgz#c241dc454e5b5917e40d37e525e2f4530c399298" 202 + integrity sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g== 203 203 204 - "@babel/core@^7.1.0", "@babel/core@^7.11.1", "@babel/core@^7.12.3", "@babel/core@^7.12.9", "@babel/core@^7.13.16", "@babel/core@^7.14.0", "@babel/core@^7.16.0", "@babel/core@^7.7.2", "@babel/core@^7.8.0": 205 - version "7.20.7" 206 - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.7.tgz#37072f951bd4d28315445f66e0ec9f6ae0c8c35f" 207 - integrity sha512-t1ZjCluspe5DW24bn2Rr1CDb2v9rn/hROtg9a2tmd0+QYf4bsloYfLQzjG4qHPNMhWtKdGC33R5AxGR2Af2cBw== 204 + "@babel/core@^7.1.0", "@babel/core@^7.11.1", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.13.16", "@babel/core@^7.14.0", "@babel/core@^7.16.0", "@babel/core@^7.20.0", "@babel/core@^7.7.2", "@babel/core@^7.8.0": 205 + version "7.21.0" 206 + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.21.0.tgz#1341aefdcc14ccc7553fcc688dd8986a2daffc13" 207 + integrity sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA== 208 208 dependencies: 209 - "@ampproject/remapping" "^2.1.0" 209 + "@ampproject/remapping" "^2.2.0" 210 210 "@babel/code-frame" "^7.18.6" 211 - "@babel/generator" "^7.20.7" 211 + "@babel/generator" "^7.21.0" 212 212 "@babel/helper-compilation-targets" "^7.20.7" 213 - "@babel/helper-module-transforms" "^7.20.7" 214 - "@babel/helpers" "^7.20.7" 215 - "@babel/parser" "^7.20.7" 213 + "@babel/helper-module-transforms" "^7.21.0" 214 + "@babel/helpers" "^7.21.0" 215 + "@babel/parser" "^7.21.0" 216 216 "@babel/template" "^7.20.7" 217 - "@babel/traverse" "^7.20.7" 218 - "@babel/types" "^7.20.7" 219 - convert-source-map "^1.7.0" 220 - debug "^4.1.0" 221 - gensync "^1.0.0-beta.2" 222 - json5 "^2.2.1" 223 - semver "^6.3.0" 224 - 225 - "@babel/core@^7.11.6", "@babel/core@^7.20.0": 226 - version "7.20.12" 227 - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.12.tgz#7930db57443c6714ad216953d1356dac0eb8496d" 228 - integrity sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg== 229 - dependencies: 230 - "@ampproject/remapping" "^2.1.0" 231 - "@babel/code-frame" "^7.18.6" 232 - "@babel/generator" "^7.20.7" 233 - "@babel/helper-compilation-targets" "^7.20.7" 234 - "@babel/helper-module-transforms" "^7.20.11" 235 - "@babel/helpers" "^7.20.7" 236 - "@babel/parser" "^7.20.7" 237 - "@babel/template" "^7.20.7" 238 - "@babel/traverse" "^7.20.12" 239 - "@babel/types" "^7.20.7" 217 + "@babel/traverse" "^7.21.0" 218 + "@babel/types" "^7.21.0" 240 219 convert-source-map "^1.7.0" 241 220 debug "^4.1.0" 242 221 gensync "^1.0.0-beta.2" ··· 252 231 eslint-visitor-keys "^2.1.0" 253 232 semver "^6.3.0" 254 233 255 - "@babel/generator@^7.20.0", "@babel/generator@^7.20.7", "@babel/generator@^7.7.2": 256 - version "7.20.7" 257 - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.7.tgz#f8ef57c8242665c5929fe2e8d82ba75460187b4a" 258 - integrity sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw== 234 + "@babel/generator@^7.20.0", "@babel/generator@^7.21.0", "@babel/generator@^7.7.2": 235 + version "7.21.1" 236 + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.1.tgz#951cc626057bc0af2c35cd23e9c64d384dea83dd" 237 + integrity sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA== 259 238 dependencies: 260 - "@babel/types" "^7.20.7" 239 + "@babel/types" "^7.21.0" 261 240 "@jridgewell/gen-mapping" "^0.3.2" 241 + "@jridgewell/trace-mapping" "^0.3.17" 262 242 jsesc "^2.5.1" 263 243 264 244 "@babel/helper-annotate-as-pure@^7.18.6": ··· 287 267 lru-cache "^5.1.1" 288 268 semver "^6.3.0" 289 269 290 - "@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.20.5", "@babel/helper-create-class-features-plugin@^7.20.7": 291 - version "7.20.7" 292 - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.7.tgz#d0e1f8d7e4ed5dac0389364d9c0c191d948ade6f" 293 - integrity sha512-LtoWbDXOaidEf50hmdDqn9g8VEzsorMexoWMQdQODbvmqYmaF23pBP5VNPAGIFHsFQCIeKokDiz3CH5Y2jlY6w== 270 + "@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0": 271 + version "7.21.0" 272 + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.0.tgz#64f49ecb0020532f19b1d014b03bccaa1ab85fb9" 273 + integrity sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ== 294 274 dependencies: 295 275 "@babel/helper-annotate-as-pure" "^7.18.6" 296 276 "@babel/helper-environment-visitor" "^7.18.9" 297 - "@babel/helper-function-name" "^7.19.0" 298 - "@babel/helper-member-expression-to-functions" "^7.20.7" 277 + "@babel/helper-function-name" "^7.21.0" 278 + "@babel/helper-member-expression-to-functions" "^7.21.0" 299 279 "@babel/helper-optimise-call-expression" "^7.18.6" 300 280 "@babel/helper-replace-supers" "^7.20.7" 281 + "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" 301 282 "@babel/helper-split-export-declaration" "^7.18.6" 302 283 303 284 "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.20.5": 304 - version "7.20.5" 305 - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz#5ea79b59962a09ec2acf20a963a01ab4d076ccca" 306 - integrity sha512-m68B1lkg3XDGX5yCvGO0kPx3v9WIYLnzjKfPcQiwntEQa5ZeRkPmo2X/ISJc8qxWGfwUr+kvZAeEzAwLec2r2w== 285 + version "7.21.0" 286 + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.21.0.tgz#53ff78472e5ce10a52664272a239787107603ebb" 287 + integrity sha512-N+LaFW/auRSWdx7SHD/HiARwXQju1vXTW4fKr4u5SgBUTm51OKEjKgj+cs00ggW3kEvNqwErnlwuq7Y3xBe4eg== 307 288 dependencies: 308 289 "@babel/helper-annotate-as-pure" "^7.18.6" 309 - regexpu-core "^5.2.1" 290 + regexpu-core "^5.3.1" 310 291 311 292 "@babel/helper-define-polyfill-provider@^0.3.3": 312 293 version "0.3.3" ··· 332 313 dependencies: 333 314 "@babel/types" "^7.18.6" 334 315 335 - "@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0": 336 - version "7.19.0" 337 - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" 338 - integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== 316 + "@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0", "@babel/helper-function-name@^7.21.0": 317 + version "7.21.0" 318 + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz#d552829b10ea9f120969304023cd0645fa00b1b4" 319 + integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg== 339 320 dependencies: 340 - "@babel/template" "^7.18.10" 341 - "@babel/types" "^7.19.0" 321 + "@babel/template" "^7.20.7" 322 + "@babel/types" "^7.21.0" 342 323 343 324 "@babel/helper-hoist-variables@^7.18.6": 344 325 version "7.18.6" ··· 347 328 dependencies: 348 329 "@babel/types" "^7.18.6" 349 330 350 - "@babel/helper-member-expression-to-functions@^7.20.7": 351 - version "7.20.7" 352 - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz#a6f26e919582275a93c3aa6594756d71b0bb7f05" 353 - integrity sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw== 331 + "@babel/helper-member-expression-to-functions@^7.20.7", "@babel/helper-member-expression-to-functions@^7.21.0": 332 + version "7.21.0" 333 + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz#319c6a940431a133897148515877d2f3269c3ba5" 334 + integrity sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q== 354 335 dependencies: 355 - "@babel/types" "^7.20.7" 336 + "@babel/types" "^7.21.0" 356 337 357 338 "@babel/helper-module-imports@^7.10.4", "@babel/helper-module-imports@^7.18.6": 358 339 version "7.18.6" ··· 361 342 dependencies: 362 343 "@babel/types" "^7.18.6" 363 344 364 - "@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.20.11", "@babel/helper-module-transforms@^7.20.7": 365 - version "7.20.11" 366 - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz#df4c7af713c557938c50ea3ad0117a7944b2f1b0" 367 - integrity sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg== 345 + "@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.20.11", "@babel/helper-module-transforms@^7.21.0": 346 + version "7.21.0" 347 + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.21.0.tgz#89a8f86ad748870e3d024e470b2e8405e869db67" 348 + integrity sha512-eD/JQ21IG2i1FraJnTMbUarAUkA7G988ofehG5MDCRXaUU91rEBJuCeSoou2Sk1y4RbLYXzqEg1QLwEmRU4qcQ== 368 349 dependencies: 369 350 "@babel/helper-environment-visitor" "^7.18.9" 370 351 "@babel/helper-module-imports" "^7.18.6" ··· 372 353 "@babel/helper-split-export-declaration" "^7.18.6" 373 354 "@babel/helper-validator-identifier" "^7.19.1" 374 355 "@babel/template" "^7.20.7" 375 - "@babel/traverse" "^7.20.10" 376 - "@babel/types" "^7.20.7" 356 + "@babel/traverse" "^7.21.0" 357 + "@babel/types" "^7.21.0" 377 358 378 359 "@babel/helper-optimise-call-expression@^7.18.6": 379 360 version "7.18.6" ··· 440 421 resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" 441 422 integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== 442 423 443 - "@babel/helper-validator-option@^7.18.6": 444 - version "7.18.6" 445 - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" 446 - integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== 424 + "@babel/helper-validator-option@^7.18.6", "@babel/helper-validator-option@^7.21.0": 425 + version "7.21.0" 426 + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz#8224c7e13ace4bafdc4004da2cf064ef42673180" 427 + integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ== 447 428 448 429 "@babel/helper-wrap-function@^7.18.9": 449 430 version "7.20.5" ··· 455 436 "@babel/traverse" "^7.20.5" 456 437 "@babel/types" "^7.20.5" 457 438 458 - "@babel/helpers@^7.20.7": 459 - version "7.20.7" 460 - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.7.tgz#04502ff0feecc9f20ecfaad120a18f011a8e6dce" 461 - integrity sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA== 439 + "@babel/helpers@^7.21.0": 440 + version "7.21.0" 441 + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.21.0.tgz#9dd184fb5599862037917cdc9eecb84577dc4e7e" 442 + integrity sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA== 462 443 dependencies: 463 444 "@babel/template" "^7.20.7" 464 - "@babel/traverse" "^7.20.7" 465 - "@babel/types" "^7.20.7" 445 + "@babel/traverse" "^7.21.0" 446 + "@babel/types" "^7.21.0" 466 447 467 448 "@babel/highlight@^7.18.6": 468 449 version "7.18.6" ··· 473 454 chalk "^2.0.0" 474 455 js-tokens "^4.0.0" 475 456 476 - "@babel/parser@^7.1.0", "@babel/parser@^7.13.16", "@babel/parser@^7.14.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.0", "@babel/parser@^7.20.7": 477 - version "7.20.7" 478 - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.7.tgz#66fe23b3c8569220817d5feb8b9dcdc95bb4f71b" 479 - integrity sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg== 457 + "@babel/parser@^7.1.0", "@babel/parser@^7.13.16", "@babel/parser@^7.14.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.0", "@babel/parser@^7.20.7", "@babel/parser@^7.21.0": 458 + version "7.21.1" 459 + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.1.tgz#a8f81ee2fe872af23faea4b17a08fcc869de7bcc" 460 + integrity sha512-JzhBFpkuhBNYUY7qs+wTzNmyCWUHEaAFpQQD2YfU1rPL38/L43Wvid0fFkiOCnHvsGncRZgEPyGnltABLcVDTg== 480 461 481 462 "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": 482 463 version "7.18.6" ··· 513 494 "@babel/helper-plugin-utils" "^7.18.6" 514 495 515 496 "@babel/plugin-proposal-class-static-block@^7.18.6": 516 - version "7.20.7" 517 - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.20.7.tgz#92592e9029b13b15be0f7ce6a7aedc2879ca45a7" 518 - integrity sha512-AveGOoi9DAjUYYuUAG//Ig69GlazLnoyzMw68VCDux+c1tsnnH/OkYcpz/5xzMkEFC6UxjR5Gw1c+iY2wOGVeQ== 497 + version "7.21.0" 498 + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.21.0.tgz#77bdd66fb7b605f3a61302d224bdfacf5547977d" 499 + integrity sha512-XP5G9MWNUskFuP30IfFSEFB0Z6HzLIUcjYM4bYOPHXl7eiJ9HFv8tWj6TXTN5QODiEhDZAeI4hLok2iHFFV4hw== 519 500 dependencies: 520 - "@babel/helper-create-class-features-plugin" "^7.20.7" 501 + "@babel/helper-create-class-features-plugin" "^7.21.0" 521 502 "@babel/helper-plugin-utils" "^7.20.2" 522 503 "@babel/plugin-syntax-class-static-block" "^7.14.5" 523 504 524 505 "@babel/plugin-proposal-decorators@^7.16.4": 525 - version "7.20.7" 526 - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.7.tgz#05d37453c2ce818f3e47bbeda9468c8de947eecc" 527 - integrity sha512-JB45hbUweYpwAGjkiM7uCyXMENH2lG+9r3G2E+ttc2PRXAoEkpfd/KW5jDg4j8RS6tLtTG1jZi9LbHZVSfs1/A== 506 + version "7.21.0" 507 + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.21.0.tgz#70e0c89fdcd7465c97593edb8f628ba6e4199d63" 508 + integrity sha512-MfgX49uRrFUTL/HvWtmx3zmpyzMMr4MTj3d527MLlr/4RTT9G/ytFFP7qet2uM2Ve03b+BkpWUpK+lRXnQ+v9w== 528 509 dependencies: 529 - "@babel/helper-create-class-features-plugin" "^7.20.7" 510 + "@babel/helper-create-class-features-plugin" "^7.21.0" 530 511 "@babel/helper-plugin-utils" "^7.20.2" 531 512 "@babel/helper-replace-supers" "^7.20.7" 532 513 "@babel/helper-split-export-declaration" "^7.18.6" 533 - "@babel/plugin-syntax-decorators" "^7.19.0" 514 + "@babel/plugin-syntax-decorators" "^7.21.0" 534 515 535 516 "@babel/plugin-proposal-dynamic-import@^7.18.6": 536 517 version "7.18.6" ··· 608 589 "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" 609 590 610 591 "@babel/plugin-proposal-optional-chaining@^7.0.0", "@babel/plugin-proposal-optional-chaining@^7.13.12", "@babel/plugin-proposal-optional-chaining@^7.16.0", "@babel/plugin-proposal-optional-chaining@^7.18.9", "@babel/plugin-proposal-optional-chaining@^7.20.7": 611 - version "7.20.7" 612 - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.20.7.tgz#49f2b372519ab31728cc14115bb0998b15bfda55" 613 - integrity sha512-T+A7b1kfjtRM51ssoOfS1+wbyCVqorfyZhT99TvxxLMirPShD8CzKMRepMlCBGM5RpHMbn8s+5MMHnPstJH6mQ== 592 + version "7.21.0" 593 + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz#886f5c8978deb7d30f678b2e24346b287234d3ea" 594 + integrity sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA== 614 595 dependencies: 615 596 "@babel/helper-plugin-utils" "^7.20.2" 616 597 "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" ··· 625 606 "@babel/helper-plugin-utils" "^7.18.6" 626 607 627 608 "@babel/plugin-proposal-private-property-in-object@^7.18.6": 628 - version "7.20.5" 629 - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.20.5.tgz#309c7668f2263f1c711aa399b5a9a6291eef6135" 630 - integrity sha512-Vq7b9dUA12ByzB4EjQTPo25sFhY+08pQDBSZRtUAkj7lb7jahaHR5igera16QZ+3my1nYR4dKsNdYj5IjPHilQ== 609 + version "7.21.0" 610 + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0.tgz#19496bd9883dd83c23c7d7fc45dcd9ad02dfa1dc" 611 + integrity sha512-ha4zfehbJjc5MmXBlHec1igel5TJXXLDDRbuJ4+XT2TJcyD9/V1919BA8gMvsdHcNMBy4WBUBiRb3nw/EQUtBw== 631 612 dependencies: 632 613 "@babel/helper-annotate-as-pure" "^7.18.6" 633 - "@babel/helper-create-class-features-plugin" "^7.20.5" 614 + "@babel/helper-create-class-features-plugin" "^7.21.0" 634 615 "@babel/helper-plugin-utils" "^7.20.2" 635 616 "@babel/plugin-syntax-private-property-in-object" "^7.14.5" 636 617 ··· 670 651 dependencies: 671 652 "@babel/helper-plugin-utils" "^7.14.5" 672 653 673 - "@babel/plugin-syntax-decorators@^7.19.0": 674 - version "7.19.0" 675 - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.19.0.tgz#5f13d1d8fce96951bea01a10424463c9a5b3a599" 676 - integrity sha512-xaBZUEDntt4faL1yN8oIFlhfXeQAWJW7CLKYsHTUqriCUbj8xOra8bfxxKGi/UwExPFBuPdH4XfHc9rGQhrVkQ== 654 + "@babel/plugin-syntax-decorators@^7.21.0": 655 + version "7.21.0" 656 + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.21.0.tgz#d2b3f31c3e86fa86e16bb540b7660c55bd7d0e78" 657 + integrity sha512-tIoPpGBR8UuM4++ccWN3gifhVvQu7ZizuR1fklhRJrd5ewgbkUS+0KVFeWWxELtn18NTLoW32XV7zyOgIAiz+w== 677 658 dependencies: 678 - "@babel/helper-plugin-utils" "^7.19.0" 659 + "@babel/helper-plugin-utils" "^7.20.2" 679 660 680 661 "@babel/plugin-syntax-dynamic-import@^7.0.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": 681 662 version "7.8.3" ··· 698 679 dependencies: 699 680 "@babel/helper-plugin-utils" "^7.8.3" 700 681 701 - "@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.18.0", "@babel/plugin-syntax-flow@^7.18.6", "@babel/plugin-syntax-flow@^7.2.0": 682 + "@babel/plugin-syntax-flow@^7.0.0", "@babel/plugin-syntax-flow@^7.18.0", "@babel/plugin-syntax-flow@^7.18.6": 702 683 version "7.18.6" 703 684 resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.18.6.tgz#774d825256f2379d06139be0c723c4dd444f3ca1" 704 685 integrity sha512-LUbR+KNTBWCUAqRG9ex5Gnzu2IOkt8jRJbHHXFT9q+L9zm7M/QQbEqXyw1n1pohYvOyWC8CjeyjrSaIwiYjK7A== ··· 820 801 "@babel/helper-plugin-utils" "^7.18.6" 821 802 822 803 "@babel/plugin-transform-block-scoping@^7.0.0", "@babel/plugin-transform-block-scoping@^7.20.2": 823 - version "7.20.11" 824 - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.20.11.tgz#9f5a3424bd112a3f32fe0cf9364fbb155cff262a" 825 - integrity sha512-tA4N427a7fjf1P0/2I4ScsHGc5jcHPbb30xMbaTke2gxDuWpUfXDuX1FEymJwKk4tuGUvGcejAR6HdZVqmmPyw== 804 + version "7.21.0" 805 + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.21.0.tgz#e737b91037e5186ee16b76e7ae093358a5634f02" 806 + integrity sha512-Mdrbunoh9SxwFZapeHVrwFmri16+oYotcZysSzhNIVDwIAb1UV+kvnxULSYq9J3/q5MDG+4X6w8QVgD1zhBXNQ== 826 807 dependencies: 827 808 "@babel/helper-plugin-utils" "^7.20.2" 828 809 829 810 "@babel/plugin-transform-classes@^7.0.0", "@babel/plugin-transform-classes@^7.20.2": 830 - version "7.20.7" 831 - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.20.7.tgz#f438216f094f6bb31dc266ebfab8ff05aecad073" 832 - integrity sha512-LWYbsiXTPKl+oBlXUGlwNlJZetXD5Am+CyBdqhPsDVjM9Jc8jwBJFrKhHf900Kfk2eZG1y9MAG3UNajol7A4VQ== 811 + version "7.21.0" 812 + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.21.0.tgz#f469d0b07a4c5a7dbb21afad9e27e57b47031665" 813 + integrity sha512-RZhbYTCEUAe6ntPehC4hlslPWosNHDox+vAs4On/mCLRLfoDVHf6hVEd7kuxr1RnHwJmxFfUM3cZiZRmPxJPXQ== 833 814 dependencies: 834 815 "@babel/helper-annotate-as-pure" "^7.18.6" 835 816 "@babel/helper-compilation-targets" "^7.20.7" 836 817 "@babel/helper-environment-visitor" "^7.18.9" 837 - "@babel/helper-function-name" "^7.19.0" 818 + "@babel/helper-function-name" "^7.21.0" 838 819 "@babel/helper-optimise-call-expression" "^7.18.6" 839 820 "@babel/helper-plugin-utils" "^7.20.2" 840 821 "@babel/helper-replace-supers" "^7.20.7" ··· 880 861 "@babel/helper-plugin-utils" "^7.18.6" 881 862 882 863 "@babel/plugin-transform-flow-strip-types@^7.0.0", "@babel/plugin-transform-flow-strip-types@^7.16.0", "@babel/plugin-transform-flow-strip-types@^7.18.6": 883 - version "7.19.0" 884 - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.19.0.tgz#e9e8606633287488216028719638cbbb2f2dde8f" 885 - integrity sha512-sgeMlNaQVbCSpgLSKP4ZZKfsJVnFnNQlUSk6gPYzR/q7tzCgQF2t8RBKAP6cKJeZdveei7Q7Jm527xepI8lNLg== 864 + version "7.21.0" 865 + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.21.0.tgz#6aeca0adcb81dc627c8986e770bfaa4d9812aff5" 866 + integrity sha512-FlFA2Mj87a6sDkW4gfGrQQqwY/dLlBAyJa2dJEZ+FHXUVHBflO2wyKvg+OOEzXfrKYIa4HWl0mgmbCzt0cMb7w== 886 867 dependencies: 887 - "@babel/helper-plugin-utils" "^7.19.0" 868 + "@babel/helper-plugin-utils" "^7.20.2" 888 869 "@babel/plugin-syntax-flow" "^7.18.6" 889 870 890 871 "@babel/plugin-transform-for-of@^7.0.0", "@babel/plugin-transform-for-of@^7.18.8": 891 - version "7.18.8" 892 - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz#6ef8a50b244eb6a0bdbad0c7c61877e4e30097c1" 893 - integrity sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ== 872 + version "7.21.0" 873 + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.21.0.tgz#964108c9988de1a60b4be2354a7d7e245f36e86e" 874 + integrity sha512-LlUYlydgDkKpIY7mcBWvyPPmMcOphEyYA27Ef4xpbh1IiDNLr0kZsos2nf92vz3IccvJI25QUwp86Eo5s6HmBQ== 894 875 dependencies: 895 - "@babel/helper-plugin-utils" "^7.18.6" 876 + "@babel/helper-plugin-utils" "^7.20.2" 896 877 897 878 "@babel/plugin-transform-function-name@^7.0.0", "@babel/plugin-transform-function-name@^7.18.9": 898 879 version "7.18.9" ··· 1018 999 "@babel/plugin-transform-react-jsx" "^7.18.6" 1019 1000 1020 1001 "@babel/plugin-transform-react-jsx-self@^7.0.0": 1021 - version "7.18.6" 1022 - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.18.6.tgz#3849401bab7ae8ffa1e3e5687c94a753fc75bda7" 1023 - integrity sha512-A0LQGx4+4Jv7u/tWzoJF7alZwnBDQd6cGLh9P+Ttk4dpiL+J5p7NSNv/9tlEFFJDq3kjxOavWmbm6t0Gk+A3Ig== 1002 + version "7.21.0" 1003 + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.21.0.tgz#ec98d4a9baafc5a1eb398da4cf94afbb40254a54" 1004 + integrity sha512-f/Eq+79JEu+KUANFks9UZCcvydOOGMgF7jBrcwjHa5jTZD8JivnhCJYvmlhR/WTXBWonDExPoW0eO/CR4QJirA== 1024 1005 dependencies: 1025 - "@babel/helper-plugin-utils" "^7.18.6" 1006 + "@babel/helper-plugin-utils" "^7.20.2" 1026 1007 1027 1008 "@babel/plugin-transform-react-jsx-source@^7.0.0": 1028 1009 version "7.19.6" ··· 1032 1013 "@babel/helper-plugin-utils" "^7.19.0" 1033 1014 1034 1015 "@babel/plugin-transform-react-jsx@^7.0.0", "@babel/plugin-transform-react-jsx@^7.18.6": 1035 - version "7.20.7" 1036 - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.20.7.tgz#025d85a1935fd7e19dfdcb1b1d4df34d4da484f7" 1037 - integrity sha512-Tfq7qqD+tRj3EoDhY00nn2uP2hsRxgYGi5mLQ5TimKav0a9Lrpd4deE+fcLXU8zFYRjlKPHZhpCvfEA6qnBxqQ== 1016 + version "7.21.0" 1017 + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.21.0.tgz#656b42c2fdea0a6d8762075d58ef9d4e3c4ab8a2" 1018 + integrity sha512-6OAWljMvQrZjR2DaNhVfRz6dkCAVV+ymcLUmaf8bccGOHn2v5rHJK3tTpij0BuhdYWP4LLaqj5lwcdlpAAPuvg== 1038 1019 dependencies: 1039 1020 "@babel/helper-annotate-as-pure" "^7.18.6" 1040 1021 "@babel/helper-module-imports" "^7.18.6" 1041 1022 "@babel/helper-plugin-utils" "^7.20.2" 1042 1023 "@babel/plugin-syntax-jsx" "^7.18.6" 1043 - "@babel/types" "^7.20.7" 1024 + "@babel/types" "^7.21.0" 1044 1025 1045 1026 "@babel/plugin-transform-react-pure-annotations@^7.18.6": 1046 1027 version "7.18.6" ··· 1066 1047 "@babel/helper-plugin-utils" "^7.18.6" 1067 1048 1068 1049 "@babel/plugin-transform-runtime@^7.0.0", "@babel/plugin-transform-runtime@^7.12.1", "@babel/plugin-transform-runtime@^7.16.4": 1069 - version "7.19.6" 1070 - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz#9d2a9dbf4e12644d6f46e5e75bfbf02b5d6e9194" 1071 - integrity sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw== 1050 + version "7.21.0" 1051 + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.21.0.tgz#2a884f29556d0a68cd3d152dcc9e6c71dfb6eee8" 1052 + integrity sha512-ReY6pxwSzEU0b3r2/T/VhqMKg/AkceBT19X0UptA3/tYi5Pe2eXgEUH+NNMC5nok6c6XQz5tyVTUpuezRfSMSg== 1072 1053 dependencies: 1073 1054 "@babel/helper-module-imports" "^7.18.6" 1074 - "@babel/helper-plugin-utils" "^7.19.0" 1055 + "@babel/helper-plugin-utils" "^7.20.2" 1075 1056 babel-plugin-polyfill-corejs2 "^0.3.3" 1076 1057 babel-plugin-polyfill-corejs3 "^0.6.0" 1077 1058 babel-plugin-polyfill-regenerator "^0.4.1" ··· 1113 1094 dependencies: 1114 1095 "@babel/helper-plugin-utils" "^7.18.9" 1115 1096 1116 - "@babel/plugin-transform-typescript@^7.18.6", "@babel/plugin-transform-typescript@^7.5.0": 1117 - version "7.20.7" 1118 - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.7.tgz#673f49499cd810ae32a1ea5f3f8fab370987e055" 1119 - integrity sha512-m3wVKEvf6SoszD8pu4NZz3PvfKRCMgk6D6d0Qi9hNnlM5M6CFS92EgF4EiHVLKbU0r/r7ty1hg7NPZwE7WRbYw== 1097 + "@babel/plugin-transform-typescript@^7.21.0", "@babel/plugin-transform-typescript@^7.5.0": 1098 + version "7.21.0" 1099 + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.0.tgz#f0956a153679e3b377ae5b7f0143427151e4c848" 1100 + integrity sha512-xo///XTPp3mDzTtrqXoBlK9eiAYW3wv9JXglcn/u1bi60RW11dEUxIgA8cbnDhutS1zacjMRmAwxE0gMklLnZg== 1120 1101 dependencies: 1121 - "@babel/helper-create-class-features-plugin" "^7.20.7" 1102 + "@babel/helper-create-class-features-plugin" "^7.21.0" 1122 1103 "@babel/helper-plugin-utils" "^7.20.2" 1123 1104 "@babel/plugin-syntax-typescript" "^7.20.0" 1124 1105 ··· 1137 1118 "@babel/helper-create-regexp-features-plugin" "^7.18.6" 1138 1119 "@babel/helper-plugin-utils" "^7.18.6" 1139 1120 1140 - "@babel/preset-env@^7.11.0", "@babel/preset-env@^7.12.1", "@babel/preset-env@^7.14.0", "@babel/preset-env@^7.16.4": 1121 + "@babel/preset-env@^7.11.0", "@babel/preset-env@^7.12.1", "@babel/preset-env@^7.16.4", "@babel/preset-env@^7.20.0": 1141 1122 version "7.20.2" 1142 1123 resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.20.2.tgz#9b1642aa47bb9f43a86f9630011780dab7f86506" 1143 1124 integrity sha512-1G0efQEWR1EHkKvKHqbG+IN/QdgwfByUpM5V5QroDzGV2t3S/WXNQd693cHiHTlCFMpr9B6FkPFXDA2lQcKoDg== ··· 1251 1232 "@babel/plugin-transform-react-pure-annotations" "^7.18.6" 1252 1233 1253 1234 "@babel/preset-typescript@^7.13.0", "@babel/preset-typescript@^7.16.0", "@babel/preset-typescript@^7.16.7": 1254 - version "7.18.6" 1255 - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz#ce64be3e63eddc44240c6358daefac17b3186399" 1256 - integrity sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ== 1235 + version "7.21.0" 1236 + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.21.0.tgz#bcbbca513e8213691fe5d4b23d9251e01f00ebff" 1237 + integrity sha512-myc9mpoVA5m1rF8K8DgLEatOYFDpwC+RkMkjZ0Du6uI62YvDe8uxIEYVs/VCdSJ097nlALiU/yBC7//3nI+hNg== 1257 1238 dependencies: 1258 - "@babel/helper-plugin-utils" "^7.18.6" 1259 - "@babel/helper-validator-option" "^7.18.6" 1260 - "@babel/plugin-transform-typescript" "^7.18.6" 1239 + "@babel/helper-plugin-utils" "^7.20.2" 1240 + "@babel/helper-validator-option" "^7.21.0" 1241 + "@babel/plugin-transform-typescript" "^7.21.0" 1261 1242 1262 1243 "@babel/register@^7.13.16": 1263 - version "7.18.9" 1264 - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.18.9.tgz#1888b24bc28d5cc41c412feb015e9ff6b96e439c" 1265 - integrity sha512-ZlbnXDcNYHMR25ITwwNKT88JiaukkdVj/nG7r3wnuXkOTHc60Uy05PwMCPre0hSkY68E6zK3xz+vUJSP2jWmcw== 1244 + version "7.21.0" 1245 + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.21.0.tgz#c97bf56c2472e063774f31d344c592ebdcefa132" 1246 + integrity sha512-9nKsPmYDi5DidAqJaQooxIhsLJiNMkGr8ypQ8Uic7cIox7UCDsM7HuUGxdGT7mSDTYbqzIdsOWzfBton/YJrMw== 1266 1247 dependencies: 1267 1248 clone-deep "^4.0.1" 1268 1249 find-cache-dir "^2.0.0" ··· 1270 1251 pirates "^4.0.5" 1271 1252 source-map-support "^0.5.16" 1272 1253 1273 - "@babel/runtime-corejs3@^7.10.2": 1274 - version "7.20.7" 1275 - resolved "https://registry.yarnpkg.com/@babel/runtime-corejs3/-/runtime-corejs3-7.20.7.tgz#a1e5ea3d758ba6beb715210142912e3f29981d84" 1276 - integrity sha512-jr9lCZ4RbRQmCR28Q8U8Fu49zvFqLxTY9AMOUz+iyMohMoAgpEcVxY+wJNay99oXOpOcCTODkk70NDN2aaJEeg== 1277 - dependencies: 1278 - core-js-pure "^3.25.1" 1279 - regenerator-runtime "^0.13.11" 1280 - 1281 - "@babel/runtime@^7.0.0", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.8.4": 1282 - version "7.20.7" 1283 - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.7.tgz#fcb41a5a70550e04a7b708037c7c32f7f356d8fd" 1284 - integrity sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ== 1285 - dependencies: 1286 - regenerator-runtime "^0.13.11" 1254 + "@babel/regjsgen@^0.8.0": 1255 + version "0.8.0" 1256 + resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" 1257 + integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== 1287 1258 1288 - "@babel/runtime@^7.18.6": 1289 - version "7.20.13" 1290 - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.13.tgz#7055ab8a7cff2b8f6058bf6ae45ff84ad2aded4b" 1291 - integrity sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA== 1259 + "@babel/runtime@^7.0.0", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.18.6", "@babel/runtime@^7.20.0", "@babel/runtime@^7.20.7", "@babel/runtime@^7.8.4": 1260 + version "7.21.0" 1261 + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673" 1262 + integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw== 1292 1263 dependencies: 1293 1264 regenerator-runtime "^0.13.11" 1294 1265 ··· 1301 1272 "@babel/parser" "^7.20.7" 1302 1273 "@babel/types" "^7.20.7" 1303 1274 1304 - "@babel/traverse@^7.14.0", "@babel/traverse@^7.20.10", "@babel/traverse@^7.20.5", "@babel/traverse@^7.20.7", "@babel/traverse@^7.7.2", "@babel/traverse@^7.7.4": 1305 - version "7.20.10" 1306 - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.10.tgz#2bf98239597fcec12f842756f186a9dde6d09230" 1307 - integrity sha512-oSf1juCgymrSez8NI4A2sr4+uB/mFd9MXplYGPEBnfAuWmmyeVcHa6xLPiaRBcXkcb/28bgxmQLTVwFKE1yfsg== 1308 - dependencies: 1309 - "@babel/code-frame" "^7.18.6" 1310 - "@babel/generator" "^7.20.7" 1311 - "@babel/helper-environment-visitor" "^7.18.9" 1312 - "@babel/helper-function-name" "^7.19.0" 1313 - "@babel/helper-hoist-variables" "^7.18.6" 1314 - "@babel/helper-split-export-declaration" "^7.18.6" 1315 - "@babel/parser" "^7.20.7" 1316 - "@babel/types" "^7.20.7" 1317 - debug "^4.1.0" 1318 - globals "^11.1.0" 1319 - 1320 - "@babel/traverse@^7.20.0", "@babel/traverse@^7.20.12": 1321 - version "7.20.12" 1322 - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.12.tgz#7f0f787b3a67ca4475adef1f56cb94f6abd4a4b5" 1323 - integrity sha512-MsIbFN0u+raeja38qboyF8TIT7K0BFzz/Yd/77ta4MsUsmP2RAnidIlwq7d5HFQrH/OZJecGV6B71C4zAgpoSQ== 1275 + "@babel/traverse@^7.20.0", "@babel/traverse@^7.20.5", "@babel/traverse@^7.20.7", "@babel/traverse@^7.21.0", "@babel/traverse@^7.7.2", "@babel/traverse@^7.7.4": 1276 + version "7.21.0" 1277 + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.0.tgz#0e1807abd5db98e6a19c204b80ed1e3f5bca0edc" 1278 + integrity sha512-Xdt2P1H4LKTO8ApPfnO1KmzYMFpp7D/EinoXzLYN/cHcBNrVCAkAtGUcXnHXrl/VGktureU6fkQrHSBE2URfoA== 1324 1279 dependencies: 1325 1280 "@babel/code-frame" "^7.18.6" 1326 - "@babel/generator" "^7.20.7" 1281 + "@babel/generator" "^7.21.0" 1327 1282 "@babel/helper-environment-visitor" "^7.18.9" 1328 - "@babel/helper-function-name" "^7.19.0" 1283 + "@babel/helper-function-name" "^7.21.0" 1329 1284 "@babel/helper-hoist-variables" "^7.18.6" 1330 1285 "@babel/helper-split-export-declaration" "^7.18.6" 1331 - "@babel/parser" "^7.20.7" 1332 - "@babel/types" "^7.20.7" 1286 + "@babel/parser" "^7.21.0" 1287 + "@babel/types" "^7.21.0" 1333 1288 debug "^4.1.0" 1334 1289 globals "^11.1.0" 1335 1290 1336 - "@babel/types@^7.0.0", "@babel/types@^7.12.6", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.5", "@babel/types@^7.20.7", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": 1337 - version "7.20.7" 1338 - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.7.tgz#54ec75e252318423fc07fb644dc6a58a64c09b7f" 1339 - integrity sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg== 1291 + "@babel/types@^7.0.0", "@babel/types@^7.12.6", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.5", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": 1292 + version "7.21.0" 1293 + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.0.tgz#1da00d89c2f18b226c9207d96edbeb79316a1819" 1294 + integrity sha512-uR7NWq2VNFnDi7EYqiRz2Jv/VQIu38tu64Zy8TX2nQFQ6etJ9V/Rr2msW8BS132mum2rL645qpDrLtAJtVpuow== 1340 1295 dependencies: 1341 1296 "@babel/helper-string-parser" "^7.19.4" 1342 1297 "@babel/helper-validator-identifier" "^7.19.1" 1343 1298 to-fast-properties "^2.0.0" 1344 1299 1345 1300 "@bam.tech/react-native-image-resizer@^3.0.4": 1346 - version "3.0.4" 1347 - resolved "https://registry.yarnpkg.com/@bam.tech/react-native-image-resizer/-/react-native-image-resizer-3.0.4.tgz#3e127818e88df89e5c51a07e2556bf6ef872df26" 1348 - integrity sha512-p2Ecs469bntk4Ke4CEYyEoVBKBT+8JyaXXPz4Fm55s9G+jEg99p1V9MHkza2k7OAq1iUF8oAtZ/wZ9zKn6b43Q== 1301 + version "3.0.5" 1302 + resolved "https://registry.yarnpkg.com/@bam.tech/react-native-image-resizer/-/react-native-image-resizer-3.0.5.tgz#6661ba020de156268f73bdc92fbb93ef86f88a13" 1303 + integrity sha512-u5QGUQGGVZiVCJ786k9/kd7pPRZ6eYfJCYO18myVCH8FbVI7J8b5GT2Svjj2x808DlWeqfaZOOzxPqo27XYvrQ== 1349 1304 1350 1305 "@bcoe/v8-coverage@^0.2.3": 1351 1306 version "0.2.3" ··· 1459 1414 integrity sha512-c8J4roPBILnelAsdLr4XOAR/GsTm0GJi4XpcfvoWk3U6KiTCqiFYc63KhRMQQX35jYMp4Ao8Ij9+IZRgMfJp1g== 1460 1415 1461 1416 "@csstools/selector-specificity@^2.0.0", "@csstools/selector-specificity@^2.0.2": 1462 - version "2.0.2" 1463 - resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz#1bfafe4b7ed0f3e4105837e056e0a89b108ebe36" 1464 - integrity sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg== 1417 + version "2.1.1" 1418 + resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-2.1.1.tgz#c9c61d9fe5ca5ac664e1153bb0aa0eba1c6d6308" 1419 + integrity sha512-jwx+WCqszn53YHOfvFMJJRd/B2GqkCBt+1MJSG6o5/s8+ytHMvDZXsJgUEWLk12UnLd7HYKac4BYU5i/Ron1Cw== 1465 1420 1466 1421 "@discoveryjs/json-ext@^0.5.0": 1467 1422 version "0.5.7" ··· 1490 1445 minimatch "^3.1.2" 1491 1446 strip-json-comments "^3.1.1" 1492 1447 1493 - "@fortawesome/fontawesome-common-types@6.2.1": 1494 - version "6.2.1" 1495 - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.2.1.tgz#411e02a820744d3f7e0d8d9df9d82b471beaa073" 1496 - integrity sha512-Sz07mnQrTekFWLz5BMjOzHl/+NooTdW8F8kDQxjWwbpOJcnoSg4vUDng8d/WR1wOxM0O+CY9Zw0nR054riNYtQ== 1448 + "@fortawesome/fontawesome-common-types@6.3.0": 1449 + version "6.3.0" 1450 + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.3.0.tgz#51f734e64511dbc3674cd347044d02f4dd26e86b" 1451 + integrity sha512-4BC1NMoacEBzSXRwKjZ/X/gmnbp/HU5Qqat7E8xqorUtBFZS+bwfGH5/wqOC2K6GV0rgEobp3OjGRMa5fK9pFg== 1497 1452 1498 1453 "@fortawesome/fontawesome-svg-core@^6.1.1": 1499 - version "6.2.1" 1500 - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.2.1.tgz#e87e905e444b5e7b715af09b64d27b53d4c8f9d9" 1501 - integrity sha512-HELwwbCz6C1XEcjzyT1Jugmz2NNklMrSPjZOWMlc+ZsHIVk+XOvOXLGGQtFBwSyqfJDNgRq4xBCwWOaZ/d9DEA== 1454 + version "6.3.0" 1455 + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.3.0.tgz#b6a17d48d231ac1fad93e43fca7271676bf316cf" 1456 + integrity sha512-uz9YifyKlixV6AcKlOX8WNdtF7l6nakGyLYxYaCa823bEBqyj/U2ssqtctO38itNEwXb8/lMzjdoJ+aaJuOdrw== 1502 1457 dependencies: 1503 - "@fortawesome/fontawesome-common-types" "6.2.1" 1458 + "@fortawesome/fontawesome-common-types" "6.3.0" 1504 1459 1505 1460 "@fortawesome/free-regular-svg-icons@^6.1.1": 1506 - version "6.2.1" 1507 - resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.2.1.tgz#650e56d937755a8341f2eef258ecb6f95458820f" 1508 - integrity sha512-wiqcNDNom75x+pe88FclpKz7aOSqS2lOivZeicMV5KRwOAeypxEYWAK/0v+7r+LrEY30+qzh8r2XDaEHvoLsMA== 1461 + version "6.3.0" 1462 + resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.3.0.tgz#286f87f777e6c96af59151e86647c81083029ee2" 1463 + integrity sha512-cZnwiVHZ51SVzWHOaNCIA+u9wevZjCuAGSvSYpNlm6A4H4Vhwh8481Bf/5rwheIC3fFKlgXxLKaw8Xeroz8Ntg== 1509 1464 dependencies: 1510 - "@fortawesome/fontawesome-common-types" "6.2.1" 1465 + "@fortawesome/fontawesome-common-types" "6.3.0" 1511 1466 1512 1467 "@fortawesome/free-solid-svg-icons@^6.1.1": 1513 - version "6.2.1" 1514 - resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.2.1.tgz#2290ea5adcf1537cbd0c43de6feb38af02141d27" 1515 - integrity sha512-oKuqrP5jbfEPJWTij4sM+/RvgX+RMFwx3QZCZcK9PrBDgxC35zuc7AOFsyMjMd/PIFPeB2JxyqDr5zs/DZFPPw== 1468 + version "6.3.0" 1469 + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.3.0.tgz#d3bd33ae18bb15fdfc3ca136e2fea05f32768a65" 1470 + integrity sha512-x5tMwzF2lTH8pyv8yeZRodItP2IVlzzmBuD1M7BjawWgg9XAvktqJJ91Qjgoaf8qJpHQ8FEU9VxRfOkLhh86QA== 1516 1471 dependencies: 1517 - "@fortawesome/fontawesome-common-types" "6.2.1" 1472 + "@fortawesome/fontawesome-common-types" "6.3.0" 1518 1473 1519 1474 "@fortawesome/react-native-fontawesome@^0.3.0": 1520 1475 version "0.3.0" ··· 1632 1587 jest-util "^28.1.3" 1633 1588 slash "^3.0.0" 1634 1589 1635 - "@jest/console@^29.3.1": 1636 - version "29.3.1" 1637 - resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.3.1.tgz#3e3f876e4e47616ea3b1464b9fbda981872e9583" 1638 - integrity sha512-IRE6GD47KwcqA09RIWrabKdHPiKDGgtAL31xDxbi/RjQMsr+lY+ppxmHwY0dUEV3qvvxZzoe5Hl0RXZJOjQNUg== 1590 + "@jest/console@^29.4.3": 1591 + version "29.4.3" 1592 + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.4.3.tgz#1f25a99f7f860e4c46423b5b1038262466fadde1" 1593 + integrity sha512-W/o/34+wQuXlgqlPYTansOSiBnuxrTv61dEVkA6HNmpcgHLUjfaUbdqt6oVvOzaawwo9IdW9QOtMgQ1ScSZC4A== 1639 1594 dependencies: 1640 - "@jest/types" "^29.3.1" 1595 + "@jest/types" "^29.4.3" 1641 1596 "@types/node" "*" 1642 1597 chalk "^4.0.0" 1643 - jest-message-util "^29.3.1" 1644 - jest-util "^29.3.1" 1598 + jest-message-util "^29.4.3" 1599 + jest-util "^29.4.3" 1645 1600 slash "^3.0.0" 1646 1601 1647 1602 "@jest/core@^27.5.1": ··· 1678 1633 slash "^3.0.0" 1679 1634 strip-ansi "^6.0.0" 1680 1635 1681 - "@jest/core@^29.3.1": 1682 - version "29.3.1" 1683 - resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.3.1.tgz#bff00f413ff0128f4debec1099ba7dcd649774a1" 1684 - integrity sha512-0ohVjjRex985w5MmO5L3u5GR1O30DexhBSpuwx2P+9ftyqHdJXnk7IUWiP80oHMvt7ubHCJHxV0a0vlKVuZirw== 1636 + "@jest/core@^29.4.3": 1637 + version "29.4.3" 1638 + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.4.3.tgz#829dd65bffdb490de5b0f69e97de8e3b5eadd94b" 1639 + integrity sha512-56QvBq60fS4SPZCuM7T+7scNrkGIe7Mr6PVIXUpu48ouvRaWOFqRPV91eifvFM0ay2HmfswXiGf97NGUN5KofQ== 1685 1640 dependencies: 1686 - "@jest/console" "^29.3.1" 1687 - "@jest/reporters" "^29.3.1" 1688 - "@jest/test-result" "^29.3.1" 1689 - "@jest/transform" "^29.3.1" 1690 - "@jest/types" "^29.3.1" 1641 + "@jest/console" "^29.4.3" 1642 + "@jest/reporters" "^29.4.3" 1643 + "@jest/test-result" "^29.4.3" 1644 + "@jest/transform" "^29.4.3" 1645 + "@jest/types" "^29.4.3" 1691 1646 "@types/node" "*" 1692 1647 ansi-escapes "^4.2.1" 1693 1648 chalk "^4.0.0" 1694 1649 ci-info "^3.2.0" 1695 1650 exit "^0.1.2" 1696 1651 graceful-fs "^4.2.9" 1697 - jest-changed-files "^29.2.0" 1698 - jest-config "^29.3.1" 1699 - jest-haste-map "^29.3.1" 1700 - jest-message-util "^29.3.1" 1701 - jest-regex-util "^29.2.0" 1702 - jest-resolve "^29.3.1" 1703 - jest-resolve-dependencies "^29.3.1" 1704 - jest-runner "^29.3.1" 1705 - jest-runtime "^29.3.1" 1706 - jest-snapshot "^29.3.1" 1707 - jest-util "^29.3.1" 1708 - jest-validate "^29.3.1" 1709 - jest-watcher "^29.3.1" 1652 + jest-changed-files "^29.4.3" 1653 + jest-config "^29.4.3" 1654 + jest-haste-map "^29.4.3" 1655 + jest-message-util "^29.4.3" 1656 + jest-regex-util "^29.4.3" 1657 + jest-resolve "^29.4.3" 1658 + jest-resolve-dependencies "^29.4.3" 1659 + jest-runner "^29.4.3" 1660 + jest-runtime "^29.4.3" 1661 + jest-snapshot "^29.4.3" 1662 + jest-util "^29.4.3" 1663 + jest-validate "^29.4.3" 1664 + jest-watcher "^29.4.3" 1710 1665 micromatch "^4.0.4" 1711 - pretty-format "^29.3.1" 1666 + pretty-format "^29.4.3" 1712 1667 slash "^3.0.0" 1713 1668 strip-ansi "^6.0.0" 1714 1669 1715 1670 "@jest/create-cache-key-function@^29.2.1": 1716 - version "29.3.1" 1717 - resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-29.3.1.tgz#3a0970ea595ab3d9507244edbcef14d6b016cdc9" 1718 - integrity sha512-4i+E+E40gK13K78ffD/8cy4lSSqeWwyXeTZoq16tndiCP12hC8uQsPJdIu5C6Kf22fD8UbBk71so7s/6VwpUOQ== 1671 + version "29.4.3" 1672 + resolved "https://registry.yarnpkg.com/@jest/create-cache-key-function/-/create-cache-key-function-29.4.3.tgz#ea37769f69523019d81ee089a25a62550f209eb7" 1673 + integrity sha512-AJVFQTTy6jnZAQiAZrdOaTAPzJUrvAE/4IMe+Foav6WPhypFszqg7a4lOTyuzYQEEiT5RSrGYg9IY+/ivxiyXw== 1719 1674 dependencies: 1720 - "@jest/types" "^29.3.1" 1675 + "@jest/types" "^29.4.3" 1721 1676 1722 1677 "@jest/environment@^27.5.1": 1723 1678 version "27.5.1" ··· 1729 1684 "@types/node" "*" 1730 1685 jest-mock "^27.5.1" 1731 1686 1732 - "@jest/environment@^29.3.1": 1733 - version "29.3.1" 1734 - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.3.1.tgz#eb039f726d5fcd14698acd072ac6576d41cfcaa6" 1735 - integrity sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag== 1687 + "@jest/environment@^29.4.3": 1688 + version "29.4.3" 1689 + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.4.3.tgz#9fe2f3169c3b33815dc4bd3960a064a83eba6548" 1690 + integrity sha512-dq5S6408IxIa+lr54zeqce+QgI+CJT4nmmA+1yzFgtcsGK8c/EyiUb9XQOgz3BMKrRDfKseeOaxj2eO8LlD3lA== 1736 1691 dependencies: 1737 - "@jest/fake-timers" "^29.3.1" 1738 - "@jest/types" "^29.3.1" 1692 + "@jest/fake-timers" "^29.4.3" 1693 + "@jest/types" "^29.4.3" 1739 1694 "@types/node" "*" 1740 - jest-mock "^29.3.1" 1695 + jest-mock "^29.4.3" 1741 1696 1742 - "@jest/expect-utils@^29.3.1": 1743 - version "29.3.1" 1744 - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.3.1.tgz#531f737039e9b9e27c42449798acb5bba01935b6" 1745 - integrity sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g== 1697 + "@jest/expect-utils@^29.4.3": 1698 + version "29.4.3" 1699 + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.4.3.tgz#95ce4df62952f071bcd618225ac7c47eaa81431e" 1700 + integrity sha512-/6JWbkxHOP8EoS8jeeTd9dTfc9Uawi+43oLKHfp6zzux3U2hqOOVnV3ai4RpDYHOccL6g+5nrxpoc8DmJxtXVQ== 1746 1701 dependencies: 1747 - jest-get-type "^29.2.0" 1702 + jest-get-type "^29.4.3" 1748 1703 1749 - "@jest/expect@^29.3.1": 1750 - version "29.3.1" 1751 - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.3.1.tgz#456385b62894349c1d196f2d183e3716d4c6a6cd" 1752 - integrity sha512-QivM7GlSHSsIAWzgfyP8dgeExPRZ9BIe2LsdPyEhCGkZkoyA+kGsoIzbKAfZCvvRzfZioKwPtCZIt5SaoxYCvg== 1704 + "@jest/expect@^29.4.3": 1705 + version "29.4.3" 1706 + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.4.3.tgz#d31a28492e45a6bcd0f204a81f783fe717045c6e" 1707 + integrity sha512-iktRU/YsxEtumI9zsPctYUk7ptpC+AVLLk1Ax3AsA4g1C+8OOnKDkIQBDHtD5hA/+VtgMd5AWI5gNlcAlt2vxQ== 1753 1708 dependencies: 1754 - expect "^29.3.1" 1755 - jest-snapshot "^29.3.1" 1709 + expect "^29.4.3" 1710 + jest-snapshot "^29.4.3" 1756 1711 1757 1712 "@jest/fake-timers@^27.5.1": 1758 1713 version "27.5.1" ··· 1766 1721 jest-mock "^27.5.1" 1767 1722 jest-util "^27.5.1" 1768 1723 1769 - "@jest/fake-timers@^29.3.1": 1770 - version "29.3.1" 1771 - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.3.1.tgz#b140625095b60a44de820876d4c14da1aa963f67" 1772 - integrity sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A== 1724 + "@jest/fake-timers@^29.4.3": 1725 + version "29.4.3" 1726 + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.4.3.tgz#31e982638c60fa657d310d4b9d24e023064027b0" 1727 + integrity sha512-4Hote2MGcCTWSD2gwl0dwbCpBRHhE6olYEuTj8FMowdg3oQWNKr2YuxenPQYZ7+PfqPY1k98wKDU4Z+Hvd4Tiw== 1773 1728 dependencies: 1774 - "@jest/types" "^29.3.1" 1775 - "@sinonjs/fake-timers" "^9.1.2" 1729 + "@jest/types" "^29.4.3" 1730 + "@sinonjs/fake-timers" "^10.0.2" 1776 1731 "@types/node" "*" 1777 - jest-message-util "^29.3.1" 1778 - jest-mock "^29.3.1" 1779 - jest-util "^29.3.1" 1732 + jest-message-util "^29.4.3" 1733 + jest-mock "^29.4.3" 1734 + jest-util "^29.4.3" 1780 1735 1781 1736 "@jest/globals@^27.5.1": 1782 1737 version "27.5.1" ··· 1787 1742 "@jest/types" "^27.5.1" 1788 1743 expect "^27.5.1" 1789 1744 1790 - "@jest/globals@^29.3.1": 1791 - version "29.3.1" 1792 - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.3.1.tgz#92be078228e82d629df40c3656d45328f134a0c6" 1793 - integrity sha512-cTicd134vOcwO59OPaB6AmdHQMCtWOe+/DitpTZVxWgMJ+YvXL1HNAmPyiGbSHmF/mXVBkvlm8YYtQhyHPnV6Q== 1745 + "@jest/globals@^29.4.3": 1746 + version "29.4.3" 1747 + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.4.3.tgz#63a2c4200d11bc6d46f12bbe25b07f771fce9279" 1748 + integrity sha512-8BQ/5EzfOLG7AaMcDh7yFCbfRLtsc+09E1RQmRBI4D6QQk4m6NSK/MXo+3bJrBN0yU8A2/VIcqhvsOLFmziioA== 1794 1749 dependencies: 1795 - "@jest/environment" "^29.3.1" 1796 - "@jest/expect" "^29.3.1" 1797 - "@jest/types" "^29.3.1" 1798 - jest-mock "^29.3.1" 1750 + "@jest/environment" "^29.4.3" 1751 + "@jest/expect" "^29.4.3" 1752 + "@jest/types" "^29.4.3" 1753 + jest-mock "^29.4.3" 1799 1754 1800 1755 "@jest/reporters@^27.5.1": 1801 1756 version "27.5.1" ··· 1828 1783 terminal-link "^2.0.0" 1829 1784 v8-to-istanbul "^8.1.0" 1830 1785 1831 - "@jest/reporters@^29.3.1": 1832 - version "29.3.1" 1833 - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.3.1.tgz#9a6d78c109608e677c25ddb34f907b90e07b4310" 1834 - integrity sha512-GhBu3YFuDrcAYW/UESz1JphEAbvUjaY2vShRZRoRY1mxpCMB3yGSJ4j9n0GxVlEOdCf7qjvUfBCrTUUqhVfbRA== 1786 + "@jest/reporters@^29.4.3": 1787 + version "29.4.3" 1788 + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.4.3.tgz#0a68a0c0f20554760cc2e5443177a0018969e353" 1789 + integrity sha512-sr2I7BmOjJhyqj9ANC6CTLsL4emMoka7HkQpcoMRlhCbQJjz2zsRzw0BDPiPyEFDXAbxKgGFYuQZiSJ1Y6YoTg== 1835 1790 dependencies: 1836 1791 "@bcoe/v8-coverage" "^0.2.3" 1837 - "@jest/console" "^29.3.1" 1838 - "@jest/test-result" "^29.3.1" 1839 - "@jest/transform" "^29.3.1" 1840 - "@jest/types" "^29.3.1" 1792 + "@jest/console" "^29.4.3" 1793 + "@jest/test-result" "^29.4.3" 1794 + "@jest/transform" "^29.4.3" 1795 + "@jest/types" "^29.4.3" 1841 1796 "@jridgewell/trace-mapping" "^0.3.15" 1842 1797 "@types/node" "*" 1843 1798 chalk "^4.0.0" ··· 1850 1805 istanbul-lib-report "^3.0.0" 1851 1806 istanbul-lib-source-maps "^4.0.0" 1852 1807 istanbul-reports "^3.1.3" 1853 - jest-message-util "^29.3.1" 1854 - jest-util "^29.3.1" 1855 - jest-worker "^29.3.1" 1808 + jest-message-util "^29.4.3" 1809 + jest-util "^29.4.3" 1810 + jest-worker "^29.4.3" 1856 1811 slash "^3.0.0" 1857 1812 string-length "^4.0.1" 1858 1813 strip-ansi "^6.0.0" ··· 1865 1820 dependencies: 1866 1821 "@sinclair/typebox" "^0.24.1" 1867 1822 1868 - "@jest/schemas@^29.0.0": 1869 - version "29.0.0" 1870 - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.0.0.tgz#5f47f5994dd4ef067fb7b4188ceac45f77fe952a" 1871 - integrity sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA== 1823 + "@jest/schemas@^29.4.3": 1824 + version "29.4.3" 1825 + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.3.tgz#39cf1b8469afc40b6f5a2baaa146e332c4151788" 1826 + integrity sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg== 1872 1827 dependencies: 1873 - "@sinclair/typebox" "^0.24.1" 1828 + "@sinclair/typebox" "^0.25.16" 1874 1829 1875 1830 "@jest/source-map@^27.5.1": 1876 1831 version "27.5.1" ··· 1881 1836 graceful-fs "^4.2.9" 1882 1837 source-map "^0.6.0" 1883 1838 1884 - "@jest/source-map@^29.2.0": 1885 - version "29.2.0" 1886 - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.2.0.tgz#ab3420c46d42508dcc3dc1c6deee0b613c235744" 1887 - integrity sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ== 1839 + "@jest/source-map@^29.4.3": 1840 + version "29.4.3" 1841 + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.4.3.tgz#ff8d05cbfff875d4a791ab679b4333df47951d20" 1842 + integrity sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w== 1888 1843 dependencies: 1889 1844 "@jridgewell/trace-mapping" "^0.3.15" 1890 1845 callsites "^3.0.0" ··· 1910 1865 "@types/istanbul-lib-coverage" "^2.0.0" 1911 1866 collect-v8-coverage "^1.0.0" 1912 1867 1913 - "@jest/test-result@^29.3.1": 1914 - version "29.3.1" 1915 - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.3.1.tgz#92cd5099aa94be947560a24610aa76606de78f50" 1916 - integrity sha512-qeLa6qc0ddB0kuOZyZIhfN5q0e2htngokyTWsGriedsDhItisW7SDYZ7ceOe57Ii03sL988/03wAcBh3TChMGw== 1868 + "@jest/test-result@^29.4.3": 1869 + version "29.4.3" 1870 + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.4.3.tgz#e13d973d16c8c7cc0c597082d5f3b9e7f796ccb8" 1871 + integrity sha512-Oi4u9NfBolMq9MASPwuWTlC5WvmNRwI4S8YrQg5R5Gi47DYlBe3sh7ILTqi/LGrK1XUE4XY9KZcQJTH1WJCLLA== 1917 1872 dependencies: 1918 - "@jest/console" "^29.3.1" 1919 - "@jest/types" "^29.3.1" 1873 + "@jest/console" "^29.4.3" 1874 + "@jest/types" "^29.4.3" 1920 1875 "@types/istanbul-lib-coverage" "^2.0.0" 1921 1876 collect-v8-coverage "^1.0.0" 1922 1877 ··· 1930 1885 jest-haste-map "^27.5.1" 1931 1886 jest-runtime "^27.5.1" 1932 1887 1933 - "@jest/test-sequencer@^29.3.1": 1934 - version "29.3.1" 1935 - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.3.1.tgz#fa24b3b050f7a59d48f7ef9e0b782ab65123090d" 1936 - integrity sha512-IqYvLbieTv20ArgKoAMyhLHNrVHJfzO6ARZAbQRlY4UGWfdDnLlZEF0BvKOMd77uIiIjSZRwq3Jb3Fa3I8+2UA== 1888 + "@jest/test-sequencer@^29.4.3": 1889 + version "29.4.3" 1890 + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.4.3.tgz#0862e876a22993385a0f3e7ea1cc126f208a2898" 1891 + integrity sha512-yi/t2nES4GB4G0mjLc0RInCq/cNr9dNwJxcGg8sslajua5Kb4kmozAc+qPLzplhBgfw1vLItbjyHzUN92UXicw== 1937 1892 dependencies: 1938 - "@jest/test-result" "^29.3.1" 1893 + "@jest/test-result" "^29.4.3" 1939 1894 graceful-fs "^4.2.9" 1940 - jest-haste-map "^29.3.1" 1895 + jest-haste-map "^29.4.3" 1941 1896 slash "^3.0.0" 1942 1897 1943 1898 "@jest/transform@^27.5.1": ··· 1961 1916 source-map "^0.6.1" 1962 1917 write-file-atomic "^3.0.0" 1963 1918 1964 - "@jest/transform@^29.3.1": 1965 - version "29.3.1" 1966 - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.3.1.tgz#1e6bd3da4af50b5c82a539b7b1f3770568d6e36d" 1967 - integrity sha512-8wmCFBTVGYqFNLWfcOWoVuMuKYPUBTnTMDkdvFtAYELwDOl9RGwOsvQWGPFxDJ8AWY9xM/8xCXdqmPK3+Q5Lug== 1919 + "@jest/transform@^29.4.3": 1920 + version "29.4.3" 1921 + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.4.3.tgz#f7d17eac9cb5bb2e1222ea199c7c7e0835e0c037" 1922 + integrity sha512-8u0+fBGWolDshsFgPQJESkDa72da/EVwvL+II0trN2DR66wMwiQ9/CihaGfHdlLGFzbBZwMykFtxuwFdZqlKwg== 1968 1923 dependencies: 1969 1924 "@babel/core" "^7.11.6" 1970 - "@jest/types" "^29.3.1" 1925 + "@jest/types" "^29.4.3" 1971 1926 "@jridgewell/trace-mapping" "^0.3.15" 1972 1927 babel-plugin-istanbul "^6.1.1" 1973 1928 chalk "^4.0.0" 1974 1929 convert-source-map "^2.0.0" 1975 1930 fast-json-stable-stringify "^2.1.0" 1976 1931 graceful-fs "^4.2.9" 1977 - jest-haste-map "^29.3.1" 1978 - jest-regex-util "^29.2.0" 1979 - jest-util "^29.3.1" 1932 + jest-haste-map "^29.4.3" 1933 + jest-regex-util "^29.4.3" 1934 + jest-util "^29.4.3" 1980 1935 micromatch "^4.0.4" 1981 1936 pirates "^4.0.4" 1982 1937 slash "^3.0.0" 1983 - write-file-atomic "^4.0.1" 1938 + write-file-atomic "^4.0.2" 1984 1939 1985 1940 "@jest/types@^26.6.2": 1986 1941 version "26.6.2" ··· 2016 1971 "@types/yargs" "^17.0.8" 2017 1972 chalk "^4.0.0" 2018 1973 2019 - "@jest/types@^29.3.1": 2020 - version "29.3.1" 2021 - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.3.1.tgz#7c5a80777cb13e703aeec6788d044150341147e3" 2022 - integrity sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA== 1974 + "@jest/types@^29.4.3": 1975 + version "29.4.3" 1976 + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.4.3.tgz#9069145f4ef09adf10cec1b2901b2d390031431f" 1977 + integrity sha512-bPYfw8V65v17m2Od1cv44FH+SiKW7w2Xu7trhcdTLUmSv85rfKsP+qXSjO4KGJr4dtPSzl/gvslZBXctf1qGEA== 2023 1978 dependencies: 2024 - "@jest/schemas" "^29.0.0" 1979 + "@jest/schemas" "^29.4.3" 2025 1980 "@types/istanbul-lib-coverage" "^2.0.0" 2026 1981 "@types/istanbul-reports" "^3.0.0" 2027 1982 "@types/node" "*" ··· 2068 2023 resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" 2069 2024 integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== 2070 2025 2071 - "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.9": 2026 + "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.14", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": 2072 2027 version "0.3.17" 2073 2028 resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" 2074 2029 integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== ··· 2082 2037 integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== 2083 2038 2084 2039 "@mattermost/react-native-paste-input@^0.6.0": 2085 - version "0.6.0" 2086 - resolved "https://registry.yarnpkg.com/@mattermost/react-native-paste-input/-/react-native-paste-input-0.6.0.tgz#bc920c8f1b442266a6bc58f9122df137b73bc9fa" 2087 - integrity sha512-Hy4w8RaiiXl2AKcLXT0FjJJsh4FXtLiWCxfh6zaBtCkx7jsr4d9xwJ/zqrnjv0jkG7XbRUCp40dgNBpWYZ1pyQ== 2040 + version "0.6.2" 2041 + resolved "https://registry.yarnpkg.com/@mattermost/react-native-paste-input/-/react-native-paste-input-0.6.2.tgz#783779bc60758927781270293f35d6b4f937cd07" 2042 + integrity sha512-+92KQfHytTdVzKzydkJQetyLy8H91uwCoDxKswJ4+fK4f4zNJpF/10LrHL+/aijcy0vJG+6gUC8zXvyLzv6wCw== 2088 2043 dependencies: 2089 2044 semver "7.3.8" 2090 2045 ··· 2127 2082 fastq "^1.6.0" 2128 2083 2129 2084 "@notifee/react-native@^7.4.0": 2130 - version "7.4.0" 2131 - resolved "https://registry.yarnpkg.com/@notifee/react-native/-/react-native-7.4.0.tgz#0f20744307bf3b800f7b56eb2d0bbdd474748d09" 2132 - integrity sha512-c8pkxDQFRbw0JlUmTb07OTG/4LQHRj8MBodMLwEcO+SvqIxK8ya8zSUEzfdcdWsSVqdoym0v3zpSNroR3Quj/w== 2085 + version "7.5.0" 2086 + resolved "https://registry.yarnpkg.com/@notifee/react-native/-/react-native-7.5.0.tgz#3d846b6a607a6352e798a3440cd3880c005a7d56" 2087 + integrity sha512-FR1xzQI2KpMyLuM7YZyHHjCcOXbjAcBWMeRlarro8peujr6gJZSg4j2Aw4o8O4ifMHDopFrovwyK1uYBaB9MUg== 2133 2088 2134 2089 "@pmmmwh/react-refresh-webpack-plugin@^0.5.3": 2135 2090 version "0.5.10" ··· 2154 2109 merge-options "^3.0.4" 2155 2110 2156 2111 "@react-native-camera-roll/camera-roll@^5.2.2": 2157 - version "5.2.2" 2158 - resolved "https://registry.yarnpkg.com/@react-native-camera-roll/camera-roll/-/camera-roll-5.2.2.tgz#dbdfa4ffb126b4d7efa01f3c5fc030ce3bfcdf2d" 2159 - integrity sha512-LVzUX1KdKvOXJGiV/9tlkDyDSOEjvAzuiV8OkSUD13TXN/Tk5u2KVHTYRYJz5pmXanLN2dmEamctJcqKCeXYxg== 2112 + version "5.2.4" 2113 + resolved "https://registry.yarnpkg.com/@react-native-camera-roll/camera-roll/-/camera-roll-5.2.4.tgz#216d0ea4656b6538c10b60f057118c6f5e704c0d" 2114 + integrity sha512-pEQDartgO8Nqy6QDm1efvIPpv4q5W+AtTgS05JGK/9x8VzSj8fJ/cvHmMZBlm/4sFpJyvJZ+1KYxKsvFJLbGuQ== 2160 2115 2161 2116 "@react-native-clipboard/clipboard@^1.10.0": 2162 2117 version "1.11.1" ··· 2168 2123 resolved "https://registry.yarnpkg.com/@react-native-community/blur/-/blur-4.3.0.tgz#e5018b3b0bd6de9632ac6cf34e9f8e0f1a9a28ec" 2169 2124 integrity sha512-d6phh39kKcbZ4IluDftiVWqfeFOgjl1AbQWzN47x+hLKQ5GvQJ6QhRvgAuDZ+xbJksrbXgNpMjVYkjsbcVehxg== 2170 2125 2171 - "@react-native-community/cli-clean@^10.0.0": 2172 - version "10.0.0" 2173 - resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-10.0.0.tgz#09cc4c63116e81d3765ffedecc38387bcc7b4483" 2174 - integrity sha512-9uHRicQXycqu55rSplQh2/o/nDdA5qDXiU09/s7/fJbUlCNUySy5rXw5FtbQv+Bj+bD9tXFoDRKN1ZnNHtT4QQ== 2126 + "@react-native-community/cli-clean@^10.1.1": 2127 + version "10.1.1" 2128 + resolved "https://registry.yarnpkg.com/@react-native-community/cli-clean/-/cli-clean-10.1.1.tgz#4c73ce93a63a24d70c0089d4025daac8184ff504" 2129 + integrity sha512-iNsrjzjIRv9yb5y309SWJ8NDHdwYtnCpmxZouQDyOljUdC9MwdZ4ChbtA4rwQyAwgOVfS9F/j56ML3Cslmvrxg== 2175 2130 dependencies: 2176 - "@react-native-community/cli-tools" "^10.0.0" 2131 + "@react-native-community/cli-tools" "^10.1.1" 2177 2132 chalk "^4.1.2" 2178 2133 execa "^1.0.0" 2179 2134 prompts "^2.4.0" 2180 2135 2181 - "@react-native-community/cli-config@^10.0.0": 2182 - version "10.0.0" 2183 - resolved "https://registry.yarnpkg.com/@react-native-community/cli-config/-/cli-config-10.0.0.tgz#25b87760153ffc3b5bad3018c485f17ce982fc74" 2184 - integrity sha512-cbJfncqFtONfPPFnfL4bgdYYZU+Muo6jQMgTnR+rbp6gNxTPUYioctHgXcvyJAubl886mr3lirfU31V+a96AqA== 2136 + "@react-native-community/cli-config@^10.1.1": 2137 + version "10.1.1" 2138 + resolved "https://registry.yarnpkg.com/@react-native-community/cli-config/-/cli-config-10.1.1.tgz#08dcc5d7ca1915647dc06507ed853fe0c1488395" 2139 + integrity sha512-p4mHrjC+s/ayiNVG6T35GdEGdP6TuyBUg5plVGRJfTl8WT6LBfLYLk+fz/iETrEZ/YkhQIsQcEUQC47MqLNHog== 2185 2140 dependencies: 2186 - "@react-native-community/cli-tools" "^10.0.0" 2141 + "@react-native-community/cli-tools" "^10.1.1" 2187 2142 chalk "^4.1.2" 2188 2143 cosmiconfig "^5.1.0" 2189 2144 deepmerge "^3.2.0" ··· 2197 2152 dependencies: 2198 2153 serve-static "^1.13.1" 2199 2154 2200 - "@react-native-community/cli-doctor@^10.0.0": 2201 - version "10.1.0" 2202 - resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-10.1.0.tgz#582f33fb149c515820605ee1cecf148b96d34080" 2203 - integrity sha512-3TMZX44QJ7njaimtmbHY2Q5Hb/R2YAYjx2ICi0TiHMLvofBlyXlxkJDs4nl7KDxLmZV9NpRw8fpkpCiHqimAhQ== 2155 + "@react-native-community/cli-doctor@^10.1.1": 2156 + version "10.2.0" 2157 + resolved "https://registry.yarnpkg.com/@react-native-community/cli-doctor/-/cli-doctor-10.2.0.tgz#6050030eea9200ce3c35de360cf8455e126b4d45" 2158 + integrity sha512-yLxJazUmNSPslHxeeev0gLvsK0nQan8BmGWbtqPz2WwbIbD89vbytC7G96OxiQXr46iWEWAwEJiTTdgA7jlA5Q== 2204 2159 dependencies: 2205 - "@react-native-community/cli-config" "^10.0.0" 2206 - "@react-native-community/cli-platform-ios" "^10.1.0" 2207 - "@react-native-community/cli-tools" "^10.0.0" 2160 + "@react-native-community/cli-config" "^10.1.1" 2161 + "@react-native-community/cli-platform-ios" "^10.2.0" 2162 + "@react-native-community/cli-tools" "^10.1.1" 2208 2163 chalk "^4.1.2" 2209 2164 command-exists "^1.2.8" 2210 2165 envinfo "^7.7.2" ··· 2219 2174 sudo-prompt "^9.0.0" 2220 2175 wcwidth "^1.0.1" 2221 2176 2222 - "@react-native-community/cli-hermes@^10.0.0": 2223 - version "10.1.0" 2224 - resolved "https://registry.yarnpkg.com/@react-native-community/cli-hermes/-/cli-hermes-10.1.0.tgz#c28ad9452657f8dea5ffc514bbbb019809e1e0fc" 2225 - integrity sha512-A79Z5lm44xRbF0JDyT4i1Cq06hXskl5l/iAWZFxCkpbgMqTyghTG1gFeoCZudIv7Ez+nwQbX5edcSerotbzcxg== 2177 + "@react-native-community/cli-hermes@^10.1.3": 2178 + version "10.2.0" 2179 + resolved "https://registry.yarnpkg.com/@react-native-community/cli-hermes/-/cli-hermes-10.2.0.tgz#cc252f435b149f74260bc918ce22fdf58033a87e" 2180 + integrity sha512-urfmvNeR8IiO/Sd92UU3xPO+/qI2lwCWQnxOkWaU/i2EITFekE47MD6MZrfVulRVYRi5cuaFqKZO/ccOdOB/vQ== 2226 2181 dependencies: 2227 - "@react-native-community/cli-platform-android" "^10.1.0" 2228 - "@react-native-community/cli-tools" "^10.0.0" 2182 + "@react-native-community/cli-platform-android" "^10.2.0" 2183 + "@react-native-community/cli-tools" "^10.1.1" 2229 2184 chalk "^4.1.2" 2230 2185 hermes-profile-transformer "^0.0.6" 2231 2186 ip "^1.1.5" 2232 2187 2233 - "@react-native-community/cli-platform-android@10.0.0": 2234 - version "10.0.0" 2235 - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-10.0.0.tgz#9894a0b54de94da4d01f3b9db4e6b51ba112fa72" 2236 - integrity sha512-wUXq+//PagXVjG6ZedO+zIbNPkCsAiP+uiE45llFTsCtI6vFBwa6oJFHH6fhfeib4mOd7DvIh2Kktrpgyb6nBg== 2188 + "@react-native-community/cli-platform-android@10.1.3": 2189 + version "10.1.3" 2190 + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-10.1.3.tgz#8380799cd4d3f9a0ca568b0f5b4ae9e462ce3669" 2191 + integrity sha512-8YZEpBL6yd9l4CIoFcLOgrV8x2GDujdqrdWrNsNERDAbsiFwqAQvfjyyb57GAZVuEPEJCoqUlGlMCwOh3XQb9A== 2237 2192 dependencies: 2238 - "@react-native-community/cli-tools" "^10.0.0" 2193 + "@react-native-community/cli-tools" "^10.1.1" 2239 2194 chalk "^4.1.2" 2240 2195 execa "^1.0.0" 2241 2196 glob "^7.1.3" 2242 2197 logkitty "^0.7.1" 2243 2198 2244 - "@react-native-community/cli-platform-android@^10.1.0": 2245 - version "10.1.0" 2246 - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-10.1.0.tgz#0c80b4ef4253990cc49e4cccf2344716f1316c16" 2247 - integrity sha512-Mr5eBuhHDdib1hUeh+s3N/eztPVtUOiuh/soZd8QT9fEufayqOnpm++gP8D993DaI0R3knzfAisz8jTMZSRMow== 2199 + "@react-native-community/cli-platform-android@^10.2.0": 2200 + version "10.2.0" 2201 + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-10.2.0.tgz#0bc689270a5f1d9aaf9e723181d43ca4dbfffdef" 2202 + integrity sha512-CBenYwGxwFdObZTn1lgxWtMGA5ms2G/ALQhkS+XTAD7KHDrCxFF9yT/fnAjFZKM6vX/1TqGI1RflruXih3kAhw== 2248 2203 dependencies: 2249 - "@react-native-community/cli-tools" "^10.0.0" 2204 + "@react-native-community/cli-tools" "^10.1.1" 2250 2205 chalk "^4.1.2" 2251 2206 execa "^1.0.0" 2252 2207 glob "^7.1.3" 2253 2208 logkitty "^0.7.1" 2254 2209 2255 - "@react-native-community/cli-platform-ios@10.0.0": 2256 - version "10.0.0" 2257 - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-10.0.0.tgz#91ee301620e509b44db5fd7c93eaf7ee992d097a" 2258 - integrity sha512-WLpXzZQ53zb1RhkpSDNHyBR3SIN3WObDRTEaR0TMXsXDeTj8/Eu2DPFpT+uEnD10ly/Y6/DqJsAt4Ku2X76klA== 2210 + "@react-native-community/cli-platform-ios@10.1.1": 2211 + version "10.1.1" 2212 + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-10.1.1.tgz#39ed6810117d8e7330d3aa4d85818fb6ae358785" 2213 + integrity sha512-EB9/L8j1LqrqyfJtLRixU+d8FIP6Pr83rEgUgXgya/u8wk3h/bvX70w+Ff2skwjdPLr5dLUQ/n5KFX4r3bsNmA== 2259 2214 dependencies: 2260 - "@react-native-community/cli-tools" "^10.0.0" 2215 + "@react-native-community/cli-tools" "^10.1.1" 2261 2216 chalk "^4.1.2" 2262 2217 execa "^1.0.0" 2263 2218 glob "^7.1.3" 2264 2219 ora "^5.4.1" 2265 2220 2266 - "@react-native-community/cli-platform-ios@^10.1.0": 2267 - version "10.1.0" 2268 - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-10.1.0.tgz#503932e0655b95973c393dedbda1190501564d95" 2269 - integrity sha512-w5bhqwxvW9RmZQfLWNr3eLB2cjV0mrwLfWVN2XUFAlXS5B8H0ee9sydkBSEApcKYaHjA3EUvq3sewM+/m7u6Hw== 2221 + "@react-native-community/cli-platform-ios@^10.2.0": 2222 + version "10.2.0" 2223 + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-10.2.0.tgz#be21c0e3bbf17358d540cc23e5556bf679f6322e" 2224 + integrity sha512-hIPK3iL/mL+0ChXmQ9uqqzNOKA48H+TAzg+hrxQLll/6dNMxDeK9/wZpktcsh8w+CyhqzKqVernGcQs7tPeKGw== 2270 2225 dependencies: 2271 - "@react-native-community/cli-tools" "^10.0.0" 2226 + "@react-native-community/cli-tools" "^10.1.1" 2272 2227 chalk "^4.1.2" 2273 2228 execa "^1.0.0" 2229 + fast-xml-parser "^4.0.12" 2274 2230 glob "^7.1.3" 2275 2231 ora "^5.4.1" 2276 2232 2277 - "@react-native-community/cli-plugin-metro@^10.0.0": 2278 - version "10.1.0" 2279 - resolved "https://registry.yarnpkg.com/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-10.1.0.tgz#11dff6a83fa0441a44eae0ce3ff6f57cc742960a" 2280 - integrity sha512-dRlUjD6F2EsR5lqfb3O9dMY26E/OLIXpastWJgdqLtoCYDlk38aGtiRM365CYFpO77vvn38OhE0TujygkeLpLg== 2233 + "@react-native-community/cli-plugin-metro@^10.1.1": 2234 + version "10.2.0" 2235 + resolved "https://registry.yarnpkg.com/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-10.2.0.tgz#83cabbc04c80f7e94f88ed998b72c7d572c6f094" 2236 + integrity sha512-9eiJrKYuauEDkQLCrjJUh7tS9T0oaMQqVUSSSuyDG6du7HQcfaR4mSf21wK75jvhKiwcQLpsFmMdctAb+0v+Cg== 2281 2237 dependencies: 2282 - "@react-native-community/cli-server-api" "^10.0.0" 2283 - "@react-native-community/cli-tools" "^10.0.0" 2238 + "@react-native-community/cli-server-api" "^10.1.1" 2239 + "@react-native-community/cli-tools" "^10.1.1" 2284 2240 chalk "^4.1.2" 2285 2241 execa "^1.0.0" 2286 - metro "0.73.7" 2287 - metro-config "0.73.7" 2288 - metro-core "0.73.7" 2289 - metro-react-native-babel-transformer "0.73.7" 2290 - metro-resolver "0.73.7" 2291 - metro-runtime "0.73.7" 2242 + metro "0.73.8" 2243 + metro-config "0.73.8" 2244 + metro-core "0.73.8" 2245 + metro-react-native-babel-transformer "0.73.8" 2246 + metro-resolver "0.73.8" 2247 + metro-runtime "0.73.8" 2292 2248 readline "^1.3.0" 2293 2249 2294 - "@react-native-community/cli-server-api@^10.0.0": 2295 - version "10.0.0" 2296 - resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-10.0.0.tgz#b3f69f30285bed2019d4ee22879abb6b5c85b609" 2297 - integrity sha512-UXOYno0NMisMm8F61q1bG/HzVWkgvJvfuL5C9W036vo83y6oQGjjZBpIRWi/QF94BULz0hrdiPXFNXworLmAcQ== 2250 + "@react-native-community/cli-server-api@^10.1.1": 2251 + version "10.1.1" 2252 + resolved "https://registry.yarnpkg.com/@react-native-community/cli-server-api/-/cli-server-api-10.1.1.tgz#e382269de281bb380c2e685431364fbbb8c1cb3a" 2253 + integrity sha512-NZDo/wh4zlm8as31UEBno2bui8+ufzsZV+KN7QjEJWEM0levzBtxaD+4je0OpfhRIIkhaRm2gl/vVf7OYAzg4g== 2298 2254 dependencies: 2299 2255 "@react-native-community/cli-debugger-ui" "^10.0.0" 2300 - "@react-native-community/cli-tools" "^10.0.0" 2256 + "@react-native-community/cli-tools" "^10.1.1" 2301 2257 compression "^1.7.1" 2302 2258 connect "^3.6.5" 2303 2259 errorhandler "^1.5.0" ··· 2306 2262 serve-static "^1.13.1" 2307 2263 ws "^7.5.1" 2308 2264 2309 - "@react-native-community/cli-tools@^10.0.0": 2310 - version "10.0.0" 2311 - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-10.0.0.tgz#51ec1775f699951837091cf84dc765e290377a53" 2312 - integrity sha512-cPUaOrahRcMJvJpBaoc/zpYPHoPqj91qV5KmvA9cJvKktY4rl/PFfUi1A0gTqqFhdH7qW1zkeyKo80lWq7NvxA== 2265 + "@react-native-community/cli-tools@^10.1.1": 2266 + version "10.1.1" 2267 + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-10.1.1.tgz#fa66e509c0d3faa31f7bb87ed7d42ad63f368ddd" 2268 + integrity sha512-+FlwOnZBV+ailEzXjcD8afY2ogFEBeHOw/8+XXzMgPaquU2Zly9B+8W089tnnohO3yfiQiZqkQlElP423MY74g== 2313 2269 dependencies: 2314 2270 appdirsjs "^1.2.4" 2315 2271 chalk "^4.1.2" ··· 2328 2284 dependencies: 2329 2285 joi "^17.2.1" 2330 2286 2331 - "@react-native-community/cli@10.0.0": 2332 - version "10.0.0" 2333 - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-10.0.0.tgz#46f68a1184014956dc237e12e6c2ca9b318a04db" 2334 - integrity sha512-KHV9/AbPeIK87jHP7iY07/HQG00J5AYF/dHz2rzqAZGB2WYFAbc5uoLRw90u/U2AcSeO7ep+4kawm+/B9LJreg== 2287 + "@react-native-community/cli@10.1.3": 2288 + version "10.1.3" 2289 + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-10.1.3.tgz#ad610c46da9fc7c717272024ec757dc646726506" 2290 + integrity sha512-kzh6bYLGN1q1q0IiczKSP1LTrovFeVzppYRTKohPI9VdyZwp7b5JOgaQMB/Ijtwm3MxBDrZgV9AveH/eUmUcKQ== 2335 2291 dependencies: 2336 - "@react-native-community/cli-clean" "^10.0.0" 2337 - "@react-native-community/cli-config" "^10.0.0" 2292 + "@react-native-community/cli-clean" "^10.1.1" 2293 + "@react-native-community/cli-config" "^10.1.1" 2338 2294 "@react-native-community/cli-debugger-ui" "^10.0.0" 2339 - "@react-native-community/cli-doctor" "^10.0.0" 2340 - "@react-native-community/cli-hermes" "^10.0.0" 2341 - "@react-native-community/cli-plugin-metro" "^10.0.0" 2342 - "@react-native-community/cli-server-api" "^10.0.0" 2343 - "@react-native-community/cli-tools" "^10.0.0" 2295 + "@react-native-community/cli-doctor" "^10.1.1" 2296 + "@react-native-community/cli-hermes" "^10.1.3" 2297 + "@react-native-community/cli-plugin-metro" "^10.1.1" 2298 + "@react-native-community/cli-server-api" "^10.1.1" 2299 + "@react-native-community/cli-tools" "^10.1.1" 2344 2300 "@react-native-community/cli-types" "^10.0.0" 2345 2301 chalk "^4.1.2" 2346 2302 commander "^9.4.1" ··· 2433 2389 integrity sha512-sXo/qW2/pAcmT43VoRKOJbDOfV3cYpq3szSVfIThQXNt+E4DfKj361vaAt3c88U5tPUxzEswam7GW48PJqtKAg== 2434 2390 2435 2391 "@segment/analytics-react-native@^2.10.1": 2436 - version "2.10.1" 2437 - resolved "https://registry.yarnpkg.com/@segment/analytics-react-native/-/analytics-react-native-2.10.1.tgz#cfc6c2186eaffc31a73b2ea1f229581dbad1f928" 2438 - integrity sha512-9CzqVijoQK86K/piItYfg88sFSHOg9G2RmZ0uKQyrplHo0Cm3ngzzyhf7Ry/A7XNT6ebIIgMrh8UGIRR7YwY3g== 2392 + version "2.13.0" 2393 + resolved "https://registry.yarnpkg.com/@segment/analytics-react-native/-/analytics-react-native-2.13.0.tgz#2a612253219cd91ea3716f46d4fa837231d968d8" 2394 + integrity sha512-Yt2/t7jNcEaMaYRgeT8KqMsemzjIBaxx5jk01+WI/TXPf0P1OBizMjoxYH3Bpv7CzyEVbVSFlUSrJmD5ll9xtQ== 2439 2395 dependencies: 2440 2396 "@react-native-async-storage/async-storage" "^1.15.17" 2441 2397 "@segment/sovran-react-native" "^0.4.5" 2442 2398 deepmerge "^4.2.2" 2443 2399 js-base64 "^3.7.2" 2444 - promise.allsettled "^1.0.5" 2445 2400 react-native-uuid "^2.0.1" 2446 2401 2447 2402 "@segment/sovran-react-native@^0.4.5": ··· 2468 2423 dependencies: 2469 2424 "@hapi/hoek" "^10.0.0" 2470 2425 2471 - "@sideway/formula@^3.0.0": 2426 + "@sideway/formula@^3.0.1": 2472 2427 version "3.0.1" 2473 2428 resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f" 2474 2429 integrity sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg== ··· 2483 2438 resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" 2484 2439 integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== 2485 2440 2441 + "@sinclair/typebox@^0.25.16": 2442 + version "0.25.23" 2443 + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.23.tgz#1c15b0d2b872d89cc0f47c7243eacb447df8b8bd" 2444 + integrity sha512-VEB8ygeP42CFLWyAJhN5OklpxUliqdNEUcXb4xZ/CINqtYGTjL5ukluKdKzQ0iWdUxyQ7B0539PAUhHKrCNWSQ== 2445 + 2486 2446 "@sinonjs/commons@^1.7.0": 2487 2447 version "1.8.6" 2488 2448 resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.6.tgz#80c516a4dc264c2a69115e7578d62581ff455ed9" ··· 2490 2450 dependencies: 2491 2451 type-detect "4.0.8" 2492 2452 2453 + "@sinonjs/commons@^2.0.0": 2454 + version "2.0.0" 2455 + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-2.0.0.tgz#fd4ca5b063554307e8327b4564bd56d3b73924a3" 2456 + integrity sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg== 2457 + dependencies: 2458 + type-detect "4.0.8" 2459 + 2460 + "@sinonjs/fake-timers@^10.0.2": 2461 + version "10.0.2" 2462 + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz#d10549ed1f423d80639c528b6c7f5a1017747d0c" 2463 + integrity sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw== 2464 + dependencies: 2465 + "@sinonjs/commons" "^2.0.0" 2466 + 2493 2467 "@sinonjs/fake-timers@^8.0.1": 2494 2468 version "8.1.0" 2495 2469 resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" 2496 2470 integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== 2497 - dependencies: 2498 - "@sinonjs/commons" "^1.7.0" 2499 - 2500 - "@sinonjs/fake-timers@^9.1.2": 2501 - version "9.1.2" 2502 - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz#4eaab737fab77332ab132d396a3c0d364bd0ea8c" 2503 - integrity sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw== 2504 2471 dependencies: 2505 2472 "@sinonjs/commons" "^1.7.0" 2506 2473 ··· 2618 2585 loader-utils "^2.0.0" 2619 2586 2620 2587 "@testing-library/jest-native@^5.3.3": 2621 - version "5.4.0" 2622 - resolved "https://registry.yarnpkg.com/@testing-library/jest-native/-/jest-native-5.4.0.tgz#d294d82f9780acb0be248a4cf261280997d6b213" 2623 - integrity sha512-6zoWxj1aDV/eRiGcrKX4bgxc7cIbK6iWyWWT6zzGCEacpcCfiIdhbQs+qbL+GzSmMufltzojCvka7X76JhooEg== 2588 + version "5.4.2" 2589 + resolved "https://registry.yarnpkg.com/@testing-library/jest-native/-/jest-native-5.4.2.tgz#6b0c987cc57f8d900763e763025d00d26ccbc85f" 2590 + integrity sha512-Vo/CE1uvCVH1H8YPoOEXLXVsm+BjzSQTq35+wkri1fr0O5D+A2WZ+m3ni5g6f1OCzNKNGIAHmisBEWkDs1P1mw== 2624 2591 dependencies: 2625 2592 chalk "^4.1.2" 2626 2593 jest-diff "^29.0.1" ··· 2629 2596 redent "^3.0.0" 2630 2597 2631 2598 "@testing-library/react-native@^11.5.0": 2632 - version "11.5.0" 2633 - resolved "https://registry.yarnpkg.com/@testing-library/react-native/-/react-native-11.5.0.tgz#b043c5db7b15eca42a65e95d3f3ae196fab9493b" 2634 - integrity sha512-seV+qebsbX4E5CWk/wizU1+2wVLsPyqEzG7sTgrhJ81cgAawg7ay06fIZR9IS75pDeWn2KZVd4mGk1pjJ3i3Zw== 2599 + version "11.5.2" 2600 + resolved "https://registry.yarnpkg.com/@testing-library/react-native/-/react-native-11.5.2.tgz#64238431de1ce4e128810bf8277a7cc118f1c812" 2601 + integrity sha512-haa/82Sy4ngAbXF6VTw5U306ZQHWfv7OKxALA4AkMKnX+6frhSd9aAe9rp50CyI2XJsNna0Rh6G+CSw+SPztYg== 2635 2602 dependencies: 2636 - pretty-format "^29.0.0" 2603 + pretty-format "^29.4.0" 2637 2604 2638 2605 "@tokenizer/token@^0.3.0": 2639 2606 version "0.3.0" ··· 2656 2623 integrity sha512-jE58snEKBd9DXfyR4+ssZmYJ/W2mOSnNrvljR0aLyQJL9JKX6vlWELHkRjb3HBbcM9Uy0hZGijXbqEAjOERW2A== 2657 2624 2658 2625 "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": 2659 - version "7.1.20" 2660 - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.20.tgz#e168cdd612c92a2d335029ed62ac94c95b362359" 2661 - integrity sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ== 2626 + version "7.20.0" 2627 + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.0.tgz#61bc5a4cae505ce98e1e36c5445e4bee060d8891" 2628 + integrity sha512-+n8dL/9GWblDO0iU6eZAwEIJVr5DWigtle+Q6HLOrh/pdbXOhOtqzq8VPPE2zvNJzSKY4vH/z3iT3tn0A3ypiQ== 2662 2629 dependencies: 2663 - "@babel/parser" "^7.1.0" 2664 - "@babel/types" "^7.0.0" 2630 + "@babel/parser" "^7.20.7" 2631 + "@babel/types" "^7.20.7" 2665 2632 "@types/babel__generator" "*" 2666 2633 "@types/babel__template" "*" 2667 2634 "@types/babel__traverse" "*" ··· 2727 2694 "@types/estree" "*" 2728 2695 2729 2696 "@types/eslint@*", "@types/eslint@^7.29.0 || ^8.4.1": 2730 - version "8.4.10" 2731 - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.4.10.tgz#19731b9685c19ed1552da7052b6f668ed7eb64bb" 2732 - integrity sha512-Sl/HOqN8NKPmhWo2VBEPm0nvHnu2LL3v9vKo8MEq0EtbJ4eVzGPl41VNPvn5E1i5poMk4/XD8UriLHpJvEP/Nw== 2697 + version "8.21.1" 2698 + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.21.1.tgz#110b441a210d53ab47795124dbc3e9bb993d1e7c" 2699 + integrity sha512-rc9K8ZpVjNcLs8Fp0dkozd5Pt2Apk1glO4Vgz8ix1u6yFByxfqo5Yavpy65o+93TAe24jr7v+eSBtFLvOQtCRQ== 2733 2700 dependencies: 2734 2701 "@types/estree" "*" 2735 2702 "@types/json-schema" "*" ··· 2749 2716 resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" 2750 2717 integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== 2751 2718 2752 - "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.31": 2753 - version "4.17.32" 2754 - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.32.tgz#93dda387f5516af616d8d3f05f2c4c79d81e1b82" 2755 - integrity sha512-aI5h/VOkxOF2Z1saPy0Zsxs5avets/iaiAJYznQFm5By/pamU31xWKL//epiF4OfUA2qTOc9PV6tCUjhO8wlZA== 2719 + "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": 2720 + version "4.17.33" 2721 + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.33.tgz#de35d30a9d637dc1450ad18dd583d75d5733d543" 2722 + integrity sha512-TPBqmR/HRYI3eC2E5hmiivIzv+bidAfXofM+sbonAGvyDhySGw9/PQZFt2BLOrjUUR++4eJVpx6KnLQK1Fk9tA== 2756 2723 dependencies: 2757 2724 "@types/node" "*" 2758 2725 "@types/qs" "*" 2759 2726 "@types/range-parser" "*" 2760 2727 2761 2728 "@types/express@*", "@types/express@^4.17.13": 2762 - version "4.17.15" 2763 - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.15.tgz#9290e983ec8b054b65a5abccb610411953d417ff" 2764 - integrity sha512-Yv0k4bXGOH+8a+7bELd2PqHQsuiANB+A8a4gnQrkRWzrkKlb6KHaVvyXhqs04sVW/OWlbPyYxRgYlIXLfrufMQ== 2729 + version "4.17.17" 2730 + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.17.tgz#01d5437f6ef9cfa8668e616e13c2f2ac9a491ae4" 2731 + integrity sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q== 2765 2732 dependencies: 2766 2733 "@types/body-parser" "*" 2767 - "@types/express-serve-static-core" "^4.17.31" 2734 + "@types/express-serve-static-core" "^4.17.33" 2768 2735 "@types/qs" "*" 2769 2736 "@types/serve-static" "*" 2770 2737 2771 - "@types/graceful-fs@^4.1.2": 2772 - version "4.1.5" 2773 - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" 2774 - integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== 2775 - dependencies: 2776 - "@types/node" "*" 2777 - 2778 - "@types/graceful-fs@^4.1.3": 2738 + "@types/graceful-fs@^4.1.2", "@types/graceful-fs@^4.1.3": 2779 2739 version "4.1.6" 2780 2740 resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" 2781 2741 integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== ··· 2788 2748 integrity sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA== 2789 2749 2790 2750 "@types/he@^1.1.2": 2791 - version "1.1.2" 2792 - resolved "https://registry.yarnpkg.com/@types/he/-/he-1.1.2.tgz#0c8b275f36d2b8b651104638e4d45693349c3953" 2793 - integrity sha512-kSJPcLO1x+oolc0R89pUl2kozldQ/fVQ1C1p5mp8fPoLdF/ZcBvckaTC2M8xXh3GYendXvCpy5m/a2eSbfgNgw== 2751 + version "1.2.0" 2752 + resolved "https://registry.yarnpkg.com/@types/he/-/he-1.2.0.tgz#3845193e597d943bab4e61ca5d7f3d8fc3d572a3" 2753 + integrity sha512-uH2smqTN4uGReAiKedIVzoLUAXIYLBTbSofhx3hbNqj74Ua6KqFsLYszduTrLCMEAEAozF73DbGi/SC1bzQq4g== 2794 2754 2795 2755 "@types/html-minifier-terser@^6.0.0": 2796 2756 version "6.1.0" ··· 2798 2758 integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== 2799 2759 2800 2760 "@types/http-proxy@^1.17.8": 2801 - version "1.17.9" 2802 - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.9.tgz#7f0e7931343761efde1e2bf48c40f02f3f75705a" 2803 - integrity sha512-QsbSjA/fSk7xB+UXlCT3wHBy5ai9wOcNDWwZAtud+jXhwOM3l+EYZh8Lng4+/6n8uar0J7xILzqftJdJ/Wdfkw== 2761 + version "1.17.10" 2762 + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.10.tgz#e576c8e4a0cc5c6a138819025a88e167ebb38d6c" 2763 + integrity sha512-Qs5aULi+zV1bwKAg5z1PWnDXWmsn+LxIvUGv6E2+OOMYhclZMO+OXd9pYVf2gLykf2I7IV2u7oTHwChPNsvJ7g== 2804 2764 dependencies: 2805 2765 "@types/node" "*" 2806 2766 2807 - "@types/invariant@^2.2.35": 2808 - version "2.2.35" 2809 - resolved "https://registry.yarnpkg.com/@types/invariant/-/invariant-2.2.35.tgz#cd3ebf581a6557452735688d8daba6cf0bd5a3be" 2810 - integrity sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg== 2811 - 2812 2767 "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": 2813 2768 version "2.0.4" 2814 2769 resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" ··· 2853 2808 dependencies: 2854 2809 "@types/lodash" "*" 2855 2810 2811 + "@types/lodash.clonedeep@^4.5.7": 2812 + version "4.5.7" 2813 + resolved "https://registry.yarnpkg.com/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.7.tgz#0e119f582ed6f9e6b373c04a644651763214f197" 2814 + integrity sha512-ccNqkPptFIXrpVqUECi60/DFxjNKsfoQxSQsgcBJCX/fuX1wgyQieojkcWH/KpE3xzLoWN/2k+ZeGqIN3paSvw== 2815 + dependencies: 2816 + "@types/lodash" "*" 2817 + 2818 + "@types/lodash.isequal@^4.5.6": 2819 + version "4.5.6" 2820 + resolved "https://registry.yarnpkg.com/@types/lodash.isequal/-/lodash.isequal-4.5.6.tgz#ff42a1b8e20caa59a97e446a77dc57db923bc02b" 2821 + integrity sha512-Ww4UGSe3DmtvLLJm2F16hDwEQSv7U0Rr8SujLUA2wHI2D2dm8kPu6Et+/y303LfjTIwSBKXB/YTUcAKpem/XEg== 2822 + dependencies: 2823 + "@types/lodash" "*" 2824 + 2856 2825 "@types/lodash.omit@^4.5.7": 2857 2826 version "4.5.7" 2858 2827 resolved "https://registry.yarnpkg.com/@types/lodash.omit/-/lodash.omit-4.5.7.tgz#2357ed2412b4164344e8ee41f85bb0b2920304ba" 2859 2828 integrity sha512-6q6cNg0tQ6oTWjSM+BcYMBhan54P/gLqBldG4AuXd3nKr0oeVekWNS4VrNEu3BhCSDXtGapi7zjhnna0s03KpA== 2829 + dependencies: 2830 + "@types/lodash" "*" 2831 + 2832 + "@types/lodash.shuffle@^4.2.7": 2833 + version "4.2.7" 2834 + resolved "https://registry.yarnpkg.com/@types/lodash.shuffle/-/lodash.shuffle-4.2.7.tgz#b714d829af948a266b0df1477d629c70de2f4c72" 2835 + integrity sha512-b+K0NBpB4WcNoQTfifuTmi5nm5mJXRw9DBdbFfBr1q1+EVoTKkClDxq/7r1sq2GZcRelMFRsFcGGHrHQgxRySg== 2860 2836 dependencies: 2861 2837 "@types/lodash" "*" 2862 2838 ··· 2871 2847 integrity sha512-Y4XFY5VJAuw0FgAqPNd6NNoV44jbq9Bz2L7Rh/J6jLTiHBSBJa9fxqQIvkIld4GsoDOcCbvzOUAbLPsSKKg+uA== 2872 2848 2873 2849 "@types/node@*": 2874 - version "18.11.18" 2875 - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.11.18.tgz#8dfb97f0da23c2293e554c5a50d61ef134d7697f" 2876 - integrity sha512-DHQpWGjyQKSHj3ebjFI/wRKcqQcdR+MoFBygntYOZytCqNfkd2ZC4ARDJ2DQqhjH5p85Nnd3jhUJIXrszFX/JA== 2850 + version "18.14.0" 2851 + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.14.0.tgz#94c47b9217bbac49d4a67a967fdcdeed89ebb7d0" 2852 + integrity sha512-5EWrvLmglK+imbCJY0+INViFWUHg1AHel1sq4ZVSfdcNqGy9Edv3UB9IIzzg+xPaUcAgZYcfVs2fBcwDeZzU0A== 2877 2853 2878 2854 "@types/parse-json@^4.0.0": 2879 2855 version "4.0.0" ··· 2913 2889 "@types/react" "*" 2914 2890 2915 2891 "@types/react-native@^0.67.3": 2916 - version "0.67.17" 2917 - resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.67.17.tgz#afebc3fff1d6314840c13b7936e17fa350eb7aae" 2918 - integrity sha512-HYo9XbYPwyf5L7FWhRjawbDQ4ma5k/bEzxrpDjG2olwLbXR/IR5ZghCmUUIcEtHB9KDg0QIAs+WriddtOKVmFg== 2892 + version "0.67.19" 2893 + resolved "https://registry.yarnpkg.com/@types/react-native/-/react-native-0.67.19.tgz#8f2fb257bd9f7b56b07a98be488aab0d79f087fe" 2894 + integrity sha512-tk3D4HtJ4KBmnoOMiPWY5og0m34cwavCPSlV75hMqut2WgcDF9SXvkqZU0RP6qddHwvEstYIJSvSfLMPOak5vQ== 2919 2895 dependencies: 2920 2896 "@types/react" "^17" 2921 2897 ··· 2927 2903 "@types/react" "^17" 2928 2904 2929 2905 "@types/react@*", "@types/react@^17": 2930 - version "17.0.52" 2931 - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.52.tgz#10d8b907b5c563ac014a541f289ae8eaa9bf2e9b" 2932 - integrity sha512-vwk8QqVODi0VaZZpDXQCmEmiOuyjEFPY7Ttaw5vjM112LOq37yz1CDJGrRJwA1fYEq4Iitd5rnjd1yWAc/bT+A== 2906 + version "17.0.53" 2907 + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.53.tgz#10d4d5999b8af3d6bc6a9369d7eb953da82442ab" 2908 + integrity sha512-1yIpQR2zdYu1Z/dc1OxC+MA6GR240u3gcnP4l6mvj/PJiVaqHsQPmWttsvHsfnhfPbU2FuGmo0wSITPygjBmsw== 2933 2909 dependencies: 2934 2910 "@types/prop-types" "*" 2935 2911 "@types/scheduler" "*" ··· 2985 2961 integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== 2986 2962 2987 2963 "@types/trusted-types@^2.0.2": 2988 - version "2.0.2" 2989 - resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.2.tgz#fc25ad9943bcac11cceb8168db4f275e0e72e756" 2990 - integrity sha512-F5DIZ36YVLE+PN+Zwws4kJogq47hNgX3Nx6WyDJ3kcplxyke3XIzB8uK5n/Lpm1HBsbGzd6nmGehL8cPekP+Tg== 2964 + version "2.0.3" 2965 + resolved "https://registry.yarnpkg.com/@types/trusted-types/-/trusted-types-2.0.3.tgz#a136f83b0758698df454e328759dbd3d44555311" 2966 + integrity sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g== 2991 2967 2992 2968 "@types/ws@^8.5.1": 2993 2969 version "8.5.4" ··· 3002 2978 integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== 3003 2979 3004 2980 "@types/yargs@^15.0.0": 3005 - version "15.0.14" 3006 - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.14.tgz#26d821ddb89e70492160b66d10a0eb6df8f6fb06" 3007 - integrity sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ== 2981 + version "15.0.15" 2982 + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.15.tgz#e609a2b1ef9e05d90489c2f5f45bbfb2be092158" 2983 + integrity sha512-IziEYMU9XoVj8hWg7k+UJrXALkGFjWJhn5QFEv9q4p+v40oZhSuC135M38st8XPjICL7Ey4TV64ferBGUoJhBg== 3008 2984 dependencies: 3009 2985 "@types/yargs-parser" "*" 3010 2986 3011 2987 "@types/yargs@^16.0.0": 3012 - version "16.0.4" 3013 - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977" 3014 - integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== 2988 + version "16.0.5" 2989 + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.5.tgz#12cc86393985735a283e387936398c2f9e5f88e3" 2990 + integrity sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ== 3015 2991 dependencies: 3016 2992 "@types/yargs-parser" "*" 3017 2993 3018 2994 "@types/yargs@^17.0.8": 3019 - version "17.0.18" 3020 - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.18.tgz#466225ab4fbabb9aa711f5b406796daf1374a5b7" 3021 - integrity sha512-eIJR1UER6ur3EpKM3d+2Pgd+ET+k6Kn9B4ZItX0oPjjVI5PrfaRjKyLT5UYendDpLuoiJMNJvovLQbEXqhsPaw== 2995 + version "17.0.22" 2996 + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.22.tgz#7dd37697691b5f17d020f3c63e7a45971ff71e9a" 2997 + integrity sha512-pet5WJ9U8yPVRhkwuEIp5ktAeAqRZOq4UdAyWLWzxbtpyXnzbtLdKiXAjJzi/KLmPGS9wk86lUFWZFN6sISo4g== 3022 2998 dependencies: 3023 2999 "@types/yargs-parser" "*" 3024 3000 3025 - "@typescript-eslint/eslint-plugin@^5.30.5", "@typescript-eslint/eslint-plugin@^5.48.2": 3026 - version "5.48.2" 3027 - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.2.tgz#112e6ae1e23a1dc8333ce82bb9c65c2608b4d8a3" 3028 - integrity sha512-sR0Gja9Ky1teIq4qJOl0nC+Tk64/uYdX+mi+5iB//MH8gwyx8e3SOyhEzeLZEFEEfCaLf8KJq+Bd/6je1t+CAg== 3029 - dependencies: 3030 - "@typescript-eslint/scope-manager" "5.48.2" 3031 - "@typescript-eslint/type-utils" "5.48.2" 3032 - "@typescript-eslint/utils" "5.48.2" 3033 - debug "^4.3.4" 3034 - ignore "^5.2.0" 3035 - natural-compare-lite "^1.4.0" 3036 - regexpp "^3.2.0" 3037 - semver "^7.3.7" 3038 - tsutils "^3.21.0" 3039 - 3040 - "@typescript-eslint/eslint-plugin@^5.5.0": 3041 - version "5.48.0" 3042 - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.0.tgz#54f8368d080eb384a455f60c2ee044e948a8ce67" 3043 - integrity sha512-SVLafp0NXpoJY7ut6VFVUU9I+YeFsDzeQwtK0WZ+xbRN3mtxJ08je+6Oi2N89qDn087COdO0u3blKZNv9VetRQ== 3001 + "@typescript-eslint/eslint-plugin@^5.30.5", "@typescript-eslint/eslint-plugin@^5.48.2", "@typescript-eslint/eslint-plugin@^5.5.0": 3002 + version "5.53.0" 3003 + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.53.0.tgz#24b8b4a952f3c615fe070e3c461dd852b5056734" 3004 + integrity sha512-alFpFWNucPLdUOySmXCJpzr6HKC3bu7XooShWM+3w/EL6J2HIoB2PFxpLnq4JauWVk6DiVeNKzQlFEaE+X9sGw== 3044 3005 dependencies: 3045 - "@typescript-eslint/scope-manager" "5.48.0" 3046 - "@typescript-eslint/type-utils" "5.48.0" 3047 - "@typescript-eslint/utils" "5.48.0" 3006 + "@typescript-eslint/scope-manager" "5.53.0" 3007 + "@typescript-eslint/type-utils" "5.53.0" 3008 + "@typescript-eslint/utils" "5.53.0" 3048 3009 debug "^4.3.4" 3010 + grapheme-splitter "^1.0.4" 3049 3011 ignore "^5.2.0" 3050 3012 natural-compare-lite "^1.4.0" 3051 3013 regexpp "^3.2.0" ··· 3053 3015 tsutils "^3.21.0" 3054 3016 3055 3017 "@typescript-eslint/experimental-utils@^5.0.0": 3056 - version "5.48.0" 3057 - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.48.0.tgz#10c0871a1dfee734fbcd49399b6a07ce38bdb61c" 3058 - integrity sha512-ehoJFf67UViwnYuz6JUneZ8qxgDk0qEWKiTLmpE8WpPEr15e2cSLtp0E6Zicx2DaYdwctUA0uLRTbLckxQpurg== 3018 + version "5.53.0" 3019 + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.53.0.tgz#e249e3a47ace290ea3d83a5a08c8d90cd7fe2a53" 3020 + integrity sha512-4SklZEwRn0jqkhtW+pPZpbKFXprwGneBndRM0TGzJu/LWdb9QV2hBgFIVU9AREo02BzqFvyG/ypd+xAW5YGhXw== 3059 3021 dependencies: 3060 - "@typescript-eslint/utils" "5.48.0" 3022 + "@typescript-eslint/utils" "5.53.0" 3061 3023 3062 - "@typescript-eslint/parser@^5.30.5", "@typescript-eslint/parser@^5.48.2": 3063 - version "5.48.2" 3064 - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.48.2.tgz#c9edef2a0922d26a37dba03be20c5fff378313b3" 3065 - integrity sha512-38zMsKsG2sIuM5Oi/olurGwYJXzmtdsHhn5mI/pQogP+BjYVkK5iRazCQ8RGS0V+YLk282uWElN70zAAUmaYHw== 3024 + "@typescript-eslint/parser@^5.30.5", "@typescript-eslint/parser@^5.48.2", "@typescript-eslint/parser@^5.5.0": 3025 + version "5.53.0" 3026 + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.53.0.tgz#a1f2b9ae73b83181098747e96683f1b249ecab52" 3027 + integrity sha512-MKBw9i0DLYlmdOb3Oq/526+al20AJZpANdT6Ct9ffxcV8nKCHz63t/S0IhlTFNsBIHJv+GY5SFJ0XfqVeydQrQ== 3066 3028 dependencies: 3067 - "@typescript-eslint/scope-manager" "5.48.2" 3068 - "@typescript-eslint/types" "5.48.2" 3069 - "@typescript-eslint/typescript-estree" "5.48.2" 3029 + "@typescript-eslint/scope-manager" "5.53.0" 3030 + "@typescript-eslint/types" "5.53.0" 3031 + "@typescript-eslint/typescript-estree" "5.53.0" 3070 3032 debug "^4.3.4" 3071 3033 3072 - "@typescript-eslint/parser@^5.5.0": 3073 - version "5.48.0" 3074 - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.48.0.tgz#02803355b23884a83e543755349809a50b7ed9ba" 3075 - integrity sha512-1mxNA8qfgxX8kBvRDIHEzrRGrKHQfQlbW6iHyfHYS0Q4X1af+S6mkLNtgCOsGVl8+/LUPrqdHMssAemkrQ01qg== 3034 + "@typescript-eslint/scope-manager@5.53.0": 3035 + version "5.53.0" 3036 + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.53.0.tgz#42b54f280e33c82939275a42649701024f3fafef" 3037 + integrity sha512-Opy3dqNsp/9kBBeCPhkCNR7fmdSQqA+47r21hr9a14Bx0xnkElEQmhoHga+VoaoQ6uDHjDKmQPIYcUcKJifS7w== 3076 3038 dependencies: 3077 - "@typescript-eslint/scope-manager" "5.48.0" 3078 - "@typescript-eslint/types" "5.48.0" 3079 - "@typescript-eslint/typescript-estree" "5.48.0" 3080 - debug "^4.3.4" 3039 + "@typescript-eslint/types" "5.53.0" 3040 + "@typescript-eslint/visitor-keys" "5.53.0" 3081 3041 3082 - "@typescript-eslint/scope-manager@5.48.0": 3083 - version "5.48.0" 3084 - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.48.0.tgz#607731cb0957fbc52fd754fd79507d1b6659cecf" 3085 - integrity sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow== 3086 - dependencies: 3087 - "@typescript-eslint/types" "5.48.0" 3088 - "@typescript-eslint/visitor-keys" "5.48.0" 3089 - 3090 - "@typescript-eslint/scope-manager@5.48.2": 3091 - version "5.48.2" 3092 - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.48.2.tgz#bb7676cb78f1e94921eaab637a4b5d596f838abc" 3093 - integrity sha512-zEUFfonQid5KRDKoI3O+uP1GnrFd4tIHlvs+sTJXiWuypUWMuDaottkJuR612wQfOkjYbsaskSIURV9xo4f+Fw== 3094 - dependencies: 3095 - "@typescript-eslint/types" "5.48.2" 3096 - "@typescript-eslint/visitor-keys" "5.48.2" 3097 - 3098 - "@typescript-eslint/type-utils@5.48.0": 3099 - version "5.48.0" 3100 - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.48.0.tgz#40496dccfdc2daa14a565f8be80ad1ae3882d6d6" 3101 - integrity sha512-vbtPO5sJyFjtHkGlGK4Sthmta0Bbls4Onv0bEqOGm7hP9h8UpRsHJwsrCiWtCUndTRNQO/qe6Ijz9rnT/DB+7g== 3102 - dependencies: 3103 - "@typescript-eslint/typescript-estree" "5.48.0" 3104 - "@typescript-eslint/utils" "5.48.0" 3105 - debug "^4.3.4" 3106 - tsutils "^3.21.0" 3107 - 3108 - "@typescript-eslint/type-utils@5.48.2": 3109 - version "5.48.2" 3110 - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.48.2.tgz#7d3aeca9fa37a7ab7e3d9056a99b42f342c48ad7" 3111 - integrity sha512-QVWx7J5sPMRiOMJp5dYshPxABRoZV1xbRirqSk8yuIIsu0nvMTZesKErEA3Oix1k+uvsk8Cs8TGJ6kQ0ndAcew== 3042 + "@typescript-eslint/type-utils@5.53.0": 3043 + version "5.53.0" 3044 + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.53.0.tgz#41665449935ba9b4e6a1ba6e2a3f4b2c31d6cf97" 3045 + integrity sha512-HO2hh0fmtqNLzTAme/KnND5uFNwbsdYhCZghK2SoxGp3Ifn2emv+hi0PBUjzzSh0dstUIFqOj3bp0AwQlK4OWw== 3112 3046 dependencies: 3113 - "@typescript-eslint/typescript-estree" "5.48.2" 3114 - "@typescript-eslint/utils" "5.48.2" 3047 + "@typescript-eslint/typescript-estree" "5.53.0" 3048 + "@typescript-eslint/utils" "5.53.0" 3115 3049 debug "^4.3.4" 3116 3050 tsutils "^3.21.0" 3117 3051 3118 - "@typescript-eslint/types@5.48.0": 3119 - version "5.48.0" 3120 - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.48.0.tgz#d725da8dfcff320aab2ac6f65c97b0df30058449" 3121 - integrity sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw== 3122 - 3123 - "@typescript-eslint/types@5.48.2": 3124 - version "5.48.2" 3125 - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.48.2.tgz#635706abb1ec164137f92148f06f794438c97b8e" 3126 - integrity sha512-hE7dA77xxu7ByBc6KCzikgfRyBCTst6dZQpwaTy25iMYOnbNljDT4hjhrGEJJ0QoMjrfqrx+j1l1B9/LtKeuqA== 3127 - 3128 - "@typescript-eslint/typescript-estree@5.48.0": 3129 - version "5.48.0" 3130 - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.0.tgz#a7f04bccb001003405bb5452d43953a382c2fac2" 3131 - integrity sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw== 3132 - dependencies: 3133 - "@typescript-eslint/types" "5.48.0" 3134 - "@typescript-eslint/visitor-keys" "5.48.0" 3135 - debug "^4.3.4" 3136 - globby "^11.1.0" 3137 - is-glob "^4.0.3" 3138 - semver "^7.3.7" 3139 - tsutils "^3.21.0" 3052 + "@typescript-eslint/types@5.53.0": 3053 + version "5.53.0" 3054 + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.53.0.tgz#f79eca62b97e518ee124086a21a24f3be267026f" 3055 + integrity sha512-5kcDL9ZUIP756K6+QOAfPkigJmCPHcLN7Zjdz76lQWWDdzfOhZDTj1irs6gPBKiXx5/6O3L0+AvupAut3z7D2A== 3140 3056 3141 - "@typescript-eslint/typescript-estree@5.48.2": 3142 - version "5.48.2" 3143 - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.2.tgz#6e206b462942b32383582a6c9251c05021cc21b0" 3144 - integrity sha512-bibvD3z6ilnoVxUBFEgkO0k0aFvUc4Cttt0dAreEr+nrAHhWzkO83PEVVuieK3DqcgL6VAK5dkzK8XUVja5Zcg== 3057 + "@typescript-eslint/typescript-estree@5.53.0": 3058 + version "5.53.0" 3059 + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.53.0.tgz#bc651dc28cf18ab248ecd18a4c886c744aebd690" 3060 + integrity sha512-eKmipH7QyScpHSkhbptBBYh9v8FxtngLquq292YTEQ1pxVs39yFBlLC1xeIZcPPz1RWGqb7YgERJRGkjw8ZV7w== 3145 3061 dependencies: 3146 - "@typescript-eslint/types" "5.48.2" 3147 - "@typescript-eslint/visitor-keys" "5.48.2" 3062 + "@typescript-eslint/types" "5.53.0" 3063 + "@typescript-eslint/visitor-keys" "5.53.0" 3148 3064 debug "^4.3.4" 3149 3065 globby "^11.1.0" 3150 3066 is-glob "^4.0.3" 3151 3067 semver "^7.3.7" 3152 3068 tsutils "^3.21.0" 3153 3069 3154 - "@typescript-eslint/utils@5.48.0", "@typescript-eslint/utils@^5.13.0": 3155 - version "5.48.0" 3156 - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.48.0.tgz#eee926af2733f7156ad8d15e51791e42ce300273" 3157 - integrity sha512-x2jrMcPaMfsHRRIkL+x96++xdzvrdBCnYRd5QiW5Wgo1OB4kDYPbC1XjWP/TNqlfK93K/lUL92erq5zPLgFScQ== 3158 - dependencies: 3159 - "@types/json-schema" "^7.0.9" 3160 - "@types/semver" "^7.3.12" 3161 - "@typescript-eslint/scope-manager" "5.48.0" 3162 - "@typescript-eslint/types" "5.48.0" 3163 - "@typescript-eslint/typescript-estree" "5.48.0" 3164 - eslint-scope "^5.1.1" 3165 - eslint-utils "^3.0.0" 3166 - semver "^7.3.7" 3167 - 3168 - "@typescript-eslint/utils@5.48.2", "@typescript-eslint/utils@^5.10.0": 3169 - version "5.48.2" 3170 - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.48.2.tgz#3777a91dcb22b8499a25519e06eef2e9569295a3" 3171 - integrity sha512-2h18c0d7jgkw6tdKTlNaM7wyopbLRBiit8oAxoP89YnuBOzCZ8g8aBCaCqq7h208qUTroL7Whgzam7UY3HVLow== 3070 + "@typescript-eslint/utils@5.53.0", "@typescript-eslint/utils@^5.10.0", "@typescript-eslint/utils@^5.43.0": 3071 + version "5.53.0" 3072 + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.53.0.tgz#e55eaad9d6fffa120575ffaa530c7e802f13bce8" 3073 + integrity sha512-VUOOtPv27UNWLxFwQK/8+7kvxVC+hPHNsJjzlJyotlaHjLSIgOCKj9I0DBUjwOOA64qjBwx5afAPjksqOxMO0g== 3172 3074 dependencies: 3173 3075 "@types/json-schema" "^7.0.9" 3174 3076 "@types/semver" "^7.3.12" 3175 - "@typescript-eslint/scope-manager" "5.48.2" 3176 - "@typescript-eslint/types" "5.48.2" 3177 - "@typescript-eslint/typescript-estree" "5.48.2" 3077 + "@typescript-eslint/scope-manager" "5.53.0" 3078 + "@typescript-eslint/types" "5.53.0" 3079 + "@typescript-eslint/typescript-estree" "5.53.0" 3178 3080 eslint-scope "^5.1.1" 3179 3081 eslint-utils "^3.0.0" 3180 3082 semver "^7.3.7" 3181 3083 3182 - "@typescript-eslint/visitor-keys@5.48.0": 3183 - version "5.48.0" 3184 - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz#4446d5e7f6cadde7140390c0e284c8702d944904" 3185 - integrity sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q== 3186 - dependencies: 3187 - "@typescript-eslint/types" "5.48.0" 3188 - eslint-visitor-keys "^3.3.0" 3189 - 3190 - "@typescript-eslint/visitor-keys@5.48.2": 3191 - version "5.48.2" 3192 - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.2.tgz#c247582a0bcce467461d7b696513bf9455000060" 3193 - integrity sha512-z9njZLSkwmjFWUelGEwEbdf4NwKvfHxvGC0OcGN1Hp/XNDIcJ7D5DpPNPv6x6/mFvc1tQHsaWmpD/a4gOvvCJQ== 3084 + "@typescript-eslint/visitor-keys@5.53.0": 3085 + version "5.53.0" 3086 + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.53.0.tgz#8a5126623937cdd909c30d8fa72f79fa56cc1a9f" 3087 + integrity sha512-JqNLnX3leaHFZEN0gCh81sIvgrp/2GOACZNgO4+Tkf64u51kTpAyWFOY8XHx8XuXr3N2C9zgPPHtcpMg6z1g0w== 3194 3088 dependencies: 3195 - "@typescript-eslint/types" "5.48.2" 3089 + "@typescript-eslint/types" "5.53.0" 3196 3090 eslint-visitor-keys "^3.3.0" 3197 3091 3198 3092 "@ucans/core@0.11.0": ··· 3416 3310 integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== 3417 3311 3418 3312 acorn@^8.2.4, acorn@^8.5.0, acorn@^8.7.1, acorn@^8.8.0: 3419 - version "8.8.1" 3420 - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.1.tgz#0a3f9cbecc4ec3bea6f0a80b66ae8dd2da250b73" 3421 - integrity sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA== 3313 + version "8.8.2" 3314 + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.2.tgz#1b2f25db02af965399b9776b0c2c391276d37c4a" 3315 + integrity sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw== 3422 3316 3423 3317 address@^1.0.1, address@^1.1.2: 3424 3318 version "1.2.2" ··· 3469 3363 json-schema-traverse "^0.4.1" 3470 3364 uri-js "^4.2.2" 3471 3365 3472 - ajv@^8.0.0, ajv@^8.6.0, ajv@^8.8.0: 3366 + ajv@^8.0.0, ajv@^8.6.0, ajv@^8.6.3, ajv@^8.8.0: 3473 3367 version "8.12.0" 3474 3368 resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" 3475 3369 integrity sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA== ··· 3569 3463 resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" 3570 3464 integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== 3571 3465 3572 - aria-query@^4.2.2: 3573 - version "4.2.2" 3574 - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-4.2.2.tgz#0d2ca6c9aceb56b8977e9fed6aed7e15bbd2f83b" 3575 - integrity sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA== 3466 + aria-query@^5.1.3: 3467 + version "5.1.3" 3468 + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.1.3.tgz#19db27cd101152773631396f7a95a3b58c22c35e" 3469 + integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== 3576 3470 dependencies: 3577 - "@babel/runtime" "^7.10.2" 3578 - "@babel/runtime-corejs3" "^7.10.2" 3471 + deep-equal "^2.0.5" 3579 3472 3580 3473 arr-diff@^4.0.0: 3581 3474 version "4.0.0" ··· 3602 3495 resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" 3603 3496 integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== 3604 3497 3605 - array-includes@^3.1.4, array-includes@^3.1.5, array-includes@^3.1.6: 3498 + array-includes@^3.1.5, array-includes@^3.1.6: 3606 3499 version "3.1.6" 3607 3500 resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f" 3608 3501 integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw== ··· 3623 3516 resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" 3624 3517 integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== 3625 3518 3626 - array.prototype.flat@^1.2.5: 3519 + array.prototype.flat@^1.3.1: 3627 3520 version "1.3.1" 3628 3521 resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz#ffc6576a7ca3efc2f46a143b9d1dda9b4b3cf5e2" 3629 3522 integrity sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA== ··· 3643 3536 es-abstract "^1.20.4" 3644 3537 es-shim-unscopables "^1.0.0" 3645 3538 3646 - array.prototype.map@^1.0.5: 3647 - version "1.0.5" 3648 - resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.5.tgz#6e43c2fee6c0fb5e4806da2dc92eb00970809e55" 3649 - integrity sha512-gfaKntvwqYIuC7mLLyv2wzZIJqrRhn5PZ9EfFejSx6a78sV7iDsGpG9P+3oUPtm1Rerqm6nrKS4FYuTIvWfo3g== 3650 - dependencies: 3651 - call-bind "^1.0.2" 3652 - define-properties "^1.1.4" 3653 - es-abstract "^1.20.4" 3654 - es-array-method-boxes-properly "^1.0.0" 3655 - is-string "^1.0.7" 3656 - 3657 3539 array.prototype.reduce@^1.0.5: 3658 3540 version "1.0.5" 3659 3541 resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.5.tgz#6b20b0daa9d9734dd6bc7ea66b5bbce395471eac" ··· 3752 3634 picocolors "^1.0.0" 3753 3635 postcss-value-parser "^4.2.0" 3754 3636 3755 - axe-core@^4.4.3: 3756 - version "4.6.1" 3757 - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.6.1.tgz#79cccdee3e3ab61a8f42c458d4123a6768e6fbce" 3758 - integrity sha512-lCZN5XRuOnpG4bpMq8v0khrWtUOn+i8lZSb6wHZH56ZfbIEv6XwJV84AAueh9/zi7qPVJ/E4yz6fmsiyOmXR4w== 3637 + available-typed-arrays@^1.0.5: 3638 + version "1.0.5" 3639 + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" 3640 + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== 3641 + 3642 + await-lock@^2.2.2: 3643 + version "2.2.2" 3644 + resolved "https://registry.yarnpkg.com/await-lock/-/await-lock-2.2.2.tgz#a95a9b269bfd2f69d22b17a321686f551152bcef" 3645 + integrity sha512-aDczADvlvTGajTDjcjpJMqRkOF6Qdz3YbPZm/PyW6tKPkx2hlYBzxMhEywM/tU72HrVZjgl5VCdRuMlA7pZ8Gw== 3646 + 3647 + axe-core@^4.6.2: 3648 + version "4.6.3" 3649 + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.6.3.tgz#fc0db6fdb65cc7a80ccf85286d91d64ababa3ece" 3650 + integrity sha512-/BQzOX780JhsxDnPpH4ZiyrJAzcd8AfzFPkv+89veFSr1rcMjuq2JDCwypKaPeB6ljHp9KjXhPpjgCvQlWYuqg== 3759 3651 3760 3652 axios@^0.24.0: 3761 3653 version "0.24.0" ··· 3772 3664 follow-redirects "^1.14.9" 3773 3665 form-data "^4.0.0" 3774 3666 3775 - axobject-query@^2.2.0: 3776 - version "2.2.0" 3777 - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be" 3778 - integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA== 3667 + axobject-query@^3.1.1: 3668 + version "3.1.1" 3669 + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.1.1.tgz#3b6e5c6d4e43ca7ba51c5babf99d22a9c68485e1" 3670 + integrity sha512-goKlv8DZrK9hUh975fnHzhNIO4jUnFCfv/dszV5VwUGDFjI6vQ2VwoyjYjYNEbBE8AH87TduWP5uyDR1D+Iteg== 3671 + dependencies: 3672 + deep-equal "^2.0.5" 3779 3673 3780 3674 babel-core@^7.0.0-bridge.0: 3781 3675 version "7.0.0-bridge.0" ··· 3796 3690 graceful-fs "^4.2.9" 3797 3691 slash "^3.0.0" 3798 3692 3799 - babel-jest@^29.2.1, babel-jest@^29.3.1: 3800 - version "29.3.1" 3801 - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.3.1.tgz#05c83e0d128cd48c453eea851482a38782249f44" 3802 - integrity sha512-aard+xnMoxgjwV70t0L6wkW/3HQQtV+O0PEimxKgzNqCJnbYmroPojdP2tqKSOAt8QAKV/uSZU8851M7B5+fcA== 3693 + babel-jest@^29.2.1, babel-jest@^29.4.3: 3694 + version "29.4.3" 3695 + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.4.3.tgz#478b84d430972b277ad67dd631be94abea676792" 3696 + integrity sha512-o45Wyn32svZE+LnMVWv/Z4x0SwtLbh4FyGcYtR20kIWd+rdrDZ9Fzq8Ml3MYLD+mZvEdzCjZsCnYZ2jpJyQ+Nw== 3803 3697 dependencies: 3804 - "@jest/transform" "^29.3.1" 3698 + "@jest/transform" "^29.4.3" 3805 3699 "@types/babel__core" "^7.1.14" 3806 3700 babel-plugin-istanbul "^6.1.1" 3807 - babel-preset-jest "^29.2.0" 3701 + babel-preset-jest "^29.4.3" 3808 3702 chalk "^4.0.0" 3809 3703 graceful-fs "^4.2.9" 3810 3704 slash "^3.0.0" ··· 3848 3742 "@types/babel__core" "^7.0.0" 3849 3743 "@types/babel__traverse" "^7.0.6" 3850 3744 3851 - babel-plugin-jest-hoist@^29.2.0: 3852 - version "29.2.0" 3853 - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz#23ee99c37390a98cfddf3ef4a78674180d823094" 3854 - integrity sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA== 3745 + babel-plugin-jest-hoist@^29.4.3: 3746 + version "29.4.3" 3747 + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.4.3.tgz#ad1dfb5d31940957e00410ef7d9b2aa94b216101" 3748 + integrity sha512-mB6q2q3oahKphy5V7CpnNqZOCkxxZ9aokf1eh82Dy3jQmg4xvM1tGrh5y6BQUJh4a3Pj9+eLfwvAZ7VNKg7H8Q== 3855 3749 dependencies: 3856 3750 "@babel/template" "^7.3.3" 3857 3751 "@babel/types" "^7.3.3" ··· 3981 3875 babel-plugin-jest-hoist "^27.5.1" 3982 3876 babel-preset-current-node-syntax "^1.0.0" 3983 3877 3984 - babel-preset-jest@^29.2.0: 3985 - version "29.2.0" 3986 - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz#3048bea3a1af222e3505e4a767a974c95a7620dc" 3987 - integrity sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA== 3878 + babel-preset-jest@^29.4.3: 3879 + version "29.4.3" 3880 + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.4.3.tgz#bb926b66ae253b69c6e3ef87511b8bb5c53c5b52" 3881 + integrity sha512-gWx6COtSuma6n9bw+8/F+2PCXrIgxV/D1TJFnp6OyBK2cxPWg0K9p/sriNYeifKjpUkMViWQ09DSWtzJQRETsw== 3988 3882 dependencies: 3989 - babel-plugin-jest-hoist "^29.2.0" 3883 + babel-plugin-jest-hoist "^29.4.3" 3990 3884 babel-preset-current-node-syntax "^1.0.0" 3991 3885 3992 3886 babel-preset-react-app@^10.0.1: ··· 4093 3987 inherits "^2.0.4" 4094 3988 readable-stream "^3.4.0" 4095 3989 4096 - bluebird@^3.5.5: 3990 + bluebird@^3.5.4, bluebird@^3.5.5: 4097 3991 version "3.7.2" 4098 3992 resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" 4099 3993 integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== ··· 4117 4011 unpipe "1.0.0" 4118 4012 4119 4013 bonjour-service@^1.0.11: 4120 - version "1.0.14" 4121 - resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.14.tgz#c346f5bc84e87802d08f8d5a60b93f758e514ee7" 4122 - integrity sha512-HIMbgLnk1Vqvs6B4Wq5ep7mxvj9sGz5d1JJyDNSGNIdA/w2MCz6GTjWTdjqOJV1bEPj+6IkxDvWNFKEBxNt4kQ== 4014 + version "1.1.0" 4015 + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.1.0.tgz#424170268d68af26ff83a5c640b95def01803a13" 4016 + integrity sha512-LVRinRB3k1/K0XzZ2p58COnWvkQknIY6sf0zF2rpErvcJXpMBttEPQSxK+HEXSS9VmpZlDoDnQWv8ftJT20B0Q== 4123 4017 dependencies: 4124 4018 array-flatten "^2.1.2" 4125 4019 dns-equal "^1.0.0" ··· 4179 4073 resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" 4180 4074 integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== 4181 4075 4182 - browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.18.1, browserslist@^4.21.3, browserslist@^4.21.4: 4183 - version "4.21.4" 4184 - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" 4185 - integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== 4076 + browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.18.1, browserslist@^4.21.3, browserslist@^4.21.4, browserslist@^4.21.5: 4077 + version "4.21.5" 4078 + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" 4079 + integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== 4186 4080 dependencies: 4187 - caniuse-lite "^1.0.30001400" 4188 - electron-to-chromium "^1.4.251" 4189 - node-releases "^2.0.6" 4190 - update-browserslist-db "^1.0.9" 4081 + caniuse-lite "^1.0.30001449" 4082 + electron-to-chromium "^1.4.284" 4083 + node-releases "^2.0.8" 4084 + update-browserslist-db "^1.0.10" 4191 4085 4192 4086 bser@2.1.1: 4193 4087 version "2.1.1" ··· 4232 4126 resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" 4233 4127 integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== 4234 4128 4129 + bunyan-debug-stream@^3.1.0: 4130 + version "3.1.0" 4131 + resolved "https://registry.yarnpkg.com/bunyan-debug-stream/-/bunyan-debug-stream-3.1.0.tgz#78309c67ad85cfb8f011155334152c49209dcda8" 4132 + integrity sha512-VaFYbDVdiSn3ZpdozrjZ8mFpxHXl26t11C1DKRQtbo0EgffqeFNrRLOGIESKVeGEvVu4qMxMSSxzNlSw7oTj7w== 4133 + dependencies: 4134 + chalk "^4.1.2" 4135 + 4136 + bunyan@^1.8.12: 4137 + version "1.8.15" 4138 + resolved "https://registry.yarnpkg.com/bunyan/-/bunyan-1.8.15.tgz#8ce34ca908a17d0776576ca1b2f6cbd916e93b46" 4139 + integrity sha512-0tECWShh6wUysgucJcBAoYegf3JJoZWibxdqhTm7OHPeT42qdjkZ29QCMcKwbgU1kiH+auSIasNRXMLWXafXig== 4140 + optionalDependencies: 4141 + dtrace-provider "~0.8" 4142 + moment "^2.19.3" 4143 + mv "~2" 4144 + safe-json-stringify "~1" 4145 + 4235 4146 bytes@3.0.0: 4236 4147 version "3.0.0" 4237 4148 resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" ··· 4257 4168 union-value "^1.0.0" 4258 4169 unset-value "^1.0.0" 4259 4170 4171 + caf@^15.0.1: 4172 + version "15.0.1" 4173 + resolved "https://registry.yarnpkg.com/caf/-/caf-15.0.1.tgz#28f1f17bd93dc4b5d95207ad07066eddf4768160" 4174 + integrity sha512-Xp/IK6vMwujxWZXra7djdYzPdPnEQKa7Mudu2wZgDQ3TJry1I0TgtjEgwZHpoBcMp68j4fb0/FZ1SJyMEgJrXQ== 4175 + 4260 4176 call-bind@^1.0.0, call-bind@^1.0.2: 4261 4177 version "1.0.2" 4262 4178 resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" ··· 4322 4238 lodash.memoize "^4.1.2" 4323 4239 lodash.uniq "^4.5.0" 4324 4240 4325 - caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001426: 4326 - version "1.0.30001441" 4327 - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz#987437b266260b640a23cd18fbddb509d7f69f3e" 4328 - integrity sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg== 4241 + caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001426, caniuse-lite@^1.0.30001449: 4242 + version "1.0.30001457" 4243 + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz#6af34bb5d720074e2099432aa522c21555a18301" 4244 + integrity sha512-SDIV6bgE1aVbK6XyxdURbUE89zY7+k1BBBaOwYwkNCglXlel/E7mELiHC64HQ+W0xSKlqWhV9Wh7iHxUjMs4fA== 4329 4245 4330 4246 case-sensitive-paths-webpack-plugin@^2.4.0: 4331 4247 version "2.4.0" ··· 4337 4253 resolved "https://registry.yarnpkg.com/cborg/-/cborg-1.10.0.tgz#0fe157961dd47b537ccb84dc9ba681de8b699013" 4338 4254 integrity sha512-/eM0JCaL99HDHxjySNQJLaolZFVdl6VA0/hEKIoiQPcQzE5LrG5QHdml0HaBt31brgB9dNe1zMr3f8IVrpotRQ== 4339 4255 4340 - chalk@^2.0.0, chalk@^2.4.1: 4256 + chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: 4341 4257 version "2.4.2" 4342 4258 resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" 4343 4259 integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== ··· 4369 4285 resolved "https://registry.yarnpkg.com/check-types/-/check-types-11.2.2.tgz#7afc0b6a860d686885062f2dba888ba5710335b4" 4370 4286 integrity sha512-HBiYvXvn9Z70Z88XKjz3AEKd4HJhBXsa3j7xFnITAzoS8+q6eIGi8qDB8FKPBAjtuxjI/zFpwuiCb8oDtKOYrA== 4371 4287 4288 + child-process-promise@^2.2.0: 4289 + version "2.2.1" 4290 + resolved "https://registry.yarnpkg.com/child-process-promise/-/child-process-promise-2.2.1.tgz#4730a11ef610fad450b8f223c79d31d7bdad8074" 4291 + integrity sha512-Fi4aNdqBsr0mv+jgWxcZ/7rAIC2mgihrptyVI4foh/rrjY/3BNjfP9+oaiFx/fzim+1ZyCNBae0DlyfQhSugog== 4292 + dependencies: 4293 + cross-spawn "^4.0.2" 4294 + node-version "^1.0.0" 4295 + promise-polyfill "^6.0.1" 4296 + 4372 4297 chokidar@^3.4.2, chokidar@^3.5.3: 4373 4298 version "3.5.3" 4374 4299 resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" ··· 4400 4325 integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== 4401 4326 4402 4327 ci-info@^3.2.0: 4403 - version "3.7.1" 4404 - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.7.1.tgz#708a6cdae38915d597afdf3b145f2f8e1ff55f3f" 4405 - integrity sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w== 4328 + version "3.8.0" 4329 + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" 4330 + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== 4406 4331 4407 4332 cjs-module-lexer@^1.0.0: 4408 4333 version "1.2.2" ··· 4420 4345 static-extend "^0.1.1" 4421 4346 4422 4347 clean-css@^5.2.2: 4423 - version "5.3.1" 4424 - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.1.tgz#d0610b0b90d125196a2894d35366f734e5d7aa32" 4425 - integrity sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg== 4348 + version "5.3.2" 4349 + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.2.tgz#70ecc7d4d4114921f5d298349ff86a31a9975224" 4350 + integrity sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww== 4426 4351 dependencies: 4427 4352 source-map "~0.6.0" 4428 4353 ··· 4671 4596 safe-buffer "5.2.1" 4672 4597 4673 4598 content-type@~1.0.4: 4674 - version "1.0.4" 4675 - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" 4676 - integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== 4599 + version "1.0.5" 4600 + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" 4601 + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== 4677 4602 4678 4603 convert-source-map@^1.4.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: 4679 4604 version "1.9.0" ··· 4701 4626 integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== 4702 4627 4703 4628 core-js-compat@^3.25.1: 4704 - version "3.27.1" 4705 - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.27.1.tgz#b5695eb25c602d72b1d30cbfba3cb7e5e4cf0a67" 4706 - integrity sha512-Dg91JFeCDA17FKnneN7oCMz4BkQ4TcffkgHP4OWwp9yx3pi7ubqMDXXSacfNak1PQqjc95skyt+YBLHQJnkJwA== 4629 + version "3.28.0" 4630 + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.28.0.tgz#c08456d854608a7264530a2afa281fadf20ecee6" 4631 + integrity sha512-myzPgE7QodMg4nnd3K1TDoES/nADRStM8Gpz0D6nhkwbmwEnE0ZGJgoWsvQ722FR8D7xS0n0LV556RcEicjTyg== 4707 4632 dependencies: 4708 - browserslist "^4.21.4" 4633 + browserslist "^4.21.5" 4709 4634 4710 - core-js-pure@^3.23.3, core-js-pure@^3.25.1: 4711 - version "3.27.1" 4712 - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.27.1.tgz#ede4a6b8440585c7190062757069c01d37a19dca" 4713 - integrity sha512-BS2NHgwwUppfeoqOXqi08mUqS5FiZpuRuJJpKsaME7kJz0xxuk0xkhDdfMIlP/zLa80krBqss1LtD7f889heAw== 4635 + core-js-pure@^3.23.3: 4636 + version "3.28.0" 4637 + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.28.0.tgz#4ef2888475b6c856ef6f5aeef8b4f618b76ad048" 4638 + integrity sha512-DSOVleA9/v3LNj/vFxAPfUHttKTzrB2RXhAPvR5TPXn4vrra3Z2ssytvRyt8eruJwAfwAiFADEbrjcRdcvPLQQ== 4714 4639 4715 4640 core-js@^3.19.2: 4716 - version "3.27.1" 4717 - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.27.1.tgz#23cc909b315a6bb4e418bf40a52758af2103ba46" 4718 - integrity sha512-GutwJLBChfGCpwwhbYoqfv03LAfmiz7e7D/BNxzeMxwQf10GRSzqiOjx7AmtEk+heiD/JWmBuyBPgFtx0Sg1ww== 4641 + version "3.28.0" 4642 + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.28.0.tgz#ed8b9e99c273879fdfff0edfc77ee709a5800e4a" 4643 + integrity sha512-GiZn9D4Z/rSYvTeg1ljAIsEqFm0LaN9gVtwDCrKL80zHtS31p9BAjmTxVqTQDMpwlMolJZOFntUG2uwyj7DAqw== 4719 4644 4720 4645 core-util-is@~1.0.0: 4721 4646 version "1.0.3" ··· 4776 4701 integrity sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw== 4777 4702 dependencies: 4778 4703 node-fetch "2.6.7" 4704 + 4705 + cross-spawn@^4.0.2: 4706 + version "4.0.2" 4707 + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-4.0.2.tgz#7b9247621c23adfdd3856004a823cbe397424d41" 4708 + integrity sha512-yAXz/pA1tD8Gtg2S98Ekf/sewp3Lcp3YoFKJ4Hkp5h5yLWnKVTDU0kwjKJ8NDCYcfTLfyGkzTikst+jWypT1iA== 4709 + dependencies: 4710 + lru-cache "^4.0.1" 4711 + which "^1.2.9" 4779 4712 4780 4713 cross-spawn@^6.0.0: 4781 4714 version "6.0.5" ··· 4923 4856 integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== 4924 4857 4925 4858 cssdb@^7.1.0: 4926 - version "7.2.0" 4927 - resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-7.2.0.tgz#f44bd4abc430f0ff7f4c64b8a1fb857a753f77a8" 4928 - integrity sha512-JYlIsE7eKHSi0UNuCyo96YuIDFqvhGgHw4Ck6lsN+DP0Tp8M64UTDT2trGbkMDqnCoEjks7CkS0XcjU0rkvBdg== 4859 + version "7.4.1" 4860 + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-7.4.1.tgz#61d55c0173126689922a219e15e131e4b5caf422" 4861 + integrity sha512-0Q8NOMpXJ3iTDDbUv9grcmQAfdDx4qz+fN/+Md2FGbevT+6+bJNQ2LjB2YIUlLbpBTM32idU1Sb+tb/uGt6/XQ== 4929 4862 4930 4863 cssesc@^3.0.0: 4931 4864 version "3.0.0" 4932 4865 resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" 4933 4866 integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== 4934 4867 4935 - cssnano-preset-default@^5.2.13: 4936 - version "5.2.13" 4937 - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.13.tgz#e7353b0c57975d1bdd97ac96e68e5c1b8c68e990" 4938 - integrity sha512-PX7sQ4Pb+UtOWuz8A1d+Rbi+WimBIxJTRyBdgGp1J75VU0r/HFQeLnMYgHiCAp6AR4rqrc7Y4R+1Rjk3KJz6DQ== 4868 + cssnano-preset-default@^5.2.14: 4869 + version "5.2.14" 4870 + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz#309def4f7b7e16d71ab2438052093330d9ab45d8" 4871 + integrity sha512-t0SFesj/ZV2OTylqQVOrFgEh5uanxbO6ZAdeCrNsUQ6fVuXwYTxJPNAGvGTxHbD68ldIJNec7PyYZDBrfDQ+6A== 4939 4872 dependencies: 4940 4873 css-declaration-sorter "^6.3.1" 4941 4874 cssnano-utils "^3.1.0" 4942 4875 postcss-calc "^8.2.3" 4943 - postcss-colormin "^5.3.0" 4876 + postcss-colormin "^5.3.1" 4944 4877 postcss-convert-values "^5.1.3" 4945 4878 postcss-discard-comments "^5.1.2" 4946 4879 postcss-discard-duplicates "^5.1.0" 4947 4880 postcss-discard-empty "^5.1.1" 4948 4881 postcss-discard-overridden "^5.1.0" 4949 4882 postcss-merge-longhand "^5.1.7" 4950 - postcss-merge-rules "^5.1.3" 4883 + postcss-merge-rules "^5.1.4" 4951 4884 postcss-minify-font-values "^5.1.0" 4952 4885 postcss-minify-gradients "^5.1.1" 4953 4886 postcss-minify-params "^5.1.4" ··· 4962 4895 postcss-normalize-url "^5.1.0" 4963 4896 postcss-normalize-whitespace "^5.1.1" 4964 4897 postcss-ordered-values "^5.1.3" 4965 - postcss-reduce-initial "^5.1.1" 4898 + postcss-reduce-initial "^5.1.2" 4966 4899 postcss-reduce-transforms "^5.1.0" 4967 4900 postcss-svgo "^5.1.0" 4968 4901 postcss-unique-selectors "^5.1.1" ··· 4973 4906 integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA== 4974 4907 4975 4908 cssnano@^5.0.6: 4976 - version "5.1.14" 4977 - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.14.tgz#07b0af6da73641276fe5a6d45757702ebae2eb05" 4978 - integrity sha512-Oou7ihiTocbKqi0J1bB+TRJIQX5RMR3JghA8hcWSw9mjBLQ5Y3RWqEDoYG3sRNlAbCIXpqMoZGbq5KDR3vdzgw== 4909 + version "5.1.15" 4910 + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.15.tgz#ded66b5480d5127fcb44dac12ea5a983755136bf" 4911 + integrity sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw== 4979 4912 dependencies: 4980 - cssnano-preset-default "^5.2.13" 4913 + cssnano-preset-default "^5.2.14" 4981 4914 lilconfig "^2.0.3" 4982 4915 yaml "^1.10.2" 4983 4916 ··· 5029 4962 resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.7.tgz#4b296922642f70999544d1144a2c25730fce63e2" 5030 4963 integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ== 5031 4964 5032 - debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: 4965 + debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0: 5033 4966 version "2.6.9" 5034 4967 resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" 5035 4968 integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== ··· 5055 4988 resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 5056 4989 integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== 5057 4990 4991 + decamelize@^4.0.0: 4992 + version "4.0.0" 4993 + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" 4994 + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== 4995 + 5058 4996 decimal.js@^10.2.1: 5059 4997 version "10.4.3" 5060 4998 resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" ··· 5077 5015 resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" 5078 5016 integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== 5079 5017 5018 + deep-equal@^2.0.5: 5019 + version "2.2.0" 5020 + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.0.tgz#5caeace9c781028b9ff459f33b779346637c43e6" 5021 + integrity sha512-RdpzE0Hv4lhowpIUKKMJfeH6C1pXdtT1/it80ubgWqwI3qpuxUBpC1S4hnHg+zjnuOoDkzUtUCEEkG+XG5l3Mw== 5022 + dependencies: 5023 + call-bind "^1.0.2" 5024 + es-get-iterator "^1.1.2" 5025 + get-intrinsic "^1.1.3" 5026 + is-arguments "^1.1.1" 5027 + is-array-buffer "^3.0.1" 5028 + is-date-object "^1.0.5" 5029 + is-regex "^1.1.4" 5030 + is-shared-array-buffer "^1.0.2" 5031 + isarray "^2.0.5" 5032 + object-is "^1.1.5" 5033 + object-keys "^1.1.1" 5034 + object.assign "^4.1.4" 5035 + regexp.prototype.flags "^1.4.3" 5036 + side-channel "^1.0.4" 5037 + which-boxed-primitive "^1.0.2" 5038 + which-collection "^1.0.1" 5039 + which-typed-array "^1.1.9" 5040 + 5080 5041 deep-extend@^0.6.0: 5081 5042 version "0.6.0" 5082 5043 resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" ··· 5093 5054 integrity sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA== 5094 5055 5095 5056 deepmerge@^4.2.2: 5096 - version "4.2.2" 5097 - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" 5098 - integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== 5057 + version "4.3.0" 5058 + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.0.tgz#65491893ec47756d44719ae520e0e2609233b59b" 5059 + integrity sha512-z2wJZXrmeHdvYJp/Ux55wIjqo81G5Bp4c+oELTW+7ar6SogWHajt5a9gO3s3IDaGSAXjDk0vlQKN3rms8ab3og== 5099 5060 5100 5061 default-gateway@^6.0.3: 5101 5062 version "6.0.3" ··· 5117 5078 integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== 5118 5079 5119 5080 define-properties@^1.1.3, define-properties@^1.1.4: 5120 - version "1.1.4" 5121 - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" 5122 - integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== 5081 + version "1.2.0" 5082 + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.0.tgz#52988570670c9eacedd8064f4a990f2405849bd5" 5083 + integrity sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA== 5123 5084 dependencies: 5124 5085 has-property-descriptors "^1.0.0" 5125 5086 object-keys "^1.1.1" ··· 5231 5192 defined "^1.0.0" 5232 5193 minimist "^1.2.6" 5233 5194 5195 + detox@^20.1.2: 5196 + version "20.2.0" 5197 + resolved "https://registry.yarnpkg.com/detox/-/detox-20.2.0.tgz#b0662ace6a1bc1f61cbf6c08ce9f748a68831add" 5198 + integrity sha512-br2af9iFkHqpgPe1+ChwQu+/rc/3VPMK31LlQNbdK+x/yeRfR0Rww3BFsmehJF6hD9oFpojtm4siJsX32X3Esw== 5199 + dependencies: 5200 + ajv "^8.6.3" 5201 + bunyan "^1.8.12" 5202 + bunyan-debug-stream "^3.1.0" 5203 + caf "^15.0.1" 5204 + chalk "^2.4.2" 5205 + child-process-promise "^2.2.0" 5206 + find-up "^4.1.0" 5207 + fs-extra "^4.0.2" 5208 + funpermaproxy "^1.1.0" 5209 + glob "^8.0.3" 5210 + ini "^1.3.4" 5211 + json-cycle "^1.3.0" 5212 + lodash "^4.17.11" 5213 + multi-sort-stream "^1.0.3" 5214 + multipipe "^4.0.0" 5215 + node-ipc "^9.2.1" 5216 + proper-lockfile "^3.0.2" 5217 + resolve-from "^5.0.0" 5218 + sanitize-filename "^1.6.1" 5219 + semver "^7.0.0" 5220 + serialize-error "^8.0.1" 5221 + shell-quote "^1.7.2" 5222 + signal-exit "^3.0.3" 5223 + stream-json "^1.7.4" 5224 + strip-ansi "^6.0.1" 5225 + telnet-client "1.2.8" 5226 + tempfile "^2.0.0" 5227 + trace-event-lib "^1.3.1" 5228 + which "^1.3.1" 5229 + ws "^7.0.0" 5230 + yargs "^16.0.3" 5231 + yargs-parser "^20.2.9" 5232 + yargs-unparser "^2.0.0" 5233 + 5234 5234 did-resolver@^4.0.0: 5235 5235 version "4.0.1" 5236 5236 resolved "https://registry.yarnpkg.com/did-resolver/-/did-resolver-4.0.1.tgz#11bb3f19ed1c8f53f4af4702912fa9f7852fc305" ··· 5251 5251 resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" 5252 5252 integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== 5253 5253 5254 - diff-sequences@^29.3.1: 5255 - version "29.3.1" 5256 - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.3.1.tgz#104b5b95fe725932421a9c6e5b4bef84c3f2249e" 5257 - integrity sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ== 5254 + diff-sequences@^29.4.3: 5255 + version "29.4.3" 5256 + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2" 5257 + integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA== 5258 5258 5259 5259 dir-glob@^3.0.1: 5260 5260 version "3.0.1" ··· 5407 5407 resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" 5408 5408 integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== 5409 5409 5410 + dtrace-provider@~0.8: 5411 + version "0.8.8" 5412 + resolved "https://registry.yarnpkg.com/dtrace-provider/-/dtrace-provider-0.8.8.tgz#2996d5490c37e1347be263b423ed7b297fb0d97e" 5413 + integrity sha512-b7Z7cNtHPhH9EJhNNbbeqTcXB8LGFFZhq1PGgEvpeHlzd36bhbdTWoE/Ba/YguqpBSlAPKnARWhVlhunCMwfxg== 5414 + dependencies: 5415 + nan "^2.14.0" 5416 + 5417 + duplexer2@^0.1.2: 5418 + version "0.1.4" 5419 + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" 5420 + integrity sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA== 5421 + dependencies: 5422 + readable-stream "^2.0.2" 5423 + 5410 5424 duplexer@^0.1.2: 5411 5425 version "0.1.2" 5412 5426 resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" 5413 5427 integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== 5428 + 5429 + easy-stack@^1.0.1: 5430 + version "1.0.1" 5431 + resolved "https://registry.yarnpkg.com/easy-stack/-/easy-stack-1.0.1.tgz#8afe4264626988cabb11f3c704ccd0c835411066" 5432 + integrity sha512-wK2sCs4feiiJeFXn3zvY0p41mdU5VUgbgs1rNsc/y5ngFUijdWd+iIN8eoyuZHKB8xN6BL4PdWmzqFmxNg6V2w== 5414 5433 5415 5434 ecdsa-sig-formatter@1.0.11: 5416 5435 version "1.0.11" ··· 5431 5450 dependencies: 5432 5451 jake "^10.8.5" 5433 5452 5434 - electron-to-chromium@^1.4.251: 5435 - version "1.4.284" 5436 - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz#61046d1e4cab3a25238f6bf7413795270f125592" 5437 - integrity sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA== 5453 + electron-to-chromium@^1.4.284: 5454 + version "1.4.306" 5455 + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.306.tgz#3f16bc14e150ad79803145fffeaf0bee15d3fca7" 5456 + integrity sha512-1zGmLFfpcs2v7ELt/1HgLZF6Gm2CCHaAdNKxd9Ge4INSU/HDYWjs7fcWU6eVMmhkpwmh+52ZrGCUU+Ji9OJihA== 5438 5457 5439 5458 email-validator@^2.0.4: 5440 5459 version "2.0.4" ··· 5529 5548 escape-html "~1.0.3" 5530 5549 5531 5550 es-abstract@^1.17.2, es-abstract@^1.19.0, es-abstract@^1.20.4: 5532 - version "1.20.5" 5533 - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.5.tgz#e6dc99177be37cacda5988e692c3fa8b218e95d2" 5534 - integrity sha512-7h8MM2EQhsCA7pU/Nv78qOXFpD8Rhqd12gYiSJVkrH9+e8VuA8JlPJK/hQjjlLv6pJvx/z1iRFKzYb0XT/RuAQ== 5551 + version "1.21.1" 5552 + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.1.tgz#e6105a099967c08377830a0c9cb589d570dd86c6" 5553 + integrity sha512-QudMsPOz86xYz/1dG1OuGBKOELjCh99IIWHLzy5znUB6j8xG2yMA7bfTV86VSqKF+Y/H08vQPR+9jyXpuC6hfg== 5535 5554 dependencies: 5555 + available-typed-arrays "^1.0.5" 5536 5556 call-bind "^1.0.2" 5557 + es-set-tostringtag "^2.0.1" 5537 5558 es-to-primitive "^1.2.1" 5538 5559 function-bind "^1.1.1" 5539 5560 function.prototype.name "^1.1.5" 5540 5561 get-intrinsic "^1.1.3" 5541 5562 get-symbol-description "^1.0.0" 5563 + globalthis "^1.0.3" 5542 5564 gopd "^1.0.1" 5543 5565 has "^1.0.3" 5544 5566 has-property-descriptors "^1.0.0" 5567 + has-proto "^1.0.1" 5545 5568 has-symbols "^1.0.3" 5546 - internal-slot "^1.0.3" 5569 + internal-slot "^1.0.4" 5570 + is-array-buffer "^3.0.1" 5547 5571 is-callable "^1.2.7" 5548 5572 is-negative-zero "^2.0.2" 5549 5573 is-regex "^1.1.4" 5550 5574 is-shared-array-buffer "^1.0.2" 5551 5575 is-string "^1.0.7" 5576 + is-typed-array "^1.1.10" 5552 5577 is-weakref "^1.0.2" 5553 5578 object-inspect "^1.12.2" 5554 5579 object-keys "^1.1.1" ··· 5557 5582 safe-regex-test "^1.0.0" 5558 5583 string.prototype.trimend "^1.0.6" 5559 5584 string.prototype.trimstart "^1.0.6" 5585 + typed-array-length "^1.0.4" 5560 5586 unbox-primitive "^1.0.2" 5587 + which-typed-array "^1.1.9" 5561 5588 5562 5589 es-array-method-boxes-properly@^1.0.0: 5563 5590 version "1.0.0" 5564 5591 resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" 5565 5592 integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== 5566 5593 5567 - es-get-iterator@^1.0.2: 5594 + es-get-iterator@^1.1.2: 5568 5595 version "1.1.3" 5569 5596 resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6" 5570 5597 integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== ··· 5584 5611 resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" 5585 5612 integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== 5586 5613 5614 + es-set-tostringtag@^2.0.1: 5615 + version "2.0.1" 5616 + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" 5617 + integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== 5618 + dependencies: 5619 + get-intrinsic "^1.1.3" 5620 + has "^1.0.3" 5621 + has-tostringtag "^1.0.0" 5622 + 5587 5623 es-shim-unscopables@^1.0.0: 5588 5624 version "1.0.0" 5589 5625 resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" ··· 5609 5645 version "1.0.3" 5610 5646 resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" 5611 5647 integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== 5648 + 5649 + escape-string-regexp@2.0.0, escape-string-regexp@^2.0.0: 5650 + version "2.0.0" 5651 + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" 5652 + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== 5612 5653 5613 5654 escape-string-regexp@^1.0.5: 5614 5655 version "1.0.5" 5615 5656 resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" 5616 5657 integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== 5617 5658 5618 - escape-string-regexp@^2.0.0: 5619 - version "2.0.0" 5620 - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" 5621 - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== 5622 - 5623 5659 escape-string-regexp@^4.0.0: 5624 5660 version "4.0.0" 5625 5661 resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" ··· 5662 5698 eslint-plugin-react-hooks "^4.3.0" 5663 5699 eslint-plugin-testing-library "^5.0.1" 5664 5700 5665 - eslint-import-resolver-node@^0.3.6: 5666 - version "0.3.6" 5667 - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz#4048b958395da89668252001dbd9eca6b83bacbd" 5668 - integrity sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw== 5701 + eslint-import-resolver-node@^0.3.7: 5702 + version "0.3.7" 5703 + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz#83b375187d412324a1963d84fa664377a23eb4d7" 5704 + integrity sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA== 5669 5705 dependencies: 5670 5706 debug "^3.2.7" 5671 - resolve "^1.20.0" 5707 + is-core-module "^2.11.0" 5708 + resolve "^1.22.1" 5672 5709 5673 - eslint-module-utils@^2.7.3: 5710 + eslint-module-utils@^2.7.4: 5674 5711 version "2.7.4" 5675 5712 resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz#4f3e41116aaf13a20792261e61d3a2e7e0583974" 5676 5713 integrity sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA== 5677 5714 dependencies: 5678 5715 debug "^3.2.7" 5716 + 5717 + eslint-plugin-detox@^1.0.0: 5718 + version "1.0.0" 5719 + resolved "https://registry.yarnpkg.com/eslint-plugin-detox/-/eslint-plugin-detox-1.0.0.tgz#2d9c0130e8ebc4ced56efb6eeaf0d0f5c163398d" 5720 + integrity sha512-Dd+Cwyap5IO9DBKXOKrQTE1RQk9hvSSi+qsS1cMVPZY37mojz2PvriEOfGhKj5XN1G14lJ8TArf+6Y+Np2ZsoQ== 5721 + dependencies: 5722 + requireindex "~1.1.0" 5679 5723 5680 5724 eslint-plugin-eslint-comments@^3.2.0: 5681 5725 version "3.2.0" ··· 5693 5737 lodash "^4.17.21" 5694 5738 string-natural-compare "^3.0.1" 5695 5739 5696 - eslint-plugin-ft-flow@^2.0.1: 5740 + eslint-plugin-ft-flow@^2.0.1, eslint-plugin-ft-flow@^2.0.3: 5697 5741 version "2.0.3" 5698 5742 resolved "https://registry.yarnpkg.com/eslint-plugin-ft-flow/-/eslint-plugin-ft-flow-2.0.3.tgz#3b3c113c41902bcbacf0e22b536debcfc3c819e8" 5699 5743 integrity sha512-Vbsd/b+LYA99jUbsL6viEUWShFaYQt2YQs3QN3f+aeszOhh2sgdcU0mjzDyD4yyBvMc8qy2uwvBBWfMzEX06tg== ··· 5702 5746 string-natural-compare "^3.0.1" 5703 5747 5704 5748 eslint-plugin-import@^2.25.3: 5705 - version "2.26.0" 5706 - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz#f812dc47be4f2b72b478a021605a59fc6fe8b88b" 5707 - integrity sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA== 5749 + version "2.27.5" 5750 + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz#876a6d03f52608a3e5bb439c2550588e51dd6c65" 5751 + integrity sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow== 5708 5752 dependencies: 5709 - array-includes "^3.1.4" 5710 - array.prototype.flat "^1.2.5" 5711 - debug "^2.6.9" 5753 + array-includes "^3.1.6" 5754 + array.prototype.flat "^1.3.1" 5755 + array.prototype.flatmap "^1.3.1" 5756 + debug "^3.2.7" 5712 5757 doctrine "^2.1.0" 5713 - eslint-import-resolver-node "^0.3.6" 5714 - eslint-module-utils "^2.7.3" 5758 + eslint-import-resolver-node "^0.3.7" 5759 + eslint-module-utils "^2.7.4" 5715 5760 has "^1.0.3" 5716 - is-core-module "^2.8.1" 5761 + is-core-module "^2.11.0" 5717 5762 is-glob "^4.0.3" 5718 5763 minimatch "^3.1.2" 5719 - object.values "^1.1.5" 5720 - resolve "^1.22.0" 5764 + object.values "^1.1.6" 5765 + resolve "^1.22.1" 5766 + semver "^6.3.0" 5721 5767 tsconfig-paths "^3.14.1" 5722 5768 5723 5769 eslint-plugin-jest@^25.3.0: ··· 5735 5781 "@typescript-eslint/utils" "^5.10.0" 5736 5782 5737 5783 eslint-plugin-jsx-a11y@^6.5.1: 5738 - version "6.6.1" 5739 - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz#93736fc91b83fdc38cc8d115deedfc3091aef1ff" 5740 - integrity sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q== 5784 + version "6.7.1" 5785 + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz#fca5e02d115f48c9a597a6894d5bcec2f7a76976" 5786 + integrity sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA== 5741 5787 dependencies: 5742 - "@babel/runtime" "^7.18.9" 5743 - aria-query "^4.2.2" 5744 - array-includes "^3.1.5" 5788 + "@babel/runtime" "^7.20.7" 5789 + aria-query "^5.1.3" 5790 + array-includes "^3.1.6" 5791 + array.prototype.flatmap "^1.3.1" 5745 5792 ast-types-flow "^0.0.7" 5746 - axe-core "^4.4.3" 5747 - axobject-query "^2.2.0" 5793 + axe-core "^4.6.2" 5794 + axobject-query "^3.1.1" 5748 5795 damerau-levenshtein "^1.0.8" 5749 5796 emoji-regex "^9.2.2" 5750 5797 has "^1.0.3" 5751 - jsx-ast-utils "^3.3.2" 5752 - language-tags "^1.0.5" 5798 + jsx-ast-utils "^3.3.3" 5799 + language-tags "=1.0.5" 5753 5800 minimatch "^3.1.2" 5801 + object.entries "^1.1.6" 5802 + object.fromentries "^2.0.6" 5754 5803 semver "^6.3.0" 5755 5804 5756 5805 eslint-plugin-prettier@^4.2.1: ··· 5778 5827 "@babel/traverse" "^7.7.4" 5779 5828 eslint-plugin-react-native-globals "^0.1.1" 5780 5829 5781 - eslint-plugin-react@^7.27.1: 5782 - version "7.31.11" 5783 - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz#011521d2b16dcf95795df688a4770b4eaab364c8" 5784 - integrity sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw== 5785 - dependencies: 5786 - array-includes "^3.1.6" 5787 - array.prototype.flatmap "^1.3.1" 5788 - array.prototype.tosorted "^1.1.1" 5789 - doctrine "^2.1.0" 5790 - estraverse "^5.3.0" 5791 - jsx-ast-utils "^2.4.1 || ^3.0.0" 5792 - minimatch "^3.1.2" 5793 - object.entries "^1.1.6" 5794 - object.fromentries "^2.0.6" 5795 - object.hasown "^1.1.2" 5796 - object.values "^1.1.6" 5797 - prop-types "^15.8.1" 5798 - resolve "^2.0.0-next.3" 5799 - semver "^6.3.0" 5800 - string.prototype.matchall "^4.0.8" 5801 - 5802 - eslint-plugin-react@^7.30.1: 5803 - version "7.32.1" 5804 - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.32.1.tgz#88cdeb4065da8ca0b64e1274404f53a0f9890200" 5805 - integrity sha512-vOjdgyd0ZHBXNsmvU+785xY8Bfe57EFbTYYk8XrROzWpr9QBvpjITvAXt9xqcE6+8cjR/g1+mfumPToxsl1www== 5830 + eslint-plugin-react@^7.27.1, eslint-plugin-react@^7.30.1: 5831 + version "7.32.2" 5832 + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz#e71f21c7c265ebce01bcbc9d0955170c55571f10" 5833 + integrity sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg== 5806 5834 dependencies: 5807 5835 array-includes "^3.1.6" 5808 5836 array.prototype.flatmap "^1.3.1" ··· 5821 5849 string.prototype.matchall "^4.0.8" 5822 5850 5823 5851 eslint-plugin-testing-library@^5.0.1: 5824 - version "5.9.1" 5825 - resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.9.1.tgz#12e4bd34c48683ee98af4df2e3318ec9f51dcf8a" 5826 - integrity sha512-6BQp3tmb79jLLasPHJmy8DnxREe+2Pgf7L+7o09TSWPfdqqtQfRZmZNetr5mOs3yqZk/MRNxpN3RUpJe0wB4LQ== 5852 + version "5.10.2" 5853 + resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.10.2.tgz#12f231ad9b52b6aef45c801fd00aa129a932e0c2" 5854 + integrity sha512-f1DmDWcz5SDM+IpCkEX0lbFqrrTs8HRsEElzDEqN/EBI0hpRj8Cns5+IVANXswE8/LeybIJqPAOQIFu2j5Y5sw== 5827 5855 dependencies: 5828 - "@typescript-eslint/utils" "^5.13.0" 5856 + "@typescript-eslint/utils" "^5.43.0" 5829 5857 5830 5858 eslint-scope@5.1.1, eslint-scope@^5.1.1: 5831 5859 version "5.1.1" ··· 5871 5899 normalize-path "^3.0.0" 5872 5900 schema-utils "^4.0.0" 5873 5901 5874 - eslint@^8.19.0: 5875 - version "8.32.0" 5876 - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.32.0.tgz#d9690056bb6f1a302bd991e7090f5b68fbaea861" 5877 - integrity sha512-nETVXpnthqKPFyuY2FNjz/bEd6nbosRgKbkgS/y1C7LJop96gYHWpiguLecMHQ2XCPxn77DS0P+68WzG6vkZSQ== 5878 - dependencies: 5879 - "@eslint/eslintrc" "^1.4.1" 5880 - "@humanwhocodes/config-array" "^0.11.8" 5881 - "@humanwhocodes/module-importer" "^1.0.1" 5882 - "@nodelib/fs.walk" "^1.2.8" 5883 - ajv "^6.10.0" 5884 - chalk "^4.0.0" 5885 - cross-spawn "^7.0.2" 5886 - debug "^4.3.2" 5887 - doctrine "^3.0.0" 5888 - escape-string-regexp "^4.0.0" 5889 - eslint-scope "^7.1.1" 5890 - eslint-utils "^3.0.0" 5891 - eslint-visitor-keys "^3.3.0" 5892 - espree "^9.4.0" 5893 - esquery "^1.4.0" 5894 - esutils "^2.0.2" 5895 - fast-deep-equal "^3.1.3" 5896 - file-entry-cache "^6.0.1" 5897 - find-up "^5.0.0" 5898 - glob-parent "^6.0.2" 5899 - globals "^13.19.0" 5900 - grapheme-splitter "^1.0.4" 5901 - ignore "^5.2.0" 5902 - import-fresh "^3.0.0" 5903 - imurmurhash "^0.1.4" 5904 - is-glob "^4.0.0" 5905 - is-path-inside "^3.0.3" 5906 - js-sdsl "^4.1.4" 5907 - js-yaml "^4.1.0" 5908 - json-stable-stringify-without-jsonify "^1.0.1" 5909 - levn "^0.4.1" 5910 - lodash.merge "^4.6.2" 5911 - minimatch "^3.1.2" 5912 - natural-compare "^1.4.0" 5913 - optionator "^0.9.1" 5914 - regexpp "^3.2.0" 5915 - strip-ansi "^6.0.1" 5916 - strip-json-comments "^3.1.0" 5917 - text-table "^0.2.0" 5918 - 5919 - eslint@^8.3.0: 5920 - version "8.31.0" 5921 - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.31.0.tgz#75028e77cbcff102a9feae1d718135931532d524" 5922 - integrity sha512-0tQQEVdmPZ1UtUKXjX7EMm9BlgJ08G90IhWh0PKDCb3ZLsgAOHI8fYSIzYVZej92zsgq+ft0FGsxhJ3xo2tbuA== 5902 + eslint@^8.19.0, eslint@^8.3.0: 5903 + version "8.34.0" 5904 + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.34.0.tgz#fe0ab0ef478104c1f9ebc5537e303d25a8fb22d6" 5905 + integrity sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg== 5923 5906 dependencies: 5924 5907 "@eslint/eslintrc" "^1.4.1" 5925 5908 "@humanwhocodes/config-array" "^0.11.8" ··· 5976 5959 integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== 5977 5960 5978 5961 esquery@^1.4.0: 5979 - version "1.4.0" 5980 - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" 5981 - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== 5962 + version "1.4.2" 5963 + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.2.tgz#c6d3fee05dd665808e2ad870631f221f5617b1d1" 5964 + integrity sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng== 5982 5965 dependencies: 5983 5966 estraverse "^5.1.0" 5984 5967 ··· 6014 5997 resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" 6015 5998 integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== 6016 5999 6000 + event-pubsub@4.3.0: 6001 + version "4.3.0" 6002 + resolved "https://registry.yarnpkg.com/event-pubsub/-/event-pubsub-4.3.0.tgz#f68d816bc29f1ec02c539dc58c8dd40ce72cb36e" 6003 + integrity sha512-z7IyloorXvKbFx9Bpie2+vMJKKx1fH1EN5yiTfp8CiLOTptSYy1g8H4yDpGlEdshL1PBiFtBHepF2cNsqeEeFQ== 6004 + 6017 6005 event-target-shim@^5.0.0, event-target-shim@^5.0.1: 6018 6006 version "5.0.1" 6019 6007 resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" ··· 6090 6078 jest-matcher-utils "^27.5.1" 6091 6079 jest-message-util "^27.5.1" 6092 6080 6093 - expect@^29.3.1: 6094 - version "29.3.1" 6095 - resolved "https://registry.yarnpkg.com/expect/-/expect-29.3.1.tgz#92877aad3f7deefc2e3f6430dd195b92295554a6" 6096 - integrity sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA== 6081 + expect@^29.4.3: 6082 + version "29.4.3" 6083 + resolved "https://registry.yarnpkg.com/expect/-/expect-29.4.3.tgz#5e47757316df744fe3b8926c3ae8a3ebdafff7fe" 6084 + integrity sha512-uC05+Q7eXECFpgDrHdXA4k2rpMyStAYPItEDLyQDo5Ta7fVkJnNA/4zh/OIVkVVNZ1oOK1PipQoyNjuZ6sz6Dg== 6097 6085 dependencies: 6098 - "@jest/expect-utils" "^29.3.1" 6099 - jest-get-type "^29.2.0" 6100 - jest-matcher-utils "^29.3.1" 6101 - jest-message-util "^29.3.1" 6102 - jest-util "^29.3.1" 6086 + "@jest/expect-utils" "^29.4.3" 6087 + jest-get-type "^29.4.3" 6088 + jest-matcher-utils "^29.4.3" 6089 + jest-message-util "^29.4.3" 6090 + jest-util "^29.4.3" 6103 6091 6104 6092 express-async-errors@^3.1.1: 6105 6093 version "3.1.1" ··· 6230 6218 resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.1.2.tgz#d58e69e9084ce9fa4c1a6fa98a3e1ecf5d7839aa" 6231 6219 integrity sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw== 6232 6220 6233 - fast-url-parser@^1.1.3: 6234 - version "1.1.3" 6235 - resolved "https://registry.yarnpkg.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d" 6236 - integrity sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ== 6221 + fast-xml-parser@^4.0.12: 6222 + version "4.1.2" 6223 + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-4.1.2.tgz#5a98c18238d28a57bbdfa9fe4cda01211fff8f4a" 6224 + integrity sha512-CDYeykkle1LiA/uqQyNwYpFbyF6Axec6YapmpUP+/RHWIoR1zKjocdvNaTsxCxZzQ6v9MLXaSYm9Qq0thv0DHg== 6237 6225 dependencies: 6238 - punycode "^1.3.2" 6226 + strnum "^1.0.5" 6239 6227 6240 6228 fastest-levenshtein@^1.0.12: 6241 6229 version "1.0.16" ··· 6422 6410 flatted "^3.1.0" 6423 6411 rimraf "^3.0.2" 6424 6412 6413 + flat@^5.0.2: 6414 + version "5.0.2" 6415 + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" 6416 + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== 6417 + 6425 6418 flatted@^3.1.0: 6426 6419 version "3.2.7" 6427 6420 resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.7.tgz#609f39207cb614b89d0765b477cb2d437fbf9787" 6428 6421 integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== 6429 6422 6430 6423 flow-parser@0.*: 6431 - version "0.196.3" 6432 - resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.196.3.tgz#dd923f29a6c194770a4f999f8026ef1da79d428b" 6433 - integrity sha512-R8wj12eHW6og+IBWeRS6aihkdac1Prh4zw1bfxtt/aeu8r5OFmQEZjnmINcjO/5Q+OKvI4Eg367ygz2SHvtH+w== 6424 + version "0.200.0" 6425 + resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.200.0.tgz#7cbdd4cace2843e2fd6098df68247b3876f55917" 6426 + integrity sha512-01eYYVlCEO2p6JexhTbMbDNPeDKQZV++SJbaHE/HzypTkV83oJmsJQVjVCGD8FYWiQ3ha9ALD/AHwsFhPwnZJA== 6434 6427 6435 6428 flow-parser@^0.185.0: 6436 6429 version "0.185.2" ··· 6441 6434 version "1.15.2" 6442 6435 resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" 6443 6436 integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== 6437 + 6438 + for-each@^0.3.3: 6439 + version "0.3.3" 6440 + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" 6441 + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== 6442 + dependencies: 6443 + is-callable "^1.1.3" 6444 6444 6445 6445 for-in@^1.0.2: 6446 6446 version "1.0.2" ··· 6520 6520 jsonfile "^6.0.1" 6521 6521 universalify "^2.0.0" 6522 6522 6523 + fs-extra@^4.0.2: 6524 + version "4.0.3" 6525 + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.3.tgz#0d852122e5bc5beb453fb028e9c0c9bf36340c94" 6526 + integrity sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg== 6527 + dependencies: 6528 + graceful-fs "^4.1.2" 6529 + jsonfile "^4.0.0" 6530 + universalify "^0.1.0" 6531 + 6523 6532 fs-extra@^8.1.0: 6524 6533 version "8.1.0" 6525 6534 resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-8.1.0.tgz#49d43c45a88cd9677668cb7be1b46efdb8d2e1c0" ··· 6573 6582 version "1.2.3" 6574 6583 resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" 6575 6584 integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== 6585 + 6586 + funpermaproxy@^1.1.0: 6587 + version "1.1.0" 6588 + resolved "https://registry.yarnpkg.com/funpermaproxy/-/funpermaproxy-1.1.0.tgz#39cb0b8bea908051e4608d8a414f1d87b55bf557" 6589 + integrity sha512-2Sp1hWuO8m5fqeFDusyhKqYPT+7rGLw34N3qonDcdRP8+n7M7Gl/yKp/q7oCxnnJ6pWCectOmLFJpsMU/++KrQ== 6576 6590 6577 6591 gensync@^1.0.0-beta.2: 6578 6592 version "1.0.0-beta.2" ··· 6584 6598 resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 6585 6599 integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 6586 6600 6587 - get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3: 6588 - version "1.1.3" 6589 - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.3.tgz#063c84329ad93e83893c7f4f243ef63ffa351385" 6590 - integrity sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A== 6601 + get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0: 6602 + version "1.2.0" 6603 + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.0.tgz#7ad1dc0535f3a2904bba075772763e5051f6d05f" 6604 + integrity sha512-L049y6nFOuom5wGyRc3/gdTLO94dySVKRACj1RmJZBQXlbTMhtNIgkWkUHq+jYmZvKf14EW1EoJnnjbmoHij0Q== 6591 6605 dependencies: 6592 6606 function-bind "^1.1.1" 6593 6607 has "^1.0.3" ··· 6664 6678 once "^1.3.0" 6665 6679 path-is-absolute "^1.0.0" 6666 6680 6681 + glob@^6.0.1: 6682 + version "6.0.4" 6683 + resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22" 6684 + integrity sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A== 6685 + dependencies: 6686 + inflight "^1.0.4" 6687 + inherits "2" 6688 + minimatch "2 || 3" 6689 + once "^1.3.0" 6690 + path-is-absolute "^1.0.0" 6691 + 6667 6692 glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: 6668 6693 version "7.2.3" 6669 6694 resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" ··· 6709 6734 integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== 6710 6735 6711 6736 globals@^13.19.0: 6712 - version "13.19.0" 6713 - resolved "https://registry.yarnpkg.com/globals/-/globals-13.19.0.tgz#7a42de8e6ad4f7242fbcca27ea5b23aca367b5c8" 6714 - integrity sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ== 6737 + version "13.20.0" 6738 + resolved "https://registry.yarnpkg.com/globals/-/globals-13.20.0.tgz#ea276a1e508ffd4f1612888f9d1bad1e2717bf82" 6739 + integrity sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ== 6715 6740 dependencies: 6716 6741 type-fest "^0.20.2" 6717 6742 6718 - globalthis@^1.0.2: 6743 + globalthis@^1.0.2, globalthis@^1.0.3: 6719 6744 version "1.0.3" 6720 6745 resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" 6721 6746 integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== ··· 6801 6826 integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== 6802 6827 dependencies: 6803 6828 get-intrinsic "^1.1.1" 6829 + 6830 + has-proto@^1.0.1: 6831 + version "1.0.1" 6832 + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" 6833 + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== 6804 6834 6805 6835 has-symbols@^1.0.1, has-symbols@^1.0.2, has-symbols@^1.0.3: 6806 6836 version "1.0.3" ··· 7099 7129 integrity sha512-47xSUiQioGaB96nqtp5/q55m0aBQSQdyIloMOc/x+QVTDZLNmXE892IIDrJ0hM1A5vcNUDD5tDffkSP5lCaIIA== 7100 7130 7101 7131 immer@^9.0.7: 7102 - version "9.0.17" 7103 - resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.17.tgz#7cfe8fbb8b461096444e9da7a5ec4a67c6c4adf4" 7104 - integrity sha512-+hBruaLSQvkPfxRiTLK/mi4vLH+/VQS6z2KJahdoxlleFOI8ARqzOF17uy12eFDlqWmPoygwc5evgwcp+dlHhg== 7132 + version "9.0.19" 7133 + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.19.tgz#67fb97310555690b5f9cd8380d38fc0aabb6b38b" 7134 + integrity sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ== 7105 7135 7106 7136 import-fresh@^2.0.0: 7107 7137 version "2.0.0" ··· 7155 7185 resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" 7156 7186 integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== 7157 7187 7158 - ini@^1.3.5, ini@~1.3.0: 7188 + ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: 7159 7189 version "1.3.8" 7160 7190 resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" 7161 7191 integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== ··· 7169 7199 fast-loops "^1.1.3" 7170 7200 7171 7201 internal-slot@^1.0.3, internal-slot@^1.0.4: 7172 - version "1.0.4" 7173 - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.4.tgz#8551e7baf74a7a6ba5f749cfb16aa60722f0d6f3" 7174 - integrity sha512-tA8URYccNzMo94s5MQZgH8NB/XTa6HsOo0MLfXTKKEnHVVdegzaQoFZ7Jp44bdvLvY2waT5dc+j5ICEswhi7UQ== 7202 + version "1.0.5" 7203 + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" 7204 + integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== 7175 7205 dependencies: 7176 - get-intrinsic "^1.1.3" 7206 + get-intrinsic "^1.2.0" 7177 7207 has "^1.0.3" 7178 7208 side-channel "^1.0.4" 7179 7209 ··· 7182 7212 resolved "https://registry.yarnpkg.com/interpret/-/interpret-3.1.1.tgz#5be0ceed67ca79c6c4bc5cf0d7ee843dcea110c4" 7183 7213 integrity sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ== 7184 7214 7185 - invariant@*, invariant@^2.2.4: 7215 + invariant@*, invariant@2.2.4, invariant@^2.2.4: 7186 7216 version "2.2.4" 7187 7217 resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" 7188 7218 integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== ··· 7226 7256 call-bind "^1.0.2" 7227 7257 has-tostringtag "^1.0.0" 7228 7258 7259 + is-array-buffer@^3.0.1: 7260 + version "3.0.1" 7261 + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.1.tgz#deb1db4fcae48308d54ef2442706c0393997052a" 7262 + integrity sha512-ASfLknmY8Xa2XtB4wmbz13Wu202baeA18cJBCeCy0wXUHZF0IPyVEXqKEcd+t2fNSLLL1vC6k7lxZEojNbISXQ== 7263 + dependencies: 7264 + call-bind "^1.0.2" 7265 + get-intrinsic "^1.1.3" 7266 + is-typed-array "^1.1.10" 7267 + 7229 7268 is-arrayish@^0.2.1: 7230 7269 version "0.2.1" 7231 7270 resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" ··· 7263 7302 resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" 7264 7303 integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== 7265 7304 7266 - is-callable@^1.1.4, is-callable@^1.2.7: 7305 + is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: 7267 7306 version "1.2.7" 7268 7307 resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" 7269 7308 integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== 7270 7309 7271 - is-core-module@^2.8.1, is-core-module@^2.9.0: 7310 + is-core-module@^2.11.0, is-core-module@^2.9.0: 7272 7311 version "2.11.0" 7273 7312 resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144" 7274 7313 integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw== ··· 7289 7328 dependencies: 7290 7329 kind-of "^6.0.0" 7291 7330 7292 - is-date-object@^1.0.1: 7331 + is-date-object@^1.0.1, is-date-object@^1.0.5: 7293 7332 version "1.0.5" 7294 7333 resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" 7295 7334 integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== ··· 7368 7407 resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" 7369 7408 integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== 7370 7409 7371 - is-map@^2.0.2: 7410 + is-map@^2.0.1, is-map@^2.0.2: 7372 7411 version "2.0.2" 7373 7412 resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" 7374 7413 integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== ··· 7452 7491 resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" 7453 7492 integrity sha512-AGOriNp96vNBd3HtU+RzFEc75FfR5ymiYv8E553I71SCeXBiMsVDUtdio1OEFvrPyLIQ9tVR5RxXIFe5PUFjMg== 7454 7493 7455 - is-set@^2.0.2: 7494 + is-set@^2.0.1, is-set@^2.0.2: 7456 7495 version "2.0.2" 7457 7496 resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" 7458 7497 integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== ··· 7488 7527 dependencies: 7489 7528 has-symbols "^1.0.2" 7490 7529 7530 + is-typed-array@^1.1.10, is-typed-array@^1.1.9: 7531 + version "1.1.10" 7532 + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" 7533 + integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== 7534 + dependencies: 7535 + available-typed-arrays "^1.0.5" 7536 + call-bind "^1.0.2" 7537 + for-each "^0.3.3" 7538 + gopd "^1.0.1" 7539 + has-tostringtag "^1.0.0" 7540 + 7491 7541 is-typedarray@^1.0.0: 7492 7542 version "1.0.0" 7493 7543 resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" ··· 7497 7547 version "0.1.0" 7498 7548 resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" 7499 7549 integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== 7550 + 7551 + is-weakmap@^2.0.1: 7552 + version "2.0.1" 7553 + resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" 7554 + integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== 7500 7555 7501 7556 is-weakref@^1.0.2: 7502 7557 version "1.0.2" ··· 7505 7560 dependencies: 7506 7561 call-bind "^1.0.2" 7507 7562 7563 + is-weakset@^2.0.1: 7564 + version "2.0.2" 7565 + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.2.tgz#4569d67a747a1ce5a994dfd4ef6dcea76e7c0a1d" 7566 + integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== 7567 + dependencies: 7568 + call-bind "^1.0.2" 7569 + get-intrinsic "^1.1.1" 7570 + 7508 7571 is-windows@^1.0.2: 7509 7572 version "1.0.2" 7510 7573 resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" ··· 7596 7659 html-escaper "^2.0.0" 7597 7660 istanbul-lib-report "^3.0.0" 7598 7661 7599 - iterate-iterator@^1.0.1: 7600 - version "1.0.2" 7601 - resolved "https://registry.yarnpkg.com/iterate-iterator/-/iterate-iterator-1.0.2.tgz#551b804c9eaa15b847ea6a7cdc2f5bf1ec150f91" 7602 - integrity sha512-t91HubM4ZDQ70M9wqp+pcNpu8OyJ9UAtXntT/Bcsvp5tZMnz9vRa+IunKXeI8AnfZMTv0jNuVEmGeLSMjVvfPw== 7603 - 7604 - iterate-value@^1.0.2: 7605 - version "1.0.2" 7606 - resolved "https://registry.yarnpkg.com/iterate-value/-/iterate-value-1.0.2.tgz#935115bd37d006a52046535ebc8d07e9c9337f57" 7607 - integrity sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ== 7608 - dependencies: 7609 - es-get-iterator "^1.0.2" 7610 - iterate-iterator "^1.0.1" 7611 - 7612 7662 jake@^10.8.5: 7613 7663 version "10.8.5" 7614 7664 resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46" ··· 7628 7678 execa "^5.0.0" 7629 7679 throat "^6.0.1" 7630 7680 7631 - jest-changed-files@^29.2.0: 7632 - version "29.2.0" 7633 - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.2.0.tgz#b6598daa9803ea6a4dce7968e20ab380ddbee289" 7634 - integrity sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA== 7681 + jest-changed-files@^29.4.3: 7682 + version "29.4.3" 7683 + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.4.3.tgz#7961fe32536b9b6d5c28dfa0abcfab31abcf50a7" 7684 + integrity sha512-Vn5cLuWuwmi2GNNbokPOEcvrXGSGrqVnPEZV7rC6P7ck07Dyw9RFnvWglnupSh+hGys0ajGtw/bc2ZgweljQoQ== 7635 7685 dependencies: 7636 7686 execa "^5.0.0" 7637 7687 p-limit "^3.1.0" ··· 7661 7711 stack-utils "^2.0.3" 7662 7712 throat "^6.0.1" 7663 7713 7664 - jest-circus@^29.3.1: 7665 - version "29.3.1" 7666 - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.3.1.tgz#177d07c5c0beae8ef2937a67de68f1e17bbf1b4a" 7667 - integrity sha512-wpr26sEvwb3qQQbdlmei+gzp6yoSSoSL6GsLPxnuayZSMrSd5Ka7IjAvatpIernBvT2+Ic6RLTg+jSebScmasg== 7714 + jest-circus@^29.4.3: 7715 + version "29.4.3" 7716 + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.4.3.tgz#fff7be1cf5f06224dd36a857d52a9efeb005ba04" 7717 + integrity sha512-Vw/bVvcexmdJ7MLmgdT3ZjkJ3LKu8IlpefYokxiqoZy6OCQ2VAm6Vk3t/qHiAGUXbdbJKJWnc8gH3ypTbB/OBw== 7668 7718 dependencies: 7669 - "@jest/environment" "^29.3.1" 7670 - "@jest/expect" "^29.3.1" 7671 - "@jest/test-result" "^29.3.1" 7672 - "@jest/types" "^29.3.1" 7719 + "@jest/environment" "^29.4.3" 7720 + "@jest/expect" "^29.4.3" 7721 + "@jest/test-result" "^29.4.3" 7722 + "@jest/types" "^29.4.3" 7673 7723 "@types/node" "*" 7674 7724 chalk "^4.0.0" 7675 7725 co "^4.6.0" 7676 7726 dedent "^0.7.0" 7677 7727 is-generator-fn "^2.0.0" 7678 - jest-each "^29.3.1" 7679 - jest-matcher-utils "^29.3.1" 7680 - jest-message-util "^29.3.1" 7681 - jest-runtime "^29.3.1" 7682 - jest-snapshot "^29.3.1" 7683 - jest-util "^29.3.1" 7728 + jest-each "^29.4.3" 7729 + jest-matcher-utils "^29.4.3" 7730 + jest-message-util "^29.4.3" 7731 + jest-runtime "^29.4.3" 7732 + jest-snapshot "^29.4.3" 7733 + jest-util "^29.4.3" 7684 7734 p-limit "^3.1.0" 7685 - pretty-format "^29.3.1" 7735 + pretty-format "^29.4.3" 7686 7736 slash "^3.0.0" 7687 7737 stack-utils "^2.0.3" 7688 7738 ··· 7704 7754 prompts "^2.0.1" 7705 7755 yargs "^16.2.0" 7706 7756 7707 - jest-cli@^29.3.1: 7708 - version "29.3.1" 7709 - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.3.1.tgz#e89dff427db3b1df50cea9a393ebd8640790416d" 7710 - integrity sha512-TO/ewvwyvPOiBBuWZ0gm04z3WWP8TIK8acgPzE4IxgsLKQgb377NYGrQLc3Wl/7ndWzIH2CDNNsUjGxwLL43VQ== 7757 + jest-cli@^29.4.3: 7758 + version "29.4.3" 7759 + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.4.3.tgz#fe31fdd0c90c765f392b8b7c97e4845071cd2163" 7760 + integrity sha512-PiiAPuFNfWWolCE6t3ZrDXQc6OsAuM3/tVW0u27UWc1KE+n/HSn5dSE6B2juqN7WP+PP0jAcnKtGmI4u8GMYCg== 7711 7761 dependencies: 7712 - "@jest/core" "^29.3.1" 7713 - "@jest/test-result" "^29.3.1" 7714 - "@jest/types" "^29.3.1" 7762 + "@jest/core" "^29.4.3" 7763 + "@jest/test-result" "^29.4.3" 7764 + "@jest/types" "^29.4.3" 7715 7765 chalk "^4.0.0" 7716 7766 exit "^0.1.2" 7717 7767 graceful-fs "^4.2.9" 7718 7768 import-local "^3.0.2" 7719 - jest-config "^29.3.1" 7720 - jest-util "^29.3.1" 7721 - jest-validate "^29.3.1" 7769 + jest-config "^29.4.3" 7770 + jest-util "^29.4.3" 7771 + jest-validate "^29.4.3" 7722 7772 prompts "^2.0.1" 7723 7773 yargs "^17.3.1" 7724 7774 ··· 7752 7802 slash "^3.0.0" 7753 7803 strip-json-comments "^3.1.1" 7754 7804 7755 - jest-config@^29.3.1: 7756 - version "29.3.1" 7757 - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.3.1.tgz#0bc3dcb0959ff8662957f1259947aedaefb7f3c6" 7758 - integrity sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg== 7805 + jest-config@^29.4.3: 7806 + version "29.4.3" 7807 + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.4.3.tgz#fca9cdfe6298ae6d04beef1624064d455347c978" 7808 + integrity sha512-eCIpqhGnIjdUCXGtLhz4gdDoxKSWXKjzNcc5r+0S1GKOp2fwOipx5mRcwa9GB/ArsxJ1jlj2lmlD9bZAsBxaWQ== 7759 7809 dependencies: 7760 7810 "@babel/core" "^7.11.6" 7761 - "@jest/test-sequencer" "^29.3.1" 7762 - "@jest/types" "^29.3.1" 7763 - babel-jest "^29.3.1" 7811 + "@jest/test-sequencer" "^29.4.3" 7812 + "@jest/types" "^29.4.3" 7813 + babel-jest "^29.4.3" 7764 7814 chalk "^4.0.0" 7765 7815 ci-info "^3.2.0" 7766 7816 deepmerge "^4.2.2" 7767 7817 glob "^7.1.3" 7768 7818 graceful-fs "^4.2.9" 7769 - jest-circus "^29.3.1" 7770 - jest-environment-node "^29.3.1" 7771 - jest-get-type "^29.2.0" 7772 - jest-regex-util "^29.2.0" 7773 - jest-resolve "^29.3.1" 7774 - jest-runner "^29.3.1" 7775 - jest-util "^29.3.1" 7776 - jest-validate "^29.3.1" 7819 + jest-circus "^29.4.3" 7820 + jest-environment-node "^29.4.3" 7821 + jest-get-type "^29.4.3" 7822 + jest-regex-util "^29.4.3" 7823 + jest-resolve "^29.4.3" 7824 + jest-runner "^29.4.3" 7825 + jest-util "^29.4.3" 7826 + jest-validate "^29.4.3" 7777 7827 micromatch "^4.0.4" 7778 7828 parse-json "^5.2.0" 7779 - pretty-format "^29.3.1" 7829 + pretty-format "^29.4.3" 7780 7830 slash "^3.0.0" 7781 7831 strip-json-comments "^3.1.1" 7782 7832 ··· 7800 7850 jest-get-type "^27.5.1" 7801 7851 pretty-format "^27.5.1" 7802 7852 7803 - jest-diff@^29.0.1, jest-diff@^29.3.1: 7804 - version "29.3.1" 7805 - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.3.1.tgz#d8215b72fed8f1e647aed2cae6c752a89e757527" 7806 - integrity sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw== 7853 + jest-diff@^29.0.1, jest-diff@^29.4.3: 7854 + version "29.4.3" 7855 + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.4.3.tgz#42f4eb34d0bf8c0fb08b0501069b87e8e84df347" 7856 + integrity sha512-YB+ocenx7FZ3T5O9lMVMeLYV4265socJKtkwgk/6YUz/VsEzYDkiMuMhWzZmxm3wDRQvayJu/PjkjjSkjoHsCA== 7807 7857 dependencies: 7808 7858 chalk "^4.0.0" 7809 - diff-sequences "^29.3.1" 7810 - jest-get-type "^29.2.0" 7811 - pretty-format "^29.3.1" 7859 + diff-sequences "^29.4.3" 7860 + jest-get-type "^29.4.3" 7861 + pretty-format "^29.4.3" 7812 7862 7813 7863 jest-docblock@^27.5.1: 7814 7864 version "27.5.1" ··· 7817 7867 dependencies: 7818 7868 detect-newline "^3.0.0" 7819 7869 7820 - jest-docblock@^29.2.0: 7821 - version "29.2.0" 7822 - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.2.0.tgz#307203e20b637d97cee04809efc1d43afc641e82" 7823 - integrity sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A== 7870 + jest-docblock@^29.4.3: 7871 + version "29.4.3" 7872 + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.4.3.tgz#90505aa89514a1c7dceeac1123df79e414636ea8" 7873 + integrity sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg== 7824 7874 dependencies: 7825 7875 detect-newline "^3.0.0" 7826 7876 ··· 7835 7885 jest-util "^27.5.1" 7836 7886 pretty-format "^27.5.1" 7837 7887 7838 - jest-each@^29.3.1: 7839 - version "29.3.1" 7840 - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.3.1.tgz#bc375c8734f1bb96625d83d1ca03ef508379e132" 7841 - integrity sha512-qrZH7PmFB9rEzCSl00BWjZYuS1BSOH8lLuC0azQE9lQrAx3PWGKHTDudQiOSwIy5dGAJh7KA0ScYlCP7JxvFYA== 7888 + jest-each@^29.4.3: 7889 + version "29.4.3" 7890 + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.4.3.tgz#a434c199a2f6151c5e3dc80b2d54586bdaa72819" 7891 + integrity sha512-1ElHNAnKcbJb/b+L+7j0/w7bDvljw4gTv1wL9fYOczeJrbTbkMGQ5iQPFJ3eFQH19VPTx1IyfePdqSpePKss7Q== 7842 7892 dependencies: 7843 - "@jest/types" "^29.3.1" 7893 + "@jest/types" "^29.4.3" 7844 7894 chalk "^4.0.0" 7845 - jest-get-type "^29.2.0" 7846 - jest-util "^29.3.1" 7847 - pretty-format "^29.3.1" 7895 + jest-get-type "^29.4.3" 7896 + jest-util "^29.4.3" 7897 + pretty-format "^29.4.3" 7848 7898 7849 7899 jest-environment-jsdom@^27.5.1: 7850 7900 version "27.5.1" ··· 7871 7921 jest-mock "^27.5.1" 7872 7922 jest-util "^27.5.1" 7873 7923 7874 - jest-environment-node@^29.2.1, jest-environment-node@^29.3.1: 7875 - version "29.3.1" 7876 - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.3.1.tgz#5023b32472b3fba91db5c799a0d5624ad4803e74" 7877 - integrity sha512-xm2THL18Xf5sIHoU7OThBPtuH6Lerd+Y1NLYiZJlkE3hbE+7N7r8uvHIl/FkZ5ymKXJe/11SQuf3fv4v6rUMag== 7924 + jest-environment-node@^29.2.1, jest-environment-node@^29.4.3: 7925 + version "29.4.3" 7926 + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.4.3.tgz#579c4132af478befc1889ddc43c2413a9cdbe014" 7927 + integrity sha512-gAiEnSKF104fsGDXNkwk49jD/0N0Bqu2K9+aMQXA6avzsA9H3Fiv1PW2D+gzbOSR705bWd2wJZRFEFpV0tXISg== 7878 7928 dependencies: 7879 - "@jest/environment" "^29.3.1" 7880 - "@jest/fake-timers" "^29.3.1" 7881 - "@jest/types" "^29.3.1" 7929 + "@jest/environment" "^29.4.3" 7930 + "@jest/fake-timers" "^29.4.3" 7931 + "@jest/types" "^29.4.3" 7882 7932 "@types/node" "*" 7883 - jest-mock "^29.3.1" 7884 - jest-util "^29.3.1" 7933 + jest-mock "^29.4.3" 7934 + jest-util "^29.4.3" 7885 7935 7886 7936 jest-get-type@^26.3.0: 7887 7937 version "26.3.0" ··· 7893 7943 resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" 7894 7944 integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== 7895 7945 7896 - jest-get-type@^29.2.0: 7897 - version "29.2.0" 7898 - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.2.0.tgz#726646f927ef61d583a3b3adb1ab13f3a5036408" 7899 - integrity sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA== 7946 + jest-get-type@^29.4.3: 7947 + version "29.4.3" 7948 + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" 7949 + integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== 7900 7950 7901 7951 jest-haste-map@^27.5.1: 7902 7952 version "27.5.1" ··· 7918 7968 optionalDependencies: 7919 7969 fsevents "^2.3.2" 7920 7970 7921 - jest-haste-map@^29.3.1: 7922 - version "29.3.1" 7923 - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.3.1.tgz#af83b4347f1dae5ee8c2fb57368dc0bb3e5af843" 7924 - integrity sha512-/FFtvoG1xjbbPXQLFef+WSU4yrc0fc0Dds6aRPBojUid7qlPqZvxdUBA03HW0fnVHXVCnCdkuoghYItKNzc/0A== 7971 + jest-haste-map@^29.4.3: 7972 + version "29.4.3" 7973 + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.4.3.tgz#085a44283269e7ace0645c63a57af0d2af6942e2" 7974 + integrity sha512-eZIgAS8tvm5IZMtKlR8Y+feEOMfo2pSQkmNbufdbMzMSn9nitgGxF1waM/+LbryO3OkMcKS98SUb+j/cQxp/vQ== 7925 7975 dependencies: 7926 - "@jest/types" "^29.3.1" 7976 + "@jest/types" "^29.4.3" 7927 7977 "@types/graceful-fs" "^4.1.3" 7928 7978 "@types/node" "*" 7929 7979 anymatch "^3.0.3" 7930 7980 fb-watchman "^2.0.0" 7931 7981 graceful-fs "^4.2.9" 7932 - jest-regex-util "^29.2.0" 7933 - jest-util "^29.3.1" 7934 - jest-worker "^29.3.1" 7982 + jest-regex-util "^29.4.3" 7983 + jest-util "^29.4.3" 7984 + jest-worker "^29.4.3" 7935 7985 micromatch "^4.0.4" 7936 7986 walker "^1.0.8" 7937 7987 optionalDependencies: ··· 7978 8028 jest-get-type "^27.5.1" 7979 8029 pretty-format "^27.5.1" 7980 8030 7981 - jest-leak-detector@^29.3.1: 7982 - version "29.3.1" 7983 - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.3.1.tgz#95336d020170671db0ee166b75cd8ef647265518" 7984 - integrity sha512-3DA/VVXj4zFOPagGkuqHnSQf1GZBmmlagpguxEERO6Pla2g84Q1MaVIB3YMxgUaFIaYag8ZnTyQgiZ35YEqAQA== 8031 + jest-leak-detector@^29.4.3: 8032 + version "29.4.3" 8033 + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.4.3.tgz#2b35191d6b35aa0256e63a9b79b0f949249cf23a" 8034 + integrity sha512-9yw4VC1v2NspMMeV3daQ1yXPNxMgCzwq9BocCwYrRgXe4uaEJPAN0ZK37nFBhcy3cUwEVstFecFLaTHpF7NiGA== 7985 8035 dependencies: 7986 - jest-get-type "^29.2.0" 7987 - pretty-format "^29.3.1" 8036 + jest-get-type "^29.4.3" 8037 + pretty-format "^29.4.3" 7988 8038 7989 8039 jest-matcher-utils@^27.5.1: 7990 8040 version "27.5.1" ··· 7996 8046 jest-get-type "^27.5.1" 7997 8047 pretty-format "^27.5.1" 7998 8048 7999 - jest-matcher-utils@^29.0.1, jest-matcher-utils@^29.3.1: 8000 - version "29.3.1" 8001 - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.3.1.tgz#6e7f53512f80e817dfa148672bd2d5d04914a572" 8002 - integrity sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ== 8049 + jest-matcher-utils@^29.0.1, jest-matcher-utils@^29.4.3: 8050 + version "29.4.3" 8051 + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.4.3.tgz#ea68ebc0568aebea4c4213b99f169ff786df96a0" 8052 + integrity sha512-TTciiXEONycZ03h6R6pYiZlSkvYgT0l8aa49z/DLSGYjex4orMUcafuLXYyyEDWB1RKglq00jzwY00Ei7yFNVg== 8003 8053 dependencies: 8004 8054 chalk "^4.0.0" 8005 - jest-diff "^29.3.1" 8006 - jest-get-type "^29.2.0" 8007 - pretty-format "^29.3.1" 8055 + jest-diff "^29.4.3" 8056 + jest-get-type "^29.4.3" 8057 + pretty-format "^29.4.3" 8008 8058 8009 8059 jest-message-util@^27.5.1: 8010 8060 version "27.5.1" ··· 8036 8086 slash "^3.0.0" 8037 8087 stack-utils "^2.0.3" 8038 8088 8039 - jest-message-util@^29.3.1: 8040 - version "29.3.1" 8041 - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.3.1.tgz#37bc5c468dfe5120712053dd03faf0f053bd6adb" 8042 - integrity sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA== 8089 + jest-message-util@^29.4.3: 8090 + version "29.4.3" 8091 + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.4.3.tgz#65b5280c0fdc9419503b49d4f48d4999d481cb5b" 8092 + integrity sha512-1Y8Zd4ZCN7o/QnWdMmT76If8LuDv23Z1DRovBj/vcSFNlGCJGoO8D1nJDw1AdyAGUk0myDLFGN5RbNeJyCRGCw== 8043 8093 dependencies: 8044 8094 "@babel/code-frame" "^7.12.13" 8045 - "@jest/types" "^29.3.1" 8095 + "@jest/types" "^29.4.3" 8046 8096 "@types/stack-utils" "^2.0.0" 8047 8097 chalk "^4.0.0" 8048 8098 graceful-fs "^4.2.9" 8049 8099 micromatch "^4.0.4" 8050 - pretty-format "^29.3.1" 8100 + pretty-format "^29.4.3" 8051 8101 slash "^3.0.0" 8052 8102 stack-utils "^2.0.3" 8053 8103 ··· 8059 8109 "@jest/types" "^27.5.1" 8060 8110 "@types/node" "*" 8061 8111 8062 - jest-mock@^29.3.1: 8063 - version "29.3.1" 8064 - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.3.1.tgz#60287d92e5010979d01f218c6b215b688e0f313e" 8065 - integrity sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA== 8112 + jest-mock@^29.4.3: 8113 + version "29.4.3" 8114 + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.4.3.tgz#23d84a20a74cdfff0510fdbeefb841ed57b0fe7e" 8115 + integrity sha512-LjFgMg+xed9BdkPMyIJh+r3KeHt1klXPJYBULXVVAkbTaaKjPX1o1uVCAZADMEp/kOxGTwy/Ot8XbvgItOrHEg== 8066 8116 dependencies: 8067 - "@jest/types" "^29.3.1" 8117 + "@jest/types" "^29.4.3" 8068 8118 "@types/node" "*" 8069 - jest-util "^29.3.1" 8119 + jest-util "^29.4.3" 8070 8120 8071 8121 jest-pnp-resolver@^1.2.2: 8072 8122 version "1.2.3" ··· 8083 8133 resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-28.0.2.tgz#afdc377a3b25fb6e80825adcf76c854e5bf47ead" 8084 8134 integrity sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw== 8085 8135 8086 - jest-regex-util@^29.2.0: 8087 - version "29.2.0" 8088 - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.2.0.tgz#82ef3b587e8c303357728d0322d48bbfd2971f7b" 8089 - integrity sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA== 8136 + jest-regex-util@^29.4.3: 8137 + version "29.4.3" 8138 + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.4.3.tgz#a42616141e0cae052cfa32c169945d00c0aa0bb8" 8139 + integrity sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg== 8090 8140 8091 8141 jest-resolve-dependencies@^27.5.1: 8092 8142 version "27.5.1" ··· 8097 8147 jest-regex-util "^27.5.1" 8098 8148 jest-snapshot "^27.5.1" 8099 8149 8100 - jest-resolve-dependencies@^29.3.1: 8101 - version "29.3.1" 8102 - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.3.1.tgz#a6a329708a128e68d67c49f38678a4a4a914c3bf" 8103 - integrity sha512-Vk0cYq0byRw2WluNmNWGqPeRnZ3p3hHmjJMp2dyyZeYIfiBskwq4rpiuGFR6QGAdbj58WC7HN4hQHjf2mpvrLA== 8150 + jest-resolve-dependencies@^29.4.3: 8151 + version "29.4.3" 8152 + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.4.3.tgz#9ad7f23839a6d88cef91416bda9393a6e9fd1da5" 8153 + integrity sha512-uvKMZAQ3nmXLH7O8WAOhS5l0iWyT3WmnJBdmIHiV5tBbdaDZ1wqtNX04FONGoaFvSOSHBJxnwAVnSn1WHdGVaw== 8104 8154 dependencies: 8105 - jest-regex-util "^29.2.0" 8106 - jest-snapshot "^29.3.1" 8155 + jest-regex-util "^29.4.3" 8156 + jest-snapshot "^29.4.3" 8107 8157 8108 8158 jest-resolve@^27.4.2, jest-resolve@^27.5.1: 8109 8159 version "27.5.1" ··· 8121 8171 resolve.exports "^1.1.0" 8122 8172 slash "^3.0.0" 8123 8173 8124 - jest-resolve@^29.3.1: 8125 - version "29.3.1" 8126 - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.3.1.tgz#9a4b6b65387a3141e4a40815535c7f196f1a68a7" 8127 - integrity sha512-amXJgH/Ng712w3Uz5gqzFBBjxV8WFLSmNjoreBGMqxgCz5cH7swmBZzgBaCIOsvb0NbpJ0vgaSFdJqMdT+rADw== 8174 + jest-resolve@^29.4.3: 8175 + version "29.4.3" 8176 + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.4.3.tgz#3c5b5c984fa8a763edf9b3639700e1c7900538e2" 8177 + integrity sha512-GPokE1tzguRyT7dkxBim4wSx6E45S3bOQ7ZdKEG+Qj0Oac9+6AwJPCk0TZh5Vu0xzeX4afpb+eDmgbmZFFwpOw== 8128 8178 dependencies: 8129 8179 chalk "^4.0.0" 8130 8180 graceful-fs "^4.2.9" 8131 - jest-haste-map "^29.3.1" 8181 + jest-haste-map "^29.4.3" 8132 8182 jest-pnp-resolver "^1.2.2" 8133 - jest-util "^29.3.1" 8134 - jest-validate "^29.3.1" 8183 + jest-util "^29.4.3" 8184 + jest-validate "^29.4.3" 8135 8185 resolve "^1.20.0" 8136 - resolve.exports "^1.1.0" 8186 + resolve.exports "^2.0.0" 8137 8187 slash "^3.0.0" 8138 8188 8139 8189 jest-runner@^27.5.1: ··· 8163 8213 source-map-support "^0.5.6" 8164 8214 throat "^6.0.1" 8165 8215 8166 - jest-runner@^29.3.1: 8167 - version "29.3.1" 8168 - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.3.1.tgz#a92a879a47dd096fea46bb1517b0a99418ee9e2d" 8169 - integrity sha512-oFvcwRNrKMtE6u9+AQPMATxFcTySyKfLhvso7Sdk/rNpbhg4g2GAGCopiInk1OP4q6gz3n6MajW4+fnHWlU3bA== 8216 + jest-runner@^29.4.3: 8217 + version "29.4.3" 8218 + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.4.3.tgz#68dc82c68645eda12bea42b5beece6527d7c1e5e" 8219 + integrity sha512-GWPTEiGmtHZv1KKeWlTX9SIFuK19uLXlRQU43ceOQ2hIfA5yPEJC7AMkvFKpdCHx6pNEdOD+2+8zbniEi3v3gA== 8170 8220 dependencies: 8171 - "@jest/console" "^29.3.1" 8172 - "@jest/environment" "^29.3.1" 8173 - "@jest/test-result" "^29.3.1" 8174 - "@jest/transform" "^29.3.1" 8175 - "@jest/types" "^29.3.1" 8221 + "@jest/console" "^29.4.3" 8222 + "@jest/environment" "^29.4.3" 8223 + "@jest/test-result" "^29.4.3" 8224 + "@jest/transform" "^29.4.3" 8225 + "@jest/types" "^29.4.3" 8176 8226 "@types/node" "*" 8177 8227 chalk "^4.0.0" 8178 8228 emittery "^0.13.1" 8179 8229 graceful-fs "^4.2.9" 8180 - jest-docblock "^29.2.0" 8181 - jest-environment-node "^29.3.1" 8182 - jest-haste-map "^29.3.1" 8183 - jest-leak-detector "^29.3.1" 8184 - jest-message-util "^29.3.1" 8185 - jest-resolve "^29.3.1" 8186 - jest-runtime "^29.3.1" 8187 - jest-util "^29.3.1" 8188 - jest-watcher "^29.3.1" 8189 - jest-worker "^29.3.1" 8230 + jest-docblock "^29.4.3" 8231 + jest-environment-node "^29.4.3" 8232 + jest-haste-map "^29.4.3" 8233 + jest-leak-detector "^29.4.3" 8234 + jest-message-util "^29.4.3" 8235 + jest-resolve "^29.4.3" 8236 + jest-runtime "^29.4.3" 8237 + jest-util "^29.4.3" 8238 + jest-watcher "^29.4.3" 8239 + jest-worker "^29.4.3" 8190 8240 p-limit "^3.1.0" 8191 8241 source-map-support "0.5.13" 8192 8242 ··· 8218 8268 slash "^3.0.0" 8219 8269 strip-bom "^4.0.0" 8220 8270 8221 - jest-runtime@^29.3.1: 8222 - version "29.3.1" 8223 - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.3.1.tgz#21efccb1a66911d6d8591276a6182f520b86737a" 8224 - integrity sha512-jLzkIxIqXwBEOZx7wx9OO9sxoZmgT2NhmQKzHQm1xwR1kNW/dn0OjxR424VwHHf1SPN6Qwlb5pp1oGCeFTQ62A== 8271 + jest-runtime@^29.4.3: 8272 + version "29.4.3" 8273 + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.4.3.tgz#f25db9874dcf35a3ab27fdaabca426666cc745bf" 8274 + integrity sha512-F5bHvxSH+LvLV24vVB3L8K467dt3y3dio6V3W89dUz9nzvTpqd/HcT9zfYKL2aZPvD63vQFgLvaUX/UpUhrP6Q== 8225 8275 dependencies: 8226 - "@jest/environment" "^29.3.1" 8227 - "@jest/fake-timers" "^29.3.1" 8228 - "@jest/globals" "^29.3.1" 8229 - "@jest/source-map" "^29.2.0" 8230 - "@jest/test-result" "^29.3.1" 8231 - "@jest/transform" "^29.3.1" 8232 - "@jest/types" "^29.3.1" 8276 + "@jest/environment" "^29.4.3" 8277 + "@jest/fake-timers" "^29.4.3" 8278 + "@jest/globals" "^29.4.3" 8279 + "@jest/source-map" "^29.4.3" 8280 + "@jest/test-result" "^29.4.3" 8281 + "@jest/transform" "^29.4.3" 8282 + "@jest/types" "^29.4.3" 8233 8283 "@types/node" "*" 8234 8284 chalk "^4.0.0" 8235 8285 cjs-module-lexer "^1.0.0" 8236 8286 collect-v8-coverage "^1.0.0" 8237 8287 glob "^7.1.3" 8238 8288 graceful-fs "^4.2.9" 8239 - jest-haste-map "^29.3.1" 8240 - jest-message-util "^29.3.1" 8241 - jest-mock "^29.3.1" 8242 - jest-regex-util "^29.2.0" 8243 - jest-resolve "^29.3.1" 8244 - jest-snapshot "^29.3.1" 8245 - jest-util "^29.3.1" 8289 + jest-haste-map "^29.4.3" 8290 + jest-message-util "^29.4.3" 8291 + jest-mock "^29.4.3" 8292 + jest-regex-util "^29.4.3" 8293 + jest-resolve "^29.4.3" 8294 + jest-snapshot "^29.4.3" 8295 + jest-util "^29.4.3" 8246 8296 slash "^3.0.0" 8247 8297 strip-bom "^4.0.0" 8248 8298 ··· 8282 8332 pretty-format "^27.5.1" 8283 8333 semver "^7.3.2" 8284 8334 8285 - jest-snapshot@^29.3.1: 8286 - version "29.3.1" 8287 - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.3.1.tgz#17bcef71a453adc059a18a32ccbd594b8cc4e45e" 8288 - integrity sha512-+3JOc+s28upYLI2OJM4PWRGK9AgpsMs/ekNryUV0yMBClT9B1DF2u2qay8YxcQd338PPYSFNb0lsar1B49sLDA== 8335 + jest-snapshot@^29.4.3: 8336 + version "29.4.3" 8337 + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.4.3.tgz#183d309371450d9c4a3de7567ed2151eb0e91145" 8338 + integrity sha512-NGlsqL0jLPDW91dz304QTM/SNO99lpcSYYAjNiX0Ou+sSGgkanKBcSjCfp/pqmiiO1nQaOyLp6XQddAzRcx3Xw== 8289 8339 dependencies: 8290 8340 "@babel/core" "^7.11.6" 8291 8341 "@babel/generator" "^7.7.2" ··· 8293 8343 "@babel/plugin-syntax-typescript" "^7.7.2" 8294 8344 "@babel/traverse" "^7.7.2" 8295 8345 "@babel/types" "^7.3.3" 8296 - "@jest/expect-utils" "^29.3.1" 8297 - "@jest/transform" "^29.3.1" 8298 - "@jest/types" "^29.3.1" 8346 + "@jest/expect-utils" "^29.4.3" 8347 + "@jest/transform" "^29.4.3" 8348 + "@jest/types" "^29.4.3" 8299 8349 "@types/babel__traverse" "^7.0.6" 8300 8350 "@types/prettier" "^2.1.5" 8301 8351 babel-preset-current-node-syntax "^1.0.0" 8302 8352 chalk "^4.0.0" 8303 - expect "^29.3.1" 8353 + expect "^29.4.3" 8304 8354 graceful-fs "^4.2.9" 8305 - jest-diff "^29.3.1" 8306 - jest-get-type "^29.2.0" 8307 - jest-haste-map "^29.3.1" 8308 - jest-matcher-utils "^29.3.1" 8309 - jest-message-util "^29.3.1" 8310 - jest-util "^29.3.1" 8355 + jest-diff "^29.4.3" 8356 + jest-get-type "^29.4.3" 8357 + jest-haste-map "^29.4.3" 8358 + jest-matcher-utils "^29.4.3" 8359 + jest-message-util "^29.4.3" 8360 + jest-util "^29.4.3" 8311 8361 natural-compare "^1.4.0" 8312 - pretty-format "^29.3.1" 8362 + pretty-format "^29.4.3" 8313 8363 semver "^7.3.5" 8314 8364 8315 8365 jest-util@^27.2.0, jest-util@^27.5.1: ··· 8336 8386 graceful-fs "^4.2.9" 8337 8387 picomatch "^2.2.3" 8338 8388 8339 - jest-util@^29.3.1: 8340 - version "29.3.1" 8341 - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.3.1.tgz#1dda51e378bbcb7e3bc9d8ab651445591ed373e1" 8342 - integrity sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ== 8389 + jest-util@^29.4.3: 8390 + version "29.4.3" 8391 + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.4.3.tgz#851a148e23fc2b633c55f6dad2e45d7f4579f496" 8392 + integrity sha512-ToSGORAz4SSSoqxDSylWX8JzkOQR7zoBtNRsA7e+1WUX5F8jrOwaNpuh1YfJHJKDHXLHmObv5eOjejUd+/Ws+Q== 8343 8393 dependencies: 8344 - "@jest/types" "^29.3.1" 8394 + "@jest/types" "^29.4.3" 8345 8395 "@types/node" "*" 8346 8396 chalk "^4.0.0" 8347 8397 ci-info "^3.2.0" ··· 8372 8422 leven "^3.1.0" 8373 8423 pretty-format "^27.5.1" 8374 8424 8375 - jest-validate@^29.3.1: 8376 - version "29.3.1" 8377 - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.3.1.tgz#d56fefaa2e7d1fde3ecdc973c7f7f8f25eea704a" 8378 - integrity sha512-N9Lr3oYR2Mpzuelp1F8negJR3YE+L1ebk1rYA5qYo9TTY3f9OWdptLoNSPP9itOCBIRBqjt/S5XHlzYglLN67g== 8425 + jest-validate@^29.4.3: 8426 + version "29.4.3" 8427 + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.4.3.tgz#a13849dec4f9e95446a7080ad5758f58fa88642f" 8428 + integrity sha512-J3u5v7aPQoXPzaar6GndAVhdQcZr/3osWSgTeKg5v574I9ybX/dTyH0AJFb5XgXIB7faVhf+rS7t4p3lL9qFaw== 8379 8429 dependencies: 8380 - "@jest/types" "^29.3.1" 8430 + "@jest/types" "^29.4.3" 8381 8431 camelcase "^6.2.0" 8382 8432 chalk "^4.0.0" 8383 - jest-get-type "^29.2.0" 8433 + jest-get-type "^29.4.3" 8384 8434 leven "^3.1.0" 8385 - pretty-format "^29.3.1" 8435 + pretty-format "^29.4.3" 8386 8436 8387 8437 jest-watch-typeahead@^1.0.0: 8388 8438 version "1.1.0" ··· 8424 8474 jest-util "^28.1.3" 8425 8475 string-length "^4.0.1" 8426 8476 8427 - jest-watcher@^29.3.1: 8428 - version "29.3.1" 8429 - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.3.1.tgz#3341547e14fe3c0f79f9c3a4c62dbc3fc977fd4a" 8430 - integrity sha512-RspXG2BQFDsZSRKGCT/NiNa8RkQ1iKAjrO0//soTMWx/QUt+OcxMqMSBxz23PYGqUuWm2+m2mNNsmj0eIoOaFg== 8477 + jest-watcher@^29.4.3: 8478 + version "29.4.3" 8479 + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.4.3.tgz#e503baa774f0c2f8f3c8db98a22ebf885f19c384" 8480 + integrity sha512-zwlXH3DN3iksoIZNk73etl1HzKyi5FuQdYLnkQKm5BW4n8HpoG59xSwpVdFrnh60iRRaRBGw0gcymIxjJENPcA== 8431 8481 dependencies: 8432 - "@jest/test-result" "^29.3.1" 8433 - "@jest/types" "^29.3.1" 8482 + "@jest/test-result" "^29.4.3" 8483 + "@jest/types" "^29.4.3" 8434 8484 "@types/node" "*" 8435 8485 ansi-escapes "^4.2.1" 8436 8486 chalk "^4.0.0" 8437 8487 emittery "^0.13.1" 8438 - jest-util "^29.3.1" 8488 + jest-util "^29.4.3" 8439 8489 string-length "^4.0.1" 8440 8490 8441 8491 jest-worker@^26.2.1: ··· 8465 8515 merge-stream "^2.0.0" 8466 8516 supports-color "^8.0.0" 8467 8517 8468 - jest-worker@^29.3.1: 8469 - version "29.3.1" 8470 - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.3.1.tgz#e9462161017a9bb176380d721cab022661da3d6b" 8471 - integrity sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw== 8518 + jest-worker@^29.4.3: 8519 + version "29.4.3" 8520 + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.4.3.tgz#9a4023e1ea1d306034237c7133d7da4240e8934e" 8521 + integrity sha512-GLHN/GTAAMEy5BFdvpUfzr9Dr80zQqBrh0fz1mtRMe05hqP45+HfQltu7oTBfduD0UeZs09d+maFtFYAXFWvAA== 8472 8522 dependencies: 8473 8523 "@types/node" "*" 8474 - jest-util "^29.3.1" 8524 + jest-util "^29.4.3" 8475 8525 merge-stream "^2.0.0" 8476 8526 supports-color "^8.0.0" 8477 8527 ··· 8485 8535 jest-cli "^27.5.1" 8486 8536 8487 8537 jest@^29.2.1: 8488 - version "29.3.1" 8489 - resolved "https://registry.yarnpkg.com/jest/-/jest-29.3.1.tgz#c130c0d551ae6b5459b8963747fed392ddbde122" 8490 - integrity sha512-6iWfL5DTT0Np6UYs/y5Niu7WIfNv/wRTtN5RSXt2DIEft3dx3zPuw/3WJQBCJfmEzvDiEKwoqMbGD9n49+qLSA== 8538 + version "29.4.3" 8539 + resolved "https://registry.yarnpkg.com/jest/-/jest-29.4.3.tgz#1b8be541666c6feb99990fd98adac4737e6e6386" 8540 + integrity sha512-XvK65feuEFGZT8OO0fB/QAQS+LGHvQpaadkH5p47/j3Ocqq3xf2pK9R+G0GzgfuhXVxEv76qCOOcMb5efLk6PA== 8491 8541 dependencies: 8492 - "@jest/core" "^29.3.1" 8493 - "@jest/types" "^29.3.1" 8542 + "@jest/core" "^29.4.3" 8543 + "@jest/types" "^29.4.3" 8494 8544 import-local "^3.0.2" 8495 - jest-cli "^29.3.1" 8545 + jest-cli "^29.4.3" 8496 8546 8497 8547 joi@^17.2.1: 8498 - version "17.7.0" 8499 - resolved "https://registry.yarnpkg.com/joi/-/joi-17.7.0.tgz#591a33b1fe1aca2bc27f290bcad9b9c1c570a6b3" 8500 - integrity sha512-1/ugc8djfn93rTE3WRKdCzGGt/EtiYKxITMO4Wiv6q5JL1gl9ePt4kBsl1S499nbosspfctIQTpYIhSmHA3WAg== 8548 + version "17.8.3" 8549 + resolved "https://registry.yarnpkg.com/joi/-/joi-17.8.3.tgz#d772fe27a87a5cda21aace5cf11eee8671ca7e6f" 8550 + integrity sha512-q5Fn6Tj/jR8PfrLrx4fpGH4v9qM6o+vDUfD4/3vxxyg34OmKcNqYZ1qn2mpLza96S8tL0p0rIw2gOZX+/cTg9w== 8501 8551 dependencies: 8502 8552 "@hapi/hoek" "^9.0.0" 8503 8553 "@hapi/topo" "^5.0.0" 8504 8554 "@sideway/address" "^4.1.3" 8505 - "@sideway/formula" "^3.0.0" 8555 + "@sideway/formula" "^3.0.1" 8506 8556 "@sideway/pinpoint" "^2.0.0" 8507 8557 8508 8558 js-base64@^3.7.2: 8509 - version "3.7.4" 8510 - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-3.7.4.tgz#af95b20f23efc8034afd2d1cc5b9d0adf7419037" 8511 - integrity sha512-wpM/wi20Tl+3ifTyi0RdDckS4YTD4Lf953mBRrpG8547T7hInHNPEj8+ck4gB8VDcGyeAWFK++Wb/fU1BeavKQ== 8559 + version "3.7.5" 8560 + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-3.7.5.tgz#21e24cf6b886f76d6f5f165bfcd69cc55b9e3fca" 8561 + integrity sha512-3MEt5DTINKqfScXKfJFrRbxkrnk2AxPWGBL/ycjz4dK8iqiSJ06UxD8jh8xuh6p10TX4t2+7FsBYVxxQbMg+qA== 8562 + 8563 + js-message@1.0.7: 8564 + version "1.0.7" 8565 + resolved "https://registry.yarnpkg.com/js-message/-/js-message-1.0.7.tgz#fbddd053c7a47021871bb8b2c95397cc17c20e47" 8566 + integrity sha512-efJLHhLjIyKRewNS9EGZ4UpI8NguuL6fKkhRxVuMmrGV2xN/0APGdQYwLFky5w9naebSZ0OwAGp0G6/2Cg90rA== 8567 + 8568 + js-queue@2.0.2: 8569 + version "2.0.2" 8570 + resolved "https://registry.yarnpkg.com/js-queue/-/js-queue-2.0.2.tgz#0be590338f903b36c73d33c31883a821412cd482" 8571 + integrity sha512-pbKLsbCfi7kriM3s1J4DDCo7jQkI58zPLHi0heXPzPlj0hjUsm+FesPUbE0DSbIVIK503A36aUBoCN7eMFedkA== 8572 + dependencies: 8573 + easy-stack "^1.0.1" 8512 8574 8513 8575 js-sdsl@^4.1.4: 8514 - version "4.2.0" 8515 - resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.2.0.tgz#278e98b7bea589b8baaf048c20aeb19eb7ad09d0" 8516 - integrity sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ== 8576 + version "4.3.0" 8577 + resolved "https://registry.yarnpkg.com/js-sdsl/-/js-sdsl-4.3.0.tgz#aeefe32a451f7af88425b11fdb5f58c90ae1d711" 8578 + integrity sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ== 8517 8579 8518 8580 "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: 8519 8581 version "4.0.0" ··· 8608 8670 resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" 8609 8671 integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== 8610 8672 8673 + json-cycle@^1.3.0: 8674 + version "1.3.0" 8675 + resolved "https://registry.yarnpkg.com/json-cycle/-/json-cycle-1.3.0.tgz#c4f6f7d926c2979012cba173b06f9cae9e866d3f" 8676 + integrity sha512-FD/SedD78LCdSvJaOUQAXseT8oQBb5z6IVYaQaCrVUlu9zOAr1BDdKyVYQaSD/GDsAMrXpKcOyBD4LIl8nfjHw== 8677 + 8611 8678 json-parse-better-errors@^1.0.1: 8612 8679 version "1.0.2" 8613 8680 resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" ··· 8645 8712 dependencies: 8646 8713 minimist "^1.2.0" 8647 8714 8648 - json5@^2.1.1, json5@^2.1.2, json5@^2.2.0, json5@^2.2.1, json5@^2.2.2: 8715 + json5@^2.1.1, json5@^2.1.2, json5@^2.2.0, json5@^2.2.2: 8649 8716 version "2.2.3" 8650 8717 resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" 8651 8718 integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== ··· 8687 8754 ms "^2.1.1" 8688 8755 semver "^5.6.0" 8689 8756 8690 - "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.2: 8757 + "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.3: 8691 8758 version "3.3.3" 8692 8759 resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" 8693 8760 integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw== ··· 8742 8809 integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== 8743 8810 8744 8811 klona@^2.0.4, klona@^2.0.5: 8745 - version "2.0.5" 8746 - resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc" 8747 - integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ== 8812 + version "2.0.6" 8813 + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22" 8814 + integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== 8748 8815 8749 8816 kysely@^0.22.0: 8750 8817 version "0.22.0" 8751 8818 resolved "https://registry.yarnpkg.com/kysely/-/kysely-0.22.0.tgz#8aac53942da3cadc604d7d154a746d983fe8f7b9" 8752 8819 integrity sha512-ZE3qWtnqLOalodzfK5QUEcm7AEulhxsPNuKaGFsC3XiqO92vMLm+mAHk/NnbSIOtC4RmGm0nsv700i8KDp1gfQ== 8753 8820 8754 - language-subtag-registry@^0.3.20: 8821 + language-subtag-registry@~0.3.2: 8755 8822 version "0.3.22" 8756 8823 resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" 8757 8824 integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== 8758 8825 8759 - language-tags@^1.0.5: 8760 - version "1.0.7" 8761 - resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.7.tgz#41cc248730f3f12a452c2e2efe32bc0bbce67967" 8762 - integrity sha512-bSytju1/657hFjgUzPAPqszxH62ouE8nQFoFaVlIQfne4wO/wXC9A4+m8jYve7YBBvi59eq0SUpcshvG8h5Usw== 8826 + language-tags@=1.0.5: 8827 + version "1.0.5" 8828 + resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a" 8829 + integrity sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ== 8763 8830 dependencies: 8764 - language-subtag-registry "^0.3.20" 8831 + language-subtag-registry "~0.3.2" 8765 8832 8766 8833 leven@^3.1.0: 8767 8834 version "3.1.0" ··· 8840 8907 resolved "https://registry.yarnpkg.com/lodash.chunk/-/lodash.chunk-4.2.0.tgz#66e5ce1f76ed27b4303d8c6512e8d1216e8106bc" 8841 8908 integrity sha512-ZzydJKfUHJwHa+hF5X66zLFCBrWn5GeF28OHEr4WVWtNDXlQ/IjWKPBiikqKo2ne0+v6JgCgJ0GzJp8k8bHC7w== 8842 8909 8910 + lodash.clonedeep@^4.5.0: 8911 + version "4.5.0" 8912 + resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" 8913 + integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ== 8914 + 8843 8915 lodash.debounce@^4.0.8: 8844 8916 version "4.0.8" 8845 8917 resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" ··· 8900 8972 resolved "https://registry.yarnpkg.com/lodash.once/-/lodash.once-4.1.1.tgz#0dd3971213c7c56df880977d504c88fb471a97ac" 8901 8973 integrity sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg== 8902 8974 8975 + lodash.shuffle@^4.2.0: 8976 + version "4.2.0" 8977 + resolved "https://registry.yarnpkg.com/lodash.shuffle/-/lodash.shuffle-4.2.0.tgz#145b5053cf875f6f5c2a33f48b6e9948c6ec7b4b" 8978 + integrity sha512-V/rTAABKLFjoecTZjKSv+A1ZomG8hZg8hlgeG6wwQVD9AGv+10zqqSf6mFq2tVA703Zd5R0YhSuSlXA+E/Ei+Q== 8979 + 8903 8980 lodash.sortby@^4.7.0: 8904 8981 version "4.7.0" 8905 8982 resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" ··· 8915 8992 resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" 8916 8993 integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== 8917 8994 8918 - lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: 8995 + lodash@^4.17.11, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: 8919 8996 version "4.17.21" 8920 8997 resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" 8921 8998 integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== ··· 8951 9028 dependencies: 8952 9029 tslib "^2.0.3" 8953 9030 9031 + lru-cache@^4.0.1: 9032 + version "4.1.5" 9033 + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" 9034 + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== 9035 + dependencies: 9036 + pseudomap "^1.0.2" 9037 + yallist "^2.1.2" 9038 + 8954 9039 lru-cache@^5.1.1: 8955 9040 version "5.1.1" 8956 9041 resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" ··· 9027 9112 integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== 9028 9113 9029 9114 memfs@^3.1.2, memfs@^3.4.3: 9030 - version "3.4.12" 9031 - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.12.tgz#d00f8ad8dab132dc277c659dc85bfd14b07d03bd" 9032 - integrity sha512-BcjuQn6vfqP+k100e0E9m61Hyqa//Brp+I3f0OBmN0ATHlFA8vx3Lt8z57R3u2bPqe3WGDBC+nF72fTH7isyEw== 9115 + version "3.4.13" 9116 + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.13.tgz#248a8bd239b3c240175cd5ec548de5227fc4f345" 9117 + integrity sha512-omTM41g3Skpvx5dSYeZIbXKcXoAVc/AoMNwn9TKx++L/gaen/+4TTttmu8ZSch5vfVJ8uJvGbroTsIlslRg6lg== 9033 9118 dependencies: 9034 9119 fs-monkey "^1.0.3" 9035 9120 ··· 9065 9150 resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" 9066 9151 integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== 9067 9152 9068 - metro-babel-transformer@0.73.5: 9069 - version "0.73.5" 9070 - resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.73.5.tgz#e7ebe371cd8bf5df90b0e9153587b4d5089d2ce7" 9071 - integrity sha512-G3awAJ9of/R2jEg+MRokYcq/TNvMSxJipwybQ2NfwwSj5iLEmRH2YbwTx5w8f5qKgs2K4SS2pmBIs8qjdV6p3Q== 9072 - dependencies: 9073 - "@babel/core" "^7.14.0" 9074 - hermes-parser "0.8.0" 9075 - metro-source-map "0.73.5" 9076 - nullthrows "^1.1.1" 9077 - 9078 9153 metro-babel-transformer@0.73.7: 9079 9154 version "0.73.7" 9080 9155 resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.73.7.tgz#561ffa0336eb6d7d112e7128e957114c729fdb71" ··· 9085 9160 metro-source-map "0.73.7" 9086 9161 nullthrows "^1.1.1" 9087 9162 9088 - metro-cache-key@0.73.7: 9089 - version "0.73.7" 9090 - resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.73.7.tgz#fa3b4ece5f3191ce238a623051a0d03bada2a153" 9091 - integrity sha512-GngYzrHwZU9U0Xl81H4aq9Tn5cjQyU12v9/flB0hzpeiYO5A89TIeilb4Kg8jtfC6JcmmsdK9nxYIGEq7odHhQ== 9163 + metro-babel-transformer@0.73.8: 9164 + version "0.73.8" 9165 + resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.73.8.tgz#521374cb9234ba126f3f8d63588db5901308b4ed" 9166 + integrity sha512-GO6H/W2RjZ0/gm1pIvdO9EP34s3XN6kzoeyxqmfqKfYhJmYZf1SzXbyiIHyMbJNwJVrsKuHqu32+GopTlKscWw== 9167 + dependencies: 9168 + "@babel/core" "^7.20.0" 9169 + hermes-parser "0.8.0" 9170 + metro-source-map "0.73.8" 9171 + nullthrows "^1.1.1" 9092 9172 9093 - metro-cache@0.73.7: 9094 - version "0.73.7" 9095 - resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.73.7.tgz#dd2b6a791b2754eae9c0a86dcf714b98e025fd95" 9096 - integrity sha512-CPPgI+i9yVzOEDCdmEEZ67JgOvZyNDs8kStmGUFgDuLSjj3//HhkqT5XyfWjGeH6KmyGiS8ip3cgLOVn3IsOSA== 9173 + metro-cache-key@0.73.8: 9174 + version "0.73.8" 9175 + resolved "https://registry.yarnpkg.com/metro-cache-key/-/metro-cache-key-0.73.8.tgz#afc9f63454edbd9d207544445a66e8a4e119462d" 9176 + integrity sha512-VzFGu4kJGIkLjyDgVoM2ZxIHlMdCZWMqVIux9N+EeyMVMvGXTiXW8eGROgxzDhVjyR58IjfMsYpRCKz5dR+2ew== 9177 + 9178 + metro-cache@0.73.8: 9179 + version "0.73.8" 9180 + resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.73.8.tgz#85e2d7f7c7c74d1f942b7ecd168f7aceb987d883" 9181 + integrity sha512-/uFbTIw813Rvb8kSAIHvax9gWl41dtgjY2SpJLNIBLdQ6oFZ3CVo3ahZIiEZOrCeHl9xfGn5tmvNb8CEFa/Q5w== 9097 9182 dependencies: 9098 - metro-core "0.73.7" 9183 + metro-core "0.73.8" 9099 9184 rimraf "^3.0.2" 9100 9185 9101 - metro-config@0.73.7: 9102 - version "0.73.7" 9103 - resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.73.7.tgz#8935054ece6155d214420c263272cd3a690a82e2" 9104 - integrity sha512-pD/F+vK3u37cbj1skYmI6cUsEEscqNRtW2KlDKu1m+n8nooDB2oGTOZatlS5WQa7Ga6jYQRydftlq4CLDexAfA== 9186 + metro-config@0.73.8: 9187 + version "0.73.8" 9188 + resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.73.8.tgz#8f6c22c94528919635c6688ed8d2ad8a10c70b27" 9189 + integrity sha512-sAYq+llL6ZAfro64U99ske8HcKKswxX4wIZbll9niBKG7TkWm7tfMY1jO687XEmE4683rHncZeBRav9pLngIzg== 9105 9190 dependencies: 9106 9191 cosmiconfig "^5.0.5" 9107 9192 jest-validate "^26.5.2" 9108 - metro "0.73.7" 9109 - metro-cache "0.73.7" 9110 - metro-core "0.73.7" 9111 - metro-runtime "0.73.7" 9193 + metro "0.73.8" 9194 + metro-cache "0.73.8" 9195 + metro-core "0.73.8" 9196 + metro-runtime "0.73.8" 9112 9197 9113 - metro-core@0.73.7: 9114 - version "0.73.7" 9115 - resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.73.7.tgz#f5abe2448ea72a65f54db9bc90068f3308de1df2" 9116 - integrity sha512-H7j1Egj1VnNnsSYf9ZKv0SRwijgtRKIcaGNQq/T+er73vqqb4kR9H+2VIJYPXi6R8lT+QLIMfs6CWSUHAJUgtg== 9198 + metro-core@0.73.8: 9199 + version "0.73.8" 9200 + resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.73.8.tgz#a31ba7d7bfe3f4c2ac2c7a2493aa4229ecad701e" 9201 + integrity sha512-Aew4dthbZf8bRRjlYGL3cnai3+LKYTf6mc7YS2xLQRWtgGZ1b/H8nQtBvXZpfRYFcS84UeEQ10vwIf5eR3qPdQ== 9117 9202 dependencies: 9118 9203 lodash.throttle "^4.1.1" 9119 - metro-resolver "0.73.7" 9204 + metro-resolver "0.73.8" 9120 9205 9121 - metro-file-map@0.73.7: 9122 - version "0.73.7" 9123 - resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.73.7.tgz#709f33ac5ea6f87668d454c77973ab296b7a064b" 9124 - integrity sha512-BYaCo2e/4FMN4nOajeN+Za5cPfecfikzUYuFWWMyLAmHU6dj7B+PFkaJ4OEJO3vmRoeq5vMOmhpKXgysYbNXJg== 9206 + metro-file-map@0.73.8: 9207 + version "0.73.8" 9208 + resolved "https://registry.yarnpkg.com/metro-file-map/-/metro-file-map-0.73.8.tgz#88d666e7764e1b0adf5fd634d91e97e3135d2db7" 9209 + integrity sha512-CM552hUO9om02jJdLszOCIDADKNaaeVz8CjYXItndvgr5jmFlQYAR+UMvaDzeT8oYdAV1DXAljma2CS2UBymPg== 9125 9210 dependencies: 9126 9211 abort-controller "^3.0.0" 9127 9212 anymatch "^3.0.3" ··· 9139 9224 optionalDependencies: 9140 9225 fsevents "^2.3.2" 9141 9226 9142 - metro-hermes-compiler@0.73.7: 9143 - version "0.73.7" 9144 - resolved "https://registry.yarnpkg.com/metro-hermes-compiler/-/metro-hermes-compiler-0.73.7.tgz#d1b519c4040423240d89e7816340ca9635deeae8" 9145 - integrity sha512-F8PlJ8mWEEumGNH3eMRA3gjgP70ZvH4Ex5F1KY6ofD/gpn7w5HJHSPTeVw8gtUb1pYLN4nevptpyXGg04Jfcog== 9227 + metro-hermes-compiler@0.73.8: 9228 + version "0.73.8" 9229 + resolved "https://registry.yarnpkg.com/metro-hermes-compiler/-/metro-hermes-compiler-0.73.8.tgz#c522e2c97afc8bdc249755d88146a75720bc2498" 9230 + integrity sha512-2d7t+TEoQLk+jyXgBykmAtPPJK2B46DB3qUYIMKDFDDaKzCljrojyVuGgQq6SM1f95fe6HDAQ3K9ihTjeB90yw== 9146 9231 9147 - metro-inspector-proxy@0.73.7: 9148 - version "0.73.7" 9149 - resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.73.7.tgz#edb966c1581a41a3302860d264f3228e1f57a220" 9150 - integrity sha512-TsAtQeKr9X7NaQHlpshu+ZkGWlPi5fFKNqieLkfqvT1oXN4PQF/4q38INyiZtWLPvoUzTR6PRnm4pcUbJ7+Nzg== 9232 + metro-inspector-proxy@0.73.8: 9233 + version "0.73.8" 9234 + resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.73.8.tgz#67d5aadfc33fe97f61c716eb168db4bd5d0e3c96" 9235 + integrity sha512-F0QxwDTox0TDeXVRN7ZmI7BknBjPDVKQ1ZeKznFBiMa0SXiD1kzoksfpDbZ6hTEKrhVM9Ep0YQmC7avwZouOnA== 9151 9236 dependencies: 9152 9237 connect "^3.6.5" 9153 9238 debug "^2.2.0" 9154 9239 ws "^7.5.1" 9155 9240 yargs "^17.5.1" 9156 9241 9157 - metro-minify-terser@0.73.7: 9158 - version "0.73.7" 9159 - resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.73.7.tgz#e45fc05eb2e3bc76c9b4fe4abccee0fffeedcf75" 9160 - integrity sha512-gbv1fmMOZm6gJ6dQoD+QktlCi2wk6nlTR8j8lQCjeeXGbs6O9e5XLWNPOexHqo7S69bdbohEnfZnLJFcxgHeNw== 9242 + metro-minify-terser@0.73.8: 9243 + version "0.73.8" 9244 + resolved "https://registry.yarnpkg.com/metro-minify-terser/-/metro-minify-terser-0.73.8.tgz#a0fe857d6aaf99cba3a2aef59ee06ac409682c6b" 9245 + integrity sha512-pnagyXAoMPhihWrHRIWqCxrP6EJ8Hfugv5RXBb6HbOANmwajn2uQuzeu18+dXaN1yPoDCMCgpg/UA4ibFN5jtQ== 9161 9246 dependencies: 9162 9247 terser "^5.15.0" 9163 9248 9164 - metro-minify-uglify@0.73.7: 9165 - version "0.73.7" 9166 - resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.73.7.tgz#3dfd397e8202905731e4a519a58fc334d9232a15" 9167 - integrity sha512-DmDCzfdbaPExQuQ7NQozCNOSOAgp5Ux9kWzmKAT8seQ38/3NtUepW+PTgxXIHmwNjJV4oHsHwlBlTwJmYihKXg== 9249 + metro-minify-uglify@0.73.8: 9250 + version "0.73.8" 9251 + resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.73.8.tgz#b2e2430014c340479db4fc393a2ea4c5bad75ecd" 9252 + integrity sha512-9wZqKfraVfmtMXdOzRyan+6r1woQXqqa4KeXfVh7+Mxl+5+J0Lmw6EvTrWawsaOEpvpn32q9MfoHC1d8plDJwA== 9168 9253 dependencies: 9169 9254 uglify-es "^3.1.9" 9170 9255 9171 - metro-react-native-babel-preset@0.73.5: 9172 - version "0.73.5" 9173 - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.73.5.tgz#9b92f1ebc2b3d96f511c45a03f8e35e0fc46cc19" 9174 - integrity sha512-Ej6J8ozWSs6nrh0nwX7hgX4oPXUai40ckah37cSLu8qeED2XiEtfLV1YksTLafFE8fX0EieiP97U97dkOGHP4w== 9256 + metro-react-native-babel-preset@0.73.7: 9257 + version "0.73.7" 9258 + resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.73.7.tgz#78e1ce448aa9a5cf3651c0ebe73cb225465211b4" 9259 + integrity sha512-RKcmRZREjJCzHKP+JhC9QTCohkeb3xa/DtqHU14U5KWzJHdC0mMrkTZYNXhV0cryxsaVKVEw5873KhbZyZHMVw== 9175 9260 dependencies: 9176 - "@babel/core" "^7.14.0" 9261 + "@babel/core" "^7.20.0" 9177 9262 "@babel/plugin-proposal-async-generator-functions" "^7.0.0" 9178 9263 "@babel/plugin-proposal-class-properties" "^7.0.0" 9179 9264 "@babel/plugin-proposal-export-default-from" "^7.0.0" ··· 9183 9268 "@babel/plugin-proposal-optional-chaining" "^7.0.0" 9184 9269 "@babel/plugin-syntax-dynamic-import" "^7.0.0" 9185 9270 "@babel/plugin-syntax-export-default-from" "^7.0.0" 9186 - "@babel/plugin-syntax-flow" "^7.2.0" 9271 + "@babel/plugin-syntax-flow" "^7.18.0" 9187 9272 "@babel/plugin-syntax-nullish-coalescing-operator" "^7.0.0" 9188 9273 "@babel/plugin-syntax-optional-chaining" "^7.0.0" 9189 9274 "@babel/plugin-transform-arrow-functions" "^7.0.0" ··· 9212 9297 "@babel/template" "^7.0.0" 9213 9298 react-refresh "^0.4.0" 9214 9299 9215 - metro-react-native-babel-preset@0.73.7: 9216 - version "0.73.7" 9217 - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.73.7.tgz#78e1ce448aa9a5cf3651c0ebe73cb225465211b4" 9218 - integrity sha512-RKcmRZREjJCzHKP+JhC9QTCohkeb3xa/DtqHU14U5KWzJHdC0mMrkTZYNXhV0cryxsaVKVEw5873KhbZyZHMVw== 9300 + metro-react-native-babel-preset@0.73.8, metro-react-native-babel-preset@^0.73.7: 9301 + version "0.73.8" 9302 + resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.73.8.tgz#04908f264f5d99c944ae20b5b11f659431328431" 9303 + integrity sha512-spNrcQJTbQntEIqJnCA6yL4S+dzV9fXCk7U+Rm7yJasZ4o4Frn7jP23isu7FlZIp1Azx1+6SbP7SgQM+IP5JgQ== 9219 9304 dependencies: 9220 9305 "@babel/core" "^7.20.0" 9221 9306 "@babel/plugin-proposal-async-generator-functions" "^7.0.0" ··· 9256 9341 "@babel/template" "^7.0.0" 9257 9342 react-refresh "^0.4.0" 9258 9343 9259 - metro-react-native-babel-transformer@0.73.5: 9260 - version "0.73.5" 9261 - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.73.5.tgz#fb1d48cc73ce26371cf2a115f702b7bf3bb5516b" 9262 - integrity sha512-CZYgUguqFTzV9vSOZb60p8qlp31aWz8aBB6OqoZ2gJday+n/1k+Y0yy6VPr/tfXJheuQYVIXKvG1gMmUDyxt+Q== 9263 - dependencies: 9264 - "@babel/core" "^7.14.0" 9265 - babel-preset-fbjs "^3.4.0" 9266 - hermes-parser "0.8.0" 9267 - metro-babel-transformer "0.73.5" 9268 - metro-react-native-babel-preset "0.73.5" 9269 - metro-source-map "0.73.5" 9270 - nullthrows "^1.1.1" 9271 - 9272 9344 metro-react-native-babel-transformer@0.73.7: 9273 9345 version "0.73.7" 9274 9346 resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.73.7.tgz#a92055fd564cd403255cc34f925c5e99ce457565" ··· 9282 9354 metro-source-map "0.73.7" 9283 9355 nullthrows "^1.1.1" 9284 9356 9285 - metro-resolver@0.73.7: 9286 - version "0.73.7" 9287 - resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.73.7.tgz#1e174cf59eac84c0869172764316042b466daaa5" 9288 - integrity sha512-mGW3XPeKBCwZnkHcKo1dhFa9olcx7SyNzG1vb5kjzJYe4Qs3yx04r/qFXIJLcIgLItB69TIGvosznUhpeOOXzg== 9357 + metro-react-native-babel-transformer@0.73.8: 9358 + version "0.73.8" 9359 + resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.73.8.tgz#cbcd4b243216878431dc4311ce46f02a928e3991" 9360 + integrity sha512-oH/LCCJPauteAE28c0KJAiSrkV+1VJbU0PwA9UwaWnle+qevs/clpKQ8LrIr33YbBj4CiI1kFoVRuNRt5h4NFg== 9289 9361 dependencies: 9290 - absolute-path "^0.0.0" 9362 + "@babel/core" "^7.20.0" 9363 + babel-preset-fbjs "^3.4.0" 9364 + hermes-parser "0.8.0" 9365 + metro-babel-transformer "0.73.8" 9366 + metro-react-native-babel-preset "0.73.8" 9367 + metro-source-map "0.73.8" 9368 + nullthrows "^1.1.1" 9291 9369 9292 - metro-runtime@0.73.5: 9293 - version "0.73.5" 9294 - resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.73.5.tgz#8c92c3947e97a8dede6347ba6a9844bfb8be8258" 9295 - integrity sha512-8QJOS7bhJmR6r/Gkki/qY9oX/DdxnLhS8FpdG1Xmm2hDeUVAug12ekWTiCRMu7d1CDVv1F8WvUz09QckZ0dO0g== 9370 + metro-resolver@0.73.8: 9371 + version "0.73.8" 9372 + resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.73.8.tgz#65cc158575d130363296f66a33257c7971228640" 9373 + integrity sha512-GiBWont7/OgAftkkj2TiEp+Gf1PYZUk8xV4MbtnQjIKyy3MlGY3GbpMQ1BHih9GUQqlF0n9jsUlC2K5P0almXQ== 9296 9374 dependencies: 9297 - "@babel/runtime" "^7.0.0" 9298 - react-refresh "^0.4.0" 9375 + absolute-path "^0.0.0" 9299 9376 9300 9377 metro-runtime@0.73.7: 9301 9378 version "0.73.7" ··· 9305 9382 "@babel/runtime" "^7.0.0" 9306 9383 react-refresh "^0.4.0" 9307 9384 9308 - metro-source-map@0.73.5: 9309 - version "0.73.5" 9310 - resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.73.5.tgz#67e14bd1fcc1074b9623640ca311cd99d07426fa" 9311 - integrity sha512-58p3zNWgUrqYYjFJb0KkZ+uJurTL4oz7i5T7577b3kvTYuJ0eK4y7rtYf8EwOfMYxRAn/m20aH1Y1fHTsLUwjQ== 9385 + metro-runtime@0.73.8: 9386 + version "0.73.8" 9387 + resolved "https://registry.yarnpkg.com/metro-runtime/-/metro-runtime-0.73.8.tgz#dadae7c154fbbde24390cf7f7e7d934a2768cd18" 9388 + integrity sha512-M+Bg9M4EN5AEpJ8NkiUsawD75ifYvYfHi05w6QzHXaqOrsTeaRbbeLuOGCYxU2f/tPg17wQV97/rqUQzs9qEtA== 9312 9389 dependencies: 9313 - "@babel/traverse" "^7.14.0" 9314 - "@babel/types" "^7.20.0" 9315 - invariant "^2.2.4" 9316 - metro-symbolicate "0.73.5" 9317 - nullthrows "^1.1.1" 9318 - ob1 "0.73.5" 9319 - source-map "^0.5.6" 9320 - vlq "^1.0.0" 9390 + "@babel/runtime" "^7.0.0" 9391 + react-refresh "^0.4.0" 9321 9392 9322 9393 metro-source-map@0.73.7: 9323 9394 version "0.73.7" ··· 9333 9404 source-map "^0.5.6" 9334 9405 vlq "^1.0.0" 9335 9406 9336 - metro-symbolicate@0.73.5: 9337 - version "0.73.5" 9338 - resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.73.5.tgz#8de118be231decd55c8c70ed54deb308fdffceda" 9339 - integrity sha512-aIC8sDlaEdtn0dTt+64IFZFEATatFx3GtzRbJi0+jJx47RjDRiuCt9fzmTMLuadWwnbFK9ZfVMuWEXM9sdtQ7w== 9407 + metro-source-map@0.73.8: 9408 + version "0.73.8" 9409 + resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.73.8.tgz#5134174e3d43de26ad331b95f637944c6547d441" 9410 + integrity sha512-wozFXuBYMAy7b8BCYwC+qoXsvayVJBHWtSTlSLva99t+CoUSG9JO9kg1umzbOz28YYPxKmvb/wbnLMkHdas2cA== 9340 9411 dependencies: 9412 + "@babel/traverse" "^7.20.0" 9413 + "@babel/types" "^7.20.0" 9341 9414 invariant "^2.2.4" 9342 - metro-source-map "0.73.5" 9415 + metro-symbolicate "0.73.8" 9343 9416 nullthrows "^1.1.1" 9417 + ob1 "0.73.8" 9344 9418 source-map "^0.5.6" 9345 - through2 "^2.0.1" 9346 9419 vlq "^1.0.0" 9347 9420 9348 9421 metro-symbolicate@0.73.7: ··· 9357 9430 through2 "^2.0.1" 9358 9431 vlq "^1.0.0" 9359 9432 9360 - metro-transform-plugins@0.73.7: 9361 - version "0.73.7" 9362 - resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.73.7.tgz#49ff2571742d557f20301880f55b00054e468e52" 9363 - integrity sha512-M5isiWEau0jMudb5ezaNBZnYqXxcATMqnAYc+Cu25IahT1NHi5aWwLok9EBmBpN5641IZUZXScf+KnS7fPxPCQ== 9433 + metro-symbolicate@0.73.8: 9434 + version "0.73.8" 9435 + resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.73.8.tgz#96920f607bce484283d822ee5fe18d932f69c03d" 9436 + integrity sha512-xkBAcceYYp0GGdCCuMzkCF1ejHsd0lYlbKBkjSRgM0Nlj80VapPaSwumYoAvSaDxcbkvS7/sCjURGp5DsSFgRQ== 9437 + dependencies: 9438 + invariant "^2.2.4" 9439 + metro-source-map "0.73.8" 9440 + nullthrows "^1.1.1" 9441 + source-map "^0.5.6" 9442 + through2 "^2.0.1" 9443 + vlq "^1.0.0" 9444 + 9445 + metro-transform-plugins@0.73.8: 9446 + version "0.73.8" 9447 + resolved "https://registry.yarnpkg.com/metro-transform-plugins/-/metro-transform-plugins-0.73.8.tgz#07be7fd94a448ea1b245ab02ce7d277d757f9a32" 9448 + integrity sha512-IxjlnB5eA49M0WfvPEzvRikK3Rr6bECUUfcZt/rWpSphq/mttgyLYcHQ+VTZZl0zHolC3cTLwgoDod4IIJBn1A== 9364 9449 dependencies: 9365 9450 "@babel/core" "^7.20.0" 9366 9451 "@babel/generator" "^7.20.0" ··· 9368 9453 "@babel/traverse" "^7.20.0" 9369 9454 nullthrows "^1.1.1" 9370 9455 9371 - metro-transform-worker@0.73.7: 9372 - version "0.73.7" 9373 - resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.73.7.tgz#be111805e92ea48b7c76dd75830798f318e252e0" 9374 - integrity sha512-gZYIu9JAqEI9Rxi0xGMuMW6QsHGbMSptozlTOwOd7T7yXX3WwYS/I3yLPbLhbZTjOhwMHkTt8Nhm2qBo8nh14g== 9456 + metro-transform-worker@0.73.8: 9457 + version "0.73.8" 9458 + resolved "https://registry.yarnpkg.com/metro-transform-worker/-/metro-transform-worker-0.73.8.tgz#701a006c2b4d93f1bb24802f3f2834c963153db9" 9459 + integrity sha512-B8kR6lmcvyG4UFSF2QDfr/eEnWJvg0ZadooF8Dg6m/3JSm9OAqfSoC0YrWqAuvtWImNDnbeKWN7/+ns44Hv6tg== 9375 9460 dependencies: 9376 9461 "@babel/core" "^7.20.0" 9377 9462 "@babel/generator" "^7.20.0" 9378 9463 "@babel/parser" "^7.20.0" 9379 9464 "@babel/types" "^7.20.0" 9380 9465 babel-preset-fbjs "^3.4.0" 9381 - metro "0.73.7" 9382 - metro-babel-transformer "0.73.7" 9383 - metro-cache "0.73.7" 9384 - metro-cache-key "0.73.7" 9385 - metro-hermes-compiler "0.73.7" 9386 - metro-source-map "0.73.7" 9387 - metro-transform-plugins "0.73.7" 9466 + metro "0.73.8" 9467 + metro-babel-transformer "0.73.8" 9468 + metro-cache "0.73.8" 9469 + metro-cache-key "0.73.8" 9470 + metro-hermes-compiler "0.73.8" 9471 + metro-source-map "0.73.8" 9472 + metro-transform-plugins "0.73.8" 9388 9473 nullthrows "^1.1.1" 9389 9474 9390 - metro@0.73.7: 9391 - version "0.73.7" 9392 - resolved "https://registry.yarnpkg.com/metro/-/metro-0.73.7.tgz#435081339ac209e4d8802c57ac522638140c802b" 9393 - integrity sha512-pkRqFhuGUvkiu8HxKPUQelbCuyy6te6okMssTyLzQwsKilNLK4YMI2uD6PHnypg5SiMJ58lwfqkp/t5w72jEvw== 9475 + metro@0.73.8: 9476 + version "0.73.8" 9477 + resolved "https://registry.yarnpkg.com/metro/-/metro-0.73.8.tgz#25f014e4064eb34a4833c316e0a9094528061a8c" 9478 + integrity sha512-2EMJME9w5x7Uzn+DnQ4hzWr33u/aASaOBGdpf4lxbrlk6/vl4UBfX1sru6KU535qc/0Z1BMt4Vq9qsP3ZGFmWg== 9394 9479 dependencies: 9395 9480 "@babel/code-frame" "^7.0.0" 9396 9481 "@babel/core" "^7.20.0" ··· 9414 9499 invariant "^2.2.4" 9415 9500 jest-worker "^27.2.0" 9416 9501 lodash.throttle "^4.1.1" 9417 - metro-babel-transformer "0.73.7" 9418 - metro-cache "0.73.7" 9419 - metro-cache-key "0.73.7" 9420 - metro-config "0.73.7" 9421 - metro-core "0.73.7" 9422 - metro-file-map "0.73.7" 9423 - metro-hermes-compiler "0.73.7" 9424 - metro-inspector-proxy "0.73.7" 9425 - metro-minify-terser "0.73.7" 9426 - metro-minify-uglify "0.73.7" 9427 - metro-react-native-babel-preset "0.73.7" 9428 - metro-resolver "0.73.7" 9429 - metro-runtime "0.73.7" 9430 - metro-source-map "0.73.7" 9431 - metro-symbolicate "0.73.7" 9432 - metro-transform-plugins "0.73.7" 9433 - metro-transform-worker "0.73.7" 9502 + metro-babel-transformer "0.73.8" 9503 + metro-cache "0.73.8" 9504 + metro-cache-key "0.73.8" 9505 + metro-config "0.73.8" 9506 + metro-core "0.73.8" 9507 + metro-file-map "0.73.8" 9508 + metro-hermes-compiler "0.73.8" 9509 + metro-inspector-proxy "0.73.8" 9510 + metro-minify-terser "0.73.8" 9511 + metro-minify-uglify "0.73.8" 9512 + metro-react-native-babel-preset "0.73.8" 9513 + metro-resolver "0.73.8" 9514 + metro-runtime "0.73.8" 9515 + metro-source-map "0.73.8" 9516 + metro-symbolicate "0.73.8" 9517 + metro-transform-plugins "0.73.8" 9518 + metro-transform-worker "0.73.8" 9434 9519 mime-types "^2.1.27" 9435 9520 node-fetch "^2.2.0" 9436 9521 nullthrows "^1.1.1" ··· 9519 9604 resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" 9520 9605 integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== 9521 9606 9522 - minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: 9607 + "minimatch@2 || 3", minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: 9523 9608 version "3.1.2" 9524 9609 resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" 9525 9610 integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== ··· 9527 9612 brace-expansion "^1.1.7" 9528 9613 9529 9614 minimatch@^5.0.1: 9530 - version "5.1.2" 9531 - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.2.tgz#0939d7d6f0898acbd1508abe534d1929368a8fff" 9532 - integrity sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg== 9615 + version "5.1.6" 9616 + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" 9617 + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== 9533 9618 dependencies: 9534 9619 brace-expansion "^2.0.1" 9535 9620 9536 9621 minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6: 9537 - version "1.2.7" 9538 - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" 9539 - integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g== 9622 + version "1.2.8" 9623 + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" 9624 + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== 9540 9625 9541 9626 mixin-deep@^1.2.0: 9542 9627 version "1.3.2" ··· 9569 9654 integrity sha512-bRuZp3C0itgLKHu/VNxi66DN/XVkQG7xtoBVWxpvC5FhAqbOCP21+nPhULjnzEqd7xBMybp6KwytdUpZKEgpIQ== 9570 9655 9571 9656 mobx@^6.6.1: 9572 - version "6.7.0" 9573 - resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.7.0.tgz#2d805610fee1801fd015c54fd5400d2601aa3768" 9574 - integrity sha512-1kBLBdSNG2bA522HQdbsTvwAwYf9hq9FWxmlhX7wTsJUAI54907J+ozfGW+LoYUo06vjit748g6QH1AAGLNebw== 9657 + version "6.8.0" 9658 + resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.8.0.tgz#59051755fdb5c8a9f3f2e0a9b6abaf86bab7f843" 9659 + integrity sha512-+o/DrHa4zykFMSKfS8Z+CPSEg5LW9tSNGTuN8o6MF1GKxlfkSHSeJn5UtgxvPkGgaouplnrLXCF+duAsmm6FHQ== 9660 + 9661 + moment@^2.19.3: 9662 + version "2.29.4" 9663 + resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" 9664 + integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== 9575 9665 9576 9666 ms@2.0.0: 9577 9667 version "2.0.0" ··· 9588 9678 resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" 9589 9679 integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 9590 9680 9681 + multi-sort-stream@^1.0.3: 9682 + version "1.0.4" 9683 + resolved "https://registry.yarnpkg.com/multi-sort-stream/-/multi-sort-stream-1.0.4.tgz#e4348edc9edc36e16333e531a90c0f166235cc99" 9684 + integrity sha512-hAZ8JOEQFbgdLe8HWZbb7gdZg0/yAIHF00Qfo3kd0rXFv96nXe+/bPTrKHZ2QMHugGX4FiAyET1Lt+jiB+7Qlg== 9685 + 9591 9686 multicast-dns@^7.2.5: 9592 9687 version "7.2.5" 9593 9688 resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" ··· 9601 9696 resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.9.0.tgz#c68354e7d21037a8f1f8833c8ccd68618e8f1d37" 9602 9697 integrity sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg== 9603 9698 9699 + multipipe@^4.0.0: 9700 + version "4.0.0" 9701 + resolved "https://registry.yarnpkg.com/multipipe/-/multipipe-4.0.0.tgz#d302554ae664c1157dbfd1e8f98f03c517b3948a" 9702 + integrity sha512-jzcEAzFXoWwWwUbvHCNPwBlTz3WCWe/jPcXSmTfbo/VjRwRTfvLZ/bdvtiTdqCe8d4otCSsPCbhGYcX+eggpKQ== 9703 + dependencies: 9704 + duplexer2 "^0.1.2" 9705 + object-assign "^4.1.0" 9706 + 9707 + mv@~2: 9708 + version "2.1.1" 9709 + resolved "https://registry.yarnpkg.com/mv/-/mv-2.1.1.tgz#ae6ce0d6f6d5e0a4f7d893798d03c1ea9559b6a2" 9710 + integrity sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg== 9711 + dependencies: 9712 + mkdirp "~0.5.1" 9713 + ncp "~2.0.0" 9714 + rimraf "~2.4.0" 9715 + 9716 + nan@^2.14.0: 9717 + version "2.17.0" 9718 + resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb" 9719 + integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ== 9720 + 9604 9721 nanoid@^3.3.1, nanoid@^3.3.4: 9605 9722 version "3.3.4" 9606 9723 resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" ··· 9638 9755 resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" 9639 9756 integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== 9640 9757 9758 + ncp@~2.0.0: 9759 + version "2.0.0" 9760 + resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" 9761 + integrity sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA== 9762 + 9641 9763 negotiator@0.6.3: 9642 9764 version "0.6.3" 9643 9765 resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" ··· 9667 9789 integrity sha512-WDD0bdg9mbq6F4mRxEYcPWwfA1vxd0mrvKOyxI7Xj/atfRHVeutzuWByG//jfm4uPzp0y4Kj051EORCBSQMycw== 9668 9790 9669 9791 node-abi@^3.3.0: 9670 - version "3.31.0" 9671 - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.31.0.tgz#dfb2ea3d01188eb80859f69bb4a4354090c1b355" 9672 - integrity sha512-eSKV6s+APenqVh8ubJyiu/YhZgxQpGP66ntzUb3lY1xB9ukSRaGnx0AIxI+IM+1+IVYC1oWobgG5L3Lt9ARykQ== 9792 + version "3.33.0" 9793 + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.33.0.tgz#8b23a0cec84e1c5f5411836de6a9b84bccf26e7f" 9794 + integrity sha512-7GGVawqyHF4pfd0YFybhv/eM9JwTtPqx0mAanQ146O3FlSh3pA24zf9IRQTOsfTSqXTNzPSP5iagAJ94jjuVog== 9673 9795 dependencies: 9674 9796 semver "^7.3.5" 9675 9797 ··· 9685 9807 dependencies: 9686 9808 minimatch "^3.0.2" 9687 9809 9688 - node-fetch@2.6.7, node-fetch@^2.2.0, node-fetch@^2.6.0: 9810 + node-fetch@2.6.7: 9689 9811 version "2.6.7" 9690 9812 resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" 9691 9813 integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== 9692 9814 dependencies: 9693 9815 whatwg-url "^5.0.0" 9694 9816 9817 + node-fetch@^2.2.0, node-fetch@^2.6.0: 9818 + version "2.6.9" 9819 + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.9.tgz#7c7f744b5cc6eb5fd404e0c7a9fec630a55657e6" 9820 + integrity sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg== 9821 + dependencies: 9822 + whatwg-url "^5.0.0" 9823 + 9695 9824 node-forge@^1: 9696 9825 version "1.3.1" 9697 9826 resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" ··· 9702 9831 resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" 9703 9832 integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== 9704 9833 9705 - node-releases@^2.0.6: 9706 - version "2.0.8" 9707 - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.8.tgz#0f349cdc8fcfa39a92ac0be9bc48b7706292b9ae" 9708 - integrity sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A== 9834 + node-ipc@^9.2.1: 9835 + version "9.2.1" 9836 + resolved "https://registry.yarnpkg.com/node-ipc/-/node-ipc-9.2.1.tgz#b32f66115f9d6ce841dc4ec2009d6a733f98bb6b" 9837 + integrity sha512-mJzaM6O3xHf9VT8BULvJSbdVbmHUKRNOH7zDDkCrA1/T+CVjq2WVIDfLt0azZRXpgArJtl3rtmEozrbXPZ9GaQ== 9838 + dependencies: 9839 + event-pubsub "4.3.0" 9840 + js-message "1.0.7" 9841 + js-queue "2.0.2" 9842 + 9843 + node-releases@^2.0.8: 9844 + version "2.0.10" 9845 + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" 9846 + integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== 9709 9847 9710 9848 node-stream-zip@^1.9.1: 9711 9849 version "1.15.0" 9712 9850 resolved "https://registry.yarnpkg.com/node-stream-zip/-/node-stream-zip-1.15.0.tgz#158adb88ed8004c6c49a396b50a6a5de3bca33ea" 9713 9851 integrity sha512-LN4fydt9TqhZhThkZIVQnF9cwjU3qmUH9h78Mx/K7d3VvfRqqwthLwJEUOEL0QPZ0XQmNN7be5Ggit5+4dq3Bw== 9714 9852 9853 + node-version@^1.0.0: 9854 + version "1.2.0" 9855 + resolved "https://registry.yarnpkg.com/node-version/-/node-version-1.2.0.tgz#34fde3ffa8e1149bd323983479dda620e1b5060d" 9856 + integrity sha512-ma6oU4Sk0qOoKEAymVoTvk8EdXEobdS7m/mAGhDJ8Rouugho48crHBORAmy5BoOcv8wraPM6xumapQp5hl4iIQ== 9857 + 9715 9858 nodemailer-html-to-text@^3.2.0: 9716 9859 version "3.2.0" 9717 9860 resolved "https://registry.yarnpkg.com/nodemailer-html-to-text/-/nodemailer-html-to-text-3.2.0.tgz#91b959491fef8f7d91796047abb728aa86d4a12b" ··· 9720 9863 html-to-text "7.1.1" 9721 9864 9722 9865 nodemailer@^6.8.0: 9723 - version "6.9.0" 9724 - resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.9.0.tgz#a17488ff470ff9edf1bb31d9ec23079bc94f7dd3" 9725 - integrity sha512-jFaCEGTeT3E/m/5R2MHWiyQH3pSARECRUDM+1hokOYc3lQAAG7ASuy+2jIsYVf+RVa9zePopSQwKNVFH8DKUpA== 9866 + version "6.9.1" 9867 + resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.9.1.tgz#8249d928a43ed85fec17b13d2870c8f758a126ed" 9868 + integrity sha512-qHw7dOiU5UKNnQpXktdgQ1d3OFgRAekuvbJLcdG5dnEo/GtcTHRYM7+UfJARdOFU9WUQO8OiIamgWPmiSFHYAA== 9726 9869 9727 9870 normalize-css-color@^1.0.2: 9728 9871 version "1.0.2" ··· 9743 9886 version "6.1.0" 9744 9887 resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" 9745 9888 integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== 9889 + 9890 + normalize-url@^8.0.0: 9891 + version "8.0.0" 9892 + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-8.0.0.tgz#593dbd284f743e8dcf6a5ddf8fadff149c82701a" 9893 + integrity sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw== 9746 9894 9747 9895 npm-run-path@^2.0.0: 9748 9896 version "2.0.2" ··· 9781 9929 version "2.2.2" 9782 9930 resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.2.tgz#e5418863e7905df67d51ec95938d67bf801f0bb0" 9783 9931 integrity sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw== 9784 - 9785 - ob1@0.73.5: 9786 - version "0.73.5" 9787 - resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.73.5.tgz#b80dc4a6f787044e3d8afde3c2d034ae23d05a86" 9788 - integrity sha512-MxQH/rCq9/COvgTQbjCldArmesGEidZVVQIn4vDUJvJJ8uMphXOTCBsgWTief2ugvb0WUimIaslKSA+qryFjjQ== 9789 9932 9790 9933 ob1@0.73.7: 9791 9934 version "0.73.7" 9792 9935 resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.73.7.tgz#14c9b6ddc26cf99144f59eb542d7ae956e6b3192" 9793 9936 integrity sha512-DfelfvR843KADhSUATGGhuepVMRcf5VQX+6MQLy5AW0BKDLlO7Usj6YZeAAZP7P86QwsoTxB0RXCFiA7t6S1IQ== 9794 9937 9938 + ob1@0.73.8: 9939 + version "0.73.8" 9940 + resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.73.8.tgz#c569f1a15ce2d04da6fd70293ad44b5a93b11978" 9941 + integrity sha512-1F7j+jzD+edS6ohQP7Vg5f3yiIk5i3x1uLrNIHOmLHWzWK1t3zrDpjnoXghccdVlsU+UjbyURnDynm4p0GgXeA== 9942 + 9795 9943 object-assign@^4, object-assign@^4.1.0, object-assign@^4.1.1: 9796 9944 version "4.1.1" 9797 9945 resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" ··· 9812 9960 integrity sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw== 9813 9961 9814 9962 object-inspect@^1.12.2, object-inspect@^1.9.0: 9815 - version "1.12.2" 9816 - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" 9817 - integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== 9963 + version "1.12.3" 9964 + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" 9965 + integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== 9966 + 9967 + object-is@^1.1.5: 9968 + version "1.1.5" 9969 + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" 9970 + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== 9971 + dependencies: 9972 + call-bind "^1.0.2" 9973 + define-properties "^1.1.3" 9818 9974 9819 9975 object-keys@^1.1.1: 9820 9976 version "1.1.1" ··· 9881 10037 dependencies: 9882 10038 isobject "^3.0.1" 9883 10039 9884 - object.values@^1.1.0, object.values@^1.1.5, object.values@^1.1.6: 10040 + object.values@^1.1.0, object.values@^1.1.6: 9885 10041 version "1.1.6" 9886 10042 resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.6.tgz#4abbaa71eba47d63589d402856f908243eea9b1d" 9887 10043 integrity sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw== ··· 9946 10102 is-wsl "^1.1.0" 9947 10103 9948 10104 open@^8.0.9, open@^8.4.0: 9949 - version "8.4.0" 9950 - resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" 9951 - integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== 10105 + version "8.4.2" 10106 + resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" 10107 + integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== 9952 10108 dependencies: 9953 10109 define-lazy-prop "^2.0.0" 9954 10110 is-docker "^2.1.1" ··· 10204 10360 resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.5.2.tgz#ed1bed1fb8d79f1c6fd5fb1c99e990fbf9ddf178" 10205 10361 integrity sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w== 10206 10362 10207 - pg-protocol@^1.5.0: 10208 - version "1.5.0" 10209 - resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.5.0.tgz#b5dd452257314565e2d54ab3c132adc46565a6a0" 10210 - integrity sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ== 10363 + pg-protocol@^1.6.0: 10364 + version "1.6.0" 10365 + resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.6.0.tgz#4c91613c0315349363af2084608db843502f8833" 10366 + integrity sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q== 10211 10367 10212 10368 pg-types@^2.1.0: 10213 10369 version "2.2.0" ··· 10221 10377 postgres-interval "^1.1.0" 10222 10378 10223 10379 pg@^8.8.0: 10224 - version "8.8.0" 10225 - resolved "https://registry.yarnpkg.com/pg/-/pg-8.8.0.tgz#a77f41f9d9ede7009abfca54667c775a240da686" 10226 - integrity sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw== 10380 + version "8.9.0" 10381 + resolved "https://registry.yarnpkg.com/pg/-/pg-8.9.0.tgz#73c5d77a854d36b0e185450dacb8b90c669e040b" 10382 + integrity sha512-ZJM+qkEbtOHRuXjmvBtOgNOXOtLSbxiMiUVMgE4rV6Zwocy03RicCVvDXgx8l4Biwo8/qORUnEqn2fdQzV7KCg== 10227 10383 dependencies: 10228 10384 buffer-writer "2.0.0" 10229 10385 packet-reader "1.0.0" 10230 10386 pg-connection-string "^2.5.0" 10231 10387 pg-pool "^3.5.2" 10232 - pg-protocol "^1.5.0" 10388 + pg-protocol "^1.6.0" 10233 10389 pg-types "^2.1.0" 10234 10390 pgpass "1.x" 10235 10391 ··· 10274 10430 split2 "^4.0.0" 10275 10431 10276 10432 pino-http@^8.2.1: 10277 - version "8.3.1" 10278 - resolved "https://registry.yarnpkg.com/pino-http/-/pino-http-8.3.1.tgz#d33ade22044ce6efa7b5ed512e1bd7afdf9904ba" 10279 - integrity sha512-wqQMH2H+Di4ur5gaCYvWOMYhGmmmygHsgJduKr2HASSoegNsxfxiCDGxYYV8muOB8jKDHPoBXKGp03af+JESqg== 10433 + version "8.3.3" 10434 + resolved "https://registry.yarnpkg.com/pino-http/-/pino-http-8.3.3.tgz#2b140e734bfc6babe0df272a43bb8f36f2b525c0" 10435 + integrity sha512-p4umsNIXXVu95HD2C8wie/vXH7db5iGRpc+yj1/ZQ3sRtTQLXNjoS6Be5+eI+rQbqCRxen/7k/KSN+qiZubGDw== 10280 10436 dependencies: 10281 - fast-url-parser "^1.1.3" 10282 10437 get-caller-file "^2.0.5" 10283 10438 pino "^8.0.0" 10284 10439 pino-std-serializers "^6.0.0" ··· 10290 10445 integrity sha512-KO0m2f1HkrPe9S0ldjx7za9BJjeHqBku5Ch8JyxETxT8dEFGz1PwgrHaOQupVYitpzbFSYm7nnljxD8dik2c+g== 10291 10446 10292 10447 pino@^8.0.0, pino@^8.6.1: 10293 - version "8.8.0" 10294 - resolved "https://registry.yarnpkg.com/pino/-/pino-8.8.0.tgz#1f0d6695a224aa06afc7ad60f2ccc4772d3b9233" 10295 - integrity sha512-cF8iGYeu2ODg2gIwgAHcPrtR63ILJz3f7gkogaHC/TXVVXxZgInmNYiIpDYEwgEkxZti2Se6P2W2DxlBIZe6eQ== 10448 + version "8.11.0" 10449 + resolved "https://registry.yarnpkg.com/pino/-/pino-8.11.0.tgz#2a91f454106b13e708a66c74ebc1c2ab7ab38498" 10450 + integrity sha512-Z2eKSvlrl2rH8p5eveNUnTdd4AjJk8tAsLkHYZQKGHP4WTh2Gi1cOSOs3eWPqaj+niS3gj4UkoreoaWgF3ZWYg== 10296 10451 dependencies: 10297 10452 atomic-sleep "^1.0.0" 10298 10453 fast-redact "^3.1.1" ··· 10385 10540 dependencies: 10386 10541 postcss-value-parser "^4.2.0" 10387 10542 10388 - postcss-colormin@^5.3.0: 10389 - version "5.3.0" 10390 - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.0.tgz#3cee9e5ca62b2c27e84fce63affc0cfb5901956a" 10391 - integrity sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg== 10543 + postcss-colormin@^5.3.1: 10544 + version "5.3.1" 10545 + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.1.tgz#86c27c26ed6ba00d96c79e08f3ffb418d1d1988f" 10546 + integrity sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ== 10392 10547 dependencies: 10393 - browserslist "^4.16.6" 10548 + browserslist "^4.21.4" 10394 10549 caniuse-api "^3.0.0" 10395 10550 colord "^2.9.1" 10396 10551 postcss-value-parser "^4.2.0" ··· 10517 10672 integrity sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ== 10518 10673 10519 10674 postcss-js@^4.0.0: 10520 - version "4.0.0" 10521 - resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.0.tgz#31db79889531b80dc7bc9b0ad283e418dce0ac00" 10522 - integrity sha512-77QESFBwgX4irogGVPgQ5s07vLvFqWr228qZY+w6lW599cRlK/HmnlivnnVUxkjHnCu4J16PDMHcH+e+2HbvTQ== 10675 + version "4.0.1" 10676 + resolved "https://registry.yarnpkg.com/postcss-js/-/postcss-js-4.0.1.tgz#61598186f3703bab052f1c4f7d805f3991bee9d2" 10677 + integrity sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw== 10523 10678 dependencies: 10524 10679 camelcase-css "^2.0.1" 10525 10680 ··· 10566 10721 postcss-value-parser "^4.2.0" 10567 10722 stylehacks "^5.1.1" 10568 10723 10569 - postcss-merge-rules@^5.1.3: 10570 - version "5.1.3" 10571 - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.3.tgz#8f97679e67cc8d08677a6519afca41edf2220894" 10572 - integrity sha512-LbLd7uFC00vpOuMvyZop8+vvhnfRGpp2S+IMQKeuOZZapPRY4SMq5ErjQeHbHsjCUgJkRNrlU+LmxsKIqPKQlA== 10724 + postcss-merge-rules@^5.1.4: 10725 + version "5.1.4" 10726 + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz#2f26fa5cacb75b1402e213789f6766ae5e40313c" 10727 + integrity sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g== 10573 10728 dependencies: 10574 10729 browserslist "^4.21.4" 10575 10730 caniuse-api "^3.0.0" ··· 10817 10972 dependencies: 10818 10973 postcss-selector-parser "^6.0.10" 10819 10974 10820 - postcss-reduce-initial@^5.1.1: 10821 - version "5.1.1" 10822 - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.1.tgz#c18b7dfb88aee24b1f8e4936541c29adbd35224e" 10823 - integrity sha512-//jeDqWcHPuXGZLoolFrUXBDyuEGbr9S2rMo19bkTIjBQ4PqkaO+oI8wua5BOUxpfi97i3PCoInsiFIEBfkm9w== 10975 + postcss-reduce-initial@^5.1.2: 10976 + version "5.1.2" 10977 + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz#798cd77b3e033eae7105c18c9d371d989e1382d6" 10978 + integrity sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg== 10824 10979 dependencies: 10825 10980 browserslist "^4.21.4" 10826 10981 caniuse-api "^3.0.0" ··· 10844 10999 dependencies: 10845 11000 postcss-selector-parser "^6.0.10" 10846 11001 10847 - postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: 11002 + postcss-selector-parser@^6.0.10, postcss-selector-parser@^6.0.11, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: 10848 11003 version "6.0.11" 10849 11004 resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz#2e41dc39b7ad74046e1615185185cd0b17d0c8dc" 10850 11005 integrity sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g== ··· 10880 11035 picocolors "^0.2.1" 10881 11036 source-map "^0.6.1" 10882 11037 10883 - postcss@^8.3.5, postcss@^8.4.18, postcss@^8.4.19, postcss@^8.4.4: 10884 - version "8.4.20" 10885 - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.20.tgz#64c52f509644cecad8567e949f4081d98349dc56" 10886 - integrity sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g== 11038 + postcss@^8.0.9, postcss@^8.3.5, postcss@^8.4.19, postcss@^8.4.4: 11039 + version "8.4.21" 11040 + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.21.tgz#c639b719a57efc3187b13a1d765675485f4134f4" 11041 + integrity sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg== 10887 11042 dependencies: 10888 11043 nanoid "^3.3.4" 10889 11044 picocolors "^1.0.0" ··· 10947 11102 fast-diff "^1.1.2" 10948 11103 10949 11104 prettier@^2.8.3: 10950 - version "2.8.3" 10951 - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.3.tgz#ab697b1d3dd46fb4626fbe2f543afe0cc98d8632" 10952 - integrity sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw== 11105 + version "2.8.4" 11106 + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.4.tgz#34dd2595629bfbb79d344ac4a91ff948694463c3" 11107 + integrity sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw== 10953 11108 10954 11109 pretty-bytes@^5.3.0, pretty-bytes@^5.4.1: 10955 11110 version "5.6.0" ··· 10993 11148 ansi-styles "^5.0.0" 10994 11149 react-is "^18.0.0" 10995 11150 10996 - pretty-format@^29.0.0, pretty-format@^29.0.3, pretty-format@^29.3.1: 10997 - version "29.3.1" 10998 - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.3.1.tgz#1841cac822b02b4da8971dacb03e8a871b4722da" 10999 - integrity sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg== 11151 + pretty-format@^29.0.3, pretty-format@^29.4.0, pretty-format@^29.4.3: 11152 + version "29.4.3" 11153 + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.4.3.tgz#25500ada21a53c9e8423205cf0337056b201244c" 11154 + integrity sha512-cvpcHTc42lcsvOOAzd3XuNWTcvk1Jmnzqeu+WsOuiPmxUJTnkbAcFNsRKvEpBEUFVUgy/GTZLulZDcDEi+CIlA== 11000 11155 dependencies: 11001 - "@jest/schemas" "^29.0.0" 11156 + "@jest/schemas" "^29.4.3" 11002 11157 ansi-styles "^5.0.0" 11003 11158 react-is "^18.0.0" 11004 11159 ··· 11017 11172 resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" 11018 11173 integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== 11019 11174 11020 - promise.allsettled@^1.0.5: 11021 - version "1.0.6" 11022 - resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.6.tgz#8dc8ba8edf429feb60f8e81335b920e109c94b6e" 11023 - integrity sha512-22wJUOD3zswWFqgwjNHa1965LvqTX87WPu/lreY2KSd7SVcERfuZ4GfUaOnJNnvtoIv2yXT/W00YIGMetXtFXg== 11024 - dependencies: 11025 - array.prototype.map "^1.0.5" 11026 - call-bind "^1.0.2" 11027 - define-properties "^1.1.4" 11028 - es-abstract "^1.20.4" 11029 - get-intrinsic "^1.1.3" 11030 - iterate-value "^1.0.2" 11175 + promise-polyfill@^6.0.1: 11176 + version "6.1.0" 11177 + resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-6.1.0.tgz#dfa96943ea9c121fca4de9b5868cb39d3472e057" 11178 + integrity sha512-g0LWaH0gFsxovsU7R5LrrhHhWAWiHRnh1GPrhXnPgYsDkIqjRYUYSZEsej/wtleDrz5xVSIDbeKfidztp2XHFQ== 11031 11179 11032 11180 promise@^7.1.1: 11033 11181 version "7.3.1" ··· 11060 11208 object-assign "^4.1.1" 11061 11209 react-is "^16.13.1" 11062 11210 11211 + proper-lockfile@^3.0.2: 11212 + version "3.2.0" 11213 + resolved "https://registry.yarnpkg.com/proper-lockfile/-/proper-lockfile-3.2.0.tgz#89ca420eea1d55d38ca552578851460067bcda66" 11214 + integrity sha512-iMghHHXv2bsxl6NchhEaFck8tvX3F9cknEEh1SUpguUOBjN7PAAW9BLzmbc1g/mCD1gY3EE2EABBHPJfFdHFmA== 11215 + dependencies: 11216 + graceful-fs "^4.1.11" 11217 + retry "^0.12.0" 11218 + signal-exit "^3.0.2" 11219 + 11063 11220 proxy-addr@~2.0.7: 11064 11221 version "2.0.7" 11065 11222 resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" ··· 11067 11224 dependencies: 11068 11225 forwarded "0.2.0" 11069 11226 ipaddr.js "1.9.1" 11227 + 11228 + pseudomap@^1.0.2: 11229 + version "1.0.2" 11230 + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" 11231 + integrity sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ== 11070 11232 11071 11233 psl@^1.1.33: 11072 11234 version "1.9.0" ··· 11081 11243 end-of-stream "^1.1.0" 11082 11244 once "^1.3.1" 11083 11245 11084 - punycode@^1.3.2: 11085 - version "1.4.1" 11086 - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" 11087 - integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== 11088 - 11089 11246 punycode@^2.1.0, punycode@^2.1.1: 11090 - version "2.1.1" 11091 - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" 11092 - integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A== 11247 + version "2.3.0" 11248 + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" 11249 + integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== 11093 11250 11094 11251 q@^1.1.2: 11095 11252 version "1.5.1" 11096 11253 resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" 11097 11254 integrity sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw== 11098 11255 11099 - qs@6.11.0: 11256 + qs@6.11.0, qs@^6.5.1: 11100 11257 version "6.11.0" 11101 11258 resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" 11102 11259 integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== ··· 11219 11376 text-table "^0.2.0" 11220 11377 11221 11378 react-devtools-core@^4.26.1: 11222 - version "4.27.1" 11223 - resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.27.1.tgz#167aa174383c65786cbb7e965a5b39c702f0a2d3" 11224 - integrity sha512-qXhcxxDWiFmFAOq48jts9YQYe1+wVoUXzJTlY4jbaATzyio6dd6CUGu3dXBhREeVgpZ+y4kg6vFJzIOZh6vY2w== 11379 + version "4.27.2" 11380 + resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.27.2.tgz#d20fc57e258c656eedabafc2c851d38b33583148" 11381 + integrity sha512-8SzmIkpO87alD7Xr6gWIEa1jHkMjawOZ+6egjazlnjB4UUcbnzGDf/vBJ4BzGuWWEM+pzrxuzsPpcMqlQkYK2g== 11225 11382 dependencies: 11226 11383 shell-quote "^1.6.1" 11227 11384 ws "^7" ··· 11270 11427 integrity sha512-/qe86laa0n4AbD6mrLL8SCGR+K5693URX95e02/bTJh3UkdS3+sU1Jyc/XTlz4MQwlquI929/lm5EZh8AOUqzQ== 11271 11428 11272 11429 react-native-codegen@^0.71.3: 11273 - version "0.71.3" 11274 - resolved "https://registry.yarnpkg.com/react-native-codegen/-/react-native-codegen-0.71.3.tgz#75fbc591819050791319ebdb9fe341ee4df5c288" 11275 - integrity sha512-5AvdHVU1sAaXg05i0dG664ZTaCaIFaY1znV5vNsj+wUu6MGxNEUNbDKk9dxKUkkxOyk2KZOK5uhzWL0p5H5yZQ== 11430 + version "0.71.5" 11431 + resolved "https://registry.yarnpkg.com/react-native-codegen/-/react-native-codegen-0.71.5.tgz#454a42a891cd4ca5fc436440d301044dc1349c14" 11432 + integrity sha512-rfsuc0zkuUuMjFnrT55I1mDZ+pBRp2zAiRwxck3m6qeGJBGK5OV5JH66eDQ4aa+3m0of316CqrJDRzVlYufzIg== 11276 11433 dependencies: 11277 11434 "@babel/parser" "^7.14.0" 11278 11435 flow-parser "^0.185.0" ··· 11280 11437 nullthrows "^1.1.1" 11281 11438 11282 11439 react-native-dotenv@^3.3.1: 11283 - version "3.4.6" 11284 - resolved "https://registry.yarnpkg.com/react-native-dotenv/-/react-native-dotenv-3.4.6.tgz#7860f9b4543789f661765a0e7c3f40914133fa4e" 11285 - integrity sha512-OS+XdceNZmfFTIobQg8J5ZT6979Dr3j5GTgsIzu1JDdKV2IjIfYBTryTT3hJ8VMwdj5WiaredmZEVWwrRIwdtg== 11440 + version "3.4.7" 11441 + resolved "https://registry.yarnpkg.com/react-native-dotenv/-/react-native-dotenv-3.4.7.tgz#131374dd5c22b1173f7025b2a3b4e124b0142e03" 11442 + integrity sha512-GqUDdmrtKw7qYS9jjQLipEPctMd0YuSBNVZBNlaHtaHMJ63iaB4FABO4uX0iSUJpgMwozZki4fRv4dDHmVUoLg== 11286 11443 dependencies: 11287 11444 dotenv "^16.0.3" 11445 + 11446 + react-native-fast-image@^8.6.3: 11447 + version "8.6.3" 11448 + resolved "https://registry.yarnpkg.com/react-native-fast-image/-/react-native-fast-image-8.6.3.tgz#6edc3f9190092a909d636d93eecbcc54a8822255" 11449 + integrity sha512-Sdw4ESidXCXOmQ9EcYguNY2swyoWmx53kym2zRsvi+VeFCHEdkO+WG1DK+6W81juot40bbfLNhkc63QnWtesNg== 11288 11450 11289 11451 react-native-fs@^2.20.0: 11290 11452 version "2.20.0" ··· 11295 11457 utf8 "^3.0.0" 11296 11458 11297 11459 react-native-gesture-handler@^2.5.0: 11298 - version "2.8.0" 11299 - resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-2.8.0.tgz#ef9857871c10663c95a51546225b6e00cd4740cf" 11300 - integrity sha512-poOSfz/w0IyD6Qwq7aaIRRfEaVTl1ecQFoyiIbpOpfNTjm2B1niY2FLrdVQIOtIOe+K9nH55Qal04nr4jGkHdQ== 11460 + version "2.9.0" 11461 + resolved "https://registry.yarnpkg.com/react-native-gesture-handler/-/react-native-gesture-handler-2.9.0.tgz#2f63812e523c646f25b9ad660fc6f75948e51241" 11462 + integrity sha512-a0BcH3Qb1tgVqUutc6d3VuWQkI1AM3+fJx8dkxzZs9t06qA27QgURYFoklpabuWpsUTzuKRpxleykp25E8m7tg== 11301 11463 dependencies: 11302 11464 "@egjs/hammerjs" "^2.0.17" 11303 11465 hoist-non-react-statics "^3.3.0" ··· 11305 11467 lodash "^4.17.21" 11306 11468 prop-types "^15.7.2" 11307 11469 11308 - react-native-gradle-plugin@^0.71.12: 11309 - version "0.71.12" 11310 - resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.71.12.tgz#7f0000b3d9593288183a13889fd6225d0ab506b8" 11311 - integrity sha512-ILujN0C+cX5QHmm22MXbHqZR619OzV/VThLHFhe7qnzZWpPh8O4KSvbtezoYMiBbmowAfy8SQpohwlN3nv6wZQ== 11470 + react-native-gradle-plugin@^0.71.13: 11471 + version "0.71.15" 11472 + resolved "https://registry.yarnpkg.com/react-native-gradle-plugin/-/react-native-gradle-plugin-0.71.15.tgz#9e6b506f30729fe8eb086981702f4e3c891d2b13" 11473 + integrity sha512-7S3pAuPaQJlhax6EZ4JMsDNpj05TfuzX9gPgWLrFfAIWIFLuJ6aDQYAZy2TEI9QJALPoWrj8LWaqP/DGYh14pw== 11312 11474 11313 11475 react-native-haptic-feedback@^1.14.0: 11314 11476 version "1.14.0" ··· 11334 11496 integrity sha512-Z8Xxvupsex+9BBFoSYS87bilNPWcRfRsGC0cpJk72Nxb5p2nEkGSBv73xZbEHnW2mUFvP+huYxrVvjZkr/gRjQ== 11335 11497 11336 11498 react-native-pager-view@^6.0.2: 11337 - version "6.1.2" 11338 - resolved "https://registry.yarnpkg.com/react-native-pager-view/-/react-native-pager-view-6.1.2.tgz#3522079b9a9d6634ca5e8d153bc0b4d660254552" 11339 - integrity sha512-qs2KSFc+7N7B+UZ6SG2sTvCkppagm5fVyRclv1KFKc7lDtrhXLzN59tXJw575LDP/dRJoXsNwqUAhZJdws6ABQ== 11499 + version "6.1.4" 11500 + resolved "https://registry.yarnpkg.com/react-native-pager-view/-/react-native-pager-view-6.1.4.tgz#3a63ebd1b72f81991157ea552bb9c887e529bc8c" 11501 + integrity sha512-fmTwgGwPxGCBusKAq7gHzm+s1Yp0qh5rKPoQszaCuxrb+76KgK4Qe82jJNPUp2xTZOKSw+FbJU2QahF8ncTl+w== 11502 + 11503 + react-native-permissions@^3.6.1: 11504 + version "3.6.1" 11505 + resolved "https://registry.yarnpkg.com/react-native-permissions/-/react-native-permissions-3.6.1.tgz#73adcc1cef8cd57a9ef167b4507405f4ff5749c4" 11506 + integrity sha512-fzPpPQXeD34inUccqtoResSwYubfrwUguP4qrVUUv8+KSMjYSaHGoS5HaIJLZHlN9gO+TvLJZ2L5ZljTsb6qnQ== 11340 11507 11341 11508 react-native-progress@^5.0.0: 11342 11509 version "5.0.0" ··· 11346 11513 prop-types "^15.7.2" 11347 11514 11348 11515 react-native-reanimated@^2.9.1: 11349 - version "2.13.0" 11350 - resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-2.13.0.tgz#d64c1386626822d4dc22094b4efe028ff2c49cc9" 11351 - integrity sha512-yUHyYVIegWWIza4+nVyS3CSmI/Mc8kLFVHw2c6gnSHaYhYA4LeEjH/jBkoMzHk9Xd0Ra3cwtjYKAMG8OTp6JVg== 11516 + version "2.14.4" 11517 + resolved "https://registry.yarnpkg.com/react-native-reanimated/-/react-native-reanimated-2.14.4.tgz#3fa3da4e7b99f5dfb28f86bcf24d9d1024d38836" 11518 + integrity sha512-DquSbl7P8j4SAmc+kRdd75Ianm8G+IYQ9T4AQ6lrpLVeDkhZmjWI0wkutKWnp6L7c5XNVUrFDUf69dwETLCItQ== 11352 11519 dependencies: 11353 11520 "@babel/plugin-transform-object-assign" "^7.16.7" 11354 11521 "@babel/preset-typescript" "^7.16.7" 11355 - "@types/invariant" "^2.2.35" 11522 + convert-source-map "^1.7.0" 11356 11523 invariant "^2.2.4" 11357 11524 lodash.isequal "^4.5.0" 11358 11525 setimmediate "^1.0.5" ··· 11364 11531 integrity sha512-sdmLElNs5PDWqmZmj4/aNH4anyxreaPm61c4ZkRiR8SO/GzLg6KjAbb0e17RmMdnBdD0AIQbS38h/l55YKN4ZA== 11365 11532 11366 11533 react-native-root-toast@^3.4.0: 11367 - version "3.4.0" 11368 - resolved "https://registry.yarnpkg.com/react-native-root-toast/-/react-native-root-toast-3.4.0.tgz#f5fedc06c80b0ed20a93be8832d32e9a67762187" 11369 - integrity sha512-2jv9XG9tK0rbXkD3IaO/clSJJQYXRnOCnGliZnYP/Z6I3u2QtdOp5xQ/ni8BbLqpPwSeKfCuO7R9H6iHuAN+Ig== 11534 + version "3.4.1" 11535 + resolved "https://registry.yarnpkg.com/react-native-root-toast/-/react-native-root-toast-3.4.1.tgz#8832dcf9d7f6296f689b2c02dd6cab125d9aa040" 11536 + integrity sha512-rZFoaVZWZiPCcwP9n5a+1KtVM22JNp6pkodluCoRIb5oE2ip8mhpdvlZUIWoM5nxfmL4TBThWDp7se6j4X7lPA== 11370 11537 dependencies: 11371 11538 deprecated-react-native-prop-types "^2.3.0" 11372 11539 prop-types "^15.5.10" 11373 11540 react-native-root-siblings "^4.0.0" 11374 11541 11375 11542 react-native-safe-area-context@^4.4.1: 11376 - version "4.4.1" 11377 - resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-4.4.1.tgz#239c60b8a9a80eac70a38a822b04c0f1d15ffc01" 11378 - integrity sha512-N9XTjiuD73ZpVlejHrUWIFZc+6Z14co1K/p1IFMkImU7+avD69F3y+lhkqA2hN/+vljdZrBSiOwXPkuo43nFQA== 11543 + version "4.5.0" 11544 + resolved "https://registry.yarnpkg.com/react-native-safe-area-context/-/react-native-safe-area-context-4.5.0.tgz#9208313236e8f49e1920ac1e2a2c975f03aed284" 11545 + integrity sha512-0WORnk9SkREGUg2V7jHZbuN5x4vcxj/1B0QOcXJjdYWrzZHgLcUzYWWIUecUPJh747Mwjt/42RZDOaFn3L8kPQ== 11379 11546 11380 11547 react-native-screens@^3.13.1: 11381 - version "3.18.2" 11382 - resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-3.18.2.tgz#d7ab2d145258d3db9fa630fa5379dc4474117866" 11383 - integrity sha512-ANUEuvMUlsYJ1QKukEhzhfrvOUO9BVH9Nzg+6eWxpn3cfD/O83yPBOF8Mx6x5H/2+sMy+VS5x/chWOOo/U7QJw== 11548 + version "3.20.0" 11549 + resolved "https://registry.yarnpkg.com/react-native-screens/-/react-native-screens-3.20.0.tgz#4d154177395e5541387d9a05bc2e12e54d2fb5b1" 11550 + integrity sha512-joWUKWAVHxymP3mL9gYApFHAsbd9L6ZcmpoZa6Sl3W/82bvvNVMqcfP7MeNqVCg73qZ8yL4fW+J/syusHleUgg== 11384 11551 dependencies: 11385 11552 react-freeze "^1.0.0" 11386 11553 warn-once "^0.1.0" ··· 11391 11558 integrity sha512-rGjt6HkoSXxMqH4SQUJ1gnPQlPJV8+J47+4yhgTIan4bVvAwJhEeJH7wWt9hXSdH4+VfwTS0GTaflj1Tw83IhA== 11392 11559 11393 11560 react-native-svg@^12.4.0: 11394 - version "12.5.0" 11395 - resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-12.5.0.tgz#61e4395eb5eb52bbd0511b3c227473f7dbf98a16" 11396 - integrity sha512-xVMA6QjwU2E30DHLzjmewjHSmby4mMMlUaiKnFCYPWpsezsaB3zHS7eURwKNJLmcRYOPi3f6aBhxvFTNj/5j/A== 11561 + version "12.5.1" 11562 + resolved "https://registry.yarnpkg.com/react-native-svg/-/react-native-svg-12.5.1.tgz#7dfd9daf2f8ed7843c0f3e7a16af193bd5f9b287" 11563 + integrity sha512-c374ENsq2MWCfr+7jC7TGwSeOAuC1Dp0osh2pw8PjpYFxmmB/toFIwcnCLz+SgBd6iLJClRhbATealqM05HOGg== 11397 11564 dependencies: 11398 11565 css-select "^5.1.0" 11399 11566 css-tree "^1.1.3" 11400 11567 11401 11568 react-native-tab-view@^3.3.0: 11402 - version "3.3.4" 11403 - resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-3.3.4.tgz#856d4527f3bbf05e2649302ec80abe9f2f004666" 11404 - integrity sha512-rceAYWpHa6knA7tsTnnjlcOxlCErR4F+yXQPpNm125IvYFyv09YRhE5uMU2IzyPIQ1CJvADCHurF3KySzVI+4Q== 11569 + version "3.5.0" 11570 + resolved "https://registry.yarnpkg.com/react-native-tab-view/-/react-native-tab-view-3.5.0.tgz#eee4af05708578a1a0c6bcd2c98bf9f204778cc6" 11571 + integrity sha512-Dvvs54zPtI4f8x6GuTGy4VUMeMSnmjQFa0PsJkogWuRnxcYT+CunCDMOvxzSesh2AbL6UaTNPmTQ0Le9ybYsHg== 11405 11572 dependencies: 11406 11573 use-latest-callback "^0.1.5" 11407 11574 ··· 11427 11594 resolved "https://registry.yarnpkg.com/react-native-web-linear-gradient/-/react-native-web-linear-gradient-1.1.2.tgz#33f85f7085a0bb5ffa5106faf02ed105b92a9ed7" 11428 11595 integrity sha512-SmUnpwT49CEe78pXvIvYf72Es8Pv+ZYKCnEOgb2zAKpEUDMo0+xElfRJhwt5nfI8krJ5WbFPKnoDgD0uUjAN1A== 11429 11596 11597 + react-native-web-webview@^1.0.2: 11598 + version "1.0.2" 11599 + resolved "https://registry.yarnpkg.com/react-native-web-webview/-/react-native-web-webview-1.0.2.tgz#c215efa70c17589f2c8d640b1f1dc669b18c6e02" 11600 + integrity sha512-oNAYNuqUqeqTuAAdIejzDqvUtYA+k5lrvhUYmASdUznZNmyIaoQFA6OKoA4K9F3wdMvark42vUXkUWIp875ewg== 11601 + dependencies: 11602 + qs "^6.5.1" 11603 + 11430 11604 react-native-web@^0.18.11: 11431 11605 version "0.18.12" 11432 11606 resolved "https://registry.yarnpkg.com/react-native-web/-/react-native-web-0.18.12.tgz#d4bb3a783ece2514ba0508d7805b09c0a98f5a8e" ··· 11440 11614 postcss-value-parser "^4.2.0" 11441 11615 styleq "^0.1.2" 11442 11616 11443 - react-native@0.71.0: 11444 - version "0.71.0" 11445 - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.71.0.tgz#ce47c3cb6239484fcd686d1f45b363b7014b6c62" 11446 - integrity sha512-b5oCS/cPVqXT5E2K+0CfQMERAoRu6/6g1no9XRAcjQ4b5JG608WgDh5QgXPHaMSVhAvsJ1DuRoU8C/xqTjQITA== 11617 + react-native-webview@^11.26.1: 11618 + version "11.26.1" 11619 + resolved "https://registry.yarnpkg.com/react-native-webview/-/react-native-webview-11.26.1.tgz#658c09ed5162dc170b361e48c2dd26c9712879da" 11620 + integrity sha512-hC7BkxOpf+z0UKhxFSFTPAM4shQzYmZHoELa6/8a/MspcjEP7ukYKpuSUTLDywQditT8yI9idfcKvfZDKQExGw== 11621 + dependencies: 11622 + escape-string-regexp "2.0.0" 11623 + invariant "2.2.4" 11624 + 11625 + react-native-youtube-iframe@^2.2.2: 11626 + version "2.2.2" 11627 + resolved "https://registry.yarnpkg.com/react-native-youtube-iframe/-/react-native-youtube-iframe-2.2.2.tgz#ade1a2e4ead3d539fbb80463f45b59ff1b510b55" 11628 + integrity sha512-og2KW21kCwAHKcnWoyWWBYC6J2Xtqjjwpghhoy9G6zfwZkr8Ej27BbQIAKM/TheJJUZ5/YUrqsgqAdnFYDx5TQ== 11629 + dependencies: 11630 + events "^3.2.0" 11631 + 11632 + react-native@0.71.1: 11633 + version "0.71.1" 11634 + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.71.1.tgz#72b45af2b29e3d5a660c63425ab5003bf2112f99" 11635 + integrity sha512-bLP5+IBj2IX6tgF9WnC/UL2ZPYkVUPsU4xqZV1jntTC2TH4xyLrvfKACjGlz5nQ3Mx4BmOFqsnMxithm53+6Aw== 11447 11636 dependencies: 11448 11637 "@jest/create-cache-key-function" "^29.2.1" 11449 - "@react-native-community/cli" "10.0.0" 11450 - "@react-native-community/cli-platform-android" "10.0.0" 11451 - "@react-native-community/cli-platform-ios" "10.0.0" 11638 + "@react-native-community/cli" "10.1.3" 11639 + "@react-native-community/cli-platform-android" "10.1.3" 11640 + "@react-native-community/cli-platform-ios" "10.1.1" 11452 11641 "@react-native/assets" "1.0.0" 11453 11642 "@react-native/normalize-color" "2.1.0" 11454 11643 "@react-native/polyfills" "2.0.0" ··· 11461 11650 jest-environment-node "^29.2.1" 11462 11651 jsc-android "^250230.2.1" 11463 11652 memoize-one "^5.0.0" 11464 - metro-react-native-babel-transformer "0.73.5" 11465 - metro-runtime "0.73.5" 11466 - metro-source-map "0.73.5" 11653 + metro-react-native-babel-transformer "0.73.7" 11654 + metro-runtime "0.73.7" 11655 + metro-source-map "0.73.7" 11467 11656 mkdirp "^0.5.1" 11468 11657 nullthrows "^1.1.1" 11469 11658 pretty-format "^26.5.2" 11470 11659 promise "^8.3.0" 11471 11660 react-devtools-core "^4.26.1" 11472 11661 react-native-codegen "^0.71.3" 11473 - react-native-gradle-plugin "^0.71.12" 11662 + react-native-gradle-plugin "^0.71.13" 11474 11663 react-refresh "^0.4.0" 11475 11664 react-shallow-renderer "^16.15.0" 11476 11665 regenerator-runtime "^0.13.2" ··· 11576 11765 dependencies: 11577 11766 pify "^2.3.0" 11578 11767 11579 - readable-stream@^2.0.1, readable-stream@~2.3.6: 11768 + readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@~2.3.6: 11580 11769 version "2.3.7" 11581 11770 resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" 11582 11771 integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== ··· 11715 11904 resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" 11716 11905 integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== 11717 11906 11718 - regexpu-core@^5.2.1: 11719 - version "5.2.2" 11720 - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.2.2.tgz#3e4e5d12103b64748711c3aad69934d7718e75fc" 11721 - integrity sha512-T0+1Zp2wjF/juXMrMxHxidqGYn8U4R+zleSJhX9tQ1PUsS8a9UtYfbsF9LdiVgNX3kiX8RNaKM42nfSgvFJjmw== 11907 + regexpu-core@^5.3.1: 11908 + version "5.3.1" 11909 + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.1.tgz#66900860f88def39a5cb79ebd9490e84f17bcdfb" 11910 + integrity sha512-nCOzW2V/X15XpLsK2rlgdwrysrBq+AauCn+omItIz4R1pIcmeot5zvjdmOBRLzEH/CkC6IxMJVmxDe3QcMuNVQ== 11722 11911 dependencies: 11912 + "@babel/regjsgen" "^0.8.0" 11723 11913 regenerate "^1.4.2" 11724 11914 regenerate-unicode-properties "^10.1.0" 11725 - regjsgen "^0.7.1" 11726 11915 regjsparser "^0.9.1" 11727 11916 unicode-match-property-ecmascript "^2.0.0" 11728 11917 unicode-match-property-value-ecmascript "^2.1.0" 11729 11918 11730 - regjsgen@^0.7.1: 11731 - version "0.7.1" 11732 - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.7.1.tgz#ee5ef30e18d3f09b7c369b76e7c2373ed25546f6" 11733 - integrity sha512-RAt+8H2ZEzHeYWxZ3H2z6tF18zyyOnlcdaafLrm21Bguj7uZy6ULibiAFdXEtKQY4Sy7wDTwDiOazasMLc4KPA== 11734 - 11735 11919 regjsparser@^0.9.1: 11736 11920 version "0.9.1" 11737 11921 resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" ··· 11780 11964 resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" 11781 11965 integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== 11782 11966 11967 + requireindex@~1.1.0: 11968 + version "1.1.0" 11969 + resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.1.0.tgz#e5404b81557ef75db6e49c5a72004893fe03e162" 11970 + integrity sha512-LBnkqsDE7BZKvqylbmn7lTIVdpx4K/QCduRATpO5R+wtPmky/a8pN1bO2D6wXppn1497AJF9mNjqAXr6bdl9jg== 11971 + 11783 11972 requires-port@^1.0.0: 11784 11973 version "1.0.0" 11785 11974 resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" ··· 11829 12018 integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== 11830 12019 11831 12020 resolve.exports@^1.1.0: 11832 - version "1.1.0" 11833 - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.0.tgz#5ce842b94b05146c0e03076985d1d0e7e48c90c9" 11834 - integrity sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ== 12021 + version "1.1.1" 12022 + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.1.tgz#05cfd5b3edf641571fd46fa608b610dda9ead999" 12023 + integrity sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ== 11835 12024 11836 - resolve@^1.1.7, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.0, resolve@^1.22.1: 12025 + resolve.exports@^2.0.0: 12026 + version "2.0.0" 12027 + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.0.tgz#c1a0028c2d166ec2fbf7d0644584927e76e7400e" 12028 + integrity sha512-6K/gDlqgQscOlg9fSRpWstA8sYe8rbELsSTNpx+3kTrsVCzvSl0zIvRErM7fdl9ERWDsKnrLnwB+Ne89918XOg== 12029 + 12030 + resolve@^1.1.7, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.1: 11837 12031 version "1.22.1" 11838 12032 resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" 11839 12033 integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== ··· 11842 12036 path-parse "^1.0.7" 11843 12037 supports-preserve-symlinks-flag "^1.0.0" 11844 12038 11845 - resolve@^2.0.0-next.3, resolve@^2.0.0-next.4: 12039 + resolve@^2.0.0-next.4: 11846 12040 version "2.0.0-next.4" 11847 12041 resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.4.tgz#3d37a113d6429f496ec4752d2a2e58efb1fd4660" 11848 12042 integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ== ··· 11864 12058 resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" 11865 12059 integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== 11866 12060 12061 + retry@^0.12.0: 12062 + version "0.12.0" 12063 + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" 12064 + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== 12065 + 11867 12066 retry@^0.13.1: 11868 12067 version "0.13.1" 11869 12068 resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" ··· 11890 12089 version "2.2.8" 11891 12090 resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" 11892 12091 integrity sha512-R5KMKHnPAQaZMqLOsyuyUmcIjSeDm+73eoqQpaXA7AZ22BL+6C+1mcUscgOsNd8WVlJuvlgAPsegcx7pjlV0Dg== 12092 + 12093 + rimraf@~2.4.0: 12094 + version "2.4.5" 12095 + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.4.5.tgz#ee710ce5d93a8fdb856fb5ea8ff0e2d75934b2da" 12096 + integrity sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ== 12097 + dependencies: 12098 + glob "^6.0.1" 11893 12099 11894 12100 rimraf@~2.6.2: 11895 12101 version "2.6.3" ··· 11959 12165 resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" 11960 12166 integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 11961 12167 12168 + safe-json-stringify@~1: 12169 + version "1.2.0" 12170 + resolved "https://registry.yarnpkg.com/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz#356e44bc98f1f93ce45df14bcd7c01cda86e0afd" 12171 + integrity sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg== 12172 + 11962 12173 safe-regex-test@^1.0.0: 11963 12174 version "1.0.0" 11964 12175 resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" ··· 11984 12195 version "2.1.2" 11985 12196 resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" 11986 12197 integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 12198 + 12199 + sanitize-filename@^1.6.1: 12200 + version "1.6.3" 12201 + resolved "https://registry.yarnpkg.com/sanitize-filename/-/sanitize-filename-1.6.3.tgz#755ebd752045931977e30b2025d340d7c9090378" 12202 + integrity sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg== 12203 + dependencies: 12204 + truncate-utf8-bytes "^1.0.0" 11987 12205 11988 12206 sanitize.css@*: 11989 12207 version "13.0.0" ··· 12071 12289 resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc" 12072 12290 integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow== 12073 12291 12074 - semver@7.3.8, semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8: 12292 + semver@7.3.8, semver@^7.0.0, semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8: 12075 12293 version "7.3.8" 12076 12294 resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" 12077 12295 integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== ··· 12112 12330 resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-2.1.0.tgz#50b679d5635cdf84667bdc8e59af4e5b81d5f60a" 12113 12331 integrity sha512-ghgmKt5o4Tly5yEG/UJp8qTd0AN7Xalw4XBtDEKP655B699qMEtra1WlXeE6WIvdEG481JvRxULKsInq/iNysw== 12114 12332 12333 + serialize-error@^8.0.1: 12334 + version "8.1.0" 12335 + resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-8.1.0.tgz#3a069970c712f78634942ddd50fbbc0eaebe2f67" 12336 + integrity sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ== 12337 + dependencies: 12338 + type-fest "^0.20.2" 12339 + 12115 12340 serialize-javascript@^4.0.0: 12116 12341 version "4.0.0" 12117 12342 resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" ··· 12120 12345 randombytes "^2.1.0" 12121 12346 12122 12347 serialize-javascript@^6.0.0: 12123 - version "6.0.0" 12124 - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" 12125 - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== 12348 + version "6.0.1" 12349 + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" 12350 + integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== 12126 12351 dependencies: 12127 12352 randombytes "^2.1.0" 12128 12353 ··· 12229 12454 resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123" 12230 12455 integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw== 12231 12456 12232 - shell-quote@^1.6.1, shell-quote@^1.7.3: 12233 - version "1.7.4" 12234 - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.4.tgz#33fe15dee71ab2a81fcbd3a52106c5cfb9fb75d8" 12235 - integrity sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw== 12457 + shell-quote@^1.6.1, shell-quote@^1.7.2, shell-quote@^1.7.3: 12458 + version "1.8.0" 12459 + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.0.tgz#20d078d0eaf71d54f43bd2ba14a1b5b9bfa5c8ba" 12460 + integrity sha512-QHsz8GgQIGKlRi24yFc6a6lN69Idnx634w49ay6+jA5yFh7a1UY+4Rp6HPx/L/1zcEDPEij8cIsiqR6bQsE5VQ== 12236 12461 12237 12462 side-channel@^1.0.4: 12238 12463 version "1.0.4" ··· 12506 12731 dependencies: 12507 12732 internal-slot "^1.0.4" 12508 12733 12734 + stream-chain@^2.2.5: 12735 + version "2.2.5" 12736 + resolved "https://registry.yarnpkg.com/stream-chain/-/stream-chain-2.2.5.tgz#b30967e8f14ee033c5b9a19bbe8a2cba90ba0d09" 12737 + integrity sha512-1TJmBx6aSWqZ4tx7aTpBDXK0/e2hhcNSTV8+CbFJtDjbb+I1mZ8lHit0Grw9GRT+6JbIrrDd8esncgBi8aBXGA== 12738 + 12739 + stream-json@^1.7.4: 12740 + version "1.7.5" 12741 + resolved "https://registry.yarnpkg.com/stream-json/-/stream-json-1.7.5.tgz#2ff0563011f22cea4f6a28dbfc0344a53c761fe4" 12742 + integrity sha512-NSkoVduGakxZ8a+pTPUlcGEeAGQpWL9rKJhOFCV+J/QtdQUEU5vtBgVg6eJXn8JB8RZvpbJWZGvXkhz70MLWoA== 12743 + dependencies: 12744 + stream-chain "^2.2.5" 12745 + 12509 12746 string-hash-64@^1.0.3: 12510 12747 version "1.0.3" 12511 12748 resolved "https://registry.yarnpkg.com/string-hash-64/-/string-hash-64-1.0.3.tgz#0deb56df58678640db5c479ccbbb597aaa0de322" ··· 12664 12901 resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" 12665 12902 integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== 12666 12903 12904 + strnum@^1.0.5: 12905 + version "1.0.5" 12906 + resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.5.tgz#5c4e829fe15ad4ff0d20c3db5ac97b73c9b072db" 12907 + integrity sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA== 12908 + 12667 12909 strtok3@^6.2.4: 12668 12910 version "6.3.0" 12669 12911 resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.3.0.tgz#358b80ffe6d5d5620e19a073aa78ce947a90f9a0" ··· 12772 13014 integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== 12773 13015 12774 13016 tailwindcss@^3.0.2: 12775 - version "3.2.4" 12776 - resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.2.4.tgz#afe3477e7a19f3ceafb48e4b083e292ce0dc0250" 12777 - integrity sha512-AhwtHCKMtR71JgeYDaswmZXhPcW9iuI9Sp2LvZPo9upDZ7231ZJ7eA9RaURbhpXGVlrjX4cFNlB4ieTetEb7hQ== 13017 + version "3.2.7" 13018 + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.2.7.tgz#5936dd08c250b05180f0944500c01dce19188c07" 13019 + integrity sha512-B6DLqJzc21x7wntlH/GsZwEXTBttVSl1FtCzC8WP4oBc/NKef7kaax5jeihkkCEWc831/5NDJ9gRNDK6NEioQQ== 12778 13020 dependencies: 12779 13021 arg "^5.0.2" 12780 13022 chokidar "^3.5.3" ··· 12790 13032 normalize-path "^3.0.0" 12791 13033 object-hash "^3.0.0" 12792 13034 picocolors "^1.0.0" 12793 - postcss "^8.4.18" 13035 + postcss "^8.0.9" 12794 13036 postcss-import "^14.1.0" 12795 13037 postcss-js "^4.0.0" 12796 13038 postcss-load-config "^3.1.4" 12797 13039 postcss-nested "6.0.0" 12798 - postcss-selector-parser "^6.0.10" 13040 + postcss-selector-parser "^6.0.11" 12799 13041 postcss-value-parser "^4.2.0" 12800 13042 quick-lru "^5.1.1" 12801 13043 resolve "^1.22.1" ··· 12831 13073 inherits "^2.0.3" 12832 13074 readable-stream "^3.1.1" 12833 13075 13076 + telnet-client@1.2.8: 13077 + version "1.2.8" 13078 + resolved "https://registry.yarnpkg.com/telnet-client/-/telnet-client-1.2.8.tgz#946c0dadc8daa3f19bb40a3e898cb870403a4ca4" 13079 + integrity sha512-W+w4k3QAmULVNhBVT2Fei369kGZCh/TH25M7caJAXW+hLxwoQRuw0di3cX4l0S9fgH3Mvq7u+IFMoBDpEw/eIg== 13080 + dependencies: 13081 + bluebird "^3.5.4" 13082 + 13083 + temp-dir@^1.0.0: 13084 + version "1.0.0" 13085 + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" 13086 + integrity sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ== 13087 + 12834 13088 temp-dir@^2.0.0: 12835 13089 version "2.0.0" 12836 13090 resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" ··· 12851 13105 dependencies: 12852 13106 rimraf "~2.6.2" 12853 13107 13108 + tempfile@^2.0.0: 13109 + version "2.0.0" 13110 + resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-2.0.0.tgz#6b0446856a9b1114d1856ffcbe509cccb0977265" 13111 + integrity sha512-ZOn6nJUgvgC09+doCEF3oB+r3ag7kUvlsXEGX069QRD60p+P3uP7XG9N2/at+EyIRGSN//ZY3LyEotA1YpmjuA== 13112 + dependencies: 13113 + temp-dir "^1.0.0" 13114 + uuid "^3.0.1" 13115 + 12854 13116 tempy@^0.6.0: 12855 13117 version "0.6.0" 12856 13118 resolved "https://registry.yarnpkg.com/tempy/-/tempy-0.6.0.tgz#65e2c35abc06f1124a97f387b08303442bde59f3" ··· 12881 13143 terser "^5.14.1" 12882 13144 12883 13145 terser@^5.0.0, terser@^5.10.0, terser@^5.14.1, terser@^5.15.0: 12884 - version "5.16.1" 12885 - resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.1.tgz#5af3bc3d0f24241c7fb2024199d5c461a1075880" 12886 - integrity sha512-xvQfyfA1ayT0qdK47zskQgRZeWLoOQ8JQ6mIgRGVNwZKdQMU+5FkCBjmv4QjcrTzyZquRw2FVtlJSRUmMKQslw== 13146 + version "5.16.4" 13147 + resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.4.tgz#51284b440b93242291a98f2a9903c024cfb70e6e" 13148 + integrity sha512-5yEGuZ3DZradbogeYQ1NaGz7rXVBDWujWlx1PT8efXO6Txn+eWbfKqB2bTDVmFXmePFkoLU6XI8UektMIEA0ug== 12887 13149 dependencies: 12888 13150 "@jridgewell/source-map" "^0.3.2" 12889 13151 acorn "^8.5.0" ··· 13023 13285 resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" 13024 13286 integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== 13025 13287 13288 + trace-event-lib@^1.3.1: 13289 + version "1.3.1" 13290 + resolved "https://registry.yarnpkg.com/trace-event-lib/-/trace-event-lib-1.3.1.tgz#8113146caa30778f45d0ec479d899f9eda94d594" 13291 + integrity sha512-RO/TD5E9RNqU6MhOfi/njFWKYhrzOJCpRXlEQHgXwM+6boLSrQnOZ9xbHwOXzC+Luyixc7LNNSiTsqTVeF7I1g== 13292 + dependencies: 13293 + browser-process-hrtime "^1.0.0" 13294 + lodash "^4.17.21" 13295 + 13296 + truncate-utf8-bytes@^1.0.0: 13297 + version "1.0.2" 13298 + resolved "https://registry.yarnpkg.com/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz#405923909592d56f78a5818434b0b78489ca5f2b" 13299 + integrity sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ== 13300 + dependencies: 13301 + utf8-byte-length "^1.0.1" 13302 + 13026 13303 tryer@^1.0.1: 13027 13304 version "1.0.1" 13028 13305 resolved "https://registry.yarnpkg.com/tryer/-/tryer-1.0.1.tgz#f2c85406800b9b0f74c9f7465b81eaad241252f8" ··· 13044 13321 integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== 13045 13322 13046 13323 tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.4.0: 13047 - version "2.4.1" 13048 - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.1.tgz#0d0bfbaac2880b91e22df0768e55be9753a5b17e" 13049 - integrity sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA== 13324 + version "2.5.0" 13325 + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" 13326 + integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== 13050 13327 13051 13328 tsutils@^3.21.0: 13052 13329 version "3.21.0" ··· 13114 13391 media-typer "0.3.0" 13115 13392 mime-types "~2.1.24" 13116 13393 13394 + typed-array-length@^1.0.4: 13395 + version "1.0.4" 13396 + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" 13397 + integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== 13398 + dependencies: 13399 + call-bind "^1.0.2" 13400 + for-each "^0.3.3" 13401 + is-typed-array "^1.1.9" 13402 + 13117 13403 typed-emitter@^2.1.0: 13118 13404 version "2.1.0" 13119 13405 resolved "https://registry.yarnpkg.com/typed-emitter/-/typed-emitter-2.1.0.tgz#ca78e3d8ef1476f228f548d62e04e3d4d3fd77fb" ··· 13129 13415 is-typedarray "^1.0.0" 13130 13416 13131 13417 typescript@^4.4.4: 13132 - version "4.9.4" 13133 - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.4.tgz#a2a3d2756c079abda241d75f149df9d561091e78" 13134 - integrity sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg== 13418 + version "4.9.5" 13419 + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" 13420 + integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== 13135 13421 13136 13422 ua-parser-js@^0.7.30: 13137 - version "0.7.32" 13138 - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.32.tgz#cd8c639cdca949e30fa68c44b7813ef13e36d211" 13139 - integrity sha512-f9BESNVhzlhEFf2CHMSj40NWOjYPl1YKYbrvIr/hFTDEmLq7SRbWvm7FcdcpCYT95zrOhC7gZSxjdnnTpBcwVw== 13423 + version "0.7.33" 13424 + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.33.tgz#1d04acb4ccef9293df6f70f2c3d22f3030d8b532" 13425 + integrity sha512-s8ax/CeZdK9R/56Sui0WM6y9OFREJarMRHqLB2EwkovemBxNQ+Bqu8GAsUnVcXKgphb++ghr/B2BZx4mahujPw== 13140 13426 13141 13427 uglify-es@^3.1.9: 13142 13428 version "3.3.9" ··· 13246 13532 resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" 13247 13533 integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== 13248 13534 13249 - update-browserslist-db@^1.0.9: 13535 + update-browserslist-db@^1.0.10: 13250 13536 version "1.0.10" 13251 13537 resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" 13252 13538 integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== ··· 13298 13584 resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" 13299 13585 integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== 13300 13586 13587 + utf8-byte-length@^1.0.1: 13588 + version "1.0.4" 13589 + resolved "https://registry.yarnpkg.com/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz#f45f150c4c66eee968186505ab93fcbb8ad6bf61" 13590 + integrity sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA== 13591 + 13301 13592 utf8@^3.0.0: 13302 13593 version "3.0.0" 13303 13594 resolved "https://registry.yarnpkg.com/utf8/-/utf8-3.0.0.tgz#f052eed1364d696e769ef058b183df88c87f69d1" ··· 13328 13619 resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" 13329 13620 integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== 13330 13621 13622 + uuid@^3.0.1: 13623 + version "3.4.0" 13624 + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" 13625 + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== 13626 + 13331 13627 uuid@^8.3.2: 13332 13628 version "8.3.2" 13333 13629 resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" ··· 13343 13639 source-map "^0.7.3" 13344 13640 13345 13641 v8-to-istanbul@^9.0.1: 13346 - version "9.0.1" 13347 - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" 13348 - integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w== 13642 + version "9.1.0" 13643 + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz#1b83ed4e397f58c85c266a570fc2558b5feb9265" 13644 + integrity sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA== 13349 13645 dependencies: 13350 13646 "@jridgewell/trace-mapping" "^0.3.12" 13351 13647 "@types/istanbul-lib-coverage" "^2.0.1" ··· 13643 13939 is-string "^1.0.5" 13644 13940 is-symbol "^1.0.3" 13645 13941 13942 + which-collection@^1.0.1: 13943 + version "1.0.1" 13944 + resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" 13945 + integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== 13946 + dependencies: 13947 + is-map "^2.0.1" 13948 + is-set "^2.0.1" 13949 + is-weakmap "^2.0.1" 13950 + is-weakset "^2.0.1" 13951 + 13646 13952 which-module@^2.0.0: 13647 13953 version "2.0.0" 13648 13954 resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" 13649 13955 integrity sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q== 13650 13956 13957 + which-typed-array@^1.1.9: 13958 + version "1.1.9" 13959 + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" 13960 + integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== 13961 + dependencies: 13962 + available-typed-arrays "^1.0.5" 13963 + call-bind "^1.0.2" 13964 + for-each "^0.3.3" 13965 + gopd "^1.0.1" 13966 + has-tostringtag "^1.0.0" 13967 + is-typed-array "^1.1.10" 13968 + 13651 13969 which@^1.2.9, which@^1.3.1: 13652 13970 version "1.3.1" 13653 13971 resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" ··· 13888 14206 signal-exit "^3.0.2" 13889 14207 typedarray-to-buffer "^3.1.5" 13890 14208 13891 - write-file-atomic@^4.0.1: 14209 + write-file-atomic@^4.0.2: 13892 14210 version "4.0.2" 13893 14211 resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-4.0.2.tgz#a9df01ae5b77858a027fd2e80768ee433555fcfd" 13894 14212 integrity sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg== ··· 13903 14221 dependencies: 13904 14222 async-limiter "~1.0.0" 13905 14223 13906 - ws@^7, ws@^7.4.6, ws@^7.5.1: 14224 + ws@^7, ws@^7.0.0, ws@^7.4.6, ws@^7.5.1: 13907 14225 version "7.5.9" 13908 14226 resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" 13909 14227 integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== 13910 14228 13911 14229 ws@^8.4.2: 13912 - version "8.11.0" 13913 - resolved "https://registry.yarnpkg.com/ws/-/ws-8.11.0.tgz#6a0d36b8edfd9f96d8b25683db2f8d7de6e8e143" 13914 - integrity sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg== 14230 + version "8.12.1" 14231 + resolved "https://registry.yarnpkg.com/ws/-/ws-8.12.1.tgz#c51e583d79140b5e42e39be48c934131942d4a8f" 14232 + integrity sha512-1qo+M9Ba+xNhPB+YTWUlK6M17brTut5EXbcBaMRN5pH5dFrXz7lzz1ChFSUq3bOUl8yEvSenhHmYUNJxFzdJew== 13915 14233 13916 14234 xml-name-validator@^3.0.0: 13917 14235 version "3.0.0" ··· 13943 14261 resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" 13944 14262 integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== 13945 14263 14264 + yallist@^2.1.2: 14265 + version "2.1.2" 14266 + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" 14267 + integrity sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A== 14268 + 13946 14269 yallist@^3.0.2: 13947 14270 version "3.1.1" 13948 14271 resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" ··· 13966 14289 camelcase "^5.0.0" 13967 14290 decamelize "^1.2.0" 13968 14291 13969 - yargs-parser@^20.2.2: 14292 + yargs-parser@^20.2.2, yargs-parser@^20.2.9: 13970 14293 version "20.2.9" 13971 14294 resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" 13972 14295 integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== ··· 13976 14299 resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" 13977 14300 integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== 13978 14301 14302 + yargs-unparser@^2.0.0: 14303 + version "2.0.0" 14304 + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" 14305 + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== 14306 + dependencies: 14307 + camelcase "^6.0.0" 14308 + decamelize "^4.0.0" 14309 + flat "^5.0.2" 14310 + is-plain-obj "^2.1.0" 14311 + 13979 14312 yargs@^15.1.0: 13980 14313 version "15.4.1" 13981 14314 resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" ··· 13993 14326 y18n "^4.0.0" 13994 14327 yargs-parser "^18.1.2" 13995 14328 13996 - yargs@^16.2.0: 14329 + yargs@^16.0.3, yargs@^16.2.0: 13997 14330 version "16.2.0" 13998 14331 resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" 13999 14332 integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== ··· 14007 14340 yargs-parser "^20.2.2" 14008 14341 14009 14342 yargs@^17.3.1, yargs@^17.5.1: 14010 - version "17.6.2" 14011 - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.2.tgz#2e23f2944e976339a1ee00f18c77fedee8332541" 14012 - integrity sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw== 14343 + version "17.7.1" 14344 + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.1.tgz#34a77645201d1a8fc5213ace787c220eabbd0967" 14345 + integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw== 14013 14346 dependencies: 14014 14347 cliui "^8.0.1" 14015 14348 escalade "^3.1.1" ··· 14025 14358 integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== 14026 14359 14027 14360 zod@^3.14.2, zod@^3.20.2: 14028 - version "3.20.2" 14029 - resolved "https://registry.yarnpkg.com/zod/-/zod-3.20.2.tgz#068606642c8f51b3333981f91c0a8ab37dfc2807" 14030 - integrity sha512-1MzNQdAvO+54H+EaK5YpyEy0T+Ejo/7YLHS93G3RnYWh5gaotGHwGeN/ZO687qEDU2y4CdStQYXVHIgrUl5UVQ== 14361 + version "3.20.6" 14362 + resolved "https://registry.yarnpkg.com/zod/-/zod-3.20.6.tgz#2f2f08ff81291d47d99e86140fedb4e0db08361a" 14363 + integrity sha512-oyu0m54SGCtzh6EClBVqDDlAYRz4jrVtKwQ7ZnsEmMI9HnzuZFj8QFwAY1M5uniIYACdGvv0PBWPF2kO0aNofA==