docsmind 0.6.0__tar.gz → 0.7.0__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 (495) hide show
  1. {docsmind-0.6.0 → docsmind-0.7.0}/CHANGELOG.md +21 -0
  2. {docsmind-0.6.0 → docsmind-0.7.0}/PKG-INFO +1 -1
  3. {docsmind-0.6.0 → docsmind-0.7.0}/pyproject.toml +1 -1
  4. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/agent.py +5 -4
  5. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/prompts.py +11 -3
  6. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/subagents/specs.py +3 -2
  7. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/tools/__init__.py +5 -2
  8. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/tools/base.py +16 -0
  9. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/tools/delegate.py +5 -0
  10. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/tools/documents.py +14 -0
  11. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/tools/search.py +24 -7
  12. docsmind-0.7.0/src/docsmind/agent/tools/web.py +273 -0
  13. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/config.py +7 -0
  14. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/retrieval/keyword.py +3 -1
  15. docsmind-0.7.0/src/docsmind/server/ui/assets/index-B1Hm9KMP.css +1 -0
  16. docsmind-0.6.0/src/docsmind/server/ui/assets/index-CqXag2rP.js → docsmind-0.7.0/src/docsmind/server/ui/assets/index-CsNUfZkw.js +112 -112
  17. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/index.html +2 -2
  18. docsmind-0.6.0/src/docsmind/server/ui/assets/index-QYKdGecG.css +0 -1
  19. {docsmind-0.6.0 → docsmind-0.7.0}/.gitignore +0 -0
  20. {docsmind-0.6.0 → docsmind-0.7.0}/README.md +0 -0
  21. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/__init__.py +0 -0
  22. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/__init__.py +0 -0
  23. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/blobs/__init__.py +0 -0
  24. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/blobs/filesystem.py +0 -0
  25. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/embeddings/__init__.py +0 -0
  26. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/embeddings/openai_embeddings.py +0 -0
  27. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/llm/__init__.py +0 -0
  28. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/llm/anthropic_llm.py +0 -0
  29. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/llm/openai_llm.py +0 -0
  30. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/storage/__init__.py +0 -0
  31. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/storage/memory.py +0 -0
  32. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/storage/postgres/__init__.py +0 -0
  33. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/storage/postgres/agent_store.py +0 -0
  34. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/storage/postgres/engine.py +0 -0
  35. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/storage/postgres/repository.py +0 -0
  36. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/storage/postgres/tables.py +0 -0
  37. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/tracing/__init__.py +0 -0
  38. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/vision/__init__.py +0 -0
  39. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/adapters/vision/captioners.py +0 -0
  40. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/__init__.py +0 -0
  41. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/catalog.py +0 -0
  42. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/harness/__init__.py +0 -0
  43. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/harness/context.py +0 -0
  44. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/harness/memory.py +0 -0
  45. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/harness/summarizer.py +0 -0
  46. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/harness/tokens.py +0 -0
  47. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/loop.py +0 -0
  48. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/orchestrator.py +0 -0
  49. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/planner.py +0 -0
  50. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/sources.py +0 -0
  51. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/subagents/__init__.py +0 -0
  52. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/subagents/change_analysis/__init__.py +0 -0
  53. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/agent/util.py +0 -0
  54. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/cli/__init__.py +0 -0
  55. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/cli/app.py +0 -0
  56. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/cli/chat.py +0 -0
  57. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/cli/db.py +0 -0
  58. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/cli/diff.py +0 -0
  59. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/cli/doctor.py +0 -0
  60. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/cli/enrich.py +0 -0
  61. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/cli/ingest.py +0 -0
  62. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/cli/inspect.py +0 -0
  63. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/cli/serve.py +0 -0
  64. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/client.py +0 -0
  65. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/domain/__init__.py +0 -0
  66. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/domain/agent.py +0 -0
  67. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/domain/changes.py +0 -0
  68. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/domain/citations.py +0 -0
  69. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/domain/documents.py +0 -0
  70. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/domain/errors.py +0 -0
  71. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/domain/ports.py +0 -0
  72. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/domain/tables.py +0 -0
  73. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/enrichment/__init__.py +0 -0
  74. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/enrichment/pricing.py +0 -0
  75. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/enrichment/service.py +0 -0
  76. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/ingestion/__init__.py +0 -0
  77. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/ingestion/chunking/__init__.py +0 -0
  78. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/ingestion/chunking/page.py +0 -0
  79. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/ingestion/chunking/structural.py +0 -0
  80. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/ingestion/enrichment/__init__.py +0 -0
  81. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/ingestion/parsers/__init__.py +0 -0
  82. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/ingestion/parsers/pdf.py +0 -0
  83. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/ingestion/pipeline.py +0 -0
  84. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/py.typed +0 -0
  85. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/retrieval/__init__.py +0 -0
  86. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/retrieval/fusion.py +0 -0
  87. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/retrieval/hybrid.py +0 -0
  88. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/__init__.py +0 -0
  89. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/app.py +0 -0
  90. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/jobs.py +0 -0
  91. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/routes/__init__.py +0 -0
  92. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/routes/chat.py +0 -0
  93. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/routes/documents.py +0 -0
  94. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/routes/enrichment.py +0 -0
  95. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/favicon.svg +0 -0
  96. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/LICENSE +0 -0
  97. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/78-EUC-H.bcmap +0 -0
  98. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/78-EUC-V.bcmap +0 -0
  99. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/78-H.bcmap +0 -0
  100. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/78-RKSJ-H.bcmap +0 -0
  101. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/78-RKSJ-V.bcmap +0 -0
  102. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/78-V.bcmap +0 -0
  103. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/78ms-RKSJ-H.bcmap +0 -0
  104. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/78ms-RKSJ-V.bcmap +0 -0
  105. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/83pv-RKSJ-H.bcmap +0 -0
  106. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/90ms-RKSJ-H.bcmap +0 -0
  107. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/90ms-RKSJ-V.bcmap +0 -0
  108. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/90msp-RKSJ-H.bcmap +0 -0
  109. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/90msp-RKSJ-V.bcmap +0 -0
  110. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/90pv-RKSJ-H.bcmap +0 -0
  111. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/90pv-RKSJ-V.bcmap +0 -0
  112. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Add-H.bcmap +0 -0
  113. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Add-RKSJ-H.bcmap +0 -0
  114. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Add-RKSJ-V.bcmap +0 -0
  115. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Add-V.bcmap +0 -0
  116. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-0.bcmap +0 -0
  117. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-1.bcmap +0 -0
  118. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-2.bcmap +0 -0
  119. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-3.bcmap +0 -0
  120. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-4.bcmap +0 -0
  121. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-5.bcmap +0 -0
  122. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-6.bcmap +0 -0
  123. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-CNS1-UCS2.bcmap +0 -0
  124. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-0.bcmap +0 -0
  125. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-1.bcmap +0 -0
  126. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-2.bcmap +0 -0
  127. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-3.bcmap +0 -0
  128. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-4.bcmap +0 -0
  129. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-5.bcmap +0 -0
  130. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-GB1-UCS2.bcmap +0 -0
  131. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-0.bcmap +0 -0
  132. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-1.bcmap +0 -0
  133. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-2.bcmap +0 -0
  134. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-3.bcmap +0 -0
  135. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-4.bcmap +0 -0
  136. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-5.bcmap +0 -0
  137. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-6.bcmap +0 -0
  138. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Japan1-UCS2.bcmap +0 -0
  139. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Korea1-0.bcmap +0 -0
  140. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Korea1-1.bcmap +0 -0
  141. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Korea1-2.bcmap +0 -0
  142. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Adobe-Korea1-UCS2.bcmap +0 -0
  143. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/B5-H.bcmap +0 -0
  144. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/B5-V.bcmap +0 -0
  145. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/B5pc-H.bcmap +0 -0
  146. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/B5pc-V.bcmap +0 -0
  147. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/CNS-EUC-H.bcmap +0 -0
  148. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/CNS-EUC-V.bcmap +0 -0
  149. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/CNS1-H.bcmap +0 -0
  150. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/CNS1-V.bcmap +0 -0
  151. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/CNS2-H.bcmap +0 -0
  152. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/CNS2-V.bcmap +0 -0
  153. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/ETHK-B5-H.bcmap +0 -0
  154. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/ETHK-B5-V.bcmap +0 -0
  155. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/ETen-B5-H.bcmap +0 -0
  156. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/ETen-B5-V.bcmap +0 -0
  157. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/ETenms-B5-H.bcmap +0 -0
  158. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/ETenms-B5-V.bcmap +0 -0
  159. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/EUC-H.bcmap +0 -0
  160. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/EUC-V.bcmap +0 -0
  161. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Ext-H.bcmap +0 -0
  162. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Ext-RKSJ-H.bcmap +0 -0
  163. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Ext-RKSJ-V.bcmap +0 -0
  164. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Ext-V.bcmap +0 -0
  165. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GB-EUC-H.bcmap +0 -0
  166. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GB-EUC-V.bcmap +0 -0
  167. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GB-H.bcmap +0 -0
  168. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GB-V.bcmap +0 -0
  169. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBK-EUC-H.bcmap +0 -0
  170. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBK-EUC-V.bcmap +0 -0
  171. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBK2K-H.bcmap +0 -0
  172. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBK2K-V.bcmap +0 -0
  173. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBKp-EUC-H.bcmap +0 -0
  174. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBKp-EUC-V.bcmap +0 -0
  175. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBT-EUC-H.bcmap +0 -0
  176. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBT-EUC-V.bcmap +0 -0
  177. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBT-H.bcmap +0 -0
  178. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBT-V.bcmap +0 -0
  179. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBTpc-EUC-H.bcmap +0 -0
  180. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBTpc-EUC-V.bcmap +0 -0
  181. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBpc-EUC-H.bcmap +0 -0
  182. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/GBpc-EUC-V.bcmap +0 -0
  183. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/H.bcmap +0 -0
  184. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKdla-B5-H.bcmap +0 -0
  185. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKdla-B5-V.bcmap +0 -0
  186. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKdlb-B5-H.bcmap +0 -0
  187. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKdlb-B5-V.bcmap +0 -0
  188. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKgccs-B5-H.bcmap +0 -0
  189. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKgccs-B5-V.bcmap +0 -0
  190. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKm314-B5-H.bcmap +0 -0
  191. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKm314-B5-V.bcmap +0 -0
  192. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKm471-B5-H.bcmap +0 -0
  193. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKm471-B5-V.bcmap +0 -0
  194. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKscs-B5-H.bcmap +0 -0
  195. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/HKscs-B5-V.bcmap +0 -0
  196. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Hankaku.bcmap +0 -0
  197. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Hiragana.bcmap +0 -0
  198. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-EUC-H.bcmap +0 -0
  199. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-EUC-V.bcmap +0 -0
  200. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-H.bcmap +0 -0
  201. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-Johab-H.bcmap +0 -0
  202. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-Johab-V.bcmap +0 -0
  203. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSC-V.bcmap +0 -0
  204. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSCms-UHC-H.bcmap +0 -0
  205. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSCms-UHC-HW-H.bcmap +0 -0
  206. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSCms-UHC-HW-V.bcmap +0 -0
  207. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSCms-UHC-V.bcmap +0 -0
  208. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSCpc-EUC-H.bcmap +0 -0
  209. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/KSCpc-EUC-V.bcmap +0 -0
  210. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Katakana.bcmap +0 -0
  211. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/LICENSE +0 -0
  212. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/NWP-H.bcmap +0 -0
  213. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/NWP-V.bcmap +0 -0
  214. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/RKSJ-H.bcmap +0 -0
  215. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/RKSJ-V.bcmap +0 -0
  216. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/Roman.bcmap +0 -0
  217. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UCS2-H.bcmap +0 -0
  218. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UCS2-V.bcmap +0 -0
  219. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF16-H.bcmap +0 -0
  220. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF16-V.bcmap +0 -0
  221. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF32-H.bcmap +0 -0
  222. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF32-V.bcmap +0 -0
  223. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF8-H.bcmap +0 -0
  224. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniCNS-UTF8-V.bcmap +0 -0
  225. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UCS2-H.bcmap +0 -0
  226. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UCS2-V.bcmap +0 -0
  227. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF16-H.bcmap +0 -0
  228. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF16-V.bcmap +0 -0
  229. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF32-H.bcmap +0 -0
  230. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF32-V.bcmap +0 -0
  231. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF8-H.bcmap +0 -0
  232. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniGB-UTF8-V.bcmap +0 -0
  233. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UCS2-H.bcmap +0 -0
  234. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UCS2-HW-H.bcmap +0 -0
  235. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UCS2-HW-V.bcmap +0 -0
  236. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UCS2-V.bcmap +0 -0
  237. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF16-H.bcmap +0 -0
  238. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF16-V.bcmap +0 -0
  239. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF32-H.bcmap +0 -0
  240. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF32-V.bcmap +0 -0
  241. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF8-H.bcmap +0 -0
  242. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS-UTF8-V.bcmap +0 -0
  243. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF16-H.bcmap +0 -0
  244. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF16-V.bcmap +0 -0
  245. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF32-H.bcmap +0 -0
  246. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF32-V.bcmap +0 -0
  247. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF8-H.bcmap +0 -0
  248. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJIS2004-UTF8-V.bcmap +0 -0
  249. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISPro-UCS2-HW-V.bcmap +0 -0
  250. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISPro-UCS2-V.bcmap +0 -0
  251. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISPro-UTF8-V.bcmap +0 -0
  252. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISX0213-UTF32-H.bcmap +0 -0
  253. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISX0213-UTF32-V.bcmap +0 -0
  254. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISX02132004-UTF32-H.bcmap +0 -0
  255. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniJISX02132004-UTF32-V.bcmap +0 -0
  256. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UCS2-H.bcmap +0 -0
  257. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UCS2-V.bcmap +0 -0
  258. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF16-H.bcmap +0 -0
  259. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF16-V.bcmap +0 -0
  260. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF32-H.bcmap +0 -0
  261. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF32-V.bcmap +0 -0
  262. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF8-H.bcmap +0 -0
  263. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/UniKS-UTF8-V.bcmap +0 -0
  264. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/V.bcmap +0 -0
  265. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/cmaps/WP-Symbol.bcmap +0 -0
  266. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/iccs/CGATS001Compat-v2-micro.icc +0 -0
  267. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/iccs/LICENSE +0 -0
  268. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/altText_add.svg +0 -0
  269. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/altText_disclaimer.svg +0 -0
  270. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/altText_done.svg +0 -0
  271. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/altText_spinner.svg +0 -0
  272. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/altText_warning.svg +0 -0
  273. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-check.svg +0 -0
  274. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-comment.svg +0 -0
  275. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-help.svg +0 -0
  276. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-insert.svg +0 -0
  277. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-key.svg +0 -0
  278. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-newparagraph.svg +0 -0
  279. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-noicon.svg +0 -0
  280. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-note.svg +0 -0
  281. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-paperclip.svg +0 -0
  282. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-paragraph.svg +0 -0
  283. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/annotation-pushpin.svg +0 -0
  284. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/checkmark.svg +0 -0
  285. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/comment-actionsButton.svg +0 -0
  286. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/comment-closeButton.svg +0 -0
  287. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/comment-editButton.svg +0 -0
  288. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/comment-popup-editButton.svg +0 -0
  289. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/cursor-editorFreeHighlight.svg +0 -0
  290. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/cursor-editorFreeText.svg +0 -0
  291. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/cursor-editorInk.svg +0 -0
  292. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/cursor-editorTextHighlight.svg +0 -0
  293. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/editor-toolbar-delete.svg +0 -0
  294. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/editor-toolbar-edit.svg +0 -0
  295. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/findbarButton-next.svg +0 -0
  296. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/findbarButton-previous.svg +0 -0
  297. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/gv-toolbarButton-download.svg +0 -0
  298. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/loading-icon.gif +0 -0
  299. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/loading.svg +0 -0
  300. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/messageBar_closingButton.svg +0 -0
  301. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/messageBar_info.svg +0 -0
  302. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/messageBar_warning.svg +0 -0
  303. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/pages_closeButton.svg +0 -0
  304. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/pages_selected.svg +0 -0
  305. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/pages_viewArrow.svg +0 -0
  306. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/pages_viewButton.svg +0 -0
  307. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-documentProperties.svg +0 -0
  308. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-firstPage.svg +0 -0
  309. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-handTool.svg +0 -0
  310. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-lastPage.svg +0 -0
  311. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-rotateCcw.svg +0 -0
  312. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-rotateCw.svg +0 -0
  313. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-scrollHorizontal.svg +0 -0
  314. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-scrollPage.svg +0 -0
  315. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-scrollVertical.svg +0 -0
  316. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-scrollWrapped.svg +0 -0
  317. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-selectTool.svg +0 -0
  318. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-spreadEven.svg +0 -0
  319. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-spreadNone.svg +0 -0
  320. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/secondaryToolbarButton-spreadOdd.svg +0 -0
  321. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/signature-properties-row-check.svg +0 -0
  322. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-bookmark.svg +0 -0
  323. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-currentOutlineItem.svg +0 -0
  324. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-download.svg +0 -0
  325. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-editorFreeText.svg +0 -0
  326. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-editorHighlight.svg +0 -0
  327. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-editorInk.svg +0 -0
  328. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-editorSignature.svg +0 -0
  329. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-editorStamp.svg +0 -0
  330. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-menuArrow.svg +0 -0
  331. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-menuArrowNova.svg +0 -0
  332. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-openFile.svg +0 -0
  333. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-pageDown.svg +0 -0
  334. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-pageUp.svg +0 -0
  335. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-presentationMode.svg +0 -0
  336. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-print.svg +0 -0
  337. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-search.svg +0 -0
  338. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-secondaryToolbarToggle.svg +0 -0
  339. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-signaturePropertiesError.svg +0 -0
  340. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-signaturePropertiesVerified.svg +0 -0
  341. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-viewAttachments.svg +0 -0
  342. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-viewLayers.svg +0 -0
  343. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-viewOutline.svg +0 -0
  344. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-viewThumbnail.svg +0 -0
  345. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-viewsManagerToggle.svg +0 -0
  346. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-zoomIn.svg +0 -0
  347. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/toolbarButton-zoomOut.svg +0 -0
  348. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/treeitem-collapsed.svg +0 -0
  349. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/images/treeitem-expanded.svg +0 -0
  350. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ach/viewer.ftl +0 -0
  351. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/af/viewer.ftl +0 -0
  352. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/an/viewer.ftl +0 -0
  353. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ar/viewer.ftl +0 -0
  354. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ast/viewer.ftl +0 -0
  355. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/az/viewer.ftl +0 -0
  356. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/be/viewer.ftl +0 -0
  357. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/bg/viewer.ftl +0 -0
  358. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/bn/viewer.ftl +0 -0
  359. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/bo/viewer.ftl +0 -0
  360. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/bqi/viewer.ftl +0 -0
  361. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/br/viewer.ftl +0 -0
  362. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/brx/viewer.ftl +0 -0
  363. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/bs/viewer.ftl +0 -0
  364. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ca/viewer.ftl +0 -0
  365. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/cak/viewer.ftl +0 -0
  366. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ckb/viewer.ftl +0 -0
  367. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/cs/viewer.ftl +0 -0
  368. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/cy/viewer.ftl +0 -0
  369. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/da/viewer.ftl +0 -0
  370. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/de/viewer.ftl +0 -0
  371. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/dsb/viewer.ftl +0 -0
  372. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/el/viewer.ftl +0 -0
  373. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/en-CA/viewer.ftl +0 -0
  374. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/en-GB/viewer.ftl +0 -0
  375. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/en-US/viewer.ftl +0 -0
  376. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/eo/viewer.ftl +0 -0
  377. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/es-AR/viewer.ftl +0 -0
  378. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/es-CL/viewer.ftl +0 -0
  379. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/es-ES/viewer.ftl +0 -0
  380. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/es-MX/viewer.ftl +0 -0
  381. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/et/viewer.ftl +0 -0
  382. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/eu/viewer.ftl +0 -0
  383. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/fa/viewer.ftl +0 -0
  384. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ff/viewer.ftl +0 -0
  385. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/fi/viewer.ftl +0 -0
  386. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/fr/viewer.ftl +0 -0
  387. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/fur/viewer.ftl +0 -0
  388. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/fy-NL/viewer.ftl +0 -0
  389. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ga-IE/viewer.ftl +0 -0
  390. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/gd/viewer.ftl +0 -0
  391. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/gl/viewer.ftl +0 -0
  392. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/gn/viewer.ftl +0 -0
  393. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/gu-IN/viewer.ftl +0 -0
  394. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/he/viewer.ftl +0 -0
  395. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/hi-IN/viewer.ftl +0 -0
  396. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/hr/viewer.ftl +0 -0
  397. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/hsb/viewer.ftl +0 -0
  398. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/hu/viewer.ftl +0 -0
  399. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/hy-AM/viewer.ftl +0 -0
  400. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/hye/viewer.ftl +0 -0
  401. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ia/viewer.ftl +0 -0
  402. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/id/viewer.ftl +0 -0
  403. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/is/viewer.ftl +0 -0
  404. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/it/viewer.ftl +0 -0
  405. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ja/viewer.ftl +0 -0
  406. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ka/viewer.ftl +0 -0
  407. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/kab/viewer.ftl +0 -0
  408. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/kk/viewer.ftl +0 -0
  409. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/km/viewer.ftl +0 -0
  410. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/kn/viewer.ftl +0 -0
  411. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ko/viewer.ftl +0 -0
  412. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/lij/viewer.ftl +0 -0
  413. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/lo/viewer.ftl +0 -0
  414. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/locale.json +0 -0
  415. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/lt/viewer.ftl +0 -0
  416. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ltg/viewer.ftl +0 -0
  417. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/lv/viewer.ftl +0 -0
  418. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/meh/viewer.ftl +0 -0
  419. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/mk/viewer.ftl +0 -0
  420. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ml/viewer.ftl +0 -0
  421. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/mr/viewer.ftl +0 -0
  422. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ms/viewer.ftl +0 -0
  423. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/my/viewer.ftl +0 -0
  424. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/nb-NO/viewer.ftl +0 -0
  425. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ne-NP/viewer.ftl +0 -0
  426. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/nl/viewer.ftl +0 -0
  427. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/nn-NO/viewer.ftl +0 -0
  428. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/oc/viewer.ftl +0 -0
  429. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/pa-IN/viewer.ftl +0 -0
  430. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/pl/viewer.ftl +0 -0
  431. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/pt-BR/viewer.ftl +0 -0
  432. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/pt-PT/viewer.ftl +0 -0
  433. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/rm/viewer.ftl +0 -0
  434. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ro/viewer.ftl +0 -0
  435. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ru/viewer.ftl +0 -0
  436. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/sat/viewer.ftl +0 -0
  437. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/sc/viewer.ftl +0 -0
  438. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/scn/viewer.ftl +0 -0
  439. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/sco/viewer.ftl +0 -0
  440. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/si/viewer.ftl +0 -0
  441. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/sk/viewer.ftl +0 -0
  442. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/skr/viewer.ftl +0 -0
  443. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/sl/viewer.ftl +0 -0
  444. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/son/viewer.ftl +0 -0
  445. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/sq/viewer.ftl +0 -0
  446. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/sr/viewer.ftl +0 -0
  447. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/sv-SE/viewer.ftl +0 -0
  448. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/szl/viewer.ftl +0 -0
  449. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ta/viewer.ftl +0 -0
  450. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/te/viewer.ftl +0 -0
  451. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/tg/viewer.ftl +0 -0
  452. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/th/viewer.ftl +0 -0
  453. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/tl/viewer.ftl +0 -0
  454. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/tr/viewer.ftl +0 -0
  455. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/trs/viewer.ftl +0 -0
  456. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/uk/viewer.ftl +0 -0
  457. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/ur/viewer.ftl +0 -0
  458. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/uz/viewer.ftl +0 -0
  459. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/vi/viewer.ftl +0 -0
  460. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/wo/viewer.ftl +0 -0
  461. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/xh/viewer.ftl +0 -0
  462. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/zh-CN/viewer.ftl +0 -0
  463. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/locale/zh-TW/viewer.ftl +0 -0
  464. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitDingbats.pfb +0 -0
  465. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitFixed.pfb +0 -0
  466. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitFixedBold.pfb +0 -0
  467. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitFixedBoldItalic.pfb +0 -0
  468. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitFixedItalic.pfb +0 -0
  469. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitSerif.pfb +0 -0
  470. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitSerifBold.pfb +0 -0
  471. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitSerifBoldItalic.pfb +0 -0
  472. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitSerifItalic.pfb +0 -0
  473. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/FoxitSymbol.pfb +0 -0
  474. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/LICENSE_FOXIT +0 -0
  475. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/LICENSE_LIBERATION +0 -0
  476. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/LiberationSans-Bold.ttf +0 -0
  477. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/LiberationSans-BoldItalic.ttf +0 -0
  478. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/LiberationSans-Italic.ttf +0 -0
  479. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/standard_fonts/LiberationSans-Regular.ttf +0 -0
  480. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/viewer.css +0 -0
  481. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/viewer.html +0 -0
  482. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/viewer.mjs +0 -0
  483. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_JBIG2 +0 -0
  484. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_OPENJPEG +0 -0
  485. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_PDFJS_JBIG2 +0 -0
  486. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_PDFJS_OPENJPEG +0 -0
  487. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_PDFJS_QCMS +0 -0
  488. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/LICENSE_QCMS +0 -0
  489. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/jbig2.wasm +0 -0
  490. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/jbig2_nowasm_fallback.js +0 -0
  491. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/openjpeg.wasm +0 -0
  492. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/openjpeg_nowasm_fallback.js +0 -0
  493. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/qcms_bg.wasm +0 -0
  494. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/quickjs-eval.js +0 -0
  495. {docsmind-0.6.0 → docsmind-0.7.0}/src/docsmind/server/ui/pdfjs/web/wasm/quickjs-eval.wasm +0 -0
@@ -2,6 +2,27 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.7.0] - 2026-11-12
6
+
7
+ ### Added
8
+
9
+ - Change Analyzer can now look for a published changelog online when the documents themselves
10
+ contain none, using two new subagent-only tools:
11
+ - `web_search`: searches the web via Tavily, optionally limited to given domains. Only offered
12
+ when `DOCSMIND_WEB_SEARCH_API_KEY` is set.
13
+ - `fetch_url`: reads a public web page as text. Hardened for model-supplied URLs (http(s) on
14
+ ports 80/443 only, no credentials, no private/loopback addresses on any redirect hop,
15
+ bounded size and time).
16
+ - Config: `web_search_api_key`, `web_timeout_s`, `web_fetch_max_bytes` (documented in
17
+ `.env.example`).
18
+ - Implementation brief for the Change Analyzer (`docs/`) and unit tests for the web tools.
19
+
20
+ ### Changed
21
+
22
+ - Change Analyzer prompt and tool list updated to use the web tools as a fallback, preferring
23
+ the publisher's own domain.
24
+ - Rebuilt the bundled frontend UI assets.
25
+
5
26
  ## [0.6.0] - 2026-11-10
6
27
 
7
28
  ### Added
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: docsmind
3
- Version: 0.6.0
3
+ Version: 0.7.0
4
4
  Summary: Chat with your documents. Version-aware retrieval, change analysis, and an editable table workspace, backed by Postgres/pgvector.
5
5
  Project-URL: Homepage, https://github.com/yauheniya-ai/docsmind
6
6
  Project-URL: Repository, https://github.com/yauheniya-ai/docsmind
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "docsmind"
7
- version = "0.6.0"
7
+ version = "0.7.0"
8
8
  description = "Chat with your documents. Version-aware retrieval, change analysis, and an editable table workspace, backed by Postgres/pgvector."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -75,6 +75,7 @@ class DocsmindAgent:
75
75
  self._memory = memory
76
76
  self._query_embedder = None
77
77
  self.tools = tools or build_registry()
78
+ self.main_tools = self.tools.for_executor()
78
79
  self.builder = ContextBuilder(config)
79
80
  self._background: set[asyncio.Task] = set()
80
81
 
@@ -187,7 +188,7 @@ class DocsmindAgent:
187
188
  "with citations that are verified against what it actually read."
188
189
  ),
189
190
  "model": self.config.llm_model,
190
- "tools": self.tools.info(),
191
+ "tools": self.main_tools.info(),
191
192
  },
192
193
  "stages": [
193
194
  {
@@ -403,11 +404,11 @@ class DocsmindAgent:
403
404
  delegate=self._make_delegate(llm, catalog, sources, usage, emit),
404
405
  embedder=self.query_embedder,
405
406
  )
406
- bundle = self.builder.executor(state, self.tools.specs())
407
+ bundle = self.builder.executor(state, self.main_tools.specs())
407
408
  result = await run_tool_loop(
408
409
  llm=llm,
409
410
  bundle=bundle,
410
- registry=self.tools,
411
+ registry=self.main_tools,
411
412
  ctx=tool_ctx,
412
413
  usage=usage,
413
414
  emit=emit,
@@ -482,7 +483,7 @@ class DocsmindAgent:
482
483
  delegate=None, # no recursion
483
484
  embedder=self.query_embedder,
484
485
  )
485
- registry = self.tools.subset(spec.tools)
486
+ registry = self.tools.subset(spec.tools).configured(self.config)
486
487
  bundle = self.builder.subagent(spec, task, sub_catalog, registry.specs())
487
488
 
488
489
  emit(AgentEvent(type="subagent_start", data={"id": sub_id, "name": spec.name, "task": task}))
@@ -22,12 +22,12 @@ You are the Mind, the assistant inside docsmind. You answer questions about the
22
22
 
23
23
  How to work
24
24
  - Documents are referred to by handle (D1, D2, ...); the register is listed below.
25
- - search: ranked keyword search; start here for most questions. Use distinctive words, not the whole question.
25
+ - search: ranked hybrid search (keywords plus meaning); start here for most questions. Write the query in natural language, e.g. the question or a descriptive phrase.
26
26
  - grep: exact phrase or identifier (a clause number, a defined term). Use when search blurs exact wording.
27
27
  - read_pages: read the actual text of pages. Read around a promising hit before relying on a snippet.
28
28
  - get_outline: the document's table of contents with page numbers.
29
29
  - list_documents: only if you need page/word counts again.
30
- - delegate: hand a self-contained task to a subagent with a fresh context when the work is large or independent (comparing several documents or versions, reading many sections). It returns a short summary that keeps the same [S#] handles. Several delegate calls in one step run in parallel.
30
+ - delegate: hand a self-contained task to a subagent with a fresh context when the work is large or independent (comparing several documents or versions, reading many sections). It returns a short summary that keeps the same [S#] handles; web pages it used appear as markdown links, which you keep as given. Several delegate calls in one step run in parallel.
31
31
  - Make independent tool calls in the same step. Prefer a few precise calls over many vague ones. Do not narrate before calling tools.
32
32
  - If the question is conversational or not about the documents, answer directly without tools.
33
33
 
@@ -73,7 +73,15 @@ Role: researcher. Gather the evidence needed for a focused question. Search, gre
73
73
  CHANGE_ANALYZER = f"""\
74
74
  {SUBAGENT_COMMON}
75
75
 
76
- Role: change analyzer. Compare two versions of the same document (or two related documents) and report what was added, removed or reworded, section by section, and why it matters. Use get_outline on both to align sections, then read_pages on matching sections. Cite both sides of every difference. If the versions are identical in the area asked about, say so."""
76
+ Role: change analyzer. Compare two versions of the same document (or two related documents) and report what was added, removed or reworded, section by section, and why it matters.
77
+
78
+ Step 1, always first: look for a changelog before comparing any text.
79
+ - In the documents: search for "revision history", "summary of changes", "changelog", "what's new", "errata", "change log"; check get_outline for such a section (usually at the front or in an appendix), and read it with read_pages.
80
+ - Online, only if web_search / fetch_url are among your tools and the documents give no usable changelog: search for the publisher's changes page for these exact versions (prefer the publisher's own domain), then fetch_url the best result. Follow a link from that page at most once or twice.
81
+ - Treat a changelog as a map of where to look, not as proof. Confirm every change you report against the document text on both sides.
82
+ - Cite changelog entries that come from a document with [S#]. For a web page, name it as a markdown link [title](url); never give a web page an [S#] handle. If you found no changelog, say so in one line and continue.
83
+
84
+ Step 2: use get_outline on both to align sections, then read_pages on matching sections. Cite both sides of every difference. If the versions are identical in the area asked about, say so."""
77
85
 
78
86
  SUMMARIZER = """\
79
87
  You maintain the running summary of a conversation between a user and a document assistant. Merge the new turns into the existing summary.
@@ -35,10 +35,11 @@ CHANGE_ANALYZER = SubagentSpec(
35
35
  role="Version comparison",
36
36
  description=(
37
37
  "Compares two versions of a document (or two related documents) and reports what was "
38
- "added, removed or reworded, section by section, with citations on both sides."
38
+ "added, removed or reworded, section by section, with citations on both sides. It first "
39
+ "looks for a changelog in the documents and, when web access is configured, online."
39
40
  ),
40
41
  prompt=prompts.CHANGE_ANALYZER,
41
- tools=("search", "grep", "read_pages", "get_outline"),
42
+ tools=("search", "grep", "read_pages", "get_outline", "web_search", "fetch_url"),
42
43
  )
43
44
 
44
45
  SUBAGENTS: dict[str, SubagentSpec] = {s.name: s for s in (RESEARCHER, CHANGE_ANALYZER)}
@@ -6,13 +6,14 @@ from docsmind.agent.tools.base import Tool, ToolContext, ToolOutput, ToolRegistr
6
6
  from docsmind.agent.tools.delegate import DelegateTool
7
7
  from docsmind.agent.tools.documents import ListDocumentsTool, OutlineTool, ReadPagesTool
8
8
  from docsmind.agent.tools.search import GrepTool, SearchTool
9
+ from docsmind.agent.tools.web import FetchUrlTool, WebSearchTool
9
10
 
10
11
  __all__ = ["Tool", "ToolContext", "ToolOutput", "ToolRegistry", "build_registry"]
11
12
 
12
13
 
13
14
  def build_registry() -> ToolRegistry:
14
- """Every tool the main executor can call. Subagents get a subset (see
15
- `agent/subagents/specs.py`) and never `delegate`."""
15
+ """Every tool. The main executor gets all but the `subagent_only` ones (the web tools);
16
+ subagents get the subset their spec lists (see `agent/subagents/specs.py`) and never `delegate`."""
16
17
  return ToolRegistry(
17
18
  [
18
19
  SearchTool(),
@@ -21,5 +22,7 @@ def build_registry() -> ToolRegistry:
21
22
  OutlineTool(),
22
23
  ListDocumentsTool(),
23
24
  DelegateTool(),
25
+ WebSearchTool(),
26
+ FetchUrlTool(),
24
27
  ]
25
28
  )
@@ -51,8 +51,15 @@ class Tool:
51
51
  name: ClassVar[str]
52
52
  description: ClassVar[str] # written for the model
53
53
  summary: ClassVar[str] = "" # one plain sentence for people (shown in the UI)
54
+ how_it_works: ClassVar[tuple[str, ...]] = () # quick-reference steps for people (UI only, never sent to the model)
55
+ subagent_only: ClassVar[bool] = False # True: never offered to the main executor, only to subagents that list it
54
56
  Args: ClassVar[type[BaseModel]]
55
57
 
58
+ @classmethod
59
+ def available(cls, config: DocsmindConfig) -> bool:
60
+ """False when the tool needs configuration that is missing (it is then not offered to the model)."""
61
+ return True
62
+
56
63
  async def run(self, args: Any, ctx: ToolContext) -> ToolOutput: # pragma: no cover
57
64
  raise NotImplementedError
58
65
 
@@ -103,6 +110,7 @@ class ToolRegistry:
103
110
  {
104
111
  "name": n,
105
112
  "description": tool.summary,
113
+ "how_it_works": list(tool.how_it_works),
106
114
  "instructions": spec.description,
107
115
  "parameters": spec.parameters,
108
116
  }
@@ -112,6 +120,14 @@ class ToolRegistry:
112
120
  def subset(self, names: tuple[str, ...] | list[str]) -> ToolRegistry:
113
121
  return ToolRegistry([t for n, t in self._tools.items() if n in names])
114
122
 
123
+ def for_executor(self) -> ToolRegistry:
124
+ """The tools the main executor may call: everything except subagent-only tools."""
125
+ return ToolRegistry([t for t in self._tools.values() if not t.subagent_only])
126
+
127
+ def configured(self, config: DocsmindConfig) -> ToolRegistry:
128
+ """Drops tools whose configuration is missing, so the model never sees a tool it cannot use."""
129
+ return ToolRegistry([t for t in self._tools.values() if t.available(config)])
130
+
115
131
  def specs(self) -> list[ToolSpec]:
116
132
  return [t.spec() for t in self._tools.values()]
117
133
 
@@ -37,6 +37,11 @@ class DelegateTool(Tool):
37
37
  "short report with [S#] citations. Use for large or independent work; several delegate calls in "
38
38
  "one step run in parallel.\nSubagents:\n" + _ROSTER
39
39
  )
40
+ how_it_works = (
41
+ "The Mind picks a subagent and writes a self-contained task; the subagent never sees the conversation.",
42
+ "The subagent works in a fresh context with its own tools (search, grep, read_pages, get_outline) and cannot delegate further.",
43
+ "Only its short report comes back, with the same [S#] source handles. Several delegations in one step run in parallel.",
44
+ )
40
45
  Args = DelegateArgs
41
46
 
42
47
  async def run(self, args: DelegateArgs, ctx: ToolContext) -> ToolOutput:
@@ -20,6 +20,10 @@ class ListDocumentsTool(Tool):
20
20
  name = "list_documents"
21
21
  summary = "Lists the documents in the register with their collection, version and size."
22
22
  description = "List the documents in the register with their handles, collection, version label, page and word counts."
23
+ how_it_works = (
24
+ "Reads the catalog built for this conversation (no database query).",
25
+ "Returns each document's handle (D1, D2, ...), title, collection, version, and page and word counts.",
26
+ )
23
27
  Args = ListDocumentsArgs
24
28
 
25
29
  async def run(self, args: ListDocumentsArgs, ctx: ToolContext) -> ToolOutput:
@@ -37,6 +41,11 @@ class OutlineTool(Tool):
37
41
  "The document's table of contents (from the PDF's own bookmarks) with page numbers. "
38
42
  "Use it to find which pages cover a topic, then read_pages."
39
43
  )
44
+ how_it_works = (
45
+ "Loads the document's sections, taken from the PDF's own bookmarks.",
46
+ "Lists them indented by depth, each with its page number (up to 200 entries).",
47
+ "If the PDF has no bookmarks, it says so and the model falls back to search.",
48
+ )
40
49
  Args = OutlineArgs
41
50
 
42
51
  async def run(self, args: OutlineArgs, ctx: ToolContext) -> ToolOutput:
@@ -74,6 +83,11 @@ class ReadPagesTool(Tool):
74
83
  "Read the full text of one or a few consecutive pages of a document. Each chunk comes with a "
75
84
  "source handle to cite."
76
85
  )
86
+ how_it_works = (
87
+ "Checks the page range: at most 4 pages per call, and within the document.",
88
+ "Loads every text chunk that overlaps those pages.",
89
+ "Returns the full text, each chunk with a source handle to cite.",
90
+ )
77
91
  Args = ReadPagesArgs
78
92
 
79
93
  async def run(self, args: ReadPagesArgs, ctx: ToolContext) -> ToolOutput:
@@ -24,7 +24,14 @@ def format_passage(doc: CatalogDoc, handle: str, page_start: int | None, page_en
24
24
 
25
25
 
26
26
  class SearchArgs(BaseModel):
27
- query: str = Field(min_length=2, description="Distinctive words to look for (not a full sentence).")
27
+ query: str = Field(
28
+ min_length=2,
29
+ max_length=1000,
30
+ description=(
31
+ "Natural-language query: a question or a descriptive phrase. "
32
+ "Use grep instead for exact wording, identifiers or clause numbers."
33
+ ),
34
+ )
28
35
  documents: list[str] | None = Field(default=None, description=_DOCUMENTS_HELP)
29
36
  limit: int = Field(default=6, ge=1, le=10, description="Maximum passages to return.")
30
37
 
@@ -32,14 +39,19 @@ class SearchArgs(BaseModel):
32
39
  class SearchTool(Tool):
33
40
  name = "search"
34
41
  summary = (
35
- "Searches the documents by keywords, and by meaning once they have been embedded. "
36
- "Returns the best matching passages to cite."
42
+ "Hybrid search over the documents: stemmed keyword matching plus semantic (embedding) similarity, "
43
+ "fused by reciprocal rank fusion. Returns the best matching passages to cite."
37
44
  )
38
45
  description = (
39
- "Search the documents' text (and figure captions, if images were captioned). Matches by "
40
- "stemmed keywords, plus by meaning when the documents have been embedded, so paraphrases can "
41
- "match too. Returns the best passages, each with a source handle like [S1] to cite; use "
42
- "read_pages on a hit to see the surrounding text."
46
+ "Find passages by topic or meaning in the documents' text and figure captions. Takes a "
47
+ "natural-language query; matches keywords and paraphrases, ranked best first. Returns passages "
48
+ "with a source handle like [S1] to cite; use read_pages to see the surrounding text. "
49
+ )
50
+ how_it_works = (
51
+ "Keyword search: the query is stemmed and matched with Postgres full-text search.",
52
+ "Semantic search: the query is embedded and the nearest passages are found by cosine similarity (skipped if the documents are not embedded).",
53
+ "Reciprocal rank fusion: each list scores a passage 1 / (60 + rank) and the scores are added, so passages ranked well by both come first.",
54
+ "The top passages come back with source handles to cite.",
43
55
  )
44
56
  Args = SearchArgs
45
57
 
@@ -102,6 +114,11 @@ class GrepTool(Tool):
102
114
  "Find an exact phrase, clause number or identifier (case-insensitive, literal match, no stemming). "
103
115
  "Returns the pages containing it, each with a source handle to cite."
104
116
  )
117
+ how_it_works = (
118
+ "Escapes the text and runs a case-insensitive substring match (ILIKE) over every page of the chosen documents.",
119
+ "No stemming and no ranking: only literal matches, in document and page order.",
120
+ "Returns a snippet around the first hit on each page, with the number of occurrences and a source handle.",
121
+ )
105
122
  Args = GrepArgs
106
123
 
107
124
  async def run(self, args: GrepArgs, ctx: ToolContext) -> ToolOutput:
@@ -0,0 +1,273 @@
1
+ """Web tools, for the Change Analyzer only: find and read a published changelog.
2
+
3
+ Everything a web page says is untrusted DATA, like document text. The fetcher
4
+ is hardened because the URL comes from a model: http(s) on ports 80/443 only,
5
+ no credentials in the URL, no private/loopback/link-local addresses (checked on
6
+ every redirect hop), bounded size and time.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import asyncio
12
+ import ipaddress
13
+ import re
14
+ import socket
15
+ from html.parser import HTMLParser
16
+ from urllib.parse import urljoin, urlsplit
17
+
18
+ import httpx
19
+ from pydantic import BaseModel, Field
20
+
21
+ from docsmind.agent.tools.base import Tool, ToolContext, ToolOutput
22
+ from docsmind.config import DocsmindConfig
23
+ from docsmind.domain.errors import ToolInputError
24
+
25
+ TAVILY_URL = "https://api.tavily.com/search"
26
+ PAGE_CHARS = 10_000 # per fetch_url call; below agent_tool_result_max_chars so it is never cut again
27
+ MAX_REDIRECTS = 4
28
+ ALLOWED_PORTS = {None, 80, 443}
29
+ TEXT_TYPES = ("text/html", "application/xhtml", "text/plain", "text/markdown")
30
+ USER_AGENT = "docsmind/1.0 (document assistant; reads public pages)"
31
+
32
+
33
+ # -- web_search ------------------------------------------------------------------------
34
+
35
+
36
+ class WebSearchArgs(BaseModel):
37
+ query: str = Field(min_length=3, max_length=400, description="What to look for on the web.")
38
+ domains: list[str] | None = Field(
39
+ default=None,
40
+ max_length=5,
41
+ description="Only search these sites, e.g. the publisher's domain. Omit to search the whole web.",
42
+ )
43
+ limit: int = Field(default=5, ge=1, le=8, description="Maximum results to return.")
44
+
45
+
46
+ class WebSearchTool(Tool):
47
+ name = "web_search"
48
+ subagent_only = True
49
+ summary = (
50
+ "Searches the public web, mainly to find a published changelog or release notes for a document. "
51
+ "Needs a Tavily API key (DOCSMIND_WEB_SEARCH_API_KEY)."
52
+ )
53
+ description = (
54
+ "Search the public web. Returns the title, URL and an excerpt of each result. Use it to find "
55
+ "an official changelog, revision history or release notes for a document; prefer the "
56
+ "publisher's own site. Read a result in full with fetch_url."
57
+ )
58
+ how_it_works = (
59
+ "Sends the query (optionally limited to given domains) to the Tavily search API.",
60
+ "Returns each result's title, URL and excerpt. The model reads promising pages with fetch_url.",
61
+ "Only offered when DOCSMIND_WEB_SEARCH_API_KEY is set.",
62
+ )
63
+ Args = WebSearchArgs
64
+
65
+ @classmethod
66
+ def available(cls, config: DocsmindConfig) -> bool:
67
+ return bool(config.web_search_api_key)
68
+
69
+ async def run(self, args: WebSearchArgs, ctx: ToolContext) -> ToolOutput:
70
+ key = ctx.config.web_search_api_key
71
+ if not key:
72
+ raise ToolInputError("Web search is not configured. Work from the documents only.")
73
+ payload: dict = {
74
+ "query": args.query,
75
+ "max_results": args.limit,
76
+ "search_depth": "basic",
77
+ "include_answer": False,
78
+ }
79
+ if args.domains:
80
+ payload["include_domains"] = args.domains
81
+ try:
82
+ async with httpx.AsyncClient(timeout=ctx.config.web_timeout_s) as client:
83
+ response = await client.post(TAVILY_URL, json=payload, headers={"Authorization": f"Bearer {key}"})
84
+ except httpx.HTTPError as exc:
85
+ raise ToolInputError("Web search is unreachable right now. Work from the documents only.") from exc
86
+ if response.status_code in (401, 403):
87
+ raise ToolInputError("Web search rejected its API key. Work from the documents only.")
88
+ if response.status_code >= 400:
89
+ raise ToolInputError(f"Web search failed (HTTP {response.status_code}). Try different words or skip it.")
90
+
91
+ results = response.json().get("results") or []
92
+ if not results:
93
+ return ToolOutput(
94
+ f"No web results for '{args.query}'. Try other words or a different site.", summary="no results"
95
+ )
96
+ lines = []
97
+ for i, result in enumerate(results[: args.limit], start=1):
98
+ excerpt = re.sub(r"\s+", " ", result.get("content") or "").strip()[:500]
99
+ lines.append(f"{i}. {result.get('title') or '(untitled)'}\n {result.get('url')}\n {excerpt}")
100
+ return ToolOutput("\n\n".join(lines), summary=f"{len(lines)} results")
101
+
102
+
103
+ # -- fetch_url -------------------------------------------------------------------------
104
+
105
+
106
+ class FetchUrlArgs(BaseModel):
107
+ url: str = Field(min_length=8, max_length=2000, description="Full http(s) URL of a public web page.")
108
+ offset: int = Field(default=0, ge=0, description="Character to start from, to continue a long page.")
109
+
110
+
111
+ class FetchUrlTool(Tool):
112
+ name = "fetch_url"
113
+ subagent_only = True
114
+ summary = "Reads the text of one public web page, with its links, for example a changelog or release notes."
115
+ description = (
116
+ "Fetch a public web page (HTML or plain text; not PDFs) and return its text, with link targets "
117
+ "shown as 'text (url)'. Long pages come in parts: pass the offset given at the end to continue. "
118
+ "Use it on a changelog, revision history or release-notes page."
119
+ )
120
+ how_it_works = (
121
+ "Accepts only public http(s) URLs: private and local addresses are refused, also after redirects.",
122
+ "Downloads the page (size and time limited) and converts the HTML to plain text, keeping link URLs.",
123
+ "Returns the text in parts of about 10,000 characters; the model asks for the next part with an offset.",
124
+ )
125
+ Args = FetchUrlArgs
126
+
127
+ async def run(self, args: FetchUrlArgs, ctx: ToolContext) -> ToolOutput:
128
+ final_url, content_type, body = await _fetch(args.url, ctx.config)
129
+ if "html" in content_type or "xml" in content_type:
130
+ title, text = _html_to_text(body, final_url)
131
+ else:
132
+ title, text = "", body.strip()
133
+ if not text:
134
+ return ToolOutput(f"{final_url} has no readable text.", summary="no text")
135
+
136
+ total = len(text)
137
+ if args.offset >= total:
138
+ raise ToolInputError(f"offset is past the end of the page ({total} characters).")
139
+ end = min(total, args.offset + PAGE_CHARS)
140
+ header = f"Web page: {final_url}" + (f"\nTitle: {title}" if title else "")
141
+ footer = (
142
+ f"\n[Showing characters {args.offset}-{end} of {total}. Call again with offset={end} for more.]"
143
+ if end < total
144
+ else ""
145
+ )
146
+ host = urlsplit(final_url).hostname or final_url
147
+ return ToolOutput(f"{header}\n\n{text[args.offset:end]}{footer}", summary=f"{host} ({total} chars)")
148
+
149
+
150
+ async def _assert_public(host: str) -> None:
151
+ try:
152
+ infos = await asyncio.get_running_loop().getaddrinfo(host, None, type=socket.SOCK_STREAM)
153
+ except socket.gaierror as exc:
154
+ raise ToolInputError(f"Cannot resolve {host}.") from exc
155
+ for info in infos:
156
+ ip = ipaddress.ip_address(info[4][0].split("%")[0])
157
+ if ip.version == 6 and ip.ipv4_mapped is not None:
158
+ ip = ip.ipv4_mapped
159
+ if not ip.is_global:
160
+ raise ToolInputError("That address is on a private or local network and cannot be fetched.")
161
+
162
+
163
+ def _check_url(url: str) -> str:
164
+ parts = urlsplit(url.strip())
165
+ if parts.scheme not in ("http", "https") or not parts.hostname:
166
+ raise ToolInputError("Only full http(s) URLs can be fetched.")
167
+ if parts.username or parts.password:
168
+ raise ToolInputError("URLs with credentials are not allowed.")
169
+ try:
170
+ port = parts.port
171
+ except ValueError as exc:
172
+ raise ToolInputError("The URL has an invalid port.") from exc
173
+ if port not in ALLOWED_PORTS:
174
+ raise ToolInputError("Only the standard web ports (80, 443) are allowed.")
175
+ return parts.geturl()
176
+
177
+
178
+ async def _fetch(url: str, config: DocsmindConfig) -> tuple[str, str, str]:
179
+ """-> (final url, content type, decoded body). Redirects are followed by hand so every hop is checked."""
180
+ url = _check_url(url)
181
+ headers = {"User-Agent": USER_AGENT, "Accept": "text/html,text/plain;q=0.9,*/*;q=0.1"}
182
+ async with httpx.AsyncClient(timeout=config.web_timeout_s, follow_redirects=False, headers=headers) as client:
183
+ for _ in range(MAX_REDIRECTS + 1):
184
+ await _assert_public(urlsplit(url).hostname or "")
185
+ try:
186
+ async with client.stream("GET", url) as response:
187
+ if response.is_redirect:
188
+ location = response.headers.get("location")
189
+ if not location:
190
+ raise ToolInputError("The server redirected without saying where.")
191
+ url = _check_url(urljoin(url, location))
192
+ continue
193
+ if response.status_code >= 400:
194
+ raise ToolInputError(f"The server answered HTTP {response.status_code} for {url}.")
195
+ content_type = response.headers.get("content-type", "").split(";")[0].strip().lower()
196
+ if content_type and not content_type.startswith(TEXT_TYPES):
197
+ raise ToolInputError(
198
+ f"{url} is {content_type}, which cannot be read here. Only HTML or plain text pages work."
199
+ )
200
+ data = bytearray()
201
+ async for chunk in response.aiter_bytes():
202
+ data += chunk
203
+ if len(data) > config.web_fetch_max_bytes:
204
+ break
205
+ encoding = response.encoding or "utf-8"
206
+ try:
207
+ return url, content_type or "text/html", bytes(data).decode(encoding, errors="replace")
208
+ except LookupError:
209
+ return url, content_type or "text/html", bytes(data).decode("utf-8", errors="replace")
210
+ except httpx.HTTPError as exc:
211
+ raise ToolInputError(f"Could not fetch {url}: {type(exc).__name__}.") from exc
212
+ raise ToolInputError("Too many redirects.")
213
+
214
+
215
+ _BLOCK_TAGS = {
216
+ "p", "div", "br", "li", "tr", "section", "article", "header", "footer", "blockquote", "pre",
217
+ "ul", "ol", "table", "h1", "h2", "h3", "h4", "h5", "h6", "dt", "dd", "hr",
218
+ } # fmt: skip
219
+ _SKIP_TAGS = {"script", "style", "noscript", "svg", "template"}
220
+
221
+
222
+ class _TextExtractor(HTMLParser):
223
+ """Visible text, one block per line, with links written as 'text (url)'."""
224
+
225
+ def __init__(self, base_url: str) -> None:
226
+ super().__init__(convert_charrefs=True)
227
+ self.base_url = base_url
228
+ self.title = ""
229
+ self.parts: list[str] = []
230
+ self._skip = 0
231
+ self._in_title = False
232
+ self._links: list[str | None] = []
233
+
234
+ def handle_starttag(self, tag: str, attrs: list[tuple[str, str | None]]) -> None:
235
+ if tag in _SKIP_TAGS:
236
+ self._skip += 1
237
+ elif tag == "title":
238
+ self._in_title = True
239
+ elif tag == "a":
240
+ href = dict(attrs).get("href") or ""
241
+ target = urljoin(self.base_url, href) if href and not href.startswith(("#", "javascript:", "mailto:")) else None
242
+ self._links.append(target if target and target.startswith(("http://", "https://")) else None)
243
+ if tag in _BLOCK_TAGS:
244
+ self.parts.append("\n")
245
+
246
+ def handle_endtag(self, tag: str) -> None:
247
+ if tag in _SKIP_TAGS and self._skip:
248
+ self._skip -= 1
249
+ elif tag == "title":
250
+ self._in_title = False
251
+ elif tag == "a" and self._links:
252
+ target = self._links.pop()
253
+ if target:
254
+ self.parts.append(f" ({target})")
255
+ if tag in _BLOCK_TAGS:
256
+ self.parts.append("\n")
257
+
258
+ def handle_data(self, data: str) -> None:
259
+ if self._in_title:
260
+ self.title += data
261
+ elif not self._skip:
262
+ self.parts.append(data)
263
+
264
+
265
+ def _html_to_text(html: str, base_url: str) -> tuple[str, str]:
266
+ parser = _TextExtractor(base_url)
267
+ parser.feed(html)
268
+ parser.close()
269
+ text = "".join(parser.parts)
270
+ text = re.sub(r"[ \t\r\f\v]+", " ", text)
271
+ text = re.sub(r" ?\n ?", "\n", text)
272
+ text = re.sub(r"\n{2,}", "\n", text).strip()
273
+ return re.sub(r"\s+", " ", parser.title).strip(), text
@@ -62,6 +62,13 @@ class DocsmindConfig(BaseSettings):
62
62
  agent_recent_turns: int = 4 # user/assistant pairs always kept verbatim
63
63
  agent_memory_enabled: bool = True
64
64
 
65
+ # --- web access (Change Analyzer only) ---
66
+ # Tavily API key (https://tavily.com). Unset = the `web_search` tool is not offered; `fetch_url`
67
+ # (read one public web page) needs no key and stays available.
68
+ web_search_api_key: str | None = None
69
+ web_timeout_s: float = 15.0 # per web request
70
+ web_fetch_max_bytes: int = 2_000_000 # page bytes read before giving up
71
+
65
72
  # --- ingestion ---
66
73
  chunk_size_tokens: int = 700
67
74
  chunk_overlap_tokens: int = 100
@@ -5,7 +5,9 @@ from __future__ import annotations
5
5
  import re
6
6
 
7
7
  _TOKEN_RE = re.compile(r"[^\W_]+", re.UNICODE)
8
- MAX_QUERY_TERMS = 12
8
+ # Safety bound only (keeps the tsquery a sane size for pathological input);
9
+ # normal questions never get near it, and the vector side embeds the full text.
10
+ MAX_QUERY_TERMS = 64
9
11
 
10
12
 
11
13
  def query_terms(text: str) -> list[str]: