Laura Wagner commited on
Commit
21c17c8
·
1 Parent(s): 239055a

renaming all scripts according to new order

Browse files
Files changed (31) hide show
  1. .gitignore +1 -0
  2. misc/deepseek_query_index.txt +1 -0
  3. misc/lists/danbooru.json +0 -0
  4. public/05_gender_sunburst.html +0 -92
  5. public/{06_danbooru_tree.html → Figure_13.html} +0 -0
  6. public/{05_sb_gender_prof_II.html → Figure_8a_sunburst.html} +2 -2
  7. public/{05_sunburst_countries_professions.html → Figure_8b_sunburst.html} +2 -2
  8. public/{sankey_v2.html → Figure_9.html} +0 -0
  9. public/{all_models_.html → Figure_9_old.html} +0 -0
  10. public/danbooru.html +0 -82
  11. public/danbooru.ipynb +0 -0
  12. public/json/8a.json +52 -0
  13. public/json/danbooru_flat.json +131 -131
  14. public/json/tags_america.json +356 -356
  15. public/network. +0 -0
  16. public/network.html +0 -193
  17. public/tag_groups.html +0 -389
  18. public/tags_landscape.html +0 -396
  19. scripts/03_NER_characters_real_persons.ipynb +0 -380
  20. scripts/0_Scraping_image_metadata.ipynb +35 -1
  21. scripts/{Section_3-3-1_Figure_3_histogram.ipynb → Section_3-2-1_Figure_3_histogram.ipynb} +0 -0
  22. scripts/{Section_3-3-1_Figure_4_Mivolo.ipynb → Section_3-2-1_Figure_4_Mivolo.ipynb} +0 -0
  23. scripts/{02_filtered_tags_source_creation.ipynb → Section_3-3-1_Figure_5_tags.ipynb} +22 -147
  24. scripts/{05_female_male.ipynb → Section_3-3-4_Figure_8a.ipynb} +12 -54
  25. scripts/{Section_3-3-4_Figure_8_deepfake_victims.ipynb → Section_3-3-4_Figure_8b.ipynb} +9 -84
  26. scripts/{01_prepare_sankey_csv.ipynb → Section_3-3-4_Figure_9_Sankey.ipynb} +0 -0
  27. scripts/{Section_3-3-4_deepfake_adapter.ipynb → Section_3-3-4_LLM_annotation.ipynb} +229 -103
  28. scripts/Section_3-4_extract_LoRA_metadata.ipynb +0 -0
  29. scripts/{get_Danbooru_Tags_and categorize.ipynb → SuppM_Figure_12_Danbooru_Taxonomy.ipynb} +0 -0
  30. scripts/{04_training_data_network_data_prep.ipynb → SuppM_Figure_13.ipynb} +7 -0
  31. public/06_danbooru_structure.ipynb → scripts/SuppM_Figure_13_Danbooru_taxonomy.ipynb +10 -10
.gitignore CHANGED
@@ -7,3 +7,4 @@ misc/credentials/*
7
  misc/credentials
8
  scripts/ARCHIVE
9
  scripts/CEMETARY
 
 
7
  misc/credentials
8
  scripts/ARCHIVE
9
  scripts/CEMETARY
10
+ cemetary
misc/deepseek_query_index.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ 4
misc/lists/danbooru.json ADDED
The diff for this file is too large to render. See raw diff
 
public/05_gender_sunburst.html DELETED
@@ -1,92 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <title>D3 Sunburst Chart with Symbols</title>
6
- <script src="https://d3js.org/d3.v7.min.js"></script>
7
- </head>
8
- <body>
9
- <svg width="600" height="600"></svg>
10
-
11
- <script>
12
- const width = 300;
13
- const height = 300;
14
- const radius = Math.min(width, height) / 2;
15
-
16
- const genderSymbols = {
17
- "Male": "♂",
18
- "Female": "♀",
19
- "Non-binary": "★",
20
- "Unknown": "★"
21
- };
22
-
23
- d3.json("json/gender_sunburst.json").then(genderData => {
24
- const genderRoot = d3.hierarchy(genderData).sum(d => d.value);
25
-
26
- d3.partition().size([2 * Math.PI, radius])(genderRoot);
27
-
28
- const svg = d3.select("svg")
29
- .append("g")
30
- .attr("transform", `translate(${width / 2},${height / 2})`);
31
-
32
- const genderArc = d3.arc()
33
- .startAngle(d => d.x0)
34
- .endAngle(d => d.x1)
35
- .innerRadius(d => d.y0)
36
- .outerRadius(d => d.y1);
37
-
38
- const genderColorMap = {
39
- "Male": "white",
40
- "Female": "white",
41
- "Non-binary": "white",
42
- "Unknown": "white"
43
- };
44
-
45
- svg.selectAll("path")
46
- .data(genderRoot.descendants().slice(1))
47
- .join("path")
48
- .attr("d", genderArc)
49
- .attr("fill", d => genderColorMap[d.data.name] || "#ccc")
50
- .attr("stroke", "#000")
51
- .attr("stroke-width", 3)
52
- .append("title")
53
- .text(d => `${d.data.name}: ${d.value}`);
54
-
55
- // Labels for Male and Female
56
- svg.selectAll("text.label")
57
- .data(genderRoot.descendants().slice(1).filter(d => d.data.name === "Male" || d.data.name === "Female"))
58
- .join("text")
59
- .attr("class", "label")
60
- .attr("transform", d => {
61
- const [x, y] = genderArc.centroid(d);
62
- return `translate(${x},${y})`;
63
- })
64
- .attr("text-anchor", "middle")
65
- .attr("dominant-baseline", "middle")
66
- .style("pointer-events", "none")
67
- .html(d => `<tspan style="font-size:35px;font-weight:bold;">${genderSymbols[d.data.name]}</tspan><tspan style="font-size:16px;">: ${d.value}</tspan>`);
68
-
69
- // Non-binary/Unknown total
70
- const specialSegments = genderRoot.descendants().slice(1).filter(d => d.data.name === "Non-binary" || d.data.name === "Unknown");
71
- const specialTotal = specialSegments.reduce((sum, d) => sum + d.value, 0);
72
-
73
- svg.append("text")
74
- .attr("x", 0)
75
- .attr("y", radius + 20)
76
- .attr("text-anchor", "middle")
77
- .style("font-size", "14px")
78
- .style("font-weight", "bold")
79
- .text(`★ Non-binary/Unknown: ${specialTotal}`);
80
-
81
- svg.append("text")
82
- .attr("text-anchor", "middle")
83
- .attr("dy", "0.35em")
84
- .style("font-weight", "bold")
85
- .text("Gender");
86
-
87
- }).catch(error => {
88
- console.error("Error loading JSON:", error);
89
- });
90
- </script>
91
- </body>
92
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
public/{06_danbooru_tree.html → Figure_13.html} RENAMED
File without changes
public/{05_sb_gender_prof_II.html → Figure_8a_sunburst.html} RENAMED
@@ -90,7 +90,7 @@ function partition(data) {
90
 
91
 
92
 
93
- d3.json("json/sunburst_gender_profession.json").then(data => {
94
  const root = partition(data);
95
  root.each(d => d.current = d);
96
 
@@ -156,7 +156,7 @@ root.children.forEach(d => {
156
  const angle = ((d.x0 + d.x1) / 2) + angleOffset;
157
  const x = Math.cos(angle - Math.PI / 2) * (radius / root.height + -50);
158
  const y = Math.sin(angle - Math.PI / 2) * (radius / root.height + -50);
159
- return `translate(${x},${y}) rotate(${(angle * 180 / Math.PI - 90)})`;
160
  })
161
  .attr("dy", "0.35em")
162
  .attr("class", "label")
 
90
 
91
 
92
 
93
+ d3.json("json/sunburst_gender.json").then(data => {
94
  const root = partition(data);
95
  root.each(d => d.current = d);
96
 
 
156
  const angle = ((d.x0 + d.x1) / 2) + angleOffset;
157
  const x = Math.cos(angle - Math.PI / 2) * (radius / root.height + -50);
158
  const y = Math.sin(angle - Math.PI / 2) * (radius / root.height + -50);
159
+ return `translate(${x},${y}) rotate(${(angle / Math.PI)})`;
160
  })
161
  .attr("dy", "0.35em")
162
  .attr("class", "label")
public/{05_sunburst_countries_professions.html → Figure_8b_sunburst.html} RENAMED
@@ -116,7 +116,7 @@ function partition(data) {
116
 
117
 
118
 
119
- d3.json("json/sunburst_data.json").then(data => {
120
  const root = partition(data);
121
  root.each(d => d.current = d);
122
 
@@ -173,7 +173,7 @@ d3.json("json/sunburst_data.json").then(data => {
173
  const angle = (d.x0 + d.x1) / 2;
174
  const x = Math.cos(angle - Math.PI / 2) * (radius / root.height + -50);
175
  const y = Math.sin(angle - Math.PI / 2) * (radius / root.height + -50);
176
- return `translate(${x},${y}) rotate(${(angle * 180 / Math.PI - 90)})`;
177
  })
178
  .attr("dy", "0.35em")
179
  .attr("class", "label")
 
116
 
117
 
118
 
119
+ d3.json("json/sunburst_countries_A.json").then(data => {
120
  const root = partition(data);
121
  root.each(d => d.current = d);
122
 
 
173
  const angle = (d.x0 + d.x1) / 2;
174
  const x = Math.cos(angle - Math.PI / 2) * (radius / root.height + -50);
175
  const y = Math.sin(angle - Math.PI / 2) * (radius / root.height + -50);
176
+ return `translate(${x},${y}) rotate(${(angle / Math.PI)})`;
177
  })
178
  .attr("dy", "0.35em")
179
  .attr("class", "label")
public/{sankey_v2.html → Figure_9.html} RENAMED
File without changes
public/{all_models_.html → Figure_9_old.html} RENAMED
File without changes
public/danbooru.html DELETED
@@ -1,82 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <script src="https://d3js.org/d3.v7.min.js"></script>
6
- <style>
7
- body {
8
- font-family: Arial, sans-serif;
9
- margin: 0;
10
- padding: 2rem;
11
- background-color: #f5f5f5;
12
- }
13
-
14
- .card {
15
- background: white;
16
- border-radius: 12px;
17
- box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1);
18
- padding: 2rem;
19
- max-width: 100%;
20
- margin: auto;
21
- }
22
-
23
- .controls {
24
- margin-bottom: 1rem;
25
- }
26
-
27
- .description {
28
- margin-top: 1rem;
29
- font-size: 1rem;
30
- color: #444;
31
- }
32
-
33
- .nav-buttons {
34
- display: flex;
35
- justify-content: space-between;
36
- margin-top: 2rem;
37
- }
38
-
39
- .nav-buttons a {
40
- text-decoration: none;
41
- background-color: #007bff;
42
- color: white;
43
- padding: 0.6rem 1.2rem;
44
- border-radius: 5px;
45
- font-weight: bold;
46
- }
47
-
48
- .nav-buttons a:hover {
49
- background-color: #0056b3;
50
- }
51
-
52
- .node { stroke: none; }
53
- text { font-family: Arial, sans-serif; fill: black; }
54
- .legend rect { stroke: black; stroke-width: 0.5px; }
55
- </style>
56
- </head>
57
- <body>
58
- <div class="card">
59
- <div class="controls">
60
- <button onclick="saveSvg()">Save SVG</button><br><br>
61
- <label for="tagSlider">Number of tags shown:</label>
62
- <input type="range" id="tagSlider" min="0" max="1000" value="100" step="10" />
63
- <span id="tagCount">100</span>
64
- </div>
65
-
66
- <svg width="1600" height="1600"></svg>
67
-
68
- <div class="description">
69
- This network visualization shows tag co-occurrences across categories. Adjust the slider to show more or fewer labels.
70
- </div>
71
-
72
- <div class="nav-buttons">
73
- <a href="index.html">← Back</a>
74
- <a href="sankey.html">Next →</a>
75
- </div>
76
- </div>
77
-
78
- <script>
79
- // your full JavaScript code stays the same here
80
- </script>
81
- </body>
82
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
public/danbooru.ipynb DELETED
File without changes
public/json/8a.json ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "root",
3
+ "children": [
4
+ {
5
+ "name": "Female",
6
+ "children": [
7
+ {
8
+ "name": "Actor",
9
+ "value": 8
10
+ },
11
+ {
12
+ "name": "Adult Performer",
13
+ "value": 2
14
+ },
15
+ {
16
+ "name": "Online Personality",
17
+ "value": 4
18
+ },
19
+ {
20
+ "name": "Singer, Musician",
21
+ "value": 2
22
+ },
23
+ {
24
+ "name": "Sports Professional",
25
+ "value": 1
26
+ },
27
+ {
28
+ "name": "Voice Actor",
29
+ "value": 1
30
+ }
31
+ ]
32
+ },
33
+ {
34
+ "name": "Male",
35
+ "children": [
36
+ {
37
+ "name": "Voice Actor",
38
+ "value": 1
39
+ }
40
+ ]
41
+ },
42
+ {
43
+ "name": "Other",
44
+ "children": [
45
+ {
46
+ "name": "Other",
47
+ "value": 2
48
+ }
49
+ ]
50
+ }
51
+ ]
52
+ }
public/json/danbooru_flat.json CHANGED
@@ -2,7 +2,7 @@
2
  "name": "root",
3
  "children": [
4
  {
5
- "name": "attire",
6
  "children": [
7
  {
8
  "name": "attire",
@@ -10,7 +10,7 @@
10
  {
11
  "name": "attire_general",
12
  "children": [],
13
- "color": "#888888",
14
  "tags": [
15
  "balaclava",
16
  "..."
@@ -22,7 +22,7 @@
22
  {
23
  "name": "dress",
24
  "children": [],
25
- "color": "#888888",
26
  "tags": [
27
  "Dress",
28
  "..."
@@ -34,7 +34,7 @@
34
  {
35
  "name": "handwear",
36
  "children": [],
37
- "color": "#888888",
38
  "tags": [
39
  "Elbow gloves",
40
  "..."
@@ -46,7 +46,7 @@
46
  {
47
  "name": "headwear",
48
  "children": [],
49
- "color": "#888888",
50
  "tags": [
51
  "crown",
52
  "..."
@@ -58,7 +58,7 @@
58
  {
59
  "name": "legwear",
60
  "children": [],
61
- "color": "#888888",
62
  "tags": [
63
  "socks",
64
  "..."
@@ -70,7 +70,7 @@
70
  {
71
  "name": "mask",
72
  "children": [],
73
- "color": "#888888",
74
  "tags": [
75
  "covered face",
76
  "..."
@@ -82,7 +82,7 @@
82
  {
83
  "name": "neck_and_neckwear",
84
  "children": [],
85
- "color": "#888888",
86
  "tags": [
87
  "Collarbone",
88
  "..."
@@ -97,7 +97,7 @@
97
  {
98
  "name": "sexual_attire_general",
99
  "children": [],
100
- "color": "#888888",
101
  "tags": [
102
  "lingerie",
103
  "..."
@@ -109,7 +109,7 @@
109
  {
110
  "name": "bra",
111
  "children": [],
112
- "color": "#888888",
113
  "tags": [
114
  "bra",
115
  "..."
@@ -121,7 +121,7 @@
121
  {
122
  "name": "panties",
123
  "children": [],
124
- "color": "#888888",
125
  "tags": [
126
  "panties",
127
  "..."
@@ -131,14 +131,14 @@
131
  "category_count": 0
132
  }
133
  ],
134
- "color": "#888888",
135
  "tag_count": 213,
136
  "category_count": 3
137
  },
138
  {
139
  "name": "sleeves",
140
  "children": [],
141
- "color": "#888888",
142
  "tags": [
143
  "See-through sleeves",
144
  "..."
@@ -150,7 +150,7 @@
150
  {
151
  "name": "swimsuit",
152
  "children": [],
153
- "color": "#888888",
154
  "tags": [
155
  "bathing",
156
  "..."
@@ -160,14 +160,14 @@
160
  "category_count": 0
161
  }
162
  ],
163
- "color": "#888888",
164
  "tag_count": 2020,
165
  "category_count": 13
166
  },
167
  {
168
  "name": "embellishment",
169
  "children": [],
170
- "color": "#888888",
171
  "tags": [
172
  "gem-studded",
173
  "..."
@@ -179,7 +179,7 @@
179
  {
180
  "name": "eyewear",
181
  "children": [],
182
- "color": "#888888",
183
  "tags": [
184
  "glasses",
185
  "..."
@@ -191,7 +191,7 @@
191
  {
192
  "name": "fashion_style",
193
  "children": [],
194
- "color": "#888888",
195
  "tags": [
196
  "1980s fashion",
197
  "..."
@@ -203,7 +203,7 @@
203
  {
204
  "name": "nudity",
205
  "children": [],
206
- "color": "#888888",
207
  "tags": [
208
  "completely nude",
209
  "..."
@@ -218,7 +218,7 @@
218
  {
219
  "name": "body_general",
220
  "children": [],
221
- "color": "#888888",
222
  "tags": [
223
  "alpaca ears",
224
  "..."
@@ -228,12 +228,12 @@
228
  "category_count": 0
229
  }
230
  ],
231
- "color": "#888888",
232
  "tag_count": 326,
233
  "category_count": 1
234
  }
235
  ],
236
- "color": "#888888",
237
  "tag_count": 2688,
238
  "category_count": 20
239
  },
@@ -246,7 +246,7 @@
246
  {
247
  "name": "body_parts_general",
248
  "children": [],
249
- "color": "#e76f51",
250
  "tags": [
251
  "ear focus",
252
  "..."
@@ -258,7 +258,7 @@
258
  {
259
  "name": "ass",
260
  "children": [],
261
- "color": "#e76f51",
262
  "tags": [
263
  "ass",
264
  "..."
@@ -270,7 +270,7 @@
270
  {
271
  "name": "breasts_tags",
272
  "children": [],
273
- "color": "#e76f51",
274
  "tags": [
275
  "breasts",
276
  "..."
@@ -282,7 +282,7 @@
282
  {
283
  "name": "ears_tags",
284
  "children": [],
285
- "color": "#e76f51",
286
  "tags": [
287
  "animal ears",
288
  "..."
@@ -297,7 +297,7 @@
297
  {
298
  "name": "face_tags_general",
299
  "children": [],
300
- "color": "#e76f51",
301
  "tags": [
302
  "multiple expressions",
303
  "..."
@@ -309,7 +309,7 @@
309
  {
310
  "name": "eyes_tags",
311
  "children": [],
312
- "color": "#e76f51",
313
  "tags": [
314
  "aqua eyes",
315
  "..."
@@ -319,7 +319,7 @@
319
  "category_count": 0
320
  }
321
  ],
322
- "color": "#e76f51",
323
  "tag_count": 391,
324
  "category_count": 2
325
  },
@@ -329,7 +329,7 @@
329
  {
330
  "name": "hair_general",
331
  "children": [],
332
- "color": "#e76f51",
333
  "tags": [
334
  "tag group:hair color",
335
  "..."
@@ -341,7 +341,7 @@
341
  {
342
  "name": "hair_color",
343
  "children": [],
344
- "color": "#e76f51",
345
  "tags": [
346
  "tag group:hair styles",
347
  "..."
@@ -353,7 +353,7 @@
353
  {
354
  "name": "hair_styles",
355
  "children": [],
356
- "color": "#e76f51",
357
  "tags": [
358
  "very short hair",
359
  "..."
@@ -363,7 +363,7 @@
363
  "category_count": 0
364
  }
365
  ],
366
- "color": "#e76f51",
367
  "tag_count": 288,
368
  "category_count": 3
369
  },
@@ -373,7 +373,7 @@
373
  {
374
  "name": "hands_general",
375
  "children": [],
376
- "color": "#e76f51",
377
  "tags": [
378
  "Adjusting eyewear",
379
  "..."
@@ -385,7 +385,7 @@
385
  {
386
  "name": "gestures",
387
  "children": [],
388
- "color": "#e76f51",
389
  "tags": [
390
  "air quotes",
391
  "..."
@@ -395,14 +395,14 @@
395
  "category_count": 0
396
  }
397
  ],
398
- "color": "#e76f51",
399
  "tag_count": 199,
400
  "category_count": 2
401
  },
402
  {
403
  "name": "neck_and_neckwear",
404
  "children": [],
405
- "color": "#e76f51",
406
  "tags": [
407
  "Collarbone",
408
  "..."
@@ -414,7 +414,7 @@
414
  {
415
  "name": "penis",
416
  "children": [],
417
- "color": "#e76f51",
418
  "tags": [
419
  "penis",
420
  "..."
@@ -426,7 +426,7 @@
426
  {
427
  "name": "posture",
428
  "children": [],
429
- "color": "#e76f51",
430
  "tags": [
431
  "Kneeling",
432
  "..."
@@ -438,7 +438,7 @@
438
  {
439
  "name": "pussy",
440
  "children": [],
441
- "color": "#e76f51",
442
  "tags": [
443
  "Clitoris",
444
  "..."
@@ -450,7 +450,7 @@
450
  {
451
  "name": "shoulders",
452
  "children": [],
453
- "color": "#e76f51",
454
  "tags": [
455
  "Nape",
456
  "..."
@@ -462,7 +462,7 @@
462
  {
463
  "name": "skin_color",
464
  "children": [],
465
- "color": "#e76f51",
466
  "tags": [
467
  "Dark skin",
468
  "..."
@@ -474,7 +474,7 @@
474
  {
475
  "name": "tail",
476
  "children": [],
477
- "color": "#e76f51",
478
  "tags": [
479
  "Tail",
480
  "..."
@@ -486,7 +486,7 @@
486
  {
487
  "name": "wings",
488
  "children": [],
489
- "color": "#e76f51",
490
  "tags": [
491
  "Wings",
492
  "..."
@@ -496,14 +496,14 @@
496
  "category_count": 0
497
  }
498
  ],
499
- "color": "#e76f51",
500
  "tag_count": 2180,
501
  "category_count": 22
502
  },
503
  {
504
  "name": "injury",
505
  "children": [],
506
- "color": "#e76f51",
507
  "tags": [
508
  "gun",
509
  "..."
@@ -513,7 +513,7 @@
513
  "category_count": 0
514
  }
515
  ],
516
- "color": "#e76f51",
517
  "tag_count": 2234,
518
  "category_count": 24
519
  },
@@ -523,7 +523,7 @@
523
  {
524
  "name": "ace_attorney",
525
  "children": [],
526
- "color": "#2a9d8f",
527
  "tags": [
528
  "Ace Attorney",
529
  "..."
@@ -535,7 +535,7 @@
535
  {
536
  "name": "arknights",
537
  "children": [],
538
- "color": "#2a9d8f",
539
  "tags": [
540
  "Arknights",
541
  "..."
@@ -547,7 +547,7 @@
547
  {
548
  "name": "atelier",
549
  "children": [],
550
- "color": "#2a9d8f",
551
  "tags": [
552
  "Gust",
553
  "..."
@@ -559,7 +559,7 @@
559
  {
560
  "name": "azur_lane",
561
  "children": [],
562
- "color": "#2a9d8f",
563
  "tags": [
564
  "Azur Lane",
565
  "..."
@@ -571,7 +571,7 @@
571
  {
572
  "name": "bleach",
573
  "children": [],
574
- "color": "#2a9d8f",
575
  "tags": [
576
  "Bleach",
577
  "..."
@@ -583,7 +583,7 @@
583
  {
584
  "name": "bokujou_monogatari",
585
  "children": [],
586
- "color": "#2a9d8f",
587
  "tags": [
588
  "Bokujou Monogatari",
589
  "..."
@@ -595,7 +595,7 @@
595
  {
596
  "name": "brave_girl_ravens",
597
  "children": [],
598
- "color": "#2a9d8f",
599
  "tags": [
600
  "DMM",
601
  "..."
@@ -607,7 +607,7 @@
607
  {
608
  "name": "cardcaptor_sakura",
609
  "children": [],
610
- "color": "#2a9d8f",
611
  "tags": [
612
  "Clamp (circle)",
613
  "..."
@@ -619,7 +619,7 @@
619
  {
620
  "name": "danganronpa",
621
  "children": [],
622
- "color": "#2a9d8f",
623
  "tags": [
624
  "Danganronpa (series)",
625
  "..."
@@ -634,7 +634,7 @@
634
  {
635
  "name": "digimon_general",
636
  "children": [],
637
- "color": "#2a9d8f",
638
  "tags": [
639
  "Digimon",
640
  "..."
@@ -646,7 +646,7 @@
646
  {
647
  "name": "digimon_characters",
648
  "children": [],
649
- "color": "#2a9d8f",
650
  "tags": [
651
  "Digimon",
652
  "..."
@@ -656,14 +656,14 @@
656
  "category_count": 0
657
  }
658
  ],
659
- "color": "#2a9d8f",
660
  "tag_count": 1252,
661
  "category_count": 2
662
  },
663
  {
664
  "name": "dragon_ball",
665
  "children": [],
666
- "color": "#2a9d8f",
667
  "tags": [
668
  "Dragon Ball",
669
  "..."
@@ -675,7 +675,7 @@
675
  {
676
  "name": "dragon_quest",
677
  "children": [],
678
- "color": "#2a9d8f",
679
  "tags": [
680
  "Square Enix",
681
  "..."
@@ -687,7 +687,7 @@
687
  {
688
  "name": "fate_series",
689
  "children": [],
690
- "color": "#2a9d8f",
691
  "tags": [
692
  "fate (series)",
693
  "..."
@@ -699,7 +699,7 @@
699
  {
700
  "name": "final_fantasy",
701
  "children": [],
702
- "color": "#2a9d8f",
703
  "tags": [
704
  "Final Fantasy",
705
  "..."
@@ -711,7 +711,7 @@
711
  {
712
  "name": "fire_emblem",
713
  "children": [],
714
- "color": "#2a9d8f",
715
  "tags": [
716
  "Fire Emblem",
717
  "..."
@@ -723,7 +723,7 @@
723
  {
724
  "name": "flower_knight_girl",
725
  "children": [],
726
- "color": "#2a9d8f",
727
  "tags": [
728
  "DMM",
729
  "..."
@@ -735,7 +735,7 @@
735
  {
736
  "name": "genderswap",
737
  "children": [],
738
- "color": "#2a9d8f",
739
  "tags": [
740
  "Genderswap",
741
  "..."
@@ -747,7 +747,7 @@
747
  {
748
  "name": "gensou_suikoden",
749
  "children": [],
750
- "color": "#2a9d8f",
751
  "tags": [
752
  "Gensou Suikoden",
753
  "..."
@@ -759,7 +759,7 @@
759
  {
760
  "name": "girls_und_panzer",
761
  "children": [],
762
- "color": "#2a9d8f",
763
  "tags": [
764
  "Girls und Panzer",
765
  "..."
@@ -771,7 +771,7 @@
771
  {
772
  "name": "gundam_mechas",
773
  "children": [],
774
- "color": "#2a9d8f",
775
  "tags": [
776
  "Zaku II F/J",
777
  "..."
@@ -783,7 +783,7 @@
783
  {
784
  "name": "hunter_x_hunter",
785
  "children": [],
786
- "color": "#2a9d8f",
787
  "tags": [
788
  "Hunter x Hunter",
789
  "..."
@@ -795,7 +795,7 @@
795
  {
796
  "name": "jojo_no_kimyou_na_bouken",
797
  "children": [],
798
- "color": "#2a9d8f",
799
  "tags": [
800
  "JoJo no Kimyou na Bouken",
801
  "..."
@@ -807,7 +807,7 @@
807
  {
808
  "name": "kamen_rider",
809
  "children": [],
810
- "color": "#2a9d8f",
811
  "tags": [
812
  "Kamen Rider (1st Series)",
813
  "..."
@@ -819,7 +819,7 @@
819
  {
820
  "name": "kantai_collection",
821
  "children": [],
822
- "color": "#2a9d8f",
823
  "tags": [
824
  "Kantai Collection",
825
  "..."
@@ -831,7 +831,7 @@
831
  {
832
  "name": "kingdom_hearts",
833
  "children": [],
834
- "color": "#2a9d8f",
835
  "tags": [
836
  "Kingdom Hearts",
837
  "..."
@@ -843,7 +843,7 @@
843
  {
844
  "name": "mahou_sensei_negima",
845
  "children": [],
846
- "color": "#2a9d8f",
847
  "tags": [
848
  "Mahou Sensei Negima!",
849
  "..."
@@ -855,7 +855,7 @@
855
  {
856
  "name": "meitantei_conan",
857
  "children": [],
858
- "color": "#2a9d8f",
859
  "tags": [
860
  "Meitantei Conan",
861
  "..."
@@ -867,7 +867,7 @@
867
  {
868
  "name": "minecraft",
869
  "children": [],
870
- "color": "#2a9d8f",
871
  "tags": [
872
  "Minecraft",
873
  "..."
@@ -879,7 +879,7 @@
879
  {
880
  "name": "naruto",
881
  "children": [],
882
- "color": "#2a9d8f",
883
  "tags": [
884
  "Naruto",
885
  "..."
@@ -891,7 +891,7 @@
891
  {
892
  "name": "nippon_ichi",
893
  "children": [],
894
- "color": "#2a9d8f",
895
  "tags": [
896
  "nippon ichi",
897
  "..."
@@ -903,7 +903,7 @@
903
  {
904
  "name": "official_mascots",
905
  "children": [],
906
- "color": "#2a9d8f",
907
  "tags": [
908
  "mascot",
909
  "..."
@@ -915,7 +915,7 @@
915
  {
916
  "name": "one_piece",
917
  "children": [],
918
- "color": "#2a9d8f",
919
  "tags": [
920
  "Oda Eiichirou",
921
  "..."
@@ -927,7 +927,7 @@
927
  {
928
  "name": "oshiro_project",
929
  "children": [],
930
- "color": "#2a9d8f",
931
  "tags": [
932
  "Oshiro Project:re",
933
  "..."
@@ -942,7 +942,7 @@
942
  {
943
  "name": "pokemon_general",
944
  "children": [],
945
- "color": "#2a9d8f",
946
  "tags": [
947
  "pokemon",
948
  "..."
@@ -954,7 +954,7 @@
954
  {
955
  "name": "elite_four_members",
956
  "children": [],
957
- "color": "#2a9d8f",
958
  "tags": [
959
  "pokemon",
960
  "..."
@@ -966,7 +966,7 @@
966
  {
967
  "name": "families_of_pokemon_main_characters",
968
  "children": [],
969
- "color": "#2a9d8f",
970
  "tags": [
971
  "list_of_pokemon_characters",
972
  "..."
@@ -978,7 +978,7 @@
978
  {
979
  "name": "gym_leaders",
980
  "children": [],
981
- "color": "#2a9d8f",
982
  "tags": [
983
  "list_of_pokemon_characters",
984
  "..."
@@ -990,7 +990,7 @@
990
  {
991
  "name": "pokemon_ranger_characters",
992
  "children": [],
993
- "color": "#2a9d8f",
994
  "tags": [
995
  "list_of_pokemon_characters",
996
  "..."
@@ -1002,7 +1002,7 @@
1002
  {
1003
  "name": "pokemon_trainer_classes",
1004
  "children": [],
1005
- "color": "#2a9d8f",
1006
  "tags": [
1007
  "list_of_pokemon_characters",
1008
  "..."
@@ -1012,14 +1012,14 @@
1012
  "category_count": 0
1013
  }
1014
  ],
1015
- "color": "#2a9d8f",
1016
  "tag_count": 1900,
1017
  "category_count": 6
1018
  },
1019
  {
1020
  "name": "pretty_cure",
1021
  "children": [],
1022
- "color": "#2a9d8f",
1023
  "tags": [
1024
  "precure",
1025
  "..."
@@ -1031,7 +1031,7 @@
1031
  {
1032
  "name": "ragnarok_online",
1033
  "children": [],
1034
- "color": "#2a9d8f",
1035
  "tags": [
1036
  "Ragnarok Online",
1037
  "..."
@@ -1043,7 +1043,7 @@
1043
  {
1044
  "name": "real_life_racehorses",
1045
  "children": [],
1046
- "color": "#2a9d8f",
1047
  "tags": [
1048
  "real life",
1049
  "..."
@@ -1055,7 +1055,7 @@
1055
  {
1056
  "name": "rosenkreuzstilette",
1057
  "children": [],
1058
- "color": "#2a9d8f",
1059
  "tags": [
1060
  "Rosenkreuzstilette",
1061
  "..."
@@ -1067,7 +1067,7 @@
1067
  {
1068
  "name": "sailor_moon",
1069
  "children": [],
1070
- "color": "#2a9d8f",
1071
  "tags": [
1072
  "Bishoujo Senshi Sailor Moon",
1073
  "..."
@@ -1079,7 +1079,7 @@
1079
  {
1080
  "name": "street_fighter",
1081
  "children": [],
1082
- "color": "#2a9d8f",
1083
  "tags": [
1084
  "Street Fighter",
1085
  "..."
@@ -1091,7 +1091,7 @@
1091
  {
1092
  "name": "toaru_majutsu_no_index",
1093
  "children": [],
1094
- "color": "#2a9d8f",
1095
  "tags": [
1096
  "Toaru Majutsu no Index",
1097
  "..."
@@ -1103,7 +1103,7 @@
1103
  {
1104
  "name": "touhou",
1105
  "children": [],
1106
- "color": "#2a9d8f",
1107
  "tags": [
1108
  "Touhou",
1109
  "..."
@@ -1115,7 +1115,7 @@
1115
  {
1116
  "name": "touken_ranbu",
1117
  "children": [],
1118
- "color": "#2a9d8f",
1119
  "tags": [
1120
  "Mikazuki Munechika",
1121
  "..."
@@ -1127,7 +1127,7 @@
1127
  {
1128
  "name": "ultra_series",
1129
  "children": [],
1130
- "color": "#2a9d8f",
1131
  "tags": [
1132
  "Ultra Series",
1133
  "..."
@@ -1139,7 +1139,7 @@
1139
  {
1140
  "name": "umamusume",
1141
  "children": [],
1142
- "color": "#2a9d8f",
1143
  "tags": [
1144
  "Umamusume",
1145
  "..."
@@ -1151,7 +1151,7 @@
1151
  {
1152
  "name": "vocaloid",
1153
  "children": [],
1154
- "color": "#2a9d8f",
1155
  "tags": [
1156
  "VOCALOID",
1157
  "..."
@@ -1163,7 +1163,7 @@
1163
  {
1164
  "name": "world_witches_series",
1165
  "children": [],
1166
- "color": "#2a9d8f",
1167
  "tags": [
1168
  "World Witches Series",
1169
  "..."
@@ -1173,12 +1173,12 @@
1173
  "category_count": 0
1174
  }
1175
  ],
1176
- "color": "#2a9d8f",
1177
  "tag_count": 18329,
1178
  "category_count": 55
1179
  },
1180
  {
1181
- "name": "copyrighted",
1182
  "children": [
1183
  {
1184
  "name": "genres_of_video_games",
@@ -1262,7 +1262,7 @@
1262
  {
1263
  "name": "animals_general",
1264
  "children": [],
1265
- "color": "#8ecae6",
1266
  "tags": [
1267
  "animal",
1268
  "..."
@@ -1274,7 +1274,7 @@
1274
  {
1275
  "name": "birds",
1276
  "children": [],
1277
- "color": "#8ecae6",
1278
  "tags": [
1279
  "tag groups",
1280
  "..."
@@ -1286,7 +1286,7 @@
1286
  {
1287
  "name": "cats",
1288
  "children": [],
1289
- "color": "#8ecae6",
1290
  "tags": [
1291
  "tag groups",
1292
  "..."
@@ -1298,7 +1298,7 @@
1298
  {
1299
  "name": "dogs",
1300
  "children": [],
1301
- "color": "#8ecae6",
1302
  "tags": [
1303
  "tag groups",
1304
  "..."
@@ -1308,14 +1308,14 @@
1308
  "category_count": 0
1309
  }
1310
  ],
1311
- "color": "#8ecae6",
1312
  "tag_count": 868,
1313
  "category_count": 4
1314
  },
1315
  {
1316
  "name": "legendary_creatures",
1317
  "children": [],
1318
- "color": "#8ecae6",
1319
  "tags": [
1320
  "tag groups",
1321
  "..."
@@ -1325,7 +1325,7 @@
1325
  "category_count": 0
1326
  }
1327
  ],
1328
- "color": "#8ecae6",
1329
  "tag_count": 1153,
1330
  "category_count": 6
1331
  },
@@ -1347,7 +1347,7 @@
1347
  {
1348
  "name": "board_games",
1349
  "children": [],
1350
- "color": "#3a86ff",
1351
  "tags": [
1352
  "tag groups",
1353
  "..."
@@ -1359,7 +1359,7 @@
1359
  {
1360
  "name": "fighting_games",
1361
  "children": [],
1362
- "color": "#3a86ff",
1363
  "tags": [
1364
  "tag groups",
1365
  "..."
@@ -1371,7 +1371,7 @@
1371
  {
1372
  "name": "game_activities",
1373
  "children": [],
1374
- "color": "#3a86ff",
1375
  "tags": [
1376
  "cat's cradle",
1377
  "..."
@@ -1383,7 +1383,7 @@
1383
  {
1384
  "name": "sports",
1385
  "children": [],
1386
- "color": "#3a86ff",
1387
  "tags": [
1388
  "Playing sports",
1389
  "..."
@@ -1395,7 +1395,7 @@
1395
  {
1396
  "name": "video_game",
1397
  "children": [],
1398
- "color": "#3a86ff",
1399
  "tags": [
1400
  "Tag Groups",
1401
  "..."
@@ -1405,14 +1405,14 @@
1405
  "category_count": 0
1406
  }
1407
  ],
1408
- "color": "#3a86ff",
1409
  "tag_count": 818,
1410
  "category_count": 5
1411
  },
1412
  {
1413
  "name": "metatags",
1414
  "children": [],
1415
- "color": "#ffbe0b",
1416
  "tags": [
1417
  "help:metatags",
1418
  "..."
@@ -1427,7 +1427,7 @@
1427
  {
1428
  "name": "dances",
1429
  "children": [],
1430
- "color": "#b5179e",
1431
  "tags": [
1432
  "tag groups",
1433
  "..."
@@ -1439,7 +1439,7 @@
1439
  {
1440
  "name": "family_relationships",
1441
  "children": [],
1442
- "color": "#b5179e",
1443
  "tags": [
1444
  "tag groups",
1445
  "..."
@@ -1451,7 +1451,7 @@
1451
  {
1452
  "name": "fire",
1453
  "children": [],
1454
- "color": "#b5179e",
1455
  "tags": [
1456
  "tag groups",
1457
  "..."
@@ -1463,7 +1463,7 @@
1463
  {
1464
  "name": "food_tags",
1465
  "children": [],
1466
- "color": "#b5179e",
1467
  "tags": [
1468
  "tag groups",
1469
  "..."
@@ -1475,7 +1475,7 @@
1475
  {
1476
  "name": "groups",
1477
  "children": [],
1478
- "color": "#b5179e",
1479
  "tags": [
1480
  "tag groups",
1481
  "..."
@@ -1487,7 +1487,7 @@
1487
  {
1488
  "name": "phrases",
1489
  "children": [],
1490
- "color": "#b5179e",
1491
  "tags": [
1492
  "Akeome",
1493
  "..."
@@ -1499,7 +1499,7 @@
1499
  {
1500
  "name": "scan",
1501
  "children": [],
1502
- "color": "#b5179e",
1503
  "tags": [
1504
  "scan",
1505
  "..."
@@ -1511,7 +1511,7 @@
1511
  {
1512
  "name": "subjective",
1513
  "children": [],
1514
- "color": "#b5179e",
1515
  "tags": [
1516
  "tag groups",
1517
  "..."
@@ -1523,7 +1523,7 @@
1523
  {
1524
  "name": "technology",
1525
  "children": [],
1526
- "color": "#b5179e",
1527
  "tags": [
1528
  "Science fiction",
1529
  "..."
@@ -1535,7 +1535,7 @@
1535
  {
1536
  "name": "verbs_and_gerunds",
1537
  "children": [],
1538
- "color": "#b5179e",
1539
  "tags": [
1540
  "aiming",
1541
  "..."
@@ -1547,7 +1547,7 @@
1547
  {
1548
  "name": "water",
1549
  "children": [],
1550
- "color": "#b5179e",
1551
  "tags": [
1552
  "tag groups",
1553
  "..."
@@ -1557,7 +1557,7 @@
1557
  "category_count": 0
1558
  }
1559
  ],
1560
- "color": "#b5179e",
1561
  "tag_count": 2155,
1562
  "category_count": 11
1563
  },
@@ -1925,7 +1925,7 @@
1925
  "name": "visual_characteristics",
1926
  "children": [
1927
  {
1928
- "name": "image composition, style",
1929
  "children": [
1930
  {
1931
  "name": "artistic_license",
 
2
  "name": "root",
3
  "children": [
4
  {
5
+ "name": "attire_and_body_accessories",
6
  "children": [
7
  {
8
  "name": "attire",
 
10
  {
11
  "name": "attire_general",
12
  "children": [],
13
+ "color": "#DC143C",
14
  "tags": [
15
  "balaclava",
16
  "..."
 
22
  {
23
  "name": "dress",
24
  "children": [],
25
+ "color": "#DC143C",
26
  "tags": [
27
  "Dress",
28
  "..."
 
34
  {
35
  "name": "handwear",
36
  "children": [],
37
+ "color": "#DC143C",
38
  "tags": [
39
  "Elbow gloves",
40
  "..."
 
46
  {
47
  "name": "headwear",
48
  "children": [],
49
+ "color": "#DC143C",
50
  "tags": [
51
  "crown",
52
  "..."
 
58
  {
59
  "name": "legwear",
60
  "children": [],
61
+ "color": "#DC143C",
62
  "tags": [
63
  "socks",
64
  "..."
 
70
  {
71
  "name": "mask",
72
  "children": [],
73
+ "color": "#DC143C",
74
  "tags": [
75
  "covered face",
76
  "..."
 
82
  {
83
  "name": "neck_and_neckwear",
84
  "children": [],
85
+ "color": "#DC143C",
86
  "tags": [
87
  "Collarbone",
88
  "..."
 
97
  {
98
  "name": "sexual_attire_general",
99
  "children": [],
100
+ "color": "#DC143C",
101
  "tags": [
102
  "lingerie",
103
  "..."
 
109
  {
110
  "name": "bra",
111
  "children": [],
112
+ "color": "#DC143C",
113
  "tags": [
114
  "bra",
115
  "..."
 
121
  {
122
  "name": "panties",
123
  "children": [],
124
+ "color": "#DC143C",
125
  "tags": [
126
  "panties",
127
  "..."
 
131
  "category_count": 0
132
  }
133
  ],
134
+ "color": "#DC143C",
135
  "tag_count": 213,
136
  "category_count": 3
137
  },
138
  {
139
  "name": "sleeves",
140
  "children": [],
141
+ "color": "#DC143C",
142
  "tags": [
143
  "See-through sleeves",
144
  "..."
 
150
  {
151
  "name": "swimsuit",
152
  "children": [],
153
+ "color": "#DC143C",
154
  "tags": [
155
  "bathing",
156
  "..."
 
160
  "category_count": 0
161
  }
162
  ],
163
+ "color": "#DC143C",
164
  "tag_count": 2020,
165
  "category_count": 13
166
  },
167
  {
168
  "name": "embellishment",
169
  "children": [],
170
+ "color": "#DC143C",
171
  "tags": [
172
  "gem-studded",
173
  "..."
 
179
  {
180
  "name": "eyewear",
181
  "children": [],
182
+ "color": "#DC143C",
183
  "tags": [
184
  "glasses",
185
  "..."
 
191
  {
192
  "name": "fashion_style",
193
  "children": [],
194
+ "color": "#DC143C",
195
  "tags": [
196
  "1980s fashion",
197
  "..."
 
203
  {
204
  "name": "nudity",
205
  "children": [],
206
+ "color": "#DC143C",
207
  "tags": [
208
  "completely nude",
209
  "..."
 
218
  {
219
  "name": "body_general",
220
  "children": [],
221
+ "color": "#DC143C",
222
  "tags": [
223
  "alpaca ears",
224
  "..."
 
228
  "category_count": 0
229
  }
230
  ],
231
+ "color": "#DC143C",
232
  "tag_count": 326,
233
  "category_count": 1
234
  }
235
  ],
236
+ "color": "#DC143C",
237
  "tag_count": 2688,
238
  "category_count": 20
239
  },
 
246
  {
247
  "name": "body_parts_general",
248
  "children": [],
249
+ "color": "coral",
250
  "tags": [
251
  "ear focus",
252
  "..."
 
258
  {
259
  "name": "ass",
260
  "children": [],
261
+ "color": "coral",
262
  "tags": [
263
  "ass",
264
  "..."
 
270
  {
271
  "name": "breasts_tags",
272
  "children": [],
273
+ "color": "coral",
274
  "tags": [
275
  "breasts",
276
  "..."
 
282
  {
283
  "name": "ears_tags",
284
  "children": [],
285
+ "color": "coral",
286
  "tags": [
287
  "animal ears",
288
  "..."
 
297
  {
298
  "name": "face_tags_general",
299
  "children": [],
300
+ "color": "coral",
301
  "tags": [
302
  "multiple expressions",
303
  "..."
 
309
  {
310
  "name": "eyes_tags",
311
  "children": [],
312
+ "color": "coral",
313
  "tags": [
314
  "aqua eyes",
315
  "..."
 
319
  "category_count": 0
320
  }
321
  ],
322
+ "color": "coral",
323
  "tag_count": 391,
324
  "category_count": 2
325
  },
 
329
  {
330
  "name": "hair_general",
331
  "children": [],
332
+ "color": "coral",
333
  "tags": [
334
  "tag group:hair color",
335
  "..."
 
341
  {
342
  "name": "hair_color",
343
  "children": [],
344
+ "color": "coral",
345
  "tags": [
346
  "tag group:hair styles",
347
  "..."
 
353
  {
354
  "name": "hair_styles",
355
  "children": [],
356
+ "color": "coral",
357
  "tags": [
358
  "very short hair",
359
  "..."
 
363
  "category_count": 0
364
  }
365
  ],
366
+ "color": "coral",
367
  "tag_count": 288,
368
  "category_count": 3
369
  },
 
373
  {
374
  "name": "hands_general",
375
  "children": [],
376
+ "color": "coral",
377
  "tags": [
378
  "Adjusting eyewear",
379
  "..."
 
385
  {
386
  "name": "gestures",
387
  "children": [],
388
+ "color": "coral",
389
  "tags": [
390
  "air quotes",
391
  "..."
 
395
  "category_count": 0
396
  }
397
  ],
398
+ "color": "coral",
399
  "tag_count": 199,
400
  "category_count": 2
401
  },
402
  {
403
  "name": "neck_and_neckwear",
404
  "children": [],
405
+ "color": "coral",
406
  "tags": [
407
  "Collarbone",
408
  "..."
 
414
  {
415
  "name": "penis",
416
  "children": [],
417
+ "color": "coral",
418
  "tags": [
419
  "penis",
420
  "..."
 
426
  {
427
  "name": "posture",
428
  "children": [],
429
+ "color": "coral",
430
  "tags": [
431
  "Kneeling",
432
  "..."
 
438
  {
439
  "name": "pussy",
440
  "children": [],
441
+ "color": "coral",
442
  "tags": [
443
  "Clitoris",
444
  "..."
 
450
  {
451
  "name": "shoulders",
452
  "children": [],
453
+ "color": "coral",
454
  "tags": [
455
  "Nape",
456
  "..."
 
462
  {
463
  "name": "skin_color",
464
  "children": [],
465
+ "color": "coral",
466
  "tags": [
467
  "Dark skin",
468
  "..."
 
474
  {
475
  "name": "tail",
476
  "children": [],
477
+ "color": "coral",
478
  "tags": [
479
  "Tail",
480
  "..."
 
486
  {
487
  "name": "wings",
488
  "children": [],
489
+ "color": "coral",
490
  "tags": [
491
  "Wings",
492
  "..."
 
496
  "category_count": 0
497
  }
498
  ],
499
+ "color": "coral",
500
  "tag_count": 2180,
501
  "category_count": 22
502
  },
503
  {
504
  "name": "injury",
505
  "children": [],
506
+ "color": "coral",
507
  "tags": [
508
  "gun",
509
  "..."
 
513
  "category_count": 0
514
  }
515
  ],
516
+ "color": "coral",
517
  "tag_count": 2234,
518
  "category_count": 24
519
  },
 
523
  {
524
  "name": "ace_attorney",
525
  "children": [],
526
+ "color": "silver",
527
  "tags": [
528
  "Ace Attorney",
529
  "..."
 
535
  {
536
  "name": "arknights",
537
  "children": [],
538
+ "color": "silver",
539
  "tags": [
540
  "Arknights",
541
  "..."
 
547
  {
548
  "name": "atelier",
549
  "children": [],
550
+ "color": "silver",
551
  "tags": [
552
  "Gust",
553
  "..."
 
559
  {
560
  "name": "azur_lane",
561
  "children": [],
562
+ "color": "silver",
563
  "tags": [
564
  "Azur Lane",
565
  "..."
 
571
  {
572
  "name": "bleach",
573
  "children": [],
574
+ "color": "silver",
575
  "tags": [
576
  "Bleach",
577
  "..."
 
583
  {
584
  "name": "bokujou_monogatari",
585
  "children": [],
586
+ "color": "silver",
587
  "tags": [
588
  "Bokujou Monogatari",
589
  "..."
 
595
  {
596
  "name": "brave_girl_ravens",
597
  "children": [],
598
+ "color": "silver",
599
  "tags": [
600
  "DMM",
601
  "..."
 
607
  {
608
  "name": "cardcaptor_sakura",
609
  "children": [],
610
+ "color": "silver",
611
  "tags": [
612
  "Clamp (circle)",
613
  "..."
 
619
  {
620
  "name": "danganronpa",
621
  "children": [],
622
+ "color": "silver",
623
  "tags": [
624
  "Danganronpa (series)",
625
  "..."
 
634
  {
635
  "name": "digimon_general",
636
  "children": [],
637
+ "color": "silver",
638
  "tags": [
639
  "Digimon",
640
  "..."
 
646
  {
647
  "name": "digimon_characters",
648
  "children": [],
649
+ "color": "silver",
650
  "tags": [
651
  "Digimon",
652
  "..."
 
656
  "category_count": 0
657
  }
658
  ],
659
+ "color": "silver",
660
  "tag_count": 1252,
661
  "category_count": 2
662
  },
663
  {
664
  "name": "dragon_ball",
665
  "children": [],
666
+ "color": "silver",
667
  "tags": [
668
  "Dragon Ball",
669
  "..."
 
675
  {
676
  "name": "dragon_quest",
677
  "children": [],
678
+ "color": "silver",
679
  "tags": [
680
  "Square Enix",
681
  "..."
 
687
  {
688
  "name": "fate_series",
689
  "children": [],
690
+ "color": "silver",
691
  "tags": [
692
  "fate (series)",
693
  "..."
 
699
  {
700
  "name": "final_fantasy",
701
  "children": [],
702
+ "color": "silver",
703
  "tags": [
704
  "Final Fantasy",
705
  "..."
 
711
  {
712
  "name": "fire_emblem",
713
  "children": [],
714
+ "color": "silver",
715
  "tags": [
716
  "Fire Emblem",
717
  "..."
 
723
  {
724
  "name": "flower_knight_girl",
725
  "children": [],
726
+ "color": "silver",
727
  "tags": [
728
  "DMM",
729
  "..."
 
735
  {
736
  "name": "genderswap",
737
  "children": [],
738
+ "color": "silver",
739
  "tags": [
740
  "Genderswap",
741
  "..."
 
747
  {
748
  "name": "gensou_suikoden",
749
  "children": [],
750
+ "color": "silver",
751
  "tags": [
752
  "Gensou Suikoden",
753
  "..."
 
759
  {
760
  "name": "girls_und_panzer",
761
  "children": [],
762
+ "color": "silver",
763
  "tags": [
764
  "Girls und Panzer",
765
  "..."
 
771
  {
772
  "name": "gundam_mechas",
773
  "children": [],
774
+ "color": "silver",
775
  "tags": [
776
  "Zaku II F/J",
777
  "..."
 
783
  {
784
  "name": "hunter_x_hunter",
785
  "children": [],
786
+ "color": "silver",
787
  "tags": [
788
  "Hunter x Hunter",
789
  "..."
 
795
  {
796
  "name": "jojo_no_kimyou_na_bouken",
797
  "children": [],
798
+ "color": "silver",
799
  "tags": [
800
  "JoJo no Kimyou na Bouken",
801
  "..."
 
807
  {
808
  "name": "kamen_rider",
809
  "children": [],
810
+ "color": "silver",
811
  "tags": [
812
  "Kamen Rider (1st Series)",
813
  "..."
 
819
  {
820
  "name": "kantai_collection",
821
  "children": [],
822
+ "color": "silver",
823
  "tags": [
824
  "Kantai Collection",
825
  "..."
 
831
  {
832
  "name": "kingdom_hearts",
833
  "children": [],
834
+ "color": "silver",
835
  "tags": [
836
  "Kingdom Hearts",
837
  "..."
 
843
  {
844
  "name": "mahou_sensei_negima",
845
  "children": [],
846
+ "color": "silver",
847
  "tags": [
848
  "Mahou Sensei Negima!",
849
  "..."
 
855
  {
856
  "name": "meitantei_conan",
857
  "children": [],
858
+ "color": "silver",
859
  "tags": [
860
  "Meitantei Conan",
861
  "..."
 
867
  {
868
  "name": "minecraft",
869
  "children": [],
870
+ "color": "silver",
871
  "tags": [
872
  "Minecraft",
873
  "..."
 
879
  {
880
  "name": "naruto",
881
  "children": [],
882
+ "color": "silver",
883
  "tags": [
884
  "Naruto",
885
  "..."
 
891
  {
892
  "name": "nippon_ichi",
893
  "children": [],
894
+ "color": "silver",
895
  "tags": [
896
  "nippon ichi",
897
  "..."
 
903
  {
904
  "name": "official_mascots",
905
  "children": [],
906
+ "color": "silver",
907
  "tags": [
908
  "mascot",
909
  "..."
 
915
  {
916
  "name": "one_piece",
917
  "children": [],
918
+ "color": "silver",
919
  "tags": [
920
  "Oda Eiichirou",
921
  "..."
 
927
  {
928
  "name": "oshiro_project",
929
  "children": [],
930
+ "color": "silver",
931
  "tags": [
932
  "Oshiro Project:re",
933
  "..."
 
942
  {
943
  "name": "pokemon_general",
944
  "children": [],
945
+ "color": "silver",
946
  "tags": [
947
  "pokemon",
948
  "..."
 
954
  {
955
  "name": "elite_four_members",
956
  "children": [],
957
+ "color": "silver",
958
  "tags": [
959
  "pokemon",
960
  "..."
 
966
  {
967
  "name": "families_of_pokemon_main_characters",
968
  "children": [],
969
+ "color": "silver",
970
  "tags": [
971
  "list_of_pokemon_characters",
972
  "..."
 
978
  {
979
  "name": "gym_leaders",
980
  "children": [],
981
+ "color": "silver",
982
  "tags": [
983
  "list_of_pokemon_characters",
984
  "..."
 
990
  {
991
  "name": "pokemon_ranger_characters",
992
  "children": [],
993
+ "color": "silver",
994
  "tags": [
995
  "list_of_pokemon_characters",
996
  "..."
 
1002
  {
1003
  "name": "pokemon_trainer_classes",
1004
  "children": [],
1005
+ "color": "silver",
1006
  "tags": [
1007
  "list_of_pokemon_characters",
1008
  "..."
 
1012
  "category_count": 0
1013
  }
1014
  ],
1015
+ "color": "silver",
1016
  "tag_count": 1900,
1017
  "category_count": 6
1018
  },
1019
  {
1020
  "name": "pretty_cure",
1021
  "children": [],
1022
+ "color": "silver",
1023
  "tags": [
1024
  "precure",
1025
  "..."
 
1031
  {
1032
  "name": "ragnarok_online",
1033
  "children": [],
1034
+ "color": "silver",
1035
  "tags": [
1036
  "Ragnarok Online",
1037
  "..."
 
1043
  {
1044
  "name": "real_life_racehorses",
1045
  "children": [],
1046
+ "color": "silver",
1047
  "tags": [
1048
  "real life",
1049
  "..."
 
1055
  {
1056
  "name": "rosenkreuzstilette",
1057
  "children": [],
1058
+ "color": "silver",
1059
  "tags": [
1060
  "Rosenkreuzstilette",
1061
  "..."
 
1067
  {
1068
  "name": "sailor_moon",
1069
  "children": [],
1070
+ "color": "silver",
1071
  "tags": [
1072
  "Bishoujo Senshi Sailor Moon",
1073
  "..."
 
1079
  {
1080
  "name": "street_fighter",
1081
  "children": [],
1082
+ "color": "silver",
1083
  "tags": [
1084
  "Street Fighter",
1085
  "..."
 
1091
  {
1092
  "name": "toaru_majutsu_no_index",
1093
  "children": [],
1094
+ "color": "silver",
1095
  "tags": [
1096
  "Toaru Majutsu no Index",
1097
  "..."
 
1103
  {
1104
  "name": "touhou",
1105
  "children": [],
1106
+ "color": "silver",
1107
  "tags": [
1108
  "Touhou",
1109
  "..."
 
1115
  {
1116
  "name": "touken_ranbu",
1117
  "children": [],
1118
+ "color": "silver",
1119
  "tags": [
1120
  "Mikazuki Munechika",
1121
  "..."
 
1127
  {
1128
  "name": "ultra_series",
1129
  "children": [],
1130
+ "color": "silver",
1131
  "tags": [
1132
  "Ultra Series",
1133
  "..."
 
1139
  {
1140
  "name": "umamusume",
1141
  "children": [],
1142
+ "color": "silver",
1143
  "tags": [
1144
  "Umamusume",
1145
  "..."
 
1151
  {
1152
  "name": "vocaloid",
1153
  "children": [],
1154
+ "color": "silver",
1155
  "tags": [
1156
  "VOCALOID",
1157
  "..."
 
1163
  {
1164
  "name": "world_witches_series",
1165
  "children": [],
1166
+ "color": "silver",
1167
  "tags": [
1168
  "World Witches Series",
1169
  "..."
 
1173
  "category_count": 0
1174
  }
1175
  ],
1176
+ "color": "silver",
1177
  "tag_count": 18329,
1178
  "category_count": 55
1179
  },
1180
  {
1181
+ "name": "copyrights_artists_projects_and_media",
1182
  "children": [
1183
  {
1184
  "name": "genres_of_video_games",
 
1262
  {
1263
  "name": "animals_general",
1264
  "children": [],
1265
+ "color": "silver",
1266
  "tags": [
1267
  "animal",
1268
  "..."
 
1274
  {
1275
  "name": "birds",
1276
  "children": [],
1277
+ "color": "silver",
1278
  "tags": [
1279
  "tag groups",
1280
  "..."
 
1286
  {
1287
  "name": "cats",
1288
  "children": [],
1289
+ "color": "silver",
1290
  "tags": [
1291
  "tag groups",
1292
  "..."
 
1298
  {
1299
  "name": "dogs",
1300
  "children": [],
1301
+ "color": "silver",
1302
  "tags": [
1303
  "tag groups",
1304
  "..."
 
1308
  "category_count": 0
1309
  }
1310
  ],
1311
+ "color": "silver",
1312
  "tag_count": 868,
1313
  "category_count": 4
1314
  },
1315
  {
1316
  "name": "legendary_creatures",
1317
  "children": [],
1318
+ "color": "silver",
1319
  "tags": [
1320
  "tag groups",
1321
  "..."
 
1325
  "category_count": 0
1326
  }
1327
  ],
1328
+ "color": "silver",
1329
  "tag_count": 1153,
1330
  "category_count": 6
1331
  },
 
1347
  {
1348
  "name": "board_games",
1349
  "children": [],
1350
+ "color": "silver",
1351
  "tags": [
1352
  "tag groups",
1353
  "..."
 
1359
  {
1360
  "name": "fighting_games",
1361
  "children": [],
1362
+ "color": "silver",
1363
  "tags": [
1364
  "tag groups",
1365
  "..."
 
1371
  {
1372
  "name": "game_activities",
1373
  "children": [],
1374
+ "color": "silver",
1375
  "tags": [
1376
  "cat's cradle",
1377
  "..."
 
1383
  {
1384
  "name": "sports",
1385
  "children": [],
1386
+ "color": "silver",
1387
  "tags": [
1388
  "Playing sports",
1389
  "..."
 
1395
  {
1396
  "name": "video_game",
1397
  "children": [],
1398
+ "color": "silver",
1399
  "tags": [
1400
  "Tag Groups",
1401
  "..."
 
1405
  "category_count": 0
1406
  }
1407
  ],
1408
+ "color": "silver",
1409
  "tag_count": 818,
1410
  "category_count": 5
1411
  },
1412
  {
1413
  "name": "metatags",
1414
  "children": [],
1415
+ "color": "silver",
1416
  "tags": [
1417
  "help:metatags",
1418
  "..."
 
1427
  {
1428
  "name": "dances",
1429
  "children": [],
1430
+ "color": "silver",
1431
  "tags": [
1432
  "tag groups",
1433
  "..."
 
1439
  {
1440
  "name": "family_relationships",
1441
  "children": [],
1442
+ "color": "silver",
1443
  "tags": [
1444
  "tag groups",
1445
  "..."
 
1451
  {
1452
  "name": "fire",
1453
  "children": [],
1454
+ "color": "silver",
1455
  "tags": [
1456
  "tag groups",
1457
  "..."
 
1463
  {
1464
  "name": "food_tags",
1465
  "children": [],
1466
+ "color": "silver",
1467
  "tags": [
1468
  "tag groups",
1469
  "..."
 
1475
  {
1476
  "name": "groups",
1477
  "children": [],
1478
+ "color": "silver",
1479
  "tags": [
1480
  "tag groups",
1481
  "..."
 
1487
  {
1488
  "name": "phrases",
1489
  "children": [],
1490
+ "color": "silver",
1491
  "tags": [
1492
  "Akeome",
1493
  "..."
 
1499
  {
1500
  "name": "scan",
1501
  "children": [],
1502
+ "color": "silver",
1503
  "tags": [
1504
  "scan",
1505
  "..."
 
1511
  {
1512
  "name": "subjective",
1513
  "children": [],
1514
+ "color": "silver",
1515
  "tags": [
1516
  "tag groups",
1517
  "..."
 
1523
  {
1524
  "name": "technology",
1525
  "children": [],
1526
+ "color": "silver",
1527
  "tags": [
1528
  "Science fiction",
1529
  "..."
 
1535
  {
1536
  "name": "verbs_and_gerunds",
1537
  "children": [],
1538
+ "color": "silver",
1539
  "tags": [
1540
  "aiming",
1541
  "..."
 
1547
  {
1548
  "name": "water",
1549
  "children": [],
1550
+ "color": "silver",
1551
  "tags": [
1552
  "tag groups",
1553
  "..."
 
1557
  "category_count": 0
1558
  }
1559
  ],
1560
+ "color": "silver",
1561
  "tag_count": 2155,
1562
  "category_count": 11
1563
  },
 
1925
  "name": "visual_characteristics",
1926
  "children": [
1927
  {
1928
+ "name": "image_composition_and_style",
1929
  "children": [
1930
  {
1931
  "name": "artistic_license",
public/json/tags_america.json CHANGED
@@ -352,10 +352,6 @@
352
  "id": "mature",
353
  "size": 1
354
  },
355
- {
356
- "id": "photography",
357
- "size": 1
358
- },
359
  {
360
  "id": "thanksgiving",
361
  "size": 1
@@ -368,6 +364,10 @@
368
  "id": "puritans",
369
  "size": 1
370
  },
 
 
 
 
371
  {
372
  "id": "uncle sam",
373
  "size": 1
@@ -418,8 +418,8 @@
418
  "value": 1
419
  },
420
  {
421
- "source": "american",
422
- "target": "america",
423
  "value": 4
424
  },
425
  {
@@ -443,8 +443,8 @@
443
  "value": 1
444
  },
445
  {
446
- "source": "funny",
447
- "target": "america",
448
  "value": 1
449
  },
450
  {
@@ -468,8 +468,8 @@
468
  "value": 3
469
  },
470
  {
471
- "source": "celebrity",
472
- "target": "politician",
473
  "value": 2
474
  },
475
  {
@@ -478,8 +478,8 @@
478
  "value": 1
479
  },
480
  {
481
- "source": "political",
482
- "target": "america",
483
  "value": 2
484
  },
485
  {
@@ -498,8 +498,8 @@
498
  "value": 4
499
  },
500
  {
501
- "source": "joke",
502
- "target": "america",
503
  "value": 1
504
  },
505
  {
@@ -523,8 +523,8 @@
523
  "value": 1
524
  },
525
  {
526
- "source": "vintage",
527
- "target": "airbrushed",
528
  "value": 1
529
  },
530
  {
@@ -533,8 +533,8 @@
533
  "value": 1
534
  },
535
  {
536
- "source": "vintage",
537
- "target": "america",
538
  "value": 1
539
  },
540
  {
@@ -543,8 +543,8 @@
543
  "value": 1
544
  },
545
  {
546
- "source": "posters",
547
- "target": "pin-up",
548
  "value": 1
549
  },
550
  {
@@ -558,8 +558,8 @@
558
  "value": 1
559
  },
560
  {
561
- "source": "pin-up",
562
- "target": "america",
563
  "value": 1
564
  },
565
  {
@@ -583,8 +583,8 @@
583
  "value": 1
584
  },
585
  {
586
- "source": "posters",
587
- "target": "airbrushed",
588
  "value": 1
589
  },
590
  {
@@ -593,8 +593,8 @@
593
  "value": 1
594
  },
595
  {
596
- "source": "posters",
597
- "target": "america",
598
  "value": 1
599
  },
600
  {
@@ -608,23 +608,23 @@
608
  "value": 1
609
  },
610
  {
611
- "source": "wwii",
612
- "target": "america",
613
  "value": 1
614
  },
615
  {
616
- "source": "photorealistic",
617
- "target": "1950s",
618
  "value": 1
619
  },
620
  {
621
- "source": "1950s",
622
- "target": "oldschool",
623
  "value": 1
624
  },
625
  {
626
- "source": "1950s",
627
- "target": "america",
628
  "value": 1
629
  },
630
  {
@@ -643,48 +643,48 @@
643
  "value": 1
644
  },
645
  {
646
- "source": "photorealistic",
647
- "target": "oldschool",
648
  "value": 1
649
  },
650
  {
651
- "source": "photorealistic",
652
- "target": "america",
653
  "value": 3
654
  },
655
  {
656
- "source": "photorealistic",
657
- "target": "style",
658
  "value": 1
659
  },
660
  {
661
- "source": "photorealistic",
662
- "target": "realistic",
663
  "value": 1
664
  },
665
  {
666
- "source": "photorealistic",
667
- "target": "usa",
668
  "value": 1
669
  },
670
  {
671
- "source": "america",
672
- "target": "oldschool",
673
  "value": 1
674
  },
675
  {
676
- "source": "style",
677
- "target": "oldschool",
678
  "value": 1
679
  },
680
  {
681
- "source": "realistic",
682
- "target": "oldschool",
683
  "value": 1
684
  },
685
  {
686
- "source": "usa",
687
- "target": "oldschool",
688
  "value": 1
689
  },
690
  {
@@ -693,13 +693,13 @@
693
  "value": 3
694
  },
695
  {
696
- "source": "realistic",
697
- "target": "america",
698
  "value": 1
699
  },
700
  {
701
- "source": "usa",
702
- "target": "america",
703
  "value": 5
704
  },
705
  {
@@ -718,8 +718,8 @@
718
  "value": 1
719
  },
720
  {
721
- "source": "photorealistic",
722
- "target": "politician",
723
  "value": 1
724
  },
725
  {
@@ -728,13 +728,13 @@
728
  "value": 1
729
  },
730
  {
731
- "source": "photorealistic",
732
- "target": "celebrity",
733
  "value": 1
734
  },
735
  {
736
- "source": "photorealistic",
737
- "target": "photorealism",
738
  "value": 1
739
  },
740
  {
@@ -748,8 +748,8 @@
748
  "value": 1
749
  },
750
  {
751
- "source": "politician",
752
- "target": "photorealism",
753
  "value": 1
754
  },
755
  {
@@ -758,8 +758,8 @@
758
  "value": 1
759
  },
760
  {
761
- "source": "woman",
762
- "target": "america",
763
  "value": 4
764
  },
765
  {
@@ -768,8 +768,8 @@
768
  "value": 1
769
  },
770
  {
771
- "source": "real person",
772
- "target": "america",
773
  "value": 1
774
  },
775
  {
@@ -788,8 +788,8 @@
788
  "value": 1
789
  },
790
  {
791
- "source": "celebrity",
792
- "target": "photorealism",
793
  "value": 1
794
  },
795
  {
@@ -798,8 +798,8 @@
798
  "value": 1
799
  },
800
  {
801
- "source": "real person",
802
- "target": "photorealism",
803
  "value": 1
804
  },
805
  {
@@ -868,8 +868,8 @@
868
  "value": 1
869
  },
870
  {
871
- "source": "female",
872
- "target": "america",
873
  "value": 1
874
  },
875
  {
@@ -883,8 +883,8 @@
883
  "value": 1
884
  },
885
  {
886
- "source": "blonde",
887
- "target": "america",
888
  "value": 2
889
  },
890
  {
@@ -903,13 +903,13 @@
903
  "value": 1
904
  },
905
  {
906
- "source": "clothing",
907
- "target": "trump",
908
  "value": 1
909
  },
910
  {
911
- "source": "donald trump",
912
- "target": "clothing",
913
  "value": 1
914
  },
915
  {
@@ -928,38 +928,38 @@
928
  "value": 1
929
  },
930
  {
931
- "source": "clothing",
932
- "target": "maga hat",
933
  "value": 1
934
  },
935
  {
936
- "source": "donald trump",
937
- "target": "trump",
938
  "value": 1
939
  },
940
  {
941
- "source": "maga",
942
- "target": "trump",
943
  "value": 1
944
  },
945
  {
946
- "source": "maga cap",
947
- "target": "trump",
948
  "value": 1
949
  },
950
  {
951
- "source": "make america great again hat",
952
- "target": "trump",
953
  "value": 1
954
  },
955
  {
956
- "source": "trump",
957
- "target": "maga hat",
958
  "value": 1
959
  },
960
  {
961
- "source": "donald trump",
962
- "target": "maga",
963
  "value": 1
964
  },
965
  {
@@ -973,8 +973,8 @@
973
  "value": 1
974
  },
975
  {
976
- "source": "donald trump",
977
- "target": "maga hat",
978
  "value": 1
979
  },
980
  {
@@ -983,28 +983,28 @@
983
  "value": 1
984
  },
985
  {
986
- "source": "make america great again hat",
987
- "target": "maga",
988
  "value": 1
989
  },
990
  {
991
- "source": "maga",
992
- "target": "maga hat",
993
  "value": 1
994
  },
995
  {
996
- "source": "make america great again hat",
997
- "target": "maga cap",
998
  "value": 1
999
  },
1000
  {
1001
- "source": "maga cap",
1002
- "target": "maga hat",
1003
  "value": 1
1004
  },
1005
  {
1006
- "source": "make america great again hat",
1007
- "target": "maga hat",
1008
  "value": 1
1009
  },
1010
  {
@@ -1013,13 +1013,13 @@
1013
  "value": 3
1014
  },
1015
  {
1016
- "source": "indigenous cultures",
1017
- "target": "base model",
1018
  "value": 3
1019
  },
1020
  {
1021
- "source": "north america",
1022
- "target": "base model",
1023
  "value": 1
1024
  },
1025
  {
@@ -1028,8 +1028,8 @@
1028
  "value": 1
1029
  },
1030
  {
1031
- "source": "north-america",
1032
- "target": "base model",
1033
  "value": 1
1034
  },
1035
  {
@@ -1083,13 +1083,13 @@
1083
  "value": 1
1084
  },
1085
  {
1086
- "source": "south america",
1087
- "target": "base model",
1088
  "value": 1
1089
  },
1090
  {
1091
- "source": "south-america",
1092
- "target": "base model",
1093
  "value": 1
1094
  },
1095
  {
@@ -1113,13 +1113,13 @@
1113
  "value": 1
1114
  },
1115
  {
1116
- "source": "south america",
1117
- "target": "indigenous cultures",
1118
  "value": 1
1119
  },
1120
  {
1121
- "source": "south-america",
1122
- "target": "indigenous cultures",
1123
  "value": 1
1124
  },
1125
  {
@@ -1133,8 +1133,8 @@
1133
  "value": 1
1134
  },
1135
  {
1136
- "source": "south america",
1137
- "target": "south american",
1138
  "value": 1
1139
  },
1140
  {
@@ -1168,8 +1168,8 @@
1168
  "value": 1
1169
  },
1170
  {
1171
- "source": "military",
1172
- "target": "america",
1173
  "value": 1
1174
  },
1175
  {
@@ -1193,13 +1193,13 @@
1193
  "value": 1
1194
  },
1195
  {
1196
- "source": "clothing",
1197
- "target": "america",
1198
  "value": 2
1199
  },
1200
  {
1201
- "source": "uniform",
1202
- "target": "america",
1203
  "value": 1
1204
  },
1205
  {
@@ -1218,13 +1218,13 @@
1218
  "value": 1
1219
  },
1220
  {
1221
- "source": "clothing",
1222
- "target": "soldier",
1223
  "value": 1
1224
  },
1225
  {
1226
- "source": "clothing",
1227
- "target": "military uniform",
1228
  "value": 1
1229
  },
1230
  {
@@ -1243,8 +1243,8 @@
1243
  "value": 1
1244
  },
1245
  {
1246
- "source": "background",
1247
- "target": "america",
1248
  "value": 1
1249
  },
1250
  {
@@ -1253,13 +1253,13 @@
1253
  "value": 1
1254
  },
1255
  {
1256
- "source": "landmark",
1257
- "target": "america",
1258
  "value": 1
1259
  },
1260
  {
1261
- "source": "latin american",
1262
- "target": "america",
1263
  "value": 1
1264
  },
1265
  {
@@ -1278,13 +1278,13 @@
1278
  "value": 1
1279
  },
1280
  {
1281
- "source": "landmark",
1282
- "target": "place",
1283
  "value": 1
1284
  },
1285
  {
1286
- "source": "latin american",
1287
- "target": "place",
1288
  "value": 1
1289
  },
1290
  {
@@ -1293,8 +1293,8 @@
1293
  "value": 1
1294
  },
1295
  {
1296
- "source": "american",
1297
- "target": "base model",
1298
  "value": 1
1299
  },
1300
  {
@@ -1308,8 +1308,8 @@
1308
  "value": 1
1309
  },
1310
  {
1311
- "source": "america",
1312
- "target": "base model",
1313
  "value": 1
1314
  },
1315
  {
@@ -1318,8 +1318,8 @@
1318
  "value": 1
1319
  },
1320
  {
1321
- "source": "indigenous cultures",
1322
- "target": "america",
1323
  "value": 1
1324
  },
1325
  {
@@ -1338,8 +1338,8 @@
1338
  "value": 1
1339
  },
1340
  {
1341
- "source": "character",
1342
- "target": "airplane",
1343
  "value": 1
1344
  },
1345
  {
@@ -1348,24 +1348,24 @@
1348
  "value": 1
1349
  },
1350
  {
1351
- "source": "photorealistic",
1352
- "target": "sexy",
1353
  "value": 1
1354
  },
1355
  {
1356
- "source": "photorealistic",
1357
- "target": "american",
1358
  "value": 1
1359
  },
1360
  {
1361
- "source": "photorealistic",
1362
- "target": "airplane",
1363
  "value": 1
1364
  },
1365
  {
1366
- "source": "photorealistic",
1367
- "target": "vehicles",
1368
- "value": 1
1369
  },
1370
  {
1371
  "source": "american",
@@ -1373,8 +1373,8 @@
1373
  "value": 1
1374
  },
1375
  {
1376
- "source": "sexy",
1377
- "target": "airplane",
1378
  "value": 1
1379
  },
1380
  {
@@ -1383,23 +1383,23 @@
1383
  "value": 1
1384
  },
1385
  {
1386
- "source": "sexy",
1387
- "target": "america",
1388
  "value": 2
1389
  },
1390
  {
1391
- "source": "american",
1392
- "target": "airplane",
1393
  "value": 1
1394
  },
1395
  {
1396
- "source": "vehicles",
1397
- "target": "american",
1398
  "value": 1
1399
  },
1400
  {
1401
- "source": "vehicles",
1402
- "target": "airplane",
1403
  "value": 1
1404
  },
1405
  {
@@ -1408,8 +1408,8 @@
1408
  "value": 1
1409
  },
1410
  {
1411
- "source": "vehicles",
1412
- "target": "america",
1413
  "value": 1
1414
  },
1415
  {
@@ -1418,28 +1418,28 @@
1418
  "value": 1
1419
  },
1420
  {
1421
- "source": "character",
1422
- "target": "comics",
1423
  "value": 1
1424
  },
1425
  {
1426
- "source": "character",
1427
- "target": "america chavez",
1428
  "value": 1
1429
  },
1430
  {
1431
- "source": "marvel",
1432
- "target": "comics",
1433
  "value": 1
1434
  },
1435
  {
1436
- "source": "marvel",
1437
- "target": "woman",
1438
  "value": 2
1439
  },
1440
  {
1441
- "source": "marvel",
1442
- "target": "america chavez",
1443
  "value": 1
1444
  },
1445
  {
@@ -1458,13 +1458,13 @@
1458
  "value": 1
1459
  },
1460
  {
1461
- "source": "objects",
1462
- "target": "america",
1463
  "value": 1
1464
  },
1465
  {
1466
- "source": "objects",
1467
- "target": "flag",
1468
  "value": 1
1469
  },
1470
  {
@@ -1473,13 +1473,13 @@
1473
  "value": 1
1474
  },
1475
  {
1476
- "source": "objects",
1477
- "target": "american flag",
1478
  "value": 1
1479
  },
1480
  {
1481
- "source": "objects",
1482
- "target": "us flag",
1483
  "value": 1
1484
  },
1485
  {
@@ -1488,8 +1488,8 @@
1488
  "value": 1
1489
  },
1490
  {
1491
- "source": "flag",
1492
- "target": "america",
1493
  "value": 1
1494
  },
1495
  {
@@ -1498,8 +1498,8 @@
1498
  "value": 1
1499
  },
1500
  {
1501
- "source": "us flag",
1502
- "target": "america",
1503
  "value": 1
1504
  },
1505
  {
@@ -1513,13 +1513,13 @@
1513
  "value": 1
1514
  },
1515
  {
1516
- "source": "flag",
1517
- "target": "american flag",
1518
  "value": 1
1519
  },
1520
  {
1521
- "source": "flag",
1522
- "target": "us flag",
1523
  "value": 1
1524
  },
1525
  {
@@ -1528,8 +1528,8 @@
1528
  "value": 1
1529
  },
1530
  {
1531
- "source": "usa",
1532
- "target": "american flag",
1533
  "value": 1
1534
  },
1535
  {
@@ -1548,8 +1548,8 @@
1548
  "value": 1
1549
  },
1550
  {
1551
- "source": "united states flag",
1552
- "target": "american flag",
1553
  "value": 1
1554
  },
1555
  {
@@ -1563,13 +1563,13 @@
1563
  "value": 1
1564
  },
1565
  {
1566
- "source": "marvel",
1567
- "target": "hayley atwell",
1568
  "value": 1
1569
  },
1570
  {
1571
- "source": "marvel",
1572
- "target": "captain america",
1573
  "value": 1
1574
  },
1575
  {
@@ -1578,8 +1578,8 @@
1578
  "value": 1
1579
  },
1580
  {
1581
- "source": "marvel",
1582
- "target": "peggy carter",
1583
  "value": 1
1584
  },
1585
  {
@@ -1613,8 +1613,8 @@
1613
  "value": 1
1614
  },
1615
  {
1616
- "source": "mcu suit designs",
1617
- "target": "celebrity",
1618
  "value": 1
1619
  },
1620
  {
@@ -1623,8 +1623,8 @@
1623
  "value": 1
1624
  },
1625
  {
1626
- "source": "captain america",
1627
- "target": "hayley atwell",
1628
  "value": 1
1629
  },
1630
  {
@@ -1643,18 +1643,18 @@
1643
  "value": 1
1644
  },
1645
  {
1646
- "source": "captain america",
1647
- "target": "peggy carter",
1648
  "value": 1
1649
  },
1650
  {
1651
- "source": "mcu suit designs",
1652
- "target": "peggy carter",
1653
  "value": 1
1654
  },
1655
  {
1656
- "source": "character",
1657
- "target": "politician",
1658
  "value": 1
1659
  },
1660
  {
@@ -1713,13 +1713,13 @@
1713
  "value": 1
1714
  },
1715
  {
1716
- "source": "right",
1717
- "target": "america",
1718
  "value": 1
1719
  },
1720
  {
1721
- "source": "male",
1722
- "target": "america",
1723
  "value": 1
1724
  },
1725
  {
@@ -1728,8 +1728,8 @@
1728
  "value": 1
1729
  },
1730
  {
1731
- "source": "concept",
1732
- "target": "red",
1733
  "value": 1
1734
  },
1735
  {
@@ -1748,13 +1748,13 @@
1748
  "value": 1
1749
  },
1750
  {
1751
- "source": "concept",
1752
- "target": "filter",
1753
  "value": 1
1754
  },
1755
  {
1756
- "source": "concept",
1757
- "target": "colorize",
1758
  "value": 1
1759
  },
1760
  {
@@ -1763,8 +1763,8 @@
1763
  "value": 1
1764
  },
1765
  {
1766
- "source": "stardust",
1767
- "target": "red",
1768
  "value": 1
1769
  },
1770
  {
@@ -1773,23 +1773,23 @@
1773
  "value": 1
1774
  },
1775
  {
1776
- "source": "red",
1777
- "target": "filter",
1778
  "value": 1
1779
  },
1780
  {
1781
- "source": "red",
1782
- "target": "colorize",
1783
  "value": 1
1784
  },
1785
  {
1786
- "source": "stardust",
1787
- "target": "america",
1788
  "value": 1
1789
  },
1790
  {
1791
- "source": "blue",
1792
- "target": "america",
1793
  "value": 1
1794
  },
1795
  {
@@ -1803,28 +1803,28 @@
1803
  "value": 1
1804
  },
1805
  {
1806
- "source": "stardust",
1807
- "target": "blue",
1808
  "value": 1
1809
  },
1810
  {
1811
- "source": "stardust",
1812
- "target": "filter",
1813
  "value": 1
1814
  },
1815
  {
1816
- "source": "stardust",
1817
- "target": "colorize",
1818
  "value": 1
1819
  },
1820
  {
1821
- "source": "blue",
1822
- "target": "filter",
1823
  "value": 1
1824
  },
1825
  {
1826
- "source": "blue",
1827
- "target": "colorize",
1828
  "value": 1
1829
  },
1830
  {
@@ -1843,8 +1843,8 @@
1843
  "value": 1
1844
  },
1845
  {
1846
- "source": "character",
1847
- "target": "boku no hero academia",
1848
  "value": 1
1849
  },
1850
  {
@@ -1853,13 +1853,13 @@
1853
  "value": 1
1854
  },
1855
  {
1856
- "source": "superhero",
1857
- "target": "my hero academia",
1858
  "value": 1
1859
  },
1860
  {
1861
- "source": "superhero",
1862
- "target": "america",
1863
  "value": 1
1864
  },
1865
  {
@@ -1873,8 +1873,8 @@
1873
  "value": 1
1874
  },
1875
  {
1876
- "source": "my hero academia",
1877
- "target": "america",
1878
  "value": 1
1879
  },
1880
  {
@@ -1883,8 +1883,8 @@
1883
  "value": 1
1884
  },
1885
  {
1886
- "source": "cape",
1887
- "target": "my hero academia",
1888
  "value": 1
1889
  },
1890
  {
@@ -1893,8 +1893,8 @@
1893
  "value": 1
1894
  },
1895
  {
1896
- "source": "cape",
1897
- "target": "america",
1898
  "value": 1
1899
  },
1900
  {
@@ -1948,8 +1948,8 @@
1948
  "value": 1
1949
  },
1950
  {
1951
- "source": "south america",
1952
- "target": "clothing",
1953
  "value": 1
1954
  },
1955
  {
@@ -1958,18 +1958,18 @@
1958
  "value": 1
1959
  },
1960
  {
1961
- "source": "south america",
1962
- "target": "inca",
1963
  "value": 1
1964
  },
1965
  {
1966
- "source": "inca",
1967
- "target": "andes",
1968
  "value": 1
1969
  },
1970
  {
1971
- "source": "south america",
1972
- "target": "andes",
1973
  "value": 1
1974
  },
1975
  {
@@ -1993,23 +1993,23 @@
1993
  "value": 1
1994
  },
1995
  {
1996
- "source": "superhero",
1997
- "target": "avengers",
1998
  "value": 1
1999
  },
2000
  {
2001
- "source": "superhero",
2002
- "target": "captain america",
2003
  "value": 1
2004
  },
2005
  {
2006
- "source": "superhero",
2007
- "target": "american dream",
2008
  "value": 1
2009
  },
2010
  {
2011
- "source": "superhero",
2012
- "target": "shannon carter",
2013
  "value": 1
2014
  },
2015
  {
@@ -2018,23 +2018,23 @@
2018
  "value": 1
2019
  },
2020
  {
2021
- "source": "avengers",
2022
- "target": "american dream",
2023
  "value": 1
2024
  },
2025
  {
2026
- "source": "avengers",
2027
- "target": "shannon carter",
2028
  "value": 1
2029
  },
2030
  {
2031
- "source": "captain america",
2032
- "target": "american dream",
2033
  "value": 1
2034
  },
2035
  {
2036
- "source": "captain america",
2037
- "target": "shannon carter",
2038
  "value": 1
2039
  },
2040
  {
@@ -2043,13 +2043,13 @@
2043
  "value": 1
2044
  },
2045
  {
2046
- "source": "illustration",
2047
- "target": "america",
2048
  "value": 1
2049
  },
2050
  {
2051
- "source": "post-war",
2052
- "target": "america",
2053
  "value": 1
2054
  },
2055
  {
@@ -2058,8 +2058,8 @@
2058
  "value": 1
2059
  },
2060
  {
2061
- "source": "illustration",
2062
- "target": "style",
2063
  "value": 1
2064
  },
2065
  {
@@ -2068,8 +2068,8 @@
2068
  "value": 1
2069
  },
2070
  {
2071
- "source": "battle of the sexes",
2072
- "target": "style",
2073
  "value": 1
2074
  },
2075
  {
@@ -2098,13 +2098,13 @@
2098
  "value": 1
2099
  },
2100
  {
2101
- "source": "sexy",
2102
- "target": "pornstar",
2103
  "value": 1
2104
  },
2105
  {
2106
- "source": "mature",
2107
- "target": "sexy",
2108
  "value": 1
2109
  },
2110
  {
@@ -2113,8 +2113,8 @@
2113
  "value": 1
2114
  },
2115
  {
2116
- "source": "mature",
2117
- "target": "america",
2118
  "value": 1
2119
  },
2120
  {
@@ -2138,18 +2138,8 @@
2138
  "value": 1
2139
  },
2140
  {
2141
- "source": "mature",
2142
- "target": "pornstar",
2143
- "value": 1
2144
- },
2145
- {
2146
- "source": "america",
2147
- "target": "photography",
2148
- "value": 1
2149
- },
2150
- {
2151
- "source": "style",
2152
- "target": "photography",
2153
  "value": 1
2154
  },
2155
  {
@@ -2158,18 +2148,18 @@
2158
  "value": 1
2159
  },
2160
  {
2161
- "source": "anime",
2162
- "target": "colonial america",
2163
  "value": 1
2164
  },
2165
  {
2166
- "source": "anime",
2167
- "target": "puritans",
2168
  "value": 1
2169
  },
2170
  {
2171
- "source": "thanksgiving",
2172
- "target": "america",
2173
  "value": 1
2174
  },
2175
  {
@@ -2203,28 +2193,38 @@
2203
  "value": 1
2204
  },
2205
  {
2206
- "source": "clothing",
2207
- "target": "colonial america",
2208
  "value": 1
2209
  },
2210
  {
2211
- "source": "clothing",
2212
- "target": "puritans",
2213
  "value": 1
2214
  },
2215
  {
2216
- "source": "thanksgiving",
 
 
 
 
 
 
 
 
 
 
2217
  "target": "colonial america",
2218
  "value": 1
2219
  },
2220
  {
2221
- "source": "thanksgiving",
2222
- "target": "puritans",
2223
  "value": 1
2224
  },
2225
  {
2226
- "source": "colonial america",
2227
- "target": "puritans",
2228
  "value": 1
2229
  },
2230
  {
@@ -2233,8 +2233,8 @@
2233
  "value": 1
2234
  },
2235
  {
2236
- "source": "character",
2237
- "target": "uncle sam",
2238
  "value": 1
2239
  },
2240
  {
@@ -2243,8 +2243,8 @@
2243
  "value": 1
2244
  },
2245
  {
2246
- "source": "usa",
2247
- "target": "uncle sam",
2248
  "value": 1
2249
  },
2250
  {
@@ -2268,13 +2268,13 @@
2268
  "value": 1
2269
  },
2270
  {
2271
- "source": "fries",
2272
- "target": "america",
2273
  "value": 1
2274
  },
2275
  {
2276
- "source": "hamburger",
2277
- "target": "america",
2278
  "value": 1
2279
  },
2280
  {
@@ -2288,33 +2288,33 @@
2288
  "value": 1
2289
  },
2290
  {
2291
- "source": "usa",
2292
- "target": "hamburger",
2293
  "value": 1
2294
  },
2295
  {
2296
- "source": "usa",
2297
- "target": "freedom",
2298
  "value": 1
2299
  },
2300
  {
2301
- "source": "fries",
2302
- "target": "hamburger",
2303
  "value": 1
2304
  },
2305
  {
2306
- "source": "fries",
2307
- "target": "freedom",
2308
  "value": 1
2309
  },
2310
  {
2311
- "source": "hamburger",
2312
- "target": "freedom",
2313
  "value": 1
2314
  },
2315
  {
2316
- "source": "man",
2317
- "target": "america",
2318
  "value": 1
2319
  },
2320
  {
@@ -2328,8 +2328,8 @@
2328
  "value": 1
2329
  },
2330
  {
2331
- "source": "celebrity,",
2332
- "target": "america",
2333
  "value": 1
2334
  },
2335
  {
@@ -2348,8 +2348,8 @@
2348
  "value": 1
2349
  },
2350
  {
2351
- "source": "celebrity",
2352
- "target": "influencer",
2353
  "value": 1
2354
  },
2355
  {
@@ -2383,18 +2383,18 @@
2383
  "value": 1
2384
  },
2385
  {
2386
- "source": "usa",
2387
- "target": "influencer",
2388
  "value": 1
2389
  },
2390
  {
2391
- "source": "usa",
2392
- "target": "celebrity,",
2393
  "value": 1
2394
  },
2395
  {
2396
- "source": "president",
2397
- "target": "influencer",
2398
  "value": 1
2399
  },
2400
  {
@@ -2403,8 +2403,8 @@
2403
  "value": 1
2404
  },
2405
  {
2406
- "source": "celebrity,",
2407
- "target": "influencer",
2408
  "value": 1
2409
  }
2410
  ]
 
352
  "id": "mature",
353
  "size": 1
354
  },
 
 
 
 
355
  {
356
  "id": "thanksgiving",
357
  "size": 1
 
364
  "id": "puritans",
365
  "size": 1
366
  },
367
+ {
368
+ "id": "photography",
369
+ "size": 1
370
+ },
371
  {
372
  "id": "uncle sam",
373
  "size": 1
 
418
  "value": 1
419
  },
420
  {
421
+ "source": "america",
422
+ "target": "american",
423
  "value": 4
424
  },
425
  {
 
443
  "value": 1
444
  },
445
  {
446
+ "source": "america",
447
+ "target": "funny",
448
  "value": 1
449
  },
450
  {
 
468
  "value": 3
469
  },
470
  {
471
+ "source": "politician",
472
+ "target": "celebrity",
473
  "value": 2
474
  },
475
  {
 
478
  "value": 1
479
  },
480
  {
481
+ "source": "america",
482
+ "target": "political",
483
  "value": 2
484
  },
485
  {
 
498
  "value": 4
499
  },
500
  {
501
+ "source": "america",
502
+ "target": "joke",
503
  "value": 1
504
  },
505
  {
 
523
  "value": 1
524
  },
525
  {
526
+ "source": "airbrushed",
527
+ "target": "vintage",
528
  "value": 1
529
  },
530
  {
 
533
  "value": 1
534
  },
535
  {
536
+ "source": "america",
537
+ "target": "vintage",
538
  "value": 1
539
  },
540
  {
 
543
  "value": 1
544
  },
545
  {
546
+ "source": "pin-up",
547
+ "target": "posters",
548
  "value": 1
549
  },
550
  {
 
558
  "value": 1
559
  },
560
  {
561
+ "source": "america",
562
+ "target": "pin-up",
563
  "value": 1
564
  },
565
  {
 
583
  "value": 1
584
  },
585
  {
586
+ "source": "airbrushed",
587
+ "target": "posters",
588
  "value": 1
589
  },
590
  {
 
593
  "value": 1
594
  },
595
  {
596
+ "source": "america",
597
+ "target": "posters",
598
  "value": 1
599
  },
600
  {
 
608
  "value": 1
609
  },
610
  {
611
+ "source": "america",
612
+ "target": "wwii",
613
  "value": 1
614
  },
615
  {
616
+ "source": "1950s",
617
+ "target": "photorealistic",
618
  "value": 1
619
  },
620
  {
621
+ "source": "oldschool",
622
+ "target": "1950s",
623
  "value": 1
624
  },
625
  {
626
+ "source": "america",
627
+ "target": "1950s",
628
  "value": 1
629
  },
630
  {
 
643
  "value": 1
644
  },
645
  {
646
+ "source": "oldschool",
647
+ "target": "photorealistic",
648
  "value": 1
649
  },
650
  {
651
+ "source": "america",
652
+ "target": "photorealistic",
653
  "value": 3
654
  },
655
  {
656
+ "source": "style",
657
+ "target": "photorealistic",
658
  "value": 1
659
  },
660
  {
661
+ "source": "realistic",
662
+ "target": "photorealistic",
663
  "value": 1
664
  },
665
  {
666
+ "source": "usa",
667
+ "target": "photorealistic",
668
  "value": 1
669
  },
670
  {
671
+ "source": "oldschool",
672
+ "target": "america",
673
  "value": 1
674
  },
675
  {
676
+ "source": "oldschool",
677
+ "target": "style",
678
  "value": 1
679
  },
680
  {
681
+ "source": "oldschool",
682
+ "target": "realistic",
683
  "value": 1
684
  },
685
  {
686
+ "source": "oldschool",
687
+ "target": "usa",
688
  "value": 1
689
  },
690
  {
 
693
  "value": 3
694
  },
695
  {
696
+ "source": "america",
697
+ "target": "realistic",
698
  "value": 1
699
  },
700
  {
701
+ "source": "america",
702
+ "target": "usa",
703
  "value": 5
704
  },
705
  {
 
718
  "value": 1
719
  },
720
  {
721
+ "source": "politician",
722
+ "target": "photorealistic",
723
  "value": 1
724
  },
725
  {
 
728
  "value": 1
729
  },
730
  {
731
+ "source": "celebrity",
732
+ "target": "photorealistic",
733
  "value": 1
734
  },
735
  {
736
+ "source": "photorealism",
737
+ "target": "photorealistic",
738
  "value": 1
739
  },
740
  {
 
748
  "value": 1
749
  },
750
  {
751
+ "source": "photorealism",
752
+ "target": "politician",
753
  "value": 1
754
  },
755
  {
 
758
  "value": 1
759
  },
760
  {
761
+ "source": "america",
762
+ "target": "woman",
763
  "value": 4
764
  },
765
  {
 
768
  "value": 1
769
  },
770
  {
771
+ "source": "america",
772
+ "target": "real person",
773
  "value": 1
774
  },
775
  {
 
788
  "value": 1
789
  },
790
  {
791
+ "source": "photorealism",
792
+ "target": "celebrity",
793
  "value": 1
794
  },
795
  {
 
798
  "value": 1
799
  },
800
  {
801
+ "source": "photorealism",
802
+ "target": "real person",
803
  "value": 1
804
  },
805
  {
 
868
  "value": 1
869
  },
870
  {
871
+ "source": "america",
872
+ "target": "female",
873
  "value": 1
874
  },
875
  {
 
883
  "value": 1
884
  },
885
  {
886
+ "source": "america",
887
+ "target": "blonde",
888
  "value": 2
889
  },
890
  {
 
903
  "value": 1
904
  },
905
  {
906
+ "source": "trump",
907
+ "target": "clothing",
908
  "value": 1
909
  },
910
  {
911
+ "source": "clothing",
912
+ "target": "donald trump",
913
  "value": 1
914
  },
915
  {
 
928
  "value": 1
929
  },
930
  {
931
+ "source": "maga hat",
932
+ "target": "clothing",
933
  "value": 1
934
  },
935
  {
936
+ "source": "trump",
937
+ "target": "donald trump",
938
  "value": 1
939
  },
940
  {
941
+ "source": "trump",
942
+ "target": "maga",
943
  "value": 1
944
  },
945
  {
946
+ "source": "trump",
947
+ "target": "maga cap",
948
  "value": 1
949
  },
950
  {
951
+ "source": "trump",
952
+ "target": "make america great again hat",
953
  "value": 1
954
  },
955
  {
956
+ "source": "maga hat",
957
+ "target": "trump",
958
  "value": 1
959
  },
960
  {
961
+ "source": "maga",
962
+ "target": "donald trump",
963
  "value": 1
964
  },
965
  {
 
973
  "value": 1
974
  },
975
  {
976
+ "source": "maga hat",
977
+ "target": "donald trump",
978
  "value": 1
979
  },
980
  {
 
983
  "value": 1
984
  },
985
  {
986
+ "source": "maga",
987
+ "target": "make america great again hat",
988
  "value": 1
989
  },
990
  {
991
+ "source": "maga hat",
992
+ "target": "maga",
993
  "value": 1
994
  },
995
  {
996
+ "source": "maga cap",
997
+ "target": "make america great again hat",
998
  "value": 1
999
  },
1000
  {
1001
+ "source": "maga hat",
1002
+ "target": "maga cap",
1003
  "value": 1
1004
  },
1005
  {
1006
+ "source": "maga hat",
1007
+ "target": "make america great again hat",
1008
  "value": 1
1009
  },
1010
  {
 
1013
  "value": 3
1014
  },
1015
  {
1016
+ "source": "base model",
1017
+ "target": "indigenous cultures",
1018
  "value": 3
1019
  },
1020
  {
1021
+ "source": "base model",
1022
+ "target": "north america",
1023
  "value": 1
1024
  },
1025
  {
 
1028
  "value": 1
1029
  },
1030
  {
1031
+ "source": "base model",
1032
+ "target": "north-america",
1033
  "value": 1
1034
  },
1035
  {
 
1083
  "value": 1
1084
  },
1085
  {
1086
+ "source": "base model",
1087
+ "target": "south america",
1088
  "value": 1
1089
  },
1090
  {
1091
+ "source": "base model",
1092
+ "target": "south-america",
1093
  "value": 1
1094
  },
1095
  {
 
1113
  "value": 1
1114
  },
1115
  {
1116
+ "source": "indigenous cultures",
1117
+ "target": "south america",
1118
  "value": 1
1119
  },
1120
  {
1121
+ "source": "indigenous cultures",
1122
+ "target": "south-america",
1123
  "value": 1
1124
  },
1125
  {
 
1133
  "value": 1
1134
  },
1135
  {
1136
+ "source": "south american",
1137
+ "target": "south america",
1138
  "value": 1
1139
  },
1140
  {
 
1168
  "value": 1
1169
  },
1170
  {
1171
+ "source": "america",
1172
+ "target": "military",
1173
  "value": 1
1174
  },
1175
  {
 
1193
  "value": 1
1194
  },
1195
  {
1196
+ "source": "america",
1197
+ "target": "clothing",
1198
  "value": 2
1199
  },
1200
  {
1201
+ "source": "america",
1202
+ "target": "uniform",
1203
  "value": 1
1204
  },
1205
  {
 
1218
  "value": 1
1219
  },
1220
  {
1221
+ "source": "soldier",
1222
+ "target": "clothing",
1223
  "value": 1
1224
  },
1225
  {
1226
+ "source": "military uniform",
1227
+ "target": "clothing",
1228
  "value": 1
1229
  },
1230
  {
 
1243
  "value": 1
1244
  },
1245
  {
1246
+ "source": "america",
1247
+ "target": "background",
1248
  "value": 1
1249
  },
1250
  {
 
1253
  "value": 1
1254
  },
1255
  {
1256
+ "source": "america",
1257
+ "target": "landmark",
1258
  "value": 1
1259
  },
1260
  {
1261
+ "source": "america",
1262
+ "target": "latin american",
1263
  "value": 1
1264
  },
1265
  {
 
1278
  "value": 1
1279
  },
1280
  {
1281
+ "source": "place",
1282
+ "target": "landmark",
1283
  "value": 1
1284
  },
1285
  {
1286
+ "source": "place",
1287
+ "target": "latin american",
1288
  "value": 1
1289
  },
1290
  {
 
1293
  "value": 1
1294
  },
1295
  {
1296
+ "source": "base model",
1297
+ "target": "american",
1298
  "value": 1
1299
  },
1300
  {
 
1308
  "value": 1
1309
  },
1310
  {
1311
+ "source": "base model",
1312
+ "target": "america",
1313
  "value": 1
1314
  },
1315
  {
 
1318
  "value": 1
1319
  },
1320
  {
1321
+ "source": "america",
1322
+ "target": "indigenous cultures",
1323
  "value": 1
1324
  },
1325
  {
 
1338
  "value": 1
1339
  },
1340
  {
1341
+ "source": "airplane",
1342
+ "target": "character",
1343
  "value": 1
1344
  },
1345
  {
 
1348
  "value": 1
1349
  },
1350
  {
1351
+ "source": "sexy",
1352
+ "target": "photorealistic",
1353
  "value": 1
1354
  },
1355
  {
1356
+ "source": "american",
1357
+ "target": "photorealistic",
1358
  "value": 1
1359
  },
1360
  {
1361
+ "source": "airplane",
1362
+ "target": "photorealistic",
1363
  "value": 1
1364
  },
1365
  {
1366
+ "source": "vehicles",
1367
+ "target": "photorealistic",
1368
+ "value": 1
1369
  },
1370
  {
1371
  "source": "american",
 
1373
  "value": 1
1374
  },
1375
  {
1376
+ "source": "airplane",
1377
+ "target": "sexy",
1378
  "value": 1
1379
  },
1380
  {
 
1383
  "value": 1
1384
  },
1385
  {
1386
+ "source": "america",
1387
+ "target": "sexy",
1388
  "value": 2
1389
  },
1390
  {
1391
+ "source": "airplane",
1392
+ "target": "american",
1393
  "value": 1
1394
  },
1395
  {
1396
+ "source": "american",
1397
+ "target": "vehicles",
1398
  "value": 1
1399
  },
1400
  {
1401
+ "source": "airplane",
1402
+ "target": "vehicles",
1403
  "value": 1
1404
  },
1405
  {
 
1408
  "value": 1
1409
  },
1410
  {
1411
+ "source": "america",
1412
+ "target": "vehicles",
1413
  "value": 1
1414
  },
1415
  {
 
1418
  "value": 1
1419
  },
1420
  {
1421
+ "source": "comics",
1422
+ "target": "character",
1423
  "value": 1
1424
  },
1425
  {
1426
+ "source": "america chavez",
1427
+ "target": "character",
1428
  "value": 1
1429
  },
1430
  {
1431
+ "source": "comics",
1432
+ "target": "marvel",
1433
  "value": 1
1434
  },
1435
  {
1436
+ "source": "woman",
1437
+ "target": "marvel",
1438
  "value": 2
1439
  },
1440
  {
1441
+ "source": "america chavez",
1442
+ "target": "marvel",
1443
  "value": 1
1444
  },
1445
  {
 
1458
  "value": 1
1459
  },
1460
  {
1461
+ "source": "america",
1462
+ "target": "objects",
1463
  "value": 1
1464
  },
1465
  {
1466
+ "source": "flag",
1467
+ "target": "objects",
1468
  "value": 1
1469
  },
1470
  {
 
1473
  "value": 1
1474
  },
1475
  {
1476
+ "source": "american flag",
1477
+ "target": "objects",
1478
  "value": 1
1479
  },
1480
  {
1481
+ "source": "us flag",
1482
+ "target": "objects",
1483
  "value": 1
1484
  },
1485
  {
 
1488
  "value": 1
1489
  },
1490
  {
1491
+ "source": "america",
1492
+ "target": "flag",
1493
  "value": 1
1494
  },
1495
  {
 
1498
  "value": 1
1499
  },
1500
  {
1501
+ "source": "america",
1502
+ "target": "us flag",
1503
  "value": 1
1504
  },
1505
  {
 
1513
  "value": 1
1514
  },
1515
  {
1516
+ "source": "american flag",
1517
+ "target": "flag",
1518
  "value": 1
1519
  },
1520
  {
1521
+ "source": "us flag",
1522
+ "target": "flag",
1523
  "value": 1
1524
  },
1525
  {
 
1528
  "value": 1
1529
  },
1530
  {
1531
+ "source": "american flag",
1532
+ "target": "usa",
1533
  "value": 1
1534
  },
1535
  {
 
1548
  "value": 1
1549
  },
1550
  {
1551
+ "source": "american flag",
1552
+ "target": "united states flag",
1553
  "value": 1
1554
  },
1555
  {
 
1563
  "value": 1
1564
  },
1565
  {
1566
+ "source": "hayley atwell",
1567
+ "target": "marvel",
1568
  "value": 1
1569
  },
1570
  {
1571
+ "source": "captain america",
1572
+ "target": "marvel",
1573
  "value": 1
1574
  },
1575
  {
 
1578
  "value": 1
1579
  },
1580
  {
1581
+ "source": "peggy carter",
1582
+ "target": "marvel",
1583
  "value": 1
1584
  },
1585
  {
 
1613
  "value": 1
1614
  },
1615
  {
1616
+ "source": "celebrity",
1617
+ "target": "mcu suit designs",
1618
  "value": 1
1619
  },
1620
  {
 
1623
  "value": 1
1624
  },
1625
  {
1626
+ "source": "hayley atwell",
1627
+ "target": "captain america",
1628
  "value": 1
1629
  },
1630
  {
 
1643
  "value": 1
1644
  },
1645
  {
1646
+ "source": "peggy carter",
1647
+ "target": "captain america",
1648
  "value": 1
1649
  },
1650
  {
1651
+ "source": "peggy carter",
1652
+ "target": "mcu suit designs",
1653
  "value": 1
1654
  },
1655
  {
1656
+ "source": "politician",
1657
+ "target": "character",
1658
  "value": 1
1659
  },
1660
  {
 
1713
  "value": 1
1714
  },
1715
  {
1716
+ "source": "america",
1717
+ "target": "right",
1718
  "value": 1
1719
  },
1720
  {
1721
+ "source": "america",
1722
+ "target": "male",
1723
  "value": 1
1724
  },
1725
  {
 
1728
  "value": 1
1729
  },
1730
  {
1731
+ "source": "red",
1732
+ "target": "concept",
1733
  "value": 1
1734
  },
1735
  {
 
1748
  "value": 1
1749
  },
1750
  {
1751
+ "source": "filter",
1752
+ "target": "concept",
1753
  "value": 1
1754
  },
1755
  {
1756
+ "source": "colorize",
1757
+ "target": "concept",
1758
  "value": 1
1759
  },
1760
  {
 
1763
  "value": 1
1764
  },
1765
  {
1766
+ "source": "red",
1767
+ "target": "stardust",
1768
  "value": 1
1769
  },
1770
  {
 
1773
  "value": 1
1774
  },
1775
  {
1776
+ "source": "filter",
1777
+ "target": "red",
1778
  "value": 1
1779
  },
1780
  {
1781
+ "source": "colorize",
1782
+ "target": "red",
1783
  "value": 1
1784
  },
1785
  {
1786
+ "source": "america",
1787
+ "target": "stardust",
1788
  "value": 1
1789
  },
1790
  {
1791
+ "source": "america",
1792
+ "target": "blue",
1793
  "value": 1
1794
  },
1795
  {
 
1803
  "value": 1
1804
  },
1805
  {
1806
+ "source": "blue",
1807
+ "target": "stardust",
1808
  "value": 1
1809
  },
1810
  {
1811
+ "source": "filter",
1812
+ "target": "stardust",
1813
  "value": 1
1814
  },
1815
  {
1816
+ "source": "colorize",
1817
+ "target": "stardust",
1818
  "value": 1
1819
  },
1820
  {
1821
+ "source": "filter",
1822
+ "target": "blue",
1823
  "value": 1
1824
  },
1825
  {
1826
+ "source": "colorize",
1827
+ "target": "blue",
1828
  "value": 1
1829
  },
1830
  {
 
1843
  "value": 1
1844
  },
1845
  {
1846
+ "source": "boku no hero academia",
1847
+ "target": "character",
1848
  "value": 1
1849
  },
1850
  {
 
1853
  "value": 1
1854
  },
1855
  {
1856
+ "source": "my hero academia",
1857
+ "target": "superhero",
1858
  "value": 1
1859
  },
1860
  {
1861
+ "source": "america",
1862
+ "target": "superhero",
1863
  "value": 1
1864
  },
1865
  {
 
1873
  "value": 1
1874
  },
1875
  {
1876
+ "source": "america",
1877
+ "target": "my hero academia",
1878
  "value": 1
1879
  },
1880
  {
 
1883
  "value": 1
1884
  },
1885
  {
1886
+ "source": "my hero academia",
1887
+ "target": "cape",
1888
  "value": 1
1889
  },
1890
  {
 
1893
  "value": 1
1894
  },
1895
  {
1896
+ "source": "america",
1897
+ "target": "cape",
1898
  "value": 1
1899
  },
1900
  {
 
1948
  "value": 1
1949
  },
1950
  {
1951
+ "source": "clothing",
1952
+ "target": "south america",
1953
  "value": 1
1954
  },
1955
  {
 
1958
  "value": 1
1959
  },
1960
  {
1961
+ "source": "inca",
1962
+ "target": "south america",
1963
  "value": 1
1964
  },
1965
  {
1966
+ "source": "andes",
1967
+ "target": "inca",
1968
  "value": 1
1969
  },
1970
  {
1971
+ "source": "andes",
1972
+ "target": "south america",
1973
  "value": 1
1974
  },
1975
  {
 
1993
  "value": 1
1994
  },
1995
  {
1996
+ "source": "avengers",
1997
+ "target": "superhero",
1998
  "value": 1
1999
  },
2000
  {
2001
+ "source": "captain america",
2002
+ "target": "superhero",
2003
  "value": 1
2004
  },
2005
  {
2006
+ "source": "american dream",
2007
+ "target": "superhero",
2008
  "value": 1
2009
  },
2010
  {
2011
+ "source": "shannon carter",
2012
+ "target": "superhero",
2013
  "value": 1
2014
  },
2015
  {
 
2018
  "value": 1
2019
  },
2020
  {
2021
+ "source": "american dream",
2022
+ "target": "avengers",
2023
  "value": 1
2024
  },
2025
  {
2026
+ "source": "shannon carter",
2027
+ "target": "avengers",
2028
  "value": 1
2029
  },
2030
  {
2031
+ "source": "american dream",
2032
+ "target": "captain america",
2033
  "value": 1
2034
  },
2035
  {
2036
+ "source": "shannon carter",
2037
+ "target": "captain america",
2038
  "value": 1
2039
  },
2040
  {
 
2043
  "value": 1
2044
  },
2045
  {
2046
+ "source": "america",
2047
+ "target": "illustration",
2048
  "value": 1
2049
  },
2050
  {
2051
+ "source": "america",
2052
+ "target": "post-war",
2053
  "value": 1
2054
  },
2055
  {
 
2058
  "value": 1
2059
  },
2060
  {
2061
+ "source": "style",
2062
+ "target": "illustration",
2063
  "value": 1
2064
  },
2065
  {
 
2068
  "value": 1
2069
  },
2070
  {
2071
+ "source": "style",
2072
+ "target": "battle of the sexes",
2073
  "value": 1
2074
  },
2075
  {
 
2098
  "value": 1
2099
  },
2100
  {
2101
+ "source": "pornstar",
2102
+ "target": "sexy",
2103
  "value": 1
2104
  },
2105
  {
2106
+ "source": "sexy",
2107
+ "target": "mature",
2108
  "value": 1
2109
  },
2110
  {
 
2113
  "value": 1
2114
  },
2115
  {
2116
+ "source": "america",
2117
+ "target": "mature",
2118
  "value": 1
2119
  },
2120
  {
 
2138
  "value": 1
2139
  },
2140
  {
2141
+ "source": "pornstar",
2142
+ "target": "mature",
 
 
 
 
 
 
 
 
 
 
2143
  "value": 1
2144
  },
2145
  {
 
2148
  "value": 1
2149
  },
2150
  {
2151
+ "source": "colonial america",
2152
+ "target": "anime",
2153
  "value": 1
2154
  },
2155
  {
2156
+ "source": "puritans",
2157
+ "target": "anime",
2158
  "value": 1
2159
  },
2160
  {
2161
+ "source": "america",
2162
+ "target": "thanksgiving",
2163
  "value": 1
2164
  },
2165
  {
 
2193
  "value": 1
2194
  },
2195
  {
2196
+ "source": "colonial america",
2197
+ "target": "clothing",
2198
  "value": 1
2199
  },
2200
  {
2201
+ "source": "puritans",
2202
+ "target": "clothing",
2203
  "value": 1
2204
  },
2205
  {
2206
+ "source": "colonial america",
2207
+ "target": "thanksgiving",
2208
+ "value": 1
2209
+ },
2210
+ {
2211
+ "source": "puritans",
2212
+ "target": "thanksgiving",
2213
+ "value": 1
2214
+ },
2215
+ {
2216
+ "source": "puritans",
2217
  "target": "colonial america",
2218
  "value": 1
2219
  },
2220
  {
2221
+ "source": "america",
2222
+ "target": "photography",
2223
  "value": 1
2224
  },
2225
  {
2226
+ "source": "style",
2227
+ "target": "photography",
2228
  "value": 1
2229
  },
2230
  {
 
2233
  "value": 1
2234
  },
2235
  {
2236
+ "source": "uncle sam",
2237
+ "target": "character",
2238
  "value": 1
2239
  },
2240
  {
 
2243
  "value": 1
2244
  },
2245
  {
2246
+ "source": "uncle sam",
2247
+ "target": "usa",
2248
  "value": 1
2249
  },
2250
  {
 
2268
  "value": 1
2269
  },
2270
  {
2271
+ "source": "america",
2272
+ "target": "fries",
2273
  "value": 1
2274
  },
2275
  {
2276
+ "source": "america",
2277
+ "target": "hamburger",
2278
  "value": 1
2279
  },
2280
  {
 
2288
  "value": 1
2289
  },
2290
  {
2291
+ "source": "hamburger",
2292
+ "target": "usa",
2293
  "value": 1
2294
  },
2295
  {
2296
+ "source": "freedom",
2297
+ "target": "usa",
2298
  "value": 1
2299
  },
2300
  {
2301
+ "source": "hamburger",
2302
+ "target": "fries",
2303
  "value": 1
2304
  },
2305
  {
2306
+ "source": "freedom",
2307
+ "target": "fries",
2308
  "value": 1
2309
  },
2310
  {
2311
+ "source": "freedom",
2312
+ "target": "hamburger",
2313
  "value": 1
2314
  },
2315
  {
2316
+ "source": "america",
2317
+ "target": "man",
2318
  "value": 1
2319
  },
2320
  {
 
2328
  "value": 1
2329
  },
2330
  {
2331
+ "source": "america",
2332
+ "target": "celebrity,",
2333
  "value": 1
2334
  },
2335
  {
 
2348
  "value": 1
2349
  },
2350
  {
2351
+ "source": "influencer",
2352
+ "target": "celebrity",
2353
  "value": 1
2354
  },
2355
  {
 
2383
  "value": 1
2384
  },
2385
  {
2386
+ "source": "influencer",
2387
+ "target": "usa",
2388
  "value": 1
2389
  },
2390
  {
2391
+ "source": "celebrity,",
2392
+ "target": "usa",
2393
  "value": 1
2394
  },
2395
  {
2396
+ "source": "influencer",
2397
+ "target": "president",
2398
  "value": 1
2399
  },
2400
  {
 
2403
  "value": 1
2404
  },
2405
  {
2406
+ "source": "influencer",
2407
+ "target": "celebrity,",
2408
  "value": 1
2409
  }
2410
  ]
public/network. DELETED
File without changes
public/network.html DELETED
@@ -1,193 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8" />
5
- <title>Danbooru Tree from JSON</title>
6
- <script src="https://d3js.org/d3.v7.min.js"></script>
7
- <style>
8
- body {
9
- margin: 0;
10
- padding: 0;
11
- font-family: 'Segoe UI', sans-serif;
12
- background-color: #f9f9f9;
13
- }
14
-
15
- .container {
16
- max-width: 1200px;
17
- margin: 0 auto;
18
- padding: 2rem;
19
- }
20
-
21
- h2 {
22
- margin-bottom: 1rem;
23
- color: #333;
24
- }
25
-
26
- .frame-wrapper {
27
- border: 1px solid #ccc;
28
- border-radius: 8px;
29
- background-color: white;
30
- padding: 1rem;
31
- overflow-x: auto;
32
- overflow-y: scroll;
33
- max-height: 80vh;
34
- box-shadow: 0 4px 8px rgba(0, 0, 0, 0.05);
35
- }
36
-
37
- svg {
38
- width: 1000px; /* Adjust as needed */
39
- height: 1500px;
40
- }
41
-
42
- .controls {
43
- margin-bottom: 1rem;
44
- }
45
-
46
- .controls button {
47
- padding: 0.5rem 1rem;
48
- font-size: 14px;
49
- background-color: #0077cc;
50
- color: white;
51
- border: none;
52
- border-radius: 4px;
53
- cursor: pointer;
54
- }
55
-
56
- .controls button:hover {
57
- background-color: #005fa3;
58
- }
59
-
60
- .node circle {
61
- fill: steelblue;
62
- }
63
-
64
- .node text {
65
- font-size: 12px;
66
- fill: #333;
67
- }
68
-
69
- .link {
70
- fill: none;
71
- stroke: #ccc;
72
- stroke-width: 1.5px;
73
- }
74
- </style>
75
- </head>
76
- <body>
77
- <div class="container">
78
- <h2>Danbooru Categories</h2>
79
- <div class="controls">
80
- <button id="downloadBtn">Download SVG</button>
81
- </div>
82
- <div class="frame-wrapper">
83
- <svg></svg>
84
- </div>
85
- </div>
86
-
87
- <script>
88
- d3.json("json/danbooru_flat.json").then(function(data) {
89
- const svg = d3.select("svg");
90
- const width = 1000;
91
- const height = 1500;
92
-
93
- function limitSecondLevel(node, depth = 0) {
94
- if (node.children && depth === 1 && node.children.length > 5) {
95
- const visible = node.children.slice(0, 5);
96
- visible.push({ name: "...", children: [] });
97
- node.children = visible;
98
- }
99
- if (node.children) {
100
- node.children.forEach(child => limitSecondLevel(child, depth + 1));
101
- }
102
- return node;
103
- }
104
-
105
- const limited = limitSecondLevel(structuredClone(data));
106
- const root = d3.hierarchy(limited, d => d.children);
107
-
108
- root.eachAfter(d => {
109
- if (d.depth === 1) {
110
- d.data.rootCategory = d.data.name;
111
- } else if (d.parent) {
112
- d.data.rootCategory = d.parent.data.rootCategory;
113
- }
114
- });
115
-
116
- const treeLayout = d3.tree().size([height, width]);
117
- treeLayout(root);
118
-
119
- const allTagCounts = root.descendants()
120
- .filter(d => d.depth > 0)
121
- .map(d => d.data.tag_count || 0);
122
- const sizeScale = d3.scaleSqrt()
123
- .domain([0, d3.max(allTagCounts)])
124
- .range([4, 20]);
125
-
126
- const categoryColors = {
127
- "attire": "#f4a261", "body": "#e76f51", "characters": "#2a9d8f",
128
- "copyrights": "#264653", "creatures": "#8ecae6",
129
- "drawing software": "#219ebc", "games": "#3a86ff",
130
- "metatags": "#ffbe0b", "more": "#b5179e", "objects": "#6d6875",
131
- "plant": "#7cb518", "real_world": "#a5a58d", "sex": "#ef476f",
132
- "visual_characteristics": "#06d6a0", "subject": "#ffd166",
133
- "uncategorized": "#adb5bd", "actions_and_expressions": "#d00000",
134
- "objects_and_backgrounds": "#118ab2"
135
- };
136
-
137
- function getColor(d) {
138
- if (d.data.name === "...") return "gray";
139
- const category = d.data.rootCategory?.toLowerCase();
140
- return categoryColors[category] || "steelblue";
141
- }
142
-
143
- svg.selectAll(".link")
144
- .data(root.links())
145
- .join("path")
146
- .attr("class", "link")
147
- .attr("d", d3.linkHorizontal()
148
- .x(d => d.y)
149
- .y(d => d.x)
150
- );
151
-
152
- const node = svg.selectAll(".node")
153
- .data(root.descendants())
154
- .join("g")
155
- .attr("class", "node")
156
- .attr("transform", d => `translate(${d.y},${d.x})`);
157
-
158
- node.append("circle")
159
- .attr("r", d => d.depth === 0 ? 6 : sizeScale(d.data.tag_count || 0))
160
- .style("fill", getColor);
161
-
162
- node.append("title")
163
- .text(d => `${d.data.name}\nTags: ${d.data.tag_count || 0}`);
164
-
165
- node.append("text")
166
- .attr("x", 10)
167
- .style("font-weight", "bold")
168
- .attr("dy", "0.32em")
169
- .text(d => d.data.name);
170
- });
171
-
172
- document.getElementById("downloadBtn").addEventListener("click", () => {
173
- const svgNode = document.querySelector("svg");
174
- const clonedSvg = svgNode.cloneNode(true);
175
- const outer = document.createElement("div");
176
- outer.appendChild(clonedSvg);
177
- clonedSvg.setAttribute("xmlns", "http://www.w3.org/2000/svg");
178
-
179
- const svgData = new XMLSerializer().serializeToString(clonedSvg);
180
- const svgBlob = new Blob([svgData], { type: "image/svg+xml;charset=utf-8" });
181
-
182
- const url = URL.createObjectURL(svgBlob);
183
- const a = document.createElement("a");
184
- a.href = url;
185
- a.download = "danbooru_tree.svg";
186
- document.body.appendChild(a);
187
- a.click();
188
- document.body.removeChild(a);
189
- URL.revokeObjectURL(url);
190
- });
191
- </script>
192
- </body>
193
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
public/tag_groups.html DELETED
@@ -1,389 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <script src="https://d3js.org/d3.v7.min.js"></script>
6
- <style>
7
- text { font-family: Arial, sans-serif; fill: black; }
8
- </style>
9
- </head>
10
- <body>
11
- <div style="margin: 20px;">
12
- <label>Top N Nodes:
13
- <input type="range" id="nodeCountInput" value="20" min="1" max="100" />
14
- <output id="nodeCountOutput">20</output>
15
- </label><br/>
16
-
17
- <label>Link Distance Scale:
18
- <input type="range" id="linkScaleInput" value="0" min="0" max="5000" />
19
- <output id="linkScaleOutput">0</output>
20
- </label><br/>
21
-
22
- <label>Charge Strength:
23
- <input type="range" id="chargeInput" value="5." min="0" max="5." />
24
- <output id="chargeOutput">5.</output>
25
- </label><br/>
26
-
27
- <label>Collide Strength:
28
- <input type="range" id="collideInput" value="2" min="0" max="10" step="0.1" />
29
- <output id="collideOutput">2</output>
30
- </label><br/>
31
-
32
- <label>Collide Base Radius:
33
- <input type="range" id="collideBaseInput" value="17" min="0" max="100" />
34
- <output id="collideBaseOutput">17</output>
35
- </label><br/>
36
-
37
- <label>Node Radius Scale:
38
- <input type="range" id="radiusInput" value="30" min="5" max="100" />
39
- <output id="radiusOutput">30</output>
40
- </label><br/>
41
-
42
- <label>Font Size Scale:
43
- <input type="range" id="fontInput" value="25" min="1" max="50" />
44
- <output id="fontOutput">25</output>
45
- </label><br/>
46
-
47
- <label>Link Thickness Base:
48
- <input type="range" id="LinkStrokeIn" value="13" min="1" max="50" />
49
- <output id="LinkStrokeOut">5</output>
50
- </label><br/>
51
-
52
- <select id="jsonSelector">
53
- <!-- General -->
54
- <option value="json/tags_american.json">American</option>
55
- <option value="json/tags_asian.json">Asian</option>
56
- <option value="json/tags_chinese.json">Chinese</option>
57
- <option value="json/tags_german.json">German</option>
58
- <option value="json/tags_indian.json">Indian</option>
59
- <option value="json/tags_japanese.json">Japanese</option>
60
- <option value="json/tags_korean.json">Korean</option>
61
- <option value="json/tags_russian.json">Russian</option>
62
- <option value="json/tags_style.json">Style</option>
63
- <option value="json/tags_man.json">Man</option>
64
- <option value="json/tags_woman.json">Woman</option>
65
- <option value="json/tags_instagram.json">instagram</option>
66
- <option value="json/tags_japan.json">Japan</option>
67
- <option value="json/tags_russia.json">Russia</option>
68
-
69
- <!-- POI / Real person models -->
70
- <option value="json/tags_american_poi.json">American (Real)</option>
71
- <option value="json/tags_asian_poi.json">Asian (Real)</option>
72
- <option value="json/tags_chinese_poi.json">Chinese (Real)</option>
73
- <option value="json/tags_german_poi.json">German (Real)</option>
74
- <option value="json/tags_indian_poi.json">Indian (Real)</option>
75
- <option value="json/tags_japanese_poi.json">Japanese (Real)</option>
76
- <option value="json/tags_korean_poi.json">Korean (Real)</option>
77
- <option value="json/tags_russian_poi.json">Russian (Real)</option>
78
- <option value="json/tags_style_poi.json">Style (Real)</option>
79
- <option value="json/tags_man_poi.json">Man (Real)</option>
80
- <option value="json/tags_woman_poi.json">Woman (Real)</option>
81
-
82
- <!-- Promo and special sets -->
83
- <option value="json/nodes_all.json">All Tags (Promo)</option>
84
- <option value="json/promo_tags_poi_true.json">Real Person Models (Promo)</option>
85
- </select>
86
-
87
- </select>
88
- <button id="resetBtn">Reset</button>
89
- <button id="downloadBtn">Download SVG</button>
90
-
91
- </div>
92
-
93
- <svg width="1000" height="1000"></svg>
94
-
95
- <script>
96
- const width = 800;
97
- const height = 800;
98
- const NODE_BASE_RADIUS = 1;
99
- const FONT_SIZE_BASE = 10;
100
-
101
- let LINK_DISTANCE_SCALE = -200;
102
- let CHARGE_STRENGTH = 80;
103
- let COLLIDE_STRENGTH = 2;
104
- let COLLIDE_BASE_RADIUS = 17;
105
- let NODE_RADIUS_SCALE = 30;
106
- let FONT_SIZE_SCALE = 25;
107
- let LINK_THICKNESS_BASE = 5;
108
-
109
- const svg = d3.select("svg");
110
- let fullGraph = null;
111
-
112
- function renderGraph(graph, nodeCount = 50) {
113
- svg.selectAll("*").remove();
114
-
115
- const nodeMap = new Map(graph.nodes.map(n => [n.id, n]));
116
-
117
- graph.nodes.sort((a, b) => b.size - a.size);
118
- const filteredNodes = graph.nodes.slice(0, nodeCount);
119
- const topIds = new Set(filteredNodes.map(n => n.id));
120
- const filteredLinks = graph.links.filter(link => topIds.has(link.source) && topIds.has(link.target))
121
- .map(link => ({ ...link, source: nodeMap.get(link.source), target: nodeMap.get(link.target) }));
122
-
123
- const [minNodeSize, maxNodeSize] = d3.extent(filteredNodes, n => n.size);
124
- filteredNodes.forEach(n => {
125
- n.normSize = (n.size - minNodeSize) / (maxNodeSize - minNodeSize || 1);
126
- });
127
-
128
- const [minLinkVal, maxLinkVal] = d3.extent(filteredLinks, d => d.value);
129
- filteredLinks.forEach(d => {
130
- d.normValue = (d.value - minLinkVal) / (maxLinkVal - minLinkVal || 1);
131
- d.distance = 100 + d.normValue * LINK_DISTANCE_SCALE;
132
- });
133
-
134
- const edgeColor = d3.scaleLinear()
135
- .domain([0, 0.3, 1])
136
- .interpolate(d3.interpolateRgb)
137
- .range(["#BC8F8F", "#FF7F50", "#800000"]);
138
-
139
- const link = svg.append("g").selectAll("line")
140
- .data(filteredLinks)
141
- .enter().append("line")
142
- .attr("stroke", d => edgeColor(d.normValue))
143
- .attr("stroke-width", d => Math.max(0.1, d.value / maxLinkVal * LINK_THICKNESS_BASE))
144
- .attr("stroke-opacity", d => Math.max(0.0, d.value / 50));
145
-
146
- const node = svg.append("g").selectAll("circle")
147
- .data(filteredNodes)
148
- .enter().append("circle")
149
- .attr("r", d => d.size / maxNodeSize * NODE_RADIUS_SCALE)
150
- .attr("fill", "#FF7F50")
151
- .attr("stroke", "#800000")
152
- .attr("stroke-width", 3)
153
- .call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended));
154
-
155
- const labels = svg.append("g")
156
- .attr("class", "label-group")
157
- .selectAll("g")
158
- .data(filteredNodes)
159
- .enter().append("g")
160
- .attr("class", "label");
161
-
162
- labels.append("text")
163
- .attr("text-anchor", "start")
164
- .style("font-weight", "bold")
165
- .style("font-size", d => `${FONT_SIZE_BASE + d.normSize * FONT_SIZE_SCALE}px`)
166
- .attr("x", d => NODE_BASE_RADIUS + d.normSize * NODE_RADIUS_SCALE + 6)
167
- .text(d => d.id);
168
-
169
- const top10 = filteredNodes.slice(0, 3);
170
- const insideLabels = svg.append("g")
171
- .selectAll("text")
172
- .data(top10)
173
- .enter().append("text")
174
- .attr("text-anchor", "middle")
175
- .attr("dy", "0.35em")
176
- .style("font-weight", "bold")
177
- .style("fill", "#800000")
178
- .style("pointer-events", "none")
179
- .style("font-size", d => `${FONT_SIZE_BASE + d.normSize * FONT_SIZE_SCALE * 0.2}px`)
180
- .text(d => d.size);
181
-
182
- labels.each(function(d) {
183
- const group = d3.select(this);
184
- const text = group.select("text");
185
-
186
- const fontSize = FONT_SIZE_BASE + d.normSize * FONT_SIZE_SCALE;
187
- const paddingX = 4;
188
- const paddingY = 2;
189
-
190
- // Set text attributes first
191
- const labelX = NODE_BASE_RADIUS + d.normSize * NODE_RADIUS_SCALE + 6;
192
- text
193
- .attr("x", labelX)
194
- .attr("y", 0)
195
- .attr("dy", "0.35em")
196
- .style("font-size", `${fontSize}px`);
197
-
198
- // Now that the text is rendered, we can get its actual width
199
- const actualWidth = text.node().getComputedTextLength();
200
- const actualHeight = fontSize;
201
-
202
- group.insert("rect", "text")
203
- .attr("x", labelX - paddingX)
204
- .attr("y", -actualHeight / 2 - paddingY)
205
- .attr("width", actualWidth + paddingX * 2)
206
- .attr("height", actualHeight + paddingY * 2)
207
- .attr("rx", 4)
208
- .attr("ry", 4)
209
- .attr("fill", "white")
210
- .attr("fill-opacity", 0.7)
211
- .attr("stroke", "#800000")
212
- .attr("stroke-width", 2)
213
- .attr("stroke-opacity", 1);
214
- });
215
-
216
-
217
-
218
- const simulation = d3.forceSimulation(filteredNodes)
219
- .force("link", d3.forceLink(filteredLinks).id(d => d.id).distance(d => d.distance))
220
- .force("charge", d3.forceManyBody().strength(CHARGE_STRENGTH))
221
- .force("center", d3.forceCenter(width / 2, height / 2))
222
- .force("collide", d3.forceCollide().radius(d =>
223
- COLLIDE_BASE_RADIUS + d.normSize * NODE_RADIUS_SCALE + (FONT_SIZE_BASE + d.normSize * FONT_SIZE_SCALE) * 0.1
224
- ).strength(COLLIDE_STRENGTH))
225
- .on("tick", ticked);
226
-
227
- function ticked() {
228
- link.attr("x1", d => d.source.x).attr("y1", d => d.source.y)
229
- .attr("x2", d => d.target.x).attr("y2", d => d.target.y);
230
- node.attr("cx", d => d.x).attr("cy", d => d.y);
231
- labels.attr("transform", d => `translate(${d.x}, ${d.y})`);
232
- insideLabels.attr("x", d => d.x).attr("y", d => d.y);
233
- }
234
-
235
- function dragstarted(event, d) {
236
- if (!event.active) simulation.alphaTarget(0.3).restart();
237
- d.fx = d.x; d.fy = d.y;
238
- }
239
-
240
- function dragged(event, d) {
241
- d.fx = event.x; d.fy = event.y;
242
- }
243
-
244
- function dragended(event, d) {
245
- if (!event.active) simulation.alphaTarget(0);
246
- }
247
- }
248
-
249
- const sliders = {
250
- nodeCount: document.getElementById("nodeCountInput"),
251
- linkScale: document.getElementById("linkScaleInput"),
252
- charge: document.getElementById("chargeInput"),
253
- collide: document.getElementById("collideInput"),
254
- collideBase: document.getElementById("collideBaseInput"),
255
- radius: document.getElementById("radiusInput"),
256
- font: document.getElementById("fontInput"),
257
- linkThickness: document.getElementById("LinkStrokeIn"),
258
- };
259
-
260
- const outputs = {
261
- nodeCount: document.getElementById("nodeCountOutput"),
262
- linkScale: document.getElementById("linkScaleOutput"),
263
- charge: document.getElementById("chargeOutput"),
264
- collide: document.getElementById("collideOutput"),
265
- collideBase: document.getElementById("collideBaseOutput"),
266
- radius: document.getElementById("radiusOutput"),
267
- font: document.getElementById("fontOutput"),
268
- linkThickness: document.getElementById("LinkStrokeOut"),
269
- };
270
-
271
- function updateAndRender() {
272
- LINK_DISTANCE_SCALE = +sliders.linkScale.value;
273
- CHARGE_STRENGTH = +sliders.charge.value;
274
- COLLIDE_STRENGTH = +sliders.collide.value;
275
- COLLIDE_BASE_RADIUS = +sliders.collideBase.value;
276
- NODE_RADIUS_SCALE = +sliders.radius.value;
277
- FONT_SIZE_SCALE = +sliders.font.value;
278
- LINK_THICKNESS_BASE = +sliders.linkThickness.value;
279
-
280
- outputs.linkScale.textContent = LINK_DISTANCE_SCALE;
281
- outputs.charge.textContent = CHARGE_STRENGTH;
282
- outputs.collide.textContent = COLLIDE_STRENGTH;
283
- outputs.collideBase.textContent = COLLIDE_BASE_RADIUS;
284
- outputs.radius.textContent = NODE_RADIUS_SCALE;
285
- outputs.font.textContent = FONT_SIZE_SCALE;
286
- outputs.linkThickness.textContent = LINK_THICKNESS_BASE;
287
- outputs.nodeCount.textContent = sliders.nodeCount.value;
288
-
289
- if (fullGraph) renderGraph(fullGraph, +sliders.nodeCount.value);
290
- }
291
-
292
- for (const key in sliders) {
293
- sliders[key].addEventListener("input", updateAndRender);
294
- }
295
-
296
- document.getElementById("resetBtn").addEventListener("click", () => {
297
- sliders.nodeCount.value = 50;
298
- sliders.linkScale.value = -200;
299
- sliders.charge.value = 80;
300
- sliders.collide.value = 2;
301
- sliders.collideBase.value = 17;
302
- sliders.radius.value = 30;
303
- sliders.font.value = 25;
304
- sliders.linkThickness.value = 5;
305
- updateAndRender();
306
- });
307
-
308
- document.getElementById("jsonSelector").addEventListener("change", () => loadJSON(selector.value));
309
-
310
- function loadJSON(filePath) {
311
- d3.json(filePath).then(graph => {
312
- fullGraph = graph;
313
- updateAndRender();
314
- });
315
- }
316
-
317
- const selector = document.getElementById("jsonSelector");
318
- loadJSON(selector.value);
319
-
320
-
321
- function inlineStyles(svgElem) {
322
- const allElements = svgElem.querySelectorAll("*");
323
- allElements.forEach(el => {
324
- const computedStyle = getComputedStyle(el);
325
- const style = [];
326
-
327
- const properties = [
328
- "stroke",
329
- "stroke-width",
330
- "stroke-opacity",
331
- "fill",
332
- "fill-opacity",
333
- "font-size",
334
- "font-weight"
335
- ];
336
-
337
- properties.forEach(prop => {
338
- const val = computedStyle.getPropertyValue(prop);
339
- if (val && val !== "none" && val !== "normal" && val !== "0px") {
340
- style.push(`${prop}:${val}`);
341
- }
342
- });
343
-
344
- if (style.length) {
345
- el.setAttribute("style", style.join(";"));
346
- }
347
- });
348
- }
349
-
350
-
351
- document.getElementById("downloadBtn").addEventListener("click", () => {
352
- const svg = document.querySelector("svg");
353
- const clone = svg.cloneNode(true);
354
-
355
- // Inline computed styles to preserve appearance
356
- inlineStyles(clone);
357
-
358
- // Get bounding box of all content
359
- const bbox = svg.getBBox();
360
- const padding = 0;
361
-
362
- const x = bbox.x - padding;
363
- const y = bbox.y - padding;
364
- const width = bbox.width + padding * 2;
365
- const height = bbox.height + padding * 2;
366
-
367
- clone.setAttribute("viewBox", `${x} ${y} ${width} ${height}`);
368
- clone.setAttribute("width", width);
369
- clone.setAttribute("height", height);
370
-
371
- const serializer = new XMLSerializer();
372
- const svgString = serializer.serializeToString(clone);
373
-
374
- const blob = new Blob([svgString], {type: "image/svg+xml;charset=utf-8"});
375
- const url = URL.createObjectURL(blob);
376
-
377
- const link = document.createElement("a");
378
- link.href = url;
379
- link.download = "graph-export.svg";
380
- document.body.appendChild(link);
381
- link.click();
382
- document.body.removeChild(link);
383
- URL.revokeObjectURL(url);
384
- });
385
-
386
-
387
- </script>
388
- </body>
389
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
public/tags_landscape.html DELETED
@@ -1,396 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="utf-8">
5
- <script src="https://d3js.org/d3.v7.min.js"></script>
6
- <style>
7
- text { font-family: Arial, sans-serif; fill: black; }
8
- </style>
9
- </head>
10
- <body>
11
- <div style="margin: 70px;">
12
- <label>Top N Nodes:
13
- <input type="range" id="nodeCountInput" value="300" min="1" max="300" />
14
- <output id="nodeCountOutput">20</output>
15
- </label><br/>
16
-
17
- <label>Link Distance Scale:
18
- <input type="range" id="linkScaleInput" value="0" min="0" max="10000" />
19
- <output id="linkScaleOutput">0</output>
20
- </label><br/>
21
-
22
- <label>Charge Strength:
23
- <input type="range" id="chargeInput" value="10" min="0" max="50" />
24
- <output id="chargeOutput">5</output>
25
- </label><br/>
26
-
27
- <label>Collide Strength:
28
- <input type="range" id="collideInput" value="2" min="0" max="10" step="0.1" />
29
- <output id="collideOutput">2</output>
30
- </label><br/>
31
-
32
- <label>Collide Base Radius:
33
- <input type="range" id="collideBaseInput" value="22" min="0" max="35" />
34
- <output id="collideBaseOutput">17</output>
35
- </label><br/>
36
-
37
- <label>Node Radius Scale:
38
- <input type="range" id="radiusInput" value="65" min="5" max="80" />
39
- <output id="radiusOutput">30</output>
40
- </label><br/>
41
-
42
- <label>Font Size Scale:
43
- <input type="range" id="fontInput" value="25" min="1" max="50" />
44
- <output id="fontOutput">25</output>
45
- </label><br/>
46
-
47
- <label>Link Thickness Base:
48
- <input type="range" id="LinkStrokeIn" value="30" min="1" max="50" />
49
- <output id="LinkStrokeOut">5</output>
50
- </label><br/>
51
-
52
- <select id="jsonSelector">
53
- <!-- General -->
54
- <option value="json/tags_american.json">American</option>
55
- <option value="json/tags_asian.json">Asian</option>
56
- <option value="json/tags_chinese.json">Chinese</option>
57
- <option value="json/tags_german.json">German</option>
58
- <option value="json/tags_indian.json">Indian</option>
59
- <option value="json/tags_japanese.json">Japanese</option>
60
- <option value="json/tags_korean.json">Korean</option>
61
- <option value="json/tags_russian.json">Russian</option>
62
- <option value="json/tags_style.json">Style</option>
63
- <option value="json/tags_man.json">Man</option>
64
- <option value="json/tags_woman.json">Woman</option>
65
- <option value="json/tags_instagram.json">instagram</option>
66
- <option value="json/tags_japan.json">Japan</option>
67
- <option value="json/tags_russia.json">Russia</option>
68
- <option value="json/tags_japan.json">Japan</option>
69
- <option value="json/tags_canada.json">Canada</option>
70
- <option value="json/tags_uk.json">United Kingdom</option>
71
- <option value="json/tags_germany.json">Germany</option>
72
- <option value="json/tags_china.json">China</option>
73
- <option value="json/tags_india.json">India</option>
74
- <option value="json/tags_korea.json">Korea</option>
75
- <!-- POI / Real person models -->
76
- <option value="json/tags_american_poi.json">American (Real)</option>
77
- <option value="json/tags_asian_poi.json">Asian (Real)</option>
78
- <option value="json/tags_chinese_poi.json">Chinese (Real)</option>
79
- <option value="json/tags_german_poi.json">German (Real)</option>
80
- <option value="json/tags_indian_poi.json">Indian (Real)</option>
81
- <option value="json/tags_japanese_poi.json">Japanese (Real)</option>
82
- <option value="json/tags_korean_poi.json">Korean (Real)</option>
83
- <option value="json/tags_russian_poi.json">Russian (Real)</option>
84
- <option value="json/tags_style_poi.json">Style (Real)</option>
85
- <option value="json/tags_man_poi.json">Man (Real)</option>
86
- <option value="json/tags_woman_poi.json">Woman (Real)</option>
87
-
88
- <!-- Promo and special sets -->
89
- <option value="json/promo_tags.json">All Tags (Promo)</option>
90
- <option value="json/promo_tags_poi_true.json">Real Person Models (Promo)</option>
91
- </select>
92
-
93
- </select>
94
- <button id="resetBtn">Reset</button>
95
- <button id="downloadBtn">Download SVG</button>
96
-
97
- </div>
98
-
99
- <svg width="1200" height="1200"></svg>
100
-
101
- <script>
102
- const width = window.innerWidth * 0.95;
103
- const height = window.innerHeight * 0.8;
104
- const NODE_BASE_RADIUS = 1;
105
- const FONT_SIZE_BASE = 14;
106
-
107
- let LINK_DISTANCE_SCALE = -200;
108
- let CHARGE_STRENGTH = 80;
109
- let COLLIDE_STRENGTH = 2;
110
- let COLLIDE_BASE_RADIUS = 17;
111
- let NODE_RADIUS_SCALE = 30;
112
- let FONT_SIZE_SCALE = 25;
113
- let LINK_THICKNESS_BASE = 5;
114
-
115
- const svg = d3.select("svg")
116
- .attr("width", width)
117
- .attr("height", height);
118
- let fullGraph = null;
119
-
120
- function renderGraph(graph, nodeCount = 50) {
121
- svg.selectAll("*").remove();
122
-
123
- const nodeMap = new Map(graph.nodes.map(n => [n.id, n]));
124
-
125
- graph.nodes.sort((a, b) => b.size - a.size);
126
- const filteredNodes = graph.nodes.slice(0, nodeCount);
127
- const topIds = new Set(filteredNodes.map(n => n.id));
128
- const filteredLinks = graph.links
129
- .filter(link => topIds.has(link.source) && topIds.has(link.target) && link.value >= 80)
130
- .map(link => ({
131
- ...link,
132
- source: nodeMap.get(link.source),
133
- target: nodeMap.get(link.target)
134
- }));
135
-
136
- const [minNodeSize, maxNodeSize] = d3.extent(filteredNodes, n => n.size);
137
- filteredNodes.forEach(n => {
138
- n.normSize = (n.size - minNodeSize) / (maxNodeSize - minNodeSize || 1);
139
- });
140
-
141
- const [minLinkVal, maxLinkVal] = d3.extent(filteredLinks, d => d.value);
142
- filteredLinks.forEach(d => {
143
- d.normValue = (d.value - minLinkVal) / (maxLinkVal - minLinkVal || 1);
144
- d.distance = 100 + d.normValue * LINK_DISTANCE_SCALE;
145
- });
146
-
147
- const edgeColor = d3.scaleLinear()
148
- .domain([0, 0.3, 1])
149
- .interpolate(d3.interpolateRgb)
150
- .range(["#BC8F8F", "#FF7F50", "#800000"]);
151
-
152
- const link = svg.append("g")
153
- .selectAll("line")
154
- .data(filteredLinks.sort((a, b) => a.value - b.value)) // thinner first, thicker last
155
- .enter().append("line")
156
-
157
- .attr("stroke", d => edgeColor(d.normValue))
158
- .attr("stroke-width", d => Math.max(0.1, d.value / maxLinkVal * LINK_THICKNESS_BASE))
159
- .attr("stroke-opacity", d => d.normValue + 10)
160
-
161
-
162
- const node = svg.append("g").selectAll("circle")
163
- .data(filteredNodes)
164
- .enter().append("circle")
165
- .attr("r", d => d.size / maxNodeSize * NODE_RADIUS_SCALE)
166
- .attr("fill", "#FF7F50")
167
- .attr("stroke", "#800000")
168
- .attr("stroke-width", 3)
169
- .call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended));
170
-
171
- const labels = svg.append("g")
172
- .attr("class", "label-group")
173
- .selectAll("g")
174
- .data(filteredNodes)
175
- .enter().append("g")
176
- .attr("class", "label");
177
-
178
- labels.append("text")
179
- .attr("text-anchor", "start")
180
- .style("font-weight", "bold")
181
- .style("font-size", d => `${FONT_SIZE_BASE + d.normSize * FONT_SIZE_SCALE}px`)
182
- .attr("x", d => NODE_BASE_RADIUS + d.normSize * NODE_RADIUS_SCALE + 6)
183
- .text(d => d.id);
184
-
185
- const top10 = filteredNodes.slice(0, 3);
186
- const insideLabels = svg.append("g")
187
- .selectAll("text")
188
- .data(top10)
189
- .enter().append("text")
190
- .attr("text-anchor", "middle")
191
- .attr("dy", "0.35em")
192
- .style("font-weight", "bold")
193
- .style("fill", "#800000")
194
- .style("pointer-events", "none")
195
- .style("font-size", d => `${FONT_SIZE_BASE + d.normSize * FONT_SIZE_SCALE * 0.2}px`)
196
- .text(d => d.size);
197
-
198
- labels.each(function(d) {
199
- const group = d3.select(this);
200
- const text = group.select("text");
201
-
202
- const fontSize = FONT_SIZE_BASE + d.normSize * FONT_SIZE_SCALE;
203
- const paddingX = 4;
204
- const paddingY = 2;
205
-
206
- // Set text attributes first
207
- const labelX = NODE_BASE_RADIUS + d.normSize * NODE_RADIUS_SCALE + 6;
208
- text
209
- .attr("x", labelX)
210
- .attr("y", 0)
211
- .attr("dy", "0.35em")
212
- .style("font-size", `${fontSize}px`);
213
-
214
- // Now that the text is rendered, we can get its actual width
215
- const actualWidth = text.node().getComputedTextLength();
216
- const actualHeight = fontSize;
217
- //const extraRightPad = 10;
218
- const extraRightPad = fontSize * 0.3; // dynamic: ~30% of the text size
219
-
220
-
221
- group.insert("rect", "text")
222
- .attr("x", labelX - paddingX)
223
- .attr("y", -actualHeight / 2 - paddingY)
224
- .attr("width", actualWidth + paddingX * 2 + extraRightPad)
225
- .attr("height", actualHeight + paddingY * 2)
226
- .attr("rx", 4)
227
- .attr("ry", 4)
228
- .attr("fill", "white")
229
- .attr("fill-opacity", 0.7)
230
- .attr("stroke", "#800000")
231
- .attr("stroke-width", 2)
232
- .attr("stroke-opacity", 1);
233
- });
234
-
235
-
236
-
237
- const simulation = d3.forceSimulation(filteredNodes)
238
- .force("link", d3.forceLink(filteredLinks).id(d => d.id).distance(d => d.distance))
239
- .force("charge", d3.forceManyBody().strength(CHARGE_STRENGTH))
240
- .force("center", d3.forceCenter(width / 2, height / 2))
241
- .force("y", d3.forceY(width / 2).strength(0.04))
242
- .force("collide", d3.forceCollide().radius(d =>
243
- COLLIDE_BASE_RADIUS +
244
- (d.normSize * NODE_RADIUS_SCALE) +
245
- ((FONT_SIZE_BASE + d.normSize * FONT_SIZE_SCALE) * 0.3) // allow padding for labels
246
- ).strength(COLLIDE_STRENGTH))
247
-
248
- .on("tick", ticked);
249
-
250
- function ticked() {
251
- link
252
- .attr("x1", d => d.source.x)
253
- .attr("y1", d => d.source.y)
254
- .attr("x2", d => d.target.x)
255
- .attr("y2", d => d.target.y);
256
-
257
- node
258
- .attr("cx", d => d.x = Math.max(NODE_RADIUS_SCALE, Math.min(width - NODE_RADIUS_SCALE, d.x)))
259
- .attr("cy", d => d.y = Math.max(NODE_RADIUS_SCALE, Math.min(height - NODE_RADIUS_SCALE, d.y)));
260
-
261
- labels
262
- .attr("transform", d => {
263
- // Constrain label position too
264
- d.x = Math.max(0, Math.min(width, d.x));
265
- d.y = Math.max(0, Math.min(height, d.y));
266
- return `translate(${d.x}, ${d.y})`;
267
- });
268
-
269
- insideLabels
270
- .attr("x", d => d.x)
271
- .attr("y", d => d.y);
272
- }
273
-
274
-
275
-
276
- function dragstarted(event, d) {
277
- if (!event.active) simulation.alphaTarget(0.3).restart();
278
- d.fx = d.x; d.fy = d.y;
279
- }
280
-
281
- function dragged(event, d) {
282
- d.fx = event.x; d.fy = event.y;
283
- }
284
-
285
- function dragended(event, d) {
286
- if (!event.active) simulation.alphaTarget(0);
287
- }
288
- }
289
-
290
- const sliders = {
291
- nodeCount: document.getElementById("nodeCountInput"),
292
- linkScale: document.getElementById("linkScaleInput"),
293
- charge: document.getElementById("chargeInput"),
294
- collide: document.getElementById("collideInput"),
295
- collideBase: document.getElementById("collideBaseInput"),
296
- radius: document.getElementById("radiusInput"),
297
- font: document.getElementById("fontInput"),
298
- linkThickness: document.getElementById("LinkStrokeIn"),
299
- };
300
-
301
- const outputs = {
302
- nodeCount: document.getElementById("nodeCountOutput"),
303
- linkScale: document.getElementById("linkScaleOutput"),
304
- charge: document.getElementById("chargeOutput"),
305
- collide: document.getElementById("collideOutput"),
306
- collideBase: document.getElementById("collideBaseOutput"),
307
- radius: document.getElementById("radiusOutput"),
308
- font: document.getElementById("fontOutput"),
309
- linkThickness: document.getElementById("LinkStrokeOut"),
310
- };
311
-
312
- function updateAndRender() {
313
- LINK_DISTANCE_SCALE = +sliders.linkScale.value;
314
- CHARGE_STRENGTH = +sliders.charge.value;
315
- COLLIDE_STRENGTH = +sliders.collide.value;
316
- COLLIDE_BASE_RADIUS = +sliders.collideBase.value;
317
- NODE_RADIUS_SCALE = +sliders.radius.value;
318
- FONT_SIZE_SCALE = +sliders.font.value;
319
- LINK_THICKNESS_BASE = +sliders.linkThickness.value;
320
-
321
- outputs.linkScale.textContent = LINK_DISTANCE_SCALE;
322
- outputs.charge.textContent = CHARGE_STRENGTH;
323
- outputs.collide.textContent = COLLIDE_STRENGTH;
324
- outputs.collideBase.textContent = COLLIDE_BASE_RADIUS;
325
- outputs.radius.textContent = NODE_RADIUS_SCALE;
326
- outputs.font.textContent = FONT_SIZE_SCALE;
327
- outputs.linkThickness.textContent = LINK_THICKNESS_BASE;
328
- outputs.nodeCount.textContent = sliders.nodeCount.value;
329
-
330
- if (fullGraph) renderGraph(fullGraph, +sliders.nodeCount.value);
331
- }
332
-
333
- for (const key in sliders) {
334
- sliders[key].addEventListener("input", updateAndRender);
335
- }
336
-
337
- document.getElementById("resetBtn").addEventListener("click", () => {
338
- sliders.nodeCount.value = 50;
339
- sliders.linkScale.value = -200;
340
- sliders.charge.value = 80;
341
- sliders.collide.value = 2;
342
- sliders.collideBase.value = 17;
343
- sliders.radius.value = 30;
344
- sliders.font.value = 25;
345
- sliders.linkThickness.value = 5;
346
- updateAndRender();
347
- });
348
-
349
- document.getElementById("jsonSelector").addEventListener("change", () => loadJSON(selector.value));
350
-
351
- function loadJSON(filePath) {
352
- d3.json(filePath).then(graph => {
353
- fullGraph = graph;
354
- updateAndRender();
355
- });
356
- }
357
-
358
- const selector = document.getElementById("jsonSelector");
359
- loadJSON(selector.value);
360
-
361
- document.getElementById("downloadBtn").addEventListener("click", () => {
362
- const svg = document.querySelector("svg");
363
- const clone = svg.cloneNode(true);
364
-
365
- // Get bounding box of all content
366
- const bbox = svg.getBBox();
367
- const padding = 0; // change to 10 or so if you want a little breathing room
368
-
369
- const x = bbox.x - padding;
370
- const y = bbox.y - padding;
371
- const width = bbox.width + padding * 2;
372
- const height = bbox.height + padding * 2;
373
-
374
- // Set exact viewBox and size on the clone
375
- clone.setAttribute("viewBox", `${x} ${y} ${width} ${height}`);
376
- clone.setAttribute("width", width);
377
- clone.setAttribute("height", height);
378
-
379
- const serializer = new XMLSerializer();
380
- const svgString = serializer.serializeToString(clone);
381
-
382
- const blob = new Blob([svgString], {type: "image/svg+xml;charset=utf-8"});
383
- const url = URL.createObjectURL(blob);
384
-
385
- const link = document.createElement("a");
386
- link.href = url;
387
- link.download = "graph-export.svg";
388
- document.body.appendChild(link);
389
- link.click();
390
- document.body.removeChild(link);
391
- URL.revokeObjectURL(url);
392
- });
393
-
394
- </script>
395
- </body>
396
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
scripts/03_NER_characters_real_persons.ipynb DELETED
@@ -1,380 +0,0 @@
1
- {
2
- "cells": [
3
- {
4
- "cell_type": "markdown",
5
- "metadata": {},
6
- "source": [
7
- "# Characters and Real People Tag Identification"
8
- ]
9
- },
10
- {
11
- "cell_type": "markdown",
12
- "metadata": {},
13
- "source": [
14
- "## Step 01: extract Character Tags and Real People Tags from Danbooru Vocabulary"
15
- ]
16
- },
17
- {
18
- "cell_type": "code",
19
- "execution_count": 3,
20
- "metadata": {},
21
- "outputs": [
22
- {
23
- "name": "stdout",
24
- "output_type": "stream",
25
- "text": [
26
- "CSV file saved as 'data/CSV/misc/danbooru_real_people_and_characters.csv'\n"
27
- ]
28
- }
29
- ],
30
- "source": [
31
- "import json\n",
32
- "import pandas as pd\n",
33
- "\n",
34
- "# Load the JSON file\n",
35
- "with open(\"data/json/danbooru_vocabulary.json\", \"r\", encoding=\"utf-8\") as f:\n",
36
- " data = json.load(f)\n",
37
- "\n",
38
- "# Recursive function to collect tags from nested structure\n",
39
- "def collect_tags(category):\n",
40
- " tags = set()\n",
41
- " if isinstance(category, dict):\n",
42
- " for subcat in category.values():\n",
43
- " tags.update(collect_tags(subcat))\n",
44
- " elif isinstance(category, list):\n",
45
- " tags.update(category)\n",
46
- " return tags\n",
47
- "\n",
48
- "# Locate real people and character tag categories by matching known tag examples\n",
49
- "real_people_tags = []\n",
50
- "character_tags = []\n",
51
- "\n",
52
- "for key, value in data.items():\n",
53
- " tags = collect_tags(value)\n",
54
- " if \"Aimee-Ffion Edwards\" in tags or \"Akabane Kenji\" in tags:\n",
55
- " real_people_tags = list(tags)\n",
56
- " if \"Azur Lane\" in tags or \"Little Boy Commander_(azur_lane)\" in tags:\n",
57
- " character_tags = list(tags)\n",
58
- "\n",
59
- "# Clean tags: remove underscores and sort\n",
60
- "real_people_tags = sorted(tag.replace(\"_\", \" \") for tag in real_people_tags)\n",
61
- "character_tags = sorted(tag.replace(\"_\", \" \") for tag in character_tags)\n",
62
- "\n",
63
- "# Equalize list lengths for the CSV\n",
64
- "max_len = max(len(real_people_tags), len(character_tags))\n",
65
- "real_people_tags += [\"\"] * (max_len - len(real_people_tags))\n",
66
- "character_tags += [\"\"] * (max_len - len(character_tags))\n",
67
- "\n",
68
- "# Create and save DataFrame\n",
69
- "df = pd.DataFrame({\n",
70
- " \"Real People Tags\": real_people_tags,\n",
71
- " \"Character Tags\": character_tags\n",
72
- "})\n",
73
- "\n",
74
- "df.to_csv(\"data/CSV/misc/danbooru_real_people_and_characters.csv\", index=False, encoding=\"utf-8\")\n",
75
- "print(\"CSV file saved as 'data/CSV/misc/danbooru_real_people_and_characters.csv'\")\n"
76
- ]
77
- },
78
- {
79
- "cell_type": "markdown",
80
- "metadata": {},
81
- "source": [
82
- "## Step 02: NER"
83
- ]
84
- },
85
- {
86
- "cell_type": "markdown",
87
- "metadata": {},
88
- "source": []
89
- },
90
- {
91
- "cell_type": "code",
92
- "execution_count": 5,
93
- "metadata": {},
94
- "outputs": [
95
- {
96
- "name": "stdout",
97
- "output_type": "stream",
98
- "text": [
99
- "Requirement already satisfied: spacy in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (3.8.3)\n",
100
- "Requirement already satisfied: spacy-legacy<3.1.0,>=3.0.11 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from spacy) (3.0.12)\n",
101
- "Requirement already satisfied: spacy-loggers<2.0.0,>=1.0.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from spacy) (1.0.5)\n",
102
- "Requirement already satisfied: murmurhash<1.1.0,>=0.28.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from spacy) (1.0.11)\n",
103
- "Requirement already satisfied: cymem<2.1.0,>=2.0.2 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from spacy) (2.0.10)\n",
104
- "Requirement already satisfied: preshed<3.1.0,>=3.0.2 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from spacy) (3.0.9)\n",
105
- "Requirement already satisfied: thinc<8.4.0,>=8.3.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from spacy) (8.3.3)\n",
106
- "Requirement already satisfied: wasabi<1.2.0,>=0.9.1 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from spacy) (1.1.3)\n",
107
- "Requirement already satisfied: srsly<3.0.0,>=2.4.3 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from spacy) (2.5.0)\n",
108
- "Requirement already satisfied: catalogue<2.1.0,>=2.0.6 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from spacy) (2.0.10)\n",
109
- "Requirement already satisfied: weasel<0.5.0,>=0.1.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from spacy) (0.4.1)\n",
110
- "Requirement already satisfied: typer<1.0.0,>=0.3.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from spacy) (0.15.1)\n",
111
- "Requirement already satisfied: tqdm<5.0.0,>=4.38.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from spacy) (4.66.5)\n",
112
- "Requirement already satisfied: numpy>=1.19.0 in /home/lauhp/.local/lib/python3.10/site-packages (from spacy) (2.2.2)\n",
113
- "Requirement already satisfied: requests<3.0.0,>=2.13.0 in /home/lauhp/.local/lib/python3.10/site-packages (from spacy) (2.32.3)\n",
114
- "Requirement already satisfied: pydantic!=1.8,!=1.8.1,<3.0.0,>=1.7.4 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from spacy) (2.9.2)\n",
115
- "Requirement already satisfied: jinja2 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from spacy) (3.1.4)\n",
116
- "Requirement already satisfied: setuptools in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from spacy) (75.1.0)\n",
117
- "Requirement already satisfied: packaging>=20.0 in /home/lauhp/.local/lib/python3.10/site-packages (from spacy) (24.2)\n",
118
- "Requirement already satisfied: langcodes<4.0.0,>=3.2.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from spacy) (3.5.0)\n",
119
- "Requirement already satisfied: language-data>=1.2 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from langcodes<4.0.0,>=3.2.0->spacy) (1.3.0)\n",
120
- "Requirement already satisfied: annotated-types>=0.6.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from pydantic!=1.8,!=1.8.1,<3.0.0,>=1.7.4->spacy) (0.7.0)\n",
121
- "Requirement already satisfied: pydantic-core==2.23.4 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from pydantic!=1.8,!=1.8.1,<3.0.0,>=1.7.4->spacy) (2.23.4)\n",
122
- "Requirement already satisfied: typing-extensions>=4.6.1 in /home/lauhp/.local/lib/python3.10/site-packages (from pydantic!=1.8,!=1.8.1,<3.0.0,>=1.7.4->spacy) (4.12.2)\n",
123
- "Requirement already satisfied: charset-normalizer<4,>=2 in /home/lauhp/.local/lib/python3.10/site-packages (from requests<3.0.0,>=2.13.0->spacy) (3.4.1)\n",
124
- "Requirement already satisfied: idna<4,>=2.5 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from requests<3.0.0,>=2.13.0->spacy) (3.10)\n",
125
- "Requirement already satisfied: urllib3<3,>=1.21.1 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from requests<3.0.0,>=2.13.0->spacy) (2.2.3)\n",
126
- "Requirement already satisfied: certifi>=2017.4.17 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from requests<3.0.0,>=2.13.0->spacy) (2024.8.30)\n",
127
- "Requirement already satisfied: blis<1.2.0,>=1.1.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from thinc<8.4.0,>=8.3.0->spacy) (1.1.0)\n",
128
- "Requirement already satisfied: confection<1.0.0,>=0.0.1 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from thinc<8.4.0,>=8.3.0->spacy) (0.1.5)\n",
129
- "Requirement already satisfied: click>=8.0.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from typer<1.0.0,>=0.3.0->spacy) (8.1.7)\n",
130
- "Requirement already satisfied: shellingham>=1.3.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from typer<1.0.0,>=0.3.0->spacy) (1.5.4)\n",
131
- "Requirement already satisfied: rich>=10.11.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from typer<1.0.0,>=0.3.0->spacy) (13.9.4)\n",
132
- "Requirement already satisfied: cloudpathlib<1.0.0,>=0.7.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from weasel<0.5.0,>=0.1.0->spacy) (0.20.0)\n",
133
- "Requirement already satisfied: smart-open<8.0.0,>=5.2.1 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from weasel<0.5.0,>=0.1.0->spacy) (7.1.0)\n",
134
- "Requirement already satisfied: MarkupSafe>=2.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from jinja2->spacy) (3.0.2)\n",
135
- "Requirement already satisfied: marisa-trie>=1.1.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from language-data>=1.2->langcodes<4.0.0,>=3.2.0->spacy) (1.2.1)\n",
136
- "Requirement already satisfied: markdown-it-py>=2.2.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from rich>=10.11.0->typer<1.0.0,>=0.3.0->spacy) (3.0.0)\n",
137
- "Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from rich>=10.11.0->typer<1.0.0,>=0.3.0->spacy) (2.15.1)\n",
138
- "Requirement already satisfied: wrapt in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from smart-open<8.0.0,>=5.2.1->weasel<0.5.0,>=0.1.0->spacy) (1.17.0)\n",
139
- "Requirement already satisfied: mdurl~=0.1 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from markdown-it-py>=2.2.0->rich>=10.11.0->typer<1.0.0,>=0.3.0->spacy) (0.1.2)\n",
140
- "Collecting en-core-web-sm==3.8.0\n",
141
- " Downloading https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.8.0/en_core_web_sm-3.8.0-py3-none-any.whl (12.8 MB)\n",
142
- "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m12.8/12.8 MB\u001b[0m \u001b[31m28.6 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0ma \u001b[36m0:00:01\u001b[0m\n",
143
- "\u001b[?25h\u001b[38;5;2m✔ Download and installation successful\u001b[0m\n",
144
- "You can now load the package via spacy.load('en_core_web_sm')\n"
145
- ]
146
- }
147
- ],
148
- "source": [
149
- "!pip install spacy\n",
150
- "!python -m spacy download en_core_web_sm\n"
151
- ]
152
- },
153
- {
154
- "cell_type": "code",
155
- "execution_count": 2,
156
- "metadata": {},
157
- "outputs": [
158
- {
159
- "name": "stdout",
160
- "output_type": "stream",
161
- "text": [
162
- "Collecting en-core-web-trf==3.8.0\n",
163
- " Downloading https://github.com/explosion/spacy-models/releases/download/en_core_web_trf-3.8.0/en_core_web_trf-3.8.0-py3-none-any.whl (457.4 MB)\n",
164
- "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m457.4/457.4 MB\u001b[0m \u001b[31m8.3 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m00:01\u001b[0m00:02\u001b[0m\n",
165
- "\u001b[?25hCollecting spacy-curated-transformers<1.0.0,>=0.2.2 (from en-core-web-trf==3.8.0)\n",
166
- " Downloading spacy_curated_transformers-0.3.0-py2.py3-none-any.whl.metadata (2.7 kB)\n",
167
- "Collecting curated-transformers<0.2.0,>=0.1.0 (from spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0)\n",
168
- " Downloading curated_transformers-0.1.1-py2.py3-none-any.whl.metadata (965 bytes)\n",
169
- "Collecting curated-tokenizers<0.1.0,>=0.0.9 (from spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0)\n",
170
- " Downloading curated_tokenizers-0.0.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (1.9 kB)\n",
171
- "Requirement already satisfied: torch>=1.12.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (2.5.0)\n",
172
- "Requirement already satisfied: regex>=2022 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from curated-tokenizers<0.1.0,>=0.0.9->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (2024.9.11)\n",
173
- "Requirement already satisfied: filelock in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (3.16.1)\n",
174
- "Requirement already satisfied: typing-extensions>=4.8.0 in /home/lauhp/.local/lib/python3.10/site-packages (from torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (4.12.2)\n",
175
- "Requirement already satisfied: networkx in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (3.4.1)\n",
176
- "Requirement already satisfied: jinja2 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (3.1.4)\n",
177
- "Requirement already satisfied: fsspec in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (2024.10.0)\n",
178
- "Requirement already satisfied: nvidia-cuda-nvrtc-cu12==12.4.127 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (12.4.127)\n",
179
- "Requirement already satisfied: nvidia-cuda-runtime-cu12==12.4.127 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (12.4.127)\n",
180
- "Requirement already satisfied: nvidia-cuda-cupti-cu12==12.4.127 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (12.4.127)\n",
181
- "Requirement already satisfied: nvidia-cudnn-cu12==9.1.0.70 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (9.1.0.70)\n",
182
- "Requirement already satisfied: nvidia-cublas-cu12==12.4.5.8 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (12.4.5.8)\n",
183
- "Requirement already satisfied: nvidia-cufft-cu12==11.2.1.3 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (11.2.1.3)\n",
184
- "Requirement already satisfied: nvidia-curand-cu12==10.3.5.147 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (10.3.5.147)\n",
185
- "Requirement already satisfied: nvidia-cusolver-cu12==11.6.1.9 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (11.6.1.9)\n",
186
- "Requirement already satisfied: nvidia-cusparse-cu12==12.3.1.170 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (12.3.1.170)\n",
187
- "Requirement already satisfied: nvidia-nccl-cu12==2.21.5 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (2.21.5)\n",
188
- "Requirement already satisfied: nvidia-nvtx-cu12==12.4.127 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (12.4.127)\n",
189
- "Requirement already satisfied: nvidia-nvjitlink-cu12==12.4.127 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (12.4.127)\n",
190
- "Requirement already satisfied: triton==3.1.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (3.1.0)\n",
191
- "Requirement already satisfied: sympy==1.13.1 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (1.13.1)\n",
192
- "Requirement already satisfied: mpmath<1.4,>=1.1.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from sympy==1.13.1->torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (1.3.0)\n",
193
- "Requirement already satisfied: MarkupSafe>=2.0 in /home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages (from jinja2->torch>=1.12.0->spacy-curated-transformers<1.0.0,>=0.2.2->en-core-web-trf==3.8.0) (3.0.2)\n",
194
- "Downloading spacy_curated_transformers-0.3.0-py2.py3-none-any.whl (236 kB)\n",
195
- "Downloading curated_tokenizers-0.0.9-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (731 kB)\n",
196
- "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m731.6/731.6 kB\u001b[0m \u001b[31m7.2 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m\n",
197
- "\u001b[?25hDownloading curated_transformers-0.1.1-py2.py3-none-any.whl (25 kB)\n",
198
- "Installing collected packages: curated-tokenizers, curated-transformers, spacy-curated-transformers, en-core-web-trf\n",
199
- "Successfully installed curated-tokenizers-0.0.9 curated-transformers-0.1.1 en-core-web-trf-3.8.0 spacy-curated-transformers-0.3.0\n",
200
- "\u001b[38;5;2m✔ Download and installation successful\u001b[0m\n",
201
- "You can now load the package via spacy.load('en_core_web_trf')\n"
202
- ]
203
- }
204
- ],
205
- "source": [
206
- "!python -m spacy download en_core_web_trf\n"
207
- ]
208
- },
209
- {
210
- "cell_type": "code",
211
- "execution_count": null,
212
- "metadata": {},
213
- "outputs": [
214
- {
215
- "name": "stderr",
216
- "output_type": "stream",
217
- "text": [
218
- "/home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
219
- " from .autonotebook import tqdm as notebook_tqdm\n",
220
- "/home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages/thinc/shims/pytorch.py:261: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n",
221
- " model.load_state_dict(torch.load(filelike, map_location=device))\n",
222
- "/tmp/ipykernel_27737/425520401.py:9: DtypeWarning: Columns (50,51,54,55,56,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,458) have mixed types. Specify dtype option on import or set low_memory=False.\n",
223
- " df = pd.read_csv(\"data/CSV/all_models_with_tags.csv\")\n"
224
- ]
225
- }
226
- ],
227
- "source": [
228
- "import pandas as pd\n",
229
- "import spacy\n",
230
- "import re\n",
231
- "\n",
232
- "# Load spaCy NER model\n",
233
- "nlp = spacy.load(\"en_core_web_trf\")\n",
234
- "\n",
235
- "# Load CSV and extract tag columns\n",
236
- "df = pd.read_csv(\"data/CSV/all_models_with_tags.csv\")\n",
237
- "tag_columns = [f\"tag_{i}\" for i in range(1, 8)]\n",
238
- "tags = df[tag_columns].values.flatten()\n",
239
- "tags = pd.Series(tags).dropna().astype(str)\n",
240
- "\n",
241
- "# Clean tag for NER-friendly format\n",
242
- "def ner_friendly(tag):\n",
243
- " return tag.replace(\"_\", \" \").replace(\"-\", \" \").strip()\n",
244
- "\n",
245
- "# Clean tag for matching\n",
246
- "def match_clean(tag):\n",
247
- " tag = tag.lower().replace(\"_\", \" \").replace(\"-\", \" \")\n",
248
- " tag = re.sub(r\"[^\\w\\s]\", \"\", tag)\n",
249
- " return tag.strip()\n",
250
- "\n",
251
- "# Load reference list and prepare cleaned sets\n",
252
- "ref_df = pd.read_csv(\"data/CSV/misc/danbooru_real_people_and_characters.csv\")\n",
253
- "real_people_set = set(ref_df['Real People Tags'].dropna().map(match_clean))\n",
254
- "character_set = set(ref_df['Character Tags'].dropna().map(match_clean))\n",
255
- "\n",
256
- "# Apply NER to each tag in a naturalized format\n",
257
- "def is_person_tag(tag):\n",
258
- " doc = nlp(ner_friendly(tag))\n",
259
- " return any(ent.label_ == \"PERSON\" for ent in doc.ents)\n",
260
- "\n",
261
- "# Detect possible names\n",
262
- "person_tags = tags[tags.apply(is_person_tag)]\n",
263
- "person_tag_counts = person_tags.value_counts()\n",
264
- "\n",
265
- "# Classify tags\n",
266
- "real_people_detected = {}\n",
267
- "characters_detected = {}\n",
268
- "unclassified_names = {}\n",
269
- "\n",
270
- "for tag, count in person_tag_counts.items():\n",
271
- " cleaned = match_clean(tag)\n",
272
- " if cleaned in character_set:\n",
273
- " characters_detected[tag] = count\n",
274
- " elif cleaned in real_people_set:\n",
275
- " real_people_detected[tag] = count\n",
276
- " else:\n",
277
- " unclassified_names[tag] = count\n",
278
- "\n",
279
- "# Convert to DataFrames\n",
280
- "df_real_people = pd.DataFrame(real_people_detected.items(), columns=[\"Tag\", \"Count\"])\n",
281
- "df_characters = pd.DataFrame(characters_detected.items(), columns=[\"Tag\", \"Count\"])\n",
282
- "df_unclassified = pd.DataFrame(unclassified_names.items(), columns=[\"Tag\", \"Count\"])\n",
283
- "\n",
284
- "# Save to CSV\n",
285
- "df_real_people.to_csv(\"real_people_detected.csv\", index=False)\n",
286
- "df_characters.to_csv(\"characters_detected.csv\", index=False)\n",
287
- "df_unclassified.to_csv(\"unclassified_named_entities.csv\", index=False)\n",
288
- "\n",
289
- "print(\"✅ CSVs saved: real_people_detected.csv, characters_detected.csv, unclassified_named_entities.csv\")\n"
290
- ]
291
- },
292
- {
293
- "cell_type": "code",
294
- "execution_count": 1,
295
- "metadata": {},
296
- "outputs": [
297
- {
298
- "name": "stdout",
299
- "output_type": "stream",
300
- "text": [
301
- "Collecting en-core-web-sm==3.8.0\n",
302
- " Downloading https://github.com/explosion/spacy-models/releases/download/en_core_web_sm-3.8.0/en_core_web_sm-3.8.0-py3-none-any.whl (12.8 MB)\n",
303
- "\u001b[2K \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m12.8/12.8 MB\u001b[0m \u001b[31m24.4 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0m \u001b[36m0:00:01\u001b[0m\n",
304
- "\u001b[?25h\u001b[38;5;2m✔ Download and installation successful\u001b[0m\n",
305
- "You can now load the package via spacy.load('en_core_web_sm')\n"
306
- ]
307
- }
308
- ],
309
- "source": [
310
- "!python -m spacy download en_core_web_sm"
311
- ]
312
- },
313
- {
314
- "cell_type": "code",
315
- "execution_count": 2,
316
- "metadata": {},
317
- "outputs": [
318
- {
319
- "name": "stderr",
320
- "output_type": "stream",
321
- "text": [
322
- "/tmp/ipykernel_85592/3775345104.py:5: DtypeWarning: Columns (4,12,20) have mixed types. Specify dtype option on import or set low_memory=False.\n",
323
- " df = pd.read_csv(\"/home/lauhp/000_PHD/000_000_RESEARCH/000_X_Research_phase_1/d3js/data/model_subsets/POI_models_info.csv\")\n",
324
- "/home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
325
- " from .autonotebook import tqdm as notebook_tqdm\n"
326
- ]
327
- }
328
- ],
329
- "source": [
330
- "import pandas as pd\n",
331
- "import spacy\n",
332
- "\n",
333
- "# Load your CSV\n",
334
- "df = pd.read_csv(\"/home/lauhp/000_PHD/000_000_RESEARCH/000_X_Research_phase_1/d3js/data/model_subsets/POI_models_info.csv\")\n",
335
- "\n",
336
- "# Load the spaCy English NER model\n",
337
- "nlp = spacy.load(\"en_core_web_sm\")\n",
338
- "\n",
339
- "# Extract person names\n",
340
- "def extract_person_name(text):\n",
341
- " doc = nlp(str(text))\n",
342
- " persons = [ent.text for ent in doc.ents if ent.label_ == \"PERSON\"]\n",
343
- " return persons[0] if persons else None\n",
344
- "\n",
345
- "df['extracted_name'] = df['name'].apply(extract_person_name)\n",
346
- "\n",
347
- "# Save the pre-cleaned version\n",
348
- "df.to_csv(\"precleaned_with_names.csv\", index=False)\n"
349
- ]
350
- },
351
- {
352
- "cell_type": "code",
353
- "execution_count": null,
354
- "metadata": {},
355
- "outputs": [],
356
- "source": []
357
- }
358
- ],
359
- "metadata": {
360
- "kernelspec": {
361
- "display_name": "latm",
362
- "language": "python",
363
- "name": "python3"
364
- },
365
- "language_info": {
366
- "codemirror_mode": {
367
- "name": "ipython",
368
- "version": 3
369
- },
370
- "file_extension": ".py",
371
- "mimetype": "text/x-python",
372
- "name": "python",
373
- "nbconvert_exporter": "python",
374
- "pygments_lexer": "ipython3",
375
- "version": "3.10.15"
376
- }
377
- },
378
- "nbformat": 4,
379
- "nbformat_minor": 2
380
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
scripts/0_Scraping_image_metadata.ipynb CHANGED
@@ -1284,7 +1284,41 @@
1284
  "id": "49e35088-8b2e-4189-83e1-3098d55dcad2",
1285
  "metadata": {},
1286
  "outputs": [],
1287
- "source": []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1288
  }
1289
  ],
1290
  "metadata": {
 
1284
  "id": "49e35088-8b2e-4189-83e1-3098d55dcad2",
1285
  "metadata": {},
1286
  "outputs": [],
1287
+ "source": [
1288
+ "import pandas as pd\n",
1289
+ "import os\n",
1290
+ "\n",
1291
+ "# Load the dataset\n",
1292
+ "df = pd.read_csv('data/all_models_with_tags.csv')\n",
1293
+ "\n",
1294
+ "# Filter for rows where poi is True\n",
1295
+ "filtered_df = df[df['poi'] == True]\n",
1296
+ "os.makedirs('data/model_subsets', exist_ok=True)\n",
1297
+ "\n",
1298
+ "# Save the filtered DataFrame to a new CSV file\n",
1299
+ "filtered_df.to_csv('data/model_subsets/all_models_poi.csv', index=False)\n"
1300
+ ]
1301
+ },
1302
+ {
1303
+ "cell_type": "code",
1304
+ "execution_count": null,
1305
+ "id": "06c15f2c",
1306
+ "metadata": {},
1307
+ "outputs": [],
1308
+ "source": [
1309
+ "import pandas as pd\n",
1310
+ "import os\n",
1311
+ "\n",
1312
+ "# Load the dataset\n",
1313
+ "df = pd.read_csv('data/all_models_with_tags.csv')\n",
1314
+ "\n",
1315
+ "# Filter for rows where poi is True\n",
1316
+ "filtered_df = df[df['poi'] == False]\n",
1317
+ "os.makedirs('data/model_subsets', exist_ok=True)\n",
1318
+ "\n",
1319
+ "# Save the filtered DataFrame to a new CSV file\n",
1320
+ "filtered_df.to_csv('data/model_subsets/all_models_poi_false.csv', index=False)\n"
1321
+ ]
1322
  }
1323
  ],
1324
  "metadata": {
scripts/{Section_3-3-1_Figure_3_histogram.ipynb → Section_3-2-1_Figure_3_histogram.ipynb} RENAMED
File without changes
scripts/{Section_3-3-1_Figure_4_Mivolo.ipynb → Section_3-2-1_Figure_4_Mivolo.ipynb} RENAMED
File without changes
scripts/{02_filtered_tags_source_creation.ipynb → Section_3-3-1_Figure_5_tags.ipynb} RENAMED
@@ -1,26 +1,23 @@
1
  {
2
  "cells": [
 
 
 
 
 
 
 
3
  {
4
  "cell_type": "code",
5
- "execution_count": 3,
6
  "metadata": {},
7
  "outputs": [
8
- {
9
- "name": "stderr",
10
- "output_type": "stream",
11
- "text": [
12
- "/tmp/ipykernel_68582/2065722533.py:17: DtypeWarning: Columns (50,51,54,55,56,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,458) have mixed types. Specify dtype option on import or set low_memory=False.\n",
13
- " df = pd.read_csv(file_path)\n"
14
- ]
15
- },
16
  {
17
  "name": "stdout",
18
  "output_type": "stream",
19
  "text": [
20
- "Processing: germany\n",
21
- " ✅ Saved to public/json/tags_germany.json\n",
22
  "Processing: america\n",
23
- " ✅ Saved to public/json/tags_america.json\n"
24
  ]
25
  }
26
  ],
@@ -32,12 +29,15 @@
32
  "import re\n",
33
  "import os\n",
34
  "\n",
 
 
 
35
  "# === CONFIG ===\n",
36
- "file_path = \"data/CSV/all_models_with_tags.csv\"\n",
37
- "output_dir = \"public/json/\"\n",
38
  "#target_terms = [\"asian\", \"indian\", \"man\", \"woman\", \"german\", \"korean\", \"american\", \"russian\", \"style\", \"japanese\", \"chinese\"] # Add any tags you want to process\n",
39
  "#target_terms = [\"character\", \"instagram\", \"youtuber\", \"actor\", \"actress\", \"celebrity\", \"vtuber\", \"kpop\"] # Add any tags you want to process\n",
40
- "target_terms = [\"germany\", \"america\"] # Add any tags you want to process\n",
41
  "min_connections = 1 # minimum number of link connections per node\n",
42
  "\n",
43
  "# === LOAD DATA ===\n",
@@ -101,6 +101,13 @@
101
  " print(f\" ✅ Saved to {output_file}\")\n"
102
  ]
103
  },
 
 
 
 
 
 
 
104
  {
105
  "cell_type": "code",
106
  "execution_count": 2,
@@ -281,138 +288,6 @@
281
  "\n",
282
  "print(f\"✅ Exported {len(nodes)} nodes and {len(edges)} links to {output_file}\")\n"
283
  ]
284
- },
285
- {
286
- "cell_type": "markdown",
287
- "metadata": {},
288
- "source": [
289
- "### with concept mapping"
290
- ]
291
- },
292
- {
293
- "cell_type": "code",
294
- "execution_count": 2,
295
- "metadata": {},
296
- "outputs": [
297
- {
298
- "name": "stderr",
299
- "output_type": "stream",
300
- "text": [
301
- "/tmp/ipykernel_43462/1387610847.py:36: DtypeWarning: Columns (50,51,54,55,56,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,458) have mixed types. Specify dtype option on import or set low_memory=False.\n",
302
- " df = pd.read_csv(file_path)\n"
303
- ]
304
- },
305
- {
306
- "name": "stdout",
307
- "output_type": "stream",
308
- "text": [
309
- "Processing: russia\n",
310
- " ✅ Saved to public/json/tags_russia.json\n"
311
- ]
312
- }
313
- ],
314
- "source": [
315
- "import pandas as pd\n",
316
- "from itertools import combinations\n",
317
- "from collections import Counter, defaultdict\n",
318
- "import json\n",
319
- "import re\n",
320
- "import os\n",
321
- "\n",
322
- "# === CONFIG ===\n",
323
- "file_path = \"data/CSV/all_models_with_tags.csv\"\n",
324
- "output_dir = \"public/json/\"\n",
325
- "target_terms = [\"russia\"]\n",
326
- "min_connections = 10\n",
327
- "\n",
328
- "# === CUSTOM CONCEPT MAP ===\n",
329
- "concept_map = {\n",
330
- " \"latina\": \"latin\",\n",
331
- " \"latin\": \"latin\",\n",
332
- " \"latin american\": \"latin\",\n",
333
- " \"latino\": \"latin\",\n",
334
- " \"black\": \"black\",\n",
335
- " \"african american\": \"black\",\n",
336
- " \"white\": \"white\",\n",
337
- " \"caucasian\": \"white\",\n",
338
- " \"asian\": \"asian\",\n",
339
- " \"east asian\": \"asian\",\n",
340
- " \"south asian\": \"asian\",\n",
341
- " \"japan\": \"japan\", # self-mapping for clarity\n",
342
- " # Add more mappings as needed\n",
343
- "}\n",
344
- "\n",
345
- "def normalize_tag(tag):\n",
346
- " tag = str(tag).strip().lower()\n",
347
- " return concept_map.get(tag, tag) # fallback to original if not mapped\n",
348
- "\n",
349
- "# === LOAD DATA ===\n",
350
- "df = pd.read_csv(file_path)\n",
351
- "tag_columns = [f\"tag_{i}\" for i in range(1, 8)]\n",
352
- "df_tags = df[tag_columns]\n",
353
- "\n",
354
- "# === MAIN LOOP ===\n",
355
- "for target_term in target_terms:\n",
356
- " print(f\"Processing: {target_term}\")\n",
357
- " \n",
358
- " pattern = re.compile(rf'\\b{re.escape(target_term)}\\b', flags=re.IGNORECASE)\n",
359
- " df_filtered = df_tags[df_tags.apply(\n",
360
- " lambda row: row.astype(str).apply(lambda x: bool(pattern.search(x))).any(),\n",
361
- " axis=1\n",
362
- " )]\n",
363
- "\n",
364
- " if df_filtered.empty:\n",
365
- " print(f\" ⚠️ No matches for '{target_term}', skipping.\")\n",
366
- " continue\n",
367
- "\n",
368
- " # === FLATTEN & NORMALIZE TAGS ===\n",
369
- " all_tags = df_filtered.values.flatten()\n",
370
- " all_tags = [normalize_tag(tag) for tag in all_tags if pd.notna(tag)]\n",
371
- " tag_counts = Counter(all_tags)\n",
372
- "\n",
373
- " # === CO-OCCURRENCE ===\n",
374
- " co_occurrences = defaultdict(int)\n",
375
- " for tags in df_filtered.itertuples(index=False, name=None):\n",
376
- " norm_tags = [normalize_tag(tag) for tag in tags if pd.notna(tag)]\n",
377
- " for tag1, tag2 in combinations(norm_tags, 2):\n",
378
- " if tag1 != tag2: # prevent self-links\n",
379
- " co_occurrences[frozenset([tag1, tag2])] += 1\n",
380
- "\n",
381
- " edges = [(list(pair)[0], list(pair)[1], weight) for pair, weight in co_occurrences.items()]\n",
382
- "\n",
383
- " # === FILTER BY CONNECTIONS ===\n",
384
- " connected_tags = Counter()\n",
385
- " for tag1, tag2, _ in edges:\n",
386
- " connected_tags[tag1] += 1\n",
387
- " connected_tags[tag2] += 1\n",
388
- "\n",
389
- " nodes = [{\"id\": tag, \"size\": tag_counts[tag]} for tag in tag_counts if connected_tags[tag] >= min_connections]\n",
390
- " valid_ids = set(node[\"id\"] for node in nodes)\n",
391
- " links = [{\"source\": tag1, \"target\": tag2, \"value\": weight}\n",
392
- " for tag1, tag2, weight in edges\n",
393
- " if tag1 in valid_ids and tag2 in valid_ids]\n",
394
- "\n",
395
- " if not nodes or not links:\n",
396
- " print(f\" ⚠️ Not enough connections for '{target_term}', skipping.\")\n",
397
- " continue\n",
398
- "\n",
399
- " # === EXPORT ===\n",
400
- " d3_data = {\"nodes\": nodes, \"links\": links}\n",
401
- " safe_term = re.sub(r'\\W+', '_', target_term.lower())\n",
402
- " output_file = os.path.join(output_dir, f\"tags_{safe_term}.json\")\n",
403
- " \n",
404
- " with open(output_file, \"w\") as f:\n",
405
- " json.dump(d3_data, f, indent=4)\n",
406
- " \n",
407
- " print(f\" ✅ Saved to {output_file}\")\n"
408
- ]
409
- },
410
- {
411
- "cell_type": "code",
412
- "execution_count": null,
413
- "metadata": {},
414
- "outputs": [],
415
- "source": []
416
  }
417
  ],
418
  "metadata": {
 
1
  {
2
  "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# Create *.json for figure 5 (Co-occurence network of Tags)"
8
+ ]
9
+ },
10
  {
11
  "cell_type": "code",
12
+ "execution_count": 5,
13
  "metadata": {},
14
  "outputs": [
 
 
 
 
 
 
 
 
15
  {
16
  "name": "stdout",
17
  "output_type": "stream",
18
  "text": [
 
 
19
  "Processing: america\n",
20
+ " ✅ Saved to /home/lauhp/000_PHD/000_010_PUBLICATION/2025_SAGE/CODE/pm-paper_uzh_gitlab/pm-paper/public/json/tags_america.json\n"
21
  ]
22
  }
23
  ],
 
29
  "import re\n",
30
  "import os\n",
31
  "\n",
32
+ "from pathlib import Path\n",
33
+ "current_dir = Path.cwd()\n",
34
+ "\n",
35
  "# === CONFIG ===\n",
36
+ "file_path = current_dir.parent / \"data/CSV/Models/Civi_models.csv\"\n",
37
+ "output_dir = current_dir.parent / \"public/json/\"\n",
38
  "#target_terms = [\"asian\", \"indian\", \"man\", \"woman\", \"german\", \"korean\", \"american\", \"russian\", \"style\", \"japanese\", \"chinese\"] # Add any tags you want to process\n",
39
  "#target_terms = [\"character\", \"instagram\", \"youtuber\", \"actor\", \"actress\", \"celebrity\", \"vtuber\", \"kpop\"] # Add any tags you want to process\n",
40
+ "target_terms = [\"america\"] # Add any tags you want to process\n",
41
  "min_connections = 1 # minimum number of link connections per node\n",
42
  "\n",
43
  "# === LOAD DATA ===\n",
 
101
  " print(f\" ✅ Saved to {output_file}\")\n"
102
  ]
103
  },
104
+ {
105
+ "cell_type": "markdown",
106
+ "metadata": {},
107
+ "source": [
108
+ "## Different Countries"
109
+ ]
110
+ },
111
  {
112
  "cell_type": "code",
113
  "execution_count": 2,
 
288
  "\n",
289
  "print(f\"✅ Exported {len(nodes)} nodes and {len(edges)} links to {output_file}\")\n"
290
  ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
291
  }
292
  ],
293
  "metadata": {
scripts/{05_female_male.ipynb → Section_3-3-4_Figure_8a.ipynb} RENAMED
@@ -1,68 +1,22 @@
1
  {
2
  "cells": [
3
  {
4
- "cell_type": "code",
5
- "execution_count": 1,
6
  "metadata": {},
7
- "outputs": [
8
- {
9
- "name": "stdout",
10
- "output_type": "stream",
11
- "text": [
12
- "✅ Gender sunburst JSON saved to public/json/gender_sunburst.json\n"
13
- ]
14
- }
15
- ],
16
  "source": [
17
- "import pandas as pd\n",
18
- "import json\n",
19
- "from pathlib import Path\n",
20
- "\n",
21
- "# Load the dataset\n",
22
- "df = pd.read_csv(\"/home/lauhp/000_PHD/000_000_RESEARCH/000_X_Research_phase_1/d3js/data/model_subsets/POI/countries_professions.csv\")\n",
23
- "\n",
24
- "\n",
25
- "\n",
26
- "# Normalize gender values\n",
27
- "def normalize_gender(g):\n",
28
- " g = str(g).strip().lower()\n",
29
- " if g in [\"female\", \"woman\", \"female (group)\", \"female (transgender)\", \"female (virtual persona)\", \"female (group members)\"]:\n",
30
- " return \"Female\"\n",
31
- " elif g in [\"male\", \"male (android)\", \"male (character)\"]:\n",
32
- " return \"Male\"\n",
33
- " elif g in [\"non-binary\"]:\n",
34
- " return \"Non-binary\"\n",
35
- " else:\n",
36
- " return \"Unknown\"\n",
37
- "\n",
38
- "df['gender_normalized'] = df['gender'].apply(normalize_gender)\n",
39
- "\n",
40
- "# Count values\n",
41
- "gender_counts = df['gender_normalized'].value_counts().to_dict()\n",
42
- "\n",
43
- "# Create sunburst structure\n",
44
- "gender_sunburst = {\n",
45
- " \"name\": \"root\",\n",
46
- " \"children\": [{\"name\": gender, \"value\": int(count)} for gender, count in gender_counts.items()]\n",
47
- "}\n",
48
- "\n",
49
- "# Save to JSON\n",
50
- "with open(\"public/json/gender_sunburst.json\", \"w\", encoding=\"utf-8\") as f:\n",
51
- " json.dump(gender_sunburst, f, indent=2)\n",
52
- "\n",
53
- "print(\"✅ Gender sunburst JSON saved to public/json/gender_sunburst.json\")\n"
54
  ]
55
  },
56
  {
57
  "cell_type": "code",
58
- "execution_count": 4,
59
  "metadata": {},
60
  "outputs": [
61
  {
62
  "name": "stdout",
63
  "output_type": "stream",
64
  "text": [
65
- "✅ Sunburst gender-profession data saved to sunburst_gender_profession.json\n"
66
  ]
67
  }
68
  ],
@@ -70,10 +24,14 @@
70
  "import pandas as pd\n",
71
  "from collections import defaultdict\n",
72
  "import json\n",
 
 
 
 
73
  "\n",
74
- "# Load the dataset\n",
75
- "df = pd.read_csv(\"/home/lauhp/000_PHD/000_000_RESEARCH/000_X_Research_phase_1/d3js/data/model_subsets/POI/valid.csv\")\n",
76
  "\n",
 
 
77
  "# ---- Normalize Gender (group Non-binary and Unknown into 'Other') ----\n",
78
  "def normalize_gender(g):\n",
79
  " g = str(g).strip().lower()\n",
@@ -131,10 +89,10 @@
131
  " sunburst_dict[\"children\"].append({\"name\": gender, \"children\": professions})\n",
132
  "\n",
133
  "# ---- Step 5: Save to a JSON file ----\n",
134
- "with open(\"public/json/sunburst_gender_profession.json\", \"w\", encoding='utf-8') as f:\n",
135
  " json.dump(sunburst_dict, f, ensure_ascii=False, indent=2)\n",
136
  "\n",
137
- "print(\"✅ Sunburst gender-profession data saved to sunburst_gender_profession.json\")\n"
138
  ]
139
  },
140
  {
 
1
  {
2
  "cells": [
3
  {
4
+ "cell_type": "markdown",
 
5
  "metadata": {},
 
 
 
 
 
 
 
 
 
6
  "source": [
7
+ "# Prepare *.json for Figure 8a"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  ]
9
  },
10
  {
11
  "cell_type": "code",
12
+ "execution_count": 8,
13
  "metadata": {},
14
  "outputs": [
15
  {
16
  "name": "stdout",
17
  "output_type": "stream",
18
  "text": [
19
+ "8a.json\n"
20
  ]
21
  }
22
  ],
 
24
  "import pandas as pd\n",
25
  "from collections import defaultdict\n",
26
  "import json\n",
27
+ "from pathlib import Path \n",
28
+ "\n",
29
+ "current_dir = Path.cwd()\n",
30
+ "sunburst_json = current_dir.parent / \"public/json/8a.json\"\n",
31
  "\n",
 
 
32
  "\n",
33
+ "aggregated_poi = current_dir.parent / \"data/CSV/Deepseek_annotated_POI_aggregated.csv\"\n",
34
+ "df = pd.read_csv(aggregated_poi)\n",
35
  "# ---- Normalize Gender (group Non-binary and Unknown into 'Other') ----\n",
36
  "def normalize_gender(g):\n",
37
  " g = str(g).strip().lower()\n",
 
89
  " sunburst_dict[\"children\"].append({\"name\": gender, \"children\": professions})\n",
90
  "\n",
91
  "# ---- Step 5: Save to a JSON file ----\n",
92
+ "with open(sunburst_json, \"w\", encoding='utf-8') as f:\n",
93
  " json.dump(sunburst_dict, f, ensure_ascii=False, indent=2)\n",
94
  "\n",
95
+ "print(\"8a.json\")\n"
96
  ]
97
  },
98
  {
scripts/{Section_3-3-4_Figure_8_deepfake_victims.ipynb → Section_3-3-4_Figure_8b.ipynb} RENAMED
@@ -1,5 +1,12 @@
1
  {
2
  "cells": [
 
 
 
 
 
 
 
3
  {
4
  "cell_type": "code",
5
  "execution_count": 5,
@@ -83,94 +90,12 @@
83
  "cell_type": "markdown",
84
  "metadata": {},
85
  "source": [
86
- "# V2"
87
  ]
88
  },
89
  {
90
- "cell_type": "code",
91
- "execution_count": 12,
92
- "metadata": {},
93
- "outputs": [
94
- {
95
- "name": "stdout",
96
- "output_type": "stream",
97
- "text": [
98
- "✅ Sunburst data saved to sunburst_data.json\n"
99
- ]
100
- }
101
- ],
102
- "source": [
103
- "import pandas as pd\n",
104
- "from collections import defaultdict\n",
105
- "import json\n",
106
- "\n",
107
- "# Load the dataset\n",
108
- "df = pd.read_csv(\"/home/lauhp/000_PHD/000_000_RESEARCH/000_X_Research_phase_1/d3js/data/model_subsets/POI/valid.csv\")\n",
109
- "\n",
110
- "# ---- Step 1: Limit to top 10 countries ----\n",
111
- "# Treat 'Isle of Man' as 'Unknown'\n",
112
- "df['country'] = df['country'].replace('Isle of Man', 'Unknown')\n",
113
- "\n",
114
- "# Force 'Unknown' and empty countries to 'Other' before computing top countries\n",
115
- "df['country_cleaned'] = df['country'].apply(lambda x: x if x not in ['Unknown', '', None] else 'Other')\n",
116
- "\n",
117
- "# Get top 15 countries excluding 'Other'\n",
118
- "top_countries = df['country_cleaned'].value_counts().nlargest(15).index.tolist()\n",
119
- "\n",
120
- "# Final limited country column\n",
121
- "df['country_limited'] = df['country_cleaned'].apply(lambda x: x if x in top_countries else 'Other')\n",
122
- "\n",
123
- "# ---- Step 2: Limit professions and normalize professions ----\n",
124
- "valid_categories = [\n",
125
- " \"Actor\", \"Adult Performer\", \"Singer, Musician\", \"Model\",\n",
126
- " \"Online Personality\", \"TV Personality\", \"Voice Actor\",\"Public Figure\", \"Sports Professional\"\n",
127
- "]\n",
128
- "\n",
129
- "def remap_profession(profession):\n",
130
- " if profession == 'Unknown' or profession not in valid_categories:\n",
131
- " return 'Other'\n",
132
- " elif profession == 'Fictional Character':\n",
133
- " return 'Actor'\n",
134
- " elif profession == 'Voice actor':\n",
135
- " return 'Voice Actor'\n",
136
- " return profession\n",
137
- "\n",
138
- "df['profession_limited'] = df['mapped_profession'].apply(remap_profession)\n",
139
- "\n",
140
- "# ---- Step 3: Group by the limited country and profession ----\n",
141
- "sunburst_data = df.groupby(['country_limited', 'profession_limited']).size().reset_index(name='count')\n",
142
- "\n",
143
- "# ---- Step 4: Create a nested structure for D3.js ----\n",
144
- "sunburst_dict = {\"name\": \"root\", \"children\": []}\n",
145
- "country_map = defaultdict(list)\n",
146
- "\n",
147
- "for _, row in sunburst_data.iterrows():\n",
148
- " country = row['country_limited']\n",
149
- " profession = row['profession_limited']\n",
150
- " count = int(row['count'])\n",
151
- " country_map[country].append({\"name\": profession, \"value\": count})\n",
152
- "\n",
153
- "# Sort 'Other' professions to appear last\n",
154
- "for country, professions in country_map.items():\n",
155
- " professions_sorted = sorted(professions, key=lambda d: (d[\"name\"] == \"Other\", d[\"name\"]))\n",
156
- " country_map[country] = professions_sorted\n",
157
- "\n",
158
- "# Add countries to the root structure\n",
159
- "for country, professions in country_map.items():\n",
160
- " sunburst_dict[\"children\"].append({\"name\": country, \"children\": professions})\n",
161
- "\n",
162
- "# ---- Step 5: Save to a JSON file ----\n",
163
- "with open(\"public/json/sunburst_data.json\", \"w\", encoding='utf-8') as f:\n",
164
- " json.dump(sunburst_dict, f, ensure_ascii=False, indent=2)\n",
165
- "\n",
166
- "print(\"✅ Sunburst data saved to sunburst_data.json\")\n"
167
- ]
168
- },
169
- {
170
- "cell_type": "code",
171
- "execution_count": null,
172
  "metadata": {},
173
- "outputs": [],
174
  "source": []
175
  }
176
  ],
 
1
  {
2
  "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# Prepare *.json for Figure 8b"
8
+ ]
9
+ },
10
  {
11
  "cell_type": "code",
12
  "execution_count": 5,
 
90
  "cell_type": "markdown",
91
  "metadata": {},
92
  "source": [
93
+ "the resulting *.json is the input for Figure_8.html"
94
  ]
95
  },
96
  {
97
+ "cell_type": "markdown",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
98
  "metadata": {},
 
99
  "source": []
100
  }
101
  ],
scripts/{01_prepare_sankey_csv.ipynb → Section_3-3-4_Figure_9_Sankey.ipynb} RENAMED
File without changes
scripts/{Section_3-3-4_deepfake_adapter.ipynb → Section_3-3-4_LLM_annotation.ipynb} RENAMED
@@ -26,7 +26,53 @@
26
  },
27
  {
28
  "cell_type": "code",
29
- "execution_count": null,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
  "id": "8348c4a4",
31
  "metadata": {},
32
  "outputs": [
@@ -34,33 +80,11 @@
34
  "name": "stdout",
35
  "output_type": "stream",
36
  "text": [
37
- "Done! Saved to precleaned_with_real_names.csv\n"
38
  ]
39
  }
40
  ],
41
  "source": [
42
- "import pandas as pd\n",
43
- "import spacy\n",
44
- "import re\n",
45
- "import torch\n",
46
- "from pathlib import Path\n",
47
- "import unicodedata\n",
48
- "\n",
49
- "\n",
50
- "\n",
51
- "\n",
52
- "# Setup\n",
53
- "current_dir = Path.cwd()\n",
54
- "\n",
55
- "\n",
56
- "poi_models_dir = current_dir.parent / \"data/CSV/model_subsets/POI_models.csv\" ### POI models dataset\n",
57
- "output = current_dir.parent / \"data/CSV/model_subsets/NER_poi_step_01.csv\" ### Output file\n",
58
- "\n",
59
- "\n",
60
- "nlp = spacy.load(\"en_core_web_sm\") # or another model of your choice\n",
61
- "\n",
62
- "\n",
63
- "\n",
64
  "def preprocess_name(name):\n",
65
  " name = str(name)\n",
66
  "\n",
@@ -150,7 +174,7 @@
150
  },
151
  {
152
  "cell_type": "code",
153
- "execution_count": 27,
154
  "id": "414954ed",
155
  "metadata": {},
156
  "outputs": [
@@ -265,7 +289,7 @@
265
  },
266
  {
267
  "cell_type": "code",
268
- "execution_count": 29,
269
  "id": "054f230b",
270
  "metadata": {},
271
  "outputs": [],
@@ -285,7 +309,7 @@
285
  },
286
  {
287
  "cell_type": "code",
288
- "execution_count": null,
289
  "id": "504b970f",
290
  "metadata": {},
291
  "outputs": [],
@@ -295,7 +319,7 @@
295
  },
296
  {
297
  "cell_type": "code",
298
- "execution_count": 31,
299
  "id": "7c209115",
300
  "metadata": {},
301
  "outputs": [
@@ -303,64 +327,14 @@
303
  "name": "stdout",
304
  "output_type": "stream",
305
  "text": [
306
- "Row 1/29...\n",
307
  "Saved up to row 1\n",
308
- "Row 2/29...\n",
309
  "Saved up to row 2\n",
310
- "Row 3/29...\n",
311
  "Saved up to row 3\n",
312
- "Row 4/29...\n",
313
  "Saved up to row 4\n",
314
- "Row 5/29...\n",
315
- "Saved up to row 5\n",
316
- "Row 6/29...\n",
317
- "Saved up to row 6\n",
318
- "Row 7/29...\n",
319
- "Saved up to row 7\n",
320
- "Row 8/29...\n",
321
- "Saved up to row 8\n",
322
- "Row 9/29...\n",
323
- "Saved up to row 9\n",
324
- "Row 10/29...\n",
325
- "Saved up to row 10\n",
326
- "Row 11/29...\n",
327
- "Saved up to row 11\n",
328
- "Row 12/29...\n",
329
- "Saved up to row 12\n",
330
- "Row 13/29...\n",
331
- "Saved up to row 13\n",
332
- "Row 14/29...\n",
333
- "Saved up to row 14\n",
334
- "Row 15/29...\n",
335
- "Saved up to row 15\n",
336
- "Row 16/29...\n",
337
- "Saved up to row 16\n",
338
- "Row 17/29...\n",
339
- "Saved up to row 17\n",
340
- "Row 18/29...\n",
341
- "Saved up to row 18\n",
342
- "Row 19/29...\n",
343
- "Saved up to row 19\n",
344
- "Row 20/29...\n",
345
- "Saved up to row 20\n",
346
- "Row 21/29...\n",
347
- "Saved up to row 21\n",
348
- "Row 22/29...\n",
349
- "Saved up to row 22\n",
350
- "Row 23/29...\n",
351
- "Saved up to row 23\n",
352
- "Row 24/29...\n",
353
- "Saved up to row 24\n",
354
- "Row 25/29...\n",
355
- "Saved up to row 25\n",
356
- "Row 26/29...\n",
357
- "Saved up to row 26\n",
358
- "Row 27/29...\n",
359
- "Saved up to row 27\n",
360
- "Row 28/29...\n",
361
- "Saved up to row 28\n",
362
- "Row 29/29...\n",
363
- "Saved up to row 29\n",
364
  "All done! Files: /home/lauhp/000_PHD/000_010_PUBLICATION/2025_SAGE/CODE/pm-paper_uzh_gitlab/pm-paper/data/CSV/Deepseek_annotated_POI.csv /home/lauhp/000_PHD/000_010_PUBLICATION/2025_SAGE/CODE/pm-paper_uzh_gitlab/pm-paper/data/CSV/Deepseek_annotated_POI.xlsx\n"
365
  ]
366
  }
@@ -376,15 +350,15 @@
376
  "# === PATHS & CONFIG ===\n",
377
  "current_dir = Path.cwd()\n",
378
  "inputCSV = current_dir.parent / \"data/CSV/model_subsets/NER_poi_step_02.csv\"\n",
379
- "api_key = current_dir.parent / \"misc/credentials/deepseek_api_key2.txt\" #store your API key under misc/credentials/deepseek_api_key.txt\n",
380
  "\n",
381
  "# Output both CSV and Excel for compatibility\n",
382
  "OUTPUT_CSV = current_dir.parent / \"data/CSV/Deepseek_annotated_POI.csv\"\n",
383
  "OUTPUT_XLSX = current_dir.parent / \"data/CSV/Deepseek_annotated_POI.xlsx\"\n",
384
- "INDEX_FILE = current_dir.parent / \"misc/deepseek_query_ind3x.txt\"\n",
385
  "SAVE_INTERVAL = 1 # Save every N rows\n",
386
  "START_ROW = 1 # Row index to start from (0-based)\n",
387
- "END_ROW = 30 # Row index to end (exclusive)\n",
388
  "\n",
389
  "# === LOAD API KEY & CLIENT ===\n",
390
  "with open(api_key_file) as f:\n",
@@ -486,28 +460,180 @@
486
  "print(\"All done! Files:\", OUTPUT_CSV, OUTPUT_XLSX)\n"
487
  ]
488
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
489
  {
490
  "cell_type": "code",
491
- "execution_count": null,
492
  "id": "747c3a2f",
493
  "metadata": {},
494
- "outputs": [
495
- {
496
- "name": "stdout",
497
- "output_type": "stream",
498
- "text": [
499
- "Collecting openpyxl\n",
500
- " Downloading openpyxl-3.1.5-py2.py3-none-any.whl.metadata (2.5 kB)\n",
501
- "Collecting et-xmlfile (from openpyxl)\n",
502
- " Downloading et_xmlfile-2.0.0-py3-none-any.whl.metadata (2.7 kB)\n",
503
- "Downloading openpyxl-3.1.5-py2.py3-none-any.whl (250 kB)\n",
504
- "Downloading et_xmlfile-2.0.0-py3-none-any.whl (18 kB)\n",
505
- "Installing collected packages: et-xmlfile, openpyxl\n",
506
- "Successfully installed et-xmlfile-2.0.0 openpyxl-3.1.5\n"
507
- ]
508
- }
509
- ],
510
- "source": []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
511
  },
512
  {
513
  "cell_type": "code",
 
26
  },
27
  {
28
  "cell_type": "code",
29
+ "execution_count": 1,
30
+ "id": "f177df11",
31
+ "metadata": {},
32
+ "outputs": [],
33
+ "source": [
34
+ "import pandas as pd\n",
35
+ "import spacy\n",
36
+ "import re\n",
37
+ "import torch\n",
38
+ "from pathlib import Path\n",
39
+ "import unicodedata\n"
40
+ ]
41
+ },
42
+ {
43
+ "cell_type": "code",
44
+ "execution_count": 2,
45
+ "id": "a2383f32",
46
+ "metadata": {},
47
+ "outputs": [],
48
+ "source": [
49
+ "current_dir = Path.cwd()\n",
50
+ "poi_models_dir = current_dir.parent / \"data/CSV/model_subsets/POI_models.csv\" ### POI models dataset\n",
51
+ "output = current_dir.parent / \"data/CSV/model_subsets/NER_poi_step_01.csv\" ### Output file"
52
+ ]
53
+ },
54
+ {
55
+ "cell_type": "code",
56
+ "execution_count": 3,
57
+ "id": "66fc691f",
58
+ "metadata": {},
59
+ "outputs": [
60
+ {
61
+ "name": "stderr",
62
+ "output_type": "stream",
63
+ "text": [
64
+ "/home/lauhp/anaconda3/envs/latm/lib/python3.10/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n",
65
+ " from .autonotebook import tqdm as notebook_tqdm\n"
66
+ ]
67
+ }
68
+ ],
69
+ "source": [
70
+ "nlp = spacy.load(\"en_core_web_sm\") # or another model of your choice"
71
+ ]
72
+ },
73
+ {
74
+ "cell_type": "code",
75
+ "execution_count": 4,
76
  "id": "8348c4a4",
77
  "metadata": {},
78
  "outputs": [
 
80
  "name": "stdout",
81
  "output_type": "stream",
82
  "text": [
83
+ "Done! Saved to NER_poi_step_01.csv\n"
84
  ]
85
  }
86
  ],
87
  "source": [
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  "def preprocess_name(name):\n",
89
  " name = str(name)\n",
90
  "\n",
 
174
  },
175
  {
176
  "cell_type": "code",
177
+ "execution_count": 5,
178
  "id": "414954ed",
179
  "metadata": {},
180
  "outputs": [
 
289
  },
290
  {
291
  "cell_type": "code",
292
+ "execution_count": 6,
293
  "id": "054f230b",
294
  "metadata": {},
295
  "outputs": [],
 
309
  },
310
  {
311
  "cell_type": "code",
312
+ "execution_count": 7,
313
  "id": "504b970f",
314
  "metadata": {},
315
  "outputs": [],
 
319
  },
320
  {
321
  "cell_type": "code",
322
+ "execution_count": 10,
323
  "id": "7c209115",
324
  "metadata": {},
325
  "outputs": [
 
327
  "name": "stdout",
328
  "output_type": "stream",
329
  "text": [
330
+ "Row 1/4...\n",
331
  "Saved up to row 1\n",
332
+ "Row 2/4...\n",
333
  "Saved up to row 2\n",
334
+ "Row 3/4...\n",
335
  "Saved up to row 3\n",
336
+ "Row 4/4...\n",
337
  "Saved up to row 4\n",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
  "All done! Files: /home/lauhp/000_PHD/000_010_PUBLICATION/2025_SAGE/CODE/pm-paper_uzh_gitlab/pm-paper/data/CSV/Deepseek_annotated_POI.csv /home/lauhp/000_PHD/000_010_PUBLICATION/2025_SAGE/CODE/pm-paper_uzh_gitlab/pm-paper/data/CSV/Deepseek_annotated_POI.xlsx\n"
339
  ]
340
  }
 
350
  "# === PATHS & CONFIG ===\n",
351
  "current_dir = Path.cwd()\n",
352
  "inputCSV = current_dir.parent / \"data/CSV/model_subsets/NER_poi_step_02.csv\"\n",
353
+ "api_key_file = current_dir.parent / \"misc/credentials/deepseek_api_key.txt\" #store your API key under misc/credentials/deepseek_api_key.txt\n",
354
  "\n",
355
  "# Output both CSV and Excel for compatibility\n",
356
  "OUTPUT_CSV = current_dir.parent / \"data/CSV/Deepseek_annotated_POI.csv\"\n",
357
  "OUTPUT_XLSX = current_dir.parent / \"data/CSV/Deepseek_annotated_POI.xlsx\"\n",
358
+ "INDEX_FILE = current_dir.parent / \"misc/deepseek_query_index.txt\"\n",
359
  "SAVE_INTERVAL = 1 # Save every N rows\n",
360
  "START_ROW = 1 # Row index to start from (0-based)\n",
361
+ "END_ROW = 5 # Row index to end (exclusive)\n",
362
  "\n",
363
  "# === LOAD API KEY & CLIENT ===\n",
364
  "with open(api_key_file) as f:\n",
 
460
  "print(\"All done! Files:\", OUTPUT_CSV, OUTPUT_XLSX)\n"
461
  ]
462
  },
463
+ {
464
+ "cell_type": "markdown",
465
+ "id": "7910e574",
466
+ "metadata": {},
467
+ "source": []
468
+ },
469
+ {
470
+ "cell_type": "markdown",
471
+ "id": "9d377005",
472
+ "metadata": {},
473
+ "source": [
474
+ "# Aggregate by individual names"
475
+ ]
476
+ },
477
+ {
478
+ "cell_type": "markdown",
479
+ "id": "d2e75354",
480
+ "metadata": {},
481
+ "source": [
482
+ " ##### e.g. Emma Watson [model1, model2, model3] etc."
483
+ ]
484
+ },
485
  {
486
  "cell_type": "code",
487
+ "execution_count": 11,
488
  "id": "747c3a2f",
489
  "metadata": {},
490
+ "outputs": [],
491
+ "source": [
492
+ "import pandas as pd\n",
493
+ "import re\n",
494
+ "from pathlib import Path\n",
495
+ "current_dir = Path.cwd()\n",
496
+ "\n",
497
+ "profession_map = current_dir.parent / \"misc/lists/mapped_professions.csv\"\n",
498
+ "\n",
499
+ "poi_df = current_dir.parent / \"data/CSV/Deepseek_annotated_POI.csv\"\n",
500
+ "\n",
501
+ "output = current_dir.parent / \"data/CSV/Deepseek_annotated_POI_aggregated.csv\"\n",
502
+ "\n",
503
+ "countries_csv = current_dir.parent / \"misc/lists/countries.csv\"\n",
504
+ "countries_df = pd.read_csv(countries_csv)\n",
505
+ "\n",
506
+ "# Extract valid country names (strip whitespace)\n",
507
+ "valid_countries = set(countries_df['en_short_name'].str.strip())\n",
508
+ "\n",
509
+ "\n",
510
+ "# Load the dataset\n",
511
+ "df = pd.read_csv(poi_df) # Update path if needed\n",
512
+ "\n",
513
+ "# Step 1: Group by 'full_name' and aggregate required information\n",
514
+ "grouped_df = df.groupby('full_name').agg(\n",
515
+ " No_of_models=('id', 'count'),\n",
516
+ " modelIDs=('id', lambda x: list(x)),\n",
517
+ " combinedDownloadCount=('downloadCount', 'sum')\n",
518
+ ").reset_index()\n",
519
+ "\n",
520
+ "# Step 2: Keep representative info for each person\n",
521
+ "# Keep representative info (including aliases)\n",
522
+ "additional_columns = df.groupby('full_name').agg(\n",
523
+ " country=('country', 'first'),\n",
524
+ " profession_llm=('profession_llm', 'first'),\n",
525
+ " gender=('gender', 'first'),\n",
526
+ " aliases=('aliases', 'first') # ✅ Add this line\n",
527
+ ").reset_index()\n",
528
+ "\n",
529
+ "\n",
530
+ "\n",
531
+ "def standardize_country(country):\n",
532
+ " if not isinstance(country, str):\n",
533
+ " return \"Unknown\"\n",
534
+ "\n",
535
+ " country_clean = country.strip()\n",
536
+ " lowered = country_clean.lower()\n",
537
+ "\n",
538
+ " # Handle fictional or fantasy countries\n",
539
+ " fictional_keywords = [\"fictional\", \"westeros\", \"asgard\", \"middle-earth\", \"naboo\", \"middle earth\", \"latveria\"]\n",
540
+ " if any(keyword in lowered for keyword in fictional_keywords):\n",
541
+ " return \"Unknown\"\n",
542
+ "\n",
543
+ " # Handle known region-based adjustments\n",
544
+ " if \"macau\" in lowered:\n",
545
+ " return \"Macau\"\n",
546
+ " elif \"hong kong\" in lowered:\n",
547
+ " return \"Hong Kong\"\n",
548
+ " elif \"taiwan\" in lowered:\n",
549
+ " return \"Taiwan\"\n",
550
+ "\n",
551
+ " # Normalize complex or alternate country names\n",
552
+ " lowered = lowered.replace(\"United Kingdom of Great Britain and Northern Ireland\", \"united kingdom\")\n",
553
+ " lowered = lowered.replace(\"england\", \"united kingdom\")\n",
554
+ " lowered = lowered.replace(\"united states of america\", \"united states\")\n",
555
+ "\n",
556
+ " # Remove anything in brackets and after commas\n",
557
+ " country_clean = re.sub(r\"\\(.*?\\)\", \"\", country_clean)\n",
558
+ " country_clean = country_clean.split(',')[0].strip().lower()\n",
559
+ "\n",
560
+ " # Manual overrides\n",
561
+ " replacements = {\n",
562
+ " \"united kingdom\": \"UK\",\n",
563
+ " \"united kingdom of great britain and northern ireland\": \"UK\",\n",
564
+ " \"french southern territories\": \"Other\",\n",
565
+ " \"united states\": \"US\",\n",
566
+ " \"united states of america\": \"US\",\n",
567
+ " \"turkey\": \"Türkiye\",\n",
568
+ " \"czech republic\": \"Czechia\"\n",
569
+ " }\n",
570
+ "\n",
571
+ " if country_clean in replacements:\n",
572
+ " return replacements[country_clean]\n",
573
+ "\n",
574
+ " # Final check against valid country list (case-insensitive)\n",
575
+ " for valid in valid_countries:\n",
576
+ " if country_clean == valid.lower():\n",
577
+ " return valid\n",
578
+ "\n",
579
+ " return \"Unknown\"\n",
580
+ "\n",
581
+ "\n",
582
+ "# Updated function to fully remove anything in brackets (complete or not)\n",
583
+ "def get_profession_short(profession):\n",
584
+ " if isinstance(profession, str):\n",
585
+ " # Get first part before comma\n",
586
+ " first_prof = profession.split(',')[0].strip()\n",
587
+ " # Remove all bracketed content, even malformed\n",
588
+ " first_prof = re.sub(r\"[\\[].∗?[\\[].*?[\\]]\", \"\", first_prof) # removes properly closed\n",
589
+ " first_prof = re.sub(r\"[\\(\\[].*\", \"\", first_prof) # removes malformed\n",
590
+ " cleaned = first_prof.strip()\n",
591
+ " # Normalize 'Actress' to 'Actor'\n",
592
+ " if cleaned.lower() == \"actress\":\n",
593
+ " return \"Actor\"\n",
594
+ " return cleaned\n",
595
+ " return None\n",
596
+ "\n",
597
+ "# Load your mapping file\n",
598
+ "mapping_df = pd.read_csv(profession_map, on_bad_lines='skip') # or 'warn'\n",
599
+ "\n",
600
+ "\n",
601
+ "# Ensure the mapping columns are named correctly\n",
602
+ "# (Assuming columns are: 'profession_llm' or 'profession_short', and 'category' or 'mapped_profession')\n",
603
+ "# Adjust these as needed\n",
604
+ "mapping_df.columns = [col.strip().lower() for col in mapping_df.columns]\n",
605
+ "\n",
606
+ "# Rename for clarity and consistency\n",
607
+ "if 'profession_llm' in mapping_df.columns:\n",
608
+ " mapping_df = mapping_df.rename(columns={'profession_llm': 'profession_short'})\n",
609
+ "if 'category' in mapping_df.columns:\n",
610
+ " mapping_df = mapping_df.rename(columns={'category': 'mapped_profession'})\n",
611
+ "\n",
612
+ "# Merge the mapped profession into final_df\n",
613
+ "#final_df = final_df.merge(mapping_df[['profession_short', 'mapped_profession']], on='profession_short', how='left')\n",
614
+ "\n",
615
+ "\n",
616
+ "additional_columns = df.groupby('full_name').agg(\n",
617
+ " country=('country', 'first'),\n",
618
+ " profession_llm=('profession_llm', 'first'),\n",
619
+ " gender=('gender', 'first'),\n",
620
+ " aliases=('aliases', 'first') # <-- Added this line\n",
621
+ ").reset_index()\n",
622
+ "\n",
623
+ "\n",
624
+ "# Step 3: Merge the aggregated info with the representative info\n",
625
+ "final_df = pd.merge(grouped_df, additional_columns, on='full_name', how='left')\n",
626
+ "\n",
627
+ "# Step 4: Clean and transform columns\n",
628
+ "final_df['profession_short'] = final_df['profession_llm'].apply(get_profession_short)\n",
629
+ "final_df['country'] = final_df['country'].apply(standardize_country)\n",
630
+ "\n",
631
+ "# Step 5: Merge with profession mapping\n",
632
+ "final_df = final_df.merge(mapping_df[['profession_short', 'mapped_profession']], on='profession_short', how='left')\n",
633
+ "\n",
634
+ "# Optional: Save the result to a CSV file\n",
635
+ "final_df.to_csv(output, index=False)\n"
636
+ ]
637
  },
638
  {
639
  "cell_type": "code",
scripts/Section_3-4_extract_LoRA_metadata.ipynb CHANGED
The diff for this file is too large to render. See raw diff
 
scripts/{get_Danbooru_Tags_and categorize.ipynb → SuppM_Figure_12_Danbooru_Taxonomy.ipynb} RENAMED
File without changes
scripts/{04_training_data_network_data_prep.ipynb → SuppM_Figure_13.ipynb} RENAMED
@@ -1,5 +1,12 @@
1
  {
2
  "cells": [
 
 
 
 
 
 
 
3
  {
4
  "cell_type": "code",
5
  "execution_count": null,
 
1
  {
2
  "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# Prepare *.json for Figure 13"
8
+ ]
9
+ },
10
  {
11
  "cell_type": "code",
12
  "execution_count": null,
public/06_danbooru_structure.ipynb → scripts/SuppM_Figure_13_Danbooru_taxonomy.ipynb RENAMED
@@ -2,7 +2,7 @@
2
  "cells": [
3
  {
4
  "cell_type": "code",
5
- "execution_count": 8,
6
  "metadata": {},
7
  "outputs": [],
8
  "source": [
@@ -15,15 +15,15 @@
15
  "\n",
16
  "# ---- CATEGORY COLORS ----\n",
17
  "CATEGORY_COLORS = {\n",
18
- " \"attire\": \"#f4a261\",\n",
19
- " \"body\": \"#e76f51\",\n",
20
- " \"characters\": \"#2a9d8f\",\n",
21
  " \"copyrights\": \"#264653\",\n",
22
- " \"creatures\": \"#8ecae6\",\n",
23
  " \"drawing software\": \"#219ebc\",\n",
24
- " \"games\": \"#3a86ff\",\n",
25
- " \"metatags\": \"#ffbe0b\",\n",
26
- " \"more\": \"#b5179e\",\n",
27
  " \"objects\": \"#6d6875\",\n",
28
  " \"plant\": \"#7cb518\",\n",
29
  " \"real_world\": \"#a5a58d\",\n",
@@ -119,7 +119,7 @@
119
  ],
120
  "metadata": {
121
  "kernelspec": {
122
- "display_name": "Python 3",
123
  "language": "python",
124
  "name": "python3"
125
  },
@@ -133,7 +133,7 @@
133
  "name": "python",
134
  "nbconvert_exporter": "python",
135
  "pygments_lexer": "ipython3",
136
- "version": "3.10.12"
137
  }
138
  },
139
  "nbformat": 4,
 
2
  "cells": [
3
  {
4
  "cell_type": "code",
5
+ "execution_count": 2,
6
  "metadata": {},
7
  "outputs": [],
8
  "source": [
 
15
  "\n",
16
  "# ---- CATEGORY COLORS ----\n",
17
  "CATEGORY_COLORS = {\n",
18
+ " \"attire_and_body_accessories\": \"#DC143C\",\n",
19
+ " \"body\": \"coral\",\n",
20
+ " \"characters\": \"silver\",\n",
21
  " \"copyrights\": \"#264653\",\n",
22
+ " \"creatures\": \"silver\",\n",
23
  " \"drawing software\": \"#219ebc\",\n",
24
+ " \"games\": \"silver\",\n",
25
+ " \"metatags\": \"silver\",\n",
26
+ " \"more\": \"silver\",\n",
27
  " \"objects\": \"#6d6875\",\n",
28
  " \"plant\": \"#7cb518\",\n",
29
  " \"real_world\": \"#a5a58d\",\n",
 
119
  ],
120
  "metadata": {
121
  "kernelspec": {
122
+ "display_name": "latm",
123
  "language": "python",
124
  "name": "python3"
125
  },
 
133
  "name": "python",
134
  "nbconvert_exporter": "python",
135
  "pygments_lexer": "ipython3",
136
+ "version": "3.10.15"
137
  }
138
  },
139
  "nbformat": 4,