├── .gitignore ├── LICENSE.md ├── README.md ├── art └── github-feature.png ├── composer.json ├── composer.lock ├── phpbench.json ├── phpunit.xml ├── src ├── Parser.php ├── Token.php ├── TokenType.php ├── Tokenizer.php └── index.php └── tests ├── Benchmark ├── Datasets │ └── all.json ├── ParserBench.php └── TokenizerBench.php ├── Datasets ├── invalidJson.php ├── jsonOrgFail.php ├── jsonOrgPass.php ├── validJson.php ├── validLiterals.php └── validNumbers.php ├── Feature └── ExampleTest.php ├── JSONOrg ├── fail10.json ├── fail11.json ├── fail12.json ├── fail13.json ├── fail14.json ├── fail15.json ├── fail16.json ├── fail17.json ├── fail19.json ├── fail2.json ├── fail20.json ├── fail21.json ├── fail22.json ├── fail23.json ├── fail24.json ├── fail25.json ├── fail26.json ├── fail27.json ├── fail28.json ├── fail29.json ├── fail3.json ├── fail30.json ├── fail31.json ├── fail32.json ├── fail33.json ├── fail4.json ├── fail5.json ├── fail6.json ├── fail7.json ├── fail8.json ├── fail9.json ├── pass1.json ├── pass2.json ├── pass3.json ├── pass4.json └── pass5.json ├── Pest.php ├── TestCase.php └── Unit ├── ExampleTest.php ├── JsonOrgTest.php ├── ParseTest.php └── TokenizerTest.php /.gitignore: -------------------------------------------------------------------------------- 1 | /vendor/ 2 | 3 | /.phpbench/ 4 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Daniel Hemmati 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # 🚀 Json parser in mighty php 2 | 3 |

4 | JSON Parser Banner 5 |

6 | 7 | ## Overview 8 | 9 | A simple JSON parser implementation in PHP that parses JSON strings into PHP data structures. This project demonstrates how to build a JSON parser from scratch without relying on PHP's built-in `json_decode()` function. 10 | 11 | If you like to build your own JSON parser and you need to understand how it works, this project is for you. 12 | 13 | ## Features 14 | 15 | - ✅ **Complete JSON compliance** - Passes the official [JSON.org test suite](https://www.json.org/JSON_checker/) 16 | - ✅ **Full data type support**: 17 | - Strings with escape sequences (`\"`, `\\`, `\/`, `\b`, `\f`, `\n`, `\r`, `\t`) 18 | - Numbers (integers, floats, scientific notation: `1e3`, `5.5e-1`) 19 | - Booleans (`true`/`false`) 20 | - `null` values 21 | - Arrays (nested and empty) 22 | - Objects (nested and empty) 23 | - ✅ **Advanced string parsing**: 24 | - Unicode escape sequences (`\uXXXX`) 25 | - Control character validation (prevents unescaped control chars) 26 | - ✅ **Robust number validation**: 27 | - Prevents invalid leading zeros (e.g., `013`) 28 | - Supports scientific notation (`1e3`, `2e+00`, `5.5e-1`) 29 | - Handles negative numbers and decimals 30 | 31 | ## Installation 32 | 33 | ### Prerequisites 34 | 35 | - PHP 8.4+ 36 | - Composer 37 | 38 | ### Local Setup 39 | 40 | 1. Clone the repository: 41 | 42 | ```bash 43 | git clone https://github.com/DanielHemmati/json-parser-in-php 44 | cd json-parser-in-php 45 | ``` 46 | 47 | 2. Install dependencies: 48 | 49 | ```bash 50 | composer install 51 | ``` 52 | 53 | 3. Run the tests: 54 | 55 | ```bash 56 | ./vendor/bin/pest 57 | ``` 58 | 59 | ## Contributing 60 | 61 | Contributions are welcome! Please feel free to submit a pull request. 62 | 63 | ### Todos 64 | 65 | - [x] Add benchmark to the project. (thanks to [@mamazu](https://github.com/DanielHemmati/json-parser-in-php/pull/2)) 66 | - [ ] Add suppport for not loading all of the json into memory at once (see [read json-machine for study](https://github.com/halaxa/json-machine), also [mlebkowski showed his parser](https://github.com/mlebkowski/advent-of-code-php/tree/main/src/Solutions/Y2017/D09) Good place to get deeper into parser) 67 | - [ ] Add pint & phpstan 68 | 69 | ## License 70 | 71 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. 72 | -------------------------------------------------------------------------------- /art/github-feature.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DanielHemmati/json-parser-in-php/eab62a29023dad0e9b3a6ed219852e46d848eaff/art/github-feature.png -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "daniel/json-parser-in-php", 3 | "license": "MIT", 4 | "authors": [ 5 | { 6 | "name": "DanielHemmati", 7 | "email": "danialups1997@gmail.com" 8 | } 9 | ], 10 | "require": { 11 | "php": "^8.4" 12 | }, 13 | "autoload": { 14 | "psr-4": { 15 | "JsonParser\\": "src/" 16 | } 17 | }, 18 | "autoload-dev": { 19 | "psr-4": { 20 | "Tests\\": "tests/" 21 | } 22 | }, 23 | "require-dev": { 24 | "pestphp/pest": "^3.8", 25 | "symfony/var-dumper": "^7.3", 26 | "phpbench/phpbench": "^1.4" 27 | }, 28 | "config": { 29 | "allow-plugins": { 30 | "pestphp/pest-plugin": true 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /phpbench.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema":"./vendor/phpbench/phpbench/phpbench.schema.json", 3 | "runner.bootstrap": "vendor/autoload.php" 4 | } 5 | -------------------------------------------------------------------------------- /phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | ./tests 10 | 11 | 12 | 13 | 14 | app 15 | src 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/Parser.php: -------------------------------------------------------------------------------- 1 | tokenizer = new Tokenizer($json); 18 | $this->advance(); 19 | } 20 | 21 | public function parse(): mixed 22 | { 23 | $value = $this->parseValue(); 24 | 25 | // imagine you have sth like "true false" as json. 26 | // true is correct and after that we exepect 27 | // EOF but we get false, which is wrong 28 | if ($this->current !== null) { 29 | throw $this->error("Trailing data after top-level value"); 30 | } 31 | 32 | return $value; 33 | } 34 | 35 | private function advance() 36 | { 37 | $this->current = $this->tokenizer->nextToken(); 38 | } 39 | 40 | private function consume(TokenType ...$types): Token 41 | { 42 | if ($this->current === null) { 43 | throw $this->error("Unexpected end of input"); 44 | } 45 | 46 | foreach ($types as $type) { 47 | if ($this->current->type === $type) { 48 | $tok = $this->current; 49 | $this->advance(); 50 | return $tok; 51 | } 52 | } 53 | 54 | $expected = implode("|", array_map(fn($t) => $t->value, $types)); 55 | throw $this->error("Expected $expected, got {$this->current->type->value}"); 56 | } 57 | 58 | private function error(string $msg): \RuntimeException 59 | { 60 | // if there is a token give the line and column for hooman 61 | if ($this->current) { 62 | return new \RuntimeException("$msg at {$this->current->line}:{$this->current->column}"); 63 | } 64 | // if not (means we $this->current is null) then just throw an error 65 | return new \RuntimeException($msg); 66 | } 67 | 68 | 69 | private function parseValue(): mixed 70 | { 71 | if ($this->current === null) { 72 | throw $this->error("Unexpected end of input while parsing value"); 73 | } 74 | 75 | return match ($this->current->type) { 76 | TokenType::String => $this->consume(TokenType::String)->value, 77 | TokenType::Number => $this->consume(TokenType::Number)->value, 78 | TokenType::True => $this->consume(TokenType::True)->value, 79 | TokenType::False => $this->consume(TokenType::False)->value, 80 | TokenType::Null => $this->consume(TokenType::Null)->value, 81 | TokenType::BraceOpen => $this->parseObject(), 82 | TokenType::BracketOpen => $this->parseArray(), 83 | default => throw $this->error("Unexpected token {$this->current->type->value} while parsing value") 84 | }; 85 | } 86 | 87 | private function parseObject(): array 88 | { 89 | $this->consume(TokenType::BraceOpen); 90 | $object = []; 91 | 92 | if ($this->current?->type === TokenType::BraceClose) { 93 | $this->advance(); 94 | return $object; 95 | } 96 | 97 | while (true) { 98 | $keyTok = $this->consume(TokenType::String); // json must start with " 99 | $this->consume(TokenType::Colon); // then consume and advance 100 | $value = $this->parseValue(); // get the value by going throw parseValue again 101 | $object[$keyTok->value] = $value; 102 | 103 | if ($this->current?->type === TokenType::Comma) { 104 | $this->advance(); 105 | continue; 106 | } 107 | 108 | if ($this->current?->type === TokenType::BraceClose) { 109 | $this->advance(); 110 | break; 111 | } 112 | 113 | throw $this->error('Expected , or } in object'); 114 | } 115 | 116 | return $object; 117 | } 118 | 119 | private function parseArray(): array 120 | { 121 | $this->consume(TokenType::BracketOpen); 122 | $list = []; 123 | 124 | if ($this->current?->type === TokenType::BracketClose) { 125 | $this->advance(); 126 | return $list; 127 | } 128 | 129 | while (true) { 130 | $list[] = $this->parseValue(); 131 | 132 | if ($this->current?->type === TokenType::Comma) { 133 | $this->advance(); 134 | continue; 135 | } 136 | 137 | if ($this->current?->type === TokenType::BracketClose) { 138 | $this->advance(); 139 | break; 140 | } 141 | 142 | throw $this->error('Expected , or ] in array'); 143 | } 144 | 145 | return $list; 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/Token.php: -------------------------------------------------------------------------------- 1 | input = $json; 22 | $this->length = strlen($json); 23 | } 24 | 25 | public function nextToken(): ?Token 26 | { 27 | // skip white space 28 | $this->skipWhiteSpace(); 29 | 30 | // i don't think we ever hit this 31 | if ($this->pos >= $this->length) { 32 | return null; 33 | } 34 | 35 | $char = $this->input[$this->pos]; 36 | 37 | return match ($char) { 38 | '{' => $this->emit(TokenType::BraceOpen), 39 | '}' => $this->emit(TokenType::BraceClose), 40 | '[' => $this->emit(TokenType::BracketOpen), 41 | ']' => $this->emit(TokenType::BracketClose), 42 | ':' => $this->emit(TokenType::Colon), 43 | ',' => $this->emit(TokenType::Comma), 44 | '"' => $this->readString(), 45 | default => $this->readNumberOrLiteral() 46 | }; 47 | } 48 | 49 | private function emit(TokenType $type): Token 50 | { 51 | $token = new Token( 52 | $type, 53 | $this->input[$this->pos], 54 | $this->line, 55 | $this->column 56 | ); 57 | $this->advanceCurosr(); 58 | return $token; 59 | } 60 | 61 | private function readString(): Token 62 | { 63 | $startLine = $this->line; 64 | $startColumn = $this->column; 65 | 66 | $this->advanceCurosr(); 67 | 68 | $value = ''; 69 | while ($this->pos < $this->length) { 70 | $ch = $this->input[$this->pos]; 71 | 72 | /** 73 | * Why 0x20?? b/c anything from 0x00 to 0x20 is un-printable characters. 74 | * so if we have any of those in the beginning we are going to just 75 | * throw an error. 76 | */ 77 | if (ord($ch) < 0x20) { 78 | throw new \RuntimeException( 79 | "Unescaped control character \\x" . sprintf('%02X', ord($ch)) . 80 | " in string at {$this->line}:{$this->column}" 81 | ); 82 | } 83 | 84 | if ($ch === '\\') { 85 | $this->advanceCurosr(); // skip the baskslash 86 | if ($this->pos >= $this->length) { 87 | throw new \RuntimeException("Unterminated escape sequence at end of input (started {$startLine}:{$startColumn}"); 88 | } 89 | 90 | $escaped = $this->input[$this->pos]; 91 | $value .= match ($escaped) { 92 | '"' => '"', // \" -> " 93 | '\\' => '\\', // \\ -> \ 94 | '/' => "/", // \/ -> / 95 | 'b' => "\x08", // \b -> backspace 96 | 'f' => "\x0C", // \f -> form feed 97 | 'n' => "\n", // \n -> newline 98 | 'r' => "\r", // \r -> carriage return 99 | 't' => "\t", // \t -> tab 100 | 'u' => $this->parseUnicodeEscape(), // \xXXXX -> unicode char (UTF-8) 101 | default => throw new \RuntimeException("Invalid escape sequence: \\$escaped") 102 | }; 103 | 104 | $this->advanceCurosr(); 105 | 106 | continue; 107 | } 108 | 109 | /** 110 | * The moment we hit the " we are already at the end of string 111 | * @link https://www.json.org/json-en.html 112 | */ 113 | if ($ch === '"') { 114 | break; 115 | } 116 | 117 | $value .= $ch; 118 | $this->advanceCurosr(); 119 | } 120 | 121 | if ($this->pos >= $this->length) { 122 | throw new \RuntimeException("Unterminated string literal starting at {$startLine}:{$startColumn}"); 123 | } 124 | 125 | $this->advanceCurosr(); 126 | 127 | return new Token(TokenType::String, $value, $startLine, $startColumn); 128 | } 129 | 130 | private function readNumberOrLiteral(): Token 131 | { 132 | $char = $this->input[$this->pos]; 133 | 134 | // if the number if sth like "-7" and you use is_numeric it will be false b/c is_numeric('-') is false 135 | // the readLiteral intead of readNumber, that's why we use 136 | // ctype_digit and we check for the negative using '-" 137 | if (ctype_digit($char) || $char === '-' || $char === '.') { 138 | return $this->readNumber(); 139 | } 140 | 141 | return $this->readLiteral(); 142 | } 143 | 144 | private function readNumber(): Token 145 | { 146 | $startLine = $this->line; 147 | $startColumn = $this->column; 148 | $start = $this->pos; 149 | 150 | while ($this->pos < $this->length) { 151 | $ch = $this->input[$this->pos]; 152 | if ( 153 | !ctype_digit($ch) && 154 | $ch !== '.' && 155 | $ch !== '-' && 156 | $ch !== 'e' && 157 | $ch !== 'E' && 158 | $ch !== '+' 159 | ) { 160 | break; 161 | } 162 | $this->advanceCurosr(); 163 | } 164 | 165 | $literal = substr($this->input, $start, $this->pos - $start); 166 | 167 | // we added this b/c of fail13.json file. 168 | if (preg_match('/^-?0\d/', $literal)) { 169 | throw new \RuntimeException("Invalid number format '$literal' at {$startLine}:{$startColumn}"); 170 | } 171 | 172 | if (is_numeric($literal)) { 173 | return new Token(TokenType::Number, +$literal, $startLine, $startColumn); 174 | } 175 | 176 | throw new \RuntimeException("Invalid number '$literal' at {$startLine}:{$startColumn}"); 177 | } 178 | 179 | private function readLiteral(): Token 180 | { 181 | $startLine = $this->line; 182 | $startColumn = $this->column; 183 | $start = $this->pos; 184 | 185 | while ($this->pos < $this->length && ctype_alpha($this->input[$this->pos])) { 186 | $this->advanceCurosr(); 187 | } 188 | 189 | $literal = substr($this->input, $start, $this->pos - $start); 190 | 191 | return match ($literal) { 192 | 'true' => new Token(TokenType::True, true, $startLine, $startColumn), 193 | 'false' => new Token(TokenType::False, false, $startLine, $startColumn), 194 | 'null' => new Token(TokenType::Null, null, $startLine, $startColumn), 195 | default => throw new \RuntimeException("Unexptected literal '$literal' at {$startLine}:{$startColumn}") 196 | }; 197 | } 198 | 199 | /** 200 | * In order to understand why we need high surrogate and low surrogate 201 | * Do read this two links: 202 | * @link https://www.wikiwand.com/en/articles/UTF-16#:~:text=The%20high%20ten,0xDC00%E2%80%930xDFFF. 203 | * @link https://www.oilshell.org/blog/2023/06/surrogate-pair.html 204 | */ 205 | private function parseUnicodeEscape(): string 206 | { 207 | $hex = $this->read4HexDigits(); 208 | $code = hexdec($hex); 209 | 210 | if ($code >= 0xD800 && $code <= 0xDBFF) { 211 | if ($this->peek() !== '\\' || $this->peek(1) !== 'u') { 212 | throw new \RuntimeException( 213 | "High surrogate \\u$hex not followed by low surrogate at {$this->line}:{$this->column}" 214 | ); 215 | } 216 | 217 | // at this point we have checked the first \uXXXX 218 | // now it's time to check the second \uYYYY 219 | // TODO: this should be better. unfortunately i don't have that much rn 220 | $this->advanceCurosr(); // which is backslash 221 | $this->advanceCurosr(); // which should be \u 222 | 223 | $lowHex = $this->read4HexDigits(); // e.g DAC9 224 | $lowCode = hexdec($lowHex); 225 | 226 | if ($lowCode < 0xDC00 || $lowCode > 0xDFFF) { 227 | throw new \RuntimeException( 228 | "Expected low surrogate after \\u$hex, got \\u$lowHex at {$this->line}:{$this->column}" 229 | ); 230 | } 231 | 232 | // ? figure out how does this works exactly 233 | // in order to understand this read this blog: https://russellcottrell.com/greek/utilities/SurrogatePairCalculator.htm 234 | $codePoint = 0x10000 + (($code - 0xD800) << 10) + ($lowCode - 0xDC00); 235 | return mb_chr($codePoint, 'UTF-8'); 236 | } 237 | 238 | if ($code >= 0xDC00 && $code <= 0xDFFF){ 239 | throw new \RuntimeException( 240 | "Orphan low surrogate \\u$hex at {$this->line}:{$this->column}" 241 | ); 242 | } 243 | 244 | return mb_chr($code, 'UTF-8'); 245 | } 246 | 247 | private function read4HexDigits(): string 248 | { 249 | $hex = ''; 250 | 251 | for ($i = 0; $i < 4; $i++) { 252 | $this->advanceCurosr(); // we don't want \u itself we care about the next 4 253 | 254 | if ($this->pos >= $this->length) { 255 | throw new \RuntimeException( 256 | "Incomplete Unicode escape sequence at {$this->line}:{$this->column}" 257 | ); 258 | } 259 | 260 | $ch = $this->input[$this->pos]; 261 | 262 | if (!ctype_xdigit($ch)) { 263 | throw new \RuntimeException( 264 | "Invalid Unicode escape sequence: expected hex digit, got '$ch' at {$this->line}:{$this->column}" 265 | ); 266 | } 267 | 268 | $hex .= $ch; 269 | } 270 | return $hex; 271 | } 272 | 273 | private function peek(int $offset = 0): ?string 274 | { 275 | $idx = $this->pos + 1 + $offset; 276 | return $idx < $this->length ? $this->input[$idx] : null; 277 | } 278 | 279 | /** 280 | * Skip RFC-8259 insignificant whitespace (space, tab, LF, CR). 281 | * @link https://datatracker.ietf.org/doc/html/rfc8259 282 | */ 283 | private function skipWhiteSpace(): void 284 | { 285 | while ($this->pos < $this->length) { 286 | $ch = $this->input[$this->pos]; 287 | 288 | if ($ch !== ' ' && $ch !== "\t" && $ch !== "\n" && $ch !== "\r") { 289 | return; 290 | } 291 | 292 | $this->advanceCurosr(); 293 | } 294 | } 295 | 296 | private function advanceCurosr(): void 297 | { 298 | /** 299 | * this is me just being defensive. b/c nextToken method already check this 300 | * as well 301 | **/ 302 | if ($this->pos >= $this->length) { 303 | return; 304 | } 305 | 306 | // $this->pos++ will move the position forward 307 | $ch = $this->input[$this->pos++]; 308 | 309 | if ($ch === "\n") { 310 | $this->line++; 311 | $this->column = 1; 312 | } else { 313 | $this->column++; 314 | } 315 | } 316 | } 317 | -------------------------------------------------------------------------------- /src/index.php: -------------------------------------------------------------------------------- 1 | parse(); 20 | 21 | echo "Parsed result:\n"; 22 | var_dump($result); 23 | } catch (\RuntimeException $e) { 24 | echo "Error parsing JSON: " . $e->getMessage() . "\n"; 25 | } 26 | 27 | dump(hexdec("\ud83d") >= 0xD800); 28 | dump(hexdec("\ud83d") <= 0xDBFF); 29 | -------------------------------------------------------------------------------- /tests/Benchmark/Datasets/all.json: -------------------------------------------------------------------------------- 1 | {"kind": "Listing", "data": {"after": "t3_1lo891y", "dist": 25, "modhash": "", "geo_filter": null, "children": [{"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "pics", "selftext": "", "author_fullname": "t2_yt99m", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "My seven year old wasn\u2019t impressed she had to wake up early for camp today.", "link_flair_richtext": [], "subreddit_name_prefixed": "r/pics", "hidden": false, "pwls": 7, "link_flair_css_class": null, "downs": 0, "thumbnail_height": 96, "top_awarded_type": null, "hide_score": false, "name": "t3_1loe9zp", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.92, "author_flair_background_color": null, "subreddit_type": "public", "ups": 30310, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": true, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": null, "can_mod_post": false, "score": 30310, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "https://b.thumbs.redditmedia.com/30S_fgVeLRgTgslfLPxHkbyThlIxr-LfIcGMvvzjcJY.jpg", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "image", "content_categories": ["photography"], "is_self": false, "mod_note": null, "created": 1751305947.0, "link_flair_type": "text", "wls": 7, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "i.redd.it", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": null, "banned_at_utc": null, "url_overridden_by_dest": "https://i.redd.it/ibryb87qr3af1.jpeg", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://preview.redd.it/ibryb87qr3af1.jpeg?auto=webp&s=0a1301cb114cca3ce27095392219e62cc9aeaa42", "width": 3408, "height": 2357}, "resolutions": [{"url": "https://preview.redd.it/ibryb87qr3af1.jpeg?width=108&crop=smart&auto=webp&s=61781c22b6728bf77184fe95cf208abaa574ff61", "width": 108, "height": 74}, {"url": "https://preview.redd.it/ibryb87qr3af1.jpeg?width=216&crop=smart&auto=webp&s=5d2607b23cd30025cc736fe1e66a8625cb774253", "width": 216, "height": 149}, {"url": "https://preview.redd.it/ibryb87qr3af1.jpeg?width=320&crop=smart&auto=webp&s=a740761c5bfa45ee4927ed6db986439c3ba1a7d8", "width": 320, "height": 221}, {"url": "https://preview.redd.it/ibryb87qr3af1.jpeg?width=640&crop=smart&auto=webp&s=687dc11c5adefae7275a12cedab94c3ac673cf8d", "width": 640, "height": 442}, {"url": "https://preview.redd.it/ibryb87qr3af1.jpeg?width=960&crop=smart&auto=webp&s=b4d72521f71311748de7c58c3315546fdec95fc9", "width": 960, "height": 663}, {"url": "https://preview.redd.it/ibryb87qr3af1.jpeg?width=1080&crop=smart&auto=webp&s=e6928f8a9b1a61f9f09568c5fcdfe1433f857a90", "width": 1080, "height": 746}], "variants": {}, "id": "xgeWssQm-hVxIMLH5I1CCdpJNnozciPoG4cunWW9kZ4"}], "enabled": true}, "all_awardings": [], "awarders": [], "media_only": false, "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh0u", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "", "id": "1loe9zp", "is_robot_indexable": true, "report_reasons": null, "author": "MAINsalad1", "discussion_type": null, "num_comments": 822, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/pics/comments/1loe9zp/my_seven_year_old_wasnt_impressed_she_had_to_wake/", "stickied": false, "url": "https://i.redd.it/ibryb87qr3af1.jpeg", "subreddit_subscribers": 32894007, "created_utc": 1751305947.0, "num_crossposts": 1, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "nextfuckinglevel", "selftext": "", "author_fullname": "t2_70mqq", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "UPS driver joins in on a slip and slide", "link_flair_richtext": [], "subreddit_name_prefixed": "r/nextfuckinglevel", "hidden": false, "pwls": 6, "link_flair_css_class": null, "downs": 0, "thumbnail_height": 140, "top_awarded_type": null, "hide_score": false, "name": "t3_1loejka", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.95, "author_flair_background_color": "", "subreddit_type": "public", "ups": 17280, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": {"reddit_video": {"bitrate_kbps": 5000, "fallback_url": "https://v.redd.it/f71ix1bit3af1/DASH_1080.mp4?source=fallback", "has_audio": true, "height": 1920, "width": 1080, "scrubber_media_url": "https://v.redd.it/f71ix1bit3af1/DASH_96.mp4", "dash_url": "https://v.redd.it/f71ix1bit3af1/DASHPlaylist.mpd?a=1753908005%2COTI2NGVlZmFmMmViZTFkNTY2YTgyMWIyNDY4YzAzZDQxYzk4MDY4MTRlYmFkZWQwZTMwZTBhZjEzMDU1ZTlhZQ%3D%3D&v=1&f=sd", "duration": 20, "hls_url": "https://v.redd.it/f71ix1bit3af1/HLSPlaylist.m3u8?a=1753908005%2CZTRhYTMyMDIzMWZhNmU2MGJkYzQ1MDM3ZTA5OTNkOTJjY2M2MWI5MGFjOWI5YjBlOTE4NjIxNmY5NjRiYWE1Yg%3D%3D&v=1&f=sd", "is_gif": false, "transcoding_status": "completed"}}, "is_reddit_media_domain": true, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": null, "can_mod_post": false, "score": 17280, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "https://external-preview.redd.it/ZzhnZ3ppZWl0M2FmMYLPqRVp6D3sDN1H8NnTQxEyugSxG2SVo_HLqj5XRJyU.png?width=140&height=140&crop=140:140,smart&format=jpg&v=enabled&lthumb=true&s=76e2209d62bc85f50ae50c0f66c3f91e36be9ddf", "edited": false, "author_flair_css_class": "C1", "author_flair_richtext": [], "gildings": {}, "post_hint": "hosted:video", "content_categories": null, "is_self": false, "mod_note": null, "created": 1751306547.0, "link_flair_type": "text", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "v.redd.it", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": "top", "banned_at_utc": null, "url_overridden_by_dest": "https://v.redd.it/f71ix1bit3af1", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://external-preview.redd.it/ZzhnZ3ppZWl0M2FmMYLPqRVp6D3sDN1H8NnTQxEyugSxG2SVo_HLqj5XRJyU.png?format=pjpg&auto=webp&s=f5bb5cff7e6bc7f810145b8c27e5003006cfd6c0", "width": 933, "height": 1659}, "resolutions": [{"url": "https://external-preview.redd.it/ZzhnZ3ppZWl0M2FmMYLPqRVp6D3sDN1H8NnTQxEyugSxG2SVo_HLqj5XRJyU.png?width=108&crop=smart&format=pjpg&auto=webp&s=f4ac9d52d482aa3aa7435f759bff21e98e5e6eef", "width": 108, "height": 192}, {"url": "https://external-preview.redd.it/ZzhnZ3ppZWl0M2FmMYLPqRVp6D3sDN1H8NnTQxEyugSxG2SVo_HLqj5XRJyU.png?width=216&crop=smart&format=pjpg&auto=webp&s=2de87b8b9f9566b362812e7d7b4fb58cfa985707", "width": 216, "height": 384}, {"url": "https://external-preview.redd.it/ZzhnZ3ppZWl0M2FmMYLPqRVp6D3sDN1H8NnTQxEyugSxG2SVo_HLqj5XRJyU.png?width=320&crop=smart&format=pjpg&auto=webp&s=40c6abcc53f3ad61ed395488c3d5baffebf44263", "width": 320, "height": 569}, {"url": "https://external-preview.redd.it/ZzhnZ3ppZWl0M2FmMYLPqRVp6D3sDN1H8NnTQxEyugSxG2SVo_HLqj5XRJyU.png?width=640&crop=smart&format=pjpg&auto=webp&s=247cf8d034e0a6004c2c031560adbd0231adf0be", "width": 640, "height": 1138}], "variants": {}, "id": "ZzhnZ3ppZWl0M2FmMYLPqRVp6D3sDN1H8NnTQxEyugSxG2SVo_HLqj5XRJyU"}], "enabled": false}, "all_awardings": [], "awarders": [], "media_only": false, "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_m0bnr", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "", "id": "1loejka", "is_robot_indexable": true, "report_reasons": null, "author": "bigbusta", "discussion_type": null, "num_comments": 257, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": "dark", "permalink": "/r/nextfuckinglevel/comments/1loejka/ups_driver_joins_in_on_a_slip_and_slide/", "stickied": false, "url": "https://v.redd.it/f71ix1bit3af1", "subreddit_subscribers": 9634822, "created_utc": 1751306547.0, "num_crossposts": 7, "media": {"reddit_video": {"bitrate_kbps": 5000, "fallback_url": "https://v.redd.it/f71ix1bit3af1/DASH_1080.mp4?source=fallback", "has_audio": true, "height": 1920, "width": 1080, "scrubber_media_url": "https://v.redd.it/f71ix1bit3af1/DASH_96.mp4", "dash_url": "https://v.redd.it/f71ix1bit3af1/DASHPlaylist.mpd?a=1753908005%2COTI2NGVlZmFmMmViZTFkNTY2YTgyMWIyNDY4YzAzZDQxYzk4MDY4MTRlYmFkZWQwZTMwZTBhZjEzMDU1ZTlhZQ%3D%3D&v=1&f=sd", "duration": 20, "hls_url": "https://v.redd.it/f71ix1bit3af1/HLSPlaylist.m3u8?a=1753908005%2CZTRhYTMyMDIzMWZhNmU2MGJkYzQ1MDM3ZTA5OTNkOTJjY2M2MWI5MGFjOWI5YjBlOTE4NjIxNmY5NjRiYWE1Yg%3D%3D&v=1&f=sd", "is_gif": false, "transcoding_status": "completed"}}, "is_video": true}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "news", "selftext": "", "author_fullname": "t2_11htgw1s16", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Trump\u2019s justice department issues directive to strip naturalized Americans of citizenship for criminal offenses", "link_flair_richtext": [], "subreddit_name_prefixed": "r/news", "hidden": false, "pwls": 6, "link_flair_css_class": null, "downs": 0, "thumbnail_height": 73, "top_awarded_type": null, "hide_score": false, "name": "t3_1lobug4", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.96, "author_flair_background_color": null, "subreddit_type": "public", "ups": 23436, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": null, "can_mod_post": false, "score": 23436, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "default", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "link", "content_categories": null, "is_self": false, "mod_note": null, "created": 1751300444.0, "link_flair_type": "text", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "theguardian.com", "allow_live_comments": true, "selftext_html": null, "likes": null, "suggested_sort": null, "banned_at_utc": null, "url_overridden_by_dest": "https://www.theguardian.com/us-news/2025/jun/30/trump-birthright-citizenship-naturalized-citizens?CMP=Share_iOSApp_Other", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://external-preview.redd.it/1BW_tEI_79MxQWKq6jUAgoobqbYuMH8_3SwDBOz0-wE.jpeg?auto=webp&s=32503629f7d59924d2844b8911dad0c6dd4e0b34", "width": 1200, "height": 630}, "resolutions": [{"url": "https://external-preview.redd.it/1BW_tEI_79MxQWKq6jUAgoobqbYuMH8_3SwDBOz0-wE.jpeg?width=108&crop=smart&auto=webp&s=2bfaa3eeffd829fae0c859b64e1949059aa8cd11", "width": 108, "height": 56}, {"url": "https://external-preview.redd.it/1BW_tEI_79MxQWKq6jUAgoobqbYuMH8_3SwDBOz0-wE.jpeg?width=216&crop=smart&auto=webp&s=b64f1057f1c30b009c4e671b9eaedbd724f1d5d2", "width": 216, "height": 113}, {"url": "https://external-preview.redd.it/1BW_tEI_79MxQWKq6jUAgoobqbYuMH8_3SwDBOz0-wE.jpeg?width=320&crop=smart&auto=webp&s=6542659aba4ea47a2f94d711df00256767b9864d", "width": 320, "height": 168}, {"url": "https://external-preview.redd.it/1BW_tEI_79MxQWKq6jUAgoobqbYuMH8_3SwDBOz0-wE.jpeg?width=640&crop=smart&auto=webp&s=39798792740c277128f3a6edbab4401c8a0aa777", "width": 640, "height": 336}, {"url": "https://external-preview.redd.it/1BW_tEI_79MxQWKq6jUAgoobqbYuMH8_3SwDBOz0-wE.jpeg?width=960&crop=smart&auto=webp&s=ac692b1c91a4ae978bcbf308fd2bdec2516594b6", "width": 960, "height": 504}, {"url": "https://external-preview.redd.it/1BW_tEI_79MxQWKq6jUAgoobqbYuMH8_3SwDBOz0-wE.jpeg?width=1080&crop=smart&auto=webp&s=84df9a1d043528291794a5ac9a79ee1ae5f1b195", "width": 1080, "height": 567}], "variants": {}, "id": "1BW_tEI_79MxQWKq6jUAgoobqbYuMH8_3SwDBOz0-wE"}], "enabled": false}, "all_awardings": [], "awarders": [], "media_only": false, "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh3l", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "", "id": "1lobug4", "is_robot_indexable": true, "report_reasons": null, "author": "AlexandrTheTolerable", "discussion_type": null, "num_comments": 1868, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/news/comments/1lobug4/trumps_justice_department_issues_directive_to/", "stickied": false, "url": "https://www.theguardian.com/us-news/2025/jun/30/trump-birthright-citizenship-naturalized-citizens?CMP=Share_iOSApp_Other", "subreddit_subscribers": 30647410, "created_utc": 1751300444.0, "num_crossposts": 4, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "minnesota", "selftext": "Pride Parade 25'", "author_fullname": "t2_1jrylgjmkb", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Proud Dad", "link_flair_richtext": [{"e": "text", "t": "Events \ud83c\udfaa"}], "subreddit_name_prefixed": "r/minnesota", "hidden": false, "pwls": 6, "link_flair_css_class": "", "downs": 0, "thumbnail_height": 140, "top_awarded_type": null, "hide_score": false, "name": "t3_1lodfw7", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.9, "author_flair_background_color": null, "ups": 18577, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": true, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Events \ud83c\udfaa", "can_mod_post": false, "score": 18577, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "https://external-preview.redd.it/YH52PusQCz9wqtxMTtrlIWrwJKzS9nGtGaXt2LTCTsw.png?width=140&height=140&crop=140:140,smart&auto=webp&s=73f240fa43ca2f8e39f8b551d7b76c103f299aa2", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "image", "content_categories": null, "is_self": false, "subreddit_type": "public", "created": 1751304064.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "i.redd.it", "allow_live_comments": false, "selftext_html": "<!-- SC_OFF --><div class=\"md\"><p>Pride Parade 25&#39;</p>\n</div><!-- SC_ON -->", "likes": null, "suggested_sort": null, "banned_at_utc": null, "url_overridden_by_dest": "https://i.redd.it/wufc3hd4m3af1.png", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://preview.redd.it/wufc3hd4m3af1.png?auto=webp&s=5cb67a55274b4565ddf07e9a4b27c81c2fa4dd8c", "width": 1080, "height": 1351}, "resolutions": [{"url": "https://preview.redd.it/wufc3hd4m3af1.png?width=108&crop=smart&auto=webp&s=ef7de902cdfe9e65f17fc6c61da62790f9b42773", "width": 108, "height": 135}, {"url": "https://preview.redd.it/wufc3hd4m3af1.png?width=216&crop=smart&auto=webp&s=ecb3055afec9c2712562c9a1f19bc4c202fb5b90", "width": 216, "height": 270}, {"url": "https://preview.redd.it/wufc3hd4m3af1.png?width=320&crop=smart&auto=webp&s=8586367beac3f08881055e724f39fae5a47ec74a", "width": 320, "height": 400}, {"url": "https://preview.redd.it/wufc3hd4m3af1.png?width=640&crop=smart&auto=webp&s=c27794920d6c25cecd362d05e7bf7a1906acb274", "width": 640, "height": 800}, {"url": "https://preview.redd.it/wufc3hd4m3af1.png?width=960&crop=smart&auto=webp&s=743dfd2379bce981607ba455604a9d9acedcaef7", "width": 960, "height": 1200}, {"url": "https://preview.redd.it/wufc3hd4m3af1.png?width=1080&crop=smart&auto=webp&s=a5745682584bcbf418348b5efbe6b3e463bac4f0", "width": 1080, "height": 1351}], "variants": {}, "id": "YH52PusQCz9wqtxMTtrlIWrwJKzS9nGtGaXt2LTCTsw"}], "enabled": true}, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "5dedf5de-a192-11eb-a5ff-0ef466ac23a1", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "mod_note": null, "distinguished": null, "subreddit_id": "t5_2qhxs", "author_is_blocked": false, "mod_reason_by": null, "num_reports": null, "removal_reason": null, "link_flair_background_color": "#646d73", "id": "1lodfw7", "is_robot_indexable": true, "report_reasons": null, "author": "buttdaddyilovehim", "discussion_type": null, "num_comments": 434, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/minnesota/comments/1lodfw7/proud_dad/", "stickied": false, "url": "https://i.redd.it/wufc3hd4m3af1.png", "subreddit_subscribers": 404397, "created_utc": 1751304064.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "BeAmazed", "selftext": "", "author_fullname": "t2_1nsoa6ua", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Ryan Reynolds responds to a fan (burned victim)", "link_flair_richtext": [], "subreddit_name_prefixed": "r/BeAmazed", "hidden": false, "pwls": 6, "link_flair_css_class": "", "downs": 0, "thumbnail_height": 140, "top_awarded_type": null, "hide_score": false, "name": "t3_1lobivu", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.91, "author_flair_background_color": null, "ups": 55846, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": true, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Miscellaneous / Others", "can_mod_post": false, "score": 55846, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": true, "thumbnail": "https://external-preview.redd.it/VEJi86EXl6EshKP9IFVLd0pmiB-a9mVCz4ETBoRlRN8.jpeg?width=140&height=140&crop=140:140,smart&auto=webp&s=f1667d9a69060827e1431afb16acd5f4a40051fe", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "image", "content_categories": null, "is_self": false, "subreddit_type": "public", "created": 1751299698.0, "link_flair_type": "text", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "i.redd.it", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": "confidence", "banned_at_utc": null, "url_overridden_by_dest": "https://i.redd.it/ef7bvk6593af1.jpeg", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://preview.redd.it/ef7bvk6593af1.jpeg?auto=webp&s=b857f272d6b27ce5d4d45ef8803f42bbfd12b0b5", "width": 1320, "height": 1541}, "resolutions": [{"url": "https://preview.redd.it/ef7bvk6593af1.jpeg?width=108&crop=smart&auto=webp&s=f7d1d7aab9929aee8228b88ed1205af261cef5bc", "width": 108, "height": 126}, {"url": "https://preview.redd.it/ef7bvk6593af1.jpeg?width=216&crop=smart&auto=webp&s=5d7b0143490d5fb2a26ecbcfbb4ba60c1f749702", "width": 216, "height": 252}, {"url": "https://preview.redd.it/ef7bvk6593af1.jpeg?width=320&crop=smart&auto=webp&s=980ecfbc855b793731eca5da856eea2e6ef7377f", "width": 320, "height": 373}, {"url": "https://preview.redd.it/ef7bvk6593af1.jpeg?width=640&crop=smart&auto=webp&s=fddd2327d9187cea889b954970b46e6e015232b0", "width": 640, "height": 747}, {"url": "https://preview.redd.it/ef7bvk6593af1.jpeg?width=960&crop=smart&auto=webp&s=814efc35f28b14b20838902f1f1727a9e604708b", "width": 960, "height": 1120}, {"url": "https://preview.redd.it/ef7bvk6593af1.jpeg?width=1080&crop=smart&auto=webp&s=4d0521975361f0df6fdef1e4baa5d92d9dc7112f", "width": 1080, "height": 1260}], "variants": {}, "id": "VEJi86EXl6EshKP9IFVLd0pmiB-a9mVCz4ETBoRlRN8"}], "enabled": true}, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "93cfbe3e-c28e-11ed-afc7-6afce31ba6da", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "mod_note": null, "distinguished": null, "subreddit_id": "t5_363r3", "author_is_blocked": false, "mod_reason_by": null, "num_reports": null, "removal_reason": null, "link_flair_background_color": "#0266b3", "id": "1lobivu", "is_robot_indexable": true, "report_reasons": null, "author": "Kaos2018", "discussion_type": null, "num_comments": 433, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/BeAmazed/comments/1lobivu/ryan_reynolds_responds_to_a_fan_burned_victim/", "stickied": false, "url": "https://i.redd.it/ef7bvk6593af1.jpeg", "subreddit_subscribers": 8984173, "created_utc": 1751299698.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "BlackPeopleTwitter", "selftext": "", "author_fullname": "t2_13nt2o", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "It was only a matter of time.", "link_flair_richtext": [], "subreddit_name_prefixed": "r/BlackPeopleTwitter", "hidden": false, "pwls": 7, "link_flair_css_class": "asmode", "downs": 0, "thumbnail_height": 140, "top_awarded_type": null, "hide_score": true, "name": "t3_1lofjg9", "quarantine": false, "link_flair_text_color": null, "upvote_ratio": 0.97, "author_flair_background_color": "transparent", "ups": 9566, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": "417e582c-6534-11e9-869c-0edc8a2d5890", "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": true, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Country Club Thread", "can_mod_post": false, "score": 9566, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "https://b.thumbs.redditmedia.com/C0lFBL_UyKgvsylt0BAY6qsI5jJVpQbkvuhB60k35tk.jpg", "edited": false, "author_flair_css_class": "ccmember", "author_flair_richtext": [], "gildings": {}, "post_hint": "image", "content_categories": null, "is_self": false, "subreddit_type": "public", "created": 1751308843.0, "link_flair_type": "text", "wls": 7, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "i.redd.it", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": "top", "banned_at_utc": null, "url_overridden_by_dest": "https://i.redd.it/av2gik7c04af1.jpeg", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://preview.redd.it/av2gik7c04af1.jpeg?auto=webp&s=1705b3e4ad05bc6120bb903852ba67358e11cb11", "width": 1421, "height": 2053}, "resolutions": [{"url": "https://preview.redd.it/av2gik7c04af1.jpeg?width=108&crop=smart&auto=webp&s=ebeda23d47a60ad4e33745f0b3de1b92f735c0d7", "width": 108, "height": 156}, {"url": "https://preview.redd.it/av2gik7c04af1.jpeg?width=216&crop=smart&auto=webp&s=543b4eaae7a4cc7545842e72742180b5aee54712", "width": 216, "height": 312}, {"url": "https://preview.redd.it/av2gik7c04af1.jpeg?width=320&crop=smart&auto=webp&s=b3a1ad05719f01e3b653189f38b154b6aae3841d", "width": 320, "height": 462}, {"url": "https://preview.redd.it/av2gik7c04af1.jpeg?width=640&crop=smart&auto=webp&s=4749a346b8c098bf75ac7e0e89819568a932df85", "width": 640, "height": 924}, {"url": "https://preview.redd.it/av2gik7c04af1.jpeg?width=960&crop=smart&auto=webp&s=4c06df2c3c87b10285744e117fe3a1fadd8d0abf", "width": 960, "height": 1386}, {"url": "https://preview.redd.it/av2gik7c04af1.jpeg?width=1080&crop=smart&auto=webp&s=50ca30b3b8b27764df50822b79cbf52d57fc46ff", "width": 1080, "height": 1560}], "variants": {}, "id": "xeMUEDuqt15S_fn7xebecsygZa9nqz3MRzNGoda5hzw"}], "enabled": true}, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "45b97b1c-6217-11e9-854d-0eb19e2a4558", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": "\u2611\ufe0f", "treatment_tags": [], "visited": false, "removed_by": null, "mod_note": null, "distinguished": null, "subreddit_id": "t5_33x33", "author_is_blocked": false, "mod_reason_by": null, "num_reports": null, "removal_reason": null, "link_flair_background_color": "#73ad34", "id": "1lofjg9", "is_robot_indexable": true, "report_reasons": null, "author": "TheCommonKoala", "discussion_type": null, "num_comments": 384, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": "dark", "permalink": "/r/BlackPeopleTwitter/comments/1lofjg9/it_was_only_a_matter_of_time/", "stickied": false, "url": "https://i.redd.it/av2gik7c04af1.jpeg", "subreddit_subscribers": 6125401, "created_utc": 1751308843.0, "num_crossposts": 1, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "mildlyinteresting", "selftext": "", "author_fullname": "t2_4ex0q2a6", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "My son was born missing a toenail.", "link_flair_richtext": [], "subreddit_name_prefixed": "r/mildlyinteresting", "hidden": false, "pwls": 6, "link_flair_css_class": null, "downs": 0, "thumbnail_height": 140, "top_awarded_type": null, "hide_score": false, "name": "t3_1lod0kh", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.92, "author_flair_background_color": null, "subreddit_type": "public", "ups": 16083, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": true, "user_reports": [], "secure_media": null, "is_reddit_media_domain": true, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": null, "can_mod_post": false, "score": 16083, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "https://external-preview.redd.it/lKO4tGQLNb2RECLk0SgzhmJrQcbJI7KQvcygtxCaDBY.jpeg?width=140&height=140&crop=140:140,smart&auto=webp&s=ac377138633fe427dde3ac6bcb5d2156b1865545", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "image", "content_categories": null, "is_self": false, "mod_note": null, "created": 1751303115.0, "link_flair_type": "text", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "i.redd.it", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": null, "banned_at_utc": null, "url_overridden_by_dest": "https://i.redd.it/wop4bfraj3af1.jpeg", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://preview.redd.it/wop4bfraj3af1.jpeg?auto=webp&s=8d5055b0b57ccf94d575164e7a5560c387508a00", "width": 1714, "height": 2102}, "resolutions": [{"url": "https://preview.redd.it/wop4bfraj3af1.jpeg?width=108&crop=smart&auto=webp&s=0dac91467c1cf4e33bd54ba209d73600962264ec", "width": 108, "height": 132}, {"url": "https://preview.redd.it/wop4bfraj3af1.jpeg?width=216&crop=smart&auto=webp&s=6d9467026b0d620142f01fd1daeadfca0dc10ede", "width": 216, "height": 264}, {"url": "https://preview.redd.it/wop4bfraj3af1.jpeg?width=320&crop=smart&auto=webp&s=60c86cc7e475b782fe9519f9e5c85643520da0d0", "width": 320, "height": 392}, {"url": "https://preview.redd.it/wop4bfraj3af1.jpeg?width=640&crop=smart&auto=webp&s=5fc8d3002a857f407a3eaa90a5db3f728b2d1e1f", "width": 640, "height": 784}, {"url": "https://preview.redd.it/wop4bfraj3af1.jpeg?width=960&crop=smart&auto=webp&s=bd2c66c8ab5a5668104840ea2338f03eda980954", "width": 960, "height": 1177}, {"url": "https://preview.redd.it/wop4bfraj3af1.jpeg?width=1080&crop=smart&auto=webp&s=7ecded0af27547096040a7098c5de52789e23d67", "width": 1080, "height": 1324}], "variants": {}, "id": "lKO4tGQLNb2RECLk0SgzhmJrQcbJI7KQvcygtxCaDBY"}], "enabled": true}, "all_awardings": [], "awarders": [], "media_only": false, "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2ti4h", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "", "id": "1lod0kh", "is_robot_indexable": true, "report_reasons": null, "author": "jfarnworth15", "discussion_type": null, "num_comments": 1099, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/mildlyinteresting/comments/1lod0kh/my_son_was_born_missing_a_toenail/", "stickied": false, "url": "https://i.redd.it/wop4bfraj3af1.jpeg", "subreddit_subscribers": 24739373, "created_utc": 1751303115.0, "num_crossposts": 2, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "politics", "selftext": "", "author_fullname": "t2_123g5l", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "2024 election results lawsuit advances as documents requested", "link_flair_richtext": [], "subreddit_name_prefixed": "r/politics", "hidden": false, "pwls": 6, "link_flair_css_class": null, "downs": 0, "thumbnail_height": 93, "top_awarded_type": null, "hide_score": false, "name": "t3_1loaept", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.96, "author_flair_background_color": null, "subreddit_type": "public", "ups": 23147, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": "22a2077c-8e73-11e6-abdb-0e7000497d17", "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": null, "can_mod_post": false, "score": 23147, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "https://external-preview.redd.it/pLmkmKEmbj5XPiJjgHHW3CLSRiLI9dS8JXvGmh-tcF0.jpeg?width=140&height=93&crop=140:93,smart&auto=webp&s=12635fafe8396c08b2b3f95604bc4db323eaacbc", "edited": false, "author_flair_css_class": "wisconsin-flag", "author_flair_richtext": [{"a": ":flag-wi:", "e": "emoji", "u": "https://emoji.redditmedia.com/1311899yoxe11_t5_2cneq/flag-wi"}, {"e": "text", "t": " Wisconsin"}], "gildings": {}, "post_hint": "link", "content_categories": null, "is_self": false, "mod_note": null, "created": 1751297133.0, "link_flair_type": "text", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "richtext", "domain": "newsweek.com", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": null, "banned_at_utc": null, "url_overridden_by_dest": "https://www.newsweek.com/2024-election-results-lawsuit-documents-2091077", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://external-preview.redd.it/pLmkmKEmbj5XPiJjgHHW3CLSRiLI9dS8JXvGmh-tcF0.jpeg?auto=webp&s=42533f05c6c8395a6db8486b56a631707502d560", "width": 2500, "height": 1667}, "resolutions": [{"url": "https://external-preview.redd.it/pLmkmKEmbj5XPiJjgHHW3CLSRiLI9dS8JXvGmh-tcF0.jpeg?width=108&crop=smart&auto=webp&s=6be84d6abd6757a663dcfc7693a5d09a06be6f3d", "width": 108, "height": 72}, {"url": "https://external-preview.redd.it/pLmkmKEmbj5XPiJjgHHW3CLSRiLI9dS8JXvGmh-tcF0.jpeg?width=216&crop=smart&auto=webp&s=68af0d114ea54fa1aae9830fba6afb070be16869", "width": 216, "height": 144}, {"url": "https://external-preview.redd.it/pLmkmKEmbj5XPiJjgHHW3CLSRiLI9dS8JXvGmh-tcF0.jpeg?width=320&crop=smart&auto=webp&s=5682b82d5d9ce62bae8e4af08caca1a1bd0ab84f", "width": 320, "height": 213}, {"url": "https://external-preview.redd.it/pLmkmKEmbj5XPiJjgHHW3CLSRiLI9dS8JXvGmh-tcF0.jpeg?width=640&crop=smart&auto=webp&s=cd09bfc04c3b619ae48113bfcb87ba49ed0ca460", "width": 640, "height": 426}, {"url": "https://external-preview.redd.it/pLmkmKEmbj5XPiJjgHHW3CLSRiLI9dS8JXvGmh-tcF0.jpeg?width=960&crop=smart&auto=webp&s=c7400dcc0b3067b0d25fb927757dd3c1e53a6057", "width": 960, "height": 640}, {"url": "https://external-preview.redd.it/pLmkmKEmbj5XPiJjgHHW3CLSRiLI9dS8JXvGmh-tcF0.jpeg?width=1080&crop=smart&auto=webp&s=bd3be326b89d04af522e06156b0b71504be9bcf6", "width": 1080, "height": 720}], "variants": {}, "id": "pLmkmKEmbj5XPiJjgHHW3CLSRiLI9dS8JXvGmh-tcF0"}], "enabled": false}, "all_awardings": [], "awarders": [], "media_only": false, "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": ":flag-wi: Wisconsin", "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2cneq", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "", "id": "1loaept", "is_robot_indexable": true, "report_reasons": null, "author": "schuey_08", "discussion_type": null, "num_comments": 1277, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": "dark", "permalink": "/r/politics/comments/1loaept/2024_election_results_lawsuit_advances_as/", "stickied": false, "url": "https://www.newsweek.com/2024-election-results-lawsuit-documents-2091077", "subreddit_subscribers": 8858101, "created_utc": 1751297133.0, "num_crossposts": 7, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "comics", "selftext": "", "author_fullname": "t2_cfijs3z2", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Beach body", "link_flair_richtext": [{"e": "text", "t": "Comics Community"}], "subreddit_name_prefixed": "r/comics", "hidden": false, "pwls": 6, "link_flair_css_class": null, "downs": 0, "thumbnail_height": 140, "top_awarded_type": null, "hide_score": false, "name": "t3_1lob0pv", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.88, "author_flair_background_color": "", "ups": 28768, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": true, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Comics Community", "can_mod_post": false, "score": 28768, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": true, "thumbnail": "https://external-preview.redd.it/5esgZHdTsRnBYdXR9raEJh5v5LGdqr96UFbTkLq-BKs.png?width=140&height=140&crop=140:140,smart&auto=webp&s=1a975d0a5960dcaaf0416071a7d375db65efa518", "edited": false, "author_flair_css_class": "artist", "author_flair_richtext": [{"e": "text", "t": "PizzaCake"}], "gildings": {}, "post_hint": "image", "content_categories": ["comics"], "is_self": false, "subreddit_type": "public", "created": 1751298548.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "richtext", "domain": "i.redd.it", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": null, "banned_at_utc": null, "url_overridden_by_dest": "https://i.redd.it/8osp0bog53af1.png", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://preview.redd.it/8osp0bog53af1.png?auto=webp&s=77dbed0aa80f5b52266231fa80143a63a381e829", "width": 3289, "height": 3752}, "resolutions": [{"url": "https://preview.redd.it/8osp0bog53af1.png?width=108&crop=smart&auto=webp&s=0a39c61d3aa64a59b62243c0e7c0436c95292d2b", "width": 108, "height": 123}, {"url": "https://preview.redd.it/8osp0bog53af1.png?width=216&crop=smart&auto=webp&s=8c006086dcb4fd96e9aa68f38cabad1c9c1a8019", "width": 216, "height": 246}, {"url": "https://preview.redd.it/8osp0bog53af1.png?width=320&crop=smart&auto=webp&s=9affeb273860d899e5eb22a6506b06991aa84ccc", "width": 320, "height": 365}, {"url": "https://preview.redd.it/8osp0bog53af1.png?width=640&crop=smart&auto=webp&s=66f096db759fb1cf1f028885c5e84c0d0a75aee0", "width": 640, "height": 730}, {"url": "https://preview.redd.it/8osp0bog53af1.png?width=960&crop=smart&auto=webp&s=4b2762cf0e728fc6f01248438682b572681cb676", "width": 960, "height": 1095}, {"url": "https://preview.redd.it/8osp0bog53af1.png?width=1080&crop=smart&auto=webp&s=19135ac66fd21cb7eec6882509d22bb6aa7bb450", "width": 1080, "height": 1232}], "variants": {}, "id": "5esgZHdTsRnBYdXR9raEJh5v5LGdqr96UFbTkLq-BKs"}], "enabled": true}, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "7bae6768-32ac-11ee-88d9-ce8a0c76065b", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": "PizzaCake", "treatment_tags": [], "visited": false, "removed_by": null, "mod_note": null, "distinguished": null, "subreddit_id": "t5_2qh0s", "author_is_blocked": false, "mod_reason_by": null, "num_reports": null, "removal_reason": null, "link_flair_background_color": "#46d160", "id": "1lob0pv", "is_robot_indexable": true, "report_reasons": null, "author": "Pizzacakecomic", "discussion_type": null, "num_comments": 543, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": "dark", "permalink": "/r/comics/comments/1lob0pv/beach_body/", "stickied": false, "url": "https://i.redd.it/8osp0bog53af1.png", "subreddit_subscribers": 3466312, "created_utc": 1751298548.0, "num_crossposts": 2, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "interestingasfuck", "selftext": "", "author_fullname": "t2_s8u40rjf", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "They asked a boxer to test an \"indestructible\" TV", "link_flair_richtext": [{"e": "text", "t": " /r/all, /r/popular"}], "subreddit_name_prefixed": "r/interestingasfuck", "hidden": false, "pwls": 7, "link_flair_css_class": null, "downs": 0, "thumbnail_height": 140, "top_awarded_type": null, "hide_score": false, "name": "t3_1lo9y1f", "quarantine": false, "link_flair_text_color": null, "upvote_ratio": 0.93, "author_flair_background_color": null, "subreddit_type": "public", "ups": 43186, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": {"reddit_video": {"bitrate_kbps": 2400, "fallback_url": "https://v.redd.it/gynn00cay2af1/DASH_720.mp4?source=fallback", "has_audio": true, "height": 1280, "width": 720, "scrubber_media_url": "https://v.redd.it/gynn00cay2af1/DASH_96.mp4", "dash_url": "https://v.redd.it/gynn00cay2af1/DASHPlaylist.mpd?a=1753908005%2CMDg1NWM2ZTJmM2E1NzJmMzVlNzZlNTFhYTEwMTNkM2QxYmNiZmFmNmY5NmIwMGVkYTkzN2U3MTVjN2NmOWJhMQ%3D%3D&v=1&f=sd", "duration": 11, "hls_url": "https://v.redd.it/gynn00cay2af1/HLSPlaylist.m3u8?a=1753908005%2CYmIzODBlYjVjOTk5NmIwYTRjMmMxNTRlZDdkYThmYjZhYzI5YTRhOTYwYTUzZWE5YWE3N2MyMjdmNGQyYTI4MA%3D%3D&v=1&f=sd", "is_gif": false, "transcoding_status": "completed"}}, "is_reddit_media_domain": true, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": " /r/all, /r/popular", "can_mod_post": false, "score": 43186, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "https://external-preview.redd.it/N2wzOTZ6ZmF5MmFmMbPCg01W8_FMaMF39ngSGzzhw-bQ1iEbAnu2z7BC36b8.png?width=140&height=140&crop=140:140,smart&format=jpg&v=enabled&lthumb=true&s=83ed00395298460ad807256ca2e772d0398df45e", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "hosted:video", "content_categories": null, "is_self": false, "mod_note": null, "created": 1751296056.0, "link_flair_type": "richtext", "wls": 7, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "v.redd.it", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": null, "banned_at_utc": null, "url_overridden_by_dest": "https://v.redd.it/gynn00cay2af1", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://external-preview.redd.it/N2wzOTZ6ZmF5MmFmMbPCg01W8_FMaMF39ngSGzzhw-bQ1iEbAnu2z7BC36b8.png?format=pjpg&auto=webp&s=0bf3b56f50295ba46f2daf09aa676d8b499b6ef8", "width": 660, "height": 1175}, "resolutions": [{"url": "https://external-preview.redd.it/N2wzOTZ6ZmF5MmFmMbPCg01W8_FMaMF39ngSGzzhw-bQ1iEbAnu2z7BC36b8.png?width=108&crop=smart&format=pjpg&auto=webp&s=d719364f3a19e7af799a61dbbcf3ca19840f1faf", "width": 108, "height": 192}, {"url": "https://external-preview.redd.it/N2wzOTZ6ZmF5MmFmMbPCg01W8_FMaMF39ngSGzzhw-bQ1iEbAnu2z7BC36b8.png?width=216&crop=smart&format=pjpg&auto=webp&s=85f9e8e4dbbdd4d10d1560f7e4d3ee699897270a", "width": 216, "height": 384}, {"url": "https://external-preview.redd.it/N2wzOTZ6ZmF5MmFmMbPCg01W8_FMaMF39ngSGzzhw-bQ1iEbAnu2z7BC36b8.png?width=320&crop=smart&format=pjpg&auto=webp&s=538732b0cb540375cd3807e79f0f7737c471b8e5", "width": 320, "height": 569}, {"url": "https://external-preview.redd.it/N2wzOTZ6ZmF5MmFmMbPCg01W8_FMaMF39ngSGzzhw-bQ1iEbAnu2z7BC36b8.png?width=640&crop=smart&format=pjpg&auto=webp&s=0583fdb0c77b398b949cd302c8fdb47556c9a82a", "width": 640, "height": 1139}], "variants": {}, "id": "N2wzOTZ6ZmF5MmFmMbPCg01W8_FMaMF39ngSGzzhw-bQ1iEbAnu2z7BC36b8"}], "enabled": false}, "all_awardings": [], "awarders": [], "media_only": false, "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qhsa", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": null, "id": "1lo9y1f", "is_robot_indexable": true, "report_reasons": null, "author": "beekay8845", "discussion_type": null, "num_comments": 828, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/interestingasfuck/comments/1lo9y1f/they_asked_a_boxer_to_test_an_indestructible_tv/", "stickied": false, "url": "https://v.redd.it/gynn00cay2af1", "subreddit_subscribers": 15034710, "created_utc": 1751296056.0, "num_crossposts": 2, "media": {"reddit_video": {"bitrate_kbps": 2400, "fallback_url": "https://v.redd.it/gynn00cay2af1/DASH_720.mp4?source=fallback", "has_audio": true, "height": 1280, "width": 720, "scrubber_media_url": "https://v.redd.it/gynn00cay2af1/DASH_96.mp4", "dash_url": "https://v.redd.it/gynn00cay2af1/DASHPlaylist.mpd?a=1753908005%2CMDg1NWM2ZTJmM2E1NzJmMzVlNzZlNTFhYTEwMTNkM2QxYmNiZmFmNmY5NmIwMGVkYTkzN2U3MTVjN2NmOWJhMQ%3D%3D&v=1&f=sd", "duration": 11, "hls_url": "https://v.redd.it/gynn00cay2af1/HLSPlaylist.m3u8?a=1753908005%2CYmIzODBlYjVjOTk5NmIwYTRjMmMxNTRlZDdkYThmYjZhYzI5YTRhOTYwYTUzZWE5YWE3N2MyMjdmNGQyYTI4MA%3D%3D&v=1&f=sd", "is_gif": false, "transcoding_status": "completed"}}, "is_video": true}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "MadeMeSmile", "selftext": "Hydrangea season in Japan", "author_fullname": "t2_w9h53g21", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "The sight of ducks walking on Hydrangea petals \ud83e\udd86", "link_flair_richtext": [{"a": ":orly:", "e": "emoji", "u": "https://emoji.redditmedia.com/crum4urt1guz_t5_3nqvj/orly"}, {"e": "text", "t": "ANIMALS "}, {"a": ":sloth:", "e": "emoji", "u": "https://emoji.redditmedia.com/rpczqdwy1guz_t5_3nqvj/sloth"}], "subreddit_name_prefixed": "r/MadeMeSmile", "hidden": false, "pwls": 6, "link_flair_css_class": "animal", "downs": 0, "thumbnail_height": 140, "top_awarded_type": null, "hide_score": false, "name": "t3_1lob0pp", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.99, "author_flair_background_color": null, "ups": 20752, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": {"reddit_video": {"bitrate_kbps": 2400, "fallback_url": "https://v.redd.it/gzklc8of43af1/DASH_720.mp4?source=fallback", "has_audio": true, "height": 1280, "width": 720, "scrubber_media_url": "https://v.redd.it/gzklc8of43af1/DASH_96.mp4", "dash_url": "https://v.redd.it/gzklc8of43af1/DASHPlaylist.mpd?a=1753908005%2CNjZiOGVjMGQ5MmUyYWMzZTYyOTA1YzYzNTYxOGI2MTZiNWYxZGE0ZmE1NDA3MjRlYzk2NDc4MmFiMTY2OThmMg%3D%3D&v=1&f=sd", "duration": 27, "hls_url": "https://v.redd.it/gzklc8of43af1/HLSPlaylist.m3u8?a=1753908005%2CMTQ2MDEwYTFiNWQyNWM5ODE1MThlOWQ1YTIxYTQ4N2YyZmNlYzhmOTI3ZTljZmRiMTI4Y2M1ZTVjMjgyMjU5YQ%3D%3D&v=1&f=sd", "is_gif": false, "transcoding_status": "completed"}}, "is_reddit_media_domain": true, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": ":orly:ANIMALS :sloth:", "can_mod_post": false, "score": 20752, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "https://external-preview.redd.it/NWtqdXM5b2Y0M2FmMXfJkHkgI998Dyyly0n_Hpkwjp_kDbDOn7ef5G9Emz0N.png?width=140&height=140&crop=140:140,smart&format=jpg&v=enabled&lthumb=true&s=3195330ca5e4a4acbfe5d5bfce4017218376b590", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "hosted:video", "content_categories": null, "is_self": false, "subreddit_type": "public", "created": 1751298548.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "v.redd.it", "allow_live_comments": false, "selftext_html": "<!-- SC_OFF --><div class=\"md\"><p>Hydrangea season in Japan</p>\n</div><!-- SC_ON -->", "likes": null, "suggested_sort": null, "banned_at_utc": null, "url_overridden_by_dest": "https://v.redd.it/gzklc8of43af1", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://external-preview.redd.it/NWtqdXM5b2Y0M2FmMXfJkHkgI998Dyyly0n_Hpkwjp_kDbDOn7ef5G9Emz0N.png?format=pjpg&auto=webp&s=99c575e3d6b8a1b155a6c35a48bfd0e114f3fe6c", "width": 720, "height": 1280}, "resolutions": [{"url": "https://external-preview.redd.it/NWtqdXM5b2Y0M2FmMXfJkHkgI998Dyyly0n_Hpkwjp_kDbDOn7ef5G9Emz0N.png?width=108&crop=smart&format=pjpg&auto=webp&s=562c26f0f0446c47a9f8aea7a35fa1c9fc0ad69b", "width": 108, "height": 192}, {"url": "https://external-preview.redd.it/NWtqdXM5b2Y0M2FmMXfJkHkgI998Dyyly0n_Hpkwjp_kDbDOn7ef5G9Emz0N.png?width=216&crop=smart&format=pjpg&auto=webp&s=d507034eb6e54f19ec27354b652647a277c1c200", "width": 216, "height": 384}, {"url": "https://external-preview.redd.it/NWtqdXM5b2Y0M2FmMXfJkHkgI998Dyyly0n_Hpkwjp_kDbDOn7ef5G9Emz0N.png?width=320&crop=smart&format=pjpg&auto=webp&s=09e566c433707148647c4cc2b74b29ff87f87445", "width": 320, "height": 568}, {"url": "https://external-preview.redd.it/NWtqdXM5b2Y0M2FmMXfJkHkgI998Dyyly0n_Hpkwjp_kDbDOn7ef5G9Emz0N.png?width=640&crop=smart&format=pjpg&auto=webp&s=bf8bbaf00cde9cace208a36cd48ed755887c7629", "width": 640, "height": 1137}], "variants": {}, "id": "NWtqdXM5b2Y0M2FmMXfJkHkgI998Dyyly0n_Hpkwjp_kDbDOn7ef5G9Emz0N"}], "enabled": false}, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "65eb7136-b970-11ea-af2a-0e0556d65e6b", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "mod_note": null, "distinguished": null, "subreddit_id": "t5_2uqcm", "author_is_blocked": false, "mod_reason_by": null, "num_reports": null, "removal_reason": null, "link_flair_background_color": "#edeff1", "id": "1lob0pp", "is_robot_indexable": true, "report_reasons": null, "author": "Boundaries1st", "discussion_type": null, "num_comments": 144, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/MadeMeSmile/comments/1lob0pp/the_sight_of_ducks_walking_on_hydrangea_petals/", "stickied": false, "url": "https://v.redd.it/gzklc8of43af1", "subreddit_subscribers": 11622721, "created_utc": 1751298548.0, "num_crossposts": 11, "media": {"reddit_video": {"bitrate_kbps": 2400, "fallback_url": "https://v.redd.it/gzklc8of43af1/DASH_720.mp4?source=fallback", "has_audio": true, "height": 1280, "width": 720, "scrubber_media_url": "https://v.redd.it/gzklc8of43af1/DASH_96.mp4", "dash_url": "https://v.redd.it/gzklc8of43af1/DASHPlaylist.mpd?a=1753908005%2CNjZiOGVjMGQ5MmUyYWMzZTYyOTA1YzYzNTYxOGI2MTZiNWYxZGE0ZmE1NDA3MjRlYzk2NDc4MmFiMTY2OThmMg%3D%3D&v=1&f=sd", "duration": 27, "hls_url": "https://v.redd.it/gzklc8of43af1/HLSPlaylist.m3u8?a=1753908005%2CMTQ2MDEwYTFiNWQyNWM5ODE1MThlOWQ1YTIxYTQ4N2YyZmNlYzhmOTI3ZTljZmRiMTI4Y2M1ZTVjMjgyMjU5YQ%3D%3D&v=1&f=sd", "is_gif": false, "transcoding_status": "completed"}}, "is_video": true}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "worldnews", "selftext": "", "author_fullname": "t2_dca49b9y8", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Canada transfers US$1.7bn in revenues from frozen Russian assets to Ukraine", "link_flair_richtext": [{"e": "text", "t": "Russia/Ukraine"}], "subreddit_name_prefixed": "r/worldnews", "hidden": false, "pwls": 7, "link_flair_css_class": "russia", "downs": 0, "thumbnail_height": 78, "top_awarded_type": null, "hide_score": false, "name": "t3_1loakb3", "quarantine": false, "link_flair_text_color": null, "upvote_ratio": 0.98, "author_flair_background_color": null, "subreddit_type": "public", "ups": 17688, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Russia/Ukraine", "can_mod_post": false, "score": 17688, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "https://external-preview.redd.it/4RBPOjAvzUzPvZ0QKC1MlPUAMAhbpR3ErD9OqLGhDaw.jpeg?width=140&height=78&crop=140:78,smart&auto=webp&s=969009a91f219da634ac65b316a3532e0d6ed160", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "link", "content_categories": null, "is_self": false, "mod_note": null, "created": 1751297504.0, "link_flair_type": "richtext", "wls": 7, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "pravda.com.ua", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": null, "banned_at_utc": null, "url_overridden_by_dest": "https://www.pravda.com.ua/eng/news/2025/06/30/7519499/", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://external-preview.redd.it/4RBPOjAvzUzPvZ0QKC1MlPUAMAhbpR3ErD9OqLGhDaw.jpeg?auto=webp&s=c07fbb18fe75430625f05d12112ffc3a21fb9821", "width": 1300, "height": 729}, "resolutions": [{"url": "https://external-preview.redd.it/4RBPOjAvzUzPvZ0QKC1MlPUAMAhbpR3ErD9OqLGhDaw.jpeg?width=108&crop=smart&auto=webp&s=7c06e8fb7bbc03b204aa1fde2a956f9532d88748", "width": 108, "height": 60}, {"url": "https://external-preview.redd.it/4RBPOjAvzUzPvZ0QKC1MlPUAMAhbpR3ErD9OqLGhDaw.jpeg?width=216&crop=smart&auto=webp&s=35cd5d9f6d77574c76711f19badf0c544cb4aeb3", "width": 216, "height": 121}, {"url": "https://external-preview.redd.it/4RBPOjAvzUzPvZ0QKC1MlPUAMAhbpR3ErD9OqLGhDaw.jpeg?width=320&crop=smart&auto=webp&s=effe4671da0786d11fefc4b22b0495d1ac27e290", "width": 320, "height": 179}, {"url": "https://external-preview.redd.it/4RBPOjAvzUzPvZ0QKC1MlPUAMAhbpR3ErD9OqLGhDaw.jpeg?width=640&crop=smart&auto=webp&s=50265cf1b26ece2a07d178f9bd6b605d79a103ed", "width": 640, "height": 358}, {"url": "https://external-preview.redd.it/4RBPOjAvzUzPvZ0QKC1MlPUAMAhbpR3ErD9OqLGhDaw.jpeg?width=960&crop=smart&auto=webp&s=ee2810d1ddedbc9464764657f80c95601d97ff00", "width": 960, "height": 538}, {"url": "https://external-preview.redd.it/4RBPOjAvzUzPvZ0QKC1MlPUAMAhbpR3ErD9OqLGhDaw.jpeg?width=1080&crop=smart&auto=webp&s=dff12b69fa2196b99d6cfb26134a265ca32a71f8", "width": 1080, "height": 605}], "variants": {}, "id": "4RBPOjAvzUzPvZ0QKC1MlPUAMAhbpR3ErD9OqLGhDaw"}], "enabled": false}, "all_awardings": [], "awarders": [], "media_only": false, "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qh13", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": null, "id": "1loakb3", "is_robot_indexable": true, "report_reasons": null, "author": "Aggravating_Money992", "discussion_type": null, "num_comments": 308, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/worldnews/comments/1loakb3/canada_transfers_us17bn_in_revenues_from_frozen/", "stickied": false, "url": "https://www.pravda.com.ua/eng/news/2025/06/30/7519499/", "subreddit_subscribers": 46648719, "created_utc": 1751297504.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "SipsTea", "selftext": "", "author_fullname": "t2_1oj9p6b1zu", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Your thought", "link_flair_richtext": [{"e": "text", "t": "Chugging tea "}, {"a": ":Kermit:", "e": "emoji", "u": "https://emoji.redditmedia.com/hmnsf4uclfl81_t5_5tdqj0/Kermit"}], "subreddit_name_prefixed": "r/SipsTea", "hidden": false, "pwls": 7, "link_flair_css_class": "", "downs": 0, "thumbnail_height": 140, "top_awarded_type": null, "hide_score": false, "name": "t3_1loadgl", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.96, "author_flair_background_color": null, "ups": 27341, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": true, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Chugging tea :Kermit:", "can_mod_post": false, "score": 27341, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "https://external-preview.redd.it/7hpM5dFCwdeQUb5U7RNfIRN8byrZNH0k89cQVj7L83U.jpeg?width=140&height=140&crop=140:140,smart&auto=webp&s=ecd3c7999cdb1825ca23263cdf9d54991303b5bc", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "image", "content_categories": null, "is_self": false, "subreddit_type": "public", "created": 1751297049.0, "link_flair_type": "richtext", "wls": 7, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "i.redd.it", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": null, "banned_at_utc": null, "url_overridden_by_dest": "https://i.redd.it/5mlf2lj913af1.jpeg", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://preview.redd.it/5mlf2lj913af1.jpeg?auto=webp&s=b929563f4e0de26b2e377ef48ca218f622149c56", "width": 1080, "height": 1326}, "resolutions": [{"url": "https://preview.redd.it/5mlf2lj913af1.jpeg?width=108&crop=smart&auto=webp&s=2483d3293bc147016bbc4a147ca00d5691d2d460", "width": 108, "height": 132}, {"url": "https://preview.redd.it/5mlf2lj913af1.jpeg?width=216&crop=smart&auto=webp&s=5a75a12395207dfbef5a7d9ad5f4290eb691206c", "width": 216, "height": 265}, {"url": "https://preview.redd.it/5mlf2lj913af1.jpeg?width=320&crop=smart&auto=webp&s=fcb9bef42d7efcc1ef21ac828b7a8cddca1d4d1c", "width": 320, "height": 392}, {"url": "https://preview.redd.it/5mlf2lj913af1.jpeg?width=640&crop=smart&auto=webp&s=186c9fcf9a85cab18b0c24d2ce63bcb0a90fe008", "width": 640, "height": 785}, {"url": "https://preview.redd.it/5mlf2lj913af1.jpeg?width=960&crop=smart&auto=webp&s=76f468838006a6660bf0328bdc81e67a9bffa539", "width": 960, "height": 1178}, {"url": "https://preview.redd.it/5mlf2lj913af1.jpeg?width=1080&crop=smart&auto=webp&s=5bba00417436eaf90e4714c73597c926a01119ec", "width": 1080, "height": 1326}], "variants": {}, "id": "7hpM5dFCwdeQUb5U7RNfIRN8byrZNH0k89cQVj7L83U"}], "enabled": true}, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "75494202-a1a4-11ec-8b4b-ae20b4018c06", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "mod_note": null, "distinguished": null, "subreddit_id": "t5_5tdqj0", "author_is_blocked": false, "mod_reason_by": null, "num_reports": null, "removal_reason": null, "link_flair_background_color": "#46d160", "id": "1loadgl", "is_robot_indexable": true, "report_reasons": null, "author": "NIR0SH4N", "discussion_type": null, "num_comments": 943, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/SipsTea/comments/1loadgl/your_thought/", "stickied": false, "url": "https://i.redd.it/5mlf2lj913af1.jpeg", "subreddit_subscribers": 2497803, "created_utc": 1751297049.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "MurderedByWords", "selftext": "", "author_fullname": "t2_jnbd2jxuz", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Bro eats pizza with chopsticks.", "link_flair_richtext": [], "subreddit_name_prefixed": "r/MurderedByWords", "hidden": false, "pwls": 7, "link_flair_css_class": null, "downs": 0, "thumbnail_height": 140, "top_awarded_type": null, "hide_score": false, "name": "t3_1loapu2", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.95, "author_flair_background_color": null, "subreddit_type": "public", "ups": 17538, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": true, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": null, "can_mod_post": false, "score": 17538, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "https://external-preview.redd.it/lTlLCCm544tHFt_Huh0sWPwMD8c5bkrVlkc4M2Qqgk8.jpeg?width=140&height=140&crop=140:140,smart&auto=webp&s=4978c4515d092185ad26163a316e6cf8fd4a02da", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "image", "content_categories": null, "is_self": false, "mod_note": null, "created": 1751297853.0, "link_flair_type": "text", "wls": 7, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "i.redd.it", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": "confidence", "banned_at_utc": null, "url_overridden_by_dest": "https://i.redd.it/sucr7s8n33af1.jpeg", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://preview.redd.it/sucr7s8n33af1.jpeg?auto=webp&s=5223e3c34d64ea91be963472d1b5c82a3e4eda3f", "width": 1179, "height": 1563}, "resolutions": [{"url": "https://preview.redd.it/sucr7s8n33af1.jpeg?width=108&crop=smart&auto=webp&s=33df16a4198ddb91a870ed8f23d1195274a75134", "width": 108, "height": 143}, {"url": "https://preview.redd.it/sucr7s8n33af1.jpeg?width=216&crop=smart&auto=webp&s=a1bf6174456ac5515ea113330bda14eb8fa6f722", "width": 216, "height": 286}, {"url": "https://preview.redd.it/sucr7s8n33af1.jpeg?width=320&crop=smart&auto=webp&s=22169efa85ac36fc28dcffc0e2eb0515f5ca2ea3", "width": 320, "height": 424}, {"url": "https://preview.redd.it/sucr7s8n33af1.jpeg?width=640&crop=smart&auto=webp&s=a4258e92cd3686c5f90b67a4fe640245787d7579", "width": 640, "height": 848}, {"url": "https://preview.redd.it/sucr7s8n33af1.jpeg?width=960&crop=smart&auto=webp&s=8e44325aa9ef04fbce8994f5a450ebaad7ca8265", "width": 960, "height": 1272}, {"url": "https://preview.redd.it/sucr7s8n33af1.jpeg?width=1080&crop=smart&auto=webp&s=88a3910bafad189593956e904d03e01931680175", "width": 1080, "height": 1431}], "variants": {}, "id": "lTlLCCm544tHFt_Huh0sWPwMD8c5bkrVlkc4M2Qqgk8"}], "enabled": true}, "all_awardings": [], "awarders": [], "media_only": false, "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_3hx3r", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "", "id": "1loapu2", "is_robot_indexable": true, "report_reasons": null, "author": "DullEconomist718", "discussion_type": null, "num_comments": 842, "send_replies": false, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/MurderedByWords/comments/1loapu2/bro_eats_pizza_with_chopsticks/", "stickied": false, "url": "https://i.redd.it/sucr7s8n33af1.jpeg", "subreddit_subscribers": 3288281, "created_utc": 1751297853.0, "num_crossposts": 1, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "nottheonion", "selftext": "", "author_fullname": "t2_u90kmmgb", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "When Jon Stewart took over \u2018The Daily Show,\u2019 satire became a trusted news source", "link_flair_richtext": [], "subreddit_name_prefixed": "r/nottheonion", "hidden": false, "pwls": 7, "link_flair_css_class": null, "downs": 0, "thumbnail_height": 105, "top_awarded_type": null, "hide_score": false, "name": "t3_1lobfdz", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.95, "author_flair_background_color": null, "subreddit_type": "public", "ups": 11932, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": null, "can_mod_post": false, "score": 11932, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "https://external-preview.redd.it/0Adc3Dv4i2xBEeRcyFxhqGSrKgZ21F5AQaPpZlAE16c.jpeg?width=140&height=105&crop=140:105,smart&auto=webp&s=488c09ac3c133df96dc1870e5164f0e2c9296275", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "link", "content_categories": null, "is_self": false, "mod_note": null, "created": 1751299472.0, "link_flair_type": "text", "wls": 7, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "poynter.org", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": null, "banned_at_utc": null, "url_overridden_by_dest": "https://www.poynter.org/ethics-trust/2025/poynter-50-jon-stewart-satire-news/", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://external-preview.redd.it/0Adc3Dv4i2xBEeRcyFxhqGSrKgZ21F5AQaPpZlAE16c.jpeg?auto=webp&s=f10219ccd9e0ee9faf45b3b86df93df0cc3b753e", "width": 1080, "height": 810}, "resolutions": [{"url": "https://external-preview.redd.it/0Adc3Dv4i2xBEeRcyFxhqGSrKgZ21F5AQaPpZlAE16c.jpeg?width=108&crop=smart&auto=webp&s=6a71e801936cecd8871e529a6482f2cdbd9a2755", "width": 108, "height": 81}, {"url": "https://external-preview.redd.it/0Adc3Dv4i2xBEeRcyFxhqGSrKgZ21F5AQaPpZlAE16c.jpeg?width=216&crop=smart&auto=webp&s=4ebaabeb0abd2e5919caab77f9aebacc5525d971", "width": 216, "height": 162}, {"url": "https://external-preview.redd.it/0Adc3Dv4i2xBEeRcyFxhqGSrKgZ21F5AQaPpZlAE16c.jpeg?width=320&crop=smart&auto=webp&s=3457ed98f3cb11257c258ad9782cf79afd862cb8", "width": 320, "height": 240}, {"url": "https://external-preview.redd.it/0Adc3Dv4i2xBEeRcyFxhqGSrKgZ21F5AQaPpZlAE16c.jpeg?width=640&crop=smart&auto=webp&s=70ab8904d10072f45c8deac844ff9e82e1cb8e46", "width": 640, "height": 480}, {"url": "https://external-preview.redd.it/0Adc3Dv4i2xBEeRcyFxhqGSrKgZ21F5AQaPpZlAE16c.jpeg?width=960&crop=smart&auto=webp&s=aa25baf2e301b5d0ad4f5abdd0074d1329cbd2dc", "width": 960, "height": 720}, {"url": "https://external-preview.redd.it/0Adc3Dv4i2xBEeRcyFxhqGSrKgZ21F5AQaPpZlAE16c.jpeg?width=1080&crop=smart&auto=webp&s=3c4ef07292118048c7061ac525ba1bf9e55f45d9", "width": 1080, "height": 810}], "variants": {}, "id": "0Adc3Dv4i2xBEeRcyFxhqGSrKgZ21F5AQaPpZlAE16c"}], "enabled": false}, "all_awardings": [], "awarders": [], "media_only": false, "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qnts", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "", "id": "1lobfdz", "is_robot_indexable": true, "report_reasons": null, "author": "Past_Distribution144", "discussion_type": null, "num_comments": 326, "send_replies": false, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/nottheonion/comments/1lobfdz/when_jon_stewart_took_over_the_daily_show_satire/", "stickied": false, "url": "https://www.poynter.org/ethics-trust/2025/poynter-50-jon-stewart-satire-news/", "subreddit_subscribers": 25824526, "created_utc": 1751299472.0, "num_crossposts": 2, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "PublicFreakout", "selftext": "", "author_fullname": "t2_3prne0od", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Karoline Leavitt indicates the administration is open to a denaturalization-oriented investigation against Zohran Mamdani", "link_flair_richtext": [{"e": "text", "t": "r/all"}], "subreddit_name_prefixed": "r/PublicFreakout", "hidden": false, "pwls": null, "link_flair_css_class": null, "downs": 0, "thumbnail_height": 78, "top_awarded_type": null, "hide_score": false, "name": "t3_1loey9c", "quarantine": false, "link_flair_text_color": null, "upvote_ratio": 0.97, "author_flair_background_color": "", "subreddit_type": "public", "ups": 6654, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": {"reddit_video": {"bitrate_kbps": 2400, "fallback_url": "https://v.redd.it/r3cjarz9w3af1/DASH_720.mp4?source=fallback", "has_audio": true, "height": 720, "width": 1280, "scrubber_media_url": "https://v.redd.it/r3cjarz9w3af1/DASH_96.mp4", "dash_url": "https://v.redd.it/r3cjarz9w3af1/DASHPlaylist.mpd?a=1753908005%2CMjc1ZTk4MWMyYTljOWE2MjdkNDE5NGU5MTVjZjgwOGY3ZGY2NTQxODk1ZWY2ZmJmM2E5YzNjODJiYzlhMTI4ZA%3D%3D&v=1&f=sd", "duration": 51, "hls_url": "https://v.redd.it/r3cjarz9w3af1/HLSPlaylist.m3u8?a=1753908005%2CN2U5ZDZmNTM2Y2JjZGUyZWEzYjJkMTc4OTViYzQ1Zjc1YTgwZTQ1YWY0MDRmZTMyZmZlZTNjZDJkMGY4MGY2Yw%3D%3D&v=1&f=sd", "is_gif": false, "transcoding_status": "completed"}}, "is_reddit_media_domain": true, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "r/all", "can_mod_post": false, "score": 6654, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": true, "thumbnail": "https://external-preview.redd.it/MWtxcTlqMGF3M2FmMSvMQmgMbDsOYIWUelZQ1tk_q9izACUwC1eoQYBjNf3P.png?width=140&height=78&crop=140:78,smart&format=jpg&v=enabled&lthumb=true&s=a66885435883b01ffe71d4478223d049082302b8", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [{"e": "text", "t": "what is your fascination with my forbidden closet of mystery? \ud83e\udd28"}], "gildings": {}, "post_hint": "hosted:video", "content_categories": null, "is_self": false, "mod_note": null, "created": 1751307477.0, "link_flair_type": "richtext", "wls": null, "removed_by_category": null, "banned_by": null, "author_flair_type": "richtext", "domain": "v.redd.it", "allow_live_comments": true, "selftext_html": null, "likes": null, "suggested_sort": null, "banned_at_utc": null, "url_overridden_by_dest": "https://v.redd.it/r3cjarz9w3af1", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://external-preview.redd.it/MWtxcTlqMGF3M2FmMSvMQmgMbDsOYIWUelZQ1tk_q9izACUwC1eoQYBjNf3P.png?format=pjpg&auto=webp&s=12dd689850afea5e580c527f1c5806de3c6e34ea", "width": 1080, "height": 607}, "resolutions": [{"url": "https://external-preview.redd.it/MWtxcTlqMGF3M2FmMSvMQmgMbDsOYIWUelZQ1tk_q9izACUwC1eoQYBjNf3P.png?width=108&crop=smart&format=pjpg&auto=webp&s=d73eff1ba4271c46a063e3eaede2f00dbd7f0190", "width": 108, "height": 60}, {"url": "https://external-preview.redd.it/MWtxcTlqMGF3M2FmMSvMQmgMbDsOYIWUelZQ1tk_q9izACUwC1eoQYBjNf3P.png?width=216&crop=smart&format=pjpg&auto=webp&s=4e4cbc087cb1afbaaac4acb607673a8f09816c1c", "width": 216, "height": 121}, {"url": "https://external-preview.redd.it/MWtxcTlqMGF3M2FmMSvMQmgMbDsOYIWUelZQ1tk_q9izACUwC1eoQYBjNf3P.png?width=320&crop=smart&format=pjpg&auto=webp&s=d4bfae5cc5e790194a6e84e805552a17417ee329", "width": 320, "height": 179}, {"url": "https://external-preview.redd.it/MWtxcTlqMGF3M2FmMSvMQmgMbDsOYIWUelZQ1tk_q9izACUwC1eoQYBjNf3P.png?width=640&crop=smart&format=pjpg&auto=webp&s=eb254d899022044cbe55fe01f9a44f6c555b0c9b", "width": 640, "height": 359}, {"url": "https://external-preview.redd.it/MWtxcTlqMGF3M2FmMSvMQmgMbDsOYIWUelZQ1tk_q9izACUwC1eoQYBjNf3P.png?width=960&crop=smart&format=pjpg&auto=webp&s=c2d35ac3cd327da1c597340f0fc7ba92036b0795", "width": 960, "height": 539}, {"url": "https://external-preview.redd.it/MWtxcTlqMGF3M2FmMSvMQmgMbDsOYIWUelZQ1tk_q9izACUwC1eoQYBjNf3P.png?width=1080&crop=smart&format=pjpg&auto=webp&s=f8ca0652bc7079205ef0c2f4a8810f2e3f524d33", "width": 1080, "height": 607}], "variants": {}, "id": "MWtxcTlqMGF3M2FmMSvMQmgMbDsOYIWUelZQ1tk_q9izACUwC1eoQYBjNf3P"}], "enabled": false}, "all_awardings": [], "awarders": [], "media_only": false, "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": "what is your fascination with my forbidden closet of mystery? \ud83e\udd28", "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2yrq6", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": null, "id": "1loey9c", "is_robot_indexable": true, "report_reasons": null, "author": "ExactlySorta", "discussion_type": null, "num_comments": 570, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": "dark", "permalink": "/r/PublicFreakout/comments/1loey9c/karoline_leavitt_indicates_the_administration_is/", "stickied": false, "url": "https://v.redd.it/r3cjarz9w3af1", "subreddit_subscribers": 4711256, "created_utc": 1751307477.0, "num_crossposts": 4, "media": {"reddit_video": {"bitrate_kbps": 2400, "fallback_url": "https://v.redd.it/r3cjarz9w3af1/DASH_720.mp4?source=fallback", "has_audio": true, "height": 720, "width": 1280, "scrubber_media_url": "https://v.redd.it/r3cjarz9w3af1/DASH_96.mp4", "dash_url": "https://v.redd.it/r3cjarz9w3af1/DASHPlaylist.mpd?a=1753908005%2CMjc1ZTk4MWMyYTljOWE2MjdkNDE5NGU5MTVjZjgwOGY3ZGY2NTQxODk1ZWY2ZmJmM2E5YzNjODJiYzlhMTI4ZA%3D%3D&v=1&f=sd", "duration": 51, "hls_url": "https://v.redd.it/r3cjarz9w3af1/HLSPlaylist.m3u8?a=1753908005%2CN2U5ZDZmNTM2Y2JjZGUyZWEzYjJkMTc4OTViYzQ1Zjc1YTgwZTQ1YWY0MDRmZTMyZmZlZTNjZDJkMGY4MGY2Yw%3D%3D&v=1&f=sd", "is_gif": false, "transcoding_status": "completed"}}, "is_video": true}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "facepalm", "selftext": "", "author_fullname": "t2_rwd1itob", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "PSA my fellow Americans should see", "link_flair_richtext": [{"a": ":Protest:", "e": "emoji", "u": "https://emoji.redditmedia.com/b656hxb7ruo61_t5_2r5rp/Protest"}, {"e": "text", "t": "\ud83c\uddf5\u200b\ud83c\uddf7\u200b\ud83c\uddf4\u200b\ud83c\uddf9\u200b\ud83c\uddea\u200b\ud83c\uddf8\u200b\ud83c\uddf9\u200b"}], "subreddit_name_prefixed": "r/facepalm", "hidden": false, "pwls": 7, "link_flair_css_class": "", "downs": 0, "thumbnail_height": 140, "top_awarded_type": null, "hide_score": false, "name": "t3_1lodbxg", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.98, "author_flair_background_color": null, "ups": 8457, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": true, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": ":Protest:\ud83c\uddf5\u200b\ud83c\uddf7\u200b\ud83c\uddf4\u200b\ud83c\uddf9\u200b\ud83c\uddea\u200b\ud83c\uddf8\u200b\ud83c\uddf9\u200b", "can_mod_post": false, "score": 8457, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "https://external-preview.redd.it/EH8mCMTJYCUSUHmscRRjws0zZH1abuzo6nH6BU84vsQ.jpeg?width=140&height=140&crop=140:140,smart&auto=webp&s=d2ab847f9121b49746b494d8f1fb0b2f6d4ff9af", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "image", "content_categories": null, "is_self": false, "subreddit_type": "public", "created": 1751303814.0, "link_flair_type": "richtext", "wls": 7, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "i.redd.it", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": null, "banned_at_utc": null, "url_overridden_by_dest": "https://i.redd.it/mqx586xdl3af1.jpeg", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://preview.redd.it/mqx586xdl3af1.jpeg?auto=webp&s=bfc439d23ac7feacc04dd2ec9bbbe8b52fc87591", "width": 1284, "height": 1688}, "resolutions": [{"url": "https://preview.redd.it/mqx586xdl3af1.jpeg?width=108&crop=smart&auto=webp&s=2ceda2c51ced420cf6d3ff159e21a10ab5d2fc76", "width": 108, "height": 141}, {"url": "https://preview.redd.it/mqx586xdl3af1.jpeg?width=216&crop=smart&auto=webp&s=a0a6a0acfbc048308daa4e3aa6bf2fe96c2237a2", "width": 216, "height": 283}, {"url": "https://preview.redd.it/mqx586xdl3af1.jpeg?width=320&crop=smart&auto=webp&s=b649ba155772d43b5fdcd80cba894e5784ad37c7", "width": 320, "height": 420}, {"url": "https://preview.redd.it/mqx586xdl3af1.jpeg?width=640&crop=smart&auto=webp&s=c8131eba299585d3c569522ddb4c04540b06fac6", "width": 640, "height": 841}, {"url": "https://preview.redd.it/mqx586xdl3af1.jpeg?width=960&crop=smart&auto=webp&s=a8e9377c1c88beec2b27e85cf01920748e15f18b", "width": 960, "height": 1262}, {"url": "https://preview.redd.it/mqx586xdl3af1.jpeg?width=1080&crop=smart&auto=webp&s=e852d98cc54518711bedcd4b1659a08e88e8276f", "width": 1080, "height": 1419}], "variants": {}, "id": "EH8mCMTJYCUSUHmscRRjws0zZH1abuzo6nH6BU84vsQ"}], "enabled": true}, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "21222a3a-a4a4-11ea-9861-0e408d2c3d1f", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "mod_note": null, "distinguished": null, "subreddit_id": "t5_2r5rp", "author_is_blocked": false, "mod_reason_by": null, "num_reports": null, "removal_reason": null, "link_flair_background_color": "#edeff1", "id": "1lodbxg", "is_robot_indexable": true, "report_reasons": null, "author": "Anemic_Zombie", "discussion_type": null, "num_comments": 91, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/facepalm/comments/1lodbxg/psa_my_fellow_americans_should_see/", "stickied": false, "url": "https://i.redd.it/mqx586xdl3af1.jpeg", "subreddit_subscribers": 8118597, "created_utc": 1751303814.0, "num_crossposts": 2, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "todayilearned", "selftext": "", "author_fullname": "t2_gs4d9", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "TIL \"It Wasn't Me\" by Shaggy was one of Michael Jackson's favorite songs. When he met Shaggy, he told him it sounded like a song he would write, which prompted Shaggy to quip, \"So you be bangin', huh?\"", "link_flair_richtext": [], "subreddit_name_prefixed": "r/todayilearned", "hidden": false, "pwls": 6, "link_flair_css_class": null, "downs": 0, "thumbnail_height": 140, "top_awarded_type": null, "hide_score": false, "name": "t3_1loatkq", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.96, "author_flair_background_color": "", "subreddit_type": "public", "ups": 10624, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": null, "can_mod_post": false, "score": 10624, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": true, "thumbnail": "https://external-preview.redd.it/a7GYp8BVvjLvIRHyvIQ4ntpDOmYBA8BD0tuU3eCqJ_w.jpeg?width=140&height=140&crop=140:140,smart&auto=webp&s=b80346ae6ee77ffc8cadcd7785b7cc608e1b5b0b", "edited": false, "author_flair_css_class": "points points-1 q-GmXa3Z", "author_flair_richtext": [], "gildings": {}, "post_hint": "link", "content_categories": null, "is_self": false, "mod_note": null, "created": 1751298091.0, "link_flair_type": "text", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "en.wikipedia.org", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": null, "banned_at_utc": null, "url_overridden_by_dest": "https://en.wikipedia.org/wiki/It_Wasn%27t_Me", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://external-preview.redd.it/a7GYp8BVvjLvIRHyvIQ4ntpDOmYBA8BD0tuU3eCqJ_w.jpeg?auto=webp&s=4766a90a93d224f9e20a6bb1c8b1a143e5b3d2c2", "width": 300, "height": 300}, "resolutions": [{"url": "https://external-preview.redd.it/a7GYp8BVvjLvIRHyvIQ4ntpDOmYBA8BD0tuU3eCqJ_w.jpeg?width=108&crop=smart&auto=webp&s=4c1b9d3b49f9763a84d254eec9e6e0154df50da0", "width": 108, "height": 108}, {"url": "https://external-preview.redd.it/a7GYp8BVvjLvIRHyvIQ4ntpDOmYBA8BD0tuU3eCqJ_w.jpeg?width=216&crop=smart&auto=webp&s=0251f98898408481c5d7b9ee84c6f6084db3b11b", "width": 216, "height": 216}], "variants": {}, "id": "a7GYp8BVvjLvIRHyvIQ4ntpDOmYBA8BD0tuU3eCqJ_w"}], "enabled": false}, "all_awardings": [], "awarders": [], "media_only": false, "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": "3", "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_2qqjc", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "", "id": "1loatkq", "is_robot_indexable": true, "report_reasons": null, "author": "holyfruits", "discussion_type": null, "num_comments": 291, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": "dark", "permalink": "/r/todayilearned/comments/1loatkq/til_it_wasnt_me_by_shaggy_was_one_of_michael/", "stickied": false, "url": "https://en.wikipedia.org/wiki/It_Wasn%27t_Me", "subreddit_subscribers": 40948417, "created_utc": 1751298091.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "therewasanattempt", "selftext": "", "author_fullname": "t2_1s2myb6v", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "To put someone under arrest", "link_flair_richtext": [], "subreddit_name_prefixed": "r/therewasanattempt", "hidden": false, "pwls": null, "link_flair_css_class": null, "downs": 0, "thumbnail_height": 140, "top_awarded_type": null, "hide_score": false, "name": "t3_1loeryw", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.99, "author_flair_background_color": null, "subreddit_type": "public", "ups": 6139, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": {"reddit_video": {"bitrate_kbps": 5000, "fallback_url": "https://v.redd.it/865e6cq1v3af1/DASH_1080.mp4?source=fallback", "has_audio": true, "height": 1920, "width": 1080, "scrubber_media_url": "https://v.redd.it/865e6cq1v3af1/DASH_96.mp4", "dash_url": "https://v.redd.it/865e6cq1v3af1/DASHPlaylist.mpd?a=1753908005%2CMTNlNTIzNDliM2ZiMzM0Y2RjMmVhNmUyZGE0YmY1YWNlZGIyYjM0NDFiMGMzZDNjMGNmYjQ0YWY4NDc3MGFhMg%3D%3D&v=1&f=sd", "duration": 43, "hls_url": "https://v.redd.it/865e6cq1v3af1/HLSPlaylist.m3u8?a=1753908005%2CZDVjMzQ2YjBiMTdkNGNjN2RkYmU4NDdhZjhkOTM1NTFlYjVlYzQ3MjZmMjMwNmJjZTAyMjBkNzJkYWU1MDlmYQ%3D%3D&v=1&f=sd", "is_gif": false, "transcoding_status": "completed"}}, "is_reddit_media_domain": true, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": null, "can_mod_post": false, "score": 6139, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "https://external-preview.redd.it/dWJmdWpvcjF2M2FmMdSWFoRP8Mk5FYkkiHsH4DEarpk_XU_udn2oK5pL6wt5.png?width=140&height=140&crop=140:140,smart&format=jpg&v=enabled&lthumb=true&s=1d8a01fdc10bc0387e3ce32ad07300e36ec74ef5", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "hosted:video", "content_categories": null, "is_self": false, "mod_note": null, "created": 1751307072.0, "link_flair_type": "text", "wls": null, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "v.redd.it", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": "top", "banned_at_utc": null, "url_overridden_by_dest": "https://v.redd.it/865e6cq1v3af1", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://external-preview.redd.it/dWJmdWpvcjF2M2FmMdSWFoRP8Mk5FYkkiHsH4DEarpk_XU_udn2oK5pL6wt5.png?format=pjpg&auto=webp&s=a855cdcc35ee5481fa4bf616ed74fbdcd926032c", "width": 1004, "height": 1786}, "resolutions": [{"url": "https://external-preview.redd.it/dWJmdWpvcjF2M2FmMdSWFoRP8Mk5FYkkiHsH4DEarpk_XU_udn2oK5pL6wt5.png?width=108&crop=smart&format=pjpg&auto=webp&s=dcd052b04a6dd319788cda8463fff68728e271e9", "width": 108, "height": 192}, {"url": "https://external-preview.redd.it/dWJmdWpvcjF2M2FmMdSWFoRP8Mk5FYkkiHsH4DEarpk_XU_udn2oK5pL6wt5.png?width=216&crop=smart&format=pjpg&auto=webp&s=8fbcf5f90df0084ec8b8e9f70a90268862a637b3", "width": 216, "height": 384}, {"url": "https://external-preview.redd.it/dWJmdWpvcjF2M2FmMdSWFoRP8Mk5FYkkiHsH4DEarpk_XU_udn2oK5pL6wt5.png?width=320&crop=smart&format=pjpg&auto=webp&s=2afa319c5659e10b38d2d7531b17d7cedad314d1", "width": 320, "height": 569}, {"url": "https://external-preview.redd.it/dWJmdWpvcjF2M2FmMdSWFoRP8Mk5FYkkiHsH4DEarpk_XU_udn2oK5pL6wt5.png?width=640&crop=smart&format=pjpg&auto=webp&s=f9380a87b316284bf2af84bee873a8943aa11296", "width": 640, "height": 1138}, {"url": "https://external-preview.redd.it/dWJmdWpvcjF2M2FmMdSWFoRP8Mk5FYkkiHsH4DEarpk_XU_udn2oK5pL6wt5.png?width=960&crop=smart&format=pjpg&auto=webp&s=1bdf450182f0eb505b1d8a7b4ba93afbda7ee3b9", "width": 960, "height": 1707}], "variants": {}, "id": "dWJmdWpvcjF2M2FmMdSWFoRP8Mk5FYkkiHsH4DEarpk_XU_udn2oK5pL6wt5"}], "enabled": false}, "all_awardings": [], "awarders": [], "media_only": false, "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_39ne7", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "", "id": "1loeryw", "is_robot_indexable": true, "report_reasons": null, "author": "CorgiLoveCluj", "discussion_type": null, "num_comments": 198, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/therewasanattempt/comments/1loeryw/to_put_someone_under_arrest/", "stickied": false, "url": "https://v.redd.it/865e6cq1v3af1", "subreddit_subscribers": 7159351, "created_utc": 1751307072.0, "num_crossposts": 1, "media": {"reddit_video": {"bitrate_kbps": 5000, "fallback_url": "https://v.redd.it/865e6cq1v3af1/DASH_1080.mp4?source=fallback", "has_audio": true, "height": 1920, "width": 1080, "scrubber_media_url": "https://v.redd.it/865e6cq1v3af1/DASH_96.mp4", "dash_url": "https://v.redd.it/865e6cq1v3af1/DASHPlaylist.mpd?a=1753908005%2CMTNlNTIzNDliM2ZiMzM0Y2RjMmVhNmUyZGE0YmY1YWNlZGIyYjM0NDFiMGMzZDNjMGNmYjQ0YWY4NDc3MGFhMg%3D%3D&v=1&f=sd", "duration": 43, "hls_url": "https://v.redd.it/865e6cq1v3af1/HLSPlaylist.m3u8?a=1753908005%2CZDVjMzQ2YjBiMTdkNGNjN2RkYmU4NDdhZjhkOTM1NTFlYjVlYzQ3MjZmMjMwNmJjZTAyMjBkNzJkYWU1MDlmYQ%3D%3D&v=1&f=sd", "is_gif": false, "transcoding_status": "completed"}}, "is_video": true}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "goodnews", "selftext": "", "author_fullname": "t2_czohgvm4", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "'Free America': Anti-Trump Protests Taking Place Nationwide on 4th of July", "link_flair_richtext": [{"e": "text", "t": "Political positivity \ud83d\udcc8"}], "subreddit_name_prefixed": "r/goodnews", "hidden": false, "pwls": 6, "link_flair_css_class": "", "downs": 0, "thumbnail_height": 93, "top_awarded_type": null, "hide_score": false, "name": "t3_1lo7elh", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.93, "author_flair_background_color": null, "ups": 28411, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": false, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Political positivity \ud83d\udcc8", "can_mod_post": false, "score": 28411, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "https://external-preview.redd.it/txT6uXNImwpdHKuwYBexn9-HdanmmCBQK9ulnRTzszI.jpeg?width=140&height=93&crop=140:93,smart&auto=webp&s=479fb4282596ba4737d4c4446d56b4ec8cc04426", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "link", "content_categories": null, "is_self": false, "subreddit_type": "public", "created": 1751289777.0, "link_flair_type": "richtext", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "newsweek.com", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": null, "banned_at_utc": null, "url_overridden_by_dest": "https://www.newsweek.com/free-america-protests-nationwide-july-4-2092433", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://external-preview.redd.it/txT6uXNImwpdHKuwYBexn9-HdanmmCBQK9ulnRTzszI.jpeg?auto=webp&s=2509b37c75f5fa278485e9d7158bc7d5fd22fd22", "width": 2500, "height": 1667}, "resolutions": [{"url": "https://external-preview.redd.it/txT6uXNImwpdHKuwYBexn9-HdanmmCBQK9ulnRTzszI.jpeg?width=108&crop=smart&auto=webp&s=9f41b95d64315cbbeb6d144fbb03deafebceb703", "width": 108, "height": 72}, {"url": "https://external-preview.redd.it/txT6uXNImwpdHKuwYBexn9-HdanmmCBQK9ulnRTzszI.jpeg?width=216&crop=smart&auto=webp&s=5b5091b2ea6cb8cf76e99c15a4fdf5b3cf448842", "width": 216, "height": 144}, {"url": "https://external-preview.redd.it/txT6uXNImwpdHKuwYBexn9-HdanmmCBQK9ulnRTzszI.jpeg?width=320&crop=smart&auto=webp&s=e79a4ed2225d9a858d9ddeeddbd58588d0b1774f", "width": 320, "height": 213}, {"url": "https://external-preview.redd.it/txT6uXNImwpdHKuwYBexn9-HdanmmCBQK9ulnRTzszI.jpeg?width=640&crop=smart&auto=webp&s=00889ee5b4215b4b438db74a2a6a532ed90af248", "width": 640, "height": 426}, {"url": "https://external-preview.redd.it/txT6uXNImwpdHKuwYBexn9-HdanmmCBQK9ulnRTzszI.jpeg?width=960&crop=smart&auto=webp&s=9bc0c1e2314ce702365526671a59ee078b87844b", "width": 960, "height": 640}, {"url": "https://external-preview.redd.it/txT6uXNImwpdHKuwYBexn9-HdanmmCBQK9ulnRTzszI.jpeg?width=1080&crop=smart&auto=webp&s=ff19bf6f0cbaf9d8281f80f59988da2e50910937", "width": 1080, "height": 720}], "variants": {}, "id": "txT6uXNImwpdHKuwYBexn9-HdanmmCBQK9ulnRTzszI"}], "enabled": false}, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "7bd40ddc-e2f6-11ef-9fb6-6271ee18cba8", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "mod_note": null, "distinguished": null, "subreddit_id": "t5_2qirj", "author_is_blocked": false, "mod_reason_by": null, "num_reports": null, "removal_reason": null, "link_flair_background_color": "#ff884d", "id": "1lo7elh", "is_robot_indexable": true, "report_reasons": null, "author": "BreakfastTop6899", "discussion_type": null, "num_comments": 962, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/goodnews/comments/1lo7elh/free_america_antitrump_protests_taking_place/", "stickied": false, "url": "https://www.newsweek.com/free-america-protests-nationwide-july-4-2092433", "subreddit_subscribers": 280186, "created_utc": 1751289777.0, "num_crossposts": 11, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "Fauxmoi", "selftext": "", "author_fullname": "t2_3in26siv", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Liam Cunningham via his IG story: \u201cIf chants and slogans offend you more than an actual genocide - YOU are part of the problem.\u201d", "link_flair_richtext": [], "subreddit_name_prefixed": "r/Fauxmoi", "hidden": false, "pwls": 7, "link_flair_css_class": null, "downs": 0, "thumbnail_height": 140, "top_awarded_type": null, "hide_score": false, "name": "t3_1lo98he", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.92, "author_flair_background_color": "transparent", "ups": 15315, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": "d6565a10-8533-11ef-97b3-62fb6f052ad4", "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": true, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "STAN / ANTI SHIELD", "can_mod_post": false, "score": 15315, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "https://external-preview.redd.it/skppn7LNa1oMOGH840tEwiK6lqWs6VGtBlo0-iOFCWI.jpeg?width=140&height=140&crop=140:140,smart&auto=webp&s=150c0058723d12b547b22c5dca3e9d64043998b3", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "image", "content_categories": null, "is_self": false, "subreddit_type": "public", "created": 1751294391.0, "link_flair_type": "text", "wls": 7, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "i.redd.it", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": "top", "banned_at_utc": null, "url_overridden_by_dest": "https://i.redd.it/bo3dck7dt2af1.jpeg", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://preview.redd.it/bo3dck7dt2af1.jpeg?auto=webp&s=df2c5a090695fa96149789e8a114adbb539222a1", "width": 1125, "height": 1456}, "resolutions": [{"url": "https://preview.redd.it/bo3dck7dt2af1.jpeg?width=108&crop=smart&auto=webp&s=762ee678b58d022dd47b6371c6cd966088a66cf6", "width": 108, "height": 139}, {"url": "https://preview.redd.it/bo3dck7dt2af1.jpeg?width=216&crop=smart&auto=webp&s=179b17e2a9c091e0f2046a50806437d148ee8ef2", "width": 216, "height": 279}, {"url": "https://preview.redd.it/bo3dck7dt2af1.jpeg?width=320&crop=smart&auto=webp&s=65a7a8c762710821fd9552f83b2bdf7e9fd4d406", "width": 320, "height": 414}, {"url": "https://preview.redd.it/bo3dck7dt2af1.jpeg?width=640&crop=smart&auto=webp&s=4c46705cc4fc22675e547ae9bb5f7f1dfbf26170", "width": 640, "height": 828}, {"url": "https://preview.redd.it/bo3dck7dt2af1.jpeg?width=960&crop=smart&auto=webp&s=b5513cc41afa920907c88a7061daf220ac481ad2", "width": 960, "height": 1242}, {"url": "https://preview.redd.it/bo3dck7dt2af1.jpeg?width=1080&crop=smart&auto=webp&s=80b76f905e0648b554f769424d6ef523dc041db8", "width": 1080, "height": 1397}], "variants": {}, "id": "skppn7LNa1oMOGH840tEwiK6lqWs6VGtBlo0-iOFCWI"}], "enabled": true}, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "59c83e4c-d6ea-11ef-8742-0a36bd49e469", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": "i ain\u2019t reading all that, free palestine", "treatment_tags": [], "visited": false, "removed_by": null, "mod_note": null, "distinguished": null, "subreddit_id": "t5_2rqcm8", "author_is_blocked": false, "mod_reason_by": null, "num_reports": null, "removal_reason": null, "link_flair_background_color": "#fb0456", "id": "1lo98he", "is_robot_indexable": true, "report_reasons": null, "author": "cmaia1503", "discussion_type": null, "num_comments": 156, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": "dark", "permalink": "/r/Fauxmoi/comments/1lo98he/liam_cunningham_via_his_ig_story_if_chants_and/", "stickied": false, "url": "https://i.redd.it/bo3dck7dt2af1.jpeg", "subreddit_subscribers": 6381044, "created_utc": 1751294391.0, "num_crossposts": 3, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "WhatsWrongWithYourDog", "selftext": "", "author_fullname": "t2_cxtoa", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "W A L T E R", "link_flair_richtext": [], "subreddit_name_prefixed": "r/WhatsWrongWithYourDog", "hidden": false, "pwls": 6, "link_flair_css_class": null, "downs": 0, "thumbnail_height": 140, "top_awarded_type": null, "hide_score": false, "name": "t3_1lo9sfs", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.97, "author_flair_background_color": null, "subreddit_type": "public", "ups": 13824, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": true, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": null, "can_mod_post": false, "score": 13824, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "https://external-preview.redd.it/9faj_MWINbmhlfJGG1aJL85C0u5lbbftbywHxRCv29E.png?width=140&height=140&crop=140:140,smart&auto=webp&s=b56ac52bacc61fd10c164022924d95a8bffc61b9", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "image", "content_categories": null, "is_self": false, "mod_note": null, "created": 1751295709.0, "link_flair_type": "text", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "i.redd.it", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": null, "banned_at_utc": null, "url_overridden_by_dest": "https://i.redd.it/wy5g2ca6x2af1.png", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://preview.redd.it/wy5g2ca6x2af1.png?auto=webp&s=333d5fe3f0f7608eb8ab1d8383783fa4b77e6a8a", "width": 525, "height": 655}, "resolutions": [{"url": "https://preview.redd.it/wy5g2ca6x2af1.png?width=108&crop=smart&auto=webp&s=65acd6325a35fcd18008a5e988fc9c4cf9a7a438", "width": 108, "height": 134}, {"url": "https://preview.redd.it/wy5g2ca6x2af1.png?width=216&crop=smart&auto=webp&s=72517bf0492b27e6bf8ddbdbe4a18c0cfc792599", "width": 216, "height": 269}, {"url": "https://preview.redd.it/wy5g2ca6x2af1.png?width=320&crop=smart&auto=webp&s=b7b6fb1a272ebdc87a319b277cbf51506ad4d347", "width": 320, "height": 399}], "variants": {}, "id": "9faj_MWINbmhlfJGG1aJL85C0u5lbbftbywHxRCv29E"}], "enabled": true}, "all_awardings": [], "awarders": [], "media_only": false, "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_39ht3", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "", "id": "1lo9sfs", "is_robot_indexable": true, "report_reasons": null, "author": "Nedwolp", "discussion_type": null, "num_comments": 93, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/WhatsWrongWithYourDog/comments/1lo9sfs/w_a_l_t_e_r/", "stickied": false, "url": "https://i.redd.it/wy5g2ca6x2af1.png", "subreddit_subscribers": 2251937, "created_utc": 1751295709.0, "num_crossposts": 1, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "NonPoliticalTwitter", "selftext": "", "author_fullname": "t2_1feyrioyx8", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "All hail the LOL", "link_flair_richtext": [], "subreddit_name_prefixed": "r/NonPoliticalTwitter", "hidden": false, "pwls": 6, "link_flair_css_class": null, "downs": 0, "thumbnail_height": 140, "top_awarded_type": null, "hide_score": false, "name": "t3_1lobbbx", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.97, "author_flair_background_color": "transparent", "subreddit_type": "public", "ups": 9862, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": "39c9ba88-e8f2-11eb-96ec-0e895ae83161", "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": true, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": null, "can_mod_post": false, "score": 9862, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "https://external-preview.redd.it/gpXbNf_WTJ0Ek9JlZ_618RCEniTJRHjJT4oPxYJVVJI.jpeg?width=140&height=140&crop=140:140,smart&auto=webp&s=5f99ea5081b20c24c39383939e78246c79edfc8b", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [{"a": ":red1:", "e": "emoji", "u": "https://emoji.redditmedia.com/3ndnut4cj9c71_t5_39gt6y/red1"}, {"a": ":red2:", "e": "emoji", "u": "https://emoji.redditmedia.com/3g17nu2cj9c71_t5_39gt6y/red2"}, {"a": ":1111:", "e": "emoji", "u": "https://emoji.redditmedia.com/qiynwtu1j9c71_t5_39gt6y/1111"}, {"a": ":1112:", "e": "emoji", "u": "https://emoji.redditmedia.com/7sxmtqw1j9c71_t5_39gt6y/1112"}], "gildings": {}, "post_hint": "image", "content_categories": null, "is_self": false, "mod_note": null, "created": 1751299229.0, "link_flair_type": "text", "wls": 6, "removed_by_category": null, "banned_by": null, "author_flair_type": "richtext", "domain": "i.redd.it", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": null, "banned_at_utc": null, "url_overridden_by_dest": "https://i.redd.it/zo0k4qdq73af1.jpeg", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://preview.redd.it/zo0k4qdq73af1.jpeg?auto=webp&s=c975dc69d8fde7eface8032ee8f45a4aa2bee284", "width": 640, "height": 640}, "resolutions": [{"url": "https://preview.redd.it/zo0k4qdq73af1.jpeg?width=108&crop=smart&auto=webp&s=f3355d1959d7925773eae5d3f1b2f2e297fec55a", "width": 108, "height": 108}, {"url": "https://preview.redd.it/zo0k4qdq73af1.jpeg?width=216&crop=smart&auto=webp&s=2e32f9778e4683620824bce94887a6c4f6a2159c", "width": 216, "height": 216}, {"url": "https://preview.redd.it/zo0k4qdq73af1.jpeg?width=320&crop=smart&auto=webp&s=b4c9501342b1c8f53adfdc163515fd82838ab500", "width": 320, "height": 320}, {"url": "https://preview.redd.it/zo0k4qdq73af1.jpeg?width=640&crop=smart&auto=webp&s=b15f1d886159246fdbc3a6b49aa60e78196e0114", "width": 640, "height": 640}], "variants": {}, "id": "gpXbNf_WTJ0Ek9JlZ_618RCEniTJRHjJT4oPxYJVVJI"}], "enabled": true}, "all_awardings": [], "awarders": [], "media_only": false, "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": ":red1::red2::1111::1112:", "treatment_tags": [], "visited": false, "removed_by": null, "num_reports": null, "distinguished": null, "subreddit_id": "t5_39gt6y", "author_is_blocked": false, "mod_reason_by": null, "removal_reason": null, "link_flair_background_color": "", "id": "1lobbbx", "is_robot_indexable": true, "report_reasons": null, "author": "Treasure-boy", "discussion_type": null, "num_comments": 183, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": "dark", "permalink": "/r/NonPoliticalTwitter/comments/1lobbbx/all_hail_the_lol/", "stickied": false, "url": "https://i.redd.it/zo0k4qdq73af1.jpeg", "subreddit_subscribers": 549644, "created_utc": 1751299229.0, "num_crossposts": 0, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "agedlikemilk", "selftext": "", "author_fullname": "t2_15nmkah", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "They stand by nothing.", "link_flair_richtext": [], "subreddit_name_prefixed": "r/agedlikemilk", "hidden": false, "pwls": 7, "link_flair_css_class": "", "downs": 0, "thumbnail_height": 140, "top_awarded_type": null, "hide_score": false, "name": "t3_1lo6qkl", "quarantine": false, "link_flair_text_color": "dark", "upvote_ratio": 0.95, "author_flair_background_color": null, "ups": 47034, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": null, "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": true, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "Screenshots", "can_mod_post": false, "score": 47034, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": false, "thumbnail": "https://external-preview.redd.it/KRAe8_DMuTJVL9VjKsafRbAQSaTUCsHP1pKggegM7C4.jpeg?width=140&height=140&crop=140:140,smart&auto=webp&s=27739b4105b956d3a76d8c6209f2c9a8a9afe7e3", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "image", "content_categories": null, "is_self": false, "subreddit_type": "public", "created": 1751287959.0, "link_flair_type": "text", "wls": 7, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "i.redd.it", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": null, "banned_at_utc": null, "url_overridden_by_dest": "https://i.redd.it/p7ztekn8a2af1.jpeg", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://preview.redd.it/p7ztekn8a2af1.jpeg?auto=webp&s=f3f088d88135ab1ca2c469f6deba9f528b4f77b0", "width": 680, "height": 680}, "resolutions": [{"url": "https://preview.redd.it/p7ztekn8a2af1.jpeg?width=108&crop=smart&auto=webp&s=0054d9912358b7a12a94300896f7f818d3cffaee", "width": 108, "height": 108}, {"url": "https://preview.redd.it/p7ztekn8a2af1.jpeg?width=216&crop=smart&auto=webp&s=d428af016ca3dcc78fa4193c8f1147a65eac44d1", "width": 216, "height": 216}, {"url": "https://preview.redd.it/p7ztekn8a2af1.jpeg?width=320&crop=smart&auto=webp&s=dc489d2792c05da3ce113847c9e59890e4aeea9d", "width": 320, "height": 320}, {"url": "https://preview.redd.it/p7ztekn8a2af1.jpeg?width=640&crop=smart&auto=webp&s=6fcb8b5c28f08d6f855ffc88c75668dfb4dacdb1", "width": 640, "height": 640}], "variants": {}, "id": "KRAe8_DMuTJVL9VjKsafRbAQSaTUCsHP1pKggegM7C4"}], "enabled": true}, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "aefae4f4-3961-11ea-a694-0ee9903d6ec7", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": null, "treatment_tags": [], "visited": false, "removed_by": null, "mod_note": null, "distinguished": null, "subreddit_id": "t5_o7cng", "author_is_blocked": false, "mod_reason_by": null, "num_reports": null, "removal_reason": null, "link_flair_background_color": "", "id": "1lo6qkl", "is_robot_indexable": true, "report_reasons": null, "author": "c-k-q99903", "discussion_type": null, "num_comments": 332, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": null, "permalink": "/r/agedlikemilk/comments/1lo6qkl/they_stand_by_nothing/", "stickied": false, "url": "https://i.redd.it/p7ztekn8a2af1.jpeg", "subreddit_subscribers": 1330608, "created_utc": 1751287959.0, "num_crossposts": 3, "media": null, "is_video": false}}, {"kind": "t3", "data": {"approved_at_utc": null, "subreddit": "WorkReform", "selftext": "", "author_fullname": "t2_156vk", "saved": false, "mod_reason_title": null, "gilded": 0, "clicked": false, "title": "Landlords do not provide housing. We will never have affordable housing until we eliminate corporate landlords.", "link_flair_richtext": [], "subreddit_name_prefixed": "r/WorkReform", "hidden": false, "pwls": 7, "link_flair_css_class": "", "downs": 0, "thumbnail_height": 140, "top_awarded_type": null, "hide_score": false, "name": "t3_1lo891y", "quarantine": false, "link_flair_text_color": "light", "upvote_ratio": 0.95, "author_flair_background_color": "#014980", "ups": 17494, "total_awards_received": 0, "media_embed": {}, "thumbnail_width": 140, "author_flair_template_id": "8e50a8fa-8627-11ec-8e4a-225e5c272daa", "is_original_content": false, "user_reports": [], "secure_media": null, "is_reddit_media_domain": true, "is_meta": false, "category": null, "secure_media_embed": {}, "link_flair_text": "\ud83d\ude21 Venting", "can_mod_post": false, "score": 17494, "approved_by": null, "is_created_from_ads_ui": false, "author_premium": true, "thumbnail": "https://external-preview.redd.it/RDlkJP4DbGRZHvZyy92cIJF1R-qnMadEQBV7hzBhMyM.jpeg?width=140&height=140&crop=140:140,smart&auto=webp&s=93262f17a8996399c9fc5239af4cf07ac6506507", "edited": false, "author_flair_css_class": null, "author_flair_richtext": [], "gildings": {}, "post_hint": "image", "content_categories": null, "is_self": false, "subreddit_type": "public", "created": 1751291964.0, "link_flair_type": "text", "wls": 7, "removed_by_category": null, "banned_by": null, "author_flair_type": "text", "domain": "i.redd.it", "allow_live_comments": false, "selftext_html": null, "likes": null, "suggested_sort": "confidence", "banned_at_utc": null, "url_overridden_by_dest": "https://i.redd.it/sxcap51sl2af1.jpeg", "view_count": null, "archived": false, "no_follow": false, "is_crosspostable": false, "pinned": false, "over_18": false, "preview": {"images": [{"source": {"url": "https://preview.redd.it/sxcap51sl2af1.jpeg?auto=webp&s=1acba926dcee5887b62481852757bebcb3b93c70", "width": 1080, "height": 1286}, "resolutions": [{"url": "https://preview.redd.it/sxcap51sl2af1.jpeg?width=108&crop=smart&auto=webp&s=fe24b24b4b736e49034d676aae744166787b9c8c", "width": 108, "height": 128}, {"url": "https://preview.redd.it/sxcap51sl2af1.jpeg?width=216&crop=smart&auto=webp&s=fbdc6af68235525dee5a7a06498c37e6dd4ecc95", "width": 216, "height": 257}, {"url": "https://preview.redd.it/sxcap51sl2af1.jpeg?width=320&crop=smart&auto=webp&s=eba3caf0aab42aaba4f763091a47f6d083ae2c65", "width": 320, "height": 381}, {"url": "https://preview.redd.it/sxcap51sl2af1.jpeg?width=640&crop=smart&auto=webp&s=921df7e8bc2564a847ef6d3420c8b67b31bf3976", "width": 640, "height": 762}, {"url": "https://preview.redd.it/sxcap51sl2af1.jpeg?width=960&crop=smart&auto=webp&s=a5b8930d23256b3157ed6a55d34341c0e18ffd88", "width": 960, "height": 1143}, {"url": "https://preview.redd.it/sxcap51sl2af1.jpeg?width=1080&crop=smart&auto=webp&s=f03d4766c9ebd64e039e787bb4d712e2a599ede3", "width": 1080, "height": 1286}], "variants": {}, "id": "RDlkJP4DbGRZHvZyy92cIJF1R-qnMadEQBV7hzBhMyM"}], "enabled": true}, "all_awardings": [], "awarders": [], "media_only": false, "link_flair_template_id": "708ff2f4-f2af-11ec-8d50-5e3d47744d9f", "can_gild": false, "spoiler": false, "locked": false, "author_flair_text": "\ud83e\udd1d Join A Union", "treatment_tags": [], "visited": false, "removed_by": null, "mod_note": null, "distinguished": null, "subreddit_id": "t5_5qpzgw", "author_is_blocked": false, "mod_reason_by": null, "num_reports": null, "removal_reason": null, "link_flair_background_color": "#373c3f", "id": "1lo891y", "is_robot_indexable": true, "report_reasons": null, "author": "zzill6", "discussion_type": null, "num_comments": 872, "send_replies": true, "contest_mode": false, "mod_reports": [], "author_patreon_flair": false, "author_flair_text_color": "light", "permalink": "/r/WorkReform/comments/1lo891y/landlords_do_not_provide_housing_we_will_never/", "stickied": false, "url": "https://i.redd.it/sxcap51sl2af1.jpeg", "subreddit_subscribers": 757744, "created_utc": 1751291964.0, "num_crossposts": 3, "media": null, "is_video": false}}], "before": null}} -------------------------------------------------------------------------------- /tests/Benchmark/ParserBench.php: -------------------------------------------------------------------------------- 1 | parse(); 14 | } 15 | 16 | public function benchComplexDocument(): void { 17 | $content = file_get_contents(__DIR__.'/Datasets/all.json'); 18 | $parser = new Parser($content)->parse(); 19 | } 20 | 21 | public function benchComplexDocumentJSON(): void { 22 | $content = file_get_contents(__DIR__.'/Datasets/all.json'); 23 | $parser = json_decode($content); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /tests/Benchmark/TokenizerBench.php: -------------------------------------------------------------------------------- 1 | testData = [ 17 | 'tiny' => $this->generateJson(1), 18 | 'small' => $this->generateJson(10), 19 | 'medium' => $this->generateJson(100), 20 | 'large' => $this->generateJson(1000), 21 | 'huge' => $this->generateJson(10000), 22 | 'mixed_types' => $this->generateMixedTypesJson(), 23 | 'deep_nested' => $this->generateDeepNestedJson(), 24 | 'wide_shallow' => $this->generateWideShallowJson(), 25 | 'string_heavy' => $this->generateStringHeavyJson(), 26 | 'number_heavy' => $this->generateNumberHeavyJson(), 27 | ]; 28 | } 29 | 30 | /** 31 | * @Groups({"size"}) 32 | */ 33 | public function benchTinyJson(): void 34 | { 35 | $tokenizer = new Tokenizer($this->testData['tiny']); 36 | $this->consumeAllTokens($tokenizer); 37 | } 38 | 39 | /** 40 | * @Groups({"size"}) 41 | */ 42 | public function benchSmallJson(): void 43 | { 44 | $tokenizer = new Tokenizer($this->testData['small']); 45 | $this->consumeAllTokens($tokenizer); 46 | } 47 | 48 | /** 49 | * @Groups({"size"}) 50 | */ 51 | public function benchMediumJson(): void 52 | { 53 | $tokenizer = new Tokenizer($this->testData['medium']); 54 | $this->consumeAllTokens($tokenizer); 55 | } 56 | 57 | /** 58 | * @Groups({"size"}) 59 | */ 60 | public function benchLargeJson(): void 61 | { 62 | $tokenizer = new Tokenizer($this->testData['large']); 63 | $this->consumeAllTokens($tokenizer); 64 | } 65 | 66 | /** 67 | * @Groups({"size"}) 68 | */ 69 | public function benchHugeJson(): void 70 | { 71 | $tokenizer = new Tokenizer($this->testData['huge']); 72 | $this->consumeAllTokens($tokenizer); 73 | } 74 | 75 | /** 76 | * @Groups({"patterns"}) 77 | */ 78 | public function benchMixedTypesJson(): void 79 | { 80 | $tokenizer = new Tokenizer($this->testData['mixed_types']); 81 | $this->consumeAllTokens($tokenizer); 82 | } 83 | 84 | /** 85 | * @Groups({"patterns"}) 86 | */ 87 | public function benchDeepNestedJson(): void 88 | { 89 | $tokenizer = new Tokenizer($this->testData['deep_nested']); 90 | $this->consumeAllTokens($tokenizer); 91 | } 92 | 93 | /** 94 | * @Groups({"patterns"}) 95 | */ 96 | public function benchWideShallowJson(): void 97 | { 98 | $tokenizer = new Tokenizer($this->testData['wide_shallow']); 99 | $this->consumeAllTokens($tokenizer); 100 | } 101 | 102 | /** 103 | * @Groups({"patterns"}) 104 | */ 105 | public function benchStringHeavy(): void 106 | { 107 | $tokenizer = new Tokenizer('"This is a very long string that will test the tokenizer performance with repeated content."'); 108 | $this->consumeAllTokens($tokenizer); 109 | } 110 | 111 | /** 112 | * @Groups({"patterns"}) 113 | */ 114 | public function benchStringHeavyJson(): void 115 | { 116 | $tokenizer = new Tokenizer($this->testData['string_heavy']); 117 | $this->consumeAllTokens($tokenizer); 118 | } 119 | 120 | /** 121 | * @Groups({"patterns"}) 122 | */ 123 | public function benchNumberHeavyJson(): void 124 | { 125 | $tokenizer = new Tokenizer($this->testData['number_heavy']); 126 | $this->consumeAllTokens($tokenizer); 127 | } 128 | 129 | /** 130 | * @Groups({"memory"}) 131 | */ 132 | public function benchMemoryEfficient(): void 133 | { 134 | $json = $this->generateJson(5000); 135 | $tokenizer = new Tokenizer($json); 136 | 137 | $tokenCount = 0; 138 | while ($tokenizer->nextToken() !== null) { 139 | $tokenCount++; 140 | // Simulate processing without storing tokens 141 | } 142 | } 143 | 144 | /** 145 | * @Groups({"stress"}) 146 | */ 147 | public function benchStressTest(): void 148 | { 149 | $json = $this->generateStressTestJson(); 150 | $tokenizer = new Tokenizer($json); 151 | $this->consumeAllTokens($tokenizer); 152 | } 153 | 154 | private function consumeAllTokens(Tokenizer $tokenizer): void 155 | { 156 | while ($tokenizer->nextToken() !== null) { 157 | // Continue until all tokens are consumed 158 | } 159 | } 160 | 161 | private function generateJson(int $size): string 162 | { 163 | $data = []; 164 | for ($i = 0; $i < $size; $i++) { 165 | $data["key_$i"] = $this->getRandomValue(); 166 | } 167 | return json_encode($data); 168 | } 169 | 170 | private function getRandomValue(): mixed 171 | { 172 | $types = ['string', 'number', 'boolean', 'null', 'array', 'object']; 173 | $type = $types[array_rand($types)]; 174 | 175 | return match ($type) { 176 | 'string' => 'value_' . uniqid(), 177 | 'number' => rand(-1000, 1000) + (rand(0, 100) / 100), 178 | 'boolean' => (bool)rand(0, 1), 179 | 'null' => null, 180 | 'array' => array_slice(range(1, 10), 0, rand(1, 5)), 181 | 'object' => ['nested' => 'value'], 182 | }; 183 | } 184 | 185 | private function generateMixedTypesJson(): string 186 | { 187 | return json_encode([ 188 | 'strings' => ['hello', 'world', 'test'], 189 | 'numbers' => [1, 2.5, -3, 1e6], 190 | 'booleans' => [true, false], 191 | 'nulls' => [null], 192 | 'arrays' => [[1, 2], [3, 4]], 193 | 'objects' => [['a' => 1], ['b' => 2]], 194 | 'mixed' => [ 195 | 'string' => 'value', 196 | 'number' => 42, 197 | 'boolean' => true, 198 | 'null' => null, 199 | 'array' => [1, 2, 3], 200 | 'object' => ['nested' => 'value'] 201 | ] 202 | ]); 203 | } 204 | 205 | private function generateDeepNestedJson(): string 206 | { 207 | $data = 'value'; 208 | for ($i = 0; $i < 20; $i++) { 209 | $data = ['nested' => $data]; 210 | } 211 | return json_encode($data); 212 | } 213 | 214 | private function generateWideShallowJson(): string 215 | { 216 | $data = []; 217 | for ($i = 0; $i < 1000; $i++) { 218 | $data["key_$i"] = "value_$i"; 219 | } 220 | return json_encode($data); 221 | } 222 | 223 | private function generateStringHeavyJson(): string 224 | { 225 | $data = []; 226 | $longString = str_repeat('This is a very long string with many characters. ', 50); 227 | for ($i = 0; $i < 100; $i++) { 228 | $data["string_$i"] = $longString . $i; 229 | } 230 | return json_encode($data); 231 | } 232 | 233 | private function generateNumberHeavyJson(): string 234 | { 235 | $data = []; 236 | for ($i = 0; $i < 1000; $i++) { 237 | $data["num_$i"] = rand(-10000, 10000) + (rand(0, 100) / 100); 238 | } 239 | return json_encode($data); 240 | } 241 | 242 | private function generateStressTestJson(): string 243 | { 244 | $data = []; 245 | for ($i = 0; $i < 100; $i++) { 246 | $data["key_$i"] = [ 247 | 'string' => str_repeat('stress_test_string_', 10) . $i, 248 | 'number' => rand(-999999, 999999), 249 | 'boolean' => (bool)rand(0, 1), 250 | 'null' => null, 251 | 'array' => range(1, 100), 252 | 'object' => array_fill_keys(range('a', 'z'), 'value'), 253 | 'escaped' => "String with \"quotes\" and \\backslashes\\ and \n\t\r special chars" 254 | ]; 255 | } 256 | return json_encode($data); 257 | } 258 | } -------------------------------------------------------------------------------- /tests/Datasets/invalidJson.php: -------------------------------------------------------------------------------- 1 | ['{]'], // wrong closing token 7 | 'missing‑brace' => ['{"a":1'], // unterminated object 8 | 'trailing‑data' => ['{"a":1} true'], // two top‑level values 9 | 'unquoted‑key' => ['{a:1}'], // key not string 10 | 'array‑missing‑comma' => ['[1 2]'], // no comma between elems 11 | ]); 12 | -------------------------------------------------------------------------------- /tests/Datasets/jsonOrgFail.php: -------------------------------------------------------------------------------- 1 | [file_get_contents($file, true)]; 9 | } 10 | }); 11 | -------------------------------------------------------------------------------- /tests/Datasets/jsonOrgPass.php: -------------------------------------------------------------------------------- 1 | [$json, $expected]; 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /tests/Datasets/validJson.php: -------------------------------------------------------------------------------- 1 | ['{}', []], 7 | 'empty‑array' => ['[]', []], 8 | 'flat‑object' => ['{"a":1,"b":true}', ['a' => 1, 'b' => true]], 9 | 'nested‑array' => ['{"arr":[1,null,false]}', ['arr' => [1, null, false]]], 10 | 'mixed' => ['[{"x":10}, false]', [['x' => 10], false]], 11 | ]); 12 | -------------------------------------------------------------------------------- /tests/Datasets/validLiterals.php: -------------------------------------------------------------------------------- 1 | ['true', true, TokenType::True], 7 | 'false' => ['false', false, TokenType::False], 8 | 'null' => ['null', null, TokenType::Null], 9 | ]); 10 | -------------------------------------------------------------------------------- /tests/Datasets/validNumbers.php: -------------------------------------------------------------------------------- 1 | ['42', 42], 5 | 'float-leading-dot' => ['.42', .42], 6 | 'neg-int' => ['-7', -7], 7 | 'float' => ['3.14', 3.14], 8 | 'exp-pos' => ['1e3', 1000.0], 9 | 'exp-neg' => ['5.5e-1', 0.55], 10 | ]); 11 | -------------------------------------------------------------------------------- /tests/Feature/ExampleTest.php: -------------------------------------------------------------------------------- 1 | toBeTrue(); 5 | }); 6 | -------------------------------------------------------------------------------- /tests/JSONOrg/fail10.json: -------------------------------------------------------------------------------- 1 | {"Extra value after close": true} "misplaced quoted value" -------------------------------------------------------------------------------- /tests/JSONOrg/fail11.json: -------------------------------------------------------------------------------- 1 | {"Illegal expression": 1 + 2} -------------------------------------------------------------------------------- /tests/JSONOrg/fail12.json: -------------------------------------------------------------------------------- 1 | {"Illegal invocation": alert()} -------------------------------------------------------------------------------- /tests/JSONOrg/fail13.json: -------------------------------------------------------------------------------- 1 | {"Numbers cannot have leading zeroes": 013} -------------------------------------------------------------------------------- /tests/JSONOrg/fail14.json: -------------------------------------------------------------------------------- 1 | {"Numbers cannot be hex": 0x14} -------------------------------------------------------------------------------- /tests/JSONOrg/fail15.json: -------------------------------------------------------------------------------- 1 | ["Illegal backslash escape: \x15"] -------------------------------------------------------------------------------- /tests/JSONOrg/fail16.json: -------------------------------------------------------------------------------- 1 | [\naked] -------------------------------------------------------------------------------- /tests/JSONOrg/fail17.json: -------------------------------------------------------------------------------- 1 | ["Illegal backslash escape: \017"] -------------------------------------------------------------------------------- /tests/JSONOrg/fail19.json: -------------------------------------------------------------------------------- 1 | {"Missing colon" null} -------------------------------------------------------------------------------- /tests/JSONOrg/fail2.json: -------------------------------------------------------------------------------- 1 | ["Unclosed array" -------------------------------------------------------------------------------- /tests/JSONOrg/fail20.json: -------------------------------------------------------------------------------- 1 | {"Double colon":: null} -------------------------------------------------------------------------------- /tests/JSONOrg/fail21.json: -------------------------------------------------------------------------------- 1 | {"Comma instead of colon", null} -------------------------------------------------------------------------------- /tests/JSONOrg/fail22.json: -------------------------------------------------------------------------------- 1 | ["Colon instead of comma": false] -------------------------------------------------------------------------------- /tests/JSONOrg/fail23.json: -------------------------------------------------------------------------------- 1 | ["Bad value", truth] -------------------------------------------------------------------------------- /tests/JSONOrg/fail24.json: -------------------------------------------------------------------------------- 1 | ['single quote'] -------------------------------------------------------------------------------- /tests/JSONOrg/fail25.json: -------------------------------------------------------------------------------- 1 | [" tab character in string "] -------------------------------------------------------------------------------- /tests/JSONOrg/fail26.json: -------------------------------------------------------------------------------- 1 | ["tab\ character\ in\ string\ "] -------------------------------------------------------------------------------- /tests/JSONOrg/fail27.json: -------------------------------------------------------------------------------- 1 | ["line 2 | break"] -------------------------------------------------------------------------------- /tests/JSONOrg/fail28.json: -------------------------------------------------------------------------------- 1 | ["line\ 2 | break"] -------------------------------------------------------------------------------- /tests/JSONOrg/fail29.json: -------------------------------------------------------------------------------- 1 | [0e] -------------------------------------------------------------------------------- /tests/JSONOrg/fail3.json: -------------------------------------------------------------------------------- 1 | {unquoted_key: "keys must be quoted"} -------------------------------------------------------------------------------- /tests/JSONOrg/fail30.json: -------------------------------------------------------------------------------- 1 | [0e+] -------------------------------------------------------------------------------- /tests/JSONOrg/fail31.json: -------------------------------------------------------------------------------- 1 | [0e+-1] -------------------------------------------------------------------------------- /tests/JSONOrg/fail32.json: -------------------------------------------------------------------------------- 1 | {"Comma instead if closing brace": true, -------------------------------------------------------------------------------- /tests/JSONOrg/fail33.json: -------------------------------------------------------------------------------- 1 | ["mismatch"} -------------------------------------------------------------------------------- /tests/JSONOrg/fail4.json: -------------------------------------------------------------------------------- 1 | ["extra comma",] -------------------------------------------------------------------------------- /tests/JSONOrg/fail5.json: -------------------------------------------------------------------------------- 1 | ["double extra comma",,] -------------------------------------------------------------------------------- /tests/JSONOrg/fail6.json: -------------------------------------------------------------------------------- 1 | [ , "<-- missing value"] -------------------------------------------------------------------------------- /tests/JSONOrg/fail7.json: -------------------------------------------------------------------------------- 1 | ["Comma after the close"], -------------------------------------------------------------------------------- /tests/JSONOrg/fail8.json: -------------------------------------------------------------------------------- 1 | ["Extra close"]] -------------------------------------------------------------------------------- /tests/JSONOrg/fail9.json: -------------------------------------------------------------------------------- 1 | {"Extra comma": true,} -------------------------------------------------------------------------------- /tests/JSONOrg/pass1.json: -------------------------------------------------------------------------------- 1 | [ 2 | "JSON Test Pattern pass1", 3 | {"object with 1 member":["array with 1 element"]}, 4 | {}, 5 | [], 6 | -42, 7 | true, 8 | false, 9 | null, 10 | { 11 | "integer": 1234567890, 12 | "real": -9876.543210, 13 | "e": 0.123456789e-12, 14 | "E": 1.234567890E+34, 15 | "": 23456789012E66, 16 | "zero": 0, 17 | "one": 1, 18 | "space": " ", 19 | "quote": "\"", 20 | "backslash": "\\", 21 | "controls": "\b\f\n\r\t", 22 | "slash": "/ & \/", 23 | "alpha": "abcdefghijklmnopqrstuvwyz", 24 | "ALPHA": "ABCDEFGHIJKLMNOPQRSTUVWYZ", 25 | "digit": "0123456789", 26 | "0123456789": "digit", 27 | "special": "`1~!@#$%^&*()_+-={':[,]}|;.?", 28 | "hex": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A", 29 | "true": true, 30 | "false": false, 31 | "null": null, 32 | "array":[ ], 33 | "object":{ }, 34 | "address": "50 St. James Street", 35 | "url": "http://www.JSON.org/", 36 | "comment": "// /* */": " ", 38 | " s p a c e d " :[1,2 , 3 39 | 40 | , 41 | 42 | 4 , 5 , 6 ,7 ],"compact":[1,2,3,4,5,6,7], 43 | "jsontext": "{\"object with 1 member\":[\"array with 1 element\"]}", 44 | "quotes": "" \u0022 %22 0x22 034 "", 45 | "\/\\\"\uCAFE\uBABE\uAB98\uFCDE\ubcda\uef4A\b\f\n\r\t`1~!@#$%^&*()_+-=[]{}|;:',./<>?" 46 | : "A key can be any string" 47 | }, 48 | 0.5 ,98.6 49 | , 50 | 99.44 51 | , 52 | 53 | 1066, 54 | 1e1, 55 | 0.1e1, 56 | 1e-1, 57 | 1e00,2e+00,2e-00 58 | ,"rosebud"] -------------------------------------------------------------------------------- /tests/JSONOrg/pass2.json: -------------------------------------------------------------------------------- 1 | [[[[[[[[[[[[[[[[[[["Not too deep"]]]]]]]]]]]]]]]]]]] -------------------------------------------------------------------------------- /tests/JSONOrg/pass3.json: -------------------------------------------------------------------------------- 1 | { 2 | "JSON Test Pattern pass3": { 3 | "The outermost value": "must be an object or array.", 4 | "In this test": "It is an object." 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /tests/JSONOrg/pass4.json: -------------------------------------------------------------------------------- 1 | "A JSON payload should be an object or array, not a string." -------------------------------------------------------------------------------- /tests/JSONOrg/pass5.json: -------------------------------------------------------------------------------- 1 | [[[[[[[[[[[[[[[[[[[["Too deep"]]]]]]]]]]]]]]]]]]]] -------------------------------------------------------------------------------- /tests/Pest.php: -------------------------------------------------------------------------------- 1 | extend(Tests\TestCase::class)->in('Feature'); 15 | 16 | /* 17 | |-------------------------------------------------------------------------- 18 | | Expectations 19 | |-------------------------------------------------------------------------- 20 | | 21 | | When you're writing tests, you often need to check that values meet certain conditions. The 22 | | "expect()" function gives you access to a set of "expectations" methods that you can use 23 | | to assert different things. Of course, you may extend the Expectation API at any time. 24 | | 25 | */ 26 | 27 | expect()->extend('toBeOne', function () { 28 | return $this->toBe(1); 29 | }); 30 | 31 | /* 32 | |-------------------------------------------------------------------------- 33 | | Functions 34 | |-------------------------------------------------------------------------- 35 | | 36 | | While Pest is very powerful out-of-the-box, you may have some testing code specific to your 37 | | project that you don't want to repeat in every file. Here you can also expose helpers as 38 | | global functions to help you to reduce the number of lines of code in your test files. 39 | | 40 | */ 41 | 42 | function something() 43 | { 44 | // .. 45 | } 46 | -------------------------------------------------------------------------------- /tests/TestCase.php: -------------------------------------------------------------------------------- 1 | toBeTrue(); 5 | }); 6 | -------------------------------------------------------------------------------- /tests/Unit/JsonOrgTest.php: -------------------------------------------------------------------------------- 1 | parse(); 11 | expect($parsed)->toEqual($expected); 12 | })->with('jsonOrgPass'); 13 | 14 | it('throws all JSON.org fail*.json files', function (string $json) { 15 | (new Parser($json))->parse(); 16 | })->with('jsonOrgFail')->throws(RuntimeException::class); 17 | -------------------------------------------------------------------------------- /tests/Unit/ParseTest.php: -------------------------------------------------------------------------------- 1 | parse(); 11 | 12 | expect(fn () => $parser->parse()) 13 | ->toThrow(RuntimeException::class, 'Unexpected end of input while parsing value'); 14 | }); 15 | 16 | it('should parse a empty json', function () { 17 | $parser = (new Parser('{}'))->parse(); 18 | expect($parser)->toBe([]); 19 | }); 20 | 21 | it('parse a json with values', function () { 22 | $parser = (new Parser('{"name": "Daniel", "x": "daniellhemmati"}'))->parse(); 23 | expect($parser)->toBe([ 24 | 'name' => 'Daniel', 25 | 'x' => 'daniellhemmati' 26 | ]); 27 | }); 28 | 29 | it('parse a json with nested object', function () { 30 | $parser = new Parser('{"name": "Daniel", "x": "daniellhemmati", "others": { 31 | "tech": "php,typescript,python,go", 32 | "framework": "laravel,next.js,astro" 33 | }}'); 34 | $result = $parser->parse(); 35 | expect($result)->toBe([ 36 | 'name' => 'Daniel', 37 | 'x' => 'daniellhemmati', 38 | 'others' => [ 39 | 'tech' => 'php,typescript,python,go', 40 | 'framework' => 'laravel,next.js,astro' 41 | ] 42 | ]); 43 | }); 44 | 45 | it('should parse an empty array correctly', function () { 46 | $parser = (new Parser('[]'))->parse(); 47 | expect($parser)->toBe([]); 48 | }); 49 | 50 | it('should parse array with values correctly', function () { 51 | $parser = (new Parser('["daniel", "hemmati", "php"]'))->parse(); 52 | expect($parser)->toBe(['daniel', 'hemmati', 'php']); 53 | }); 54 | 55 | it('parse valid json into native php values', function (string $json, $expected) { 56 | $parser = (new Parser($json))->parse(); 57 | expect($parser)->toEqual($expected); 58 | })->with('validJson'); 59 | 60 | it('throws RuntimeException on invalid json', function (string $json) { 61 | (new Parser($json))->parse(); 62 | })->with('invalidJson')->throws(RuntimeException::class); 63 | 64 | it('should parse quote correctly', function () { 65 | $parser = (new Parser('{"quote": "\""}'))->parse(); 66 | expect($parser)->toEqual([ 67 | 'quote' => '"' 68 | ]); 69 | }); 70 | 71 | it('should parse unicode escape sequences correctly', function () { 72 | $parser = (new Parser('{"unicode": "\u0123\u4567\u89AB\uCDEF\uabcd\uef4A"}'))->parse(); 73 | expect($parser)->toEqual([ 74 | 'unicode' => "\u{0123}\u{4567}\u{89AB}\u{CDEF}\u{abcd}\u{ef4A}" 75 | ]); 76 | }); 77 | 78 | // from fail13.json file 79 | it('should fail on json that have a leading 0', function () { 80 | (new Parser('{"test": 013}'))->parse(); 81 | })->throws(RuntimeException::class); 82 | 83 | // from fail25.json and fail27.json 84 | it('should fail on un-printable characters', function () { 85 | (new Parser('[" tab character in string "]'))->parse(); 86 | })->throws(RuntimeException::class); 87 | 88 | 89 | it('handles high and low surrogate', function () { 90 | $tokenizer = new Parser('[ "Posting this: \ud83d\udca9" ]')->parse(); 91 | dump($tokenizer); 92 | expect($tokenizer)->toEqual([ 93 | "Posting this: 💩" 94 | ]); 95 | })->only()->note(note: <<nextToken(); 12 | expect($token)->toBeInstanceOf(Token::class); 13 | expect($token->type)->toBe(TokenType::BraceOpen); 14 | }); 15 | 16 | it('should return brace close', function () { 17 | $tokenizer = new Tokenizer('}'); 18 | $token = $tokenizer->nextToken(); 19 | expect($token)->toBeInstanceOf(Token::class); 20 | expect($token->type)->toBe(TokenType::BraceClose); 21 | }); 22 | 23 | it('should tokenize empty object correctly', function () { 24 | $tokenizer = new Tokenizer('{}'); 25 | 26 | $firstToken = $tokenizer->nextToken(); 27 | expect($firstToken)->toBeInstanceOf(Token::class); 28 | expect($firstToken->type)->toBe(TokenType::BraceOpen); 29 | expect($firstToken->value)->toBe('{'); 30 | 31 | $secondToken = $tokenizer->nextToken(); 32 | expect($secondToken)->toBeInstanceOf(Token::class); 33 | expect($secondToken->type)->toBe(TokenType::BraceClose); 34 | expect($secondToken->value)->toBe('}'); 35 | 36 | $thirdToken = $tokenizer->nextToken(); 37 | expect($thirdToken)->toBeNull(); 38 | }); 39 | 40 | it('should return bracket open', function () { 41 | $tokenizer = new Tokenizer('['); 42 | $token = $tokenizer->nextToken(); 43 | expect($token)->toBeInstanceOf(Token::class); 44 | expect($token->type)->toBe(TokenType::BracketOpen); 45 | }); 46 | 47 | it('should return bracket close', function () { 48 | $tokenizer = new Tokenizer(']'); 49 | $token = $tokenizer->nextToken(); 50 | expect($token)->toBeInstanceOf(Token::class); 51 | expect($token->type)->toBe(TokenType::BracketClose); 52 | }); 53 | 54 | it('should tokenize empty array correctly', function () { 55 | $tokenizer = new Tokenizer('[]'); 56 | 57 | $firstToken = $tokenizer->nextToken(); 58 | expect($firstToken)->toBeInstanceOf(Token::class); 59 | expect($firstToken->type)->toBe(TokenType::BracketOpen); 60 | expect($firstToken->value)->toBe('['); 61 | 62 | $secondToken = $tokenizer->nextToken(); 63 | expect($secondToken)->toBeInstanceOf(Token::class); 64 | expect($secondToken->type)->toBe(TokenType::BracketClose); 65 | expect($secondToken->value)->toBe(']'); 66 | 67 | $thirdToken = $tokenizer->nextToken(); 68 | expect($thirdToken)->toBeNull(); 69 | }); 70 | 71 | it('tokenize a simple JSON string', function () { 72 | $tokenizer = new Tokenizer('"hello"'); 73 | 74 | /** @var Token $tok */ 75 | $tok = $tokenizer->nextToken(); 76 | 77 | expect($tok)->toBeInstanceOf(Token::class); 78 | expect($tok->type)->toBe(TokenType::String); 79 | expect($tok->value)->toBe('hello'); 80 | 81 | expect($tokenizer->nextToken())->toBeNull(); 82 | }); 83 | 84 | it('keeps esace sequence intact', function () { 85 | $json = '"He said: \\"hi\\""'; // -> \"hi\" 86 | $tokenizer = new Tokenizer($json); 87 | 88 | $tok = $tokenizer->nextToken(); 89 | 90 | expect($tok->type)->toBe(TokenType::String); 91 | expect($tok->value)->toBe('He said: "hi"'); 92 | }); 93 | 94 | 95 | it('handles unicode escape sequence intact', function () { 96 | $tokenizer = new Tokenizer('"unicode: \\u0041"'); 97 | 98 | $tok = $tokenizer->nextToken(); 99 | 100 | expect($tok->value)->toBe('unicode: A'); 101 | }); 102 | 103 | it('throws on unterminated string', function () { 104 | $tokenizer = new Tokenizer('"no-close'); 105 | 106 | expect(fn() => $tokenizer->nextToken()) 107 | ->toThrow(RuntimeException::class, 'Unterminated string literal'); 108 | }); 109 | 110 | it('throws on backslashes at end of input', function () { 111 | $tokenizer = new Tokenizer('"abc\\'); 112 | 113 | expect(fn() => $tokenizer->nextToken()) 114 | ->toThrow(RuntimeException::class, 'Unterminated escape sequence'); 115 | }); 116 | 117 | it('tokenizes a colon', function () { 118 | $tokenizer = new Tokenizer(':'); 119 | $tok = $tokenizer->nextToken(); 120 | 121 | expect($tok)->not()->toBeNull(); 122 | expect($tok->type)->toBe(TokenType::Colon); 123 | expect($tok->value)->toBe(':'); 124 | }); 125 | 126 | it('tokenizes a comma', function () { 127 | $tokenizer = new Tokenizer(','); 128 | $tok = $tokenizer->nextToken(); 129 | 130 | expect($tok)->not()->toBeNull(); 131 | expect($tok->type)->toBe(TokenType::Comma); 132 | expect($tok->value)->toBe(','); 133 | }); 134 | 135 | 136 | it('tokenises valid numbers correctly', function (string $input, float|int $expected) { 137 | $tokenizer = new Tokenizer($input); 138 | $token = $tokenizer->nextToken(); 139 | 140 | expect($token)->not()->toBeNull() 141 | ->and($token->type)->toBe(TokenType::Number) 142 | ->and($token->value)->toBe($expected); 143 | })->with('validNumbers'); 144 | 145 | it('tokenises true/false/null', function (string $input, $expectedValue, TokenType $expectedType) { 146 | $tokenizer = new Tokenizer($input); 147 | $token = $tokenizer->nextToken(); 148 | 149 | expect($token)->not()->toBeNull() 150 | ->and($token->type)->toBe($expectedType) 151 | ->and($token->value)->toBe($expectedValue); 152 | })->with('validLiterals'); 153 | 154 | it('throws on invalid number', function () { 155 | $tokenizer = new Tokenizer('.e'); 156 | $tokenizer->nextToken(); 157 | })->throws(RuntimeException::class); 158 | --------------------------------------------------------------------------------