YsnHdn commited on
Commit
baf039a
1 Parent(s): cf75fd2

adding French

Browse files
Camembert/Camembert/label_encoder.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0298d9049295e4472f832099653bec067850fb84c8e19f84aa994a7124d5cf4e
3
+ size 187
Camembert/Camembert/saved_model/config.json ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_name_or_path": "camembert-base",
3
+ "architectures": [
4
+ "CamembertForSequenceClassification"
5
+ ],
6
+ "attention_probs_dropout_prob": 0.1,
7
+ "bos_token_id": 5,
8
+ "classifier_dropout": null,
9
+ "eos_token_id": 6,
10
+ "hidden_act": "gelu",
11
+ "hidden_dropout_prob": 0.1,
12
+ "hidden_size": 768,
13
+ "id2label": {
14
+ "0": "LABEL_0",
15
+ "1": "LABEL_1",
16
+ "2": "LABEL_2",
17
+ "3": "LABEL_3",
18
+ "4": "LABEL_4"
19
+ },
20
+ "initializer_range": 0.02,
21
+ "intermediate_size": 3072,
22
+ "label2id": {
23
+ "LABEL_0": 0,
24
+ "LABEL_1": 1,
25
+ "LABEL_2": 2,
26
+ "LABEL_3": 3,
27
+ "LABEL_4": 4
28
+ },
29
+ "layer_norm_eps": 1e-05,
30
+ "max_position_embeddings": 514,
31
+ "model_type": "camembert",
32
+ "num_attention_heads": 12,
33
+ "num_hidden_layers": 12,
34
+ "output_past": true,
35
+ "pad_token_id": 1,
36
+ "position_embedding_type": "absolute",
37
+ "problem_type": "single_label_classification",
38
+ "torch_dtype": "float32",
39
+ "transformers_version": "4.41.2",
40
+ "type_vocab_size": 1,
41
+ "use_cache": true,
42
+ "vocab_size": 32005
43
+ }
Camembert/Camembert/saved_model/model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:9d1747b6e96c281ed0206a061b49f1233b2354c33f7371c163b4df3c8f1dc1b2
3
+ size 442527332
Camembert/Camembert/saved_tokenizer/added_tokens.json ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ {
2
+ "<unk>NOTUSED": 32005
3
+ }
Camembert/Camembert/saved_tokenizer/sentencepiece.bpe.model ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:988bc5a00281c6d210a5d34bd143d0363741a432fefe741bf71e61b1869d4314
3
+ size 810912
Camembert/Camembert/saved_tokenizer/special_tokens_map.json ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "additional_special_tokens": [
3
+ "<s>NOTUSED",
4
+ "</s>NOTUSED",
5
+ "<unk>NOTUSED"
6
+ ],
7
+ "bos_token": "<s>",
8
+ "cls_token": "<s>",
9
+ "eos_token": "</s>",
10
+ "mask_token": {
11
+ "content": "<mask>",
12
+ "lstrip": true,
13
+ "normalized": false,
14
+ "rstrip": false,
15
+ "single_word": false
16
+ },
17
+ "pad_token": "<pad>",
18
+ "sep_token": "</s>",
19
+ "unk_token": "<unk>"
20
+ }
Camembert/Camembert/saved_tokenizer/tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
Camembert/Camembert/saved_tokenizer/tokenizer_config.json ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "added_tokens_decoder": {
3
+ "0": {
4
+ "content": "<s>NOTUSED",
5
+ "lstrip": false,
6
+ "normalized": false,
7
+ "rstrip": false,
8
+ "single_word": false,
9
+ "special": true
10
+ },
11
+ "1": {
12
+ "content": "<pad>",
13
+ "lstrip": false,
14
+ "normalized": false,
15
+ "rstrip": false,
16
+ "single_word": false,
17
+ "special": true
18
+ },
19
+ "2": {
20
+ "content": "</s>NOTUSED",
21
+ "lstrip": false,
22
+ "normalized": false,
23
+ "rstrip": false,
24
+ "single_word": false,
25
+ "special": true
26
+ },
27
+ "4": {
28
+ "content": "<unk>",
29
+ "lstrip": false,
30
+ "normalized": false,
31
+ "rstrip": false,
32
+ "single_word": false,
33
+ "special": true
34
+ },
35
+ "5": {
36
+ "content": "<s>",
37
+ "lstrip": false,
38
+ "normalized": false,
39
+ "rstrip": false,
40
+ "single_word": false,
41
+ "special": true
42
+ },
43
+ "6": {
44
+ "content": "</s>",
45
+ "lstrip": false,
46
+ "normalized": false,
47
+ "rstrip": false,
48
+ "single_word": false,
49
+ "special": true
50
+ },
51
+ "32004": {
52
+ "content": "<mask>",
53
+ "lstrip": true,
54
+ "normalized": false,
55
+ "rstrip": false,
56
+ "single_word": false,
57
+ "special": true
58
+ },
59
+ "32005": {
60
+ "content": "<unk>NOTUSED",
61
+ "lstrip": false,
62
+ "normalized": false,
63
+ "rstrip": false,
64
+ "single_word": false,
65
+ "special": true
66
+ }
67
+ },
68
+ "additional_special_tokens": [
69
+ "<s>NOTUSED",
70
+ "</s>NOTUSED",
71
+ "<unk>NOTUSED"
72
+ ],
73
+ "bos_token": "<s>",
74
+ "clean_up_tokenization_spaces": true,
75
+ "cls_token": "<s>",
76
+ "eos_token": "</s>",
77
+ "mask_token": "<mask>",
78
+ "model_max_length": 512,
79
+ "pad_token": "<pad>",
80
+ "sep_token": "</s>",
81
+ "tokenizer_class": "CamembertTokenizer",
82
+ "unk_token": "<unk>"
83
+ }
FrModel.py ADDED
@@ -0,0 +1,159 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import torch
3
+ import torch.nn as nn
4
+ import numpy as np
5
+ from transformers import AutoTokenizer
6
+ import pickle
7
+
8
+ fr_tokenizer = AutoTokenizer.from_pretrained("camembert-base")
9
+
10
+ # FRENCH Tokenizer
11
+ fr_tokenizer.add_special_tokens({'additional_special_tokens': ['<MULT>']})
12
+ fr_mult_token_id = fr_tokenizer.convert_tokens_to_ids('<MULT>')
13
+ fr_cls_token_id = fr_tokenizer.cls_token_id
14
+ fr_sep_token_id = fr_tokenizer.sep_token_id
15
+ fr_pad_token_id = fr_tokenizer.pad_token_id
16
+
17
+ ## Voice Part functions
18
+ maxlen = 255 # maximum of length
19
+ batch_size = 32
20
+ max_pred = 5 # max tokens of prediction
21
+ n_layers = 6 # number of Encoder of Encoder Layer
22
+ n_heads = 12 # number of heads in Multi-Head Attention
23
+ d_model = 768 # Embedding Size
24
+ d_ff = 768 * 4 # 4*d_model, FeedForward dimension
25
+ d_k = d_v = 64 # dimension of K(=Q), V
26
+ n_segments = 2
27
+ fr_vocab_size = fr_tokenizer.vocab_size +2
28
+
29
+ def get_attn_pad_mask(seq_q, seq_k):
30
+ batch_size, len_q = seq_q.size()
31
+ batch_size, len_k = seq_k.size()
32
+ # eq(zero) is PAD token
33
+ pad_attn_mask = seq_k.data.eq(1).unsqueeze(1) # batch_size x 1 x len_k(=len_q), one is masking
34
+ return pad_attn_mask.expand(batch_size, len_q, len_k) # batch_size x len_q x len_k
35
+
36
+ class Embedding(nn.Module):
37
+ def __init__(self):
38
+ super(Embedding, self).__init__()
39
+ self.tok_embed = nn.Embedding(fr_vocab_size, d_model) # token embedding
40
+ self.pos_embed = nn.Embedding(maxlen, d_model) # position embedding
41
+ self.seg_embed = nn.Embedding(n_segments, d_model) # segment(token type) embedding
42
+ self.norm = nn.LayerNorm(d_model)
43
+
44
+ def forward(self, x, seg):
45
+ seq_len = x.size(1)
46
+ pos = torch.arange(seq_len, dtype=torch.long, device=x.device)
47
+ pos = pos.unsqueeze(0).expand_as(x) # (seq_len,) -> (batch_size, seq_len)
48
+ embedding = self.tok_embed(x)
49
+ embedding += self.pos_embed(pos)
50
+ embedding += self.seg_embed(seg)
51
+ return self.norm(embedding)
52
+
53
+ class ScaledDotProductAttention(nn.Module):
54
+ def __init__(self):
55
+ super(ScaledDotProductAttention, self).__init__()
56
+
57
+ def forward(self, Q, K, V, attn_mask):
58
+ scores = torch.matmul(Q, K.transpose(-1, -2)) / np.sqrt(d_k) # scores : [batch_size x n_heads x len_q(=len_k) x len_k(=len_q)]
59
+ scores.masked_fill_(attn_mask, -1e9) # Fills elements of self tensor with value where mask is one.
60
+ attn = nn.Softmax(dim=-1)(scores)
61
+ context = torch.matmul(attn, V)
62
+ return scores , context, attn
63
+
64
+ class MultiHeadAttention(nn.Module):
65
+ def __init__(self):
66
+ super(MultiHeadAttention, self).__init__()
67
+ self.W_Q = nn.Linear(d_model, d_k * n_heads)
68
+ self.W_K = nn.Linear(d_model, d_k * n_heads)
69
+ self.W_V = nn.Linear(d_model, d_v * n_heads)
70
+ self.fc = nn.Linear(n_heads * d_v, d_model)
71
+ self.norm = nn.LayerNorm(d_model)
72
+ def forward(self, Q, K, V, attn_mask):
73
+ # q: [batch_size x len_q x d_model], k: [batch_size x len_k x d_model], v: [batch_size x len_k x d_model]
74
+ residual, batch_size = Q, Q.size(0)
75
+ device = Q.device
76
+ Q, K, V = Q.to(device), K.to(device), V.to(device)
77
+ # (B, S, D) -proj-> (B, S, D) -split-> (B, S, H, W) -trans-> (B, H, S, W)
78
+ q_s = self.W_Q(Q).view(batch_size, -1, n_heads, d_k).transpose(1,2) # q_s: [batch_size x n_heads x len_q x d_k]
79
+ k_s = self.W_K(K).view(batch_size, -1, n_heads, d_k).transpose(1,2) # k_s: [batch_size x n_heads x len_k x d_k]
80
+ v_s = self.W_V(V).view(batch_size, -1, n_heads, d_v).transpose(1,2) # v_s: [batch_size x n_heads x len_k x d_v]
81
+
82
+ attn_mask = attn_mask.unsqueeze(1).repeat(1, n_heads, 1, 1) # attn_mask : [batch_size x n_heads x len_q x len_k]
83
+
84
+ # context: [batch_size x n_heads x len_q x d_v], attn: [batch_size x n_heads x len_q(=len_k) x len_k(=len_q)]
85
+ scores ,context, attn = ScaledDotProductAttention()(q_s, k_s, v_s, attn_mask)
86
+ context = context.transpose(1, 2).contiguous().view(batch_size, -1, n_heads * d_v) # context: [batch_size x len_q x n_heads * d_v]
87
+ output = self.fc(context)
88
+ return self.norm(output + residual), attn # output: [batch_size x len_q x d_model]
89
+
90
+ class PoswiseFeedForwardNet(nn.Module):
91
+ def __init__(self):
92
+ super(PoswiseFeedForwardNet, self).__init__()
93
+ self.fc1 = nn.Linear(d_model, d_ff)
94
+ self.fc2 = nn.Linear(d_ff, d_model)
95
+ self.gelu = nn.GELU()
96
+ def forward(self, x):
97
+ # (batch_size, len_seq, d_model) -> (batch_size, len_seq, d_ff) -> (batch_size, len_seq, d_model)
98
+ return self.fc2(self.gelu(self.fc1(x)))
99
+
100
+ class EncoderLayer(nn.Module):
101
+ def __init__(self):
102
+ super(EncoderLayer, self).__init__()
103
+ self.enc_self_attn = MultiHeadAttention()
104
+ self.pos_ffn = PoswiseFeedForwardNet()
105
+
106
+ def forward(self, enc_inputs, enc_self_attn_mask):
107
+ enc_outputs, attn = self.enc_self_attn(enc_inputs, enc_inputs, enc_inputs, enc_self_attn_mask.to(enc_inputs.device)) # enc_inputs to same Q,K,V
108
+ enc_outputs = self.pos_ffn(enc_outputs) # enc_outputs: [batch_size x len_q x d_model]
109
+ return enc_outputs, attn
110
+
111
+ class FR_BERT(nn.Module):
112
+ def __init__(self):
113
+ super(FR_BERT, self).__init__()
114
+ self.embedding = Embedding()
115
+ self.layers = nn.ModuleList([EncoderLayer() for _ in range(n_layers)])
116
+ self.fc = nn.Linear(d_model, d_model)
117
+ self.activ1 = nn.Tanh()
118
+ self.linear = nn.Linear(d_model, d_model)
119
+ self.activ2 = nn.GELU()
120
+ self.norm = nn.LayerNorm(d_model)
121
+ self.classifier = nn.Linear(d_model, 2)
122
+ # decoder is shared with embedding layer
123
+ embed_weight = self.embedding.tok_embed.weight
124
+ n_vocab, n_dim = embed_weight.size()
125
+ self.decoder = nn.Linear(n_dim, n_vocab, bias=False)
126
+ self.decoder.weight = embed_weight
127
+ self.decoder_bias = nn.Parameter(torch.zeros(n_vocab))
128
+ self.mclassifier = nn.Linear(d_model, 17)
129
+
130
+ def forward(self, input_ids, segment_ids, masked_pos):
131
+ output = self.embedding(input_ids, segment_ids)
132
+ enc_self_attn_mask = get_attn_pad_mask(input_ids, input_ids).to(output.device)
133
+ for layer in self.layers:
134
+ output, enc_self_attn = layer(output, enc_self_attn_mask)
135
+ # output : [batch_size, len, d_model], attn : [batch_size, n_heads, d_mode, d_model]
136
+ # it will be decided by first token(CLS)
137
+ h_pooled = self.activ1(self.fc(output[:, 0])) # [batch_size, d_model]
138
+ logits_clsf = self.classifier(h_pooled) # [batch_size, 2]
139
+
140
+ masked_pos = masked_pos[:, :, None].expand(-1, -1, output.size(-1)) # [batch_size, max_pred, d_model]
141
+ # get masked position from final output of transformer.
142
+ h_masked = torch.gather(output, 1, masked_pos) # masking position [batch_size, max_pred, d_model]
143
+ h_masked = self.norm(self.activ2(self.linear(h_masked)))
144
+ logits_lm = self.decoder(h_masked) + self.decoder_bias # [batch_size, max_pred, n_vocab]
145
+
146
+ h_mult_sent1 = self.activ1(self.fc(output[:, 1]))
147
+ logits_mclsf1 = self.mclassifier(h_mult_sent1)
148
+
149
+ mult2_token_id = fr_mult_token_id # Assuming mult_token_id is defined globally
150
+ mult2_positions = (input_ids == mult2_token_id).nonzero(as_tuple=False) # Find positions of [MULT2] tokens
151
+ # Ensure there are exactly two [MULT] tokens in each input sequence
152
+ assert mult2_positions.size(0) == 2 * input_ids.size(0)
153
+ mult2_positions = mult2_positions[1::2][:, 1]
154
+ # Gather the hidden states corresponding to the second [MULT] token
155
+ h_mult_sent2 = output[torch.arange(output.size(0)), mult2_positions]
156
+
157
+ logits_mclsf2 = self.mclassifier(h_mult_sent2)
158
+ logits_mclsf2 = self.mclassifier(h_mult_sent2)
159
+ return logits_lm, logits_clsf , logits_mclsf1 , logits_mclsf2
Model.py CHANGED
@@ -2,7 +2,7 @@
2
  import torch
3
  import torch.nn as nn
4
  import numpy as np
5
- from transformers import AutoTokenizer
6
  import pickle
7
 
8
  # Load the tokenizer
 
2
  import torch
3
  import torch.nn as nn
4
  import numpy as np
5
+ from transformers import AutoTokenizer
6
  import pickle
7
 
8
  # Load the tokenizer
__pycache__/FrModel.cpython-310.pyc ADDED
Binary file (6.15 kB). View file
 
__pycache__/Model.cpython-310.pyc CHANGED
Binary files a/__pycache__/Model.cpython-310.pyc and b/__pycache__/Model.cpython-310.pyc differ
 
__pycache__/app.cpython-310.pyc CHANGED
Binary files a/__pycache__/app.cpython-310.pyc and b/__pycache__/app.cpython-310.pyc differ
 
__pycache__/helper_functions.cpython-310.pyc CHANGED
Binary files a/__pycache__/helper_functions.cpython-310.pyc and b/__pycache__/helper_functions.cpython-310.pyc differ
 
app.py CHANGED
@@ -1,5 +1,6 @@
1
  from flask import Flask, render_template,request, redirect,url_for, jsonify , session
2
- from helper_functions import predict_class , prepare_text , inference , predict , align_predictions_with_sentences , load_models
 
3
  import fitz # PyMuPDF
4
  import os, shutil
5
  import torch
@@ -13,13 +14,21 @@ app.config['UPLOAD_FOLDER'] = 'static/uploads'
13
  # Global variables for models
14
  global_model = None
15
  global_neptune = None
16
- global_tokenizer = None
17
  global_pipe = None
 
 
 
 
 
18
 
19
  def init_app():
20
  global global_model, global_neptune, global_pipe
21
- print("Loading models...")
22
  global_model, global_neptune, global_pipe = load_models()
 
 
 
 
23
  print("Models loaded successfully!")
24
 
25
  init_app()
@@ -36,11 +45,12 @@ def pdf():
36
  predict_class = ""
37
  class_probabilities = dict()
38
  chart_data = dict()
39
- return render_template('pdf.html', class_probabilities= class_probabilities, predicted_class=predict_class,chart_data = chart_data)
 
40
 
41
  @app.route('/pdf/upload' , methods = ['POST'])
42
  def treatment():
43
- global global_model, global_tokenizer
44
  if request.method == 'POST' :
45
  # Récupérer le fichier PDF de la requête
46
  file = request.files['file']
@@ -71,6 +81,10 @@ def treatment():
71
  pdf_document.close()
72
  # Prepare data for the chart
73
  predicted_class , class_probabilities = predict_class([extracted_text] , global_model)
 
 
 
 
74
  chart_data = {
75
  'datasets': [{
76
  'data': list(class_probabilities.values()),
@@ -81,6 +95,7 @@ def treatment():
81
  }
82
  print(predict_class)
83
  print(chart_data)
 
84
  # clear the uploads folder
85
  for filename in os.listdir(app.config['UPLOAD_FOLDER']):
86
  file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
@@ -91,14 +106,14 @@ def treatment():
91
  shutil.rmtree(file_path)
92
  except Exception as e:
93
  print('Failed to delete %s. Reason: %s' % (file_path, e))
94
- return render_template('pdf.html',extracted_text = extracted_text, class_probabilities=class_probabilities, predicted_class=predicted_class, chart_data = chart_data)
95
  return render_template('pdf.html')
96
 
97
  ## Sentence
98
 
99
  @app.route('/sentence' , methods = ['GET' , 'POST'])
100
  def sentence():
101
- global global_model, global_tokenizer
102
  if request.method == 'POST':
103
  # Get the form data
104
  text = [request.form['text']]
@@ -113,16 +128,6 @@ def sentence():
113
  'labels': [label[0] for label in class_probabilities.keys()]
114
  }
115
  print(chart_data)
116
- # clear the uploads folder
117
- for filename in os.listdir(app.config['UPLOAD_FOLDER']):
118
- file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
119
- try:
120
- if os.path.isfile(file_path) or os.path.islink(file_path):
121
- os.unlink(file_path)
122
- elif os.path.isdir(file_path):
123
- shutil.rmtree(file_path)
124
- except Exception as e:
125
- print('Failed to delete %s. Reason: %s' % (file_path, e))
126
  return render_template('response_sentence.html', text=text, class_probabilities=class_probabilities, predicted_class=predicted_class,chart_data = chart_data)
127
 
128
  # Render the initial form page
@@ -244,5 +249,171 @@ def slu():
244
  chart_data={},
245
  sentences_prediction={})
246
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
247
  if __name__ == '__main__':
248
  app.run(debug=True)
 
1
  from flask import Flask, render_template,request, redirect,url_for, jsonify , session
2
+ from helper_functions import predict_class , inference , predict , align_predictions_with_sentences , load_models , load_fr_models
3
+ from helper_functions import predict_fr_class, fr_inference , align_fr_predictions_with_sentences
4
  import fitz # PyMuPDF
5
  import os, shutil
6
  import torch
 
14
  # Global variables for models
15
  global_model = None
16
  global_neptune = None
 
17
  global_pipe = None
18
+ global_fr_model = None
19
+ global_fr_neptune = None
20
+ global_fr_pipe = None
21
+
22
+
23
 
24
  def init_app():
25
  global global_model, global_neptune, global_pipe
26
+ print("Loading English models...")
27
  global_model, global_neptune, global_pipe = load_models()
28
+
29
+ global global_fr_model, global_fr_neptune, global_fr_pipe
30
+ print("Loading French models...")
31
+ global_fr_model , global_fr_neptune , global_fr_pipe = load_fr_models()
32
  print("Models loaded successfully!")
33
 
34
  init_app()
 
45
  predict_class = ""
46
  class_probabilities = dict()
47
  chart_data = dict()
48
+ sentences_prediction = dict()
49
+ return render_template('pdf.html', class_probabilities= class_probabilities, predicted_class=predict_class,chart_data = chart_data,sentences_prediction=sentences_prediction)
50
 
51
  @app.route('/pdf/upload' , methods = ['POST'])
52
  def treatment():
53
+ global global_model , global_neptune
54
  if request.method == 'POST' :
55
  # Récupérer le fichier PDF de la requête
56
  file = request.files['file']
 
81
  pdf_document.close()
82
  # Prepare data for the chart
83
  predicted_class , class_probabilities = predict_class([extracted_text] , global_model)
84
+ # Process the transcribed text
85
+ inference_batch, sentences = inference(extracted_text)
86
+ predictions = predict(inference_batch, global_neptune)
87
+ sentences_prediction = align_predictions_with_sentences(sentences, predictions)
88
  chart_data = {
89
  'datasets': [{
90
  'data': list(class_probabilities.values()),
 
95
  }
96
  print(predict_class)
97
  print(chart_data)
98
+ print(sentences_prediction)
99
  # clear the uploads folder
100
  for filename in os.listdir(app.config['UPLOAD_FOLDER']):
101
  file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
 
106
  shutil.rmtree(file_path)
107
  except Exception as e:
108
  print('Failed to delete %s. Reason: %s' % (file_path, e))
109
+ return render_template('pdf.html',extracted_text = extracted_text, class_probabilities=class_probabilities, predicted_class=predicted_class, chart_data = chart_data,sentences_prediction=sentences_prediction)
110
  return render_template('pdf.html')
111
 
112
  ## Sentence
113
 
114
  @app.route('/sentence' , methods = ['GET' , 'POST'])
115
  def sentence():
116
+ global global_model
117
  if request.method == 'POST':
118
  # Get the form data
119
  text = [request.form['text']]
 
128
  'labels': [label[0] for label in class_probabilities.keys()]
129
  }
130
  print(chart_data)
 
 
 
 
 
 
 
 
 
 
131
  return render_template('response_sentence.html', text=text, class_probabilities=class_probabilities, predicted_class=predicted_class,chart_data = chart_data)
132
 
133
  # Render the initial form page
 
249
  chart_data={},
250
  sentences_prediction={})
251
 
252
+ ## French Pages
253
+ @app.route('/pdf_fr')
254
+ def pdf_fr():
255
+ predict_class = ""
256
+ class_probabilities = dict()
257
+ chart_data = dict()
258
+ return render_template('pdf_fr.html', class_probabilities= class_probabilities, predicted_class=predict_class,chart_data = chart_data)
259
+
260
+ @app.route('/pdf_fr/upload' , methods = ['POST'])
261
+ def treatment_fr():
262
+ global global_fr_neptune
263
+ if request.method == 'POST' :
264
+ # Récupérer le fichier PDF de la requête
265
+ file = request.files['file']
266
+ filename = file.filename
267
+
268
+ # Enregistrer le fichier dans le répertoire de téléchargement
269
+ filepath = app.config['UPLOAD_FOLDER'] + "/" + filename
270
+ file.save(filepath)
271
+
272
+ # Ouvrir le fichier PDF
273
+ pdf_document = fitz.open(filepath)
274
+
275
+ # Initialiser une variable pour stocker le texte extrait
276
+ extracted_text = ""
277
+
278
+ # Boucler à travers chaque page pour extraire le texte
279
+ for page_num in range(len(pdf_document)):
280
+ # Récupérer l'objet de la page
281
+ page = pdf_document.load_page(page_num)
282
+
283
+ # Extraire le texte de la page
284
+ page_text = page.get_text()
285
+
286
+ # Ajouter le texte de la page à la variable d'extraction
287
+ extracted_text += f"\nPage {page_num + 1}:\n{page_text}"
288
+
289
+ # Fermer le fichier PDF
290
+ pdf_document.close()
291
+ # Process the text
292
+ inference_batch, sentences = fr_inference(extracted_text)
293
+ predictions = predict(inference_batch, global_fr_neptune)
294
+ sentences_prediction = align_fr_predictions_with_sentences(sentences, predictions)
295
+ # Prepare data for the chart
296
+ predicted_class , class_probabilities = predict_fr_class([extracted_text] , global_fr_model)
297
+
298
+ chart_data = {
299
+ 'datasets': [{
300
+ 'data': list(class_probabilities.values()),
301
+ 'backgroundColor': [color[2] for color in class_probabilities.keys()],
302
+ 'borderColor': [color[2] for color in class_probabilities.keys()]
303
+ }],
304
+ 'labels': [label[0] for label in class_probabilities.keys()]
305
+ }
306
+ print(predict_class)
307
+ print(chart_data)
308
+ # clear the uploads folder
309
+ for filename in os.listdir(app.config['UPLOAD_FOLDER']):
310
+ file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
311
+ try:
312
+ if os.path.isfile(file_path) or os.path.islink(file_path):
313
+ os.unlink(file_path)
314
+ elif os.path.isdir(file_path):
315
+ shutil.rmtree(file_path)
316
+ except Exception as e:
317
+ print('Failed to delete %s. Reason: %s' % (file_path, e))
318
+ return render_template('pdf_fr.html',extracted_text = extracted_text, class_probabilities=class_probabilities, predicted_class=predicted_class, chart_data = chart_data, sentences_prediction=sentences_prediction)
319
+ return render_template('pdf_fr.html')
320
+
321
+ @app.route('/sentence_fr' , methods = ['GET' , 'POST'])
322
+ def sentence_fr():
323
+ global global_fr_model
324
+ if request.method == 'POST':
325
+ # Get the form data
326
+ text = [request.form['text']]
327
+ predicted_class , class_probabilities = predict_fr_class(text , global_fr_model)
328
+ # Prepare data for the chart
329
+ chart_data = {
330
+ 'datasets': [{
331
+ 'data': list(class_probabilities.values()),
332
+ 'backgroundColor': [color[2 ] for color in class_probabilities.keys()],
333
+ 'borderColor': [color[2] for color in class_probabilities.keys()]
334
+ }],
335
+ 'labels': [label[0] for label in class_probabilities.keys()]
336
+ }
337
+ print(predicted_class)
338
+ print(chart_data)
339
+ return render_template('response_fr_sentence.html', text=text, class_probabilities=class_probabilities, predicted_class=predicted_class,chart_data = chart_data)
340
+
341
+ # Render the initial form page
342
+ return render_template('sentence_fr.html')
343
+
344
+ @app.route("/voice_fr", methods=['GET', 'POST'])
345
+ def slu_fr():
346
+ global global_fr_neptune, global_fr_pipe, global_fr_model
347
+
348
+ if request.method == 'POST':
349
+ logging.debug("Received POST request")
350
+ audio_file = request.files.get('audio')
351
+
352
+ if audio_file:
353
+ logging.debug(f"Received audio file: {audio_file.filename}")
354
+
355
+ # Save audio data to a temporary file
356
+ with tempfile.NamedTemporaryFile(delete=False, suffix='.wav') as temp_audio:
357
+ audio_file.save(temp_audio)
358
+ temp_audio_path = temp_audio.name
359
+
360
+ logging.debug(f"Saved audio to temporary file: {temp_audio_path}")
361
+
362
+ try:
363
+ # Transcribe audio using Whisper
364
+ result = global_fr_pipe(temp_audio_path)
365
+ extracted_text = result["text"]
366
+ logging.debug(f"Transcribed text: {extracted_text}")
367
+
368
+ # Process the transcribed text
369
+ inference_batch, sentences = fr_inference(extracted_text)
370
+ predictions = predict(inference_batch, global_fr_neptune)
371
+ sentences_prediction = align_fr_predictions_with_sentences(sentences, predictions)
372
+ predicted_class, class_probabilities = predict_fr_class([extracted_text], global_fr_model)
373
+
374
+ chart_data = {
375
+ 'datasets': [{
376
+ 'data': list(class_probabilities.values()),
377
+ 'backgroundColor': [color[2] for color in class_probabilities.keys()],
378
+ 'borderColor': [color[2] for color in class_probabilities.keys()]
379
+ }],
380
+ 'labels': [label[0] for label in class_probabilities.keys()]
381
+ }
382
+
383
+ response_data = {
384
+ 'extracted_text': extracted_text,
385
+ 'class_probabilities' : class_probabilities,
386
+ 'predicted_class': predicted_class,
387
+ 'chart_data': chart_data,
388
+ 'sentences_prediction': sentences_prediction
389
+ }
390
+ logging.debug(f"Prepared response data: {response_data}")
391
+
392
+ return render_template('voice_fr.html',
393
+ class_probabilities= class_probabilities,
394
+ predicted_class= predicted_class,
395
+ chart_data= chart_data,
396
+ sentences_prediction=sentences_prediction)
397
+
398
+ except Exception as e:
399
+ logging.error(f"Error processing audio: {str(e)}")
400
+ return jsonify({'error': str(e)}), 500
401
+
402
+ finally:
403
+ # Remove temporary file
404
+ os.unlink(temp_audio_path)
405
+
406
+ else:
407
+ logging.error("No audio file received")
408
+ return jsonify({'error': 'No audio file received'}), 400
409
+
410
+ # For GET request
411
+ logging.debug("Received GET request")
412
+ return render_template('voice_fr.html',
413
+ class_probabilities={},
414
+ predicted_class=[""],
415
+ chart_data={},
416
+ sentences_prediction={})
417
+
418
  if __name__ == '__main__':
419
  app.run(debug=True)
fr_neptune/fr_neptune/added_tokens.json ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ {
2
+ "<MULT>": 32006,
3
+ "<unk>NOTUSED": 32005
4
+ }
fr_neptune/fr_neptune/model.pt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:bd05f03e109cff6f56e6508f8e281da9c608e707bf967fd524f5a5c0771db112
3
+ size 274139674
fr_neptune/fr_neptune/sentencepiece.bpe.model ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:988bc5a00281c6d210a5d34bd143d0363741a432fefe741bf71e61b1869d4314
3
+ size 810912
fr_neptune/fr_neptune/special_tokens_map.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "additional_special_tokens": [
3
+ {
4
+ "content": "<MULT>",
5
+ "lstrip": false,
6
+ "normalized": false,
7
+ "rstrip": false,
8
+ "single_word": false
9
+ }
10
+ ],
11
+ "bos_token": "<s>",
12
+ "cls_token": "<s>",
13
+ "eos_token": "</s>",
14
+ "mask_token": {
15
+ "content": "<mask>",
16
+ "lstrip": true,
17
+ "normalized": false,
18
+ "rstrip": false,
19
+ "single_word": false
20
+ },
21
+ "pad_token": "<pad>",
22
+ "sep_token": "</s>",
23
+ "unk_token": "<unk>"
24
+ }
fr_neptune/fr_neptune/tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
fr_neptune/fr_neptune/tokenizer_config.json ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "added_tokens_decoder": {
3
+ "0": {
4
+ "content": "<s>NOTUSED",
5
+ "lstrip": false,
6
+ "normalized": false,
7
+ "rstrip": false,
8
+ "single_word": false,
9
+ "special": true
10
+ },
11
+ "1": {
12
+ "content": "<pad>",
13
+ "lstrip": false,
14
+ "normalized": false,
15
+ "rstrip": false,
16
+ "single_word": false,
17
+ "special": true
18
+ },
19
+ "2": {
20
+ "content": "</s>NOTUSED",
21
+ "lstrip": false,
22
+ "normalized": false,
23
+ "rstrip": false,
24
+ "single_word": false,
25
+ "special": true
26
+ },
27
+ "4": {
28
+ "content": "<unk>",
29
+ "lstrip": false,
30
+ "normalized": false,
31
+ "rstrip": false,
32
+ "single_word": false,
33
+ "special": true
34
+ },
35
+ "5": {
36
+ "content": "<s>",
37
+ "lstrip": false,
38
+ "normalized": false,
39
+ "rstrip": false,
40
+ "single_word": false,
41
+ "special": true
42
+ },
43
+ "6": {
44
+ "content": "</s>",
45
+ "lstrip": false,
46
+ "normalized": false,
47
+ "rstrip": false,
48
+ "single_word": false,
49
+ "special": true
50
+ },
51
+ "32004": {
52
+ "content": "<mask>",
53
+ "lstrip": true,
54
+ "normalized": false,
55
+ "rstrip": false,
56
+ "single_word": false,
57
+ "special": true
58
+ },
59
+ "32005": {
60
+ "content": "<unk>NOTUSED",
61
+ "lstrip": false,
62
+ "normalized": false,
63
+ "rstrip": false,
64
+ "single_word": false,
65
+ "special": true
66
+ },
67
+ "32006": {
68
+ "content": "<MULT>",
69
+ "lstrip": false,
70
+ "normalized": false,
71
+ "rstrip": false,
72
+ "single_word": false,
73
+ "special": true
74
+ }
75
+ },
76
+ "additional_special_tokens": [
77
+ "<MULT>"
78
+ ],
79
+ "bos_token": "<s>",
80
+ "clean_up_tokenization_spaces": true,
81
+ "cls_token": "<s>",
82
+ "eos_token": "</s>",
83
+ "mask_token": "<mask>",
84
+ "model_max_length": 512,
85
+ "pad_token": "<pad>",
86
+ "sep_token": "</s>",
87
+ "tokenizer_class": "CamembertTokenizer",
88
+ "unk_token": "<unk>"
89
+ }
fr_neptune/fr_neptune/unique_labels.json ADDED
@@ -0,0 +1 @@
 
 
1
+ ["Physics", "ai", "economies", "environments", "sports", "technologies"]
helper_functions.py CHANGED
@@ -1,13 +1,15 @@
1
  import torch
2
  import pickle
3
- from transformers import AutoTokenizer , DistilBertForSequenceClassification
4
  from transformers import BatchEncoding, PreTrainedTokenizerBase
5
  from typing import Optional
6
  from torch import Tensor
7
  import numpy as np
8
  from random import shuffle
9
  from Model import BERT
 
10
  from Model import tokenizer , mult_token_id , cls_token_id , pad_token_id , max_pred , maxlen , sep_token_id
 
11
  from transformers import pipeline
12
 
13
  device = "cpu"
@@ -37,6 +39,28 @@ def load_models():
37
 
38
  return model, neptune, pipe
39
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  class_labels = {
41
  16: ('vehicles','info' , '#4f9ef8'),
42
  10: ('environments','success' , '#0cbc87'),
@@ -333,4 +357,189 @@ def align_predictions_with_sentences(sentences, preds):
333
  dc = {} # Initialize an empty dictionary
334
  for sentence, pred in zip(sentences, preds): # Iterate through sentences and predictions
335
  dc[sentence] = class_labels.get(pred, "Unknown") # Look up the label for each prediction
336
- return dc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import torch
2
  import pickle
3
+ from transformers import AutoTokenizer , DistilBertForSequenceClassification , CamembertForSequenceClassification
4
  from transformers import BatchEncoding, PreTrainedTokenizerBase
5
  from typing import Optional
6
  from torch import Tensor
7
  import numpy as np
8
  from random import shuffle
9
  from Model import BERT
10
+ from FrModel import FR_BERT
11
  from Model import tokenizer , mult_token_id , cls_token_id , pad_token_id , max_pred , maxlen , sep_token_id
12
+ from FrModel import fr_tokenizer , fr_mult_token_id , fr_cls_token_id , fr_pad_token_id , fr_sep_token_id
13
  from transformers import pipeline
14
 
15
  device = "cpu"
 
39
 
40
  return model, neptune, pipe
41
 
42
+ def load_fr_models():
43
+ print("Loading Camembert model")
44
+ fr_model = CamembertForSequenceClassification.from_pretrained("Camembert/Camembert/saved_model")
45
+ print("Loading BERT model...")
46
+ fr_neptune = FR_BERT()
47
+ device = "cpu"
48
+ model_save_path = "fr_neptune/fr_neptune/model.pt"
49
+ fr_neptune.load_state_dict(torch.load(model_save_path, map_location=torch.device('cpu')))
50
+ fr_neptune.to(device)
51
+ print("Loading speech recognition pipeline...")
52
+ pipe = pipeline(
53
+ "automatic-speech-recognition",
54
+ model="openai/whisper-tiny.en",
55
+ chunk_length_s=30,
56
+ device=device,
57
+ )
58
+ print(pipe)
59
+ return fr_model , fr_neptune , pipe
60
+
61
+ fr_class_labels = {0: ('Physics', 'primary', '#0f6fec'), 1: ('AI','cyan', '#0dcaf0'),
62
+ 2: ('economies', 'warning' , '#f7c32e'), 3: ('environments','success' , '#0cbc87'),
63
+ 4: ('sports', 'orange', '#fd7e14')}
64
  class_labels = {
65
  16: ('vehicles','info' , '#4f9ef8'),
66
  10: ('environments','success' , '#0cbc87'),
 
357
  dc = {} # Initialize an empty dictionary
358
  for sentence, pred in zip(sentences, preds): # Iterate through sentences and predictions
359
  dc[sentence] = class_labels.get(pred, "Unknown") # Look up the label for each prediction
360
+ return dc
361
+
362
+ #### FRENCH PREPROCESSING ####
363
+ def predict_fr_class(text , model):
364
+ # Tokenisation du texte
365
+ inputs = transform_list_of_fr_texts(text, fr_tokenizer, 126, 30, 1, 2550)
366
+ # Extraire le tenseur de la liste
367
+ input_ids_tensor = inputs["input_ids"][0]
368
+ attention_mask_tensor = inputs["attention_mask"][0]
369
+ # Passage du texte à travers le modèle
370
+ with torch.no_grad():
371
+ outputs = model(input_ids=input_ids_tensor, attention_mask=attention_mask_tensor)
372
+
373
+ # Application de la fonction softmax
374
+ probabilities = torch.softmax(outputs.logits, dim=1)[0]
375
+
376
+ # Identification de la classe majoritaire
377
+ predicted_class_index = torch.argmax(probabilities).item()
378
+ predicted_class = fr_class_labels[predicted_class_index]
379
+
380
+ # Créer un dictionnaire de pourcentages trié par probabilité
381
+ sorted_percentages = {fr_class_labels[idx]: probabilities[idx].item() * 100 for idx in range(len(fr_class_labels))}
382
+ sorted_percentages = dict(sorted(sorted_percentages.items(), key=lambda item: item[1], reverse=True))
383
+
384
+ return predicted_class, sorted_percentages
385
+
386
+ def prepare_fr_text(tokens_splitted: BatchEncoding):
387
+ batch = []
388
+ sentences = []
389
+ input_ids_list = tokens_splitted['input_ids']
390
+
391
+ for i in range(0, len(input_ids_list), 2): # Adjust loop to stop at second last index
392
+ k = i + 1
393
+ if k == len(input_ids_list):
394
+ input_ids_a = input_ids_list[i]
395
+ input_ids_a = [token for token in input_ids_a.view(-1).tolist() if token != pad_token_id]
396
+ input_ids_b = []
397
+ input_ids = [fr_cls_token_id] + [fr_mult_token_id] + input_ids_a + [fr_sep_token_id] + [fr_mult_token_id] + input_ids_b + [fr_sep_token_id]
398
+ text_input_a = fr_tokenizer.decode(input_ids_a)
399
+ sentences.append(text_input_a)
400
+ segment_ids = [0] * (1 + 1 + len(input_ids_a) + 1) + [1] * (1 + len(input_ids_b) + 1)
401
+
402
+ # MASK LM
403
+ n_pred = min(max_pred, max(1, int(round(len(input_ids) * 0.15))))
404
+ cand_masked_pos = [idx for idx, token in enumerate(input_ids) if token not in [fr_cls_token_id, fr_sep_token_id, fr_mult_token_id]]
405
+ shuffle(cand_masked_pos)
406
+ masked_tokens, masked_pos = [], []
407
+ for pos in cand_masked_pos[:n_pred]:
408
+ masked_pos.append(pos)
409
+ masked_tokens.append(input_ids[pos])
410
+ input_ids[pos] = fr_tokenizer.mask_token_id
411
+
412
+ # Zero Padding
413
+ n_pad = maxlen - len(input_ids)
414
+ input_ids.extend([fr_pad_token_id] * n_pad)
415
+ segment_ids.extend([0] * n_pad)
416
+
417
+ # Zero Padding for masked tokens
418
+ if max_pred > n_pred:
419
+ n_pad = max_pred - n_pred
420
+ masked_tokens.extend([0] * n_pad)
421
+ masked_pos.extend([0] * n_pad)
422
+ else:
423
+ input_ids_a = input_ids_list[i] # Correct the indexing here
424
+ input_ids_b = input_ids_list[k] # Correct the indexing here
425
+ input_ids_a = [token for token in input_ids_a.view(-1).tolist() if token != pad_token_id]
426
+ input_ids_b = [token for token in input_ids_b.view(-1).tolist() if token != pad_token_id]
427
+ input_ids = [fr_cls_token_id] + [fr_mult_token_id] + input_ids_a + [fr_sep_token_id] + [fr_mult_token_id] + input_ids_b + [fr_sep_token_id]
428
+ segment_ids = [0] * (1 + 1 + len(input_ids_a) + 1) + [1] * (1 + len(input_ids_b) + 1)
429
+ text_input_a = fr_tokenizer.decode(input_ids_a)
430
+ text_input_b = fr_tokenizer.decode(input_ids_b)
431
+ sentences.append(text_input_a)
432
+ sentences.append(text_input_b)
433
+
434
+ # MASK LM
435
+ n_pred = min(max_pred, max(1, int(round(len(input_ids) * 0.15))))
436
+ cand_masked_pos = [idx for idx, token in enumerate(input_ids) if token not in [fr_cls_token_id, fr_sep_token_id, fr_mult_token_id]]
437
+ shuffle(cand_masked_pos)
438
+ masked_tokens, masked_pos = [], []
439
+ for pos in cand_masked_pos[:n_pred]:
440
+ masked_pos.append(pos)
441
+ masked_tokens.append(input_ids[pos])
442
+ input_ids[pos] = fr_tokenizer.mask_token_id
443
+
444
+ # Zero Padding
445
+ n_pad = maxlen - len(input_ids)
446
+ input_ids.extend([fr_pad_token_id] * n_pad)
447
+ segment_ids.extend([0] * n_pad)
448
+
449
+ # Zero Padding for masked tokens
450
+ if max_pred > n_pred:
451
+ n_pad = max_pred - n_pred
452
+ masked_tokens.extend([0] * n_pad)
453
+ masked_pos.extend([0] * n_pad)
454
+
455
+ batch.append([input_ids, segment_ids, masked_pos])
456
+ return batch, sentences
457
+
458
+ def fr_inference(text: str):
459
+ encoded_text = transform_for_inference_fr_text(text, fr_tokenizer, 125, 125, 1, 2550)
460
+ batch, sentences = prepare_fr_text(encoded_text)
461
+ return batch, sentences
462
+
463
+ def align_fr_predictions_with_sentences(sentences, preds):
464
+ dc = {} # Initialize an empty dictionary
465
+ for sentence, pred in zip(sentences, preds): # Iterate through sentences and predictions
466
+ dc[sentence] = fr_class_labels.get(pred, "Unknown") # Look up the label for each prediction
467
+ return dc
468
+
469
+ def transform_for_inference_fr_text(text: str,
470
+ tokenizer: PreTrainedTokenizerBase,
471
+ chunk_size: int,
472
+ stride: int,
473
+ minimal_chunk_length: int,
474
+ maximal_text_length: Optional[int],) -> BatchEncoding:
475
+ if maximal_text_length:
476
+ tokens = tokenize_text_with_truncation(text, tokenizer, maximal_text_length)
477
+ else:
478
+ tokens = tokenize_whole_text(text, tokenizer)
479
+ input_id_chunks, mask_chunks = split_tokens_into_smaller_chunks(tokens, chunk_size, stride, minimal_chunk_length)
480
+ add_special_tokens_at_beginning_and_end_inference(input_id_chunks, mask_chunks)
481
+ add_padding_fr_tokens_inference(input_id_chunks, mask_chunks, chunk_size)
482
+ input_ids, attention_mask = stack_tokens_from_all_chunks_for_inference(input_id_chunks, mask_chunks)
483
+ return {"input_ids": input_ids, "attention_mask": attention_mask}
484
+
485
+ def add_padding_fr_tokens_inference(input_id_chunks: list[Tensor], mask_chunks: list[Tensor], chunk_size: int) -> None:
486
+ """Adds padding tokens at the end to make sure that all chunks have exactly chunk_size tokens."""
487
+ pad_token_id = 1 # Assuming this is defined somewhere in your code
488
+ for i in range(len(input_id_chunks)):
489
+ # get required padding length
490
+ pad_len = chunk_size - input_id_chunks[i].shape[0]
491
+ # check if tensor length satisfies required chunk size
492
+ if pad_len > 0:
493
+ # if padding length is more than 0, we must add padding
494
+ input_id_chunks[i] = torch.cat([input_id_chunks[i], torch.tensor([pad_token_id] * pad_len)])
495
+ mask_chunks[i] = torch.cat([mask_chunks[i], torch.tensor([0] * pad_len)])
496
+
497
+
498
+ def transform_list_of_fr_texts(
499
+ texts: list[str],
500
+ tokenizer: PreTrainedTokenizerBase,
501
+ chunk_size: int,
502
+ stride: int,
503
+ minimal_chunk_length: int,
504
+ maximal_text_length: Optional[int] = None,
505
+ ) -> BatchEncoding:
506
+ model_inputs = [
507
+ transform_single_fr_text(text, tokenizer, chunk_size, stride, minimal_chunk_length, maximal_text_length)
508
+ for text in texts
509
+ ]
510
+ input_ids = [model_input[0] for model_input in model_inputs]
511
+ attention_mask = [model_input[1] for model_input in model_inputs]
512
+ tokens = {"input_ids": input_ids, "attention_mask": attention_mask}
513
+ return BatchEncoding(tokens)
514
+
515
+
516
+ def transform_single_fr_text(
517
+ text: str,
518
+ tokenizer: PreTrainedTokenizerBase,
519
+ chunk_size: int,
520
+ stride: int,
521
+ minimal_chunk_length: int,
522
+ maximal_text_length: Optional[int],
523
+ ) -> tuple[Tensor, Tensor]:
524
+ """Transforms (the entire) text to model input of BERT model."""
525
+ if maximal_text_length:
526
+ tokens = tokenize_text_with_truncation(text, tokenizer, maximal_text_length)
527
+ else:
528
+ tokens = tokenize_whole_text(text, tokenizer)
529
+ input_id_chunks, mask_chunks = split_tokens_into_smaller_chunks(tokens, chunk_size, stride, minimal_chunk_length)
530
+ add_fr_special_tokens_at_beginning_and_end(input_id_chunks, mask_chunks)
531
+ add_padding_tokens(input_id_chunks, mask_chunks , chunk_size)
532
+ input_ids, attention_mask = stack_tokens_from_all_chunks(input_id_chunks, mask_chunks)
533
+ return input_ids, attention_mask
534
+
535
+ def add_fr_special_tokens_at_beginning_and_end(input_id_chunks: list[Tensor], mask_chunks: list[Tensor]) -> None:
536
+ """
537
+ Adds special CLS token (token id = 101) at the beginning.
538
+ Adds SEP token (token id = 102) at the end of each chunk.
539
+ Adds corresponding attention masks equal to 1 (attention mask is boolean).
540
+ """
541
+ for i in range(len(input_id_chunks)):
542
+ # adding CLS (token id 101) and SEP (token id 102) tokens
543
+ input_id_chunks[i] = torch.cat([Tensor([5]), input_id_chunks[i], Tensor([6])])
544
+ # adding attention masks corresponding to special tokens
545
+ mask_chunks[i] = torch.cat([Tensor([1]), mask_chunks[i], Tensor([1])])
static/icons/English.svg ADDED
static/icons/France.svg ADDED
static/icons/flag-for-flag-france.htm ADDED
@@ -0,0 +1 @@
 
 
1
+ <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><link rel="icon" href="/favicon.ico"/><link rel="search" href="/opensearch.xml" type="application/opensearchdescription+xml" title="SVG Repo"/><script type="application/ld+json">[{"@context":"http://schema.org","@type":"WebSite","url":"https://www.svgrepo.com/","name":"SVG Repo - Free SVG Vectors and Icons","alternateName":"Free SVG Icons","potentialAction":{"@type":"SearchAction","target":"http://www.svgrepo.com/vectors/{search_term_string}/","query-input":"required name=search_term_string"}},{"@context":"http://schema.org","@type":"Organization","name":"SVG Repo","legalName":"SVG Repo LLC","foundingDate":"2013","url":"https://www.svgrepo.com","logo":"https://www.svgrepo.com/logo.png","founders":[{"@type":"Person","name":"Burak Tokak"}],"address":{"@type":"PostalAddress","streetAddress":"123 Genting Lane","addressLocality":"Yenom","addressRegion":"SG","postalCode":"24","addressCountry":"Singapore"},"contactPoint":{"@type":"ContactPoint","contactType":"Support","telephone":"[+561-526-8457]","email":"info@svgrepo.com"},"sameAs":["http://www.twitter.com/svgrepo","http://www.instagram.com/svgrepo","http://www.facebook.com/svgrepo","https://www.producthunt.com/products/svgrepo","https://dribbble.com/svgrepo"]},{"@context":"http://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"item":{"@id":"https://www.svgrepo.com/","name":"Home"}},{"@type":"ListItem","position":2,"item":{"@id":"https://www.svgrepo.com/collections/","name":"SVG Vector"}},{"@type":"ListItem","position":3,"item":{"@id":"https://www.svgrepo.com/svg/405485/flag-for-flag-france","name":"Flag For Flag France"}}]}]</script><title>Flag For Flag France Vector SVG Icon - SVG Repo</title><meta name="robots" content="index,follow,max-image-preview:large"/><meta name="googlebot" content="index,follow,max-image-preview:large"/><meta name="description" content="Free Flag For Flag France Vector Icon in SVG format. ✅ Download Free Flag For Flag France Vector and icons for commercial use. Flag For Flag France SVG vector illustration graphic art design format.SVG Vector vectors."/><meta name="twitter:card" content="summary_large_image"/><meta name="twitter:site" content="@svgrepo"/><meta name="twitter:creator" content="@svgrepo"/><meta property="og:title" content="Flag For Flag France Vector SVG Icon - SVG Repo"/><meta property="og:description" content="Free Flag For Flag France Vector Icon in SVG format. ✅ Download Free Flag For Flag France Vector and icons for commercial use. Flag For Flag France SVG vector illustration graphic art design format.SVG Vector vectors."/><meta property="og:url" content="https://www.svgrepo.com/svg/405485/flag-for-flag-france"/><meta property="og:image" content="https://www.svgrepo.com/social.png"/><meta property="og:image:alt" content=" Free Icons and Vectors"/><meta property="og:image:type" content="image/png"/><meta property="og:image:width" content="1600"/><meta property="og:image:height" content="800"/><meta property="og:site_name" content="SVG Repo"/><link rel="canonical" href="https://www.svgrepo.com/svg/405485/flag-for-flag-france"/><link rel="preload" href="/show/405485/flag-for-flag-france.svg" as="image" fetchpriority="high"/><meta name="next-head-count" content="23"/><meta name="next-font-preconnect"/><link rel="preload" href="/_next/static/media/c9a5bc6a7c948fb0-s.p.woff2" as="font" type="font/woff2" crossorigin="anonymous" data-next-font="size-adjust"/><link rel="preload" href="/_next/static/css/c9f2e23721645114.css" as="style"/><link rel="stylesheet" href="/_next/static/css/c9f2e23721645114.css" data-n-g=""/><link rel="preload" href="/_next/static/css/b4b0348ba0c97866.css" as="style"/><link rel="stylesheet" href="/_next/static/css/b4b0348ba0c97866.css" data-n-p=""/><link rel="preload" href="/_next/static/css/fb2c987d854b03ca.css" as="style"/><link rel="stylesheet" href="/_next/static/css/fb2c987d854b03ca.css"/><link rel="preload" href="/_next/static/css/853c26dabccca674.css" as="style"/><link rel="stylesheet" href="/_next/static/css/853c26dabccca674.css"/><link rel="preload" href="/_next/static/css/f5d51dbe22da7e06.css" as="style"/><link rel="stylesheet" href="/_next/static/css/f5d51dbe22da7e06.css"/><noscript data-n-css=""></noscript><link rel="preload" href="/_next/static/chunks/675-bbaffee85ab26582.js" as="script"/><link rel="preload" href="/_next/static/chunks/400-cf97d6bdbdf0f340.js" as="script"/><link rel="preload" href="/_next/static/chunks/451.5f026fc39acc1202.js" as="script"/><link rel="preload" href="/_next/static/chunks/929.0b4636598979df75.js" as="script"/><link rel="preload" href="/_next/static/chunks/293.58b6d7eb60abc47f.js" as="script"/><link rel="preload" href="/_next/static/chunks/webpack-915b915b0059e2ac.js" as="script"/><link rel="preload" href="/_next/static/chunks/framework-63157d71ad419e09.js" as="script"/><link rel="preload" href="/_next/static/chunks/main-76fff4db6e2e1f3e.js" as="script"/><link rel="preload" href="/_next/static/chunks/pages/_app-14ac00e97c23b48c.js" as="script"/><link rel="preload" href="/_next/static/chunks/914-237739ac1bf6acde.js" as="script"/><link rel="preload" href="/_next/static/chunks/675-bbaffee85ab26582.js" as="script"/><link rel="preload" href="/_next/static/chunks/962-5f0fda52dcac7bd5.js" as="script"/><link rel="preload" href="/_next/static/chunks/28-3a8558ea2bc8e2bd.js" as="script"/><link rel="preload" href="/_next/static/chunks/454-8e7fbd1b315808b6.js" as="script"/><link rel="preload" href="/_next/static/chunks/pages/svg/%5B%5B...param%5D%5D-6f17f889eae5f5f5.js" as="script"/><style id="__jsx-619996359">html,input{font-family:'__Inter_e66fe9', '__Inter_Fallback_e66fe9',-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif}</style></head><body><div id="__next"><div><div class="style_header__zGlFh"><div class="style_headerHolder__i_tTb"><a style="display:auto" href="/"><span class="style_logoHolder__YKj11"><img class="style_logo__OFa7_" src="/logo.svg" width="73" height="22" alt="SVG Repo - Search, explore, edit and share open licensed SVG vectors"/></span></a><div class="style_searchHolder__s_8Sf" style="display:auto"><div class="style_search__5Sx9r"><div class="style_pressEnter__Rv8T3"><span>CTRL</span> + K</div><div class="style_searchIndicator__sASd0"><svg alt="Search" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style="transform:scale(1)"><path d="M16.32 14.9l5.39 5.4a1 1 0 0 1-1.42 1.4l-5.38-5.38a8 8 0 1 1 1.41-1.41zM10 16a6 6 0 1 0 0-12 6 6 0 0 0 0 12z"></path></svg><img alt="Searching" loading="lazy" width="21" height="21" decoding="async" data-nimg="1" style="color:transparent;opacity:0" src="/_next/static/media/spin.6ffd8bb2.svg"/></div><form><input type="text" placeholder="Search for vectors and icons..." style="text-indent:40px" value=""/><input type="submit" style="display:none"/></form><div class="style_recommendation__SXg4e" style="opacity:1"></div></div></div><ul class="style_menuMobile__uHUfg" style="display:auto"><li><a alt="Saved Vectors" title="Saved Vectors" href="/saved/"><svg style="position:relative;top:5px;margin-left:5px;margin-right:5px" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg></a></li><li><div><svg style="position:relative;top:5px;margin-left:5px;margin-right:5px" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="21" height="21" fill="#333"><path d="M16.32 14.9l5.39 5.4a1 1 0 0 1-1.42 1.4l-5.38-5.38a8 8 0 1 1 1.41-1.41zM10 16a6 6 0 1 0 0-12 6 6 0 0 0 0 12z"></path></svg></div></li></ul><ul class="style_menu__qDQTZ"><li><a href="/collections/">Vector Collections</a></li><li><a alt="Saved Vectors" title="Saved Vectors" href="/saved/"><svg style="position:relative;top:5px;margin-left:5px;margin-right:5px" width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#333" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg></a></li></ul></div></div><div class="style_headerSpacer__lt8mM"></div><div class="style_fixed__LxyCF"><div class="style_breadCrumbs__UNVWH"><div class="style_breadCrumbsScroller__93Cu8"><a href="/"><span>Home</span></a><div><svg width="24" height="24" viewBox="0 0 24 24" fill="#e1e1e1"><path d="M8.59,16.59L13.17,12L8.59,7.41L10,6l6,6l-6,6L8.59,16.59z"></path><path fill="none" d="M0,0h24v24H0V0z"></path></svg><a href="/collections/"><span>SVG Vector</span></a></div><div><svg width="24" height="24" viewBox="0 0 24 24" fill="#e1e1e1"><path d="M8.59,16.59L13.17,12L8.59,7.41L10,6l6,6l-6,6L8.59,16.59z"></path><path fill="none" d="M0,0h24v24H0V0z"></path></svg><a href="/svg/405485/flag-for-flag-france"><span class="style_current__O54cA">Flag For Flag France</span></a></div></div></div><div class="styles_contentHolder__tGZ_5" style="opacity:1"><div class="styles_mediaDescription__RUGi3"><h1>Flag For Flag France<!-- --> SVG Vector </h1><p class="subtext" style="margin-bottom:5px">Free Download <!-- -->Flag For Flag France<!-- --> SVG vector file in monocolor and multicolor type for Sketch and Figma from <!-- -->Flag For Flag France<!-- --> Vectors svg vector collection. <!-- -->Flag For Flag France<!-- --> Vectors SVG vector illustration graphic art design format.</p><ul class="styles_manifest__YTzNu"><li><b>COLLECTION:</b> <a href="/collections/">SVG Vector</a></li><li><b>LICENSE:</b> <a target="_blank" href="/page/licensing/#CC0">CC0<!-- --> License</a></li><li><b>UPLOADER<!-- -->:</b> <a href="/">SVG Repo</a></li><li class="styles_tags__Ng0DG"><a class="tag" style="margin-left:0" href="/vectors/flag-for-flag-france/">flag for flag france</a></li></ul><div class="styles_buttons__BCMQN"><div><div class="button buttonActive" style="padding-right:35px"><a style="width:100%;display:flex;justify-content:center;align-items:center;height:100%" href="/download/405485/flag-for-flag-france.svg"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="3" stroke-linecap="round"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span>Download SVG<span> Vector</span></span></a><div class="buttonExtra"><svg height="18" width="18" viewBox="0 0 24 24" stroke="#fff" fill="none" transform="rotate(90)" stroke-width="2" stroke-linecap="round" stroke-linejoin="arcs" style="margin-left:5px"><path d="M9 18l6-6-6-6"></path></svg></div><div class="buttonOptions"><a href="/download/405485/flag-for-flag-france.svg"><li>SVG <span>Optimized</span></li></a><a href="/svg/405485/flag-for-flag-france?edit=true"><li>PNG <span>256x256</span></li></a><a href="/svg/405485/flag-for-flag-france?edit=true"><li>PNG <span>512x512</span></li></a><a href="/svg/405485/flag-for-flag-france?edit=true"><li>PNG <span>1024x1024</span></li></a></div></div></div><div style="width:15px"></div><div class="button"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="3" stroke-linecap="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><span>Save</span></div></div></div><div class="styles_mediaContent__xVExe" itemscope="" itemType="http://schema.org/ImageObject"><img alt="Flag For Flag France SVG Vector Icon" fetchpriority="high" width="250" height="250" decoding="async" data-nimg="1" style="color:transparent;width:250px;height:250px" src="/show/405485/flag-for-flag-france.svg"/><div class="styles_mediaButtons__gS452"><a href="/svg/405485/flag-for-flag-france?edit=true"><div class="button buttonSmall"><svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="2" stroke-linecap="round"><circle cx="13.5" cy="6.5" r=".5"></circle><circle cx="17.5" cy="10.5" r=".5"></circle><circle cx="8.5" cy="7.5" r=".5"></circle><circle cx="6.5" cy="12.5" r=".5"></circle><path d="M12 2C6.5 2 2 6.5 2 12s4.5 10 10 10c.926 0 1.648-.746 1.648-1.688 0-.437-.18-.835-.437-1.125-.29-.289-.438-.652-.438-1.125a1.64 1.64 0 011.668-1.668h1.996c3.051 0 5.555-2.503 5.555-5.554C21.965 6.012 17.461 2 12 2z"></path></svg><span>Edit Vector</span></div></a><span itemProp="creator" itemscope="" itemType="http://schema.org/Organization"><meta itemProp="name" content="SVG Repo"/></span><meta itemProp="author" content="SVG Repo"/><meta itemProp="name" content="Flag For Flag France SVG Vector Icon"/><meta itemProp="contentUrl" content="https://www.svgrepo.com/show/405485/flag-for-flag-france.svg"/><meta itemProp="creditText" content="SVG Repo"/><meta itemProp="copyrightNotice" content="CC0"/><meta itemProp="license" content="https://www.svgrepo.com/page/licensing/#CC0"/><meta itemProp="acquireLicensePage" content="https://www.svgrepo.com/page/licensing/#CC0"/><meta itemProp="url" content="https://www.svgrepo.com/svg/405485/flag-for-flag-france"/></div><div></div></div></div><div class="style_native__ce_K5" id="native-vector-405485" style="min-height:110px"><div class="style_nativeInline__5nS3E"><div class="style_nativeContent__6Vvo4"><div class="style_nativeImagePlaceholder___q1OM"></div><div class="style_nativeText__faLaF"><div class="style_textPlaceholder__Tlefp" style="width:60%"></div><div class="style_textPlaceholder__Tlefp" style="width:90%"></div></div></div></div><div class="style_request__p92Kt" style="opacity:0;top:10px"><h3>No Ads here 🤗</h3><p style="font-size:15px">Instead, you can give us a <a href="http://twitter.com/share?text=Check%20out%20SVG%20Repo%21%0AFree%20500.000%20Open%20Licensed%20SVG%20Vector%20and%20Icons%0A%F0%9F%91%87&amp;url=https://www.svgrepo.com/ @svgrepo" target="_blank" rel="noreferrer">Share on Twitter.</a></p><p style="position:absolute;top:20px;right:20px;padding:1px;padding-left:10px;padding-right:10px;border-radius:50px;cursor:pointer;background-color:#fafafa">×</p></div></div><div class="carrier"><div class="content"><div class="compact"><h2>SVG Vector<!-- --> SVG Vectors</h2><p class="description">Flag For Flag France<!-- --> SVG Vector is a part of <!-- -->SVG Vector<!-- --> vector collection. Following vectors are from the same pack as this vector also checkout all <!-- -->SVG Vector<!-- --> icons and vectors.</p></div><div class="style_nodeListing__7Nmro"><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div></div><a href="/collections/"><div class="button" style="margin-bottom:15px"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="3" stroke-linecap="round"><path d="M5 12h13M12 5l7 7-7 7"></path></svg><span>See All Collection</span></div></a><div class="style_native__ce_K5" id="native-vector-405485-2" style="min-height:80px"><div class="style_nativeInline__5nS3E"><div class="style_nativeContent__6Vvo4"><div class="style_nativeImagePlaceholder___q1OM"></div><div class="style_nativeText__faLaF"><div class="style_textPlaceholder__Tlefp" style="width:60%"></div><div class="style_textPlaceholder__Tlefp" style="width:90%"></div></div></div></div><div class="style_request__p92Kt" style="opacity:0;top:10px"><h3>No Ads here 🤗</h3><p style="font-size:15px">Instead, you can give us a <a href="http://twitter.com/share?text=Check%20out%20SVG%20Repo%21%0AFree%20500.000%20Open%20Licensed%20SVG%20Vector%20and%20Icons%0A%F0%9F%91%87&amp;url=https://www.svgrepo.com/ @svgrepo" target="_blank" rel="noreferrer">Share on Twitter.</a></p><p style="position:absolute;top:20px;right:20px;padding:1px;padding-left:10px;padding-right:10px;border-radius:50px;cursor:pointer;background-color:#fafafa">×</p></div></div><h2>Flag For Flag France<!-- --> SVG Vectors</h2><p class="description">Checkout other <!-- -->Flag For Flag France<!-- --> Vectors with different styles in SVG vector and icon library.</p><div class="style_nodeListing__7Nmro"><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div><div class="style_Node__GkK82"><div class="style_NodeImage__FiBL5"><div class="style_loading__ImzqA"></div></div><div class="style_action__wYD0A"><svg class="" title="Like undefined SVG File" width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z"></path></svg><svg width="21" height="21" viewBox="0 0 24 24" fill="none" stroke="#8899a4" stroke-width="2" stroke-linecap="square" stroke-linejoin="arcs"><path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path></svg><span class="style_actionTitle__o1rFS"> SVG Icon</span></div></div></div><a href="/vectors/flag-for-flag-france/"><div class="button"><svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#000" stroke-width="3" stroke-linecap="round"><path d="M5 12h13M12 5l7 7-7 7"></path></svg><span>See More <span>Flag For Flag France<!-- --> </span>Vectors</span></div></a></div></div></div><div class="style_flexbarHolder__DgQcl"><div class="style_flexbar__DvWpX" id="native-flex-svg-405485-flag-for-flag-france"></div></div><div class="style_footerCarrier__SziG4"><h3 style="height:0;overflow:hidden;padding:0;margin:0">Website Content</h3><div class="style_footer__Ozqwl"><div class="style_footerInner__HZ_6Q"><div class="style_footerLogoHolder__zWQrk"><a id="footer" href="/"><span class="style_logoHolder__vMETC"><img alt="SVG Repo - Search, explore, edit and share open licensed SVG vectors" loading="lazy" width="100" height="30" decoding="async" data-nimg="1" class="style_logo___nBAe" style="color:transparent" src="/logo.svg"/></span></a><p>Search, explore, edit and share open-licensed SVG vectors</p><div class="style_socialLinks__Bvs4v"><a href="https://twitter.com/svgrepo" target="_blank" rel="noopener noreferrer"><img alt="SVG Repo Twitter" loading="lazy" width="21" height="21" decoding="async" data-nimg="1" style="color:transparent" src="/_next/static/media/twitter.29b6fbd9.svg"/></a><a href="https://instagram.com/svgrepo" target="_blank" rel="noopener noreferrer"><img alt="SVG Repo Instagram" loading="lazy" width="21" height="21" decoding="async" data-nimg="1" style="color:transparent" src="/_next/static/media/instagram.7062f55e.svg"/></a><a href="https://dribbble.com/svgrepo" target="_blank" rel="noopener noreferrer"><img alt="SVG Repo Dribbble" loading="lazy" width="21" height="21" decoding="async" data-nimg="1" style="color:transparent" src="/_next/static/media/dribbble.e6cbf389.svg"/></a><a href="https://producthunt.com/products/svgrepo" target="_blank" rel="noopener noreferrer"><img alt="SVG Repo ProductHunt" loading="lazy" width="21" height="21" decoding="async" data-nimg="1" style="color:transparent" src="/_next/static/media/producthunt.fabbb697.svg"/></a></div><div style="height:60px"><div><div id="footer-native-native-flex-svg-405485-flag-for-flag-france"></div></div></div></div><div><h4>Free Vectors</h4><ul><li><a href="/collections/monocolor/">Monocolor Vectors</a></li><li><a href="/collections/multicolor/">Multicolor Vectors</a></li><li><a href="/collections/filled/">Filled Vectors</a></li><li><a href="/collections/outlined/">Outlined Vectors</a></li><li><a href="/collections/icon/">Icon Vectors</a></li></ul></div><div><h4>Other Collections</h4><ul><li><a href="/collections/icon/">Glyphs Vectors</a></li><li><a href="/collections/circular/">Circular Vectors</a></li><li><a href="/collections/duotone/">Duotone Vectors</a></li><li><a href="/collections/flat/">Flat Vectors</a></li><li><a href="https://upload.svgrepo.com" target="_blank" rel="noopener">Submit Assets</a></li></ul></div><div><h4>Developers / Designers</h4><ul><li><a href="/tools/">Free Tools</a></li><li><a href="https://www.svgapi.com" target="_blank" rel="noopener">Icon API</a></li><li><a href="https://vectormaker.co" target="_blank" rel="noopener">vectormaker</a></li><li><a href="https://www.fontrepo.com" target="_blank" rel="noopener">Font Repo</a></li><li><a href="https://svgfind.com" target="_blank" rel="noopener">SVG Find</a></li></ul></div></div><div class="style_footerBottom__l8wqE"><div>© <!-- -->2024<!-- --> · SVG Repo LLC</div><div><a href="/page/terms-of-use/">Terms of Use</a><a href="/page/privacy-policy/">Privacy Policy</a><a href="/page/licensing/">Licensing</a><a href="/page/contact/">Contact</a></div></div></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"ssrIcon":{"id":"405485","slug":"flag-for-flag-france","title":"flag-for-flag-france","similar":[false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false,false]}},"__N_SSP":true},"page":"/svg/[[...param]]","query":{"param":["405485/flag-for-flag-france"]},"buildId":"9UdWXZJ2dR-D_IkpQGEy7","isFallback":false,"dynamicIds":[451,6929,2293],"gssp":true,"customServer":true,"scriptLoader":[]}</script><script nomodule="" src="/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script async="" src="/_next/static/chunks/400-cf97d6bdbdf0f340.js"></script><script async="" src="/_next/static/chunks/451.5f026fc39acc1202.js"></script><script async="" src="/_next/static/chunks/929.0b4636598979df75.js"></script><script async="" src="/_next/static/chunks/293.58b6d7eb60abc47f.js"></script><script src="/_next/static/chunks/webpack-915b915b0059e2ac.js" async=""></script><script src="/_next/static/chunks/framework-63157d71ad419e09.js" async=""></script><script src="/_next/static/chunks/main-76fff4db6e2e1f3e.js" async=""></script><script src="/_next/static/chunks/pages/_app-14ac00e97c23b48c.js" async=""></script><script src="/_next/static/chunks/914-237739ac1bf6acde.js" async=""></script><script src="/_next/static/chunks/675-bbaffee85ab26582.js" async=""></script><script src="/_next/static/chunks/962-5f0fda52dcac7bd5.js" async=""></script><script src="/_next/static/chunks/28-3a8558ea2bc8e2bd.js" async=""></script><script src="/_next/static/chunks/454-8e7fbd1b315808b6.js" async=""></script><script src="/_next/static/chunks/pages/svg/%5B%5B...param%5D%5D-6f17f889eae5f5f5.js" async=""></script><script src="/_next/static/9UdWXZJ2dR-D_IkpQGEy7/_buildManifest.js" async=""></script><script src="/_next/static/9UdWXZJ2dR-D_IkpQGEy7/_ssgManifest.js" async=""></script></body></html>
static/js/pdf.js CHANGED
@@ -8,8 +8,10 @@ const reset = document.getElementById("reset");
8
  const imagePreview = dropArea.querySelector("#image-preview");
9
  const currentClassProbabilitiesList = document.getElementById("class-probabilities");
10
  const currentPredictedClass = document.getElementById('predicted-class')
 
11
  const staticDiv = document.getElementById("static");
12
  const dynamicDiv = document.getElementById("dynamic");
 
13
  var chartData;
14
  let file;
15
 
@@ -115,9 +117,21 @@ form.addEventListener("submit", (event) => {
115
  currentClassProbabilitiesList.innerHTML = classProbabilitiesList.innerHTML;
116
  const PredictedClass = responseDOM.getElementById("predicted-class")
117
  currentPredictedClass.innerHTML = PredictedClass.innerHTML;
 
 
 
118
  dynamicDiv.classList.remove('d-none');
119
  staticDiv.classList.add('d-none');
120
-
 
 
 
 
 
 
 
 
 
121
  var canvasElement = responseDOM.querySelector('.bestSellers'); // Sélectionnez le premier élément avec la classe 'bestSellers'
122
  chartData = canvasElement.getAttribute('data-chart');
123
  var data = JSON.parse(chartData).datasets[0].data.slice(0, 5);
 
8
  const imagePreview = dropArea.querySelector("#image-preview");
9
  const currentClassProbabilitiesList = document.getElementById("class-probabilities");
10
  const currentPredictedClass = document.getElementById('predicted-class')
11
+ const sentencePredictions = document.getElementById('classifiedText')
12
  const staticDiv = document.getElementById("static");
13
  const dynamicDiv = document.getElementById("dynamic");
14
+ const sentenceResultDiv = document.getElementById("dynamicResult");
15
  var chartData;
16
  let file;
17
 
 
117
  currentClassProbabilitiesList.innerHTML = classProbabilitiesList.innerHTML;
118
  const PredictedClass = responseDOM.getElementById("predicted-class")
119
  currentPredictedClass.innerHTML = PredictedClass.innerHTML;
120
+ document.getElementById('transcribedText').innerHTML = responseDOM.getElementById('transcribedText').innerHTML;
121
+ const sentencePredictionsResponse= responseDOM.getElementById('classifiedText').innerHTML;
122
+ sentencePredictions.innerHTML = sentencePredictionsResponse;
123
  dynamicDiv.classList.remove('d-none');
124
  staticDiv.classList.add('d-none');
125
+ sentenceResultDiv.classList.remove('d-none');
126
+ setTimeout(() => {
127
+ const resultsDiv = document.getElementById('dynamicResult');
128
+ if (resultsDiv) {
129
+ resultsDiv.scrollIntoView({ behavior: 'smooth', block: 'start' });
130
+ }
131
+ }, 100);
132
+ if (resultsHeading) {
133
+ resultsHeading.scrollIntoView({ behavior: 'smooth' });
134
+ }
135
  var canvasElement = responseDOM.querySelector('.bestSellers'); // Sélectionnez le premier élément avec la classe 'bestSellers'
136
  chartData = canvasElement.getAttribute('data-chart');
137
  var data = JSON.parse(chartData).datasets[0].data.slice(0, 5);
static/js/pdf_fr.js ADDED
@@ -0,0 +1,236 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const dropArea = document.getElementById("dropArea");
2
+ const dragText = dropArea.querySelector("h6");
3
+ const input = dropArea.querySelector("input");
4
+ const form = document.querySelector("form");
5
+ const ocrResult = document.getElementById("ocr-result");
6
+ const categoryResult = document.getElementById("category-result")
7
+ const reset = document.getElementById("reset");
8
+ const imagePreview = dropArea.querySelector("#image-preview");
9
+ const currentClassProbabilitiesList = document.getElementById("class-probabilities");
10
+ const currentPredictedClass = document.getElementById('predicted-class')
11
+ const sentencePredictions = document.getElementById('classifiedText')
12
+ const staticDiv = document.getElementById("static");
13
+ const dynamicDiv = document.getElementById("dynamic");
14
+ const sentenceResultDiv = document.getElementById("dynamicResult");
15
+ var chartData;
16
+ let file;
17
+
18
+
19
+
20
+ // Event listener for clicking the dropArea to upload a file
21
+ dropArea.addEventListener("click", () => {
22
+ // Trigger click event on the file input when the dropArea is clicked
23
+ const input = document.getElementById("file-input");
24
+ input.click();
25
+ });
26
+
27
+ // Update the event listener for input change to handle file selection
28
+ const fileInput = document.getElementById("file-input");
29
+ fileInput.addEventListener("change", function () {
30
+ file = this.files[0];
31
+ dropArea.classList.add("active");
32
+ viewFile();
33
+ });
34
+
35
+
36
+ input.addEventListener("change", function () {
37
+ file = this.files[0];
38
+ dropArea.classList.add("active");
39
+ viewFile();
40
+ });
41
+
42
+ dropArea.addEventListener("dragover", (event) => {
43
+ event.preventDefault();
44
+ dropArea.classList.add("active");
45
+ dragText.textContent = "Release to Upload File";
46
+ });
47
+
48
+ dropArea.addEventListener("dragleave", () => {
49
+ dropArea.classList.remove("active");
50
+ dragText.textContent = "Drag & Drop or Click to Upload File";
51
+ });
52
+
53
+ dropArea.addEventListener("drop", (event) => {
54
+ event.preventDefault();
55
+ file = event.dataTransfer.files[0];
56
+ viewFile();
57
+ });
58
+
59
+ // Définir la fonction initializeChart en premier
60
+ function initializeChart(data, backgroundColor, borderColor, labels) {
61
+ // Créer une nouvelle instance Chart.js pour chaque élément canvas avec la classe 'bestSellers'
62
+ data = data.map(function (element) {
63
+ return parseFloat(element).toFixed(2);
64
+ });
65
+ document.querySelectorAll('.bestSellers').forEach(function (canvas) {
66
+ // Initialiser le graphique
67
+ new Chart(canvas, {
68
+ type: 'doughnut', // Définir le type de graphique sur doughnut
69
+ data: {
70
+ datasets: [{
71
+ data: data,
72
+ backgroundColor: backgroundColor,
73
+ borderColor: borderColor,
74
+ }],
75
+ labels: labels
76
+ },
77
+ options: {
78
+ responsive: true, // Rendre le graphique responsive
79
+ cutoutPercentage: 80, // Définir le pourcentage de découpe
80
+ legend: {
81
+ display: false, // Masquer la légende
82
+ },
83
+ animation: {
84
+ animateScale: true,
85
+ animateRotate: true
86
+ },
87
+ plugins: {
88
+ datalabels: {
89
+ display: false,
90
+ align: 'center',
91
+ anchor: 'center'
92
+ }
93
+ }
94
+ }
95
+ });
96
+ });
97
+ }
98
+
99
+ form.addEventListener("submit", (event) => {
100
+ event.preventDefault();
101
+ if (!file) {
102
+ alert("Please select a file!");
103
+ return;
104
+ }
105
+ const formData = new FormData();
106
+ formData.append("file", file);
107
+ fetch("/pdf_fr/upload", {
108
+ method: "POST",
109
+ body: formData,
110
+ })
111
+ .then((response) => response.text())
112
+ .then((html) => {
113
+ const responseDOM = new DOMParser().parseFromString(html, "text/html");
114
+ const resultTextArea = responseDOM.getElementById("ocr-result");
115
+ ocrResult.value = resultTextArea.value;
116
+ const classProbabilitiesList = responseDOM.getElementById("class-probabilities");
117
+ currentClassProbabilitiesList.innerHTML = classProbabilitiesList.innerHTML;
118
+ const PredictedClass = responseDOM.getElementById("predicted-class")
119
+ currentPredictedClass.innerHTML = PredictedClass.innerHTML;
120
+ document.getElementById('transcribedText').innerHTML = responseDOM.getElementById('transcribedText').innerHTML;
121
+ const sentencePredictionsResponse= responseDOM.getElementById('classifiedText').innerHTML;
122
+ sentencePredictions.innerHTML = sentencePredictionsResponse;
123
+ dynamicDiv.classList.remove('d-none');
124
+ staticDiv.classList.add('d-none');
125
+ sentenceResultDiv.classList.remove('d-none');
126
+ setTimeout(() => {
127
+ const resultsDiv = document.getElementById('dynamicResult');
128
+ if (resultsDiv) {
129
+ resultsDiv.scrollIntoView({ behavior: 'smooth', block: 'start' });
130
+ }
131
+ }, 100);
132
+ if (resultsHeading) {
133
+ resultsHeading.scrollIntoView({ behavior: 'smooth' });
134
+ }
135
+ var canvasElement = responseDOM.querySelector('.bestSellers'); // Sélectionnez le premier élément avec la classe 'bestSellers'
136
+ chartData = canvasElement.getAttribute('data-chart');
137
+ var data = JSON.parse(chartData).datasets[0].data.slice(0, 5);
138
+ var backgroundColor = JSON.parse(chartData).datasets[0].backgroundColor.slice(0, 5);
139
+ var borderColor = JSON.parse(chartData).datasets[0].borderColor.slice(0, 5);
140
+ var labels = JSON.parse(chartData).labels.slice(0, 5);
141
+
142
+ // Créer de nouveaux graphiques
143
+ loadDashboardScript(data, backgroundColor, borderColor, labels);
144
+ })
145
+ .catch((error) => console.error(error));
146
+ });
147
+
148
+ function destroyPreviousCharts() {
149
+ // Trouver tous les éléments canvas avec la classe 'bestSellers'
150
+ document.querySelectorAll('.bestSellers').forEach(function (canvas) {
151
+ // Récupérer l'instance du graphique
152
+ var chartInstance = Chart.getChart(canvas);
153
+ // Si une instance existe, détruire le graphique
154
+ if (chartInstance) {
155
+ chartInstance.destroy();
156
+ }
157
+ });
158
+ }
159
+
160
+ function loadDashboardScript(data, backgroundColor, borderColor, labels) { // Correction ici
161
+ var scriptElement = document.createElement('script');
162
+ scriptElement.type = 'text/javascript';
163
+ scriptElement.src = '../static/js/dashboard_pdf.js';
164
+ // Attendez que le script soit chargé avant d'appeler la fonction d'initialisation
165
+ scriptElement.onload = function () {
166
+ initializeChart(data, backgroundColor, borderColor, labels);
167
+ };
168
+ document.body.appendChild(scriptElement);
169
+ }
170
+
171
+
172
+ // Define the original HTML structure of the drop area
173
+ const originalDropAreaHTML = `
174
+ <h6 class="text-white-50">Drag and Drop File Here</h6>
175
+ <span class="text-white-50">OR</span>
176
+ <h6 class="text-white-50">Click here</h6>
177
+ <input id="file-input" type="file" name="image" accept=".pdf" hidden>
178
+ `;
179
+
180
+ function deleteCurrentFile() {
181
+ // Recharger le fichier index.js après l'envoi du formulaire
182
+ window.location.reload();
183
+ file = null;
184
+
185
+ // Restore the original HTML structure
186
+ dropArea.innerHTML = originalDropAreaHTML;
187
+
188
+ // Remove the 'active' class to reset the styling
189
+ dropArea.classList.remove("active");
190
+
191
+ // Update the event listener for input change to handle file selection
192
+ const fileInput = document.getElementById("file-input");
193
+
194
+ fileInput.addEventListener("change", function () {
195
+ file = this.files[0];
196
+ dropArea.classList.add("active");
197
+ viewFile();
198
+ });
199
+ }
200
+
201
+
202
+ function viewFile() {
203
+ let fileType = file.type;
204
+ let validExtensions = ["application/pdf"];
205
+ if (validExtensions.includes(fileType)) {
206
+ let fileURL = URL.createObjectURL(file);
207
+ let pdfTag = `<iframe src="${fileURL}" style="width:100%;height:100%;"></iframe>`;
208
+ dropArea.innerHTML = pdfTag;
209
+ } else {
210
+ alert("This is not a PDF File!");
211
+ dropArea.classList.remove("active");
212
+ dragText.textContent = "Drag & Drop or Click to Upload File";
213
+ }
214
+ }
215
+
216
+ const copyBtn = document.getElementById("copy-btn");
217
+
218
+ copyBtn.addEventListener("click", () => {
219
+ ocrResult.select();
220
+ document.execCommand("copy");
221
+ });
222
+
223
+ function createResponseElement(response) {
224
+ var pdfResponseElement = document.createElement('ul');
225
+ pdfResponseElement.classList.add('graph-legend-rectangle');
226
+ pdfResponseElement.innerHTML = response;
227
+ return pdfResponseElement;
228
+ }
229
+
230
+ // Modifiez la fonction reloadDashboardScript pour accepter les données supplémentaires
231
+ function reloadDashboardScript(data, backgroundColor, borderColor, labels) {
232
+ var scriptElement = document.createElement('script');
233
+ scriptElement.type = 'text/javascript';
234
+ scriptElement.src = `../static/js/dashboard_pdf.js?data=${encodeURIComponent(JSON.stringify(data))}&backgroundColor=${encodeURIComponent(JSON.stringify(backgroundColor))}&borderColor=${encodeURIComponent(JSON.stringify(borderColor))}&labels=${encodeURIComponent(JSON.stringify(labels))}`;
235
+ document.body.appendChild(scriptElement);
236
+ }
static/js/sentence_fr.js ADDED
@@ -0,0 +1,253 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ var chartData;
2
+ function generateUniqueId() {
3
+ return 'chart-' + Date.now(); // Utilisez un timestamp comme identifiant unique
4
+ }
5
+
6
+ function submitForm() {
7
+ event.preventDefault(); // Prevent the default form submission
8
+
9
+ var form = document.getElementById('sentenceForm');
10
+ var textarea = document.getElementById("ocr-result");
11
+
12
+ // Check if the textarea is empty
13
+ if (textarea.value.trim() === "") {
14
+ textarea.setCustomValidity("Input is required."); // Set custom validation message
15
+ textarea.reportValidity(); // Display the validation message
16
+ return; // Do not proceed with form submission
17
+ } else {
18
+ textarea.setCustomValidity(""); // Clear any previous validation message
19
+ }
20
+ $
21
+ var formData = new FormData(form);
22
+
23
+ // Hide the presentation div
24
+ var presentationDiv = document.getElementById('presentation');
25
+ presentationDiv.classList.add('d-none');
26
+
27
+ // Send a POST request to the Flask route with the form data
28
+ fetch('/sentence_fr', {
29
+ method: 'POST',
30
+ body: formData
31
+ })
32
+ .then(response => response.text())
33
+ .then(data => {
34
+
35
+ // Reset the textarea height to its initial value
36
+ var textarea = document.getElementById("ocr-result");
37
+ textarea.style.height = "50px";
38
+
39
+ // Add the new user message to the chat conversation
40
+ var userMessageElement = createUserMessageElement(formData.get('text'));
41
+ var chatConversation = document.querySelector('.chat-conversation-content .os-content');
42
+ chatConversation.appendChild(userMessageElement);
43
+
44
+ // Create a new message element for Flask response
45
+ var flaskResponseElement = createFlaskResponseElement(data);
46
+ // Append the Flask response as a left message to the chat conversation
47
+ chatConversation.appendChild(flaskResponseElement);
48
+ var canvasElement = document.querySelector('.bestSellers'); // Sélectionnez le premier élément avec la classe 'bestSellers'
49
+ chartData = canvasElement.getAttribute('data-chart');
50
+ var data = JSON.parse(chartData).datasets[0].data.slice(0, 5);
51
+ var backgroundColor = JSON.parse(chartData).datasets[0].backgroundColor.slice(0, 5);
52
+ var borderColor = JSON.parse(chartData).datasets[0].borderColor.slice(0, 5);
53
+ var labels = JSON.parse(chartData).labels.slice(0, 5);
54
+ // Scroll to the bottom of the chat conversation
55
+ addAutoResize();
56
+ scrollDown();
57
+ // Clear the textarea after submitting
58
+ form.reset();
59
+ // Create a new canvas element for the new chart
60
+ var canvasId = generateUniqueId();
61
+ var canvasHTML = document.getElementById('bestSellers#');
62
+ canvasHTML.id = generateUniqueId();
63
+ canvasId = canvasHTML.id;
64
+
65
+ // Update the new chart with data
66
+ updateChart(canvasId);
67
+ })
68
+ .catch(error => console.error('Error:', error));
69
+ }
70
+ function updateChart(canvasId) {
71
+ var canvas = document.getElementById(canvasId);
72
+ var chartData = JSON.parse(canvas.dataset.chart);
73
+ var data = chartData.datasets[0].data.slice(0, 5).map(function(element) {
74
+ return parseFloat(element).toFixed(2);
75
+ });
76
+ var backgroundColor = chartData.datasets[0].backgroundColor.slice(0,5);
77
+ var borderColor = chartData.datasets[0].borderColor.slice(0,5);
78
+ var labels = chartData.labels.slice(0,5);
79
+ var Data = {
80
+ datasets: [{
81
+ data: data,
82
+ backgroundColor:
83
+ backgroundColor
84
+ ,
85
+ borderColor: backgroundColor,
86
+ }],
87
+ // These labels appear in the legend and in the tooltips when hovering different arcs
88
+ labels: labels
89
+ };
90
+ var pieChart = new Chart(canvas, {
91
+ type: 'doughnut',
92
+ data: Data,
93
+ options: {
94
+ responsive: true, // Rendre le graphique responsive
95
+ cutoutPercentage: 80, // Définir le pourcentage de découpe
96
+ legend: {
97
+ display: false, // Masquer la légende
98
+ },
99
+ animation: {
100
+ animateScale: true,
101
+ animateRotate: true
102
+ },
103
+ plugins: {
104
+ datalabels: {
105
+ display: false,
106
+ align: 'center',
107
+ anchor: 'center'
108
+ }
109
+ }
110
+ }
111
+ });
112
+ }
113
+
114
+
115
+ function handleEnter(event) {
116
+ if (event.key === "Enter" && !event.shiftKey) {
117
+ event.preventDefault(); // Prevent default behavior (line break)
118
+ submitForm(); // Submit the form asynchronously
119
+ }
120
+ }
121
+
122
+
123
+ document.getElementById('sentenceForm').addEventListener('submit', function (event) {
124
+ event.preventDefault(); // Prevent the form from submitting normally
125
+ var form = event.target;
126
+ var formData = new FormData(form);
127
+
128
+ // Hide the presentation div
129
+ var presentationDiv = document.getElementById('presentation');
130
+ presentationDiv.classList.add('d-none');
131
+
132
+ // Send a POST request to the Flask route with the form data
133
+ fetch('/sentence_fr', {
134
+ method: 'POST',
135
+ body: formData
136
+ })
137
+ .then(response => response.text())
138
+ .then(data => {
139
+
140
+ // Reset the textarea height to its initial value
141
+ var textarea = document.getElementById("ocr-result");
142
+ textarea.style.height = "50px";
143
+ // Add the new user message to the chat conversation
144
+ var userMessageElement = createUserMessageElement(formData.get('text'));
145
+ var chatConversation = document.querySelector('.chat-conversation-content .os-content');
146
+ chatConversation.appendChild(userMessageElement);
147
+
148
+ // Create a new message element for Flask response
149
+ var flaskResponseElement = createFlaskResponseElement(data);
150
+
151
+ // Append the Flask response as a left message to the chat conversation
152
+ chatConversation.appendChild(flaskResponseElement);
153
+ var canvasElement = document.querySelector('.bestSellers'); // Sélectionnez le premier élément avec la classe 'bestSellers'
154
+ chartData = canvasElement.getAttribute('data-chart');
155
+ var data = JSON.parse(chartData).datasets[0].data.slice(0, 5);
156
+ var backgroundColor = JSON.parse(chartData).datasets[0].backgroundColor.slice(0, 5);
157
+ var borderColor = JSON.parse(chartData).datasets[0].borderColor.slice(0, 5);
158
+ var labels = JSON.parse(chartData).labels.slice(0, 5);
159
+ addAutoResize();
160
+ scrollDown();
161
+ // Clear the textarea after submitting
162
+ form.reset();
163
+ // Create a new canvas element for the new chart
164
+ var canvasId = generateUniqueId();
165
+ var canvasHTML = document.getElementById('bestSellers#');
166
+ canvasHTML.id = generateUniqueId();
167
+ canvasId = canvasHTML.id;
168
+
169
+ // Update the new chart with data
170
+ updateChart(canvasId);
171
+ })
172
+ .catch(error => console.error('Error:', error));
173
+ });
174
+
175
+ // Function to create a message element for user's message
176
+ function createUserMessageElement(message) {
177
+ var userMessageElement = document.createElement('div');
178
+ userMessageElement.classList.add('d-flex', 'justify-content-end', 'text-end', 'mb-1');
179
+ var userMessageSubElement = document.createElement('div');
180
+ userMessageSubElement.classList.add('w-100');
181
+ var userMessageContainer = document.createElement('div');
182
+ userMessageContainer.classList.add('d-flex', 'flex-column', 'align-items-end');
183
+ // Add message content
184
+ var userMessageContent = document.createElement('div');
185
+ userMessageContent.classList.add('bg-primary', 'text-white', 'p-2', 'px-3', 'rounded-2', 'mw-80');
186
+ var userMessageText = document.createTextNode(message);
187
+ userMessageContent.appendChild(userMessageText);
188
+ userMessageContainer.appendChild(userMessageContent);
189
+ userMessageSubElement.appendChild(userMessageContainer);
190
+ userMessageElement.appendChild(userMessageSubElement);
191
+ return userMessageElement;
192
+ }
193
+
194
+ // Function to create a message element for Flask response
195
+ function createFlaskResponseElement(response) {
196
+ var flaskResponseElement = document.createElement('div');
197
+ flaskResponseElement.classList.add('d-flex', 'mb-1');
198
+ var flaskAvatarElement = document.createElement('div');
199
+ flaskAvatarElement.classList.add('flex-shrink-0', 'avatar', 'avatar-xs', 'me-2');
200
+ var flaskAvatarImg = document.createElement('img');
201
+ flaskAvatarImg.classList.add('avatar-img', 'rounded-circle');
202
+ flaskAvatarImg.setAttribute('src', '../static/icons/logo_header_128x128.png');
203
+ flaskAvatarElement.appendChild(flaskAvatarImg);
204
+ var flaskMessageContent = document.createElement('div');
205
+ flaskMessageContent.classList.add('flex-grow-1');
206
+ flaskMessageContent.innerHTML = response;
207
+ flaskResponseElement.appendChild(flaskAvatarElement);
208
+ flaskResponseElement.appendChild(flaskMessageContent);
209
+ return flaskResponseElement;
210
+ }
211
+ // Function to reload the dashboard.js file with chartData
212
+ function reloadDashboardScript(data, backgroundColor, borderColor, labels) {
213
+ // Create a new script element
214
+ var scriptElement = document.createElement('script');
215
+ scriptElement.type = 'text/javascript';
216
+ scriptElement.onload = function () {
217
+ initializeChart(data, backgroundColor, borderColor, labels);
218
+ };
219
+ // Add chartData to the script source as a query parameter
220
+ scriptElement.src = `../static/js/dashboard_sentence.js?data=${data}&backgroundColor=${backgroundColor}&borderColor=${borderColor}&labels=${labels}`;
221
+
222
+ // Append the script element to the body
223
+ document.body.appendChild(scriptElement);
224
+ }
225
+ // START: 12 Auto resize textarea
226
+ function addAutoResize() {
227
+ document.querySelectorAll('[data-autoresize]').forEach(function (element) {
228
+ element.style.boxSizing = 'border-box';
229
+ var offset = element.offsetHeight - element.clientHeight;
230
+ element.addEventListener('input', function (event) {
231
+ event.target.style.height = 'auto';
232
+ event.target.style.height = event.target.scrollHeight + offset + 'px';
233
+ });
234
+ element.removeAttribute('data-autoresize');
235
+ });
236
+ }
237
+ // SCROLLDOWN
238
+ function scrollDown() {
239
+ var objDiv = document.getElementsByClassName("os-viewport os-viewport-native-scrollbars-invisible");
240
+ var index = 0;
241
+ while (index < objDiv.length) {
242
+ objDiv[index].scrollTop = objDiv[index].scrollHeight;
243
+ index++;
244
+ }
245
+ }
246
+
247
+ // RESIZE TEXTAREA
248
+ function resizeTextarea(textarea) {
249
+ textarea.style.height = "auto";
250
+ textarea.style.height = textarea.scrollHeight + "px";
251
+ }
252
+
253
+
templates/pdf.html CHANGED
@@ -2,7 +2,7 @@
2
  <html lang="en-US">
3
 
4
  <head>
5
- <title>OCR</title>
6
  <link rel="icon" href="https://cdn-icons-png.flaticon.com/512/5262/5262072.png">
7
  <link rel="stylesheet" href="../static/css/style2.css">
8
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
@@ -45,6 +45,14 @@
45
  <li class="nav-item nav-pills nav-pills-ocr">
46
  <a class="nav-item nav-link " href="voice">SLU</a>
47
  </li>
 
 
 
 
 
 
 
 
48
  </ul>
49
  </div>
50
  <!-- Main navbar END -->
@@ -79,12 +87,12 @@
79
  <div class="col-12 d-flex justify-content-center">
80
  <div class="col-sm-12 d-inline align-items-center" style="height: 175px; width: 229px;">
81
  <div class="flex-shrink-0 avatar avatar-lg me-2 mb-3 mt-4">
82
- <img class="avatar-img rounded-circle"
83
- src="../static/icons/logo_header_128x128.png" alt="">
84
  </div>
85
  <h5 class="card-title text-white-50">Get more insights about your pdf 📑📑.</h5>
86
  </div>
87
-
88
  </div>
89
  </div>
90
  <div class="card-body d-none" id="dynamic">
@@ -128,6 +136,36 @@
128
 
129
  <!-- Right sidebar END -->
130
  </div> <!-- Row END -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  </div>
132
  </main>
133
 
 
2
  <html lang="en-US">
3
 
4
  <head>
5
+ <title>Pdf Categorization</title>
6
  <link rel="icon" href="https://cdn-icons-png.flaticon.com/512/5262/5262072.png">
7
  <link rel="stylesheet" href="../static/css/style2.css">
8
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
 
45
  <li class="nav-item nav-pills nav-pills-ocr">
46
  <a class="nav-item nav-link " href="voice">SLU</a>
47
  </li>
48
+ <li class="nav-item dropdown">
49
+ <a class="nav-link" href="#" id="accounntMenu" data-bs-toggle="dropdown" aria-haspopup="true"
50
+ aria-expanded="false">language</a>
51
+ <ul class="dropdown-menu" aria-labelledby="accounntMenu">
52
+ <li> <a class="dropdown-item " href="pdf_fr"><img src="../static/icons/France.svg"
53
+ class="avatar avatar" style="height: 20px;" alt="French flag"> French </a> </li>
54
+ </ul>
55
+ </li>
56
  </ul>
57
  </div>
58
  <!-- Main navbar END -->
 
87
  <div class="col-12 d-flex justify-content-center">
88
  <div class="col-sm-12 d-inline align-items-center" style="height: 175px; width: 229px;">
89
  <div class="flex-shrink-0 avatar avatar-lg me-2 mb-3 mt-4">
90
+ <img class="avatar-img rounded-circle" src="../static/icons/logo_header_128x128.png"
91
+ alt="">
92
  </div>
93
  <h5 class="card-title text-white-50">Get more insights about your pdf 📑📑.</h5>
94
  </div>
95
+
96
  </div>
97
  </div>
98
  <div class="card-body d-none" id="dynamic">
 
136
 
137
  <!-- Right sidebar END -->
138
  </div> <!-- Row END -->
139
+
140
+ </div>
141
+ <div class="row d-sm-flex justify-content-center mb-5">
142
+ <div class="col-11">
143
+ <div class="row d-none" id='dynamicResult'>
144
+ <h1 id="resultsHeading" class="text-center text-white-50">Results</h1>
145
+ <div class="col-12">
146
+ <div class="card" style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
147
+ <div class="card-body">
148
+ <h5 class="card-title text-white mb-3">Transcribed and Classified Text</h5>
149
+ <div id="transcribedText" class="text-white-50 mb-4"></div>
150
+ <div class="text-center">
151
+ <div class="col-12 d-flex justify-content-center">
152
+ <div class="col-sm-12 d-inline align-items-center" id="classifiedText">
153
+ {% if sentences_prediction %}
154
+ {% for sentence, color in sentences_prediction.items() %}
155
+ <span class="text-bold text-start bg-{{color[1]}}">
156
+ {{sentence}}
157
+ </span>
158
+ {% endfor %}
159
+ {% endif %}
160
+ </div>
161
+ </div>
162
+ </div>
163
+ </div>
164
+ </div>
165
+ </div>
166
+ </div>
167
+ </div>
168
+
169
  </div>
170
  </main>
171
 
templates/pdf_fr.html ADDED
@@ -0,0 +1,177 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en-US">
3
+
4
+ <head>
5
+ <title>Pdf Categorization</title>
6
+ <link rel="icon" href="https://cdn-icons-png.flaticon.com/512/5262/5262072.png">
7
+ <link rel="stylesheet" href="../static/css/style2.css">
8
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
9
+ <link rel="stylesheet" href="../static/css/vendor.bundle.base.css">
10
+
11
+
12
+ </head>
13
+
14
+ <body style="background-color: #1F2020;">
15
+ <nav class="navbar navbar-expand-lg bg-ocr mb-5">
16
+ <div class="container h-100">
17
+ <!-- Logo START -->
18
+ <a class="navbar-brand" href="pdf_fr">
19
+ <img class="navbar-brand-item" src="../static/icons/avignon_universite_blanc_RVB.png" alt="logo">
20
+ </a>
21
+ <!-- Logo END -->
22
+
23
+ <!-- Responsive navbar toggler -->
24
+ <button class="navbar-toggler ms-auto icon-md btn btn-light p-0 collapsed" type="button"
25
+ data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse"
26
+ aria-expanded="false" aria-label="Toggle navigation">
27
+ <span class="navbar-toggler-animation">
28
+ <span></span>
29
+ <span></span>
30
+ <span></span>
31
+ </span>
32
+ </button>
33
+
34
+ <!-- Main navbar START -->
35
+ <div class="navbar-collapse collapse" id="navbarCollapse">
36
+ <ul class="navbar-nav navbar-nav-scroll ms-auto p-xl-0">
37
+ <!-- Nav item 1 Demos -->
38
+ <li class="nav-item nav-pills nav-pills-ocr">
39
+ <a class="nav-item nav-link active mb-5" href="pdf_fr">Classificateur PDF</a>
40
+ </li>
41
+ <!-- Nav item 2 Pages -->
42
+ <li class="nav-item nav-pills nav-pills-ocr">
43
+ <a class="nav-item nav-link " href="sentence_fr">Classificateur de texte</a>
44
+ </li>
45
+ <li class="nav-item nav-pills nav-pills-ocr">
46
+ <a class="nav-item nav-link " href="voice_fr">SLU</a>
47
+ </li>
48
+ <li class="nav-item dropdown">
49
+ <a class="nav-link" href="#" id="accounntMenu" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">langue</a>
50
+ <ul class="dropdown-menu" aria-labelledby="accounntMenu">
51
+ <li> <a class="dropdown-item " href="pdf"><img src="../static/icons/English.svg" class="avatar avatar" style="height: 20px;" alt="French flag"> English</a> </li>
52
+ </ul>
53
+ </li>
54
+ </ul>
55
+ </div>
56
+ <!-- Main navbar END -->
57
+ </div>
58
+ </nav>
59
+ <!-- Container START -->
60
+ <main>
61
+ <div class="row d-sm-flex justify-content-center ">
62
+ <div class="col-lg-6 col-11 mb-lg-0 mb-5">
63
+ <form class="" action="/pdf/upload" style="height: 88%;" id="upload-form" method="POST"
64
+ enctype="multipart/form-data">
65
+
66
+ <div class="drag-image" id="dropArea">
67
+ <div class="text-center ">
68
+ <h6 class="text-white-50 mb-3">Glisser-déposer le PDF ici</h6>
69
+ <span class="text-white-50">OU</span>
70
+ <h6 class="text-white-50 mt-3">Cliquez ici</h6>
71
+ <input id="file-input" type="file" name="image" accept=".pdf" hidden>
72
+ </div>
73
+ </div>
74
+ <div class="d-flex justify-content-center">
75
+ <button class="btn me-3 btn-ocr" id="reset" type="button" onclick="deleteCurrentFile()"> <i
76
+ class="bi bi-pencil-fill pe-1"></i> Supprimer </button>
77
+ <button type="submit" class="btn ms-3 btn-ocr">Envoyer</button>
78
+ </div>
79
+ </form>
80
+ </div>
81
+ <!-- la categorie la plus dominante-->
82
+ <div class="col-lg-5 col-xl-5 col-11 mt-5 mt-lg-0">
83
+ <div class="card" style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
84
+ <div class="card-body text-center" id="static">
85
+ <div class="col-12 d-flex justify-content-center">
86
+ <div class="col-sm-12 d-inline align-items-center" style="height: 175px; width: 260px;">
87
+ <div class="flex-shrink-0 avatar avatar-lg me-2 mb-3 mt-4">
88
+ <img class="avatar-img rounded-circle"
89
+ src="../static/icons/logo_header_128x128.png" alt="">
90
+ </div>
91
+ <h5 class="card-title text-white-50">Obtenez plus d'informations sur votre pdf 📑📑.</h5>
92
+ </div>
93
+
94
+ </div>
95
+ </div>
96
+ <div class="card-body d-none" id="dynamic">
97
+ <h4 class="card-title text-white">Catégorie du texte</h4>
98
+ <div class="row d-flex">
99
+ <div class="col-sm-7 col-6">
100
+ <ul class="graphl-legend-rectangle" id="class-probabilities">
101
+ {% for class_label, probability in class_probabilities.items() %}
102
+ {% if loop.index <= 5 %} <li class="text-white-50">
103
+ <span class="bg-{{ class_label[1] }}"></span>
104
+ <div class="d-flex justify-content-center">
105
+ {{ class_label[0] }}:
106
+ <span class="text-white w-100">&nbsp;{{ "%.2f" % probability }}%</span>
107
+ </div>
108
+ </li>
109
+ {% endif %}
110
+ {% endfor %}
111
+ </ul>
112
+ </div>
113
+ <div class="col-sm-5 grid-margin col-6">
114
+ <canvas class="bestSellers" data-chart='{{ chart_data | tojson | safe }}'
115
+ id="bestSellers#"></canvas>
116
+ </div>
117
+ </div>
118
+ <div class="mb-lg-0 text-white-50">
119
+ la classe la plus dominante est <span class="fw-bolder text-white" id="predicted-class">{{
120
+ predicted_class[0]
121
+ }}</span>
122
+ </div>
123
+ </div>
124
+ </div>
125
+ <!-- <div class="">
126
+ <textarea id="category-result" readonly>{{predicted_class}}</textarea>
127
+ </div> -->
128
+
129
+ <div class="result mt-3">
130
+ <h6 class="text-start">Texte extrait</h6>
131
+ <textarea id="ocr-result" readonly>{{extracted_text}}</textarea>
132
+ <button id="copy-btn" class="btn btn-ocr">Copier</button>
133
+ </div>
134
+
135
+ <!-- Right sidebar END -->
136
+ </div> <!-- Row END -->
137
+ </div>
138
+ <div class="row d-sm-flex justify-content-center mb-5">
139
+ <div class="col-11">
140
+ <div class="row d-none" id='dynamicResult'>
141
+ <h1 id="resultsHeading" class="text-center text-white-50">Results</h1>
142
+ <div class="col-12">
143
+ <div class="card" style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
144
+ <div class="card-body">
145
+ <h5 class="card-title text-white mb-3">Transcribed and Classified Text</h5>
146
+ <div id="transcribedText" class="text-white-50 mb-4"></div>
147
+ <div class="text-center">
148
+ <div class="col-12 d-flex justify-content-center">
149
+ <div class="col-sm-12 d-inline align-items-center" id="classifiedText">
150
+ {% if sentences_prediction %}
151
+ {% for sentence, color in sentences_prediction.items() %}
152
+ <span class="text-bold text-start bg-{{color[1]}}">
153
+ {{sentence}}
154
+ </span>
155
+ {% endfor %}
156
+ {% endif %}
157
+ </div>
158
+ </div>
159
+ </div>
160
+ </div>
161
+ </div>
162
+ </div>
163
+ </div>
164
+ </div>
165
+
166
+ </div>
167
+ </main>
168
+
169
+ <!-- Container END -->
170
+ <script id="dashboard-pdf-script" src="../static/js/dashboard_pdf.js"></script>
171
+ <script src="../static/js/Chart.min.js"></script>
172
+ <script src="../static/js/pdf_fr.js" type="text/javascript"></script>
173
+ <script src="../static/js/vendor.bundle.base.js"></script>
174
+
175
+ </body>
176
+
177
+ </html>
templates/response_fr_sentence.html ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
7
+ <!-- Include jQuery library -->
8
+ <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
9
+ </head>
10
+ <body>
11
+ <div class="d-flex flex-column align-items-start">
12
+ <div class="text-secondary p-2 px-3 rounded-2">
13
+ <div class="card" style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
14
+ <div class="card-body">
15
+ <h4 class="card-title text-white">Text's Category</h4>
16
+ <div class="row d-flex">
17
+ <div class="col-sm-6 col-6">
18
+ <ul class="graphl-legend-rectangle">
19
+ <!-- Populate categories dynamically -->
20
+ <!-- class_label has two elements : the class and the color (for display)-->
21
+ {% for class_label, probability in class_probabilities.items() %}
22
+ {% if loop.index <= 5 %} <li class="text-white-50">
23
+ <span class="bg-{{ class_label[1] }}"></span>
24
+ <div class="d-flex justify-content-center">
25
+ {{ class_label[0] }}:
26
+ <span class="text-white w-100">&nbsp;{{ "%.2f" % probability }}%</span>
27
+ </div>
28
+ </li>
29
+ {% endif %}
30
+ {% endfor %}
31
+
32
+ </ul>
33
+ </div>
34
+ <div class="col-sm-6 grid-margin col-6">
35
+ <canvas class="bestSellers" data-chart = '{{ chart_data | tojson | safe }}' id="bestSellers#"></canvas>
36
+ </div>
37
+ </div>
38
+ <div class="mb-lg-0 text-white-50">
39
+ la classe la plus dominante est <span class="fw-bolder text-white">{{ predicted_class[0] }}</span>
40
+ </div>
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </div>
45
+ <script>
46
+ var chartData = {{ chart_data | tojson | safe}};
47
+ </script>
48
+ <script src="../static/js/dashboard_sentence.js"></script>
49
+ </body>
50
+ </html>
templates/sentence.html CHANGED
@@ -2,7 +2,7 @@
2
  <html lang="en-US">
3
 
4
  <head>
5
- <title>OCR</title>
6
  <link rel="icon" href="https://cdn-icons-png.flaticon.com/512/5262/5262072.png">
7
  <link rel="stylesheet" href="../static/css/style2.css">
8
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
@@ -47,6 +47,12 @@
47
  <li class="nav-item nav-pills nav-pills-ocr">
48
  <a class="nav-item nav-link " href="voice">SLU</a>
49
  </li>
 
 
 
 
 
 
50
  </ul>
51
  </div>
52
  <!-- Main navbar END -->
@@ -61,7 +67,7 @@
61
  <div class="justify-content-lg-around justify-content-xl-center justify-content-md-between">
62
 
63
  <!-- Chat conversation START -->
64
- <div class="card card-chat bg-ocr" >
65
  <div class="card-body h-100 bg-ocr rounded-2">
66
  <div class="tab-content py-0 mb-0 h-100" id="chatTabsContent">
67
  <!-- Conversation item START -->
@@ -75,17 +81,16 @@
75
  style="overflow-y: scroll;">
76
  <div class="os-content" style="padding: 0px; height: 100%; width: 100%;">
77
  <!-- Chat message right -->
78
- <div class="d-inline mb-1 align-content-between position-relative top-xl-45 top-lg-0 top-lg-30" id = "presentation">
 
79
  <div class="flex-grow-1 row">
80
  <div class="w-100 col-1 text-center">
81
  <div class="d-flex flex-column">
82
  <div class="text-secondary p-2 px-3 rounded-2">
83
  <div class="card"
84
  style="background-color: #303131;">
85
- <div
86
- class="card-body">
87
- <div
88
- class="">
89
  <div
90
  class="flex-shrink-0 avatar avatar-lg mb-lg-3 ">
91
  <img class="avatar-img rounded-circle"
@@ -106,14 +111,17 @@
106
  <div class="flex-grow-1">
107
  <div class="w-100">
108
  <div class="d-flex flex-column align-items-start">
109
- <div class="text-secondary p-2 px-3 rounded-2 w-100">
 
110
  <div class="card"
111
  style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
112
  <div class="card-body">
113
  <h5 class="card-title text-white">
114
  Text Classifier</h5>
115
  <div class="mb-lg-0 text-white-50">
116
- Enter a sentence or paragraph in the text box below to discover its category.
 
 
117
  </div>
118
 
119
  </div>
@@ -127,14 +135,21 @@
127
  <div class="flex-grow-1">
128
  <div class="w-100">
129
  <div class="d-flex flex-column align-items-start">
130
- <div class="text-secondary p-2 px-3 rounded-2 w-100">
 
131
  <div class="card"
132
  style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
133
  <div class="card-body">
134
  <h5 class="card-title text-white">
135
  Example</h5>
136
  <div class="mb-lg-0 text-white-50">
137
- The sentence <span class="text-white">'Chatbots use AI to communicate with users'</span> is categorized as <span class="text-white"> 'Artificial Intelligence' </span> .
 
 
 
 
 
 
138
  </div>
139
 
140
  </div>
@@ -172,14 +187,16 @@
172
  </div>
173
 
174
  <div class="card-footer" style="background-color: #242525;">
175
- <form class="d-flex align-items-center" action="/sentence" method="post" id="sentenceForm" onsubmit="submitForm(event)">
 
176
  <textarea class="form-control mb-sm-0 mb-3" id="ocr-result" name="text" data-autoresize=""
177
  placeholder="Type your text" rows="1" style="height: 50px;box-sizing: border-box;
178
- resize: none; max-height: 120px;" onclick="addAutoResize()" onkeydown="handleEnter(event)" required></textarea>
 
179
  <button class="btn btn-sm btn-sentence ms-2" type="submit"><img class="avatar avatar-xs"
180
  src="../static/icons/avignon_universite_blanc_RVB-1.png"></button>
181
  </form>
182
- </div>
183
  </div>
184
  <!-- Chat conversation END -->
185
  </div> <!-- Row END -->
 
2
  <html lang="en-US">
3
 
4
  <head>
5
+ <title>Chat Categorization</title>
6
  <link rel="icon" href="https://cdn-icons-png.flaticon.com/512/5262/5262072.png">
7
  <link rel="stylesheet" href="../static/css/style2.css">
8
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
 
47
  <li class="nav-item nav-pills nav-pills-ocr">
48
  <a class="nav-item nav-link " href="voice">SLU</a>
49
  </li>
50
+ <li class="nav-item dropdown">
51
+ <a class="nav-link" href="#" id="accounntMenu" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">language</a>
52
+ <ul class="dropdown-menu" aria-labelledby="accounntMenu">
53
+ <li> <a class="dropdown-item " href="sentence_fr"><img src="../static/icons/France.svg" class="avatar avatar" style="height: 20px;" alt="French flag"> French</a> </li>
54
+ </ul>
55
+ </li>
56
  </ul>
57
  </div>
58
  <!-- Main navbar END -->
 
67
  <div class="justify-content-lg-around justify-content-xl-center justify-content-md-between">
68
 
69
  <!-- Chat conversation START -->
70
+ <div class="card card-chat bg-ocr">
71
  <div class="card-body h-100 bg-ocr rounded-2">
72
  <div class="tab-content py-0 mb-0 h-100" id="chatTabsContent">
73
  <!-- Conversation item START -->
 
81
  style="overflow-y: scroll;">
82
  <div class="os-content" style="padding: 0px; height: 100%; width: 100%;">
83
  <!-- Chat message right -->
84
+ <div class="d-inline mb-1 align-content-between position-relative top-xl-45 top-lg-0 top-lg-30"
85
+ id="presentation">
86
  <div class="flex-grow-1 row">
87
  <div class="w-100 col-1 text-center">
88
  <div class="d-flex flex-column">
89
  <div class="text-secondary p-2 px-3 rounded-2">
90
  <div class="card"
91
  style="background-color: #303131;">
92
+ <div class="card-body">
93
+ <div class="">
 
 
94
  <div
95
  class="flex-shrink-0 avatar avatar-lg mb-lg-3 ">
96
  <img class="avatar-img rounded-circle"
 
111
  <div class="flex-grow-1">
112
  <div class="w-100">
113
  <div class="d-flex flex-column align-items-start">
114
+ <div
115
+ class="text-secondary p-2 px-3 rounded-2 w-100">
116
  <div class="card"
117
  style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
118
  <div class="card-body">
119
  <h5 class="card-title text-white">
120
  Text Classifier</h5>
121
  <div class="mb-lg-0 text-white-50">
122
+ Enter a sentence or paragraph in
123
+ the text box below to discover
124
+ its category.
125
  </div>
126
 
127
  </div>
 
135
  <div class="flex-grow-1">
136
  <div class="w-100">
137
  <div class="d-flex flex-column align-items-start">
138
+ <div
139
+ class="text-secondary p-2 px-3 rounded-2 w-100">
140
  <div class="card"
141
  style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
142
  <div class="card-body">
143
  <h5 class="card-title text-white">
144
  Example</h5>
145
  <div class="mb-lg-0 text-white-50">
146
+ The sentence <span
147
+ class="text-white">'Chatbots
148
+ use AI to communicate with
149
+ users'</span> is categorized
150
+ as <span class="text-white">
151
+ 'Artificial Intelligence'
152
+ </span> .
153
  </div>
154
 
155
  </div>
 
187
  </div>
188
 
189
  <div class="card-footer" style="background-color: #242525;">
190
+ <form class="d-flex align-items-center" action="/sentence" method="post" id="sentenceForm"
191
+ onsubmit="submitForm(event)">
192
  <textarea class="form-control mb-sm-0 mb-3" id="ocr-result" name="text" data-autoresize=""
193
  placeholder="Type your text" rows="1" style="height: 50px;box-sizing: border-box;
194
+ resize: none; max-height: 120px;" onclick="addAutoResize()"
195
+ onkeydown="handleEnter(event)" required></textarea>
196
  <button class="btn btn-sm btn-sentence ms-2" type="submit"><img class="avatar avatar-xs"
197
  src="../static/icons/avignon_universite_blanc_RVB-1.png"></button>
198
  </form>
199
+ </div>
200
  </div>
201
  <!-- Chat conversation END -->
202
  </div> <!-- Row END -->
templates/sentence_fr.html ADDED
@@ -0,0 +1,229 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en-US">
3
+
4
+ <head>
5
+ <title>Chat Categorization</title>
6
+ <link rel="icon" href="https://cdn-icons-png.flaticon.com/512/5262/5262072.png">
7
+ <link rel="stylesheet" href="../static/css/style2.css">
8
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
9
+ <link rel="stylesheet" href="../static/css/vendor.bundle.base.css">
10
+ <link rel="stylesheet" href="../static/css/OverlayScrollbars.min.css">
11
+
12
+
13
+ </head>
14
+
15
+ <body style="background-color: #1F2020">
16
+ <header>
17
+ <nav class="navbar navbar-expand-lg bg-ocr mb-5">
18
+ <div class="container h-100">
19
+ <!-- Logo START -->
20
+ <a class="navbar-brand" href="pdf_fr">
21
+ <img class="navbar-brand-item" src="../static/icons/avignon_universite_blanc_RVB.png" alt="logo">
22
+ </a>
23
+ <!-- Logo END -->
24
+
25
+ <!-- Responsive navbar toggler -->
26
+ <button class="navbar-toggler ms-auto icon-md btn btn-light p-0 collapsed" type="button"
27
+ data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse"
28
+ aria-expanded="false" aria-label="Toggle navigation">
29
+ <span class="navbar-toggler-animation">
30
+ <span></span>
31
+ <span></span>
32
+ <span></span>
33
+ </span>
34
+ </button>
35
+
36
+ <!-- Main navbar START -->
37
+ <div class="navbar-collapse collapse" id="navbarCollapse">
38
+ <ul class="navbar-nav navbar-nav-scroll ms-auto p-xl-0">
39
+ <!-- Nav item 1 Demos -->
40
+ <li class="nav-item nav-pills nav-pills-ocr">
41
+ <a class="nav-item nav-link" href="pdf_fr">Classificateur PDF</a>
42
+ </li>
43
+ <!-- Nav item 2 Pages -->
44
+ <li class="nav-item nav-pills nav-pills-ocr">
45
+ <a class="nav-item nav-link active" href="sentence_fr">Classificateur de texte</a>
46
+ </li>
47
+ <li class="nav-item nav-pills nav-pills-ocr">
48
+ <a class="nav-item nav-link " href="voice_fr">SLU</a>
49
+ </li>
50
+ <li class="nav-item dropdown">
51
+ <a class="nav-link" href="#" id="accounntMenu" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">langue</a>
52
+ <ul class="dropdown-menu" aria-labelledby="accounntMenu">
53
+ <li> <a class="dropdown-item " href="sentence"><img src="../static/icons/English.svg" class="avatar avatar" style="height: 20px;" alt="French flag"> English</a> </li>
54
+ </ul>
55
+ </li>
56
+ </ul>
57
+ </div>
58
+ <!-- Main navbar END -->
59
+ </div>
60
+ </nav>
61
+ </header>
62
+
63
+ <main class="pt-3 pt-md-5 pb-md-5 pt-lg-0 mt-3 ">
64
+
65
+ <!-- Container START -->
66
+ <div class="container mt-lg-7 ">
67
+ <div class="justify-content-lg-around justify-content-xl-center justify-content-md-between">
68
+
69
+ <!-- Chat conversation START -->
70
+ <div class="card card-chat bg-ocr">
71
+ <div class="card-body h-100 bg-ocr rounded-2">
72
+ <div class="tab-content py-0 mb-0 h-100" id="chatTabsContent">
73
+ <!-- Conversation item START -->
74
+ <div class="fade tab-pane show active h-100" id="chat-1" role="tabpanel"
75
+ aria-labelledby="chat-1-tab">
76
+ <!-- Chat conversation START -->
77
+ <div
78
+ class="chat-conversation-content custom-scrollbar os-host os-theme-dark os-host-overflow os-host-overflow-y os-host-resize-disabled os-host-scrollbar-horizontal-hidden os-host-transition h-100">
79
+ <div class="os-padding">
80
+ <div class="os-viewport os-viewport-native-scrollbars-invisible"
81
+ style="overflow-y: scroll;">
82
+ <div class="os-content" style="padding: 0px; height: 100%; width: 100%;">
83
+ <!-- Chat message right -->
84
+ <div class="d-inline mb-1 align-content-between position-relative top-xl-45 top-lg-0 top-lg-30"
85
+ id="presentation">
86
+ <div class="flex-grow-1 row">
87
+ <div class="w-100 col-1 text-center">
88
+ <div class="d-flex flex-column">
89
+ <div class="text-secondary p-2 px-3 rounded-2">
90
+ <div class="card"
91
+ style="background-color: #303131;">
92
+ <div class="card-body">
93
+ <div class="">
94
+ <div
95
+ class="flex-shrink-0 avatar avatar-lg mb-lg-3 ">
96
+ <img class="avatar-img rounded-circle"
97
+ src="../static/icons/logo_header_128x128.png"
98
+ alt="">
99
+ </div>
100
+ <h4 class="text-white">Comment puis-je vous aider aujourd'hui ?</h4>
101
+ </div>
102
+ </div>
103
+ </div>
104
+ </div>
105
+ </div>
106
+ </div>
107
+ </div>
108
+ <div class="row d-flex justify-content-center">
109
+ <div class="col-lg-6 ">
110
+ <div class="flex-grow-1">
111
+ <div class="w-100">
112
+ <div class="d-flex flex-column align-items-start">
113
+ <div
114
+ class="text-secondary p-2 px-3 rounded-2 w-100">
115
+ <div class="card"
116
+ style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
117
+ <div class="card-body">
118
+ <h5 class="card-title text-white">
119
+ Classificateur de texte</h5>
120
+ <div class="mb-lg-0 text-white-50">
121
+ Saisissez une phrase ou un paragraphe dans la zone de texte ci-dessous pour découvrir sa catégorie.
122
+ </div>
123
+
124
+ </div>
125
+ </div>
126
+ </div>
127
+ </div>
128
+ </div>
129
+ </div>
130
+ </div>
131
+ <div class="col-lg-6 ">
132
+ <div class="flex-grow-1">
133
+ <div class="w-100">
134
+ <div class="d-flex flex-column align-items-start">
135
+ <div
136
+ class="text-secondary p-2 px-3 rounded-2 w-100">
137
+ <div class="card"
138
+ style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
139
+ <div class="card-body">
140
+ <h5 class="card-title text-white">
141
+ Exemple</h5>
142
+ <div class="mb-lg-0 text-white-50">
143
+ La phrase <span
144
+ class="text-white">'Les chatbots utilisent l'IA pour communiquer avec les utilisateurs'</span> est classée <span class="text-white">
145
+ 'Artificial Intelligence'
146
+ </span> .
147
+ </div>
148
+
149
+ </div>
150
+ </div>
151
+ </div>
152
+ </div>
153
+ </div>
154
+ </div>
155
+ </div>
156
+ </div>
157
+ </div>
158
+ <!-- Chat message left -->
159
+ </div>
160
+ </div>
161
+ </div>
162
+ <div
163
+ class="os-scrollbar os-scrollbar-horizontal os-scrollbar-unusable os-scrollbar-auto-hidden">
164
+ <div class="os-scrollbar-track os-scrollbar-track-off">
165
+ <div class="os-scrollbar-handle"
166
+ style="width: 100%; transform: translate(0px, 0px);"></div>
167
+ </div>
168
+ </div>
169
+ <div class="os-scrollbar os-scrollbar-vertical os-scrollbar-auto-hidden">
170
+ <div class="os-scrollbar-track os-scrollbar-track-off">
171
+ <div class="os-scrollbar-handle"
172
+ style="height: 32.4192%; transform: translate(0px, 0px);"></div>
173
+ </div>
174
+ </div>
175
+ <div class="os-scrollbar-corner"></div>
176
+ </div>
177
+ <!-- Chat conversation END -->
178
+ </div>
179
+ <!-- Conversation item END -->
180
+ </div>
181
+ </div>
182
+
183
+ <div class="card-footer" style="background-color: #242525;">
184
+ <form class="d-flex align-items-center" action="/sentence_fr" method="post" id="sentenceForm"
185
+ onsubmit="submitForm(event)">
186
+ <textarea class="form-control mb-sm-0 mb-3" id="ocr-result" name="text" data-autoresize=""
187
+ placeholder="Saisir votre texte" rows="1" style="height: 50px;box-sizing: border-box;
188
+ resize: none; max-height: 120px;" onclick="addAutoResize()"
189
+ onkeydown="handleEnter(event)" required></textarea>
190
+ <button class="btn btn-sm btn-sentence ms-2" type="submit"><img class="avatar avatar-xs"
191
+ src="../static/icons/avignon_universite_blanc_RVB-1.png"></button>
192
+ </form>
193
+ </div>
194
+ </div>
195
+ <!-- Chat conversation END -->
196
+ </div> <!-- Row END -->
197
+ <!-- =======================
198
+ Chat END -->
199
+
200
+ </div>
201
+ <!-- Container END -->
202
+
203
+ </main>
204
+ <!-- Container END -->
205
+ <script src="../static/js/sentence_fr.js" type="text/javascript"></script>
206
+ <script src="../static/js/vendor.bundle.base.js"></script>
207
+ <script src="../static/js/Chart.min.js"></script>
208
+ <!-- Custom js for this page-->
209
+
210
+ <script src="../static/js/bootstrap.bundle.min.js"></script>
211
+ <script src="../static/js/OverlayScrollbars.min.js"></script>
212
+ <script>
213
+ // START: 12 Auto resize textarea
214
+ function addAutoResize() {
215
+ document.querySelectorAll('[data-autoresize]').forEach(function (element) {
216
+ element.style.boxSizing = 'border-box';
217
+ var offset = element.offsetHeight - element.clientHeight;
218
+ element.addEventListener('input', function (event) {
219
+ event.target.style.height = 'auto';
220
+ event.target.style.height = event.target.scrollHeight + offset + 'px';
221
+ });
222
+ element.removeAttribute('data-autoresize');
223
+ });
224
+ }
225
+ // END: Auto resize textarea
226
+ </script>
227
+ </body>
228
+
229
+ </html>
templates/voice.html CHANGED
@@ -41,6 +41,12 @@
41
  <li class="nav-item nav-pills nav-pills-ocr">
42
  <a class="nav-item nav-link active" href="voice">SLU</a>
43
  </li>
 
 
 
 
 
 
44
  </ul>
45
  </div>
46
  <!-- Main navbar END -->
 
41
  <li class="nav-item nav-pills nav-pills-ocr">
42
  <a class="nav-item nav-link active" href="voice">SLU</a>
43
  </li>
44
+ <li class="nav-item dropdown">
45
+ <a class="nav-link" href="#" id="accounntMenu" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">language</a>
46
+ <ul class="dropdown-menu" aria-labelledby="accounntMenu">
47
+ <li> <a class="dropdown-item " href="voice_fr"><img src="../static/icons/France.svg" class="avatar avatar" style="height: 20px;" alt="French flag"> French</a> </li>
48
+ </ul>
49
+ </li>
50
  </ul>
51
  </div>
52
  <!-- Main navbar END -->
templates/voice_fr.html ADDED
@@ -0,0 +1,235 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en-US">
3
+
4
+ <head>
5
+ <title>Speech Transcription</title>
6
+ <link rel="icon" href="https://cdn-icons-png.flaticon.com/512/5262/5262072.png">
7
+ <link rel="stylesheet" href="../static/css/style2.css">
8
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
9
+ <link rel="stylesheet" href="../static/css/vendor.bundle.base.css">
10
+ </head>
11
+
12
+ <body style="background-color: #1F2020;">
13
+ <nav class="navbar navbar-expand-lg bg-ocr mb-5">
14
+ <div class="container h-100">
15
+ <!-- Logo START -->
16
+ <a class="navbar-brand" href="pdf_fr">
17
+ <img class="navbar-brand-item" src="../static/icons/avignon_universite_blanc_RVB.png" alt="logo">
18
+ </a>
19
+ <!-- Logo END -->
20
+
21
+ <!-- Responsive navbar toggler -->
22
+ <button class="navbar-toggler ms-auto icon-md btn btn-light p-0 collapsed" type="button"
23
+ data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse"
24
+ aria-expanded="false" aria-label="Toggle navigation">
25
+ <span class="navbar-toggler-animation">
26
+ <span></span>
27
+ <span></span>
28
+ <span></span>
29
+ </span>
30
+ </button>
31
+
32
+ <!-- Main navbar START -->
33
+ <div class="navbar-collapse collapse" id="navbarCollapse">
34
+ <ul class="navbar-nav navbar-nav-scroll ms-auto p-xl-0">
35
+ <!-- Nav item 1 Demos -->
36
+ <li class="nav-item nav-pills nav-pills-ocr">
37
+ <a class="nav-item nav-link" href="pdf_fr">Classificateur PDF</a>
38
+ </li>
39
+ <!-- Nav item 2 Pages -->
40
+ <li class="nav-item nav-pills nav-pills-ocr">
41
+ <a class="nav-item nav-link " href="sentence_fr">Classificateur de texte</a>
42
+ </li>
43
+ <li class="nav-item nav-pills nav-pills-ocr">
44
+ <a class="nav-item nav-link active" href="voice_fr">SLU</a>
45
+ </li>
46
+ <li class="nav-item dropdown">
47
+ <a class="nav-link" href="#" id="accounntMenu" data-bs-toggle="dropdown" aria-haspopup="true" aria-expanded="false">langue</a>
48
+ <ul class="dropdown-menu" aria-labelledby="accounntMenu">
49
+ <li> <a class="dropdown-item " href="voice"><img src="../static/icons/English.svg" class="avatar avatar" style="height: 20px;" alt="French flag"> English</a> </li>
50
+ </ul>
51
+ </li>
52
+ </ul>
53
+ </div>
54
+ <!-- Main navbar END -->
55
+ </div>
56
+ </nav>
57
+
58
+ <main class="pt-3 pt-md-5 pb-md-5 pt-lg-0 mt-3">
59
+ <div class="container mt-lg-7">
60
+ <div class="row">
61
+ <div class="col-lg-6 mb-4">
62
+ <div class="card bg-ocr h-100">
63
+ <div class="card-body">
64
+ <h5 class="card-title text-white">Enregistrement du discours</h5>
65
+ <p class="card-text text-white-50">Cliquez sur le bouton pour commencer à enregistrer votre discours.</p>
66
+ <div class="mt-auto text-center">
67
+ <button id="startRecord" class="btn btn-ocr">Démarrer l'enregistrement</button>
68
+ <button id="stopRecord" class="btn btn-green" disabled>Arrêter l'enregistrement</button>
69
+ </div>
70
+ </div>
71
+ </div>
72
+ </div>
73
+ <div class="col-lg-6 mb-4">
74
+ <div class="card bg-ocr">
75
+ <div class="card-body">
76
+ <h5 class="card-title text-white">Télécharger un fichier audio</h5>
77
+ <p class="card-text text-white-50">Cliquez ou faites un glisser-déposer pour télécharger un fichier audio.</p>
78
+ <div class="file-upload-wrapper" id="fileUploadWrapper">
79
+ <input type="file" id="audioFileInput" accept="audio/*">
80
+ <div class="file-upload-text">
81
+ <i class="bi bi-cloud-upload" style="font-size: 2rem;"></i>
82
+ <p>Cliquez ou glissez le fichier audio ici</p>
83
+ <p class="file-name"></p>
84
+ </div>
85
+ </div>
86
+ <div class="text-center">
87
+ <button id="uploadAudio" class="btn btn-ocr mt-3 text-center">Télécharger et transcrire</button>
88
+ </div>
89
+ </div>
90
+ </div>
91
+ </div>
92
+ </div>
93
+ <h1 class="text-center text-white-50"> R��sultats</h1>
94
+ <div class="card" id = 'static' style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
95
+ <div class="card-body text-center" id="static">
96
+ <div class="col-12 d-flex justify-content-center">
97
+ <div class="col-sm-12 d-inline align-items-center" style="height: 175px; width: 290px;">
98
+ <div class="flex-shrink-0 avatar avatar-lg me-2 mb-3 mt-4">
99
+ <img class="avatar-img rounded-circle"
100
+ src="../static/icons/logo_header_128x128.png" alt="">
101
+ </div>
102
+ <h5 class="card-title text-white-50">Obtenez plus d'informations sur votre discours 📣📢.</h5>
103
+ </div>
104
+
105
+ </div>
106
+ </div>
107
+ </div>
108
+ <div class="row d-none" id = 'dynamic'>
109
+ <div class="col-4">
110
+ <div class="nav flex-column position-sticky top-10 shadow-lg" style="background-color: #222424;">
111
+ <div class="card mb-3" style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
112
+ <div class="card-body">
113
+ <h4 class="card-title text-white">Catégorie du texte</h4>
114
+ <div class="row d-flex">
115
+ <div class="col-sm-7 col-6">
116
+ <ul class="graphl-legend-rectangle" id="class-probabilities">
117
+ {% if class_probabilities %}
118
+ {% for class_label, probability in class_probabilities.items() %}
119
+ {% if loop.index <= 5 %}
120
+ <li class="text-white-50">
121
+ <span class="bg-{{ class_label[1] }}"></span>
122
+ <div class="d-flex justify-content-center">
123
+ {{ class_label[0] }}:
124
+ <span class="text-white w-100">&nbsp;{{ "%.2f" % (probability) }}%</span>
125
+ </div>
126
+ </li>
127
+ {% endif %}
128
+ {% endfor %}
129
+ {% endif %}
130
+ </ul>
131
+ </div>
132
+ <div class="col-sm-5 grid-margin col-6">
133
+ <canvas class="bestSellers" data-chart='{{ chart_data | tojson}}'
134
+ id="bestSellers"></canvas>
135
+ </div>
136
+ </div>
137
+ <div class="mb-lg-0 text-white-50">
138
+ la classe la plus dominante est <span class="fw-bolder text-white"
139
+ id="predicted-class">{{
140
+ predicted_class[0] if predicted_class else ""
141
+ }}</span>
142
+ </div>
143
+ </div>
144
+ </div>
145
+ <div class="card my-auto mt-3"
146
+ style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
147
+ <div class="card-body">
148
+ <h4 class="card-title text-white">Légende</h4>
149
+ <div class="row d-flex">
150
+ <div class="col-sm-6 col-6">
151
+ <ul class="graphl-legend-rectangle">
152
+ <li class="text-white-50"><span class="bg-info "></span>vehicles
153
+ </li>
154
+ <li class="text-white-50"><span class="bg-success"></span>environments
155
+ </li>
156
+ <li class="text-white-50"><span class="bg-danger"></span>energies
157
+ </li>
158
+ <li class="text-white-50"><span class="bg-primary"></span>Physics
159
+ </li>
160
+ <li class="text-white-50"><span class="bg-moss"></span>robotics
161
+ </li>
162
+ <li class="text-white-50"><span class="bg-agri"></span>agriculture
163
+ </li>
164
+ <li class="text-white-50"><span class="bg-yellow"></span>ML
165
+ </li>
166
+ <li class="text-white-50"><span class="bg-warning"></span>economies
167
+ </li>
168
+ <li class="text-white-50"><span class="bg-vanila"></span>technologies
169
+ </li>
170
+ </ul>
171
+ </div>
172
+ <div class="col-sm-6 col-6">
173
+ <ul class="graphl-legend-rectangle">
174
+
175
+ <li class="text-white-50"><span class="bg-coffe"></span>mathematics
176
+ </li>
177
+ <li class="text-white-50"><span class="bg-orange "></span>sports
178
+ </li>
179
+ <li class="text-white-50"><span class="bg-cyan"></span>AI
180
+ </li>
181
+ <li class="text-white-50"><span class="bg-rosy"></span>Innovation
182
+ </li>
183
+ <li class="text-white-50"><span class="bg-picton"></span>Science
184
+ </li>
185
+ <li class="text-white-50"><span class="bg-purple"></span>Societies
186
+ </li>
187
+ <li class="text-white-50"><span class="bg-pink"></span>administration
188
+ </li>
189
+ <li class="text-white-50"><span class="bg-cambridge"></span>biology
190
+ </li>
191
+ </ul>
192
+ </div>
193
+ </div>
194
+ </div>
195
+ </div>
196
+ </div>
197
+ </div>
198
+
199
+ <div class="col-8">
200
+ <div class="card" style="background-color: #303131; border: 2px dashed rgb(82, 82, 82);">
201
+ <div class="card-body">
202
+ <h5 class="card-title text-white mb-3">Texte transcrit et classifié</h5>
203
+ <div id="transcribedText" class="text-white-50 mb-4"></div>
204
+ <div id="static" class="text-center">
205
+ <div class="col-12 d-flex justify-content-center">
206
+ <div class="col-sm-12 d-inline align-items-center" id="classifiedText">
207
+ {% if sentences_prediction %}
208
+ {% for sentence, color in sentences_prediction.items() %}
209
+ <span class="text-bold text-start bg-{{color[1]}}">
210
+ {{sentence}}
211
+ </span>
212
+ {% endfor %}
213
+ {% endif %}
214
+ </div>
215
+ </div>
216
+ </div>
217
+ </div>
218
+ </div>
219
+ </div>
220
+ </div>
221
+ </div>
222
+ </main>
223
+
224
+ <div id="loadingIndicator" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.5); z-index: 9999;">
225
+ <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); color: white;">
226
+ Processing...
227
+ </div>
228
+ </div>
229
+
230
+ <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
231
+ <script src="../static/js/voice.js" type="text/javascript"></script>
232
+ <script src="../static/js/vendor.bundle.base.js"></script>
233
+ </body>
234
+
235
+ </html>