Commit e303b2e4fa00b5446b162a90f0d053e174183ab1

Authored by yibo
1 parent c9009a54

Restyle live channel to infiniteslop.ai's comic-panel look, add queue upvoting

Reworks live.css/live.html to match infiniteslop.ai's visual language: Tahoma
bold type, pure-black canvas, hot-pink accent, and hand-drawn white cards with
a thick black border + hard offset shadow for every button/bubble/prompt card.
Left queue now groups into 接下来播放/生成中/排队中 sections, the center gets a
white "now playing" card (time + requester + prompt) plus a pulsing LIVE pill,
chat bubbles are colored per-nickname via a pastel hash, and the top bar gained
a chat-close toggle alongside mute and the watching count.

Adds real upvoting to go with the new queue UI: POST /api/queue/vote/:id
toggles a per-viewer (cookie uid) vote on a queued prompt, and pickNextClip
now schedules the highest-voted matched/ready entry first instead of strict
FIFO — lets chat bump a favorite prompt to the front of the line.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0144MiJ2cLjMd9jWaeEpVfUJ
library.json
1 [ 1 [
2 { 2 {
  3 + "id": "4af4c61b64a6",
  4 + "source": "h3console",
  5 + "prompt": "一只白猫坐着,镜头缓慢推进,最终定格",
  6 + "fullPrompt": "一只白猫坐着,镜头缓慢推进,最终定格",
  7 + "edited": false,
  8 + "width": 832,
  9 + "height": 480,
  10 + "duration": 1,
  11 + "partition": "fl2va",
  12 + "likes": 0,
  13 + "createdAt": 1788251288958
  14 + },
  15 + {
3 "id": "8024972d6019", 16 "id": "8024972d6019",
4 "source": "h3console", 17 "source": "h3console",
5 "prompt": "蛤蟆文太跳出来了打架", 18 "prompt": "蛤蟆文太跳出来了打架",
@@ -51,7 +64,7 @@ @@ -51,7 +64,7 @@
51 "likes": 0, 64 "likes": 0,
52 "createdAt": 1788192916199, 65 "createdAt": 1788192916199,
53 "promptEn": "taoist eyes the old house suspiciously", 66 "promptEn": "taoist eyes the old house suspiciously",
54 - "lastPlayedAt": 1788242974304 67 + "lastPlayedAt": 1788253021349
55 }, 68 },
56 { 69 {
57 "id": "cb5baad5d724", 70 "id": "cb5baad5d724",
@@ -66,7 +79,7 @@ @@ -66,7 +79,7 @@
66 "likes": 0, 79 "likes": 0,
67 "createdAt": 1788192915845, 80 "createdAt": 1788192915845,
68 "promptEn": "scholar watches the room warily", 81 "promptEn": "scholar watches the room warily",
69 - "lastPlayedAt": 1788249895446 82 + "lastPlayedAt": 1788251736825
70 }, 83 },
71 { 84 {
72 "id": "e8cbb73560ef", 85 "id": "e8cbb73560ef",
@@ -81,7 +94,7 @@ @@ -81,7 +94,7 @@
81 "likes": 0, 94 "likes": 0,
82 "createdAt": 1788192915549, 95 "createdAt": 1788192915549,
83 "promptEn": "taoist steels himself to exorcise something", 96 "promptEn": "taoist steels himself to exorcise something",
84 - "lastPlayedAt": 1788246217066 97 + "lastPlayedAt": 1788252086979
85 }, 98 },
86 { 99 {
87 "id": "5b6dcb357792", 100 "id": "5b6dcb357792",
@@ -96,7 +109,7 @@ @@ -96,7 +109,7 @@
96 "likes": 0, 109 "likes": 0,
97 "createdAt": 1788192915268, 110 "createdAt": 1788192915268,
98 "promptEn": "scholar softens up, starts to trust", 111 "promptEn": "scholar softens up, starts to trust",
99 - "lastPlayedAt": 1788249389537 112 + "lastPlayedAt": 1788250818261
100 }, 113 },
101 { 114 {
102 "id": "0c7565a5c8e8", 115 "id": "0c7565a5c8e8",
@@ -111,7 +124,7 @@ @@ -111,7 +124,7 @@
111 "likes": 0, 124 "likes": 0,
112 "createdAt": 1788192914949, 125 "createdAt": 1788192914949,
113 "promptEn": "taoist acts tough but is nervous", 126 "promptEn": "taoist acts tough but is nervous",
114 - "lastPlayedAt": 1788247784361 127 + "lastPlayedAt": 1788252613211
115 }, 128 },
116 { 129 {
117 "id": "167ce1bfa285", 130 "id": "167ce1bfa285",
@@ -126,7 +139,7 @@ @@ -126,7 +139,7 @@
126 "likes": 0, 139 "likes": 0,
127 "createdAt": 1788192914047, 140 "createdAt": 1788192914047,
128 "promptEn": "scholar looks scared, wants to flee", 141 "promptEn": "scholar looks scared, wants to flee",
129 - "lastPlayedAt": 1788247259915 142 + "lastPlayedAt": 1788252155012
130 }, 143 },
131 { 144 {
132 "id": "053bc957b4f8", 145 "id": "053bc957b4f8",
@@ -141,7 +154,7 @@ @@ -141,7 +154,7 @@
141 "likes": 0, 154 "likes": 0,
142 "createdAt": 1788192913886, 155 "createdAt": 1788192913886,
143 "promptEn": "taoist panics, freaked out", 156 "promptEn": "taoist panics, freaked out",
144 - "lastPlayedAt": 1788247778362 157 + "lastPlayedAt": 1788250312031
145 }, 158 },
146 { 159 {
147 "id": "45c1136d1e05", 160 "id": "45c1136d1e05",
@@ -156,7 +169,7 @@ @@ -156,7 +169,7 @@
156 "likes": 0, 169 "likes": 0,
157 "createdAt": 1788192913551, 170 "createdAt": 1788192913551,
158 "promptEn": "taoist looking panicked and scared", 171 "promptEn": "taoist looking panicked and scared",
159 - "lastPlayedAt": 1788249177441 172 + "lastPlayedAt": 1788252637227
160 }, 173 },
161 { 174 {
162 "id": "d169d42a67de", 175 "id": "d169d42a67de",
@@ -171,7 +184,7 @@ @@ -171,7 +184,7 @@
171 "likes": 0, 184 "likes": 0,
172 "createdAt": 1788192913492, 185 "createdAt": 1788192913492,
173 "promptEn": "scholar defiant out of desperation", 186 "promptEn": "scholar defiant out of desperation",
174 - "lastPlayedAt": 1788248821262 187 + "lastPlayedAt": 1788252431138
175 }, 188 },
176 { 189 {
177 "id": "2abd2793fae9", 190 "id": "2abd2793fae9",
@@ -186,7 +199,7 @@ @@ -186,7 +199,7 @@
186 "likes": 0, 199 "likes": 0,
187 "createdAt": 1788192913244, 200 "createdAt": 1788192913244,
188 "promptEn": "scholar cornered but still defiant", 201 "promptEn": "scholar cornered but still defiant",
189 - "lastPlayedAt": 1788248124656 202 + "lastPlayedAt": 1788250669748
190 }, 203 },
191 { 204 {
192 "id": "bbf7efb467e0", 205 "id": "bbf7efb467e0",
@@ -201,7 +214,7 @@ @@ -201,7 +214,7 @@
201 "likes": 0, 214 "likes": 0,
202 "createdAt": 1788192912912, 215 "createdAt": 1788192912912,
203 "promptEn": "taoist charmed, hesitating", 216 "promptEn": "taoist charmed, hesitating",
204 - "lastPlayedAt": 1788249011362 217 + "lastPlayedAt": 1788251760826
205 }, 218 },
206 { 219 {
207 "id": "f8da9934c823", 220 "id": "f8da9934c823",
@@ -216,7 +229,7 @@ @@ -216,7 +229,7 @@
216 "likes": 0, 229 "likes": 0,
217 "createdAt": 1788192912819, 230 "createdAt": 1788192912819,
218 "promptEn": "scholar dazed, charmed", 231 "promptEn": "scholar dazed, charmed",
219 - "lastPlayedAt": 1788249063385 232 + "lastPlayedAt": 1788252975330
220 }, 233 },
221 { 234 {
222 "id": "feb96d5be50f", 235 "id": "feb96d5be50f",
@@ -231,7 +244,7 @@ @@ -231,7 +244,7 @@
231 "likes": 0, 244 "likes": 0,
232 "createdAt": 1788191432903, 245 "createdAt": 1788191432903,
233 "promptEn": "woman in white startled, a bit shy", 246 "promptEn": "woman in white startled, a bit shy",
234 - "lastPlayedAt": 1788247175839 247 + "lastPlayedAt": 1788252189029
235 }, 248 },
236 { 249 {
237 "id": "14f482bdae7f", 250 "id": "14f482bdae7f",
@@ -246,7 +259,7 @@ @@ -246,7 +259,7 @@
246 "likes": 0, 259 "likes": 0,
247 "createdAt": 1788191432362, 260 "createdAt": 1788191432362,
248 "promptEn": "woman in white being intimate and alluring", 261 "promptEn": "woman in white being intimate and alluring",
249 - "lastPlayedAt": 1788247648262 262 + "lastPlayedAt": 1788251702786
250 }, 263 },
251 { 264 {
252 "id": "362b15ab1811", 265 "id": "362b15ab1811",
@@ -261,7 +274,7 @@ @@ -261,7 +274,7 @@
261 "likes": 0, 274 "likes": 0,
262 "createdAt": 1788191431874, 275 "createdAt": 1788191431874,
263 "promptEn": "woman in white gently comforting someone", 276 "promptEn": "woman in white gently comforting someone",
264 - "lastPlayedAt": 1788245286273 277 + "lastPlayedAt": 1788251802847
265 }, 278 },
266 { 279 {
267 "id": "a2c515055269", 280 "id": "a2c515055269",
@@ -276,7 +289,7 @@ @@ -276,7 +289,7 @@
276 "likes": 0, 289 "likes": 0,
277 "createdAt": 1788191431505, 290 "createdAt": 1788191431505,
278 "promptEn": "woman in white scared, dodging the question", 291 "promptEn": "woman in white scared, dodging the question",
279 - "lastPlayedAt": 1788248629102 292 + "lastPlayedAt": 1788252941314
280 }, 293 },
281 { 294 {
282 "id": "667978d52305", 295 "id": "667978d52305",
@@ -291,7 +304,7 @@ @@ -291,7 +304,7 @@
291 "likes": 0, 304 "likes": 0,
292 "createdAt": 1788191431016, 305 "createdAt": 1788191431016,
293 "promptEn": "woman in white coldly threatening", 306 "promptEn": "woman in white coldly threatening",
294 - "lastPlayedAt": 1788249305499 307 + "lastPlayedAt": 1788251764831
295 }, 308 },
296 { 309 {
297 "id": "7f5213748d87", 310 "id": "7f5213748d87",
@@ -306,7 +319,7 @@ @@ -306,7 +319,7 @@
306 "likes": 0, 319 "likes": 0,
307 "createdAt": 1788188423583, 320 "createdAt": 1788188423583,
308 "promptEn": "woman in white scared, dodging", 321 "promptEn": "woman in white scared, dodging",
309 - "lastPlayedAt": 1788244191373 322 + "lastPlayedAt": 1788251198437
310 }, 323 },
311 { 324 {
312 "id": "1597db4be561", 325 "id": "1597db4be561",
@@ -320,7 +333,7 @@ @@ -320,7 +333,7 @@
320 "partition": "ref2va", 333 "partition": "ref2va",
321 "likes": 0, 334 "likes": 0,
322 "createdAt": 1788187365789, 335 "createdAt": 1788187365789,
323 - "lastPlayedAt": 1788249805778, 336 + "lastPlayedAt": 1788251380546,
324 "promptEn": "woman in white being gentle and comforting" 337 "promptEn": "woman in white being gentle and comforting"
325 }, 338 },
326 { 339 {
@@ -335,7 +348,7 @@ @@ -335,7 +348,7 @@
335 "partition": "ref2va", 348 "partition": "ref2va",
336 "likes": 0, 349 "likes": 0,
337 "createdAt": 1788186218619, 350 "createdAt": 1788186218619,
338 - "lastPlayedAt": 1788248797247, 351 + "lastPlayedAt": 1788252471153,
339 "promptEn": "woman in white evading, scared" 352 "promptEn": "woman in white evading, scared"
340 }, 353 },
341 { 354 {
@@ -351,7 +364,7 @@ @@ -351,7 +364,7 @@
351 "likes": 0, 364 "likes": 0,
352 "createdAt": 1788185090875, 365 "createdAt": 1788185090875,
353 "promptEn": "woman in white cold and threatening", 366 "promptEn": "woman in white cold and threatening",
354 - "lastPlayedAt": 1788249227469 367 + "lastPlayedAt": 1788251808852
355 }, 368 },
356 { 369 {
357 "id": "a46f1daa9ee0", 370 "id": "a46f1daa9ee0",
@@ -366,7 +379,7 @@ @@ -366,7 +379,7 @@
366 "likes": 0, 379 "likes": 0,
367 "createdAt": 1788181569491, 380 "createdAt": 1788181569491,
368 "promptEn": "a massive warship glides through the stars, the bridge suddenly shakes hard", 381 "promptEn": "a massive warship glides through the stars, the bridge suddenly shakes hard",
369 - "lastPlayedAt": 1788244309493 382 + "lastPlayedAt": 1788251214448
370 }, 383 },
371 { 384 {
372 "id": "44bf5b969e94", 385 "id": "44bf5b969e94",
@@ -381,7 +394,7 @@ @@ -381,7 +394,7 @@
381 "likes": 0, 394 "likes": 0,
382 "createdAt": 1788162094002, 395 "createdAt": 1788162094002,
383 "promptEn": "woman in old chinese robe talking, gentle but wary, in an old room", 396 "promptEn": "woman in old chinese robe talking, gentle but wary, in an old room",
384 - "lastPlayedAt": 1788248591076 397 + "lastPlayedAt": 1788250690213
385 }, 398 },
386 { 399 {
387 "id": "e17cfe57f56a", 400 "id": "e17cfe57f56a",
@@ -396,7 +409,7 @@ @@ -396,7 +409,7 @@
396 "likes": 0, 409 "likes": 0,
397 "createdAt": 1788160917846, 410 "createdAt": 1788160917846,
398 "promptEn": "woman in old chinese robe talking, gentle but wary, in an old room", 411 "promptEn": "woman in old chinese robe talking, gentle but wary, in an old room",
399 - "lastPlayedAt": 1788248635111 412 + "lastPlayedAt": 1788251177165
400 }, 413 },
401 { 414 {
402 "id": "24e49e5ae069", 415 "id": "24e49e5ae069",
@@ -411,7 +424,7 @@ @@ -411,7 +424,7 @@
411 "likes": 0, 424 "likes": 0,
412 "createdAt": 1788159367556, 425 "createdAt": 1788159367556,
413 "promptEn": "constable talking nervously in an old room, looking scared", 426 "promptEn": "constable talking nervously in an old room, looking scared",
414 - "lastPlayedAt": 1788249213459 427 + "lastPlayedAt": 1788252509170
415 }, 428 },
416 { 429 {
417 "id": "a6d767413426", 430 "id": "a6d767413426",
@@ -426,7 +439,7 @@ @@ -426,7 +439,7 @@
426 "likes": 0, 439 "likes": 0,
427 "createdAt": 1788157322611, 440 "createdAt": 1788157322611,
428 "promptEn": "constable talking, looking scared", 441 "promptEn": "constable talking, looking scared",
429 - "lastPlayedAt": 1788244543682 442 + "lastPlayedAt": 1788250916299
430 }, 443 },
431 { 444 {
432 "id": "7977eeeabe8b", 445 "id": "7977eeeabe8b",
@@ -441,7 +454,7 @@ @@ -441,7 +454,7 @@
441 "likes": 0, 454 "likes": 0,
442 "createdAt": 1788157177505, 455 "createdAt": 1788157177505,
443 "promptEn": "constable bursts in and blocks the door, talks to a pale woman behind the screen", 456 "promptEn": "constable bursts in and blocks the door, talks to a pale woman behind the screen",
444 - "lastPlayedAt": 1788249173441 457 + "lastPlayedAt": 1788250622191
445 }, 458 },
446 { 459 {
447 "id": "a9c4ba5e453b", 460 "id": "a9c4ba5e453b",
@@ -456,7 +469,7 @@ @@ -456,7 +469,7 @@
456 "likes": 0, 469 "likes": 0,
457 "createdAt": 1788156878022, 470 "createdAt": 1788156878022,
458 "promptEn": "constable bursts in and blocks the door, talks to a pale woman behind the screen", 471 "promptEn": "constable bursts in and blocks the door, talks to a pale woman behind the screen",
459 - "lastPlayedAt": 1788245662609 472 + "lastPlayedAt": 1788252225046
460 }, 473 },
461 { 474 {
462 "id": "a0b752e7ac0d", 475 "id": "a0b752e7ac0d",
@@ -471,7 +484,7 @@ @@ -471,7 +484,7 @@
471 "likes": 0, 484 "likes": 0,
472 "createdAt": 1788154942596, 485 "createdAt": 1788154942596,
473 "promptEn": "constable talking, looking scared", 486 "promptEn": "constable talking, looking scared",
474 - "lastPlayedAt": 1788247279933 487 + "lastPlayedAt": 1788252145004
475 }, 488 },
476 { 489 {
477 "id": "b6608e2eac60", 490 "id": "b6608e2eac60",
@@ -486,7 +499,7 @@ @@ -486,7 +499,7 @@
486 "likes": 0, 499 "likes": 0,
487 "createdAt": 1788153988474, 500 "createdAt": 1788153988474,
488 "promptEn": "astronaut at a martian canyon, visor reflecting alien ruins, then aerial view of the city", 501 "promptEn": "astronaut at a martian canyon, visor reflecting alien ruins, then aerial view of the city",
489 - "lastPlayedAt": 1788248997353 502 + "lastPlayedAt": 1788251428589
490 }, 503 },
491 { 504 {
492 "id": "194fc2b56cb5", 505 "id": "194fc2b56cb5",
@@ -501,7 +514,7 @@ @@ -501,7 +514,7 @@
501 "likes": 0, 514 "likes": 0,
502 "createdAt": 1788138492364, 515 "createdAt": 1788138492364,
503 "promptEn": "astronaut on a Martian canyon, helmet reflecting an alien ruined city", 516 "promptEn": "astronaut on a Martian canyon, helmet reflecting an alien ruined city",
504 - "lastPlayedAt": 1788250133927 517 + "lastPlayedAt": 1788251558701
505 }, 518 },
506 { 519 {
507 "id": "f84b8f044ec5", 520 "id": "f84b8f044ec5",
@@ -531,7 +544,7 @@ @@ -531,7 +544,7 @@
531 "likes": 0, 544 "likes": 0,
532 "createdAt": 1788120171608, 545 "createdAt": 1788120171608,
533 "promptEn": "constable bursts in and blocks the door, talks to a pale woman behind the screen", 546 "promptEn": "constable bursts in and blocks the door, talks to a pale woman behind the screen",
534 - "lastPlayedAt": 1788248811254 547 + "lastPlayedAt": 1788252411133
535 }, 548 },
536 { 549 {
537 "id": "b8c762a3672e", 550 "id": "b8c762a3672e",
@@ -561,7 +574,7 @@ @@ -561,7 +574,7 @@
561 "likes": 0, 574 "likes": 0,
562 "createdAt": 1788085282201, 575 "createdAt": 1788085282201,
563 "promptEn": "constable stands still, quietly says he won't make a sound, woman stays silent behind the screen", 576 "promptEn": "constable stands still, quietly says he won't make a sound, woman stays silent behind the screen",
564 - "lastPlayedAt": 1788248290798 577 + "lastPlayedAt": 1788251288482
565 }, 578 },
566 { 579 {
567 "id": "683ab2fd4681", 580 "id": "683ab2fd4681",
@@ -576,7 +589,7 @@ @@ -576,7 +589,7 @@
576 "likes": 0, 589 "likes": 0,
577 "createdAt": 1788071067702, 590 "createdAt": 1788071067702,
578 "promptEn": "constable stands still, quietly says he won't make a sound, woman stays silent behind the screen", 591 "promptEn": "constable stands still, quietly says he won't make a sound, woman stays silent behind the screen",
579 - "lastPlayedAt": 1788249939841 592 + "lastPlayedAt": 1788251524674
580 }, 593 },
581 { 594 {
582 "id": "2e09fcd3d42c", 595 "id": "2e09fcd3d42c",
@@ -591,7 +604,7 @@ @@ -591,7 +604,7 @@
591 "likes": 0, 604 "likes": 0,
592 "createdAt": 1788062322252, 605 "createdAt": 1788062322252,
593 "promptEn": "constable stands still, quietly says he won't make a sound, woman stays silent behind the screen", 606 "promptEn": "constable stands still, quietly says he won't make a sound, woman stays silent behind the screen",
594 - "lastPlayedAt": 1788247317966 607 + "lastPlayedAt": 1788252491166
595 }, 608 },
596 { 609 {
597 "id": "12ea9ce00f36", 610 "id": "12ea9ce00f36",
@@ -606,7 +619,7 @@ @@ -606,7 +619,7 @@
606 "likes": 0, 619 "likes": 0,
607 "createdAt": 1788039783070, 620 "createdAt": 1788039783070,
608 "promptEn": "silver-haired idol backstage, red light pulsing, offering a blood-red contract", 621 "promptEn": "silver-haired idol backstage, red light pulsing, offering a blood-red contract",
609 - "lastPlayedAt": 1788247167832 622 + "lastPlayedAt": 1788251726803
610 }, 623 },
611 { 624 {
612 "id": "75bdbacd3012", 625 "id": "75bdbacd3012",
@@ -621,7 +634,7 @@ @@ -621,7 +634,7 @@
621 "likes": 0, 634 "likes": 0,
622 "createdAt": 1788039782992, 635 "createdAt": 1788039782992,
623 "promptEn": "silver-haired idol backstage, red light pulsing, offering a blood-red contract", 636 "promptEn": "silver-haired idol backstage, red light pulsing, offering a blood-red contract",
624 - "lastPlayedAt": 1788249243476 637 + "lastPlayedAt": 1788250966325
625 }, 638 },
626 { 639 {
627 "id": "69e75a6b3997", 640 "id": "69e75a6b3997",
@@ -636,7 +649,7 @@ @@ -636,7 +649,7 @@
636 "likes": 0, 649 "likes": 0,
637 "createdAt": 1788027833836, 650 "createdAt": 1788027833836,
638 "promptEn": "wounded hunter at a ruined subway dungeon entrance, lightning flickers, pointing into the tunnel", 651 "promptEn": "wounded hunter at a ruined subway dungeon entrance, lightning flickers, pointing into the tunnel",
639 - "lastPlayedAt": 1788248889310 652 + "lastPlayedAt": 1788250480118
640 }, 653 },
641 { 654 {
642 "id": "cde399c27dc4", 655 "id": "cde399c27dc4",
@@ -651,7 +664,7 @@ @@ -651,7 +664,7 @@
651 "likes": 0, 664 "likes": 0,
652 "createdAt": 1788026877547, 665 "createdAt": 1788026877547,
653 "promptEn": "a deity in gold crown and red veil, quietly judging you in a moonlit bridal chamber", 666 "promptEn": "a deity in gold crown and red veil, quietly judging you in a moonlit bridal chamber",
654 - "lastPlayedAt": 1788249765707 667 + "lastPlayedAt": 1788252887292
655 }, 668 },
656 { 669 {
657 "id": "d5f811737e95", 670 "id": "d5f811737e95",
@@ -666,7 +679,7 @@ @@ -666,7 +679,7 @@
666 "likes": 0, 679 "likes": 0,
667 "createdAt": 1788026876886, 680 "createdAt": 1788026876886,
668 "promptEn": "apartment manager in an eerie corridor, red elevator light flickering, holding out a key", 681 "promptEn": "apartment manager in an eerie corridor, red elevator light flickering, holding out a key",
669 - "lastPlayedAt": 1788245048064 682 + "lastPlayedAt": 1788250332049
670 }, 683 },
671 { 684 {
672 "id": "cdd03cca8461", 685 "id": "cdd03cca8461",
@@ -681,7 +694,7 @@ @@ -681,7 +694,7 @@
681 "likes": 0, 694 "likes": 0,
682 "createdAt": 1788026569422, 695 "createdAt": 1788026569422,
683 "promptEn": "stitched-face long-haired curse on a subway platform, flickering lights, cruel smile", 696 "promptEn": "stitched-face long-haired curse on a subway platform, flickering lights, cruel smile",
684 - "lastPlayedAt": 1788247712313 697 + "lastPlayedAt": 1788253043365
685 }, 698 },
686 { 699 {
687 "id": "b8dd0f62f648", 700 "id": "b8dd0f62f648",
@@ -696,7 +709,7 @@ @@ -696,7 +709,7 @@
696 "likes": 0, 709 "likes": 0,
697 "createdAt": 1788026569123, 710 "createdAt": 1788026569123,
698 "promptEn": "pale dream demon in a suit, reaching out a hand inside a dream train car", 711 "promptEn": "pale dream demon in a suit, reaching out a hand inside a dream train car",
699 - "lastPlayedAt": 1788250129929 712 + "lastPlayedAt": 1788252102983
700 }, 713 },
701 { 714 {
702 "id": "bd6e2b264243", 715 "id": "bd6e2b264243",
@@ -711,7 +724,7 @@ @@ -711,7 +724,7 @@
711 "likes": 0, 724 "likes": 0,
712 "createdAt": 1788026568815, 725 "createdAt": 1788026568815,
713 "promptEn": "blond soldier in combat gear, bracing at the entrance of a ruined basement battlefield", 726 "promptEn": "blond soldier in combat gear, bracing at the entrance of a ruined basement battlefield",
714 - "lastPlayedAt": 1788249067384 727 + "lastPlayedAt": 1788252839269
715 }, 728 },
716 { 729 {
717 "id": "b0d6af33eace", 730 "id": "b0d6af33eace",
@@ -726,7 +739,7 @@ @@ -726,7 +739,7 @@
726 "likes": 0, 739 "likes": 0,
727 "createdAt": 1788026568516, 740 "createdAt": 1788026568516,
728 "promptEn": "orange-haired villain in a black cloak with red clouds, raising a hand in a ruined village", 741 "promptEn": "orange-haired villain in a black cloak with red clouds, raising a hand in a ruined village",
729 - "lastPlayedAt": 1788248893311 742 + "lastPlayedAt": 1788251692781
730 }, 743 },
731 { 744 {
732 "id": "b077fd090415", 745 "id": "b077fd090415",
@@ -741,7 +754,7 @@ @@ -741,7 +754,7 @@
741 "likes": 0, 754 "likes": 0,
742 "createdAt": 1788026568242, 755 "createdAt": 1788026568242,
743 "promptEn": "magma commander in a white coat, raising a lava fist on the battlefield", 756 "promptEn": "magma commander in a white coat, raising a lava fist on the battlefield",
744 - "lastPlayedAt": 1788248741209 757 + "lastPlayedAt": 1788252487163
745 }, 758 },
746 { 759 {
747 "id": "1442013e94f0", 760 "id": "1442013e94f0",
@@ -756,7 +769,7 @@ @@ -756,7 +769,7 @@
756 "likes": 0, 769 "likes": 0,
757 "createdAt": 1788026068497, 770 "createdAt": 1788026068497,
758 "promptEn": "black-haired prince in a red cloak, pressing down an execution order in the trial hall", 771 "promptEn": "black-haired prince in a red cloak, pressing down an execution order in the trial hall",
759 - "lastPlayedAt": 1788249833797 772 + "lastPlayedAt": 1788251740816
760 }, 773 },
761 { 774 {
762 "id": "0a5e37bb328c", 775 "id": "0a5e37bb328c",
@@ -771,7 +784,7 @@ @@ -771,7 +784,7 @@
771 "likes": 0, 784 "likes": 0,
772 "createdAt": 1788025642732, 785 "createdAt": 1788025642732,
773 "promptEn": "Vecna reaching out a claw in his lair in the Upside Down, red lightning", 786 "promptEn": "Vecna reaching out a claw in his lair in the Upside Down, red lightning",
774 - "lastPlayedAt": 1788249929837 787 + "lastPlayedAt": 1788252559192
775 }, 788 },
776 { 789 {
777 "id": "00862f966c3f", 790 "id": "00862f966c3f",
@@ -786,7 +799,7 @@ @@ -786,7 +799,7 @@
786 "likes": 0, 799 "likes": 0,
787 "createdAt": 1788025640972, 800 "createdAt": 1788025640972,
788 "promptEn": "Voldemort in a graveyard, wand raised, stepping closer", 801 "promptEn": "Voldemort in a graveyard, wand raised, stepping closer",
789 - "lastPlayedAt": 1788249433560 802 + "lastPlayedAt": 1788252161011
790 }, 803 },
791 { 804 {
792 "id": "c3875fbd6cc4", 805 "id": "c3875fbd6cc4",
@@ -801,7 +814,7 @@ @@ -801,7 +814,7 @@
801 "likes": 0, 814 "likes": 0,
802 "createdAt": 1788025632028, 815 "createdAt": 1788025632028,
803 "promptEn": "a giant mouth embedded in the wall at the end of an endless hotel corridor, slowly opening", 816 "promptEn": "a giant mouth embedded in the wall at the end of an endless hotel corridor, slowly opening",
804 - "lastPlayedAt": 1788246707462 817 + "lastPlayedAt": 1788252701202
805 }, 818 },
806 { 819 {
807 "id": "1c6e2df243f4", 820 "id": "1c6e2df243f4",
@@ -816,7 +829,7 @@ @@ -816,7 +829,7 @@
816 "likes": 0, 829 "likes": 0,
817 "createdAt": 1788025630249, 830 "createdAt": 1788025630249,
818 "promptEn": "white-haired villain in a ruined street at night, cracked smile, reaching out a hand", 831 "promptEn": "white-haired villain in a ruined street at night, cracked smile, reaching out a hand",
819 - "lastPlayedAt": 1788248865293 832 + "lastPlayedAt": 1788251462624
820 }, 833 },
821 { 834 {
822 "id": "d735f1fc010f", 835 "id": "d735f1fc010f",
@@ -831,7 +844,7 @@ @@ -831,7 +844,7 @@
831 "likes": 0, 844 "likes": 0,
832 "createdAt": 1788025624377, 845 "createdAt": 1788025624377,
833 "promptEn": "cat-eared white-haired guard crouching in a ruined palace, purple aura around them", 846 "promptEn": "cat-eared white-haired guard crouching in a ruined palace, purple aura around them",
834 - "lastPlayedAt": 1788244791899 847 + "lastPlayedAt": 1788252499167
835 }, 848 },
836 { 849 {
837 "id": "b16b64e52f83", 850 "id": "b16b64e52f83",
@@ -846,7 +859,7 @@ @@ -846,7 +859,7 @@
846 "likes": 0, 859 "likes": 0,
847 "createdAt": 1788025623833, 860 "createdAt": 1788025623833,
848 "promptEn": "cat-eared white-haired guard crouching in a ruined palace, purple aura around them", 861 "promptEn": "cat-eared white-haired guard crouching in a ruined palace, purple aura around them",
849 - "lastPlayedAt": 1788249503586 862 + "lastPlayedAt": 1788251424585
850 }, 863 },
851 { 864 {
852 "id": "0d721acbc298", 865 "id": "0d721acbc298",
@@ -861,7 +874,7 @@ @@ -861,7 +874,7 @@
861 "likes": 0, 874 "likes": 0,
862 "createdAt": 1788025622363, 875 "createdAt": 1788025622363,
863 "promptEn": "detective in a surveillance room squinting at the monitors", 876 "promptEn": "detective in a surveillance room squinting at the monitors",
864 - "lastPlayedAt": 1788247902462 877 + "lastPlayedAt": 1788250159958
865 }, 878 },
866 { 879 {
867 "id": "639069dea7c5", 880 "id": "639069dea7c5",
@@ -876,7 +889,7 @@ @@ -876,7 +889,7 @@
876 "likes": 0, 889 "likes": 0,
877 "createdAt": 1788025620717, 890 "createdAt": 1788025620717,
878 "promptEn": "alien tyrant holding a glowing energy sphere, sneering on a rocky green battlefield", 891 "promptEn": "alien tyrant holding a glowing energy sphere, sneering on a rocky green battlefield",
879 - "lastPlayedAt": 1788249089402 892 + "lastPlayedAt": 1788252495168
880 }, 893 },
881 { 894 {
882 "id": "9db41d807330", 895 "id": "9db41d807330",
@@ -891,7 +904,7 @@ @@ -891,7 +904,7 @@
891 "likes": 0, 904 "likes": 0,
892 "createdAt": 1788025220954, 905 "createdAt": 1788025220954,
893 "promptEn": "pirate captain plants a cutlass on the table, making a dangerous bargain", 906 "promptEn": "pirate captain plants a cutlass on the table, making a dangerous bargain",
894 - "lastPlayedAt": 1788247468104 907 + "lastPlayedAt": 1788251456618
895 }, 908 },
896 { 909 {
897 "id": "3e03975ff40a", 910 "id": "3e03975ff40a",
@@ -921,7 +934,7 @@ @@ -921,7 +934,7 @@
921 "likes": 0, 934 "likes": 0,
922 "createdAt": 1788024900966, 935 "createdAt": 1788024900966,
923 "promptEn": "player 101 blocking the path on a high glass bridge, threatening you", 936 "promptEn": "player 101 blocking the path on a high glass bridge, threatening you",
924 - "lastPlayedAt": 1788248885312 937 + "lastPlayedAt": 1788251722799
925 }, 938 },
926 { 939 {
927 "id": "d6aab3fce63d", 940 "id": "d6aab3fce63d",
@@ -936,7 +949,7 @@ @@ -936,7 +949,7 @@
936 "likes": 0, 949 "likes": 0,
937 "createdAt": 1788024747209, 950 "createdAt": 1788024747209,
938 "promptEn": "wounded hunter leaning on a subway turnstile, ordering you into the tunnel", 951 "promptEn": "wounded hunter leaning on a subway turnstile, ordering you into the tunnel",
939 - "lastPlayedAt": 1788248130662 952 + "lastPlayedAt": 1788252002941
940 }, 953 },
941 { 954 {
942 "id": "fdefca4e4980", 955 "id": "fdefca4e4980",
@@ -951,7 +964,7 @@ @@ -951,7 +964,7 @@
951 "likes": 0, 964 "likes": 0,
952 "createdAt": 1788024491625, 965 "createdAt": 1788024491625,
953 "promptEn": "prince signs an execution order in the trial hall, points at the guillotine", 966 "promptEn": "prince signs an execution order in the trial hall, points at the guillotine",
954 - "lastPlayedAt": 1788247143814 967 + "lastPlayedAt": 1788251928912
955 }, 968 },
956 { 969 {
957 "id": "8a933feb52c4", 970 "id": "8a933feb52c4",
@@ -966,7 +979,7 @@ @@ -966,7 +979,7 @@
966 "likes": 0, 979 "likes": 0,
967 "createdAt": 1788019483999, 980 "createdAt": 1788019483999,
968 "promptEn": "constable rushes in, glances back at the door, then talks to the woman behind the screen", 981 "promptEn": "constable rushes in, glances back at the door, then talks to the woman behind the screen",
969 - "lastPlayedAt": 1788249277490 982 + "lastPlayedAt": 1788252139001
970 }, 983 },
971 { 984 {
972 "id": "998e3e6f9a2f", 985 "id": "998e3e6f9a2f",
@@ -981,7 +994,7 @@ @@ -981,7 +994,7 @@
981 "likes": 0, 994 "likes": 0,
982 "createdAt": 1788016668421, 995 "createdAt": 1788016668421,
983 "promptEn": "pirate negotiation, catching Barbossa's flaw and turning the tables", 996 "promptEn": "pirate negotiation, catching Barbossa's flaw and turning the tables",
984 - "lastPlayedAt": 1788248855284 997 + "lastPlayedAt": 1788250676206
985 }, 998 },
986 { 999 {
987 "id": "e3b18b5dfd8e", 1000 "id": "e3b18b5dfd8e",
@@ -996,7 +1009,7 @@ @@ -996,7 +1009,7 @@
996 "likes": 0, 1009 "likes": 0,
997 "createdAt": 1788016434846, 1010 "createdAt": 1788016434846,
998 "promptEn": "pirate negotiation, catching Barbossa's flaw and turning the tables", 1011 "promptEn": "pirate negotiation, catching Barbossa's flaw and turning the tables",
999 - "lastPlayedAt": 1788241122721 1012 + "lastPlayedAt": 1788251638752
1000 }, 1013 },
1001 { 1014 {
1002 "id": "03e32ff5f0ef", 1015 "id": "03e32ff5f0ef",
@@ -1011,7 +1024,7 @@ @@ -1011,7 +1024,7 @@
1011 "likes": 0, 1024 "likes": 0,
1012 "createdAt": 1788016203093, 1025 "createdAt": 1788016203093,
1013 "promptEn": "pirate negotiation, held the goal but paid a price", 1026 "promptEn": "pirate negotiation, held the goal but paid a price",
1014 - "lastPlayedAt": 1788248931331 1027 + "lastPlayedAt": 1788250906296
1015 }, 1028 },
1016 { 1029 {
1017 "id": "18aa882cbd0b", 1030 "id": "18aa882cbd0b",
@@ -1041,7 +1054,7 @@ @@ -1041,7 +1054,7 @@
1041 "likes": 0, 1054 "likes": 0,
1042 "createdAt": 1788015737873, 1055 "createdAt": 1788015737873,
1043 "promptEn": "pirate negotiation, went in head-on and Barbossa saw it coming", 1056 "promptEn": "pirate negotiation, went in head-on and Barbossa saw it coming",
1044 - "lastPlayedAt": 1788245038056 1057 + "lastPlayedAt": 1788252825264
1045 }, 1058 },
1046 { 1059 {
1047 "id": "2a5ee87b8f13", 1060 "id": "2a5ee87b8f13",
@@ -1056,7 +1069,7 @@ @@ -1056,7 +1069,7 @@
1056 "likes": 0, 1069 "likes": 0,
1057 "createdAt": 1788015493445, 1070 "createdAt": 1788015493445,
1058 "promptEn": "pirate negotiation, went in head-on and Barbossa saw it coming", 1071 "promptEn": "pirate negotiation, went in head-on and Barbossa saw it coming",
1059 - "lastPlayedAt": 1788249283490 1072 + "lastPlayedAt": 1788250790245
1060 }, 1073 },
1061 { 1074 {
1062 "id": "3f30f5097438", 1075 "id": "3f30f5097438",
@@ -1071,7 +1084,7 @@ @@ -1071,7 +1084,7 @@
1071 "likes": 0, 1084 "likes": 0,
1072 "createdAt": 1788015035234, 1085 "createdAt": 1788015035234,
1073 "promptEn": "pirate negotiation, stayed passive and got cornered", 1086 "promptEn": "pirate negotiation, stayed passive and got cornered",
1074 - "lastPlayedAt": 1788241330893 1087 + "lastPlayedAt": 1788251632751
1075 }, 1088 },
1076 { 1089 {
1077 "id": "6a0d14cabe17", 1090 "id": "6a0d14cabe17",
@@ -1086,7 +1099,7 @@ @@ -1086,7 +1099,7 @@
1086 "likes": 0, 1099 "likes": 0,
1087 "createdAt": 1788014791733, 1100 "createdAt": 1788014791733,
1088 "promptEn": "pirate negotiation, stayed passive and got cornered", 1101 "promptEn": "pirate negotiation, stayed passive and got cornered",
1089 - "lastPlayedAt": 1788249325507 1102 + "lastPlayedAt": 1788252169019
1090 }, 1103 },
1091 { 1104 {
1092 "id": "08120928cc77", 1105 "id": "08120928cc77",
@@ -1101,7 +1114,7 @@ @@ -1101,7 +1114,7 @@
1101 "likes": 0, 1114 "likes": 0,
1102 "createdAt": 1788014790969, 1115 "createdAt": 1788014790969,
1103 "promptEn": "pirate negotiation, stayed passive and got cornered", 1116 "promptEn": "pirate negotiation, stayed passive and got cornered",
1104 - "lastPlayedAt": 1788248146678 1117 + "lastPlayedAt": 1788251730808
1105 }, 1118 },
1106 { 1119 {
1107 "id": "e14fe7c3220e", 1120 "id": "e14fe7c3220e",
@@ -1116,7 +1129,7 @@ @@ -1116,7 +1129,7 @@
1116 "likes": 0, 1129 "likes": 0,
1117 "createdAt": 1788014563344, 1130 "createdAt": 1788014563344,
1118 "promptEn": "captain's cabin on the Black Pearl, surrounded by pirates, negotiation could turn into an execution", 1131 "promptEn": "captain's cabin on the Black Pearl, surrounded by pirates, negotiation could turn into an execution",
1119 - "lastPlayedAt": 1788246847578 1132 + "lastPlayedAt": 1788252563192
1120 }, 1133 },
1121 { 1134 {
1122 "id": "c6e8560f62a2", 1135 "id": "c6e8560f62a2",
@@ -1131,7 +1144,7 @@ @@ -1131,7 +1144,7 @@
1131 "likes": 0, 1144 "likes": 0,
1132 "createdAt": 1788014336515, 1145 "createdAt": 1788014336515,
1133 "promptEn": "captain's cabin on the Black Pearl, surrounded by pirates, negotiation could turn into an execution", 1146 "promptEn": "captain's cabin on the Black Pearl, surrounded by pirates, negotiation could turn into an execution",
1134 - "lastPlayedAt": 1788245304286 1147 + "lastPlayedAt": 1788250666207
1135 }, 1148 },
1136 { 1149 {
1137 "id": "eae105ee1204", 1150 "id": "eae105ee1204",
@@ -1146,7 +1159,7 @@ @@ -1146,7 +1159,7 @@
1146 "likes": 0, 1159 "likes": 0,
1147 "createdAt": 1788014099497, 1160 "createdAt": 1788014099497,
1148 "promptEn": "glass bridge game, exploiting a flaw to push back player 101", 1161 "promptEn": "glass bridge game, exploiting a flaw to push back player 101",
1149 - "lastPlayedAt": 1788249885816 1162 + "lastPlayedAt": 1788251098395
1150 }, 1163 },
1151 { 1164 {
1152 "id": "24576c264a25", 1165 "id": "24576c264a25",
@@ -1176,7 +1189,7 @@ @@ -1176,7 +1189,7 @@
1176 "likes": 0, 1189 "likes": 0,
1177 "createdAt": 1788013634333, 1190 "createdAt": 1788013634333,
1178 "promptEn": "glass bridge game, held the goal but paid a price", 1191 "promptEn": "glass bridge game, held the goal but paid a price",
1179 - "lastPlayedAt": 1788247720319 1192 + "lastPlayedAt": 1788252773238
1180 }, 1193 },
1181 { 1194 {
1182 "id": "5b8ef21616d4", 1195 "id": "5b8ef21616d4",
@@ -1191,7 +1204,7 @@ @@ -1191,7 +1204,7 @@
1191 "likes": 0, 1204 "likes": 0,
1192 "createdAt": 1788013632065, 1205 "createdAt": 1788013632065,
1193 "promptEn": "glass bridge game, held the goal but paid a price", 1206 "promptEn": "glass bridge game, held the goal but paid a price",
1194 - "lastPlayedAt": 1788249933837 1207 + "lastPlayedAt": 1788252935312
1195 }, 1208 },
1196 { 1209 {
1197 "id": "892b923eed29", 1210 "id": "892b923eed29",
@@ -1221,7 +1234,7 @@ @@ -1221,7 +1234,7 @@
1221 "likes": 0, 1234 "likes": 0,
1222 "createdAt": 1788013155592, 1235 "createdAt": 1788013155592,
1223 "promptEn": "glass bridge game, stayed passive and got cornered", 1236 "promptEn": "glass bridge game, stayed passive and got cornered",
1224 - "lastPlayedAt": 1788242766130 1237 + "lastPlayedAt": 1788252737220
1225 }, 1238 },
1226 { 1239 {
1227 "id": "f80c8ec1a8c8", 1240 "id": "f80c8ec1a8c8",
@@ -1236,7 +1249,7 @@ @@ -1236,7 +1249,7 @@
1236 "likes": 0, 1249 "likes": 0,
1237 "createdAt": 1788012917294, 1250 "createdAt": 1788012917294,
1238 "promptEn": "standing on the glass bridge, facing off with player 101", 1251 "promptEn": "standing on the glass bridge, facing off with player 101",
1239 - "lastPlayedAt": 1788248120651 1252 + "lastPlayedAt": 1788251642756
1240 }, 1253 },
1241 { 1254 {
1242 "id": "8f23de61904f", 1255 "id": "8f23de61904f",
@@ -1251,7 +1264,7 @@ @@ -1251,7 +1264,7 @@
1251 "likes": 0, 1264 "likes": 0,
1252 "createdAt": 1788012917185, 1265 "createdAt": 1788012917185,
1253 "promptEn": "standing on the glass bridge, facing off with player 101", 1266 "promptEn": "standing on the glass bridge, facing off with player 101",
1254 - "lastPlayedAt": 1788244377528 1267 + "lastPlayedAt": 1788250786246
1255 }, 1268 },
1256 { 1269 {
1257 "id": "bb4a8351d822", 1270 "id": "bb4a8351d822",
@@ -1281,7 +1294,7 @@ @@ -1281,7 +1294,7 @@
1281 "likes": 0, 1294 "likes": 0,
1282 "createdAt": 1788012441458, 1295 "createdAt": 1788012441458,
1283 "promptEn": "facing Vecna, held the goal but paid a price", 1296 "promptEn": "facing Vecna, held the goal but paid a price",
1284 - "lastPlayedAt": 1788248951336 1297 + "lastPlayedAt": 1788251798845
1285 }, 1298 },
1286 { 1299 {
1287 "id": "691c2f679759", 1300 "id": "691c2f679759",
@@ -1296,7 +1309,7 @@ @@ -1296,7 +1309,7 @@
1296 "likes": 0, 1309 "likes": 0,
1297 "createdAt": 1788012202802, 1310 "createdAt": 1788012202802,
1298 "promptEn": "facing Vecna, went in head-on and got seen through", 1311 "promptEn": "facing Vecna, went in head-on and got seen through",
1299 - "lastPlayedAt": 1788244267443 1312 + "lastPlayedAt": 1788252096983
1300 }, 1313 },
1301 { 1314 {
1302 "id": "07f957783a09", 1315 "id": "07f957783a09",
@@ -1341,7 +1354,7 @@ @@ -1341,7 +1354,7 @@
1341 "likes": 0, 1354 "likes": 0,
1342 "createdAt": 1788011727444, 1355 "createdAt": 1788011727444,
1343 "promptEn": "entering Vecna's mental lair, red lightning, twisted space", 1356 "promptEn": "entering Vecna's mental lair, red lightning, twisted space",
1344 - "lastPlayedAt": 1788237488190 1357 + "lastPlayedAt": 1788251520666
1345 }, 1358 },
1346 { 1359 {
1347 "id": "6a9af7e7368d", 1360 "id": "6a9af7e7368d",
@@ -1356,7 +1369,7 @@ @@ -1356,7 +1369,7 @@
1356 "likes": 0, 1369 "likes": 0,
1357 "createdAt": 1788011488775, 1370 "createdAt": 1788011488775,
1358 "promptEn": "graveyard standoff, exploiting a flaw to counter Voldemort", 1371 "promptEn": "graveyard standoff, exploiting a flaw to counter Voldemort",
1359 - "lastPlayedAt": 1788249467572 1372 + "lastPlayedAt": 1788252403130
1360 }, 1373 },
1361 { 1374 {
1362 "id": "24845be71ea0", 1375 "id": "24845be71ea0",
@@ -1371,7 +1384,7 @@ @@ -1371,7 +1384,7 @@
1371 "likes": 0, 1384 "likes": 0,
1372 "createdAt": 1788011488667, 1385 "createdAt": 1788011488667,
1373 "promptEn": "graveyard standoff, exploiting a flaw to counter Voldemort", 1386 "promptEn": "graveyard standoff, exploiting a flaw to counter Voldemort",
1374 - "lastPlayedAt": 1788248432935 1387 + "lastPlayedAt": 1788252803254
1375 }, 1388 },
1376 { 1389 {
1377 "id": "f1012a3d7aa7", 1390 "id": "f1012a3d7aa7",
@@ -1386,7 +1399,7 @@ @@ -1386,7 +1399,7 @@
1386 "likes": 0, 1399 "likes": 0,
1387 "createdAt": 1788011251158, 1400 "createdAt": 1788011251158,
1388 "promptEn": "facing Voldemort, held the goal but paid a price", 1401 "promptEn": "facing Voldemort, held the goal but paid a price",
1389 - "lastPlayedAt": 1788244998065 1402 + "lastPlayedAt": 1788251207183
1390 }, 1403 },
1391 { 1404 {
1392 "id": "58f68b111429", 1405 "id": "58f68b111429",
@@ -1401,7 +1414,7 @@ @@ -1401,7 +1414,7 @@
1401 "likes": 0, 1414 "likes": 0,
1402 "createdAt": 1788011013309, 1415 "createdAt": 1788011013309,
1403 "promptEn": "facing Voldemort, went in head-on and got seen through", 1416 "promptEn": "facing Voldemort, went in head-on and got seen through",
1404 - "lastPlayedAt": 1788245638583 1417 + "lastPlayedAt": 1788252965327
1405 }, 1418 },
1406 { 1419 {
1407 "id": "682cbc166479", 1420 "id": "682cbc166479",
@@ -1416,7 +1429,7 @@ @@ -1416,7 +1429,7 @@
1416 "likes": 0, 1429 "likes": 0,
1417 "createdAt": 1788010775613, 1430 "createdAt": 1788010775613,
1418 "promptEn": "facing Voldemort, stayed passive and got cornered", 1431 "promptEn": "facing Voldemort, stayed passive and got cornered",
1419 - "lastPlayedAt": 1788249909833 1432 + "lastPlayedAt": 1788252633224
1420 }, 1433 },
1421 { 1434 {
1422 "id": "795842efa4a1", 1435 "id": "795842efa4a1",
@@ -1446,7 +1459,7 @@ @@ -1446,7 +1459,7 @@
1446 "likes": 0, 1459 "likes": 0,
1447 "createdAt": 1788010299688, 1460 "createdAt": 1788010299688,
1448 "promptEn": "facing Thanos, exploiting a flaw to counter him", 1461 "promptEn": "facing Thanos, exploiting a flaw to counter him",
1449 - "lastPlayedAt": 1788249423555 1462 + "lastPlayedAt": 1788251102950
1450 }, 1463 },
1451 { 1464 {
1452 "id": "469294a4ed09", 1465 "id": "469294a4ed09",
@@ -1461,7 +1474,7 @@ @@ -1461,7 +1474,7 @@
1461 "likes": 0, 1474 "likes": 0,
1462 "createdAt": 1788010062535, 1475 "createdAt": 1788010062535,
1463 "promptEn": "facing Thanos, held the goal but paid a price", 1476 "promptEn": "facing Thanos, held the goal but paid a price",
1464 - "lastPlayedAt": 1788247440076 1477 + "lastPlayedAt": 1788252076972
1465 }, 1478 },
1466 { 1479 {
1467 "id": "324b84ebc607", 1480 "id": "324b84ebc607",
@@ -1476,7 +1489,7 @@ @@ -1476,7 +1489,7 @@
1476 "likes": 0, 1489 "likes": 0,
1477 "createdAt": 1788009825082, 1490 "createdAt": 1788009825082,
1478 "promptEn": "facing Thanos, went in head-on and got seen through", 1491 "promptEn": "facing Thanos, went in head-on and got seen through",
1479 - "lastPlayedAt": 1788248991352 1492 + "lastPlayedAt": 1788252393143
1480 }, 1493 },
1481 { 1494 {
1482 "id": "a6ead2cbe03f", 1495 "id": "a6ead2cbe03f",
@@ -1506,7 +1519,7 @@ @@ -1506,7 +1519,7 @@
1506 "likes": 0, 1519 "likes": 0,
1507 "createdAt": 1788009346020, 1520 "createdAt": 1788009346020,
1508 "promptEn": "battlefield on Titan, the last chance to stop Thanos", 1521 "promptEn": "battlefield on Titan, the last chance to stop Thanos",
1509 - "lastPlayedAt": 1788246895620 1522 + "lastPlayedAt": 1788252467159
1510 }, 1523 },
1511 { 1524 {
1512 "id": "66a96c6bc7cb", 1525 "id": "66a96c6bc7cb",
@@ -1521,7 +1534,7 @@ @@ -1521,7 +1534,7 @@
1521 "likes": 0, 1534 "likes": 0,
1522 "createdAt": 1788009108302, 1535 "createdAt": 1788009108302,
1523 "promptEn": "in the endless hotel, exploiting a flaw to counter the Eternity Devil", 1536 "promptEn": "in the endless hotel, exploiting a flaw to counter the Eternity Devil",
1524 - "lastPlayedAt": 1788249037369 1537 + "lastPlayedAt": 1788252247056
1525 }, 1538 },
1526 { 1539 {
1527 "id": "71c590b0ea8f", 1540 "id": "71c590b0ea8f",
@@ -1536,7 +1549,7 @@ @@ -1536,7 +1549,7 @@
1536 "likes": 0, 1549 "likes": 0,
1537 "createdAt": 1788008870118, 1550 "createdAt": 1788008870118,
1538 "promptEn": "facing the Eternity Devil, held the goal but paid a price", 1551 "promptEn": "facing the Eternity Devil, held the goal but paid a price",
1539 - "lastPlayedAt": 1788245856782 1552 + "lastPlayedAt": 1788252165013
1540 }, 1553 },
1541 { 1554 {
1542 "id": "35833c2cabb9", 1555 "id": "35833c2cabb9",
@@ -1551,7 +1564,7 @@ @@ -1551,7 +1564,7 @@
1551 "likes": 0, 1564 "likes": 0,
1552 "createdAt": 1788008632603, 1565 "createdAt": 1788008632603,
1553 "promptEn": "facing the Eternity Devil, went in head-on and got seen through", 1566 "promptEn": "facing the Eternity Devil, went in head-on and got seen through",
1554 - "lastPlayedAt": 1788248382886 1567 + "lastPlayedAt": 1788250580165
1555 }, 1568 },
1556 { 1569 {
1557 "id": "361c80537652", 1570 "id": "361c80537652",
@@ -1566,7 +1579,7 @@ @@ -1566,7 +1579,7 @@
1566 "likes": 0, 1579 "likes": 0,
1567 "createdAt": 1788008394344, 1580 "createdAt": 1788008394344,
1568 "promptEn": "facing the Eternity Devil, stayed passive and got cornered", 1581 "promptEn": "facing the Eternity Devil, stayed passive and got cornered",
1569 - "lastPlayedAt": 1788247716320 1582 + "lastPlayedAt": 1788252833268
1570 }, 1583 },
1571 { 1584 {
1572 "id": "1a57de01bad0", 1585 "id": "1a57de01bad0",
@@ -1581,7 +1594,7 @@ @@ -1581,7 +1594,7 @@
1581 "likes": 0, 1594 "likes": 0,
1582 "createdAt": 1788008156307, 1595 "createdAt": 1788008156307,
1583 "promptEn": "hotel floor sealed by the Eternity Devil, an endless looping corridor", 1596 "promptEn": "hotel floor sealed by the Eternity Devil, an endless looping corridor",
1584 - "lastPlayedAt": 1788248987350 1597 + "lastPlayedAt": 1788251948919
1585 }, 1598 },
1586 { 1599 {
1587 "id": "cd3b6dda90ad", 1600 "id": "cd3b6dda90ad",
@@ -1596,7 +1609,7 @@ @@ -1596,7 +1609,7 @@
1596 "likes": 0, 1609 "likes": 0,
1597 "createdAt": 1788007915610, 1610 "createdAt": 1788007915610,
1598 "promptEn": "in the ruined city, exploiting a flaw to counter Tomura", 1611 "promptEn": "in the ruined city, exploiting a flaw to counter Tomura",
1599 - "lastPlayedAt": 1788249919450 1612 + "lastPlayedAt": 1788252961326
1600 }, 1613 },
1601 { 1614 {
1602 "id": "f67685cd6862", 1615 "id": "f67685cd6862",
@@ -1611,7 +1624,7 @@ @@ -1611,7 +1624,7 @@
1611 "likes": 0, 1624 "likes": 0,
1612 "createdAt": 1788007678723, 1625 "createdAt": 1788007678723,
1613 "promptEn": "facing Tomura, held the goal but paid a price", 1626 "promptEn": "facing Tomura, held the goal but paid a price",
1614 - "lastPlayedAt": 1788248458956 1627 + "lastPlayedAt": 1788252219044
1615 }, 1628 },
1616 { 1629 {
1617 "id": "ee5bd111d8bd", 1630 "id": "ee5bd111d8bd",
@@ -1626,7 +1639,7 @@ @@ -1626,7 +1639,7 @@
1626 "likes": 0, 1639 "likes": 0,
1627 "createdAt": 1788007441156, 1640 "createdAt": 1788007441156,
1628 "promptEn": "battlefield in Jaku city, the city in ruins, heroes in crisis", 1641 "promptEn": "battlefield in Jaku city, the city in ruins, heroes in crisis",
1629 - "lastPlayedAt": 1788243420700 1642 + "lastPlayedAt": 1788251770832
1630 }, 1643 },
1631 { 1644 {
1632 "id": "68219d6b68c8", 1645 "id": "68219d6b68c8",
@@ -1641,7 +1654,7 @@ @@ -1641,7 +1654,7 @@
1641 "likes": 0, 1654 "likes": 0,
1642 "createdAt": 1788007201908, 1655 "createdAt": 1788007201908,
1643 "promptEn": "breaking into the palace, Neferpitou stalling to protect the king", 1656 "promptEn": "breaking into the palace, Neferpitou stalling to protect the king",
1644 - "lastPlayedAt": 1788249889814 1657 + "lastPlayedAt": 1788252681196
1645 }, 1658 },
1646 { 1659 {
1647 "id": "628026375795", 1660 "id": "628026375795",
@@ -1656,7 +1669,7 @@ @@ -1656,7 +1669,7 @@
1656 "likes": 0, 1669 "likes": 0,
1657 "createdAt": 1788006964122, 1670 "createdAt": 1788006964122,
1658 "promptEn": "grabbing an evidence flaw to counter L", 1671 "promptEn": "grabbing an evidence flaw to counter L",
1659 - "lastPlayedAt": 1788249155428 1672 + "lastPlayedAt": 1788251193178
1660 }, 1673 },
1661 { 1674 {
1662 "id": "0c6306b07f79", 1675 "id": "0c6306b07f79",
@@ -1671,7 +1684,7 @@ @@ -1671,7 +1684,7 @@
1671 "likes": 0, 1684 "likes": 0,
1672 "createdAt": 1788006725887, 1685 "createdAt": 1788006725887,
1673 "promptEn": "facing off with L, went in head-on and got seen through", 1686 "promptEn": "facing off with L, went in head-on and got seen through",
1674 - "lastPlayedAt": 1788244141322 1687 + "lastPlayedAt": 1788252617213
1675 }, 1688 },
1676 { 1689 {
1677 "id": "ee82188227fa", 1690 "id": "ee82188227fa",
@@ -1686,7 +1699,7 @@ @@ -1686,7 +1699,7 @@
1686 "likes": 0, 1699 "likes": 0,
1687 "createdAt": 1788006252918, 1700 "createdAt": 1788006252918,
1688 "promptEn": "facing L, stayed passive and the evidence pressure maxed out", 1701 "promptEn": "facing L, stayed passive and the evidence pressure maxed out",
1689 - "lastPlayedAt": 1788247598221 1702 + "lastPlayedAt": 1788251482641
1690 }, 1703 },
1691 { 1704 {
1692 "id": "0e28a7fecf03", 1705 "id": "0e28a7fecf03",
@@ -1701,7 +1714,7 @@ @@ -1701,7 +1714,7 @@
1701 "likes": 0, 1714 "likes": 0,
1702 "createdAt": 1788006252824, 1715 "createdAt": 1788006252824,
1703 "promptEn": "facing L, stayed passive and the evidence pressure maxed out", 1716 "promptEn": "facing L, stayed passive and the evidence pressure maxed out",
1704 - "lastPlayedAt": 1788248392895 1717 + "lastPlayedAt": 1788250153939
1705 }, 1718 },
1706 { 1719 {
1707 "id": "fb0738ad3e3b", 1720 "id": "fb0738ad3e3b",
@@ -1716,7 +1729,7 @@ @@ -1716,7 +1729,7 @@
1716 "likes": 0, 1729 "likes": 0,
1717 "createdAt": 1788006015175, 1730 "createdAt": 1788006015175,
1718 "promptEn": "on the ruined planet, exploiting a flaw to counter Frieza", 1731 "promptEn": "on the ruined planet, exploiting a flaw to counter Frieza",
1719 - "lastPlayedAt": 1788249419549 1732 + "lastPlayedAt": 1788252971329
1720 }, 1733 },
1721 { 1734 {
1722 "id": "e6fda5c2237d", 1735 "id": "e6fda5c2237d",
@@ -1761,7 +1774,7 @@ @@ -1761,7 +1774,7 @@
1761 "likes": 0, 1774 "likes": 0,
1762 "createdAt": 1788005305091, 1775 "createdAt": 1788005305091,
1763 "promptEn": "facing Frieza, stayed passive and got cornered", 1776 "promptEn": "facing Frieza, stayed passive and got cornered",
1764 - "lastPlayedAt": 1788246715470 1777 + "lastPlayedAt": 1788252623220
1765 }, 1778 },
1766 { 1779 {
1767 "id": "d680e111ade5", 1780 "id": "d680e111ade5",
@@ -1776,7 +1789,7 @@ @@ -1776,7 +1789,7 @@
1776 "likes": 0, 1789 "likes": 0,
1777 "createdAt": 1788005066484, 1790 "createdAt": 1788005066484,
1778 "promptEn": "Namek is about to be destroyed, the dragon ball wish still up for grabs", 1791 "promptEn": "Namek is about to be destroyed, the dragon ball wish still up for grabs",
1779 - "lastPlayedAt": 1788246173033 1792 + "lastPlayedAt": 1788251174432
1780 }, 1793 },
1781 { 1794 {
1782 "id": "565059763888", 1795 "id": "565059763888",
@@ -1791,7 +1804,7 @@ @@ -1791,7 +1804,7 @@
1791 "likes": 0, 1804 "likes": 0,
1792 "createdAt": 1788004828526, 1805 "createdAt": 1788004828526,
1793 "promptEn": "in the subway, exploiting a flaw to counter Mahito", 1806 "promptEn": "in the subway, exploiting a flaw to counter Mahito",
1794 - "lastPlayedAt": 1788249383535 1807 + "lastPlayedAt": 1788250659744
1795 }, 1808 },
1796 { 1809 {
1797 "id": "323737948733", 1810 "id": "323737948733",
@@ -1806,7 +1819,7 @@ @@ -1806,7 +1819,7 @@
1806 "likes": 0, 1819 "likes": 0,
1807 "createdAt": 1788004590937, 1820 "createdAt": 1788004590937,
1808 "promptEn": "facing Mahito, held the goal but paid a price", 1821 "promptEn": "facing Mahito, held the goal but paid a price",
1809 - "lastPlayedAt": 1788244441588 1822 + "lastPlayedAt": 1788253015358
1810 }, 1823 },
1811 { 1824 {
1812 "id": "9996a8ac8326", 1825 "id": "9996a8ac8326",
@@ -1821,7 +1834,7 @@ @@ -1821,7 +1834,7 @@
1821 "likes": 0, 1834 "likes": 0,
1822 "createdAt": 1788004353928, 1835 "createdAt": 1788004353928,
1823 "promptEn": "facing Mahito, went in head-on and got seen through", 1836 "promptEn": "facing Mahito, went in head-on and got seen through",
1824 - "lastPlayedAt": 1788250119920 1837 + "lastPlayedAt": 1788251822858
1825 }, 1838 },
1826 { 1839 {
1827 "id": "971d80ec087c", 1840 "id": "971d80ec087c",
@@ -1836,7 +1849,7 @@ @@ -1836,7 +1849,7 @@
1836 "likes": 0, 1849 "likes": 0,
1837 "createdAt": 1788004115725, 1850 "createdAt": 1788004115725,
1838 "promptEn": "facing Mahito, stayed passive and got cornered", 1851 "promptEn": "facing Mahito, stayed passive and got cornered",
1839 - "lastPlayedAt": 1788249363526 1852 + "lastPlayedAt": 1788252799252
1840 }, 1853 },
1841 { 1854 {
1842 "id": "5dd52c568f66", 1855 "id": "5dd52c568f66",
@@ -1851,7 +1864,7 @@ @@ -1851,7 +1864,7 @@
1851 "likes": 0, 1864 "likes": 0,
1852 "createdAt": 1788004115612, 1865 "createdAt": 1788004115612,
1853 "promptEn": "facing Mahito, stayed passive and got cornered", 1866 "promptEn": "facing Mahito, stayed passive and got cornered",
1854 - "lastPlayedAt": 1788248314826 1867 + "lastPlayedAt": 1788252553190
1855 }, 1868 },
1856 { 1869 {
1857 "id": "f4a2870386c6", 1870 "id": "f4a2870386c6",
@@ -1866,7 +1879,7 @@ @@ -1866,7 +1879,7 @@
1866 "likes": 0, 1879 "likes": 0,
1867 "createdAt": 1788003877425, 1880 "createdAt": 1788003877425,
1868 "promptEn": "in the dream, exploiting a flaw to counter Enmu", 1881 "promptEn": "in the dream, exploiting a flaw to counter Enmu",
1869 - "lastPlayedAt": 1788249187447 1882 + "lastPlayedAt": 1788252533186
1870 }, 1883 },
1871 { 1884 {
1872 "id": "7c4f9460e6b7", 1885 "id": "7c4f9460e6b7",
@@ -1881,7 +1894,7 @@ @@ -1881,7 +1894,7 @@
1881 "likes": 0, 1894 "likes": 0,
1882 "createdAt": 1788003639415, 1895 "createdAt": 1788003639415,
1883 "promptEn": "facing Enmu, held the goal but paid a price", 1896 "promptEn": "facing Enmu, held the goal but paid a price",
1884 - "lastPlayedAt": 1788248428932 1897 + "lastPlayedAt": 1788252106986
1885 }, 1898 },
1886 { 1899 {
1887 "id": "6881dbe839a0", 1900 "id": "6881dbe839a0",
@@ -1896,7 +1909,7 @@ @@ -1896,7 +1909,7 @@
1896 "likes": 0, 1909 "likes": 0,
1897 "createdAt": 1788003402559, 1910 "createdAt": 1788003402559,
1898 "promptEn": "facing Enmu, went in head-on and got seen through", 1911 "promptEn": "facing Enmu, went in head-on and got seen through",
1899 - "lastPlayedAt": 1788246589381 1912 + "lastPlayedAt": 1788252072968
1900 }, 1913 },
1901 { 1914 {
1902 "id": "5c0f1663f4ae", 1915 "id": "5c0f1663f4ae",
@@ -1911,7 +1924,7 @@ @@ -1911,7 +1924,7 @@
1911 "likes": 0, 1924 "likes": 0,
1912 "createdAt": 1788003166117, 1925 "createdAt": 1788003166117,
1913 "promptEn": "facing Enmu, stayed passive and got cornered", 1926 "promptEn": "facing Enmu, stayed passive and got cornered",
1914 - "lastPlayedAt": 1788246683440 1927 + "lastPlayedAt": 1788252727219
1915 }, 1928 },
1916 { 1929 {
1917 "id": "a3f39da74c1f", 1930 "id": "a3f39da74c1f",
@@ -1926,7 +1939,7 @@ @@ -1926,7 +1939,7 @@
1926 "likes": 0, 1939 "likes": 0,
1927 "createdAt": 1788002929455, 1940 "createdAt": 1788002929455,
1928 "promptEn": "facing Reiner, exploiting a flaw to counter him", 1941 "promptEn": "facing Reiner, exploiting a flaw to counter him",
1929 - "lastPlayedAt": 1788243602857 1942 + "lastPlayedAt": 1788252195030
1930 }, 1943 },
1931 { 1944 {
1932 "id": "ea8b38014674", 1945 "id": "ea8b38014674",
@@ -1941,7 +1954,7 @@ @@ -1941,7 +1954,7 @@
1941 "likes": 0, 1954 "likes": 0,
1942 "createdAt": 1788002691822, 1955 "createdAt": 1788002691822,
1943 "promptEn": "facing Reiner, held the goal but paid a price", 1956 "promptEn": "facing Reiner, held the goal but paid a price",
1944 - "lastPlayedAt": 1788249915447 1957 + "lastPlayedAt": 1788252655237
1945 }, 1958 },
1946 { 1959 {
1947 "id": "f65b15d67966", 1960 "id": "f65b15d67966",
@@ -1956,7 +1969,7 @@ @@ -1956,7 +1969,7 @@
1956 "likes": 0, 1969 "likes": 0,
1957 "createdAt": 1788002455066, 1970 "createdAt": 1788002455066,
1958 "promptEn": "facing Reiner, went in head-on and got seen through", 1971 "promptEn": "facing Reiner, went in head-on and got seen through",
1959 - "lastPlayedAt": 1788249057379 1972 + "lastPlayedAt": 1788251886889
1960 }, 1973 },
1961 { 1974 {
1962 "id": "5846d645e870", 1975 "id": "5846d645e870",
@@ -1971,7 +1984,7 @@ @@ -1971,7 +1984,7 @@
1971 "likes": 0, 1984 "likes": 0,
1972 "createdAt": 1788002217928, 1985 "createdAt": 1788002217928,
1973 "promptEn": "facing Reiner, stayed passive and got cornered", 1986 "promptEn": "facing Reiner, stayed passive and got cornered",
1974 - "lastPlayedAt": 1788247906463 1987 + "lastPlayedAt": 1788251696779
1975 }, 1988 },
1976 { 1989 {
1977 "id": "3fedf5531999", 1990 "id": "3fedf5531999",
@@ -1986,7 +1999,7 @@ @@ -1986,7 +1999,7 @@
1986 "likes": 0, 1999 "likes": 0,
1987 "createdAt": 1788001981272, 2000 "createdAt": 1788001981272,
1988 "promptEn": "basement in Shiganshina, the titan secret weighing down on you", 2001 "promptEn": "basement in Shiganshina, the titan secret weighing down on you",
1989 - "lastPlayedAt": 1788248186714 2002 + "lastPlayedAt": 1788252675244
1990 }, 2003 },
1991 { 2004 {
1992 "id": "7c2351a27a96", 2005 "id": "7c2351a27a96",
@@ -2001,7 +2014,7 @@ @@ -2001,7 +2014,7 @@
2001 "likes": 0, 2014 "likes": 0,
2002 "createdAt": 1788001508988, 2015 "createdAt": 1788001508988,
2003 "promptEn": "in the ruins of Konoha, exploiting a flaw to counter Pain", 2016 "promptEn": "in the ruins of Konoha, exploiting a flaw to counter Pain",
2004 - "lastPlayedAt": 1788244357522 2017 + "lastPlayedAt": 1788252503166
2005 }, 2018 },
2006 { 2019 {
2007 "id": "79304c061606", 2020 "id": "79304c061606",
@@ -2016,7 +2029,7 @@ @@ -2016,7 +2029,7 @@
2016 "likes": 0, 2029 "likes": 0,
2017 "createdAt": 1788001428705, 2030 "createdAt": 1788001428705,
2018 "promptEn": "in the ruins of Konoha, exploiting a flaw to counter Pain", 2031 "promptEn": "in the ruins of Konoha, exploiting a flaw to counter Pain",
2019 - "lastPlayedAt": 1788249429557 2032 + "lastPlayedAt": 1788251776833
2020 }, 2033 },
2021 { 2034 {
2022 "id": "e486fab4c24d", 2035 "id": "e486fab4c24d",
@@ -2031,7 +2044,7 @@ @@ -2031,7 +2044,7 @@
2031 "likes": 0, 2044 "likes": 0,
2032 "createdAt": 1788001285796, 2045 "createdAt": 1788001285796,
2033 "promptEn": "in the ruins of Konoha, exploiting a flaw to counter Pain", 2046 "promptEn": "in the ruins of Konoha, exploiting a flaw to counter Pain",
2034 - "lastPlayedAt": 1788248869294 2047 + "lastPlayedAt": 1788252231046
2035 }, 2048 },
2036 { 2049 {
2037 "id": "808e89ca06a4", 2050 "id": "808e89ca06a4",
@@ -2046,7 +2059,7 @@ @@ -2046,7 +2059,7 @@
2046 "likes": 0, 2059 "likes": 0,
2047 "createdAt": 1788001049233, 2060 "createdAt": 1788001049233,
2048 "promptEn": "facing Pain, held the goal but paid a price", 2061 "promptEn": "facing Pain, held the goal but paid a price",
2049 - "lastPlayedAt": 1788249071386 2062 + "lastPlayedAt": 1788251780839
2050 }, 2063 },
2051 { 2064 {
2052 "id": "7ecd480a3c31", 2065 "id": "7ecd480a3c31",
@@ -2061,7 +2074,7 @@ @@ -2061,7 +2074,7 @@
2061 "likes": 0, 2074 "likes": 0,
2062 "createdAt": 1788000812932, 2075 "createdAt": 1788000812932,
2063 "promptEn": "facing Pain, went in head-on and got seen through", 2076 "promptEn": "facing Pain, went in head-on and got seen through",
2064 - "lastPlayedAt": 1788249183444 2077 + "lastPlayedAt": 1788252529179
2065 }, 2078 },
2066 { 2079 {
2067 "id": "f691ac021df0", 2080 "id": "f691ac021df0",
@@ -2076,7 +2089,7 @@ @@ -2076,7 +2089,7 @@
2076 "likes": 0, 2089 "likes": 0,
2077 "createdAt": 1788000577474, 2090 "createdAt": 1788000577474,
2078 "promptEn": "facing Pain, stayed passive and got cornered", 2091 "promptEn": "facing Pain, stayed passive and got cornered",
2079 - "lastPlayedAt": 1788246411240 2092 + "lastPlayedAt": 1788253009344
2080 }, 2093 },
2081 { 2094 {
2082 "id": "5ef9489bdc5b", 2095 "id": "5ef9489bdc5b",
@@ -2091,7 +2104,7 @@ @@ -2091,7 +2104,7 @@
2091 "likes": 0, 2104 "likes": 0,
2092 "createdAt": 1788000341927, 2105 "createdAt": 1788000341927,
2093 "promptEn": "Konoha destroyed by Shinra Tensei, Pain declaring order in the ruins", 2106 "promptEn": "Konoha destroyed by Shinra Tensei, Pain declaring order in the ruins",
2094 - "lastPlayedAt": 1788247898463 2107 + "lastPlayedAt": 1788251102395
2095 }, 2108 },
2096 { 2109 {
2097 "id": "e245dbcc6d36", 2110 "id": "e245dbcc6d36",
@@ -2106,7 +2119,7 @@ @@ -2106,7 +2119,7 @@
2106 "likes": 0, 2119 "likes": 0,
2107 "createdAt": 1788000105889, 2120 "createdAt": 1788000105889,
2108 "promptEn": "facing Sakazuki, exploiting a flaw to counter him", 2121 "promptEn": "facing Sakazuki, exploiting a flaw to counter him",
2109 - "lastPlayedAt": 1788249083398 2122 + "lastPlayedAt": 1788250850269
2110 }, 2123 },
2111 { 2124 {
2112 "id": "c9be7c07b793", 2125 "id": "c9be7c07b793",
@@ -2121,7 +2134,7 @@ @@ -2121,7 +2134,7 @@
2121 "likes": 0, 2134 "likes": 0,
2122 "createdAt": 1787999869694, 2135 "createdAt": 1787999869694,
2123 "promptEn": "facing Sakazuki, held the goal but paid a price", 2136 "promptEn": "facing Sakazuki, held the goal but paid a price",
2124 - "lastPlayedAt": 1788249637645 2137 + "lastPlayedAt": 1788251688777
2125 }, 2138 },
2126 { 2139 {
2127 "id": "677941e683c4", 2140 "id": "677941e683c4",
@@ -2136,7 +2149,7 @@ @@ -2136,7 +2149,7 @@
2136 "likes": 0, 2149 "likes": 0,
2137 "createdAt": 1787999633745, 2150 "createdAt": 1787999633745,
2138 "promptEn": "facing Sakazuki, went in head-on and got seen through", 2151 "promptEn": "facing Sakazuki, went in head-on and got seen through",
2139 - "lastPlayedAt": 1788241280859 2152 + "lastPlayedAt": 1788251912902
2140 }, 2153 },
2141 { 2154 {
2142 "id": "932d15f7f8bd", 2155 "id": "932d15f7f8bd",
@@ -2151,7 +2164,7 @@ @@ -2151,7 +2164,7 @@
2151 "likes": 0, 2164 "likes": 0,
2152 "createdAt": 1787999633670, 2165 "createdAt": 1787999633670,
2153 "promptEn": "facing Sakazuki, went in head-on and got seen through", 2166 "promptEn": "facing Sakazuki, went in head-on and got seen through",
2154 - "lastPlayedAt": 1788248228749 2167 + "lastPlayedAt": 1788251129144
2155 }, 2168 },
2156 { 2169 {
2157 "id": "a8b8b4430ee3", 2170 "id": "a8b8b4430ee3",
@@ -2166,7 +2179,7 @@ @@ -2166,7 +2179,7 @@
2166 "likes": 0, 2179 "likes": 0,
2167 "createdAt": 1787999397097, 2180 "createdAt": 1787999397097,
2168 "promptEn": "facing Sakazuki, stayed passive and got cornered", 2181 "promptEn": "facing Sakazuki, stayed passive and got cornered",
2169 - "lastPlayedAt": 1788245170174 2182 + "lastPlayedAt": 1788252397128
2170 }, 2183 },
2171 { 2184 {
2172 "id": "88923aaf57f3", 2185 "id": "88923aaf57f3",
@@ -2181,7 +2194,7 @@ @@ -2181,7 +2194,7 @@
2181 "likes": 0, 2194 "likes": 0,
2182 "createdAt": 1787999161013, 2195 "createdAt": 1787999161013,
2183 "promptEn": "execution platform at Marineford, Ace about to be executed, navy vs pirates", 2196 "promptEn": "execution platform at Marineford, Ace about to be executed, navy vs pirates",
2184 - "lastPlayedAt": 1788242772136 2197 + "lastPlayedAt": 1788253025350
2185 }, 2198 },
2186 { 2199 {
2187 "id": "00476b62bf75", 2200 "id": "00476b62bf75",
@@ -2196,7 +2209,7 @@ @@ -2196,7 +2209,7 @@
2196 "likes": 0, 2209 "likes": 0,
2197 "createdAt": 1787903583872, 2210 "createdAt": 1787903583872,
2198 "promptEn": "constable asks if she's always been alone here, she doesn't answer", 2211 "promptEn": "constable asks if she's always been alone here, she doesn't answer",
2199 - "lastPlayedAt": 1788249399541 2212 + "lastPlayedAt": 1788253047365
2200 }, 2213 },
2201 { 2214 {
2202 "id": "2ab2094e5679", 2215 "id": "2ab2094e5679",
@@ -2211,7 +2224,7 @@ @@ -2211,7 +2224,7 @@
2211 "likes": 0, 2224 "likes": 0,
2212 "createdAt": 1787900324972, 2225 "createdAt": 1787900324972,
2213 "promptEn": "constable declines a drink, asks what this place is, she watches him through the screen", 2226 "promptEn": "constable declines a drink, asks what this place is, she watches him through the screen",
2214 - "lastPlayedAt": 1788248246767 2227 + "lastPlayedAt": 1788252709206
2215 }, 2228 },
2216 { 2229 {
2217 "id": "43ee5c728f1b", 2230 "id": "43ee5c728f1b",
@@ -2226,7 +2239,7 @@ @@ -2226,7 +2239,7 @@
2226 "likes": 0, 2239 "likes": 0,
2227 "createdAt": 1787850191899, 2240 "createdAt": 1787850191899,
2228 "promptEn": "constable reaches out to touch her hand through the screen gap, no response", 2241 "promptEn": "constable reaches out to touch her hand through the screen gap, no response",
2229 - "lastPlayedAt": 1788246881603 2242 + "lastPlayedAt": 1788251708784
2230 }, 2243 },
2231 { 2244 {
2232 "id": "9bd8c9fbf1f6", 2245 "id": "9bd8c9fbf1f6",
@@ -2241,7 +2254,7 @@ @@ -2241,7 +2254,7 @@
2241 "likes": 0, 2254 "likes": 0,
2242 "createdAt": 1787847447661, 2255 "createdAt": 1787847447661,
2243 "promptEn": "constable tells the woman behind the screen he'll trust her tonight", 2256 "promptEn": "constable tells the woman behind the screen he'll trust her tonight",
2244 - "lastPlayedAt": 1788247912475 2257 + "lastPlayedAt": 1788250278003
2245 }, 2258 },
2246 { 2259 {
2247 "id": "8cb493338cb3", 2260 "id": "8cb493338cb3",
@@ -2256,7 +2269,7 @@ @@ -2256,7 +2269,7 @@
2256 "likes": 0, 2269 "likes": 0,
2257 "createdAt": 1787831362083, 2270 "createdAt": 1787831362083,
2258 "promptEn": "constable promises to get her out safely if she trusts him", 2271 "promptEn": "constable promises to get her out safely if she trusts him",
2259 - "lastPlayedAt": 1788248697169 2272 + "lastPlayedAt": 1788251652757
2260 }, 2273 },
2261 { 2274 {
2262 "id": "5ede61c01b22", 2275 "id": "5ede61c01b22",
@@ -2286,7 +2299,7 @@ @@ -2286,7 +2299,7 @@
2286 "likes": 0, 2299 "likes": 0,
2287 "createdAt": 1787762332289, 2300 "createdAt": 1787762332289,
2288 "promptEn": "woman behind the screen stirs and softly reassures him", 2301 "promptEn": "woman behind the screen stirs and softly reassures him",
2289 - "lastPlayedAt": 1788248214738 2302 + "lastPlayedAt": 1788251932913
2290 }, 2303 },
2291 { 2304 {
2292 "id": "0abf6e529c92", 2305 "id": "0abf6e529c92",
@@ -2301,7 +2314,7 @@ @@ -2301,7 +2314,7 @@
2301 "likes": 0, 2314 "likes": 0,
2302 "createdAt": 1787762311804, 2315 "createdAt": 1787762311804,
2303 "promptEn": "constable sits with a cup of water, slowly looking up at the woman behind the screen", 2316 "promptEn": "constable sits with a cup of water, slowly looking up at the woman behind the screen",
2304 - "lastPlayedAt": 1788250038963 2317 + "lastPlayedAt": 1788251410573
2305 }, 2318 },
2306 { 2319 {
2307 "id": "850f13881576", 2320 "id": "850f13881576",
@@ -2316,7 +2329,7 @@ @@ -2316,7 +2329,7 @@
2316 "likes": 0, 2329 "likes": 0,
2317 "createdAt": 1787762286261, 2330 "createdAt": 1787762286261,
2318 "promptEn": "constable stares at her through the screen, silent, saying nothing", 2331 "promptEn": "constable stares at her through the screen, silent, saying nothing",
2319 - "lastPlayedAt": 1788248262778 2332 + "lastPlayedAt": 1788251618745
2320 }, 2333 },
2321 { 2334 {
2322 "id": "59711a102e84", 2335 "id": "59711a102e84",
@@ -2331,7 +2344,7 @@ @@ -2331,7 +2344,7 @@
2331 "likes": 0, 2344 "likes": 0,
2332 "createdAt": 1787762224218, 2345 "createdAt": 1787762224218,
2333 "promptEn": "constable stands under the lamp, holding her gaze through the screen, not backing away", 2346 "promptEn": "constable stands under the lamp, holding her gaze through the screen, not backing away",
2334 - "lastPlayedAt": 1788249041367 2347 + "lastPlayedAt": 1788252377122
2335 }, 2348 },
2336 { 2349 {
2337 "id": "f2e70205766b", 2350 "id": "f2e70205766b",
@@ -2346,7 +2359,7 @@ @@ -2346,7 +2359,7 @@
2346 "likes": 0, 2359 "likes": 0,
2347 "createdAt": 1787738044140, 2360 "createdAt": 1787738044140,
2348 "promptEn": "constable carefully checks the door and window latches, she watches from behind the screen", 2361 "promptEn": "constable carefully checks the door and window latches, she watches from behind the screen",
2349 - "lastPlayedAt": 1788245190190 2362 + "lastPlayedAt": 1788252857278
2350 }, 2363 },
2351 { 2364 {
2352 "id": "cfbef6e37ae4", 2365 "id": "cfbef6e37ae4",
@@ -2361,7 +2374,7 @@ @@ -2361,7 +2374,7 @@
2361 "likes": 0, 2374 "likes": 0,
2362 "createdAt": 1787730413689, 2375 "createdAt": 1787730413689,
2363 "promptEn": "constable grabs the oil lamp and hurls it at the portrait, the scroll catches fire", 2376 "promptEn": "constable grabs the oil lamp and hurls it at the portrait, the scroll catches fire",
2364 - "lastPlayedAt": 1788249473574 2377 + "lastPlayedAt": 1788251572712
2365 }, 2378 },
2366 { 2379 {
2367 "id": "e6c23c6adc42", 2380 "id": "e6c23c6adc42",
@@ -2376,7 +2389,7 @@ @@ -2376,7 +2389,7 @@
2376 "likes": 0, 2389 "likes": 0,
2377 "createdAt": 1787730331754, 2390 "createdAt": 1787730331754,
2378 "promptEn": "constable steps in from the rainy night, spots her, introduces himself with a cover story", 2391 "promptEn": "constable steps in from the rainy night, spots her, introduces himself with a cover story",
2379 - "lastPlayedAt": 1788247554188 2392 + "lastPlayedAt": 1788250400085
2380 }, 2393 },
2381 { 2394 {
2382 "id": "d720d52c783f", 2395 "id": "d720d52c783f",
@@ -2406,7 +2419,7 @@ @@ -2406,7 +2419,7 @@
2406 "likes": 0, 2419 "likes": 0,
2407 "createdAt": 1787724313620, 2420 "createdAt": 1787724313620,
2408 "promptEn": "first-person view bursting into the room, glancing back in fear, the woman startled", 2421 "promptEn": "first-person view bursting into the room, glancing back in fear, the woman startled",
2409 - "lastPlayedAt": 1788249869811 2422 + "lastPlayedAt": 1788252843270
2410 }, 2423 },
2411 { 2424 {
2412 "id": "81b6c3789111", 2425 "id": "81b6c3789111",
@@ -2421,7 +2434,7 @@ @@ -2421,7 +2434,7 @@
2421 "likes": 0, 2434 "likes": 0,
2422 "createdAt": 1787708713767, 2435 "createdAt": 1787708713767,
2423 "promptEn": "constable stops looking around, turns to face the screen, speaks to her silhouette", 2436 "promptEn": "constable stops looking around, turns to face the screen, speaks to her silhouette",
2424 - "lastPlayedAt": 1788245738674 2437 + "lastPlayedAt": 1788252811258
2425 }, 2438 },
2426 { 2439 {
2427 "id": "5dc95a15cd5d", 2440 "id": "5dc95a15cd5d",
@@ -2436,7 +2449,7 @@ @@ -2436,7 +2449,7 @@
2436 "likes": 0, 2449 "likes": 0,
2437 "createdAt": 1787708701547, 2450 "createdAt": 1787708701547,
2438 "promptEn": "constable gently tells her he'll stay and keep her company", 2451 "promptEn": "constable gently tells her he'll stay and keep her company",
2439 - "lastPlayedAt": 1788245988880 2452 + "lastPlayedAt": 1788252873286
2440 }, 2453 },
2441 { 2454 {
2442 "id": "8d9c1dad041f", 2455 "id": "8d9c1dad041f",
@@ -2466,7 +2479,7 @@ @@ -2466,7 +2479,7 @@
2466 "likes": 0, 2479 "likes": 0,
2467 "createdAt": 1787708684658, 2480 "createdAt": 1787708684658,
2468 "promptEn": "constable sees her silent gesture, lets go of his sword hilt, steps closer and agrees", 2481 "promptEn": "constable sees her silent gesture, lets go of his sword hilt, steps closer and agrees",
2469 - "lastPlayedAt": 1788246805543 2482 + "lastPlayedAt": 1788251970926
2470 }, 2483 },
2471 { 2484 {
2472 "id": "abdbe25f3121", 2485 "id": "abdbe25f3121",
@@ -2481,7 +2494,7 @@ @@ -2481,7 +2494,7 @@
2481 "likes": 0, 2494 "likes": 0,
2482 "createdAt": 1787708674508, 2495 "createdAt": 1787708674508,
2483 "promptEn": "constable sees through her painted disguise and rips her face off, revealing a demonic visage underneath", 2496 "promptEn": "constable sees through her painted disguise and rips her face off, revealing a demonic visage underneath",
2484 - "lastPlayedAt": 1788248903320 2497 + "lastPlayedAt": 1788252661239
2485 }, 2498 },
2486 { 2499 {
2487 "id": "6d433dcc104c", 2500 "id": "6d433dcc104c",
@@ -2496,7 +2509,7 @@ @@ -2496,7 +2509,7 @@
2496 "likes": 0, 2509 "likes": 0,
2497 "createdAt": 1787708663418, 2510 "createdAt": 1787708663418,
2498 "promptEn": "constable catches his breath, thanks her, and rests on the couch while she watches", 2511 "promptEn": "constable catches his breath, thanks her, and rests on the couch while she watches",
2499 - "lastPlayedAt": 1788245906827 2512 + "lastPlayedAt": 1788250466114
2500 }, 2513 },
2501 { 2514 {
2502 "id": "cd22c2b491fc", 2515 "id": "cd22c2b491fc",
@@ -2511,7 +2524,7 @@ @@ -2511,7 +2524,7 @@
2511 "likes": 0, 2524 "likes": 0,
2512 "createdAt": 1787708653181, 2525 "createdAt": 1787708653181,
2513 "promptEn": "constable holds her gaze, quietly says \"go on\", then waits in silence", 2526 "promptEn": "constable holds her gaze, quietly says \"go on\", then waits in silence",
2514 - "lastPlayedAt": 1788249737695 2527 + "lastPlayedAt": 1788251130405
2515 }, 2528 },
2516 { 2529 {
2517 "id": "55f98ceec9e4", 2530 "id": "55f98ceec9e4",
@@ -2526,7 +2539,7 @@ @@ -2526,7 +2539,7 @@
2526 "likes": 0, 2539 "likes": 0,
2527 "createdAt": 1787708648409, 2540 "createdAt": 1787708648409,
2528 "promptEn": "she reaches a hand through the screen gap beckoning him, he steps back and firmly refuses", 2541 "promptEn": "she reaches a hand through the screen gap beckoning him, he steps back and firmly refuses",
2529 - "lastPlayedAt": 1788248366872 2542 + "lastPlayedAt": 1788251828861
2530 }, 2543 },
2531 { 2544 {
2532 "id": "3f0c28f5373a", 2545 "id": "3f0c28f5373a",
@@ -2541,7 +2554,7 @@ @@ -2541,7 +2554,7 @@
2541 "likes": 0, 2554 "likes": 0,
2542 "createdAt": 1787708646888, 2555 "createdAt": 1787708646888,
2543 "promptEn": "constable studies her through the screen growing suspicious, hand drifting to his sword", 2556 "promptEn": "constable studies her through the screen growing suspicious, hand drifting to his sword",
2544 - "lastPlayedAt": 1788249453571 2557 + "lastPlayedAt": 1788251602734
2545 }, 2558 },
2546 { 2559 {
2547 "id": "1c0c203cfb3b", 2560 "id": "1c0c203cfb3b",
@@ -2556,7 +2569,7 @@ @@ -2556,7 +2569,7 @@
2556 "likes": 0, 2569 "likes": 0,
2557 "createdAt": 1787708641782, 2570 "createdAt": 1787708641782,
2558 "promptEn": "constable sits down at the table, studying her expression through the screen", 2571 "promptEn": "constable sits down at the table, studying her expression through the screen",
2559 - "lastPlayedAt": 1788249369530 2572 + "lastPlayedAt": 1788252435140
2560 }, 2573 },
2561 { 2574 {
2562 "id": "89975be9def4", 2575 "id": "89975be9def4",
@@ -2571,7 +2584,7 @@ @@ -2571,7 +2584,7 @@
2571 "likes": 0, 2584 "likes": 0,
2572 "createdAt": 1787708626228, 2585 "createdAt": 1787708626228,
2573 "promptEn": "constable drinks some water first, thanks her, watching the screen warily as he drinks", 2586 "promptEn": "constable drinks some water first, thanks her, watching the screen warily as he drinks",
2574 - "lastPlayedAt": 1788249247478 2587 + "lastPlayedAt": 1788251160420
2575 }, 2588 },
2576 { 2589 {
2577 "id": "e08f7f7e54dd", 2590 "id": "e08f7f7e54dd",
@@ -2586,7 +2599,7 @@ @@ -2586,7 +2599,7 @@
2586 "likes": 0, 2599 "likes": 0,
2587 "createdAt": 1787708622306, 2600 "createdAt": 1787708622306,
2588 "promptEn": "constable gives a clasped-hand salute and thanks her, she gives a subtle nod", 2601 "promptEn": "constable gives a clasped-hand salute and thanks her, she gives a subtle nod",
2589 - "lastPlayedAt": 1788242193644 2602 + "lastPlayedAt": 1788250263997
2590 }, 2603 },
2591 { 2604 {
2592 "id": "538dc7e5746f", 2605 "id": "538dc7e5746f",
@@ -2601,7 +2614,7 @@ @@ -2601,7 +2614,7 @@
2601 "likes": 0, 2614 "likes": 0,
2602 "createdAt": 1787708622178, 2615 "createdAt": 1787708622178,
2603 "promptEn": "constable gives a clasped-hand salute and thanks her, she gives a subtle nod", 2616 "promptEn": "constable gives a clasped-hand salute and thanks her, she gives a subtle nod",
2604 - "lastPlayedAt": 1788247151819 2617 + "lastPlayedAt": 1788253057370
2605 }, 2618 },
2606 { 2619 {
2607 "id": "1721c75dbc3b", 2620 "id": "1721c75dbc3b",
@@ -2616,7 +2629,7 @@ @@ -2616,7 +2629,7 @@
2616 "likes": 0, 2629 "likes": 0,
2617 "createdAt": 1787708615415, 2630 "createdAt": 1787708615415,
2618 "promptEn": "she slides her hand through the screen gap asking him to warm it, he hesitates without touching", 2631 "promptEn": "she slides her hand through the screen gap asking him to warm it, he hesitates without touching",
2619 - "lastPlayedAt": 1788246669438 2632 + "lastPlayedAt": 1788252911303
2620 }, 2633 },
2621 { 2634 {
2622 "id": "c2b145b111e2", 2635 "id": "c2b145b111e2",
@@ -2631,7 +2644,7 @@ @@ -2631,7 +2644,7 @@
2631 "likes": 0, 2644 "likes": 0,
2632 "createdAt": 1787708613364, 2645 "createdAt": 1787708613364,
2633 "promptEn": "constable steps in, notices her behind the screen, greets her, she just watches silently", 2646 "promptEn": "constable steps in, notices her behind the screen, greets her, she just watches silently",
2634 - "lastPlayedAt": 1788248681145 2647 + "lastPlayedAt": 1788252945316
2635 }, 2648 },
2636 { 2649 {
2637 "id": "a5d5d353bbf8", 2650 "id": "a5d5d353bbf8",
@@ -2646,7 +2659,7 @@ @@ -2646,7 +2659,7 @@
2646 "likes": 0, 2659 "likes": 0,
2647 "createdAt": 1787674768144, 2660 "createdAt": 1787674768144,
2648 "promptEn": "constable lifts a bronze mirror, reflecting candlelight onto the portrait on the wall", 2661 "promptEn": "constable lifts a bronze mirror, reflecting candlelight onto the portrait on the wall",
2649 - "lastPlayedAt": 1788249403540 2662 + "lastPlayedAt": 1788251856874
2650 }, 2663 },
2651 { 2664 {
2652 "id": "3be1f275fde2", 2665 "id": "3be1f275fde2",
@@ -2661,7 +2674,7 @@ @@ -2661,7 +2674,7 @@
2661 "likes": 0, 2674 "likes": 0,
2662 "createdAt": 1787674743188, 2675 "createdAt": 1787674743188,
2663 "promptEn": "constable draws his sword and breaks the sealed talisman on the screen, revealing her behind it", 2676 "promptEn": "constable draws his sword and breaks the sealed talisman on the screen, revealing her behind it",
2664 - "lastPlayedAt": 1788249643649 2677 + "lastPlayedAt": 1788252539184
2665 }, 2678 },
2666 { 2679 {
2667 "id": "693e0b9ca66a", 2680 "id": "693e0b9ca66a",
@@ -2691,7 +2704,7 @@ @@ -2691,7 +2704,7 @@
2691 "likes": 0, 2704 "likes": 0,
2692 "createdAt": 1787674716075, 2705 "createdAt": 1787674716075,
2693 "promptEn": "constable watches the oil lamp flame flicker, her silhouette motionless behind the screen", 2706 "promptEn": "constable watches the oil lamp flame flicker, her silhouette motionless behind the screen",
2694 - "lastPlayedAt": 1788246721475 2707 + "lastPlayedAt": 1788251352521
2695 }, 2708 },
2696 { 2709 {
2697 "id": "23d1ae1982e6", 2710 "id": "23d1ae1982e6",
@@ -2706,7 +2719,7 @@ @@ -2706,7 +2719,7 @@
2706 "likes": 0, 2719 "likes": 0,
2707 "createdAt": 1787674713724, 2720 "createdAt": 1787674713724,
2708 "promptEn": "constable enters and cautiously looks around, his gaze settling on her silhouette behind the screen", 2721 "promptEn": "constable enters and cautiously looks around, his gaze settling on her silhouette behind the screen",
2709 - "lastPlayedAt": 1788249347518 2722 + "lastPlayedAt": 1788252056963
2710 }, 2723 },
2711 { 2724 {
2712 "id": "b69389094416", 2725 "id": "b69389094416",
@@ -2721,7 +2734,7 @@ @@ -2721,7 +2734,7 @@
2721 "likes": 0, 2734 "likes": 0,
2722 "createdAt": 1787674695703, 2735 "createdAt": 1787674695703,
2723 "promptEn": "constable stops, faces the screen, quietly promises to keep his voice down", 2736 "promptEn": "constable stops, faces the screen, quietly promises to keep his voice down",
2724 - "lastPlayedAt": 1788250023879 2737 + "lastPlayedAt": 1788252743222
2725 }, 2738 },
2726 { 2739 {
2727 "id": "94dc455e26bf", 2740 "id": "94dc455e26bf",
@@ -2736,7 +2749,7 @@ @@ -2736,7 +2749,7 @@
2736 "likes": 0, 2749 "likes": 0,
2737 "createdAt": 1787674688717, 2750 "createdAt": 1787674688717,
2738 "promptEn": "constable agrees to stay, lets his guard down, she gives a barely-there nod", 2751 "promptEn": "constable agrees to stay, lets his guard down, she gives a barely-there nod",
2739 - "lastPlayedAt": 1788248320834 2752 + "lastPlayedAt": 1788250832261
2740 }, 2753 },
2741 { 2754 {
2742 "id": "4874fe3fdbc9", 2755 "id": "4874fe3fdbc9",
@@ -2781,7 +2794,7 @@ @@ -2781,7 +2794,7 @@
2781 "likes": 0, 2794 "likes": 0,
2782 "createdAt": 1787674642026, 2795 "createdAt": 1787674642026,
2783 "promptEn": "constable enters from the side and sits down on a stool by the lamp to rest", 2796 "promptEn": "constable enters from the side and sits down on a stool by the lamp to rest",
2784 - "lastPlayedAt": 1788247574201 2797 + "lastPlayedAt": 1788251330505
2785 }, 2798 },
2786 { 2799 {
2787 "id": "fe7ffbe65653", 2800 "id": "fe7ffbe65653",
@@ -2796,7 +2809,7 @@ @@ -2796,7 +2809,7 @@
2796 "likes": 0, 2809 "likes": 0,
2797 "createdAt": 1787674639055, 2810 "createdAt": 1787674639055,
2798 "promptEn": "constable checks his reflection in the mirror, sees her behind his shoulder in it, turns around to find the screen empty", 2811 "promptEn": "constable checks his reflection in the mirror, sees her behind his shoulder in it, turns around to find the screen empty",
2799 - "lastPlayedAt": 1788249777714 2812 + "lastPlayedAt": 1788253073377
2800 }, 2813 },
2801 { 2814 {
2802 "id": "ebaf0dde3d9f", 2815 "id": "ebaf0dde3d9f",
@@ -2811,7 +2824,7 @@ @@ -2811,7 +2824,7 @@
2811 "likes": 0, 2824 "likes": 0,
2812 "createdAt": 1787674623678, 2825 "createdAt": 1787674623678,
2813 "promptEn": "constable bows to the screen, thanking her for sheltering him", 2826 "promptEn": "constable bows to the screen, thanking her for sheltering him",
2814 - "lastPlayedAt": 1788248150683 2827 + "lastPlayedAt": 1788251144418
2815 }, 2828 },
2816 { 2829 {
2817 "id": "d94991a1e21b", 2830 "id": "d94991a1e21b",
@@ -2841,7 +2854,7 @@ @@ -2841,7 +2854,7 @@
2841 "likes": 0, 2854 "likes": 0,
2842 "createdAt": 1787674446841, 2855 "createdAt": 1787674446841,
2843 "promptEn": "player panics into the room, glances back, out of breath, says something's chasing him outside", 2856 "promptEn": "player panics into the room, glances back, out of breath, says something's chasing him outside",
2844 - "lastPlayedAt": 1788247932497 2857 + "lastPlayedAt": 1788250856275
2845 }, 2858 },
2846 { 2859 {
2847 "id": "c25d53a5e086", 2860 "id": "c25d53a5e086",
@@ -2856,7 +2869,7 @@ @@ -2856,7 +2869,7 @@
2856 "likes": 0, 2869 "likes": 0,
2857 "createdAt": 1787674395006, 2870 "createdAt": 1787674395006,
2858 "promptEn": "constable and the woman hold a tense silent stare through the screen", 2871 "promptEn": "constable and the woman hold a tense silent stare through the screen",
2859 - "lastPlayedAt": 1788248761225 2872 + "lastPlayedAt": 1788252897296
2860 }, 2873 },
2861 { 2874 {
2862 "id": "f264bce22903", 2875 "id": "f264bce22903",
@@ -2871,7 +2884,7 @@ @@ -2871,7 +2884,7 @@
2871 "likes": 0, 2884 "likes": 0,
2872 "createdAt": 1787674361187, 2885 "createdAt": 1787674361187,
2873 "promptEn": "constable presses his hand to his chest, vowing his heart to her, she gives a knowing smile", 2886 "promptEn": "constable presses his hand to his chest, vowing his heart to her, she gives a knowing smile",
2874 - "lastPlayedAt": 1788247321970 2887 + "lastPlayedAt": 1788252451148
2875 }, 2888 },
2876 { 2889 {
2877 "id": "8aba0a6bf05b", 2890 "id": "8aba0a6bf05b",
@@ -2886,7 +2899,7 @@ @@ -2886,7 +2899,7 @@
2886 "likes": 0, 2899 "likes": 0,
2887 "createdAt": 1787674351536, 2900 "createdAt": 1787674351536,
2888 "promptEn": "constable searches an old house at night, candle flickering, woman hiding behind the screen", 2901 "promptEn": "constable searches an old house at night, candle flickering, woman hiding behind the screen",
2889 - "lastPlayedAt": 1788246491297 2902 + "lastPlayedAt": 1788250201967
2890 }, 2903 },
2891 { 2904 {
2892 "id": "dc13e4f165dc", 2905 "id": "dc13e4f165dc",
@@ -2901,7 +2914,7 @@ @@ -2901,7 +2914,7 @@
2901 "likes": 0, 2914 "likes": 0,
2902 "createdAt": 1787672849330, 2915 "createdAt": 1787672849330,
2903 "promptEn": "constable cautiously follows her silent gesture, hand near his sword, tracking her movement", 2916 "promptEn": "constable cautiously follows her silent gesture, hand near his sword, tracking her movement",
2904 - "lastPlayedAt": 1788245314287 2917 + "lastPlayedAt": 1788252175018
2905 }, 2918 },
2906 { 2919 {
2907 "id": "feb4df69e1a2", 2920 "id": "feb4df69e1a2",
@@ -2916,7 +2929,7 @@ @@ -2916,7 +2929,7 @@
2916 "likes": 0, 2929 "likes": 0,
2917 "createdAt": 1787665100787, 2930 "createdAt": 1787665100787,
2918 "promptEn": "constable politely asks the woman behind the screen for tea", 2931 "promptEn": "constable politely asks the woman behind the screen for tea",
2919 - "lastPlayedAt": 1788246062936 2932 + "lastPlayedAt": 1788250618187
2920 }, 2933 },
2921 { 2934 {
2922 "id": "d2c77b87b84b", 2935 "id": "d2c77b87b84b",
@@ -2930,7 +2943,7 @@ @@ -2930,7 +2943,7 @@
2930 "partition": "ref2va", 2943 "partition": "ref2va",
2931 "likes": 0, 2944 "likes": 0,
2932 "createdAt": 1787652321725, 2945 "createdAt": 1787652321725,
2933 - "lastPlayedAt": 1788246485298, 2946 + "lastPlayedAt": 1788250646200,
2934 "promptEn": "constable talking to the woman through the screen" 2947 "promptEn": "constable talking to the woman through the screen"
2935 }, 2948 },
2936 { 2949 {
@@ -2961,7 +2974,7 @@ @@ -2961,7 +2974,7 @@
2961 "likes": 0, 2974 "likes": 0,
2962 "createdAt": 1787640567001, 2975 "createdAt": 1787640567001,
2963 "promptEn": "summoned toad Wentai, beat the painted-skin female ghost", 2976 "promptEn": "summoned toad Wentai, beat the painted-skin female ghost",
2964 - "lastPlayedAt": 1788249437562 2977 + "lastPlayedAt": 1788252685196
2965 }, 2978 },
2966 { 2979 {
2967 "id": "1cc42a8669a1", 2980 "id": "1cc42a8669a1",
@@ -2975,7 +2988,7 @@ @@ -2975,7 +2988,7 @@
2975 "partition": "ref2va", 2988 "partition": "ref2va",
2976 "likes": 0, 2989 "likes": 0,
2977 "createdAt": 1787639957338, 2990 "createdAt": 1787639957338,
2978 - "lastPlayedAt": 1788248897311, 2991 + "lastPlayedAt": 1788251344514,
2979 "promptEn": "constable talking to the woman through the screen" 2992 "promptEn": "constable talking to the woman through the screen"
2980 }, 2993 },
2981 { 2994 {
@@ -2991,7 +3004,7 @@ @@ -2991,7 +3004,7 @@
2991 "likes": 0, 3004 "likes": 0,
2992 "createdAt": 1787637292741, 3005 "createdAt": 1787637292741,
2993 "promptEn": "constable bursts in panicked, spots the woman behind the screen", 3006 "promptEn": "constable bursts in panicked, spots the woman behind the screen",
2994 - "lastPlayedAt": 1788248346857 3007 + "lastPlayedAt": 1788251872881
2995 }, 3008 },
2996 { 3009 {
2997 "id": "93c2b84a2a10", 3010 "id": "93c2b84a2a10",
@@ -3006,7 +3019,7 @@ @@ -3006,7 +3019,7 @@
3006 "likes": 0, 3019 "likes": 0,
3007 "createdAt": 1787635935502, 3020 "createdAt": 1787635935502,
3008 "promptEn": "constable bursts in panicked, spots the woman behind the screen", 3021 "promptEn": "constable bursts in panicked, spots the woman behind the screen",
3009 - "lastPlayedAt": 1788246137001 3022 + "lastPlayedAt": 1788250520137
3010 }, 3023 },
3011 { 3024 {
3012 "id": "b32769bf80db", 3025 "id": "b32769bf80db",
@@ -3021,7 +3034,7 @@ @@ -3021,7 +3034,7 @@
3021 "likes": 0, 3034 "likes": 0,
3022 "createdAt": 1787632587351, 3035 "createdAt": 1787632587351,
3023 "promptEn": "constable bursts in panicked, spots the woman behind the screen", 3036 "promptEn": "constable bursts in panicked, spots the woman behind the screen",
3024 - "lastPlayedAt": 1788248791245 3037 + "lastPlayedAt": 1788250612184
3025 }, 3038 },
3026 { 3039 {
3027 "id": "282281777d1b", 3040 "id": "282281777d1b",
@@ -3036,7 +3049,7 @@ @@ -3036,7 +3049,7 @@
3036 "likes": 0, 3049 "likes": 0,
3037 "createdAt": 1787615243753, 3050 "createdAt": 1787615243753,
3038 "promptEn": "robot arm picks up a red block and puts it down", 3051 "promptEn": "robot arm picks up a red block and puts it down",
3039 - "lastPlayedAt": 1788249857808 3052 + "lastPlayedAt": 1788251258468
3040 }, 3053 },
3041 { 3054 {
3042 "id": "d040eec16a88", 3055 "id": "d040eec16a88",
@@ -3051,7 +3064,7 @@ @@ -3051,7 +3064,7 @@
3051 "likes": 0, 3064 "likes": 0,
3052 "createdAt": 1787615242602, 3065 "createdAt": 1787615242602,
3053 "promptEn": "otome game male lead showcase PV", 3066 "promptEn": "otome game male lead showcase PV",
3054 - "lastPlayedAt": 1788249753702 3067 + "lastPlayedAt": 1788251108401
3055 }, 3068 },
3056 { 3069 {
3057 "id": "423a20afba5a", 3070 "id": "423a20afba5a",
@@ -3066,7 +3079,7 @@ @@ -3066,7 +3079,7 @@
3066 "likes": 0, 3079 "likes": 0,
3067 "createdAt": 1787615241814, 3080 "createdAt": 1787615241814,
3068 "promptEn": "xianxia character turning, only back and side profile shown", 3081 "promptEn": "xianxia character turning, only back and side profile shown",
3069 - "lastPlayedAt": 1788247390027 3082 + "lastPlayedAt": 1788250526137
3070 }, 3083 },
3071 { 3084 {
3072 "id": "1a398591663e", 3085 "id": "1a398591663e",
@@ -3081,7 +3094,7 @@ @@ -3081,7 +3094,7 @@
3081 "likes": 0, 3094 "likes": 0,
3082 "createdAt": 1787615240988, 3095 "createdAt": 1787615240988,
3083 "promptEn": "clay fox sprints off a cliff, slow-mo leap over the canyon", 3096 "promptEn": "clay fox sprints off a cliff, slow-mo leap over the canyon",
3084 - "lastPlayedAt": 1788249951846 3097 + "lastPlayedAt": 1788251894893
3085 }, 3098 },
3086 { 3099 {
3087 "id": "db125dc6a831", 3100 "id": "db125dc6a831",
@@ -3095,7 +3108,7 @@ @@ -3095,7 +3108,7 @@
3095 "partition": "text", 3108 "partition": "text",
3096 "likes": 0, 3109 "likes": 0,
3097 "createdAt": 1787615240199, 3110 "createdAt": 1787615240199,
3098 - "lastPlayedAt": 1788244934012, 3111 + "lastPlayedAt": 1788251786843,
3099 "promptEn": "website UI title slides in, car light fades to red" 3112 "promptEn": "website UI title slides in, car light fades to red"
3100 }, 3113 },
3101 { 3114 {
@@ -3111,7 +3124,7 @@ @@ -3111,7 +3124,7 @@
3111 "likes": 0, 3124 "likes": 0,
3112 "createdAt": 1787588547172, 3125 "createdAt": 1787588547172,
3113 "promptEn": "product website scrolling down with flashy effects", 3126 "promptEn": "product website scrolling down with flashy effects",
3114 - "lastPlayedAt": 1788248841279 3127 + "lastPlayedAt": 1788251228453
3115 }, 3128 },
3116 { 3129 {
3117 "id": "2e18bf09b46a", 3130 "id": "2e18bf09b46a",
@@ -3141,7 +3154,7 @@ @@ -3141,7 +3154,7 @@
3141 "likes": 0, 3154 "likes": 0,
3142 "createdAt": 1787588545243, 3155 "createdAt": 1787588545243,
3143 "promptEn": "ergonomic office chair 360 showcase ad", 3156 "promptEn": "ergonomic office chair 360 showcase ad",
3144 - "lastPlayedAt": 1788250058966 3157 + "lastPlayedAt": 1788253031360
3145 }, 3158 },
3146 { 3159 {
3147 "id": "b0d258352c3c", 3160 "id": "b0d258352c3c",
@@ -3171,7 +3184,7 @@ @@ -3171,7 +3184,7 @@
3171 "likes": 0, 3184 "likes": 0,
3172 "createdAt": 1787588544109, 3185 "createdAt": 1787588544109,
3173 "promptEn": "vampire romance drama trailer, girl wanders into the castle", 3186 "promptEn": "vampire romance drama trailer, girl wanders into the castle",
3174 - "lastPlayedAt": 1788248955338 3187 + "lastPlayedAt": 1788250187972
3175 }, 3188 },
3176 { 3189 {
3177 "id": "7ded7db676d3", 3190 "id": "7ded7db676d3",
@@ -3186,7 +3199,7 @@ @@ -3186,7 +3199,7 @@
3186 "likes": 0, 3199 "likes": 0,
3187 "createdAt": 1787588543551, 3200 "createdAt": 1787588543551,
3188 "promptEn": "MiniMax H3 tech brand film, blue waveform logo", 3201 "promptEn": "MiniMax H3 tech brand film, blue waveform logo",
3189 - "lastPlayedAt": 1788246819557 3202 + "lastPlayedAt": 1788250954321
3190 }, 3203 },
3191 { 3204 {
3192 "id": "81711242178d", 3205 "id": "81711242178d",
@@ -3201,7 +3214,7 @@ @@ -3201,7 +3214,7 @@
3201 "likes": 0, 3214 "likes": 0,
3202 "createdAt": 1787588542968, 3215 "createdAt": 1787588542968,
3203 "promptEn": "mystery crime title sequence, collage split-screen credits", 3216 "promptEn": "mystery crime title sequence, collage split-screen credits",
3204 - "lastPlayedAt": 1788247850421 3217 + "lastPlayedAt": 1788251444607
3205 }, 3218 },
3206 { 3219 {
3207 "id": "67ababbea78f", 3220 "id": "67ababbea78f",
@@ -3216,7 +3229,7 @@ @@ -3216,7 +3229,7 @@
3216 "likes": 0, 3229 "likes": 0,
3217 "createdAt": 1787588542426, 3230 "createdAt": 1787588542426,
3218 "promptEn": "fashion guy in sunglasses and coat by a fire", 3231 "promptEn": "fashion guy in sunglasses and coat by a fire",
3219 - "lastPlayedAt": 1788245774711 3232 + "lastPlayedAt": 1788250364064
3220 }, 3233 },
3221 { 3234 {
3222 "id": "c1237b599bf4", 3235 "id": "c1237b599bf4",
@@ -3231,7 +3244,7 @@ @@ -3231,7 +3244,7 @@
3231 "likes": 0, 3244 "likes": 0,
3232 "createdAt": 1787588541726, 3245 "createdAt": 1787588541726,
3233 "promptEn": "woman opens the trunk on a desert road, takes out a bag", 3246 "promptEn": "woman opens the trunk on a desert road, takes out a bag",
3234 - "lastPlayedAt": 1788250107920 3247 + "lastPlayedAt": 1788251984934
3235 }, 3248 },
3236 { 3249 {
3237 "id": "97846542ab09", 3250 "id": "97846542ab09",
@@ -3246,7 +3259,7 @@ @@ -3246,7 +3259,7 @@
3246 "likes": 0, 3259 "likes": 0,
3247 "createdAt": 1787588541164, 3260 "createdAt": 1787588541164,
3248 "promptEn": "tiny silhouette before a huge cosmic gate, title fades in", 3261 "promptEn": "tiny silhouette before a huge cosmic gate, title fades in",
3249 - "lastPlayedAt": 1788248234756 3262 + "lastPlayedAt": 1788252110986
3250 }, 3263 },
3251 { 3264 {
3252 "id": "5cc09dcdf470", 3265 "id": "5cc09dcdf470",
@@ -3261,7 +3274,7 @@ @@ -3261,7 +3274,7 @@
3261 "likes": 0, 3274 "likes": 0,
3262 "createdAt": 1787588540642, 3275 "createdAt": 1787588540642,
3263 "promptEn": "telescope view searching for a MiniMax device, fashionable passerby", 3276 "promptEn": "telescope view searching for a MiniMax device, fashionable passerby",
3264 - "lastPlayedAt": 1788248919321 3277 + "lastPlayedAt": 1788250804249
3265 }, 3278 },
3266 { 3279 {
3267 "id": "a59cae01ec39", 3280 "id": "a59cae01ec39",
@@ -3291,7 +3304,7 @@ @@ -3291,7 +3304,7 @@
3291 "likes": 0, 3304 "likes": 0,
3292 "createdAt": 1787588114381, 3305 "createdAt": 1787588114381,
3293 "promptEn": "underground rap duo freestyling at the camera", 3306 "promptEn": "underground rap duo freestyling at the camera",
3294 - "lastPlayedAt": 1788248935327 3307 + "lastPlayedAt": 1788251744817
3295 }, 3308 },
3296 { 3309 {
3297 "id": "58a439a93c02", 3310 "id": "58a439a93c02",
@@ -3306,7 +3319,7 @@ @@ -3306,7 +3319,7 @@
3306 "likes": 0, 3319 "likes": 0,
3307 "createdAt": 1787577878370, 3320 "createdAt": 1787577878370,
3308 "promptEn": "man barges into the old house apologizing, woman in white behind the screen", 3321 "promptEn": "man barges into the old house apologizing, woman in white behind the screen",
3309 - "lastPlayedAt": 1788245984875 3322 + "lastPlayedAt": 1788250294012
3310 }, 3323 },
3311 { 3324 {
3312 "id": "0e75ef71c3d0", 3325 "id": "0e75ef71c3d0",
@@ -3321,7 +3334,7 @@ @@ -3321,7 +3334,7 @@
3321 "likes": 0, 3334 "likes": 0,
3322 "createdAt": 1787577088842, 3335 "createdAt": 1787577088842,
3323 "promptEn": "man thanks the woman for taking him in, behind the screen", 3336 "promptEn": "man thanks the woman for taking him in, behind the screen",
3324 - "lastPlayedAt": 1788247530161 3337 + "lastPlayedAt": 1788252705203
3325 }, 3338 },
3326 { 3339 {
3327 "id": "e656777b6eef", 3340 "id": "e656777b6eef",
@@ -3336,7 +3349,7 @@ @@ -3336,7 +3349,7 @@
3336 "likes": 0, 3349 "likes": 0,
3337 "createdAt": 1787577088778, 3350 "createdAt": 1787577088778,
3338 "promptEn": "man thanks the woman for taking him in", 3351 "promptEn": "man thanks the woman for taking him in",
3339 - "lastPlayedAt": 1788246381212 3352 + "lastPlayedAt": 1788252149006
3340 }, 3353 },
3341 { 3354 {
3342 "id": "8d0270466c35", 3355 "id": "8d0270466c35",
@@ -3351,7 +3364,7 @@ @@ -3351,7 +3364,7 @@
3351 "likes": 0, 3364 "likes": 0,
3352 "createdAt": 1787576943673, 3365 "createdAt": 1787576943673,
3353 "promptEn": "man lowers his voice like she said, checks the door, window and lamp", 3366 "promptEn": "man lowers his voice like she said, checks the door, window and lamp",
3354 - "lastPlayedAt": 1788249077393 3367 + "lastPlayedAt": 1788251202953
3355 }, 3368 },
3356 { 3369 {
3357 "id": "396de15c1439", 3370 "id": "396de15c1439",
@@ -3381,7 +3394,7 @@ @@ -3381,7 +3394,7 @@
3381 "likes": 0, 3394 "likes": 0,
3382 "createdAt": 1787576798050, 3395 "createdAt": 1787576798050,
3383 "promptEn": "man says he's willing to give her his heart", 3396 "promptEn": "man says he's willing to give her his heart",
3384 - "lastPlayedAt": 1788245790726 3397 + "lastPlayedAt": 1788252199033
3385 }, 3398 },
3386 { 3399 {
3387 "id": "57f2c6fa351d", 3400 "id": "57f2c6fa351d",
@@ -3396,7 +3409,7 @@ @@ -3396,7 +3409,7 @@
3396 "likes": 0, 3409 "likes": 0,
3397 "createdAt": 1787576651668, 3410 "createdAt": 1787576651668,
3398 "promptEn": "man silently looks at her, doesn't respond", 3411 "promptEn": "man silently looks at her, doesn't respond",
3399 - "lastPlayedAt": 1788248969344 3412 + "lastPlayedAt": 1788251536684
3400 }, 3413 },
3401 { 3414 {
3402 "id": "5958b86ab8f4", 3415 "id": "5958b86ab8f4",
@@ -3486,7 +3499,7 @@ @@ -3486,7 +3499,7 @@
3486 "likes": 0, 3499 "likes": 0,
3487 "createdAt": 1787575164766, 3500 "createdAt": 1787575164766,
3488 "promptEn": "man apologizes, says something outside was chasing him", 3501 "promptEn": "man apologizes, says something outside was chasing him",
3489 - "lastPlayedAt": 1788248174703 3502 + "lastPlayedAt": 1788251998941
3490 }, 3503 },
3491 { 3504 {
3492 "id": "fb3000701384", 3505 "id": "fb3000701384",
@@ -3501,7 +3514,7 @@ @@ -3501,7 +3514,7 @@
3501 "likes": 0, 3514 "likes": 0,
3502 "createdAt": 1787573698485, 3515 "createdAt": 1787573698485,
3503 "promptEn": "underground rap duo freestyling at the camera", 3516 "promptEn": "underground rap duo freestyling at the camera",
3504 - "lastPlayedAt": 1788248190717 3517 + "lastPlayedAt": 1788252777241
3505 }, 3518 },
3506 { 3519 {
3507 "id": "e5246eae814e", 3520 "id": "e5246eae814e",
@@ -3516,7 +3529,7 @@ @@ -3516,7 +3529,7 @@
3516 "likes": 0, 3529 "likes": 0,
3517 "createdAt": 1787569314178, 3530 "createdAt": 1787569314178,
3518 "promptEn": "man apologizes, says something outside was chasing him", 3531 "promptEn": "man apologizes, says something outside was chasing him",
3519 - "lastPlayedAt": 1788247634250 3532 + "lastPlayedAt": 1788252793246
3520 }, 3533 },
3521 { 3534 {
3522 "id": "a0d7a106b8d6", 3535 "id": "a0d7a106b8d6",
@@ -3530,7 +3543,7 @@ @@ -3530,7 +3543,7 @@
3530 "partition": "text", 3543 "partition": "text",
3531 "likes": 0, 3544 "likes": 0,
3532 "createdAt": 1787568512602, 3545 "createdAt": 1787568512602,
3533 - "lastPlayedAt": 1788246313154, 3546 + "lastPlayedAt": 1788252082974,
3534 "promptEn": "man apologizes, says something outside was chasing him" 3547 "promptEn": "man apologizes, says something outside was chasing him"
3535 }, 3548 },
3536 { 3549 {
@@ -3545,7 +3558,7 @@ @@ -3545,7 +3558,7 @@
3545 "partition": "ref2va", 3558 "partition": "ref2va",
3546 "likes": 0, 3559 "likes": 0,
3547 "createdAt": 1787559156410, 3560 "createdAt": 1787559156410,
3548 - "lastPlayedAt": 1788248745205, 3561 + "lastPlayedAt": 1788251306490,
3549 "promptEn": "two characters sitting, game menu UI swaps in a mechanical arm" 3562 "promptEn": "two characters sitting, game menu UI swaps in a mechanical arm"
3550 }, 3563 },
3551 { 3564 {
@@ -3561,7 +3574,7 @@ @@ -3561,7 +3574,7 @@
3561 "likes": 0, 3574 "likes": 0,
3562 "createdAt": 1787542770522, 3575 "createdAt": 1787542770522,
3563 "promptEn": "clip cut to match a reference video's editing rhythm", 3576 "promptEn": "clip cut to match a reference video's editing rhythm",
3564 - "lastPlayedAt": 1788249969849 3577 + "lastPlayedAt": 1788251906899
3565 }, 3578 },
3566 { 3579 {
3567 "id": "f9286d694bad", 3580 "id": "f9286d694bad",
@@ -3576,7 +3589,7 @@ @@ -3576,7 +3589,7 @@
3576 "likes": 0, 3589 "likes": 0,
3577 "createdAt": 1787497396594, 3590 "createdAt": 1787497396594,
3578 "promptEn": "otome game male lead showcase PV", 3591 "promptEn": "otome game male lead showcase PV",
3579 - "lastPlayedAt": 1788249489586 3592 + "lastPlayedAt": 1788250885690
3580 }, 3593 },
3581 { 3594 {
3582 "id": "36ac12f2f29e", 3595 "id": "36ac12f2f29e",
@@ -3591,7 +3604,7 @@ @@ -3591,7 +3604,7 @@
3591 "likes": 0, 3604 "likes": 0,
3592 "createdAt": 1787493339415, 3605 "createdAt": 1787493339415,
3593 "promptEn": "game menu UI, character swaps out a mechanical arm", 3606 "promptEn": "game menu UI, character swaps out a mechanical arm",
3594 - "lastPlayedAt": 1788247514144 3607 + "lastPlayedAt": 1788252205054
3595 }, 3608 },
3596 { 3609 {
3597 "id": "656c897b04fc", 3610 "id": "656c897b04fc",
@@ -3606,7 +3619,7 @@ @@ -3606,7 +3619,7 @@
3606 "likes": 0, 3619 "likes": 0,
3607 "createdAt": 1787493303602, 3620 "createdAt": 1787493303602,
3608 "promptEn": "game menu UI, character swaps out a mechanical arm", 3621 "promptEn": "game menu UI, character swaps out a mechanical arm",
3609 - "lastPlayedAt": 1788246195051 3622 + "lastPlayedAt": 1788252523177
3610 }, 3623 },
3611 { 3624 {
3612 "id": "e1fd99e4ab97", 3625 "id": "e1fd99e4ab97",
@@ -3621,7 +3634,7 @@ @@ -3621,7 +3634,7 @@
3621 "likes": 0, 3634 "likes": 0,
3622 "createdAt": 1787470101960, 3635 "createdAt": 1787470101960,
3623 "promptEn": "cute hand-drawn beagle dog making faces, game screen", 3636 "promptEn": "cute hand-drawn beagle dog making faces, game screen",
3624 - "lastPlayedAt": 1788249793727 3637 + "lastPlayedAt": 1788252643229
3625 }, 3638 },
3626 { 3639 {
3627 "id": "4067993ff824", 3640 "id": "4067993ff824",
@@ -3636,7 +3649,7 @@ @@ -3636,7 +3649,7 @@
3636 "likes": 0, 3649 "likes": 0,
3637 "createdAt": 1787470101693, 3650 "createdAt": 1787470101693,
3638 "promptEn": "black-background product-launch style shot of a roast duck", 3651 "promptEn": "black-background product-launch style shot of a roast duck",
3639 - "lastPlayedAt": 1788243072394 3652 + "lastPlayedAt": 1788251246462
3640 }, 3653 },
3641 { 3654 {
3642 "id": "99e771bbb50d", 3655 "id": "99e771bbb50d",
@@ -3651,7 +3664,7 @@ @@ -3651,7 +3664,7 @@
3651 "likes": 0, 3664 "likes": 0,
3652 "createdAt": 1787470101411, 3665 "createdAt": 1787470101411,
3653 "promptEn": "vertical family-fight drama, arguing with an older woman", 3666 "promptEn": "vertical family-fight drama, arguing with an older woman",
3654 - "lastPlayedAt": 1788247732323 3667 + "lastPlayedAt": 1788251276478
3655 }, 3668 },
3656 { 3669 {
3657 "id": "57169e6751d0", 3670 "id": "57169e6751d0",
@@ -3666,7 +3679,7 @@ @@ -3666,7 +3679,7 @@
3666 "likes": 0, 3679 "likes": 0,
3667 "createdAt": 1787470101060, 3680 "createdAt": 1787470101060,
3668 "promptEn": "snowy bamboo forest at night, wuxia mystery standoff", 3681 "promptEn": "snowy bamboo forest at night, wuxia mystery standoff",
3669 - "lastPlayedAt": 1788248617097 3682 + "lastPlayedAt": 1788250430095
3670 }, 3683 },
3671 { 3684 {
3672 "id": "125751cac1c8", 3685 "id": "125751cac1c8",
@@ -3681,7 +3694,7 @@ @@ -3681,7 +3694,7 @@
3681 "likes": 0, 3694 "likes": 0,
3682 "createdAt": 1787470100377, 3695 "createdAt": 1787470100377,
3683 "promptEn": "all-black background, experimental Chinese kinetic typography", 3696 "promptEn": "all-black background, experimental Chinese kinetic typography",
3684 - "lastPlayedAt": 1788247193855 3697 + "lastPlayedAt": 1788250298018
3685 }, 3698 },
3686 { 3699 {
3687 "id": "c24c15736daa", 3700 "id": "c24c15736daa",
@@ -3711,7 +3724,7 @@ @@ -3711,7 +3724,7 @@
3711 "likes": 0, 3724 "likes": 0,
3712 "createdAt": 1787470100022, 3725 "createdAt": 1787470100022,
3713 "promptEn": "MiniMax H3 brand motion graphics, a dot growing into a network", 3726 "promptEn": "MiniMax H3 brand motion graphics, a dot growing into a network",
3714 - "lastPlayedAt": 1788248873291 3727 + "lastPlayedAt": 1788251916904
3715 }, 3728 },
3716 { 3729 {
3717 "id": "eaf2a1433c41", 3730 "id": "eaf2a1433c41",
@@ -3726,7 +3739,7 @@ @@ -3726,7 +3739,7 @@
3726 "likes": 0, 3739 "likes": 0,
3727 "createdAt": 1787470099635, 3740 "createdAt": 1787470099635,
3728 "promptEn": "pointing at things at a beach market, they turn into hand-drawn animation", 3741 "promptEn": "pointing at things at a beach market, they turn into hand-drawn animation",
3729 - "lastPlayedAt": 1788249097406 3742 + "lastPlayedAt": 1788251368535
3730 }, 3743 },
3731 { 3744 {
3732 "id": "0fe0f2101c44", 3745 "id": "0fe0f2101c44",
@@ -3741,7 +3754,7 @@ @@ -3741,7 +3754,7 @@
3741 "likes": 0, 3754 "likes": 0,
3742 "createdAt": 1787470099306, 3755 "createdAt": 1787470099306,
3743 "promptEn": "late-night laundromat footage mixed with glowing hand-drawn animation", 3756 "promptEn": "late-night laundromat footage mixed with glowing hand-drawn animation",
3744 - "lastPlayedAt": 1788249293496 3757 + "lastPlayedAt": 1788251502656
3745 }, 3758 },
3746 { 3759 {
3747 "id": "c0e23beb4132", 3760 "id": "c0e23beb4132",
@@ -3756,7 +3769,7 @@ @@ -3756,7 +3769,7 @@
3756 "likes": 0, 3769 "likes": 0,
3757 "createdAt": 1787470098914, 3770 "createdAt": 1787470098914,
3758 "promptEn": "evening kitchen footage mixed with a glowing hand-drawn creature", 3771 "promptEn": "evening kitchen footage mixed with a glowing hand-drawn creature",
3759 - "lastPlayedAt": 1788249331511 3772 + "lastPlayedAt": 1788252599204
3760 }, 3773 },
3761 { 3774 {
3762 "id": "6639b07acc7b", 3775 "id": "6639b07acc7b",
@@ -3771,7 +3784,7 @@ @@ -3771,7 +3784,7 @@
3771 "likes": 0, 3784 "likes": 0,
3772 "createdAt": 1787470098570, 3785 "createdAt": 1787470098570,
3773 "promptEn": "fast-cut spaceship trailer title sequence", 3786 "promptEn": "fast-cut spaceship trailer title sequence",
3774 - "lastPlayedAt": 1788247744340 3787 + "lastPlayedAt": 1788252235049
3775 }, 3788 },
3776 { 3789 {
3777 "id": "1e55e540df11", 3790 "id": "1e55e540df11",
@@ -3786,7 +3799,7 @@ @@ -3786,7 +3799,7 @@
3786 "likes": 0, 3799 "likes": 0,
3787 "createdAt": 1787461994394, 3800 "createdAt": 1787461994394,
3788 "promptEn": "a quiet mountain village at dawn (second attempt)", 3801 "promptEn": "a quiet mountain village at dawn (second attempt)",
3789 - "lastPlayedAt": 1788248859286 3802 + "lastPlayedAt": 1788251098955
3790 }, 3803 },
3791 { 3804 {
3792 "id": "8e16b6faafd9", 3805 "id": "8e16b6faafd9",
@@ -3801,7 +3814,7 @@ @@ -3801,7 +3814,7 @@
3801 "likes": 0, 3814 "likes": 0,
3802 "createdAt": 1787455895150, 3815 "createdAt": 1787455895150,
3803 "promptEn": "protagonist leaps across rooftops fleeing pursuers", 3816 "promptEn": "protagonist leaps across rooftops fleeing pursuers",
3804 - "lastPlayedAt": 1788249507592 3817 + "lastPlayedAt": 1788252253059
3805 }, 3818 },
3806 { 3819 {
3807 "id": "2a4e45820135", 3820 "id": "2a4e45820135",
@@ -3816,7 +3829,7 @@ @@ -3816,7 +3829,7 @@
3816 "likes": 0, 3829 "likes": 0,
3817 "createdAt": 1787453697093, 3830 "createdAt": 1787453697093,
3818 "promptEn": "protagonist leaps across rooftops fleeing pursuers", 3831 "promptEn": "protagonist leaps across rooftops fleeing pursuers",
3819 - "lastPlayedAt": 1788248464962 3832 + "lastPlayedAt": 1788250986335
3820 }, 3833 },
3821 { 3834 {
3822 "id": "bfe13d1cc4a2", 3835 "id": "bfe13d1cc4a2",
@@ -3861,7 +3874,7 @@ @@ -3861,7 +3874,7 @@
3861 "likes": 0, 3874 "likes": 0,
3862 "createdAt": 1787447175021, 3875 "createdAt": 1787447175021,
3863 "promptEn": "protagonist leaps across rooftops fleeing pursuers", 3876 "promptEn": "protagonist leaps across rooftops fleeing pursuers",
3864 - "lastPlayedAt": 1788247824398 3877 + "lastPlayedAt": 1788252583201
3865 }, 3878 },
3866 { 3879 {
3867 "id": "4580ca66725a", 3880 "id": "4580ca66725a",
@@ -3876,7 +3889,7 @@ @@ -3876,7 +3889,7 @@
3876 "likes": 0, 3889 "likes": 0,
3877 "createdAt": 1787444313690, 3890 "createdAt": 1787444313690,
3878 "promptEn": "protagonist leaps across rooftops fleeing pursuers", 3891 "promptEn": "protagonist leaps across rooftops fleeing pursuers",
3879 - "lastPlayedAt": 1788246104977 3892 + "lastPlayedAt": 1788250484120
3880 }, 3893 },
3881 { 3894 {
3882 "id": "e56962bd770f", 3895 "id": "e56962bd770f",
@@ -3906,7 +3919,7 @@ @@ -3906,7 +3919,7 @@
3906 "likes": 0, 3919 "likes": 0,
3907 "createdAt": 1787437988124, 3920 "createdAt": 1787437988124,
3908 "promptEn": "protagonist leaps across rooftops fleeing pursuers", 3921 "promptEn": "protagonist leaps across rooftops fleeing pursuers",
3909 - "lastPlayedAt": 1788247948508 3922 + "lastPlayedAt": 1788252010944
3910 }, 3923 },
3911 { 3924 {
3912 "id": "e497093c79ce", 3925 "id": "e497093c79ce",
@@ -3951,7 +3964,7 @@ @@ -3951,7 +3964,7 @@
3951 "likes": 0, 3964 "likes": 0,
3952 "createdAt": 1787428860940, 3965 "createdAt": 1787428860940,
3953 "promptEn": "protagonist leaps across rooftops fleeing pursuers", 3966 "promptEn": "protagonist leaps across rooftops fleeing pursuers",
3954 - "lastPlayedAt": 1788249125420 3967 + "lastPlayedAt": 1788252981335
3955 }, 3968 },
3956 { 3969 {
3957 "id": "dbc7c27b72ba", 3970 "id": "dbc7c27b72ba",
@@ -3981,7 +3994,7 @@ @@ -3981,7 +3994,7 @@
3981 "likes": 0, 3994 "likes": 0,
3982 "createdAt": 1787426484939, 3995 "createdAt": 1787426484939,
3983 "promptEn": "small boat sailing through a misty forest river", 3996 "promptEn": "small boat sailing through a misty forest river",
3984 - "lastPlayedAt": 1788248206733 3997 + "lastPlayedAt": 1788252927307
3985 }, 3998 },
3986 { 3999 {
3987 "id": "9fbcf0d87021", 4000 "id": "9fbcf0d87021",
@@ -4011,7 +4024,7 @@ @@ -4011,7 +4024,7 @@
4011 "likes": 0, 4024 "likes": 0,
4012 "createdAt": 1787415067615, 4025 "createdAt": 1787415067615,
4013 "promptEn": "protagonist leaps across rooftops fleeing pursuers", 4026 "promptEn": "protagonist leaps across rooftops fleeing pursuers",
4014 - "lastPlayedAt": 1788249017364 4027 + "lastPlayedAt": 1788250586170
4015 }, 4028 },
4016 { 4029 {
4017 "id": "9bcff387cddf", 4030 "id": "9bcff387cddf",
@@ -4026,7 +4039,7 @@ @@ -4026,7 +4039,7 @@
4026 "likes": 0, 4039 "likes": 0,
4027 "createdAt": 1787413999418, 4040 "createdAt": 1787413999418,
4028 "promptEn": "protagonist leaps across rooftops fleeing pursuers", 4041 "promptEn": "protagonist leaps across rooftops fleeing pursuers",
4029 - "lastPlayedAt": 1788247492126 4042 + "lastPlayedAt": 1788251954922
4030 }, 4043 },
4031 { 4044 {
4032 "id": "ade0318a7a4a", 4045 "id": "ade0318a7a4a",
@@ -4041,7 +4054,7 @@ @@ -4041,7 +4054,7 @@
4041 "likes": 0, 4054 "likes": 0,
4042 "createdAt": 1787413511959, 4055 "createdAt": 1787413511959,
4043 "promptEn": "protagonist leaps across rooftops fleeing pursuers", 4056 "promptEn": "protagonist leaps across rooftops fleeing pursuers",
4044 - "lastPlayedAt": 1788241595119 4057 + "lastPlayedAt": 1788251161159
4045 }, 4058 },
4046 { 4059 {
4047 "id": "5d4f40bf0889", 4060 "id": "5d4f40bf0889",
@@ -4056,7 +4069,7 @@ @@ -4056,7 +4069,7 @@
4056 "likes": 0, 4069 "likes": 0,
4057 "createdAt": 1787412952086, 4070 "createdAt": 1787412952086,
4058 "promptEn": "protagonist leaps across rooftops fleeing pursuers", 4071 "promptEn": "protagonist leaps across rooftops fleeing pursuers",
4059 - "lastPlayedAt": 1788245274259 4072 + "lastPlayedAt": 1788251143150
4060 }, 4073 },
4061 { 4074 {
4062 "id": "59fd7a087f5b", 4075 "id": "59fd7a087f5b",
@@ -4071,7 +4084,7 @@ @@ -4071,7 +4084,7 @@
4071 "likes": 0, 4084 "likes": 0,
4072 "createdAt": 1787412606465, 4085 "createdAt": 1787412606465,
4073 "promptEn": "protagonist leaps across rooftops fleeing pursuers", 4086 "promptEn": "protagonist leaps across rooftops fleeing pursuers",
4074 - "lastPlayedAt": 1788249769708 4087 + "lastPlayedAt": 1788251848870
4075 }, 4088 },
4076 { 4089 {
4077 "id": "29a99dc412b2", 4090 "id": "29a99dc412b2",
@@ -4086,7 +4099,7 @@ @@ -4086,7 +4099,7 @@
4086 "likes": 0, 4099 "likes": 0,
4087 "createdAt": 1787412150062, 4100 "createdAt": 1787412150062,
4088 "promptEn": "protagonist leaps across rooftops fleeing pursuers", 4101 "promptEn": "protagonist leaps across rooftops fleeing pursuers",
4089 - "lastPlayedAt": 1788249081394 4102 + "lastPlayedAt": 1788252809259
4090 }, 4103 },
4091 { 4104 {
4092 "id": "9d2486d6f969", 4105 "id": "9d2486d6f969",
@@ -4101,7 +4114,7 @@ @@ -4101,7 +4114,7 @@
4101 "likes": 0, 4114 "likes": 0,
4102 "createdAt": 1787397450973, 4115 "createdAt": 1787397450973,
4103 "promptEn": "a cat sitting on a windowsill", 4116 "promptEn": "a cat sitting on a windowsill",
4104 - "lastPlayedAt": 1788249343516 4117 + "lastPlayedAt": 1788251736809
4105 }, 4118 },
4106 { 4119 {
4107 "id": "580d1d722adc", 4120 "id": "580d1d722adc",
@@ -4116,7 +4129,7 @@ @@ -4116,7 +4129,7 @@
4116 "likes": 0, 4129 "likes": 0,
4117 "createdAt": 1787388090646, 4130 "createdAt": 1787388090646,
4118 "promptEn": "a cat sitting on a windowsill", 4131 "promptEn": "a cat sitting on a windowsill",
4119 - "lastPlayedAt": 1788245762695 4132 + "lastPlayedAt": 1788252393130
4120 }, 4133 },
4121 { 4134 {
4122 "id": "c551457bc55e", 4135 "id": "c551457bc55e",
@@ -4130,7 +4143,7 @@ @@ -4130,7 +4143,7 @@
4130 "partition": "text", 4143 "partition": "text",
4131 "likes": 0, 4144 "likes": 0,
4132 "createdAt": 1787386316175, 4145 "createdAt": 1787386316175,
4133 - "lastPlayedAt": 1788245308283, 4146 + "lastPlayedAt": 1788253015347,
4134 "promptEn": "a cat sitting on a windowsill" 4147 "promptEn": "a cat sitting on a windowsill"
4135 }, 4148 },
4136 { 4149 {
@@ -4146,7 +4159,7 @@ @@ -4146,7 +4159,7 @@
4146 "likes": 0, 4159 "likes": 0,
4147 "createdAt": 1787384983124, 4160 "createdAt": 1787384983124,
4148 "promptEn": "protagonist leaps across rooftops fleeing pursuers", 4161 "promptEn": "protagonist leaps across rooftops fleeing pursuers",
4149 - "lastPlayedAt": 1788247864432 4162 + "lastPlayedAt": 1788251892892
4150 }, 4163 },
4151 { 4164 {
4152 "id": "7753a046ba79", 4165 "id": "7753a046ba79",
@@ -4191,7 +4204,7 @@ @@ -4191,7 +4204,7 @@
4191 "likes": 0, 4204 "likes": 0,
4192 "createdAt": 1787375413935, 4205 "createdAt": 1787375413935,
4193 "promptEn": "protagonist leaps across rooftops fleeing pursuers", 4206 "promptEn": "protagonist leaps across rooftops fleeing pursuers",
4194 - "lastPlayedAt": 1788248671135 4207 + "lastPlayedAt": 1788252421136
4195 }, 4208 },
4196 { 4209 {
4197 "id": "10112fb3c1fd", 4210 "id": "10112fb3c1fd",
@@ -4206,7 +4219,7 @@ @@ -4206,7 +4219,7 @@
4206 "likes": 0, 4219 "likes": 0,
4207 "createdAt": 1787375413623, 4220 "createdAt": 1787375413623,
4208 "promptEn": "golden portal opens, man in green jacket throws a glowing spear", 4221 "promptEn": "golden portal opens, man in green jacket throws a glowing spear",
4209 - "lastPlayedAt": 1788248286801 4222 + "lastPlayedAt": 1788250362064
4210 }, 4223 },
4211 { 4224 {
4212 "id": "78e698c924b1", 4225 "id": "78e698c924b1",
@@ -4221,7 +4234,7 @@ @@ -4221,7 +4234,7 @@
4221 "likes": 0, 4234 "likes": 0,
4222 "createdAt": 1787375413203, 4235 "createdAt": 1787375413203,
4223 "promptEn": "golden portal opens, man in green jacket throws a glowing spear", 4236 "promptEn": "golden portal opens, man in green jacket throws a glowing spear",
4224 - "lastPlayedAt": 1788247438073 4237 + "lastPlayedAt": 1788252725215
4225 }, 4238 },
4226 { 4239 {
4227 "id": "219ed88c3ea7", 4240 "id": "219ed88c3ea7",
@@ -4236,7 +4249,7 @@ @@ -4236,7 +4249,7 @@
4236 "likes": 0, 4249 "likes": 0,
4237 "createdAt": 1787375412946, 4250 "createdAt": 1787375412946,
4238 "promptEn": "golden portal opens, man in green jacket throws a glowing spear", 4251 "promptEn": "golden portal opens, man in green jacket throws a glowing spear",
4239 - "lastPlayedAt": 1788245734672 4252 + "lastPlayedAt": 1788252407133
4240 }, 4253 },
4241 { 4254 {
4242 "id": "a72236902363", 4255 "id": "a72236902363",
@@ -4251,7 +4264,7 @@ @@ -4251,7 +4264,7 @@
4251 "likes": 0, 4264 "likes": 0,
4252 "createdAt": 1787367454249, 4265 "createdAt": 1787367454249,
4253 "promptEn": "golden portal opens, man in green jacket throws a glowing spear", 4266 "promptEn": "golden portal opens, man in green jacket throws a glowing spear",
4254 - "lastPlayedAt": 1788246703457 4267 + "lastPlayedAt": 1788252831263
4255 }, 4268 },
4256 { 4269 {
4257 "id": "c48af2f34e62", 4270 "id": "c48af2f34e62",
@@ -4266,7 +4279,7 @@ @@ -4266,7 +4279,7 @@
4266 "likes": 0, 4279 "likes": 0,
4267 "createdAt": 1787367454065, 4280 "createdAt": 1787367454065,
4268 "promptEn": "golden portal opens, man in green jacket throws a glowing spear", 4281 "promptEn": "golden portal opens, man in green jacket throws a glowing spear",
4269 - "lastPlayedAt": 1788245668612 4282 + "lastPlayedAt": 1788250848268
4270 }, 4283 },
4271 { 4284 {
4272 "id": "e6c241be377f", 4285 "id": "e6c241be377f",
@@ -4281,7 +4294,7 @@ @@ -4281,7 +4294,7 @@
4281 "likes": 0, 4294 "likes": 0,
4282 "createdAt": 1787367453839, 4295 "createdAt": 1787367453839,
4283 "promptEn": "golden portal opens, man in green jacket throws a glowing spear", 4296 "promptEn": "golden portal opens, man in green jacket throws a glowing spear",
4284 - "lastPlayedAt": 1788244952031 4297 + "lastPlayedAt": 1788252006941
4285 }, 4298 },
4286 { 4299 {
4287 "id": "8402adae59dc", 4300 "id": "8402adae59dc",
@@ -4296,7 +4309,7 @@ @@ -4296,7 +4309,7 @@
4296 "likes": 0, 4309 "likes": 0,
4297 "createdAt": 1787363956909, 4310 "createdAt": 1787363956909,
4298 "promptEn": "protagonist leaps across rooftops fleeing pursuers", 4311 "promptEn": "protagonist leaps across rooftops fleeing pursuers",
4299 - "lastPlayedAt": 1788247205863 4312 + "lastPlayedAt": 1788250706222
4300 }, 4313 },
4301 { 4314 {
4302 "id": "5692965402f5", 4315 "id": "5692965402f5",
@@ -4311,7 +4324,7 @@ @@ -4311,7 +4324,7 @@
4311 "likes": 0, 4324 "likes": 0,
4312 "createdAt": 1787332996051, 4325 "createdAt": 1787332996051,
4313 "promptEn": "golden portal opens, man in green jacket throws a glowing spear", 4326 "promptEn": "golden portal opens, man in green jacket throws a glowing spear",
4314 - "lastPlayedAt": 1788247490125 4327 + "lastPlayedAt": 1788250762247
4315 }, 4328 },
4316 { 4329 {
4317 "id": "bf7d973d02a3", 4330 "id": "bf7d973d02a3",
@@ -4326,7 +4339,7 @@ @@ -4326,7 +4339,7 @@
4326 "likes": 0, 4339 "likes": 0,
4327 "createdAt": 1787332047061, 4340 "createdAt": 1787332047061,
4328 "promptEn": "golden portal opens, man in green jacket throws a glowing spear", 4341 "promptEn": "golden portal opens, man in green jacket throws a glowing spear",
4329 - "lastPlayedAt": 1788241785296 4342 + "lastPlayedAt": 1788251350521
4330 }, 4343 },
4331 { 4344 {
4332 "id": "a5688d8f5db3", 4345 "id": "a5688d8f5db3",
@@ -4341,7 +4354,7 @@ @@ -4341,7 +4354,7 @@
4341 "likes": 0, 4354 "likes": 0,
4342 "createdAt": 1787330101793, 4355 "createdAt": 1787330101793,
4343 "promptEn": "a red apple on a wooden table, cinematic lighting", 4356 "promptEn": "a red apple on a wooden table, cinematic lighting",
4344 - "lastPlayedAt": 1788246901624 4357 + "lastPlayedAt": 1788252205039
4345 }, 4358 },
4346 { 4359 {
4347 "id": "0024d3c2d4cb", 4360 "id": "0024d3c2d4cb",
@@ -4356,7 +4369,7 @@ @@ -4356,7 +4369,7 @@
4356 "likes": 0, 4369 "likes": 0,
4357 "createdAt": 1787326019663, 4370 "createdAt": 1787326019663,
4358 "promptEn": "misty Jiangnan old town at dawn, woman walking with an oil-paper umbrella", 4371 "promptEn": "misty Jiangnan old town at dawn, woman walking with an oil-paper umbrella",
4359 - "lastPlayedAt": 1788248282796 4372 + "lastPlayedAt": 1788252891295
4360 }, 4373 },
4361 { 4374 {
4362 "id": "ab42a6fba515", 4375 "id": "ab42a6fba515",
@@ -4386,7 +4399,7 @@ @@ -4386,7 +4399,7 @@
4386 "likes": 0, 4399 "likes": 0,
4387 "createdAt": 1787309864037, 4400 "createdAt": 1787309864037,
4388 "promptEn": "transparent gaming mouse product film, blue and orange lighting", 4401 "promptEn": "transparent gaming mouse product film, blue and orange lighting",
4389 - "lastPlayedAt": 1788248827266 4402 + "lastPlayedAt": 1788252567195
4390 }, 4403 },
4391 { 4404 {
4392 "id": "073f5df6427a", 4405 "id": "073f5df6427a",
@@ -4401,7 +4414,7 @@ @@ -4401,7 +4414,7 @@
4401 "likes": 0, 4414 "likes": 0,
4402 "createdAt": 1787305544815, 4415 "createdAt": 1787305544815,
4403 "promptEn": "transparent gaming mouse product film, blue and orange lighting", 4416 "promptEn": "transparent gaming mouse product film, blue and orange lighting",
4404 - "lastPlayedAt": 1788247706310 4417 + "lastPlayedAt": 1788251648757
4405 }, 4418 },
4406 { 4419 {
4407 "id": "e23b04ac2c78", 4420 "id": "e23b04ac2c78",
@@ -4416,7 +4429,7 @@ @@ -4416,7 +4429,7 @@
4416 "likes": 0, 4429 "likes": 0,
4417 "createdAt": 1787304875681, 4430 "createdAt": 1787304875681,
4418 "promptEn": "protagonist leaps across rooftops fleeing pursuers", 4431 "promptEn": "protagonist leaps across rooftops fleeing pursuers",
4419 - "lastPlayedAt": 1788249393534 4432 + "lastPlayedAt": 1788253051367
4420 }, 4433 },
4421 { 4434 {
4422 "id": "c84bc1c7bfa0", 4435 "id": "c84bc1c7bfa0",
@@ -4431,7 +4444,7 @@ @@ -4431,7 +4444,7 @@
4431 "likes": 0, 4444 "likes": 0,
4432 "createdAt": 1787304031214, 4445 "createdAt": 1787304031214,
4433 "promptEn": "constable asks how she's sure it's not human, she says a person would make a sound", 4446 "promptEn": "constable asks how she's sure it's not human, she says a person would make a sound",
4434 - "lastPlayedAt": 1788249309501 4447 + "lastPlayedAt": 1788251466626
4435 }, 4448 },
4436 { 4449 {
4437 "id": "23d2fd81eb4d", 4450 "id": "23d2fd81eb4d",
@@ -4446,7 +4459,7 @@ @@ -4446,7 +4459,7 @@
4446 "likes": 0, 4459 "likes": 0,
4447 "createdAt": 1787304031103, 4460 "createdAt": 1787304031103,
4448 "promptEn": "constable asks how she's sure it's not human, she says a person would make a sound", 4461 "promptEn": "constable asks how she's sure it's not human, she says a person would make a sound",
4449 - "lastPlayedAt": 1788249193447 4462 + "lastPlayedAt": 1788252124992
4450 }, 4463 },
4451 { 4464 {
4452 "id": "807e042dce0d", 4465 "id": "807e042dce0d",
@@ -4461,7 +4474,7 @@ @@ -4461,7 +4474,7 @@
4461 "likes": 0, 4474 "likes": 0,
4462 "createdAt": 1787290119529, 4475 "createdAt": 1787290119529,
4463 "promptEn": "misty Jiangnan old town at dawn, woman walking with an oil-paper umbrella", 4476 "promptEn": "misty Jiangnan old town at dawn, woman walking with an oil-paper umbrella",
4464 - "lastPlayedAt": 1788249287492 4477 + "lastPlayedAt": 1788251302490
4465 }, 4478 },
4466 { 4479 {
4467 "id": "06bb43196c46", 4480 "id": "06bb43196c46",
@@ -4506,7 +4519,7 @@ @@ -4506,7 +4519,7 @@
4506 "likes": 0, 4519 "likes": 0,
4507 "createdAt": 1787231456079, 4520 "createdAt": 1787231456079,
4508 "promptEn": "constable burns the beauty portrait with the lamp, the door opens on its own", 4521 "promptEn": "constable burns the beauty portrait with the lamp, the door opens on its own",
4509 - "lastPlayedAt": 1788246433257 4522 + "lastPlayedAt": 1788251682774
4510 }, 4523 },
4511 { 4524 {
4512 "id": "66158f543a20", 4525 "id": "66158f543a20",
@@ -4521,7 +4534,7 @@ @@ -4521,7 +4534,7 @@
4521 "likes": 0, 4534 "likes": 0,
4522 "createdAt": 1787231440149, 4535 "createdAt": 1787231440149,
4523 "promptEn": "constable burns the beauty portrait with the lamp, the door opens on its own", 4536 "promptEn": "constable burns the beauty portrait with the lamp, the door opens on its own",
4524 - "lastPlayedAt": 1788246941650 4537 + "lastPlayedAt": 1788250606173
4525 }, 4538 },
4526 { 4539 {
4527 "id": "63c91f4b6bc7", 4540 "id": "63c91f4b6bc7",
@@ -4550,7 +4563,7 @@ @@ -4550,7 +4563,7 @@
4550 "partition": "fl2va", 4563 "partition": "fl2va",
4551 "likes": 0, 4564 "likes": 0,
4552 "createdAt": 1787224701504, 4565 "createdAt": 1787224701504,
4553 - "lastPlayedAt": 1788247614231, 4566 + "lastPlayedAt": 1788252757232,
4554 "promptEn": "constable burns the beauty portrait with the lamp, the door opens on its own" 4567 "promptEn": "constable burns the beauty portrait with the lamp, the door opens on its own"
4555 }, 4568 },
4556 { 4569 {
@@ -4566,7 +4579,7 @@ @@ -4566,7 +4579,7 @@
4566 "likes": 0, 4579 "likes": 0,
4567 "createdAt": 1787224519456, 4580 "createdAt": 1787224519456,
4568 "promptEn": "constable burns the beauty portrait with the lamp, the door opens on its own", 4581 "promptEn": "constable burns the beauty portrait with the lamp, the door opens on its own",
4569 - "lastPlayedAt": 1788244245424 4582 + "lastPlayedAt": 1788252627218
4570 }, 4583 },
4571 { 4584 {
4572 "id": "a1cc621cc6b2", 4585 "id": "a1cc621cc6b2",
@@ -4581,6 +4594,6 @@ @@ -4581,6 +4594,6 @@
4581 "likes": 0, 4594 "likes": 0,
4582 "createdAt": 1787220579189, 4595 "createdAt": 1787220579189,
4583 "promptEn": "gothic castle at night, vampire noble carries a princess, rose petals falling", 4596 "promptEn": "gothic castle at night, vampire noble carries a princess, rose petals falling",
4584 - "lastPlayedAt": 1788248725194 4597 + "lastPlayedAt": 1788252092980
4585 } 4598 }
4586 ] 4599 ]
4587 \ No newline at end of file 4600 \ No newline at end of file
live.css
1 * { box-sizing: border-box; } 1 * { box-sizing: border-box; }
2 [hidden] { display: none !important; } 2 [hidden] { display: none !important; }
3 3
4 -/* Palette + type lifted from infiniteslop.ai: pure black, hot-pink accent,  
5 - Tahoma body copy, Shrikhand display logo with a punchy drop-shadow. */ 4 +/* Palette + type lifted from infiniteslop.ai: pure black canvas, Tahoma bold
  5 + everywhere, hot-pink accent, and a hand-drawn "comic panel" look — white
  6 + boxes with a thick black border and a hard offset drop-shadow (no blur) —
  7 + for every interactive surface (buttons, bubbles, prompt cards). */
6 :root { 8 :root {
7 --bg: #000; 9 --bg: #000;
  10 + --panel: #000;
  11 + --divider: rgba(255, 255, 255, .08);
8 --text: #fff; 12 --text: #fff;
9 - --muted: #9a9aa1;  
10 - --border: #1e1e22;  
11 - --panel: #0e0e11;  
12 - --row-hover: #17171a; 13 + --muted: rgba(255, 255, 255, .55);
  14 + --ink: #111;
13 --accent: #ff90e8; 15 --accent: #ff90e8;
14 - --accent-text: #111; 16 + --accent-text: #d81b9a;
  17 + --gen-bg: #ffe990;
  18 + --shadow-sm: 3px 3px 0 #000;
  19 + --shadow: 4px 4px 0 #000;
  20 + --shadow-lg: 5px 5px 0 #000;
15 } 21 }
16 22
17 body { 23 body {
@@ -31,34 +37,56 @@ body { @@ -31,34 +37,56 @@ body {
31 .topbar { 37 .topbar {
32 display: flex; 38 display: flex;
33 align-items: center; 39 align-items: center;
34 - gap: 14px; 40 + gap: 10px;
35 padding: 10px 16px; 41 padding: 10px 16px;
36 - border-bottom: 1px solid var(--border);  
37 flex: 0 0 auto; 42 flex: 0 0 auto;
38 } 43 }
39 .topbar .logo { 44 .topbar .logo {
40 font-family: "Shrikhand", "Cooper Black", serif; 45 font-family: "Shrikhand", "Cooper Black", serif;
41 font-weight: 400; 46 font-weight: 400;
42 - font-size: 20px; 47 + font-size: 22px;
43 margin: 0; 48 margin: 0;
44 color: #fff; 49 color: #fff;
45 - text-shadow: 2px 2px 0 var(--accent); 50 + -webkit-text-stroke: 2px #000;
  51 + paint-order: stroke fill;
  52 + text-shadow: 1px 1px 0 #000, 2px 2px 0 #000, 3px 3px 0 #000;
46 } 53 }
47 .topbar .spacer { flex: 1; } 54 .topbar .spacer { flex: 1; }
48 -.watching { font-size: 12px; font-weight: 700; color: var(--muted); } 55 +.watching {
  56 + font: bold 13px Tahoma, sans-serif;
  57 + padding: 6px 12px;
  58 + border: 3px solid #000;
  59 + border-radius: 12px;
  60 + background: #fff;
  61 + color: var(--ink);
  62 + box-shadow: var(--shadow);
  63 +}
  64 +.topbar-pill {
  65 + flex: none;
  66 + font: bold 13px Tahoma, sans-serif;
  67 + cursor: pointer;
  68 + padding: 6px 12px;
  69 + border: 3px solid #000;
  70 + border-radius: 12px;
  71 + background: #fff;
  72 + color: var(--ink);
  73 + box-shadow: var(--shadow);
  74 +}
  75 +.topbar-pill:active { transform: translate(2px, 2px); box-shadow: 2px 2px 0 #000; }
49 76
50 -.tabs { display: flex; gap: 6px; } 77 +.tabs { display: flex; gap: 8px; }
51 .tabs button { 78 .tabs button {
  79 + font: bold 12px Tahoma, sans-serif;
52 background: #fff; 80 background: #fff;
53 - border: none;  
54 - color: var(--accent-text);  
55 - border-radius: 999px; 81 + border: 3px solid #000;
  82 + color: var(--ink);
  83 + border-radius: 12px;
56 padding: 6px 14px; 84 padding: 6px 14px;
57 - font-size: 12px;  
58 - font-weight: 700; 85 + box-shadow: var(--shadow);
59 cursor: pointer; 86 cursor: pointer;
60 } 87 }
61 -.tabs button.active { background: var(--accent); color: var(--accent-text); } 88 +.tabs button:active { transform: translate(2px, 2px); box-shadow: 2px 2px 0 #000; }
  89 +.tabs button.active { background: var(--accent); }
62 90
63 .body { 91 .body {
64 flex: 1; 92 flex: 1;
@@ -68,41 +96,94 @@ body { @@ -68,41 +96,94 @@ body {
68 96
69 /* ---- left: queue / browse list ---- */ 97 /* ---- left: queue / browse list ---- */
70 .left-col { 98 .left-col {
71 - width: 300px;  
72 - min-width: 240px;  
73 - border-right: 1px solid var(--border); 99 + width: 320px;
  100 + min-width: 260px;
  101 + border-right: 1px solid var(--divider);
74 display: flex; 102 display: flex;
75 flex-direction: column; 103 flex-direction: column;
76 overflow: hidden; 104 overflow: hidden;
77 background: var(--panel); 105 background: var(--panel);
  106 + padding: 12px 10px;
  107 + gap: 8px;
78 } 108 }
79 -.left-col .section-title {  
80 - font-size: 11px;  
81 - font-weight: 700;  
82 - letter-spacing: .06em; 109 +.section-head {
  110 + font: bold 13px Tahoma, sans-serif;
  111 + color: #fff;
  112 + text-shadow: 0 1px 3px #000;
  113 + letter-spacing: .5px;
83 text-transform: uppercase; 114 text-transform: uppercase;
84 - color: var(--muted);  
85 - padding: 12px 14px 6px; 115 + margin: 10px 2px 2px;
86 } 116 }
87 -.clip-list { flex: 1; overflow-y: auto; } 117 +.section-head:first-child { margin-top: 2px; }
  118 +.clip-list { flex: 1; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; scrollbar-width: thin; scrollbar-color: rgba(255,255,255,.3) transparent; }
  119 +.clip-list::-webkit-scrollbar { width: 6px; }
  120 +.clip-list::-webkit-scrollbar-thumb { background: rgba(255,255,255,.3); border-radius: 8px; }
  121 +
88 .clip-row { 122 .clip-row {
89 - padding: 10px 14px;  
90 - border-bottom: 1px solid var(--border); 123 + align-self: flex-start;
  124 + width: 100%;
  125 + color: var(--ink);
  126 + background: #fff;
  127 + border: 3px solid #000;
  128 + border-radius: 16px;
  129 + padding: 8px 14px;
  130 + box-shadow: var(--shadow-lg);
91 cursor: pointer; 131 cursor: pointer;
92 } 132 }
93 -.clip-row:hover { background: var(--row-hover); }  
94 -.clip-row.active { background: var(--row-hover); box-shadow: inset 3px 0 0 var(--accent); } 133 +.clip-row.gen { background: var(--gen-bg); cursor: default; }
  134 +.clip-row.failed { background: #ffd2d2; cursor: default; }
  135 +.clip-row.active { outline: 3px solid var(--accent-text); outline-offset: 2px; }
95 .clip-row .prompt { 136 .clip-row .prompt {
96 - font-size: 12.5px; 137 + font-size: 13.5px;
  138 + font-weight: bold;
97 line-height: 1.4; 139 line-height: 1.4;
98 - color: #d8d8dd;  
99 display: -webkit-box; 140 display: -webkit-box;
100 -webkit-line-clamp: 2; 141 -webkit-line-clamp: 2;
101 -webkit-box-orient: vertical; 142 -webkit-box-orient: vertical;
102 overflow: hidden; 143 overflow: hidden;
103 } 144 }
104 -.clip-row .meta { font-size: 10.5px; color: #6b6b72; margin-top: 4px; }  
105 -.empty-hint { color: #6b6b72; text-align: center; margin-top: 40px; font-size: 13px; } 145 +.clip-row .meta { font-size: 11px; font-weight: bold; opacity: .6; margin-top: 3px; }
  146 +
  147 +.qrow { display: flex; align-items: flex-start; gap: 8px; }
  148 +.qrow .clip-row { flex: 1; min-width: 0; cursor: default; }
  149 +.up-btn {
  150 + flex: none;
  151 + cursor: pointer;
  152 + font: bold 12px Tahoma, sans-serif;
  153 + color: var(--ink);
  154 + background: #fff;
  155 + border: 3px solid #000;
  156 + border-radius: 12px;
  157 + box-shadow: var(--shadow-sm);
  158 + padding: 6px 8px;
  159 + display: flex;
  160 + flex-direction: column;
  161 + align-items: center;
  162 + line-height: 1;
  163 + min-width: 36px;
  164 +}
  165 +.up-btn span { margin-top: 3px; color: var(--accent-text); font-variant-numeric: tabular-nums; }
  166 +.up-btn.voted { background: var(--accent); }
  167 +.up-btn:active { transform: translate(2px, 2px); box-shadow: 1px 1px 0 #000; }
  168 +.up-btn:disabled { opacity: .6; cursor: default; }
  169 +
  170 +.empty-hint { color: var(--muted); text-align: center; margin-top: 40px; font-size: 13px; font-weight: bold; }
  171 +
  172 +.site-credit {
  173 + flex: none;
  174 + display: inline-flex;
  175 + align-items: center;
  176 + gap: 6px;
  177 + align-self: flex-start;
  178 + font: bold 14px Tahoma, sans-serif;
  179 + padding: 7px 14px;
  180 + border: 3px solid #000;
  181 + border-radius: 12px;
  182 + background: #fff;
  183 + color: var(--ink);
  184 + box-shadow: var(--shadow);
  185 +}
  186 +.site-credit span { color: var(--accent-text); }
106 187
107 /* ---- center: player, no native controls — pure "watch only" ---- */ 188 /* ---- center: player, no native controls — pure "watch only" ---- */
108 .player-col { 189 .player-col {
@@ -128,113 +209,147 @@ body { @@ -128,113 +209,147 @@ body {
128 object-fit: contain; 209 object-fit: contain;
129 } 210 }
130 211
131 -.now-playing-bar { 212 +.live-pill {
132 position: absolute; 213 position: absolute;
133 - top: 0;  
134 - left: 0;  
135 - right: 0; 214 + left: 50%;
  215 + top: 14px;
  216 + transform: translateX(-50%);
136 z-index: 2; 217 z-index: 2;
137 - padding: 12px 16px;  
138 - font-size: 13px;  
139 - font-weight: 700;  
140 - line-height: 1.4; 218 + display: inline-flex;
  219 + align-items: center;
  220 + gap: 7px;
  221 + border: none;
141 color: #fff; 222 color: #fff;
142 - background: linear-gradient(to bottom, rgba(0,0,0,.75), rgba(0,0,0,0)); 223 + font: 700 12px/1 Tahoma, sans-serif;
  224 + letter-spacing: .4px;
  225 + padding: 8px 15px;
  226 + border-radius: 999px;
  227 + background: #e11d2a;
  228 + box-shadow: 0 3px 12px rgba(0, 0, 0, .45);
143 } 229 }
144 -.now-playing-bar #liveDot { color: #ff3b3b; font-weight: 700; margin-right: 4px; } 230 +.live-pill .dot { width: 7px; height: 7px; border-radius: 50%; background: #fff; animation: livedot 1.4s ease-in-out infinite; }
  231 +@keyframes livedot { 50% { opacity: .25; } }
145 232
146 -.mute-btn { 233 +.now-playing-box {
147 position: absolute; 234 position: absolute;
148 - bottom: 14px;  
149 - right: 14px; 235 + top: 14px;
  236 + left: 14px;
150 z-index: 2; 237 z-index: 2;
  238 + max-width: min(560px, calc(100% - 28px));
151 background: #fff; 239 background: #fff;
152 - border: none;  
153 - color: var(--accent-text);  
154 - border-radius: 999px;  
155 - width: 36px;  
156 - height: 36px;  
157 - font-size: 15px;  
158 - font-weight: 700;  
159 - cursor: pointer; 240 + color: var(--ink);
  241 + border: 3px solid #000;
  242 + border-radius: 12px;
  243 + padding: 8px 14px;
  244 + box-shadow: var(--shadow);
  245 + font-size: 13px;
  246 + line-height: 1.4;
160 } 247 }
  248 +.now-playing-box .np-nick { font-weight: bold; color: var(--accent-text); margin-right: 6px; }
  249 +.now-playing-box .np-time { opacity: .5; font-variant-numeric: tabular-nums; }
  250 +.now-playing-box .np-text { font-weight: bold; margin-top: 2px; }
161 251
162 -/* ---- right: prompt input ---- */ 252 +/* ---- right: chat ---- */
163 .right-col { 253 .right-col {
164 - width: 300px;  
165 - min-width: 240px;  
166 - border-left: 1px solid var(--border); 254 + width: 320px;
  255 + min-width: 260px;
  256 + border-left: 1px solid var(--divider);
167 display: flex; 257 display: flex;
168 flex-direction: column; 258 flex-direction: column;
169 background: var(--panel); 259 background: var(--panel);
  260 + padding: 12px 10px 10px;
170 } 261 }
171 .right-col .section-title { 262 .right-col .section-title {
172 - font-size: 11px;  
173 - font-weight: 700;  
174 - letter-spacing: .06em; 263 + font: bold 13px Tahoma, sans-serif;
  264 + letter-spacing: .5px;
175 text-transform: uppercase; 265 text-transform: uppercase;
176 - color: var(--muted);  
177 - padding: 12px 14px 6px; 266 + color: #fff;
  267 + text-shadow: 0 1px 3px #000;
  268 + padding: 0 4px 8px;
  269 +}
  270 +.chat-list {
  271 + flex: 1;
  272 + overflow-y: auto;
  273 + overflow-x: hidden;
  274 + padding: 3px 4px;
  275 + display: flex;
  276 + flex-direction: column;
  277 + gap: 10px;
  278 + scrollbar-width: thin;
  279 + scrollbar-color: rgba(255, 255, 255, .3) transparent;
  280 + -webkit-mask-image: linear-gradient(to bottom, transparent 0, #000 40px);
  281 + mask-image: linear-gradient(to bottom, transparent 0, #000 40px);
  282 +}
  283 +.chat-list::-webkit-scrollbar { width: 6px; }
  284 +.chat-list::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, .3); border-radius: 8px; }
  285 +.chat-list .chat-msg:first-child { margin-top: auto; }
  286 +
  287 +.chat-msg {
  288 + align-self: flex-start;
  289 + max-width: 92%;
  290 + color: var(--ink);
  291 + background: #fff;
  292 + border: 3px solid #000;
  293 + border-radius: 16px;
  294 + padding: 7px 14px;
  295 + font-size: 14px;
  296 + line-height: 1.4;
  297 + box-shadow: var(--shadow-lg);
  298 + word-break: break-word;
178 } 299 }
  300 +.chat-nick { margin-right: 6px; }
  301 +.chat-status { display: block; font-size: 11px; opacity: .6; font-weight: bold; margin-top: 2px; }
  302 +
179 .chat-identity-row { 303 .chat-identity-row {
180 display: flex; 304 display: flex;
181 align-items: center; 305 align-items: center;
  306 + justify-content: space-between;
182 gap: 8px; 307 gap: 8px;
183 - padding: 0 14px 6px;  
184 - font-size: 11.5px;  
185 - font-weight: 700; 308 + padding: 8px 4px 2px;
  309 + font-size: 12px;
  310 + font-weight: bold;
  311 + color: var(--muted);
186 } 312 }
187 -.chat-identity-row #currentNickname { color: var(--accent); } 313 +.chat-identity-row #currentNickname { color: var(--accent-text); }
188 .chat-identity-row #changeNameBtn { 314 .chat-identity-row #changeNameBtn {
189 background: transparent; 315 background: transparent;
190 border: none; 316 border: none;
191 color: var(--muted); 317 color: var(--muted);
192 font-size: 11px; 318 font-size: 11px;
193 - font-weight: 700;  
194 - text-decoration: underline; 319 + font-weight: bold;
195 cursor: pointer; 320 cursor: pointer;
  321 + text-decoration: underline;
196 padding: 0; 322 padding: 0;
197 } 323 }
198 .chat-identity-row #changeNameBtn:hover { color: #fff; } 324 .chat-identity-row #changeNameBtn:hover { color: #fff; }
199 -.chat-list {  
200 - flex: 1;  
201 - overflow-y: auto;  
202 - padding: 0 14px;  
203 - display: flex;  
204 - flex-direction: column;  
205 - gap: 8px;  
206 -}  
207 -.chat-msg { font-size: 12.5px; line-height: 1.5; word-break: break-word; }  
208 -.chat-nick { color: var(--accent); font-weight: 700; margin-right: 6px; }  
209 -.chat-text { color: #e4e4e8; }  
210 -.chat-status { display: block; font-size: 10.5px; color: var(--muted); font-weight: 700; margin-top: 1px; }  
211 325
212 -.chat-input-row { display: flex; gap: 6px; padding: 10px 14px 4px; } 326 +.chat-input-row { display: flex; gap: 8px; padding: 8px 4px 4px; }
213 .chat-input-row input { 327 .chat-input-row input {
214 flex: 1; 328 flex: 1;
215 min-width: 0; 329 min-width: 0;
  330 + font: bold 14px Tahoma, sans-serif;
  331 + padding: 9px 13px;
  332 + border: 3px solid #000;
  333 + border-radius: 12px;
  334 + outline: none;
  335 + box-shadow: var(--shadow);
216 background: #fff; 336 background: #fff;
217 - border: none;  
218 - border-radius: 999px;  
219 - padding: 9px 14px;  
220 - color: var(--accent-text);  
221 - font-weight: 700;  
222 - font-size: 13px;  
223 - font-family: inherit; 337 + color: var(--ink);
224 } 338 }
225 -.chat-input-row input::placeholder { color: #8a8a8a; font-weight: 400; } 339 +.chat-input-row input::placeholder { color: #888; font-weight: normal; }
226 .chat-input-row button { 340 .chat-input-row button {
227 - background: var(--accent);  
228 - color: var(--accent-text);  
229 - border: none;  
230 - border-radius: 999px;  
231 - padding: 0 16px;  
232 - font-weight: 700;  
233 - font-size: 13px; 341 + font: bold 14px Tahoma, sans-serif;
234 cursor: pointer; 342 cursor: pointer;
  343 + padding: 9px 16px;
  344 + border: 3px solid #000;
  345 + border-radius: 12px;
  346 + background: var(--accent);
  347 + color: var(--ink);
  348 + box-shadow: var(--shadow);
235 } 349 }
  350 +.chat-input-row button:active { transform: translate(2px, 2px); box-shadow: 2px 2px 0 #000; }
236 .chat-input-row button:disabled { opacity: .5; cursor: not-allowed; } 351 .chat-input-row button:disabled { opacity: .5; cursor: not-allowed; }
237 -.say-hint { padding: 0 14px 10px; font-size: 11.5px; font-weight: 700; color: var(--muted); min-height: 1.4em; } 352 +.say-hint { padding: 2px 4px 0; font-size: 11.5px; font-weight: bold; color: var(--muted); min-height: 1.4em; }
238 353
239 /* ---- nickname modal ---- */ 354 /* ---- nickname modal ---- */
240 .nickname-modal { 355 .nickname-modal {
@@ -244,57 +359,66 @@ body { @@ -244,57 +359,66 @@ body {
244 display: flex; 359 display: flex;
245 align-items: center; 360 align-items: center;
246 justify-content: center; 361 justify-content: center;
247 - background: rgba(0,0,0,.7); 362 + background: rgba(0, 0, 0, .7);
248 } 363 }
249 .nickname-box { 364 .nickname-box {
250 background: #fff; 365 background: #fff;
251 - color: var(--accent-text);  
252 - border-radius: 16px;  
253 - padding: 20px;  
254 - width: 260px; 366 + color: var(--ink);
  367 + border: 3px solid #000;
  368 + border-radius: 12px;
  369 + box-shadow: 6px 6px 0 #000;
  370 + padding: 22px;
  371 + width: 280px;
255 display: flex; 372 display: flex;
256 flex-direction: column; 373 flex-direction: column;
257 - gap: 10px; 374 + gap: 12px;
258 } 375 }
259 -.nickname-title { font-weight: 700; font-size: 14px; } 376 +.nickname-title { font-weight: bold; font-size: 15px; }
260 .nickname-box input { 377 .nickname-box input {
261 - border: 1px solid #ddd;  
262 - border-radius: 10px;  
263 - padding: 8px 12px;  
264 - font-size: 13px;  
265 - font-family: inherit; 378 + font: bold 16px Tahoma, sans-serif;
  379 + border: 3px solid #000;
  380 + border-radius: 12px;
  381 + padding: 9px 13px;
  382 + box-shadow: var(--shadow);
  383 + outline: none;
266 } 384 }
267 .nickname-box button { 385 .nickname-box button {
  386 + font: bold 15px Tahoma, sans-serif;
268 background: var(--accent); 387 background: var(--accent);
269 - color: var(--accent-text);  
270 - border: none;  
271 - border-radius: 999px; 388 + color: var(--ink);
  389 + border: 3px solid #000;
  390 + border-radius: 12px;
272 padding: 9px 0; 391 padding: 9px 0;
273 - font-weight: 700;  
274 - font-size: 13px; 392 + box-shadow: var(--shadow);
275 cursor: pointer; 393 cursor: pointer;
276 } 394 }
  395 +.nickname-box button:active { transform: translate(2px, 2px); box-shadow: 2px 2px 0 #000; }
277 396
278 /* ---- mobile sub-tabs (live mode only) ---- */ 397 /* ---- mobile sub-tabs (live mode only) ---- */
279 .mobile-subtabs { 398 .mobile-subtabs {
280 display: none; 399 display: none;
281 - border-top: 1px solid var(--border); 400 + border-top: 1px solid var(--divider);
282 flex: 0 0 auto; 401 flex: 0 0 auto;
283 background: var(--panel); 402 background: var(--panel);
  403 + gap: 8px;
  404 + padding: 8px;
284 } 405 }
285 .mobile-subtabs button { 406 .mobile-subtabs button {
286 flex: 1; 407 flex: 1;
287 - background: transparent;  
288 - border: none;  
289 - color: var(--muted);  
290 - font-weight: 700;  
291 - padding: 11px 0;  
292 - font-size: 13px; 408 + font: bold 13px Tahoma, sans-serif;
  409 + background: #fff;
  410 + border: 3px solid #000;
  411 + color: var(--ink);
  412 + border-radius: 12px;
  413 + padding: 9px 0;
  414 + box-shadow: var(--shadow-sm);
293 cursor: pointer; 415 cursor: pointer;
294 } 416 }
295 -.mobile-subtabs button.active { color: #fff; box-shadow: inset 0 -2px 0 var(--accent); } 417 +.mobile-subtabs button.active { background: var(--accent); }
296 418
297 @media (max-width: 768px) { 419 @media (max-width: 768px) {
  420 + .topbar { flex-wrap: wrap; row-gap: 8px; }
  421 + .topbar .logo { font-size: 18px; }
298 .body { flex-direction: column; } 422 .body { flex-direction: column; }
299 .player-col { order: 1; flex: 0 0 46vh; } 423 .player-col { order: 1; flex: 0 0 46vh; }
300 .mobile-subtabs { display: flex; order: 2; } 424 .mobile-subtabs { display: flex; order: 2; }
@@ -306,4 +430,5 @@ body { @@ -306,4 +430,5 @@ body {
306 flex: 1; 430 flex: 1;
307 } 431 }
308 .left-col.mobile-inactive, .right-col.mobile-inactive { display: none; } 432 .left-col.mobile-inactive, .right-col.mobile-inactive { display: none; }
  433 + .now-playing-box { font-size: 11px; max-width: calc(100% - 28px); }
309 } 434 }
live.html
@@ -20,22 +20,25 @@ @@ -20,22 +20,25 @@
20 </div> 20 </div>
21 <div class="spacer"></div> 21 <div class="spacer"></div>
22 <div class="watching" id="watchingCount" hidden></div> 22 <div class="watching" id="watchingCount" hidden></div>
  23 + <button class="topbar-pill" id="chatToggleBtn">✕ 聊天</button>
  24 + <button class="topbar-pill" id="muteBtn">🔇 静音</button>
23 </header> 25 </header>
24 26
25 <div class="body" id="body"> 27 <div class="body" id="body">
26 <aside class="left-col" id="leftCol"> 28 <aside class="left-col" id="leftCol">
27 - <div class="section-title" id="listTitle">片段列表</div>  
28 <div class="clip-list" id="clipList"></div> 29 <div class="clip-list" id="clipList"></div>
  30 + <div class="site-credit">🍋 <span>AI 短剧频道</span></div>
29 </aside> 31 </aside>
30 32
31 <div class="player-col"> 33 <div class="player-col">
32 <div class="player-wrap"> 34 <div class="player-wrap">
33 - <div class="now-playing-bar">  
34 - <span id="liveDot" hidden>🔴 直播中 ·</span>  
35 - <span id="nowPlayingText">加载中…</span> 35 + <div class="live-pill" id="liveDot" hidden><span class="dot"></span>直播中</div>
  36 + <div class="now-playing-box" id="nowPlayingBox" hidden>
  37 + <span class="np-nick" id="nowPlayingNick"></span>
  38 + <span class="np-time" id="nowPlayingTime"></span>
  39 + <div class="np-text" id="nowPlayingText">加载中…</div>
36 </div> 40 </div>
37 <video id="player" autoplay muted playsinline></video> 41 <video id="player" autoplay muted playsinline></video>
38 - <button class="mute-btn" id="muteBtn">🔇</button>  
39 </div> 42 </div>
40 </div> 43 </div>
41 44
@@ -44,7 +47,7 @@ @@ -44,7 +47,7 @@
44 <div class="chat-list" id="chatList"></div> 47 <div class="chat-list" id="chatList"></div>
45 <div class="chat-identity-row" id="chatIdentityRow" hidden> 48 <div class="chat-identity-row" id="chatIdentityRow" hidden>
46 <span id="currentNickname"></span> 49 <span id="currentNickname"></span>
47 - <button id="changeNameBtn">change name</button> 50 + <button id="changeNameBtn">改昵称</button>
48 </div> 51 </div>
49 <div class="chat-input-row"> 52 <div class="chat-input-row">
50 <input type="text" id="chatInput" placeholder="说点什么,或者想看什么…" maxlength="300" /> 53 <input type="text" id="chatInput" placeholder="说点什么,或者想看什么…" maxlength="300" />
@@ -83,7 +86,9 @@ let mobileSub = &quot;queue&quot;; @@ -83,7 +86,9 @@ let mobileSub = &quot;queue&quot;;
83 86
84 const player = document.getElementById("player"); 87 const player = document.getElementById("player");
85 const clipList = document.getElementById("clipList"); 88 const clipList = document.getElementById("clipList");
86 -const listTitle = document.getElementById("listTitle"); 89 +const nowPlayingBox = document.getElementById("nowPlayingBox");
  90 +const nowPlayingNick = document.getElementById("nowPlayingNick");
  91 +const nowPlayingTime = document.getElementById("nowPlayingTime");
87 const nowPlayingText = document.getElementById("nowPlayingText"); 92 const nowPlayingText = document.getElementById("nowPlayingText");
88 const liveDot = document.getElementById("liveDot"); 93 const liveDot = document.getElementById("liveDot");
89 const leftCol = document.getElementById("leftCol"); 94 const leftCol = document.getElementById("leftCol");
@@ -95,6 +100,7 @@ const chatSendBtn = document.getElementById(&quot;chatSendBtn&quot;); @@ -95,6 +100,7 @@ const chatSendBtn = document.getElementById(&quot;chatSendBtn&quot;);
95 const chatHint = document.getElementById("chatHint"); 100 const chatHint = document.getElementById("chatHint");
96 const watchingCount = document.getElementById("watchingCount"); 101 const watchingCount = document.getElementById("watchingCount");
97 const muteBtn = document.getElementById("muteBtn"); 102 const muteBtn = document.getElementById("muteBtn");
  103 +const chatToggleBtn = document.getElementById("chatToggleBtn");
98 const nicknameModal = document.getElementById("nicknameModal"); 104 const nicknameModal = document.getElementById("nicknameModal");
99 const nicknameInput = document.getElementById("nicknameInput"); 105 const nicknameInput = document.getElementById("nicknameInput");
100 const nicknameConfirmBtn = document.getElementById("nicknameConfirmBtn"); 106 const nicknameConfirmBtn = document.getElementById("nicknameConfirmBtn");
@@ -105,7 +111,14 @@ const clientId = Math.random().toString(36).slice(2); @@ -105,7 +111,14 @@ const clientId = Math.random().toString(36).slice(2);
105 111
106 muteBtn.addEventListener("click", () => { 112 muteBtn.addEventListener("click", () => {
107 player.muted = !player.muted; 113 player.muted = !player.muted;
108 - muteBtn.textContent = player.muted ? "🔇" : "🔈"; 114 + muteBtn.textContent = player.muted ? "🔇 静音" : "🔈 有声";
  115 +});
  116 +
  117 +let chatClosed = false;
  118 +chatToggleBtn.addEventListener("click", () => {
  119 + chatClosed = !chatClosed;
  120 + chatToggleBtn.textContent = chatClosed ? "聊天" : "✕ 聊天";
  121 + if (mode === "live") rightCol.hidden = chatClosed;
109 }); 122 });
110 123
111 function fmtMeta(c) { 124 function fmtMeta(c) {
@@ -116,6 +129,16 @@ function escapeHtml(s) { @@ -116,6 +129,16 @@ function escapeHtml(s) {
116 div.textContent = s || ""; 129 div.textContent = s || "";
117 return div.innerHTML; 130 return div.innerHTML;
118 } 131 }
  132 +function fmtClock(ts) {
  133 + return new Date(ts).toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit" });
  134 +}
  135 +// Same per-nickname pastel-hash used by infiniteslop.ai — a stable, deterministic
  136 +// color per person without needing a server-assigned palette.
  137 +function pastel(name) {
  138 + let h = 0;
  139 + for (const c of name || "") h = (h * 31 + c.charCodeAt(0)) % 360;
  140 + return `hsl(${h},85%,85%)`;
  141 +}
119 142
120 // ---- viewer identity: nickname + uid, stored in cookies ---- 143 // ---- viewer identity: nickname + uid, stored in cookies ----
121 function getCookie(name) { 144 function getCookie(name) {
@@ -187,10 +210,10 @@ updateNicknameLabel(); @@ -187,10 +210,10 @@ updateNicknameLabel();
187 210
188 function renderBrowseList() { 211 function renderBrowseList() {
189 if (clips.length === 0) { 212 if (clips.length === 0) {
190 - clipList.innerHTML = `<div class="empty-hint">片段库为空</div>`; 213 + clipList.innerHTML = `<div class="section-head">片段列表</div><div class="empty-hint">片段库为空</div>`;
191 return; 214 return;
192 } 215 }
193 - clipList.innerHTML = clips 216 + const rows = clips
194 .map( 217 .map(
195 (c, i) => ` 218 (c, i) => `
196 <div class="clip-row ${i === currentIndex ? "active" : ""}" data-i="${i}"> 219 <div class="clip-row ${i === currentIndex ? "active" : ""}" data-i="${i}">
@@ -199,6 +222,7 @@ function renderBrowseList() { @@ -199,6 +222,7 @@ function renderBrowseList() {
199 </div>` 222 </div>`
200 ) 223 )
201 .join(""); 224 .join("");
  225 + clipList.innerHTML = `<div class="section-head">片段列表</div>${rows}`;
202 clipList.querySelectorAll(".clip-row").forEach((row) => { 226 clipList.querySelectorAll(".clip-row").forEach((row) => {
203 row.addEventListener("click", (e) => { 227 row.addEventListener("click", (e) => {
204 if (e.target.dataset.likes) return; 228 if (e.target.dataset.likes) return;
@@ -215,13 +239,22 @@ function renderBrowseList() { @@ -215,13 +239,22 @@ function renderBrowseList() {
215 }); 239 });
216 } 240 }
217 241
  242 +function setNowPlaying(nick, time, text) {
  243 + nowPlayingBox.hidden = false;
  244 + nowPlayingNick.hidden = !nick;
  245 + nowPlayingNick.textContent = nick || "";
  246 + nowPlayingTime.hidden = !time;
  247 + nowPlayingTime.textContent = time || "";
  248 + nowPlayingText.textContent = text;
  249 +}
  250 +
218 function playBrowse(index) { 251 function playBrowse(index) {
219 if (index < 0 || index >= clips.length) return; 252 if (index < 0 || index >= clips.length) return;
220 currentIndex = index; 253 currentIndex = index;
221 const c = clips[index]; 254 const c = clips[index];
222 player.src = `/lib/video/${c.id}`; 255 player.src = `/lib/video/${c.id}`;
223 player.play().catch(() => {}); 256 player.play().catch(() => {});
224 - nowPlayingText.textContent = c.prompt; 257 + setNowPlaying(null, null, c.prompt);
225 renderBrowseList(); 258 renderBrowseList();
226 } 259 }
227 260
@@ -237,34 +270,85 @@ async function loadBrowse(sort) { @@ -237,34 +270,85 @@ async function loadBrowse(sort) {
237 if (clips.length) playBrowse(0); 270 if (clips.length) playBrowse(0);
238 } 271 }
239 272
240 -// Left queue: prompt + who asked for it only — no resolution/duration/date. 273 +// Left queue, grouped like infiniteslop.ai: 接下来播放 (already scheduled) /
  274 +// 生成中 (mid-generation) / 排队中 (waiting their turn — votable).
241 function renderLiveList(state) { 275 function renderLiveList(state) {
242 - listTitle.textContent = "排队队列";  
243 const upcoming = state.upNext || []; 276 const upcoming = state.upNext || [];
244 const queue = state.queue || []; 277 const queue = state.queue || [];
245 - const statusLabel = { generating: "生成中…", matched: "即将播放", failed: "❌ 生成失败" };  
246 - const queueHtml = queue 278 + const generating = queue.filter((q) => q.status === "generating");
  279 + const waiting = queue.filter((q) => q.status === "matched" || q.status === "ready");
  280 + const failed = queue.filter((q) => q.status === "failed");
  281 +
  282 + const upcomingHtml = upcoming
247 .map( 283 .map(
248 - (q) => ` 284 + (c) => `
249 <div class="clip-row"> 285 <div class="clip-row">
  286 + <div class="prompt">${escapeHtml(c.prompt)}</div>
  287 + ${c.requestedBy ? `<div class="meta">by ${escapeHtml(c.requestedBy)}</div>` : ""}
  288 + </div>`
  289 + )
  290 + .join("");
  291 + const generatingHtml = generating
  292 + .map(
  293 + (q) => `
  294 + <div class="clip-row gen">
250 <div class="prompt">💬 ${escapeHtml(q.prompt)}</div> 295 <div class="prompt">💬 ${escapeHtml(q.prompt)}</div>
251 - <div class="meta">${q.nickname ? `${escapeHtml(q.nickname)} · ` : ""}${statusLabel[q.status] || q.status}</div> 296 + <div class="meta">${q.nickname ? `${escapeHtml(q.nickname)} · ` : ""}生成中…</div>
252 </div>` 297 </div>`
253 ) 298 )
254 .join(""); 299 .join("");
255 - const upcomingHtml = upcoming 300 + const waitingHtml = waiting
256 .map( 301 .map(
257 - (c) => `  
258 - <div class="clip-row">  
259 - <div class="prompt">${escapeHtml(c.prompt)}</div>  
260 - ${c.requestedBy ? `<div class="meta">by ${escapeHtml(c.requestedBy)}</div>` : ""} 302 + (q) => `
  303 + <div class="qrow">
  304 + <div class="clip-row">
  305 + <div class="prompt">💬 ${escapeHtml(q.prompt)}</div>
  306 + <div class="meta">${q.nickname ? `${escapeHtml(q.nickname)} · ` : ""}即将播放</div>
  307 + </div>
  308 + <button class="up-btn ${q.voted ? "voted" : ""}" data-vote="${q.id}">▲<span>${q.votes || 0}</span></button>
261 </div>` 309 </div>`
262 ) 310 )
263 .join(""); 311 .join("");
264 - clipList.innerHTML = queueHtml + upcomingHtml || `<div class="empty-hint">暂无排队</div>`; 312 + const failedHtml = failed
  313 + .map(
  314 + (q) => `
  315 + <div class="clip-row failed">
  316 + <div class="prompt">💬 ${escapeHtml(q.prompt)}</div>
  317 + <div class="meta">${q.nickname ? `${escapeHtml(q.nickname)} · ` : ""}❌ 生成失败</div>
  318 + </div>`
  319 + )
  320 + .join("");
  321 +
  322 + clipList.innerHTML =
  323 + (upcomingHtml ? `<div class="section-head">接下来播放</div>${upcomingHtml}` : "") +
  324 + (generatingHtml ? `<div class="section-head">生成中</div>${generatingHtml}` : "") +
  325 + (waitingHtml || failedHtml ? `<div class="section-head">排队中</div>${waitingHtml}${failedHtml}` : "") ||
  326 + `<div class="empty-hint">暂无排队</div>`;
  327 +
  328 + clipList.querySelectorAll("[data-vote]").forEach((btn) => {
  329 + btn.addEventListener("click", () => voteQueueItem(btn.dataset.vote, btn));
  330 + });
  331 +}
  332 +
  333 +async function voteQueueItem(id, btn) {
  334 + const identity = await ensureIdentity();
  335 + btn.disabled = true;
  336 + try {
  337 + const res = await fetch(`/api/queue/vote/${id}`, {
  338 + method: "POST",
  339 + headers: { "Content-Type": "application/json" },
  340 + body: JSON.stringify({ uid: identity.uid }),
  341 + });
  342 + if (!res.ok) return;
  343 + const data = await res.json();
  344 + btn.classList.toggle("voted", data.voted);
  345 + btn.querySelector("span").textContent = data.votes;
  346 + } finally {
  347 + btn.disabled = false;
  348 + }
265 } 349 }
266 350
267 -function switchToClip(clip, offsetSec) { 351 +function switchToClip(clip, offsetSec, requestedBy) {
268 currentClipId = clip.id; 352 currentClipId = clip.id;
269 player.src = `/lib/video/${clip.id}`; 353 player.src = `/lib/video/${clip.id}`;
270 if (offsetSec > 0) { 354 if (offsetSec > 0) {
@@ -277,12 +361,13 @@ function switchToClip(clip, offsetSec) { @@ -277,12 +361,13 @@ function switchToClip(clip, offsetSec) {
277 ); 361 );
278 } 362 }
279 player.play().catch(() => {}); 363 player.play().catch(() => {});
280 - nowPlayingText.textContent = clip.prompt; 364 + setNowPlaying(requestedBy, fmtClock(Date.now()), clip.prompt);
281 } 365 }
282 366
283 async function pollLive() { 367 async function pollLive() {
284 try { 368 try {
285 - const res = await fetch(`/api/live/state?cid=${clientId}`); 369 + const identity = getIdentity();
  370 + const res = await fetch(`/api/live/state?cid=${clientId}${identity ? `&uid=${encodeURIComponent(identity.uid)}` : ""}`);
286 const state = await res.json(); 371 const state = await res.json();
287 if (mode !== "live") return; 372 if (mode !== "live") return;
288 watchingCount.hidden = false; 373 watchingCount.hidden = false;
@@ -294,14 +379,14 @@ async function pollLive() { @@ -294,14 +379,14 @@ async function pollLive() {
294 if (state.current) { 379 if (state.current) {
295 if (state.current.clip.id !== currentClipId) { 380 if (state.current.clip.id !== currentClipId) {
296 const offsetSec = Math.max(0, (state.now - state.current.startAt) / 1000); 381 const offsetSec = Math.max(0, (state.now - state.current.startAt) / 1000);
297 - switchToClip(state.current.clip, offsetSec); 382 + switchToClip(state.current.clip, offsetSec, state.current.requestedBy);
298 } 383 }
299 // Fire the switch to the next clip exactly when this one should end, 384 // Fire the switch to the next clip exactly when this one should end,
300 // instead of waiting for the next 4s poll to notice — the poll still 385 // instead of waiting for the next 4s poll to notice — the poll still
301 // runs on schedule and will correct any drift. 386 // runs on schedule and will correct any drift.
302 if (upNextCache.length) { 387 if (upNextCache.length) {
303 const msUntilEnd = state.current.endAt - Date.now(); 388 const msUntilEnd = state.current.endAt - Date.now();
304 - advanceTimer = setTimeout(() => switchToClip(upNextCache[0], 0), Math.max(0, msUntilEnd)); 389 + advanceTimer = setTimeout(() => switchToClip(upNextCache[0], 0, upNextCache[0].requestedBy), Math.max(0, msUntilEnd));
305 } 390 }
306 } 391 }
307 } catch { 392 } catch {
@@ -315,7 +400,7 @@ function renderChat(messages) { @@ -315,7 +400,7 @@ function renderChat(messages) {
315 chatList.innerHTML = messages 400 chatList.innerHTML = messages
316 .map((m) => { 401 .map((m) => {
317 const status = m.status && chatStatusLabel[m.status] ? `<span class="chat-status">${chatStatusLabel[m.status]}</span>` : ""; 402 const status = m.status && chatStatusLabel[m.status] ? `<span class="chat-status">${chatStatusLabel[m.status]}</span>` : "";
318 - return `<div class="chat-msg"><span class="chat-nick">${escapeHtml(m.nickname)}</span><span class="chat-text">${escapeHtml(m.text)}</span>${status}</div>`; 403 + return `<div class="chat-msg" style="background:${pastel(m.nickname)}"><b class="chat-nick">${escapeHtml(m.nickname)}</b><span class="chat-text">${escapeHtml(m.text)}</span>${status}</div>`;
319 }) 404 })
320 .join(""); 405 .join("");
321 if (atBottom) chatList.scrollTop = chatList.scrollHeight; 406 if (atBottom) chatList.scrollTop = chatList.scrollHeight;
@@ -378,9 +463,10 @@ async function setMode(newMode) { @@ -378,9 +463,10 @@ async function setMode(newMode) {
378 clearInterval(chatPollTimer); 463 clearInterval(chatPollTimer);
379 clearTimeout(advanceTimer); 464 clearTimeout(advanceTimer);
380 currentClipId = null; 465 currentClipId = null;
  466 + chatToggleBtn.hidden = newMode !== "live";
381 if (newMode === "live") { 467 if (newMode === "live") {
382 liveDot.hidden = false; 468 liveDot.hidden = false;
383 - rightCol.hidden = false; 469 + rightCol.hidden = chatClosed;
384 mobileSubtabs.hidden = false; 470 mobileSubtabs.hidden = false;
385 applyMobileSub(); 471 applyMobileSub();
386 await Promise.all([pollLive(), pollChat()]); 472 await Promise.all([pollLive(), pollChat()]);
@@ -392,7 +478,6 @@ async function setMode(newMode) { @@ -392,7 +478,6 @@ async function setMode(newMode) {
392 mobileSubtabs.hidden = true; 478 mobileSubtabs.hidden = true;
393 watchingCount.hidden = true; 479 watchingCount.hidden = true;
394 leftCol.classList.remove("mobile-inactive"); 480 leftCol.classList.remove("mobile-inactive");
395 - listTitle.textContent = "片段列表";  
396 await loadBrowse(newMode); 481 await loadBrowse(newMode);
397 } 482 }
398 } 483 }
server.js
@@ -134,7 +134,7 @@ function updateChatStatus(id, status) { @@ -134,7 +134,7 @@ function updateChatStatus(id, status) {
134 // e.g. testing) — looks up a library match or kicks off generation, exactly 134 // e.g. testing) — looks up a library match or kicks off generation, exactly
135 // like before chat existed. `nickname` is optional (empty for /api/prompt). 135 // like before chat existed. `nickname` is optional (empty for /api/prompt).
136 function submitPromptToQueue(id, prompt, nickname) { 136 function submitPromptToQueue(id, prompt, nickname) {
137 - const entry = { id, prompt, nickname: nickname || null, submittedAt: Date.now() }; 137 + const entry = { id, prompt, nickname: nickname || null, submittedAt: Date.now(), votes: [] };
138 const match = findLibraryMatch(normalizePrompt(prompt)); 138 const match = findLibraryMatch(normalizePrompt(prompt));
139 if (match) { 139 if (match) {
140 entry.status = "matched"; 140 entry.status = "matched";
@@ -184,13 +184,33 @@ function markPlayed(id) { @@ -184,13 +184,33 @@ function markPlayed(id) {
184 // just grows forever and duplicates the same info. 184 // just grows forever and duplicates the same info.
185 // Returns {clip, requestedBy, chatId} — chatId lets the caller flip the 185 // Returns {clip, requestedBy, chatId} — chatId lets the caller flip the
186 // originating chat message to "scheduled" once it's actually about to air. 186 // originating chat message to "scheduled" once it's actually about to air.
  187 +// Among entries of the same status, the most-upvoted prompt goes first
  188 +// (ties broken by submission order) — lets chat bump a favorite to the
  189 +// front of the line instead of strict FIFO.
  190 +function voteCount(q) {
  191 + return (q.votes || []).length;
  192 +}
  193 +function pickBestIndexByStatus(status) {
  194 + let bestIdx = -1;
  195 + for (let i = 0; i < promptQueue.length; i++) {
  196 + const q = promptQueue[i];
  197 + if (q.status !== status) continue;
  198 + if (bestIdx === -1) {
  199 + bestIdx = i;
  200 + continue;
  201 + }
  202 + const best = promptQueue[bestIdx];
  203 + if (voteCount(q) > voteCount(best)) bestIdx = i;
  204 + }
  205 + return bestIdx;
  206 +}
187 function pickNextClip() { 207 function pickNextClip() {
188 - const readyIdx = promptQueue.findIndex((q) => q.status === "ready"); 208 + const readyIdx = pickBestIndexByStatus("ready");
189 if (readyIdx !== -1) { 209 if (readyIdx !== -1) {
190 const q = promptQueue.splice(readyIdx, 1)[0]; 210 const q = promptQueue.splice(readyIdx, 1)[0];
191 return { clip: q.clip, requestedBy: q.nickname, chatId: q.id }; 211 return { clip: q.clip, requestedBy: q.nickname, chatId: q.id };
192 } 212 }
193 - const matchedIdx = promptQueue.findIndex((q) => q.status === "matched"); 213 + const matchedIdx = pickBestIndexByStatus("matched");
194 if (matchedIdx !== -1) { 214 if (matchedIdx !== -1) {
195 const q = promptQueue.splice(matchedIdx, 1)[0]; 215 const q = promptQueue.splice(matchedIdx, 1)[0];
196 return { clip: q.clip, requestedBy: q.nickname, chatId: q.id }; 216 return { clip: q.clip, requestedBy: q.nickname, chatId: q.id };
@@ -356,7 +376,9 @@ http @@ -356,7 +376,9 @@ http
356 if (pathname === "/api/live/state") { 376 if (pathname === "/api/live/state") {
357 ensureSchedule(); 377 ensureSchedule();
358 const now = Date.now(); 378 const now = Date.now();
359 - const cid = new URL(req.url, "http://x").searchParams.get("cid"); 379 + const params = new URL(req.url, "http://x").searchParams;
  380 + const cid = params.get("cid");
  381 + const uid = params.get("uid") || null;
360 if (cid) viewers.set(cid, now); 382 if (cid) viewers.set(cid, now);
361 let idx = schedule.findIndex((s) => s.startAt <= now && now < s.endAt); 383 let idx = schedule.findIndex((s) => s.startAt <= now && now < s.endAt);
362 if (idx === -1) idx = schedule.length - 1; 384 if (idx === -1) idx = schedule.length - 1;
@@ -370,7 +392,17 @@ http @@ -370,7 +392,17 @@ http
370 upNext: schedule.slice(idx + 1, idx + 4).map((s) => ({ ...s.clip, requestedBy: s.requestedBy || null })), 392 upNext: schedule.slice(idx + 1, idx + 4).map((s) => ({ ...s.clip, requestedBy: s.requestedBy || null })),
371 queue: promptQueue 393 queue: promptQueue
372 .filter((q) => ["matched", "generating", "failed"].includes(q.status)) 394 .filter((q) => ["matched", "generating", "failed"].includes(q.status))
373 - .map((q) => ({ prompt: q.prompt, nickname: q.nickname, status: q.status, error: q.error })), 395 + .slice()
  396 + .sort((a, b) => voteCount(b) - voteCount(a))
  397 + .map((q) => ({
  398 + id: q.id,
  399 + prompt: q.prompt,
  400 + nickname: q.nickname,
  401 + status: q.status,
  402 + error: q.error,
  403 + votes: voteCount(q),
  404 + voted: uid ? (q.votes || []).includes(uid) : false,
  405 + })),
374 }) 406 })
375 ); 407 );
376 return; 408 return;
@@ -546,6 +578,38 @@ http @@ -546,6 +578,38 @@ http
546 return; 578 return;
547 } 579 }
548 580
  581 + if (pathname.startsWith("/api/queue/vote/") && req.method === "POST") {
  582 + const id = pathname.slice("/api/queue/vote/".length);
  583 + readJsonBody(req)
  584 + .then((body) => {
  585 + const uid = (body.uid || "").trim();
  586 + if (!uid) {
  587 + res.writeHead(400, { "Content-Type": "application/json" });
  588 + res.end(JSON.stringify({ error: "uid required" }));
  589 + return;
  590 + }
  591 + const entry = promptQueue.find((q) => q.id === id);
  592 + if (!entry || !["matched", "generating", "ready"].includes(entry.status)) {
  593 + res.writeHead(404, { "Content-Type": "application/json" });
  594 + res.end(JSON.stringify({ error: "not found" }));
  595 + return;
  596 + }
  597 + if (!Array.isArray(entry.votes)) entry.votes = [];
  598 + const i = entry.votes.indexOf(uid);
  599 + const voted = i === -1;
  600 + if (voted) entry.votes.push(uid);
  601 + else entry.votes.splice(i, 1);
  602 + saveLiveState();
  603 + res.writeHead(200, { "Content-Type": "application/json" });
  604 + res.end(JSON.stringify({ votes: entry.votes.length, voted }));
  605 + })
  606 + .catch(() => {
  607 + res.writeHead(400, { "Content-Type": "application/json" });
  608 + res.end(JSON.stringify({ error: "invalid JSON body" }));
  609 + });
  610 + return;
  611 + }
  612 +
549 if (pathname.startsWith("/api/like/") && req.method === "POST") { 613 if (pathname.startsWith("/api/like/") && req.method === "POST") {
550 const id = pathname.slice("/api/like/".length); 614 const id = pathname.slice("/api/like/".length);
551 const lib = getLibrary(); 615 const lib = getLibrary();