Ron Au commited on
Commit
5c239ba
1 Parent(s): 8a661fa
README.md CHANGED
@@ -1,12 +1,9 @@
1
  ---
2
- title: Ai Pokemon Card
3
- emoji: 📚
4
- colorFrom: green
5
  colorTo: yellow
6
  sdk: gradio
7
  app_file: app.py
8
  pinned: false
9
- license: mit
10
  ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces#reference
 
1
  ---
2
+ title: This Pokémon Does Not Exist
3
+ emoji: 🧬
4
+ colorFrom: blue
5
  colorTo: yellow
6
  sdk: gradio
7
  app_file: app.py
8
  pinned: false
 
9
  ---
 
 
app.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import time
2
+ from flask import Flask, jsonify, render_template, request
3
+
4
+ from modules.details import load_lists, rand_details
5
+ from modules.inference import generate_image
6
+
7
+ app = Flask(__name__)
8
+ app.config['TEMPLATES_AUTO_RELOAD'] = True
9
+
10
+
11
+ @app.route('/')
12
+ def index():
13
+ return render_template('index.html', **rand_details())
14
+
15
+
16
+ tasks = {}
17
+
18
+
19
+ @app.route('/task/create')
20
+ def create_task():
21
+ prompt = request.args.get('prompt') or "покемон"
22
+
23
+ task_id = f"{str(time.time())}_{prompt}"
24
+
25
+ tasks[task_id] = {
26
+ "task_id": task_id,
27
+ "prompt": prompt,
28
+ "status": "pending",
29
+ "poll_count": 0,
30
+ }
31
+
32
+ return jsonify(tasks[task_id])
33
+
34
+
35
+ @app.route('/task/queue')
36
+ def queue_task():
37
+ task_id = request.args.get('task_id')
38
+
39
+ tasks[task_id]["value"] = generate_image(tasks[task_id]["prompt"])
40
+
41
+ tasks[task_id]["status"] = "complete"
42
+
43
+ return jsonify(tasks[task_id])
44
+
45
+
46
+ @app.route('/task/poll')
47
+ def poll_task():
48
+ task_id = request.args.get('task_id')
49
+
50
+ tasks[task_id]["poll_count"] += 1
51
+
52
+ return jsonify(tasks[task_id])
53
+
54
+
55
+ @app.route('/details')
56
+ def generate_details():
57
+ return jsonify(rand_details())
58
+
59
+
60
+ if __name__ == '__main__':
61
+ app.run(host='0.0.0.0', port=7860)
lists/attacks.json ADDED
The diff for this file is too large to render. See raw diff
 
lists/descriptions.json ADDED
The diff for this file is too large to render. See raw diff
 
lists/names.json ADDED
@@ -0,0 +1,907 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ "Bulbasaur",
3
+ "Ivysaur",
4
+ "Venusaur",
5
+ "Charmander",
6
+ "Charmeleon",
7
+ "Charizard",
8
+ "Squirtle",
9
+ "Wartortle",
10
+ "Blastoise",
11
+ "Caterpie",
12
+ "Metapod",
13
+ "Butterfree",
14
+ "Weedle",
15
+ "Kakuna",
16
+ "Beedrill",
17
+ "Pidgey",
18
+ "Pidgeotto",
19
+ "Pidgeot",
20
+ "Rattata",
21
+ "Raticate",
22
+ "Spearow",
23
+ "Fearow",
24
+ "Ekans",
25
+ "Arbok",
26
+ "Pikachu",
27
+ "Raichu",
28
+ "Sandshrew",
29
+ "Sandslash",
30
+ "Nidoran♀",
31
+ "Nidorina",
32
+ "Nidoqueen",
33
+ "Nidoran♂",
34
+ "Nidorino",
35
+ "Nidoking",
36
+ "Clefairy",
37
+ "Clefable",
38
+ "Vulpix",
39
+ "Ninetales",
40
+ "Jigglypuff",
41
+ "Wigglytuff",
42
+ "Zubat",
43
+ "Golbat",
44
+ "Oddish",
45
+ "Gloom",
46
+ "Vileplume",
47
+ "Paras",
48
+ "Parasect",
49
+ "Venonat",
50
+ "Venomoth",
51
+ "Diglett",
52
+ "Dugtrio",
53
+ "Meowth",
54
+ "Persian",
55
+ "Psyduck",
56
+ "Golduck",
57
+ "Mankey",
58
+ "Primeape",
59
+ "Growlithe",
60
+ "Arcanine",
61
+ "Poliwag",
62
+ "Poliwhirl",
63
+ "Poliwrath",
64
+ "Abra",
65
+ "Kadabra",
66
+ "Alakazam",
67
+ "Machop",
68
+ "Machoke",
69
+ "Machamp",
70
+ "Bellsprout",
71
+ "Weepinbell",
72
+ "Victreebel",
73
+ "Tentacool",
74
+ "Tentacruel",
75
+ "Geodude",
76
+ "Graveler",
77
+ "Golem",
78
+ "Ponyta",
79
+ "Rapidash",
80
+ "Slowpoke",
81
+ "Slowbro",
82
+ "Magnemite",
83
+ "Magneton",
84
+ "Farfetch'd",
85
+ "Doduo",
86
+ "Dodrio",
87
+ "Seel",
88
+ "Dewgong",
89
+ "Grimer",
90
+ "Muk",
91
+ "Shellder",
92
+ "Cloyster",
93
+ "Gastly",
94
+ "Haunter",
95
+ "Gengar",
96
+ "Onix",
97
+ "Drowzee",
98
+ "Hypno",
99
+ "Krabby",
100
+ "Kingler",
101
+ "Voltorb",
102
+ "Electrode",
103
+ "Exeggcute",
104
+ "Exeggutor",
105
+ "Cubone",
106
+ "Marowak",
107
+ "Hitmonlee",
108
+ "Hitmonchan",
109
+ "Lickitung",
110
+ "Koffing",
111
+ "Weezing",
112
+ "Rhyhorn",
113
+ "Rhydon",
114
+ "Chansey",
115
+ "Tangela",
116
+ "Kangaskhan",
117
+ "Horsea",
118
+ "Seadra",
119
+ "Goldeen",
120
+ "Seaking",
121
+ "Staryu",
122
+ "Starmie",
123
+ "Mr. Mime",
124
+ "Scyther",
125
+ "Jynx",
126
+ "Electabuzz",
127
+ "Magmar",
128
+ "Pinsir",
129
+ "Tauros",
130
+ "Magikarp",
131
+ "Gyarados",
132
+ "Lapras",
133
+ "Ditto",
134
+ "Eevee",
135
+ "Vaporeon",
136
+ "Jolteon",
137
+ "Flareon",
138
+ "Porygon",
139
+ "Omanyte",
140
+ "Omastar",
141
+ "Kabuto",
142
+ "Kabutops",
143
+ "Aerodactyl",
144
+ "Snorlax",
145
+ "Articuno",
146
+ "Zapdos",
147
+ "Moltres",
148
+ "Dratini",
149
+ "Dragonair",
150
+ "Dragonite",
151
+ "Mewtwo",
152
+ "Mew",
153
+ "Chikorita",
154
+ "Bayleef",
155
+ "Meganium",
156
+ "Cyndaquil",
157
+ "Quilava",
158
+ "Typhlosion",
159
+ "Totodile",
160
+ "Croconaw",
161
+ "Feraligatr",
162
+ "Sentret",
163
+ "Furret",
164
+ "Hoothoot",
165
+ "Noctowl",
166
+ "Ledyba",
167
+ "Ledian",
168
+ "Spinarak",
169
+ "Ariados",
170
+ "Crobat",
171
+ "Chinchou",
172
+ "Lanturn",
173
+ "Pichu",
174
+ "Cleffa",
175
+ "Igglybuff",
176
+ "Togepi",
177
+ "Togetic",
178
+ "Natu",
179
+ "Xatu",
180
+ "Mareep",
181
+ "Flaaffy",
182
+ "Ampharos",
183
+ "Bellossom",
184
+ "Marill",
185
+ "Azumarill",
186
+ "Sudowoodo",
187
+ "Politoed",
188
+ "Hoppip",
189
+ "Skiploom",
190
+ "Jumpluff",
191
+ "Aipom",
192
+ "Sunkern",
193
+ "Sunflora",
194
+ "Yanma",
195
+ "Wooper",
196
+ "Quagsire",
197
+ "Espeon",
198
+ "Umbreon",
199
+ "Murkrow",
200
+ "Slowking",
201
+ "Misdreavus",
202
+ "Unown",
203
+ "Wobbuffet",
204
+ "Girafarig",
205
+ "Pineco",
206
+ "Forretress",
207
+ "Dunsparce",
208
+ "Gligar",
209
+ "Steelix",
210
+ "Snubbull",
211
+ "Granbull",
212
+ "Qwilfish",
213
+ "Scizor",
214
+ "Shuckle",
215
+ "Heracross",
216
+ "Sneasel",
217
+ "Teddiursa",
218
+ "Ursaring",
219
+ "Slugma",
220
+ "Magcargo",
221
+ "Swinub",
222
+ "Piloswine",
223
+ "Corsola",
224
+ "Remoraid",
225
+ "Octillery",
226
+ "Delibird",
227
+ "Mantine",
228
+ "Skarmory",
229
+ "Houndour",
230
+ "Houndoom",
231
+ "Kingdra",
232
+ "Phanpy",
233
+ "Donphan",
234
+ "Porygon2",
235
+ "Stantler",
236
+ "Smeargle",
237
+ "Tyrogue",
238
+ "Hitmontop",
239
+ "Smoochum",
240
+ "Elekid",
241
+ "Magby",
242
+ "Miltank",
243
+ "Blissey",
244
+ "Raikou",
245
+ "Entei",
246
+ "Suicune",
247
+ "Larvitar",
248
+ "Pupitar",
249
+ "Tyranitar",
250
+ "Lugia",
251
+ "Ho-Oh",
252
+ "Celebi",
253
+ "Treecko",
254
+ "Grovyle",
255
+ "Sceptile",
256
+ "Torchic",
257
+ "Combusken",
258
+ "Blaziken",
259
+ "Mudkip",
260
+ "Marshtomp",
261
+ "Swampert",
262
+ "Poochyena",
263
+ "Mightyena",
264
+ "Zigzagoon",
265
+ "Linoone",
266
+ "Wurmple",
267
+ "Silcoon",
268
+ "Beautifly",
269
+ "Cascoon",
270
+ "Dustox",
271
+ "Lotad",
272
+ "Lombre",
273
+ "Ludicolo",
274
+ "Seedot",
275
+ "Nuzleaf",
276
+ "Shiftry",
277
+ "Taillow",
278
+ "Swellow",
279
+ "Wingull",
280
+ "Pelipper",
281
+ "Ralts",
282
+ "Kirlia",
283
+ "Gardevoir",
284
+ "Surskit",
285
+ "Masquerain",
286
+ "Shroomish",
287
+ "Breloom",
288
+ "Slakoth",
289
+ "Vigoroth",
290
+ "Slaking",
291
+ "Nincada",
292
+ "Ninjask",
293
+ "Shedinja",
294
+ "Whismur",
295
+ "Loudred",
296
+ "Exploud",
297
+ "Makuhita",
298
+ "Hariyama",
299
+ "Azurill",
300
+ "Nosepass",
301
+ "Skitty",
302
+ "Delcatty",
303
+ "Sableye",
304
+ "Mawile",
305
+ "Aron",
306
+ "Lairon",
307
+ "Aggron",
308
+ "Meditite",
309
+ "Medicham",
310
+ "Electrike",
311
+ "Manectric",
312
+ "Plusle",
313
+ "Minun",
314
+ "Volbeat",
315
+ "Illumise",
316
+ "Roselia",
317
+ "Gulpin",
318
+ "Swalot",
319
+ "Carvanha",
320
+ "Sharpedo",
321
+ "Wailmer",
322
+ "Wailord",
323
+ "Numel",
324
+ "Camerupt",
325
+ "Torkoal",
326
+ "Spoink",
327
+ "Grumpig",
328
+ "Spinda",
329
+ "Trapinch",
330
+ "Vibrava",
331
+ "Flygon",
332
+ "Cacnea",
333
+ "Cacturne",
334
+ "Swablu",
335
+ "Altaria",
336
+ "Zangoose",
337
+ "Seviper",
338
+ "Lunatone",
339
+ "Solrock",
340
+ "Barboach",
341
+ "Whiscash",
342
+ "Corphish",
343
+ "Crawdaunt",
344
+ "Baltoy",
345
+ "Claydol",
346
+ "Lileep",
347
+ "Cradily",
348
+ "Anorith",
349
+ "Armaldo",
350
+ "Feebas",
351
+ "Milotic",
352
+ "Castform",
353
+ "Kecleon",
354
+ "Shuppet",
355
+ "Banette",
356
+ "Duskull",
357
+ "Dusclops",
358
+ "Tropius",
359
+ "Chimecho",
360
+ "Absol",
361
+ "Wynaut",
362
+ "Snorunt",
363
+ "Glalie",
364
+ "Spheal",
365
+ "Sealeo",
366
+ "Walrein",
367
+ "Clamperl",
368
+ "Huntail",
369
+ "Gorebyss",
370
+ "Relicanth",
371
+ "Luvdisc",
372
+ "Bagon",
373
+ "Shelgon",
374
+ "Salamence",
375
+ "Beldum",
376
+ "Metang",
377
+ "Metagross",
378
+ "Regirock",
379
+ "Regice",
380
+ "Registeel",
381
+ "Latias",
382
+ "Latios",
383
+ "Kyogre",
384
+ "Groudon",
385
+ "Rayquaza",
386
+ "Jirachi",
387
+ "Deoxys",
388
+ "Turtwig",
389
+ "Grotle",
390
+ "Torterra",
391
+ "Chimchar",
392
+ "Monferno",
393
+ "Infernape",
394
+ "Piplup",
395
+ "Prinplup",
396
+ "Empoleon",
397
+ "Starly",
398
+ "Staravia",
399
+ "Staraptor",
400
+ "Bidoof",
401
+ "Bibarel",
402
+ "Kricketot",
403
+ "Kricketune",
404
+ "Shinx",
405
+ "Luxio",
406
+ "Luxray",
407
+ "Budew",
408
+ "Roserade",
409
+ "Cranidos",
410
+ "Rampardos",
411
+ "Shieldon",
412
+ "Bastiodon",
413
+ "Burmy",
414
+ "Wormadam",
415
+ "Mothim",
416
+ "Combee",
417
+ "Vespiquen",
418
+ "Pachirisu",
419
+ "Buizel",
420
+ "Floatzel",
421
+ "Cherubi",
422
+ "Cherrim",
423
+ "Shellos",
424
+ "Gastrodon",
425
+ "Ambipom",
426
+ "Drifloon",
427
+ "Drifblim",
428
+ "Buneary",
429
+ "Lopunny",
430
+ "Mismagius",
431
+ "Honchkrow",
432
+ "Glameow",
433
+ "Purugly",
434
+ "Chingling",
435
+ "Stunky",
436
+ "Skuntank",
437
+ "Bronzor",
438
+ "Bronzong",
439
+ "Bonsly",
440
+ "Mime Jr.",
441
+ "Happiny",
442
+ "Chatot",
443
+ "Spiritomb",
444
+ "Gible",
445
+ "Gabite",
446
+ "Garchomp",
447
+ "Munchlax",
448
+ "Riolu",
449
+ "Lucario",
450
+ "Hippopotas",
451
+ "Hippowdon",
452
+ "Skorupi",
453
+ "Drapion",
454
+ "Croagunk",
455
+ "Toxicroak",
456
+ "Carnivine",
457
+ "Finneon",
458
+ "Lumineon",
459
+ "Mantyke",
460
+ "Snover",
461
+ "Abomasnow",
462
+ "Weavile",
463
+ "Magnezone",
464
+ "Lickilicky",
465
+ "Rhyperior",
466
+ "Tangrowth",
467
+ "Electivire",
468
+ "Magmortar",
469
+ "Togekiss",
470
+ "Yanmega",
471
+ "Leafeon",
472
+ "Glaceon",
473
+ "Gliscor",
474
+ "Mamoswine",
475
+ "Porygon-Z",
476
+ "Gallade",
477
+ "Probopass",
478
+ "Dusknoir",
479
+ "Froslass",
480
+ "Rotom",
481
+ "Uxie",
482
+ "Mesprit",
483
+ "Azelf",
484
+ "Dialga",
485
+ "Palkia",
486
+ "Heatran",
487
+ "Regigigas",
488
+ "Giratina",
489
+ "Cresselia",
490
+ "Phione",
491
+ "Manaphy",
492
+ "Darkrai",
493
+ "Shaymin",
494
+ "Arceus",
495
+ "Victini",
496
+ "Snivy",
497
+ "Servine",
498
+ "Serperior",
499
+ "Tepig",
500
+ "Pignite",
501
+ "Emboar",
502
+ "Oshawott",
503
+ "Dewott",
504
+ "Samurott",
505
+ "Patrat",
506
+ "Watchog",
507
+ "Lillipup",
508
+ "Herdier",
509
+ "Stoutland",
510
+ "Purrloin",
511
+ "Liepard",
512
+ "Pansage",
513
+ "Simisage",
514
+ "Pansear",
515
+ "Simisear",
516
+ "Panpour",
517
+ "Simipour",
518
+ "Munna",
519
+ "Musharna",
520
+ "Pidove",
521
+ "Tranquill",
522
+ "Unfezant",
523
+ "Blitzle",
524
+ "Zebstrika",
525
+ "Roggenrola",
526
+ "Boldore",
527
+ "Gigalith",
528
+ "Woobat",
529
+ "Swoobat",
530
+ "Drilbur",
531
+ "Excadrill",
532
+ "Audino",
533
+ "Timburr",
534
+ "Gurdurr",
535
+ "Conkeldurr",
536
+ "Tympole",
537
+ "Palpitoad",
538
+ "Seismitoad",
539
+ "Throh",
540
+ "Sawk",
541
+ "Sewaddle",
542
+ "Swadloon",
543
+ "Leavanny",
544
+ "Venipede",
545
+ "Whirlipede",
546
+ "Scolipede",
547
+ "Cottonee",
548
+ "Whimsicott",
549
+ "Petilil",
550
+ "Lilligant",
551
+ "Basculin",
552
+ "Sandile",
553
+ "Krokorok",
554
+ "Krookodile",
555
+ "Darumaka",
556
+ "Darmanitan",
557
+ "Maractus",
558
+ "Dwebble",
559
+ "Crustle",
560
+ "Scraggy",
561
+ "Scrafty",
562
+ "Sigilyph",
563
+ "Yamask",
564
+ "Cofagrigus",
565
+ "Tirtouga",
566
+ "Carracosta",
567
+ "Archen",
568
+ "Archeops",
569
+ "Trubbish",
570
+ "Garbodor",
571
+ "Zorua",
572
+ "Zoroark",
573
+ "Minccino",
574
+ "Cinccino",
575
+ "Gothita",
576
+ "Gothorita",
577
+ "Gothitelle",
578
+ "Solosis",
579
+ "Duosion",
580
+ "Reuniclus",
581
+ "Ducklett",
582
+ "Swanna",
583
+ "Vanillite",
584
+ "Vanillish",
585
+ "Vanilluxe",
586
+ "Deerling",
587
+ "Sawsbuck",
588
+ "Emolga",
589
+ "Karrablast",
590
+ "Escavalier",
591
+ "Foongus",
592
+ "Amoonguss",
593
+ "Frillish",
594
+ "Jellicent",
595
+ "Alomomola",
596
+ "Joltik",
597
+ "Galvantula",
598
+ "Ferroseed",
599
+ "Ferrothorn",
600
+ "Klink",
601
+ "Klang",
602
+ "Klinklang",
603
+ "Tynamo",
604
+ "Eelektrik",
605
+ "Eelektross",
606
+ "Elgyem",
607
+ "Beheeyem",
608
+ "Litwick",
609
+ "Lampent",
610
+ "Chandelure",
611
+ "Axew",
612
+ "Fraxure",
613
+ "Haxorus",
614
+ "Cubchoo",
615
+ "Beartic",
616
+ "Cryogonal",
617
+ "Shelmet",
618
+ "Accelgor",
619
+ "Stunfisk",
620
+ "Mienfoo",
621
+ "Mienshao",
622
+ "Druddigon",
623
+ "Golett",
624
+ "Golurk",
625
+ "Pawniard",
626
+ "Bisharp",
627
+ "Bouffalant",
628
+ "Rufflet",
629
+ "Braviary",
630
+ "Vullaby",
631
+ "Mandibuzz",
632
+ "Heatmor",
633
+ "Durant",
634
+ "Deino",
635
+ "Zweilous",
636
+ "Hydreigon",
637
+ "Larvesta",
638
+ "Volcarona",
639
+ "Cobalion",
640
+ "Terrakion",
641
+ "Virizion",
642
+ "Tornadus",
643
+ "Thundurus",
644
+ "Reshiram",
645
+ "Zekrom",
646
+ "Landorus",
647
+ "Kyurem",
648
+ "Keldeo",
649
+ "Meloetta",
650
+ "Genesect",
651
+ "Chespin",
652
+ "Quilladin",
653
+ "Chesnaught",
654
+ "Fennekin",
655
+ "Braixen",
656
+ "Delphox",
657
+ "Froakie",
658
+ "Frogadier",
659
+ "Greninja",
660
+ "Bunnelby",
661
+ "Diggersby",
662
+ "Fletchling",
663
+ "Fletchinder",
664
+ "Talonflame",
665
+ "Scatterbug",
666
+ "Spewpa",
667
+ "Vivillon",
668
+ "Litleo",
669
+ "Pyroar",
670
+ "Flabébé",
671
+ "Floette",
672
+ "Florges",
673
+ "Skiddo",
674
+ "Gogoat",
675
+ "Pancham",
676
+ "Pangoro",
677
+ "Furfrou",
678
+ "Espurr",
679
+ "Meowstic",
680
+ "Honedge",
681
+ "Doublade",
682
+ "Aegislash",
683
+ "Spritzee",
684
+ "Aromatisse",
685
+ "Swirlix",
686
+ "Slurpuff",
687
+ "Inkay",
688
+ "Malamar",
689
+ "Binacle",
690
+ "Barbaracle",
691
+ "Skrelp",
692
+ "Dragalge",
693
+ "Clauncher",
694
+ "Clawitzer",
695
+ "Helioptile",
696
+ "Heliolisk",
697
+ "Tyrunt",
698
+ "Tyrantrum",
699
+ "Amaura",
700
+ "Aurorus",
701
+ "Sylveon",
702
+ "Hawlucha",
703
+ "Dedenne",
704
+ "Carbink",
705
+ "Goomy",
706
+ "Sliggoo",
707
+ "Goodra",
708
+ "Klefki",
709
+ "Phantump",
710
+ "Trevenant",
711
+ "Pumpkaboo",
712
+ "Gourgeist",
713
+ "Bergmite",
714
+ "Avalugg",
715
+ "Noibat",
716
+ "Noivern",
717
+ "Xerneas",
718
+ "Yveltal",
719
+ "Zygarde",
720
+ "Diancie",
721
+ "Hoopa",
722
+ "Volcanion",
723
+ "Rowlet",
724
+ "Dartrix",
725
+ "Decidueye",
726
+ "Litten",
727
+ "Torracat",
728
+ "Incineroar",
729
+ "Popplio",
730
+ "Brionne",
731
+ "Primarina",
732
+ "Pikipek",
733
+ "Trumbeak",
734
+ "Toucannon",
735
+ "Yungoos",
736
+ "Gumshoos",
737
+ "Grubbin",
738
+ "Charjabug",
739
+ "Vikavolt",
740
+ "Crabrawler",
741
+ "Crabominable",
742
+ "Oricorio",
743
+ "Cutiefly",
744
+ "Ribombee",
745
+ "Rockruff",
746
+ "Lycanroc",
747
+ "Wishiwashi",
748
+ "Mareanie",
749
+ "Toxapex",
750
+ "Mudbray",
751
+ "Mudsdale",
752
+ "Dewpider",
753
+ "Araquanid",
754
+ "Fomantis",
755
+ "Lurantis",
756
+ "Morelull",
757
+ "Shiinotic",
758
+ "Salandit",
759
+ "Salazzle",
760
+ "Stufful",
761
+ "Bewear",
762
+ "Bounsweet",
763
+ "Steenee",
764
+ "Tsareena",
765
+ "Comfey",
766
+ "Oranguru",
767
+ "Passimian",
768
+ "Wimpod",
769
+ "Golisopod",
770
+ "Sandygast",
771
+ "Palossand",
772
+ "Pyukumuku",
773
+ "Type: Null",
774
+ "Silvally",
775
+ "Minior",
776
+ "Komala",
777
+ "Turtonator",
778
+ "Togedemaru",
779
+ "Mimikyu",
780
+ "Bruxish",
781
+ "Drampa",
782
+ "Dhelmise",
783
+ "Jangmo-o",
784
+ "Hakamo-o",
785
+ "Kommo-o",
786
+ "Tapu Koko",
787
+ "Tapu Lele",
788
+ "Tapu Bulu",
789
+ "Tapu Fini",
790
+ "Cosmog",
791
+ "Cosmoem",
792
+ "Solgaleo",
793
+ "Lunala",
794
+ "Nihilego",
795
+ "Buzzwole",
796
+ "Pheromosa",
797
+ "Xurkitree",
798
+ "Celesteela",
799
+ "Kartana",
800
+ "Guzzlord",
801
+ "Necrozma",
802
+ "Magearna",
803
+ "Marshadow",
804
+ "Poipole",
805
+ "Naganadel",
806
+ "Stakataka",
807
+ "Blacephalon",
808
+ "Zeraora",
809
+ "Meltan",
810
+ "Melmetal",
811
+ "Grookey",
812
+ "Thwackey",
813
+ "Rillaboom",
814
+ "Scorbunny",
815
+ "Raboot",
816
+ "Cinderace",
817
+ "Sobble",
818
+ "Drizzile",
819
+ "Inteleon",
820
+ "Skwovet",
821
+ "Greedent",
822
+ "Rookidee",
823
+ "Corvisquire",
824
+ "Corviknight",
825
+ "Blipbug",
826
+ "Dottler",
827
+ "Orbeetle",
828
+ "Nickit",
829
+ "Thievul",
830
+ "Gossifleur",
831
+ "Eldegoss",
832
+ "Wooloo",
833
+ "Dubwool",
834
+ "Chewtle",
835
+ "Drednaw",
836
+ "Yamper",
837
+ "Boltund",
838
+ "Rolycoly",
839
+ "Carkol",
840
+ "Coalossal",
841
+ "Applin",
842
+ "Flapple",
843
+ "Appletun",
844
+ "Silicobra",
845
+ "Sandaconda",
846
+ "Cramorant",
847
+ "Arrokuda",
848
+ "Barraskewda",
849
+ "Toxel",
850
+ "Toxtricity",
851
+ "Sizzlipede",
852
+ "Centiskorch",
853
+ "Clobbopus",
854
+ "Grapploct",
855
+ "Sinistea",
856
+ "Polteageist",
857
+ "Hatenna",
858
+ "Hattrem",
859
+ "Hatterene",
860
+ "Impidimp",
861
+ "Morgrem",
862
+ "Grimmsnarl",
863
+ "Obstagoon",
864
+ "Perrserker",
865
+ "Cursola",
866
+ "Sirfetch'd",
867
+ "Mr. Rime",
868
+ "Runerigus",
869
+ "Milcery",
870
+ "Alcremie",
871
+ "Falinks",
872
+ "Pincurchin",
873
+ "Snom",
874
+ "Frosmoth",
875
+ "Stonjourner",
876
+ "Eiscue",
877
+ "Indeedee",
878
+ "Morpeko",
879
+ "Cufant",
880
+ "Copperajah",
881
+ "Dracozolt",
882
+ "Arctozolt",
883
+ "Dracovish",
884
+ "Arctovish",
885
+ "Duraludon",
886
+ "Dreepy",
887
+ "Drakloak",
888
+ "Dragapult",
889
+ "Zacian",
890
+ "Zamazenta",
891
+ "Eternatus",
892
+ "Kubfu",
893
+ "Urshifu",
894
+ "Zarude",
895
+ "Regieleki",
896
+ "Regidrago",
897
+ "Glastrier",
898
+ "Spectrier",
899
+ "Calyrex",
900
+ "Wyrdeer",
901
+ "Kleavor",
902
+ "Ursaluna",
903
+ "Basculegion",
904
+ "Sneasler",
905
+ "Overqwil",
906
+ "Enamorus"
907
+ ]
lists/species.json ADDED
The diff for this file is too large to render. See raw diff
 
models/.gitkeep ADDED
File without changes
modules/details.py ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import random
2
+ import json
3
+
4
+
5
+ def load_lists(list_names, base_dir="lists"):
6
+ lists = {}
7
+
8
+ for name in list_names:
9
+ with open(f"{base_dir}/{name}.json", "r") as f:
10
+ lists[name] = json.load(f)
11
+
12
+ return lists
13
+
14
+
15
+ def rand_name(names):
16
+ return random.choices(names)[0]
17
+
18
+
19
+ def rand_hp():
20
+ # Weights from https://bulbapedia.bulbagarden.net/wiki/HP_(TCG)
21
+
22
+ hp_range = list(range(30, 340 + 1, 10))
23
+
24
+ weights = [156, 542, 1264, 1727, 1477, 1232, 1008, 640, 436, 515, 469, 279, 188,
25
+ 131, 132, 132, 56, 66, 97, 74, 23, 24, 25, 7, 15, 6, 0, 12, 18, 35, 18, 3]
26
+
27
+ return random.choices(hp_range, weights)[0]
28
+
29
+
30
+ def rand_type(types=['Grass', 'Fire', 'Water', 'Lightning', 'Fighting',
31
+ 'Psychic', 'Colorless', 'Darkness', 'Metal', 'Dragon', 'Fairy'], can_be_none=False):
32
+ if can_be_none:
33
+ return random.choices([random.choices(types)[0], None])[0]
34
+ else:
35
+ return random.choices(types)[0]
36
+
37
+
38
+ def rand_species(species):
39
+ random_species = random.choices(species)[0]
40
+
41
+ return f'{random_species.capitalize()}'
42
+
43
+
44
+ def rand_length():
45
+ # Weights from https://bulbapedia.bulbagarden.net/wiki/List_of_Pok%C3%A9mon_by_height
46
+
47
+ feet_ranges = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '16',
48
+ '17', '18', '19', '20', '21', '22', '23', '24', '26', '28', '30', '32', '34', '35', '47', '65', '328']
49
+
50
+ weights = [30, 220, 230, 176, 130, 109, 63, 27, 17, 17, 5, 5, 6,
51
+ 4, 3, 2, 2, 2, 1, 2, 3, 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 1, 1]
52
+
53
+ return {
54
+ "feet": random.choices(feet_ranges, weights)[0],
55
+ "inches": random.randrange(0, 11 + 1, 1)
56
+ }
57
+
58
+
59
+ def rand_weight():
60
+ # Weights from https://bulbapedia.bulbagarden.net/wiki/List_of_Pok%C3%A9mon_by_weight
61
+
62
+ weight_ranges = [{"start": 1, "end": 22}, {"start": 22, "end": 44}, {"start": 44, "end": 55}, {"start": 55, "end": 110}, {"start": 110, "end": 132}, {"start": 132, "end": 218}, {"start": 218, "end": 220}, {"start": 221, "end": 226}, {
63
+ "start": 226, "end": 331}, {"start": 331, "end": 441}, {"start": 441, "end": 451}, {"start": 452, "end": 661}, {"start": 661, "end": 677}, {"start": 677, "end": 793}, {"start": 794, "end": 903}, {"start": 903, "end": 2204}]
64
+
65
+ # 'weights' as in statistical weightings
66
+ weights = [271, 145, 53, 204, 57, 122, 1, 11, 57, 28, 7, 34, 4, 17, 5, 31]
67
+
68
+ start, end = random.choices(weight_ranges, weights)[0].values()
69
+
70
+ random_weight = random.randrange(start, end + 1, 1)
71
+
72
+ return f'{random_weight} lbs.'
73
+
74
+
75
+ def rand_attack(attacks, name):
76
+ random_attack = random.choices(attacks)[0]
77
+ random_attack['text'] = random_attack['text'].replace('<name>', name)
78
+
79
+ return random_attack
80
+
81
+
82
+ def rand_attacks(attacks, name, n=2):
83
+ attack1 = rand_attack(attacks, name)
84
+
85
+ if n > 1:
86
+ attack2 = rand_attack(attacks, name)
87
+ while attack1['text'] == attack2['text']:
88
+ attack2 = rand_attack(attacks, name)
89
+ return [attack1, attack2]
90
+ else:
91
+ return [attack1]
92
+
93
+ return attacks
94
+
95
+
96
+ def rand_retreat():
97
+ return random.randrange(0, 4, 1)
98
+
99
+
100
+ def rand_description(descriptions):
101
+ return random.choices(descriptions)[0]
102
+
103
+
104
+ def rand_rarity():
105
+ return random.choices(['●', '◆', '★'], [10, 5, 1])[0]
106
+
107
+
108
+ def rand_details(lists=load_lists(['attacks', 'descriptions', 'names', 'species'])):
109
+ name = rand_name(lists["names"])
110
+
111
+ return {
112
+ "name": name,
113
+ "hp": rand_hp(),
114
+ "energy_type": rand_type(),
115
+ "species": rand_species(lists["species"]),
116
+ "length": rand_length(),
117
+ "weight": rand_weight(),
118
+ "attacks": rand_attacks(lists["attacks"], name),
119
+ "weakness": rand_type(can_be_none=True),
120
+ "resistance": rand_type(can_be_none=True),
121
+ "retreat": rand_retreat(),
122
+ "description": rand_description(lists["descriptions"]),
123
+ "rarity": rand_rarity(),
124
+ }
modules/inference.py ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ print("Preparing for inference...") # noqa
2
+
3
+ from rudalle.pipelines import generate_images
4
+ from rudalle import get_rudalle_model, get_tokenizer, get_vae
5
+ from huggingface_hub import hf_hub_url, cached_download
6
+ import torch
7
+ from io import BytesIO
8
+ import base64
9
+
10
+ print(f"GPUs available: {torch.cuda.device_count()}")
11
+ device = "cuda" if torch.cuda.is_available() else "cpu"
12
+ fp16 = torch.cuda.is_available()
13
+
14
+ file_dir = "./models"
15
+ file_name = "pytorch_model.bin"
16
+ config_file_url = hf_hub_url(
17
+ repo_id="minimaxir/ai-generated-pokemon-rudalle", filename=file_name)
18
+ cached_download(config_file_url, cache_dir=file_dir, force_filename=file_name)
19
+
20
+ model = get_rudalle_model('Malevich', pretrained=False,
21
+ fp16=fp16, device=device)
22
+ model.load_state_dict(torch.load(
23
+ f"{file_dir}/{file_name}", map_location=f"{'cuda:0' if torch.cuda.is_available() else 'cpu'}"))
24
+
25
+ vae = get_vae().to(device)
26
+ tokenizer = get_tokenizer()
27
+
28
+ print("Ready for inference")
29
+
30
+
31
+ def english_to_russian(english_string):
32
+ word_map = {
33
+ "grass": "трава",
34
+ "fire": "Пожар",
35
+ "water": "вода",
36
+ "lightning": "молния",
37
+ "fighting": "борьба",
38
+ "psychic": "психический",
39
+ "colorless": "бесцветный",
40
+ "darkness": "темнота",
41
+ "metal": "металл",
42
+ "dragon": "Дракон",
43
+ "fairy": "сказочный"
44
+ }
45
+
46
+ return word_map[english_string.lower()]
47
+
48
+
49
+ def generate_image(prompt):
50
+ if prompt.lower() in ['grass', 'fire', 'water', 'lightning', 'fighting', 'psychic', 'colorless', 'darkness', 'metal', 'dragon', 'fairy']:
51
+ prompt = english_to_russian(prompt)
52
+
53
+ result, _ = generate_images(
54
+ prompt, tokenizer, model, vae, top_k=2048, images_num=1, top_p=0.995)
55
+
56
+ buffer = BytesIO()
57
+ result[0].save(buffer, format="PNG")
58
+ base64_bytes = base64.b64encode(buffer.getvalue())
59
+ base64_string = base64_bytes.decode("UTF-8")
60
+
61
+ return "data:image/png;base64," + base64_string
requirements.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ Flask
2
+ rudalle==1.0.0
static/favicon.ico ADDED
static/index.js ADDED
@@ -0,0 +1,239 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* HTML generation */
2
+
3
+ const TYPES = {
4
+ Grass: '🍃',
5
+ Fire: '🔥',
6
+ Water: '💧',
7
+ Lightning: '⚡',
8
+ Fighting: '✊',
9
+ Psychic: '👁️',
10
+ Colorless: '⭐',
11
+ Darkness: '🌑',
12
+ Metal: '⚙️',
13
+ Dragon: '🐲',
14
+ Fairy: '🧚',
15
+ };
16
+
17
+ const energyHTML = (type, types = TYPES) => {
18
+ return `<span title="${type} energy" class="energy ${type.toLowerCase()}">${types[type]}</span>`;
19
+ };
20
+
21
+ const attackDescriptionHTML = (text) => {
22
+ if (!text) {
23
+ return '';
24
+ }
25
+
26
+ let fontSize;
27
+
28
+ if (text.length > 185) {
29
+ fontSize = 0.7;
30
+ } else if (text.length > 140) {
31
+ fontSize = 0.8;
32
+ } else if (text.length > 90) {
33
+ fontSize = 0.9;
34
+ }
35
+
36
+ return `<span class="attack-details"${fontSize ? ` style="font-size: ${fontSize.toString()}em"` : ''}>${text}</span>`;
37
+ };
38
+
39
+ const attackRowsHTML = (attacks) => {
40
+ return attacks
41
+ .map((attack) => {
42
+ const { cost, damage, name, text } = attack;
43
+
44
+ return `
45
+ <li class="attacks-row grid-three">
46
+ <div class="attack-cost">
47
+ ${cost.map((energy) => energyHTML(energy)).join('')}
48
+ </div>
49
+ <span class="attack-text">
50
+ <span class="attack-name">${name}</span>
51
+ ${attackDescriptionHTML(text)}
52
+ </span>
53
+ <span class="attack-damage">${damage ? damage : ''}</span>
54
+ </li>
55
+ <hr role="presentation" />`;
56
+ })
57
+ .join('');
58
+ };
59
+
60
+ const cardHTML = (details) => {
61
+ const { hp, energy_type, species, length, weight, attacks, weakness, resistance, retreat, description, rarity } =
62
+ details;
63
+
64
+ const poke_name = details.name; // `name` would be reserved JS word
65
+
66
+ return `
67
+ <div class="pokecard ${energy_type.toLowerCase()}" data-displayed="true">
68
+ <p class="evolves">Basic Pokémon</p>
69
+ <header>
70
+ <h1 class="name">${poke_name}</h1>
71
+ <div>
72
+ <span class="hp">${hp} HP</span>
73
+ ${energyHTML(energy_type)}
74
+ </div>
75
+ </header>
76
+ <img class="picture frame" alt="AI generated Pokémon called ${poke_name}" />
77
+ <div class="species frame">
78
+ ${species} Pokémon. Length: ${length.feet}'${length.inches}", Weight: ${weight}
79
+ </div>
80
+ <ul class="attacks">
81
+ ${attackRowsHTML(attacks)}
82
+ </ul>
83
+ <div class="multipliers">
84
+ <div class="weakness">
85
+ <span>weakness</span>
86
+ ${weakness ? energyHTML(weakness) : ''}
87
+ </div>
88
+ <div class="resistance">
89
+ <span>resistance</span>
90
+ ${resistance ? energyHTML(resistance) : ''}
91
+ <span class="resistance-total"
92
+ >${resistance ? '-30' : ''}</span
93
+ >
94
+ </div>
95
+ <div class="retreat-cost">
96
+ <span>retreat cost</span>
97
+ <div>${energyHTML('Colorless').repeat(retreat)}</div>
98
+ </div>
99
+ </div>
100
+ <p class="description frame">${description}</p>
101
+ <div class="footer grid-three">
102
+ <span
103
+ ><a
104
+ href="https://huggingface.co/minimaxir/ai-generated-pokemon-rudalle"
105
+ >Illus. Max Woolf</a
106
+ ></span
107
+ >
108
+ <span><a href="">2022 Hugging Face</a></span>
109
+ <span>${rarity}</span>
110
+ </div>
111
+ </div>`;
112
+ };
113
+
114
+ /* Utility */
115
+
116
+ const getBasePath = () => {
117
+ return document.location.origin + document.location.pathname;
118
+ };
119
+
120
+ const generateDetails = async () => {
121
+ const details = await fetch(`${getBasePath()}/details`);
122
+ return await details.json();
123
+ };
124
+
125
+ const createTask = async (prompt) => {
126
+ const taskResponse = await fetch(`${getBasePath()}task/create?prompt=${prompt}`);
127
+ const task = await taskResponse.json();
128
+
129
+ return task;
130
+ };
131
+
132
+ const queueTask = (task_id) => {
133
+ fetch(`${getBasePath()}task/queue?task_id=${task_id}`);
134
+ };
135
+
136
+ const pollTask = async (task) => {
137
+ const taskResponse = await fetch(`${getBasePath()}task/poll?task_id=${task.task_id}`);
138
+
139
+ return await taskResponse.json();
140
+ };
141
+
142
+ const longPollTask = async (task, interval = 5_000, max) => {
143
+ if (task.status === 'complete' || (max && task.poll_count > max)) {
144
+ return task;
145
+ }
146
+
147
+ const taskResponse = await fetch(`${getBasePath()}task/poll?task_id=${task.task_id}`);
148
+
149
+ task = await taskResponse.json();
150
+
151
+ if (task.status === 'complete' || task.poll_count > max) {
152
+ return task;
153
+ }
154
+
155
+ await new Promise((resolve) => setTimeout(resolve, interval));
156
+
157
+ return await longPollTask(task, interval, max);
158
+ };
159
+
160
+ /* DOM */
161
+
162
+ const generateButton = document.querySelector('button.generate');
163
+
164
+ const rotateCard = () => {
165
+ const RANGE = 0.1;
166
+ const INTERVAL = 13; // ~75 per second
167
+ let previousTime = 0;
168
+
169
+ // Throttle closure
170
+ return (card, containerMouseEvent) => {
171
+ const currentTime = performance.now();
172
+
173
+ if (currentTime - previousTime > INTERVAL) {
174
+ previousTime = currentTime;
175
+
176
+ const rect = card.getBoundingClientRect();
177
+
178
+ const rotateX = (containerMouseEvent.clientY - rect.y - rect.height / 2) * RANGE;
179
+ const rotateY = -(containerMouseEvent.clientX - rect.x - rect.width / 2) * RANGE;
180
+
181
+ card.style.setProperty('--rotate-x', rotateX + 'deg');
182
+ card.style.setProperty('--rotate-y', rotateY + 'deg');
183
+ }
184
+ };
185
+ };
186
+
187
+ const cardRotationInitiator = (renderSection) => {
188
+ let currentCard;
189
+
190
+ return () => {
191
+ let handleMouseMove;
192
+
193
+ if (currentCard) {
194
+ handleMouseMove = rotateCard().bind(null, currentCard);
195
+ renderSection.removeEventListener('mousemove', handleMouseMove, true);
196
+ }
197
+
198
+ const newCard = document.querySelector('.pokecard');
199
+
200
+ currentCard = newCard;
201
+
202
+ handleMouseMove = rotateCard().bind(null, newCard);
203
+ renderSection.addEventListener('mousemove', handleMouseMove, true);
204
+ };
205
+ };
206
+
207
+ generateButton.addEventListener('click', async () => {
208
+ const details = await generateDetails();
209
+ console.log({ details });
210
+
211
+ const renderSection = document.querySelector('section.render');
212
+ const durationSeconds = document.querySelector('.duration > .seconds');
213
+ const initialiseCardRotation = cardRotationInitiator(renderSection);
214
+ let duration = 0.0;
215
+
216
+ try {
217
+ const task = await createTask(details.energy_type);
218
+
219
+ queueTask(task.task_id);
220
+
221
+ const incrementSeconds = setInterval(() => {
222
+ duration += 0.1;
223
+ durationSeconds.textContent = duration.toFixed(1).toString();
224
+ }, 100);
225
+
226
+ const completedTask = await longPollTask(task);
227
+
228
+ clearInterval(incrementSeconds);
229
+
230
+ renderSection.innerHTML = cardHTML(details);
231
+
232
+ const picture = document.querySelector('img.picture');
233
+ picture.src = completedTask.value;
234
+
235
+ initialiseCardRotation();
236
+ } catch (err) {
237
+ console.error(err);
238
+ }
239
+ });
static/style.css ADDED
@@ -0,0 +1,370 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ :root {
2
+ --card-h: 47;
3
+ --card-s: 95%;
4
+ --card-l: 58%;
5
+ --card-color: hsl(var(--card-h) var(--card-s) var(--card-l));
6
+ }
7
+
8
+ html,
9
+ body {
10
+ overflow: scroll;
11
+ }
12
+
13
+ body {
14
+ display: grid;
15
+ place-items: center;
16
+ height: 100vh;
17
+ font-family: 'Gill Sans', 'Gill Sans Mt', 'sans-serif';
18
+ background-color: whitesmoke;
19
+ }
20
+
21
+ .duration {
22
+ text-align: right;
23
+ }
24
+
25
+ button {
26
+ padding: 0.5rem 1rem;
27
+ margin: 1rem;
28
+ }
29
+
30
+ section.render {
31
+ perspective: 100rem;
32
+ margin: 0.5rem;
33
+ height: 40rem;
34
+ }
35
+
36
+ .grass {
37
+ --h: 90;
38
+ --s: 60%;
39
+ --l: 40%;
40
+ }
41
+ .grass.energy {
42
+ filter: contrast(0.75) grayscale(1) sepia(1) saturate(10) hue-rotate(55deg) drop-shadow(0 0 0.1rem green);
43
+ }
44
+
45
+ .fire {
46
+ --h: 0;
47
+ --s: 75%;
48
+ --l: 45%;
49
+ }
50
+ .fire.energy {
51
+ filter: contrast(0.75) grayscale(1) sepia(1) saturate(10) hue-rotate(335deg) drop-shadow(0 0 0.1rem red);
52
+ }
53
+
54
+ .water {
55
+ --h: 210;
56
+ --s: 100%;
57
+ --l: 58%;
58
+ }
59
+ .water.energy {
60
+ filter: contrast(0.75) grayscale(1) sepia(1) saturate(10) hue-rotate(180deg) drop-shadow(0 0 0.1rem cyan);
61
+ }
62
+
63
+ .lightning {
64
+ --h: 50;
65
+ --s: 100%;
66
+ --l: 58%;
67
+ }
68
+ .lightning.energy {
69
+ filter: contrast(0.75) grayscale(1) sepia(1) saturate(10) hue-rotate(5deg) drop-shadow(0 0 0.1rem gold);
70
+ }
71
+
72
+ .fighting {
73
+ --h: 25;
74
+ --s: 72%;
75
+ --l: 36%;
76
+ }
77
+ .fighting.energy {
78
+ filter: contrast(0.75) grayscale(1) sepia(1) saturate(10) hue-rotate(320deg) drop-shadow(0 0 0.1rem brown);
79
+ }
80
+
81
+ .psychic {
82
+ --h: 299;
83
+ --s: 43%;
84
+ --l: 44%;
85
+ }
86
+ .psychic.energy {
87
+ filter: grayscale(1) sepia(1) saturate(10) hue-rotate(240deg) drop-shadow(0 0 0.1rem purple);
88
+ }
89
+
90
+ .colorless {
91
+ --h: 21;
92
+ --s: 27%;
93
+ --l: 85%;
94
+ }
95
+ .colorless.energy {
96
+ font-size: 0.9em;
97
+ border-radius: 50%;
98
+ background-color: hsl(0 0% 100% / 15%);
99
+ filter: contrast(100) grayscale(1) drop-shadow(0 0 0.1rem white);
100
+ }
101
+
102
+ .darkness {
103
+ --h: 100;
104
+ --s: 3%;
105
+ --l: 17%;
106
+ }
107
+ .darkness.energy {
108
+ filter: drop-shadow(0 0 0.1rem black);
109
+ }
110
+ .darkness :not(.species) {
111
+ color: whitesmoke;
112
+ }
113
+
114
+ .metal {
115
+ --h: 240;
116
+ --s: 20%;
117
+ --l: 77%;
118
+ }
119
+ .metal.energy {
120
+ filter: drop-shadow(0 0 0.1rem silver);
121
+ }
122
+
123
+ .dragon {
124
+ --h: 30;
125
+ --s: 6%;
126
+ --l: 44%;
127
+ }
128
+ .dragon.energy {
129
+ filter: contrast(0.75) grayscale(1) sepia(1) saturate(10) hue-rotate(15deg) drop-shadow(0 0 0.1rem gold);
130
+ }
131
+
132
+ .fairy {
133
+ --h: 334;
134
+ --s: 74%;
135
+ --l: 55%;
136
+ }
137
+ .fairy.energy {
138
+ filter: contrast(0.75) grayscale(1) sepia(1) saturate(10) hue-rotate(300deg) drop-shadow(0 0 0.1rem pink);
139
+ }
140
+
141
+ .pokecard,
142
+ .pokecard * {
143
+ box-sizing: border-box;
144
+ }
145
+
146
+ .pokecard {
147
+ --color: hsl(var(--h) var(--s) var(--l));
148
+ --lighter: hsl(var(--h) var(--s) calc(var(--l) + 10%));
149
+ --lightest: hsl(var(--h) var(--s) calc(var(--l) + 30%));
150
+ --rotate-x: 0deg;
151
+ --rotate-y: 0deg;
152
+ --rotate-z: 0deg;
153
+ display: flex;
154
+ flex-direction: column;
155
+ width: 25rem;
156
+ aspect-ratio: 63 / 88;
157
+ padding: 0.5rem 1rem;
158
+ border: 1rem solid;
159
+ border-radius: 0.75rem;
160
+ border-color: var(--card-color);
161
+ background-image: linear-gradient(
162
+ 45deg,
163
+ var(--lighter) 0%,
164
+ var(--lightest) 15%,
165
+ var(--lightest) 30%,
166
+ var(--color) 50%,
167
+ var(--lightest) 90%,
168
+ var(--lighter) 100%
169
+ );
170
+ transform-origin: center;
171
+ transform-style: preserve-3d;
172
+ transform: rotateX(var(--rotate-x)) rotateY(var(--rotate-y)) translate3d(10px, 10px, 10px);
173
+ transition: transform 0.5s ease-out;
174
+ }
175
+
176
+ .pokecard[data-displayed='true'] {
177
+ display: flex;
178
+ }
179
+ .pokecard[data-displayed='false'] {
180
+ display: none;
181
+ }
182
+
183
+ .pokecard :where(header, p) {
184
+ font-family: 'Gill Sans', 'Gill Sans Mt', 'sans-serif';
185
+ }
186
+ .pokecard :is(.evolves) {
187
+ font-family: 'Century Gothic', 'sans-serif';
188
+ }
189
+ .pokecard :where(header, p) {
190
+ font-family: 'Gill Sans', 'Gill Sans Mt';
191
+ }
192
+
193
+ .evolves {
194
+ margin: 0;
195
+ font-weight: bold;
196
+ font-size: 0.5rem;
197
+ }
198
+
199
+ header {
200
+ display: flex;
201
+ flex-direction: row;
202
+ justify-content: space-between;
203
+ }
204
+
205
+ header > * {
206
+ display: inline-block;
207
+ }
208
+
209
+ .name {
210
+ justify-self: left;
211
+ font-size: 1.25rem;
212
+ margin: 0;
213
+ }
214
+
215
+ .hp {
216
+ font-size: 1.25rem;
217
+ color: hsl(0 100% 50%);
218
+ }
219
+
220
+ header .energy {
221
+ display: inline-block;
222
+ transform: translateY(-0.15rem);
223
+ }
224
+
225
+ .frame:is(.picture, .species, .description) {
226
+ --lighter: hsl(var(--card-h) var(--card-s) calc(var(--card-l) + 15%));
227
+ --lightest: hsl(var(--card-h) var(--card-s) calc(var(--card-l) + 30%));
228
+ --darker: hsl(var(--card-h) var(--card-s) calc(var(--card-l) - 15%));
229
+ border-color: var(--darker) var(--card-color) var(--lighter);
230
+ }
231
+
232
+ .picture {
233
+ width: 100%;
234
+ aspect-ratio: 4 / 3;
235
+ object-fit: contain;
236
+ background-color: white;
237
+ border: 0.375rem solid;
238
+ box-shadow: 0.25rem 0.25rem 0.5rem black;
239
+ user-select: none;
240
+ }
241
+
242
+ .species {
243
+ width: 90%;
244
+ padding: 0.1rem;
245
+ margin: 0.25rem auto;
246
+ text-align: center;
247
+ font-size: 0.75rem;
248
+ font-style: italic;
249
+ font-weight: bold;
250
+ background-image: linear-gradient(90deg, var(--card-color), var(--lightest) 45% 55%, var(--card-color));
251
+ border-width: 0 0.2rem;
252
+ border-style: solid;
253
+ border-image: linear-gradient(var(--lightest), var(--darker)) 1 100%;
254
+ }
255
+
256
+ .grid-three {
257
+ display: grid;
258
+ grid-template-columns: repeat(3, 1fr);
259
+ }
260
+
261
+ .grid-three > *:first-child {
262
+ text-align: left;
263
+ }
264
+
265
+ .grid-three > span:last-child {
266
+ text-align: right;
267
+ }
268
+
269
+ .attacks {
270
+ list-style-type: none;
271
+ padding: 0;
272
+ margin: 0.1rem auto 0;
273
+ }
274
+
275
+ .attacks-row {
276
+ max-height: 5rem;
277
+ grid-template-columns: 3rem 10fr 1fr;
278
+ align-items: center;
279
+ gap: 1rem;
280
+ font-size: 0.95em;
281
+ }
282
+
283
+ .attack-text > span:only-child {
284
+ display: block;
285
+ margin-left: -2rem;
286
+ text-align: center;
287
+ }
288
+
289
+ .attack-cost {
290
+ display: flex;
291
+ justify-content: space-evenly;
292
+ flex-flow: row wrap;
293
+ text-align: justify;
294
+ }
295
+
296
+ .energy {
297
+ width: fit-content;
298
+ aspect-ratio: 1 / 1;
299
+ cursor: default;
300
+ user-select: none;
301
+ }
302
+
303
+ .energy:only-child {
304
+ justify-self: flex-start;
305
+ margin: auto;
306
+ }
307
+
308
+ .attack-name {
309
+ font-weight: bold;
310
+ }
311
+
312
+ .attack-damage {
313
+ min-width: 2.25rem;
314
+ font-size: 1.375rem;
315
+ text-align: center;
316
+ }
317
+
318
+ hr {
319
+ background-color: black;
320
+ border: 0.5px solid black;
321
+ }
322
+
323
+ .multipliers {
324
+ display: flex;
325
+ flex-direction: row;
326
+ justify-content: space-between;
327
+ height: 2rem;
328
+ margin-top: -0.5rem;
329
+ text-align: center;
330
+ font-size: 0.75rem;
331
+ font-weight: bold;
332
+ }
333
+
334
+ .multipliers > div {
335
+ display: flex;
336
+ flex-direction: column;
337
+ align-items: center;
338
+ margin: 0;
339
+ }
340
+
341
+ .resistance {
342
+ position: relative;
343
+ }
344
+
345
+ .resistance-total {
346
+ position: absolute;
347
+ top: 1rem;
348
+ left: 2.5rem;
349
+ }
350
+
351
+ .description {
352
+ padding: 0.1rem 0.5rem;
353
+ margin: 0.25rem 0 0.5rem;
354
+ border: 0.15rem solid;
355
+ font-size: 0.65rem;
356
+ font-style: italic;
357
+ font-weight: bold;
358
+ }
359
+
360
+ .footer {
361
+ text-align: center;
362
+ font-weight: bold;
363
+ font-size: 0.6rem;
364
+ margin: auto 0;
365
+ }
366
+
367
+ a {
368
+ text-decoration: none;
369
+ color: black !important;
370
+ }
templates/index.html ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>This Pokémon Does Not Exist</title>
7
+ <link rel="shortcut icon" href="{{ url_for('static', filename='favicon.ico') }}" />
8
+ <link rel="stylesheet" id="stylesheet-tag" />
9
+ <script type="module" id="script-tag"></script>
10
+ <script>
11
+ const basePath = document.location.origin + document.location.pathname;
12
+ document.getElementById('script-tag').src = `${basePath}static/index.js`;
13
+ document.getElementById('stylesheet-tag').href = `${basePath}static/style.css`;
14
+ </script>
15
+ </head>
16
+ <body>
17
+ <h1>This Pokémon Does Not Exist</h1>
18
+ <div class="duration"><span class="seconds">0.0</span>/500s</div>
19
+ <button class="generate">Generate Pokémon Card with AI</button>
20
+ <section class="render"></section>
21
+ </body>
22
+ </html>