carlosh93 commited on
Commit
1cfc9e8
·
1 Parent(s): 07c64c1

Updating app version July 15th, 2025

Browse files
app.py CHANGED
@@ -1,8 +1,16 @@
 
 
 
 
 
 
 
1
  from ui.layout import build_ui
2
  from logic.data_utils import load_concepts, load_metadata
3
 
4
  from config.settings import HF_API_TOKEN, HF_DATASET_NAME
5
 
 
6
  concepts = load_concepts()
7
  metadata = load_metadata()
8
 
 
1
+ # import spacy.cli
2
+ # spacy.cli.download("ja_core_news_sm")
3
+ # spacy.cli.download("zh_core_web_sm")
4
+ import spacy_udpipe
5
+ spacy_udpipe.download("ja")
6
+ spacy_udpipe.download("zh")
7
+
8
  from ui.layout import build_ui
9
  from logic.data_utils import load_concepts, load_metadata
10
 
11
  from config.settings import HF_API_TOKEN, HF_DATASET_NAME
12
 
13
+
14
  concepts = load_concepts()
15
  metadata = load_metadata()
16
 
data/concepts.json CHANGED
@@ -2639,21 +2639,77 @@
2639
  "ጥብስ",
2640
  "ፍርፍር",
2641
  "ሰላጣ",
2642
- "ብርዝ"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2643
  ],
2644
  "Clothing": [
2645
  "ሱሪ",
2646
  "ነጠላ",
2647
  "ጋቢ",
2648
  "ቀሚስ",
2649
- "ካልሲ",
2650
  "ካፖርት",
2651
  "ኮት",
2652
  "ጫማ",
2653
  "ብርድ ልብስ",
2654
  "አንሶላ",
2655
  "ሰዓት",
2656
- "ሻሽ"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2657
  ],
2658
  "Buildings (interior and exterior)": [
2659
  "ቤት",
@@ -2681,7 +2737,10 @@
2681
  "አደባባይ",
2682
  "ቤተመንግስት",
2683
  "መስጊድ ",
2684
- "ቤተ ክርስቲያን "
 
 
 
2685
  ],
2686
  "Instruments, Tools and Utensils": [
2687
  "ምጣድ",
@@ -2693,18 +2752,66 @@
2693
  "ዶማ",
2694
  "ቀንበር",
2695
  "ከበሮ",
2696
- "ሞሰብ"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2697
  ],
2698
  "Celebrations, Sports and Events": [
2699
  "ሰርግ",
2700
  "ቀብር",
2701
- "የትውልድ ስም",
2702
  "አዲስ አመት",
2703
  "ኢድ አልፈጥር",
2704
  "ኢድ አልአድሃ",
2705
- "አዲስ አመት",
2706
  "ገና",
2707
- "ጥምቀት"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2708
  ]
2709
  }
2710
  },
@@ -5820,7 +5927,7 @@
5820
  "Maji",
5821
  "Sharubati",
5822
  "Mayai",
5823
- "Ugali",
5824
  "Wali",
5825
  "Maharagwe",
5826
  "Mahindi",
@@ -5829,10 +5936,10 @@
5829
  "Kuku",
5830
  "Viazi",
5831
  "Mandazi",
5832
- "Mahamri",
5833
  "Chapati",
5834
  "Pilau",
5835
- "Samaki"
 
5836
  ],
5837
  "Clothing": [
5838
  "Kaptura",
@@ -5844,7 +5951,7 @@
5844
  "Soksi",
5845
  "Kofia",
5846
  "Kitenge",
5847
- "Viatu",
5848
  "Champali",
5849
  "Sidiria"
5850
  ],
@@ -5897,7 +6004,7 @@
5897
  "Tarumbeta",
5898
  "Kayamba",
5899
  "Kinanda",
5900
- "Guitaa"
5901
  ],
5902
  "Celebrations, Sports and Events": [
5903
  "Harusi",
@@ -5917,7 +6024,7 @@
5917
  "Siku ya Wafanyakazi /Leba Dei",
5918
  "Sikukuu ya Krismasi",
5919
  "Siku ya Wanawake Duniani",
5920
- "Siku ya Kina Baba",
5921
  "Siku ya Mama"
5922
  ]
5923
  }
@@ -6343,7 +6450,6 @@
6343
  "Rijtjeshuis",
6344
  "Boerderij",
6345
  "Villa",
6346
- "Molen",
6347
  "Flat",
6348
  "Kasteel",
6349
  "Watertoren",
@@ -6356,7 +6462,8 @@
6356
  "Bunker",
6357
  "Woonboot",
6358
  "Begijnhof",
6359
- "Sluis"
 
6360
  ],
6361
  "Instruments, Tools and Utensils": [
6362
  "Poffertjespan",
@@ -6995,7 +7102,28 @@
6995
  "Galocha",
6996
  "Chapéu"
6997
  ],
6998
- "Buildings (interior and exterior)": [],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6999
  "Instruments, Tools and Utensils": [
7000
  "Guitarra portuguesa",
7001
  "Cavaquinho",
@@ -9443,8 +9571,70 @@
9443
  },
9444
  "Venezuela": {
9445
  "Spanish": {
9446
- "Food and Beverages": [],
9447
- "Clothing": [],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9448
  "Buildings (interior and exterior)": [
9449
  "Casa / Quinta",
9450
  "Apartamento",
@@ -9487,13 +9677,69 @@
9487
  "Cuartel",
9488
  "Centro Comercial"
9489
  ],
9490
- "Instruments, Tools and Utensils": [],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9491
  "Celebrations, Sports and Events": [
9492
  "Boda",
9493
  "Funeral",
9494
  "Bautizo",
9495
  "Año Nuevo",
9496
- "Cumpleaños"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9497
  ]
9498
  }
9499
  },
 
2639
  "ጥብስ",
2640
  "ፍርፍር",
2641
  "ሰላጣ",
2642
+ "ብርዝ",
2643
+ "ሽሮ",
2644
+ "ዶሮ ወጥ",
2645
+ "ምንቸት አብሽ",
2646
+ "ጎረድ ጎርድ",
2647
+ "አልጫ ",
2648
+ "ገንፎ",
2649
+ "ጨጨብሳ",
2650
+ "ፈጢራ",
2651
+ "ባቅላባ",
2652
+ "ኽለዋ",
2653
+ "ክክ ወጥ",
2654
+ "ምስር ወጥ",
2655
+ "ድንች ወጥ",
2656
+ "በየአይነቱ ",
2657
+ "አነባብሮሽ",
2658
+ "እንቁላል ፍርፍር",
2659
+ "ፉል",
2660
+ "ህልብት",
2661
+ "ፋታ",
2662
+ "ጭቆ",
2663
+ "አንባሻ",
2664
+ "ቆሎ",
2665
+ "ንፍሮ",
2666
+ "ድንች ቅቅል",
2667
+ "ሳምቡሳ",
2668
+ "ቦምቦሊኖ",
2669
+ "አጥሚት",
2670
+ "ቦርዲ",
2671
+ "ቡና",
2672
+ "አረቄ"
2673
  ],
2674
  "Clothing": [
2675
  "ሱሪ",
2676
  "ነጠላ",
2677
  "ጋቢ",
2678
  "ቀሚስ",
2679
+ "ካልስ",
2680
  "ካፖርት",
2681
  "ኮት",
2682
  "ጫማ",
2683
  "ብርድ ልብስ",
2684
  "አንሶላ",
2685
  "ሰዓት",
2686
+ "ሻሽ",
2687
+ "እጀ ጠባብ",
2688
+ "መቀነት",
2689
+ "ጉንፍ",
2690
+ "ሹፎን",
2691
+ "ሽብሽቦ",
2692
+ "ሂጃብ",
2693
+ "አባያ",
2694
+ "ጅልባብ",
2695
+ "ጀላብያ",
2696
+ "ጥምጣም",
2697
+ "ሽርጥ",
2698
+ "ፎጣ",
2699
+ "ጎጃም አዘነ",
2700
+ "ቁምጣ",
2701
+ "ጥበብ",
2702
+ "ዉስጥ ልብስ",
2703
+ "ባርኔጣ",
2704
+ "ገሳ",
2705
+ "ካባ",
2706
+ "ቤሎ",
2707
+ "መቅና",
2708
+ "ኒቃብ",
2709
+ "ማተብ",
2710
+ "የዉስጥ ሱሪ",
2711
+ "ሸበጥ",
2712
+ "ነጠላ ጫማ"
2713
  ],
2714
  "Buildings (interior and exterior)": [
2715
  "ቤት",
 
2737
  "አደባባይ",
2738
  "ቤተመንግስት",
2739
  "መስጊድ ",
2740
+ "ቤተ ክርስቲያን ",
2741
+ "ጎጆ ቤት",
2742
+ "ሽንት ቤት",
2743
+ "በረንዳ"
2744
  ],
2745
  "Instruments, Tools and Utensils": [
2746
  "ምጣድ",
 
2752
  "ዶማ",
2753
  "ቀንበር",
2754
  "ከበሮ",
2755
+ "ሞሰብ",
2756
+ "ዋሽንት",
2757
+ "ክራር",
2758
+ "ዲቢ",
2759
+ "ሰፌድ",
2760
+ "ሰባጤራ",
2761
+ "እንስራ",
2762
+ "ቶፋ",
2763
+ "ጎታ",
2764
+ "ጀበና",
2765
+ "ጥዋ",
2766
+ "ዋንጫ",
2767
+ "ብርሌ",
2768
+ "ፋጋ",
2769
+ "ሰኔል",
2770
+ "ጭልፋ",
2771
+ "መገበሪያ",
2772
+ "ሙግድ",
2773
+ "ቆጥ",
2774
+ "መደብ",
2775
+ "ቁና",
2776
+ "ቀፎ",
2777
+ "ሙቅጫ",
2778
+ "ዘነዘና",
2779
+ "ዘንቢል",
2780
+ "ወንፊት"
2781
  ],
2782
  "Celebrations, Sports and Events": [
2783
  "ሰርግ",
2784
  "ቀብር",
2785
+ "የልድተ ቀን",
2786
  "አዲስ አመት",
2787
  "ኢድ አልፈጥር",
2788
  "ኢድ አልአድሃ",
2789
+ "ተስካር",
2790
  "ገና",
2791
+ "ጥምቀት",
2792
+ "መዉሊደ",
2793
+ "ቡሄ",
2794
+ "ፋሲካ",
2795
+ "የመስቀል በዓል",
2796
+ "ታላቁ ሩጫ",
2797
+ "ህዳር ጺዎን",
2798
+ "ቁልቢ ገብርኤል",
2799
+ "የአድዋ በዓል",
2800
+ "የአርበኞች ቀን",
2801
+ "የላባደሮች ቀን",
2802
+ "የብሄር ብሄረሰቦች ቀን",
2803
+ "ኢሬቻ",
2804
+ "ሻደይ",
2805
+ "ፊቸ ጨምበላላ",
2806
+ "አሸንዳ",
2807
+ "ህዳር ሲታጠን",
2808
+ "የገና ጨዋታ",
2809
+ "እግር ኳስ ጨዋታ",
2810
+ "አገዉ ፈረሰኞች",
2811
+ "ምርቃት",
2812
+ "እርሻ",
2813
+ "ትግል",
2814
+ "ገበጣ"
2815
  ]
2816
  }
2817
  },
 
5927
  "Maji",
5928
  "Sharubati",
5929
  "Mayai",
5930
+ "Ugali/Sima",
5931
  "Wali",
5932
  "Maharagwe",
5933
  "Mahindi",
 
5936
  "Kuku",
5937
  "Viazi",
5938
  "Mandazi",
 
5939
  "Chapati",
5940
  "Pilau",
5941
+ "Samaki",
5942
+ "Mkate"
5943
  ],
5944
  "Clothing": [
5945
  "Kaptura",
 
5951
  "Soksi",
5952
  "Kofia",
5953
  "Kitenge",
5954
+ "Kiatu",
5955
  "Champali",
5956
  "Sidiria"
5957
  ],
 
6004
  "Tarumbeta",
6005
  "Kayamba",
6006
  "Kinanda",
6007
+ "Gitaa"
6008
  ],
6009
  "Celebrations, Sports and Events": [
6010
  "Harusi",
 
6024
  "Siku ya Wafanyakazi /Leba Dei",
6025
  "Sikukuu ya Krismasi",
6026
  "Siku ya Wanawake Duniani",
6027
+ "Siku ya Baba",
6028
  "Siku ya Mama"
6029
  ]
6030
  }
 
6450
  "Rijtjeshuis",
6451
  "Boerderij",
6452
  "Villa",
 
6453
  "Flat",
6454
  "Kasteel",
6455
  "Watertoren",
 
6462
  "Bunker",
6463
  "Woonboot",
6464
  "Begijnhof",
6465
+ "Sluis",
6466
+ "Fietsenstalling"
6467
  ],
6468
  "Instruments, Tools and Utensils": [
6469
  "Poffertjespan",
 
7102
  "Galocha",
7103
  "Chapéu"
7104
  ],
7105
+ "Buildings (interior and exterior)": [
7106
+ "Casa",
7107
+ "Mosteiro",
7108
+ "Hospital",
7109
+ "Quinta",
7110
+ "Igreja",
7111
+ "Escola",
7112
+ "Cozinha",
7113
+ "Restaurante",
7114
+ "Estação ferroviária",
7115
+ "Quarto",
7116
+ "Centro comercial",
7117
+ "Despensa",
7118
+ "Parque",
7119
+ "Castelo",
7120
+ "Estádio",
7121
+ "Museu",
7122
+ "Padaria",
7123
+ "Pastelaria",
7124
+ "Bar",
7125
+ "Posto de abastecimento"
7126
+ ],
7127
  "Instruments, Tools and Utensils": [
7128
  "Guitarra portuguesa",
7129
  "Cavaquinho",
 
9571
  },
9572
  "Venezuela": {
9573
  "Spanish": {
9574
+ "Food and Beverages": [
9575
+ "Cachapa",
9576
+ "Hallaca",
9577
+ "Cachito de Jamón",
9578
+ "Pabellón Criollo",
9579
+ "Chicha Criolla",
9580
+ "Asado Negro",
9581
+ "Pan de Jamon",
9582
+ "Papelón con Limón",
9583
+ "Empanada Venezolana",
9584
+ "Tequeño",
9585
+ "Golfeado",
9586
+ "Patacón",
9587
+ "Arepa",
9588
+ "Bollo Pelón",
9589
+ "Casabe",
9590
+ "Frescolita",
9591
+ "Mandoca",
9592
+ "Ponche Crema",
9593
+ "Malta",
9594
+ "Ensalda de Gallina",
9595
+ "Carne Mechada",
9596
+ "Chicharrón",
9597
+ "Guasacaca",
9598
+ "Licor de Cocuy",
9599
+ "Majarete",
9600
+ "Mojito",
9601
+ "Mondongo de chivo",
9602
+ "Parilla",
9603
+ "Pastelito",
9604
+ "Tizana",
9605
+ "Vuelve a la Vida",
9606
+ "Arepa andina / Arepa de trigo",
9607
+ "Sopa de Mondongo",
9608
+ "Pisca andina",
9609
+ "Sancocho",
9610
+ "Perico",
9611
+ "Reina Pepeada",
9612
+ "Dulce de lechosa",
9613
+ "Queso",
9614
+ "Ron"
9615
+ ],
9616
+ "Clothing": [
9617
+ "Alpargata",
9618
+ "Ruana",
9619
+ "Liqui Liqui",
9620
+ "Manta Guajira / Manta Wayuu",
9621
+ "Sombrero de Cogollo",
9622
+ "Guayabera",
9623
+ "Guayuco",
9624
+ "Sombrero de Pelo e' Guama",
9625
+ "Traje de Dama Antañona",
9626
+ "Blusa",
9627
+ "Collar de Semillas",
9628
+ "Falda Llanera",
9629
+ "Tocado Wayuu",
9630
+ "Capris",
9631
+ "Chancla / Chancleta",
9632
+ "Franela",
9633
+ "Gorra",
9634
+ "Zapatos de Goma",
9635
+ "Pantalón Tubito",
9636
+ "Franelilla"
9637
+ ],
9638
  "Buildings (interior and exterior)": [
9639
  "Casa / Quinta",
9640
  "Apartamento",
 
9677
  "Cuartel",
9678
  "Centro Comercial"
9679
  ],
9680
+ "Instruments, Tools and Utensils": [
9681
+ "Bandola",
9682
+ "Arpa",
9683
+ "Maracas",
9684
+ "Furruco",
9685
+ "Charrasca",
9686
+ "Cuatro",
9687
+ "Tambor",
9688
+ "Tostiarepa",
9689
+ "Pilón",
9690
+ "Budare",
9691
+ "Guarura",
9692
+ "Sebucán",
9693
+ "Anafre",
9694
+ "Hamaca",
9695
+ "Totuma / Tapara",
9696
+ "Flauta",
9697
+ "Cesta",
9698
+ "Coleto ",
9699
+ "Machete",
9700
+ "Gurrufío"
9701
+ ],
9702
  "Celebrations, Sports and Events": [
9703
  "Boda",
9704
  "Funeral",
9705
  "Bautizo",
9706
  "Año Nuevo",
9707
+ "Cumpleaños",
9708
+ "Feria de la Chinita",
9709
+ "Diablos Danzantes de Yare",
9710
+ "Fiesta de San Juan",
9711
+ "Día de la Divina Pastora",
9712
+ "Semana Santa",
9713
+ "Serie del Caribe",
9714
+ "Beisbol",
9715
+ "Día de la Independencia de Venezuela",
9716
+ "Día de la Resistencia Indígena",
9717
+ "Navidad",
9718
+ "Paradura del Niño",
9719
+ "Carnaval",
9720
+ "Carnaval de El Callao",
9721
+ "Feria Internacional de San Sebastián",
9722
+ "Día de Nuestra Señora de Coromoto",
9723
+ "Parranda de San Pedro",
9724
+ "Tambores de San Benito",
9725
+ "Día de la Virgen de la Candelaria",
9726
+ "Día de la Virgen del Valle",
9727
+ "Día de Reyes",
9728
+ "Bolas Criollas",
9729
+ "Coleo de toros",
9730
+ "Baloncesto",
9731
+ "Superliga Profesional de Baloncesto",
9732
+ "Quema de Judas",
9733
+ "Feria Internacional del Sol\n",
9734
+ "Miss Venezuela\n",
9735
+ "Miss Universo\n",
9736
+ "La Cruz de Mayo",
9737
+ "Día de la Madre",
9738
+ "Día del Padre",
9739
+ "Día del Maestro",
9740
+ "Ferias de San Felipe",
9741
+ "Día del Niño",
9742
+ "Futbol"
9743
  ]
9744
  }
9745
  },
data/guidelines/USA/English/instructions.md CHANGED
@@ -5,7 +5,7 @@
5
  - Images should NOT have empty backgrounds NOR watermarks.
6
  - The complexity of the image will contribute to the interestingness of the description.
7
  - You can blur all/selected faces before submitting your image. Once submitted, faces cannot be deblurred (you can still, however, re-upload the image if you want to).
8
- - If you don’t have personal pictures for a concept, please use public images:
9
  - [Google images](images.google.com)
10
 
11
  - When searching on images.google.com, you can click on “Tools” → “Usage rights” → “Creative Commons licenses”
 
5
  - Images should NOT have empty backgrounds NOR watermarks.
6
  - The complexity of the image will contribute to the interestingness of the description.
7
  - You can blur all/selected faces before submitting your image. Once submitted, faces cannot be deblurred (you can still, however, re-upload the image if you want to).
8
+ - If you don’t have personal pictures for a concept, please use public images by providing their URL (instead of downloading them):
9
  - [Google images](images.google.com)
10
 
11
  - When searching on images.google.com, you can click on “Tools” → “Usage rights” → “Creative Commons licenses”
data/guidelines/USA/English/task.md CHANGED
@@ -1,8 +1,6 @@
1
- # Wonders: Multicultural Images and Captions for Inclusive AI
2
 
3
- We want to collect images and annotations that are relevant for your culture.
4
  - **Main concept:** Choose the main category and concept for which you want to share data. You can type a new concept if it’s culturally relevant and missing from our list.
5
- - **Image:** An image where the *main concept is clearly visible*. The image needs to (1) show the concept *in typical contexts* where it can be found in your country, and (2) *include other* objects/people whenever possible. *Pictures taken by yourself* are preferred. Otherwise, please add a URL for publicly-licensed images from the Web (e.g., from pexels.com or freepik.com). For more details, see “Instructions” below.
6
  - **Description:** A long description (around 40 words) that provides extensive and detailed visual information. Descriptions must be *objective*: focus on how you would describe the image to someone who can’t see it, without adding your own opinions/speculations. The text needs to *include the main concept* and describes the content of the image in detail by including:
7
  - **Who?** The visual *appearance* and observable *emotions* (e.g., “is smiling”) of persons and animals.
8
  - **What?** The *actions* performed in the image.
 
 
1
 
 
2
  - **Main concept:** Choose the main category and concept for which you want to share data. You can type a new concept if it’s culturally relevant and missing from our list.
3
+ - **Image:** An image where the *main concept is clearly visible*. The image needs to (1) show the concept *in typical contexts* where it can be found in your country, and (2) *include other* objects/people whenever possible. *Pictures taken by yourself* are preferred. Otherwise, do not download images from the Web. Instead, add the image URL below for publicly-licensed images (e.g., from pexels.com or freepik.com). For more details, see “Instructions” below.
4
  - **Description:** A long description (around 40 words) that provides extensive and detailed visual information. Descriptions must be *objective*: focus on how you would describe the image to someone who can’t see it, without adding your own opinions/speculations. The text needs to *include the main concept* and describes the content of the image in detail by including:
5
  - **Who?** The visual *appearance* and observable *emotions* (e.g., “is smiling”) of persons and animals.
6
  - **What?** The *actions* performed in the image.
data/metadata.json CHANGED
@@ -8,8 +8,8 @@
8
  "Password": "Password (Optional)",
9
  "Concept": "Main Concept",
10
  "Image": "Image",
11
- "Image_URL": "Image URL (optional, if no image is loaded)",
12
- "Description": "Description",
13
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
14
  "Clear_btn": "Clear",
15
  "Submit_btn": "Submit",
@@ -34,8 +34,8 @@
34
  "Password": "Password (Optional)",
35
  "Concept": "Main Concept",
36
  "Image": "Image",
37
- "Image_URL": "Image URL (optional, if no image is loaded)",
38
- "Description": "Description",
39
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
40
  "Clear_btn": "Clear",
41
  "Submit_btn": "Submit",
@@ -61,7 +61,7 @@
61
  "Concept": "Main Concept",
62
  "Image": "Image",
63
  "Image_URL": "Image URL (optional, if no image is loaded)",
64
- "Description": "Description",
65
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
66
  "Clear_btn": "Clear",
67
  "Submit_btn": "Submit",
@@ -87,7 +87,7 @@
87
  "Concept": "Main Concept",
88
  "Image": "Image",
89
  "Image_URL": "Image URL (optional, if no image is loaded)",
90
- "Description": "Description",
91
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
92
  "Clear_btn": "Clear",
93
  "Submit_btn": "Submit",
@@ -113,7 +113,7 @@
113
  "Concept": "Main Concept",
114
  "Image": "Image",
115
  "Image_URL": "Image URL (optional, if no image is loaded)",
116
- "Description": "Description",
117
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
118
  "Clear_btn": "Clear",
119
  "Submit_btn": "Submit",
@@ -139,7 +139,7 @@
139
  "Concept": "Main Concept",
140
  "Image": "Image",
141
  "Image_URL": "Image URL (optional, if no image is loaded)",
142
- "Description": "Description",
143
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
144
  "Clear_btn": "Clear",
145
  "Submit_btn": "Submit",
@@ -165,7 +165,7 @@
165
  "Concept": "Main Concept",
166
  "Image": "Image",
167
  "Image_URL": "Image URL (optional, if no image is loaded)",
168
- "Description": "Description",
169
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
170
  "Clear_btn": "Clear",
171
  "Submit_btn": "Submit",
@@ -191,7 +191,7 @@
191
  "Concept": "Main Concept",
192
  "Image": "Image",
193
  "Image_URL": "Image URL (optional, if no image is loaded)",
194
- "Description": "Description",
195
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
196
  "Clear_btn": "Clear",
197
  "Submit_btn": "Submit",
@@ -217,7 +217,7 @@
217
  "Concept": "Main Concept",
218
  "Image": "Image",
219
  "Image_URL": "Image URL (optional, if no image is loaded)",
220
- "Description": "Description",
221
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
222
  "Clear_btn": "Clear",
223
  "Submit_btn": "Submit",
@@ -243,7 +243,7 @@
243
  "Concept": "Main Concept",
244
  "Image": "Image",
245
  "Image_URL": "Image URL (optional, if no image is loaded)",
246
- "Description": "Description",
247
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
248
  "Clear_btn": "Clear",
249
  "Submit_btn": "Submit",
@@ -269,7 +269,7 @@
269
  "Concept": "Main Concept",
270
  "Image": "Image",
271
  "Image_URL": "Image URL (optional, if no image is loaded)",
272
- "Description": "Description",
273
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
274
  "Clear_btn": "Clear",
275
  "Submit_btn": "Submit",
@@ -295,7 +295,7 @@
295
  "Concept": "Main Concept",
296
  "Image": "Image",
297
  "Image_URL": "Image URL (optional, if no image is loaded)",
298
- "Description": "Description",
299
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
300
  "Clear_btn": "Clear",
301
  "Submit_btn": "Submit",
@@ -321,7 +321,7 @@
321
  "Concept": "Main Concept",
322
  "Image": "Image",
323
  "Image_URL": "Image URL (optional, if no image is loaded)",
324
- "Description": "Description",
325
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
326
  "Clear_btn": "Clear",
327
  "Submit_btn": "Submit",
@@ -345,7 +345,7 @@
345
  "Concept": "Main Concept",
346
  "Image": "Image",
347
  "Image_URL": "Image URL (optional, if no image is loaded)",
348
- "Description": "Description",
349
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
350
  "Clear_btn": "Clear",
351
  "Submit_btn": "Submit",
@@ -371,7 +371,7 @@
371
  "Concept": "Main Concept",
372
  "Image": "Image",
373
  "Image_URL": "Image URL (optional, if no image is loaded)",
374
- "Description": "Description",
375
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
376
  "Clear_btn": "Clear",
377
  "Submit_btn": "Submit",
@@ -397,7 +397,7 @@
397
  "Concept": "Main Concept",
398
  "Image": "Image",
399
  "Image_URL": "Image URL (optional, if no image is loaded)",
400
- "Description": "Description",
401
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
402
  "Clear_btn": "Clear",
403
  "Submit_btn": "Submit",
@@ -423,7 +423,7 @@
423
  "Concept": "Main Concept",
424
  "Image": "Image",
425
  "Image_URL": "Image URL (optional, if no image is loaded)",
426
- "Description": "Description",
427
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
428
  "Clear_btn": "Clear",
429
  "Submit_btn": "Submit",
@@ -449,7 +449,7 @@
449
  "Concept": "Main Concept",
450
  "Image": "Image",
451
  "Image_URL": "Image URL (optional, if no image is loaded)",
452
- "Description": "Description",
453
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
454
  "Clear_btn": "Clear",
455
  "Submit_btn": "Submit",
@@ -475,7 +475,7 @@
475
  "Concept": "Main Concept",
476
  "Image": "Image",
477
  "Image_URL": "Image URL (optional, if no image is loaded)",
478
- "Description": "Description",
479
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
480
  "Clear_btn": "Clear",
481
  "Submit_btn": "Submit",
@@ -499,7 +499,7 @@
499
  "Concept": "Main Concept",
500
  "Image": "Image",
501
  "Image_URL": "Image URL (optional, if no image is loaded)",
502
- "Description": "Description",
503
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
504
  "Clear_btn": "Clear",
505
  "Submit_btn": "Submit",
@@ -525,7 +525,7 @@
525
  "Concept": "Main Concept",
526
  "Image": "Image",
527
  "Image_URL": "Image URL (optional, if no image is loaded)",
528
- "Description": "Description",
529
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
530
  "Clear_btn": "Clear",
531
  "Submit_btn": "Submit",
@@ -551,7 +551,7 @@
551
  "Concept": "Main Concept",
552
  "Image": "Image",
553
  "Image_URL": "Image URL (optional, if no image is loaded)",
554
- "Description": "Description",
555
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
556
  "Clear_btn": "Clear",
557
  "Submit_btn": "Submit",
@@ -575,7 +575,7 @@
575
  "Concept": "Main Concept",
576
  "Image": "Image",
577
  "Image_URL": "Image URL (optional, if no image is loaded)",
578
- "Description": "Description",
579
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
580
  "Clear_btn": "Clear",
581
  "Submit_btn": "Submit",
@@ -599,7 +599,7 @@
599
  "Concept": "Main Concept",
600
  "Image": "Image",
601
  "Image_URL": "Image URL (optional, if no image is loaded)",
602
- "Description": "Description",
603
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
604
  "Clear_btn": "Clear",
605
  "Submit_btn": "Submit",
@@ -625,7 +625,7 @@
625
  "Concept": "Main Concept",
626
  "Image": "Image",
627
  "Image_URL": "Image URL (optional, if no image is loaded)",
628
- "Description": "Description",
629
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
630
  "Clear_btn": "Clear",
631
  "Submit_btn": "Submit",
@@ -651,7 +651,7 @@
651
  "Concept": "Main Concept",
652
  "Image": "Image",
653
  "Image_URL": "Image URL (optional, if no image is loaded)",
654
- "Description": "Description",
655
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
656
  "Clear_btn": "Clear",
657
  "Submit_btn": "Submit",
@@ -701,7 +701,7 @@
701
  "Concept": "Main Concept",
702
  "Image": "Image",
703
  "Image_URL": "Image URL (optional, if no image is loaded)",
704
- "Description": "Description",
705
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
706
  "Clear_btn": "Clear",
707
  "Submit_btn": "Submit",
@@ -725,7 +725,7 @@
725
  "Concept": "Main Concept",
726
  "Image": "Image",
727
  "Image_URL": "Image URL (optional, if no image is loaded)",
728
- "Description": "Description",
729
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
730
  "Clear_btn": "Clear",
731
  "Submit_btn": "Submit",
@@ -749,7 +749,7 @@
749
  "Concept": "Main Concept",
750
  "Image": "Image",
751
  "Image_URL": "Image URL (optional, if no image is loaded)",
752
- "Description": "Description",
753
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
754
  "Clear_btn": "Clear",
755
  "Submit_btn": "Submit",
@@ -773,7 +773,7 @@
773
  "Concept": "Main Concept",
774
  "Image": "Image",
775
  "Image_URL": "Image URL (optional, if no image is loaded)",
776
- "Description": "Description",
777
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
778
  "Clear_btn": "Clear",
779
  "Submit_btn": "Submit",
@@ -797,7 +797,7 @@
797
  "Concept": "Main Concept",
798
  "Image": "Image",
799
  "Image_URL": "Image URL (optional, if no image is loaded)",
800
- "Description": "Description",
801
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
802
  "Clear_btn": "Clear",
803
  "Submit_btn": "Submit",
@@ -821,7 +821,7 @@
821
  "Concept": "Main Concept",
822
  "Image": "Image",
823
  "Image_URL": "Image URL (optional, if no image is loaded)",
824
- "Description": "Description",
825
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
826
  "Clear_btn": "Clear",
827
  "Submit_btn": "Submit",
@@ -845,7 +845,7 @@
845
  "Concept": "Main Concept",
846
  "Image": "Image",
847
  "Image_URL": "Image URL (optional, if no image is loaded)",
848
- "Description": "Description",
849
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
850
  "Clear_btn": "Clear",
851
  "Submit_btn": "Submit",
@@ -871,7 +871,7 @@
871
  "Concept": "Main Concept",
872
  "Image": "Image",
873
  "Image_URL": "Image URL (optional, if no image is loaded)",
874
- "Description": "Description",
875
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
876
  "Clear_btn": "Clear",
877
  "Submit_btn": "Submit",
@@ -895,7 +895,7 @@
895
  "Concept": "Main Concept",
896
  "Image": "Image",
897
  "Image_URL": "Image URL (optional, if no image is loaded)",
898
- "Description": "Description",
899
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
900
  "Clear_btn": "Clear",
901
  "Submit_btn": "Submit",
@@ -921,7 +921,7 @@
921
  "Concept": "Main Concept",
922
  "Image": "Image",
923
  "Image_URL": "Image URL (optional, if no image is loaded)",
924
- "Description": "Description",
925
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
926
  "Clear_btn": "Clear",
927
  "Submit_btn": "Submit",
@@ -947,7 +947,7 @@
947
  "Concept": "Main Concept",
948
  "Image": "Image",
949
  "Image_URL": "Image URL (optional, if no image is loaded)",
950
- "Description": "Description",
951
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
952
  "Clear_btn": "Clear",
953
  "Submit_btn": "Submit",
@@ -973,7 +973,7 @@
973
  "Concept": "Main Concept",
974
  "Image": "Image",
975
  "Image_URL": "Image URL (optional, if no image is loaded)",
976
- "Description": "Description",
977
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
978
  "Clear_btn": "Clear",
979
  "Submit_btn": "Submit",
@@ -999,7 +999,7 @@
999
  "Concept": "Main Concept",
1000
  "Image": "Image",
1001
  "Image_URL": "Image URL (optional, if no image is loaded)",
1002
- "Description": "Description",
1003
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1004
  "Clear_btn": "Clear",
1005
  "Submit_btn": "Submit",
@@ -1025,7 +1025,7 @@
1025
  "Concept": "Main Concept",
1026
  "Image": "Image",
1027
  "Image_URL": "Image URL (optional, if no image is loaded)",
1028
- "Description": "Description",
1029
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1030
  "Clear_btn": "Clear",
1031
  "Submit_btn": "Submit",
@@ -1051,7 +1051,7 @@
1051
  "Concept": "Main Concept",
1052
  "Image": "Image",
1053
  "Image_URL": "Image URL (optional, if no image is loaded)",
1054
- "Description": "Description",
1055
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1056
  "Clear_btn": "Clear",
1057
  "Submit_btn": "Submit",
@@ -1077,7 +1077,7 @@
1077
  "Concept": "Main Concept",
1078
  "Image": "Image",
1079
  "Image_URL": "Image URL (optional, if no image is loaded)",
1080
- "Description": "Description",
1081
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1082
  "Clear_btn": "Clear",
1083
  "Submit_btn": "Submit",
@@ -1101,7 +1101,7 @@
1101
  "Concept": "Main Concept",
1102
  "Image": "Image",
1103
  "Image_URL": "Image URL (optional, if no image is loaded)",
1104
- "Description": "Description",
1105
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1106
  "Clear_btn": "Clear",
1107
  "Submit_btn": "Submit",
@@ -1127,7 +1127,7 @@
1127
  "Concept": "Main Concept",
1128
  "Image": "Image",
1129
  "Image_URL": "Image URL (optional, if no image is loaded)",
1130
- "Description": "Description",
1131
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1132
  "Clear_btn": "Clear",
1133
  "Submit_btn": "Submit",
@@ -1153,7 +1153,7 @@
1153
  "Concept": "Main Concept",
1154
  "Image": "Image",
1155
  "Image_URL": "Image URL (optional, if no image is loaded)",
1156
- "Description": "Description",
1157
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1158
  "Clear_btn": "Clear",
1159
  "Submit_btn": "Submit",
@@ -1179,7 +1179,7 @@
1179
  "Concept": "Main Concept",
1180
  "Image": "Image",
1181
  "Image_URL": "Image URL (optional, if no image is loaded)",
1182
- "Description": "Description",
1183
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1184
  "Clear_btn": "Clear",
1185
  "Submit_btn": "Submit",
@@ -1205,7 +1205,7 @@
1205
  "Concept": "Main Concept",
1206
  "Image": "Image",
1207
  "Image_URL": "Image URL (optional, if no image is loaded)",
1208
- "Description": "Description",
1209
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1210
  "Clear_btn": "Clear",
1211
  "Submit_btn": "Submit",
@@ -1231,7 +1231,7 @@
1231
  "Concept": "Main Concept",
1232
  "Image": "Image",
1233
  "Image_URL": "Image URL (optional, if no image is loaded)",
1234
- "Description": "Description",
1235
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1236
  "Clear_btn": "Clear",
1237
  "Submit_btn": "Submit",
@@ -1257,7 +1257,7 @@
1257
  "Concept": "Main Concept",
1258
  "Image": "Image",
1259
  "Image_URL": "Image URL (optional, if no image is loaded)",
1260
- "Description": "Description",
1261
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1262
  "Clear_btn": "Clear",
1263
  "Submit_btn": "Submit",
@@ -1283,7 +1283,7 @@
1283
  "Concept": "Main Concept",
1284
  "Image": "Image",
1285
  "Image_URL": "Image URL (optional, if no image is loaded)",
1286
- "Description": "Description",
1287
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1288
  "Clear_btn": "Clear",
1289
  "Submit_btn": "Submit",
@@ -1309,7 +1309,7 @@
1309
  "Concept": "Main Concept",
1310
  "Image": "Image",
1311
  "Image_URL": "Image URL (optional, if no image is loaded)",
1312
- "Description": "Description",
1313
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1314
  "Clear_btn": "Clear",
1315
  "Submit_btn": "Submit",
@@ -1335,7 +1335,7 @@
1335
  "Concept": "Main Concept",
1336
  "Image": "Image",
1337
  "Image_URL": "Image URL (optional, if no image is loaded)",
1338
- "Description": "Description",
1339
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1340
  "Clear_btn": "Clear",
1341
  "Submit_btn": "Submit",
@@ -1361,7 +1361,7 @@
1361
  "Concept": "Main Concept",
1362
  "Image": "Image",
1363
  "Image_URL": "Image URL (optional, if no image is loaded)",
1364
- "Description": "Description",
1365
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1366
  "Clear_btn": "Clear",
1367
  "Submit_btn": "Submit",
@@ -1387,7 +1387,7 @@
1387
  "Concept": "Main Concept",
1388
  "Image": "Image",
1389
  "Image_URL": "Image URL (optional, if no image is loaded)",
1390
- "Description": "Description",
1391
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1392
  "Clear_btn": "Clear",
1393
  "Submit_btn": "Submit",
@@ -1413,7 +1413,7 @@
1413
  "Concept": "Main Concept",
1414
  "Image": "Image",
1415
  "Image_URL": "Image URL (optional, if no image is loaded)",
1416
- "Description": "Description",
1417
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1418
  "Clear_btn": "Clear",
1419
  "Submit_btn": "Submit",
@@ -1439,7 +1439,7 @@
1439
  "Concept": "Main Concept",
1440
  "Image": "Image",
1441
  "Image_URL": "Image URL (optional, if no image is loaded)",
1442
- "Description": "Description",
1443
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1444
  "Clear_btn": "Clear",
1445
  "Submit_btn": "Submit",
@@ -1465,7 +1465,7 @@
1465
  "Concept": "Main Concept",
1466
  "Image": "Image",
1467
  "Image_URL": "Image URL (optional, if no image is loaded)",
1468
- "Description": "Description",
1469
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1470
  "Clear_btn": "Clear",
1471
  "Submit_btn": "Submit",
@@ -1491,7 +1491,7 @@
1491
  "Concept": "Main Concept",
1492
  "Image": "Image",
1493
  "Image_URL": "Image URL (optional, if no image is loaded)",
1494
- "Description": "Description",
1495
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1496
  "Clear_btn": "Clear",
1497
  "Submit_btn": "Submit",
@@ -1517,7 +1517,7 @@
1517
  "Concept": "Main Concept",
1518
  "Image": "Image",
1519
  "Image_URL": "Image URL (optional, if no image is loaded)",
1520
- "Description": "Description",
1521
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1522
  "Clear_btn": "Clear",
1523
  "Submit_btn": "Submit",
@@ -1543,7 +1543,7 @@
1543
  "Concept": "Main Concept",
1544
  "Image": "Image",
1545
  "Image_URL": "Image URL (optional, if no image is loaded)",
1546
- "Description": "Description",
1547
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1548
  "Clear_btn": "Clear",
1549
  "Submit_btn": "Submit",
@@ -1569,7 +1569,7 @@
1569
  "Concept": "Main Concept",
1570
  "Image": "Image",
1571
  "Image_URL": "Image URL (optional, if no image is loaded)",
1572
- "Description": "Description",
1573
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1574
  "Clear_btn": "Clear",
1575
  "Submit_btn": "Submit",
@@ -1595,7 +1595,7 @@
1595
  "Concept": "Main Concept",
1596
  "Image": "Image",
1597
  "Image_URL": "Image URL (optional, if no image is loaded)",
1598
- "Description": "Description",
1599
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1600
  "Clear_btn": "Clear",
1601
  "Submit_btn": "Submit",
@@ -1621,7 +1621,7 @@
1621
  "Concept": "Main Concept",
1622
  "Image": "Image",
1623
  "Image_URL": "Image URL (optional, if no image is loaded)",
1624
- "Description": "Description",
1625
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1626
  "Clear_btn": "Clear",
1627
  "Submit_btn": "Submit",
@@ -1647,7 +1647,7 @@
1647
  "Concept": "Main Concept",
1648
  "Image": "Image",
1649
  "Image_URL": "Image URL (optional, if no image is loaded)",
1650
- "Description": "Description",
1651
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1652
  "Clear_btn": "Clear",
1653
  "Submit_btn": "Submit",
@@ -1671,7 +1671,7 @@
1671
  "Concept": "Main Concept",
1672
  "Image": "Image",
1673
  "Image_URL": "Image URL (optional, if no image is loaded)",
1674
- "Description": "Description",
1675
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1676
  "Clear_btn": "Clear",
1677
  "Submit_btn": "Submit",
 
8
  "Password": "Password (Optional)",
9
  "Concept": "Main Concept",
10
  "Image": "Image",
11
+ "Image_URL": "Image URL (optional, if no image is uploaded)",
12
+ "Description": "Description in English",
13
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
14
  "Clear_btn": "Clear",
15
  "Submit_btn": "Submit",
 
34
  "Password": "Password (Optional)",
35
  "Concept": "Main Concept",
36
  "Image": "Image",
37
+ "Image_URL": "Image URL (optional, if no image is uploaded)",
38
+ "Description": "Description in Italian",
39
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
40
  "Clear_btn": "Clear",
41
  "Submit_btn": "Submit",
 
61
  "Concept": "Main Concept",
62
  "Image": "Image",
63
  "Image_URL": "Image URL (optional, if no image is loaded)",
64
+ "Description": "Description in French",
65
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
66
  "Clear_btn": "Clear",
67
  "Submit_btn": "Submit",
 
87
  "Concept": "Main Concept",
88
  "Image": "Image",
89
  "Image_URL": "Image URL (optional, if no image is loaded)",
90
+ "Description": "Description in Spanish",
91
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
92
  "Clear_btn": "Clear",
93
  "Submit_btn": "Submit",
 
113
  "Concept": "Main Concept",
114
  "Image": "Image",
115
  "Image_URL": "Image URL (optional, if no image is loaded)",
116
+ "Description": "Description in Arabic",
117
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
118
  "Clear_btn": "Clear",
119
  "Submit_btn": "Submit",
 
139
  "Concept": "Main Concept",
140
  "Image": "Image",
141
  "Image_URL": "Image URL (optional, if no image is loaded)",
142
+ "Description": "Description in Spanish",
143
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
144
  "Clear_btn": "Clear",
145
  "Submit_btn": "Submit",
 
165
  "Concept": "Main Concept",
166
  "Image": "Image",
167
  "Image_URL": "Image URL (optional, if no image is loaded)",
168
+ "Description": "Description in English",
169
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
170
  "Clear_btn": "Clear",
171
  "Submit_btn": "Submit",
 
191
  "Concept": "Main Concept",
192
  "Image": "Image",
193
  "Image_URL": "Image URL (optional, if no image is loaded)",
194
+ "Description": "Description in Bengali",
195
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
196
  "Clear_btn": "Clear",
197
  "Submit_btn": "Submit",
 
217
  "Concept": "Main Concept",
218
  "Image": "Image",
219
  "Image_URL": "Image URL (optional, if no image is loaded)",
220
+ "Description": "Description in French",
221
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
222
  "Clear_btn": "Clear",
223
  "Submit_btn": "Submit",
 
243
  "Concept": "Main Concept",
244
  "Image": "Image",
245
  "Image_URL": "Image URL (optional, if no image is loaded)",
246
+ "Description": "Description in Portuguese",
247
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
248
  "Clear_btn": "Clear",
249
  "Submit_btn": "Submit",
 
269
  "Concept": "Main Concept",
270
  "Image": "Image",
271
  "Image_URL": "Image URL (optional, if no image is loaded)",
272
+ "Description": "Description in Bulgarian",
273
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
274
  "Clear_btn": "Clear",
275
  "Submit_btn": "Submit",
 
295
  "Concept": "Main Concept",
296
  "Image": "Image",
297
  "Image_URL": "Image URL (optional, if no image is loaded)",
298
+ "Description": "Description in Spanish",
299
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
300
  "Clear_btn": "Clear",
301
  "Submit_btn": "Submit",
 
321
  "Concept": "Main Concept",
322
  "Image": "Image",
323
  "Image_URL": "Image URL (optional, if no image is loaded)",
324
+ "Description": "Description in Mandarin Chinese",
325
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
326
  "Clear_btn": "Clear",
327
  "Submit_btn": "Submit",
 
345
  "Concept": "Main Concept",
346
  "Image": "Image",
347
  "Image_URL": "Image URL (optional, if no image is loaded)",
348
+ "Description": "Description in Yue Chinese",
349
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
350
  "Clear_btn": "Clear",
351
  "Submit_btn": "Submit",
 
371
  "Concept": "Main Concept",
372
  "Image": "Image",
373
  "Image_URL": "Image URL (optional, if no image is loaded)",
374
+ "Description": "Description in Czech",
375
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
376
  "Clear_btn": "Clear",
377
  "Submit_btn": "Submit",
 
397
  "Concept": "Main Concept",
398
  "Image": "Image",
399
  "Image_URL": "Image URL (optional, if no image is loaded)",
400
+ "Description": "Description in Danish",
401
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
402
  "Clear_btn": "Clear",
403
  "Submit_btn": "Submit",
 
423
  "Concept": "Main Concept",
424
  "Image": "Image",
425
  "Image_URL": "Image URL (optional, if no image is loaded)",
426
+ "Description": "Description in Spanish",
427
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
428
  "Clear_btn": "Clear",
429
  "Submit_btn": "Submit",
 
449
  "Concept": "Main Concept",
450
  "Image": "Image",
451
  "Image_URL": "Image URL (optional, if no image is loaded)",
452
+ "Description": "Description in Egyptian Arabic",
453
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
454
  "Clear_btn": "Clear",
455
  "Submit_btn": "Submit",
 
475
  "Concept": "Main Concept",
476
  "Image": "Image",
477
  "Image_URL": "Image URL (optional, if no image is loaded)",
478
+ "Description": "Description in Oromo",
479
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
480
  "Clear_btn": "Clear",
481
  "Submit_btn": "Submit",
 
499
  "Concept": "Main Concept",
500
  "Image": "Image",
501
  "Image_URL": "Image URL (optional, if no image is loaded)",
502
+ "Description": "Description in Amharic",
503
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
504
  "Clear_btn": "Clear",
505
  "Submit_btn": "Submit",
 
525
  "Concept": "Main Concept",
526
  "Image": "Image",
527
  "Image_URL": "Image URL (optional, if no image is loaded)",
528
+ "Description": "Description in German",
529
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
530
  "Clear_btn": "Clear",
531
  "Submit_btn": "Submit",
 
551
  "Concept": "Main Concept",
552
  "Image": "Image",
553
  "Image_URL": "Image URL (optional, if no image is loaded)",
554
+ "Description": "Description in Twi",
555
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
556
  "Clear_btn": "Clear",
557
  "Submit_btn": "Submit",
 
575
  "Concept": "Main Concept",
576
  "Image": "Image",
577
  "Image_URL": "Image URL (optional, if no image is loaded)",
578
+ "Description": "Description in Fante",
579
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
580
  "Clear_btn": "Clear",
581
  "Submit_btn": "Submit",
 
599
  "Concept": "Main Concept",
600
  "Image": "Image",
601
  "Image_URL": "Image URL (optional, if no image is loaded)",
602
+ "Description": "Description in GA",
603
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
604
  "Clear_btn": "Clear",
605
  "Submit_btn": "Submit",
 
625
  "Concept": "Main Concept",
626
  "Image": "Image",
627
  "Image_URL": "Image URL (optional, if no image is loaded)",
628
+ "Description": "Description in Greek",
629
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
630
  "Clear_btn": "Clear",
631
  "Submit_btn": "Submit",
 
651
  "Concept": "Main Concept",
652
  "Image": "Image",
653
  "Image_URL": "Image URL (optional, if no image is loaded)",
654
+ "Description": "Description in Hungarian",
655
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
656
  "Clear_btn": "Clear",
657
  "Submit_btn": "Submit",
 
701
  "Concept": "Main Concept",
702
  "Image": "Image",
703
  "Image_URL": "Image URL (optional, if no image is loaded)",
704
+ "Description": "Description in Kannada",
705
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
706
  "Clear_btn": "Clear",
707
  "Submit_btn": "Submit",
 
725
  "Concept": "Main Concept",
726
  "Image": "Image",
727
  "Image_URL": "Image URL (optional, if no image is loaded)",
728
+ "Description": "Description in Telugu",
729
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
730
  "Clear_btn": "Clear",
731
  "Submit_btn": "Submit",
 
749
  "Concept": "Main Concept",
750
  "Image": "Image",
751
  "Image_URL": "Image URL (optional, if no image is loaded)",
752
+ "Description": "Description in Tamil",
753
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
754
  "Clear_btn": "Clear",
755
  "Submit_btn": "Submit",
 
773
  "Concept": "Main Concept",
774
  "Image": "Image",
775
  "Image_URL": "Image URL (optional, if no image is loaded)",
776
+ "Description": "Description in Hindi",
777
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
778
  "Clear_btn": "Clear",
779
  "Submit_btn": "Submit",
 
797
  "Concept": "Main Concept",
798
  "Image": "Image",
799
  "Image_URL": "Image URL (optional, if no image is loaded)",
800
+ "Description": "Description in Bengali",
801
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
802
  "Clear_btn": "Clear",
803
  "Submit_btn": "Submit",
 
821
  "Concept": "Main Concept",
822
  "Image": "Image",
823
  "Image_URL": "Image URL (optional, if no image is loaded)",
824
+ "Description": "Description in Marathi",
825
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
826
  "Clear_btn": "Clear",
827
  "Submit_btn": "Submit",
 
845
  "Concept": "Main Concept",
846
  "Image": "Image",
847
  "Image_URL": "Image URL (optional, if no image is loaded)",
848
+ "Description": "Description in Urdu",
849
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
850
  "Clear_btn": "Clear",
851
  "Submit_btn": "Submit",
 
871
  "Concept": "Main Concept",
872
  "Image": "Image",
873
  "Image_URL": "Image URL (optional, if no image is loaded)",
874
+ "Description": "Description in Javanese",
875
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
876
  "Clear_btn": "Clear",
877
  "Submit_btn": "Submit",
 
895
  "Concept": "Main Concept",
896
  "Image": "Image",
897
  "Image_URL": "Image URL (optional, if no image is loaded)",
898
+ "Description": "Description in Indonesian",
899
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
900
  "Clear_btn": "Clear",
901
  "Submit_btn": "Submit",
 
921
  "Concept": "Main Concept",
922
  "Image": "Image",
923
  "Image_URL": "Image URL (optional, if no image is loaded)",
924
+ "Description": "Description in Hebrew",
925
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
926
  "Clear_btn": "Clear",
927
  "Submit_btn": "Submit",
 
947
  "Concept": "Main Concept",
948
  "Image": "Image",
949
  "Image_URL": "Image URL (optional, if no image is loaded)",
950
+ "Description": "Description in Japanese",
951
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
952
  "Clear_btn": "Clear",
953
  "Submit_btn": "Submit",
 
973
  "Concept": "Main Concept",
974
  "Image": "Image",
975
  "Image_URL": "Image URL (optional, if no image is loaded)",
976
+ "Description": "Description in Jordanian",
977
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
978
  "Clear_btn": "Clear",
979
  "Submit_btn": "Submit",
 
999
  "Concept": "Main Concept",
1000
  "Image": "Image",
1001
  "Image_URL": "Image URL (optional, if no image is loaded)",
1002
+ "Description": "Description in Spanish",
1003
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1004
  "Clear_btn": "Clear",
1005
  "Submit_btn": "Submit",
 
1025
  "Concept": "Main Concept",
1026
  "Image": "Image",
1027
  "Image_URL": "Image URL (optional, if no image is loaded)",
1028
+ "Description": "Description in Moroccan Arabic",
1029
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1030
  "Clear_btn": "Clear",
1031
  "Submit_btn": "Submit",
 
1051
  "Concept": "Main Concept",
1052
  "Image": "Image",
1053
  "Image_URL": "Image URL (optional, if no image is loaded)",
1054
+ "Description": "Description in Dutch",
1055
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1056
  "Clear_btn": "Clear",
1057
  "Submit_btn": "Submit",
 
1077
  "Concept": "Main Concept",
1078
  "Image": "Image",
1079
  "Image_URL": "Image URL (optional, if no image is loaded)",
1080
+ "Description": "Description in Yoruba",
1081
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1082
  "Clear_btn": "Clear",
1083
  "Submit_btn": "Submit",
 
1101
  "Concept": "Main Concept",
1102
  "Image": "Image",
1103
  "Image_URL": "Image URL (optional, if no image is loaded)",
1104
+ "Description": "Description in Hausa",
1105
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1106
  "Clear_btn": "Clear",
1107
  "Submit_btn": "Submit",
 
1127
  "Concept": "Main Concept",
1128
  "Image": "Image",
1129
  "Image_URL": "Image URL (optional, if no image is loaded)",
1130
+ "Description": "Description in Tagalog",
1131
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1132
  "Clear_btn": "Clear",
1133
  "Submit_btn": "Submit",
 
1153
  "Concept": "Main Concept",
1154
  "Image": "Image",
1155
  "Image_URL": "Image URL (optional, if no image is loaded)",
1156
+ "Description": "Description in Polish",
1157
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1158
  "Clear_btn": "Clear",
1159
  "Submit_btn": "Submit",
 
1179
  "Concept": "Main Concept",
1180
  "Image": "Image",
1181
  "Image_URL": "Image URL (optional, if no image is loaded)",
1182
+ "Description": "Description in Portuguese",
1183
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1184
  "Clear_btn": "Clear",
1185
  "Submit_btn": "Submit",
 
1205
  "Concept": "Main Concept",
1206
  "Image": "Image",
1207
  "Image_URL": "Image URL (optional, if no image is loaded)",
1208
+ "Description": "Description in Romanian",
1209
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1210
  "Clear_btn": "Clear",
1211
  "Submit_btn": "Submit",
 
1231
  "Concept": "Main Concept",
1232
  "Image": "Image",
1233
  "Image_URL": "Image URL (optional, if no image is loaded)",
1234
+ "Description": "Description in Russian",
1235
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1236
  "Clear_btn": "Clear",
1237
  "Submit_btn": "Submit",
 
1257
  "Concept": "Main Concept",
1258
  "Image": "Image",
1259
  "Image_URL": "Image URL (optional, if no image is loaded)",
1260
+ "Description": "Description in Kinyarwanda",
1261
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1262
  "Clear_btn": "Clear",
1263
  "Submit_btn": "Submit",
 
1283
  "Concept": "Main Concept",
1284
  "Image": "Image",
1285
  "Image_URL": "Image URL (optional, if no image is loaded)",
1286
+ "Description": "Description in Mandarin Chinese",
1287
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1288
  "Clear_btn": "Clear",
1289
  "Submit_btn": "Submit",
 
1309
  "Concept": "Main Concept",
1310
  "Image": "Image",
1311
  "Image_URL": "Image URL (optional, if no image is loaded)",
1312
+ "Description": "Description in Korean",
1313
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1314
  "Clear_btn": "Clear",
1315
  "Submit_btn": "Submit",
 
1335
  "Concept": "Main Concept",
1336
  "Image": "Image",
1337
  "Image_URL": "Image URL (optional, if no image is loaded)",
1338
+ "Description": "Description in Spanish",
1339
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1340
  "Clear_btn": "Clear",
1341
  "Submit_btn": "Submit",
 
1361
  "Concept": "Main Concept",
1362
  "Image": "Image",
1363
  "Image_URL": "Image URL (optional, if no image is loaded)",
1364
+ "Description": "Description in German",
1365
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1366
  "Clear_btn": "Clear",
1367
  "Submit_btn": "Submit",
 
1387
  "Concept": "Main Concept",
1388
  "Image": "Image",
1389
  "Image_URL": "Image URL (optional, if no image is loaded)",
1390
+ "Description": "Description in Swahili",
1391
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1392
  "Clear_btn": "Clear",
1393
  "Submit_btn": "Submit",
 
1413
  "Concept": "Main Concept",
1414
  "Image": "Image",
1415
  "Image_URL": "Image URL (optional, if no image is loaded)",
1416
+ "Description": "Description in Turkish",
1417
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1418
  "Clear_btn": "Clear",
1419
  "Submit_btn": "Submit",
 
1439
  "Concept": "Main Concept",
1440
  "Image": "Image",
1441
  "Image_URL": "Image URL (optional, if no image is loaded)",
1442
+ "Description": "Description in Ukranian",
1443
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1444
  "Clear_btn": "Clear",
1445
  "Submit_btn": "Submit",
 
1465
  "Concept": "Main Concept",
1466
  "Image": "Image",
1467
  "Image_URL": "Image URL (optional, if no image is loaded)",
1468
+ "Description": "Description in Uzbek",
1469
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1470
  "Clear_btn": "Clear",
1471
  "Submit_btn": "Submit",
 
1491
  "Concept": "Main Concept",
1492
  "Image": "Image",
1493
  "Image_URL": "Image URL (optional, if no image is loaded)",
1494
+ "Description": "Description in Vietnamese",
1495
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1496
  "Clear_btn": "Clear",
1497
  "Submit_btn": "Submit",
 
1517
  "Concept": "Main Concept",
1518
  "Image": "Image",
1519
  "Image_URL": "Image URL (optional, if no image is loaded)",
1520
+ "Description": "Description in Swahili",
1521
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1522
  "Clear_btn": "Clear",
1523
  "Submit_btn": "Submit",
 
1543
  "Concept": "Main Concept",
1544
  "Image": "Image",
1545
  "Image_URL": "Image URL (optional, if no image is loaded)",
1546
+ "Description": "Description in Somali",
1547
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1548
  "Clear_btn": "Clear",
1549
  "Submit_btn": "Submit",
 
1569
  "Concept": "Main Concept",
1570
  "Image": "Image",
1571
  "Image_URL": "Image URL (optional, if no image is loaded)",
1572
+ "Description": "Description in Thai",
1573
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1574
  "Clear_btn": "Clear",
1575
  "Submit_btn": "Submit",
 
1595
  "Concept": "Main Concept",
1596
  "Image": "Image",
1597
  "Image_URL": "Image URL (optional, if no image is loaded)",
1598
+ "Description": "Description in Luganda",
1599
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1600
  "Clear_btn": "Clear",
1601
  "Submit_btn": "Submit",
 
1621
  "Concept": "Main Concept",
1622
  "Image": "Image",
1623
  "Image_URL": "Image URL (optional, if no image is loaded)",
1624
+ "Description": "Description in Spanish",
1625
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1626
  "Clear_btn": "Clear",
1627
  "Submit_btn": "Submit",
 
1647
  "Concept": "Main Concept",
1648
  "Image": "Image",
1649
  "Image_URL": "Image URL (optional, if no image is loaded)",
1650
+ "Description": "Description in Shona",
1651
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1652
  "Clear_btn": "Clear",
1653
  "Submit_btn": "Submit",
 
1671
  "Concept": "Main Concept",
1672
  "Image": "Image",
1673
  "Image_URL": "Image URL (optional, if no image is loaded)",
1674
+ "Description": "Description in Ndebele",
1675
  "Instructs_btn": "\ud83d\udcd8 Show instructions",
1676
  "Clear_btn": "Clear",
1677
  "Submit_btn": "Submit",
data/update_metadata_from_concepts.py CHANGED
@@ -9,6 +9,9 @@ for country in concepts:
9
  for language in concepts[country]:
10
  if language not in meta[country]:
11
  meta[country][language] = meta["USA"]["English"]
 
 
 
12
 
13
  with open("metadata.json", "w", encoding="utf-8") as f:
14
  json.dump(meta, f, indent=2)
 
9
  for language in concepts[country]:
10
  if language not in meta[country]:
11
  meta[country][language] = meta["USA"]["English"]
12
+ # FIXME: Remove this after we ask language leads to translate
13
+ if not meta[country][language]["Description"].endswith(language):
14
+ meta[country][language]["Description"] += f"in {language}"
15
 
16
  with open("metadata.json", "w", encoding="utf-8") as f:
17
  json.dump(meta, f, indent=2)
logic/data_utils.py CHANGED
@@ -169,7 +169,7 @@ class CustomHFDatasetSaver:
169
  if values_dic.get("username"):
170
  sample_dir = os.path.join("logged_in_users", values_dic["country"], values_dic["language"], values_dic["username"], str(current_timestamp))
171
  else:
172
- sample_dir = os.path.join("anonymous_users", values_dic["country"], values_dic["language"], str(uuid.uuid4()))
173
 
174
  os.makedirs(os.path.join(self.local_ds_folder, sample_dir), exist_ok=True)
175
 
 
169
  if values_dic.get("username"):
170
  sample_dir = os.path.join("logged_in_users", values_dic["country"], values_dic["language"], values_dic["username"], str(current_timestamp))
171
  else:
172
+ sample_dir = os.path.join("anonymous_users", values_dic["country"], values_dic["language"], str(uuid.uuid4()), str(current_timestamp))
173
 
174
  os.makedirs(os.path.join(self.local_ds_folder, sample_dir), exist_ok=True)
175
 
logic/handlers.py CHANGED
@@ -3,6 +3,8 @@ import datetime
3
  import io
4
  import PIL
5
  import requests
 
 
6
  from datasets import load_dataset, concatenate_datasets, Image
7
  from data.lang2eng_map import lang2eng_mapping
8
  from data.words_map import words_mapping
@@ -19,6 +21,25 @@ import time
19
  import re
20
  import os
21
  import glob
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
  def update_image(image_url):
24
  try:
@@ -45,7 +66,11 @@ def update_timestamp():
45
  return gr.Textbox(datetime.datetime.now().timestamp(), label="Timestamp", visible=False) # FIXME visible=False)
46
 
47
 
48
- def clear_data():
 
 
 
 
49
  return (None, None, None, None, None, gr.update(value=None),
50
  gr.update(value=[]), gr.update(value=[]), gr.update(value=[]),
51
  gr.update(value=[]), gr.update(value=[]))
@@ -59,11 +84,23 @@ def exit():
59
  gr.update(value=None), gr.update(value=None))
60
 
61
 
62
- def validate_inputs(image, ori_img): # is_blurred
 
 
 
 
 
 
 
 
63
  # Perform your validation logic here
 
64
  if image is None:
65
  return gr.Button("Submit", variant="primary", interactive=False), None, None, # False
66
-
 
 
 
67
  # Define maximum dimensions
68
  MAX_WIDTH = 1024
69
  MAX_HEIGHT = 1024
@@ -93,6 +130,24 @@ def validate_inputs(image, ori_img): # is_blurred
93
  return gr.Button("Submit", variant="primary", interactive=True), result_image, ori_img # is_blurred
94
 
95
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
96
  def add_prefix(example, column_name, prefix):
97
  example[column_name] = (f"{prefix}/" + example[column_name])
98
  return example
@@ -135,7 +190,10 @@ def update_user_data(username, password, country, language_choice, HF_DATASET_NA
135
 
136
  # Handle all empty
137
  if not datasets_list:
138
- return gr.Dataset(samples=[]), gr.Markdown("<p style='color: red;'>No data available for this user. Please upload an image.</p>")
 
 
 
139
 
140
  dataset = concatenate_datasets(datasets_list)
141
  # TODO: we should link username with password and language and country, otherwise there will be an error when loading with different language and clicking on the example
@@ -171,7 +229,33 @@ def update_user_data(username, password, country, language_choice, HF_DATASET_NA
171
  d['image_file'], d['image_url'], d['caption'] or "", d['country'],
172
  d['language'], d['category'], d['concept'], additional_concepts_by_category, d['id']] # d['is_blurred']
173
  )
174
- return gr.Dataset(samples=samples), None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  else:
176
  # TODO: should we show the entire dataset instead? What about "other data" tab?
177
  return gr.Dataset(samples=[]), None
@@ -181,13 +265,13 @@ def update_language(local_storage, metadata_dict, concepts_dict):
181
  country, language, email, password, = local_storage
182
  # my_translator = GoogleTranslator(source='english', target=metadata_dict[country][language])
183
  categories = concepts_dict[country][lang2eng_mapping.get(language, language)]
 
184
  if language in words_mapping:
185
- categories_keys_translated = [words_mapping[language].get(cat, cat) for cat in categories.keys()]
186
  else:
187
- categories_keys_translated = list(categories.keys())
188
 
189
  # Get the 5 categories in alphabetical order
190
- categories_list = sorted(list(categories.keys()))[:5]
191
 
192
  # Create translated labels for the 5 categories
193
  translated_categories = []
@@ -197,6 +281,15 @@ def update_language(local_storage, metadata_dict, concepts_dict):
197
  else:
198
  translated_cat = cat
199
  translated_categories.append(translated_cat)
 
 
 
 
 
 
 
 
 
200
 
201
  fn = metadata_dict[country][language]["Task"]
202
  if os.path.exists(fn):
@@ -222,7 +315,7 @@ def update_language(local_storage, metadata_dict, concepts_dict):
222
  gr.update(label=metadata_dict[country][language]["Email"], value=email),
223
  gr.update(label=metadata_dict[country][language]["Password"], value=password),
224
  gr.update(choices=categories_keys_translated, interactive=True, label=metadata_dict[country][language]["Category"], allow_custom_value=False, elem_id="category_btn"),
225
- gr.update(choices=[], interactive=True, label=metadata_dict[country][language]["Concept"], allow_custom_value=True, elem_id="concept_btn"),
226
  gr.update(label=metadata_dict[country][language]["Image"]),
227
  gr.update(label=metadata_dict[country][language]["Image_URL"]),
228
  gr.update(label=metadata_dict[country][language]["Description"]),
@@ -243,11 +336,11 @@ def update_language(local_storage, metadata_dict, concepts_dict):
243
  gr.update(value=metadata_dict[country][language].get("Hide_btn","👤 Hide Specific Faces")),
244
  gr.update(value=metadata_dict[country][language].get("Unhide_btn","👀 Unhide Faces")),
245
  gr.update(value=metadata_dict[country][language].get("Exclude_btn","Exclude Selected Example")),
246
- gr.update(label=translated_categories[0], choices=sorted(concepts_dict[country][lang2eng_mapping.get(language, language)][categories_list[0]])),
247
- gr.update(label=translated_categories[1], choices=sorted(concepts_dict[country][lang2eng_mapping.get(language, language)][categories_list[1]])),
248
- gr.update(label=translated_categories[2], choices=sorted(concepts_dict[country][lang2eng_mapping.get(language, language)][categories_list[2]])),
249
- gr.update(label=translated_categories[3], choices=sorted(concepts_dict[country][lang2eng_mapping.get(language, language)][categories_list[3]])),
250
- gr.update(label=translated_categories[4], choices=sorted(concepts_dict[country][lang2eng_mapping.get(language, language)][categories_list[4]])),
251
  )
252
 
253
 
@@ -265,20 +358,58 @@ def update_intro_language(selected_country, selected_language, intro_markdown, m
265
 
266
 
267
  def handle_click_example(user_examples, concepts_dict):
268
- print("handle_click_example")
269
- print(user_examples)
270
- ex = [item for item in user_examples]
271
- # print(ex)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272
  image_inp = ex[0]
273
  image_url_inp = ex[1]
274
  long_caption_inp = ex[2]
275
- country_btn = ex[3]
276
- language_btn = ex[4]
277
  category_btn = ex[5]
278
  concept_btn = ex[6]
279
- additional_concepts_by_category = ex[7]
280
  exampleid_btn = ex[8]
281
- additional_concepts_by_category = [[] if (len(cat_concept)==1 and cat_concept[0]=='') else cat_concept for cat_concept in additional_concepts_by_category]
282
 
283
  # import pdb; pdb.set_trace()
284
  # # excluded_btn = ex[10] # TODO: add functionality that if True "exclude" button changes to "excluded"
@@ -311,6 +442,16 @@ def handle_click_example(user_examples, concepts_dict):
311
 
312
  # Need to return values for each category dropdown
313
  return [image_inp, image_url_inp, long_caption_inp, exampleid_btn, category_btn, concept_btn] + additional_concepts_by_category + [True]
 
 
 
 
 
 
 
 
 
 
314
 
315
 
316
  def is_password_correct(hashed_password, entered_password):
@@ -352,16 +493,30 @@ def select_faces_to_hide(image, blur_faces_ids):
352
  # pdb.set_trace()
353
  # Draw detections with IDs
354
  for face_id, face_data in enumerate(faces.values(), start=1):
355
- # Get face coordinates
356
- facial_area = face_data['facial_area']
357
- x1, y1, x2, y2 = facial_area
358
-
359
- # Draw rectangle around face
360
- cv2.rectangle(face_images, (x1, y1), (x2, y2), (0, 0, 255), 2)
361
-
362
- # Add ID text
363
- cv2.putText(face_images, f"ID: {face_id}", (x1, y1 - 10),
364
- cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
365
  # Update face count
366
  face_count = len(faces)
367
  blur_faces_ids = gr.update(choices=[f"Face ID: {i}" for i in range(1, face_count + 1)])
 
3
  import io
4
  import PIL
5
  import requests
6
+ from typing import Literal
7
+
8
  from datasets import load_dataset, concatenate_datasets, Image
9
  from data.lang2eng_map import lang2eng_mapping
10
  from data.words_map import words_mapping
 
21
  import re
22
  import os
23
  import glob
24
+ from pyuca import Collator
25
+ from pillow_heif import register_heif_opener
26
+ register_heif_opener()
27
+
28
+ import spacy_udpipe
29
+ # ja_nlp = spacy.load("ja_core_news_sm")
30
+ # zh_nlp = spacy.load("zh_core_web_sm")
31
+ # import ja_core_news_sm
32
+ # import zh_core_web_sm
33
+ import spacy_thai
34
+ ja_nlp = spacy_udpipe.load("ja")
35
+ zh_nlp = spacy_udpipe.load("zh")
36
+ th_nlp = spacy_thai.load()
37
+
38
+
39
+ def sort_with_pyuca(strings):
40
+ collator = Collator()
41
+ return sorted(strings, key=collator.sort_key)
42
+
43
 
44
  def update_image(image_url):
45
  try:
 
66
  return gr.Textbox(datetime.datetime.now().timestamp(), label="Timestamp", visible=False) # FIXME visible=False)
67
 
68
 
69
+ def clear_data(message: Literal["submit", "remove"] | None = None):
70
+ if message == "submit":
71
+ gr.Info("If you logged in, you will soon see it at the bottom of the page, where you can edit it or delete it", title="Thank you for submitting your data! 🎉", duration=5)
72
+ elif message == "remove":
73
+ gr.Info("", title="Your data has been deleted! 🗑️", duration=5)
74
  return (None, None, None, None, None, gr.update(value=None),
75
  gr.update(value=[]), gr.update(value=[]), gr.update(value=[]),
76
  gr.update(value=[]), gr.update(value=[]))
 
84
  gr.update(value=None), gr.update(value=None))
85
 
86
 
87
+ def validate_metadata(country, language):
88
+ # Perform your validation logic here
89
+ if country is None or language is None:
90
+ return gr.Button("Proceed", interactive=False)
91
+
92
+ return gr.Button("Proceed", interactive=True)
93
+
94
+
95
+ def validate_inputs(image, ori_img, concept): # is_blurred
96
  # Perform your validation logic here
97
+ # import pdb; pdb.set_trace()
98
  if image is None:
99
  return gr.Button("Submit", variant="primary", interactive=False), None, None, # False
100
+
101
+ if concept is None:
102
+ raise gr.Error("⚠️ Please select the main concept first. Click the ❌ on the image uploader to reset the image.", duration=10)
103
+ return gr.Button("Submit", variant="primary", interactive=False), None, None, # False
104
  # Define maximum dimensions
105
  MAX_WIDTH = 1024
106
  MAX_HEIGHT = 1024
 
130
  return gr.Button("Submit", variant="primary", interactive=True), result_image, ori_img # is_blurred
131
 
132
 
133
+ def count_words(caption, language):
134
+ match language:
135
+ case "Japanese":
136
+ doc = ja_nlp(caption)
137
+ tokens = [tok.text for tok in doc if not tok.is_punct]
138
+ num_words = len(tokens)
139
+ case "Chinese":
140
+ doc = zh_nlp(caption)
141
+ tokens = [tok.text for tok in doc if not tok.is_punct]
142
+ num_words = len(tokens)
143
+ case "Thai":
144
+ num_words = len(th_nlp(caption))
145
+ case _:
146
+ num_words = len(caption.split())
147
+ return num_words
148
+ # return gr.Markdown(f"Number of words: {num_words}")
149
+
150
+
151
  def add_prefix(example, column_name, prefix):
152
  example[column_name] = (f"{prefix}/" + example[column_name])
153
  return example
 
190
 
191
  # Handle all empty
192
  if not datasets_list:
193
+ if username: # User is logged in but has no data
194
+ return gr.Dataset(samples=[]), gr.Markdown("<p style='color: red;'>No data available for this user. Please upload an image.</p>")
195
+ else: # No user logged in
196
+ return gr.Dataset(samples=[]), gr.Markdown("")
197
 
198
  dataset = concatenate_datasets(datasets_list)
199
  # TODO: we should link username with password and language and country, otherwise there will be an error when loading with different language and clicking on the example
 
229
  d['image_file'], d['image_url'], d['caption'] or "", d['country'],
230
  d['language'], d['category'], d['concept'], additional_concepts_by_category, d['id']] # d['is_blurred']
231
  )
232
+ # return gr.Dataset(samples=samples), None
233
+ # ───────────────────────────────────────────────────
234
+ # Clean up the “Additional Concepts” column (index 7)
235
+ cleaned = []
236
+ for row in samples:
237
+ # row is a list, index 7 holds the list-of-lists
238
+ ac = row[7]
239
+
240
+ # flatten & drop empty strings
241
+ vals = []
242
+ for sub in ac:
243
+ if isinstance(sub, list):
244
+ for v in sub:
245
+ v = v.strip()
246
+ if v:
247
+ vals.append(v)
248
+
249
+ # now vals contains every non-empty string from every sub-list
250
+ # e.g. ['Arquitectura colonial española', 'Año Nuevo', 'Bata',
251
+ # 'Aborrajado', 'Ajiaco', 'Abanico/ventilador']
252
+
253
+ # make a copy and replace only that field
254
+ row_copy = list(row)
255
+ row_copy[7] = ", ".join(vals)
256
+ cleaned.append(row_copy)
257
+
258
+ return gr.Dataset(samples=cleaned), None
259
  else:
260
  # TODO: should we show the entire dataset instead? What about "other data" tab?
261
  return gr.Dataset(samples=[]), None
 
265
  country, language, email, password, = local_storage
266
  # my_translator = GoogleTranslator(source='english', target=metadata_dict[country][language])
267
  categories = concepts_dict[country][lang2eng_mapping.get(language, language)]
268
+ categories_list = sort_with_pyuca(list(categories.keys()))
269
  if language in words_mapping:
270
+ categories_keys_translated = [words_mapping[language].get(cat, cat) for cat in categories_list]
271
  else:
272
+ categories_keys_translated = categories_list
273
 
274
  # Get the 5 categories in alphabetical order
 
275
 
276
  # Create translated labels for the 5 categories
277
  translated_categories = []
 
281
  else:
282
  translated_cat = cat
283
  translated_categories.append(translated_cat)
284
+
285
+ # Load all possible concepts
286
+ concepts_list = []
287
+ # cats = [] # FIXME: Assumes concepts are unique across all categories
288
+ for cat in concepts_dict[country][language]:
289
+ for concept in concepts_dict[country][language][cat]:
290
+ # cats.append(cat)
291
+ concepts_list.append(concept)
292
+ concepts_list = sort_with_pyuca(concepts_list)
293
 
294
  fn = metadata_dict[country][language]["Task"]
295
  if os.path.exists(fn):
 
315
  gr.update(label=metadata_dict[country][language]["Email"], value=email),
316
  gr.update(label=metadata_dict[country][language]["Password"], value=password),
317
  gr.update(choices=categories_keys_translated, interactive=True, label=metadata_dict[country][language]["Category"], allow_custom_value=False, elem_id="category_btn"),
318
+ gr.update(choices=concepts_list, interactive=True, label=metadata_dict[country][language]["Concept"], allow_custom_value=True, elem_id="concept_btn"),
319
  gr.update(label=metadata_dict[country][language]["Image"]),
320
  gr.update(label=metadata_dict[country][language]["Image_URL"]),
321
  gr.update(label=metadata_dict[country][language]["Description"]),
 
336
  gr.update(value=metadata_dict[country][language].get("Hide_btn","👤 Hide Specific Faces")),
337
  gr.update(value=metadata_dict[country][language].get("Unhide_btn","👀 Unhide Faces")),
338
  gr.update(value=metadata_dict[country][language].get("Exclude_btn","Exclude Selected Example")),
339
+ gr.update(label=translated_categories[0], choices=sort_with_pyuca(concepts_dict[country][lang2eng_mapping.get(language, language)][categories_list[0]])),
340
+ gr.update(label=translated_categories[1], choices=sort_with_pyuca(concepts_dict[country][lang2eng_mapping.get(language, language)][categories_list[1]])),
341
+ gr.update(label=translated_categories[2], choices=sort_with_pyuca(concepts_dict[country][lang2eng_mapping.get(language, language)][categories_list[2]])),
342
+ gr.update(label=translated_categories[3], choices=sort_with_pyuca(concepts_dict[country][lang2eng_mapping.get(language, language)][categories_list[3]])),
343
+ gr.update(label=translated_categories[4], choices=sort_with_pyuca(concepts_dict[country][lang2eng_mapping.get(language, language)][categories_list[4]])),
344
  )
345
 
346
 
 
358
 
359
 
360
  def handle_click_example(user_examples, concepts_dict):
361
+ # print("handle_click_example")
362
+ # print(user_examples)
363
+ # ex = [item for item in user_examples]
364
+ # ───────────────────────────────────────────────────────────────
365
+ # 1) Turn the flat string in slot 7 back into a list-of-lists
366
+ ex = list(user_examples)
367
+ raw_ac = ex[7] if len(ex) > 7 else ""
368
+
369
+ country_btn = ex[3]
370
+ language_btn = ex[4]
371
+ concepts = concepts_dict[country_btn][language_btn]
372
+ categories_list = sort_with_pyuca(list(concepts.keys()))
373
+ # NOTE: assuming concepts are unique across all categories
374
+ if isinstance(raw_ac, str):
375
+ parts = [p.strip() for p in raw_ac.split(",")]
376
+ if raw_ac.strip() == "":
377
+ additional_concepts_by_category = [[], [], [] ,[], []]
378
+ else:
379
+ additional_concepts_by_category = [[], [], [] ,[], []]
380
+ for p in parts:
381
+ if p in concepts[categories_list[0]]:
382
+ additional_concepts_by_category[0].append(p)
383
+ continue
384
+ elif p in concepts[categories_list[1]]:
385
+ additional_concepts_by_category[1].append(p)
386
+ continue
387
+ elif p in concepts[categories_list[2]]:
388
+ additional_concepts_by_category[2].append(p)
389
+ continue
390
+ elif p in concepts[categories_list[3]]:
391
+ additional_concepts_by_category[3].append(p)
392
+ continue
393
+ elif p in concepts[categories_list[4]]:
394
+ additional_concepts_by_category[4].append(p)
395
+ continue
396
+ # check if any of the lists are empty, if so, add an empty string
397
+ # for i in range(len(additional_concepts_by_category)):
398
+ # if not additional_concepts_by_category[i]:
399
+ # additional_concepts_by_category[i].append("")
400
+
401
+ else:
402
+ # if it somehow already is a list, leave it
403
+ additional_concepts_by_category = raw_ac
404
+ # ───────────────────────────────────────────────────────────────
405
  image_inp = ex[0]
406
  image_url_inp = ex[1]
407
  long_caption_inp = ex[2]
 
 
408
  category_btn = ex[5]
409
  concept_btn = ex[6]
410
+ # additional_concepts_by_category = ex[7]
411
  exampleid_btn = ex[8]
412
+ # additional_concepts_by_category = [[] if (len(cat_concept)==1 and cat_concept[0]=='') else cat_concept for cat_concept in additional_concepts_by_category]
413
 
414
  # import pdb; pdb.set_trace()
415
  # # excluded_btn = ex[10] # TODO: add functionality that if True "exclude" button changes to "excluded"
 
442
 
443
  # Need to return values for each category dropdown
444
  return [image_inp, image_url_inp, long_caption_inp, exampleid_btn, category_btn, concept_btn] + additional_concepts_by_category + [True]
445
+ # return [
446
+ # image_inp,
447
+ # image_url_inp,
448
+ # long_caption_inp,
449
+ # exampleid_btn,
450
+ # category_btn,
451
+ # concept_btn,
452
+ # *additional_concepts_by_category,
453
+ # True # loading_example flag
454
+ # ]
455
 
456
 
457
  def is_password_correct(hashed_password, entered_password):
 
493
  # pdb.set_trace()
494
  # Draw detections with IDs
495
  for face_id, face_data in enumerate(faces.values(), start=1):
496
+ x1, y1, x2, y2 = face_data['facial_area']
497
+ box_h = y2 - y1
498
+
499
+ # 1) dynamic scale & thickness
500
+ scale = max(0.5, box_h / 150)
501
+ thickness = max(1, int(box_h / 200))
502
+
503
+ # 2) prepare text & size
504
+ text = f"ID:{face_id}"
505
+ font = cv2.FONT_HERSHEY_SIMPLEX
506
+ (tw, th), baseline = cv2.getTextSize(text, font, scale, thickness)
507
+
508
+ # 3) background rectangle (semi‐opaque or solid)
509
+ bg_tl = (x1, y1 - th - baseline - 4)
510
+ bg_br = (x1 + tw + 4, y1)
511
+ cv2.rectangle(face_images, bg_tl, bg_br, (0,0,0), cv2.FILLED)
512
+
513
+ # 4) put contrasting text
514
+ cv2.putText(face_images, text,
515
+ (x1 + 2, y1 - baseline - 2),
516
+ font, scale, (255,255,255), thickness, cv2.LINE_AA)
517
+
518
+ # 5) draw the face box (optional: use same contrasting color)
519
+ cv2.rectangle(face_images, (x1, y1), (x2, y2), (0,255,0), thickness)
520
  # Update face count
521
  face_count = len(faces)
522
  blur_faces_ids = gr.update(choices=[f"Face ID: {i}" for i in range(1, face_count + 1)])
ui/layout.py CHANGED
@@ -1,4 +1,5 @@
1
  import gradio as gr
 
2
 
3
  from logic.data_utils import CustomHFDatasetSaver
4
  from data.lang2eng_map import lang2eng_mapping
@@ -9,6 +10,7 @@ from functools import partial
9
 
10
  from .selection_page import build_selection_page
11
  from .main_page import build_main_page
 
12
 
13
  def get_key_by_value(dictionary, value):
14
  for key, val in dictionary.items():
@@ -25,22 +27,62 @@ def load_concepts(category, concept_btn, local_storage, loading_example, concept
25
  # I'm doing this to avoid the case where the user load a previous example and the concept 'reamins' selected even if category changed
26
  if loading_example:
27
  concept_val = concept_btn if concept_btn else None
28
- return gr.update(choices=sorted(concepts[country][lang2eng_mapping.get(lang, lang)][category]), value=concept_val), False
 
 
 
29
  else:
30
- return gr.update(choices=[], value=None), False
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
  def switch_ui(country, language, username, password, flag=False, metadata_dict=None):
 
33
  print(f"Language: {language}, Country: {country}")
34
 
 
 
 
 
35
  # Hide the selection page and show the main UI.
36
  if flag:
 
 
37
  local_storage = [None, None, "", ""]
 
38
  return (local_storage, gr.update(visible=flag), gr.update(visible=not flag),
39
  gr.update(visible=not flag),
40
- gr.update(choices=list(metadata_dict.keys()), label="Country", value=None),
41
  gr.update(value=None, choices=[], label="Language", allow_custom_value=False, interactive=False))
42
 
43
  else:
 
 
44
  local_storage = [country, language, username, password]
45
  return local_storage, gr.update(visible=flag), gr.update(visible=not flag), gr.update(visible=not flag)
46
 
@@ -54,7 +96,12 @@ def build_ui(concepts_dict, metadata_dict, HF_API_TOKEN, HF_DATASET_NAME):
54
  }
55
  .compact-btn {
56
  }
 
 
 
 
57
  """
 
58
  with gr.Blocks(css=custom_css) as ui:
59
  local_storage = gr.State([None, None, "", ""])
60
  loading_example = gr.State(False) # to check if the values are loaded from a user click on an example in
@@ -71,6 +118,7 @@ def build_ui(concepts_dict, metadata_dict, HF_API_TOKEN, HF_DATASET_NAME):
71
  image_inp = cmp_main_ui["image_inp"]
72
  image_url_inp = cmp_main_ui["image_url_inp"]
73
  long_caption_inp = cmp_main_ui["long_caption_inp"]
 
74
  category_btn = cmp_main_ui["category_btn"]
75
  concept_btn = cmp_main_ui["concept_btn"]
76
  category_concept_dropdowns = cmp_main_ui["category_concept_dropdowns"]
@@ -104,6 +152,15 @@ def build_ui(concepts_dict, metadata_dict, HF_API_TOKEN, HF_DATASET_NAME):
104
  inputs=[category_btn, concept_btn, local_storage, loading_example],
105
  outputs=[concept_btn, loading_example]
106
  )
 
 
 
 
 
 
 
 
 
107
  ####
108
 
109
  # is_blurred = gr.State(False) # Initialize as False
@@ -114,6 +171,12 @@ def build_ui(concepts_dict, metadata_dict, HF_API_TOKEN, HF_DATASET_NAME):
114
  # gr.Warning(f"⚠️ The image URL is not valid. Please provide a valid image URL.")
115
 
116
  # Event listeners
 
 
 
 
 
 
117
  gr.on(
118
  triggers=[image_url_inp.change],
119
  fn=update_image,
@@ -136,10 +199,17 @@ def build_ui(concepts_dict, metadata_dict, HF_API_TOKEN, HF_DATASET_NAME):
136
  gr.on(
137
  triggers=[image_inp.change],
138
  fn=validate_inputs,
139
- inputs=[image_inp, ori_img], # is_blurred
140
  outputs=[submit_btn, image_inp, ori_img], # is_blurred
141
  )
142
 
 
 
 
 
 
 
 
143
  # Clear Button
144
  clear_btn.click(
145
  fn=clear_data,
@@ -257,7 +327,7 @@ def build_ui(concepts_dict, metadata_dict, HF_API_TOKEN, HF_DATASET_NAME):
257
  category_concept_dropdowns[0], category_concept_dropdowns[1], category_concept_dropdowns[2],
258
  category_concept_dropdowns[3], category_concept_dropdowns[4]
259
  ],
260
- ).then(
261
  fn=partial(switch_ui, flag=True, metadata_dict=metadata_dict),
262
  inputs=[country_choice, language_choice, username, password],
263
  outputs=[local_storage, selection_page, main_ui_placeholder, browse_data_placeholder, country_choice, language_choice],
@@ -311,7 +381,7 @@ def build_ui(concepts_dict, metadata_dict, HF_API_TOKEN, HF_DATASET_NAME):
311
  list(data_outputs.values()),
312
  None,
313
  ).success(
314
- fn=clear_data,
315
  outputs=[
316
  image_inp, image_url_inp, long_caption_inp, exampleid_btn,
317
  category_btn, concept_btn,
@@ -380,7 +450,7 @@ def build_ui(concepts_dict, metadata_dict, HF_API_TOKEN, HF_DATASET_NAME):
380
  ],
381
  outputs=None
382
  ).success(
383
- fn=clear_data,
384
  outputs=[
385
  image_inp, image_url_inp, long_caption_inp, exampleid_btn,
386
  category_btn, concept_btn,
 
1
  import gradio as gr
2
+ import time
3
 
4
  from logic.data_utils import CustomHFDatasetSaver
5
  from data.lang2eng_map import lang2eng_mapping
 
10
 
11
  from .selection_page import build_selection_page
12
  from .main_page import build_main_page
13
+ from .main_page import sort_with_pyuca
14
 
15
  def get_key_by_value(dictionary, value):
16
  for key, val in dictionary.items():
 
27
  # I'm doing this to avoid the case where the user load a previous example and the concept 'reamins' selected even if category changed
28
  if loading_example:
29
  concept_val = concept_btn if concept_btn else None
30
+ if country is None or lang is None:
31
+ return gr.update(choices=[], value=None), False
32
+ else:
33
+ return gr.update(choices=sort_with_pyuca(concepts[country][lang2eng_mapping.get(lang, lang)][category]), value=concept_val), False
34
  else:
35
+ concepts_list = []
36
+ # cats = [] # FIXME: Assumes concepts are unique across all categories
37
+ if country is None or lang is None:
38
+ return gr.update(choices=[], value=None), False
39
+ else:
40
+ for cat in concepts[country][lang]:
41
+ for concept in concepts[country][lang][cat]:
42
+ # cats.append(cat)
43
+ concepts_list.append(concept)
44
+ return gr.update(choices=sort_with_pyuca(concepts_list), value=None), False
45
+ # return gr.update(choices=[], value=None), False
46
+
47
+ def update_category(category, concept_btn, local_storage, loading_example, concepts):
48
+ country, lang, _, _ = local_storage
49
+ if not category and concept_btn:
50
+ # FIXME: Assumes unique concepts across categories
51
+ for cat in concepts[country][lang2eng_mapping.get(lang, lang)]:
52
+ for concept in concepts[country][lang2eng_mapping.get(lang, lang)][cat]:
53
+ if concept == concept_btn:
54
+ category = cat
55
+ return gr.update(choices=sort_with_pyuca(concepts[country][lang2eng_mapping.get(lang, lang)]), value=category), True
56
+ else:
57
+ # import pdb; pdb.set_trace()
58
+ if country is None or lang is None:
59
+ return gr.update(choices=[], value=None), False
60
+ else:
61
+ return gr.update(choices=sort_with_pyuca(concepts[country][lang2eng_mapping.get(lang, lang)]), value=category), False
62
+
63
 
64
  def switch_ui(country, language, username, password, flag=False, metadata_dict=None):
65
+ # wait for 2 seconds
66
  print(f"Language: {language}, Country: {country}")
67
 
68
+ if not country or not language:
69
+ gr.Warning(f"⚠️ Please select Country and Language first.", duration=3)
70
+ return
71
+
72
  # Hide the selection page and show the main UI.
73
  if flag:
74
+ gr.Info(f"Loading the Language Selection UI", duration=3)
75
+ time.sleep(2)
76
  local_storage = [None, None, "", ""]
77
+ countries = sort_with_pyuca(list(metadata_dict.keys()))
78
  return (local_storage, gr.update(visible=flag), gr.update(visible=not flag),
79
  gr.update(visible=not flag),
80
+ gr.update(choices=countries, label="Country", value=None),
81
  gr.update(value=None, choices=[], label="Language", allow_custom_value=False, interactive=False))
82
 
83
  else:
84
+ gr.Info(f"Loading the Main UI", duration=3)
85
+ time.sleep(2)
86
  local_storage = [country, language, username, password]
87
  return local_storage, gr.update(visible=flag), gr.update(visible=not flag), gr.update(visible=not flag)
88
 
 
96
  }
97
  .compact-btn {
98
  }
99
+ #image_inp img {
100
+ object-fit: contain; /* make sure the full image shows */
101
+ height: 460px; /* set a fixed height */
102
+ }
103
  """
104
+ ############################################################################
105
  with gr.Blocks(css=custom_css) as ui:
106
  local_storage = gr.State([None, None, "", ""])
107
  loading_example = gr.State(False) # to check if the values are loaded from a user click on an example in
 
118
  image_inp = cmp_main_ui["image_inp"]
119
  image_url_inp = cmp_main_ui["image_url_inp"]
120
  long_caption_inp = cmp_main_ui["long_caption_inp"]
121
+ num_words_inp = cmp_main_ui["num_words_inp"]
122
  category_btn = cmp_main_ui["category_btn"]
123
  concept_btn = cmp_main_ui["concept_btn"]
124
  category_concept_dropdowns = cmp_main_ui["category_concept_dropdowns"]
 
152
  inputs=[category_btn, concept_btn, local_storage, loading_example],
153
  outputs=[concept_btn, loading_example]
154
  )
155
+ concept_btn.change(
156
+ fn=partial(update_category, concepts=concepts_dict),
157
+ inputs=[category_btn, concept_btn, local_storage, loading_example],
158
+ outputs=[category_btn, loading_example]
159
+ ).then(
160
+ fn=partial(load_concepts, concepts=concepts_dict),
161
+ inputs=[category_btn, concept_btn, local_storage, gr.State(True)],
162
+ outputs=[concept_btn, loading_example]
163
+ )
164
  ####
165
 
166
  # is_blurred = gr.State(False) # Initialize as False
 
171
  # gr.Warning(f"⚠️ The image URL is not valid. Please provide a valid image URL.")
172
 
173
  # Event listeners
174
+ gr.on(
175
+ triggers=[country_choice.change, language_choice.change],
176
+ fn=validate_metadata,
177
+ inputs=[country_choice, language_choice],
178
+ outputs=[proceed_btn],
179
+ )
180
  gr.on(
181
  triggers=[image_url_inp.change],
182
  fn=update_image,
 
199
  gr.on(
200
  triggers=[image_inp.change],
201
  fn=validate_inputs,
202
+ inputs=[image_inp, ori_img, concept_btn], # is_blurred
203
  outputs=[submit_btn, image_inp, ori_img], # is_blurred
204
  )
205
 
206
+ gr.on(
207
+ triggers=[long_caption_inp.change],
208
+ fn=count_words,
209
+ inputs=[long_caption_inp, language_choice],
210
+ outputs=[num_words_inp],
211
+ )
212
+
213
  # Clear Button
214
  clear_btn.click(
215
  fn=clear_data,
 
327
  category_concept_dropdowns[0], category_concept_dropdowns[1], category_concept_dropdowns[2],
328
  category_concept_dropdowns[3], category_concept_dropdowns[4]
329
  ],
330
+ ).success(
331
  fn=partial(switch_ui, flag=True, metadata_dict=metadata_dict),
332
  inputs=[country_choice, language_choice, username, password],
333
  outputs=[local_storage, selection_page, main_ui_placeholder, browse_data_placeholder, country_choice, language_choice],
 
381
  list(data_outputs.values()),
382
  None,
383
  ).success(
384
+ fn=partial(clear_data, "submit"),
385
  outputs=[
386
  image_inp, image_url_inp, long_caption_inp, exampleid_btn,
387
  category_btn, concept_btn,
 
450
  ],
451
  outputs=None
452
  ).success(
453
+ fn=partial(clear_data, "remove"),
454
  outputs=[
455
  image_inp, image_url_inp, long_caption_inp, exampleid_btn,
456
  category_btn, concept_btn,
ui/main_page.py CHANGED
@@ -4,6 +4,13 @@ from gradio_modal import Modal
4
  from data.lang2eng_map import lang2eng_mapping
5
  from data.words_map import words_mapping
6
  import datetime
 
 
 
 
 
 
 
7
 
8
  def build_main_page(concepts_dict, metadata_dict, local_storage):
9
  try:
@@ -19,8 +26,19 @@ def build_main_page(concepts_dict, metadata_dict, local_storage):
19
 
20
  with open(metadata_dict["USA"]["English"]["Instructions"], "r", encoding="utf-8") as f:
21
  INST_TEXT = f.read()
22
-
23
- intro_text_inp = gr.Markdown(TASK_TEXT)
 
 
 
 
 
 
 
 
 
 
 
24
 
25
  # gr.Markdown("## Data Collection")
26
  with gr.Row(equal_height=True):
@@ -33,25 +51,64 @@ def build_main_page(concepts_dict, metadata_dict, local_storage):
33
  with gr.Row(equal_height=True, ):
34
  with gr.Column():
35
  # Main category and concept row - SINGLE SELECTION
36
- with gr.Row():
37
- categories = concepts_dict["USA"]["English"]
38
- category_btn = gr.Dropdown(choices=categories.keys(), interactive=True, label="Main Category",
39
- allow_custom_value=False, elem_id="category_btn", multiselect=False, value=None)
40
- concept_btn = gr.Dropdown(choices=[], interactive=True, label="Main Concept",
41
- allow_custom_value=True, elem_id="concept_btn", multiselect=False)
 
 
 
 
 
 
 
 
42
 
43
- image_inp = gr.Image(label="Image", elem_id="image_inp", format="png", height=512, width=768)
44
- with gr.Row():
45
- hide_all_faces_btn = gr.Button("👤 Hide All Faces", elem_id="hide_all_faces_btn")
46
- hide_faces_btn = gr.Button("👤 Hide Specific Faces", elem_id="hide_faces_btn")
47
- unhide_faces_btn = gr.Button("👀 Unhide Faces", elem_id="unhide_faces_btn")
48
- image_url_inp = gr.Textbox(label="Image URL (Optional, if not uploading an image)", type="text", elem_id="image_url_inp")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
 
50
  with gr.Column():
51
  # short_caption_inp = gr.Textbox(lines=2, label="Short Description", elem_id="short_caption_inp")
52
- long_caption_inp = gr.Textbox(lines=6, label="Description", elem_id="long_caption_inp")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
- categories_list = sorted(list(concepts_dict["USA"]["English"].keys()))[:5]
55
 
56
  def create_category_dropdown(category, index):
57
  original_category = category
@@ -62,7 +119,7 @@ def build_main_page(concepts_dict, metadata_dict, local_storage):
62
  display_category = original_category
63
 
64
  category_choices = concepts_dict[country][lang2eng_mapping.get(lang, lang)][original_category]
65
- sorted_choices = sorted(category_choices)
66
 
67
  dropdown = gr.Dropdown(
68
  choices=sorted_choices,
@@ -77,24 +134,27 @@ def build_main_page(concepts_dict, metadata_dict, local_storage):
77
 
78
  category_concept_dropdowns = []
79
 
80
- # First row - categories 1 and 2
81
- with gr.Row():
82
- dropdown1 = create_category_dropdown(categories_list[0], 0)
83
- category_concept_dropdowns.append(dropdown1)
84
-
85
- dropdown2 = create_category_dropdown(categories_list[1], 1)
86
- category_concept_dropdowns.append(dropdown2)
 
 
 
87
 
88
- # Second row - categories 3 and 4
89
- # with gr.Row():
90
- dropdown3 = create_category_dropdown(categories_list[2], 2)
91
- category_concept_dropdowns.append(dropdown3)
92
-
93
- dropdown4 = create_category_dropdown(categories_list[3], 3)
94
- category_concept_dropdowns.append(dropdown4)
95
 
96
- dropdown5 = create_category_dropdown(categories_list[4], 4)
97
- category_concept_dropdowns.append(dropdown5)
98
 
99
  # Third row - category 5 and instructions button
100
  with gr.Row(equal_height=True):
@@ -137,6 +197,7 @@ def build_main_page(concepts_dict, metadata_dict, local_storage):
137
  "image_inp": image_inp,
138
  "image_url_inp": image_url_inp,
139
  "long_caption_inp": long_caption_inp,
 
140
  "category_btn": category_btn,
141
  "concept_btn": concept_btn,
142
  "category_concept_dropdowns": category_concept_dropdowns,
 
4
  from data.lang2eng_map import lang2eng_mapping
5
  from data.words_map import words_mapping
6
  import datetime
7
+ from pyuca import Collator
8
+
9
+
10
+ def sort_with_pyuca(strings):
11
+ collator = Collator()
12
+ return sorted(strings, key=collator.sort_key)
13
+
14
 
15
  def build_main_page(concepts_dict, metadata_dict, local_storage):
16
  try:
 
26
 
27
  with open(metadata_dict["USA"]["English"]["Instructions"], "r", encoding="utf-8") as f:
28
  INST_TEXT = f.read()
29
+
30
+ gr.Markdown("# Wonders: Multicultural Images and Captions for Inclusive AI")
31
+ gr.Markdown("Help us collect culturally rich images and captions to improve AI for everyone!")
32
+ gr.Markdown("Choose a concept, upload an image showing it in a typical local situation, and write a detailed description about the image.<br> For more information, see the overviews below or click on 'Show instructions' for detailed guidelines.")
33
+ gr.Markdown(""" \
34
+ ### Notes
35
+ - By participating in this task, you agree to donate images and captions under [CC BY license](https://creativecommons.org/licenses/by/4.0/), which will allow us to share the data with others to improve AI.
36
+ - You will be able to **update or remove** any provided data at any time if you wish so.
37
+ - Participants that provide more data, across more concepts and of high quality (see "Instructions" button) will be **rewarded** (see TODO).
38
+ """
39
+ )
40
+ # with gr.Accordion("📘 Show task overview", open=False):
41
+ intro_text_inp = gr.Markdown(TASK_TEXT, visible=False)
42
 
43
  # gr.Markdown("## Data Collection")
44
  with gr.Row(equal_height=True):
 
51
  with gr.Row(equal_height=True, ):
52
  with gr.Column():
53
  # Main category and concept row - SINGLE SELECTION
54
+ with gr.Group():
55
+ gr.Markdown("### Main Concept")
56
+ gr.Markdown("""\
57
+ Select the main concept and category for which you want to share data.<br>
58
+ If you want to add a new concept, you can just type it in the same box (after selecting its category).
59
+ """
60
+ )
61
+ with gr.Row():
62
+ # Use concepts_dict to populate the dropdown
63
+ categories = concepts_dict["USA"]["English"]
64
+ category_btn = gr.Dropdown(choices=sort_with_pyuca(categories.keys()), interactive=True, label="Main Category",
65
+ allow_custom_value=False, elem_id="category_btn", multiselect=False, value=None)
66
+ concept_btn = gr.Dropdown(choices=[], interactive=True, label="Main Concept",
67
+ allow_custom_value=True, elem_id="concept_btn", multiselect=False)
68
 
69
+ with gr.Group():
70
+ gr.Markdown("### Image")
71
+ with gr.Accordion("📘 An image of the main concept in typical contexts (click to read more)", open=False):
72
+ gr.Markdown("""\=
73
+ An image where the *main concept is clearly visible*
74
+ - in typical contexts in your country, and
75
+ - with other objects/people when possible
76
+
77
+ Pictures taken by yourself are preferred.
78
+ If you want to use an image from the Web, directly add its URL below.
79
+ - Please use publicly-licensed images (e.g., from pexels.com or freepik.com)
80
+
81
+ For more details, click on “Show instructions” below.
82
+ """
83
+ )
84
+ image_url_inp = gr.Textbox(label="Image URL (Optional, if not uploading an image)", type="text", elem_id="image_url_inp")
85
+ image_inp = gr.Image(label="Image", elem_id="image_inp", format="png", height=512, width=768)
86
+ with gr.Row():
87
+ hide_all_faces_btn = gr.Button("👤 Hide All Faces", elem_id="hide_all_faces_btn")
88
+ hide_faces_btn = gr.Button("👤 Hide Specific Faces", elem_id="hide_faces_btn")
89
+ unhide_faces_btn = gr.Button("👀 Unhide Faces", elem_id="unhide_faces_btn")
90
 
91
  with gr.Column():
92
  # short_caption_inp = gr.Textbox(lines=2, label="Short Description", elem_id="short_caption_inp")
93
+ with gr.Group():
94
+ gr.Markdown("### Description")
95
+ with gr.Accordion("📘 A detailed description (around 40 words covering who?, what? and where?) for the image (click to read more)", open=False):
96
+ gr.Markdown("""\
97
+ A long image description (around 40 words) with extensive and detailed visual information.<br>
98
+ Descriptions must be *objective*: focus on how you would describe the image to someone who can’t see it, without your own opinions/speculations.
99
+ The text needs to *include the main concept* and describes the content of the image in detail by including:
100
+ - **Who?** The visual *appearance* and observable *emotions* (e.g., “is smiling”) of persons and animals.
101
+ - **What?** The *actions* performed in the image.
102
+ - **Where?** The *setting* of the image, including the size, color and relationships between objects.
103
+
104
+ For more details, click on “Show instructions” below.
105
+ """
106
+ )
107
+ long_caption_inp = gr.Textbox(lines=6, label="Description", elem_id="long_caption_inp")
108
+ num_words_inp = gr.Textbox(lines=1, label="Number of words", elem_id="num_words", interactive=False, value=0)
109
+ # num_words_inp = gr.Markdown("Number of words", elem_id="num_words")
110
 
111
+ categories_list = sort_with_pyuca(list(concepts_dict["USA"]["English"].keys()))
112
 
113
  def create_category_dropdown(category, index):
114
  original_category = category
 
119
  display_category = original_category
120
 
121
  category_choices = concepts_dict[country][lang2eng_mapping.get(lang, lang)][original_category]
122
+ sorted_choices = sort_with_pyuca(category_choices)
123
 
124
  dropdown = gr.Dropdown(
125
  choices=sorted_choices,
 
134
 
135
  category_concept_dropdowns = []
136
 
137
+ with gr.Group():
138
+ gr.Markdown("### Additional concepts (optional)")
139
+ gr.Markdown("Tag any other concept that is visible in the image.")
140
+ # First row - categories 1 and 2
141
+ with gr.Row():
142
+ dropdown1 = create_category_dropdown(categories_list[0], 0)
143
+ category_concept_dropdowns.append(dropdown1)
144
+
145
+ dropdown2 = create_category_dropdown(categories_list[1], 1)
146
+ category_concept_dropdowns.append(dropdown2)
147
 
148
+ # Second row - categories 3 and 4
149
+ # with gr.Row():
150
+ dropdown3 = create_category_dropdown(categories_list[2], 2)
151
+ category_concept_dropdowns.append(dropdown3)
152
+
153
+ dropdown4 = create_category_dropdown(categories_list[3], 3)
154
+ category_concept_dropdowns.append(dropdown4)
155
 
156
+ dropdown5 = create_category_dropdown(categories_list[4], 4)
157
+ category_concept_dropdowns.append(dropdown5)
158
 
159
  # Third row - category 5 and instructions button
160
  with gr.Row(equal_height=True):
 
197
  "image_inp": image_inp,
198
  "image_url_inp": image_url_inp,
199
  "long_caption_inp": long_caption_inp,
200
+ "num_words_inp": num_words_inp,
201
  "category_btn": category_btn,
202
  "concept_btn": concept_btn,
203
  "category_concept_dropdowns": category_concept_dropdowns,
ui/selection_page.py CHANGED
@@ -2,12 +2,15 @@ import os.path
2
  import gradio as gr
3
  from functools import partial
4
 
 
 
 
5
  def update_language_options(selected_country, metadata):
6
  with open(metadata["USA"]["English"]["Intro"], "r", encoding="utf-8") as f:
7
- INTRO_TEXT = f.read() # default
8
  # Retrieve the list of languages available for the selected country.
9
  if selected_country in metadata:
10
- languages = list(metadata[selected_country].keys())
11
  if len(languages) == 0:
12
  gr.Warning("No languages available for the selected country.")
13
  return gr.Dropdown(choices=[], interactive=False, value=None), gr.Markdown(INTRO_TEXT)
@@ -17,40 +20,43 @@ def update_language_options(selected_country, metadata):
17
  with open(fn, "r", encoding="utf-8") as f:
18
  INTRO_TEXT = f.read()
19
  # Use gr.Dropdown.update to change the choices of the language dropdown.
20
- return gr.Dropdown(choices=languages, interactive=True, value=None, allow_custom_value=False), gr.Markdown(INTRO_TEXT)
 
21
  else:
22
  return gr.Dropdown(choices=[], interactive=False, value=None, allow_custom_value=False), gr.Markdown(INTRO_TEXT)
23
 
 
24
  def build_selection_page(metadata_dict):
25
  with gr.Column(visible=True, elem_classes=["compact-container"]) as selection_page:
26
- with gr.Row():
27
- with open(metadata_dict["USA"]["English"]["Intro"], "r", encoding="utf-8") as f:
28
- INTRO_TEXT = f.read()
29
- intro_markdown = gr.Markdown(INTRO_TEXT)
30
-
31
- gr.Markdown("## Please select your country")
32
-
33
- country_choice = gr.Dropdown(
34
- choices=list(metadata_dict.keys()), label="Country", allow_custom_value=False
35
- )
36
-
37
- language_choice = gr.Dropdown(
38
- choices=[],
39
- label="Language",
40
- allow_custom_value=False,
41
- interactive=False # Initially disabled.
42
- )
43
-
44
- # When the country selection changes, update the language dropdown.
45
- country_choice.change(
46
- fn=partial(update_language_options, metadata=metadata_dict),
47
- inputs=country_choice,
48
- outputs=[language_choice, intro_markdown]
49
- )
50
- with gr.Row():
51
- username = gr.Textbox(label="Email (optional)", type="email", elem_id="username_text")
52
- password = gr.Textbox(label="Password (optional)", type="password", elem_id="password_text")
53
-
54
- proceed_btn = gr.Button("Proceed")
 
55
 
56
  return selection_page, country_choice, language_choice, proceed_btn, username, password, intro_markdown
 
2
  import gradio as gr
3
  from functools import partial
4
 
5
+ from .main_page import sort_with_pyuca
6
+
7
+
8
  def update_language_options(selected_country, metadata):
9
  with open(metadata["USA"]["English"]["Intro"], "r", encoding="utf-8") as f:
10
+ INTRO_TEXT = f.read() # default
11
  # Retrieve the list of languages available for the selected country.
12
  if selected_country in metadata:
13
+ languages = sort_with_pyuca(list(metadata[selected_country].keys()))
14
  if len(languages) == 0:
15
  gr.Warning("No languages available for the selected country.")
16
  return gr.Dropdown(choices=[], interactive=False, value=None), gr.Markdown(INTRO_TEXT)
 
20
  with open(fn, "r", encoding="utf-8") as f:
21
  INTRO_TEXT = f.read()
22
  # Use gr.Dropdown.update to change the choices of the language dropdown.
23
+ val = languages[0] if len(languages) == 1 else None
24
+ return gr.Dropdown(choices=languages, interactive=True, value=val, allow_custom_value=False), gr.Markdown(INTRO_TEXT)
25
  else:
26
  return gr.Dropdown(choices=[], interactive=False, value=None, allow_custom_value=False), gr.Markdown(INTRO_TEXT)
27
 
28
+
29
  def build_selection_page(metadata_dict):
30
  with gr.Column(visible=True, elem_classes=["compact-container"]) as selection_page:
31
+ with gr.Row():
32
+ with open(metadata_dict["USA"]["English"]["Intro"], "r", encoding="utf-8") as f:
33
+ INTRO_TEXT = f.read()
34
+ intro_markdown = gr.Markdown(INTRO_TEXT)
35
+
36
+ gr.Markdown("## Please select your country")
37
+
38
+ countries = sort_with_pyuca(list(metadata_dict.keys()))
39
+ country_choice = gr.Dropdown(
40
+ choices=countries, label="Country", allow_custom_value=False, value=None,
41
+ )
42
+
43
+ language_choice = gr.Dropdown(
44
+ choices=[],
45
+ label="Language",
46
+ allow_custom_value=False,
47
+ interactive=False # Initially disabled.
48
+ )
49
+
50
+ # When the country selection changes, update the language dropdown.
51
+ country_choice.change(
52
+ fn=partial(update_language_options, metadata=metadata_dict),
53
+ inputs=country_choice,
54
+ outputs=[language_choice, intro_markdown]
55
+ )
56
+ with gr.Row():
57
+ username = gr.Textbox(label="Email (optional)", type="email", elem_id="username_text")
58
+ password = gr.Textbox(label="Password (optional)", type="password", elem_id="password_text")
59
+
60
+ proceed_btn = gr.Button("Proceed")
61
 
62
  return selection_page, country_choice, language_choice, proceed_btn, username, password, intro_markdown