GameSentenceMiner 2.9.23__py3-none-any.whl → 2.9.25__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,6 +5,8 @@ from math import floor, ceil
5
5
  from dataclasses_json import dataclass_json
6
6
  from typing import List, Optional, Union
7
7
 
8
+ from GameSentenceMiner.util.configuration import logger
9
+
8
10
 
9
11
  @dataclass_json
10
12
  @dataclass
@@ -51,14 +53,14 @@ class OCRConfig:
51
53
  import pygetwindow as gw
52
54
  try:
53
55
  set_dpi_awareness()
54
- window = gw.getWindowsWithTitle(self.window)[0]
56
+ window = get_window(self.window)
55
57
  self.window_geometry = WindowGeometry(
56
58
  left=window.left,
57
59
  top=window.top,
58
60
  width=window.width,
59
61
  height=window.height,
60
62
  )
61
- print(f"Window '{self.window}' found with geometry: {self.window_geometry}")
63
+ logger.info(f"Window '{self.window}' found with geometry: {self.window_geometry}")
62
64
  except IndexError:
63
65
  raise ValueError(f"Window with title '{self.window}' not found.")
64
66
  for rectangle in self.rectangles:
@@ -69,6 +71,27 @@ class OCRConfig:
69
71
  ceil(rectangle.coordinates[3] * self.window_geometry.height),
70
72
  ]
71
73
 
74
+ def get_window(title):
75
+ import pygetwindow as gw
76
+ windows = gw.getWindowsWithTitle(title)
77
+ if not windows:
78
+ raise ValueError(f"No windows found with title '{title}'.")
79
+ ret = None
80
+ if windows:
81
+ for window in windows:
82
+ if "cmd.exe" in window.title.lower():
83
+ logger.info(f"Skipping cmd.exe window with title: {window.title}")
84
+ continue
85
+ if len(windows) > 1:
86
+ logger.info(
87
+ f"Warning: More than 1 window with title, Window Title: {window.title}, Geometry: {window.left}, {window.top}, {window.width}, {window.height}")
88
+ if window.title == title:
89
+ if window.isMinimized or not window.visible:
90
+ logger.info(f"Warning: Window '{title}' is minimized. Attempting to restore it.")
91
+ window.restore()
92
+ return window
93
+ return ret
94
+
72
95
  # try w10+, fall back to w8.1+
73
96
  def set_dpi_awareness():
74
97
  per_monitor_awareness = 2
@@ -8,7 +8,7 @@ import mss
8
8
  from PIL import Image, ImageTk, ImageDraw
9
9
 
10
10
  from GameSentenceMiner import obs # Import your actual obs module
11
- from GameSentenceMiner.ocr.gsm_ocr_config import set_dpi_awareness
11
+ from GameSentenceMiner.ocr.gsm_ocr_config import set_dpi_awareness, get_window
12
12
  from GameSentenceMiner.util.gsm_utils import sanitize_filename
13
13
 
14
14
  try:
@@ -88,13 +88,7 @@ class ScreenSelector:
88
88
  if not self.window_name:
89
89
  return None
90
90
  try:
91
- windows = gw.getWindowsWithTitle(self.window_name)
92
- if windows:
93
- if len(windows) > 1:
94
- print(f"Warning: Multiple windows found with title '{self.window_name}'. Using the first one.")
95
- return windows[0]
96
- else:
97
- return None
91
+ return get_window(self.window_name)
98
92
  except Exception as e:
99
93
  print(f"Error finding window '{self.window_name}': {e}")
100
94
  return None
@@ -269,7 +263,7 @@ class ScreenSelector:
269
263
  """Saves rectangles to the config file, using percentages if window is targeted."""
270
264
  # Use the window geometry found during __init__ for consistency during save
271
265
  window_geom_to_save = self.target_window_geometry
272
- save_coord_system = COORD_SYSTEM_ABSOLUTE # Default if no window
266
+ save_coord_system = COORD_SYSTEM_PERCENTAGE # Default if no window
273
267
 
274
268
  config_path = self.get_scene_ocr_config()
275
269
  print(f"Saving rectangles to: {config_path}")
@@ -334,7 +328,7 @@ class ScreenSelector:
334
328
  serializable_rects.append(rect_data)
335
329
 
336
330
  # Prepare final data structure for JSON
337
- if len(rectangles) == 0:
331
+ if not self.rectangles or len(self.rectangles) == 0:
338
332
  save_coord_system = COORD_SYSTEM_PERCENTAGE
339
333
  save_data = {
340
334
  "scene": obs.get_current_scene() or "default_scene",
@@ -19,7 +19,7 @@ from GameSentenceMiner.ocr.ss_picker import ScreenCropper
19
19
  from GameSentenceMiner.owocr.owocr.run import TextFiltering
20
20
  from GameSentenceMiner.util.configuration import get_config, get_app_directory, get_temporary_directory
21
21
  from GameSentenceMiner.util.electron_config import get_ocr_scan_rate, get_requires_open_window
22
- from GameSentenceMiner.ocr.gsm_ocr_config import OCRConfig, set_dpi_awareness
22
+ from GameSentenceMiner.ocr.gsm_ocr_config import OCRConfig, set_dpi_awareness, get_window
23
23
  from GameSentenceMiner.owocr.owocr import screen_coordinate_picker, run
24
24
  from GameSentenceMiner.util.gsm_utils import sanitize_filename, do_text_replacements, OCR_REPLACEMENTS_FILE
25
25
 
@@ -238,7 +238,7 @@ def save_result_image(img):
238
238
  async def send_result(text, time):
239
239
  if text:
240
240
  text = do_text_replacements(text, OCR_REPLACEMENTS_FILE)
241
- if get_config().advanced.ocr_sends_to_clipboard or ssonly:
241
+ if get_config().advanced.ocr_sends_to_clipboard or manual:
242
242
  import pyperclip
243
243
  pyperclip.copy(text)
244
244
  try:
@@ -334,16 +334,13 @@ def run_oneocr(ocr_config: OCRConfig, rectangles):
334
334
  global done
335
335
  print("Running OneOCR")
336
336
  screen_area = None
337
- screen_areas = []
338
- exclusions = []
339
- if not ssonly:
340
- screen_areas = [",".join(str(c) for c in rect_config.coordinates) for rect_config in rectangles if not rect_config.is_excluded]
341
- exclusions = list(rect.coordinates for rect in list(filter(lambda x: x.is_excluded, rectangles)))
337
+ screen_areas = [",".join(str(c) for c in rect_config.coordinates) for rect_config in rectangles if not rect_config.is_excluded]
338
+ exclusions = list(rect.coordinates for rect in list(filter(lambda x: x.is_excluded, rectangles)))
342
339
 
343
340
  run.init_config(False)
344
341
  try:
345
- run.run(read_from="screencapture" if not ssonly else "clipboard" if ss_clipboard else "",
346
- read_from_secondary="clipboard" if ss_clipboard and not ssonly else None,
342
+ run.run(read_from="screencapture",
343
+ read_from_secondary="clipboard" if ss_clipboard else None,
347
344
  write_to="callback",
348
345
  screen_capture_area=screen_area,
349
346
  # screen_capture_monitor=monitor_config['index'],
@@ -358,7 +355,8 @@ def run_oneocr(ocr_config: OCRConfig, rectangles):
358
355
  ocr2=ocr2,
359
356
  gsm_ocr_config=ocr_config,
360
357
  screen_capture_areas=screen_areas,
361
- furigana_filter_sensitivity=furigana_filter_sensitivity)
358
+ furigana_filter_sensitivity=furigana_filter_sensitivity,
359
+ screen_capture_combo=manual_ocr_hotkey if manual_ocr_hotkey and manual else None)
362
360
  except Exception as e:
363
361
  logger.exception(f"Error running OneOCR: {e}")
364
362
  done = True
@@ -368,13 +366,12 @@ def run_oneocr(ocr_config: OCRConfig, rectangles):
368
366
  def add_ss_hotkey(ss_hotkey="ctrl+shift+g"):
369
367
  import keyboard
370
368
  cropper = ScreenCropper()
371
- filtering = TextFiltering()
369
+ filtering = TextFiltering(lang=language)
372
370
  def capture():
373
371
  print("Taking screenshot...")
374
372
  img = cropper.run()
375
373
  do_second_ocr("", datetime.now(), img, filtering)
376
374
  try:
377
- raise Exception("Forcing keyboard hotkey setup, this is a test.")
378
375
  keyboard.add_hotkey(ss_hotkey, capture)
379
376
  print(f"Press {ss_hotkey} to take a screenshot.")
380
377
  except Exception as e:
@@ -391,21 +388,6 @@ def add_ss_hotkey(ss_hotkey="ctrl+shift+g"):
391
388
  except Exception as e:
392
389
  logger.error(f"Error setting up screenshot hotkey with pynput, Screenshot Hotkey Will not work: {e}")
393
390
 
394
-
395
- def get_window(window_name):
396
- import pygetwindow as gw
397
- try:
398
- windows = gw.getWindowsWithTitle(window_name)
399
- if windows:
400
- if len(windows) > 1:
401
- print(f"Warning: Multiple windows found with title '{window_name}'. Using the first one.")
402
- return windows[0]
403
- else:
404
- return None
405
- except Exception as e:
406
- print(f"Error finding window '{window_name}': {e}")
407
- return None
408
-
409
391
  def set_force_stable_hotkey():
410
392
  import keyboard
411
393
  global force_stable
@@ -420,7 +402,7 @@ def set_force_stable_hotkey():
420
402
  print("Press Ctrl+Shift+F to toggle force stable mode.")
421
403
 
422
404
  if __name__ == "__main__":
423
- global ocr1, ocr2, twopassocr, language, ss_clipboard, ss, ocr_config, furigana_filter_sensitivity
405
+ global ocr1, ocr2, twopassocr, language, ss_clipboard, ss, ocr_config, furigana_filter_sensitivity, area_select_ocr_hotkey
424
406
  import sys
425
407
 
426
408
  import argparse
@@ -430,11 +412,12 @@ if __name__ == "__main__":
430
412
  parser.add_argument("--ocr1", type=str, default="oneocr", help="Primary OCR engine (default: oneocr)")
431
413
  parser.add_argument("--ocr2", type=str, default="glens", help="Secondary OCR engine (default: glens)")
432
414
  parser.add_argument("--twopassocr", type=int, choices=[0, 1], default=1, help="Enable two-pass OCR (default: 1)")
433
- parser.add_argument("--ssonly", action="store_true", help="Use screenshot-only mode")
415
+ parser.add_argument("--manual", action="store_true", help="Use screenshot-only mode")
434
416
  parser.add_argument("--clipboard", action="store_true", help="Use clipboard for input")
435
417
  parser.add_argument("--window", type=str, help="Specify the window name for OCR")
436
418
  parser.add_argument("--furigana_filter_sensitivity", type=float, default=0, help="Furigana Filter Sensitivity for OCR (default: 0)")
437
- parser.add_argument("--manual_ocr_hotkey", type=str, default="ctrl+shift+g", help="Hotkey for manual OCR (default: ctrl+shift+g)")
419
+ parser.add_argument("--manual_ocr_hotkey", type=str, default=None, help="Hotkey for manual OCR (default: None)")
420
+ parser.add_argument("--area_select_ocr_hotkey", type=str, default="ctrl+shift+o", help="Hotkey for area selection OCR (default: ctrl+shift+o)")
438
421
 
439
422
  args = parser.parse_args()
440
423
 
@@ -442,36 +425,35 @@ if __name__ == "__main__":
442
425
  ocr1 = args.ocr1
443
426
  ocr2 = args.ocr2 if args.ocr2 else None
444
427
  twopassocr = bool(args.twopassocr)
445
- ssonly = args.ssonly
428
+ manual = args.manual
446
429
  ss_clipboard = args.clipboard
447
430
  window_name = args.window
448
431
  furigana_filter_sensitivity = args.furigana_filter_sensitivity
449
- ss_hotkey = args.manual_ocr_hotkey.lower()
432
+ ss_hotkey = args.area_select_ocr_hotkey.lower()
433
+ manual_ocr_hotkey = args.manual_ocr_hotkey.lower().replace("ctrl", "<ctrl>").replace("shift", "<shift>").replace("alt", "<alt>") if args.manual_ocr_hotkey else None
450
434
 
451
435
  logger.info(f"Received arguments: {vars(args)}")
452
436
  # set_force_stable_hotkey()
453
- ocr_config = None
454
- if not ssonly:
455
- ocr_config: OCRConfig = get_ocr_config(window=window_name)
456
- if ocr_config:
457
- if ocr_config.window:
458
- start_time = time.time()
459
- while time.time() - start_time < 30:
460
- if get_window(ocr_config.window):
461
- break
462
- logger.info(f"Window: {ocr_config.window} Could not be found, retrying in 1 second...")
463
- time.sleep(1)
464
- else:
465
- logger.error(f"Window '{ocr_config.window}' not found within 30 seconds.")
466
- sys.exit(1)
467
- logger.info(f"Starting OCR with configuration: Window: {ocr_config.window}, Rectangles: {ocr_config.rectangles}, Engine 1: {ocr1}, Engine 2: {ocr2}, Two-pass OCR: {twopassocr}")
437
+ ocr_config: OCRConfig = get_ocr_config(window=window_name)
438
+ if ocr_config:
439
+ if ocr_config.window:
440
+ start_time = time.time()
441
+ while time.time() - start_time < 30:
442
+ if get_window(ocr_config.window):
443
+ break
444
+ logger.info(f"Window: {ocr_config.window} Could not be found, retrying in 1 second...")
445
+ time.sleep(1)
446
+ else:
447
+ logger.error(f"Window '{ocr_config.window}' not found within 30 seconds.")
448
+ sys.exit(1)
449
+ logger.info(f"Starting OCR with configuration: Window: {ocr_config.window}, Rectangles: {ocr_config.rectangles}, Engine 1: {ocr1}, Engine 2: {ocr2}, Two-pass OCR: {twopassocr}")
468
450
  set_dpi_awareness()
469
- if ssonly or ocr_config:
451
+ if manual or ocr_config:
470
452
  rectangles = ocr_config.rectangles if ocr_config and ocr_config.rectangles else []
471
453
  oneocr_threads = []
472
454
  ocr_thread = threading.Thread(target=run_oneocr, args=(ocr_config,rectangles ), daemon=True)
473
455
  ocr_thread.start()
474
- if not ssonly:
456
+ if not manual:
475
457
  worker_thread = threading.Thread(target=process_task_queue, daemon=True)
476
458
  worker_thread.start()
477
459
  websocket_server_thread = WebsocketServerThread(read=True)
@@ -307,6 +307,7 @@ class GoogleLens:
307
307
  # json.dump(response_dict, f, indent=4, ensure_ascii=False)
308
308
  res = ''
309
309
  text = response_dict['objects_response']['text']
310
+ skipped = []
310
311
  if furigana_filter_sensitivity > 0:
311
312
  if 'text_layout' in text:
312
313
  for paragraph in text['text_layout']['paragraphs']:
@@ -315,9 +316,11 @@ class GoogleLens:
315
316
  for word in line['words']:
316
317
  res += word['plain_text'] + word['text_separator']
317
318
  else:
319
+ skipped.append(word['plain_text'] for word in line['words'])
318
320
  continue
319
321
  res += '\n'
320
-
322
+ # logger.info(
323
+ # f"Skipped {len(skipped)} chars due to furigana filter sensitivity: {furigana_filter_sensitivity}")
321
324
  # widths = []
322
325
  # heights = []
323
326
  # if 'text_layout' in text:
@@ -789,7 +792,6 @@ class OneOCR:
789
792
  available = False
790
793
 
791
794
  def __init__(self, config={}):
792
- self.kana_kanji_regex = re.compile(r'[\u3041-\u3096\u30A1-\u30FA\u4E00-\u9FFF]')
793
795
  if sys.platform == 'win32':
794
796
  if int(platform.release()) < 10:
795
797
  logger.warning('OneOCR is not supported on Windows older than 10!')
@@ -836,10 +838,9 @@ class OneOCR:
836
838
  # encoding='utf-8') as f:
837
839
  # json.dump(ocr_resp, f, indent=4, ensure_ascii=False)
838
840
  res = ''
841
+ skipped = []
839
842
  if furigana_filter_sensitivity > 0:
840
843
  for line in ocr_resp['lines']:
841
- if self.kana_kanji_regex.search(line['text']) is None:
842
- continue
843
844
  x1, x2, x3, x4 = line['bounding_rect']['x1'], line['bounding_rect']['x2'], \
844
845
  line['bounding_rect']['x3'], line['bounding_rect']['x4']
845
846
  y1, y2, y3, y4 = line['bounding_rect']['y1'], line['bounding_rect']['y2'], \
@@ -849,8 +850,11 @@ class OneOCR:
849
850
  if width > furigana_filter_sensitivity and height > furigana_filter_sensitivity:
850
851
  res += line['text']
851
852
  else:
853
+ skipped.extend(char for char in line['text'])
852
854
  continue
853
855
  res += '\n'
856
+ # logger.info(
857
+ # f"Skipped {len(skipped)} chars due to furigana filter sensitivity: {furigana_filter_sensitivity}")
854
858
  # widths, heights = [], []
855
859
  # for line in ocr_resp['lines']:
856
860
  # for word in line['words']:
@@ -309,7 +309,7 @@ class RequestHandler(socketserver.BaseRequestHandler):
309
309
  class TextFiltering:
310
310
  accurate_filtering = False
311
311
 
312
- def __init__(self):
312
+ def __init__(self, lang="ja"):
313
313
  from pysbd import Segmenter
314
314
  self.segmenter = Segmenter(language=lang, clean=True)
315
315
  self.kana_kanji_regex = re.compile(r'[\u3041-\u3096\u30A1-\u30FA\u4E00-\u9FFF]')
@@ -1159,7 +1159,6 @@ def run(read_from=None,
1159
1159
 
1160
1160
  if 'screencapture' in (read_from, read_from_secondary):
1161
1161
  global take_screenshot
1162
- screen_capture_combo = config.get_general('screen_capture_combo')
1163
1162
  last_screenshot_time = 0
1164
1163
  last_result = ([], engine_index)
1165
1164
  if screen_capture_combo != '':
@@ -1216,6 +1215,8 @@ def run(read_from=None,
1216
1215
  user_input_thread = threading.Thread(target=user_input_thread_run, daemon=True)
1217
1216
  user_input_thread.start()
1218
1217
  logger.opt(ansi=True).info(f"Reading from {' and '.join(read_from_readable)}, writing to {write_to_readable} using <{engine_color}>{engine_instances[engine_index].readable_name}</{engine_color}>{' (paused)' if paused else ''}")
1218
+ if screen_capture_combo:
1219
+ logger.opt(ansi=True).info(f'Manual OCR Running... Press <{engine_color}>{screen_capture_combo.replace("<", "").replace(">", "")}</{engine_color}> to run OCR')
1219
1220
 
1220
1221
  while not terminated:
1221
1222
  ocr_start_time = datetime.now()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GameSentenceMiner
3
- Version: 2.9.23
3
+ Version: 2.9.25
4
4
  Summary: A tool for mining sentences from games.
5
5
  Author-email: Beangate <bpwhelan95@gmail.com>
6
6
  License: MIT License
@@ -16,17 +16,17 @@ GameSentenceMiner/assets/icon512.png,sha256=HxUj2GHjyQsk8NV433256UxU9phPhtjCY-YB
16
16
  GameSentenceMiner/assets/icon64.png,sha256=N8xgdZXvhqVQP9QUK3wX5iqxX9LxHljD7c-Bmgim6tM,9301
17
17
  GameSentenceMiner/assets/pickaxe.png,sha256=VfIGyXyIZdzEnVcc4PmG3wszPMO1W4KCT7Q_nFK6eSE,1403829
18
18
  GameSentenceMiner/ocr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
- GameSentenceMiner/ocr/gsm_ocr_config.py,sha256=fEQ2o2NXksGRHpueO8c4TfAp75GEdAtAr1ngTFOsdpg,2257
19
+ GameSentenceMiner/ocr/gsm_ocr_config.py,sha256=0_4aug96x8JFsOVdYr7wjs5U-l4PPW7Y_V_09oDML-8,3220
20
20
  GameSentenceMiner/ocr/ocrconfig.py,sha256=_tY8mjnzHMJrLS8E5pHqYXZjMuLoGKYgJwdhYgN-ny4,6466
21
- GameSentenceMiner/ocr/owocr_area_selector.py,sha256=HvzGDW5UaJ3AmrKV_IqOfCvZ7D7X6S3th_XnXk_LIU0,47259
22
- GameSentenceMiner/ocr/owocr_helper.py,sha256=idjVB8Ln9PwNUFZMOtRkq7wAhbteU7-haRM7Cf_wmY4,20979
21
+ GameSentenceMiner/ocr/owocr_area_selector.py,sha256=qLsnM_UEP14V7t8vpERji_-_TwpwEI3Gd4BFck4vYaY,47029
22
+ GameSentenceMiner/ocr/owocr_helper.py,sha256=QeQ0PrUcfFASVlsdbTXG5sxdke3x0d-gPnfRQw6L6RY,20666
23
23
  GameSentenceMiner/ocr/ss_picker.py,sha256=Ck2K9JliXhY_7a7nS0BVsoAmzwPFFtsW_TxHCcfxT00,4274
24
24
  GameSentenceMiner/owocr/owocr/__init__.py,sha256=87hfN5u_PbL_onLfMACbc0F5j4KyIK9lKnRCj6oZgR0,49
25
25
  GameSentenceMiner/owocr/owocr/__main__.py,sha256=XQaqZY99EKoCpU-gWQjNbTs7Kg17HvBVE7JY8LqIE0o,157
26
26
  GameSentenceMiner/owocr/owocr/config.py,sha256=qM7kISHdUhuygGXOxmgU6Ef2nwBShrZtdqu4InDCViE,8103
27
27
  GameSentenceMiner/owocr/owocr/lens_betterproto.py,sha256=oNoISsPilVVRBBPVDtb4-roJtAhp8ZAuFTci3TGXtMc,39141
28
- GameSentenceMiner/owocr/owocr/ocr.py,sha256=uEv0Pjvq7n6XJOkV4i_EiR0wxXqzi2EVpWsK2-i3SXs,51932
29
- GameSentenceMiner/owocr/owocr/run.py,sha256=bNh9nF0tzFa7BuW-ixcipyf6vTrNyaNwtgG6W4a-uIo,55063
28
+ GameSentenceMiner/owocr/owocr/ocr.py,sha256=fWrbKomSrdkSdlEiMGTKb6-F7wCgfaZZNBUo2gCqmuA,52247
29
+ GameSentenceMiner/owocr/owocr/run.py,sha256=wOileOoP1djCpOLgg7d-nWrYS78NctClNTscLZ3kwDc,55198
30
30
  GameSentenceMiner/owocr/owocr/screen_coordinate_picker.py,sha256=Na6XStbQBtpQUSdbN3QhEswtKuU1JjReFk_K8t5ezQE,3395
31
31
  GameSentenceMiner/util/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
32
32
  GameSentenceMiner/util/configuration.py,sha256=TAdd-aLMCMvpu7OS1Y5brKQC4svcK29J94nvrEb4Ue4,27535
@@ -61,9 +61,9 @@ GameSentenceMiner/web/templates/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm
61
61
  GameSentenceMiner/web/templates/index.html,sha256=HZKiIjiGJV8PGQ9T2aLDUNSfJn71qOwbYCjbRuSIjpY,213583
62
62
  GameSentenceMiner/web/templates/text_replacements.html,sha256=tV5c8mCaWSt_vKuUpbdbLAzXZ3ATZeDvQ9PnnAfqY0M,8598
63
63
  GameSentenceMiner/web/templates/utility.html,sha256=3flZinKNqUJ7pvrZk6xu__v67z44rXnaK7UTZ303R-8,16946
64
- gamesentenceminer-2.9.23.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
65
- gamesentenceminer-2.9.23.dist-info/METADATA,sha256=4NIEep_aRefXZXkRen67RttLkQRsm-Zgcb7pi9g801g,7276
66
- gamesentenceminer-2.9.23.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
67
- gamesentenceminer-2.9.23.dist-info/entry_points.txt,sha256=2APEP25DbfjSxGeHtwBstMH8mulVhLkqF_b9bqzU6vQ,65
68
- gamesentenceminer-2.9.23.dist-info/top_level.txt,sha256=V1hUY6xVSyUEohb0uDoN4UIE6rUZ_JYx8yMyPGX4PgQ,18
69
- gamesentenceminer-2.9.23.dist-info/RECORD,,
64
+ gamesentenceminer-2.9.25.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
65
+ gamesentenceminer-2.9.25.dist-info/METADATA,sha256=fH0PSv9qJAA6wBq72A3c1xEhB0Y2jE6fkWyen-i6M1Y,7276
66
+ gamesentenceminer-2.9.25.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
67
+ gamesentenceminer-2.9.25.dist-info/entry_points.txt,sha256=2APEP25DbfjSxGeHtwBstMH8mulVhLkqF_b9bqzU6vQ,65
68
+ gamesentenceminer-2.9.25.dist-info/top_level.txt,sha256=V1hUY6xVSyUEohb0uDoN4UIE6rUZ_JYx8yMyPGX4PgQ,18
69
+ gamesentenceminer-2.9.25.dist-info/RECORD,,