supervertaler 1.9.176b0__tar.gz → 1.9.177b0__tar.gz

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.
Files changed (372) hide show
  1. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/CHANGELOG.md +9 -1
  2. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/PKG-INFO +1 -1
  3. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/Supervertaler.py +71 -22
  4. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/index.html +4 -4
  5. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/database_manager.py +169 -64
  6. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/pyproject.toml +1 -1
  7. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/supervertaler.egg-info/PKG-INFO +1 -1
  8. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/FAQ.md +0 -0
  9. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/LICENSE +0 -0
  10. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/MANIFEST.in +0 -0
  11. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/README.md +0 -0
  12. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/assets/ICON_CONVERSION_GUIDE.md +0 -0
  13. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/assets/MB.ico +0 -0
  14. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/assets/README.md +0 -0
  15. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/assets/generate_icons.py +0 -0
  16. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/assets/icon.ico +0 -0
  17. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/assets/icon_128.png +0 -0
  18. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/assets/icon_24.png +0 -0
  19. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/assets/icon_256.png +0 -0
  20. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/assets/icon_32.png +0 -0
  21. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/assets/icon_48.png +0 -0
  22. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/assets/icon_64.png +0 -0
  23. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/assets/icon_preview.html +0 -0
  24. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/assets/icon_sv_modern.svg +0 -0
  25. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/assets/icon_sv_modern_paths.svg +0 -0
  26. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/assets/icon_sv_simple.svg +0 -0
  27. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/assets/patent-drawing-1951.jpg +0 -0
  28. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/assets/supervertaler_icon_colours.png +0 -0
  29. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/.nojekyll +0 -0
  30. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/CNAME +0 -0
  31. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/SIMILAR_APPS.md +0 -0
  32. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/apple-touch-icon.png +0 -0
  33. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/BUGFIX_README.md +0 -0
  34. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/CHANGELIST.md +0 -0
  35. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/CHANGELOG_Old.md +0 -0
  36. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/FAQ.md +0 -0
  37. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/INSTALLATION_v1.7.8.md +0 -0
  38. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/PROJECT_ORGANIZATION.md +0 -0
  39. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/TERMBASE_REFACTORING_SUMMARY.md +0 -0
  40. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/USER_GUIDE_v1.7.8.md +0 -0
  41. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/VERIFICATION_CHECKLIST.md +0 -0
  42. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/BEFORE_AFTER_COMPARISON.md +0 -0
  43. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/BUGFIX_SESSION_SUMMARY.md +0 -0
  44. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/COLOR_SCHEME_REFERENCE.md +0 -0
  45. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/COMPACT_LAYOUT_CHANGELOG.md +0 -0
  46. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/COMPACT_LAYOUT_DOCUMENTATION_INDEX.md +0 -0
  47. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/COMPACT_LAYOUT_IMPLEMENTATION_SUMMARY.md +0 -0
  48. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/COMPACT_LAYOUT_UPDATE.md +0 -0
  49. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/COMPLETE_IMPLEMENTATION_SUMMARY.md +0 -0
  50. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/COMPLETE_PROJECT_SUMMARY.md +0 -0
  51. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/DATABASE_FINAL_SUMMARY.md +0 -0
  52. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/DATABASE_IMPLEMENTATION.md +0 -0
  53. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/DATABASE_PRODUCTION_READY.md +0 -0
  54. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/DATABASE_QUICK_REFERENCE.md +0 -0
  55. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/DUAL_VERSION_STRATEGY.md +0 -0
  56. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/FINAL_SESSION_SUMMARY.md +0 -0
  57. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/FOLDER_STRUCTURE_UPDATE.md +0 -0
  58. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/GITHUB_PAGES_SETUP.md +0 -0
  59. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/IMPLEMENTATION_CHECKLIST.md +0 -0
  60. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/IMPLEMENTATION_COMPLETE.md +0 -0
  61. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/IMPLEMENTATION_COMPLETE_COMPACT_LAYOUT.md +0 -0
  62. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/IMPLEMENTATION_READY.md +0 -0
  63. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/IMPLEMENTATION_STATUS_PHASE2_READY.md +0 -0
  64. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/KEYBOARD_SHORTCUTS_MATCHES.md +0 -0
  65. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/LAYOUT_BEFORE_AFTER.md +0 -0
  66. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/MASTER_INDEX.md +0 -0
  67. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/MATCH_DISPLAY_IMPROVEMENTS.md +0 -0
  68. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/MATCH_DISPLAY_LONG_SEGMENTS_UPDATE.md +0 -0
  69. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/MATCH_DISPLAY_QUICK_REFERENCE.md +0 -0
  70. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/MATCH_INSERTION_FEATURES.md +0 -0
  71. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/MATCH_SHORTCUTS_QUICK_REF.md +0 -0
  72. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/MODULAR_ARCHITECTURE_GUIDE.md +0 -0
  73. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/PHASE2_IMPLEMENTATION_CHECKLIST.md +0 -0
  74. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/PHASE2_IMPLEMENTATION_DETAILED_CHECKLIST.md +0 -0
  75. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/PHASE2_IMPLEMENTATION_IN_PROGRESS.md +0 -0
  76. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/PHASE2_NEXT_STEPS.md +0 -0
  77. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/PHASE2_READY_TO_IMPLEMENT.md +0 -0
  78. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/PHASE2_START_HERE.md +0 -0
  79. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/QT_MIGRATION_PLAN.md +0 -0
  80. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/QT_SESSION_SUMMARY.md +0 -0
  81. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/QUICK_SESSION_SUMMARY.md +0 -0
  82. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/RELEASE_Qt_v1.0.0_Phase5.md +0 -0
  83. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/RELEASE_v1.9.38.md +0 -0
  84. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/RELEASE_v3.7.1.md +0 -0
  85. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/RELEASE_v3.7.6.md +0 -0
  86. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/RELEASE_v3.7.7.md +0 -0
  87. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/RESTRUCTURE_COMPLETE.md +0 -0
  88. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/SESSION_DOCUMENTATION_INDEX.md +0 -0
  89. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/SESSION_IMPLEMENTATION_SUMMARY.md +0 -0
  90. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/SESSION_LONG_SEGMENTS_COMPLETE.md +0 -0
  91. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/SESSION_MATCH_FEATURES_COMPLETE.md +0 -0
  92. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/SESSION_STATUS.md +0 -0
  93. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/SESSION_SUMMARY_Phase5.md +0 -0
  94. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/START_HERE.md +0 -0
  95. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/START_IMPLEMENTATION_HERE.md +0 -0
  96. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/STYLE_GUIDES_DELIVERABLES.md +0 -0
  97. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/STYLE_GUIDES_DOCUMENTATION_INDEX.md +0 -0
  98. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/STYLE_GUIDES_FEATURE_SUMMARY.md +0 -0
  99. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/STYLE_GUIDES_IMPLEMENTATION.md +0 -0
  100. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/STYLE_GUIDES_PROJECT_COMPLETION.md +0 -0
  101. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/STYLE_GUIDES_QUICK_REFERENCE.md +0 -0
  102. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/STYLE_GUIDES_VISUAL_ARCHITECTURE.md +0 -0
  103. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/TERMBASE_FIXES.md +0 -0
  104. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/TERMBASE_IMPLEMENTATION.md +0 -0
  105. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/TERMBASE_QUICK_START.md +0 -0
  106. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/TMX_CONCORDANCE_STYLE_HIGHLIGHTING.md +0 -0
  107. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/TMX_DUAL_HIGHLIGHTING.md +0 -0
  108. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/TMX_EDITOR_HIGHLIGHTING_UPDATE.md +0 -0
  109. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/TMX_EDITOR_IMPLEMENTATION.md +0 -0
  110. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/TMX_EDITOR_WORD_HIGHLIGHTING.md +0 -0
  111. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/TMX_TABLE_LAYOUT_INTEGRATED_EDIT.md +0 -0
  112. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/TMX_TREEVIEW_GRID_RESIZABLE.md +0 -0
  113. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/TMX_WORD_HIGHLIGHTING_IMPLEMENTATION_COMPLETE.md +0 -0
  114. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/TMX_WORD_HIGHLIGHTING_SUMMARY.md +0 -0
  115. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/TM_MATCH_PANE_CHECKLIST.md +0 -0
  116. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/TM_MATCH_PANE_IMPLEMENTATION.md +0 -0
  117. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/TM_MATCH_PANE_VISUAL_GUIDE.md +0 -0
  118. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/VISUAL_COLOR_REFERENCE.md +0 -0
  119. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/development/VISUAL_IMPLEMENTATION_SUMMARY.md +0 -0
  120. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/sessions/COLOR_FIX_EXPLANATION.md +0 -0
  121. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/sessions/DATABASE_CONSOLIDATION_REPORT.md +0 -0
  122. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/sessions/DUAL_EDITOR_WORKFLOW.md +0 -0
  123. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/sessions/DUAL_SELECTION_SYSTEM.md +0 -0
  124. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/sessions/IMPROVEMENTS_SUMMARY.md +0 -0
  125. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/sessions/ISSUES_FIXES_PROGRESS.md +0 -0
  126. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/sessions/MATCH_DISPLAY_COMPACT_FIXES.md +0 -0
  127. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/sessions/README_SESSION_TERMBASE.md +0 -0
  128. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/sessions/SAFE_DELETION_REMINDER.txt +0 -0
  129. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/sessions/SESSION_SUMMARY.md +0 -0
  130. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/sessions/TERMBASE_FIXES_APPLIED.md +0 -0
  131. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/sessions/TESTING_CHECKLIST.md +0 -0
  132. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/sessions/TMX_EDITOR_ANNOUNCEMENT.md +0 -0
  133. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/archive/sessions/TRANSLATION_RESULTS_IMPROVEMENTS.md +0 -0
  134. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/assets/Figure1.png +0 -0
  135. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/assets/patent-drawing-1951.jpg +0 -0
  136. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/changelog.html +0 -0
  137. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/dev-notes/QA.md +0 -0
  138. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/dev-notes/STYLE_GUIDES_UI_TEMPLATE.py +0 -0
  139. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/dev-notes/_Notes_2025-11-21.md +0 -0
  140. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/dev-notes/_things_to_remind_AIs_of_when_translating.md +0 -0
  141. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/dev-notes/issue_28.md +0 -0
  142. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/dev-notes/openai_debug.txt +0 -0
  143. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/dev-notes/pre-translation-dialog-enhancement.md +0 -0
  144. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/emoji_mockup.html +0 -0
  145. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/favicon.ico +0 -0
  146. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/guides/AI_PROMPT_ASSISTANT_USER_GUIDE.md +0 -0
  147. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/guides/ENCODING_REPAIR_TOOL.md +0 -0
  148. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/guides/FAQ.md +0 -0
  149. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/guides/GLOSSARY_OF_SUPERVERTALER_TERMINOLOGY.md +0 -0
  150. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/guides/JSON_EDITORS_AND_HUMAN_READABLE_FORMAT.md +0 -0
  151. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/guides/KEYBOARD_SHORTCUTS.md +0 -0
  152. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/guides/PDF_RESCUE.md +0 -0
  153. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/guides/PROMPT_ASSISTANT_USER_GUIDE.md +0 -0
  154. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/guides/QT_SETTINGS_DIALOG_GUIDE.md +0 -0
  155. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/guides/TERM_EXTRACTION_GUIDE.md +0 -0
  156. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/guides/USER_DATA_FOLDER_SETUP.md +0 -0
  157. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/idea_beijer.bot_integration_idea/BEIJERBOT_FEATURE_ANALYSIS.md +0 -0
  158. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/idea_beijer.bot_integration_idea/CLI_BRIDGE_SPECIFICATION.md +0 -0
  159. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/idea_beijer.bot_integration_idea/IMPLEMENTATION_ROADMAP.md +0 -0
  160. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/idea_beijer.bot_integration_idea/QUICKMENU_INTEGRATION_PLAN.md +0 -0
  161. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/idea_beijer.bot_integration_idea/README.md +0 -0
  162. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/idea_tag-cleaner/tag_cleaner.md +0 -0
  163. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/idea_use_vscode_as_cat_tool/ai-agent-translation-workflow.md +0 -0
  164. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/logo.png +0 -0
  165. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/2025-10-13_00-46-16.jpg +0 -0
  166. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/Superlookup_Web_resources.jpg +0 -0
  167. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/Supervertaler_AI-Assistant.jpg +0 -0
  168. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/Supervertaler_CLASSIC_v2.4.1_(tkinter).jpg +0 -0
  169. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/Supervertaler_Prompt_Manager_2026-01-14.png +0 -0
  170. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/Supervertaler_Qt_LLM_LeaderboardResults_2025-11-12.jpg +0 -0
  171. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/Supervertaler_Qt_LLM_Leaderboard_2025-11-12.jpg +0 -0
  172. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/Supervertaler_Superbrowser.jpg +0 -0
  173. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/Supervertaler_dark_mode_2025-12-16.jpg +0 -0
  174. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/Supervertaler_dark_mode_2025-12-17.jpg +0 -0
  175. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/Supervertaler_grid.jpg +0 -0
  176. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/Supervertaler_tkinter (v3.7.7).jpg +0 -0
  177. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/Supervertaler_v1.9.102_compare_panel_2026-01-14.png +0 -0
  178. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/Supervertaler_v1.9.102_grid_2026-01-14.png +0 -0
  179. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/new/Supervertaler-grid.jpg +0 -0
  180. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/new/Supervertaler_AI-Assistant.jpg +0 -0
  181. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/new/Supervertaler_Prompt-Library.jpg +0 -0
  182. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/new/Supervertaler_Qt_LLM_LeaderboardResults_2025-11-12.jpg +0 -0
  183. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/new/Supervertaler_Qt_LLM_Leaderboard_2025-11-12.jpg +0 -0
  184. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/new/Supervertaler_Superbrowser.jpg +0 -0
  185. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/old/2025-10-13_00-50-24.jpg +0 -0
  186. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/screenshots/old/Supervertaler_Qt_2025-11-12.jpg +0 -0
  187. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/script.js +0 -0
  188. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/site.webmanifest +0 -0
  189. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/specifications/AI_ASSISTANT_PHASE2_IMPLEMENTATION.md +0 -0
  190. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/specifications/AI_PROMPT_ASSISTANT.md +0 -0
  191. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/specifications/AI_PROMPT_ASSISTANT_IMPLEMENTATION.md +0 -0
  192. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/specifications/EXPORT_MENU_UPDATE.md +0 -0
  193. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/specifications/IMPLEMENTATION_SUMMARY.md +0 -0
  194. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/specifications/QT_PHASE2_COMPLETE.md +0 -0
  195. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/specifications/QT_PHASE3_COMPLETE.md +0 -0
  196. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/specifications/SUPERVERTALER_DATA_FORMAT.md +0 -0
  197. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/specifications/TASK_TYPE_SYSTEM.md +0 -0
  198. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/specifications/TERMINOLOGY_UPDATE_SUMMARY.md +0 -0
  199. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/specifications/opus-api-integration.md +0 -0
  200. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/styles.css +0 -0
  201. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/.gitbook/assets/supervertaler-logo.png +0 -0
  202. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/.gitbook/assets/sv-icon.svg +0 -0
  203. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/GITBOOK_LANDING_DRAFT.md +0 -0
  204. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/README.md +0 -0
  205. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/SUMMARY.md +0 -0
  206. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/ai-translation/batch-translation.md +0 -0
  207. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/ai-translation/ollama.md +0 -0
  208. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/ai-translation/overview.md +0 -0
  209. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/ai-translation/prompt-library.md +0 -0
  210. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/ai-translation/prompts.md +0 -0
  211. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/ai-translation/providers.md +0 -0
  212. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/ai-translation/single-segment.md +0 -0
  213. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/cat-tools/cafetran.md +0 -0
  214. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/cat-tools/memoq.md +0 -0
  215. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/cat-tools/overview.md +0 -0
  216. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/cat-tools/phrase.md +0 -0
  217. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/cat-tools/trados.md +0 -0
  218. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/editor/editing-confirming.md +0 -0
  219. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/editor/filtering.md +0 -0
  220. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/editor/find-replace.md +0 -0
  221. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/editor/keyboard-shortcuts.md +0 -0
  222. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/editor/navigation.md +0 -0
  223. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/editor/pagination.md +0 -0
  224. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/editor/translation-grid.md +0 -0
  225. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/get-started/api-keys.md +0 -0
  226. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/get-started/first-project.md +0 -0
  227. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/get-started/installation.md +0 -0
  228. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/get-started/quick-start.md +0 -0
  229. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/glossaries/basics.md +0 -0
  230. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/glossaries/creating.md +0 -0
  231. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/glossaries/extraction.md +0 -0
  232. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/glossaries/highlighting.md +0 -0
  233. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/glossaries/importing.md +0 -0
  234. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/import-export/bilingual-tables.md +0 -0
  235. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/import-export/docx-import.md +0 -0
  236. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/import-export/exporting.md +0 -0
  237. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/import-export/formats.md +0 -0
  238. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/import-export/multi-file.md +0 -0
  239. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/import-export/txt-import.md +0 -0
  240. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/qa/non-translatables.md +0 -0
  241. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/qa/spellcheck.md +0 -0
  242. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/qa/tag-validation.md +0 -0
  243. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/reference/changelog.md +0 -0
  244. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/reference/contributing.md +0 -0
  245. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/reference/faq.md +0 -0
  246. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/reference/file-formats.md +0 -0
  247. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/settings/fonts.md +0 -0
  248. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/settings/general.md +0 -0
  249. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/settings/shortcuts.md +0 -0
  250. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/settings/theme.md +0 -0
  251. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/settings/view.md +0 -0
  252. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/superlookup/glossary-search.md +0 -0
  253. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/superlookup/mt.md +0 -0
  254. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/superlookup/overview.md +0 -0
  255. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/superlookup/tm-search.md +0 -0
  256. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/superlookup/web-resources.md +0 -0
  257. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/tools/autofingers.md +0 -0
  258. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/tools/image-extractor.md +0 -0
  259. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/tools/pdf-rescue.md +0 -0
  260. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/tools/tmx-editor.md +0 -0
  261. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/tools/voice-commands.md +0 -0
  262. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/translation-memory/basics.md +0 -0
  263. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/translation-memory/fuzzy-matching.md +0 -0
  264. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/translation-memory/importing-tmx.md +0 -0
  265. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/translation-memory/managing-tms.md +0 -0
  266. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/translation-memory/supermemory.md +0 -0
  267. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/troubleshooting/api-issues.md +0 -0
  268. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/troubleshooting/common-issues.md +0 -0
  269. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/troubleshooting/import-export-errors.md +0 -0
  270. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/troubleshooting/linux.md +0 -0
  271. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/superdocs/troubleshooting/performance.md +0 -0
  272. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/sv-icon.svg +0 -0
  273. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/technical/AI_ASSISTANT_GUIDE.md +0 -0
  274. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/technical/AI_ASSISTANT_IMPLEMENTATION.md +0 -0
  275. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/technical/AI_ASSISTANT_INTEGRATION.md +0 -0
  276. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/technical/AI_ASSISTANT_QUICK_REFERENCE.md +0 -0
  277. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/technical/DATABASE_LOCATIONS.md +0 -0
  278. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/technical/FILTER_HIGHLIGHTING_FIX.md +0 -0
  279. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/technical/MODULE_HEADER_PATTERN.md +0 -0
  280. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/technical/README.md +0 -0
  281. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/technical/SUPERBROWSER_GUIDE.md +0 -0
  282. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/technical/SUPERVOICE_TROUBLESHOOTING.md +0 -0
  283. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/technical/UNIFIED_PROMPT_LIBRARY_GUIDE.md +0 -0
  284. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/technical/VOICE_DICTATION_GUIDE.md +0 -0
  285. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/tests/test_encoding_corruption.txt +0 -0
  286. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/web-app-manifest-192x192.png +0 -0
  287. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/docs/web-app-manifest-512x512.png +0 -0
  288. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/__init__.py +0 -0
  289. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/ai_actions.py +0 -0
  290. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/ai_attachment_manager.py +0 -0
  291. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/ai_file_viewer_dialog.py +0 -0
  292. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/autofingers_engine.py +0 -0
  293. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/cafetran_docx_handler.py +0 -0
  294. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/config_manager.py +0 -0
  295. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/database_migrations.py +0 -0
  296. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/dejavurtf_handler.py +0 -0
  297. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/document_analyzer.py +0 -0
  298. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/docx_handler.py +0 -0
  299. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/encoding_repair.py +0 -0
  300. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/encoding_repair_Qt.py +0 -0
  301. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/encoding_repair_ui.py +0 -0
  302. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/feature_manager.py +0 -0
  303. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/figure_context_manager.py +0 -0
  304. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/file_dialog_helper.py +0 -0
  305. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/find_replace.py +0 -0
  306. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/find_replace_qt.py +0 -0
  307. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/glossary_manager.py +0 -0
  308. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/image_extractor.py +0 -0
  309. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/keyboard_shortcuts_widget.py +0 -0
  310. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/llm_clients.py +0 -0
  311. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/llm_leaderboard.py +0 -0
  312. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/llm_superbench_ui.py +0 -0
  313. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/local_llm_setup.py +0 -0
  314. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/model_update_dialog.py +0 -0
  315. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/model_version_checker.py +0 -0
  316. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/mqxliff_handler.py +0 -0
  317. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/non_translatables_manager.py +0 -0
  318. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/pdf_rescue_Qt.py +0 -0
  319. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/pdf_rescue_tkinter.py +0 -0
  320. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/phrase_docx_handler.py +0 -0
  321. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/project_home_panel.py +0 -0
  322. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/prompt_assistant.py +0 -0
  323. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/prompt_library.py +0 -0
  324. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/prompt_library_migration.py +0 -0
  325. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/quick_access_sidebar.py +0 -0
  326. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/ribbon_widget.py +0 -0
  327. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/sdlppx_handler.py +0 -0
  328. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/setup_wizard.py +0 -0
  329. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/shortcut_manager.py +0 -0
  330. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/simple_segmenter.py +0 -0
  331. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/spellcheck_manager.py +0 -0
  332. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/statuses.py +0 -0
  333. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/style_guide_manager.py +0 -0
  334. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/superbench_ui.py +0 -0
  335. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/superbrowser.py +0 -0
  336. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/supercleaner.py +0 -0
  337. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/supercleaner_ui.py +0 -0
  338. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/superdocs.py +0 -0
  339. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/superdocs_viewer_qt.py +0 -0
  340. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/superlookup.py +0 -0
  341. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/tag_cleaner.py +0 -0
  342. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/tag_manager.py +0 -0
  343. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/term_extractor.py +0 -0
  344. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/termbase_entry_editor.py +0 -0
  345. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/termbase_import_export.py +0 -0
  346. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/termbase_manager.py +0 -0
  347. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/termview_widget.py +0 -0
  348. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/theme_manager.py +0 -0
  349. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/tm_editor_dialog.py +0 -0
  350. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/tm_manager_qt.py +0 -0
  351. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/tm_metadata_manager.py +0 -0
  352. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/tmx_editor.py +0 -0
  353. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/tmx_editor_qt.py +0 -0
  354. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/tmx_generator.py +0 -0
  355. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/tracked_changes.py +0 -0
  356. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/trados_docx_handler.py +0 -0
  357. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/translation_memory.py +0 -0
  358. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/translation_results_panel.py +0 -0
  359. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/translation_services.py +0 -0
  360. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/unified_prompt_library.py +0 -0
  361. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/unified_prompt_manager_qt.py +0 -0
  362. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/voice_commands.py +0 -0
  363. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/voice_dictation.py +0 -0
  364. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/modules/voice_dictation_lite.py +0 -0
  365. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/setup.cfg +0 -0
  366. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/setup.py +0 -0
  367. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/supervertaler.egg-info/SOURCES.txt +0 -0
  368. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/supervertaler.egg-info/dependency_links.txt +0 -0
  369. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/supervertaler.egg-info/entry_points.txt +0 -0
  370. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/supervertaler.egg-info/not-zip-safe +0 -0
  371. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/supervertaler.egg-info/requires.txt +0 -0
  372. {supervertaler-1.9.176b0 → supervertaler-1.9.177b0}/supervertaler.egg-info/top_level.txt +0 -0
@@ -2,10 +2,18 @@
2
2
 
3
3
  All notable changes to Supervertaler are documented in this file.
4
4
 
5
- **Current Version:** v1.9.176-beta (January 28, 2026)
5
+ **Current Version:** v1.9.177-beta (January 28, 2026)
6
6
 
7
7
 
8
8
 
9
+ ## v1.9.177-beta - January 28, 2026
10
+
11
+ ### ✨ New Features
12
+
13
+ - **Bidirectional Termbase Matching**: Glossaries now work like memoQ and Trados - a termbase created for NL→EN will also find matches when working on EN→NL projects (and vice versa). This "direction-insensitive" behavior means you no longer need separate termbases for different language directions. When a match is found on the target side, source and target are automatically swapped in the results.
14
+
15
+ ---
16
+
9
17
  ## v1.9.176-beta - January 28, 2026
10
18
 
11
19
  ### ✨ New Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: supervertaler
3
- Version: 1.9.176b0
3
+ Version: 1.9.177b0
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
@@ -22319,20 +22319,24 @@ class SupervertalerQt(QMainWindow):
22319
22319
  """
22320
22320
  Search termbases using a provided cursor (thread-safe for background threads).
22321
22321
  This method allows background workers to query the database without SQLite threading errors.
22322
-
22322
+
22323
+ Implements BIDIRECTIONAL matching: searches both source_term and target_term columns.
22324
+ When a match is found on target_term, source and target are swapped in the result.
22325
+ This matches memoQ/Trados behavior where a NL→EN termbase also works for EN→NL projects.
22326
+
22323
22327
  Args:
22324
22328
  source_text: The source text to search for
22325
22329
  cursor: A database cursor from a thread-local connection
22326
22330
  source_lang: Source language code
22327
22331
  target_lang: Target language code
22328
22332
  project_id: Current project ID (required to filter by activated termbases)
22329
-
22333
+
22330
22334
  Returns:
22331
22335
  Dictionary of {term: translation} matches
22332
22336
  """
22333
22337
  if not source_text or not cursor:
22334
22338
  return {}
22335
-
22339
+
22336
22340
  try:
22337
22341
  # Convert language names to codes (match interactive search logic)
22338
22342
  source_lang_code = self._convert_language_to_code(source_lang) if source_lang else None
@@ -22352,20 +22356,26 @@ class SupervertalerQt(QMainWindow):
22352
22356
  try:
22353
22357
  # JOIN termbases AND termbase_activation to filter by activated termbases
22354
22358
  # This matches the logic in database_manager.py search_termbases()
22359
+ # BIDIRECTIONAL: Search both source_term (forward) and target_term (reverse)
22360
+ # Using UNION to combine both directions
22355
22361
  query = """
22356
- SELECT
22357
- t.id, t.source_term, t.target_term, t.termbase_id, t.priority,
22358
- t.domain, t.notes, t.project, t.client, t.forbidden,
22359
- tb.is_project_termbase, tb.name as termbase_name,
22360
- COALESCE(ta.priority, tb.ranking) as ranking
22361
- FROM termbase_terms t
22362
- LEFT JOIN termbases tb ON CAST(t.termbase_id AS INTEGER) = tb.id
22363
- LEFT JOIN termbase_activation ta ON ta.termbase_id = tb.id AND ta.project_id = ? AND ta.is_active = 1
22364
- WHERE LOWER(t.source_term) LIKE ?
22365
- AND (ta.is_active = 1 OR tb.is_project_termbase = 1)
22362
+ SELECT * FROM (
22363
+ -- Forward match: search source_term
22364
+ SELECT
22365
+ t.id, t.source_term, t.target_term, t.termbase_id, t.priority,
22366
+ t.domain, t.notes, t.project, t.client, t.forbidden,
22367
+ tb.is_project_termbase, tb.name as termbase_name,
22368
+ COALESCE(ta.priority, tb.ranking) as ranking,
22369
+ 'source' as match_direction
22370
+ FROM termbase_terms t
22371
+ LEFT JOIN termbases tb ON CAST(t.termbase_id AS INTEGER) = tb.id
22372
+ LEFT JOIN termbase_activation ta ON ta.termbase_id = tb.id AND ta.project_id = ? AND ta.is_active = 1
22373
+ WHERE LOWER(t.source_term) LIKE ?
22374
+ AND (ta.is_active = 1 OR tb.is_project_termbase = 1)
22366
22375
  """
22367
22376
  params = [project_id if project_id else 0, f"%{clean_word.lower()}%"]
22368
22377
 
22378
+ # Language filters for forward query
22369
22379
  if source_lang_code:
22370
22380
  query += " AND (t.source_lang = ? OR (t.source_lang IS NULL AND tb.source_lang = ?) OR (t.source_lang IS NULL AND tb.source_lang IS NULL))"
22371
22381
  params.extend([source_lang_code, source_lang_code])
@@ -22373,15 +22383,45 @@ class SupervertalerQt(QMainWindow):
22373
22383
  query += " AND (t.target_lang = ? OR (t.target_lang IS NULL AND tb.target_lang = ?) OR (t.target_lang IS NULL AND tb.target_lang IS NULL))"
22374
22384
  params.extend([target_lang_code, target_lang_code])
22375
22385
 
22376
- # Limit raw hits per word to keep batch worker light
22377
- query += " LIMIT 15"
22386
+ # Reverse match: search target_term, swap source/target in output
22387
+ query += """
22388
+ UNION ALL
22389
+ -- Reverse match: search target_term, swap columns
22390
+ SELECT
22391
+ t.id, t.target_term as source_term, t.source_term as target_term,
22392
+ t.termbase_id, t.priority,
22393
+ t.domain, t.notes, t.project, t.client, t.forbidden,
22394
+ tb.is_project_termbase, tb.name as termbase_name,
22395
+ COALESCE(ta.priority, tb.ranking) as ranking,
22396
+ 'target' as match_direction
22397
+ FROM termbase_terms t
22398
+ LEFT JOIN termbases tb ON CAST(t.termbase_id AS INTEGER) = tb.id
22399
+ LEFT JOIN termbase_activation ta ON ta.termbase_id = tb.id AND ta.project_id = ? AND ta.is_active = 1
22400
+ WHERE LOWER(t.target_term) LIKE ?
22401
+ AND (ta.is_active = 1 OR tb.is_project_termbase = 1)
22402
+ """
22403
+ params.extend([project_id if project_id else 0, f"%{clean_word.lower()}%"])
22404
+
22405
+ # Language filters for reverse query (swapped)
22406
+ if source_lang_code:
22407
+ # For reverse: source_lang filters target_lang column
22408
+ query += " AND (t.target_lang = ? OR (t.target_lang IS NULL AND tb.target_lang = ?) OR (t.target_lang IS NULL AND tb.target_lang IS NULL))"
22409
+ params.extend([source_lang_code, source_lang_code])
22410
+ if target_lang_code:
22411
+ # For reverse: target_lang filters source_lang column
22412
+ query += " AND (t.source_lang = ? OR (t.source_lang IS NULL AND tb.source_lang = ?) OR (t.source_lang IS NULL AND tb.source_lang IS NULL))"
22413
+ params.extend([target_lang_code, target_lang_code])
22414
+
22415
+ # Close UNION and limit
22416
+ query += ") combined LIMIT 30"
22378
22417
  cursor.execute(query, params)
22379
22418
  results = cursor.fetchall()
22380
22419
 
22381
22420
  for row in results:
22382
- # Uniform access
22421
+ # Uniform access (columns are already swapped for reverse matches)
22383
22422
  source_term = row[1] if isinstance(row, tuple) else row['source_term']
22384
22423
  target_term = row[2] if isinstance(row, tuple) else row['target_term']
22424
+ match_direction = row[13] if isinstance(row, tuple) else row.get('match_direction', 'source')
22385
22425
  if not source_term or not target_term:
22386
22426
  continue
22387
22427
 
@@ -22405,8 +22445,10 @@ class SupervertalerQt(QMainWindow):
22405
22445
  existing = matches.get(source_term.strip())
22406
22446
  # Deduplicate: keep numerically lowest ranking (highest priority)
22407
22447
  # For project termbases, ranking is None so they always win
22448
+ # Also prefer 'source' matches over 'target' matches when equal
22408
22449
  if existing:
22409
22450
  existing_ranking = existing.get('ranking', None)
22451
+ existing_direction = existing.get('match_direction', 'source')
22410
22452
  if is_project_tb:
22411
22453
  # Project termbase always wins
22412
22454
  pass
@@ -22415,8 +22457,12 @@ class SupervertalerQt(QMainWindow):
22415
22457
  continue
22416
22458
  elif existing_ranking is not None and ranking is not None:
22417
22459
  # Both have rankings, keep lower (higher priority)
22418
- if existing_ranking <= ranking:
22460
+ if existing_ranking < ranking:
22419
22461
  continue
22462
+ elif existing_ranking == ranking:
22463
+ # Same ranking: prefer source match over target match
22464
+ if existing_direction == 'source' and match_direction == 'target':
22465
+ continue
22420
22466
 
22421
22467
  matches[source_term.strip()] = {
22422
22468
  'translation': target_term.strip(),
@@ -22431,15 +22477,18 @@ class SupervertalerQt(QMainWindow):
22431
22477
  'forbidden': forbidden or False,
22432
22478
  'is_project_termbase': bool(is_project_tb),
22433
22479
  'termbase_name': termbase_name or '',
22434
- 'target_synonyms': [] # Will be populated below
22480
+ 'target_synonyms': [], # Will be populated below
22481
+ 'match_direction': match_direction # Track if this was a reverse match
22435
22482
  }
22436
-
22483
+
22437
22484
  # Fetch synonyms for this term
22485
+ # For reverse matches, fetch 'source' synonyms since they become targets
22438
22486
  try:
22487
+ synonym_lang = 'source' if match_direction == 'target' else 'target'
22439
22488
  cursor.execute("""
22440
- SELECT synonym_text FROM termbase_synonyms
22441
- WHERE term_id = ? AND language = 'target' AND forbidden = 0
22442
- """, (term_id,))
22489
+ SELECT synonym_text FROM termbase_synonyms
22490
+ WHERE term_id = ? AND language = ? AND forbidden = 0
22491
+ """, (term_id, synonym_lang))
22443
22492
  synonym_rows = cursor.fetchall()
22444
22493
  for syn_row in synonym_rows:
22445
22494
  synonym = syn_row[0] if isinstance(syn_row, tuple) else syn_row['synonym_text']
@@ -17,7 +17,7 @@
17
17
  <link rel="apple-touch-icon" href="apple-touch-icon.png">
18
18
  <link rel="manifest" href="site.webmanifest">
19
19
 
20
- <link rel="stylesheet" href="styles.css?v=1.9.176-beta">
20
+ <link rel="stylesheet" href="styles.css?v=1.9.177-beta">
21
21
  <link rel="preconnect" href="https://fonts.googleapis.com">
22
22
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
23
23
  <link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap"
@@ -50,7 +50,7 @@
50
50
  class="nav-discussions">💬 Discussions</a></li>
51
51
  <li class="nav-action">
52
52
  <a href="https://github.com/michaelbeijer/Supervertaler/blob/main/CHANGELOG.md" target="_blank"
53
- class="nav-version" title="Current version">v1.9.176-beta</a>
53
+ class="nav-version" title="Current version">v1.9.177-beta</a>
54
54
  </li>
55
55
  <li class="nav-action">
56
56
  <a href="https://github.com/michaelbeijer/Supervertaler" target="_blank" class="nav-icon-link"
@@ -74,7 +74,7 @@
74
74
  Supervertaler
75
75
  <span class="gradient-text">The Ultimate Translation Workbench</span>
76
76
  </h1>
77
- <p class="version-badge">v1.9.176-beta</p>
77
+ <p class="version-badge">v1.9.177-beta</p>
78
78
  <p class="hero-subtitle">
79
79
  AI-enhanced translation workbench. Work with ChatGPT, Claude, and Gemini simultaneously.
80
80
  Built by translators, for translators and writers.
@@ -711,7 +711,7 @@
711
711
  <div style="text-align: center; margin: 40px 0;">
712
712
  <div class="download-card featured"
713
713
  style="border: 3px solid #6366F1; max-width: 700px; margin: 0 auto;">
714
- <div class="download-badge" style="background: #6366F1;">v1.9.176-beta</div>
714
+ <div class="download-badge" style="background: #6366F1;">v1.9.177-beta</div>
715
715
  <h3>🎨 Supervertaler</h3>
716
716
  <p class="download-description" style="font-weight: 600; color: #6366F1; margin-bottom: 10px;">
717
717
  Modern Professional Interface
@@ -1477,120 +1477,225 @@ class DatabaseManager:
1477
1477
  # TODO: Implement in Phase 3
1478
1478
  pass
1479
1479
 
1480
- def search_termbases(self, search_term: str, source_lang: str = None,
1480
+ def search_termbases(self, search_term: str, source_lang: str = None,
1481
1481
  target_lang: str = None, project_id: str = None,
1482
- min_length: int = 0) -> List[Dict]:
1482
+ min_length: int = 0, bidirectional: bool = True) -> List[Dict]:
1483
1483
  """
1484
- Search termbases for matching source terms
1485
-
1484
+ Search termbases for matching terms (bidirectional by default)
1485
+
1486
1486
  Args:
1487
- search_term: Source term to search for
1487
+ search_term: Term to search for
1488
1488
  source_lang: Filter by source language (optional)
1489
1489
  target_lang: Filter by target language (optional)
1490
1490
  project_id: Filter by project (optional)
1491
1491
  min_length: Minimum term length to return
1492
-
1492
+ bidirectional: If True, also search target_term and swap results (default True)
1493
+
1493
1494
  Returns:
1494
1495
  List of termbase hits, sorted by priority (lower = higher priority)
1496
+ Each result includes 'match_direction' ('source' or 'target') indicating
1497
+ which column matched. For 'target' matches, source_term and target_term
1498
+ are swapped so results are always oriented correctly for the current project.
1495
1499
  """
1496
1500
  # Build query with filters - include termbase name and ranking via JOIN
1497
1501
  # Note: termbase_id is stored as TEXT in termbase_terms but INTEGER in termbases
1498
1502
  # Use CAST to ensure proper comparison
1499
1503
  # IMPORTANT: Join with termbase_activation to get the ACTUAL priority for this project
1500
1504
  # CRITICAL FIX: Also match when search_term starts with the glossary term
1501
- # This handles cases like searching for "ca." when glossary has "ca."
1505
+ # This handles cases like searching for "ca." when glossary has "ca."
1502
1506
  # AND searching for "ca" when glossary has "ca."
1503
1507
  # We also strip trailing punctuation from glossary terms for comparison
1504
- query = """
1505
- SELECT
1506
- t.id, t.source_term, t.target_term, t.termbase_id, t.priority,
1508
+
1509
+ # Build matching conditions for a given column
1510
+ def build_match_conditions(column: str) -> str:
1511
+ return f"""(
1512
+ LOWER(t.{column}) = LOWER(?) OR
1513
+ LOWER(t.{column}) LIKE LOWER(?) OR
1514
+ LOWER(t.{column}) LIKE LOWER(?) OR
1515
+ LOWER(t.{column}) LIKE LOWER(?) OR
1516
+ LOWER(RTRIM(t.{column}, '.!?,;:')) = LOWER(?) OR
1517
+ LOWER(?) LIKE LOWER(t.{column}) || '%' OR
1518
+ LOWER(?) = LOWER(RTRIM(t.{column}, '.!?,;:'))
1519
+ )"""
1520
+
1521
+ # Build match params for one direction
1522
+ def build_match_params() -> list:
1523
+ return [
1524
+ search_term,
1525
+ f"{search_term} %",
1526
+ f"% {search_term}",
1527
+ f"% {search_term} %",
1528
+ search_term, # For RTRIM comparison
1529
+ search_term, # For reverse LIKE
1530
+ search_term # For reverse RTRIM comparison
1531
+ ]
1532
+
1533
+ # Matching patterns:
1534
+ # 1. Exact match: column = search_term
1535
+ # 2. Glossary term starts with search: column LIKE "search_term %"
1536
+ # 3. Glossary term ends with search: column LIKE "% search_term"
1537
+ # 4. Glossary term contains search: column LIKE "% search_term %"
1538
+ # 5. Glossary term (stripped) = search_term: RTRIM(column) = search_term (handles "ca." = "ca")
1539
+ # 6. Search starts with glossary term: search_term LIKE column || '%'
1540
+ # 7. Search = glossary term stripped: search_term = RTRIM(column)
1541
+
1542
+ # Base SELECT for forward matches (source_term matches)
1543
+ base_select_forward = """
1544
+ SELECT
1545
+ t.id, t.source_term, t.target_term, t.termbase_id, t.priority,
1507
1546
  t.forbidden, t.source_lang, t.target_lang, t.definition, t.domain,
1508
1547
  t.notes, t.project, t.client,
1509
1548
  tb.name as termbase_name,
1510
1549
  tb.source_lang as termbase_source_lang,
1511
1550
  tb.target_lang as termbase_target_lang,
1512
1551
  tb.is_project_termbase,
1513
- COALESCE(ta.priority, tb.ranking) as ranking
1552
+ COALESCE(ta.priority, tb.ranking) as ranking,
1553
+ 'source' as match_direction
1514
1554
  FROM termbase_terms t
1515
1555
  LEFT JOIN termbases tb ON CAST(t.termbase_id AS INTEGER) = tb.id
1516
1556
  LEFT JOIN termbase_activation ta ON ta.termbase_id = tb.id AND ta.project_id = ? AND ta.is_active = 1
1517
- WHERE (
1518
- LOWER(t.source_term) = LOWER(?) OR
1519
- LOWER(t.source_term) LIKE LOWER(?) OR
1520
- LOWER(t.source_term) LIKE LOWER(?) OR
1521
- LOWER(t.source_term) LIKE LOWER(?) OR
1522
- LOWER(RTRIM(t.source_term, '.!?,;:')) = LOWER(?) OR
1523
- LOWER(?) LIKE LOWER(t.source_term) || '%' OR
1524
- LOWER(?) = LOWER(RTRIM(t.source_term, '.!?,;:'))
1525
- )
1557
+ WHERE {match_conditions}
1526
1558
  AND (ta.is_active = 1 OR tb.is_project_termbase = 1)
1527
- """
1528
- # Matching patterns:
1529
- # 1. Exact match: source_term = search_term
1530
- # 2. Glossary term starts with search: source_term LIKE "search_term %"
1531
- # 3. Glossary term ends with search: source_term LIKE "% search_term"
1532
- # 4. Glossary term contains search: source_term LIKE "% search_term %"
1533
- # 5. Glossary term (stripped) = search_term: RTRIM(source_term) = search_term (handles "ca." = "ca")
1534
- # 6. Search starts with glossary term: search_term LIKE source_term || '%'
1535
- # 7. Search = glossary term stripped: search_term = RTRIM(source_term)
1536
- params = [
1537
- project_id if project_id else 0, # Use 0 if no project (won't match any activation records)
1538
- search_term,
1539
- f"{search_term} %",
1540
- f"% {search_term}",
1541
- f"% {search_term} %",
1542
- search_term, # For RTRIM comparison
1543
- search_term, # For reverse LIKE
1544
- search_term # For reverse RTRIM comparison
1545
- ]
1546
-
1547
- # Language filters - if term has no language, use termbase language for filtering
1559
+ """.format(match_conditions=build_match_conditions('source_term'))
1560
+
1561
+ # Base SELECT for reverse matches (target_term matches) - swap source/target in output
1562
+ base_select_reverse = """
1563
+ SELECT
1564
+ t.id, t.target_term as source_term, t.source_term as target_term,
1565
+ t.termbase_id, t.priority,
1566
+ t.forbidden, t.target_lang as source_lang, t.source_lang as target_lang,
1567
+ t.definition, t.domain,
1568
+ t.notes, t.project, t.client,
1569
+ tb.name as termbase_name,
1570
+ tb.target_lang as termbase_source_lang,
1571
+ tb.source_lang as termbase_target_lang,
1572
+ tb.is_project_termbase,
1573
+ COALESCE(ta.priority, tb.ranking) as ranking,
1574
+ 'target' as match_direction
1575
+ FROM termbase_terms t
1576
+ LEFT JOIN termbases tb ON CAST(t.termbase_id AS INTEGER) = tb.id
1577
+ LEFT JOIN termbase_activation ta ON ta.termbase_id = tb.id AND ta.project_id = ? AND ta.is_active = 1
1578
+ WHERE {match_conditions}
1579
+ AND (ta.is_active = 1 OR tb.is_project_termbase = 1)
1580
+ """.format(match_conditions=build_match_conditions('target_term'))
1581
+
1582
+ # Build params
1583
+ project_param = project_id if project_id else 0
1584
+ forward_params = [project_param] + build_match_params()
1585
+ reverse_params = [project_param] + build_match_params()
1586
+
1587
+ # Build language filter conditions
1588
+ lang_conditions_forward = ""
1589
+ lang_conditions_reverse = ""
1590
+ lang_params_forward = []
1591
+ lang_params_reverse = []
1592
+
1548
1593
  if source_lang:
1549
- query += """ AND (
1550
- t.source_lang = ? OR
1594
+ # For forward: filter on source_lang
1595
+ lang_conditions_forward += """ AND (
1596
+ t.source_lang = ? OR
1551
1597
  (t.source_lang IS NULL AND tb.source_lang = ?) OR
1552
1598
  (t.source_lang IS NULL AND tb.source_lang IS NULL)
1553
1599
  )"""
1554
- params.extend([source_lang, source_lang])
1555
-
1600
+ lang_params_forward.extend([source_lang, source_lang])
1601
+ # For reverse: source_lang becomes target_lang (swapped)
1602
+ lang_conditions_reverse += """ AND (
1603
+ t.target_lang = ? OR
1604
+ (t.target_lang IS NULL AND tb.target_lang = ?) OR
1605
+ (t.target_lang IS NULL AND tb.target_lang IS NULL)
1606
+ )"""
1607
+ lang_params_reverse.extend([source_lang, source_lang])
1608
+
1556
1609
  if target_lang:
1557
- query += """ AND (
1558
- t.target_lang = ? OR
1610
+ # For forward: filter on target_lang
1611
+ lang_conditions_forward += """ AND (
1612
+ t.target_lang = ? OR
1559
1613
  (t.target_lang IS NULL AND tb.target_lang = ?) OR
1560
1614
  (t.target_lang IS NULL AND tb.target_lang IS NULL)
1561
1615
  )"""
1562
- params.extend([target_lang, target_lang])
1563
-
1564
- # Project filter: match project-specific terms OR global terms (project_id IS NULL)
1616
+ lang_params_forward.extend([target_lang, target_lang])
1617
+ # For reverse: target_lang becomes source_lang (swapped)
1618
+ lang_conditions_reverse += """ AND (
1619
+ t.source_lang = ? OR
1620
+ (t.source_lang IS NULL AND tb.source_lang = ?) OR
1621
+ (t.source_lang IS NULL AND tb.source_lang IS NULL)
1622
+ )"""
1623
+ lang_params_reverse.extend([target_lang, target_lang])
1624
+
1625
+ # Project filter conditions
1626
+ project_conditions = ""
1627
+ project_params = []
1565
1628
  if project_id:
1566
- query += " AND (t.project_id = ? OR t.project_id IS NULL)"
1567
- params.append(project_id)
1568
-
1629
+ project_conditions = " AND (t.project_id = ? OR t.project_id IS NULL)"
1630
+ project_params = [project_id]
1631
+
1632
+ # Min length conditions
1633
+ min_len_forward = ""
1634
+ min_len_reverse = ""
1569
1635
  if min_length > 0:
1570
- query += f" AND LENGTH(t.source_term) >= {min_length}"
1571
-
1572
- # Sort by ranking (lower number = higher priority)
1573
- # Project termbases (ranking IS NULL) appear first, then by ranking, then alphabetically
1574
- # Use COALESCE to treat NULL as -1 (highest priority)
1575
- query += " ORDER BY COALESCE(tb.ranking, -1) ASC, t.source_term ASC"
1576
-
1636
+ min_len_forward = f" AND LENGTH(t.source_term) >= {min_length}"
1637
+ min_len_reverse = f" AND LENGTH(t.target_term) >= {min_length}"
1638
+
1639
+ # Build forward query
1640
+ forward_query = base_select_forward + lang_conditions_forward + project_conditions + min_len_forward
1641
+ forward_params.extend(lang_params_forward)
1642
+ forward_params.extend(project_params)
1643
+
1644
+ if bidirectional:
1645
+ # Build reverse query
1646
+ reverse_query = base_select_reverse + lang_conditions_reverse + project_conditions + min_len_reverse
1647
+ reverse_params.extend(lang_params_reverse)
1648
+ reverse_params.extend(project_params)
1649
+
1650
+ # Combine with UNION and sort
1651
+ query = f"""
1652
+ SELECT * FROM (
1653
+ {forward_query}
1654
+ UNION ALL
1655
+ {reverse_query}
1656
+ ) combined
1657
+ ORDER BY COALESCE(ranking, -1) ASC, source_term ASC
1658
+ """
1659
+ params = forward_params + reverse_params
1660
+ else:
1661
+ # Original forward-only behavior
1662
+ query = forward_query + " ORDER BY COALESCE(ranking, -1) ASC, source_term ASC"
1663
+ params = forward_params
1664
+
1577
1665
  self.cursor.execute(query, params)
1578
1666
  results = []
1667
+ seen_combinations = set() # Track (source_term, target_term, termbase_id) to avoid duplicates
1668
+
1579
1669
  for row in self.cursor.fetchall():
1580
1670
  result_dict = dict(row)
1671
+
1672
+ # Deduplicate: same term pair from same termbase should only appear once
1673
+ # Prefer 'source' match over 'target' match
1674
+ combo_key = (
1675
+ result_dict.get('source_term', '').lower(),
1676
+ result_dict.get('target_term', '').lower(),
1677
+ result_dict.get('termbase_id')
1678
+ )
1679
+ if combo_key in seen_combinations:
1680
+ continue
1681
+ seen_combinations.add(combo_key)
1682
+
1581
1683
  # SQLite stores booleans as 0/1, explicitly convert to Python bool
1582
1684
  if 'is_project_termbase' in result_dict:
1583
1685
  result_dict['is_project_termbase'] = bool(result_dict['is_project_termbase'])
1584
-
1686
+
1585
1687
  # Fetch target synonyms for this term and include them in the result
1586
1688
  term_id = result_dict.get('id')
1689
+ match_direction = result_dict.get('match_direction', 'source')
1587
1690
  if term_id:
1588
1691
  try:
1692
+ # For reverse matches, fetch 'source' synonyms since they become targets
1693
+ synonym_lang = 'source' if match_direction == 'target' else 'target'
1589
1694
  self.cursor.execute("""
1590
1695
  SELECT synonym_text, forbidden FROM termbase_synonyms
1591
- WHERE term_id = ? AND language = 'target'
1696
+ WHERE term_id = ? AND language = ?
1592
1697
  ORDER BY display_order ASC
1593
- """, (term_id,))
1698
+ """, (term_id, synonym_lang))
1594
1699
  synonyms = []
1595
1700
  for syn_row in self.cursor.fetchall():
1596
1701
  syn_text = syn_row[0]
@@ -1600,7 +1705,7 @@ class DatabaseManager:
1600
1705
  result_dict['target_synonyms'] = synonyms
1601
1706
  except Exception:
1602
1707
  result_dict['target_synonyms'] = []
1603
-
1708
+
1604
1709
  results.append(result_dict)
1605
1710
  return results
1606
1711
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "supervertaler"
7
- version = "1.9.176-beta"
7
+ version = "1.9.177-beta"
8
8
  description = "Professional AI-enhanced translation workbench with multi-LLM support, glossary system, TM, spellcheck, voice commands, and PyQt6 interface. Batteries included (core)."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: supervertaler
3
- Version: 1.9.176b0
3
+ Version: 1.9.177b0
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