snappy 3.3__cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (541) hide show
  1. snappy/CyOpenGL.cpython-310-aarch64-linux-gnu.so +0 -0
  2. snappy/SnapPy.cpython-310-aarch64-linux-gnu.so +0 -0
  3. snappy/SnapPy.ico +0 -0
  4. snappy/SnapPy.png +0 -0
  5. snappy/SnapPyHP.cpython-310-aarch64-linux-gnu.so +0 -0
  6. snappy/__init__.py +534 -0
  7. snappy/app.py +604 -0
  8. snappy/app_menus.py +372 -0
  9. snappy/browser.py +998 -0
  10. snappy/cache.py +25 -0
  11. snappy/canonical.py +249 -0
  12. snappy/cusps/__init__.py +280 -0
  13. snappy/cusps/cusp_area_matrix.py +98 -0
  14. snappy/cusps/cusp_areas_from_matrix.py +96 -0
  15. snappy/cusps/maximal_cusp_area_matrix.py +136 -0
  16. snappy/cusps/short_slopes_for_cusp.py +217 -0
  17. snappy/cusps/test.py +22 -0
  18. snappy/cusps/trig_cusp_area_matrix.py +63 -0
  19. snappy/database.py +454 -0
  20. snappy/db_utilities.py +79 -0
  21. snappy/decorated_isosig.py +717 -0
  22. snappy/dev/__init__.py +0 -0
  23. snappy/dev/extended_ptolemy/__init__.py +8 -0
  24. snappy/dev/extended_ptolemy/closed.py +106 -0
  25. snappy/dev/extended_ptolemy/complexVolumesClosed.py +149 -0
  26. snappy/dev/extended_ptolemy/direct.py +42 -0
  27. snappy/dev/extended_ptolemy/extended.py +406 -0
  28. snappy/dev/extended_ptolemy/giac_helper.py +43 -0
  29. snappy/dev/extended_ptolemy/giac_rur.py +129 -0
  30. snappy/dev/extended_ptolemy/gluing.py +46 -0
  31. snappy/dev/extended_ptolemy/phc_wrapper.py +220 -0
  32. snappy/dev/extended_ptolemy/printMatrices.py +70 -0
  33. snappy/dev/vericlosed/__init__.py +1 -0
  34. snappy/dev/vericlosed/computeApproxHyperbolicStructureNew.py +159 -0
  35. snappy/dev/vericlosed/computeApproxHyperbolicStructureOrb.py +90 -0
  36. snappy/dev/vericlosed/computeVerifiedHyperbolicStructure.py +111 -0
  37. snappy/dev/vericlosed/gimbalLoopFinder.py +130 -0
  38. snappy/dev/vericlosed/hyperbolicStructure.py +313 -0
  39. snappy/dev/vericlosed/krawczykCertifiedEdgeLengthsEngine.py +165 -0
  40. snappy/dev/vericlosed/oneVertexTruncatedComplex.py +122 -0
  41. snappy/dev/vericlosed/orb/__init__.py +1 -0
  42. snappy/dev/vericlosed/orb/orb_solution_for_snappea_finite_triangulation_mac +0 -0
  43. snappy/dev/vericlosed/parseVertexGramMatrixFile.py +47 -0
  44. snappy/dev/vericlosed/polishApproxHyperbolicStructure.py +61 -0
  45. snappy/dev/vericlosed/test.py +54 -0
  46. snappy/dev/vericlosed/truncatedComplex.py +176 -0
  47. snappy/dev/vericlosed/verificationError.py +58 -0
  48. snappy/dev/vericlosed/verifyHyperbolicStructureEngine.py +177 -0
  49. snappy/doc/_images/SnapPy-196.png +0 -0
  50. snappy/doc/_images/m004_paper_plane_on_systole.jpg +0 -0
  51. snappy/doc/_images/m125_paper_plane.jpg +0 -0
  52. snappy/doc/_images/mac.png +0 -0
  53. snappy/doc/_images/o9_00000_systole_paper_plane.jpg +0 -0
  54. snappy/doc/_images/o9_00000_systole_paper_plane_closer.jpg +0 -0
  55. snappy/doc/_images/plink-action.png +0 -0
  56. snappy/doc/_images/ubuntu.png +0 -0
  57. snappy/doc/_images/win7.png +0 -0
  58. snappy/doc/_sources/additional_classes.rst.txt +40 -0
  59. snappy/doc/_sources/bugs.rst.txt +14 -0
  60. snappy/doc/_sources/censuses.rst.txt +52 -0
  61. snappy/doc/_sources/credits.rst.txt +81 -0
  62. snappy/doc/_sources/development.rst.txt +261 -0
  63. snappy/doc/_sources/index.rst.txt +215 -0
  64. snappy/doc/_sources/installing.rst.txt +249 -0
  65. snappy/doc/_sources/manifold.rst.txt +6 -0
  66. snappy/doc/_sources/manifoldhp.rst.txt +46 -0
  67. snappy/doc/_sources/news.rst.txt +425 -0
  68. snappy/doc/_sources/other.rst.txt +25 -0
  69. snappy/doc/_sources/platonic_census.rst.txt +20 -0
  70. snappy/doc/_sources/plink.rst.txt +102 -0
  71. snappy/doc/_sources/ptolemy.rst.txt +66 -0
  72. snappy/doc/_sources/ptolemy_classes.rst.txt +42 -0
  73. snappy/doc/_sources/ptolemy_examples1.rst.txt +298 -0
  74. snappy/doc/_sources/ptolemy_examples2.rst.txt +363 -0
  75. snappy/doc/_sources/ptolemy_examples3.rst.txt +301 -0
  76. snappy/doc/_sources/ptolemy_examples4.rst.txt +61 -0
  77. snappy/doc/_sources/ptolemy_prelim.rst.txt +105 -0
  78. snappy/doc/_sources/screenshots.rst.txt +21 -0
  79. snappy/doc/_sources/snap.rst.txt +87 -0
  80. snappy/doc/_sources/snappy.rst.txt +28 -0
  81. snappy/doc/_sources/spherogram.rst.txt +103 -0
  82. snappy/doc/_sources/todo.rst.txt +47 -0
  83. snappy/doc/_sources/triangulation.rst.txt +11 -0
  84. snappy/doc/_sources/tutorial.rst.txt +49 -0
  85. snappy/doc/_sources/verify.rst.txt +210 -0
  86. snappy/doc/_sources/verify_internals.rst.txt +79 -0
  87. snappy/doc/_static/SnapPy-horizontal-128.png +0 -0
  88. snappy/doc/_static/SnapPy.ico +0 -0
  89. snappy/doc/_static/_sphinx_javascript_frameworks_compat.js +123 -0
  90. snappy/doc/_static/basic.css +906 -0
  91. snappy/doc/_static/css/badge_only.css +1 -0
  92. snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff +0 -0
  93. snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff2 +0 -0
  94. snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff +0 -0
  95. snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff2 +0 -0
  96. snappy/doc/_static/css/fonts/fontawesome-webfont.eot +0 -0
  97. snappy/doc/_static/css/fonts/fontawesome-webfont.svg +2671 -0
  98. snappy/doc/_static/css/fonts/fontawesome-webfont.ttf +0 -0
  99. snappy/doc/_static/css/fonts/fontawesome-webfont.woff +0 -0
  100. snappy/doc/_static/css/fonts/fontawesome-webfont.woff2 +0 -0
  101. snappy/doc/_static/css/fonts/lato-bold-italic.woff +0 -0
  102. snappy/doc/_static/css/fonts/lato-bold-italic.woff2 +0 -0
  103. snappy/doc/_static/css/fonts/lato-bold.woff +0 -0
  104. snappy/doc/_static/css/fonts/lato-bold.woff2 +0 -0
  105. snappy/doc/_static/css/fonts/lato-normal-italic.woff +0 -0
  106. snappy/doc/_static/css/fonts/lato-normal-italic.woff2 +0 -0
  107. snappy/doc/_static/css/fonts/lato-normal.woff +0 -0
  108. snappy/doc/_static/css/fonts/lato-normal.woff2 +0 -0
  109. snappy/doc/_static/css/theme.css +4 -0
  110. snappy/doc/_static/doctools.js +149 -0
  111. snappy/doc/_static/documentation_options.js +13 -0
  112. snappy/doc/_static/file.png +0 -0
  113. snappy/doc/_static/fonts/Lato/lato-bold.eot +0 -0
  114. snappy/doc/_static/fonts/Lato/lato-bold.ttf +0 -0
  115. snappy/doc/_static/fonts/Lato/lato-bold.woff +0 -0
  116. snappy/doc/_static/fonts/Lato/lato-bold.woff2 +0 -0
  117. snappy/doc/_static/fonts/Lato/lato-bolditalic.eot +0 -0
  118. snappy/doc/_static/fonts/Lato/lato-bolditalic.ttf +0 -0
  119. snappy/doc/_static/fonts/Lato/lato-bolditalic.woff +0 -0
  120. snappy/doc/_static/fonts/Lato/lato-bolditalic.woff2 +0 -0
  121. snappy/doc/_static/fonts/Lato/lato-italic.eot +0 -0
  122. snappy/doc/_static/fonts/Lato/lato-italic.ttf +0 -0
  123. snappy/doc/_static/fonts/Lato/lato-italic.woff +0 -0
  124. snappy/doc/_static/fonts/Lato/lato-italic.woff2 +0 -0
  125. snappy/doc/_static/fonts/Lato/lato-regular.eot +0 -0
  126. snappy/doc/_static/fonts/Lato/lato-regular.ttf +0 -0
  127. snappy/doc/_static/fonts/Lato/lato-regular.woff +0 -0
  128. snappy/doc/_static/fonts/Lato/lato-regular.woff2 +0 -0
  129. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot +0 -0
  130. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf +0 -0
  131. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff +0 -0
  132. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 +0 -0
  133. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot +0 -0
  134. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf +0 -0
  135. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff +0 -0
  136. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 +0 -0
  137. snappy/doc/_static/jquery.js +2 -0
  138. snappy/doc/_static/js/badge_only.js +1 -0
  139. snappy/doc/_static/js/theme.js +1 -0
  140. snappy/doc/_static/js/versions.js +228 -0
  141. snappy/doc/_static/language_data.js +192 -0
  142. snappy/doc/_static/minus.png +0 -0
  143. snappy/doc/_static/plus.png +0 -0
  144. snappy/doc/_static/pygments.css +75 -0
  145. snappy/doc/_static/searchtools.js +635 -0
  146. snappy/doc/_static/snappy_furo.css +33 -0
  147. snappy/doc/_static/snappy_sphinx_rtd_theme.css +42 -0
  148. snappy/doc/_static/sphinx_highlight.js +154 -0
  149. snappy/doc/additional_classes.html +1500 -0
  150. snappy/doc/bugs.html +132 -0
  151. snappy/doc/censuses.html +453 -0
  152. snappy/doc/credits.html +184 -0
  153. snappy/doc/development.html +385 -0
  154. snappy/doc/doc-latest/additional_classes.html +1500 -0
  155. snappy/doc/doc-latest/bugs.html +132 -0
  156. snappy/doc/doc-latest/censuses.html +453 -0
  157. snappy/doc/doc-latest/credits.html +184 -0
  158. snappy/doc/doc-latest/development.html +385 -0
  159. snappy/doc/doc-latest/genindex.html +1349 -0
  160. snappy/doc/doc-latest/index.html +287 -0
  161. snappy/doc/doc-latest/installing.html +346 -0
  162. snappy/doc/doc-latest/manifold.html +3632 -0
  163. snappy/doc/doc-latest/manifoldhp.html +180 -0
  164. snappy/doc/doc-latest/news.html +438 -0
  165. snappy/doc/doc-latest/objects.inv +0 -0
  166. snappy/doc/doc-latest/other.html +160 -0
  167. snappy/doc/doc-latest/platonic_census.html +376 -0
  168. snappy/doc/doc-latest/plink.html +210 -0
  169. snappy/doc/doc-latest/ptolemy.html +253 -0
  170. snappy/doc/doc-latest/ptolemy_classes.html +1144 -0
  171. snappy/doc/doc-latest/ptolemy_examples1.html +409 -0
  172. snappy/doc/doc-latest/ptolemy_examples2.html +471 -0
  173. snappy/doc/doc-latest/ptolemy_examples3.html +414 -0
  174. snappy/doc/doc-latest/ptolemy_examples4.html +195 -0
  175. snappy/doc/doc-latest/ptolemy_prelim.html +248 -0
  176. snappy/doc/doc-latest/py-modindex.html +165 -0
  177. snappy/doc/doc-latest/screenshots.html +141 -0
  178. snappy/doc/doc-latest/search.html +135 -0
  179. snappy/doc/doc-latest/searchindex.js +1 -0
  180. snappy/doc/doc-latest/snap.html +202 -0
  181. snappy/doc/doc-latest/snappy.html +181 -0
  182. snappy/doc/doc-latest/spherogram.html +1346 -0
  183. snappy/doc/doc-latest/todo.html +166 -0
  184. snappy/doc/doc-latest/triangulation.html +1676 -0
  185. snappy/doc/doc-latest/tutorial.html +159 -0
  186. snappy/doc/doc-latest/verify.html +330 -0
  187. snappy/doc/doc-latest/verify_internals.html +1235 -0
  188. snappy/doc/genindex.html +1349 -0
  189. snappy/doc/index.html +287 -0
  190. snappy/doc/installing.html +346 -0
  191. snappy/doc/manifold.html +3632 -0
  192. snappy/doc/manifoldhp.html +180 -0
  193. snappy/doc/news.html +438 -0
  194. snappy/doc/objects.inv +0 -0
  195. snappy/doc/other.html +160 -0
  196. snappy/doc/platonic_census.html +376 -0
  197. snappy/doc/plink.html +210 -0
  198. snappy/doc/ptolemy.html +253 -0
  199. snappy/doc/ptolemy_classes.html +1144 -0
  200. snappy/doc/ptolemy_examples1.html +409 -0
  201. snappy/doc/ptolemy_examples2.html +471 -0
  202. snappy/doc/ptolemy_examples3.html +414 -0
  203. snappy/doc/ptolemy_examples4.html +195 -0
  204. snappy/doc/ptolemy_prelim.html +248 -0
  205. snappy/doc/py-modindex.html +165 -0
  206. snappy/doc/screenshots.html +141 -0
  207. snappy/doc/search.html +135 -0
  208. snappy/doc/searchindex.js +1 -0
  209. snappy/doc/snap.html +202 -0
  210. snappy/doc/snappy.html +181 -0
  211. snappy/doc/spherogram.html +1346 -0
  212. snappy/doc/todo.html +166 -0
  213. snappy/doc/triangulation.html +1676 -0
  214. snappy/doc/tutorial.html +159 -0
  215. snappy/doc/verify.html +330 -0
  216. snappy/doc/verify_internals.html +1235 -0
  217. snappy/drilling/__init__.py +456 -0
  218. snappy/drilling/barycentric.py +103 -0
  219. snappy/drilling/constants.py +5 -0
  220. snappy/drilling/crush.py +270 -0
  221. snappy/drilling/cusps.py +125 -0
  222. snappy/drilling/debug.py +242 -0
  223. snappy/drilling/epsilons.py +6 -0
  224. snappy/drilling/exceptions.py +55 -0
  225. snappy/drilling/moves.py +620 -0
  226. snappy/drilling/peripheral_curves.py +210 -0
  227. snappy/drilling/perturb.py +188 -0
  228. snappy/drilling/shorten.py +36 -0
  229. snappy/drilling/subdivide.py +274 -0
  230. snappy/drilling/test.py +23 -0
  231. snappy/drilling/test_cases.py +132 -0
  232. snappy/drilling/tracing.py +351 -0
  233. snappy/exceptions.py +26 -0
  234. snappy/export_stl.py +120 -0
  235. snappy/exterior_to_link/__init__.py +2 -0
  236. snappy/exterior_to_link/barycentric_geometry.py +463 -0
  237. snappy/exterior_to_link/exceptions.py +6 -0
  238. snappy/exterior_to_link/geodesic_map.json +14408 -0
  239. snappy/exterior_to_link/hyp_utils.py +112 -0
  240. snappy/exterior_to_link/link_projection.py +323 -0
  241. snappy/exterior_to_link/main.py +198 -0
  242. snappy/exterior_to_link/mcomplex_with_expansion.py +261 -0
  243. snappy/exterior_to_link/mcomplex_with_link.py +687 -0
  244. snappy/exterior_to_link/mcomplex_with_memory.py +162 -0
  245. snappy/exterior_to_link/pl_utils.py +491 -0
  246. snappy/exterior_to_link/put_in_S3.py +156 -0
  247. snappy/exterior_to_link/rational_linear_algebra.py +130 -0
  248. snappy/exterior_to_link/rational_linear_algebra_wrapped.py +135 -0
  249. snappy/exterior_to_link/simplify_to_base_tri.py +114 -0
  250. snappy/exterior_to_link/stored_moves.py +475 -0
  251. snappy/exterior_to_link/test.py +31 -0
  252. snappy/filedialog.py +28 -0
  253. snappy/geometric_structure/__init__.py +212 -0
  254. snappy/geometric_structure/cusp_neighborhood/__init__.py +3 -0
  255. snappy/geometric_structure/cusp_neighborhood/complex_cusp_cross_section.py +691 -0
  256. snappy/geometric_structure/cusp_neighborhood/cusp_cross_section_base.py +480 -0
  257. snappy/geometric_structure/cusp_neighborhood/exceptions.py +41 -0
  258. snappy/geometric_structure/cusp_neighborhood/real_cusp_cross_section.py +294 -0
  259. snappy/geometric_structure/cusp_neighborhood/tiles_for_cusp_neighborhood.py +156 -0
  260. snappy/geometric_structure/cusp_neighborhood/vertices.py +35 -0
  261. snappy/geometric_structure/geodesic/__init__.py +0 -0
  262. snappy/geometric_structure/geodesic/add_core_curves.py +152 -0
  263. snappy/geometric_structure/geodesic/avoid_core_curves.py +369 -0
  264. snappy/geometric_structure/geodesic/canonical_representatives.py +52 -0
  265. snappy/geometric_structure/geodesic/check_away_from_core_curve.py +60 -0
  266. snappy/geometric_structure/geodesic/constants.py +6 -0
  267. snappy/geometric_structure/geodesic/exceptions.py +22 -0
  268. snappy/geometric_structure/geodesic/fixed_points.py +106 -0
  269. snappy/geometric_structure/geodesic/geodesic_start_point_info.py +435 -0
  270. snappy/geometric_structure/geodesic/graph_trace_helper.py +67 -0
  271. snappy/geometric_structure/geodesic/line.py +30 -0
  272. snappy/geometric_structure/geodesic/multiplicity.py +127 -0
  273. snappy/geometric_structure/geodesic/tiles_for_geodesic.py +128 -0
  274. snappy/geometric_structure/test.py +22 -0
  275. snappy/gui.py +121 -0
  276. snappy/horoviewer.py +443 -0
  277. snappy/hyperboloid/__init__.py +212 -0
  278. snappy/hyperboloid/distances.py +259 -0
  279. snappy/hyperboloid/horoball.py +19 -0
  280. snappy/hyperboloid/line.py +35 -0
  281. snappy/hyperboloid/point.py +9 -0
  282. snappy/hyperboloid/triangle.py +29 -0
  283. snappy/info_icon.gif +0 -0
  284. snappy/infowindow.py +65 -0
  285. snappy/isometry_signature.py +389 -0
  286. snappy/len_spec/__init__.py +609 -0
  287. snappy/len_spec/geodesic_info.py +129 -0
  288. snappy/len_spec/geodesic_key_info_dict.py +116 -0
  289. snappy/len_spec/geodesic_piece.py +146 -0
  290. snappy/len_spec/geometric_structure.py +182 -0
  291. snappy/len_spec/geometry.py +136 -0
  292. snappy/len_spec/length_spectrum_geodesic_info.py +185 -0
  293. snappy/len_spec/spine.py +128 -0
  294. snappy/len_spec/test.py +24 -0
  295. snappy/len_spec/test_cases.py +69 -0
  296. snappy/len_spec/tile.py +276 -0
  297. snappy/len_spec/word.py +86 -0
  298. snappy/manifolds/HTWKnots/alternating.gz +0 -0
  299. snappy/manifolds/HTWKnots/nonalternating.gz +0 -0
  300. snappy/manifolds/__init__.py +3 -0
  301. snappy/margulis/__init__.py +332 -0
  302. snappy/margulis/cusp_neighborhood_neighborhood.py +66 -0
  303. snappy/margulis/geodesic_neighborhood.py +152 -0
  304. snappy/margulis/margulis_info.py +21 -0
  305. snappy/margulis/mu_from_neighborhood_pair.py +175 -0
  306. snappy/margulis/neighborhood.py +29 -0
  307. snappy/margulis/test.py +22 -0
  308. snappy/math_basics.py +187 -0
  309. snappy/matrix.py +525 -0
  310. snappy/number.py +657 -0
  311. snappy/numeric_output_checker.py +345 -0
  312. snappy/pari.py +41 -0
  313. snappy/phone_home.py +57 -0
  314. snappy/polyviewer.py +259 -0
  315. snappy/ptolemy/__init__.py +17 -0
  316. snappy/ptolemy/component.py +103 -0
  317. snappy/ptolemy/coordinates.py +2290 -0
  318. snappy/ptolemy/fieldExtensions.py +153 -0
  319. snappy/ptolemy/findLoops.py +473 -0
  320. snappy/ptolemy/geometricRep.py +59 -0
  321. snappy/ptolemy/homology.py +165 -0
  322. snappy/ptolemy/magma/default.magma_template +229 -0
  323. snappy/ptolemy/magma/radicalsOfPrimaryDecomposition.magma_template +79 -0
  324. snappy/ptolemy/manifoldMethods.py +395 -0
  325. snappy/ptolemy/matrix.py +350 -0
  326. snappy/ptolemy/numericalSolutionsToGroebnerBasis.py +113 -0
  327. snappy/ptolemy/polynomial.py +856 -0
  328. snappy/ptolemy/processComponents.py +173 -0
  329. snappy/ptolemy/processFileBase.py +247 -0
  330. snappy/ptolemy/processFileDispatch.py +46 -0
  331. snappy/ptolemy/processMagmaFile.py +392 -0
  332. snappy/ptolemy/processRurFile.py +150 -0
  333. snappy/ptolemy/ptolemyGeneralizedObstructionClass.py +102 -0
  334. snappy/ptolemy/ptolemyObstructionClass.py +64 -0
  335. snappy/ptolemy/ptolemyVariety.py +995 -0
  336. snappy/ptolemy/ptolemyVarietyPrimeIdealGroebnerBasis.py +140 -0
  337. snappy/ptolemy/reginaWrapper.py +698 -0
  338. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
  339. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
  340. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
  341. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
  342. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
  343. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
  344. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
  345. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
  346. snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
  347. snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
  348. snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c0.magma_out.bz2 +0 -0
  349. snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
  350. snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
  351. snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c1.magma_out.bz2 +0 -0
  352. snappy/ptolemy/rur.py +545 -0
  353. snappy/ptolemy/solutionsToPrimeIdealGroebnerBasis.py +277 -0
  354. snappy/ptolemy/test.py +1126 -0
  355. snappy/ptolemy/testing_files/3_1__sl2_c0.magma_out.bz2 +0 -0
  356. snappy/ptolemy/testing_files/3_1__sl2_c1.magma_out.bz2 +0 -0
  357. snappy/ptolemy/testing_files/4_1__sl2_c0.magma_out.bz2 +0 -0
  358. snappy/ptolemy/testing_files/4_1__sl2_c1.magma_out.bz2 +0 -0
  359. snappy/ptolemy/testing_files/4_1__sl3_c0.magma_out.bz2 +0 -0
  360. snappy/ptolemy/testing_files/4_1__sl4_c0.magma_out.bz2 +0 -0
  361. snappy/ptolemy/testing_files/4_1__sl4_c1.magma_out.bz2 +0 -0
  362. snappy/ptolemy/testing_files/5_2__sl2_c0.magma_out.bz2 +0 -0
  363. snappy/ptolemy/testing_files/5_2__sl2_c1.magma_out.bz2 +0 -0
  364. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
  365. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
  366. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
  367. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
  368. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
  369. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
  370. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
  371. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
  372. snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c0.magma_out +95 -0
  373. snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c1.magma_out +95 -0
  374. snappy/ptolemy/testing_files/m015__sl3_c0.magma_out.bz2 +0 -0
  375. snappy/ptolemy/testing_files/m135__sl2_c0.magma_out.bz2 +0 -0
  376. snappy/ptolemy/testing_files/m135__sl2_c1.magma_out.bz2 +0 -0
  377. snappy/ptolemy/testing_files/m135__sl2_c2.magma_out.bz2 +0 -0
  378. snappy/ptolemy/testing_files/m135__sl2_c3.magma_out.bz2 +0 -0
  379. snappy/ptolemy/testing_files/m135__sl2_c4.magma_out.bz2 +0 -0
  380. snappy/ptolemy/testing_files/m135__sl2_c5.magma_out.bz2 +0 -0
  381. snappy/ptolemy/testing_files/m135__sl2_c6.magma_out.bz2 +0 -0
  382. snappy/ptolemy/testing_files/m135__sl2_c7.magma_out.bz2 +0 -0
  383. snappy/ptolemy/testing_files/s000__sl2_c0.magma_out.bz2 +0 -0
  384. snappy/ptolemy/testing_files/s000__sl2_c1.magma_out.bz2 +0 -0
  385. snappy/ptolemy/testing_files/t00000__sl2_c0.magma_out.bz2 +0 -0
  386. snappy/ptolemy/testing_files/t00000__sl2_c1.magma_out.bz2 +0 -0
  387. snappy/ptolemy/testing_files/v0000__sl2_c0.magma_out.bz2 +0 -0
  388. snappy/ptolemy/testing_files/v0000__sl2_c1.magma_out.bz2 +0 -0
  389. snappy/ptolemy/testing_files/v0000__sl2_c2.magma_out.bz2 +0 -0
  390. snappy/ptolemy/testing_files/v0000__sl2_c3.magma_out.bz2 +0 -0
  391. snappy/ptolemy/testing_files_generalized/m003__sl2_c0.magma_out.bz2 +0 -0
  392. snappy/ptolemy/testing_files_generalized/m003__sl2_c1.magma_out.bz2 +0 -0
  393. snappy/ptolemy/testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
  394. snappy/ptolemy/testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
  395. snappy/ptolemy/testing_files_generalized/m004__sl2_c0.magma_out.bz2 +0 -0
  396. snappy/ptolemy/testing_files_generalized/m004__sl2_c1.magma_out.bz2 +0 -0
  397. snappy/ptolemy/testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
  398. snappy/ptolemy/testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
  399. snappy/ptolemy/testing_files_rur/m052__sl3_c0.rur.bz2 +0 -0
  400. snappy/ptolemy/utilities.py +236 -0
  401. snappy/raytracing/__init__.py +64 -0
  402. snappy/raytracing/additional_horospheres.py +64 -0
  403. snappy/raytracing/additional_len_spec_choices.py +63 -0
  404. snappy/raytracing/cohomology_fractal.py +197 -0
  405. snappy/raytracing/eyeball.py +124 -0
  406. snappy/raytracing/finite_raytracing_data.py +237 -0
  407. snappy/raytracing/finite_viewer.py +590 -0
  408. snappy/raytracing/geodesic_tube_info.py +174 -0
  409. snappy/raytracing/geodesics.py +246 -0
  410. snappy/raytracing/geodesics_window.py +258 -0
  411. snappy/raytracing/gui_utilities.py +293 -0
  412. snappy/raytracing/hyperboloid_navigation.py +556 -0
  413. snappy/raytracing/hyperboloid_utilities.py +234 -0
  414. snappy/raytracing/ideal_raytracing_data.py +592 -0
  415. snappy/raytracing/inside_viewer.py +974 -0
  416. snappy/raytracing/pack.py +22 -0
  417. snappy/raytracing/raytracing_data.py +126 -0
  418. snappy/raytracing/raytracing_view.py +454 -0
  419. snappy/raytracing/shaders/Eye.png +0 -0
  420. snappy/raytracing/shaders/NonGeometric.png +0 -0
  421. snappy/raytracing/shaders/__init__.py +101 -0
  422. snappy/raytracing/shaders/fragment.glsl +1744 -0
  423. snappy/raytracing/test.py +29 -0
  424. snappy/raytracing/tooltip.py +146 -0
  425. snappy/raytracing/upper_halfspace_utilities.py +98 -0
  426. snappy/raytracing/view_scale_controller.py +98 -0
  427. snappy/raytracing/zoom_slider/__init__.py +263 -0
  428. snappy/raytracing/zoom_slider/inward.png +0 -0
  429. snappy/raytracing/zoom_slider/inward18.png +0 -0
  430. snappy/raytracing/zoom_slider/outward.png +0 -0
  431. snappy/raytracing/zoom_slider/outward18.png +0 -0
  432. snappy/raytracing/zoom_slider/test.py +20 -0
  433. snappy/sage_helper.py +119 -0
  434. snappy/settings.py +407 -0
  435. snappy/shell.py +53 -0
  436. snappy/snap/__init__.py +117 -0
  437. snappy/snap/character_varieties.py +375 -0
  438. snappy/snap/find_field.py +372 -0
  439. snappy/snap/fox_milnor.py +271 -0
  440. snappy/snap/fundamental_polyhedron.py +569 -0
  441. snappy/snap/generators.py +39 -0
  442. snappy/snap/interval_reps.py +81 -0
  443. snappy/snap/kernel_structures.py +128 -0
  444. snappy/snap/mcomplex_base.py +18 -0
  445. snappy/snap/nsagetools.py +716 -0
  446. snappy/snap/peripheral/__init__.py +1 -0
  447. snappy/snap/peripheral/dual_cellulation.py +219 -0
  448. snappy/snap/peripheral/link.py +127 -0
  449. snappy/snap/peripheral/peripheral.py +159 -0
  450. snappy/snap/peripheral/surface.py +522 -0
  451. snappy/snap/peripheral/test.py +35 -0
  452. snappy/snap/polished_reps.py +335 -0
  453. snappy/snap/shapes.py +152 -0
  454. snappy/snap/slice_obs_HKL/__init__.py +194 -0
  455. snappy/snap/slice_obs_HKL/basics.py +236 -0
  456. snappy/snap/slice_obs_HKL/direct.py +217 -0
  457. snappy/snap/slice_obs_HKL/poly_norm.py +212 -0
  458. snappy/snap/slice_obs_HKL/rep_theory.py +424 -0
  459. snappy/snap/t3mlite/__init__.py +2 -0
  460. snappy/snap/t3mlite/arrow.py +243 -0
  461. snappy/snap/t3mlite/corner.py +22 -0
  462. snappy/snap/t3mlite/edge.py +172 -0
  463. snappy/snap/t3mlite/face.py +37 -0
  464. snappy/snap/t3mlite/files.py +211 -0
  465. snappy/snap/t3mlite/homology.py +53 -0
  466. snappy/snap/t3mlite/linalg.py +419 -0
  467. snappy/snap/t3mlite/mcomplex.py +1499 -0
  468. snappy/snap/t3mlite/perm4.py +320 -0
  469. snappy/snap/t3mlite/setup.py +12 -0
  470. snappy/snap/t3mlite/simplex.py +199 -0
  471. snappy/snap/t3mlite/spun.py +297 -0
  472. snappy/snap/t3mlite/surface.py +519 -0
  473. snappy/snap/t3mlite/test.py +20 -0
  474. snappy/snap/t3mlite/test_vs_regina.py +86 -0
  475. snappy/snap/t3mlite/tetrahedron.py +109 -0
  476. snappy/snap/t3mlite/vertex.py +42 -0
  477. snappy/snap/test.py +139 -0
  478. snappy/snap/utilities.py +288 -0
  479. snappy/test.py +213 -0
  480. snappy/test_cases.py +263 -0
  481. snappy/testing.py +131 -0
  482. snappy/tiling/__init__.py +2 -0
  483. snappy/tiling/dict_based_set.py +79 -0
  484. snappy/tiling/floor.py +49 -0
  485. snappy/tiling/hyperboloid_dict.py +54 -0
  486. snappy/tiling/iter_utils.py +78 -0
  487. snappy/tiling/lifted_tetrahedron.py +22 -0
  488. snappy/tiling/lifted_tetrahedron_set.py +54 -0
  489. snappy/tiling/quotient_dict.py +70 -0
  490. snappy/tiling/real_hash_dict.py +164 -0
  491. snappy/tiling/test.py +23 -0
  492. snappy/tiling/tile.py +224 -0
  493. snappy/tiling/triangle.py +33 -0
  494. snappy/tkterminal.py +920 -0
  495. snappy/twister/__init__.py +20 -0
  496. snappy/twister/main.py +646 -0
  497. snappy/twister/surfaces/S_0_1 +3 -0
  498. snappy/twister/surfaces/S_0_2 +3 -0
  499. snappy/twister/surfaces/S_0_4 +7 -0
  500. snappy/twister/surfaces/S_0_4_Lantern +8 -0
  501. snappy/twister/surfaces/S_1 +3 -0
  502. snappy/twister/surfaces/S_1_1 +4 -0
  503. snappy/twister/surfaces/S_1_2 +5 -0
  504. snappy/twister/surfaces/S_1_2_5 +6 -0
  505. snappy/twister/surfaces/S_2 +6 -0
  506. snappy/twister/surfaces/S_2_1 +8 -0
  507. snappy/twister/surfaces/S_2_heeg +10 -0
  508. snappy/twister/surfaces/S_3 +8 -0
  509. snappy/twister/surfaces/S_3_1 +10 -0
  510. snappy/twister/surfaces/S_4_1 +12 -0
  511. snappy/twister/surfaces/S_5_1 +14 -0
  512. snappy/twister/surfaces/heeg_fig8 +9 -0
  513. snappy/twister/twister_core.cpython-310-aarch64-linux-gnu.so +0 -0
  514. snappy/upper_halfspace/__init__.py +146 -0
  515. snappy/upper_halfspace/ideal_point.py +29 -0
  516. snappy/verify/__init__.py +13 -0
  517. snappy/verify/canonical.py +542 -0
  518. snappy/verify/complex_volume/__init__.py +18 -0
  519. snappy/verify/complex_volume/adjust_torsion.py +86 -0
  520. snappy/verify/complex_volume/closed.py +168 -0
  521. snappy/verify/complex_volume/compute_ptolemys.py +90 -0
  522. snappy/verify/complex_volume/cusped.py +56 -0
  523. snappy/verify/complex_volume/extended_bloch.py +201 -0
  524. snappy/verify/cusp_translations.py +85 -0
  525. snappy/verify/edge_equations.py +80 -0
  526. snappy/verify/exceptions.py +254 -0
  527. snappy/verify/hyperbolicity.py +224 -0
  528. snappy/verify/interval_newton_shapes_engine.py +523 -0
  529. snappy/verify/interval_tree.py +400 -0
  530. snappy/verify/krawczyk_shapes_engine.py +518 -0
  531. snappy/verify/real_algebra.py +286 -0
  532. snappy/verify/shapes.py +25 -0
  533. snappy/verify/square_extensions.py +1005 -0
  534. snappy/verify/test.py +72 -0
  535. snappy/verify/volume.py +128 -0
  536. snappy/version.py +2 -0
  537. snappy-3.3.dist-info/METADATA +58 -0
  538. snappy-3.3.dist-info/RECORD +541 -0
  539. snappy-3.3.dist-info/WHEEL +6 -0
  540. snappy-3.3.dist-info/entry_points.txt +2 -0
  541. snappy-3.3.dist-info/top_level.txt +28 -0
snappy/tkterminal.py ADDED
@@ -0,0 +1,920 @@
1
+ # -*- coding: utf-8 -*-
2
+ import os
3
+ import sys
4
+ import re
5
+ from urllib.request import pathname2url
6
+ import tkinter as Tk_
7
+ from tkinter import ttk
8
+ from tkinter.font import Font
9
+ from tkinter.font import families as font_families
10
+ from tkinter.messagebox import askyesno
11
+ from IPython.utils import io
12
+
13
+ debug_Tk = False
14
+ ansi_seqs = re.compile(r'(?:\x01*\x1b\[((?:[0-9]*;)*[0-9]*.)\x02*)*([^\x01\x1b]*)',
15
+ re.MULTILINE)
16
+ ansi_colors = {'0;30m': 'Black',
17
+ '0;31m': 'Red',
18
+ '0;32m': 'Green',
19
+ '0;33m': 'Brown',
20
+ '0;34m': 'Blue',
21
+ '0;35m': 'Purple',
22
+ '0;36m': 'Cyan',
23
+ '0;37m': 'LightGray',
24
+ '1;30m': 'Black', # 'DarkGray',
25
+ '1;31m': 'DarkRed',
26
+ '1;32m': 'SeaGreen',
27
+ '1;33m': 'Yellow',
28
+ '1;34m': 'LightBlue',
29
+ '1;35m': 'MediumPurple',
30
+ '1;36m': 'LightCyan',
31
+ '1;37m': 'White'}
32
+ delims = re.compile(r'[\s\[\]\{\}\(\)\+\-\=\'`~!@#\$\^\&\*]+')
33
+
34
+
35
+ class FontChoice:
36
+ def __init__(self, family, size, weight, slant):
37
+ self.family = family
38
+ self.size = size
39
+ self.weight = weight
40
+ self.slant = slant
41
+ self.rest = f'{self.weight} {self.slant}'
42
+
43
+ def as_tuple(self):
44
+ size = self.size
45
+ if sys.platform == 'darwin' and Tk_.TkVersion >= 9.0:
46
+ size = int(size/1.3)
47
+ return (self.family, size, self.rest)
48
+
49
+ def __repr__(self):
50
+ return 'FontChoice' + repr((self.family, self.size, self.weight, self.slant))
51
+
52
+ def bold(self):
53
+ return FontChoice(self.family, self.size, 'bold', self.slant)
54
+
55
+
56
+ def default_terminal_font():
57
+ size = 13 if sys.platform == 'darwin' else 11
58
+ family = Font(font='TkFixedFont').actual()['family']
59
+ if sys.platform == 'win32':
60
+ # Default is Courier New which is ugly and appears blurry.
61
+ available = font_families()
62
+ for better in ['Consolas', 'Cascadia Mono SemiLight']:
63
+ if better in available:
64
+ family = better
65
+
66
+ return FontChoice(family, size, 'normal', 'roman')
67
+
68
+
69
+ class Tk(Tk_.Tk):
70
+ def __init__(self, error_handler=None):
71
+ Tk_.Tk.__init__(self, className='snappy')
72
+ # Tkinter ignores exceptions raised by callbacks, but
73
+ # calls this function to report their occurrence.
74
+ if error_handler:
75
+ self.report_callback_exception = error_handler
76
+
77
+
78
+ class TkTerminalBase:
79
+ """
80
+ A Tkinter terminal window that runs an IPython shell. This class
81
+ supports the IOStream interface, and can function as a replacement
82
+ for sys.stdout / sys.stderr.
83
+ """
84
+ def __init__(self, shell, name='TkTerm'):
85
+ if debug_Tk:
86
+ self.window = window = Tk()
87
+ io.stdout = sys.stdout = self
88
+ else:
89
+ self.window = window = Tk(self.report_callback_exception)
90
+ io.stdout = io.stderr = sys.stdout = sys.stderr = self
91
+ self._input_buffer = ''
92
+ self._current_indent = 0
93
+ # Global Tk options
94
+ window.option_add('*Menu.tearOff', 0)
95
+ window.title(name)
96
+ window.protocol("WM_DELETE_WINDOW", self.close)
97
+ self.frame = frame = Tk_.Frame(window)
98
+ self.text = text = Tk_.Text(frame,
99
+ width=85,
100
+ height=24,
101
+ foreground='Black',
102
+ borderwidth=3,
103
+ background='#ec0fffec0',
104
+ insertbackground='#ff0000',
105
+ highlightthickness=0,
106
+ relief=Tk_.FLAT
107
+ )
108
+ self.set_font(default_terminal_font())
109
+ self.scroller = scroller = Tk_.Scrollbar(frame, command=text.yview)
110
+ text.config(yscrollcommand=scroller.set)
111
+ scroller.pack(side=Tk_.RIGHT, fill=Tk_.Y, pady=10)
112
+ text.pack(fill=Tk_.BOTH, expand=Tk_.YES)
113
+ frame.pack(fill=Tk_.BOTH, expand=Tk_.YES)
114
+ text.focus_set()
115
+ window.bind('<FocusIn>', lambda event=None: text.focus_set())
116
+ text.bind('<Control-c>', self.handle_control_c)
117
+ text.bind('<KeyPress>', self.handle_keypress)
118
+ text.bind('<KeyRelease>', self.handle_keyrelease)
119
+ text.bind('<Return>', self.handle_return)
120
+ text.bind('<Shift-Return>', self.handle_shift_return)
121
+ text.bind('<BackSpace>', self.handle_backspace)
122
+ text.bind('<Delete>', self.handle_backspace)
123
+ text.bind('<Tab>', self.handle_tab)
124
+ text.bind('<Up>', self.handle_up)
125
+ text.bind('<Down>', self.handle_down)
126
+ text.bind('<Home>', self.go_to_beginning)
127
+ text.bind('<<Cut>>', self.protect_text)
128
+ text.bind('<<Copy>>', self.edit_copy)
129
+ text.bind('<<Paste>>', self.edit_paste)
130
+ text.bind('<<Clear>>', self.protect_text)
131
+ text.bind('<ButtonRelease>', self.mouse_up)
132
+ if sys.platform != 'darwin':
133
+ text.bind_all('<ButtonPress-2>', self.middle_mouse_down)
134
+ text.bind_all('<ButtonRelease-2>', self.middle_mouse_up)
135
+ text.bind('<Button-3>', lambda event:'break')
136
+ text.bind('<Button-4>', lambda event:text.yview_scroll(-1, Tk_.UNITS))
137
+ text.bind('<Button-5>', lambda event:text.yview_scroll(1, Tk_.UNITS))
138
+ if sys.platform == 'darwin':
139
+ self.window.bind_all('<Command-Key-q>', self.close)
140
+ self.window.bind_all('<Command-Key-Left>', self.go_to_beginning)
141
+ self.text.bind('<Command-Key-Up>', self.jump_up)
142
+ elif sys.platform == 'linux2' or sys.platform == 'linux':
143
+ self.window.bind_all('<Alt-Key-q>', self.close)
144
+ self.add_bindings()
145
+ # 'output_end' marks the end of the text written by us.
146
+ # Everything above this position should be
147
+ # immutable, and tagged with the "output" style.
148
+ # Normally it is set at the end of the input prompt.
149
+ self.text.mark_set('output_end', Tk_.INSERT)
150
+ self.text.mark_gravity('output_end', Tk_.LEFT)
151
+ text.tag_config('output')
152
+ # Make sure we don't override the cut-paste background.
153
+ text.tag_lower('output')
154
+ # Remember where we were when tab was pressed.
155
+ self.tab_index = None
156
+ self.tab_count = 0
157
+ # Manage history
158
+ self.hist_pointer = 0
159
+ self.hist_stem = ''
160
+ self.editing_hist = False
161
+ self.multiline = False
162
+ self.filtered_hist = []
163
+ # Remember illegal pastes
164
+ self.nasty = None
165
+ self.nasty_text = None
166
+ # Build style tags for colored text,
167
+ for code in ansi_colors:
168
+ text.tag_config(code, foreground=ansi_colors[code])
169
+ # and a style tag for messages.
170
+ text.tag_config('msg', foreground='Red')
171
+ self.build_menus()
172
+ self.window.config(menu=self.menubar)
173
+ self.output_count = 0
174
+ # Setup the IPython embedded shell
175
+ self.IP = shell
176
+ # IPython >= 5 uses this to write pygments tokenized strings (if it exists)
177
+ shell.pt_cli = self
178
+ shell.system = self.system
179
+ sys.displayhook = shell.displayhook
180
+ shell.more = False
181
+ # Figure out the size of the first input prompt
182
+ self._input_prompt()
183
+ if shell.banner1:
184
+ self.banner = shell.banner1
185
+ else:
186
+ cprt = 'Type "copyright", "credits" or "license" for more information.'
187
+ self.banner = "Python %s on %s\n%s\n(%s)\n" % (
188
+ sys.version, sys.platform, cprt,
189
+ self.__class__.__name__)
190
+ self.quiet = False
191
+ # We will set this flag if the user types ^C
192
+ self.interrupted = False
193
+ # This flag will be set when IPython is running code
194
+ self.running_code = False
195
+ # This flag will be set when a SnapPea computation is aborted
196
+ self.aborted_SnapPea = False
197
+ # This flag will be set when printing a traceback
198
+ self.showing_traceback = False
199
+ self.closed = False
200
+ self._saved_index = Tk_.END
201
+ # This flag is set to prevent quitting the app.
202
+ self.blockers = {}
203
+ self.can_quit = True
204
+ self.close_callback = lambda :None
205
+
206
+ # Emulate a ListedWindow. We are listed, even though we are unique.
207
+ def bring_to_front(self):
208
+ self.window.deiconify()
209
+ self.window.lift()
210
+ self.window.focus_force()
211
+
212
+ # For subclasses to override:
213
+ def build_menus(self):
214
+ pass
215
+
216
+ # For subclasses to override:
217
+ def add_bindings(self):
218
+ pass
219
+
220
+ def system(self, cmd):
221
+ output = self.IP.getoutput(cmd, split=False)
222
+ self.write(output)
223
+
224
+ def showtraceback(self, etype, evalue, stb):
225
+ traceback = '\n' + self.IP.InteractiveTB.stb2text(stb)
226
+ if etype == KeyboardInterrupt:
227
+ self.write('KeyboardInterrupt: ', style='msg')
228
+ self.write('%s' % evalue)
229
+ else:
230
+ self.write(traceback)
231
+ self.reset()
232
+ self.showing_traceback = True
233
+ self.process_return('\n')
234
+
235
+ def SnapPea_callback(self, interrupted=False):
236
+ """
237
+ Callback for SnapPea to keep the UI alive during long computations.
238
+ """
239
+ if interrupted:
240
+ self.interrupted = False
241
+ raise KeyboardInterrupt('SnapPea computation aborted')
242
+
243
+ def PARI_callback(self):
244
+ """
245
+ Callback for CyPari to keep the UI alive during long computations.
246
+ """
247
+ if self.running_code:
248
+ if self.interrupted:
249
+ snappy.pari.abort()
250
+ self.interrupted = False
251
+ raise KeyboardInterrupt('PARI computation aborted')
252
+
253
+ def interrupt(self):
254
+ if not self.running_code:
255
+ source_raw = self.reset()
256
+ self.IP.history_manager.store_inputs(self.IP.execution_count, source_raw)
257
+ self.IP.execution_count += 1
258
+ else:
259
+ self.interrupted = True
260
+ # Inform the SnapPea kernel about the interrupt.
261
+ snappy.SnapPy.SnapPea_interrupt()
262
+ snappy.SnapPyHP.SnapPea_interrupt()
263
+ # For some reason we need to raise a KeyboardInterrupt here. Otherwise
264
+ # the call to KeyboardInterrupt('Halted') will be ignored.
265
+ raise KeyboardInterrupt('Interrupted')
266
+
267
+ def report_callback_exception(self, exc, value, traceback):
268
+ """
269
+ Called when exceptions are caught by Tk.
270
+ """
271
+ sys.last_type = exc
272
+ sys.last_value = value
273
+ sys.last_traceback = traceback
274
+ self.IP.showtraceback()
275
+
276
+ def set_font(self, font_choice):
277
+ normal_tuple = font_choice.as_tuple()
278
+ bold_tuple = font_choice.bold().as_tuple()
279
+ normal_font = Font(font=font_choice.as_tuple())
280
+ self.char_size = normal_font.measure('M')
281
+ self.text.config(font=normal_tuple)
282
+ text = self.text
283
+ text.tag_config('output', font=normal_tuple)
284
+ text.tag_config('Prompt', foreground='#0000cc', font=normal_tuple)
285
+ text.tag_config('PromptNum', foreground='#0000bb', font=bold_tuple)
286
+ text.tag_config('OutPrompt', foreground='#cc0000', font=normal_tuple)
287
+ text.tag_config('OutPromptNum', foreground='#bb0000', font=bold_tuple)
288
+
289
+ def add_blocker(self, window, message):
290
+ self.blockers[window] = message
291
+
292
+ def remove_blocker(self, window):
293
+ self.blockers.pop(window)
294
+
295
+ def close(self, event=None):
296
+ can_quit = True
297
+ topmost = None
298
+ for blocker in self.blockers:
299
+ if blocker.attributes('-topmost'):
300
+ topmost = blocker
301
+ blocker.attributes('-topmost', False)
302
+ message = self.blockers[blocker]
303
+ answer = askyesno('Quit',
304
+ message + '\nDo you want to quit anyway?')
305
+ if not answer:
306
+ can_quit = False
307
+ break;
308
+ if topmost:
309
+ topmost.attributes('-topmost', True)
310
+ if can_quit:
311
+ for blocker in self.blockers:
312
+ blocker.destroy()
313
+ self.window.quit()
314
+ self.closed = True
315
+
316
+ def handle_control_c(self, event):
317
+ self.interrupt()
318
+ self.interrupted = False
319
+
320
+ def handle_keypress(self, event):
321
+ self.clear_completions()
322
+ protected = self.text.compare(Tk_.INSERT, '<', 'output_end')
323
+ # We only respond to ASCII keys: no accents, no emojis.
324
+ if len(event.char) > 1:
325
+ return
326
+ keysym = event.keysym
327
+ if keysym == 'Left':
328
+ # Don't go into the prompt or continuation prompt
329
+ line, pos = map(int, self.text.index(Tk_.INSERT).split('.'))
330
+ if pos <= self._prompt_size:
331
+ prompt_line = int(self.text.index('output_end').split('.')[0])
332
+ insert_line = int(self.text.index(Tk_.INSERT).split('.')[0])
333
+ if line > prompt_line:
334
+ self.text.mark_set(Tk_.INSERT, '%s.0-1c' % insert_line)
335
+ else:
336
+ self.window.bell()
337
+ return 'break'
338
+ return
339
+ if keysym == 'Right':
340
+ # Don't go into a continuation prompt or past the end
341
+ insert_pos = int(self.text.index('%s+1c' % Tk_.INSERT).split('.')[1])
342
+ if insert_pos < self._prompt_size:
343
+ insert_line = int(self.text.index(Tk_.INSERT).split('.')[0])
344
+ if self.text.compare(Tk_.INSERT, '>=', '%s-2c' % Tk_.END):
345
+ self.window.bell()
346
+ else:
347
+ self.text.mark_set(Tk_.INSERT, '%d.%d' % (
348
+ insert_line + 1, self._prompt_size))
349
+ return 'break'
350
+ return
351
+ # Check for a control character
352
+ if event.state & 4:
353
+ # Ctrl+C is an interrupt
354
+ if keysym == 'c':
355
+ self.interrupt()
356
+ # Ctrl+Shift+C copies on all platforms, even macOS
357
+ if keysym == 'C':
358
+ self.edit_copy()
359
+ # Ctrl+Shift+V pastes on all platforms, even macOS
360
+ if keysym == 'V':
361
+ self.edit_paste()
362
+ # emacs shortcuts (Ctrl-k is built-in)
363
+ if keysym == 'a':
364
+ self.text.mark_set(Tk_.INSERT, 'output_end')
365
+ return 'break'
366
+ if event.keysym == 'e':
367
+ self.text.mark_set(Tk_.INSERT, Tk_.END)
368
+ return 'break'
369
+ if event.keysym == 'u':
370
+ self.text.delete('output_end', Tk_.END)
371
+ return 'break'
372
+ # space pages down when viewing protected output
373
+ if keysym == 'space' and protected:
374
+ self.page_down()
375
+ return 'break'
376
+ # Typing in the protected area should not do anything.
377
+ if event.char and protected:
378
+ self.text.tag_remove(Tk_.SEL, '1.0', Tk_.END)
379
+ return 'break'
380
+ # Apple Fn-left sends \0121 and means ^A
381
+ if event.char == '\0121': # Apple Fn-Left
382
+ self.text.mark_set(Tk_.INSERT, 'output_end')
383
+ return 'break'
384
+
385
+ def handle_keyrelease(self, event):
386
+ if self.editing_hist and self.multiline:
387
+ self.text.tag_add('history', 'output_end', Tk_.INSERT)
388
+
389
+ def handle_return(self, event=None):
390
+ # If the input consists of one complete line of code we run it,
391
+ # regardless of where the insert cursor is located. Otherwise we only
392
+ # run the code if the cursor is at the end of the input
393
+ self.clear_completions()
394
+ if self.running_code:
395
+ return 'break'
396
+ cursor = int(self.text.index(Tk_.INSERT).split('.')[0])
397
+ last = int(self.text.index(Tk_.END).split('.')[0])
398
+ first = int(self.text.index('output_end').split('.')[0])
399
+ if cursor == first == last - 1: # single line input
400
+ self.text.mark_set(Tk_.INSERT, Tk_.END)
401
+ self.text.insert(Tk_.INSERT, '\n')
402
+ cell = self.text.get('output_end', Tk_.INSERT)
403
+ try:
404
+ self.interact_handle_input(cell)
405
+ except KeyboardInterrupt:
406
+ self.write('(IP) Keyboard Interrupt: ')
407
+ self.reset()
408
+ self.hist_pointer = 0
409
+ self.hist_stem = ''
410
+ self.interact_prompt()
411
+ self.text.see(Tk_.INSERT)
412
+ if self.IP.more:
413
+ self.text.insert(Tk_.INSERT, ' '*self._current_indent, ())
414
+ self.hist_pointer = 0
415
+ self.hist_stem = ''
416
+ return 'break'
417
+
418
+ def handle_shift_return(self, event):
419
+ self.text.mark_set(Tk_.INSERT, Tk_.END)
420
+ return self.handle_return()
421
+
422
+ def jump_up(self, event):
423
+ return self.handle_up(event, jump=True)
424
+
425
+ def handle_up(self, event, jump=False):
426
+ if self.text.compare(Tk_.INSERT, '<', 'output_end'):
427
+ return
428
+ insert_line_number = str(self.text.index(Tk_.INSERT)).split('.')[0]
429
+ prompt_line_number = str(self.text.index('output_end')).split('.')[0]
430
+ if insert_line_number != prompt_line_number:
431
+ return
432
+ if self.hist_pointer == 0:
433
+ input_history = self.IP.history_manager.input_hist_raw
434
+ self.hist_stem = self.text.get('output_end', Tk_.END).strip()
435
+ self.filtered_hist = [x for x in input_history
436
+ if x and x.startswith(self.hist_stem)]
437
+ if self.hist_pointer >= len(self.filtered_hist):
438
+ self.window.bell()
439
+ return 'break'
440
+ self.text.delete('output_end', Tk_.END)
441
+ self.hist_pointer += 1
442
+ self.write_history()
443
+ if jump:
444
+ self.text.mark_set(Tk_.INSERT, 'output_end')
445
+ return 'break'
446
+
447
+ def handle_down(self, event):
448
+ if self.text.compare(Tk_.INSERT, '<', 'output_end'):
449
+ return
450
+ if self.editing_hist:
451
+ insert_line = int(str(self.text.index(Tk_.INSERT)).split('.')[0])
452
+ bottom_line = int(str(self.text.index('history_end')).split('.')[0])
453
+ if insert_line < bottom_line:
454
+ return
455
+ if self.hist_pointer == 0:
456
+ return
457
+ self.text.delete('output_end', Tk_.END)
458
+ self.hist_pointer -= 1
459
+ if self.hist_pointer == 0:
460
+ self.write(self.hist_stem.strip('\n'), style=(), advance=False)
461
+ self.editing_hist = False
462
+ self.text.tag_delete('history')
463
+ else:
464
+ self.write_history()
465
+ return 'break'
466
+
467
+ def handle_backspace(self, event):
468
+ self.clear_completions()
469
+ if self.text.compare(Tk_.INSERT, '<=', 'output_end'):
470
+ self.window.bell()
471
+ return 'break'
472
+ line, pos = map(int, self.text.index(Tk_.INSERT).split('.'))
473
+ first_line = int(self.text.index('output_end').split('.')[0])
474
+ if pos <= self._prompt_size + 1 and line != first_line:
475
+ start = '%d.end' % (line - 1)
476
+ end = '%d.end' % (line)
477
+ self.text.mark_set(Tk_.INSERT, start)
478
+ self.text.delete(start, '%s.%s' % (line, self._prompt_size))
479
+ return 'break'
480
+ if self._current_indent >= 4:
481
+ if self.text.get(Tk_.INSERT+'-4c', Tk_.INSERT) == ' ':
482
+ self.text.delete(Tk_.INSERT+'-4c', Tk_.INSERT)
483
+ return 'break'
484
+
485
+ def handle_tab(self, event):
486
+ if self.text.compare(Tk_.INSERT, '<', 'output_end'):
487
+ return 'break'
488
+ self.tab_index = self.text.index(Tk_.INSERT)
489
+ self.tab_count += 1
490
+ if self.tab_count > 2:
491
+ self.clear_completions()
492
+ return 'break'
493
+ line = self.text.get('output_end', self.tab_index).strip('\n')
494
+ word = delims.split(line)[-1]
495
+ try:
496
+ stem, completions = self.IP.complete(word)
497
+ except TypeError:
498
+ completions = []
499
+ if word.find('_') == -1:
500
+ completions = [x for x in completions
501
+ if x.find('__') == -1 and x.find('._') == -1]
502
+ # No meaningful completions. Ring the bell.
503
+ if len(completions) == 0 or len(completions) == 1 and completions[0] == stem:
504
+ self.window.bell()
505
+ self.tab_count = 0
506
+ return 'break'
507
+ # Only one completion. Use it.
508
+ if len(completions) == 1:
509
+ self.do_completion(stem, completions[0])
510
+ self.tab_count = 0
511
+ return 'break'
512
+ max_stem = self.max_stem(stem, completions)
513
+ # Add the maximal stem of all completions if it extends the word,
514
+ if len(max_stem) > len(word):
515
+ self.do_completion(stem, max_stem)
516
+ self.tab_count = 0
517
+ return 'break'
518
+ # Show the possible completions, with a warning if there are lots.
519
+ if len(completions) > 60 and self.tab_count == 1:
520
+ self.show_completions('', '',
521
+ ['%s possibilities -- hit tab again to view them all' %
522
+ len(completions)])
523
+ else:
524
+ self.show_completions(word, stem, completions)
525
+ if len(completions) <= 60:
526
+ self.tab_count += 1
527
+ return 'break'
528
+
529
+ def go_to_beginning(self, event):
530
+ self.text.mark_set(Tk_.INSERT, 'output_end')
531
+ return 'break'
532
+
533
+ def do_completion(self, stem, completion):
534
+ tail = completion[len(stem):]
535
+ self.text.insert(self.tab_index, tail)
536
+ self.tab_index = Tk_.END
537
+ self.tab_count = 0
538
+
539
+ def show_completions(self, word, stem, comps):
540
+ n = len(stem)
541
+ comps = [word + c[n:] for c in comps]
542
+ self.text.delete(self.tab_index, Tk_.END)
543
+ width = self.text.winfo_width()
544
+ charwidth = width // self.char_size
545
+ biggest = 2 + max([len(x) for x in comps])
546
+ num_cols = max(charwidth // biggest, 1)
547
+ num_rows = (len(comps) + num_cols - 1) // num_cols
548
+ rows = []
549
+ format = '%%-%ds' % biggest
550
+ for n in range(num_rows):
551
+ rows.append(''.join(format % x for x in comps[n:len(comps):num_rows]))
552
+ view = '\n'.join(rows)
553
+ self.text.insert(self.tab_index, '\n'+view)
554
+ self.text.mark_set(Tk_.INSERT, self.tab_index)
555
+ self.text.see(Tk_.END)
556
+
557
+ def clear_completions(self):
558
+ if self.tab_index:
559
+ self.text.delete(self.tab_index, Tk_.END)
560
+ self.tab_index = None
561
+ self.tab_count = 0
562
+
563
+ def max_stem(self, stem, completions):
564
+ if len(completions) == 1:
565
+ return completions[0]
566
+ result = stem
567
+ for n in range(len(stem) + 1, 100):
568
+ heads = {w[:n] for w in completions}
569
+ if len(heads) > 1:
570
+ return result
571
+ elif len(heads) == 1:
572
+ result = heads.pop()
573
+ return result
574
+
575
+ def write_continuation_prompt(self):
576
+ prompt_tokens = self._continuation_prompt(self._prompt_size)
577
+ for style, text in prompt_tokens:
578
+ self.write(text, style, mark=Tk_.INSERT, advance=True)
579
+
580
+ def write_history(self, force_multiline=False):
581
+ self.text.see('output_end')
582
+ input = self.filtered_hist[-self.hist_pointer]
583
+ input = re.sub('\n+', '\n', input).rstrip()
584
+ lines = input.split('\n')
585
+ if len(lines) > 1 or force_multiline:
586
+ self.editing_hist = True
587
+ self.multiline = True
588
+ self.text.delete('output_end', Tk_.END)
589
+ self.write(lines[0] + '\n', mark=Tk_.INSERT, advance=True)
590
+ prompt_tokens = self._continuation_prompt(self._prompt_size)
591
+ for line in lines[1:-1]:
592
+ self.write_continuation_prompt()
593
+ self.write(line + '\n', mark=Tk_.INSERT)
594
+ self.write_continuation_prompt()
595
+ self.write(lines[-1], mark=Tk_.INSERT)
596
+ self.text.mark_set('history_end', Tk_.INSERT)
597
+ else:
598
+ self.multiline = False
599
+ self.write(input, style=(), advance=False)
600
+ self.text.see(Tk_.INSERT)
601
+
602
+ def protect_text(self, event):
603
+ try:
604
+ if self.text.compare(Tk_.SEL_FIRST, '<=', 'output_end'):
605
+ self.window.bell()
606
+ return 'break'
607
+ except:
608
+ pass
609
+
610
+ def edit_actions(self):
611
+ "Return a dictionary of allowable edit actions."
612
+ result = {}
613
+ try:
614
+ selectable = self.text.compare(Tk_.SEL_FIRST, '<', Tk_.SEL_LAST)
615
+ except:
616
+ selectable = False
617
+ try:
618
+ protected = self.text.compare(Tk_.INSERT, '<', 'output_end')
619
+ except:
620
+ protected = True
621
+ try:
622
+ clip = self.text.clipboard_get()
623
+ except:
624
+ clip = None
625
+ if selectable:
626
+ result['Copy'] = self.edit_copy
627
+ if clip:
628
+ result['Paste'] = self.edit_paste
629
+ if protected:
630
+ return result
631
+ else:
632
+ if selectable:
633
+ result['Delete'] = self.edit_delete
634
+ result['Cut'] = self.edit_cut
635
+ return result
636
+
637
+ def edit_cut(self):
638
+ try:
639
+ self.text.clipboard_clear()
640
+ self.text.clipboard_append(self.text.selection_get())
641
+ self.text.delete(Tk_.SEL_FIRST, Tk_.SEL_LAST)
642
+ except:
643
+ pass
644
+
645
+ def edit_copy(self, event=None):
646
+ try:
647
+ self.text.clipboard_clear()
648
+ self.text.clipboard_append(self.text.selection_get())
649
+ self.text.tag_remove(Tk_.SEL, '1.0', Tk_.END)
650
+ if self.text.compare(Tk_.INSERT, '<', 'output_end'):
651
+ self.text.mark_set(Tk_.INSERT, Tk_.END)
652
+ except:
653
+ pass
654
+
655
+ def edit_paste(self, event=None):
656
+ text = self.text
657
+ try:
658
+ clip = self.text.clipboard_get()
659
+ except:
660
+ return
661
+ try:
662
+ start = text.index(Tk_.SEL_FIRST)
663
+ text.delete(Tk_.SEL_FIRST, Tk_.SEL_LAST)
664
+ text.insert(Tk_.SEL_FIRST, clip)
665
+ except:
666
+ if self.text.compare(Tk_.INSERT, '<', 'output_end'):
667
+ self.text.mark_set(Tk_.INSERT, 'output_end')
668
+ text.insert(Tk_.INSERT, clip)
669
+ self.text.see(Tk_.INSERT)
670
+ try:
671
+ self.text.tag_remove(Tk_.SEL, Tk_.SEL_FIRST, Tk_.SEL_LAST)
672
+ except:
673
+ pass
674
+ # prevent multiple pastes with ^V
675
+ return 'break'
676
+
677
+ def edit_delete(self):
678
+ try:
679
+ self.text.delete(Tk_.SEL_FIRST, Tk_.SEL_LAST)
680
+ except:
681
+ pass
682
+
683
+ def mouse_up(self, event):
684
+ self.text.mark_set(Tk_.INSERT, Tk_.END)
685
+
686
+ def middle_mouse_down(self, event):
687
+ # Part 1 of a nasty hack to prevent pasting into the immutable text.
688
+ # Needed because returning 'break' does not prevent the paste.
689
+ if self.text.compare(Tk_.CURRENT, '<', 'output_end'):
690
+ self.window.bell()
691
+ try:
692
+ self.nasty = str(self.text.index(Tk_.CURRENT))
693
+ except AttributeError:
694
+ return 'break'
695
+ paste = event.widget.selection_get(selection="PRIMARY")
696
+ self.nasty_text = paste.split()[0]
697
+ return 'break'
698
+
699
+ def middle_mouse_up(self, event):
700
+ # Part 2 of the nasty hack.
701
+ if self.nasty:
702
+ # The CURRENT mark may be off by 1 from the actual paste index
703
+ # This will probably fail sometimes.
704
+ start = self.text.search(self.nasty_text, index=self.nasty+'-2c')
705
+ if start:
706
+ self.text.delete(start, Tk_.INSERT)
707
+ self.nasty = None
708
+ self.nasty_text = None
709
+ try:
710
+ self.text.tag_remove(Tk_.SEL, Tk_.SEL_FIRST, Tk_.SEL_LAST)
711
+ except Tk_.TclError:
712
+ pass
713
+ return 'break'
714
+
715
+ def start_interaction(self):
716
+ """
717
+ Display a banner and prepare to begin interaction.
718
+ """
719
+ # Subclasses should override this method
720
+ banner_label = Tk_.Label(self.text,
721
+ text="Please override the start_interaction method.",
722
+ anchor=Tk_.W,
723
+ justify=Tk_.LEFT)
724
+ self.text.window_create(Tk_.END, window=banner_label)
725
+ self.text.insert(Tk_.END, '\n')
726
+ self.text.mark_set('output_end', '2.0')
727
+
728
+ def _input_prompt(self):
729
+ result = [('Prompt', 'In['),
730
+ ('PromptNum', '%d' % self.IP.execution_count),
731
+ ('Prompt', ']: ')]
732
+ self._prompt_size = sum(len(token[1]) for token in result)
733
+ return result
734
+
735
+ def _continuation_prompt(self, size):
736
+ prompt_text = ' '*(size - 5) + '...: '
737
+ return [( 'Prompt', prompt_text)]
738
+
739
+ def interact_prompt(self):
740
+ """
741
+ Print an input prompt or a continuation prompt. For an input
742
+ prompt set the output_end mark at the end of the prompt.
743
+ """
744
+ if self.showing_traceback:
745
+ self.showing_traceback = False
746
+ return
747
+ try:
748
+ if self.IP.more or self.editing_hist:
749
+ self.write_continuation_prompt()
750
+ else:
751
+ if int(self.text.index('output_end').split('.')[1]) != 0:
752
+ self.write('\n\n', mark='output_end')
753
+ prompt_tokens = self._input_prompt()
754
+ for style, text in prompt_tokens:
755
+ self.write(text, style, mark='output_end')
756
+ except:
757
+ self.IP.showtraceback()
758
+
759
+ def clean_code(self, code):
760
+ """
761
+ Remove blank lines and continuation prompts.
762
+ """
763
+ if not code.strip():
764
+ return '\n'
765
+ lines = list(code.split('\n'))
766
+ clean_lines = [lines[0].lstrip()]
767
+ for line in lines[1:]:
768
+ try:
769
+ clean_lines.append(line.split(': ', 1)[1])
770
+ except IndexError:
771
+ pass
772
+ return '\n'.join(clean_lines)
773
+
774
+ def interact_handle_input(self, cell, script=False):
775
+ """
776
+ Validate the code in the cell. If the code is valid but
777
+ incomplete, set the indent that should follow a continuation
778
+ prompt and set the 'more' flag. If the code is valid and
779
+ complete then run the code.
780
+ """
781
+ assert cell.endswith('\n')
782
+ if not cell.strip():
783
+ self._current_indent = 0
784
+ return
785
+ if script:
786
+ self._input_buffer += cell
787
+ else:
788
+ self._input_buffer = self.clean_code(cell)
789
+ transformed_cell = self.IP.transform_cell(self._input_buffer)
790
+ status, indent = self.IP.check_complete(transformed_cell)
791
+ self._current_indent = indent or 0
792
+ if status == 'incomplete':
793
+ self.IP.more = True
794
+ return
795
+ if status == 'invalid':
796
+ # Force display of the SyntaxError
797
+ self.text.mark_set(Tk_.INSERT, self.text.index('output_end-1line'))
798
+ self.IP.run_cell(self._input_buffer, store_history=True)
799
+ self.text.insert('output_end-1line', '\n')
800
+ self.reset()
801
+ self.text.delete('output_end', Tk_.END)
802
+ return
803
+ # The code is complete, but we only run it if the cursor is on the
804
+ # last line of the input and that line is blank.
805
+ insert_line = int(self.text.index(Tk_.INSERT).split('.')[0])
806
+ prompt_line = int(self.text.index('output_end').split('.')[0])
807
+ tail = self.text.get('%d.%d' % (insert_line, self._prompt_size), Tk_.END)
808
+ if not tail.strip():
809
+ self.text.tag_delete('history')
810
+ self._input_buffer = self._input_buffer.rstrip() + '\n'
811
+ self.text.delete(Tk_.INSERT, Tk_.END)
812
+ self.text.insert(Tk_.INSERT, '\n')
813
+ self.text.mark_set('output_end', Tk_.INSERT)
814
+ self.multiline = False
815
+ self.running_code = True
816
+ self.editing_hist = False
817
+ last_line = insert_line - 1
818
+ if last_line > prompt_line:
819
+ # Delete the last continuation prompt.
820
+ self.text.delete('%d.0' % last_line, '%d.0 lineend' % last_line)
821
+ self.IP.run_cell(self._input_buffer, store_history=True)
822
+ # Add a newline after the output.
823
+ self.write('\n')
824
+ self.text.tag_add('output', 'output_end', Tk_.END)
825
+ self.reset()
826
+ else:
827
+ self.IP.more = True
828
+
829
+ def reset(self):
830
+ result = self._input_buffer
831
+ self._input_buffer = ''
832
+ self._current_indent = 0
833
+ self.text.delete('output_end',Tk_.INSERT)
834
+ self.editing_hist = False
835
+ self.multiline = False
836
+ self.running_code = False
837
+ self.IP.more = False
838
+ self.text.tag_delete('history')
839
+ return result
840
+
841
+ def write(self, string, style=('output',), advance=True,
842
+ mark='output_end', see=True):
843
+ """
844
+ Writes a string containing ansi color escape sequences to our
845
+ Text widget, starting at the specified mark. If the advance
846
+ option is True, advance the mark to the end of the output.
847
+ """
848
+ if self.quiet:
849
+ return
850
+ # if self.interrupted:
851
+ # self.interrupted = False
852
+ # raise KeyboardInterrupt('Writing')
853
+ if mark != Tk_.INSERT:
854
+ self.text.mark_set(Tk_.INSERT, mark)
855
+ pairs = ansi_seqs.findall(string)
856
+ for pair in pairs:
857
+ code, text = pair
858
+ tags = (code,) + style if code else style
859
+ if text:
860
+ self.text.insert(Tk_.INSERT, text, tags)
861
+ self.output_count += len(text)
862
+ if advance:
863
+ self.text.mark_set(mark, Tk_.INSERT)
864
+ if see:
865
+ self.text.see(Tk_.INSERT)
866
+ # Give the Text widget a chance to update itself every
867
+ # so often. In order to force processing of key events
868
+ # we have to call the evil update method, unfortunately.
869
+ if self.output_count > 2000:
870
+ self.output_count = 0
871
+ self.text.update()
872
+ if self.interrupted:
873
+ self.interrupted = False
874
+ raise KeyboardInterrupt('Halted')
875
+
876
+ def write2(self, string):
877
+ """
878
+ Write method for messages. These go in the "immutable"
879
+ part, so as not to confuse the prompt.
880
+ """
881
+ self.window.tkraise()
882
+ self.text.mark_set('save_insert', Tk_.INSERT)
883
+ self.text.mark_set('save_end', 'output_end')
884
+ self.text.mark_set(Tk_.INSERT, str(self.text.index('output_end'))+'linestart')
885
+ self.text.insert(Tk_.INSERT, string, ('output', 'msg',))
886
+ self.text.mark_set(Tk_.INSERT, 'save_insert')
887
+ self.text.see('output_end')
888
+
889
+ def writelines(self, lines):
890
+ lines = iter(lines)
891
+ for line in lines:
892
+ self.write(line)
893
+
894
+ def page(self, text):
895
+ """
896
+ Our pager. Just writes the text to the screen then jumps back to
897
+ the beginning. You can scroll down to read it.
898
+ """
899
+ index = self.text.index(Tk_.INSERT)
900
+ self.write('\n'+str(text), see=False)
901
+ self.window.after_idle(self.text.see, index)
902
+
903
+ def page_down(self):
904
+ insert_line = int(str(self.text.index(Tk_.INSERT)).split('.')[0])
905
+ prompt_line = int(str(self.text.index('output_end')).split('.')[0])
906
+ height = prompt_line - insert_line
907
+ if height < 1:
908
+ return
909
+ scroll_amount = min(int(self.text.cget('height')) - 1, height)
910
+ self.text.yview_scroll(scroll_amount, Tk_.UNITS)
911
+ # if scroll_amount == height:
912
+ # self.text.mark_set(Tk_.INSERT, 'output_end')
913
+ # else:
914
+ # self.text.mark_set(Tk_.INSERT, '%s.0'%(insert_line + scroll_amount))
915
+
916
+ def flush(self):
917
+ """
918
+ Required for a stdout / stderr proxy.
919
+ """
920
+ self.text.update_idletasks()