MrSimple07 commited on
Commit
5884230
·
1 Parent(s): bf0077f

table processing + new version of np104

Browse files
.gitattributes CHANGED
@@ -43,3 +43,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
43
  *.pdf filter=lfs diff=lfs merge=lfs -text
44
  =======
45
  >>>>>>> b38db646fba42cf62de437de07713765675b4628
 
 
43
  *.pdf filter=lfs diff=lfs merge=lfs -text
44
  =======
45
  >>>>>>> b38db646fba42cf62de437de07713765675b4628
46
+ *.xlsx filter=lfs diff=lfs merge=lfs -text
documents_prep.py CHANGED
@@ -6,6 +6,7 @@ from llama_index.core import Document
6
  from my_logging import log_message
7
  from llama_index.core.text_splitter import SentenceSplitter
8
  from config import CHUNK_SIZE, CHUNK_OVERLAP
 
9
 
10
 
11
  def chunk_document(doc, chunk_size=None, chunk_overlap=None):
@@ -378,108 +379,6 @@ def extract_zip_and_process_json(zip_path):
378
 
379
  return documents
380
 
381
- def table_to_document(table_data, document_id=None):
382
- documents = []
383
-
384
- if isinstance(table_data, dict):
385
- doc_id = document_id or table_data.get('document_id', table_data.get('document', 'Неизвестно'))
386
- table_num = table_data.get('table_number', 'Неизвестно')
387
- table_title = table_data.get('table_title', 'Неизвестно')
388
- section = table_data.get('section', 'Неизвестно')
389
-
390
- header_content = f"Таблица: {table_num}\nНазвание: {table_title}\nДокумент: {doc_id}\nРаздел: {section}\n"
391
-
392
- if 'data' in table_data and isinstance(table_data['data'], list):
393
- table_content = header_content + "\nДанные таблицы:\n"
394
- for row_idx, row in enumerate(table_data['data']):
395
- if isinstance(row, dict):
396
- row_text = " | ".join([f"{k}: {v}" for k, v in row.items()])
397
- table_content += f"Строка {row_idx + 1}: {row_text}\n"
398
-
399
- doc = Document(
400
- text=table_content,
401
- metadata={
402
- "type": "table",
403
- "table_number": table_num,
404
- "table_title": table_title,
405
- "document_id": doc_id,
406
- "section": section,
407
- "section_id": section,
408
- "total_rows": len(table_data['data'])
409
- }
410
- )
411
- documents.append(doc)
412
- else:
413
- doc = Document(
414
- text=header_content,
415
- metadata={
416
- "type": "table",
417
- "table_number": table_num,
418
- "table_title": table_title,
419
- "document_id": doc_id,
420
- "section": section,
421
- "section_id": section
422
- }
423
- )
424
- documents.append(doc)
425
-
426
- return documents
427
-
428
- def load_table_data(repo_id, hf_token, table_data_dir):
429
- log_message("Начинаю загрузку табличных данных")
430
-
431
- table_files = []
432
- try:
433
- files = list_repo_files(repo_id=repo_id, repo_type="dataset", token=hf_token)
434
- for file in files:
435
- if file.startswith(table_data_dir) and file.endswith('.json'):
436
- table_files.append(file)
437
-
438
- log_message(f"Найдено {len(table_files)} JSON файлов с таблицами")
439
-
440
- table_documents = []
441
- for file_path in table_files:
442
- try:
443
- log_message(f"Обрабатываю файл: {file_path}")
444
- local_path = hf_hub_download(
445
- repo_id=repo_id,
446
- filename=file_path,
447
- local_dir='',
448
- repo_type="dataset",
449
- token=hf_token
450
- )
451
-
452
- with open(local_path, 'r', encoding='utf-8') as f:
453
- table_data = json.load(f)
454
-
455
- if isinstance(table_data, dict):
456
- document_id = table_data.get('document', 'unknown')
457
-
458
- if 'sheets' in table_data:
459
- for sheet in table_data['sheets']:
460
- sheet['document'] = document_id
461
- # table_to_document теперь возвращает список
462
- docs_list = table_to_document(sheet, document_id)
463
- table_documents.extend(docs_list) # extend вместо append
464
- else:
465
- docs_list = table_to_document(table_data, document_id)
466
- table_documents.extend(docs_list) # extend вместо append
467
- elif isinstance(table_data, list):
468
- for table_json in table_data:
469
- docs_list = table_to_document(table_json)
470
- table_documents.extend(docs_list) # extend вместо append
471
-
472
- except Exception as e:
473
- log_message(f"Ошибка обработки файла {file_path}: {str(e)}")
474
- continue
475
-
476
- log_message(f"Создано {len(table_documents)} документов из таблиц")
477
- return table_documents
478
-
479
- except Exception as e:
480
- log_message(f"Ошибка загрузки табличных данных: {str(e)}")
481
- return []
482
-
483
  def load_image_data(repo_id, hf_token, image_data_dir):
484
  log_message("Начинаю загрузку данных изображений")
485
 
 
6
  from my_logging import log_message
7
  from llama_index.core.text_splitter import SentenceSplitter
8
  from config import CHUNK_SIZE, CHUNK_OVERLAP
9
+ from table_prep import table_to_document, load_table_data
10
 
11
 
12
  def chunk_document(doc, chunk_size=None, chunk_overlap=None):
 
379
 
380
  return documents
381
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
382
  def load_image_data(repo_id, hf_token, image_data_dir):
383
  log_message("Начинаю загрузку данных изображений")
384
 
new_xlsx.py/new_xlsx.py ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import pandas as pd
2
+ import json
3
+ import os
4
+
5
+ def excel_to_json():
6
+ input_dir = "Табличные данные"
7
+ output_dir = "Табличные данные_JSON_2"
8
+
9
+ os.makedirs(output_dir, exist_ok=True)
10
+
11
+ excel_files = [f for f in os.listdir(input_dir) if f.endswith(('.xlsx', '.xls'))]
12
+ print(f"Found {len(excel_files)} Excel files")
13
+
14
+ successful, failed = 0, 0
15
+
16
+ for file in excel_files:
17
+ try:
18
+ file_path = os.path.join(input_dir, file)
19
+ all_sheets = pd.read_excel(file_path, sheet_name=None)
20
+
21
+ result = {
22
+ "document": file,
23
+ "total_sheets": len(all_sheets),
24
+ "sheets": []
25
+ }
26
+
27
+ for sheet_name, df in all_sheets.items():
28
+ if df.empty:
29
+ continue
30
+
31
+ df = df.dropna(how='all').fillna("")
32
+
33
+ # проверим, что есть нужные колонки
34
+ if "Номер таблицы" not in df.columns:
35
+ continue
36
+
37
+ # группировка по номеру таблицы
38
+ grouped = df.groupby("Номер таблицы")
39
+
40
+ for table_number, group in grouped:
41
+ group = group.reset_index(drop=True)
42
+
43
+ sheet_data = {
44
+ "sheet_name": sheet_name,
45
+ "document_id": str(group.iloc[0].get("Обозначение документа", "")),
46
+ "section": str(group.iloc[0].get("Раздел документа", "")),
47
+ "table_number": str(table_number),
48
+ "table_title": str(group.iloc[0].get("Название таблицы", "")),
49
+ "table_description": str(group.iloc[0].get("Примечание", "")),
50
+ "headers": [col for col in df.columns if col not in ["Обозначение документа", "Раздел документа", "Номер таблицы", "Название таблицы", "Примечание"]],
51
+ "data": []
52
+ }
53
+
54
+ # добавляем строки данных
55
+ for _, row in group.iterrows():
56
+ row_dict = {}
57
+ for col in sheet_data["headers"]:
58
+ row_dict[col] = str(row[col]) if pd.notna(row[col]) else ""
59
+ sheet_data["data"].append(row_dict)
60
+
61
+ result["sheets"].append(sheet_data)
62
+
63
+ json_filename = file.replace('.xlsx', '.json').replace('.xls', '.json')
64
+ json_path = os.path.join(output_dir, json_filename)
65
+
66
+ with open(json_path, 'w', encoding='utf-8') as f:
67
+ json.dump(result, f, ensure_ascii=False, indent=2)
68
+
69
+ print(f"✓ Converted: {file} -> {json_filename}")
70
+ successful += 1
71
+
72
+ except Exception as e:
73
+ print(f"✗ Failed: {file} - {str(e)}")
74
+ failed += 1
75
+
76
+ print(f"\nResults:")
77
+ print(f"Successfully converted: {successful} files")
78
+ print(f"Failed: {failed} files")
79
+ print(f"JSON files saved to: {output_dir}")
80
+
81
+ if __name__ == "__main__":
82
+ excel_to_json()
table_prep.py ADDED
@@ -0,0 +1,325 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from collections import defaultdict
3
+ import json
4
+ import zipfile
5
+ import pandas as pd
6
+ from huggingface_hub import hf_hub_download, list_repo_files
7
+ from llama_index.core import Document
8
+ from my_logging import log_message
9
+
10
+
11
+ # Add this configuration at the top of your documents_prep file
12
+ CUSTOM_TABLE_CONFIGS = {
13
+ "ГОСТ Р 50.05.01-2018": {
14
+ "tables": {
15
+ "№3": {"method": "group_by_column", "group_column": "Класс герметичности и чувствительности"},
16
+ "№Б.1": {"method": "group_by_column", "group_column": "Класс чувствительности системы контроля"}
17
+ }
18
+ },
19
+ "ГОСТ Р 50.06.01-2017": {
20
+ "tables": {
21
+ "№ Б.2": {"method": "split_by_rows"}
22
+ }
23
+ },
24
+ "ГОСТ Р 59023.2-2020": {
25
+ "tables": {
26
+ "*": {"method": "group_entire_table"} # All tables
27
+ }
28
+ },
29
+ "НП-068-05": {
30
+ "tables": {
31
+ "Таблица 1": {"method": "group_by_column", "group_column": "Рабочее давление среды, МПа"},
32
+ "Таблица 2": {"method": "group_by_column", "group_column": "Рабочее давление среды, МПа"},
33
+ "Таблица Приложения 1": {"method": "group_by_column", "group_column": "Тип"}
34
+ }
35
+ },
36
+ "ГОСТ Р 59023.1-2020": {
37
+ "tables": {
38
+ "№ 1": {"method": "split_by_rows"},
39
+ "№ 2": {"method": "split_by_rows"},
40
+ "№ 3": {"method": "split_by_rows"}
41
+ }
42
+ }
43
+ }
44
+
45
+ def create_meta_info(document_name, section, table_number, table_title, extra_info=""):
46
+ """Create standard meta information string"""
47
+ base_info = f'Документ "{document_name}", Раздел: {section}, Номер таблицы: {table_number}, Название таблицы: {table_title}'
48
+ if extra_info:
49
+ base_info += f', {extra_info}'
50
+ return base_info + '\n'
51
+
52
+ def create_chunk_text(meta_info, headers, rows, add_row_numbers=False):
53
+ """Create chunk text with headers and rows"""
54
+ header_line = " | ".join(headers)
55
+ chunk_lines = [meta_info + "Заголовки: " + header_line]
56
+
57
+ for i, row in enumerate(rows, start=1):
58
+ row_text = " | ".join([f"{h}: {row.get(h, '')}" for h in headers])
59
+ if add_row_numbers:
60
+ chunk_lines.append(f"Строка {i}: {row_text}")
61
+ else:
62
+ chunk_lines.append(row_text)
63
+
64
+ return "\n".join(chunk_lines)
65
+
66
+ def group_by_column_method(table_data, document_name, group_column):
67
+ """Group rows by specified column value"""
68
+ documents = []
69
+ headers = table_data.get("headers", [])
70
+ rows = table_data.get("data", [])
71
+ section = table_data.get("section", "")
72
+ table_number = table_data.get("table_number", "")
73
+ table_title = table_data.get("table_title", "")
74
+
75
+ grouped = defaultdict(list)
76
+ for row in rows:
77
+ key = row.get(group_column, "UNKNOWN")
78
+ grouped[key].append(row)
79
+
80
+ for group_value, group_rows in grouped.items():
81
+ meta_info = create_meta_info(document_name, section, table_number, table_title,
82
+ f'Группа по "{group_column}": {group_value}')
83
+
84
+ chunk_text = create_chunk_text(meta_info, headers, group_rows, add_row_numbers=True)
85
+
86
+ doc = Document(
87
+ text=chunk_text,
88
+ metadata={
89
+ "type": "table",
90
+ "table_number": table_number,
91
+ "table_title": table_title,
92
+ "document_id": document_name,
93
+ "section": section,
94
+ "section_id": section,
95
+ "group_column": group_column,
96
+ "group_value": group_value,
97
+ "total_rows": len(group_rows),
98
+ "processing_method": "group_by_column"
99
+ }
100
+ )
101
+ documents.append(doc)
102
+ log_message(f"Created grouped chunk for {group_column}={group_value}, rows: {len(group_rows)}, length: {len(chunk_text)}")
103
+
104
+ return documents
105
+
106
+ def split_by_rows_method(table_data, document_name):
107
+ """Split table into individual row chunks"""
108
+ documents = []
109
+ headers = table_data.get("headers", [])
110
+ rows = table_data.get("data", [])
111
+ section = table_data.get("section", "")
112
+ table_number = table_data.get("table_number", "")
113
+ table_title = table_data.get("table_title", "")
114
+
115
+ for i, row in enumerate(rows, start=1):
116
+ meta_info = create_meta_info(document_name, section, table_number, table_title, f'Строка: {i}')
117
+
118
+ chunk_text = create_chunk_text(meta_info, headers, [row])
119
+
120
+ doc = Document(
121
+ text=chunk_text,
122
+ metadata={
123
+ "type": "table",
124
+ "table_number": table_number,
125
+ "table_title": table_title,
126
+ "document_id": document_name,
127
+ "section": section,
128
+ "section_id": section,
129
+ "row_number": i,
130
+ "total_rows": len(rows),
131
+ "processing_method": "split_by_rows"
132
+ }
133
+ )
134
+ documents.append(doc)
135
+
136
+ log_message(f"Split table {table_number} into {len(rows)} row chunks")
137
+ return documents
138
+
139
+ def group_entire_table_method(table_data, document_name):
140
+ """Group entire table as one chunk"""
141
+ headers = table_data.get("headers", [])
142
+ rows = table_data.get("data", [])
143
+ section = table_data.get("section", "")
144
+ table_number = table_data.get("table_number", "")
145
+ table_title = table_data.get("table_title", "")
146
+
147
+ meta_info = create_meta_info(document_name, section, table_number, table_title)
148
+ chunk_text = create_chunk_text(meta_info, headers, rows)
149
+
150
+ doc = Document(
151
+ text=chunk_text,
152
+ metadata={
153
+ "type": "table",
154
+ "table_number": table_number,
155
+ "table_title": table_title,
156
+ "document_id": document_name,
157
+ "section": section,
158
+ "section_id": section,
159
+ "total_rows": len(rows),
160
+ "processing_method": "group_entire_table"
161
+ }
162
+ )
163
+
164
+ log_message(f"Grouped entire table {table_number}, rows: {len(rows)}, length: {len(chunk_text)}")
165
+ return [doc]
166
+
167
+ def should_use_custom_processing(document_id, table_number):
168
+ """Check if table should use custom processing"""
169
+ for doc_pattern, config in CUSTOM_TABLE_CONFIGS.items():
170
+ if document_id.startswith(doc_pattern):
171
+ tables_config = config.get("tables", {})
172
+ # Check for exact match or wildcard
173
+ if table_number in tables_config or "*" in tables_config:
174
+ return True, doc_pattern, tables_config.get(table_number, tables_config.get("*"))
175
+ return False, None, None
176
+
177
+ def process_table_with_custom_method(table_data, document_name, method_config):
178
+ """Process table using custom method"""
179
+ method = method_config.get("method")
180
+
181
+ if method == "group_by_column":
182
+ group_column = method_config.get("group_column")
183
+ return group_by_column_method(table_data, document_name, group_column)
184
+ elif method == "split_by_rows":
185
+ return split_by_rows_method(table_data, document_name)
186
+ elif method == "group_entire_table":
187
+ return group_entire_table_method(table_data, document_name)
188
+ else:
189
+ log_message(f"Unknown custom method: {method}, falling back to default processing")
190
+ return None
191
+
192
+ def table_to_document(table_data, document_id=None):
193
+ if isinstance(table_data, dict):
194
+ doc_id = document_id or table_data.get('document_id', table_data.get('document', 'Неизвестно'))
195
+ table_num = table_data.get('table_number', 'Неизвестно')
196
+
197
+ # Check if this table should use custom processing
198
+ use_custom, doc_pattern, method_config = should_use_custom_processing(doc_id, table_num)
199
+
200
+ if use_custom:
201
+ log_message(f"Using custom processing for table {table_num} in document {doc_id}")
202
+ custom_docs = process_table_with_custom_method(table_data, doc_id, method_config)
203
+ if custom_docs:
204
+ # Return custom processed documents and skip default processing
205
+ return custom_docs
206
+
207
+ # Default processing for tables not in custom config
208
+ table_title = table_data.get('table_title', 'Неизвестно')
209
+ section = table_data.get('section', 'Неизвестно')
210
+
211
+ header_content = f"Таблица: {table_num}\nНазвание: {table_title}\nДокумент: {doc_id}\nРаздел: {section}\n"
212
+
213
+ if 'data' in table_data and isinstance(table_data['data'], list):
214
+ table_content = header_content + "\nДанные таблицы:\n"
215
+ for row_idx, row in enumerate(table_data['data']):
216
+ if isinstance(row, dict):
217
+ row_text = " | ".join([f"{k}: {v}" for k, v in row.items()])
218
+ table_content += f"Строка {row_idx + 1}: {row_text}\n"
219
+
220
+ doc = Document(
221
+ text=table_content,
222
+ metadata={
223
+ "type": "table",
224
+ "table_number": table_num,
225
+ "table_title": table_title,
226
+ "document_id": doc_id,
227
+ "section": section,
228
+ "section_id": section,
229
+ "total_rows": len(table_data['data']),
230
+ "processing_method": "default"
231
+ }
232
+ )
233
+ return [doc]
234
+ else:
235
+ doc = Document(
236
+ text=header_content,
237
+ metadata={
238
+ "type": "table",
239
+ "table_number": table_num,
240
+ "table_title": table_title,
241
+ "document_id": doc_id,
242
+ "section": section,
243
+ "section_id": section,
244
+ "processing_method": "default"
245
+ }
246
+ )
247
+ return [doc]
248
+
249
+ return []
250
+
251
+ def load_table_data(repo_id, hf_token, table_data_dir):
252
+ """Modified function with custom table processing integration"""
253
+ log_message("Начинаю загрузку табличных данных")
254
+
255
+ table_files = []
256
+ try:
257
+ files = list_repo_files(repo_id=repo_id, repo_type="dataset", token=hf_token)
258
+ for file in files:
259
+ if file.startswith(table_data_dir) and file.endswith('.json'):
260
+ table_files.append(file)
261
+
262
+ log_message(f"Найдено {len(table_files)} JSON файлов с таблицами")
263
+
264
+ table_documents = []
265
+ for file_path in table_files:
266
+ try:
267
+ log_message(f"Обрабатываю файл: {file_path}")
268
+ local_path = hf_hub_download(
269
+ repo_id=repo_id,
270
+ filename=file_path,
271
+ local_dir='',
272
+ repo_type="dataset",
273
+ token=hf_token
274
+ )
275
+
276
+ with open(local_path, 'r', encoding='utf-8') as f:
277
+ table_data = json.load(f)
278
+
279
+ if isinstance(table_data, dict):
280
+ document_id = table_data.get('document', 'unknown')
281
+
282
+ if 'sheets' in table_data:
283
+ for sheet in table_data['sheets']:
284
+ sheet['document'] = document_id
285
+ # Check if this table uses custom processing
286
+ table_num = sheet.get('table_number', 'Неизвестно')
287
+ use_custom, _, _ = should_use_custom_processing(document_id, table_num)
288
+
289
+ if use_custom:
290
+ log_message(f"Skipping default processing for custom table {table_num} in {document_id}")
291
+
292
+ docs_list = table_to_document(sheet, document_id)
293
+ table_documents.extend(docs_list)
294
+ else:
295
+ # Check if this table uses custom processing
296
+ table_num = table_data.get('table_number', 'Неизвестно')
297
+ use_custom, _, _ = should_use_custom_processing(document_id, table_num)
298
+
299
+ if use_custom:
300
+ log_message(f"Skipping default processing for custom table {table_num} in {document_id}")
301
+
302
+ docs_list = table_to_document(table_data, document_id)
303
+ table_documents.extend(docs_list)
304
+ elif isinstance(table_data, list):
305
+ for table_json in table_data:
306
+ document_id = table_json.get('document', 'unknown')
307
+ table_num = table_json.get('table_number', 'Неизвестно')
308
+ use_custom, _, _ = should_use_custom_processing(document_id, table_num)
309
+
310
+ if use_custom:
311
+ log_message(f"Skipping default processing for custom table {table_num} in {document_id}")
312
+
313
+ docs_list = table_to_document(table_json)
314
+ table_documents.extend(docs_list)
315
+
316
+ except Exception as e:
317
+ log_message(f"Ошибка обработки файла {file_path}: {str(e)}")
318
+ continue
319
+
320
+ log_message(f"Создано {len(table_documents)} документов из таблиц")
321
+ return table_documents
322
+
323
+ except Exception as e:
324
+ log_message(f"Ошибка загрузки табличных данных: {str(e)}")
325
+ return []
tempCodeRunnerFile.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ print(f"\nSuccessfully processed {len(results)} tables in {json_file}.")
2
+ else:
Табличные данные/НП-104-18_ГОСТ 59023.xlsx ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4ea4dc2f6b1cad2637b7147e050418dc6b9e2d81bcaeb091c4e6f490f6c9ceca
3
+ size 292360
Табличные данные_JSON/НП-104-18_ГОСТ 59023.json CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:ee3468bc116401f24b7ab1dff7850e458d933ab157639c3e7127451deb310291
3
- size 2642133
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4b64b00d8e90a82ba5f6a0ff8589b9e9b29b568d28e7d10a743d4a5534d3c655
3
+ size 3316944