Compare commits
	
		
			No commits in common. "master" and "pyqt_gui" have entirely different histories.
		
	
	
		
	
		
					 54 changed files with 6409 additions and 1697 deletions
				
			
		|  | @ -1,2 +0,0 @@ | ||||||
| [build] |  | ||||||
| rustflags = ["-C", "target-cpu=native"] |  | ||||||
							
								
								
									
										40
									
								
								.chglog/CHANGELOG.tpl.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								.chglog/CHANGELOG.tpl.md
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,40 @@ | ||||||
|  | {{ if .Versions -}} | ||||||
|  | ## [Unreleased] | ||||||
|  | 
 | ||||||
|  | {{ if .Unreleased.CommitGroups -}} | ||||||
|  | {{ range .Unreleased.CommitGroups -}} | ||||||
|  | ### {{ .Title }} | ||||||
|  | {{ range .Commits -}} | ||||||
|  | - {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} [{{.Hash.Short}}]({{ $.Info.RepositoryURL }}/commit/{{ .Hash.Short }}) | ||||||
|  | {{ end }} | ||||||
|  | {{ end -}} | ||||||
|  | {{ end -}} | ||||||
|  | {{ end -}} | ||||||
|  | 
 | ||||||
|  | {{ range .Versions }} | ||||||
|  | ## {{ if .Tag.Previous }}[{{ .Tag.Name }}]{{ else }}{{ .Tag.Name }}{{ end }} - {{ datetime "2006-01-02" .Tag.Date }} | ||||||
|  | {{ range .CommitGroups -}} | ||||||
|  | ### {{ .Title }} | ||||||
|  | {{ range .Commits -}} | ||||||
|  | - {{ if .Scope }}**{{ .Scope }}:** {{ end }}{{ .Subject }} [{{.Hash.Short}}]({{ $.Info.RepositoryURL }}/commit/{{ .Hash.Short }}) | ||||||
|  | {{ end }} | ||||||
|  | {{ end -}} | ||||||
|  | 
 | ||||||
|  | {{- if .NoteGroups -}} | ||||||
|  | {{ range .NoteGroups -}} | ||||||
|  | ### {{ .Title }} | ||||||
|  | {{ range .Notes }} | ||||||
|  | {{ .Body }} | ||||||
|  | {{ end }} | ||||||
|  | {{ end -}} | ||||||
|  | {{ end -}} | ||||||
|  | {{ end -}} | ||||||
|  | 
 | ||||||
|  | {{- if .Versions }} | ||||||
|  | [Unreleased]: {{ $.Info.RepositoryURL }}/compare/{{ $latest := index .Versions 0 }}{{ $latest.Tag.Name }}...HEAD | ||||||
|  | {{ range .Versions -}} | ||||||
|  | {{ if .Tag.Previous -}} | ||||||
|  | [{{ .Tag.Name }}]: {{ $.Info.RepositoryURL }}/compare/{{ .Tag.Previous.Name }}...{{ .Tag.Name }} | ||||||
|  | {{ end -}} | ||||||
|  | {{ end -}} | ||||||
|  | {{ end -}} | ||||||
							
								
								
									
										34
									
								
								.chglog/config.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								.chglog/config.yml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | ||||||
|  | style: gitlab | ||||||
|  | template: CHANGELOG.tpl.md | ||||||
|  | info: | ||||||
|  |   title: CHANGELOG | ||||||
|  |   repository_url: https://gitlab.com/Earthnuker/ed_lrr | ||||||
|  | options: | ||||||
|  |   commits: | ||||||
|  |     filters: | ||||||
|  |       Type: | ||||||
|  |         - feat | ||||||
|  |         - fix | ||||||
|  |         - perf | ||||||
|  |         - refactor | ||||||
|  |         - misc | ||||||
|  |         - other | ||||||
|  |         - docs | ||||||
|  |   commit_groups: | ||||||
|  |     title_maps: | ||||||
|  |       feat: Features | ||||||
|  |       fix: Bug Fixes | ||||||
|  |       perf: Performance Improvements | ||||||
|  |       refactor: Code Refactoring | ||||||
|  |       misc: Miscellaneous | ||||||
|  |       other: Other | ||||||
|  |       docs: Documentation | ||||||
|  |   header: | ||||||
|  |     pattern: "^(\\w*)(?:\\(([\\w\\$\\.\\-\\*\\s]*)\\))?\\:\\s(.*)$" | ||||||
|  |     pattern_maps: | ||||||
|  |       - Type | ||||||
|  |       - Scope | ||||||
|  |       - Subject | ||||||
|  |   notes: | ||||||
|  |     keywords: | ||||||
|  |       - BREAKING CHANGE | ||||||
							
								
								
									
										19
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							|  | @ -1,9 +1,24 @@ | ||||||
| /target | rust/target | ||||||
|  | rust/.history/ | ||||||
| **/*.rs.bk | **/*.rs.bk | ||||||
|  | *.tmp | ||||||
|  | *.idx | ||||||
| .vscode/** | .vscode/** | ||||||
| *.csv | *.csv | ||||||
| *.router | *.router | ||||||
| dumps/*.json |  | ||||||
| plot.py | plot.py | ||||||
| *.tmp | *.tmp | ||||||
| *.idx | *.idx | ||||||
|  | *.pyd | ||||||
|  | __pycache__ | ||||||
|  | *.egg-info | ||||||
|  | build | ||||||
|  | *.pdf | ||||||
|  | .history | ||||||
|  | .tox | ||||||
|  | pip-wheel-metadata | ||||||
|  | .eggs/ | ||||||
|  | exe/ | ||||||
|  | installer/Output/ | ||||||
|  | workspace.code-workspace   | ||||||
|  | ed_lrr_gui/web/jobs.db | ||||||
|  |  | ||||||
|  | @ -1,26 +0,0 @@ | ||||||
| # This file is a template, and might need editing before it works on your project. |  | ||||||
| # Official language image. Look for the different tagged releases at: |  | ||||||
| # https://hub.docker.com/r/library/rust/tags/ |  | ||||||
| image: "rust:latest" |  | ||||||
| 
 |  | ||||||
| # Optional: Pick zero or more services to be used on all builds. |  | ||||||
| # Only needed when using a docker container to run your tests in. |  | ||||||
| # Check out: http://docs.gitlab.com/ce/ci/docker/using_docker_images.html#what-is-a-service |  | ||||||
| # services: |  | ||||||
| #   - mysql:latest |  | ||||||
| #   - redis:latest |  | ||||||
| #   - postgres:latest |  | ||||||
| 
 |  | ||||||
| # Optional: Install a C compiler, cmake and git into the container. |  | ||||||
| # You will often need this when you (or any of your dependencies) depends on C code. |  | ||||||
| before_script: |  | ||||||
|   - apt-get update -yqq |  | ||||||
|   - apt-get install -yqq --no-install-recommends build-essential |  | ||||||
|   - rustup update nightly |  | ||||||
|   - rustup default nightly |  | ||||||
| 
 |  | ||||||
| # Use cargo to test the project |  | ||||||
| test:cargo: |  | ||||||
|   script: |  | ||||||
|     - rustc --version && cargo --version  # Print version info for debugging |  | ||||||
|     - cargo build --release |  | ||||||
							
								
								
									
										264
									
								
								CHANGELOG.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										264
									
								
								CHANGELOG.md
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,264 @@ | ||||||
|  | ## [Unreleased] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.24.0] - 2019-10-23 | ||||||
|  | ### Features | ||||||
|  | - **tests:** Add pytest.ini for pytest-qt [eb43ca8](https://gitlab.com/Earthnuker/ed_lrr/commit/eb43ca8) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.23.0] - 2019-10-23 | ||||||
|  | ### Documentation | ||||||
|  | - **readme:** Update README with more infos [634af75](https://gitlab.com/Earthnuker/ed_lrr/commit/634af75) | ||||||
|  | 
 | ||||||
|  | ### Features | ||||||
|  | - **setup.py:** Update add dependencies for HTTP API [45c11da](https://gitlab.com/Earthnuker/ed_lrr/commit/45c11da) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.22.0] - 2019-10-23 | ||||||
|  | ### Features | ||||||
|  | - **tox:** Add more python versions to test against [3115f9d](https://gitlab.com/Earthnuker/ed_lrr/commit/3115f9d) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.21.0] - 2019-10-23 | ||||||
|  | ### Features | ||||||
|  | - **html_export:** Add basic HTML-Export using Jinja2 template [bb2ee8c](https://gitlab.com/Earthnuker/ed_lrr/commit/bb2ee8c) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.20.0] - 2019-10-23 | ||||||
|  | ### Features | ||||||
|  | - **route_progress:** minor change to progress dialog message [35fc135](https://gitlab.com/Earthnuker/ed_lrr/commit/35fc135) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.19.1] - 2019-10-23 | ||||||
|  | ### Bug Fixes | ||||||
|  | - **config:** Add missing defaults [30dbd24](https://gitlab.com/Earthnuker/ed_lrr/commit/30dbd24) | ||||||
|  | 
 | ||||||
|  | ### Documentation | ||||||
|  | - Update CHANGELOG.md and README.md [38acfc7](https://gitlab.com/Earthnuker/ed_lrr/commit/38acfc7) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.19.0] - 2019-09-28 | ||||||
|  | ### Features | ||||||
|  | - **config:** impelemt save and load to GUI [65fe131](https://gitlab.com/Earthnuker/ed_lrr/commit/65fe131) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.18.0] - 2019-09-28 | ||||||
|  | ### Features | ||||||
|  | - **GUI:** implement preprocessing [f34d37a](https://gitlab.com/Earthnuker/ed_lrr/commit/f34d37a) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.17.0] - 2019-09-28 | ||||||
|  | ### Documentation | ||||||
|  | - Update TODO list in readme [4663d4e](https://gitlab.com/Earthnuker/ed_lrr/commit/4663d4e) | ||||||
|  | 
 | ||||||
|  | ### Features | ||||||
|  | - **installer:** switch from LZMA to LZMA2 [3ee952e](https://gitlab.com/Earthnuker/ed_lrr/commit/3ee952e) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.16.0] - 2019-09-28 | ||||||
|  | ### Features | ||||||
|  | - **build scripts:** skip .history folder when building UI files [92bd1b1](https://gitlab.com/Earthnuker/ed_lrr/commit/92bd1b1) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.15.0] - 2019-09-28 | ||||||
|  | ### Features | ||||||
|  | - **config:** update config format [9ec4687](https://gitlab.com/Earthnuker/ed_lrr/commit/9ec4687) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.14.0] - 2019-09-28 | ||||||
|  | ### Features | ||||||
|  | - **UI:** made dropdowns non-editable [37f5547](https://gitlab.com/Earthnuker/ed_lrr/commit/37f5547) | ||||||
|  | 
 | ||||||
|  | ### Miscellaneous | ||||||
|  | - Alsways compile in release mode [e9bcd3e](https://gitlab.com/Earthnuker/ed_lrr/commit/e9bcd3e) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.13.0] - 2019-09-28 | ||||||
|  | ### Features | ||||||
|  | - **config:** finish integrating new configuration system [a8d6a32](https://gitlab.com/Earthnuker/ed_lrr/commit/a8d6a32) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.12.0] - 2019-09-28 | ||||||
|  | ### Features | ||||||
|  | - **Router:** finish implementing route computation progress display [93f655c](https://gitlab.com/Earthnuker/ed_lrr/commit/93f655c) | ||||||
|  | 
 | ||||||
|  | ### Miscellaneous | ||||||
|  | - Add VSCode workspace config to gitignore [a91fa73](https://gitlab.com/Earthnuker/ed_lrr/commit/a91fa73) | ||||||
|  | - formatting [f78ec66](https://gitlab.com/Earthnuker/ed_lrr/commit/f78ec66) | ||||||
|  | - **CI:** rename main executable before building installer [dc0e3fc](https://gitlab.com/Earthnuker/ed_lrr/commit/dc0e3fc) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.11.0] - 2019-09-28 | ||||||
|  | ### Features | ||||||
|  | - **GUI:** Integrate route computation Job [f4e6bd3](https://gitlab.com/Earthnuker/ed_lrr/commit/f4e6bd3) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.10.0] - 2019-09-28 | ||||||
|  | ### Features | ||||||
|  | - **GUI:** Integrate new config system [22ca2d2](https://gitlab.com/Earthnuker/ed_lrr/commit/22ca2d2) | ||||||
|  | 
 | ||||||
|  | ### Miscellaneous | ||||||
|  | - re-export config from main GUI module [0d89106](https://gitlab.com/Earthnuker/ed_lrr/commit/0d89106) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.9.0] - 2019-09-28 | ||||||
|  | ### Features | ||||||
|  | - **cli:** Add config editor [8b0b56f](https://gitlab.com/Earthnuker/ed_lrr/commit/8b0b56f) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.8.0] - 2019-09-28 | ||||||
|  | ### Features | ||||||
|  | - **router:** Implement route computation job with progress dualog [2c000da](https://gitlab.com/Earthnuker/ed_lrr/commit/2c000da) | ||||||
|  | 
 | ||||||
|  | ### Miscellaneous | ||||||
|  | - **setup.py:** Pull version info from git, unify scripts (one script for GUI and CLI) [a630851](https://gitlab.com/Earthnuker/ed_lrr/commit/a630851) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.7.0] - 2019-09-28 | ||||||
|  | ### Documentation | ||||||
|  | - Update README.md [66267e7](https://gitlab.com/Earthnuker/ed_lrr/commit/66267e7) | ||||||
|  | 
 | ||||||
|  | ### Features | ||||||
|  | - **installer:** Download EDSM dumps after install [4237b30](https://gitlab.com/Earthnuker/ed_lrr/commit/4237b30) | ||||||
|  | 
 | ||||||
|  | ### Miscellaneous | ||||||
|  | - Update icon generator and regenerate icon [7838480](https://gitlab.com/Earthnuker/ed_lrr/commit/7838480) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.6.0] - 2019-09-28 | ||||||
|  | ### Features | ||||||
|  | - **router:** Start implementing route pruning support [88a0378](https://gitlab.com/Earthnuker/ed_lrr/commit/88a0378) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.5.0] - 2019-09-28 | ||||||
|  | ### Features | ||||||
|  | - **config:** Update config system to use profig [b1143c3](https://gitlab.com/Earthnuker/ed_lrr/commit/b1143c3) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.4.0] - 2019-09-28 | ||||||
|  | ### Features | ||||||
|  | - **build system:** Remove build.py (switched to tox), add output to build_gui.py [fb3a130](https://gitlab.com/Earthnuker/ed_lrr/commit/fb3a130) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.3.0] - 2019-09-28 | ||||||
|  | ### Features | ||||||
|  | - **router:** Add dialog to display computed route [d498746](https://gitlab.com/Earthnuker/ed_lrr/commit/d498746) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.2.11] - 2019-09-21 | ||||||
|  | ### Bug Fixes | ||||||
|  | - switch inno setup version in appveyor [fe3534e](https://gitlab.com/Earthnuker/ed_lrr/commit/fe3534e) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.2.10] - 2019-09-21 | ||||||
|  | ### Bug Fixes | ||||||
|  | - typo in appveyor.yml [09e6f0a](https://gitlab.com/Earthnuker/ed_lrr/commit/09e6f0a) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.2.9] - 2019-09-21 | ||||||
|  | ### Bug Fixes | ||||||
|  | - disable confirmation for conda install [eaddb18](https://gitlab.com/Earthnuker/ed_lrr/commit/eaddb18) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.2.8] - 2019-09-21 | ||||||
|  | ### Bug Fixes | ||||||
|  | - add missing conda channel [6d9f1ef](https://gitlab.com/Earthnuker/ed_lrr/commit/6d9f1ef) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.2.7] - 2019-09-21 | ||||||
|  | ### Bug Fixes | ||||||
|  | - add missing dependencies to appveyor.yml [e8beb55](https://gitlab.com/Earthnuker/ed_lrr/commit/e8beb55) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.2.6] - 2019-09-20 | ||||||
|  | ### Bug Fixes | ||||||
|  | - fix nuikta call to clean build directory [fa485be](https://gitlab.com/Earthnuker/ed_lrr/commit/fa485be) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.2.5] - 2019-09-20 | ||||||
|  | ### Bug Fixes | ||||||
|  | - fix nuikta call to download without confirmation [11efe30](https://gitlab.com/Earthnuker/ed_lrr/commit/11efe30) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.2.4] - 2019-09-20 | ||||||
|  | ### Bug Fixes | ||||||
|  | - fixed appveyor.yml [59390fe](https://gitlab.com/Earthnuker/ed_lrr/commit/59390fe) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.2.3] - 2019-09-20 | ||||||
|  | ### Bug Fixes | ||||||
|  | - fixed tox.ini [6bb7e1e](https://gitlab.com/Earthnuker/ed_lrr/commit/6bb7e1e) | ||||||
|  | 
 | ||||||
|  | ### Documentation | ||||||
|  | - small wording change [3779911](https://gitlab.com/Earthnuker/ed_lrr/commit/3779911) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.2.2] - 2019-08-31 | ||||||
|  | ### Bug Fixes | ||||||
|  | - **setup:** fix setup script to include subdirectories [4a392d9](https://gitlab.com/Earthnuker/ed_lrr/commit/4a392d9) | ||||||
|  | 
 | ||||||
|  | ### Documentation | ||||||
|  | - Insert page break after table of contents [f027e02](https://gitlab.com/Earthnuker/ed_lrr/commit/f027e02) | ||||||
|  | - Update documentation to include basic description [714741a](https://gitlab.com/Earthnuker/ed_lrr/commit/714741a) | ||||||
|  | - Rename `doc` folder to `docs`, update outline [fb54bda](https://gitlab.com/Earthnuker/ed_lrr/commit/fb54bda) | ||||||
|  | - Add skeleton for documentation [dbc6f35](https://gitlab.com/Earthnuker/ed_lrr/commit/dbc6f35) | ||||||
|  | 
 | ||||||
|  | ### Miscellaneous | ||||||
|  | - Update changelog template to make conversion to PDF easier [87550a9](https://gitlab.com/Earthnuker/ed_lrr/commit/87550a9) | ||||||
|  | - **formatting:** ran `cargo fmt` and `cargo clippy`, fixed all warnings [fb3f79b](https://gitlab.com/Earthnuker/ed_lrr/commit/fb3f79b) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.2.1] - 2019-08-05 | ||||||
|  | ### Bug Fixes | ||||||
|  | - **router:** Fixed some syntax errors created by botched merge [4b14643](https://gitlab.com/Earthnuker/ed_lrr/commit/4b14643) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.2.0] - 2019-08-05 | ||||||
|  | ### Features | ||||||
|  | - **GUI:** Implement route plotting and fuzzy search [c290d5e](https://gitlab.com/Earthnuker/ed_lrr/commit/c290d5e) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## [v0.1.0] - 2019-07-22 | ||||||
|  | ### Features | ||||||
|  | - **GUI:** Add Download functionality, update Rust code, update Python code [ec3972b](https://gitlab.com/Earthnuker/ed_lrr/commit/ec3972b) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ## v0.0.0 - 2019-07-15 | ||||||
|  | 
 | ||||||
|  | [Unreleased]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.24.0...HEAD | ||||||
|  | [v0.24.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.23.0...v0.24.0 | ||||||
|  | [v0.23.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.22.0...v0.23.0 | ||||||
|  | [v0.22.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.21.0...v0.22.0 | ||||||
|  | [v0.21.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.20.0...v0.21.0 | ||||||
|  | [v0.20.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.19.1...v0.20.0 | ||||||
|  | [v0.19.1]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.19.0...v0.19.1 | ||||||
|  | [v0.19.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.18.0...v0.19.0 | ||||||
|  | [v0.18.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.17.0...v0.18.0 | ||||||
|  | [v0.17.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.16.0...v0.17.0 | ||||||
|  | [v0.16.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.15.0...v0.16.0 | ||||||
|  | [v0.15.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.14.0...v0.15.0 | ||||||
|  | [v0.14.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.13.0...v0.14.0 | ||||||
|  | [v0.13.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.12.0...v0.13.0 | ||||||
|  | [v0.12.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.11.0...v0.12.0 | ||||||
|  | [v0.11.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.10.0...v0.11.0 | ||||||
|  | [v0.10.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.9.0...v0.10.0 | ||||||
|  | [v0.9.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.8.0...v0.9.0 | ||||||
|  | [v0.8.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.7.0...v0.8.0 | ||||||
|  | [v0.7.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.6.0...v0.7.0 | ||||||
|  | [v0.6.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.5.0...v0.6.0 | ||||||
|  | [v0.5.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.4.0...v0.5.0 | ||||||
|  | [v0.4.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.3.0...v0.4.0 | ||||||
|  | [v0.3.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.2.11...v0.3.0 | ||||||
|  | [v0.2.11]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.2.10...v0.2.11 | ||||||
|  | [v0.2.10]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.2.9...v0.2.10 | ||||||
|  | [v0.2.9]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.2.8...v0.2.9 | ||||||
|  | [v0.2.8]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.2.7...v0.2.8 | ||||||
|  | [v0.2.7]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.2.6...v0.2.7 | ||||||
|  | [v0.2.6]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.2.5...v0.2.6 | ||||||
|  | [v0.2.5]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.2.4...v0.2.5 | ||||||
|  | [v0.2.4]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.2.3...v0.2.4 | ||||||
|  | [v0.2.3]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.2.2...v0.2.3 | ||||||
|  | [v0.2.2]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.2.1...v0.2.2 | ||||||
|  | [v0.2.1]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.2.0...v0.2.1 | ||||||
|  | [v0.2.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.1.0...v0.2.0 | ||||||
|  | [v0.1.0]: https://gitlab.com/Earthnuker/ed_lrr/compare/v0.0.0...v0.1.0 | ||||||
							
								
								
									
										825
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							
							
						
						
									
										825
									
								
								Cargo.lock
									
										
									
										generated
									
									
									
								
							|  | @ -1,825 +0,0 @@ | ||||||
| # This file is automatically @generated by Cargo. |  | ||||||
| # It is not intended for manual editing. |  | ||||||
| [[package]] |  | ||||||
| name = "aho-corasick" |  | ||||||
| version = "0.7.3" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "ansi_term" |  | ||||||
| version = "0.11.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "atty" |  | ||||||
| version = "0.2.11" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "termion 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "autocfg" |  | ||||||
| version = "0.1.4" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "bincode" |  | ||||||
| version = "1.1.4" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "bitflags" |  | ||||||
| version = "1.1.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "block-buffer" |  | ||||||
| version = "0.7.3" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "block-padding" |  | ||||||
| version = "0.1.4" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "bstr" |  | ||||||
| version = "0.2.1" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "regex-automata 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "byte-tools" |  | ||||||
| version = "0.3.1" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "byteorder" |  | ||||||
| version = "1.3.2" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "cfg-if" |  | ||||||
| version = "0.1.9" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "clap" |  | ||||||
| version = "2.33.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "clicolors-control" |  | ||||||
| version = "1.0.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "cloudabi" |  | ||||||
| version = "0.0.3" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "console" |  | ||||||
| version = "0.7.7" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "clicolors-control 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "encode_unicode 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "regex 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "csv" |  | ||||||
| version = "1.1.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "bstr 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "csv-core" |  | ||||||
| version = "0.1.6" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "digest" |  | ||||||
| version = "0.8.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "ed_lrr" |  | ||||||
| version = "0.1.0" |  | ||||||
| dependencies = [ |  | ||||||
|  "bincode 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "csv 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "indicatif 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "permutohedron 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "rstar 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "serde_derive 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "either" |  | ||||||
| version = "1.5.2" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "encode_unicode" |  | ||||||
| version = "0.3.5" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "fnv" |  | ||||||
| version = "1.0.6" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "fuchsia-cprng" |  | ||||||
| version = "0.1.1" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "generic-array" |  | ||||||
| version = "0.12.3" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "heck" |  | ||||||
| version = "0.3.1" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "humantime" |  | ||||||
| version = "1.2.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "indicatif" |  | ||||||
| version = "0.11.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "console 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "number_prefix 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "regex 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "itertools" |  | ||||||
| version = "0.8.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "itoa" |  | ||||||
| version = "0.4.4" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "keccak" |  | ||||||
| version = "0.1.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "lazy_static" |  | ||||||
| version = "1.3.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "libc" |  | ||||||
| version = "0.2.58" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "lock_api" |  | ||||||
| version = "0.2.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "memchr" |  | ||||||
| version = "2.2.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "num-traits" |  | ||||||
| version = "0.2.8" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "number_prefix" |  | ||||||
| version = "0.2.8" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "numtoa" |  | ||||||
| version = "0.1.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "opaque-debug" |  | ||||||
| version = "0.2.2" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "parking_lot" |  | ||||||
| version = "0.8.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "parking_lot_core" |  | ||||||
| version = "0.5.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "pdqselect" |  | ||||||
| version = "0.1.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "permutohedron" |  | ||||||
| version = "0.2.4" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "proc-macro2" |  | ||||||
| version = "0.4.30" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "quick-error" |  | ||||||
| version = "1.2.2" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "quote" |  | ||||||
| version = "0.6.12" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "rand" |  | ||||||
| version = "0.6.5" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "rand_chacha" |  | ||||||
| version = "0.1.1" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "rand_core" |  | ||||||
| version = "0.3.1" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "rand_core" |  | ||||||
| version = "0.4.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "rand_hc" |  | ||||||
| version = "0.1.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "rand_isaac" |  | ||||||
| version = "0.1.1" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "rand_jitter" |  | ||||||
| version = "0.1.4" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "rand_os" |  | ||||||
| version = "0.1.3" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "rand_pcg" |  | ||||||
| version = "0.1.2" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "rand_xorshift" |  | ||||||
| version = "0.1.1" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "rdrand" |  | ||||||
| version = "0.4.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "redox_syscall" |  | ||||||
| version = "0.1.54" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "redox_termios" |  | ||||||
| version = "0.1.1" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "regex" |  | ||||||
| version = "1.1.7" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "regex-syntax 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "regex-automata" |  | ||||||
| version = "0.1.7" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "regex-syntax" |  | ||||||
| version = "0.6.7" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "rstar" |  | ||||||
| version = "0.4.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "pdqselect 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "rustc_version" |  | ||||||
| version = "0.2.3" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "ryu" |  | ||||||
| version = "0.2.8" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "ryu" |  | ||||||
| version = "1.0.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "scopeguard" |  | ||||||
| version = "1.0.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "semver" |  | ||||||
| version = "0.9.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "semver-parser" |  | ||||||
| version = "0.7.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "serde" |  | ||||||
| version = "1.0.94" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "serde_derive 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "serde_derive" |  | ||||||
| version = "1.0.94" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "serde_json" |  | ||||||
| version = "1.0.39" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "sha3" |  | ||||||
| version = "0.8.2" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "smallvec" |  | ||||||
| version = "0.6.10" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "strsim" |  | ||||||
| version = "0.8.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "structopt" |  | ||||||
| version = "0.2.18" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "structopt-derive" |  | ||||||
| version = "0.2.18" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "syn" |  | ||||||
| version = "0.15.39" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "termion" |  | ||||||
| version = "1.5.3" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "termios" |  | ||||||
| version = "0.3.1" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "textwrap" |  | ||||||
| version = "0.11.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "thread_local" |  | ||||||
| version = "0.3.6" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "typenum" |  | ||||||
| version = "1.10.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "ucd-util" |  | ||||||
| version = "0.1.3" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "unicode-segmentation" |  | ||||||
| version = "1.3.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "unicode-width" |  | ||||||
| version = "0.1.5" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "unicode-xid" |  | ||||||
| version = "0.1.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "utf8-ranges" |  | ||||||
| version = "1.0.3" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "vec_map" |  | ||||||
| version = "0.8.1" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "winapi" |  | ||||||
| version = "0.3.7" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| dependencies = [ |  | ||||||
|  "winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
|  "winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", |  | ||||||
| ] |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "winapi-i686-pc-windows-gnu" |  | ||||||
| version = "0.4.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [[package]] |  | ||||||
| name = "winapi-x86_64-pc-windows-gnu" |  | ||||||
| version = "0.4.0" |  | ||||||
| source = "registry+https://github.com/rust-lang/crates.io-index" |  | ||||||
| 
 |  | ||||||
| [metadata] |  | ||||||
| "checksum aho-corasick 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e6f484ae0c99fec2e858eb6134949117399f222608d84cadb3f58c1f97c2364c" |  | ||||||
| "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" |  | ||||||
| "checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652" |  | ||||||
| "checksum autocfg 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0e49efa51329a5fd37e7c79db4621af617cd4e3e5bc224939808d076077077bf" |  | ||||||
| "checksum bincode 1.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9f04a5e50dc80b3d5d35320889053637d15011aed5e66b66b37ae798c65da6f7" |  | ||||||
| "checksum bitflags 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3d155346769a6855b86399e9bc3814ab343cd3d62c7e985113d46a0ec3c281fd" |  | ||||||
| "checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" |  | ||||||
| "checksum block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4dc3af3ee2e12f3e5d224e5e1e3d73668abbeb69e566d361f7d5563a4fdf09" |  | ||||||
| "checksum bstr 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc0572e02f76cb335f309b19e0a0d585b4f62788f7d26de2a13a836a637385f" |  | ||||||
| "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" |  | ||||||
| "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" |  | ||||||
| "checksum cfg-if 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "b486ce3ccf7ffd79fdeb678eac06a9e6c09fc88d33836340becb8fffe87c5e33" |  | ||||||
| "checksum clap 2.33.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" |  | ||||||
| "checksum clicolors-control 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "73abfd4c73d003a674ce5d2933fca6ce6c42480ea84a5ffe0a2dc39ed56300f9" |  | ||||||
| "checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f" |  | ||||||
| "checksum console 0.7.7 (registry+https://github.com/rust-lang/crates.io-index)" = "8ca57c2c14b8a2bf3105bc9d15574aad80babf6a9c44b1058034cdf8bd169628" |  | ||||||
| "checksum csv 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a54cd62557f353f140b42305fb4efcff2ae08e32fbabaf5b0929423000febb63" |  | ||||||
| "checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c" |  | ||||||
| "checksum digest 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "05f47366984d3ad862010e22c7ce81a7dbcaebbdfb37241a620f8b6596ee135c" |  | ||||||
| "checksum either 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5527cfe0d098f36e3f8839852688e63c8fff1c90b2b405aef730615f9a7bcf7b" |  | ||||||
| "checksum encode_unicode 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "90b2c9496c001e8cb61827acdefad780795c42264c137744cae6f7d9e3450abd" |  | ||||||
| "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" |  | ||||||
| "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" |  | ||||||
| "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" |  | ||||||
| "checksum heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" |  | ||||||
| "checksum humantime 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3ca7e5f2e110db35f93b837c81797f3714500b81d517bf20c431b16d3ca4f114" |  | ||||||
| "checksum indicatif 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2c60da1c9abea75996b70a931bba6c750730399005b61ccd853cee50ef3d0d0c" |  | ||||||
| "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" |  | ||||||
| "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" |  | ||||||
| "checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" |  | ||||||
| "checksum lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "bc5729f27f159ddd61f4df6228e827e86643d4d3e7c32183cb30a1c08f604a14" |  | ||||||
| "checksum libc 0.2.58 (registry+https://github.com/rust-lang/crates.io-index)" = "6281b86796ba5e4366000be6e9e18bf35580adf9e63fbe2294aadb587613a319" |  | ||||||
| "checksum lock_api 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ed946d4529956a20f2d63ebe1b69996d5a2137c91913fe3ebbeff957f5bca7ff" |  | ||||||
| "checksum memchr 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2efc7bc57c883d4a4d6e3246905283d8dae951bb3bd32f49d6ef297f546e1c39" |  | ||||||
| "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" |  | ||||||
| "checksum number_prefix 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dbf9993e59c894e3c08aa1c2712914e9e6bf1fcbfc6bef283e2183df345a4fee" |  | ||||||
| "checksum numtoa 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8f8bdf33df195859076e54ab11ee78a1b208382d3a26ec40d142ffc1ecc49ef" |  | ||||||
| "checksum opaque-debug 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "93f5bb2e8e8dec81642920ccff6b61f1eb94fa3020c5a325c9851ff604152409" |  | ||||||
| "checksum parking_lot 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fa7767817701cce701d5585b9c4db3cdd02086398322c1d7e8bf5094a96a2ce7" |  | ||||||
| "checksum parking_lot_core 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "cb88cb1cb3790baa6776844f968fea3be44956cf184fa1be5a03341f5491278c" |  | ||||||
| "checksum pdqselect 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ec91767ecc0a0bbe558ce8c9da33c068066c57ecc8bb8477ef8c1ad3ef77c27" |  | ||||||
| "checksum permutohedron 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b687ff7b5da449d39e418ad391e5e08da53ec334903ddbb921db208908fc372c" |  | ||||||
| "checksum proc-macro2 0.4.30 (registry+https://github.com/rust-lang/crates.io-index)" = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" |  | ||||||
| "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" |  | ||||||
| "checksum quote 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "faf4799c5d274f3868a4aae320a0a182cbd2baee377b378f080e16a23e9d80db" |  | ||||||
| "checksum rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca" |  | ||||||
| "checksum rand_chacha 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef" |  | ||||||
| "checksum rand_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" |  | ||||||
| "checksum rand_core 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d0e7a549d590831370895ab7ba4ea0c1b6b011d106b5ff2da6eee112615e6dc0" |  | ||||||
| "checksum rand_hc 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7b40677c7be09ae76218dc623efbf7b18e34bced3f38883af07bb75630a21bc4" |  | ||||||
| "checksum rand_isaac 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ded997c9d5f13925be2a6fd7e66bf1872597f759fd9dd93513dd7e92e5a5ee08" |  | ||||||
| "checksum rand_jitter 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "1166d5c91dc97b88d1decc3285bb0a99ed84b05cfd0bc2341bdf2d43fc41e39b" |  | ||||||
| "checksum rand_os 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7b75f676a1e053fc562eafbb47838d67c84801e38fc1ba459e8f180deabd5071" |  | ||||||
| "checksum rand_pcg 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44" |  | ||||||
| "checksum rand_xorshift 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cbf7e9e623549b0e21f6e97cf8ecf247c1a8fd2e8a992ae265314300b2455d5c" |  | ||||||
| "checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" |  | ||||||
| "checksum redox_syscall 0.1.54 (registry+https://github.com/rust-lang/crates.io-index)" = "12229c14a0f65c4f1cb046a3b52047cdd9da1f4b30f8a39c5063c8bae515e252" |  | ||||||
| "checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76" |  | ||||||
| "checksum regex 1.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "0b2f0808e7d7e4fb1cb07feb6ff2f4bc827938f24f8c2e6a3beb7370af544bdd" |  | ||||||
| "checksum regex-automata 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "3ed09217220c272b29ef237a974ad58515bde75f194e3ffa7e6d0bf0f3b01f86" |  | ||||||
| "checksum regex-syntax 0.6.7 (registry+https://github.com/rust-lang/crates.io-index)" = "9d76410686f9e3a17f06128962e0ecc5755870bb890c34820c7af7f1db2e1d48" |  | ||||||
| "checksum rstar 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd08ae4f9661517777346592956ea6cdbba2895a28037af7daa600382f4b4001" |  | ||||||
| "checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" |  | ||||||
| "checksum ryu 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "b96a9549dc8d48f2c283938303c4b5a77aa29bfbc5b54b084fb1630408899a8f" |  | ||||||
| "checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" |  | ||||||
| "checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d" |  | ||||||
| "checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" |  | ||||||
| "checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" |  | ||||||
| "checksum serde 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)" = "076a696fdea89c19d3baed462576b8f6d663064414b5c793642da8dfeb99475b" |  | ||||||
| "checksum serde_derive 1.0.94 (registry+https://github.com/rust-lang/crates.io-index)" = "ef45eb79d6463b22f5f9e16d283798b7c0175ba6050bc25c1a946c122727fe7b" |  | ||||||
| "checksum serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)" = "5a23aa71d4a4d43fdbfaac00eff68ba8a06a51759a89ac3304323e800c4dd40d" |  | ||||||
| "checksum sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf" |  | ||||||
| "checksum smallvec 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "ab606a9c5e214920bb66c458cd7be8ef094f813f20fe77a54cc7dbfff220d4b7" |  | ||||||
| "checksum strsim 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" |  | ||||||
| "checksum structopt 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "16c2cdbf9cc375f15d1b4141bc48aeef444806655cd0e904207edc8d68d86ed7" |  | ||||||
| "checksum structopt-derive 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "53010261a84b37689f9ed7d395165029f9cc7abb9f56bbfe86bee2597ed25107" |  | ||||||
| "checksum syn 0.15.39 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d960b829a55e56db167e861ddb43602c003c7be0bee1d345021703fac2fb7c" |  | ||||||
| "checksum termion 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6a8fb22f7cde82c8220e5aeacb3258ed7ce996142c77cba193f203515e26c330" |  | ||||||
| "checksum termios 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "72b620c5ea021d75a735c943269bb07d30c9b77d6ac6b236bc8b5c496ef05625" |  | ||||||
| "checksum textwrap 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" |  | ||||||
| "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" |  | ||||||
| "checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169" |  | ||||||
| "checksum ucd-util 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "535c204ee4d8434478593480b8f86ab45ec9aae0e83c568ca81abf0fd0e88f86" |  | ||||||
| "checksum unicode-segmentation 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1967f4cdfc355b37fd76d2a954fb2ed3871034eb4f26d60537d88795cfc332a9" |  | ||||||
| "checksum unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "882386231c45df4700b275c7ff55b6f3698780a650026380e72dabe76fa46526" |  | ||||||
| "checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" |  | ||||||
| "checksum utf8-ranges 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9d50aa7650df78abf942826607c62468ce18d9019673d4a2ebe1865dbb96ffde" |  | ||||||
| "checksum vec_map 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" |  | ||||||
| "checksum winapi 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "f10e386af2b13e47c89e7236a7a14a086791a2b88ebad6df9bf42040195cf770" |  | ||||||
| "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" |  | ||||||
| "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" |  | ||||||
							
								
								
									
										26
									
								
								Cargo.toml
									
										
									
									
									
								
							
							
						
						
									
										26
									
								
								Cargo.toml
									
										
									
									
									
								
							|  | @ -1,26 +0,0 @@ | ||||||
| [package] |  | ||||||
| name = "ed_lrr" |  | ||||||
| version = "0.1.0" |  | ||||||
| authors = ["Daniel Seiller <earthnuker@gmail.com>"] |  | ||||||
| edition = "2018" |  | ||||||
| repository = "https://gitlab.com/Earthnuker/ed_lrr.git" |  | ||||||
| license = "WTFPL" |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| [profile.release] |  | ||||||
| # debug=true |  | ||||||
| 
 |  | ||||||
| [dependencies] |  | ||||||
| csv = "1.1.0" |  | ||||||
| serde = "1.0.94" |  | ||||||
| serde_derive = "1.0.94" |  | ||||||
| rstar = {version="0.4.0",features=["serde"]} |  | ||||||
| humantime = "1.2.0" |  | ||||||
| structopt = "0.2.18" |  | ||||||
| permutohedron = "0.2.4" |  | ||||||
| serde_json = "1.0.39" |  | ||||||
| indicatif = "0.11.0" |  | ||||||
| fnv = "1.0.6" |  | ||||||
| bincode = "1.1.4" |  | ||||||
| sha3 = "0.8.2" |  | ||||||
| byteorder = "1.3.2" |  | ||||||
							
								
								
									
										21
									
								
								LICENSE
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								LICENSE
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,21 @@ | ||||||
|  | MIT License | ||||||
|  | 
 | ||||||
|  | Copyright (c) 2019 Daniel Seiller | ||||||
|  | 
 | ||||||
|  | Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  | of this software and associated documentation files (the "Software"), to deal | ||||||
|  | in the Software without restriction, including without limitation the rights | ||||||
|  | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  | copies of the Software, and to permit persons to whom the Software is | ||||||
|  | furnished to do so, subject to the following conditions: | ||||||
|  | 
 | ||||||
|  | The above copyright notice and this permission notice shall be included in all | ||||||
|  | copies or substantial portions of the Software. | ||||||
|  | 
 | ||||||
|  | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||||
|  | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||||
|  | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||||
|  | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||||
|  | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||||
|  | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||||
|  | SOFTWARE. | ||||||
							
								
								
									
										3
									
								
								MANIFEST.in
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								MANIFEST.in
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,3 @@ | ||||||
|  | include rust/Cargo.toml | ||||||
|  | include rust/.cargo/config | ||||||
|  | recursive-include rust/src * | ||||||
							
								
								
									
										90
									
								
								README.md
									
										
									
									
									
								
							
							
						
						
									
										90
									
								
								README.md
									
										
									
									
									
								
							|  | @ -1,20 +1,82 @@ | ||||||
| # Elite: Dangerous Long Range Router (Rust Version) | # Elite: Dangerous Long-range router | ||||||
| 
 | 
 | ||||||
| ## Usage: | ## Features | ||||||
| 
 | 
 | ||||||
| 1. download `bodies.json` and `systemsWithCoordinates.json` from https://www.edsm.net/en/nightly-dumps/ and place them in the `dumps` folder | - Three different routing algorithms: | ||||||
| 2. run `cargo +nightly install --path .` or `cargo +nightly install --git https://gitlab.com/Earthnuker/ed_lrr.git` |   - **Breadth-first search:**, always finds the shortest route but is quite slow | ||||||
| 3. run `ed_lrr_pp --bodies dumps/bodies.json --systems dumps/systemsWithCoordinates.json` |   - **A-Star:** has an adjustable tradeoff between speed and quality | ||||||
|     - Alternatively run `process.py` in the `dumps` folder |   - **Greedy search:** always picks the next reachable star that's closest to the destination, very fast but very poor quality routes | ||||||
| 4. run `ed_lrr --help` | - Nice GUI! (made with PyQt5) | ||||||
|  | - Two themes! (Dark and Light) | ||||||
|  | - Uses data from (EDSM)[https://edsm.net/] for star data | ||||||
|  | - Only routes through scoopable systems, no more running out of fuel! (assuming you have a fuel scoop) | ||||||
|  | - Precomputing of BFS routing graphs for near-instant routing from your home system to any destination! | ||||||
|  | - Routing code written in Rust, so it's quite speedy! | ||||||
|  | - Export routes as HTML, JSON, CSV and SVG (WIP!) | ||||||
|  | - Automagically copy next jump destination into system clipboard (works by monitoring the player journal file) | ||||||
| 
 | 
 | ||||||
|  | # Installation | ||||||
| 
 | 
 | ||||||
|  | ## Prerequisites | ||||||
| 
 | 
 | ||||||
| ## Dependencies | - Python: | ||||||
|  |   - conda (miniconda/anaconda) | ||||||
|  |   - tox (`conda install tox`) | ||||||
|  |   - Inno Setup Compiler | ||||||
|  |     - Download from [here](http://www.jrsoftware.org/isdl.php) | ||||||
|  |     - or install via [scoop](https://scoop.sh/) `scoop install inno-setup`) | ||||||
|  | - Visual Studio 2019 | ||||||
|  | - nightly rust compiler (`x86_64-pc-windows-msvc`) | ||||||
| 
 | 
 | ||||||
| - Working nightly Rust Compiler (tested with `rustc 1.37.0-nightly (5d8f59f4b 2019-06-04)`) | ## Building an installer | ||||||
| - ~8GB of free RAM | 
 | ||||||
| - Optional: | (Assuming `conda` is in your `PATH`) | ||||||
|   - Python 3.7 | 
 | ||||||
|   - Pandas | 1. Start a Visual Studio 2019 x64 command prompt | ||||||
|   - uJSON | 2. Run `tox` | ||||||
|  | 3. Grab the installer from `installer/Output/` | ||||||
|  | 
 | ||||||
|  | ## Manual installation | ||||||
|  | 
 | ||||||
|  | (Assuming `conda` is in your `PATH`) | ||||||
|  | 
 | ||||||
|  | 1. Start a Visual Studio 2019 x64 command prompt | ||||||
|  | 2. Run the following commands: | ||||||
|  | 
 | ||||||
|  | ``` | ||||||
|  | conda install pycrypto nuitka | ||||||
|  | pip install PyQt5 setuptools_rust | ||||||
|  | python build_gui.py | ||||||
|  | pip install . | ||||||
|  | ``` | ||||||
|  | 
 | ||||||
|  | then you can run `ed_lrr -h` from your command prompt to get help | ||||||
|  | 
 | ||||||
|  | # To do | ||||||
|  | 
 | ||||||
|  | ## Router | ||||||
|  | 
 | ||||||
|  | - Caching wrapper for System | ||||||
|  |   - Only fetch position once when building Spatial-Tree | ||||||
|  |   - Fetch data on demand | ||||||
|  | 
 | ||||||
|  | ## GUI | ||||||
|  | 
 | ||||||
|  | - Implement estimate time to completion display for route computation and preprocessing | ||||||
|  | - Export route as: | ||||||
|  |   - JSON | ||||||
|  |   - HTML (WIP) | ||||||
|  |   - CSV | ||||||
|  |   - SVG | ||||||
|  | 
 | ||||||
|  | ## Installer | ||||||
|  | 
 | ||||||
|  | - Update PATH from installer | ||||||
|  | 
 | ||||||
|  | ## Preprocessing | ||||||
|  | 
 | ||||||
|  | - Build index over `systemsWithCoordinates.json` instead of loading it into RAM (reuse modified `LineCache` from `router.rs`) | ||||||
|  | 
 | ||||||
|  | ## Misc | ||||||
|  | 
 | ||||||
|  | - Luigi based Task queue for distributed routing | ||||||
							
								
								
									
										43
									
								
								appveyor.yml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								appveyor.yml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,43 @@ | ||||||
|  | image: Visual Studio 2019 | ||||||
|  | platform: x64 | ||||||
|  | version: 0.1.{build} | ||||||
|  | branches: | ||||||
|  |   only: | ||||||
|  |   - pyqt_gui | ||||||
|  | 
 | ||||||
|  | environment: | ||||||
|  |   VCVARS: C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat | ||||||
|  |   VCVARSARG: x64 | ||||||
|  |   MINICONDA: C:\Miniconda3-x64 | ||||||
|  |   INNO: C:\Program Files (x86)\Inno Setup 6 | ||||||
|  | 
 | ||||||
|  | build: off | ||||||
|  | 
 | ||||||
|  | artifacts: | ||||||
|  |   - path: exe\__main__.dist\ | ||||||
|  |     name: ED_LRR | ||||||
|  |     type: zip | ||||||
|  | 
 | ||||||
|  |   - path: installer\Output\*.exe | ||||||
|  |     name: Setup | ||||||
|  |     type: file | ||||||
|  | 
 | ||||||
|  | install: | ||||||
|  |   - set PATH=%MINICONDA%\\Library\\bin;%MINICONDA%\\Scripts;%USERPROFILE%\\.cargo\\bin;%PATH% | ||||||
|  |   - set PATH=%INNO%;%PATH% | ||||||
|  |   - appveyor DownloadFile https://win.rustup.rs/ -FileName rustup-init.exe | ||||||
|  |   - rustup-init -y --default-toolchain nightly --default-host x86_64-pc-windows-msvc | ||||||
|  |   - if defined VCVARS call "%VCVARS%" %VCVARSARG% | ||||||
|  |   - conda activate | ||||||
|  |   - conda update -y -n base -c defaults conda | ||||||
|  |   - conda install -y -c conda-forge pycrypto nuitka | ||||||
|  |   - pip install PyQt5 setuptools_rust | ||||||
|  | 
 | ||||||
|  | test_script: | ||||||
|  |   - python build_gui.py | ||||||
|  |   - pip install .[dev] | ||||||
|  |   - python -m nuitka --plugin-enable=multiprocessing --remove-output --plugin-enable=qt-plugins --standalone --assume-yes-for-downloads --follow-imports --output-dir=exe ed_lrr_gui\__main__.py | ||||||
|  |   - rename exe\__main__.dist\__main__.exe ED_LRR.exe | ||||||
|  |   - cd installer | ||||||
|  |   - iscc /QP ED_LRR.iss | ||||||
|  | 
 | ||||||
							
								
								
									
										16
									
								
								build_gui.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								build_gui.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,16 @@ | ||||||
|  | import subprocess as SP | ||||||
|  | from glob import glob | ||||||
|  | import os | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | ui_path = os.path.dirname(os.path.abspath(__file__)) | ||||||
|  | for root, folders, files in os.walk(ui_path): | ||||||
|  |     if ".history" in folders: | ||||||
|  |         folders.remove(".history") | ||||||
|  |     for file in files: | ||||||
|  |         file = os.path.join(root, file) | ||||||
|  |         outfile, ext = os.path.splitext(file) | ||||||
|  |         if ext == ".ui": | ||||||
|  |             outfile = outfile + ".py" | ||||||
|  |             print(file, "->", outfile) | ||||||
|  |             SP.check_call(["pyuic5", "--from-imports", "-o", outfile, file]) | ||||||
							
								
								
									
										11
									
								
								docs/.vscode/settings.json
									
										
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								docs/.vscode/settings.json
									
										
									
									
										vendored
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | ||||||
|  | { | ||||||
|  |     "spellright.language": [ | ||||||
|  |         "de", | ||||||
|  |         "en" | ||||||
|  |     ], | ||||||
|  |     "spellright.documentTypes": [ | ||||||
|  |         "markdown", | ||||||
|  |         "latex", | ||||||
|  |         "plaintext" | ||||||
|  |     ] | ||||||
|  | } | ||||||
							
								
								
									
										48
									
								
								docs/Makefile
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								docs/Makefile
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,48 @@ | ||||||
|  | MD = $(wildcard src/*.md) | ||||||
|  | DOTS = $(wildcard src/*.dot) | ||||||
|  | ASYS = $(wildcard src/*.asy) | ||||||
|  | PYS = $(wildcard src/img_*.py) | ||||||
|  | PDFS = $(MD:src/%.md=out/%.pdf) | ||||||
|  | 
 | ||||||
|  | IMG_PDFS = $(ASYS:src/%.asy=img/%.pdf) $(PYS:src/img_%.py=img/%.pdf) $(DOTS:src/%.dot=img/%.pdf) | ||||||
|  | 
 | ||||||
|  | IMGS = $(IMG_PDFS) | ||||||
|  | 
 | ||||||
|  | TEMPLATE = eisvogel | ||||||
|  | PDF_ENGINE = xelatex | ||||||
|  | PANDOC = pandoc | ||||||
|  | PANDOC_OPTIONS = -F panflute -F pandoc-citeproc --pdf-engine=$(PDF_ENGINE) --template $(TEMPLATE) -N --standalone --listings | ||||||
|  | 
 | ||||||
|  | GRAPHVIZ = dot | ||||||
|  | GRAPHVIZ_OPTIONS = -Tpdf | ||||||
|  | 
 | ||||||
|  | ASY = asy | ||||||
|  | ASY_OPTIONS = -noV -f pdf | ||||||
|  | 
 | ||||||
|  | PYTHON = python | ||||||
|  | PYTHON_OPTIONS = | ||||||
|  | 
 | ||||||
|  | mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST))) | ||||||
|  | current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path)))) | ||||||
|  | 
 | ||||||
|  | .PHONY: clean all default | ||||||
|  | all: $(PDFS) | ||||||
|  | default: all | ||||||
|  | 
 | ||||||
|  | out/%.pdf: src/%.md $(IMGS) Makefile | ||||||
|  | 	$(PANDOC) $(PANDOC_OPTIONS) -o $@ $< | ||||||
|  | 
 | ||||||
|  | img/%.pdf: src/%.dot | ||||||
|  | 	$(GRAPHVIZ) $(GRAPHVIZ_OPTIONS) -o $@ $< | ||||||
|  | 
 | ||||||
|  | img/%.pdf: src/img_%.py | ||||||
|  | 	$(PYTHON) $(PYTHON_OPTIONS) $< $@ | ||||||
|  | 
 | ||||||
|  | img/%.pdf: src/%.asy | ||||||
|  | 	$(ASY) $(ASY_OPTIONS) -o $@ $< | ||||||
|  | 
 | ||||||
|  | watch: | ||||||
|  | 	watchexec -w src -w data -w filters -w Makefile make all | ||||||
|  | 
 | ||||||
|  | clean: | ||||||
|  | 	-rm $(PDFS) $(IMGS) | ||||||
							
								
								
									
										157
									
								
								docs/filters/multifilter.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								docs/filters/multifilter.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,157 @@ | ||||||
|  | import contextlib | ||||||
|  | import csv | ||||||
|  | import datetime | ||||||
|  | import hashlib | ||||||
|  | import io | ||||||
|  | import os | ||||||
|  | import re | ||||||
|  | import subprocess as SP | ||||||
|  | import sys | ||||||
|  | import tempfile | ||||||
|  | from functools import partial | ||||||
|  | 
 | ||||||
|  | import panflute as pf | ||||||
|  | from dateutil.parser import parse as dateparse | ||||||
|  | from jinja2 import Environment, PackageLoader, Template, select_autoescape | ||||||
|  | from panflute import * | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def remove_pound(elem, doc): | ||||||
|  |     if type(elem) == Str: | ||||||
|  |         return Str(elem.text.lstrip("#")) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def fix_color(elem, doc): | ||||||
|  |     if type(elem) == MetaMap: | ||||||
|  |         for k in elem.content: | ||||||
|  |             if k.endswith("-color"): | ||||||
|  |                 elem[k] = elem[k].walk(remove_pound) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def update_date(elem, doc): | ||||||
|  |     if type(elem) == MetaMap: | ||||||
|  |         datefmt = doc.get_metadata("datefmt", "%Y-%m-%d") | ||||||
|  |         today = datetime.date.today().strftime(datefmt) | ||||||
|  |         date = dateparse(doc.get_metadata("date", today)).date() | ||||||
|  |         elem["date"] = MetaInlines(Str(date.strftime(datefmt))) | ||||||
|  |         return elem | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def csv_table(elem, doc): | ||||||
|  |     if type(elem) == Para and len(elem.content) == 1 and type(elem.content[0]) == Image: | ||||||
|  |         elem = elem.content[0] | ||||||
|  |         ext = os.path.splitext(elem.url)[1][1:] | ||||||
|  |         if ext == "csv": | ||||||
|  |             caption = elem.content | ||||||
|  |             has_header = elem.attributes.get("has-header", "false").lower() == "true" | ||||||
|  |             with open(elem.url) as f: | ||||||
|  |                 reader = csv.reader(f) | ||||||
|  |                 body = [] | ||||||
|  |                 for row in reader: | ||||||
|  |                     cells = [TableCell(Plain(Str(x))) for x in row] | ||||||
|  |                     body.append(TableRow(*cells)) | ||||||
|  |             header = body.pop(0) if has_header else None | ||||||
|  |             ret = Table(*body, header=header, caption=caption) | ||||||
|  |             return ret | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def code_refs(elem, doc): | ||||||
|  |     if type(elem) == Cite: | ||||||
|  |         label = elem.content[0] | ||||||
|  |         if type(label) == Str: | ||||||
|  |             label = label.text | ||||||
|  |             filename = re.findall(r"^\[@lst:(.*)\]$", label) or [None] | ||||||
|  |             if filename[0] in doc.inc_files: | ||||||
|  |                 return [ | ||||||
|  |                     RawInline( | ||||||
|  |                         "\\hyperref[{}]{{{}}}".format(filename[0], filename[0]), | ||||||
|  |                         format="tex", | ||||||
|  |                     ) | ||||||
|  |                 ] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def include_code(elem, doc): | ||||||
|  |     if type(elem) == CodeBlock: | ||||||
|  |         if "include" in elem.attributes: | ||||||
|  |             filepath = elem.attributes.pop("include") | ||||||
|  |             filename = os.path.split(filepath)[-1] | ||||||
|  |             try: | ||||||
|  |                 elem.text += elem.text + open(filepath, encoding="utf-8").read() | ||||||
|  |                 elem.attributes["caption"] = filename | ||||||
|  |                 doc.inc_files.append(filename) | ||||||
|  |             except Exception as e: | ||||||
|  |                 elem.text += "Error: {}".format(e) | ||||||
|  |             return [RawBlock("\\label{{{}}}".format(filename), format="tex"), elem] | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def py_eval(options, data, element, doc): | ||||||
|  |     out_buffer = io.StringIO() | ||||||
|  |     with contextlib.redirect_stdout(out_buffer): | ||||||
|  |         exec(data, doc.pyenv) | ||||||
|  |     out_buffer.seek(0) | ||||||
|  |     return convert_text(out_buffer.read()) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def jinja_py_filt(doc, file): | ||||||
|  |     env = {} | ||||||
|  |     code = open(file, encoding="utf-8").read() | ||||||
|  |     exec(code, env) | ||||||
|  |     return env["main"](doc) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def prepare(doc): | ||||||
|  |     doc.inc_files = [] | ||||||
|  |     doc.env = Environment() | ||||||
|  |     doc.pyenv = {} | ||||||
|  |     filters = {"py": partial(jinja_py_filt, doc)} | ||||||
|  |     doc.env.filters.update(filters) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def process_templates(elem, doc): | ||||||
|  |     if type(elem) == CodeBlock: | ||||||
|  |         if elem.classes == ["@"]: | ||||||
|  |             args = {"meta": doc.get_metadata()} | ||||||
|  |             return convert_text(doc.env.from_string(elem.text).render(args)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def yaml_filt(elem, doc): | ||||||
|  |     tags = {"eval": py_eval} | ||||||
|  |     return yaml_filter(elem, doc, tags=tags, strict_yaml=True) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def checkboxes(elem, doc): | ||||||
|  |     if type(elem) in [Para, Plain]: | ||||||
|  |         val = re.findall(r"^\[([xX]|\ )\] (.*)$", stringify(elem)) | ||||||
|  |         if val: | ||||||
|  |             val = val[0][0].lower() == "x" | ||||||
|  |         else: | ||||||
|  |             return elem | ||||||
|  |         marker = { | ||||||
|  |             True: RawInline("$\\boxtimes$", format="latex"), | ||||||
|  |             False: RawInline("$\\square$", format="latex"), | ||||||
|  |         }[val] | ||||||
|  |         cont = [] | ||||||
|  |         if val: | ||||||
|  |             cont += elem.content[2:] | ||||||
|  |         else: | ||||||
|  |             cont += elem.content[4:] | ||||||
|  |         return Plain(marker, Space, *cont) | ||||||
|  |     return elem | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def main(doc=None): | ||||||
|  |     f = [ | ||||||
|  |         process_templates, | ||||||
|  |         update_date, | ||||||
|  |         csv_table, | ||||||
|  |         include_code, | ||||||
|  |         fix_color, | ||||||
|  |         code_refs, | ||||||
|  |         yaml_filt, | ||||||
|  |         checkboxes, | ||||||
|  |     ] | ||||||
|  |     return run_filters(f, prepare=prepare, doc=doc) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     main() | ||||||
							
								
								
									
										92
									
								
								docs/src/ed-lrr.md
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										92
									
								
								docs/src/ed-lrr.md
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,92 @@ | ||||||
|  | --- | ||||||
|  | # Metadata | ||||||
|  | title: ED_LRR | ||||||
|  | author: | ||||||
|  | - Daniel Seiller <earthnuker@gmail.com> | ||||||
|  | subtitle: 'Elite Dangerous: Long-Range Router' | ||||||
|  | 
 | ||||||
|  | # Formating | ||||||
|  | toc: true | ||||||
|  | lang: en | ||||||
|  | colorlinks: true | ||||||
|  | papersize: a4 | ||||||
|  | numbersections: true | ||||||
|  | 
 | ||||||
|  | #Panflute options | ||||||
|  | panflute-filters: [multifilter] | ||||||
|  | panflute-path: 'filters' | ||||||
|  | 
 | ||||||
|  | #Template options | ||||||
|  | titlepage: true | ||||||
|  | toc-own-page: false | ||||||
|  | --- | ||||||
|  | 
 | ||||||
|  | \pagebreak | ||||||
|  | 
 | ||||||
|  | # Implementation | ||||||
|  | 
 | ||||||
|  | ## `stars.csv` format | ||||||
|  | 
 | ||||||
|  | ### Columns | ||||||
|  | 
 | ||||||
|  | | Name      | Content                                                      | | ||||||
|  | | --------- | ------------------------------------------------------------ | | ||||||
|  | | id        | unique ID-Number (not equal to id or id64, just a sequential number) | | ||||||
|  | | star_type | Type of Star                                                 | | ||||||
|  | | system    | Name of System                                               | | ||||||
|  | | body      | Name of Star                                                 | | ||||||
|  | | mult      | Jump Range Multiplier (1.5 for White Dwarfs, 4.0 for Neutron Stars) | | ||||||
|  | | distance  | Distance from arrival in Ls                                  | | ||||||
|  | | x,y,z     | Position in Galactic Coordinates with Sol at (0,0,0)         | | ||||||
|  | 
 | ||||||
|  | ## `stars.idx` format | ||||||
|  | 
 | ||||||
|  | `bincode` serialized data: | ||||||
|  | 
 | ||||||
|  | - **[u64]**: List of byte offset for records (entry 0=first recod, entry 1= second record, etc) | ||||||
|  | 
 | ||||||
|  | ## Routing Algorithms | ||||||
|  | 
 | ||||||
|  | ### Breadth-First Search (BFS) | ||||||
|  | 
 | ||||||
|  | Standard Breadth-First Search, always finds the shortest route | ||||||
|  | 
 | ||||||
|  | ### A*-Search | ||||||
|  | 
 | ||||||
|  | Modified A*-Search with adjustable "greediness". Priority Queue weighted by $\text{number of jumps from start system} + (\text{estimated number of jumps to target system} * \text{greediness})$ | ||||||
|  | 
 | ||||||
|  | A greediness of 0 is equivalent to BFS and a greediness of $\infty$ is equivalent to Greedy-Search | ||||||
|  | 
 | ||||||
|  | ### Greedy-Search | ||||||
|  | 
 | ||||||
|  | Priority Queue weighted by minimum distance to target, prefers systems with high multiplier (Neutron Stars and White Dwarfs) | ||||||
|  | 
 | ||||||
|  | ## Optimizations | ||||||
|  | 
 | ||||||
|  | ### Ellipse elimination | ||||||
|  | 
 | ||||||
|  | Only consider systems within an ellipsoid with source and destination as the foci, the width of the ellipsoid is adjustable | ||||||
|  | 
 | ||||||
|  | ## Routing Graphs | ||||||
|  | 
 | ||||||
|  | ### File format | ||||||
|  | 
 | ||||||
|  | `bincode` serialized data: | ||||||
|  | 
 | ||||||
|  | - *bool* **primary**: flag to indicate that graph only includes primary stars | ||||||
|  | - *f32* **range**: jump range for routing graph | ||||||
|  | - *[u8]* **file_hash**: sha3 hash of `stars.csv` from which graph was generated | ||||||
|  | - *String* **path**: path to `stars.csv` from which graph was generated | ||||||
|  | - *FnvHashMap* **graph**: Hashmap mapping systems to the systems from which they can be rached, traversed from destination system backwards to source to reconstruct route | ||||||
|  | 
 | ||||||
|  | # Usage | ||||||
|  | 
 | ||||||
|  | <!-- | ||||||
|  | TODO: Add screenshots | ||||||
|  | --> | ||||||
|  | 
 | ||||||
|  | ## Preprocessing Data | ||||||
|  | 
 | ||||||
|  | ## Plotting a Route | ||||||
|  | 
 | ||||||
|  | # [Changelog](https://gitlab.com/Earthnuker/ed_lrr/blob/pyqt_gui/CHANGELOG.md) | ||||||
							
								
								
									
										65
									
								
								docs/src/img_out.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								docs/src/img_out.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,65 @@ | ||||||
|  | import heapq | ||||||
|  | import sys | ||||||
|  | 
 | ||||||
|  | import numpy as np | ||||||
|  | import pylab as PL | ||||||
|  | from scipy.spatial.ckdtree import cKDTree | ||||||
|  | 
 | ||||||
|  | exit() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def vec(a, b): | ||||||
|  |     return b - a | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def bfs(points): | ||||||
|  |     return | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def in_ellipse(p, f1, f2, r, offset=0): | ||||||
|  |     df = ((f1 - f2) ** 2).sum(0) ** 0.5 | ||||||
|  |     d_f1 = ((p - f1) ** 2).sum(1) ** 0.5 | ||||||
|  |     d_f2 = ((p - f2) ** 2).sum(1) ** 0.5 | ||||||
|  |     return (d_f1 + d_f2) < (df * (1 + r)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | num_points = 100000 | ||||||
|  | 
 | ||||||
|  | p_orig = np.random.normal(0, 10, size=(num_points, 2)) | ||||||
|  | tree = cKDTree(p_orig) | ||||||
|  | f1 = np.array([0, -30]) | ||||||
|  | f2 = -f1  # np.random.normal(0, 20, (3,)) | ||||||
|  | # r = 2 ** ((n / cnt) - cnt) | ||||||
|  | 
 | ||||||
|  | mask = in_ellipse(p_orig, f1, f2, 0.1) | ||||||
|  | 
 | ||||||
|  | p = p_orig[mask] | ||||||
|  | p_orig = p_orig[~mask] | ||||||
|  | 
 | ||||||
|  | colors = np.random.random(p.shape[0]) | ||||||
|  | fig = PL.gcf() | ||||||
|  | PL.scatter( | ||||||
|  |     p_orig[:, 0], | ||||||
|  |     p_orig[:, 1], | ||||||
|  |     marker=".", | ||||||
|  |     s=0.2, | ||||||
|  |     edgecolor="None", | ||||||
|  |     c=[(0.0, 0.0, 0.0)], | ||||||
|  |     alpha=0.75, | ||||||
|  |     rasterized=True, | ||||||
|  | ) | ||||||
|  | PL.scatter( | ||||||
|  |     p[:, 0], p[:, 1], marker="s", s=0.2, edgecolor="None", c=colors, rasterized=True | ||||||
|  | ) | ||||||
|  | PL.plot(f1[0], f1[1], "r.", label="Source") | ||||||
|  | PL.plot(f2[0], f2[1], "g.", label="Destination") | ||||||
|  | 
 | ||||||
|  | max_v = max(p_orig[:, 0].max(), p_orig[:, 1].max(), f1[0], f1[1], f2[0], f2[1]) + 2 | ||||||
|  | min_v = min(p_orig[:, 0].min(), p_orig[:, 1].min(), f1[0], f1[1], f2[0], f2[1]) - 2 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | PL.xlim(min_v, max_v) | ||||||
|  | PL.ylim(min_v, max_v) | ||||||
|  | 
 | ||||||
|  | PL.legend() | ||||||
|  | PL.savefig(sys.argv[1], dpi=1200) | ||||||
							
								
								
									
										180
									
								
								dumps/process.py
									
										
									
									
									
								
							
							
						
						
									
										180
									
								
								dumps/process.py
									
										
									
									
									
								
							|  | @ -1,180 +0,0 @@ | ||||||
| import ujson as json |  | ||||||
| from tqdm import tqdm |  | ||||||
| from pprint import pprint |  | ||||||
| import itertools as ITT |  | ||||||
| import os |  | ||||||
| import sys |  | ||||||
| import csv |  | ||||||
| import sqlite3 |  | ||||||
| import pandas as pd |  | ||||||
| from urllib.parse import urljoin |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def is_scoopable(entry): |  | ||||||
|     first = entry.type.split()[0] |  | ||||||
|     return first == "Neutron" or first == "White" or first in "KGBFOAM" |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def get_mult(name): |  | ||||||
|     try: |  | ||||||
|         first = name.split()[0] |  | ||||||
|     except: |  | ||||||
|         return 1 |  | ||||||
|     if first == "Neutron": |  | ||||||
|         return 4 |  | ||||||
|     if first == "White": |  | ||||||
|         return 1.5 |  | ||||||
|     return 1 |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def dict_factory(cursor, row): |  | ||||||
|     d = {} |  | ||||||
|     for idx, col in enumerate(cursor.description): |  | ||||||
|         d[col[0]] = row[idx] |  | ||||||
|     return d |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def blocks(files, size=65536): |  | ||||||
|     while True: |  | ||||||
|         b = files.read(size) |  | ||||||
|         if not b: |  | ||||||
|             break |  | ||||||
|         yield b |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def getlines(f, fn, show_progbar=False): |  | ||||||
|     f.seek(0, 2) |  | ||||||
|     size = f.tell() |  | ||||||
|     f.seek(0) |  | ||||||
|     progbar = tqdm( |  | ||||||
|         desc="Processing " + fn, |  | ||||||
|         total=size, |  | ||||||
|         unit="b", |  | ||||||
|         unit_scale=True, |  | ||||||
|         unit_divisor=1024, |  | ||||||
|         ascii=True, |  | ||||||
|         leave=True, |  | ||||||
|         disable=(not show_progbar), |  | ||||||
|     ) |  | ||||||
|     buffer = [] |  | ||||||
|     for block in blocks(f): |  | ||||||
|         progbar.n = f.tell() |  | ||||||
|         progbar.update(0) |  | ||||||
|         if buffer: |  | ||||||
|             buffer += (buffer.pop(0) + block).splitlines(keepends=True) |  | ||||||
|         else: |  | ||||||
|             buffer += block.splitlines(keepends=True) |  | ||||||
|         while buffer and buffer[0].endswith("\n"): |  | ||||||
|             try: |  | ||||||
|                 yield json.loads(buffer.pop(0).strip().rstrip(",")) |  | ||||||
|             except ValueError: |  | ||||||
|                 pass |  | ||||||
|     while buffer: |  | ||||||
|         try: |  | ||||||
|             yield json.loads(buffer.pop(0).strip().rstrip(",")) |  | ||||||
|         except ValueError: |  | ||||||
|             pass |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def process_file(fn, show_progbar=False): |  | ||||||
|     with open(fn, "r") as f: |  | ||||||
|         for line in tqdm( |  | ||||||
|             getlines(f, fn, show_progbar), |  | ||||||
|             desc=fn, |  | ||||||
|             unit=" lines", |  | ||||||
|             unit_scale=True, |  | ||||||
|             ascii=True, |  | ||||||
|             leave=True, |  | ||||||
|             disable=(not show_progbar), |  | ||||||
|         ): |  | ||||||
|             yield line |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| if not ( |  | ||||||
|     os.path.isfile("bodies.json") and os.path.isfile("systemsWithCoordinates.json") |  | ||||||
| ): |  | ||||||
|     exit( |  | ||||||
|         "Please download bodies.json and systemsWithCoordinates.json from https://www.edsm.net/en/nightly-dumps/" |  | ||||||
|     ) |  | ||||||
| 
 |  | ||||||
| if not os.path.isfile("stars.jl"): |  | ||||||
|     print("Filtering for Stars") |  | ||||||
|     with open("stars.jl", "w") as neut: |  | ||||||
|         for body in process_file("bodies.json", True): |  | ||||||
|             T = body.get("type") or "" |  | ||||||
|             if "Star" in T: |  | ||||||
|                 neut.write(json.dumps(body) + "\n") |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| def load_systems(load=False): |  | ||||||
|     load = not os.path.isfile("systems.db") |  | ||||||
|     cache = sqlite3.connect("systems.db") |  | ||||||
|     cache.row_factory = dict_factory |  | ||||||
|     c = cache.cursor() |  | ||||||
|     if load: |  | ||||||
|         print("Caching Systems") |  | ||||||
|         c.execute("DROP TABLE IF EXISTS systems") |  | ||||||
|         c.execute( |  | ||||||
|             "CREATE TABLE systems (id64 int primary key, name text, x real, y real, z real)" |  | ||||||
|         ) |  | ||||||
|         cache.commit() |  | ||||||
|         recs = [] |  | ||||||
|         for system in process_file("systemsWithCoordinates.json", True): |  | ||||||
|             rec = [ |  | ||||||
|                 system["id64"], |  | ||||||
|                 system["name"], |  | ||||||
|                 system["coords"]["x"], |  | ||||||
|                 system["coords"]["y"], |  | ||||||
|                 system["coords"]["z"], |  | ||||||
|             ] |  | ||||||
|             recs.append(rec) |  | ||||||
|             if len(recs) % 1024 * 1024 == 0: |  | ||||||
|                 c.executemany("INSERT INTO systems VALUES (?,?,?,?,?)", recs) |  | ||||||
|                 recs.clear() |  | ||||||
|         c.executemany("INSERT INTO systems VALUES (?,?,?,?,?)", recs) |  | ||||||
|         cache.commit() |  | ||||||
|     return cache, c |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| if not os.path.isfile("stars.csv"): |  | ||||||
|     cache, cur = load_systems() |  | ||||||
|     rows = [] |  | ||||||
|     with open("stars.csv", "w", newline="") as sys_csv: |  | ||||||
|         csv_writer = csv.writer(sys_csv, dialect="excel") |  | ||||||
|         for neut in process_file("stars.jl", True): |  | ||||||
|             cur.execute( |  | ||||||
|                 "SELECT * FROM systems WHERE id64==?", (neut.get("systemId64"),) |  | ||||||
|             ) |  | ||||||
|             system = cur.fetchone() |  | ||||||
|             if not system: |  | ||||||
|                 continue |  | ||||||
|             row = [ |  | ||||||
|                 neut["systemId64"], |  | ||||||
|                 neut["subType"], |  | ||||||
|                 neut["name"], |  | ||||||
|                 get_mult(neut["subType"]), |  | ||||||
|                 system["x"], |  | ||||||
|                 system["y"], |  | ||||||
|                 system["z"], |  | ||||||
|             ] |  | ||||||
|             rows.append(row) |  | ||||||
|             if len(rows) > 1024: |  | ||||||
|                 csv_writer.writerows(rows) |  | ||||||
|                 rows.clear() |  | ||||||
|         csv_writer.writerows(rows) |  | ||||||
|         print() |  | ||||||
|     cache.close() |  | ||||||
| 
 |  | ||||||
| if not os.path.isfile("stars.csv"): |  | ||||||
|     tqdm.pandas(ascii=True, leave=True) |  | ||||||
|     print("Loading data...") |  | ||||||
|     data = pd.read_csv( |  | ||||||
|         "stars.csv", |  | ||||||
|         encoding="utf-8", |  | ||||||
|         names=["id", "type", "name", "mult", "x", "y", "z"], |  | ||||||
|     ) |  | ||||||
|     print("Cleaning data...") |  | ||||||
|     data.type.fillna("Unknown", inplace=True) |  | ||||||
|     data.drop_duplicates("id", inplace=True) |  | ||||||
|     print("Writing CSV...") |  | ||||||
|     data.to_csv("stars.csv", header=False, index=False) |  | ||||||
|  | @ -1,2 +0,0 @@ | ||||||
| https://www.edsm.net/dump/systemsWithCoordinates.json |  | ||||||
| https://www.edsm.net/dump/bodies.json |  | ||||||
							
								
								
									
										5
									
								
								ed_lrr_gui/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								ed_lrr_gui/__init__.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,5 @@ | ||||||
|  | from _ed_lrr import * | ||||||
|  | 
 | ||||||
|  | from .preprocess import Preprocessor | ||||||
|  | from .router import Router | ||||||
|  | from .config import cfg | ||||||
							
								
								
									
										403
									
								
								ed_lrr_gui/__main__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										403
									
								
								ed_lrr_gui/__main__.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,403 @@ | ||||||
|  | import sys | ||||||
|  | import multiprocessing as MP | ||||||
|  | import queue | ||||||
|  | import ctypes | ||||||
|  | import os | ||||||
|  | from datetime import datetime | ||||||
|  | from math import floor | ||||||
|  | import click | ||||||
|  | from tqdm import tqdm | ||||||
|  | from click_default_group import DefaultGroup | ||||||
|  | import requests as RQ | ||||||
|  | from urllib.parse import urljoin | ||||||
|  | from ed_lrr_gui import Router, Preprocessor, cfg | ||||||
|  | from _ed_lrr import find_sys | ||||||
|  | 
 | ||||||
|  | CONTEXT_SETTINGS = dict(help_option_names=["-h", "--help"]) | ||||||
|  | 
 | ||||||
|  | stars_path = os.path.join(cfg["folders.data_dir"], "stars.csv") | ||||||
|  | for folder in cfg["history.stars_csv_path"]: | ||||||
|  |     file = os.path.join(folder, "stars.csv") | ||||||
|  |     if os.path.isfile(file): | ||||||
|  |         stars_path = file | ||||||
|  |         break | ||||||
|  | 
 | ||||||
|  | systems_path = os.path.join(cfg["folders.data_dir"], "systemsWithCoordinates.json") | ||||||
|  | for file in cfg["history.systems_path"]: | ||||||
|  |     if os.path.isfile(file): | ||||||
|  |         systems_path = file | ||||||
|  |         break | ||||||
|  | 
 | ||||||
|  | bodies_path = os.path.join(cfg["folders.data_dir"], "bodies.json") | ||||||
|  | for file in cfg["history.bodies_path"][::-1]: | ||||||
|  |     if os.path.isfile(file): | ||||||
|  |         bodies_path = file | ||||||
|  |         break | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @click.group(invoke_without_command=True, context_settings=CONTEXT_SETTINGS) | ||||||
|  | @click.pass_context | ||||||
|  | @click.version_option() | ||||||
|  | def main(ctx): | ||||||
|  |     "Elite: Dangerous long range router, command line interface" | ||||||
|  |     MP.freeze_support() | ||||||
|  |     if ctx.invoked_subcommand != "config": | ||||||
|  |         os.makedirs(cfg["folders.data_dir"], exist_ok=True) | ||||||
|  |     if ctx.invoked_subcommand is None: | ||||||
|  |         ctx.invoke(gui) | ||||||
|  |         return | ||||||
|  |     return | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @main.command() | ||||||
|  | @click.argument("option", default=None, required=False) | ||||||
|  | @click.argument("value", default=None, required=False) | ||||||
|  | def config(option, value): | ||||||
|  |     """Change configuration | ||||||
|  |      | ||||||
|  | 
 | ||||||
|  |     If "key" and "value" are both omitted the current configuration is printed | ||||||
|  |     """ | ||||||
|  | 
 | ||||||
|  |     def print_config(key): | ||||||
|  |         default = cfg.section(key).default() | ||||||
|  |         comment = cfg.section(key).comment | ||||||
|  |         value = cfg[key] | ||||||
|  |         is_default = value == default | ||||||
|  |         if ( | ||||||
|  |             isinstance(value, list) | ||||||
|  |             and all(isinstance(element, str) for element in value) | ||||||
|  |             and len(value) != 0 | ||||||
|  |         ): | ||||||
|  |             value = "[{}]".format(", ".join(map("'{}'".format, value))) | ||||||
|  |         key = click.style("{}".format(key), fg="cyan") | ||||||
|  |         value = click.style("{}".format(value), fg="green") | ||||||
|  |         default = click.style("{}".format(default), fg="blue") | ||||||
|  |         comment = click.style("{}".format(comment), fg="yellow") | ||||||
|  |         if is_default: | ||||||
|  |             print("{}: {} # {}".format(key, default, comment)) | ||||||
|  |         else: | ||||||
|  |             print("{}: {} (default: {}) # {}".format(key, value, default, comment)) | ||||||
|  | 
 | ||||||
|  |     if option is None and value is None: | ||||||
|  |         click.secho("Config path: {}".format(cfg.sources[0]), bold=True) | ||||||
|  |         print() | ||||||
|  |         for key in cfg: | ||||||
|  |             print_config(key) | ||||||
|  |         return | ||||||
|  |     if value is None: | ||||||
|  |         if option in cfg: | ||||||
|  |             print_config(option) | ||||||
|  |         else: | ||||||
|  |             print("Invalid option:", option) | ||||||
|  |         return | ||||||
|  |     cfg[option] = value | ||||||
|  |     cfg.sync() | ||||||
|  |     return | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @main.command() | ||||||
|  | def explore(): | ||||||
|  |     "Open file manager in data folder" | ||||||
|  |     click.launch(cfg["folders.data_dir"], locate=True) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @main.command() | ||||||
|  | @click.option("--debug", help="Debug print", is_flag=True) | ||||||
|  | def gui(debug): | ||||||
|  |     "Run the ED LRR GUI (default)" | ||||||
|  |     import ed_lrr_gui.gui as ED_LRR_GUI | ||||||
|  | 
 | ||||||
|  |     if (not debug) and os.name == "nt": | ||||||
|  |         ctypes.windll.kernel32.FreeConsole() | ||||||
|  |         sys.stdin = open("NUL", "rt") | ||||||
|  |         sys.stdout = open("NUL", "wt") | ||||||
|  |         sys.stderr = open("NUL", "wt") | ||||||
|  |     sys.exit(ED_LRR_GUI.main()) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @main.command() | ||||||
|  | @click.option( | ||||||
|  |     "--url", | ||||||
|  |     "-u", | ||||||
|  |     help="Base URL", | ||||||
|  |     default="https://www.edsm.net/dump/", | ||||||
|  |     show_default=True, | ||||||
|  | ) | ||||||
|  | @click.option( | ||||||
|  |     "--folder", | ||||||
|  |     "-f", | ||||||
|  |     help="Target folder for downloads", | ||||||
|  |     default=cfg["folders.data_dir"], | ||||||
|  |     type=click.Path(exists=True, dir_okay=True, file_okay=False), | ||||||
|  |     show_default=True, | ||||||
|  | ) | ||||||
|  | def download(url, folder): | ||||||
|  |     "Download EDSM dumps" | ||||||
|  |     os.makedirs(folder, exist_ok=True) | ||||||
|  |     for file_name in ["systemsWithCoordinates.json", "bodies.json"]: | ||||||
|  |         download_url = urljoin(url, file_name) | ||||||
|  |         download_path = os.path.join(folder, file_name) | ||||||
|  |         if os.path.isfile(download_path): | ||||||
|  |             try: | ||||||
|  |                 if not click.confirm( | ||||||
|  |                     "{} already exissts, overwrite?".format(file_name) | ||||||
|  |                 ): | ||||||
|  |                     continue | ||||||
|  |             except click.Abort: | ||||||
|  |                 exit("Canceled!") | ||||||
|  |         size = RQ.head(download_url, headers={"Accept-Encoding": "None"}) | ||||||
|  |         size.raise_for_status() | ||||||
|  |         size = int(size.headers.get("Content-Length", 0)) | ||||||
|  |         with tqdm( | ||||||
|  |             total=size, | ||||||
|  |             desc="{}".format(file_name), | ||||||
|  |             unit="b", | ||||||
|  |             unit_divisor=1024, | ||||||
|  |             unit_scale=True, | ||||||
|  |             ascii=True, | ||||||
|  |         ) as pbar: | ||||||
|  |             with open(download_path, "wb") as of: | ||||||
|  |                 resp = RQ.get( | ||||||
|  |                     download_url, stream=True, headers={"Accept-Encoding": "gzip"} | ||||||
|  |                 ) | ||||||
|  |                 for chunk in resp.iter_content(1024 * 1024): | ||||||
|  |                     of.write(chunk) | ||||||
|  |                     pbar.update(len(chunk)) | ||||||
|  |     click.pause() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @main.command() | ||||||
|  | @click.option( | ||||||
|  |     "--systems", | ||||||
|  |     "-s", | ||||||
|  |     default=systems_path, | ||||||
|  |     metavar="<path>", | ||||||
|  |     help="Path to stars.csv", | ||||||
|  |     type=click.Path(exists=True, dir_okay=False), | ||||||
|  |     show_default=True, | ||||||
|  | ) | ||||||
|  | @click.option( | ||||||
|  |     "--bodies", | ||||||
|  |     "-b", | ||||||
|  |     default=bodies_path, | ||||||
|  |     metavar="<path>", | ||||||
|  |     help="Path to bodies.json", | ||||||
|  |     type=click.Path(exists=True, dir_okay=False), | ||||||
|  |     show_default=True, | ||||||
|  | ) | ||||||
|  | @click.option( | ||||||
|  |     "--output", | ||||||
|  |     "-o", | ||||||
|  |     default=stars_path, | ||||||
|  |     metavar="<path>", | ||||||
|  |     help="Path to stars.csv", | ||||||
|  |     type=click.Path(exists=False, dir_okay=False), | ||||||
|  |     show_default=True, | ||||||
|  | ) | ||||||
|  | def preprocess(systems, bodies, output): | ||||||
|  |     "Preprocess EDSM dumps" | ||||||
|  |     with click.progressbar( | ||||||
|  |         length=100, label="", show_percent=True, item_show_func=lambda v: v, width=50 | ||||||
|  |     ) as pbar: | ||||||
|  |         preproc = Preprocessor(systems, bodies, output) | ||||||
|  |         preproc.start() | ||||||
|  |         state = {} | ||||||
|  |         pstate = {} | ||||||
|  |         while not (preproc.queue.empty() and preproc.is_alive() == False): | ||||||
|  |             try: | ||||||
|  |                 event = preproc.queue.get(True, 0.1) | ||||||
|  |                 state.update(event) | ||||||
|  |                 if state != pstate: | ||||||
|  |                     prc = (state["status"]["done"] / state["status"]["total"]) * 100 | ||||||
|  |                     pbar.pos = prc | ||||||
|  |                     pbar.update(0) | ||||||
|  |                     pbar.current_item = state["status"]["message"] | ||||||
|  |                     pstate = state.copy() | ||||||
|  |             except queue.Empty: | ||||||
|  |                 pass | ||||||
|  |         pbar.pos = 100 | ||||||
|  |         pbar.update(0) | ||||||
|  |     print(state.get("result")) | ||||||
|  |     print("DONE!") | ||||||
|  |     click.pause() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @main.command() | ||||||
|  | @click.option( | ||||||
|  |     "--path", | ||||||
|  |     "-i", | ||||||
|  |     required=True, | ||||||
|  |     metavar="<path>", | ||||||
|  |     help="Path to stars.csv", | ||||||
|  |     default=stars_path, | ||||||
|  |     type=click.Path(exists=True, dir_okay=False), | ||||||
|  |     show_default=True, | ||||||
|  | ) | ||||||
|  | @click.option( | ||||||
|  |     "--precomp_file", | ||||||
|  |     "-pf", | ||||||
|  |     metavar="<path>", | ||||||
|  |     help="Precomputed routing graph to use", | ||||||
|  |     type=click.Path(exists=True, dir_okay=False), | ||||||
|  | ) | ||||||
|  | @click.option( | ||||||
|  |     "--range", | ||||||
|  |     "-r", | ||||||
|  |     default=cfg["route.range"], | ||||||
|  |     metavar="<float>", | ||||||
|  |     help="Jump range (Ly)", | ||||||
|  |     type=click.FloatRange(min=0), | ||||||
|  |     show_default=True, | ||||||
|  | ) | ||||||
|  | @click.option( | ||||||
|  |     "--prune", | ||||||
|  |     "-d", | ||||||
|  |     default=(cfg["route.prune.steps"], cfg["route.prune.min_improvement"]), | ||||||
|  |     metavar="<n> <m>", | ||||||
|  |     help="Prune search branches", | ||||||
|  |     nargs=2, | ||||||
|  |     type=click.Tuple([click.IntRange(min=0), click.FloatRange(min=0)]), | ||||||
|  |     show_default=True, | ||||||
|  | ) | ||||||
|  | @click.option( | ||||||
|  |     "--permute", | ||||||
|  |     "-p", | ||||||
|  |     type=click.Choice(["all", "keep_first", "keep_last", "keep_both"]), | ||||||
|  |     default=None, | ||||||
|  |     help="Permute hops to find shortest route", | ||||||
|  |     show_default=True, | ||||||
|  | ) | ||||||
|  | @click.option( | ||||||
|  |     "--primary/--no-primary", | ||||||
|  |     "+ps/-ps", | ||||||
|  |     is_flag=True, | ||||||
|  |     default=cfg["route.primary"], | ||||||
|  |     help="Only route through primary stars", | ||||||
|  |     show_default=True, | ||||||
|  | ) | ||||||
|  | @click.option( | ||||||
|  |     "--factor", | ||||||
|  |     "-g", | ||||||
|  |     metavar="<float>", | ||||||
|  |     default=cfg["route.greediness"], | ||||||
|  |     help="Greedyness factor for A-Star", | ||||||
|  |     show_default=True, | ||||||
|  | ) | ||||||
|  | @click.option( | ||||||
|  |     "--mode", | ||||||
|  |     "-m", | ||||||
|  |     default=cfg["route.mode"], | ||||||
|  |     help="Search mode", | ||||||
|  |     type=click.Choice(["bfs", "a-star", "greedy"]), | ||||||
|  |     show_default=True, | ||||||
|  | ) | ||||||
|  | @click.argument("systems", nargs=-1) | ||||||
|  | def route(**kwargs): | ||||||
|  |     "Compute a route" | ||||||
|  |     if len(kwargs["systems"]) < 2: | ||||||
|  |         exit("Need at least two systems to plot a route") | ||||||
|  |     if kwargs["prune"] == (0, 0): | ||||||
|  |         kwargs["prune"] = None | ||||||
|  | 
 | ||||||
|  |     def to_string(state): | ||||||
|  |         if state: | ||||||
|  |             return "{prc_done:.2f}% [N:{depth} Q:{queue_size} D:{d_rem:.2f} Ly] {system}".format( | ||||||
|  |                 **state | ||||||
|  |             ) | ||||||
|  | 
 | ||||||
|  |     keep_first, keep_last = { | ||||||
|  |         "all": (False, False), | ||||||
|  |         "keep_first": (True, False), | ||||||
|  |         "keep_last": (False, True), | ||||||
|  |         "keep_both": (True, True), | ||||||
|  |         None: (False, False), | ||||||
|  |     }[kwargs["permute"]] | ||||||
|  |     print("Resolving systems...") | ||||||
|  |     t = datetime.today() | ||||||
|  |     matches = find_sys(kwargs["systems"], kwargs["path"]) | ||||||
|  |     kwargs["systems"] = [str(matches[key][1]["id"]) for key in kwargs["systems"]] | ||||||
|  |     print("Done in", datetime.today() - t) | ||||||
|  |     args = [ | ||||||
|  |         kwargs["systems"], | ||||||
|  |         kwargs["range"], | ||||||
|  |         kwargs["prune"], | ||||||
|  |         kwargs["mode"], | ||||||
|  |         kwargs["primary"], | ||||||
|  |         kwargs["permute"] != None, | ||||||
|  |         keep_first, | ||||||
|  |         keep_last, | ||||||
|  |         kwargs["factor"], | ||||||
|  |         None, | ||||||
|  |         kwargs["path"], | ||||||
|  |     ] | ||||||
|  |     with click.progressbar( | ||||||
|  |         length=100, | ||||||
|  |         label="Computing route", | ||||||
|  |         show_percent=False, | ||||||
|  |         item_show_func=to_string, | ||||||
|  |         width=50, | ||||||
|  |     ) as pbar: | ||||||
|  |         router = Router(*args) | ||||||
|  |         t = datetime.today() | ||||||
|  |         router.start() | ||||||
|  |         state = {} | ||||||
|  |         pstate = {} | ||||||
|  |         while not (router.queue.empty() and router.is_alive() == False): | ||||||
|  |             try: | ||||||
|  |                 event = router.queue.get(True, 0.1) | ||||||
|  |                 state.update(event) | ||||||
|  |                 if state != pstate: | ||||||
|  |                     pbar.current_item = state.get("status") | ||||||
|  |                     if pbar.current_item: | ||||||
|  |                         pbar.pos = pbar.current_item["prc_done"] | ||||||
|  |                         pbar.update(0) | ||||||
|  |                     pstate = state.copy() | ||||||
|  |             except queue.Empty: | ||||||
|  |                 pass | ||||||
|  |         pbar.pos = 100 | ||||||
|  |         pbar.update(0) | ||||||
|  |     for n, jump in enumerate(state.get("return", []), 1): | ||||||
|  |         jump["n"] = n | ||||||
|  |         if jump["body"].index(jump["system"]) == -1: | ||||||
|  |             jump["where"] = "[{body}] in [{system}]".format(**jump) | ||||||
|  |         else: | ||||||
|  |             jump["where"] = "[{body}]".format(**jump) | ||||||
|  |         if jump["distance"] > 0: | ||||||
|  |             print("({n}) {where}: {star_type} ({distance} Ls)".format(**jump)) | ||||||
|  |         else: | ||||||
|  |             print("({n}) {where}: {star_type}".format(**jump)) | ||||||
|  |     print("Done in", datetime.today() - t) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @main.command() | ||||||
|  | @click.option( | ||||||
|  |     "--path", | ||||||
|  |     "-i", | ||||||
|  |     required=True, | ||||||
|  |     help="Path to stars.csv", | ||||||
|  |     default=stars_path, | ||||||
|  |     type=click.Path(exists=True, dir_okay=False), | ||||||
|  |     show_default=True, | ||||||
|  | ) | ||||||
|  | @click.option( | ||||||
|  |     "--range", "-r", required=True, help="Jump range (Ly)", type=click.FloatRange(min=0) | ||||||
|  | ) | ||||||
|  | @click.option("--primary", "-ps", help="Only route through primary stars") | ||||||
|  | @click.option( | ||||||
|  |     "--output", | ||||||
|  |     "-o", | ||||||
|  |     required=True, | ||||||
|  |     help="Output path", | ||||||
|  |     default="./stars.idx", | ||||||
|  |     type=click.Path(exists=False, dir_okay=False), | ||||||
|  |     show_default=True, | ||||||
|  | ) | ||||||
|  | @click.argument("systems", nargs=-1) | ||||||
|  | def precompute(*args, **kwargs): | ||||||
|  |     "Precompute routing graph" | ||||||
|  |     print("PreComp:", args, kwargs) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     main() | ||||||
							
								
								
									
										59
									
								
								ed_lrr_gui/config.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								ed_lrr_gui/config.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,59 @@ | ||||||
|  | import pathlib | ||||||
|  | from collections import namedtuple | ||||||
|  | import profig | ||||||
|  | import appdirs | ||||||
|  | import os | ||||||
|  | 
 | ||||||
|  | config_dir = pathlib.Path(appdirs.user_config_dir("ED_LRR", "")) | ||||||
|  | config_dir.mkdir(parents=True, exist_ok=True) | ||||||
|  | config_file = config_dir / "config.ini" | ||||||
|  | config_file.touch() | ||||||
|  | 
 | ||||||
|  | cfg = profig.Config(str(config_file), strict=True) | ||||||
|  | 
 | ||||||
|  | cfg.init( | ||||||
|  |     "history.bodies_url", | ||||||
|  |     ["https://www.edsm.net/dump/bodies.json"], | ||||||
|  |     "path_list", | ||||||
|  |     comment="history of bodies.json urls", | ||||||
|  | ) | ||||||
|  | cfg.init( | ||||||
|  |     "history.systems_url", | ||||||
|  |     ["https://www.edsm.net/dump/systemsWithCoordinates.json"], | ||||||
|  |     "path_list", | ||||||
|  |     comment="history of systems.json urls", | ||||||
|  | ) | ||||||
|  | cfg.init( | ||||||
|  |     "history.bodies_path", | ||||||
|  |     [os.path.join(config_dir, "data", "bodies.json")], | ||||||
|  |     "path_list", | ||||||
|  |     comment="history of bodies.json download paths", | ||||||
|  | ) | ||||||
|  | cfg.init( | ||||||
|  |     "history.systems_path", | ||||||
|  |     [os.path.join(config_dir, "data", "systemsWithCoordinates.json")], | ||||||
|  |     "path_list", | ||||||
|  |     comment="history of systems.json download paths", | ||||||
|  | ) | ||||||
|  | cfg.init( | ||||||
|  |     "history.stars_csv_path", | ||||||
|  |     [os.path.join(config_dir, "data", "stars.csv")], | ||||||
|  |     "path_list", | ||||||
|  |     comment="history of paths for stars.csv", | ||||||
|  | ) | ||||||
|  | cfg.init("route.range", 7.56, comment="jump range") | ||||||
|  | cfg.init("route.primary", False, comment="only route through primary stars") | ||||||
|  | cfg.init("route.mode", "bfs", comment="routing mode") | ||||||
|  | cfg.init( | ||||||
|  |     "route.prune.min_improvement", | ||||||
|  |     10.0, | ||||||
|  |     comment="path needs to improve by at least (jump_range*min_improvement) in route.prune.steps", | ||||||
|  | ) | ||||||
|  | cfg.init("route.prune.steps", 5, comment="number of steps before path gets pruned") | ||||||
|  | cfg.init("route.greediness", 0.5, comment="A* greediness") | ||||||
|  | cfg.init("folders.data_dir", os.path.join(config_dir, "data"), comment="Data directory") | ||||||
|  | 
 | ||||||
|  | cfg.init("GUI.theme", "dark", comment="GUI theme to use") | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | cfg.sync() | ||||||
							
								
								
									
										1
									
								
								ed_lrr_gui/gui/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								ed_lrr_gui/gui/__init__.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1 @@ | ||||||
|  | from .main import main | ||||||
							
								
								
									
										484
									
								
								ed_lrr_gui/gui/ed_lrr.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										484
									
								
								ed_lrr_gui/gui/ed_lrr.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,484 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | 
 | ||||||
|  | # Form implementation generated from reading ui file 'D:\devel\rust\ed_lrr_gui\ed_lrr_gui\gui\ed_lrr.ui' | ||||||
|  | # | ||||||
|  | # Created by: PyQt5 UI code generator 5.13.1 | ||||||
|  | # | ||||||
|  | # WARNING! All changes made in this file will be lost! | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | from PyQt5 import QtCore, QtGui, QtWidgets | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Ui_ED_LRR(object): | ||||||
|  |     def setupUi(self, ED_LRR): | ||||||
|  |         ED_LRR.setObjectName("ED_LRR") | ||||||
|  |         ED_LRR.setEnabled(True) | ||||||
|  |         ED_LRR.resize(577, 500) | ||||||
|  |         sizePolicy = QtWidgets.QSizePolicy( | ||||||
|  |             QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed | ||||||
|  |         ) | ||||||
|  |         sizePolicy.setHorizontalStretch(0) | ||||||
|  |         sizePolicy.setVerticalStretch(0) | ||||||
|  |         sizePolicy.setHeightForWidth(ED_LRR.sizePolicy().hasHeightForWidth()) | ||||||
|  |         ED_LRR.setSizePolicy(sizePolicy) | ||||||
|  |         ED_LRR.setMinimumSize(QtCore.QSize(577, 500)) | ||||||
|  |         ED_LRR.setMaximumSize(QtCore.QSize(577, 500)) | ||||||
|  |         ED_LRR.setStyleSheet("") | ||||||
|  |         ED_LRR.setDocumentMode(False) | ||||||
|  |         ED_LRR.setTabShape(QtWidgets.QTabWidget.Rounded) | ||||||
|  |         self.centralwidget = QtWidgets.QWidget(ED_LRR) | ||||||
|  |         sizePolicy = QtWidgets.QSizePolicy( | ||||||
|  |             QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred | ||||||
|  |         ) | ||||||
|  |         sizePolicy.setHorizontalStretch(0) | ||||||
|  |         sizePolicy.setVerticalStretch(0) | ||||||
|  |         sizePolicy.setHeightForWidth( | ||||||
|  |             self.centralwidget.sizePolicy().hasHeightForWidth() | ||||||
|  |         ) | ||||||
|  |         self.centralwidget.setSizePolicy(sizePolicy) | ||||||
|  |         self.centralwidget.setObjectName("centralwidget") | ||||||
|  |         self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget) | ||||||
|  |         self.verticalLayout.setObjectName("verticalLayout") | ||||||
|  |         self.tabs = QtWidgets.QTabWidget(self.centralwidget) | ||||||
|  |         self.tabs.setEnabled(True) | ||||||
|  |         self.tabs.setAutoFillBackground(False) | ||||||
|  |         self.tabs.setTabPosition(QtWidgets.QTabWidget.North) | ||||||
|  |         self.tabs.setTabShape(QtWidgets.QTabWidget.Rounded) | ||||||
|  |         self.tabs.setElideMode(QtCore.Qt.ElideNone) | ||||||
|  |         self.tabs.setTabsClosable(False) | ||||||
|  |         self.tabs.setTabBarAutoHide(False) | ||||||
|  |         self.tabs.setObjectName("tabs") | ||||||
|  |         self.tab_download = QtWidgets.QWidget() | ||||||
|  |         self.tab_download.setObjectName("tab_download") | ||||||
|  |         self.formLayout = QtWidgets.QFormLayout(self.tab_download) | ||||||
|  |         self.formLayout.setObjectName("formLayout") | ||||||
|  |         self.lbl_bodies_dl = QtWidgets.QLabel(self.tab_download) | ||||||
|  |         self.lbl_bodies_dl.setObjectName("lbl_bodies_dl") | ||||||
|  |         self.formLayout.setWidget( | ||||||
|  |             1, QtWidgets.QFormLayout.LabelRole, self.lbl_bodies_dl | ||||||
|  |         ) | ||||||
|  |         self.lbl_systems_dl = QtWidgets.QLabel(self.tab_download) | ||||||
|  |         self.lbl_systems_dl.setObjectName("lbl_systems_dl") | ||||||
|  |         self.formLayout.setWidget( | ||||||
|  |             3, QtWidgets.QFormLayout.LabelRole, self.lbl_systems_dl | ||||||
|  |         ) | ||||||
|  |         self.inp_bodies_dl = QtWidgets.QComboBox(self.tab_download) | ||||||
|  |         self.inp_bodies_dl.setEditable(True) | ||||||
|  |         self.inp_bodies_dl.setInsertPolicy(QtWidgets.QComboBox.InsertAtTop) | ||||||
|  |         self.inp_bodies_dl.setObjectName("inp_bodies_dl") | ||||||
|  |         self.formLayout.setWidget( | ||||||
|  |             1, QtWidgets.QFormLayout.FieldRole, self.inp_bodies_dl | ||||||
|  |         ) | ||||||
|  |         self.inp_systems_dl = QtWidgets.QComboBox(self.tab_download) | ||||||
|  |         self.inp_systems_dl.setEditable(True) | ||||||
|  |         self.inp_systems_dl.setInsertPolicy(QtWidgets.QComboBox.InsertAtTop) | ||||||
|  |         self.inp_systems_dl.setObjectName("inp_systems_dl") | ||||||
|  |         self.formLayout.setWidget( | ||||||
|  |             3, QtWidgets.QFormLayout.FieldRole, self.inp_systems_dl | ||||||
|  |         ) | ||||||
|  |         self.gridLayout = QtWidgets.QGridLayout() | ||||||
|  |         self.gridLayout.setObjectName("gridLayout") | ||||||
|  |         self.inp_bodies_dest_dl = QtWidgets.QComboBox(self.tab_download) | ||||||
|  |         sizePolicy = QtWidgets.QSizePolicy( | ||||||
|  |             QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed | ||||||
|  |         ) | ||||||
|  |         sizePolicy.setHorizontalStretch(0) | ||||||
|  |         sizePolicy.setVerticalStretch(0) | ||||||
|  |         sizePolicy.setHeightForWidth( | ||||||
|  |             self.inp_bodies_dest_dl.sizePolicy().hasHeightForWidth() | ||||||
|  |         ) | ||||||
|  |         self.inp_bodies_dest_dl.setSizePolicy(sizePolicy) | ||||||
|  |         self.inp_bodies_dest_dl.setEditable(False) | ||||||
|  |         self.inp_bodies_dest_dl.setInsertPolicy(QtWidgets.QComboBox.InsertAtTop) | ||||||
|  |         self.inp_bodies_dest_dl.setObjectName("inp_bodies_dest_dl") | ||||||
|  |         self.gridLayout.addWidget(self.inp_bodies_dest_dl, 0, 0, 1, 1) | ||||||
|  |         self.btn_bodies_dest_browse_dl = QtWidgets.QPushButton(self.tab_download) | ||||||
|  |         self.btn_bodies_dest_browse_dl.setObjectName("btn_bodies_dest_browse_dl") | ||||||
|  |         self.gridLayout.addWidget(self.btn_bodies_dest_browse_dl, 0, 1, 1, 1) | ||||||
|  |         self.formLayout.setLayout(2, QtWidgets.QFormLayout.FieldRole, self.gridLayout) | ||||||
|  |         self.gridLayout_2 = QtWidgets.QGridLayout() | ||||||
|  |         self.gridLayout_2.setObjectName("gridLayout_2") | ||||||
|  |         self.btn_systems_dest_browse_dl = QtWidgets.QPushButton(self.tab_download) | ||||||
|  |         self.btn_systems_dest_browse_dl.setObjectName("btn_systems_dest_browse_dl") | ||||||
|  |         self.gridLayout_2.addWidget(self.btn_systems_dest_browse_dl, 0, 1, 1, 1) | ||||||
|  |         self.inp_systems_dest_dl = QtWidgets.QComboBox(self.tab_download) | ||||||
|  |         sizePolicy = QtWidgets.QSizePolicy( | ||||||
|  |             QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed | ||||||
|  |         ) | ||||||
|  |         sizePolicy.setHorizontalStretch(0) | ||||||
|  |         sizePolicy.setVerticalStretch(0) | ||||||
|  |         sizePolicy.setHeightForWidth( | ||||||
|  |             self.inp_systems_dest_dl.sizePolicy().hasHeightForWidth() | ||||||
|  |         ) | ||||||
|  |         self.inp_systems_dest_dl.setSizePolicy(sizePolicy) | ||||||
|  |         self.inp_systems_dest_dl.setEditable(False) | ||||||
|  |         self.inp_systems_dest_dl.setInsertPolicy(QtWidgets.QComboBox.InsertAtTop) | ||||||
|  |         self.inp_systems_dest_dl.setObjectName("inp_systems_dest_dl") | ||||||
|  |         self.gridLayout_2.addWidget(self.inp_systems_dest_dl, 0, 0, 1, 1) | ||||||
|  |         self.formLayout.setLayout(4, QtWidgets.QFormLayout.FieldRole, self.gridLayout_2) | ||||||
|  |         self.btn_download = QtWidgets.QPushButton(self.tab_download) | ||||||
|  |         self.btn_download.setObjectName("btn_download") | ||||||
|  |         self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.btn_download) | ||||||
|  |         self.label = QtWidgets.QLabel(self.tab_download) | ||||||
|  |         self.label.setObjectName("label") | ||||||
|  |         self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label) | ||||||
|  |         self.label_2 = QtWidgets.QLabel(self.tab_download) | ||||||
|  |         self.label_2.setObjectName("label_2") | ||||||
|  |         self.formLayout.setWidget(4, QtWidgets.QFormLayout.LabelRole, self.label_2) | ||||||
|  |         self.tabs.addTab(self.tab_download, "") | ||||||
|  |         self.tab_preprocess = QtWidgets.QWidget() | ||||||
|  |         self.tab_preprocess.setObjectName("tab_preprocess") | ||||||
|  |         self.formLayout_3 = QtWidgets.QFormLayout(self.tab_preprocess) | ||||||
|  |         self.formLayout_3.setObjectName("formLayout_3") | ||||||
|  |         self.lbl_bodies_pp = QtWidgets.QLabel(self.tab_preprocess) | ||||||
|  |         self.lbl_bodies_pp.setObjectName("lbl_bodies_pp") | ||||||
|  |         self.formLayout_3.setWidget( | ||||||
|  |             0, QtWidgets.QFormLayout.LabelRole, self.lbl_bodies_pp | ||||||
|  |         ) | ||||||
|  |         self.gr_bodies_pp = QtWidgets.QGridLayout() | ||||||
|  |         self.gr_bodies_pp.setObjectName("gr_bodies_pp") | ||||||
|  |         self.btn_bodies_browse_pp = QtWidgets.QPushButton(self.tab_preprocess) | ||||||
|  |         self.btn_bodies_browse_pp.setObjectName("btn_bodies_browse_pp") | ||||||
|  |         self.gr_bodies_pp.addWidget(self.btn_bodies_browse_pp, 0, 1, 1, 1) | ||||||
|  |         self.inp_bodies_pp = QtWidgets.QComboBox(self.tab_preprocess) | ||||||
|  |         sizePolicy = QtWidgets.QSizePolicy( | ||||||
|  |             QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed | ||||||
|  |         ) | ||||||
|  |         sizePolicy.setHorizontalStretch(0) | ||||||
|  |         sizePolicy.setVerticalStretch(0) | ||||||
|  |         sizePolicy.setHeightForWidth( | ||||||
|  |             self.inp_bodies_pp.sizePolicy().hasHeightForWidth() | ||||||
|  |         ) | ||||||
|  |         self.inp_bodies_pp.setSizePolicy(sizePolicy) | ||||||
|  |         self.inp_bodies_pp.setEditable(False) | ||||||
|  |         self.inp_bodies_pp.setInsertPolicy(QtWidgets.QComboBox.InsertAtTop) | ||||||
|  |         self.inp_bodies_pp.setObjectName("inp_bodies_pp") | ||||||
|  |         self.gr_bodies_pp.addWidget(self.inp_bodies_pp, 0, 0, 1, 1) | ||||||
|  |         self.formLayout_3.setLayout( | ||||||
|  |             0, QtWidgets.QFormLayout.FieldRole, self.gr_bodies_pp | ||||||
|  |         ) | ||||||
|  |         self.lbl_systems_pp = QtWidgets.QLabel(self.tab_preprocess) | ||||||
|  |         self.lbl_systems_pp.setObjectName("lbl_systems_pp") | ||||||
|  |         self.formLayout_3.setWidget( | ||||||
|  |             1, QtWidgets.QFormLayout.LabelRole, self.lbl_systems_pp | ||||||
|  |         ) | ||||||
|  |         self.gr_systems_pp = QtWidgets.QGridLayout() | ||||||
|  |         self.gr_systems_pp.setObjectName("gr_systems_pp") | ||||||
|  |         self.btn_systems_browse_pp = QtWidgets.QPushButton(self.tab_preprocess) | ||||||
|  |         self.btn_systems_browse_pp.setObjectName("btn_systems_browse_pp") | ||||||
|  |         self.gr_systems_pp.addWidget(self.btn_systems_browse_pp, 0, 1, 1, 1) | ||||||
|  |         self.inp_systems_pp = QtWidgets.QComboBox(self.tab_preprocess) | ||||||
|  |         sizePolicy = QtWidgets.QSizePolicy( | ||||||
|  |             QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed | ||||||
|  |         ) | ||||||
|  |         sizePolicy.setHorizontalStretch(0) | ||||||
|  |         sizePolicy.setVerticalStretch(0) | ||||||
|  |         sizePolicy.setHeightForWidth( | ||||||
|  |             self.inp_systems_pp.sizePolicy().hasHeightForWidth() | ||||||
|  |         ) | ||||||
|  |         self.inp_systems_pp.setSizePolicy(sizePolicy) | ||||||
|  |         self.inp_systems_pp.setEditable(False) | ||||||
|  |         self.inp_systems_pp.setInsertPolicy(QtWidgets.QComboBox.InsertAtTop) | ||||||
|  |         self.inp_systems_pp.setObjectName("inp_systems_pp") | ||||||
|  |         self.gr_systems_pp.addWidget(self.inp_systems_pp, 0, 0, 1, 1) | ||||||
|  |         self.formLayout_3.setLayout( | ||||||
|  |             1, QtWidgets.QFormLayout.FieldRole, self.gr_systems_pp | ||||||
|  |         ) | ||||||
|  |         self.lbl_out_pp = QtWidgets.QLabel(self.tab_preprocess) | ||||||
|  |         self.lbl_out_pp.setObjectName("lbl_out_pp") | ||||||
|  |         self.formLayout_3.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.lbl_out_pp) | ||||||
|  |         self.gr_out_grid_pp = QtWidgets.QGridLayout() | ||||||
|  |         self.gr_out_grid_pp.setObjectName("gr_out_grid_pp") | ||||||
|  |         self.btn_out_browse_pp = QtWidgets.QPushButton(self.tab_preprocess) | ||||||
|  |         sizePolicy = QtWidgets.QSizePolicy( | ||||||
|  |             QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed | ||||||
|  |         ) | ||||||
|  |         sizePolicy.setHorizontalStretch(0) | ||||||
|  |         sizePolicy.setVerticalStretch(0) | ||||||
|  |         sizePolicy.setHeightForWidth( | ||||||
|  |             self.btn_out_browse_pp.sizePolicy().hasHeightForWidth() | ||||||
|  |         ) | ||||||
|  |         self.btn_out_browse_pp.setSizePolicy(sizePolicy) | ||||||
|  |         self.btn_out_browse_pp.setObjectName("btn_out_browse_pp") | ||||||
|  |         self.gr_out_grid_pp.addWidget(self.btn_out_browse_pp, 0, 1, 1, 1) | ||||||
|  |         self.inp_out_pp = QtWidgets.QComboBox(self.tab_preprocess) | ||||||
|  |         sizePolicy = QtWidgets.QSizePolicy( | ||||||
|  |             QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed | ||||||
|  |         ) | ||||||
|  |         sizePolicy.setHorizontalStretch(0) | ||||||
|  |         sizePolicy.setVerticalStretch(0) | ||||||
|  |         sizePolicy.setHeightForWidth(self.inp_out_pp.sizePolicy().hasHeightForWidth()) | ||||||
|  |         self.inp_out_pp.setSizePolicy(sizePolicy) | ||||||
|  |         self.inp_out_pp.setEditable(False) | ||||||
|  |         self.inp_out_pp.setInsertPolicy(QtWidgets.QComboBox.InsertAtTop) | ||||||
|  |         self.inp_out_pp.setObjectName("inp_out_pp") | ||||||
|  |         self.gr_out_grid_pp.addWidget(self.inp_out_pp, 0, 0, 1, 1) | ||||||
|  |         self.formLayout_3.setLayout( | ||||||
|  |             2, QtWidgets.QFormLayout.FieldRole, self.gr_out_grid_pp | ||||||
|  |         ) | ||||||
|  |         self.btn_preprocess = QtWidgets.QPushButton(self.tab_preprocess) | ||||||
|  |         self.btn_preprocess.setObjectName("btn_preprocess") | ||||||
|  |         self.formLayout_3.setWidget( | ||||||
|  |             3, QtWidgets.QFormLayout.LabelRole, self.btn_preprocess | ||||||
|  |         ) | ||||||
|  |         self.tabs.addTab(self.tab_preprocess, "") | ||||||
|  |         self.tab_route = QtWidgets.QWidget() | ||||||
|  |         self.tab_route.setObjectName("tab_route") | ||||||
|  |         self.formLayout_2 = QtWidgets.QFormLayout(self.tab_route) | ||||||
|  |         self.formLayout_2.setObjectName("formLayout_2") | ||||||
|  |         self.lbl_sys_lst = QtWidgets.QLabel(self.tab_route) | ||||||
|  |         self.lbl_sys_lst.setObjectName("lbl_sys_lst") | ||||||
|  |         self.formLayout_2.setWidget( | ||||||
|  |             0, QtWidgets.QFormLayout.LabelRole, self.lbl_sys_lst | ||||||
|  |         ) | ||||||
|  |         self.gr_sys = QtWidgets.QGridLayout() | ||||||
|  |         self.gr_sys.setObjectName("gr_sys") | ||||||
|  |         self.btn_sys_lst_browse = QtWidgets.QPushButton(self.tab_route) | ||||||
|  |         self.btn_sys_lst_browse.setObjectName("btn_sys_lst_browse") | ||||||
|  |         self.gr_sys.addWidget(self.btn_sys_lst_browse, 0, 1, 1, 1) | ||||||
|  |         self.inp_sys_lst = QtWidgets.QComboBox(self.tab_route) | ||||||
|  |         sizePolicy = QtWidgets.QSizePolicy( | ||||||
|  |             QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed | ||||||
|  |         ) | ||||||
|  |         sizePolicy.setHorizontalStretch(0) | ||||||
|  |         sizePolicy.setVerticalStretch(0) | ||||||
|  |         sizePolicy.setHeightForWidth(self.inp_sys_lst.sizePolicy().hasHeightForWidth()) | ||||||
|  |         self.inp_sys_lst.setSizePolicy(sizePolicy) | ||||||
|  |         self.inp_sys_lst.setEditable(False) | ||||||
|  |         self.inp_sys_lst.setInsertPolicy(QtWidgets.QComboBox.InsertAtTop) | ||||||
|  |         self.inp_sys_lst.setFrame(True) | ||||||
|  |         self.inp_sys_lst.setModelColumn(0) | ||||||
|  |         self.inp_sys_lst.setObjectName("inp_sys_lst") | ||||||
|  |         self.gr_sys.addWidget(self.inp_sys_lst, 0, 0, 1, 1) | ||||||
|  |         self.formLayout_2.setLayout(0, QtWidgets.QFormLayout.FieldRole, self.gr_sys) | ||||||
|  |         self.btn_add = QtWidgets.QPushButton(self.tab_route) | ||||||
|  |         self.btn_add.setObjectName("btn_add") | ||||||
|  |         self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.btn_add) | ||||||
|  |         self.inp_sys = QtWidgets.QLineEdit(self.tab_route) | ||||||
|  |         self.inp_sys.setObjectName("inp_sys") | ||||||
|  |         self.formLayout_2.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.inp_sys) | ||||||
|  |         self.btn_rm = QtWidgets.QPushButton(self.tab_route) | ||||||
|  |         self.btn_rm.setObjectName("btn_rm") | ||||||
|  |         self.formLayout_2.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.btn_rm) | ||||||
|  |         self.gr_mode = QtWidgets.QGridLayout() | ||||||
|  |         self.gr_mode.setObjectName("gr_mode") | ||||||
|  |         self.rd_comp = QtWidgets.QRadioButton(self.tab_route) | ||||||
|  |         self.rd_comp.setChecked(True) | ||||||
|  |         self.rd_comp.setObjectName("rd_comp") | ||||||
|  |         self.gr_mode.addWidget(self.rd_comp, 0, 1, 1, 1) | ||||||
|  |         self.rd_precomp = QtWidgets.QRadioButton(self.tab_route) | ||||||
|  |         self.rd_precomp.setObjectName("rd_precomp") | ||||||
|  |         self.gr_mode.addWidget(self.rd_precomp, 0, 2, 1, 1) | ||||||
|  |         self.formLayout_2.setLayout(3, QtWidgets.QFormLayout.FieldRole, self.gr_mode) | ||||||
|  |         self.chk_permute = QtWidgets.QCheckBox(self.tab_route) | ||||||
|  |         self.chk_permute.setObjectName("chk_permute") | ||||||
|  |         self.formLayout_2.setWidget( | ||||||
|  |             4, QtWidgets.QFormLayout.LabelRole, self.chk_permute | ||||||
|  |         ) | ||||||
|  |         self.gridLayout_4 = QtWidgets.QGridLayout() | ||||||
|  |         self.gridLayout_4.setObjectName("gridLayout_4") | ||||||
|  |         self.chk_permute_keep_last = QtWidgets.QCheckBox(self.tab_route) | ||||||
|  |         self.chk_permute_keep_last.setObjectName("chk_permute_keep_last") | ||||||
|  |         self.gridLayout_4.addWidget(self.chk_permute_keep_last, 0, 3, 1, 1) | ||||||
|  |         self.chk_permute_keep_first = QtWidgets.QCheckBox(self.tab_route) | ||||||
|  |         sizePolicy = QtWidgets.QSizePolicy( | ||||||
|  |             QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed | ||||||
|  |         ) | ||||||
|  |         sizePolicy.setHorizontalStretch(0) | ||||||
|  |         sizePolicy.setVerticalStretch(0) | ||||||
|  |         sizePolicy.setHeightForWidth( | ||||||
|  |             self.chk_permute_keep_first.sizePolicy().hasHeightForWidth() | ||||||
|  |         ) | ||||||
|  |         self.chk_permute_keep_first.setSizePolicy(sizePolicy) | ||||||
|  |         self.chk_permute_keep_first.setTristate(False) | ||||||
|  |         self.chk_permute_keep_first.setObjectName("chk_permute_keep_first") | ||||||
|  |         self.gridLayout_4.addWidget(self.chk_permute_keep_first, 0, 2, 1, 1) | ||||||
|  |         self.lbl_keep = QtWidgets.QLabel(self.tab_route) | ||||||
|  |         sizePolicy = QtWidgets.QSizePolicy( | ||||||
|  |             QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred | ||||||
|  |         ) | ||||||
|  |         sizePolicy.setHorizontalStretch(0) | ||||||
|  |         sizePolicy.setVerticalStretch(0) | ||||||
|  |         sizePolicy.setHeightForWidth(self.lbl_keep.sizePolicy().hasHeightForWidth()) | ||||||
|  |         self.lbl_keep.setSizePolicy(sizePolicy) | ||||||
|  |         self.lbl_keep.setObjectName("lbl_keep") | ||||||
|  |         self.gridLayout_4.addWidget(self.lbl_keep, 0, 1, 1, 1) | ||||||
|  |         self.formLayout_2.setLayout( | ||||||
|  |             4, QtWidgets.QFormLayout.FieldRole, self.gridLayout_4 | ||||||
|  |         ) | ||||||
|  |         self.lst_sys = QtWidgets.QTreeWidget(self.tab_route) | ||||||
|  |         sizePolicy = QtWidgets.QSizePolicy( | ||||||
|  |             QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Expanding | ||||||
|  |         ) | ||||||
|  |         sizePolicy.setHorizontalStretch(0) | ||||||
|  |         sizePolicy.setVerticalStretch(0) | ||||||
|  |         sizePolicy.setHeightForWidth(self.lst_sys.sizePolicy().hasHeightForWidth()) | ||||||
|  |         self.lst_sys.setSizePolicy(sizePolicy) | ||||||
|  |         self.lst_sys.setMinimumSize(QtCore.QSize(0, 0)) | ||||||
|  |         self.lst_sys.setDragEnabled(True) | ||||||
|  |         self.lst_sys.setDragDropOverwriteMode(False) | ||||||
|  |         self.lst_sys.setDragDropMode(QtWidgets.QAbstractItemView.InternalMove) | ||||||
|  |         self.lst_sys.setDefaultDropAction(QtCore.Qt.MoveAction) | ||||||
|  |         self.lst_sys.setAlternatingRowColors(True) | ||||||
|  |         self.lst_sys.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) | ||||||
|  |         self.lst_sys.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows) | ||||||
|  |         self.lst_sys.setHeaderHidden(True) | ||||||
|  |         self.lst_sys.setObjectName("lst_sys") | ||||||
|  |         self.lst_sys.headerItem().setText(0, "Name") | ||||||
|  |         self.lst_sys.header().setVisible(False) | ||||||
|  |         self.formLayout_2.setWidget(7, QtWidgets.QFormLayout.SpanningRole, self.lst_sys) | ||||||
|  |         self.lbl_range = QtWidgets.QLabel(self.tab_route) | ||||||
|  |         self.lbl_range.setObjectName("lbl_range") | ||||||
|  |         self.formLayout_2.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.lbl_range) | ||||||
|  |         self.sb_range = QtWidgets.QDoubleSpinBox(self.tab_route) | ||||||
|  |         self.sb_range.setObjectName("sb_range") | ||||||
|  |         self.formLayout_2.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.sb_range) | ||||||
|  |         self.gr_opts = QtWidgets.QGridLayout() | ||||||
|  |         self.gr_opts.setObjectName("gr_opts") | ||||||
|  |         self.cmb_mode = QtWidgets.QComboBox(self.tab_route) | ||||||
|  |         self.cmb_mode.setObjectName("cmb_mode") | ||||||
|  |         self.cmb_mode.addItem("") | ||||||
|  |         self.cmb_mode.addItem("") | ||||||
|  |         self.cmb_mode.addItem("") | ||||||
|  |         self.gr_opts.addWidget(self.cmb_mode, 0, 2, 1, 1) | ||||||
|  |         self.lbl_greedyness = QtWidgets.QLabel(self.tab_route) | ||||||
|  |         self.lbl_greedyness.setEnabled(True) | ||||||
|  |         self.lbl_greedyness.setObjectName("lbl_greedyness") | ||||||
|  |         self.gr_opts.addWidget(self.lbl_greedyness, 1, 1, 1, 1) | ||||||
|  |         self.chk_primary = QtWidgets.QCheckBox(self.tab_route) | ||||||
|  |         self.chk_primary.setObjectName("chk_primary") | ||||||
|  |         self.gr_opts.addWidget(self.chk_primary, 0, 3, 1, 1) | ||||||
|  |         self.sld_greedyness = QtWidgets.QSlider(self.tab_route) | ||||||
|  |         self.sld_greedyness.setMaximum(100) | ||||||
|  |         self.sld_greedyness.setPageStep(10) | ||||||
|  |         self.sld_greedyness.setProperty("value", 50) | ||||||
|  |         self.sld_greedyness.setOrientation(QtCore.Qt.Horizontal) | ||||||
|  |         self.sld_greedyness.setTickPosition(QtWidgets.QSlider.TicksBelow) | ||||||
|  |         self.sld_greedyness.setTickInterval(10) | ||||||
|  |         self.sld_greedyness.setObjectName("sld_greedyness") | ||||||
|  |         self.gr_opts.addWidget(self.sld_greedyness, 1, 2, 1, 2) | ||||||
|  |         self.lbl_mode = QtWidgets.QLabel(self.tab_route) | ||||||
|  |         self.lbl_mode.setObjectName("lbl_mode") | ||||||
|  |         self.gr_opts.addWidget(self.lbl_mode, 0, 1, 1, 1) | ||||||
|  |         self.formLayout_2.setLayout(9, QtWidgets.QFormLayout.SpanningRole, self.gr_opts) | ||||||
|  |         self.btn_go = QtWidgets.QPushButton(self.tab_route) | ||||||
|  |         self.btn_go.setFlat(False) | ||||||
|  |         self.btn_go.setObjectName("btn_go") | ||||||
|  |         self.formLayout_2.setWidget(10, QtWidgets.QFormLayout.LabelRole, self.btn_go) | ||||||
|  |         self.tabs.addTab(self.tab_route, "") | ||||||
|  |         self.tab_log = QtWidgets.QWidget() | ||||||
|  |         self.tab_log.setObjectName("tab_log") | ||||||
|  |         self.gridLayout_3 = QtWidgets.QGridLayout(self.tab_log) | ||||||
|  |         self.gridLayout_3.setObjectName("gridLayout_3") | ||||||
|  |         self.txt_log = QtWidgets.QTextEdit(self.tab_log) | ||||||
|  |         self.txt_log.setEnabled(True) | ||||||
|  |         self.txt_log.setFrameShadow(QtWidgets.QFrame.Sunken) | ||||||
|  |         self.txt_log.setLineWidth(1) | ||||||
|  |         self.txt_log.setReadOnly(True) | ||||||
|  |         self.txt_log.setAcceptRichText(False) | ||||||
|  |         self.txt_log.setObjectName("txt_log") | ||||||
|  |         self.gridLayout_3.addWidget(self.txt_log, 0, 0, 1, 1) | ||||||
|  |         self.tabs.addTab(self.tab_log, "") | ||||||
|  |         self.verticalLayout.addWidget(self.tabs) | ||||||
|  |         ED_LRR.setCentralWidget(self.centralwidget) | ||||||
|  |         self.menu = QtWidgets.QMenuBar(ED_LRR) | ||||||
|  |         self.menu.setGeometry(QtCore.QRect(0, 0, 577, 21)) | ||||||
|  |         self.menu.setObjectName("menu") | ||||||
|  |         self.menu_file = QtWidgets.QMenu(self.menu) | ||||||
|  |         self.menu_file.setObjectName("menu_file") | ||||||
|  |         self.menuWindow = QtWidgets.QMenu(self.menu) | ||||||
|  |         self.menuWindow.setObjectName("menuWindow") | ||||||
|  |         self.menuStyle = QtWidgets.QMenu(self.menuWindow) | ||||||
|  |         self.menuStyle.setObjectName("menuStyle") | ||||||
|  |         ED_LRR.setMenuBar(self.menu) | ||||||
|  |         self.bar_status = QtWidgets.QStatusBar(ED_LRR) | ||||||
|  |         self.bar_status.setObjectName("bar_status") | ||||||
|  |         ED_LRR.setStatusBar(self.bar_status) | ||||||
|  |         self.menu_act_quit = QtWidgets.QAction(ED_LRR) | ||||||
|  |         self.menu_act_quit.setObjectName("menu_act_quit") | ||||||
|  |         self.actionA = QtWidgets.QAction(ED_LRR) | ||||||
|  |         self.actionA.setObjectName("actionA") | ||||||
|  |         self.actionB = QtWidgets.QAction(ED_LRR) | ||||||
|  |         self.actionB.setObjectName("actionB") | ||||||
|  |         self.menu_file.addAction(self.menu_act_quit) | ||||||
|  |         self.menuWindow.addAction(self.menuStyle.menuAction()) | ||||||
|  |         self.menu.addAction(self.menu_file.menuAction()) | ||||||
|  |         self.menu.addAction(self.menuWindow.menuAction()) | ||||||
|  | 
 | ||||||
|  |         self.retranslateUi(ED_LRR) | ||||||
|  |         self.tabs.setCurrentIndex(2) | ||||||
|  |         self.menu_act_quit.triggered.connect(ED_LRR.close) | ||||||
|  |         QtCore.QMetaObject.connectSlotsByName(ED_LRR) | ||||||
|  |         ED_LRR.setTabOrder(self.rd_comp, self.cmb_mode) | ||||||
|  |         ED_LRR.setTabOrder(self.cmb_mode, self.chk_primary) | ||||||
|  |         ED_LRR.setTabOrder(self.chk_primary, self.sld_greedyness) | ||||||
|  |         ED_LRR.setTabOrder(self.sld_greedyness, self.rd_precomp) | ||||||
|  | 
 | ||||||
|  |     def retranslateUi(self, ED_LRR): | ||||||
|  |         _translate = QtCore.QCoreApplication.translate | ||||||
|  |         ED_LRR.setWindowTitle( | ||||||
|  |             _translate("ED_LRR", "Elite: Dangerous Long Range Route Plotter") | ||||||
|  |         ) | ||||||
|  |         self.lbl_bodies_dl.setText(_translate("ED_LRR", "bodies.json")) | ||||||
|  |         self.lbl_systems_dl.setText(_translate("ED_LRR", "systemsWithCoordinates.json")) | ||||||
|  |         self.inp_bodies_dl.setCurrentText( | ||||||
|  |             _translate("ED_LRR", "https://www.edsm.net/dump/bodies.json") | ||||||
|  |         ) | ||||||
|  |         self.inp_systems_dl.setCurrentText( | ||||||
|  |             _translate( | ||||||
|  |                 "ED_LRR", "https://www.edsm.net/dump/systemsWithCoordinates.json" | ||||||
|  |             ) | ||||||
|  |         ) | ||||||
|  |         self.btn_bodies_dest_browse_dl.setText(_translate("ED_LRR", "...")) | ||||||
|  |         self.btn_systems_dest_browse_dl.setText(_translate("ED_LRR", "...")) | ||||||
|  |         self.btn_download.setText(_translate("ED_LRR", "Download")) | ||||||
|  |         self.label.setText(_translate("ED_LRR", "Download path")) | ||||||
|  |         self.label_2.setText(_translate("ED_LRR", "Download path")) | ||||||
|  |         self.tabs.setTabText( | ||||||
|  |             self.tabs.indexOf(self.tab_download), _translate("ED_LRR", "Download") | ||||||
|  |         ) | ||||||
|  |         self.lbl_bodies_pp.setText(_translate("ED_LRR", "bodies.json")) | ||||||
|  |         self.btn_bodies_browse_pp.setText(_translate("ED_LRR", "...")) | ||||||
|  |         self.lbl_systems_pp.setText(_translate("ED_LRR", "systemsWithCoordinates.json")) | ||||||
|  |         self.btn_systems_browse_pp.setText(_translate("ED_LRR", "...")) | ||||||
|  |         self.lbl_out_pp.setText(_translate("ED_LRR", "Output")) | ||||||
|  |         self.btn_out_browse_pp.setText(_translate("ED_LRR", "...")) | ||||||
|  |         self.btn_preprocess.setText(_translate("ED_LRR", "Preprocess")) | ||||||
|  |         self.tabs.setTabText( | ||||||
|  |             self.tabs.indexOf(self.tab_preprocess), _translate("ED_LRR", "Preprocess") | ||||||
|  |         ) | ||||||
|  |         self.lbl_sys_lst.setText(_translate("ED_LRR", "System List")) | ||||||
|  |         self.btn_sys_lst_browse.setText(_translate("ED_LRR", "...")) | ||||||
|  |         self.btn_add.setText(_translate("ED_LRR", "Add")) | ||||||
|  |         self.inp_sys.setPlaceholderText(_translate("ED_LRR", "System Name")) | ||||||
|  |         self.btn_rm.setText(_translate("ED_LRR", "Remove")) | ||||||
|  |         self.rd_comp.setText(_translate("ED_LRR", "Compute Route")) | ||||||
|  |         self.rd_precomp.setText(_translate("ED_LRR", "Precompute Graph")) | ||||||
|  |         self.chk_permute.setText(_translate("ED_LRR", "Permute")) | ||||||
|  |         self.chk_permute_keep_last.setText(_translate("ED_LRR", "Last")) | ||||||
|  |         self.chk_permute_keep_first.setText(_translate("ED_LRR", "First")) | ||||||
|  |         self.lbl_keep.setText(_translate("ED_LRR", "Keep Endpoints:")) | ||||||
|  |         self.lst_sys.headerItem().setText(1, _translate("ED_LRR", "Type")) | ||||||
|  |         self.lbl_range.setText(_translate("ED_LRR", "Jump Range (Ly)")) | ||||||
|  |         self.cmb_mode.setCurrentText(_translate("ED_LRR", "Breadth-First Search")) | ||||||
|  |         self.cmb_mode.setItemText(0, _translate("ED_LRR", "Breadth-First Search")) | ||||||
|  |         self.cmb_mode.setItemText(1, _translate("ED_LRR", "Greedy-Search")) | ||||||
|  |         self.cmb_mode.setItemText(2, _translate("ED_LRR", "A*-Search")) | ||||||
|  |         self.lbl_greedyness.setText(_translate("ED_LRR", "Greedyness Factor")) | ||||||
|  |         self.chk_primary.setText(_translate("ED_LRR", "Primary Stars Only")) | ||||||
|  |         self.lbl_mode.setText(_translate("ED_LRR", "Mode")) | ||||||
|  |         self.btn_go.setText(_translate("ED_LRR", "GO!")) | ||||||
|  |         self.tabs.setTabText( | ||||||
|  |             self.tabs.indexOf(self.tab_route), _translate("ED_LRR", "Route") | ||||||
|  |         ) | ||||||
|  |         self.tabs.setTabText( | ||||||
|  |             self.tabs.indexOf(self.tab_log), _translate("ED_LRR", "Log") | ||||||
|  |         ) | ||||||
|  |         self.menu_file.setTitle(_translate("ED_LRR", "File")) | ||||||
|  |         self.menuWindow.setTitle(_translate("ED_LRR", "Window")) | ||||||
|  |         self.menuStyle.setTitle(_translate("ED_LRR", "Style")) | ||||||
|  |         self.menu_act_quit.setText(_translate("ED_LRR", "Quit")) | ||||||
|  |         self.menu_act_quit.setShortcut(_translate("ED_LRR", "Ctrl+Q")) | ||||||
|  |         self.actionA.setText(_translate("ED_LRR", "A")) | ||||||
|  |         self.actionB.setText(_translate("ED_LRR", "B")) | ||||||
							
								
								
									
										710
									
								
								ed_lrr_gui/gui/ed_lrr.ui
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										710
									
								
								ed_lrr_gui/gui/ed_lrr.ui
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,710 @@ | ||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <ui version="4.0"> | ||||||
|  |  <class>ED_LRR</class> | ||||||
|  |  <widget class="QMainWindow" name="ED_LRR"> | ||||||
|  |   <property name="enabled"> | ||||||
|  |    <bool>true</bool> | ||||||
|  |   </property> | ||||||
|  |   <property name="geometry"> | ||||||
|  |    <rect> | ||||||
|  |     <x>0</x> | ||||||
|  |     <y>0</y> | ||||||
|  |     <width>577</width> | ||||||
|  |     <height>500</height> | ||||||
|  |    </rect> | ||||||
|  |   </property> | ||||||
|  |   <property name="sizePolicy"> | ||||||
|  |    <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> | ||||||
|  |     <horstretch>0</horstretch> | ||||||
|  |     <verstretch>0</verstretch> | ||||||
|  |    </sizepolicy> | ||||||
|  |   </property> | ||||||
|  |   <property name="minimumSize"> | ||||||
|  |    <size> | ||||||
|  |     <width>577</width> | ||||||
|  |     <height>500</height> | ||||||
|  |    </size> | ||||||
|  |   </property> | ||||||
|  |   <property name="maximumSize"> | ||||||
|  |    <size> | ||||||
|  |     <width>577</width> | ||||||
|  |     <height>500</height> | ||||||
|  |    </size> | ||||||
|  |   </property> | ||||||
|  |   <property name="windowTitle"> | ||||||
|  |    <string>Elite: Dangerous Long Range Route Plotter</string> | ||||||
|  |   </property> | ||||||
|  |   <property name="styleSheet"> | ||||||
|  |    <string notr="true"/> | ||||||
|  |   </property> | ||||||
|  |   <property name="documentMode"> | ||||||
|  |    <bool>false</bool> | ||||||
|  |   </property> | ||||||
|  |   <property name="tabShape"> | ||||||
|  |    <enum>QTabWidget::Rounded</enum> | ||||||
|  |   </property> | ||||||
|  |   <widget class="QWidget" name="centralwidget"> | ||||||
|  |    <property name="sizePolicy"> | ||||||
|  |     <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> | ||||||
|  |      <horstretch>0</horstretch> | ||||||
|  |      <verstretch>0</verstretch> | ||||||
|  |     </sizepolicy> | ||||||
|  |    </property> | ||||||
|  |    <layout class="QVBoxLayout" name="verticalLayout"> | ||||||
|  |     <item> | ||||||
|  |      <widget class="QTabWidget" name="tabs"> | ||||||
|  |       <property name="enabled"> | ||||||
|  |        <bool>true</bool> | ||||||
|  |       </property> | ||||||
|  |       <property name="autoFillBackground"> | ||||||
|  |        <bool>false</bool> | ||||||
|  |       </property> | ||||||
|  |       <property name="tabPosition"> | ||||||
|  |        <enum>QTabWidget::North</enum> | ||||||
|  |       </property> | ||||||
|  |       <property name="tabShape"> | ||||||
|  |        <enum>QTabWidget::Rounded</enum> | ||||||
|  |       </property> | ||||||
|  |       <property name="currentIndex"> | ||||||
|  |        <number>2</number> | ||||||
|  |       </property> | ||||||
|  |       <property name="elideMode"> | ||||||
|  |        <enum>Qt::ElideNone</enum> | ||||||
|  |       </property> | ||||||
|  |       <property name="tabsClosable"> | ||||||
|  |        <bool>false</bool> | ||||||
|  |       </property> | ||||||
|  |       <property name="tabBarAutoHide"> | ||||||
|  |        <bool>false</bool> | ||||||
|  |       </property> | ||||||
|  |       <widget class="QWidget" name="tab_download"> | ||||||
|  |        <attribute name="title"> | ||||||
|  |         <string>Download</string> | ||||||
|  |        </attribute> | ||||||
|  |        <layout class="QFormLayout" name="formLayout"> | ||||||
|  |         <item row="1" column="0"> | ||||||
|  |          <widget class="QLabel" name="lbl_bodies_dl"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>bodies.json</string> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="3" column="0"> | ||||||
|  |          <widget class="QLabel" name="lbl_systems_dl"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>systemsWithCoordinates.json</string> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="1" column="1"> | ||||||
|  |          <widget class="QComboBox" name="inp_bodies_dl"> | ||||||
|  |           <property name="editable"> | ||||||
|  |            <bool>true</bool> | ||||||
|  |           </property> | ||||||
|  |           <property name="currentText"> | ||||||
|  |            <string>https://www.edsm.net/dump/bodies.json</string> | ||||||
|  |           </property> | ||||||
|  |           <property name="insertPolicy"> | ||||||
|  |            <enum>QComboBox::InsertAtTop</enum> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="3" column="1"> | ||||||
|  |          <widget class="QComboBox" name="inp_systems_dl"> | ||||||
|  |           <property name="editable"> | ||||||
|  |            <bool>true</bool> | ||||||
|  |           </property> | ||||||
|  |           <property name="currentText"> | ||||||
|  |            <string>https://www.edsm.net/dump/systemsWithCoordinates.json</string> | ||||||
|  |           </property> | ||||||
|  |           <property name="insertPolicy"> | ||||||
|  |            <enum>QComboBox::InsertAtTop</enum> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="2" column="1"> | ||||||
|  |          <layout class="QGridLayout" name="gridLayout"> | ||||||
|  |           <item row="0" column="0"> | ||||||
|  |            <widget class="QComboBox" name="inp_bodies_dest_dl"> | ||||||
|  |             <property name="sizePolicy"> | ||||||
|  |              <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> | ||||||
|  |               <horstretch>0</horstretch> | ||||||
|  |               <verstretch>0</verstretch> | ||||||
|  |              </sizepolicy> | ||||||
|  |             </property> | ||||||
|  |             <property name="editable"> | ||||||
|  |              <bool>false</bool> | ||||||
|  |             </property> | ||||||
|  |             <property name="insertPolicy"> | ||||||
|  |              <enum>QComboBox::InsertAtTop</enum> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |           <item row="0" column="1"> | ||||||
|  |            <widget class="QPushButton" name="btn_bodies_dest_browse_dl"> | ||||||
|  |             <property name="text"> | ||||||
|  |              <string>...</string> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |          </layout> | ||||||
|  |         </item> | ||||||
|  |         <item row="4" column="1"> | ||||||
|  |          <layout class="QGridLayout" name="gridLayout_2"> | ||||||
|  |           <item row="0" column="1"> | ||||||
|  |            <widget class="QPushButton" name="btn_systems_dest_browse_dl"> | ||||||
|  |             <property name="text"> | ||||||
|  |              <string>...</string> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |           <item row="0" column="0"> | ||||||
|  |            <widget class="QComboBox" name="inp_systems_dest_dl"> | ||||||
|  |             <property name="sizePolicy"> | ||||||
|  |              <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> | ||||||
|  |               <horstretch>0</horstretch> | ||||||
|  |               <verstretch>0</verstretch> | ||||||
|  |              </sizepolicy> | ||||||
|  |             </property> | ||||||
|  |             <property name="editable"> | ||||||
|  |              <bool>false</bool> | ||||||
|  |             </property> | ||||||
|  |             <property name="insertPolicy"> | ||||||
|  |              <enum>QComboBox::InsertAtTop</enum> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |          </layout> | ||||||
|  |         </item> | ||||||
|  |         <item row="5" column="0"> | ||||||
|  |          <widget class="QPushButton" name="btn_download"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>Download</string> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="2" column="0"> | ||||||
|  |          <widget class="QLabel" name="label"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>Download path</string> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="4" column="0"> | ||||||
|  |          <widget class="QLabel" name="label_2"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>Download path</string> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |        </layout> | ||||||
|  |       </widget> | ||||||
|  |       <widget class="QWidget" name="tab_preprocess"> | ||||||
|  |        <attribute name="title"> | ||||||
|  |         <string>Preprocess</string> | ||||||
|  |        </attribute> | ||||||
|  |        <layout class="QFormLayout" name="formLayout_3"> | ||||||
|  |         <item row="0" column="0"> | ||||||
|  |          <widget class="QLabel" name="lbl_bodies_pp"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>bodies.json</string> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="0" column="1"> | ||||||
|  |          <layout class="QGridLayout" name="gr_bodies_pp"> | ||||||
|  |           <item row="0" column="1"> | ||||||
|  |            <widget class="QPushButton" name="btn_bodies_browse_pp"> | ||||||
|  |             <property name="text"> | ||||||
|  |              <string>...</string> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |           <item row="0" column="0"> | ||||||
|  |            <widget class="QComboBox" name="inp_bodies_pp"> | ||||||
|  |             <property name="sizePolicy"> | ||||||
|  |              <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> | ||||||
|  |               <horstretch>0</horstretch> | ||||||
|  |               <verstretch>0</verstretch> | ||||||
|  |              </sizepolicy> | ||||||
|  |             </property> | ||||||
|  |             <property name="editable"> | ||||||
|  |              <bool>false</bool> | ||||||
|  |             </property> | ||||||
|  |             <property name="insertPolicy"> | ||||||
|  |              <enum>QComboBox::InsertAtTop</enum> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |          </layout> | ||||||
|  |         </item> | ||||||
|  |         <item row="1" column="0"> | ||||||
|  |          <widget class="QLabel" name="lbl_systems_pp"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>systemsWithCoordinates.json</string> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="1" column="1"> | ||||||
|  |          <layout class="QGridLayout" name="gr_systems_pp"> | ||||||
|  |           <item row="0" column="1"> | ||||||
|  |            <widget class="QPushButton" name="btn_systems_browse_pp"> | ||||||
|  |             <property name="text"> | ||||||
|  |              <string>...</string> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |           <item row="0" column="0"> | ||||||
|  |            <widget class="QComboBox" name="inp_systems_pp"> | ||||||
|  |             <property name="sizePolicy"> | ||||||
|  |              <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> | ||||||
|  |               <horstretch>0</horstretch> | ||||||
|  |               <verstretch>0</verstretch> | ||||||
|  |              </sizepolicy> | ||||||
|  |             </property> | ||||||
|  |             <property name="editable"> | ||||||
|  |              <bool>false</bool> | ||||||
|  |             </property> | ||||||
|  |             <property name="insertPolicy"> | ||||||
|  |              <enum>QComboBox::InsertAtTop</enum> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |          </layout> | ||||||
|  |         </item> | ||||||
|  |         <item row="2" column="0"> | ||||||
|  |          <widget class="QLabel" name="lbl_out_pp"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>Output</string> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="2" column="1"> | ||||||
|  |          <layout class="QGridLayout" name="gr_out_grid_pp"> | ||||||
|  |           <item row="0" column="1"> | ||||||
|  |            <widget class="QPushButton" name="btn_out_browse_pp"> | ||||||
|  |             <property name="sizePolicy"> | ||||||
|  |              <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> | ||||||
|  |               <horstretch>0</horstretch> | ||||||
|  |               <verstretch>0</verstretch> | ||||||
|  |              </sizepolicy> | ||||||
|  |             </property> | ||||||
|  |             <property name="text"> | ||||||
|  |              <string>...</string> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |           <item row="0" column="0"> | ||||||
|  |            <widget class="QComboBox" name="inp_out_pp"> | ||||||
|  |             <property name="sizePolicy"> | ||||||
|  |              <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> | ||||||
|  |               <horstretch>0</horstretch> | ||||||
|  |               <verstretch>0</verstretch> | ||||||
|  |              </sizepolicy> | ||||||
|  |             </property> | ||||||
|  |             <property name="editable"> | ||||||
|  |              <bool>false</bool> | ||||||
|  |             </property> | ||||||
|  |             <property name="insertPolicy"> | ||||||
|  |              <enum>QComboBox::InsertAtTop</enum> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |          </layout> | ||||||
|  |         </item> | ||||||
|  |         <item row="3" column="0"> | ||||||
|  |          <widget class="QPushButton" name="btn_preprocess"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>Preprocess</string> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |        </layout> | ||||||
|  |       </widget> | ||||||
|  |       <widget class="QWidget" name="tab_route"> | ||||||
|  |        <attribute name="title"> | ||||||
|  |         <string>Route</string> | ||||||
|  |        </attribute> | ||||||
|  |        <layout class="QFormLayout" name="formLayout_2"> | ||||||
|  |         <item row="0" column="0"> | ||||||
|  |          <widget class="QLabel" name="lbl_sys_lst"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>System List</string> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="0" column="1"> | ||||||
|  |          <layout class="QGridLayout" name="gr_sys"> | ||||||
|  |           <item row="0" column="1"> | ||||||
|  |            <widget class="QPushButton" name="btn_sys_lst_browse"> | ||||||
|  |             <property name="text"> | ||||||
|  |              <string>...</string> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |           <item row="0" column="0"> | ||||||
|  |            <widget class="QComboBox" name="inp_sys_lst"> | ||||||
|  |             <property name="sizePolicy"> | ||||||
|  |              <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> | ||||||
|  |               <horstretch>0</horstretch> | ||||||
|  |               <verstretch>0</verstretch> | ||||||
|  |              </sizepolicy> | ||||||
|  |             </property> | ||||||
|  |             <property name="editable"> | ||||||
|  |              <bool>false</bool> | ||||||
|  |             </property> | ||||||
|  |             <property name="insertPolicy"> | ||||||
|  |              <enum>QComboBox::InsertAtTop</enum> | ||||||
|  |             </property> | ||||||
|  |             <property name="frame"> | ||||||
|  |              <bool>true</bool> | ||||||
|  |             </property> | ||||||
|  |             <property name="modelColumn"> | ||||||
|  |              <number>0</number> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |          </layout> | ||||||
|  |         </item> | ||||||
|  |         <item row="1" column="0"> | ||||||
|  |          <widget class="QPushButton" name="btn_add"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>Add</string> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="1" column="1"> | ||||||
|  |          <widget class="QLineEdit" name="inp_sys"> | ||||||
|  |           <property name="placeholderText"> | ||||||
|  |            <string>System Name</string> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="3" column="0"> | ||||||
|  |          <widget class="QPushButton" name="btn_rm"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>Remove</string> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="3" column="1"> | ||||||
|  |          <layout class="QGridLayout" name="gr_mode"> | ||||||
|  |           <item row="0" column="1"> | ||||||
|  |            <widget class="QRadioButton" name="rd_comp"> | ||||||
|  |             <property name="text"> | ||||||
|  |              <string>Compute Route</string> | ||||||
|  |             </property> | ||||||
|  |             <property name="checked"> | ||||||
|  |              <bool>true</bool> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |           <item row="0" column="2"> | ||||||
|  |            <widget class="QRadioButton" name="rd_precomp"> | ||||||
|  |             <property name="text"> | ||||||
|  |              <string>Precompute Graph</string> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |          </layout> | ||||||
|  |         </item> | ||||||
|  |         <item row="4" column="0"> | ||||||
|  |          <widget class="QCheckBox" name="chk_permute"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>Permute</string> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="4" column="1"> | ||||||
|  |          <layout class="QGridLayout" name="gridLayout_4"> | ||||||
|  |           <item row="0" column="3"> | ||||||
|  |            <widget class="QCheckBox" name="chk_permute_keep_last"> | ||||||
|  |             <property name="text"> | ||||||
|  |              <string>Last</string> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |           <item row="0" column="2"> | ||||||
|  |            <widget class="QCheckBox" name="chk_permute_keep_first"> | ||||||
|  |             <property name="sizePolicy"> | ||||||
|  |              <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> | ||||||
|  |               <horstretch>0</horstretch> | ||||||
|  |               <verstretch>0</verstretch> | ||||||
|  |              </sizepolicy> | ||||||
|  |             </property> | ||||||
|  |             <property name="text"> | ||||||
|  |              <string>First</string> | ||||||
|  |             </property> | ||||||
|  |             <property name="tristate"> | ||||||
|  |              <bool>false</bool> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |           <item row="0" column="1"> | ||||||
|  |            <widget class="QLabel" name="lbl_keep"> | ||||||
|  |             <property name="sizePolicy"> | ||||||
|  |              <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> | ||||||
|  |               <horstretch>0</horstretch> | ||||||
|  |               <verstretch>0</verstretch> | ||||||
|  |              </sizepolicy> | ||||||
|  |             </property> | ||||||
|  |             <property name="text"> | ||||||
|  |              <string>Keep Endpoints:</string> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |          </layout> | ||||||
|  |         </item> | ||||||
|  |         <item row="7" column="0" colspan="2"> | ||||||
|  |          <widget class="QTreeWidget" name="lst_sys"> | ||||||
|  |           <property name="sizePolicy"> | ||||||
|  |            <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> | ||||||
|  |             <horstretch>0</horstretch> | ||||||
|  |             <verstretch>0</verstretch> | ||||||
|  |            </sizepolicy> | ||||||
|  |           </property> | ||||||
|  |           <property name="minimumSize"> | ||||||
|  |            <size> | ||||||
|  |             <width>0</width> | ||||||
|  |             <height>0</height> | ||||||
|  |            </size> | ||||||
|  |           </property> | ||||||
|  |           <property name="dragEnabled"> | ||||||
|  |            <bool>true</bool> | ||||||
|  |           </property> | ||||||
|  |           <property name="dragDropOverwriteMode"> | ||||||
|  |            <bool>false</bool> | ||||||
|  |           </property> | ||||||
|  |           <property name="dragDropMode"> | ||||||
|  |            <enum>QAbstractItemView::InternalMove</enum> | ||||||
|  |           </property> | ||||||
|  |           <property name="defaultDropAction"> | ||||||
|  |            <enum>Qt::MoveAction</enum> | ||||||
|  |           </property> | ||||||
|  |           <property name="alternatingRowColors"> | ||||||
|  |            <bool>true</bool> | ||||||
|  |           </property> | ||||||
|  |           <property name="selectionMode"> | ||||||
|  |            <enum>QAbstractItemView::ExtendedSelection</enum> | ||||||
|  |           </property> | ||||||
|  |           <property name="selectionBehavior"> | ||||||
|  |            <enum>QAbstractItemView::SelectRows</enum> | ||||||
|  |           </property> | ||||||
|  |           <property name="headerHidden"> | ||||||
|  |            <bool>true</bool> | ||||||
|  |           </property> | ||||||
|  |           <attribute name="headerVisible"> | ||||||
|  |            <bool>false</bool> | ||||||
|  |           </attribute> | ||||||
|  |           <column> | ||||||
|  |            <property name="text"> | ||||||
|  |             <string notr="true">Name</string> | ||||||
|  |            </property> | ||||||
|  |           </column> | ||||||
|  |           <column> | ||||||
|  |            <property name="text"> | ||||||
|  |             <string>Type</string> | ||||||
|  |            </property> | ||||||
|  |           </column> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="8" column="0"> | ||||||
|  |          <widget class="QLabel" name="lbl_range"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>Jump Range (Ly)</string> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |         <item row="8" column="1"> | ||||||
|  |          <widget class="QDoubleSpinBox" name="sb_range"/> | ||||||
|  |         </item> | ||||||
|  |         <item row="9" column="0" colspan="2"> | ||||||
|  |          <layout class="QGridLayout" name="gr_opts"> | ||||||
|  |           <item row="0" column="2"> | ||||||
|  |            <widget class="QComboBox" name="cmb_mode"> | ||||||
|  |             <property name="currentText"> | ||||||
|  |              <string>Breadth-First Search</string> | ||||||
|  |             </property> | ||||||
|  |             <item> | ||||||
|  |              <property name="text"> | ||||||
|  |               <string>Breadth-First Search</string> | ||||||
|  |              </property> | ||||||
|  |             </item> | ||||||
|  |             <item> | ||||||
|  |              <property name="text"> | ||||||
|  |               <string>Greedy-Search</string> | ||||||
|  |              </property> | ||||||
|  |             </item> | ||||||
|  |             <item> | ||||||
|  |              <property name="text"> | ||||||
|  |               <string>A*-Search</string> | ||||||
|  |              </property> | ||||||
|  |             </item> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |           <item row="1" column="1"> | ||||||
|  |            <widget class="QLabel" name="lbl_greedyness"> | ||||||
|  |             <property name="enabled"> | ||||||
|  |              <bool>true</bool> | ||||||
|  |             </property> | ||||||
|  |             <property name="text"> | ||||||
|  |              <string>Greedyness Factor</string> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |           <item row="0" column="3"> | ||||||
|  |            <widget class="QCheckBox" name="chk_primary"> | ||||||
|  |             <property name="text"> | ||||||
|  |              <string>Primary Stars Only</string> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |           <item row="1" column="2" colspan="2"> | ||||||
|  |            <widget class="QSlider" name="sld_greedyness"> | ||||||
|  |             <property name="maximum"> | ||||||
|  |              <number>100</number> | ||||||
|  |             </property> | ||||||
|  |             <property name="pageStep"> | ||||||
|  |              <number>10</number> | ||||||
|  |             </property> | ||||||
|  |             <property name="value"> | ||||||
|  |              <number>50</number> | ||||||
|  |             </property> | ||||||
|  |             <property name="orientation"> | ||||||
|  |              <enum>Qt::Horizontal</enum> | ||||||
|  |             </property> | ||||||
|  |             <property name="tickPosition"> | ||||||
|  |              <enum>QSlider::TicksBelow</enum> | ||||||
|  |             </property> | ||||||
|  |             <property name="tickInterval"> | ||||||
|  |              <number>10</number> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |           <item row="0" column="1"> | ||||||
|  |            <widget class="QLabel" name="lbl_mode"> | ||||||
|  |             <property name="text"> | ||||||
|  |              <string>Mode</string> | ||||||
|  |             </property> | ||||||
|  |            </widget> | ||||||
|  |           </item> | ||||||
|  |          </layout> | ||||||
|  |         </item> | ||||||
|  |         <item row="10" column="0"> | ||||||
|  |          <widget class="QPushButton" name="btn_go"> | ||||||
|  |           <property name="text"> | ||||||
|  |            <string>GO!</string> | ||||||
|  |           </property> | ||||||
|  |           <property name="flat"> | ||||||
|  |            <bool>false</bool> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |        </layout> | ||||||
|  |       </widget> | ||||||
|  |       <widget class="QWidget" name="tab_log"> | ||||||
|  |        <attribute name="title"> | ||||||
|  |         <string>Log</string> | ||||||
|  |        </attribute> | ||||||
|  |        <layout class="QGridLayout" name="gridLayout_3"> | ||||||
|  |         <item row="0" column="0"> | ||||||
|  |          <widget class="QTextEdit" name="txt_log"> | ||||||
|  |           <property name="enabled"> | ||||||
|  |            <bool>true</bool> | ||||||
|  |           </property> | ||||||
|  |           <property name="frameShadow"> | ||||||
|  |            <enum>QFrame::Sunken</enum> | ||||||
|  |           </property> | ||||||
|  |           <property name="lineWidth"> | ||||||
|  |            <number>1</number> | ||||||
|  |           </property> | ||||||
|  |           <property name="readOnly"> | ||||||
|  |            <bool>true</bool> | ||||||
|  |           </property> | ||||||
|  |           <property name="acceptRichText"> | ||||||
|  |            <bool>false</bool> | ||||||
|  |           </property> | ||||||
|  |          </widget> | ||||||
|  |         </item> | ||||||
|  |        </layout> | ||||||
|  |       </widget> | ||||||
|  |      </widget> | ||||||
|  |     </item> | ||||||
|  |    </layout> | ||||||
|  |   </widget> | ||||||
|  |   <widget class="QMenuBar" name="menu"> | ||||||
|  |    <property name="geometry"> | ||||||
|  |     <rect> | ||||||
|  |      <x>0</x> | ||||||
|  |      <y>0</y> | ||||||
|  |      <width>577</width> | ||||||
|  |      <height>21</height> | ||||||
|  |     </rect> | ||||||
|  |    </property> | ||||||
|  |    <widget class="QMenu" name="menu_file"> | ||||||
|  |     <property name="title"> | ||||||
|  |      <string>File</string> | ||||||
|  |     </property> | ||||||
|  |     <addaction name="menu_act_quit"/> | ||||||
|  |    </widget> | ||||||
|  |    <widget class="QMenu" name="menuWindow"> | ||||||
|  |     <property name="title"> | ||||||
|  |      <string>Window</string> | ||||||
|  |     </property> | ||||||
|  |     <widget class="QMenu" name="menuStyle"> | ||||||
|  |      <property name="title"> | ||||||
|  |       <string>Style</string> | ||||||
|  |      </property> | ||||||
|  |     </widget> | ||||||
|  |     <addaction name="menuStyle"/> | ||||||
|  |    </widget> | ||||||
|  |    <addaction name="menu_file"/> | ||||||
|  |    <addaction name="menuWindow"/> | ||||||
|  |   </widget> | ||||||
|  |   <widget class="QStatusBar" name="bar_status"/> | ||||||
|  |   <action name="menu_act_quit"> | ||||||
|  |    <property name="text"> | ||||||
|  |     <string>Quit</string> | ||||||
|  |    </property> | ||||||
|  |    <property name="shortcut"> | ||||||
|  |     <string>Ctrl+Q</string> | ||||||
|  |    </property> | ||||||
|  |   </action> | ||||||
|  |   <action name="actionA"> | ||||||
|  |    <property name="text"> | ||||||
|  |     <string>A</string> | ||||||
|  |    </property> | ||||||
|  |   </action> | ||||||
|  |   <action name="actionB"> | ||||||
|  |    <property name="text"> | ||||||
|  |     <string>B</string> | ||||||
|  |    </property> | ||||||
|  |   </action> | ||||||
|  |  </widget> | ||||||
|  |  <tabstops> | ||||||
|  |   <tabstop>rd_comp</tabstop> | ||||||
|  |   <tabstop>cmb_mode</tabstop> | ||||||
|  |   <tabstop>chk_primary</tabstop> | ||||||
|  |   <tabstop>sld_greedyness</tabstop> | ||||||
|  |   <tabstop>rd_precomp</tabstop> | ||||||
|  |  </tabstops> | ||||||
|  |  <resources/> | ||||||
|  |  <connections> | ||||||
|  |   <connection> | ||||||
|  |    <sender>menu_act_quit</sender> | ||||||
|  |    <signal>triggered()</signal> | ||||||
|  |    <receiver>ED_LRR</receiver> | ||||||
|  |    <slot>close()</slot> | ||||||
|  |    <hints> | ||||||
|  |     <hint type="sourcelabel"> | ||||||
|  |      <x>-1</x> | ||||||
|  |      <y>-1</y> | ||||||
|  |     </hint> | ||||||
|  |     <hint type="destinationlabel"> | ||||||
|  |      <x>288</x> | ||||||
|  |      <y>249</y> | ||||||
|  |     </hint> | ||||||
|  |    </hints> | ||||||
|  |   </connection> | ||||||
|  |  </connections> | ||||||
|  | </ui> | ||||||
							
								
								
									
										681
									
								
								ed_lrr_gui/gui/main.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										681
									
								
								ed_lrr_gui/gui/main.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,681 @@ | ||||||
|  | import csv | ||||||
|  | import gzip | ||||||
|  | import multiprocessing as MP | ||||||
|  | import os | ||||||
|  | import pathlib | ||||||
|  | import queue | ||||||
|  | import sys | ||||||
|  | from sys import exit | ||||||
|  | from datetime import datetime, timedelta | ||||||
|  | from urllib.request import Request, urlopen | ||||||
|  | 
 | ||||||
|  | import _ed_lrr | ||||||
|  | import ed_lrr_gui | ||||||
|  | import requests as RQ | ||||||
|  | from ed_lrr_gui import Preprocessor, Router, cfg | ||||||
|  | from ed_lrr_gui.gui.ed_lrr import Ui_ED_LRR | ||||||
|  | from ed_lrr_gui.gui.widget_route import Ui_diag_route | ||||||
|  | from PyQt5.QtCore import QObject, Qt, QThread, QTimer, pyqtSignal | ||||||
|  | from PyQt5.QtGui import QColor, QPalette, QIcon | ||||||
|  | from PyQt5.QtWidgets import ( | ||||||
|  |     QAction, | ||||||
|  |     QApplication, | ||||||
|  |     QFileDialog, | ||||||
|  |     QMainWindow, | ||||||
|  |     QMessageBox, | ||||||
|  |     QProgressDialog, | ||||||
|  |     QTreeWidgetItem, | ||||||
|  |     QLabel, | ||||||
|  |     QDialog, | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ProgressDialog(QProgressDialog): | ||||||
|  |     def __init__(self, *args, **kwargs): | ||||||
|  |         super().__init__(*args, **kwargs) | ||||||
|  |         self.setWindowModality(Qt.WindowModal) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def sizeof_fmt(num, suffix="B"): | ||||||
|  |     for unit in ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi"]: | ||||||
|  |         if abs(num) < 1024.0: | ||||||
|  |             return "{:.02f} {}{}".format(num, unit, suffix) | ||||||
|  |         num /= 1024.0 | ||||||
|  |     return "{:.02f} {}{}".format(num, "Yi", suffix) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def t_round(dt): | ||||||
|  |     return dt - dt % timedelta(seconds=1) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Job(QObject): | ||||||
|  |     progress = pyqtSignal("PyQt_PyObject") | ||||||
|  | 
 | ||||||
|  |     def __init__(self, app, main_window, cls, *args, **kwargs): | ||||||
|  |         super().__init__() | ||||||
|  |         self.job = cls(*args, **kwargs) | ||||||
|  |         self.timer = QTimer(app) | ||||||
|  |         self.app = app | ||||||
|  |         self.main_window = main_window | ||||||
|  |         self.timer.timeout.connect(self.interval) | ||||||
|  |         self.timer.start(100) | ||||||
|  |         self.last_val = None | ||||||
|  |         self.progress_dialog = None | ||||||
|  |         self.state = {} | ||||||
|  |         self.setup_progress(self.handle_progess) | ||||||
|  | 
 | ||||||
|  |     def setup_progress(self, handle_progess): | ||||||
|  |         self.progress.connect(lambda *args, **kwargs: handle_progess(*args, **kwargs)) | ||||||
|  | 
 | ||||||
|  |     def handle_progess(self, *args, **kwargs): | ||||||
|  |         raise NotImplementedError | ||||||
|  | 
 | ||||||
|  |     def start(self): | ||||||
|  |         if self.progress_dialog is None: | ||||||
|  |             self.progress.connect( | ||||||
|  |                 lambda *args, **kwargs: print("PROGRESS:", *args, **kwargs) | ||||||
|  |             ) | ||||||
|  |         self.started = datetime.today() | ||||||
|  |         return self.job.start() | ||||||
|  | 
 | ||||||
|  |     def cancel(self): | ||||||
|  |         self.job.terminate() | ||||||
|  |         self.job = None | ||||||
|  | 
 | ||||||
|  |     def __bool__(self): | ||||||
|  |         return not self.done | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def done(self): | ||||||
|  |         if self.job: | ||||||
|  |             return (self.job.is_alive() == False) and (self.job.queue.empty()) | ||||||
|  |         return True | ||||||
|  | 
 | ||||||
|  |     def interval(self): | ||||||
|  |         while self: | ||||||
|  |             try: | ||||||
|  |                 res = self.job.queue.get(True, 0.1) | ||||||
|  |             except queue.Empty: | ||||||
|  |                 return | ||||||
|  |             if res == self.last_val: | ||||||
|  |                 continue | ||||||
|  |             self.state.update(res) | ||||||
|  |             self.progress.emit(self.state) | ||||||
|  |             self.last_val = res | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class PreprocessJob(Job): | ||||||
|  |     def __init__(self, app, main_window, *args, **kwargs): | ||||||
|  |         super().__init__(app, main_window, Preprocessor, *args, **kwargs) | ||||||
|  |         self.progress_dialog = ProgressDialog("", "Cancel", 0, 0, self.main_window) | ||||||
|  |         self.progress_dialog.setAutoClose(False) | ||||||
|  |         self.progress_dialog.canceled.connect(self.cancel) | ||||||
|  |         self.progress_dialog.show() | ||||||
|  |         self.start() | ||||||
|  | 
 | ||||||
|  |     def handle_progess(self, state): | ||||||
|  |         sent = object() | ||||||
|  |         if state.get("return", sent) != sent: | ||||||
|  |             self.progress_dialog.close() | ||||||
|  |             return | ||||||
|  |         msg = "Processed: {}/{}".format( | ||||||
|  |             sizeof_fmt(state["status"]["done"]), sizeof_fmt(state["status"]["total"]) | ||||||
|  |         ) | ||||||
|  |         state["status"]["prc_done"] = ( | ||||||
|  |             state["status"]["done"] / state["status"]["total"] | ||||||
|  |         ) * 100 | ||||||
|  |         title = "[{prc_done:.2f}%] Processing {file}".format(**state["status"]) | ||||||
|  |         self.progress_dialog.setMinimum(0) | ||||||
|  |         self.progress_dialog.setMaximum(100 * 100) | ||||||
|  |         self.progress_dialog.setWindowTitle(title) | ||||||
|  |         self.progress_dialog.setLabelText(msg) | ||||||
|  |         self.progress_dialog.setValue(int(state["status"]["prc_done"] * 100)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class RouterJob(Job): | ||||||
|  |     def __init__(self, app, main_window, *args, **kwargs): | ||||||
|  |         super().__init__(app, main_window, Router, *args, **kwargs) | ||||||
|  |         self.progress_dialog = ProgressDialog("", "Cancel", 0, 0, self.main_window) | ||||||
|  |         self.progress_dialog.setAutoClose(False) | ||||||
|  |         self.progress_dialog.setLabelText("Loading data (this will take a bit) ...") | ||||||
|  |         self.progress_dialog.setWindowTitle("Loading...") | ||||||
|  |         self.progress_dialog.canceled.connect(self.cancel) | ||||||
|  |         self.progress_dialog.show() | ||||||
|  |         self.start() | ||||||
|  |         self.state = {} | ||||||
|  | 
 | ||||||
|  |     def handle_progess(self, state): | ||||||
|  |         sent = object() | ||||||
|  |         if state.get("return", sent) != sent: | ||||||
|  |             print(state["return"]) | ||||||
|  |             self.progress_dialog.close() | ||||||
|  |             route_win = WRoute(self.main_window, state["return"]) | ||||||
|  |             return | ||||||
|  |         msg = "Depth: {depth}\nBody: {body}\nQueued: {queue_size}\nDistance remaining: {d_rem:.2f} Ly".format( | ||||||
|  |             **state["status"] | ||||||
|  |         ) | ||||||
|  |         title = "[{prc_done:.2f}%] Plotting route from [{from}] to [{to}]".format( | ||||||
|  |             **state["status"] | ||||||
|  |         ) | ||||||
|  |         self.progress_dialog.setMinimum(0) | ||||||
|  |         self.progress_dialog.setMaximum(100 * 100) | ||||||
|  |         self.progress_dialog.setWindowTitle(title) | ||||||
|  |         self.progress_dialog.setLabelText(msg) | ||||||
|  |         self.progress_dialog.setValue(int(state["status"]["prc_done"] * 100)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class DownloadThread(QThread): | ||||||
|  |     progress = pyqtSignal("PyQt_PyObject") | ||||||
|  | 
 | ||||||
|  |     def __init__(self, systems_url, systems_file, bodies_url, bodies_file): | ||||||
|  |         super().__init__() | ||||||
|  |         self.systems_url = systems_url | ||||||
|  |         self.systems_file = systems_file | ||||||
|  |         self.bodies_url = bodies_url | ||||||
|  |         self.bodies_file = bodies_file | ||||||
|  |         self.running = True | ||||||
|  | 
 | ||||||
|  |     def __del__(self): | ||||||
|  |         self.wait() | ||||||
|  | 
 | ||||||
|  |     def stop(self): | ||||||
|  |         self.running = False | ||||||
|  | 
 | ||||||
|  |     def run(self): | ||||||
|  |         dl_jobs = [ | ||||||
|  |             (self.systems_url, self.systems_file), | ||||||
|  |             (self.bodies_url, self.bodies_file), | ||||||
|  |         ] | ||||||
|  |         for url, dest in dl_jobs: | ||||||
|  |             outfile = url.split("/")[-1] | ||||||
|  |             size = RQ.head(url, headers={"Accept-Encoding": "None"}) | ||||||
|  |             size.raise_for_status() | ||||||
|  |             size = int(size.headers.get("Content-Length", 0)) | ||||||
|  |             with open(dest, "wb") as of: | ||||||
|  |                 resp = RQ.get(url, stream=True) | ||||||
|  |                 for chunk in resp.iter_content(1024 * 1024): | ||||||
|  |                     of.write(chunk) | ||||||
|  |                     self.progress.emit( | ||||||
|  |                         {"done": of.tell(), "size": size, "outfile": outfile} | ||||||
|  |                     ) | ||||||
|  |                     if not self.running: | ||||||
|  |                         return | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class App(QApplication): | ||||||
|  |     def __init__(self): | ||||||
|  |         super().__init__(sys.argv) | ||||||
|  |         self.setStyle("Fusion") | ||||||
|  |         self.setup_styles() | ||||||
|  | 
 | ||||||
|  |     def set_style(self, style): | ||||||
|  |         print("LOAD:", style) | ||||||
|  |         self.setPalette(self.styles[style]) | ||||||
|  | 
 | ||||||
|  |     def setup_styles(self): | ||||||
|  |         self.styles = {} | ||||||
|  |         styles = { | ||||||
|  |             "Dark": { | ||||||
|  |                 "Window": QColor(53, 53, 53), | ||||||
|  |                 "WindowText": Qt.white, | ||||||
|  |                 "Base": QColor(15, 15, 15), | ||||||
|  |                 "AlternateBase": QColor(53, 53, 53), | ||||||
|  |                 "ToolTipBase": Qt.white, | ||||||
|  |                 "ToolTipText": Qt.white, | ||||||
|  |                 "Text": Qt.white, | ||||||
|  |                 "Button": QColor(53, 53, 53), | ||||||
|  |                 "ButtonText": Qt.white, | ||||||
|  |                 "BrightText": Qt.red, | ||||||
|  |                 "Highlight": QColor(255, 128, 0), | ||||||
|  |                 "HighlightedText": Qt.black, | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         for style, colors in styles.items(): | ||||||
|  |             palette = QPalette() | ||||||
|  |             for entry, color in colors.items(): | ||||||
|  |                 palette.setColor(getattr(QPalette, entry), color) | ||||||
|  |                 if color == Qt.darkGray: | ||||||
|  |                     palette.setColor( | ||||||
|  |                         QPalette.Disabled, getattr(QPalette, entry), QColor(53, 53, 53) | ||||||
|  |                     ) | ||||||
|  |                 else: | ||||||
|  |                     palette.setColor( | ||||||
|  |                         QPalette.Disabled, getattr(QPalette, entry), Qt.darkGray | ||||||
|  |                     ) | ||||||
|  |             self.styles[style] = palette | ||||||
|  |         self.styles["Light"] = self.style().standardPalette() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class WRoute(Ui_diag_route): | ||||||
|  |     def __init__(self, main_window, hops): | ||||||
|  |         super().__init__() | ||||||
|  |         self.route = hops | ||||||
|  |         dialog = QDialog(main_window) | ||||||
|  |         self.setupUi(dialog) | ||||||
|  |         for n, item in enumerate(hops): | ||||||
|  |             if item["body"].startswith(item["system"]): | ||||||
|  |                 item["body"] = item["body"].replace(item["system"], "").strip() | ||||||
|  |             item = QTreeWidgetItem( | ||||||
|  |                 self.lst_route, | ||||||
|  |                 [ | ||||||
|  |                     str(n + 1), | ||||||
|  |                     item["system"], | ||||||
|  |                     "{body} ({star_type})".format(**item), | ||||||
|  |                     str(item["distance"]), | ||||||
|  |                     "<NotImplemented>",  # Jump distance | ||||||
|  |                 ], | ||||||
|  |             ) | ||||||
|  |             item.setFlags(item.flags() & ~Qt.ItemIsDropEnabled) | ||||||
|  |         dialog.exec_() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ED_LRR(Ui_ED_LRR): | ||||||
|  |     dl_thread = None | ||||||
|  |     diag_prog = None | ||||||
|  |     dl_started = None | ||||||
|  |     system_found = pyqtSignal("PyQt_PyObject") | ||||||
|  | 
 | ||||||
|  |     def __init__(self): | ||||||
|  |         super().__init__() | ||||||
|  |         self.current_job = None | ||||||
|  | 
 | ||||||
|  |     def get_open_file(self, filetypes, callback=None): | ||||||
|  |         fileName, _ = QFileDialog.getOpenFileName( | ||||||
|  |             self.main_window, | ||||||
|  |             "Open file", | ||||||
|  |             cfg["folders.data_dir"], | ||||||
|  |             filetypes, | ||||||
|  |             options=QFileDialog.DontUseNativeDialog, | ||||||
|  |         ) | ||||||
|  |         if callback: | ||||||
|  |             return callback(fileName) | ||||||
|  |         return fileName | ||||||
|  | 
 | ||||||
|  |     def get_save_file(self, filetypes, callback=None): | ||||||
|  |         fileName, _ = QFileDialog.getSaveFileName( | ||||||
|  |             self.main_window, | ||||||
|  |             "Save file", | ||||||
|  |             cfg["folders.data_dir"], | ||||||
|  |             filetypes, | ||||||
|  |             options=QFileDialog.DontUseNativeDialog, | ||||||
|  |         ) | ||||||
|  |         if callback: | ||||||
|  |             return callback(fileName) | ||||||
|  |         return fileName | ||||||
|  | 
 | ||||||
|  |     def preprocess(self): | ||||||
|  |         if self.current_job: | ||||||
|  |             # ERROR | ||||||
|  |             return | ||||||
|  |         bodies_json = self.inp_bodies_pp.currentText() | ||||||
|  |         systems_json = self.inp_systems_pp.currentText() | ||||||
|  |         output_file = self.inp_out_pp.currentText() | ||||||
|  |         self.current_job = PreprocessJob( | ||||||
|  |             self.app, self.main_window, systems_json, bodies_json, output_file | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |     def set_sys_lst(self, path): | ||||||
|  |         if path not in cfg["history.stars_csv_path"]: | ||||||
|  |             cfg["history.stars_csv_path"].append(path) | ||||||
|  |             self.update_dropdowns() | ||||||
|  | 
 | ||||||
|  |     def set_bodies_file(self, path): | ||||||
|  |         if path not in cfg["history.bodies_path"]: | ||||||
|  |             cfg["history.bodies_path"].append(path) | ||||||
|  |             self.update_dropdowns() | ||||||
|  | 
 | ||||||
|  |     def set_systems_file(self, path): | ||||||
|  |         if path not in cfg["history.systems_path"]: | ||||||
|  |             cfg["history.systems_path"].append(path) | ||||||
|  |             self.update_dropdowns() | ||||||
|  | 
 | ||||||
|  |     def update_dropdowns(self): | ||||||
|  |         self.inp_systems_pp.clear() | ||||||
|  |         self.inp_systems_dest_dl.clear() | ||||||
|  |         for path in cfg["history.systems_path"][:]: | ||||||
|  |             self.inp_systems_pp.addItem(path) | ||||||
|  |             self.inp_systems_pp.setCurrentText(path) | ||||||
|  |             self.inp_systems_dest_dl.addItem(path) | ||||||
|  |             self.inp_systems_dest_dl.setCurrentText(path) | ||||||
|  |         self.inp_bodies_pp.clear() | ||||||
|  |         self.inp_bodies_dest_dl.clear() | ||||||
|  |         for path in cfg["history.bodies_path"][:]: | ||||||
|  |             self.inp_bodies_pp.addItem(path) | ||||||
|  |             self.inp_bodies_pp.setCurrentText(path) | ||||||
|  |             self.inp_bodies_dest_dl.addItem(path) | ||||||
|  |             self.inp_bodies_dest_dl.setCurrentText(path) | ||||||
|  |         self.inp_sys_lst.clear() | ||||||
|  |         self.inp_out_pp.clear() | ||||||
|  |         for path in cfg["history.stars_csv_path"]: | ||||||
|  |             self.inp_sys_lst.addItem(path) | ||||||
|  |             self.inp_sys_lst.setCurrentText(path) | ||||||
|  |             self.inp_out_pp.addItem(path) | ||||||
|  |             self.inp_out_pp.setCurrentText(path) | ||||||
|  |         return | ||||||
|  | 
 | ||||||
|  |     def log(self, *args): | ||||||
|  |         t = datetime.today() | ||||||
|  |         msg_t = "[{}] {}".format(t, str.format(*args)) | ||||||
|  |         self.txt_log.append(msg_t) | ||||||
|  | 
 | ||||||
|  |     def set_comp_mode(self, _): | ||||||
|  |         if self.rd_comp.isChecked(): | ||||||
|  |             comp_mode = "Compute Route" | ||||||
|  |             self.btn_add.setText("Add") | ||||||
|  |         if self.rd_precomp.isChecked(): | ||||||
|  |             comp_mode = "Precompute Graph" | ||||||
|  |             self.btn_add.setText("Select") | ||||||
|  |         self.log("COMP_MODE", comp_mode) | ||||||
|  |         self.lst_sys.setEnabled(self.rd_comp.isChecked()) | ||||||
|  |         self.btn_rm.setEnabled(self.rd_comp.isChecked()) | ||||||
|  |         self.cmb_mode.setEnabled(self.rd_comp.isChecked()) | ||||||
|  |         self.chk_permute.setEnabled(self.rd_comp.isChecked()) | ||||||
|  |         self.lbl_keep.setEnabled(self.rd_comp.isChecked()) | ||||||
|  |         self.lbl_mode.setEnabled(self.rd_comp.isChecked()) | ||||||
|  |         self.chk_permute_keep_first.setEnabled(self.rd_comp.isChecked()) | ||||||
|  |         self.chk_permute_keep_last.setEnabled(self.rd_comp.isChecked()) | ||||||
|  |         self.set_route_mode(self.rd_precomp.isChecked() or None) | ||||||
|  | 
 | ||||||
|  |     def set_route_mode(self, mode=None): | ||||||
|  |         if mode == None: | ||||||
|  |             mode = self.cmb_mode.currentText() | ||||||
|  |         self.lbl_greedyness.setEnabled(mode == "A*-Search") | ||||||
|  |         self.sld_greedyness.setEnabled(mode == "A*-Search") | ||||||
|  | 
 | ||||||
|  |     def set_greedyness(self, value): | ||||||
|  |         self.lbl_greedyness.setText("Greedyness Factor ({:.0%})".format(value / 100)) | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def systems(self): | ||||||
|  |         ret = [] | ||||||
|  |         for n in range(self.lst_sys.topLevelItemCount()): | ||||||
|  |             ret.append(self.sys_to_dict(n)) | ||||||
|  |         return ret | ||||||
|  | 
 | ||||||
|  |     def sys_to_dict(self, n): | ||||||
|  |         header = [ | ||||||
|  |             self.lst_sys.headerItem().data(c, 0) | ||||||
|  |             for c in range(self.lst_sys.headerItem().columnCount()) | ||||||
|  |         ] | ||||||
|  |         system = [ | ||||||
|  |             self.lst_sys.topLevelItem(n).data(c, 0) | ||||||
|  |             for c in range(self.lst_sys.topLevelItem(n).columnCount()) | ||||||
|  |         ] | ||||||
|  |         ret = dict(zip(header, system)) | ||||||
|  |         ret["id"] = getattr(self.lst_sys.topLevelItem(n), "__id__", None) | ||||||
|  |         ret.pop(None, None) | ||||||
|  |         return ret | ||||||
|  | 
 | ||||||
|  |     def error(self, msg): | ||||||
|  |         QMessageBox.critical(self.main_window, "ED_LRR Error", msg) | ||||||
|  | 
 | ||||||
|  |     def get_sys_list(self): | ||||||
|  |         if not self.inp_sys_lst.currentText(): | ||||||
|  |             self.error("System list is required!") | ||||||
|  |             return | ||||||
|  |         path = pathlib.Path(self.inp_sys_lst.currentText()) | ||||||
|  |         if not path.exists(): | ||||||
|  |             self.error("System list does not exist, run download and preprocess first!") | ||||||
|  |             return | ||||||
|  |         return path | ||||||
|  | 
 | ||||||
|  |     def compute_route(self): | ||||||
|  |         self.bar_status.showMessage("Resolving systems...") | ||||||
|  |         num_resolved = self.resolve_systems() | ||||||
|  |         if num_resolved: | ||||||
|  |             if ( | ||||||
|  |                 QMessageBox.question( | ||||||
|  |                     self.main_window, | ||||||
|  |                     "ED_LRR", | ||||||
|  |                     "Resolved {} system(s), are the names correct?".format( | ||||||
|  |                         num_resolved | ||||||
|  |                     ), | ||||||
|  |                 ) | ||||||
|  |                 == QMessageBox.No | ||||||
|  |             ): | ||||||
|  |                 return | ||||||
|  |         self.bar_status.clearMessage() | ||||||
|  |         print(self.systems) | ||||||
|  |         systems = [str(s["id"]) for s in self.systems] | ||||||
|  |         jump_range = self.sb_range.value() | ||||||
|  |         if jump_range == 0: | ||||||
|  |             self.error( | ||||||
|  |                 "Your jump range is set to zero, you're not going to get anywhere that way" | ||||||
|  |             ) | ||||||
|  |             return | ||||||
|  |         mode = self.cmb_mode.currentText() | ||||||
|  |         primary = self.chk_primary.isChecked() | ||||||
|  |         keep_first = self.chk_permute_keep_first.isChecked() | ||||||
|  |         keep_last = self.chk_permute_keep_last.isChecked() | ||||||
|  |         permute = self.chk_permute.isChecked() | ||||||
|  |         greedyness = ( | ||||||
|  |             self.sld_greedyness.value() / 100 | ||||||
|  |             if self.sld_greedyness.isEnabled() | ||||||
|  |             else None | ||||||
|  |         ) | ||||||
|  |         path = self.get_sys_list() | ||||||
|  |         if path is None: | ||||||
|  |             return | ||||||
|  |         precomp = None | ||||||
|  |         path = str(path) | ||||||
|  |         mode = { | ||||||
|  |             "Breadth-First Search": "bfs", | ||||||
|  |             "A*-Search": "astar", | ||||||
|  |             "Greedy-Search": "greedy", | ||||||
|  |         }[mode] | ||||||
|  |         print( | ||||||
|  |             systems, | ||||||
|  |             jump_range, | ||||||
|  |             mode, | ||||||
|  |             primary, | ||||||
|  |             permute, | ||||||
|  |             (keep_first, keep_last), | ||||||
|  |             greedyness, | ||||||
|  |             path, | ||||||
|  |             precomp, | ||||||
|  |         ) | ||||||
|  |         if not self.current_job: | ||||||
|  |             self.bar_status.showMessage("Computing Route...") | ||||||
|  |             self.current_job = RouterJob( | ||||||
|  |                 self.app, | ||||||
|  |                 self.main_window, | ||||||
|  |                 systems, | ||||||
|  |                 jump_range, | ||||||
|  |                 None, | ||||||
|  |                 mode, | ||||||
|  |                 primary, | ||||||
|  |                 permute, | ||||||
|  |                 keep_first, | ||||||
|  |                 keep_last, | ||||||
|  |                 greedyness, | ||||||
|  |                 precomp, | ||||||
|  |                 path, | ||||||
|  |             ) | ||||||
|  |         else: | ||||||
|  |             self.error("there is already a job running!") | ||||||
|  | 
 | ||||||
|  |     def find_sys_by_names(self, names): | ||||||
|  |         t_s = datetime.today() | ||||||
|  |         if not self.get_sys_list(): | ||||||
|  |             return None | ||||||
|  |         # TODO: start thread/subprocess | ||||||
|  |         ret = _ed_lrr.find_sys(names, self.inp_sys_lst.currentText()) | ||||||
|  |         print("Took:", datetime.today() - t_s) | ||||||
|  |         return ret | ||||||
|  | 
 | ||||||
|  |     def resolve_systems(self): | ||||||
|  |         # TODO: show spinner | ||||||
|  |         names = [] | ||||||
|  |         nums = [] | ||||||
|  |         for n in range(self.lst_sys.topLevelItemCount()): | ||||||
|  |             sys_id = getattr(self.lst_sys.topLevelItem(n), "__id__", None) | ||||||
|  |             if sys_id is not None: | ||||||
|  |                 continue | ||||||
|  |             names.append(self.sys_to_dict(n)["Name"]) | ||||||
|  |             nums.append(n) | ||||||
|  |         if not names: | ||||||
|  |             return 0 | ||||||
|  |         systems = self.find_sys_by_names(names) | ||||||
|  |         if systems is None: | ||||||
|  |             return | ||||||
|  |         for i, name in zip(nums, names): | ||||||
|  |             _, system = systems[name] | ||||||
|  |             self.lst_sys.topLevelItem(i).setData(0, 0, system["system"]) | ||||||
|  |             self.lst_sys.topLevelItem(i).setData(1, 0, system["star_type"]) | ||||||
|  |             self.lst_sys.topLevelItem(i).__id__ = system["id"] | ||||||
|  |         return len(names) | ||||||
|  |         # diff, item = self.find_sys_by_name(name) | ||||||
|  |         # print("Found", (diff, item)) | ||||||
|  | 
 | ||||||
|  |     def add_system(self): | ||||||
|  |         name = self.inp_sys.text() | ||||||
|  |         item = QTreeWidgetItem(self.lst_sys, [name, None]) | ||||||
|  |         item.resolved = False | ||||||
|  |         item.setFlags(item.flags() & ~Qt.ItemIsDropEnabled) | ||||||
|  | 
 | ||||||
|  |     def remove_system(self): | ||||||
|  |         root = self.lst_sys.invisibleRootItem() | ||||||
|  |         for item in self.lst_sys.selectedItems(): | ||||||
|  |             root.removeChild(item) | ||||||
|  | 
 | ||||||
|  |     def dl_canceled(self): | ||||||
|  |         if self.dl_thread: | ||||||
|  |             print("Cancel!") | ||||||
|  |             try: | ||||||
|  |                 self.dl_thread.progress.disconnect() | ||||||
|  |             except TypeError: | ||||||
|  |                 pass | ||||||
|  |             self.dl_thread.stop() | ||||||
|  |             self.dl_thread.wait() | ||||||
|  |             self.diag_prog.close() | ||||||
|  |             self.dl_thread = None | ||||||
|  |             self.diag_prog = None | ||||||
|  |             self.dl_started = None | ||||||
|  | 
 | ||||||
|  |     def handle_dl_progress(self, args): | ||||||
|  |         filename = os.path.split(args["outfile"])[-1] | ||||||
|  |         if self.diag_prog is None: | ||||||
|  |             self.diag_prog = ProgressDialog("", "Cancel", 0, 1000, self.main_window) | ||||||
|  |             if self.dl_thread: | ||||||
|  |                 self.diag_prog.canceled.connect(self.dl_canceled) | ||||||
|  |             self.diag_prog.show() | ||||||
|  |         t_elapsed = datetime.today() - self.dl_started | ||||||
|  |         rate = args["done"] / t_elapsed.total_seconds() | ||||||
|  |         remaining = (args["size"] - args["done"]) / rate | ||||||
|  |         rate = round(rate, 2) | ||||||
|  |         # print(rate, remaining) | ||||||
|  |         try: | ||||||
|  |             t_rem = timedelta(seconds=remaining) | ||||||
|  |         except OverflowError: | ||||||
|  |             t_rem = "-" | ||||||
|  |         msg = "Downloading {} [{}/{}] ({}/s)\n[{}/{}]".format( | ||||||
|  |             filename, | ||||||
|  |             sizeof_fmt(args["done"]), | ||||||
|  |             sizeof_fmt(args["size"]), | ||||||
|  |             sizeof_fmt(rate), | ||||||
|  |             t_round(t_elapsed), | ||||||
|  |             t_round(t_rem), | ||||||
|  |         ) | ||||||
|  |         self.diag_prog.setLabelText(msg) | ||||||
|  |         self.diag_prog.setWindowTitle("Downloading EDSM Dumps") | ||||||
|  |         self.diag_prog.setValue((args["done"] * 1000) // args["size"]) | ||||||
|  | 
 | ||||||
|  |     def run_download(self): | ||||||
|  |         if self.dl_thread: | ||||||
|  |             return | ||||||
|  |         self.dl_started = datetime.today() | ||||||
|  |         self.dl_thread = DownloadThread( | ||||||
|  |             self.inp_systems_dl.currentText(), | ||||||
|  |             self.inp_systems_dest_dl.currentText(), | ||||||
|  |             self.inp_bodies_dl.currentText(), | ||||||
|  |             self.inp_bodies_dest_dl.currentText(), | ||||||
|  |         ) | ||||||
|  |         self.dl_thread.progress.connect(self.handle_dl_progress) | ||||||
|  |         self.dl_thread.start() | ||||||
|  |         print(".") | ||||||
|  | 
 | ||||||
|  |     def update_permute_chk(self, state): | ||||||
|  |         self.chk_permute_keep_first.setEnabled(state) | ||||||
|  |         self.chk_permute_keep_last.setEnabled(state) | ||||||
|  |         self.lbl_keep.setEnabled(state) | ||||||
|  | 
 | ||||||
|  |     def setup_signals(self): | ||||||
|  |         self.btn_download.clicked.connect(self.run_download) | ||||||
|  |         self.set_greedyness(self.sld_greedyness.value()) | ||||||
|  |         self.cmb_mode.currentTextChanged.connect(self.set_route_mode) | ||||||
|  |         self.rd_comp.toggled.connect(self.set_comp_mode) | ||||||
|  |         self.rd_precomp.toggled.connect(self.set_comp_mode) | ||||||
|  |         self.sld_greedyness.valueChanged.connect(self.set_greedyness) | ||||||
|  |         self.btn_go.clicked.connect(self.compute_route) | ||||||
|  |         self.btn_add.clicked.connect(self.add_system) | ||||||
|  |         self.btn_rm.clicked.connect(self.remove_system) | ||||||
|  |         self.btn_preprocess.clicked.connect(self.preprocess) | ||||||
|  |         self.chk_permute.stateChanged.connect(self.update_permute_chk) | ||||||
|  |         self.btn_out_browse_pp.clicked.connect( | ||||||
|  |             lambda: self.get_save_file("CSV File (*.csv)", self.set_sys_lst) | ||||||
|  |         ) | ||||||
|  |         self.btn_sys_lst_browse.clicked.connect( | ||||||
|  |             lambda: self.get_open_file("CSV File (*.csv)", self.set_sys_lst) | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         self.btn_bodies_browse_pp.clicked.connect( | ||||||
|  |             lambda: self.get_open_file("JSON File (*.json)", self.set_bodies_file) | ||||||
|  |         ) | ||||||
|  |         self.btn_bodies_dest_browse_dl.clicked.connect( | ||||||
|  |             lambda: self.get_save_file("JSON File (*.json)", self.set_bodies_file) | ||||||
|  |         ) | ||||||
|  |         self.btn_systems_browse_pp.clicked.connect( | ||||||
|  |             lambda: self.get_open_file("JSON File (*.json)", self.set_systems_file) | ||||||
|  |         ) | ||||||
|  |         self.btn_systems_dest_browse_dl.clicked.connect( | ||||||
|  |             lambda: self.get_save_file("JSON File (*.json)", self.set_systems_file) | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |     def handle_close(self): | ||||||
|  |         for key in [ | ||||||
|  |             "history.stars_csv_path", | ||||||
|  |             "history.bodies_path", | ||||||
|  |             "history.systems_path", | ||||||
|  |         ]: | ||||||
|  |             for path in cfg[key][:]: | ||||||
|  |                 if not os.path.isfile(path): | ||||||
|  |                     cfg[key].remove(path) | ||||||
|  |         cfg.write() | ||||||
|  |         print("BYEEEEEE!") | ||||||
|  | 
 | ||||||
|  |     def setup_styles(self, win, app): | ||||||
|  |         for name in app.styles: | ||||||
|  |             action = QAction(app) | ||||||
|  |             action.setObjectName("action_load_style_" + name) | ||||||
|  |             action.setText(name) | ||||||
|  |             action.triggered.connect(lambda _, name=name: app.set_style(name)) | ||||||
|  |             self.menuStyle.addAction(action) | ||||||
|  | 
 | ||||||
|  |     def setupUi(self, MainWindow, app): | ||||||
|  |         super().setupUi(MainWindow) | ||||||
|  |         self.update_dropdowns() | ||||||
|  |         self.main_window = MainWindow | ||||||
|  |         self.app = app | ||||||
|  |         self.setup_signals() | ||||||
|  |         self.lst_sys.setHeaderLabels(["Name", "Type"]) | ||||||
|  |         self.set_route_mode() | ||||||
|  |         self.update_permute_chk(self.chk_permute.isChecked()) | ||||||
|  |         self.setup_styles(MainWindow, app) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def main(): | ||||||
|  |     MP.freeze_support() | ||||||
|  |     app = App() | ||||||
|  |     app.setWindowIcon(QIcon(r"D:\devel\rust\ed_lrr_gui\icon\icon.ico")) | ||||||
|  |     MainWindow = QMainWindow() | ||||||
|  |     MainWindow.setWindowIcon(QIcon(r"D:\devel\rust\ed_lrr_gui\icon\icon.ico")) | ||||||
|  |     ui = ED_LRR() | ||||||
|  |     ui.setupUi(MainWindow, app) | ||||||
|  |     MainWindow.show() | ||||||
|  |     ret = app.exec_() | ||||||
|  |     ui.handle_close() | ||||||
|  |     exit(ret) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     main() | ||||||
							
								
								
									
										65
									
								
								ed_lrr_gui/gui/widget_route.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								ed_lrr_gui/gui/widget_route.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,65 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | 
 | ||||||
|  | # Form implementation generated from reading ui file 'D:\devel\rust\ed_lrr_gui\ed_lrr_gui\gui\widget_route.ui' | ||||||
|  | # | ||||||
|  | # Created by: PyQt5 UI code generator 5.13.1 | ||||||
|  | # | ||||||
|  | # WARNING! All changes made in this file will be lost! | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | from PyQt5 import QtCore, QtGui, QtWidgets | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Ui_diag_route(object): | ||||||
|  |     def setupUi(self, diag_route): | ||||||
|  |         diag_route.setObjectName("diag_route") | ||||||
|  |         diag_route.setWindowModality(QtCore.Qt.WindowModal) | ||||||
|  |         diag_route.resize(430, 300) | ||||||
|  |         self.layout_main = QtWidgets.QGridLayout(diag_route) | ||||||
|  |         self.layout_main.setObjectName("layout_main") | ||||||
|  |         self.layout_top = QtWidgets.QGridLayout() | ||||||
|  |         self.layout_top.setObjectName("layout_top") | ||||||
|  |         self.lst_route = QtWidgets.QTreeWidget(diag_route) | ||||||
|  |         self.lst_route.setProperty("showDropIndicator", False) | ||||||
|  |         self.lst_route.setDefaultDropAction(QtCore.Qt.IgnoreAction) | ||||||
|  |         self.lst_route.setAlternatingRowColors(True) | ||||||
|  |         self.lst_route.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) | ||||||
|  |         self.lst_route.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerItem) | ||||||
|  |         self.lst_route.setHorizontalScrollMode( | ||||||
|  |             QtWidgets.QAbstractItemView.ScrollPerPixel | ||||||
|  |         ) | ||||||
|  |         self.lst_route.setItemsExpandable(False) | ||||||
|  |         self.lst_route.setAllColumnsShowFocus(False) | ||||||
|  |         self.lst_route.setObjectName("lst_route") | ||||||
|  |         self.layout_top.addWidget(self.lst_route, 0, 0, 1, 1) | ||||||
|  |         self.layout_main.addLayout(self.layout_top, 0, 0, 1, 1) | ||||||
|  |         self.layout_bottom = QtWidgets.QGridLayout() | ||||||
|  |         self.layout_bottom.setObjectName("layout_bottom") | ||||||
|  |         self.chk_copy = QtWidgets.QCheckBox(diag_route) | ||||||
|  |         self.chk_copy.setObjectName("chk_copy") | ||||||
|  |         self.layout_bottom.addWidget(self.chk_copy, 1, 0, 1, 1) | ||||||
|  |         self.btn_close = QtWidgets.QPushButton(diag_route) | ||||||
|  |         self.btn_close.setObjectName("btn_close") | ||||||
|  |         self.layout_bottom.addWidget(self.btn_close, 1, 2, 1, 1) | ||||||
|  |         self.btn_export = QtWidgets.QPushButton(diag_route) | ||||||
|  |         self.btn_export.setObjectName("btn_export") | ||||||
|  |         self.layout_bottom.addWidget(self.btn_export, 1, 1, 1, 1) | ||||||
|  |         self.layout_main.addLayout(self.layout_bottom, 1, 0, 1, 1) | ||||||
|  | 
 | ||||||
|  |         self.retranslateUi(diag_route) | ||||||
|  |         QtCore.QMetaObject.connectSlotsByName(diag_route) | ||||||
|  | 
 | ||||||
|  |     def retranslateUi(self, diag_route): | ||||||
|  |         _translate = QtCore.QCoreApplication.translate | ||||||
|  |         diag_route.setWindowTitle(_translate("diag_route", "Route")) | ||||||
|  |         self.lst_route.headerItem().setText(0, _translate("diag_route", "Num")) | ||||||
|  |         self.lst_route.headerItem().setText(1, _translate("diag_route", "System")) | ||||||
|  |         self.lst_route.headerItem().setText(2, _translate("diag_route", "Body")) | ||||||
|  |         self.lst_route.headerItem().setText( | ||||||
|  |             3, _translate("diag_route", "Distance (Ls)") | ||||||
|  |         ) | ||||||
|  |         self.chk_copy.setText( | ||||||
|  |             _translate("diag_route", "Auto-copy next hop to clipboard") | ||||||
|  |         ) | ||||||
|  |         self.btn_close.setText(_translate("diag_route", "Close")) | ||||||
|  |         self.btn_export.setText(_translate("diag_route", "Export")) | ||||||
							
								
								
									
										101
									
								
								ed_lrr_gui/gui/widget_route.ui
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								ed_lrr_gui/gui/widget_route.ui
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,101 @@ | ||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <ui version="4.0"> | ||||||
|  |  <class>diag_route</class> | ||||||
|  |  <widget class="QDialog" name="diag_route"> | ||||||
|  |   <property name="windowModality"> | ||||||
|  |    <enum>Qt::WindowModal</enum> | ||||||
|  |   </property> | ||||||
|  |   <property name="geometry"> | ||||||
|  |    <rect> | ||||||
|  |     <x>0</x> | ||||||
|  |     <y>0</y> | ||||||
|  |     <width>430</width> | ||||||
|  |     <height>300</height> | ||||||
|  |    </rect> | ||||||
|  |   </property> | ||||||
|  |   <property name="windowTitle"> | ||||||
|  |    <string>Route</string> | ||||||
|  |   </property> | ||||||
|  |   <layout class="QGridLayout" name="layout_main"> | ||||||
|  |    <item row="0" column="0"> | ||||||
|  |     <layout class="QGridLayout" name="layout_top"> | ||||||
|  |      <item row="0" column="0"> | ||||||
|  |       <widget class="QTreeWidget" name="lst_route"> | ||||||
|  |        <property name="showDropIndicator" stdset="0"> | ||||||
|  |         <bool>false</bool> | ||||||
|  |        </property> | ||||||
|  |        <property name="defaultDropAction"> | ||||||
|  |         <enum>Qt::IgnoreAction</enum> | ||||||
|  |        </property> | ||||||
|  |        <property name="alternatingRowColors"> | ||||||
|  |         <bool>true</bool> | ||||||
|  |        </property> | ||||||
|  |        <property name="selectionMode"> | ||||||
|  |         <enum>QAbstractItemView::NoSelection</enum> | ||||||
|  |        </property> | ||||||
|  |        <property name="verticalScrollMode"> | ||||||
|  |         <enum>QAbstractItemView::ScrollPerItem</enum> | ||||||
|  |        </property> | ||||||
|  |        <property name="horizontalScrollMode"> | ||||||
|  |         <enum>QAbstractItemView::ScrollPerPixel</enum> | ||||||
|  |        </property> | ||||||
|  |        <property name="itemsExpandable"> | ||||||
|  |         <bool>false</bool> | ||||||
|  |        </property> | ||||||
|  |        <property name="allColumnsShowFocus"> | ||||||
|  |         <bool>false</bool> | ||||||
|  |        </property> | ||||||
|  |        <column> | ||||||
|  |         <property name="text"> | ||||||
|  |          <string>Num</string> | ||||||
|  |         </property> | ||||||
|  |        </column> | ||||||
|  |        <column> | ||||||
|  |         <property name="text"> | ||||||
|  |          <string>System</string> | ||||||
|  |         </property> | ||||||
|  |        </column> | ||||||
|  |        <column> | ||||||
|  |         <property name="text"> | ||||||
|  |          <string>Body</string> | ||||||
|  |         </property> | ||||||
|  |        </column> | ||||||
|  |        <column> | ||||||
|  |         <property name="text"> | ||||||
|  |          <string>Distance (Ls)</string> | ||||||
|  |         </property> | ||||||
|  |        </column> | ||||||
|  |       </widget> | ||||||
|  |      </item> | ||||||
|  |     </layout> | ||||||
|  |    </item> | ||||||
|  |    <item row="1" column="0"> | ||||||
|  |     <layout class="QGridLayout" name="layout_bottom"> | ||||||
|  |      <item row="1" column="0"> | ||||||
|  |       <widget class="QCheckBox" name="chk_copy"> | ||||||
|  |        <property name="text"> | ||||||
|  |         <string>Auto-copy next hop to clipboard</string> | ||||||
|  |        </property> | ||||||
|  |       </widget> | ||||||
|  |      </item> | ||||||
|  |      <item row="1" column="2"> | ||||||
|  |       <widget class="QPushButton" name="btn_close"> | ||||||
|  |        <property name="text"> | ||||||
|  |         <string>Close</string> | ||||||
|  |        </property> | ||||||
|  |       </widget> | ||||||
|  |      </item> | ||||||
|  |      <item row="1" column="1"> | ||||||
|  |       <widget class="QPushButton" name="btn_export"> | ||||||
|  |        <property name="text"> | ||||||
|  |         <string>Export</string> | ||||||
|  |        </property> | ||||||
|  |       </widget> | ||||||
|  |      </item> | ||||||
|  |     </layout> | ||||||
|  |    </item> | ||||||
|  |   </layout> | ||||||
|  |  </widget> | ||||||
|  |  <resources/> | ||||||
|  |  <connections/> | ||||||
|  | </ui> | ||||||
							
								
								
									
										1000
									
								
								ed_lrr_gui/html_export.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										1000
									
								
								ed_lrr_gui/html_export.py
									
										
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										158
									
								
								ed_lrr_gui/html_export_template.html.jinja2
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								ed_lrr_gui/html_export_template.html.jinja2
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,158 @@ | ||||||
|  | <html> | ||||||
|  | 
 | ||||||
|  | <head> | ||||||
|  |     <meta charset="utf-8"/> | ||||||
|  |     <style> | ||||||
|  |         h1 { | ||||||
|  |             float: left; | ||||||
|  |         } | ||||||
|  |         body { | ||||||
|  |             background: #222; | ||||||
|  |             margin: 0px; | ||||||
|  |             width: 100%; | ||||||
|  |             height: 100%; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         table { | ||||||
|  |             border-collapse: collapse; | ||||||
|  |             max-width: 50%; | ||||||
|  |             float: right; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         #graph { | ||||||
|  |             border: 1px solid #eee; | ||||||
|  |             float: left; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         table, | ||||||
|  |         td, | ||||||
|  |         tr,th { | ||||||
|  |             color: #eee; | ||||||
|  |             margin: auto; | ||||||
|  |             border: 1px solid #eee; | ||||||
|  |             text-align: center; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /* D3 stuff */ | ||||||
|  |                  | ||||||
|  |         .d3-tip { | ||||||
|  |         line-height: 1; | ||||||
|  |         font-weight: bold; | ||||||
|  |         padding: 12px; | ||||||
|  |         background: rgba(0, 0, 0, 0.8); | ||||||
|  |         color: #fff; | ||||||
|  |         border-radius: 2px; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /* Creates a small triangle extender for the tooltip */ | ||||||
|  |         .d3-tip:after { | ||||||
|  |         box-sizing: border-box; | ||||||
|  |         display: inline; | ||||||
|  |         font-size: 10px; | ||||||
|  |         width: 100%; | ||||||
|  |         line-height: 1; | ||||||
|  |         color: rgba(0, 0, 0, 0.8); | ||||||
|  |         content: "\25BC"; | ||||||
|  |         position: absolute; | ||||||
|  |         text-align: center; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         /* Style northward tooltips differently */ | ||||||
|  |         .d3-tip.n:after { | ||||||
|  |         margin: -1px 0 0 0; | ||||||
|  |         top: 100%; | ||||||
|  |         left: 0; | ||||||
|  |         } | ||||||
|  |     </style> | ||||||
|  |     <script src="https://d3js.org/d3.v5.min.js"></script> | ||||||
|  | </head> | ||||||
|  | 
 | ||||||
|  | <body> | ||||||
|  |     <div id="graph"></div> | ||||||
|  |     <table> | ||||||
|  |         <tr> | ||||||
|  |             <th>Num</th> | ||||||
|  |             <th>Body</th> | ||||||
|  |             <th>Type</th> | ||||||
|  |             <th>Distance to arrival</th> | ||||||
|  |             <th>Jump range</th> | ||||||
|  |         </tr> | ||||||
|  |         {% for sys in route %} | ||||||
|  |         <tr> | ||||||
|  |             <td>{{sys.num}}</td> | ||||||
|  |             <td>{{sys.body}}</td> | ||||||
|  |             <td style="color: {{sys.color}}">{{sys.star_type}}</td> | ||||||
|  |             <td>{{sys.distance}}</td> | ||||||
|  |             <td>{{sys.jump_dist}}</td> | ||||||
|  |         </tr> | ||||||
|  |         {% endfor %} | ||||||
|  |         </table> | ||||||
|  |          | ||||||
|  |     <script type="text/javascript"> | ||||||
|  |         function dist(a,b) { | ||||||
|  |             var sum=0; | ||||||
|  |             for (var i=0;i<a.length;++i) { | ||||||
|  |                 sum+=Math.pow(a[i]-b[i],2) | ||||||
|  |             } | ||||||
|  |             return Math.pow(sum,0.5); | ||||||
|  |         } | ||||||
|  |         var width=512; | ||||||
|  |         var height=512; | ||||||
|  |         var route={{route|tojson}}; | ||||||
|  |         var vis=d3.select("#graph") | ||||||
|  |             .append("svg").attr("viewBox", [0, 0, width, height]);; | ||||||
|  |          | ||||||
|  |         vis.attr("width", width) | ||||||
|  |             .attr("height", height); | ||||||
|  |         var g=vis.append("g"); | ||||||
|  |          | ||||||
|  |         vis.call(d3.zoom() | ||||||
|  |         .extent([[0, 0], [width, height]]) | ||||||
|  |         .on("zoom", () => { | ||||||
|  |             g.attr("transform", d3.event.transform); | ||||||
|  |         })); | ||||||
|  |          | ||||||
|  |         var lines=[]; | ||||||
|  |         for (var i=0;i<route.length-1;++i) { | ||||||
|  |             lines.push({ | ||||||
|  |                 x1: route[i].pos[1], | ||||||
|  |                 x2: route[i+1].pos[1], | ||||||
|  |                 y1: -route[i].pos[2], | ||||||
|  |                 y2: -route[i+1].pos[2], | ||||||
|  |                 dist: dist(route[i].pos,route[i+1].pos), | ||||||
|  |                 color: ({ | ||||||
|  |                     '#99A0FF':'#99A0FF', // Neutron star | ||||||
|  |                     '#5D67EF':'#5D67EF' // White dwarf | ||||||
|  |                 }[route[i].color]||'#eee') | ||||||
|  |             }) | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         g.selectAll(".line") | ||||||
|  |         .data(lines) | ||||||
|  |         .enter() | ||||||
|  |         .append("line") | ||||||
|  |         .attr("x1", (l) => l.x1 ) | ||||||
|  |         .attr("y1", (l) => l.y1 ) | ||||||
|  |         .attr("x2", (l) => l.x2 ) | ||||||
|  |         .attr("y2", (l) => l.y2 ) | ||||||
|  |         .style("stroke", (l) => l.color ) | ||||||
|  |         .style("stroke-width", 5) | ||||||
|  |         .append("title") | ||||||
|  |         .text((l) => Math.round(l.dist*100)/100 +" Ly"); | ||||||
|  |          | ||||||
|  |         g.selectAll("circle .nodes") | ||||||
|  |         .data(route) | ||||||
|  |         .enter() | ||||||
|  |         .append("svg:circle") | ||||||
|  |         .attr("class", "nodes") | ||||||
|  |         .attr("cx", (d) => d.pos[1]) | ||||||
|  |         .attr("cy", (d) => -d.pos[2]) | ||||||
|  |         .attr("r", 10) | ||||||
|  |         .attr("fill", (d) => d.color)  | ||||||
|  |         .append("title") | ||||||
|  |         .text((d) => d.body+" ("+d.star_type+")") | ||||||
|  | 
 | ||||||
|  |     </script> | ||||||
|  | </body> | ||||||
|  | 
 | ||||||
|  | </html> | ||||||
							
								
								
									
										35
									
								
								ed_lrr_gui/preprocess.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								ed_lrr_gui/preprocess.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,35 @@ | ||||||
|  | import queue | ||||||
|  | from collections import namedtuple | ||||||
|  | from datetime import datetime, timedelta | ||||||
|  | from multiprocessing import Process, Queue, freeze_support | ||||||
|  | 
 | ||||||
|  | import _ed_lrr | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Preprocessor(Process): | ||||||
|  |     def __init__(self, *args, **kwargs): | ||||||
|  |         super().__init__() | ||||||
|  |         self.state = {} | ||||||
|  |         self.queue = Queue() | ||||||
|  |         self.daemon = True | ||||||
|  |         self.args = args | ||||||
|  |         self.kwargs = kwargs | ||||||
|  |         self.kwargs["callback"] = self.callback | ||||||
|  | 
 | ||||||
|  |     def callback(self, state): | ||||||
|  |         self.queue.put({"status": state}) | ||||||
|  | 
 | ||||||
|  |     def run(self): | ||||||
|  |         res = _ed_lrr.preprocess(*self.args, **self.kwargs) | ||||||
|  |         self.queue.put({"result": res}) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     freeze_support() | ||||||
|  |     r = Preprocessor( | ||||||
|  |         r"D:\devel\rust\ED_LRR\dumps\systemsWithCoordinates.json", | ||||||
|  |         r"D:\devel\rust\ED_LRR\dumps\bodies.json", | ||||||
|  |         r"D:\devel\rust\ED_LRR\stars.csv", | ||||||
|  |     ) | ||||||
|  |     for i, e in enumerate(r): | ||||||
|  |         print(e) | ||||||
							
								
								
									
										40
									
								
								ed_lrr_gui/router.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								ed_lrr_gui/router.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,40 @@ | ||||||
|  | import queue | ||||||
|  | from collections import namedtuple | ||||||
|  | from datetime import datetime, timedelta | ||||||
|  | from multiprocessing import Process, Queue, freeze_support | ||||||
|  | 
 | ||||||
|  | import _ed_lrr | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class Router(Process): | ||||||
|  |     def __init__(self, *args, **kwargs): | ||||||
|  |         super().__init__() | ||||||
|  |         self.state = {} | ||||||
|  |         self.queue = Queue() | ||||||
|  |         self.daemon = True | ||||||
|  |         self.args = args | ||||||
|  |         self.kwargs = kwargs | ||||||
|  |         self.kwargs["callback"] = self.callback | ||||||
|  | 
 | ||||||
|  |     def callback(self, state): | ||||||
|  |         self.queue.put({"status": state}) | ||||||
|  | 
 | ||||||
|  |     def run(self): | ||||||
|  |         route = _ed_lrr.route(*self.args, **self.kwargs) | ||||||
|  |         self.queue.put({"return": route}) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     freeze_support() | ||||||
|  |     r = Router( | ||||||
|  |         ["Ix", "Beagle Point"], | ||||||
|  |         48, | ||||||
|  |         "BFS", | ||||||
|  |         False, | ||||||
|  |         False, | ||||||
|  |         None, | ||||||
|  |         None, | ||||||
|  |         r"D:\devel\rust\ED_LRR\stars.csv", | ||||||
|  |     ) | ||||||
|  |     for e in r: | ||||||
|  |         print(e) | ||||||
							
								
								
									
										0
									
								
								ed_lrr_gui/web/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								ed_lrr_gui/web/__init__.py
									
										
									
									
									
										Normal file
									
								
							
							
								
								
									
										100
									
								
								ed_lrr_gui/web/__main__.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										100
									
								
								ed_lrr_gui/web/__main__.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,100 @@ | ||||||
|  | from flask import Flask, jsonify | ||||||
|  | import uuid | ||||||
|  | import json | ||||||
|  | from webargs import fields, validate | ||||||
|  | from webargs.flaskparser import use_args | ||||||
|  | from flask_sqlalchemy import SQLAlchemy | ||||||
|  | from sqlalchemy_utils import Timestamp, generic_repr | ||||||
|  | from sqlalchemy.ext.declarative import declarative_base | ||||||
|  | from sqlalchemy.orm import scoped_session, sessionmaker, relationship, backref | ||||||
|  | from sqlalchemy.types import Float, String, Boolean | ||||||
|  | 
 | ||||||
|  | app = Flask(__name__) | ||||||
|  | app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///jobs.db" | ||||||
|  | app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False | ||||||
|  | 
 | ||||||
|  | db = SQLAlchemy(app) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @generic_repr | ||||||
|  | class Job(db.Model, Timestamp): | ||||||
|  |     id = db.Column(db.String, default=lambda: str(uuid.uuid4()), primary_key=True) | ||||||
|  |     jump_range = db.Column(db.Float, nullable=False) | ||||||
|  |     mode = db.Column(db.String, default="bfs") | ||||||
|  |     systems = db.Column(db.String) | ||||||
|  |     permute = db.Column(db.String, default=None, nullable=True) | ||||||
|  |     primary = db.Column(db.Boolean, default=False) | ||||||
|  |     factor = db.Column(db.Float, default=0.5) | ||||||
|  |     done = db.Column(db.DateTime, nullable=True, default=None) | ||||||
|  |     started = db.Column(db.DateTime, nullable=True, default=None) | ||||||
|  |     progress = db.Column(db.Float, default=0.0) | ||||||
|  | 
 | ||||||
|  |     # ============================================================ | ||||||
|  | 
 | ||||||
|  |     @classmethod | ||||||
|  |     def new(cls, **kwargs): | ||||||
|  |         obj = cls(**kwargs) | ||||||
|  |         db.session.add(obj) | ||||||
|  |         db.session.commit() | ||||||
|  |         print(obj) | ||||||
|  |         return obj | ||||||
|  | 
 | ||||||
|  |     @property | ||||||
|  |     def dict(self): | ||||||
|  |         ret = {} | ||||||
|  |         for col in self.__table__.columns: | ||||||
|  |             ret[col.name] = getattr(self, col.name) | ||||||
|  |         ret["systems"] = json.loads(ret["systems"]) | ||||||
|  |         return ret | ||||||
|  | 
 | ||||||
|  |     @dict.setter | ||||||
|  |     def set_dict(self, *args, **kwargs): | ||||||
|  |         raise NotImplementedError | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | db.create_all() | ||||||
|  | db.session.commit() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @app.errorhandler(422) | ||||||
|  | @app.errorhandler(400) | ||||||
|  | def handle_error(err): | ||||||
|  |     headers = err.data.get("headers", None) | ||||||
|  |     messages = err.data.get("messages", ["Invalid request."]) | ||||||
|  |     if headers: | ||||||
|  |         return jsonify({"errors": messages}), err.code, headers | ||||||
|  |     else: | ||||||
|  |         return jsonify({"errors": messages}), err.code | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @app.route("/route", methods=["GET", "POST"]) | ||||||
|  | @use_args( | ||||||
|  |     { | ||||||
|  |         "jump_range": fields.Float(required=True), | ||||||
|  |         "mode": fields.String( | ||||||
|  |             missing="bfs", validate=validate.OneOf(["bfs", "greedy", "a-star"]) | ||||||
|  |         ), | ||||||
|  |         "systems": fields.DelimitedList(fields.String, required=True), | ||||||
|  |         "permute": fields.String( | ||||||
|  |             missing=None, | ||||||
|  |             validate=validate.OneOf(["all", "keep_first", "keep_last", "keep_both"]), | ||||||
|  |         ), | ||||||
|  |         "primary": fields.Boolean(missing=False), | ||||||
|  |         "factor": fields.Float(missing=0.5), | ||||||
|  |     } | ||||||
|  | ) | ||||||
|  | def route(args): | ||||||
|  |     args["systems"] = json.dumps(args["systems"]) | ||||||
|  |     for k, v in args.items(): | ||||||
|  |         print(k, v) | ||||||
|  |     return jsonify({"id": Job.new(**args).id}) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @app.route("/status/<uuid:job_id>") | ||||||
|  | def status(job_id): | ||||||
|  |     job = db.session.query(Job).get_or_404(str(job_id)) | ||||||
|  |     return jsonify(job.dict) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | if __name__ == "__main__": | ||||||
|  |     app.run(host="0.0.0.0", port=3777, debug=True) | ||||||
							
								
								
									
										
											BIN
										
									
								
								icon/icon.ico
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								icon/icon.ico
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 368 KiB | 
							
								
								
									
										133
									
								
								icon/make.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								icon/make.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,133 @@ | ||||||
|  | import svgwrite | ||||||
|  | import random | ||||||
|  | import time | ||||||
|  | from math import factorial, sin, cos, pi | ||||||
|  | from itertools import permutations | ||||||
|  | import tsp as m_tsp | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def dist(p1, p2): | ||||||
|  |     return dist2(p1, p2) ** 0.5 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def dist2(p1, p2): | ||||||
|  |     diff = 0 | ||||||
|  |     for a, b in zip(p1, p2): | ||||||
|  |         diff += (a - b) ** 2 | ||||||
|  |     return diff | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def tsp(points): | ||||||
|  |     res = [] | ||||||
|  |     for idx in m_tsp.tsp(points)[1]: | ||||||
|  |         res.append(points[idx]) | ||||||
|  |     return res | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def make_points(n, size, min_dist=0): | ||||||
|  |     min_dist *= min_dist | ||||||
|  |     points = [] | ||||||
|  |     while len(points) < n: | ||||||
|  |         px, py = random.random(), random.random() | ||||||
|  |         px *= size / 2 | ||||||
|  |         py *= size / 2 | ||||||
|  |         px += 70 | ||||||
|  |         py += 70 | ||||||
|  |         valid = True | ||||||
|  |         for p in points: | ||||||
|  |             if dist2(p, (px, py)) < min_dist: | ||||||
|  |                 valid = False | ||||||
|  |                 break | ||||||
|  |         if valid: | ||||||
|  |             points.append((px, py)) | ||||||
|  |             print("{}/{}".format(len(points), n)) | ||||||
|  |     return points | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | def generate(seed, name=None, small=False): | ||||||
|  |     sd = 1 | ||||||
|  |     if small: | ||||||
|  |         sd = 2 | ||||||
|  |     random.seed(seed) | ||||||
|  |     w = 2 | ||||||
|  |     max_rings = 3 | ||||||
|  |     num_points = 5 | ||||||
|  |     min_dist = 10 + 10 + 20 * (max_rings + 1) | ||||||
|  |     base_r = 10 | ||||||
|  |     ring_step = lambda v: 10 + v * 10 | ||||||
|  |     size = 1000 | ||||||
|  |     if name is None: | ||||||
|  |         name = seed | ||||||
|  |     dwg = svgwrite.Drawing(filename="out/{}.svg".format(name)) | ||||||
|  |     dwg.defs.add(dwg.style(".background { fill: #222; }")) | ||||||
|  |     dwg.add(dwg.rect(size=("100%", "100%"), class_="background")) | ||||||
|  |     print("Generating points...") | ||||||
|  |     color = "#eee" | ||||||
|  |     pos = make_points(num_points, size, min_dist=min_dist) | ||||||
|  |     print("TSP...") | ||||||
|  |     pos = tsp(pos) | ||||||
|  |     for (x1, y1), (x2, y2) in zip(pos, pos[1:]): | ||||||
|  |         if small: | ||||||
|  |             x1 /= sd | ||||||
|  |             x2 /= sd | ||||||
|  |             y1 /= sd | ||||||
|  |             y2 /= sd | ||||||
|  |         line = dwg.add(dwg.line((x1, y1), (x2, y2), stroke_width=w, stroke=color)) | ||||||
|  | 
 | ||||||
|  |     for (px, py) in pos: | ||||||
|  |         base_r = 3 | ||||||
|  |         if small: | ||||||
|  |             base_r = 5 | ||||||
|  |             px /= sd | ||||||
|  |             py /= sd | ||||||
|  |         if random.random() > 0.8: | ||||||
|  |             dwg.add( | ||||||
|  |                 dwg.circle( | ||||||
|  |                     (px, py), | ||||||
|  |                     r=base_r + random.random() * base_r, | ||||||
|  |                     stroke_width=w, | ||||||
|  |                     stroke="#0ae", | ||||||
|  |                 ) | ||||||
|  |             ).fill("#0ae") | ||||||
|  |         else: | ||||||
|  |             dwg.add( | ||||||
|  |                 dwg.circle( | ||||||
|  |                     (px, py), | ||||||
|  |                     r=base_r + random.random() * base_r, | ||||||
|  |                     stroke_width=w, | ||||||
|  |                     stroke=color, | ||||||
|  |                 ) | ||||||
|  |             ).fill(color) | ||||||
|  |         r = base_r | ||||||
|  |         for _ in range(random.randint(1, max_rings)): | ||||||
|  |             if small: | ||||||
|  |                 random.random() | ||||||
|  |                 random.random() | ||||||
|  |                 random.random() | ||||||
|  |                 continue | ||||||
|  |             r += ring_step(random.random()) | ||||||
|  |             ring_col = color | ||||||
|  |             if random.random() > 0.75: | ||||||
|  |                 ring_col = "#ea0" | ||||||
|  |             circ = dwg.add(dwg.circle((px, py), r=r, stroke_width=w, stroke=ring_col)) | ||||||
|  |             circ.fill(color, opacity=0) | ||||||
|  |             d = random.random() * pi * 2 | ||||||
|  |             dx = cos(d) | ||||||
|  |             dy = sin(d) | ||||||
|  |             m = random.random() | ||||||
|  |             moon = dwg.add( | ||||||
|  |                 dwg.circle( | ||||||
|  |                     (px + dx * r, py + dy * r), | ||||||
|  |                     r=2 + 2 * m, | ||||||
|  |                     stroke_width=w, | ||||||
|  |                     stroke=ring_col, | ||||||
|  |                 ) | ||||||
|  |             ) | ||||||
|  |             moon.fill(ring_col) | ||||||
|  | 
 | ||||||
|  |     dwg.save() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | seed = -4 | ||||||
|  | generate(seed, "icon_1", small=False) | ||||||
|  | generate(seed, "icon_1_small", small=True) | ||||||
							
								
								
									
										2
									
								
								icon/out/icon_1.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								icon/out/icon_1.svg
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | <?xml version="1.0" encoding="utf-8" ?> | ||||||
|  | <svg baseProfile="full" height="100%" version="1.1" width="100%" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"><![CDATA[.background { fill: #222; }]]></style></defs><rect class="background" height="100%" width="100%" x="0" y="0" /><line stroke="#eee" stroke-width="2" x1="188.02404486871725" x2="103.25754783979495" y1="121.5830171153579" y2="270.7955072425374" /><line stroke="#eee" stroke-width="2" x1="103.25754783979495" x2="528.9775215438594" y1="270.7955072425374" y2="470.2261757479043" /><line stroke="#eee" stroke-width="2" x1="528.9775215438594" x2="452.58130125271924" y1="470.2261757479043" y2="180.96408784515882" /><line stroke="#eee" stroke-width="2" x1="452.58130125271924" x2="338.3400040874068" y1="180.96408784515882" y2="208.34132172072512" /><circle cx="188.02404486871725" cy="121.5830171153579" fill="#eee" r="3.3185498772945903" stroke="#eee" stroke-width="2" /><circle cx="188.02404486871725" cy="121.5830171153579" fill="#eee" fill-opacity="0" r="22.429593602379832" stroke="#eee" stroke-width="2" /><circle cx="173.80179554276944" cy="104.23901834695114" fill="#eee" r="2.52050830126476" stroke="#eee" stroke-width="2" /><circle cx="103.25754783979495" cy="270.7955072425374" fill="#eee" r="3.4944547782059745" stroke="#eee" stroke-width="2" /><circle cx="103.25754783979495" cy="270.7955072425374" fill="#eee" fill-opacity="0" r="19.2697560241313" stroke="#eee" stroke-width="2" /><circle cx="115.03444741085107" cy="255.5433554690071" fill="#eee" r="3.7601015027223985" stroke="#eee" stroke-width="2" /><circle cx="103.25754783979495" cy="270.7955072425374" fill="#eee" fill-opacity="0" r="30.13693855048052" stroke="#eee" stroke-width="2" /><circle cx="89.02212054970202" cy="244.23260689141011" fill="#eee" r="3.0119075514208307" stroke="#eee" stroke-width="2" /><circle cx="528.9775215438594" cy="470.2261757479043" fill="#eee" r="4.420763662755435" stroke="#eee" stroke-width="2" /><circle cx="528.9775215438594" cy="470.2261757479043" fill="#eee" fill-opacity="0" r="22.44577790309402" stroke="#ea0" stroke-width="2" /><circle cx="549.9596596985477" cy="462.25354606049257" fill="#ea0" r="3.680925358835544" stroke="#ea0" stroke-width="2" /><circle cx="452.58130125271924" cy="180.96408784515882" fill="#eee" r="3.8758250081323116" stroke="#eee" stroke-width="2" /><circle cx="452.58130125271924" cy="180.96408784515882" fill="#eee" fill-opacity="0" r="21.8231723987879" stroke="#ea0" stroke-width="2" /><circle cx="430.78831758434035" cy="179.8166052191519" fill="#ea0" r="2.827892086263464" stroke="#ea0" stroke-width="2" /><circle cx="452.58130125271924" cy="180.96408784515882" fill="#eee" fill-opacity="0" r="37.812297120687795" stroke="#eee" stroke-width="2" /><circle cx="472.57653937753463" cy="213.0570818761791" fill="#eee" r="2.6102231928654778" stroke="#eee" stroke-width="2" /><circle cx="452.58130125271924" cy="180.96408784515882" fill="#eee" fill-opacity="0" r="55.938220307034" stroke="#eee" stroke-width="2" /><circle cx="506.1669380410402" cy="197.01600427617765" fill="#eee" r="3.252701491079807" stroke="#eee" stroke-width="2" /><circle cx="338.3400040874068" cy="208.34132172072512" fill="#eee" r="4.603865384638267" stroke="#eee" stroke-width="2" /><circle cx="338.3400040874068" cy="208.34132172072512" fill="#eee" fill-opacity="0" r="20.00878719559634" stroke="#eee" stroke-width="2" /><circle cx="329.11968037233845" cy="190.58358550160054" fill="#eee" r="2.132876938772122" stroke="#eee" stroke-width="2" /><circle cx="338.3400040874068" cy="208.34132172072512" fill="#eee" fill-opacity="0" r="39.144105385654704" stroke="#eee" stroke-width="2" /><circle cx="301.84139133159863" cy="222.48742554279568" fill="#eee" r="2.3674072974299003" stroke="#eee" stroke-width="2" /></svg> | ||||||
| After Width: | Height: | Size: 3.8 KiB | 
							
								
								
									
										2
									
								
								icon/out/icon_1_small.svg
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								icon/out/icon_1_small.svg
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | <?xml version="1.0" encoding="utf-8" ?> | ||||||
|  | <svg baseProfile="full" height="100%" version="1.1" width="100%" xmlns="http://www.w3.org/2000/svg" xmlns:ev="http://www.w3.org/2001/xml-events" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><style type="text/css"><![CDATA[.background { fill: #222; }]]></style></defs><rect class="background" height="100%" width="100%" x="0" y="0" /><line stroke="#eee" stroke-width="2" x1="94.01202243435863" x2="51.628773919897476" y1="60.79150855767895" y2="135.3977536212687" /><line stroke="#eee" stroke-width="2" x1="51.628773919897476" x2="264.4887607719297" y1="135.3977536212687" y2="235.11308787395214" /><line stroke="#eee" stroke-width="2" x1="264.4887607719297" x2="226.29065062635962" y1="235.11308787395214" y2="90.48204392257941" /><line stroke="#eee" stroke-width="2" x1="226.29065062635962" x2="169.1700020437034" y1="90.48204392257941" y2="104.17066086036256" /><circle cx="94.01202243435863" cy="60.79150855767895" fill="#eee" r="5.53091646215765" stroke="#eee" stroke-width="2" /><circle cx="51.628773919897476" cy="135.3977536212687" fill="#eee" r="6.358738772326545" stroke="#eee" stroke-width="2" /><circle cx="264.4887607719297" cy="235.11308787395214" fill="#0ae" r="9.400253756805997" stroke="#0ae" stroke-width="2" /><circle cx="226.29065062635962" cy="90.48204392257941" fill="#eee" r="6.236611100792434" stroke="#eee" stroke-width="2" /><circle cx="169.1700020437034" cy="104.17066086036256" fill="#eee" r="9.41158619939395" stroke="#eee" stroke-width="2" /></svg> | ||||||
| After Width: | Height: | Size: 1.5 KiB | 
							
								
								
									
										25
									
								
								installer/ED_LRR.iss
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								installer/ED_LRR.iss
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,25 @@ | ||||||
|  | [Setup] | ||||||
|  | AppName = "ED_LRR" | ||||||
|  | AppVersion ="0.1.0" | ||||||
|  | ; WizardStyle = modern | ||||||
|  | DefaultDirName = {autopf}\ED_LRR | ||||||
|  | DefaultGroupName=ED_LRR | ||||||
|  | Compression = lzma2/ultra | ||||||
|  | SolidCompression = true | ||||||
|  | InternalCompressLevel = ultra | ||||||
|  | OutputBaseFilename="ED_LRR Setup" | ||||||
|  | ChangesEnvironment = true | ||||||
|  | 
 | ||||||
|  | [Files] | ||||||
|  | Source: "..\exe\__main__.dist\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs | ||||||
|  | 
 | ||||||
|  | [Icons] | ||||||
|  | Name: "{group}\ED_LRR"; Filename: "{app}\ED_LRR.exe"; WorkingDir: "{app}" | ||||||
|  | Name: "{group}\Uninstall ED_LRR"; Filename: "{uninstallexe}" | ||||||
|  | 
 | ||||||
|  | [Tasks] | ||||||
|  | ;Name: modifypath; Description: Add application directory to PATH; Flags: unchecked | ||||||
|  | 
 | ||||||
|  | [Run] | ||||||
|  | Filename: "{app}\ED_LRR.exe"; Parameters: "download"; StatusMsg: "Downloading EDSM dumps..."; Description: "Download EDSM dumps"; Flags: postinstall | ||||||
|  | Filename: "{app}\ED_LRR.exe"; Description: "Launch ED_LRR"; Flags: postinstall nowait skipifsilent unchecked | ||||||
							
								
								
									
										2
									
								
								pyproject.toml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								pyproject.toml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | [build-system] | ||||||
|  | requires = ["setuptools", "wheel", "setuptools-rust"] | ||||||
							
								
								
									
										2
									
								
								pytest.ini
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								pytest.ini
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | [pytest] | ||||||
|  | qt_api=pyqt5 | ||||||
							
								
								
									
										2
									
								
								rust/.cargo/config
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								rust/.cargo/config
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,2 @@ | ||||||
|  | [build] | ||||||
|  | rustflags = ["-C", "target-cpu=native"] | ||||||
							
								
								
									
										533
									
								
								rust/Cargo.lock
									
										
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										533
									
								
								rust/Cargo.lock
									
										
									
										generated
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,533 @@ | ||||||
|  | # This file is automatically @generated by Cargo. | ||||||
|  | # It is not intended for manual editing. | ||||||
|  | [[package]] | ||||||
|  | name = "aho-corasick" | ||||||
|  | version = "0.7.6" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "autocfg" | ||||||
|  | version = "0.1.7" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "bincode" | ||||||
|  | version = "1.2.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "block-buffer" | ||||||
|  | version = "0.7.3" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "block-padding" | ||||||
|  | version = "0.1.4" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "bstr" | ||||||
|  | version = "0.2.8" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "byte-tools" | ||||||
|  | version = "0.3.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "byteorder" | ||||||
|  | version = "1.3.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "csv" | ||||||
|  | version = "1.1.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "csv-core" | ||||||
|  | version = "0.1.6" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "ctor" | ||||||
|  | version = "0.1.12" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "digest" | ||||||
|  | version = "0.8.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "ed_lrr" | ||||||
|  | version = "0.0.0" | ||||||
|  | dependencies = [ | ||||||
|  |  "bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "permutohedron 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "pyo3 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "rstar 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "strsim 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "either" | ||||||
|  | version = "1.5.3" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "fnv" | ||||||
|  | version = "1.0.6" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "generic-array" | ||||||
|  | version = "0.12.3" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "ghost" | ||||||
|  | version = "0.1.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "humantime" | ||||||
|  | version = "1.3.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "indoc" | ||||||
|  | version = "0.3.4" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "indoc-impl 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "indoc-impl" | ||||||
|  | version = "0.3.4" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "unindent 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "inventory" | ||||||
|  | version = "0.1.4" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "ctor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "ghost 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "inventory-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "inventory-impl" | ||||||
|  | version = "0.1.4" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "itertools" | ||||||
|  | version = "0.8.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "itoa" | ||||||
|  | version = "0.4.4" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "keccak" | ||||||
|  | version = "0.1.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "lazy_static" | ||||||
|  | version = "1.4.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "libc" | ||||||
|  | version = "0.2.65" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "memchr" | ||||||
|  | version = "2.2.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "num-traits" | ||||||
|  | version = "0.2.8" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "opaque-debug" | ||||||
|  | version = "0.2.3" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "paste" | ||||||
|  | version = "0.1.6" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "paste-impl" | ||||||
|  | version = "0.1.6" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "pdqselect" | ||||||
|  | version = "0.1.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "permutohedron" | ||||||
|  | version = "0.2.4" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "proc-macro-hack" | ||||||
|  | version = "0.5.11" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "proc-macro2" | ||||||
|  | version = "1.0.6" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "pyo3" | ||||||
|  | version = "0.8.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "indoc 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "inventory 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "pyo3cls 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "unindent 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "pyo3-derive-backend" | ||||||
|  | version = "0.8.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "pyo3cls" | ||||||
|  | version = "0.8.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "pyo3-derive-backend 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "quick-error" | ||||||
|  | version = "1.2.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "quote" | ||||||
|  | version = "1.0.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "regex" | ||||||
|  | version = "1.3.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "regex-automata" | ||||||
|  | version = "0.1.8" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "regex-syntax" | ||||||
|  | version = "0.6.12" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "rstar" | ||||||
|  | version = "0.5.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "pdqselect 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "ryu" | ||||||
|  | version = "1.0.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "serde" | ||||||
|  | version = "1.0.101" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "serde_derive" | ||||||
|  | version = "1.0.101" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "serde_json" | ||||||
|  | version = "1.0.41" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "sha3" | ||||||
|  | version = "0.8.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "spin" | ||||||
|  | version = "0.5.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "strsim" | ||||||
|  | version = "0.9.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "syn" | ||||||
|  | version = "1.0.5" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  |  "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "thread_local" | ||||||
|  | version = "0.3.6" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | dependencies = [ | ||||||
|  |  "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", | ||||||
|  | ] | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "typenum" | ||||||
|  | version = "1.11.2" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "unicode-xid" | ||||||
|  | version = "0.2.0" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "unindent" | ||||||
|  | version = "0.1.5" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [[package]] | ||||||
|  | name = "version_check" | ||||||
|  | version = "0.9.1" | ||||||
|  | source = "registry+https://github.com/rust-lang/crates.io-index" | ||||||
|  | 
 | ||||||
|  | [metadata] | ||||||
|  | "checksum aho-corasick 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "58fb5e95d83b38284460a5fda7d6470aa0b8844d283a0b614b8535e880800d2d" | ||||||
|  | "checksum autocfg 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2" | ||||||
|  | "checksum bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b8ab639324e3ee8774d296864fbc0dbbb256cf1a41c490b94cba90c082915f92" | ||||||
|  | "checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b" | ||||||
|  | "checksum block-padding 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "6d4dc3af3ee2e12f3e5d224e5e1e3d73668abbeb69e566d361f7d5563a4fdf09" | ||||||
|  | "checksum bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6c2c5b58ab920a4f5aeaaca34b4488074e8cc7596af94e6f8c6ff247c60245" | ||||||
|  | "checksum byte-tools 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" | ||||||
|  | "checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5" | ||||||
|  | "checksum csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d" | ||||||
|  | "checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c" | ||||||
|  | "checksum ctor 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "cd8ce37ad4184ab2ce004c33bf6379185d3b1c95801cab51026bd271bf68eedc" | ||||||
|  | "checksum digest 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" | ||||||
|  | "checksum either 1.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" | ||||||
|  | "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" | ||||||
|  | "checksum generic-array 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c68f0274ae0e023facc3c97b2e00f076be70e254bc851d972503b328db79b2ec" | ||||||
|  | "checksum ghost 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a36606a68532b5640dc86bb1f33c64b45c4682aad4c50f3937b317ea387f3d6" | ||||||
|  | "checksum humantime 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" | ||||||
|  | "checksum indoc 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3f9553c1e16c114b8b77ebeb329e5f2876eed62a8d51178c8bc6bff0d65f98f8" | ||||||
|  | "checksum indoc-impl 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b714fc08d0961716390977cdff1536234415ac37b509e34e5a983def8340fb75" | ||||||
|  | "checksum inventory 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f4cece20baea71d9f3435e7bbe9adf4765f091c5fe404975f844006964a71299" | ||||||
|  | "checksum inventory-impl 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c2869bf972e998977b1cb87e60df70341d48e48dca0823f534feb91ea44adaf9" | ||||||
|  | "checksum itertools 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5b8467d9c1cebe26feb08c640139247fac215782d35371ade9a2136ed6085358" | ||||||
|  | "checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" | ||||||
|  | "checksum keccak 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "67c21572b4949434e4fc1e1978b99c5f77064153c59d998bf13ecd96fb5ecba7" | ||||||
|  | "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" | ||||||
|  | "checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8" | ||||||
|  | "checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e" | ||||||
|  | "checksum num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "6ba9a427cfca2be13aa6f6403b0b7e7368fe982bfa16fccc450ce74c46cd9b32" | ||||||
|  | "checksum opaque-debug 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" | ||||||
|  | "checksum paste 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "423a519e1c6e828f1e73b720f9d9ed2fa643dce8a7737fb43235ce0b41eeaa49" | ||||||
|  | "checksum paste-impl 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "4214c9e912ef61bf42b81ba9a47e8aad1b2ffaf739ab162bf96d1e011f54e6c5" | ||||||
|  | "checksum pdqselect 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ec91767ecc0a0bbe558ce8c9da33c068066c57ecc8bb8477ef8c1ad3ef77c27" | ||||||
|  | "checksum permutohedron 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "b687ff7b5da449d39e418ad391e5e08da53ec334903ddbb921db208908fc372c" | ||||||
|  | "checksum proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)" = "ecd45702f76d6d3c75a80564378ae228a85f0b59d2f3ed43c91b4a69eb2ebfc5" | ||||||
|  | "checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27" | ||||||
|  | "checksum pyo3 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a00f96312ebe4082db7d93ad062df1818f597660002541c1bbae6752ec583244" | ||||||
|  | "checksum pyo3-derive-backend 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1a7caa60cb986fca5b488e29d078fb25ae228e01dab080b855168ce061bbef0a" | ||||||
|  | "checksum pyo3cls 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a5ccfa624ed9b5d805079f1ad64b3f1de5d551a946d4cf494f1f032b5572d39f" | ||||||
|  | "checksum quick-error 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9274b940887ce9addde99c4eee6b5c44cc494b182b97e73dc8ffdcb3397fd3f0" | ||||||
|  | "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" | ||||||
|  | "checksum regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dc220bd33bdce8f093101afe22a037b8eb0e5af33592e6a9caafff0d4cb81cbd" | ||||||
|  | "checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9" | ||||||
|  | "checksum regex-syntax 0.6.12 (registry+https://github.com/rust-lang/crates.io-index)" = "11a7e20d1cce64ef2fed88b66d347f88bd9babb82845b2b858f3edbf59a4f716" | ||||||
|  | "checksum rstar 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "08c3cf91d6318ed050a8dda79bc857665f9c3d41524b6f70bbd0396c5d9d662d" | ||||||
|  | "checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" | ||||||
|  | "checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd" | ||||||
|  | "checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e" | ||||||
|  | "checksum serde_json 1.0.41 (registry+https://github.com/rust-lang/crates.io-index)" = "2f72eb2a68a7dc3f9a691bfda9305a1c017a6215e5a4545c258500d2099a37c2" | ||||||
|  | "checksum sha3 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dd26bc0e7a2e3a7c959bc494caf58b72ee0c71d67704e9520f736ca7e4853ecf" | ||||||
|  | "checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" | ||||||
|  | "checksum strsim 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "032c03039aae92b350aad2e3779c352e104d919cb192ba2fabbd7b831ce4f0f6" | ||||||
|  | "checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf" | ||||||
|  | "checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b" | ||||||
|  | "checksum typenum 1.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6d2783fe2d6b8c1101136184eb41be8b1ad379e4657050b8aaff0c79ee7575f9" | ||||||
|  | "checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" | ||||||
|  | "checksum unindent 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "63f18aa3b0e35fed5a0048f029558b1518095ffe2a0a31fb87c93dece93a4993" | ||||||
|  | "checksum version_check 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" | ||||||
							
								
								
									
										26
									
								
								rust/Cargo.toml
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								rust/Cargo.toml
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,26 @@ | ||||||
|  | [package] | ||||||
|  | name = "ed_lrr" | ||||||
|  | version = "0.0.0" | ||||||
|  | authors = ["Daniel Seiller <earthnuker@gmail.com>"] | ||||||
|  | edition = "2018" | ||||||
|  | repository = "https://gitlab.com/Earthnuker/ed_lrr.git" | ||||||
|  | license = "WTFPL" | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | [lib] | ||||||
|  | crate-type = ["cdylib"] | ||||||
|  | name = "_ed_lrr" | ||||||
|  | 
 | ||||||
|  | [dependencies] | ||||||
|  | pyo3 = { version = "0.8.0", features = ["extension-module"] } | ||||||
|  | csv = "1.1.1" | ||||||
|  | serde = { version = "1.0.101", features = ["derive"] } | ||||||
|  | humantime = "1.3.0" | ||||||
|  | permutohedron = "0.2.4" | ||||||
|  | serde_json = "1.0.40" | ||||||
|  | fnv = "1.0.6" | ||||||
|  | bincode = "1.2.0" | ||||||
|  | sha3 = "0.8.2" | ||||||
|  | byteorder = "1.3.2" | ||||||
|  | strsim = "0.9.2" | ||||||
|  | rstar = "0.5.1" | ||||||
|  | @ -1,4 +1,6 @@ | ||||||
| use serde::{Deserialize, Serialize}; | use serde::{Deserialize, Serialize}; | ||||||
|  | use std::cmp::Ordering; | ||||||
|  | 
 | ||||||
| #[derive(Debug, Clone, Serialize, Deserialize)] | #[derive(Debug, Clone, Serialize, Deserialize)] | ||||||
| pub struct SystemSerde { | pub struct SystemSerde { | ||||||
|     pub id: u32, |     pub id: u32, | ||||||
|  | @ -36,3 +38,15 @@ pub struct System { | ||||||
|     pub distance: u32, |     pub distance: u32, | ||||||
|     pub pos: [f32; 3], |     pub pos: [f32; 3], | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | impl Ord for System { | ||||||
|  |     fn cmp(&self, other: &Self) -> Ordering { | ||||||
|  |         self.id.cmp(&other.id) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl PartialOrd for System { | ||||||
|  |     fn partial_cmp(&self, other: &Self) -> Option<Ordering> { | ||||||
|  |         Some(self.cmp(other)) | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										192
									
								
								rust/src/lib.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										192
									
								
								rust/src/lib.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,192 @@ | ||||||
|  | extern crate strsim; | ||||||
|  | mod common; | ||||||
|  | mod preprocess; | ||||||
|  | mod route; | ||||||
|  | use common::{System, SystemSerde}; | ||||||
|  | use pyo3::exceptions::*; | ||||||
|  | use pyo3::prelude::*; | ||||||
|  | use pyo3::types::{PyDict, PyList}; | ||||||
|  | use std::collections::HashMap; | ||||||
|  | use std::path::PathBuf; | ||||||
|  | 
 | ||||||
|  | fn find_matches( | ||||||
|  |     path: &PathBuf, | ||||||
|  |     names: Vec<String>, | ||||||
|  | ) -> Result<HashMap<String, (f64, Option<System>)>, String> { | ||||||
|  |     let mut best: HashMap<String, (f64, Option<System>)> = HashMap::new(); | ||||||
|  |     for name in &names { | ||||||
|  |         best.insert(name.to_string(), (0.0, None)); | ||||||
|  |     } | ||||||
|  |     let mut reader = match csv::ReaderBuilder::new().from_path(path) { | ||||||
|  |         Ok(rdr) => rdr, | ||||||
|  |         Err(e) => { | ||||||
|  |             return Err(format!("Error opening {}: {}", path.to_str().unwrap(), e).to_string()); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  |     let systems = reader.deserialize::<SystemSerde>(); | ||||||
|  |     for sys in systems { | ||||||
|  |         let sys = sys.unwrap(); | ||||||
|  |         for name in &names { | ||||||
|  |             best.entry(name.clone()).and_modify(|ent| { | ||||||
|  |                 let d1 = strsim::normalized_levenshtein(&sys.system, &name); | ||||||
|  |                 if d1 > ent.0 { | ||||||
|  |                     *ent = (d1, Some(sys.build())) | ||||||
|  |                 } | ||||||
|  |             }); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     Ok(best) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[pymodule] | ||||||
|  | pub fn _ed_lrr(_py: Python, m: &PyModule) -> PyResult<()> { | ||||||
|  |     /// preprocess(infile_systems, infile_bodies, outfile, callback)
 | ||||||
|  |     /// --
 | ||||||
|  |     ///
 | ||||||
|  |     /// Preprocess bodies.json and systemsWithCoordinates.json into stars.csv
 | ||||||
|  |     #[pyfn(m, "preprocess")] | ||||||
|  |     fn ed_lrr_preprocess( | ||||||
|  |         py: Python<'static>, | ||||||
|  |         infile_systems: String, | ||||||
|  |         infile_bodies: String, | ||||||
|  |         outfile: String, | ||||||
|  |         callback: PyObject, | ||||||
|  |     ) -> PyResult<PyObject> { | ||||||
|  |         use preprocess::*; | ||||||
|  |         let state = PyDict::new(py); | ||||||
|  |         let state_dict = PyDict::new(py); | ||||||
|  |         callback.call(py, (state_dict,), None).unwrap(); | ||||||
|  |         let callback_wrapped = move |state: &PreprocessState| { | ||||||
|  |             // println!("SEND: {:?}",state);
 | ||||||
|  |             state_dict.set_item("file", state.file.clone())?; | ||||||
|  |             state_dict.set_item("total", state.total)?; | ||||||
|  |             state_dict.set_item("count", state.count)?; | ||||||
|  |             state_dict.set_item("done", state.done)?; | ||||||
|  |             state_dict.set_item("message", state.message.clone())?; | ||||||
|  |             callback.call(py, (state_dict,), None) | ||||||
|  |         }; | ||||||
|  |         preprocess_files( | ||||||
|  |             &PathBuf::from(infile_bodies), | ||||||
|  |             &PathBuf::from(infile_systems), | ||||||
|  |             &PathBuf::from(outfile), | ||||||
|  |             &callback_wrapped, | ||||||
|  |         ) | ||||||
|  |         .unwrap(); | ||||||
|  |         Ok(state.to_object(py)) | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     ///find_sys(sys_names,sys_list)
 | ||||||
|  |     /// --
 | ||||||
|  |     ///
 | ||||||
|  |     /// Find system by name
 | ||||||
|  |     #[pyfn(m, "find_sys")] | ||||||
|  |     fn find_sys(py: Python, sys_names: Vec<String>, sys_list: String) -> PyResult<PyObject> { | ||||||
|  |         let path = PathBuf::from(sys_list); | ||||||
|  |         match find_matches(&path, sys_names) { | ||||||
|  |             Ok(vals) => { | ||||||
|  |                 let ret = PyDict::new(py); | ||||||
|  |                 for (key, (diff, sys)) in vals { | ||||||
|  |                     let ret_dict = PyDict::new(py); | ||||||
|  |                     if let Some(val) = sys { | ||||||
|  |                         let pos = PyList::new(py, val.pos.iter()); | ||||||
|  |                         ret_dict.set_item("star_type", val.star_type.clone())?; | ||||||
|  |                         ret_dict.set_item("system", val.system.clone())?; | ||||||
|  |                         ret_dict.set_item("body", val.body.clone())?; | ||||||
|  |                         ret_dict.set_item("distance", val.distance)?; | ||||||
|  |                         ret_dict.set_item("pos", pos)?; | ||||||
|  |                         ret_dict.set_item("id", val.id)?; | ||||||
|  |                         ret.set_item(key, (diff, ret_dict).to_object(py))?; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 Ok(ret.to_object(py)) | ||||||
|  |             } | ||||||
|  |             Err(e) => Err(PyErr::new::<ValueError, _>(e)), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /// route(infile, hops, range, radius_mult, mode,primary, greedyness, precomp, callback)
 | ||||||
|  |     /// --
 | ||||||
|  |     ///
 | ||||||
|  |     /// Compute a Route using the suplied parameters
 | ||||||
|  |     #[pyfn(m, "route")] | ||||||
|  |     #[allow(clippy::too_many_arguments)] | ||||||
|  |     fn route( | ||||||
|  |         py: Python<'static>, | ||||||
|  |         hops: Vec<String>, | ||||||
|  |         range: f32, | ||||||
|  |         prune: Option<(usize, f32)>, | ||||||
|  |         mode: String, | ||||||
|  |         primary: bool, | ||||||
|  |         permute: bool, | ||||||
|  |         keep_first: bool, | ||||||
|  |         keep_last: bool, | ||||||
|  |         greedyness: Option<f32>, | ||||||
|  |         precomp: Option<String>, | ||||||
|  |         path: String, | ||||||
|  |         callback: PyObject, | ||||||
|  |     ) -> PyResult<PyObject> { | ||||||
|  |         use route::*; | ||||||
|  |         let mode = match Mode::parse(&mode) { | ||||||
|  |             Ok(val) => val, | ||||||
|  |             Err(e) => { | ||||||
|  |                 return Err(PyErr::new::<ValueError, _>(e)); | ||||||
|  |             } | ||||||
|  |         }; | ||||||
|  |         let state_dict = PyDict::new(py); | ||||||
|  |         callback.call(py, (state_dict,), None).unwrap(); | ||||||
|  |         let callback_wrapped = move |state: &SearchState| { | ||||||
|  |             state_dict.set_item("mode", state.mode.clone())?; | ||||||
|  |             state_dict.set_item("system", state.system.clone())?; | ||||||
|  |             state_dict.set_item("body", state.body.clone())?; | ||||||
|  |             state_dict.set_item("depth", state.depth)?; | ||||||
|  |             state_dict.set_item("queue_size", state.queue_size)?; | ||||||
|  |             state_dict.set_item("d_rem", state.d_rem)?; | ||||||
|  |             state_dict.set_item("d_total", state.d_total)?; | ||||||
|  |             state_dict.set_item("prc_done", state.prc_done)?; | ||||||
|  |             state_dict.set_item("n_seen", state.n_seen)?; | ||||||
|  |             state_dict.set_item("prc_seen", state.prc_seen)?; | ||||||
|  |             state_dict.set_item("from", state.from.clone())?; | ||||||
|  |             state_dict.set_item("to", state.to.clone())?; | ||||||
|  |             callback.call(py, (state_dict,), None) | ||||||
|  |         }; | ||||||
|  |         let mut systems = Vec::new(); | ||||||
|  |         for sys in hops { | ||||||
|  |             systems.push(route::SysEntry::parse(&sys)) | ||||||
|  |         } | ||||||
|  |         let opts = RouteOpts { | ||||||
|  |             systems, | ||||||
|  |             range: Some(range), | ||||||
|  |             file_path: PathBuf::from(path), | ||||||
|  |             precomp_file: precomp.map(PathBuf::from), | ||||||
|  |             callback: Box::new(callback_wrapped), | ||||||
|  |             mode, | ||||||
|  |             factor: greedyness, | ||||||
|  |             precompute: false, | ||||||
|  |             permute, | ||||||
|  |             keep_first, | ||||||
|  |             keep_last, | ||||||
|  |             primary, | ||||||
|  |             prune, | ||||||
|  |         }; | ||||||
|  |         let none = ().to_object(py); | ||||||
|  |         match route(opts) { | ||||||
|  |             Ok(Some(route)) => { | ||||||
|  |                 let hops = route.iter().map(|hop| { | ||||||
|  |                     let pos = PyList::new(py, hop.pos.iter()); | ||||||
|  |                     let elem = PyDict::new(py); | ||||||
|  |                     elem.set_item("star_type", hop.star_type.clone()).unwrap(); | ||||||
|  |                     elem.set_item("system", hop.system.clone()).unwrap(); | ||||||
|  |                     elem.set_item("body", hop.body.clone()).unwrap(); | ||||||
|  |                     elem.set_item("distance", hop.distance).unwrap(); | ||||||
|  |                     elem.set_item("pos", pos).unwrap(); | ||||||
|  |                     elem | ||||||
|  |                 }); | ||||||
|  |                 let lst = PyList::new(py, hops); | ||||||
|  |                 Ok(lst.to_object(py)) | ||||||
|  |             } | ||||||
|  |             Ok(None) => Ok(none), | ||||||
|  |             Err(e) => Err(PyErr::new::<ValueError, _>(e)), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     Ok(()) | ||||||
|  | } | ||||||
							
								
								
									
										206
									
								
								rust/src/preprocess.rs
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										206
									
								
								rust/src/preprocess.rs
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,206 @@ | ||||||
|  | use crate::common::SystemSerde; | ||||||
|  | use fnv::FnvHashMap; | ||||||
|  | use pyo3::prelude::*; | ||||||
|  | use serde::Deserialize; | ||||||
|  | use serde_json::Result; | ||||||
|  | use std::fs::File; | ||||||
|  | use std::io::Seek; | ||||||
|  | use std::io::{BufRead, BufReader, BufWriter, SeekFrom}; | ||||||
|  | use std::path::PathBuf; | ||||||
|  | use std::str; | ||||||
|  | use std::time::Instant; | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Deserialize)] | ||||||
|  | #[allow(non_snake_case)] | ||||||
|  | struct Body { | ||||||
|  |     name: String, | ||||||
|  |     subType: String, | ||||||
|  |     #[serde(rename = "type")] | ||||||
|  |     body_type: String, | ||||||
|  |     systemId: i32, | ||||||
|  |     systemId64: i64, | ||||||
|  |     #[serde(rename = "distanceToArrival")] | ||||||
|  |     distance: u32, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Deserialize)] | ||||||
|  | struct Coords { | ||||||
|  |     x: f32, | ||||||
|  |     y: f32, | ||||||
|  |     z: f32, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug, Deserialize)] | ||||||
|  | struct System { | ||||||
|  |     id: i32, | ||||||
|  |     id64: i64, | ||||||
|  |     name: String, | ||||||
|  |     coords: Coords, | ||||||
|  |     date: String, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Debug)] | ||||||
|  | pub struct PreprocessState { | ||||||
|  |     pub file: String, | ||||||
|  |     pub message: String, | ||||||
|  |     pub total: u64, | ||||||
|  |     pub done: u64, | ||||||
|  |     pub count: usize, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn get_mult(star_type: &str) -> f32 { | ||||||
|  |     if star_type.contains("White Dwarf") { | ||||||
|  |         return 1.5; | ||||||
|  |     } | ||||||
|  |     if star_type.contains("Neutron") { | ||||||
|  |         return 4.0; | ||||||
|  |     } | ||||||
|  |     1.0 | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn process( | ||||||
|  |     path: &PathBuf, | ||||||
|  |     func: &mut dyn for<'r> FnMut(&'r str) -> (), | ||||||
|  |     callback: &dyn Fn(&PreprocessState) -> PyResult<PyObject>, | ||||||
|  | ) -> std::io::Result<()> { | ||||||
|  |     let mut buffer = String::new(); | ||||||
|  |     let fh = File::open(path)?; | ||||||
|  |     let total_size = fh.metadata()?.len(); | ||||||
|  |     let mut t_last = Instant::now(); | ||||||
|  |     let mut reader = BufReader::new(fh); | ||||||
|  |     let mut state = PreprocessState { | ||||||
|  |         file: path.to_str().unwrap().to_owned(), | ||||||
|  |         total: total_size, | ||||||
|  |         done: 0, | ||||||
|  |         count: 0, | ||||||
|  |         message: format!("Processing {} ...", path.to_str().unwrap()), | ||||||
|  |     }; | ||||||
|  |     println!("Loading {} ...", path.to_str().unwrap()); | ||||||
|  |     while let Ok(n) = reader.read_line(&mut buffer) { | ||||||
|  |         if n == 0 { | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |         buffer = buffer.trim_end().trim_end_matches(|c| c == ',').to_string(); | ||||||
|  |         if !buffer.is_empty() { | ||||||
|  |             func(&buffer); | ||||||
|  |         } | ||||||
|  |         let pos = reader.seek(SeekFrom::Current(0)).unwrap(); | ||||||
|  |         state.done = pos; | ||||||
|  |         state.count += 1; | ||||||
|  |         if t_last.elapsed().as_millis() > 100 { | ||||||
|  |             callback(&state)?; | ||||||
|  |             t_last = Instant::now(); | ||||||
|  |         } | ||||||
|  |         buffer.clear(); | ||||||
|  |     } | ||||||
|  |     Ok(()) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn process_systems( | ||||||
|  |     path: &PathBuf, | ||||||
|  |     callback: &dyn Fn(&PreprocessState) -> PyResult<PyObject>, | ||||||
|  | ) -> FnvHashMap<i32, System> { | ||||||
|  |     let mut ret = FnvHashMap::default(); | ||||||
|  |     process( | ||||||
|  |         path, | ||||||
|  |         &mut |line| { | ||||||
|  |             let sys_res: Result<System> = serde_json::from_str(&line); | ||||||
|  |             if let Ok(sys) = sys_res { | ||||||
|  |                 ret.insert(sys.id, sys); | ||||||
|  |             } else { | ||||||
|  |                 eprintln!("\nError parsing: {}\n\t{:?}\n", line, sys_res.unwrap_err()); | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         callback, | ||||||
|  |     ) | ||||||
|  |     .unwrap(); | ||||||
|  |     ret | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn build_index(path: &PathBuf) -> std::io::Result<()> { | ||||||
|  |     let mut wtr = BufWriter::new(File::create(path.with_extension("idx"))?); | ||||||
|  |     let mut idx: Vec<u64> = Vec::new(); | ||||||
|  |     let mut records = (csv::Reader::from_path(path)?).into_deserialize::<SystemSerde>(); | ||||||
|  |     loop { | ||||||
|  |         idx.push(records.reader().position().byte()); | ||||||
|  |         if records.next().is_none() { | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     bincode::serialize_into(&mut wtr, &idx).unwrap(); | ||||||
|  |     Ok(()) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | fn process_bodies( | ||||||
|  |     path: &PathBuf, | ||||||
|  |     out_path: &PathBuf, | ||||||
|  |     systems: &mut FnvHashMap<i32, System>, | ||||||
|  |     callback: &dyn Fn(&PreprocessState) -> PyResult<PyObject>, | ||||||
|  | ) -> std::io::Result<()> { | ||||||
|  |     println!( | ||||||
|  |         "Processing {} into {} ...", | ||||||
|  |         path.to_str().unwrap(), | ||||||
|  |         out_path.to_str().unwrap(), | ||||||
|  |     ); | ||||||
|  |     let mut n: u32 = 0; | ||||||
|  |     let mut wtr = csv::Writer::from_path(out_path)?; | ||||||
|  |     process( | ||||||
|  |         path, | ||||||
|  |         &mut |line| { | ||||||
|  |             if !line.contains("Star") { | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |             let body_res: Result<Body> = serde_json::from_str(&line); | ||||||
|  |             if let Ok(body) = body_res { | ||||||
|  |                 if !body.body_type.contains("Star") { | ||||||
|  |                     return; | ||||||
|  |                 } | ||||||
|  |                 if let Some(sys) = systems.get(&body.systemId) { | ||||||
|  |                     let sub_type = body.subType; | ||||||
|  |                     let mult = get_mult(&sub_type); | ||||||
|  |                     let sys_name = sys.name.clone(); | ||||||
|  |                     let rec = SystemSerde { | ||||||
|  |                         id: n, | ||||||
|  |                         star_type: sub_type, | ||||||
|  |                         system: sys_name, | ||||||
|  |                         body: body.name, | ||||||
|  |                         mult, | ||||||
|  |                         distance: body.distance, | ||||||
|  |                         x: sys.coords.x, | ||||||
|  |                         y: sys.coords.y, | ||||||
|  |                         z: sys.coords.z, | ||||||
|  |                     }; | ||||||
|  |                     wtr.serialize(rec).unwrap(); | ||||||
|  |                     n += 1; | ||||||
|  |                 }; | ||||||
|  |             } else { | ||||||
|  |                 eprintln!("\nError parsing: {}\n\t{:?}\n", line, body_res.unwrap_err()); | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         callback, | ||||||
|  |     ) | ||||||
|  |     .unwrap(); | ||||||
|  |     println!("Total Systems: {}", n); | ||||||
|  |     systems.clear(); | ||||||
|  |     Ok(()) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | pub fn preprocess_files( | ||||||
|  |     bodies: &PathBuf, | ||||||
|  |     systems: &PathBuf, | ||||||
|  |     out_path: &PathBuf, | ||||||
|  |     callback: &dyn Fn(&PreprocessState) -> PyResult<PyObject>, | ||||||
|  | ) -> std::io::Result<()> { | ||||||
|  |     if !out_path.exists() { | ||||||
|  |         let mut systems = process_systems(systems, &callback); | ||||||
|  |         process_bodies(bodies, out_path, &mut systems, &callback)?; | ||||||
|  |     } else { | ||||||
|  |         println!( | ||||||
|  |             "File '{}' exists, not overwriting it", | ||||||
|  |             out_path.to_str().unwrap() | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |     println!("Building index..."); | ||||||
|  |     println!("Index result: {:?}", build_index(&out_path)); | ||||||
|  |     Ok(()) | ||||||
|  | } | ||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										76
									
								
								setup.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										76
									
								
								setup.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,76 @@ | ||||||
|  | import sys | ||||||
|  | import distutils.cmd | ||||||
|  | import distutils.log | ||||||
|  | from setuptools import find_packages, setup | ||||||
|  | from setuptools_rust import Binding, RustExtension, Strip | ||||||
|  | 
 | ||||||
|  | with open("README.md", "r") as fh: | ||||||
|  |     long_description = fh.read() | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | setup( | ||||||
|  |     name="ed_lrr_gui", | ||||||
|  |     version_format="{tag}.dev{commitcount}+{gitsha}", | ||||||
|  |     author="Daniel Seiller", | ||||||
|  |     author_email="earthnuker@gmail.com", | ||||||
|  |     description="Elite: Dangerous long range route plotter", | ||||||
|  |     long_description=long_description, | ||||||
|  |     long_description_content_type="text/markdown", | ||||||
|  |     url="none yet", | ||||||
|  |     rust_extensions=[ | ||||||
|  |         RustExtension( | ||||||
|  |             "_ed_lrr", | ||||||
|  |             path="rust/Cargo.toml", | ||||||
|  |             binding=Binding.PyO3, | ||||||
|  |             strip=Strip.No, | ||||||
|  |             debug=False, | ||||||
|  |             native=True, | ||||||
|  |         ) | ||||||
|  |     ], | ||||||
|  |     packages=find_packages(), | ||||||
|  |     entry_points={"console_scripts": ["ed_lrr = ed_lrr_gui.__main__:main"]}, | ||||||
|  |     install_requires=[ | ||||||
|  |         "appdirs", | ||||||
|  |         "PyYAML", | ||||||
|  |         "requests", | ||||||
|  |         "python-dateutil", | ||||||
|  |         "pyperclip", | ||||||
|  |         "click", | ||||||
|  |         "tqdm", | ||||||
|  |         "PyQt5", | ||||||
|  |         "click-default-group", | ||||||
|  |         "profig", | ||||||
|  |         "colorama", | ||||||
|  |         "svgwrite", | ||||||
|  |     ], | ||||||
|  |     setup_requires=[ | ||||||
|  |         "setuptools", | ||||||
|  |         "setuptools-rust", | ||||||
|  |         "wheel", | ||||||
|  |         "pyinstaller", | ||||||
|  |         "pytest-runner", | ||||||
|  |         "setuptools-git-version", | ||||||
|  |     ], | ||||||
|  |     tests_require=["pytest", "pytest-pep8", "pytest-cov"], | ||||||
|  |     extras_require={ | ||||||
|  |         "dev": ["black", "pyinstaller", "jinja2", "tsp"], | ||||||
|  |         "web": [ | ||||||
|  |             "flask", | ||||||
|  |             "sqlalchemy", | ||||||
|  |             "webargs", | ||||||
|  |             "flask-sqlalchemy", | ||||||
|  |             "sqlalchemy-utils", | ||||||
|  |         ], | ||||||
|  |     }, | ||||||
|  |     classifiers=[ | ||||||
|  |         "License :: OSI Approved :: MIT License", | ||||||
|  |         "Programming Language :: Rust", | ||||||
|  |         "Programming Language :: Python", | ||||||
|  |         "Programming Language :: Python :: 3", | ||||||
|  |         "Programming Language :: Python :: 3.7", | ||||||
|  |         "Programming Language :: Python :: Implementation :: CPython", | ||||||
|  |         "Operating System :: OS Independent", | ||||||
|  |     ], | ||||||
|  |     include_package_data=True, | ||||||
|  |     zip_safe=False, | ||||||
|  | ) | ||||||
|  | @ -1,3 +0,0 @@ | ||||||
| pub mod common; |  | ||||||
| pub mod preprocess; |  | ||||||
| pub mod route; |  | ||||||
							
								
								
									
										28
									
								
								src/main.rs
									
										
									
									
									
								
							
							
						
						
									
										28
									
								
								src/main.rs
									
										
									
									
									
								
							|  | @ -1,28 +0,0 @@ | ||||||
| use ed_lrr::preprocess::{preprocess_files, PreprocessOpts}; |  | ||||||
| use ed_lrr::route::{route, RouteOpts}; |  | ||||||
| use humantime::format_duration; |  | ||||||
| use std::time::Instant; |  | ||||||
| use structopt::StructOpt; |  | ||||||
| #[derive(Debug, StructOpt)] |  | ||||||
| #[structopt(
 |  | ||||||
|     name = "ed_lrr", |  | ||||||
|     about = "Elite: Dangerous Long-Range Router", |  | ||||||
|     rename_all = "snake_case" |  | ||||||
| )] |  | ||||||
| enum Opts { |  | ||||||
|     /// Plots a route through multiple systems
 |  | ||||||
|     Route(RouteOpts), |  | ||||||
|     /// Preprocess EDSM Dump
 |  | ||||||
|     Preprocess(PreprocessOpts), |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn main() -> std::io::Result<()> { |  | ||||||
|     let t_start = Instant::now(); |  | ||||||
|     let opts = Opts::from_args(); |  | ||||||
|     let ret = match opts { |  | ||||||
|         Opts::Route(opts) => route(opts), |  | ||||||
|         Opts::Preprocess(opts) => preprocess_files(opts), |  | ||||||
|     }; |  | ||||||
|     println!("Total time: {}", format_duration(t_start.elapsed())); |  | ||||||
|     ret |  | ||||||
| } |  | ||||||
|  | @ -1,220 +0,0 @@ | ||||||
| use crate::common::SystemSerde; |  | ||||||
| use fnv::FnvHashMap; |  | ||||||
| use humantime::format_duration; |  | ||||||
| use indicatif::{ProgressBar, ProgressStyle}; |  | ||||||
| use serde::Deserialize; |  | ||||||
| use serde_json::Result; |  | ||||||
| use std::fs::File; |  | ||||||
| use std::io::Seek; |  | ||||||
| use std::io::{BufRead, BufReader, BufWriter, SeekFrom}; |  | ||||||
| use std::path::PathBuf; |  | ||||||
| use std::str; |  | ||||||
| use std::time::Instant; |  | ||||||
| use structopt::StructOpt; |  | ||||||
| 
 |  | ||||||
| #[derive(Debug, StructOpt)] |  | ||||||
| pub struct PreprocessOpts { |  | ||||||
|     #[structopt(short, long = "bodies")] |  | ||||||
|     /// Path to bodies.json
 |  | ||||||
|     pub bodies: PathBuf, |  | ||||||
|     #[structopt(short, long = "systems")] |  | ||||||
|     /// Path to systemsWithCoordinates.json
 |  | ||||||
|     pub systems: PathBuf, |  | ||||||
|     #[structopt(default_value = "stars")] |  | ||||||
|     /// outfile prefix
 |  | ||||||
|     pub prefix: String, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Debug, Deserialize)] |  | ||||||
| #[allow(non_snake_case)] |  | ||||||
| struct Body { |  | ||||||
|     name: String, |  | ||||||
|     subType: String, |  | ||||||
|     #[serde(rename = "type")] |  | ||||||
|     body_type: String, |  | ||||||
|     systemId: i32, |  | ||||||
|     systemId64: i64, |  | ||||||
|     #[serde(rename = "distanceToArrival")] |  | ||||||
|     distance: u32, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Debug, Deserialize)] |  | ||||||
| struct Coords { |  | ||||||
|     x: f32, |  | ||||||
|     y: f32, |  | ||||||
|     z: f32, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Debug, Deserialize)] |  | ||||||
| struct System { |  | ||||||
|     id: i32, |  | ||||||
|     id64: i64, |  | ||||||
|     name: String, |  | ||||||
|     coords: Coords, |  | ||||||
|     date: String, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| #[derive(Debug, StructOpt)] |  | ||||||
| #[structopt(
 |  | ||||||
|     name = "ed_lrr_pp", |  | ||||||
|     about = "Preprocessor for Elite: Dangerous Long-Range Router", |  | ||||||
|     rename_all = "snake_case" |  | ||||||
| )] |  | ||||||
| /// Preprocess data for ed_lrr
 |  | ||||||
| struct Opt { |  | ||||||
|     #[structopt(short, long = "bodies")] |  | ||||||
|     /// Path to bodies.json
 |  | ||||||
|     bodies: PathBuf, |  | ||||||
|     #[structopt(short, long = "systems")] |  | ||||||
|     /// Path to systemsWithCoordinates.json
 |  | ||||||
|     systems: PathBuf, |  | ||||||
|     #[structopt(default_value = "stars")] |  | ||||||
|     /// outfile prefix
 |  | ||||||
|     prefix: String, |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn get_mult(star_type: &str) -> f32 { |  | ||||||
|     if star_type.contains("White Dwarf") { |  | ||||||
|         return 1.5; |  | ||||||
|     } |  | ||||||
|     if star_type.contains("Neutron") { |  | ||||||
|         return 4.0; |  | ||||||
|     } |  | ||||||
|     1.0 |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn process(path: &PathBuf, func: &mut dyn for<'r> FnMut(&'r str) -> ()) -> std::io::Result<()> { |  | ||||||
|     let mut cnt = 0; |  | ||||||
|     let mut buffer = String::new(); |  | ||||||
|     let t_start = Instant::now(); |  | ||||||
|     let fh = File::open(path)?; |  | ||||||
|     let prog_bar = ProgressBar::new(fh.metadata()?.len()); |  | ||||||
|     prog_bar.set_style( |  | ||||||
|         ProgressStyle::default_bar() |  | ||||||
|             .template( |  | ||||||
|                 "[{elapsed_precise}/{eta_precise}]{spinner} [{wide_bar}] {binary_bytes}/{binary_total_bytes} ({percent}%)", |  | ||||||
|             ) |  | ||||||
|             .progress_chars("#9876543210 ") |  | ||||||
|             .tick_chars("/-\\|"), |  | ||||||
|     ); |  | ||||||
|     prog_bar.set_draw_delta(1024 * 1024); |  | ||||||
|     let mut reader = BufReader::new(fh); |  | ||||||
|     println!("Loading {} ...", path.to_str().unwrap()); |  | ||||||
|     while let Ok(n) = reader.read_line(&mut buffer) { |  | ||||||
|         if n == 0 { |  | ||||||
|             break; |  | ||||||
|         } |  | ||||||
|         buffer = buffer.trim_end().trim_end_matches(|c| c == ',').to_string(); |  | ||||||
|         if !buffer.is_empty() { |  | ||||||
|             func(&buffer); |  | ||||||
|         } |  | ||||||
|         prog_bar.set_position(reader.seek(SeekFrom::Current(0)).unwrap()); |  | ||||||
|         cnt += 1; |  | ||||||
|         buffer.clear(); |  | ||||||
|     } |  | ||||||
|     prog_bar.finish_and_clear(); |  | ||||||
|     println!( |  | ||||||
|         "Processed {} lines in {} ...", |  | ||||||
|         cnt, |  | ||||||
|         format_duration(t_start.elapsed()) |  | ||||||
|     ); |  | ||||||
|     Ok(()) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn process_systems(path: &PathBuf) -> FnvHashMap<i64, System> { |  | ||||||
|     let mut ret = FnvHashMap::default(); |  | ||||||
|     process(path, &mut |line| { |  | ||||||
|         let sys_res: Result<System> = serde_json::from_str(&line); |  | ||||||
|         if let Ok(sys) = sys_res { |  | ||||||
|             ret.insert(sys.id64, sys); |  | ||||||
|         } else { |  | ||||||
|             eprintln!("\nError parsing: {}\n\t{:?}\n", line, sys_res.unwrap_err()); |  | ||||||
|         } |  | ||||||
|     }) |  | ||||||
|     .unwrap(); |  | ||||||
|     ret |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn build_index(path: &PathBuf) -> std::io::Result<()> { |  | ||||||
|     let mut wtr = BufWriter::new(File::create(path.with_extension("idx"))?); |  | ||||||
|     let mut idx: Vec<u64> = Vec::new(); |  | ||||||
|     let mut records = (csv::Reader::from_path(path)?).into_deserialize::<SystemSerde>(); |  | ||||||
|     loop { |  | ||||||
|         idx.push(records.reader().position().byte()); |  | ||||||
|         if records.next().is_none() { |  | ||||||
|             break; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|     bincode::serialize_into(&mut wtr, &idx).unwrap(); |  | ||||||
|     Ok(()) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| fn process_bodies( |  | ||||||
|     path: &PathBuf, |  | ||||||
|     out_prefix: &str, |  | ||||||
|     systems: &mut FnvHashMap<i64, System>, |  | ||||||
| ) -> std::io::Result<()> { |  | ||||||
|     let out_path = PathBuf::from(format!("{}.csv", out_prefix)); |  | ||||||
|     println!( |  | ||||||
|         "Processing {} into {} ...", |  | ||||||
|         path.to_str().unwrap(), |  | ||||||
|         out_path.to_str().unwrap(), |  | ||||||
|     ); |  | ||||||
|     let mut n: u32 = 0; |  | ||||||
|     let mut wtr = csv::Writer::from_path(out_path)?; |  | ||||||
|     process(path, &mut |line| { |  | ||||||
|         if !line.contains("Star") { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|         let body_res: Result<Body> = serde_json::from_str(&line); |  | ||||||
|         if let Ok(body) = body_res { |  | ||||||
|             if !body.body_type.contains("Star") { |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|             if let Some(sys) = systems.get(&body.systemId64) { |  | ||||||
|                 let sub_type = body.subType; |  | ||||||
|                 let mult = get_mult(&sub_type); |  | ||||||
|                 let sys_name = sys.name.clone(); |  | ||||||
|                 let mut body_name = body.name.replace(&sys_name, "").trim().to_string(); |  | ||||||
|                 if body_name == sys_name { |  | ||||||
|                     body_name = "".to_string(); |  | ||||||
|                 } |  | ||||||
|                 let rec = SystemSerde { |  | ||||||
|                     id: n, |  | ||||||
|                     star_type: sub_type, |  | ||||||
|                     system: sys_name, |  | ||||||
|                     body: body_name, |  | ||||||
|                     mult, |  | ||||||
|                     distance: body.distance, |  | ||||||
|                     x: sys.coords.x, |  | ||||||
|                     y: sys.coords.y, |  | ||||||
|                     z: sys.coords.z, |  | ||||||
|                 }; |  | ||||||
|                 wtr.serialize(rec).unwrap(); |  | ||||||
|                 n += 1; |  | ||||||
|             }; |  | ||||||
|         } else { |  | ||||||
|             eprintln!("\nError parsing: {}\n\t{:?}\n", line, body_res.unwrap_err()); |  | ||||||
|         } |  | ||||||
|     }) |  | ||||||
|     .unwrap(); |  | ||||||
|     println!("Total Systems: {}", n); |  | ||||||
|     systems.clear(); |  | ||||||
|     Ok(()) |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| pub fn preprocess_files(opts: PreprocessOpts) -> std::io::Result<()> { |  | ||||||
|     let out_path = PathBuf::from(format!("{}.csv", &opts.prefix)); |  | ||||||
|     if !out_path.exists() { |  | ||||||
|         let mut systems = process_systems(&opts.systems); |  | ||||||
|         process_bodies(&opts.bodies, &opts.prefix, &mut systems)?; |  | ||||||
|     } else { |  | ||||||
|         println!( |  | ||||||
|             "File '{}' exists, not overwriting it", |  | ||||||
|             out_path.to_str().unwrap() |  | ||||||
|         ); |  | ||||||
|     } |  | ||||||
|     println!("Building index..."); |  | ||||||
|     println!("Index result: {:?}", build_index(&out_path)); |  | ||||||
|     Ok(()) |  | ||||||
| } |  | ||||||
							
								
								
									
										34
									
								
								tox.ini
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								tox.ini
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,34 @@ | ||||||
|  | [tox] | ||||||
|  | envlist = py35,py36,py37 | ||||||
|  | requires = tox-conda | ||||||
|  | 
 | ||||||
|  | [testenv] | ||||||
|  | description = Build ED_LRR | ||||||
|  | recreate = True | ||||||
|  | skip_install = True | ||||||
|  | skipsdist = True | ||||||
|  | deps = | ||||||
|  |     PyQt5 | ||||||
|  |     setuptools_rust | ||||||
|  | conda_deps =  | ||||||
|  |     pycrypto | ||||||
|  |     nuitka | ||||||
|  | passenv = | ||||||
|  |     CARGO_HOME | ||||||
|  |     RUSTUP_HOME | ||||||
|  |     INCLUDE | ||||||
|  |     LIB | ||||||
|  |     MSSdk | ||||||
|  |     DISTUTILS_USE_SDK | ||||||
|  | whitelist_externals = | ||||||
|  |     cargo | ||||||
|  |     iscc | ||||||
|  |     cmd | ||||||
|  | conda_channels = | ||||||
|  |     conda-forge | ||||||
|  | commands = | ||||||
|  |     python build_gui.py | ||||||
|  |     pip install . | ||||||
|  |     python -m nuitka --plugin-enable=multiprocessing --remove-output --plugin-enable=qt-plugins --standalone --assume-yes-for-downloads --follow-imports --output-dir=exe ed_lrr_gui\__main__.py | ||||||
|  |     cmd /c rename exe\__main__.dist\__main__.exe ED_LRR.exe | ||||||
|  |     iscc /F"ED_LRR_{envname}" /Qp installer/ED_LRR.iss | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue