supervertaler 1.9.153__py3-none-any.whl → 1.9.164__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.
@@ -840,11 +840,15 @@ class DatabaseManager:
840
840
  bidirectional: If True, search both directions (nl→en AND en→nl)
841
841
 
842
842
  Returns: List of matches with similarity scores
843
+
844
+ Note: When multiple TMs are provided, searches each TM separately to ensure
845
+ good matches from smaller TMs aren't pushed out by BM25 keyword ranking
846
+ from larger TMs. Results are merged and sorted by actual similarity.
843
847
  """
844
848
  # For better FTS5 matching, tokenize the query and escape special chars
845
849
  # FTS5 special characters: " ( ) - : , . ! ?
846
850
  import re
847
- from modules.tmx_generator import get_base_lang_code
851
+ from modules.tmx_generator import get_base_lang_code, get_lang_match_variants
848
852
 
849
853
  # Strip HTML/XML tags from source for clean text search
850
854
  text_without_tags = re.sub(r'<[^>]+>', '', source)
@@ -868,22 +872,57 @@ class DatabaseManager:
868
872
  # This helps find similar long segments more reliably
869
873
  search_terms_for_query = all_search_terms[:20]
870
874
 
871
- print(f"[DEBUG] search_fuzzy_matches: source='{source[:50]}...', {len(all_search_terms)} terms")
872
-
873
875
  if not search_terms_for_query:
874
876
  # If no valid terms, return empty results
875
- print(f"[DEBUG] search_fuzzy_matches: No valid search terms, returning empty")
876
877
  return []
877
878
 
878
879
  # Quote each term to prevent FTS5 syntax errors
879
880
  fts_query = ' OR '.join(f'"{term}"' for term in search_terms_for_query)
880
- print(f"[DEBUG] search_fuzzy_matches: FTS query terms = {search_terms_for_query[:10]}...")
881
881
 
882
882
  # Get base language codes for comparison
883
883
  src_base = get_base_lang_code(source_lang) if source_lang else None
884
884
  tgt_base = get_base_lang_code(target_lang) if target_lang else None
885
885
 
886
- # Use FTS5 for initial candidate retrieval (fast)
886
+ # MULTI-TM FIX: Search each TM separately to avoid BM25 ranking issues
887
+ # When a large TM is combined with a small TM, the large TM's many keyword matches
888
+ # push down genuinely similar sentences from the small TM
889
+ tms_to_search = tm_ids if tm_ids else [None] # None means search all TMs together
890
+
891
+ all_results = []
892
+
893
+ for tm_id in tms_to_search:
894
+ # Search this specific TM (or all if tm_id is None)
895
+ tm_results = self._search_single_tm_fuzzy(
896
+ source, fts_query, [tm_id] if tm_id else None,
897
+ threshold, max_results, src_base, tgt_base,
898
+ source_lang, target_lang, bidirectional
899
+ )
900
+ all_results.extend(tm_results)
901
+
902
+ # Deduplicate by source_text (keep highest similarity for each unique source)
903
+ seen = {}
904
+ for result in all_results:
905
+ key = result['source_text']
906
+ if key not in seen or result['similarity'] > seen[key]['similarity']:
907
+ seen[key] = result
908
+
909
+ deduped_results = list(seen.values())
910
+
911
+ # Sort ALL results by similarity (highest first) - this ensures the 76% match
912
+ # appears before 40% matches regardless of which TM they came from
913
+ deduped_results.sort(key=lambda x: x['similarity'], reverse=True)
914
+
915
+ return deduped_results[:max_results]
916
+
917
+ def _search_single_tm_fuzzy(self, source: str, fts_query: str, tm_ids: List[str],
918
+ threshold: float, max_results: int,
919
+ src_base: str, tgt_base: str,
920
+ source_lang: str, target_lang: str,
921
+ bidirectional: bool) -> List[Dict]:
922
+ """Search a single TM (or all TMs if tm_ids is None) for fuzzy matches"""
923
+ from modules.tmx_generator import get_lang_match_variants
924
+
925
+ # Build query for this TM
887
926
  query = """
888
927
  SELECT tu.*,
889
928
  bm25(translation_units_fts) as relevance
@@ -893,13 +932,12 @@ class DatabaseManager:
893
932
  """
894
933
  params = [fts_query]
895
934
 
896
- if tm_ids:
935
+ if tm_ids and tm_ids[0] is not None:
897
936
  placeholders = ','.join('?' * len(tm_ids))
898
937
  query += f" AND tu.tm_id IN ({placeholders})"
899
938
  params.extend(tm_ids)
900
939
 
901
940
  # Use flexible language matching (matches 'nl', 'nl-NL', 'Dutch', etc.)
902
- from modules.tmx_generator import get_lang_match_variants
903
941
  if src_base:
904
942
  src_variants = get_lang_match_variants(source_lang)
905
943
  src_conditions = []
@@ -920,19 +958,16 @@ class DatabaseManager:
920
958
  params.append(f"{variant}-%")
921
959
  query += f" AND ({' OR '.join(tgt_conditions)})"
922
960
 
923
- # Get more candidates than needed for proper scoring (increase limit for long segments)
924
- # Long segments need MANY more candidates because BM25 ranking may push down
925
- # the truly similar entries in favor of entries matching more search terms
961
+ # Per-TM candidate limit - INCREASED to catch more potential fuzzy matches
962
+ # When multiple TMs are searched, BM25 ranking can push genuinely similar
963
+ # entries far down the list due to common word matches in other entries
926
964
  candidate_limit = max(500, max_results * 50)
927
965
  query += f" ORDER BY relevance DESC LIMIT {candidate_limit}"
928
966
 
929
- print(f"[DEBUG] search_fuzzy_matches: Executing query (limit={candidate_limit})...")
930
-
931
967
  try:
932
968
  self.cursor.execute(query, params)
933
969
  all_rows = self.cursor.fetchall()
934
970
  except Exception as e:
935
- print(f"[DEBUG] search_fuzzy_matches: SQL ERROR: {e}")
936
971
  return []
937
972
 
938
973
  results = []
@@ -948,8 +983,6 @@ class DatabaseManager:
948
983
  match_dict['match_pct'] = int(similarity * 100)
949
984
  results.append(match_dict)
950
985
 
951
- print(f"[DEBUG] search_fuzzy_matches: After threshold filter ({threshold}): {len(results)} matches")
952
-
953
986
  # If bidirectional, also search reverse direction
954
987
  if bidirectional and src_base and tgt_base:
955
988
  query = """
@@ -961,13 +994,12 @@ class DatabaseManager:
961
994
  """
962
995
  params = [fts_query]
963
996
 
964
- if tm_ids:
997
+ if tm_ids and tm_ids[0] is not None:
965
998
  placeholders = ','.join('?' * len(tm_ids))
966
999
  query += f" AND tu.tm_id IN ({placeholders})"
967
1000
  params.extend(tm_ids)
968
1001
 
969
1002
  # Reversed language filters with flexible matching
970
- # For reverse: TM target_lang should match our source_lang, TM source_lang should match our target_lang
971
1003
  src_variants = get_lang_match_variants(source_lang)
972
1004
  tgt_variants = get_lang_match_variants(target_lang)
973
1005
 
@@ -991,26 +1023,27 @@ class DatabaseManager:
991
1023
 
992
1024
  query += f" ORDER BY relevance DESC LIMIT {max_results * 5}"
993
1025
 
994
- self.cursor.execute(query, params)
995
-
996
- for row in self.cursor.fetchall():
997
- match_dict = dict(row)
998
- # Calculate similarity against target_text (since we're reversing)
999
- similarity = self.calculate_similarity(source, match_dict['target_text'])
1026
+ try:
1027
+ self.cursor.execute(query, params)
1000
1028
 
1001
- # Only include matches above threshold
1002
- if similarity >= threshold:
1003
- # Swap source/target for reverse match
1004
- match_dict['source_text'], match_dict['target_text'] = match_dict['target_text'], match_dict['source_text']
1005
- match_dict['source_lang'], match_dict['target_lang'] = match_dict['target_lang'], match_dict['source_lang']
1006
- match_dict['similarity'] = similarity
1007
- match_dict['match_pct'] = int(similarity * 100)
1008
- match_dict['reverse_match'] = True
1009
- results.append(match_dict)
1010
-
1011
- # Sort by similarity (highest first) and limit results
1012
- results.sort(key=lambda x: x['similarity'], reverse=True)
1013
- return results[:max_results]
1029
+ for row in self.cursor.fetchall():
1030
+ match_dict = dict(row)
1031
+ # Calculate similarity against target_text (since we're reversing)
1032
+ similarity = self.calculate_similarity(source, match_dict['target_text'])
1033
+
1034
+ # Only include matches above threshold
1035
+ if similarity >= threshold:
1036
+ # Swap source/target for reverse match
1037
+ match_dict['source_text'], match_dict['target_text'] = match_dict['target_text'], match_dict['source_text']
1038
+ match_dict['source_lang'], match_dict['target_lang'] = match_dict['target_lang'], match_dict['source_lang']
1039
+ match_dict['similarity'] = similarity
1040
+ match_dict['match_pct'] = int(similarity * 100)
1041
+ match_dict['reverse_match'] = True
1042
+ results.append(match_dict)
1043
+ except Exception as e:
1044
+ print(f"[DEBUG] _search_single_tm_fuzzy (reverse): SQL ERROR: {e}")
1045
+
1046
+ return results
1014
1047
 
1015
1048
  def search_all(self, source: str, tm_ids: List[str] = None, enabled_only: bool = True,
1016
1049
  threshold: float = 0.75, max_results: int = 10) -> List[Dict]:
modules/superlookup.py CHANGED
@@ -88,14 +88,18 @@ class SuperlookupEngine:
88
88
  Captured text or None if failed
89
89
  """
90
90
  try:
91
- import keyboard
92
-
93
- # Wait for hotkey to release before sending Ctrl+C
94
- time.sleep(0.2)
95
-
96
- # Use keyboard library to send Ctrl+C
97
- keyboard.press_and_release('ctrl+c')
98
- time.sleep(0.2)
91
+ # keyboard module is Windows-only
92
+ try:
93
+ import keyboard
94
+ # Wait for hotkey to release before sending Ctrl+C
95
+ time.sleep(0.2)
96
+ # Use keyboard library to send Ctrl+C
97
+ keyboard.press_and_release('ctrl+c')
98
+ time.sleep(0.2)
99
+ except ImportError:
100
+ # On non-Windows, just try to get clipboard content directly
101
+ # (user needs to have copied text manually)
102
+ pass
99
103
 
100
104
  # Get clipboard
101
105
  text = pyperclip.paste()
modules/tag_manager.py CHANGED
@@ -77,15 +77,33 @@ class TagManager:
77
77
  runs = []
78
78
  current_pos = 0
79
79
 
80
+ # Check if paragraph style has bold/italic formatting
81
+ # This handles cases like "Subtitle" or "Title" styles that are bold
82
+ style_bold = False
83
+ style_italic = False
84
+ try:
85
+ if paragraph.style and paragraph.style.font:
86
+ if paragraph.style.font.bold:
87
+ style_bold = True
88
+ if paragraph.style.font.italic:
89
+ style_italic = True
90
+ except Exception:
91
+ pass # If we can't read style, just use run-level formatting
92
+
80
93
  for run in paragraph.runs:
81
94
  text = run.text
82
95
  if not text:
83
96
  continue
84
97
 
98
+ # Combine run-level formatting with style-level formatting
99
+ # run.bold can be True, False, or None (None means inherit from style)
100
+ is_bold = run.bold if run.bold is not None else style_bold
101
+ is_italic = run.italic if run.italic is not None else style_italic
102
+
85
103
  run_info = FormattingRun(
86
104
  text=text,
87
- bold=run.bold or False,
88
- italic=run.italic or False,
105
+ bold=is_bold or False,
106
+ italic=is_italic or False,
89
107
  underline=run.underline or False,
90
108
  subscript=run.font.subscript or False if run.font else False,
91
109
  superscript=run.font.superscript or False if run.font else False,
@@ -515,6 +515,9 @@ class TermviewWidget(QWidget):
515
515
  self.current_target_lang = None
516
516
  self.current_project_id = None # Store project ID for termbase priority lookup
517
517
 
518
+ # Debug mode - disable verbose tokenization logging by default (performance)
519
+ self.debug_tokenize = False
520
+
518
521
  # Default font settings (will be updated from main app settings)
519
522
  self.current_font_family = "Segoe UI"
520
523
  self.current_font_size = 10
@@ -820,7 +823,6 @@ class TermviewWidget(QWidget):
820
823
 
821
824
  # Check if this is a non-translatable
822
825
  if lookup_key in nt_dict:
823
- # Create NT block
824
826
  nt_block = NTBlock(token, nt_dict[lookup_key], self, theme_manager=self.theme_manager,
825
827
  font_size=self.current_font_size, font_family=self.current_font_family,
826
828
  font_bold=self.current_font_bold)
@@ -996,9 +998,9 @@ class TermviewWidget(QWidget):
996
998
  Returns:
997
999
  List of tokens (words/phrases/numbers), with multi-word terms kept together
998
1000
  """
999
- # DEBUG: Log multi-word terms we're looking for
1001
+ # DEBUG: Log multi-word terms we're looking for (only if debug_tokenize enabled)
1000
1002
  multi_word_terms = [k for k in matches.keys() if ' ' in k]
1001
- if multi_word_terms:
1003
+ if multi_word_terms and self.debug_tokenize:
1002
1004
  self.log(f"🔍 Tokenize: Looking for {len(multi_word_terms)} multi-word terms:")
1003
1005
  for term in sorted(multi_word_terms, key=len, reverse=True)[:3]:
1004
1006
  self.log(f" - '{term}'")
@@ -1023,11 +1025,12 @@ class TermviewWidget(QWidget):
1023
1025
  else:
1024
1026
  pattern = r'\b' + term_escaped + r'\b'
1025
1027
 
1026
- # DEBUG: Check if multi-word term is found
1028
+ # DEBUG: Check if multi-word term is found (only if debug_tokenize enabled)
1027
1029
  found = re.search(pattern, text_lower)
1028
- self.log(f"🔍 Tokenize: Pattern '{pattern}' for '{term}' → {'FOUND' if found else 'NOT FOUND'}")
1029
- if found:
1030
- self.log(f" Match at position {found.span()}: '{text[found.start():found.end()]}'")
1030
+ if self.debug_tokenize:
1031
+ self.log(f"🔍 Tokenize: Pattern '{pattern}' for '{term}' → {'FOUND' if found else 'NOT FOUND'}")
1032
+ if found:
1033
+ self.log(f" Match at position {found.span()}: '{text[found.start():found.end()]}'")
1031
1034
 
1032
1035
  # Find all matches using regex
1033
1036
  for match in re.finditer(pattern, text_lower):
@@ -1040,10 +1043,11 @@ class TermviewWidget(QWidget):
1040
1043
  original_term = text[pos:pos + len(term)]
1041
1044
  tokens_with_positions.append((pos, len(term), original_term))
1042
1045
  used_positions.update(term_positions)
1043
- self.log(f" ✅ Added multi-word token: '{original_term}' covering positions {pos}-{pos+len(term)}")
1046
+ if self.debug_tokenize:
1047
+ self.log(f" ✅ Added multi-word token: '{original_term}' covering positions {pos}-{pos+len(term)}")
1044
1048
 
1045
- # DEBUG: Log used_positions after first pass
1046
- if ' ' in sorted(matches.keys(), key=len, reverse=True)[0]:
1049
+ # DEBUG: Log used_positions after first pass (only if debug_tokenize enabled)
1050
+ if matches and ' ' in sorted(matches.keys(), key=len, reverse=True)[0] and self.debug_tokenize:
1047
1051
  self.log(f"🔍 After first pass: {len(used_positions)} positions marked as used")
1048
1052
  self.log(f" Used positions: {sorted(list(used_positions))[:20]}...")
1049
1053
 
@@ -123,8 +123,8 @@ class TMDatabase:
123
123
  if source_lang and target_lang:
124
124
  self.set_tm_languages(source_lang, target_lang)
125
125
 
126
- # Global fuzzy threshold
127
- self.fuzzy_threshold = 0.75
126
+ # Global fuzzy threshold (70% minimum similarity for fuzzy matches)
127
+ self.fuzzy_threshold = 0.7
128
128
 
129
129
  # TM metadata cache (populated from database as needed)
130
130
  # Note: Legacy 'project' and 'big_mama' TMs are no longer used.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: supervertaler
3
- Version: 1.9.153
3
+ Version: 1.9.164
4
4
  Summary: Professional AI-enhanced translation workbench with multi-LLM support, glossary system, TM, spellcheck, voice commands, and PyQt6 interface. Batteries included (core).
5
5
  Home-page: https://supervertaler.com
6
6
  Author: Michael Beijer
@@ -71,7 +71,7 @@ Dynamic: home-page
71
71
  Dynamic: license-file
72
72
  Dynamic: requires-python
73
73
 
74
- # 🚀 Supervertaler v1.9.153
74
+ # 🚀 Supervertaler v1.9.164
75
75
 
76
76
  [![PyPI version](https://badge.fury.io/py/supervertaler.svg)](https://pypi.org/project/Supervertaler/)
77
77
  [![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)
@@ -79,17 +79,27 @@ Dynamic: requires-python
79
79
 
80
80
  AI-enhanced CAT tool with multi-LLM support (GPT-4, Claude, Gemini, Ollama), innovative Superlookup concordance system offering access to multiple terminology sources (TMs, glossaries, web resources, etc.), and seamless CAT tool integration (memoQ, Trados, CafeTran, Phrase).
81
81
 
82
- **Current Version:** v1.9.153 (January 23, 2026)
82
+ **Current Version:** v1.9.164 (January 26, 2026)
83
83
 
84
- ### NEW in v1.9.153 - 📝 Tab Layout Reorganization
84
+ ### NEW in v1.9.162 - Cache Kill Switch & Performance Testing
85
85
 
86
- Redesigned the tab layout to improve workflow:
87
- - Termview stays under the grid
88
- - Second Termview instance added to right panel
89
- - Segment Note and Session Log moved to right panel
90
- - Better organization: Left panel (grid + Termview), Right panel (all other tabs)
86
+ Added experimental performance toggle to test grid responsiveness:
87
+ - **New Setting:** Settings Experimental Performance → "Disable all caching systems"
88
+ - **What it does:** Bypasses termbase cache, TM/MT cache, and prefetch workers
89
+ - **Why:** Testing showed direct database lookups may be faster than cache overhead for some workflows
90
+ - **Proactive Highlighting:** Glossary terms now highlighted in upcoming segments while you're still editing the current one
91
+ - **Improved TM Matching:** Fixed fuzzy match issues with multi-TM projects
91
92
 
92
- ### Previously in v1.9.152 - Instant Glossary Updates
93
+ ### Previously in v1.9.154 - 🎯 Match Panel Consolidation
94
+
95
+ Streamlined the right panel by replacing Compare Panel with Match Panel:
96
+ - **Match Panel** combines Termview + TM Source/Target in one tab
97
+ - Compare Panel removed (was redundant with Translation Results)
98
+ - TM matches display with green background for easy identification
99
+ - Zoom shortcuts (Ctrl+Alt+=/Ctrl+Alt+-) now work on Match Panel TM boxes
100
+ - Cleaner UI with less tab switching needed
101
+
102
+ ### v1.9.153 - 📝 Tab Layout Reorganization
93
103
 
94
104
  **Lightning-Fast Term Addition:** Adding terms to glossaries now feels instant! When you add a term with Alt+Shift+Up/Down, it appears immediately in TermView AND the source highlighting updates instantly - no more 5-6 second delays.
95
105
 
@@ -1,4 +1,4 @@
1
- Supervertaler.py,sha256=LyZjLl_NFBBGO6Y1b0p5GHWq6w2qi-9zzJqjk02RjFI,2234617
1
+ Supervertaler.py,sha256=gh-67gpR65ZbNF8grWDpJJR9pUXr5wQ1p37nTRtsj3w,2264715
2
2
  modules/__init__.py,sha256=G58XleS-EJ2sX4Kehm-3N2m618_W2Es0Kg8CW_eBG7g,327
3
3
  modules/ai_actions.py,sha256=i5MJcM-7Y6CAvKUwxmxrVHeoZAVtAP7aRDdWM5KLkO0,33877
4
4
  modules/ai_attachment_manager.py,sha256=juZlrW3UPkIkcnj0SREgOQkQROLf0fcu3ShZcKXMxsI,11361
@@ -6,7 +6,7 @@ modules/ai_file_viewer_dialog.py,sha256=lKKqUUlOEVgHmmu6aRxqH7P6ds-7dRLk4ltDyjCw
6
6
  modules/autofingers_engine.py,sha256=eJ7tBi7YJvTToe5hYTfnyGXB-qme_cHrOPZibaoR2Xw,17061
7
7
  modules/cafetran_docx_handler.py,sha256=_F7Jh0WPVaDnMhdxEsVSXuD1fN9r-S_V6i0gr86Pdfc,14076
8
8
  modules/config_manager.py,sha256=MkPY3xVFgFDkcwewLREg4BfyKueO0OJkT1cTLxehcjM,17894
9
- modules/database_manager.py,sha256=Vta2UqqSHrJg9459Qq3E440gD2feQxwzSAWeilehmyA,78715
9
+ modules/database_manager.py,sha256=ZdsiuwF67lh-FPKPdalWsW9t6IieX_FM0fA2Bca1xSQ,80221
10
10
  modules/database_migrations.py,sha256=Y1onFsLDV_6vzJLOpNy3WCZDohBZ2jc4prM-g2_RwLE,14085
11
11
  modules/dejavurtf_handler.py,sha256=8NZPPYtHga40SZCypHjPoJPmZTvm9rD-eEUUab7mjtg,28156
12
12
  modules/document_analyzer.py,sha256=t1rVvqLaTcpQTEja228C7zZnh8dXshK4wA9t1E9aGVk,19524
@@ -52,14 +52,14 @@ modules/supercleaner.py,sha256=uRJAEh03Eu4Qtujrf_jxuIyPBbcxKAZzryhV9Chi9ro,22939
52
52
  modules/supercleaner_ui.py,sha256=sVTnYxlX9R20eWs52BKCeQ15iFVFOIQEl29L72lup1c,18812
53
53
  modules/superdocs.py,sha256=vMYyUbHU8zDkS1YMSDF7niDkT8d8FJFDcfIxSktCyGc,522
54
54
  modules/superdocs_viewer_qt.py,sha256=dBxKz71m7EH0jPoKfWLXByMXeAgEZa7zMRu13YsMBBI,14975
55
- modules/superlookup.py,sha256=xXT1nArWJjefko-sXitndfsbSyL66RnqB-JweVWWKyY,8729
55
+ modules/superlookup.py,sha256=Zc6StQppFRlh6S3h7A6Rjzwl3twe0JHAkTUiybAaBU0,8980
56
56
  modules/tag_cleaner.py,sha256=u7VOchIWzD4sAhFs3X1Vuo3hX6X72zESQ0AGZE83cYc,8703
57
- modules/tag_manager.py,sha256=Buc2yUD3vE5VM40nsyQQG_qw_oRlC0qjYT8JCQJmXe8,11910
57
+ modules/tag_manager.py,sha256=g66S0JSxdguN9AhWzZG3hsIz87Ul51wQ3c2wOCTZVSk,12789
58
58
  modules/term_extractor.py,sha256=qPvKNCVXFTGEGwXNvvC0cfCmdb5c3WhzE38EOgKdKUI,11253
59
59
  modules/termbase_entry_editor.py,sha256=iWO9CgLjMomGAqBXDsGAX7TFJvDOp2s_taS4gBL1rZY,35818
60
60
  modules/termbase_import_export.py,sha256=16IAY04IS_rgt0GH5UOUzUI5NoqAli4JMfMquxmFBm0,23552
61
61
  modules/termbase_manager.py,sha256=-PlGF6fIA7KYCteoQ8FZ_0SQZNRRBFAtLimHPbmhQ6w,44544
62
- modules/termview_widget.py,sha256=Imflzotv1raLH-tL4l3MquCL2Pwb56oLIfds4hg7A20,53125
62
+ modules/termview_widget.py,sha256=O3ah7g-4Lb_iUctxl9sMyxh8V3A5I5PFxmy9iIH2Kgk,53484
63
63
  modules/theme_manager.py,sha256=EOI_5pM2bXAadw08bbl92TLN-w28lbw4Zi1E8vQ-kM0,16694
64
64
  modules/tm_editor_dialog.py,sha256=AzGwq4QW641uFJdF8DljLTRRp4FLoYX3Pe4rlTjQWNg,3517
65
65
  modules/tm_manager_qt.py,sha256=h2bvXkRuboHf_RRz9-5FX35GVRlpXgRDWeXyj1QWtPs,54406
@@ -69,7 +69,7 @@ modules/tmx_editor_qt.py,sha256=PxBIUw_06PHYTBHsd8hZzVJXW8T0A0ljfz1Wjjsa4yU,1170
69
69
  modules/tmx_generator.py,sha256=pNkxwdMLvSRMMru0lkB1gvViIpg9BQy1EVhRbwoef3k,9426
70
70
  modules/tracked_changes.py,sha256=S_BIEC6r7wVAwjG42aSy_RgH4KaMAC8GS5thEvqrYdE,39480
71
71
  modules/trados_docx_handler.py,sha256=VPRAQ73cUHs_SEj6x81z1PmSxfjnwPBp9P4fXeK3KpQ,16363
72
- modules/translation_memory.py,sha256=1dKFbpAra8JX2d4IRHAS35slDVyxT1uARm8sagmd6M0,28696
72
+ modules/translation_memory.py,sha256=k0GtO6ANTqxI1XMcv3D5mdAoTgcWlDT5iVsYHizKNUM,28738
73
73
  modules/translation_results_panel.py,sha256=DmEe0pZRSfcZFg2cWeEREK7H9vrTcPkgeuMW54Pgrys,92505
74
74
  modules/translation_services.py,sha256=lyVpWuZK1wtVtYZMDMdLoq1DHBoSaeAnp-Yejb0TlVQ,10530
75
75
  modules/unified_prompt_library.py,sha256=lzbevgjUz_qCiYSf141BB0mmuaDhSsevWju_a7welu0,26008
@@ -77,9 +77,9 @@ modules/unified_prompt_manager_qt.py,sha256=fyF3_r0N8hnImT-CcWo1AuBOQ1Dn_ExeeUCk
77
77
  modules/voice_commands.py,sha256=iBb-gjWxRMLhFH7-InSRjYJz1EIDBNA2Pog8V7TtJaY,38516
78
78
  modules/voice_dictation.py,sha256=QmitXfkG-vRt5hIQATjphHdhXfqmwhzcQcbXB6aRzIg,16386
79
79
  modules/voice_dictation_lite.py,sha256=jorY0BmWE-8VczbtGrWwt1zbnOctMoSlWOsQrcufBcc,9423
80
- supervertaler-1.9.153.dist-info/licenses/LICENSE,sha256=m28u-4qL5nXIWnJ6xlQVw__H30rWFtRK3pCOais2OuY,1092
81
- supervertaler-1.9.153.dist-info/METADATA,sha256=VzWDZXLFWzfC1B3UeLLc3RAKCv1Gupo_xHQlqh6Duoc,45887
82
- supervertaler-1.9.153.dist-info/WHEEL,sha256=qELbo2s1Yzl39ZmrAibXA2jjPLUYfnVhUNTlyF1rq0Y,92
83
- supervertaler-1.9.153.dist-info/entry_points.txt,sha256=NP4hiCvx-_30YYKqgr-jfJYQvHr1qTYBMfoVmKIXSM8,53
84
- supervertaler-1.9.153.dist-info/top_level.txt,sha256=9tUHBYUSfaE4S2E4W3eavJsDyYymkwLfeWAHHAPT6Dk,22
85
- supervertaler-1.9.153.dist-info/RECORD,,
80
+ supervertaler-1.9.164.dist-info/licenses/LICENSE,sha256=m28u-4qL5nXIWnJ6xlQVw__H30rWFtRK3pCOais2OuY,1092
81
+ supervertaler-1.9.164.dist-info/METADATA,sha256=5YYkounxUPZNOqsTIUmZbqpOZYhoJebihJuKCIXycI4,46629
82
+ supervertaler-1.9.164.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
83
+ supervertaler-1.9.164.dist-info/entry_points.txt,sha256=NP4hiCvx-_30YYKqgr-jfJYQvHr1qTYBMfoVmKIXSM8,53
84
+ supervertaler-1.9.164.dist-info/top_level.txt,sha256=9tUHBYUSfaE4S2E4W3eavJsDyYymkwLfeWAHHAPT6Dk,22
85
+ supervertaler-1.9.164.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.10.1)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5