├── .babelrc
├── .editorconfig
├── .gitattributes
├── .github
└── workflows
│ ├── build.yaml
│ └── codeql-analysis.yml
├── .gitignore
├── .prettierrc
├── .yarnclean
├── .yarnrc
├── BUILD.md
├── CHANGELOG.md
├── LICENSE.txt
├── README.md
├── TODO.md
├── craco.config.js
├── dev-app-update.yml
├── docs
├── .gitignore
├── 404.html
├── Gemfile
├── Gemfile.lock
├── _config.yml
├── _layouts
│ └── default.html
├── _sass
│ ├── additions.scss
│ ├── jekyll-theme-cayman.scss
│ └── variables.scss
├── assets
│ ├── css
│ │ └── style.scss
│ └── img
│ │ ├── icon_linux.svg
│ │ ├── icon_macos.svg
│ │ ├── icon_windows.svg
│ │ ├── raxmlgui_icon_256x256x32.png
│ │ └── screenshots
│ │ ├── basic.png
│ │ ├── basic2.png
│ │ ├── basic2_dark.png
│ │ ├── basic_dark.png
│ │ ├── console.png
│ │ ├── model.png
│ │ ├── parallel.png
│ │ ├── partition_editor.png
│ │ └── pipelines.png
├── favicon.ico
├── index.md
└── jekyll-theme-cayman
│ ├── .gitignore
│ ├── Gemfile
│ ├── LICENSE.txt
│ ├── README.md
│ ├── _layouts
│ ├── default.html
│ ├── page.html
│ └── post.html
│ └── jekyll-theme-cayman.gemspec
├── jsconfig.json
├── package.json
├── patches
└── electron-webpack+2.8.2.patch
├── public
├── disk-image.icns
├── entitlements.mac.inherit.plist
├── favicon.ico
├── icon.icns
├── icon.ico
├── index.html
└── manifest.json
├── scripts
├── download-binaries.js
└── notarize.js
├── sentry-symbols.js
├── src
├── app
│ ├── AlignmentCard.js
│ ├── App.css
│ ├── App.js
│ ├── App.test.js
│ ├── AstralTreeCard.js
│ ├── CitationModal.js
│ ├── Console.js
│ ├── Input.js
│ ├── Model.js
│ ├── Output.js
│ ├── PartitionEditor.js
│ ├── PartitionFileCard.js
│ ├── Raxml.js
│ ├── TreeCard.js
│ ├── bootstrap.js
│ ├── components
│ │ ├── CodeHighlight.js
│ │ ├── ErrorBoundary.js
│ │ ├── ErrorDialog.js
│ │ ├── ModifiedDialog.js
│ │ ├── OptionCheck.js
│ │ ├── OptionSelect.js
│ │ └── OptionTextField.js
│ ├── index.js
│ ├── jsconfig.json
│ ├── store
│ │ ├── Alignment.js
│ │ ├── AppStore.js
│ │ ├── AstralTree.js
│ │ ├── Citation.js
│ │ ├── Config.js
│ │ ├── InputFile.js
│ │ ├── Option.js
│ │ ├── Partition.js
│ │ ├── Run.js
│ │ ├── RunList.js
│ │ ├── StoreBase.js
│ │ └── index.js
│ └── theme
│ │ └── index.js
├── common
│ ├── errors.js
│ ├── fastaParser.js
│ ├── io.js
│ ├── phylipParser.js
│ ├── typecheckAlignment.js
│ └── utils.js
├── constants
│ └── ipc.js
├── electron.js
├── index.css
├── index.js
├── main
│ ├── api.js
│ ├── index.js
│ ├── menu
│ │ ├── index.js
│ │ ├── subMenuAnalysis.js
│ │ ├── subMenuDeveloper.js
│ │ └── subMenuFile.js
│ └── utils
│ │ ├── saveScreenshot.js
│ │ └── utils.js
├── registerServiceWorker.js
└── settings
│ ├── raxml.js
│ └── raxmlng.js
├── static
├── example-files
│ ├── astral
│ │ └── 1KP-genetrees.tre
│ ├── example_data_raxmlGUI.zip
│ ├── fasta
│ │ ├── aminoacid.txt
│ │ ├── bin1.txt
│ │ ├── bin2.txt
│ │ ├── binary.txt
│ │ ├── dna.txt
│ │ ├── mixed_data.txt
│ │ ├── multistate.txt
│ │ ├── nucleotide.txt
│ │ ├── partition_file.txt
│ │ └── test.fa
│ ├── nexus
│ │ ├── aminoacid.nex
│ │ └── nucleotide.nex
│ ├── phylip
│ │ ├── AA.txt
│ │ ├── align_allvariant.txt
│ │ ├── aminoacid.txt
│ │ ├── binary.txt
│ │ ├── dna_interleaved.txt
│ │ ├── dna_interleaved_relaxed.txt
│ │ ├── dna_sequential.txt
│ │ ├── dna_sequential_relaxed.txt
│ │ ├── mixed_data.txt
│ │ ├── multistate.txt
│ │ ├── nucleotide.txt
│ │ └── partition_file.txt
│ └── tree
│ │ ├── backboneConstraint
│ │ ├── backboneConstraint.txt
│ │ └── dna.phy
│ │ ├── fail
│ │ ├── align.fas
│ │ └── align.txt
│ │ ├── multifurcatingConstraint
│ │ ├── dna.phy
│ │ └── multifurcatingConstraint.txt
│ │ ├── success
│ │ ├── align.fas
│ │ └── align.txt
│ │ └── test.tre
├── test-files
│ ├── Primates.nex
│ ├── fail_bad_base_at_site.txt
│ ├── fail_bad_name.txt
│ ├── fail_different_types.fas
│ ├── fail_duplicate_taxon.fas
│ ├── fail_duplicate_taxon.phy
│ ├── fail_too_few_sequences_modeltest.txt
│ ├── fail_too_few_sequences_raxml.txt
│ ├── fail_unequal_sequence_length.fas
│ ├── fail_unequal_sequence_length.phy
│ ├── test_ambiguous_nucleotide.txt
│ ├── test_interleaved.txt
│ ├── test_invariant_sites.txt
│ ├── test_lower_case_bases.txt
│ ├── test_questionmark_nucleotide.txt
│ ├── wrong_site_count.txt
│ └── wrong_taxa_count.txt
└── test-results
│ └── ASTRAL_simulated_14taxon.gene.tre
├── webpack.config.js
└── yarn.lock
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/preset-env", {
5 | "targets": {
6 | "node": "current"
7 | }
8 | }
9 | ]
10 | ],
11 | "plugins": [
12 | ["@babel/plugin-proposal-decorators", { "legacy": true }],
13 | ["@babel/plugin-proposal-class-properties", { "loose": true }]
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: http://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | [*]
7 | end_of_line = lf
8 | indent_style = space
9 | indent_size = 2
10 | max_line_length = 120
11 | charset = utf-8
12 | trim_trailing_whitespace = true
13 | insert_final_newline = true
14 |
15 | [*.md]
16 | trim_trailing_whitespace = false
17 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text eol=lf
2 | *.png binary
3 | *.jpg binary
4 | *.jpeg binary
5 | *.ico binary
6 | *.icns binary
7 |
--------------------------------------------------------------------------------
/.github/workflows/build.yaml:
--------------------------------------------------------------------------------
1 | name: Build/release
2 |
3 | on: push
4 |
5 | jobs:
6 | release:
7 | runs-on: ${{ matrix.os }}
8 |
9 | strategy:
10 | matrix:
11 | os: [macos-latest, ubuntu-latest, windows-latest]
12 |
13 | steps:
14 | - name: Check out Git repository
15 | uses: actions/checkout@v2
16 |
17 | - name: Install Node.js, NPM and Yarn
18 | uses: actions/setup-node@v2
19 | with:
20 | node-version: 18
21 |
22 | - name: Install deps
23 | run: yarn
24 |
25 | - name: Download binaries
26 | run: npm run download-binaries
27 |
28 | - name: Build/release Electron app
29 | uses: samuelmeuli/action-electron-builder@v1
30 | with:
31 | # GitHub token, automatically provided to the action
32 | # (No need to define this secret in the repo settings)
33 | github_token: ${{ secrets.github_token }}
34 | mac_certs: ${{ secrets.mac_certs }}
35 | mac_certs_password: ${{ secrets.mac_certs_password }}
36 |
37 | # If the commit is tagged with a version (e.g. "v1.0.0"),
38 | # release the app after building
39 | release: ${{ startsWith(github.ref, 'refs/tags/v') }}
40 | env:
41 | # macOS notarization API key
42 | APPLEID: ${{ secrets.apple_id }}
43 | APPLEIDPASS: ${{ secrets.apple_id_pass }}
44 | APPLEIDTEAM: ${{ secrets.apple_id_team }}
45 | SENTRY_URL: ${{ secrets.sentry_url }}
46 | SENTRY_ORG: ${{ secrets.sentry_org }}
47 | SENTRY_PROJECT: ${{ secrets.sentry_project }}
48 | SENTRY_AUTH_TOKEN: ${{ secrets.sentry_auth_token }}
49 |
--------------------------------------------------------------------------------
/.github/workflows/codeql-analysis.yml:
--------------------------------------------------------------------------------
1 | # For most projects, this workflow file will not need changing; you simply need
2 | # to commit it to your repository.
3 | #
4 | # You may wish to alter this file to override the set of languages analyzed,
5 | # or to provide custom queries or build logic.
6 | #
7 | # ******** NOTE ********
8 | # We have attempted to detect the languages in your repository. Please check
9 | # the `language` matrix defined below to confirm you have the correct set of
10 | # supported CodeQL languages.
11 | #
12 | name: "CodeQL"
13 |
14 | on:
15 | push:
16 | branches: [ master ]
17 | pull_request:
18 | # The branches below must be a subset of the branches above
19 | branches: [ master ]
20 | schedule:
21 | - cron: '20 1 * * 4'
22 |
23 | jobs:
24 | analyze:
25 | name: Analyze
26 | runs-on: ubuntu-latest
27 | permissions:
28 | actions: read
29 | contents: read
30 | security-events: write
31 |
32 | strategy:
33 | fail-fast: false
34 | matrix:
35 | language: [ 'javascript' ]
36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ]
37 | # Learn more:
38 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed
39 |
40 | steps:
41 | - name: Checkout repository
42 | uses: actions/checkout@v2
43 |
44 | # Initializes the CodeQL tools for scanning.
45 | - name: Initialize CodeQL
46 | uses: github/codeql-action/init@v1
47 | with:
48 | languages: ${{ matrix.language }}
49 | # If you wish to specify custom queries, you can do so here or in a config file.
50 | # By default, queries listed here will override any specified in a config file.
51 | # Prefix the list here with "+" to use these queries and those in the config file.
52 | # queries: ./path/to/local/query, your-org/your-repo/queries@main
53 |
54 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
55 | # If this step fails, then you should remove it and run the build manually (see below)
56 | - name: Autobuild
57 | uses: github/codeql-action/autobuild@v1
58 |
59 | # ℹ️ Command-line programs to run using the OS shell.
60 | # 📚 https://git.io/JvXDl
61 |
62 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines
63 | # and modify them (or add more) to build your code if your project
64 | # uses a compiled language
65 |
66 | #- run: |
67 | # make bootstrap
68 | # make release
69 |
70 | - name: Perform CodeQL Analysis
71 | uses: github/codeql-action/analyze@v1
72 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 | /dist
12 | /release
13 |
14 | # misc
15 | .DS_Store
16 |
17 | # package manager
18 | npm-debug.log*
19 | yarn-debug.log*
20 | yarn-error.log*
21 | .yarn
22 | .yarnrc.yml
23 |
24 | # external dependencies
25 | /static/bin
26 |
27 | # output
28 | RAxML_*
29 | *.raxml.*
30 | *.reduced
31 | *_concat.*
32 |
33 | # environment
34 | sentry.properties
35 | .env
36 | .env.local
37 | .env.development.local
38 | .env.test.local
39 | .env.production.local
40 | .env
41 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "overrides": [
3 | {
4 | "files": [".prettierrc", ".babelrc", ".eslintrc", ".stylelintrc"],
5 | "options": {
6 | "parser": "json"
7 | }
8 | }
9 | ],
10 | "singleQuote": true,
11 | "printWidth": 80,
12 | "tabWidth": 2,
13 | "useTabs": false,
14 | "semi": true,
15 | "bracketSpacing": true,
16 | "jsxBracketSameLine": false
17 | }
18 |
--------------------------------------------------------------------------------
/.yarnclean:
--------------------------------------------------------------------------------
1 | # test directories
2 | __tests__
3 | test
4 | tests
5 | powered-test
6 |
7 | # asset directories
8 | docs
9 | doc
10 | website
11 | images
12 | assets
13 |
14 | # examples
15 | example
16 | examples
17 |
18 | # code coverage directories
19 | coverage
20 | .nyc_output
21 |
22 | # build scripts
23 | Makefile
24 | Gulpfile.js
25 | Gruntfile.js
26 |
27 | # configs
28 | appveyor.yml
29 | circle.yml
30 | codeship-services.yml
31 | codeship-steps.yml
32 | wercker.yml
33 | .tern-project
34 | .gitattributes
35 | .editorconfig
36 | .*ignore
37 | .eslintrc
38 | .jshintrc
39 | .flowconfig
40 | .documentup.json
41 | .yarn-metadata.json
42 | .travis.yml
43 |
44 | # misc
45 | LICENSE
46 | LICENSE.txt
47 | CONTRIBUTING
48 | AUTHORS
49 | *.md
50 | *.jpg
51 |
--------------------------------------------------------------------------------
/.yarnrc:
--------------------------------------------------------------------------------
1 | network-timeout 120000
2 |
--------------------------------------------------------------------------------
/BUILD.md:
--------------------------------------------------------------------------------
1 | # Building
2 |
3 | ## App
4 | ### Before pushing
5 | * Check if there are any warnings in the console. Those will be treated as errors in the CI environment.
6 |
7 | ### Recommended GitHub Releases Workflow¶
8 | From [electron.build publish](https://www.electron.build/configuration/publish#recommended-github-releases-workflow)
9 |
10 | 1. Draft a new release. Set the “Tag version” to the value of version in your application package.json, and prefix it with v. “Release title” can be anything you want.
11 | 2. For example, if your application package.json version is 1.2.3, your draft’s “Tag version” would be v1.2.3.
12 | 3. Push some commits. Every CI build will update the artifacts attached to this draft.
13 | 4. Once you are done, publish the release. GitHub will tag the latest commit for you.
14 | The benefit of this workflow is that it allows you to always have the latest artifacts, and the release can be published once it is ready.
15 | 5. Update CHANGELOG and the download links in `docs/_layouts/default.html` to the new version.
16 | 5. Bump the version in package.json to use for the next draft and push to update the download links on the github page.
17 | 6. Uploading Debug Information
18 | To get symbolicated stack traces for native crashes, you have to upload debug symbols to Sentry. Sentry Wizard creates a convenient sentry-symbols.js script that will upload the Electron symbols for you. After installing the SDK and every time you upgrade the Electron version, run this script:
19 |
20 | ## Homepage
21 |
22 | Build steps for local development
23 |
24 | ## Prerequisites
25 | Install ruby 2.4 or higher
26 |
27 | Run
28 | ```
29 | gem install jekyll bundler
30 | ```
31 |
32 | In docs folder, run
33 | ```
34 | bundle install
35 | ```
36 |
37 | ## Local serve
38 |
39 | Run npm script `docs-serve` or in docs folder run
40 | ```
41 | bundle exec jekyll serve
42 | ```
43 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 | All notable changes to this project will be documented in this file.
3 |
4 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
5 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6 |
7 | Types of changes
8 | ### Added
9 | for new features.
10 | ### Changed
11 | for changes in existing functionality.
12 | ### Deprecated
13 | for soon-to-be removed features.
14 | ### Removed
15 | for now removed features.
16 | ### Fixed
17 | for any bug fixes.
18 | ### Security
19 | in case of vulnerabilities.
20 |
21 | ## [Unreleased] - YYYY-MM-DD
22 | ### Added
23 | - Added support for species tree from gene trees inference using ASTRAL
24 |
25 | ## [2.0.15] - 2025-04-14
26 | ### Changed
27 | - Performance and security updates
28 | ### Fixed
29 | - Error when dragging and dropping alignments in the app
30 | ## [2.0.14] - 2025-02-28
31 | ### Changed
32 | - Performance and security updates
33 | ### Removed
34 | - Dropping macOS 10.13 / 10.14 support
35 | ## [2.0.13] - 2024-09-29
36 | ### Changed
37 | - Performance and security updates
38 | ### Removed
39 | - Dropping Windows 7/8/8.1 Support
40 | ## [2.0.12] - 2024-09-29
41 | ### Changed
42 | - Performance and security updates
43 | ## [2.0.11] - 2024-09-28
44 | ### Changed
45 | - Updated to include the latest binaries for raxml-ng on Mac and Linux (1.2.2).
46 | ## [2.0.10] - 2022-09-13
47 | ### Changed
48 | - Performance and security updates
49 | ## [2.0.9] - 2022-06-30
50 | ### Added
51 | - Added substantially more logging in case an error occurrs
52 | ### Changed
53 | - Some maintenance and smaller UI updates
54 | ### Removed
55 | - Removed ModelTest from Windows 7 and lower
56 | ### Fixed
57 | - Fixed problems using RAxML and ModelTest with Mac M1 laptops
58 | ## [2.0.8] - 2022-05-09
59 | ### Changed
60 | - Updated example files
61 | ### Fixed
62 | - Left aligned Run buttom to always be visible
63 | - Made substitution model options available also on selecting GTRCAT for raxml 8.x
64 | - Added GAMMA to non-GTR model labels for raxml 8.x
65 | ## [2.0.7] - 2022-02-22
66 | ### Changed
67 | - Updated to include the latest binaries for raxml-ng on Mac and Linux (1.1.0).
68 | - Allow copy RAxML command
69 | ### Fixed
70 | - Fixed Linux issue running raxml-ng binaries
71 |
72 | ## [2.0.6] - 2021-10-05
73 | ### Changed
74 | - Updated to include the latest binaries for raxml-ng on Mac and Linux (1.0.3).
75 | - Updated to include the latest binaries for RAxML on Windows 8 and 10 (8.2.12).
76 | - A bit of restyling.
77 | ### Fixed
78 | - Fixed a bug that only one error could be reported.
79 | - Fixed a bug in outgroup selection.
80 |
81 | ## [2.0.5] - 2021-05-09
82 | ### Added
83 | - Using RAxML 8 you can now select these substitution models for nucleotide data as well: JC69, K80, HKY85.
84 | - ModelTest will also recognize these models if they are the best fit.
85 | ### Fixed
86 | - Fixed an error when restarting the app after an update.
87 |
88 | ## [2.0.4] - 2021-04-22
89 | ### Fixed
90 | - Fixed a crash with ModelTest-NG on Windows.
91 |
92 | ## [2.0.3] - 2021-04-14
93 | ### Added
94 | - Modeltest-NG is now also available on Windows (Tested on Windows 10 only).
95 | ### Fixed
96 | - Fixed some smaller styling issues.
97 |
98 | ## [2.0.2] - 2021-03-29
99 | ### Added
100 | - Display more detailed information when an input alignment has been modified.
101 | - Allow completely unknown binary sequences.
102 | ### Fixed
103 | - Small bugfix: Remove "null" showing up in SnackBar text
104 |
105 | ## [2.0.1] - 2021-03-04
106 | ### Added
107 | - Some common errors in alignments will be automatically fixed when loading an alignment. This includes, replacing illegal characters with underscores in taxon names, disambiguating duplicated taxon names, shortening taxon names that are too long.
108 | ### Changed
109 | - Updated to include the latest binaries for raxml-ng on Mac and Linux (1.0.1).
110 | ### Fixed
111 | - Now correctly recognizes ? and N in nucleotide sequences.
112 | - Fixed a small bug that showed output files that are not a result of the actual analysis.
113 | - Added the correct citation for the release paper.
114 | - Fixed a bug where selecting the output dir would lead to the change in all tabs.
115 | - Fixed a bug where adding an alignment would add it in all tabs.
116 | - Fixed a crash when running ModelTest-NG on binary or multistate alignments.
117 | - Fixed a crash when the input alignment did not exist when starting a run.
118 | - Fixed a bug that deleted last parts of a taxon names with whitespaces.
119 |
120 | ## [2.0.0] - 2017-06-20
121 |
122 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # RaxmlGUI2
2 |
3 | A desktop GUI for RAxML.
4 |
5 | ## Development
6 |
7 | This is a an [Electron](https://electronjs.org/) App that was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
8 |
9 | ```yarn start``` will start the Electron app and the React app at the same time.
10 | ```yarn build``` will build the React app and package it along the Electron app.
11 |
12 |
13 | ## Input formats
14 | RaxmlGUI supports both FASTA and PHYLIP format.
15 |
16 | The strict phylip format reserves the first ten characters before each sequence for the name.
17 | The relaxed format allows longer name but requires no space within the name to know where it ends.
18 |
19 | ### Examples
20 |
21 | #### Phylip interleaved strict
22 | ```
23 | 5 42
24 | Turkey AAGCTNGGGC ATTTCAGGGT
25 | Salmo gairAAGCCTTGGC AGTGCAGGGT
26 | H. SapiensACCGGTTGGC CGTTCAGGGT
27 | Chimp AAACCCTTGC CGTTACGCTT
28 | Gorilla AAACCCTTGC CGGTACGCTT
29 |
30 | GAGCCCGGGC AATACAGGGT AT
31 | GAGCCGTGGC CGGGCACGGT AT
32 | ACAGGTTGGC CGTTCAGGGT AA
33 | AAACCGAGGC CGGGACACTC AT
34 | AAACCATTGC CGGTACGCTT AA
35 | ```
36 |
37 | #### Phylip interleaved relaxed
38 | ```
39 | 5 42
40 | Turkey AAGCTNGGGC ATTTCAGGGT
41 | Salmo_gair AAGCCTTGGC AGTGCAGGGT
42 | H._Sapiens ACCGGTTGGC CGTTCAGGGT
43 | Chimp AAACCCTTGC CGTTACGCTT
44 | Gorilla AAACCCTTGC CGGTACGCTT
45 |
46 | GAGCCCGGGC AATACAGGGT AT
47 | GAGCCGTGGC CGGGCACGGT AT
48 | ACAGGTTGGC CGTTCAGGGT AA
49 | AAACCGAGGC CGGGACACTC AT
50 | AAACCATTGC CGGTACGCTT AA
51 | ```
52 |
53 | #### Phylip sequential strict
54 | ```
55 | 5 42
56 | Turkey AAGCTNGGGC ATTTCAGGGT
57 | GAGCCCGGGC AATACAGGGT AT
58 | Salmo gairAAGCCTTGGC AGTGCAGGGT
59 | GAGCCGTGGC CGGGCACGGT AT
60 | H. SapiensACCGGTTGGC CGTTCAGGGT
61 | ACAGGTTGGC CGTTCAGGGT AA
62 | Chimp AAACCCTTGC CGTTACGCTT
63 | AAACCGAGGC CGGGACACTC AT
64 | Gorilla AAACCCTTGC CGGTACGCTT
65 | AAACCATTGC CGGTACGCTT AA
66 | ```
67 |
68 | #### Phylip sequential relaxed
69 | ```
70 | 5 42
71 | Turkey AAGCTNGGGC ATTTCAGGGT
72 | GAGCCCGGGC AATACAGGGT AT
73 | Salmo_gair AAGCCTTGGC AGTGCAGGGT
74 | GAGCCGTGGC CGGGCACGGT AT
75 | H._Sapiens ACCGGTTGGC CGTTCAGGGT
76 | ACAGGTTGGC CGTTCAGGGT AA
77 | Chimp AAACCCTTGC CGTTACGCTT
78 | AAACCGAGGC CGGGACACTC AT
79 | Gorilla AAACCCTTGC CGGTACGCTT
80 | AAACCATTGC CGGTACGCTT AA
81 | ```
82 |
83 | #### MacOS code-signing and notarizing
84 | https://medium.com/@TwitterArchiveEraser/notarize-electron-apps-7a5f988406db
85 | https://github.com/electron/electron-notarize
86 | https://stackoverflow.com/questions/53112078/how-to-upload-dmg-file-for-notarization-in-xcode/53121755#53121755
87 |
88 | #### Publishing with electron-builder
89 | Need to have a GH_TOKEN in your shell env
90 |
91 | #### Binaries
92 | The binaries for RAxML on MacOS were compiled from this repository: https://github.com/jtklein/standard-RAxML
93 |
94 |
--------------------------------------------------------------------------------
/TODO.md:
--------------------------------------------------------------------------------
1 | Todo:
2 | - Github page for downloading the latest release
3 | - Choose light or dark theme
4 | - Option for empirical frequencies?
5 | - In the Output section, add collapsable list of output files with descriptions
6 | - Option to remove existing files (shell.moveItemToTrash(fullPath))
7 | - Spinning wheel while running to distinguishing it from getting stuck
8 | - Fix parsing a relaxed phylip as strict
9 | - Don't make multithreaded binaries available if num cpus is one.
10 | - Implement auto-updating/checking mechanism.
11 | - Create publish script
12 |
--------------------------------------------------------------------------------
/craco.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | babel: {
3 | plugins: [
4 | ["@babel/plugin-proposal-decorators", { legacy: true }],
5 | ["@babel/plugin-proposal-class-properties", { loose: true }]
6 | ]
7 | },
8 | webpack: {
9 | configure: {
10 | target: 'electron-renderer'
11 | }
12 | }
13 | };
14 |
--------------------------------------------------------------------------------
/dev-app-update.yml:
--------------------------------------------------------------------------------
1 | owner: AntonelliLab
2 | repo: raxmlGUI
3 | provider: github
4 |
--------------------------------------------------------------------------------
/docs/.gitignore:
--------------------------------------------------------------------------------
1 | _site
2 | .sass-cache
3 | .jekyll-metadata
4 |
--------------------------------------------------------------------------------
/docs/404.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | ---
4 |
5 |
18 |
19 |
20 |
404
21 |
22 |
Page not found :(
23 |
The requested page could not be found.
24 |
25 |
--------------------------------------------------------------------------------
/docs/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | # Hello! This is where you manage which Jekyll version is used to run.
4 | # When you want to use a different version, change it below, save the
5 | # file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
6 | #
7 | # bundle exec jekyll serve
8 | #
9 | # This will help ensure the proper Jekyll version is running.
10 | # Happy Jekylling!
11 | gem "jekyll", "~> 3.9.0"
12 |
13 | # This is the default theme for new Jekyll sites. You may change this to anything you like.
14 | # gem "minima", "~> 2.0"
15 | gem "jekyll-theme-cayman"
16 |
17 | # If you want to use GitHub Pages, remove the "gem "jekyll"" above and
18 | # uncomment the line below. To upgrade, run `bundle update github-pages`.
19 | # gem "github-pages", group: :jekyll_plugins
20 |
21 | # If you have any plugins, put them here!
22 | group :jekyll_plugins do
23 | gem "jekyll-feed", "~> 0.6"
24 | end
25 |
26 | # Windows does not include zoneinfo files, so bundle the tzinfo-data gem
27 | # and associated library.
28 | install_if -> { RUBY_PLATFORM =~ %r!mingw|mswin|java! } do
29 | gem "tzinfo", "~> 1.2"
30 | gem "tzinfo-data"
31 | end
32 |
33 | # Performance-booster for watching directories on Windows
34 | gem "wdm", "~> 0.1.0", :install_if => Gem.win_platform?
35 |
36 | # kramdown v2 ships without the gfm parser by default. If you're using
37 | # kramdown v1, comment out this line.
38 | gem "kramdown-parser-gfm"
39 |
40 | # To preview as github page
41 | gem "github-pages", group: :jekyll_plugins
42 |
--------------------------------------------------------------------------------
/docs/_config.yml:
--------------------------------------------------------------------------------
1 | # Welcome to Jekyll!
2 | #
3 | # This config file is meant for settings that affect your whole blog, values
4 | # which you are expected to set up once and rarely edit after that. If you find
5 | # yourself editing this file very often, consider using Jekyll's data files
6 | # feature for the data you need to update frequently.
7 | #
8 | # For technical reasons, this file is *NOT* reloaded automatically when you use
9 | # 'bundle exec jekyll serve'. If you change this file, please restart the server process.
10 |
11 | # Site settings
12 | # These are used to personalize your new site. If you look in the HTML files,
13 | # you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.
14 | # You can create any custom variable you would like, and they will be accessible
15 | # in the templates via {{ site.myvariable }}.
16 | title: raxmlGUI 2.0
17 | #email: your-email@example.com
18 | description: >- # this means to ignore newlines until "baseurl:"
19 | raxmlGUI 2.0 - a new user-friendly program integrating RAxML-NG
20 | and ModelTest-NG for cutting-edge phylogenetic analysis
21 | baseurl: 'raxmlGUI' # the subpath of your site, e.g. /blog
22 | url: '' # the base hostname & protocol for your site, e.g. http://example.com
23 | twitter_username: jekyllrb
24 | github_username: jekyll
25 |
26 | # Build settings
27 | markdown: kramdown
28 | theme: jekyll-theme-cayman
29 | plugins:
30 | - jekyll-feed
31 |
32 | # Exclude from processing.
33 | # The following items will not be processed, by default. Create a custom list
34 | # to override the default setting.
35 | # exclude:
36 | # - Gemfile
37 | # - Gemfile.lock
38 | # - node_modules
39 | # - vendor/bundle/
40 | # - vendor/cache/
41 | # - vendor/gems/
42 | # - vendor/ruby/
43 |
44 | show_downloads: true
45 | show_view_on_github: false
46 | google_analytics: UA-149851800-1
47 |
48 | github: [metadata]
49 |
--------------------------------------------------------------------------------
/docs/_sass/additions.scss:
--------------------------------------------------------------------------------
1 | /* Style the collapsible content. Note: hidden by default */
2 | .collapsibleContent {
3 | padding: 0 18px;
4 | display: none;
5 | overflow: hidden;
6 | }
7 |
8 | .basic-section {
9 | position:relative;
10 | padding-top:2.5rem;
11 | padding-bottom:0;
12 | background-color:#edeef0;
13 | }
14 |
15 | .basic-container {
16 | position:relative;
17 | max-width:1248px;
18 | margin-right:auto;
19 | margin-left:auto;
20 | padding:2rem 2.625rem 2.5rem;
21 | padding-right:.75rem;
22 | padding-left:.75rem;
23 | text-align:center;
24 | padding-bottom:0;
25 | overflow:hidden;
26 | }
27 |
28 | .basic-title {
29 | position:relative;
30 | display:-webkit-box;
31 | display:-webkit-flex;
32 | display:-ms-flexbox;
33 | display:flex;
34 | margin-top:2rem;
35 | margin-bottom:2rem;
36 | -webkit-box-orient:vertical;
37 | -webkit-box-direction:normal;
38 | -webkit-flex-direction:column;
39 | -ms-flex-direction:column;
40 | flex-direction:column;
41 | -webkit-box-pack:start;
42 | -webkit-justify-content:flex-start;
43 | -ms-flex-pack:start;
44 | justify-content:flex-start;
45 | -webkit-box-align:center;
46 | -webkit-align-items:center;
47 | -ms-flex-align:center;
48 | align-items:center;
49 | text-align:center;
50 | }
51 |
52 | .basic-info {
53 | font-size:1rem;
54 | line-height:1.35em;
55 | font-weight:500;
56 | letter-spacing:-.01875rem;
57 | }
58 |
59 | .basic-screenshot-container {
60 | position:relative;
61 | height:41rem;
62 | max-height:100%;
63 | max-width:100%;
64 | }
65 |
66 | .basic-screenshot {
67 | left:0;
68 | top:0;
69 | overflow:hidden;
70 | border:.25rem solid #eee;
71 | border-radius:1.3rem;
72 | background-color:#eee;
73 | -o-object-fit:contain;
74 | object-fit:contain;
75 | vertical-align: middle;
76 | display: inline-block;
77 | max-width: 100%;
78 | position: absolute;
79 | z-index: 1;
80 | border-color: #eee;
81 | opacity: 0;
82 | }
83 |
84 | .basic-screenshot.active {
85 | opacity: 1;
86 | transition: opacity 0.5s ease-in-out;
87 | }
88 |
89 | .features-section {
90 | position:relative;
91 | padding-top:2.5rem;
92 | padding-bottom:0;
93 | background-color:#141415;
94 | }
95 |
96 | .features-container {
97 | position:relative;
98 | max-width:1248px;
99 | margin-right:auto;
100 | margin-left:auto;
101 | padding:2rem 2.625rem 2.5rem;
102 | padding-right:.75rem;
103 | padding-left:.75rem;
104 | text-align:center;
105 | align-items: stretch;
106 | }
107 |
108 | .features-title {
109 | position:relative;
110 | display:-webkit-box;
111 | display:-webkit-flex;
112 | display:-ms-flexbox;
113 | display:flex;
114 | margin-top:2rem;
115 | margin-bottom:2rem;
116 | -webkit-box-orient:vertical;
117 | -webkit-box-direction:normal;
118 | -webkit-flex-direction:column;
119 | -ms-flex-direction:column;
120 | flex-direction:column;
121 | -webkit-box-pack:start;
122 | -webkit-justify-content:flex-start;
123 | -ms-flex-pack:start;
124 | justify-content:flex-start;
125 | -webkit-box-align:center;
126 | -webkit-align-items:center;
127 | -ms-flex-align:center;
128 | align-items:center;
129 | text-align:center;
130 | color:#fafafa;
131 | }
132 |
133 | .features-info {
134 | font-size:1rem;
135 | line-height:1.35em;
136 | font-weight:500;
137 | letter-spacing:-.01875rem;
138 | color:#707070;
139 | }
140 |
141 | .feature {
142 | z-index:1;
143 | width:100%;
144 | padding:1rem;
145 | text-align:left;
146 | float:none;
147 | }
148 |
149 | .feature-grid {
150 | display:-ms-grid;
151 | display:grid;
152 | grid-column-gap:1rem;
153 | grid-row-gap:1rem;
154 | grid-template-areas:".";
155 | margin-bottom:2rem;
156 | }
157 |
158 | @media (min-width: 600px) {
159 | .feature-grid { grid-template-columns: repeat(2, 1fr); }
160 | }
161 |
162 | @media (min-width: 600px) {
163 | .feature-reversed {
164 | grid-column: 1;
165 | grid-row: 1;
166 | }
167 | }
168 |
169 | .feature-image img {
170 | height:auto;
171 | max-width:100%;
172 | vertical-align:top;
173 | }
174 |
175 | .feature-figure {
176 | display:inline-block;
177 | vertical-align:top;
178 | margin:0;
179 | max-width:100%;
180 | }
181 |
182 | .feature-header {
183 | font-size:1.5rem;
184 | line-height:1.3em;
185 | font-weight:500;
186 | letter-spacing:-.0375rem;
187 | margin-bottom:.6875rem;
188 | color:#fafafa;
189 | }
190 |
191 | .feature-info {
192 | font-size:1rem;
193 | line-height:1.35em;
194 | font-weight:500;
195 | letter-spacing:-.01875rem;
196 | margin-bottom:2rem;
197 | opacity:1;
198 | color:#707070;
199 | }
200 |
--------------------------------------------------------------------------------
/docs/_sass/jekyll-theme-cayman.scss:
--------------------------------------------------------------------------------
1 | @import "normalize";
2 | @import "rouge-github";
3 | @import "variables";
4 | @import "additions";
5 | @import url('https://fonts.googleapis.com/css?family=Open+Sans:400,700');
6 |
7 | @mixin large {
8 | @media screen and (min-width: #{$large-breakpoint}) {
9 | @content;
10 | }
11 | }
12 |
13 | @mixin medium {
14 | @media screen and (min-width: #{$medium-breakpoint}) and (max-width: #{$large-breakpoint}) {
15 | @content;
16 | }
17 | }
18 |
19 | @mixin small {
20 | @media screen and (max-width: #{$medium-breakpoint}) {
21 | @content;
22 | }
23 | }
24 |
25 | * {
26 | box-sizing: border-box;
27 | }
28 |
29 | body {
30 | padding: 0;
31 | margin: 0;
32 | font-family: "Open Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
33 | font-size: 16px;
34 | line-height: 1.5;
35 | color: $body-text-color;
36 | }
37 |
38 | a {
39 | color: $body-link-color;
40 | text-decoration: none;
41 |
42 | &:hover {
43 | text-decoration: underline;
44 | }
45 | }
46 |
47 | .btn {
48 | display: inline-block;
49 | margin-bottom: 1rem;
50 | color: rgba(255, 255, 255, 0.7);
51 | background-color: rgba(255, 255, 255, 0.08);
52 | border-color: rgba(255, 255, 255, 0.2);
53 | border-style: solid;
54 | border-width: 1px;
55 | border-radius: 0.3rem;
56 | transition: color 0.2s, background-color 0.2s, border-color 0.2s;
57 |
58 | &:hover {
59 | color: rgba(255, 255, 255, 0.8);
60 | text-decoration: none;
61 | background-color: rgba(255, 255, 255, 0.2);
62 | border-color: rgba(255, 255, 255, 0.3);
63 | }
64 |
65 | + .btn {
66 | margin-left: 1rem;
67 | }
68 |
69 | @include large {
70 | padding: 0.75rem 1rem;
71 | }
72 |
73 | @include medium {
74 | padding: 0.6rem 0.9rem;
75 | font-size: 0.9rem;
76 | }
77 |
78 | @include small {
79 | display: block;
80 | width: 100%;
81 | padding: 0.75rem;
82 | font-size: 0.9rem;
83 |
84 | + .btn {
85 | margin-top: 1rem;
86 | margin-left: 0;
87 | }
88 | }
89 | }
90 |
91 | .page-header {
92 | color: $header-heading-color;
93 | text-align: center;
94 | background-color: $header-bg-color;
95 | background-image: linear-gradient(120deg, $header-bg-color-secondary, $header-bg-color);
96 | // background-image: linear-gradient(120deg, $header-bg-color-secondary, $header-bg-color-middle, $header-bg-color);
97 | // background-image: linear-gradient(120deg, $header-bg-color-secondary, $header-bg-color-middle 40%, $header-bg-color 70%);
98 |
99 | @include large {
100 | padding: 5rem 6rem;
101 | }
102 |
103 | @include medium {
104 | padding: 3rem 4rem;
105 | }
106 |
107 | @include small {
108 | padding: 2rem 1rem;
109 | }
110 | }
111 |
112 | .project-name {
113 | margin-top: 0;
114 | margin-bottom: 0.1rem;
115 |
116 | @include large {
117 | font-size: 3.25rem;
118 | }
119 |
120 | @include medium {
121 | font-size: 2.25rem;
122 | }
123 |
124 | @include small {
125 | font-size: 1.75rem;
126 | }
127 | }
128 |
129 | .project-tagline {
130 | margin-bottom: 2rem;
131 | font-weight: normal;
132 | opacity: 0.7;
133 |
134 | @include large {
135 | font-size: 1.25rem;
136 | }
137 |
138 | @include medium {
139 | font-size: 1.15rem;
140 | }
141 |
142 | @include small {
143 | font-size: 1rem;
144 | }
145 | }
146 |
147 | .main-content {
148 | word-wrap: break-word;
149 |
150 | :first-child {
151 | margin-top: 0;
152 | }
153 |
154 | @include large {
155 | max-width: 64rem;
156 | padding: 2rem 6rem;
157 | margin: 0 auto;
158 | font-size: 1.1rem;
159 | }
160 |
161 | @include medium {
162 | padding: 2rem 4rem;
163 | font-size: 1.1rem;
164 | }
165 |
166 | @include small {
167 | padding: 2rem 1rem;
168 | font-size: 1rem;
169 | }
170 |
171 | img {
172 | max-width: 100%;
173 | }
174 |
175 | h1,
176 | h2,
177 | h3,
178 | h4,
179 | h5,
180 | h6 {
181 | margin-top: 2rem;
182 | margin-bottom: 1rem;
183 | font-weight: normal;
184 | color: $section-headings-color;
185 | }
186 |
187 | p {
188 | margin-bottom: 1em;
189 | }
190 |
191 | code {
192 | padding: 2px 4px;
193 | font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
194 | font-size: 0.9rem;
195 | color: $code-text-color;
196 | background-color: $code-bg-color;
197 | border-radius: 0.3rem;
198 | }
199 |
200 | pre {
201 | padding: 0.8rem;
202 | margin-top: 0;
203 | margin-bottom: 1rem;
204 | font: 1rem Consolas, "Liberation Mono", Menlo, Courier, monospace;
205 | color: $code-text-color;
206 | word-wrap: normal;
207 | background-color: $code-bg-color;
208 | border: solid 1px $border-color;
209 | border-radius: 0.3rem;
210 |
211 | > code {
212 | padding: 0;
213 | margin: 0;
214 | font-size: 0.9rem;
215 | color: $code-text-color;
216 | word-break: normal;
217 | white-space: pre;
218 | background: transparent;
219 | border: 0;
220 | }
221 | }
222 |
223 | .highlight {
224 | margin-bottom: 1rem;
225 |
226 | pre {
227 | margin-bottom: 0;
228 | word-break: normal;
229 | }
230 | }
231 |
232 | .highlight pre,
233 | pre {
234 | padding: 0.8rem;
235 | overflow: auto;
236 | font-size: 0.9rem;
237 | line-height: 1.45;
238 | border-radius: 0.3rem;
239 | -webkit-overflow-scrolling: touch;
240 | }
241 |
242 | pre code,
243 | pre tt {
244 | display: inline;
245 | max-width: initial;
246 | padding: 0;
247 | margin: 0;
248 | overflow: initial;
249 | line-height: inherit;
250 | word-wrap: normal;
251 | background-color: transparent;
252 | border: 0;
253 |
254 | &:before,
255 | &:after {
256 | content: normal;
257 | }
258 | }
259 |
260 | ul,
261 | ol {
262 | margin-top: 0;
263 | }
264 |
265 | blockquote {
266 | padding: 0 1rem;
267 | margin-left: 0;
268 | color: $blockquote-text-color;
269 | border-left: 0.3rem solid $border-color;
270 |
271 | > :first-child {
272 | margin-top: 0;
273 | }
274 |
275 | > :last-child {
276 | margin-bottom: 0;
277 | }
278 | }
279 |
280 | table {
281 | display: block;
282 | width: 100%;
283 | overflow: auto;
284 | word-break: normal;
285 | word-break: keep-all; // For Firefox to horizontally scroll wider tables.
286 | -webkit-overflow-scrolling: touch;
287 |
288 | th {
289 | font-weight: bold;
290 | }
291 |
292 | th,
293 | td {
294 | padding: 0.5rem 1rem;
295 | border: 1px solid $table-border-color;
296 | }
297 | }
298 |
299 | dl {
300 | padding: 0;
301 |
302 | dt {
303 | padding: 0;
304 | margin-top: 1rem;
305 | font-size: 1rem;
306 | font-weight: bold;
307 | }
308 |
309 | dd {
310 | padding: 0;
311 | margin-bottom: 1rem;
312 | }
313 | }
314 |
315 | hr {
316 | height: 2px;
317 | padding: 0;
318 | margin: 1rem 0;
319 | background-color: $hr-border-color;
320 | border: 0;
321 | }
322 | }
323 |
324 | .site-footer {
325 | padding-top: 2rem;
326 | margin-top: 2rem;
327 | border-top: solid 1px $hr-border-color;
328 |
329 | @include large {
330 | font-size: 1rem;
331 | }
332 |
333 | @include medium {
334 | font-size: 1rem;
335 | }
336 |
337 | @include small {
338 | font-size: 0.9rem;
339 | }
340 | }
341 |
342 | .site-footer-owner {
343 | display: block;
344 | font-weight: bold;
345 | }
346 |
347 | .site-footer-credits {
348 | color: $blockquote-text-color;
349 | }
350 |
--------------------------------------------------------------------------------
/docs/_sass/variables.scss:
--------------------------------------------------------------------------------
1 | // Breakpoints
2 | $large-breakpoint: 64em !default;
3 | $medium-breakpoint: 42em !default;
4 |
5 | // Headers
6 | $header-heading-color: #fff !default;
7 | // $header-bg-color: hsla(211, 34%, 83%, 1) !default;
8 | // $header-bg-color: hsla(211, 34%, 77%, 1) !default;
9 | $header-bg-color: hsla(211, 34%, 41%, 1) !default;
10 | // $header-bg-color-middle: hsla(33, 34%, 83%, 1) !default;
11 | // $header-bg-color-middle: hsla(33, 34%, 77%, 1) !default;
12 | $header-bg-color-middle: hsla(33, 34%, 41%, 1) !default;
13 | // $header-bg-color-secondary: hsla(92, 34%, 83%, 1) !default;
14 | // $header-bg-color-secondary: hsla(92, 34%, 77%, 1) !default;
15 | $header-bg-color-secondary: hsla(92, 34%, 41%, 1) !default;
16 |
17 | // Text
18 | $section-headings-color: hsla(211, 27%, 23%, 1) !default;
19 | $body-text-color: #606c71 !default;
20 | $body-link-color: #1e6bb8 !default;
21 | $blockquote-text-color: #819198 !default;
22 |
23 | // Code
24 | $code-bg-color: #f3f6fa !default;
25 | $code-text-color: #567482 !default;
26 |
27 | // Borders
28 | $border-color: #dce6f0 !default;
29 | $table-border-color: #e9ebec !default;
30 | $hr-border-color: #eff0f1 !default;
31 |
--------------------------------------------------------------------------------
/docs/assets/css/style.scss:
--------------------------------------------------------------------------------
1 | ---
2 | ---
3 |
4 | @import "{{ site.theme }}";
5 |
--------------------------------------------------------------------------------
/docs/assets/img/icon_macos.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/assets/img/icon_windows.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/docs/assets/img/raxmlgui_icon_256x256x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AntonelliLab/raxmlGUI/f5b59126ea6c34e84e89a1c2c07b966e07afd216/docs/assets/img/raxmlgui_icon_256x256x32.png
--------------------------------------------------------------------------------
/docs/assets/img/screenshots/basic.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AntonelliLab/raxmlGUI/f5b59126ea6c34e84e89a1c2c07b966e07afd216/docs/assets/img/screenshots/basic.png
--------------------------------------------------------------------------------
/docs/assets/img/screenshots/basic2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AntonelliLab/raxmlGUI/f5b59126ea6c34e84e89a1c2c07b966e07afd216/docs/assets/img/screenshots/basic2.png
--------------------------------------------------------------------------------
/docs/assets/img/screenshots/basic2_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AntonelliLab/raxmlGUI/f5b59126ea6c34e84e89a1c2c07b966e07afd216/docs/assets/img/screenshots/basic2_dark.png
--------------------------------------------------------------------------------
/docs/assets/img/screenshots/basic_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AntonelliLab/raxmlGUI/f5b59126ea6c34e84e89a1c2c07b966e07afd216/docs/assets/img/screenshots/basic_dark.png
--------------------------------------------------------------------------------
/docs/assets/img/screenshots/console.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AntonelliLab/raxmlGUI/f5b59126ea6c34e84e89a1c2c07b966e07afd216/docs/assets/img/screenshots/console.png
--------------------------------------------------------------------------------
/docs/assets/img/screenshots/model.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AntonelliLab/raxmlGUI/f5b59126ea6c34e84e89a1c2c07b966e07afd216/docs/assets/img/screenshots/model.png
--------------------------------------------------------------------------------
/docs/assets/img/screenshots/parallel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AntonelliLab/raxmlGUI/f5b59126ea6c34e84e89a1c2c07b966e07afd216/docs/assets/img/screenshots/parallel.png
--------------------------------------------------------------------------------
/docs/assets/img/screenshots/partition_editor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AntonelliLab/raxmlGUI/f5b59126ea6c34e84e89a1c2c07b966e07afd216/docs/assets/img/screenshots/partition_editor.png
--------------------------------------------------------------------------------
/docs/assets/img/screenshots/pipelines.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AntonelliLab/raxmlGUI/f5b59126ea6c34e84e89a1c2c07b966e07afd216/docs/assets/img/screenshots/pipelines.png
--------------------------------------------------------------------------------
/docs/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AntonelliLab/raxmlGUI/f5b59126ea6c34e84e89a1c2c07b966e07afd216/docs/favicon.ico
--------------------------------------------------------------------------------
/docs/index.md:
--------------------------------------------------------------------------------
1 | ---
2 | # Feel free to add content and custom Front Matter to this file.
3 | # To modify the layout, see https://jekyllrb.com/docs/themes/#overriding-theme-defaults
4 |
5 | #layout: home
6 | description: A new user-friendly program integrating RAxML-NG and ModelTest-NG for cutting-edge phylogenetic analysis
7 | ---
8 |
9 | The program presented here is the first release, the most important functions and analyses are implemented and functional. However, we encourage users to [send us any feedback they may have](mailto:raxmlgui.help@gmail.com). raxmlGUI 2.0 facilitates phylogenetic analyses by coupling an intuitive interface with the unmatched performance of RAxML. Read more in the [accompanying paper](http://dx.doi.org/10.1111/2041-210X.13512).
10 |
11 | ------------------------
12 |
13 |
14 | 1 Edler, D., J. Klein, A. Antonelli, and D. Silvestro. 2020. **raxmlGUI 2.0: A graphical interface and toolkit for phylogenetic analyses using RAxML.** _Methods in Ecology and Evolution_, doi: http://dx.doi.org/10.1111/2041-210X.13512
15 |
16 |
17 |
18 | 2 Silvestro, D. and I. Michalak. 2012. **raxmlGUI: a graphical front-end for RAxML.** _Organisms Diversity and Evolution_ 12:335–337.
19 |
20 |
21 |
22 | 3 Stamatakis, A. 2014. **Raxml version 8: a tool for phylogenetic analysis andpost-analysis of large phylogenies.** _Bioinformatics_ 30:1312–1313.
23 |
24 |
25 |
26 | 4 Kozlov, A. M., D. Darriba, T. Flouri, B. Morel, and A. Stamatakis. 2019. **RAxML-NG: a fast, scalable and user-friendly tool for maximum likelihood phylogenetic inference.** _Bioinformatics_ 35:4453–4455.
27 |
28 |
29 |
30 | 5 Darriba, D., D. Posada, A. M. Kozlov, A. Stamatakis, B. Morel, T. Flouri. 2020. **ModelTest-NG: A New and Scalable Tool for the Selection of DNA and Protein Evolutionary Models.** _Molecular Biology and Evolution_ 37:291–294.
31 |
32 |
--------------------------------------------------------------------------------
/docs/jekyll-theme-cayman/.gitignore:
--------------------------------------------------------------------------------
1 | *.gem
2 | .bundle
3 | .sass-cache
4 | _site
5 | Gemfile.lock
6 |
--------------------------------------------------------------------------------
/docs/jekyll-theme-cayman/Gemfile:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | source "https://rubygems.org"
4 | gemspec
5 |
--------------------------------------------------------------------------------
/docs/jekyll-theme-cayman/LICENSE.txt:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2021 Daniel Edler
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/docs/jekyll-theme-cayman/README.md:
--------------------------------------------------------------------------------
1 | # jekyll-theme-cayman
2 |
3 | Welcome to your new Jekyll theme! In this directory, you'll find the files you need to be able to package up your theme into a gem. Put your layouts in `_layouts`, your includes in `_includes`, your sass files in `_sass` and any other assets in `assets`.
4 |
5 | To experiment with this code, add some sample content and run `bundle exec jekyll serve` – this directory is setup just like a Jekyll site!
6 |
7 | TODO: Delete this and the text above, and describe your gem
8 |
9 |
10 | ## Installation
11 |
12 | Add this line to your Jekyll site's `Gemfile`:
13 |
14 | ```ruby
15 | gem "jekyll-theme-cayman"
16 | ```
17 |
18 | And add this line to your Jekyll site's `_config.yml`:
19 |
20 | ```yaml
21 | theme: jekyll-theme-cayman
22 | ```
23 |
24 | And then execute:
25 |
26 | $ bundle
27 |
28 | Or install it yourself as:
29 |
30 | $ gem install jekyll-theme-cayman
31 |
32 | ## Usage
33 |
34 | TODO: Write usage instructions here. Describe your available layouts, includes, sass and/or assets.
35 |
36 | ## Contributing
37 |
38 | Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/hello. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
39 |
40 | ## Development
41 |
42 | To set up your environment to develop this theme, run `bundle install`.
43 |
44 | Your theme is setup just like a normal Jekyll site! To test your theme, run `bundle exec jekyll serve` and open your browser at `http://localhost:4000`. This starts a Jekyll server using your theme. Add pages, documents, data, etc. like normal to test your theme's contents. As you make modifications to your theme and to your content, your site will regenerate and you should see the changes in the browser after a refresh, just like normal.
45 |
46 | When your theme is released, only the files in `_layouts`, `_includes`, `_sass` and `assets` tracked with Git will be bundled.
47 | To add a custom directory to your theme-gem, please edit the regexp in `jekyll-theme-cayman.gemspec` accordingly.
48 |
49 | ## License
50 |
51 | The theme is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
52 |
53 |
--------------------------------------------------------------------------------
/docs/jekyll-theme-cayman/_layouts/default.html:
--------------------------------------------------------------------------------
1 | {{ content }}
2 |
--------------------------------------------------------------------------------
/docs/jekyll-theme-cayman/_layouts/page.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | ---
4 |
5 | {{ content }}
6 |
--------------------------------------------------------------------------------
/docs/jekyll-theme-cayman/_layouts/post.html:
--------------------------------------------------------------------------------
1 | ---
2 | layout: default
3 | ---
4 |
5 | {{ content }}
6 |
--------------------------------------------------------------------------------
/docs/jekyll-theme-cayman/jekyll-theme-cayman.gemspec:
--------------------------------------------------------------------------------
1 | # frozen_string_literal: true
2 |
3 | Gem::Specification.new do |spec|
4 | spec.name = "jekyll-theme-cayman"
5 | spec.version = "0.1.0"
6 | spec.authors = ["Daniel Edler"]
7 | spec.email = ["edler.dev@gmail.com"]
8 |
9 | spec.summary = "TODO: Write a short summary, because Rubygems requires one."
10 | spec.homepage = "TODO: Put your gem's website or public repo URL here."
11 | spec.license = "MIT"
12 |
13 | spec.files = `git ls-files -z`.split("\x0").select { |f| f.match(%r!^(assets|_layouts|_includes|_sass|LICENSE|README)!i) }
14 |
15 | spec.add_runtime_dependency "jekyll", "~> 3.9"
16 |
17 | spec.add_development_dependency "bundler", ">= 2.1.0"
18 | spec.add_development_dependency "rake", "~> 12.0"
19 | end
20 |
--------------------------------------------------------------------------------
/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "esnext"
4 | },
5 | "exclude": [
6 | "node_modules",
7 | "build",
8 | "dist"
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "raxmlgui",
3 | "productName": "raxmlGUI",
4 | "version": "2.0.16",
5 | "private": true,
6 | "author": "AntonelliLab ",
7 | "license": "AGPL-3.0",
8 | "description": "raxmlGUI - A new graphical front-end for RAxML",
9 | "homepage": "./",
10 | "repository": {
11 | "type": "git",
12 | "url": "git+https://github.com/AntonelliLab/raxmlGUI.git"
13 | },
14 | "bugs": {
15 | "url": "https://github.com/AntonelliLab/raxmlGUI/issues"
16 | },
17 | "keywords": [
18 | "Electron",
19 | "RAxML",
20 | "GUI",
21 | "Phylogenetics"
22 | ],
23 | "main": "build/electron.js",
24 | "scripts": {
25 | "start": "cross-env ELECTRON_START_URL=http://localhost:3000/ run-p react-start electron-dev",
26 | "react-start": "cross-env BROWSER=none craco start",
27 | "react-build": "craco build",
28 | "react-test": "craco test --env=jsdom",
29 | "react-eject": "react-scripts eject",
30 | "wait-dev": "wait-on $ELECTRON_START_URL",
31 | "download-binaries": "node scripts/download-binaries.js",
32 | "electron-dev": "electron-webpack dev",
33 | "electron-start": "cross-env DEV=true run-s wait-dev electron-dev",
34 | "electron-build": "electron-builder",
35 | "electron-build-win": "electron-builder -w",
36 | "electron-build-linux": "electron-builder -l",
37 | "electron-build-all": "electron-builder -mwl",
38 | "electron-build-publish-all": "electron-builder -mwl -p always",
39 | "electron-pack": "electron-builder --dir -c.compression=store -c.mac.identity=null",
40 | "electron-pack-win": "electron-builder -w --dir -c.compression=store",
41 | "electron-compile": "electron-webpack",
42 | "electron-copy": "shx cp dist/main/main.js build/electron.js",
43 | "compile": "run-s electron-compile electron-copy",
44 | "build": "run-s react-build compile",
45 | "build-mac": "run-s react-build compile electron-build",
46 | "build-win": "run-s react-build compile electron-build-win",
47 | "build-linux": "run-s react-build compile electron-build-linux",
48 | "build-all": "run-s react-build compile electron-build-all",
49 | "dist-pack": "run-s react-build compile electron-pack",
50 | "dist-pack-win": "run-s react-build compile electron-pack-win",
51 | "publish-all": "run-s react-build compile electron-build-publish-all",
52 | "postinstall-deps": "electron-builder install-app-deps",
53 | "postinstall-patch": "patch-package",
54 | "postinstall": "run-s postinstall-deps postinstall-patch",
55 | "docs-serve": "cd docs && bundle exec jekyll serve"
56 | },
57 | "dependencies": {
58 | "@babel/plugin-proposal-decorators": "^7.19.0",
59 | "@craco/craco": "^7.1.0",
60 | "@emotion/react": "^11.14.0",
61 | "@emotion/styled": "^11.14.0",
62 | "@mui/icons-material": "^6.4.11",
63 | "@mui/lab": "^6.0.1-beta.34",
64 | "@mui/material": "^6.4.11",
65 | "@mui/styles": "^6.4.11",
66 | "@sentry/electron": "^4.0.2",
67 | "classnames": "^2.3.2",
68 | "clean-stack": "3.0.1",
69 | "clsx": "^1.2.1",
70 | "computed-async-mobx": "^4.2.0",
71 | "cpus": "^1.0.3",
72 | "d3-array": "^3.2.4",
73 | "electron-better-ipc": "^2.0.1",
74 | "electron-log": "^4.4.8",
75 | "electron-progressbar": "^2.2.1",
76 | "electron-store": "^8.1.0",
77 | "electron-updater": "^5.2.4",
78 | "filenamify": "^4.3.0",
79 | "lodash": "^4.17.21",
80 | "mobx": "^5.15.7",
81 | "mobx-react": "^6.3.1",
82 | "mobx-react-lite": "^2.2.2",
83 | "mobx-utils": "^5.6.2",
84 | "parse-filepath": "^1.0.2",
85 | "patch-package": "^6.4.7",
86 | "postinstall-postinstall": "^2.1.0",
87 | "prismjs": "^1.30.0",
88 | "prismjs-bibtex": "^2.1.0",
89 | "prop-types": "^15.8.1",
90 | "react": "^18.3.1",
91 | "react-dom": "^18.3.1",
92 | "react-dropzone": "14.2.10",
93 | "react-scripts": "^5.0.1",
94 | "react-split-pane": "^0.1.92",
95 | "serialize-error": "^8.1.0",
96 | "source-map-support": "^0.5.21",
97 | "yup": "^0.32.11"
98 | },
99 | "devDependencies": {
100 | "@babel/plugin-proposal-class-properties": "^7.18.6",
101 | "@babel/preset-env": "^7.19.0",
102 | "@electron/notarize": "^2.5.0",
103 | "@sentry/cli": "^2.5.2",
104 | "@sentry/webpack-plugin": "^1.19.0",
105 | "cross-env": "^7.0.3",
106 | "dotenv": "^16.5.0",
107 | "download": "^8.0.0",
108 | "electron": "^36.2.1",
109 | "electron-builder": "^24.13.3",
110 | "electron-download": "^4.1.1",
111 | "electron-webpack": "^2.8.2",
112 | "nodemon": "^3.1.9",
113 | "npm-run-all": "^4.1.5",
114 | "prettier": "^2.8.8",
115 | "shx": "^0.4.0",
116 | "typescript": "^4.9.5",
117 | "wait-on": "^8.0.3"
118 | },
119 | "browserslist": [
120 | ">0.2%",
121 | "not dead",
122 | "not ie <= 11",
123 | "not op_mini all"
124 | ],
125 | "electronWebpack": {
126 | "commonSourceDirectory": "src/common",
127 | "staticSourceDirectory": "static",
128 | "main": {
129 | "sourceDirectory": "src/main",
130 | "webpackConfig": "webpack.config.js"
131 | },
132 | "renderer": {
133 | "sourceDirectory": null,
134 | "webpackConfig": "webpack.config.js"
135 | }
136 | },
137 | "build": {
138 | "appId": "org.jtklein.raxmlGUI2",
139 | "productName": "raxmlGUI",
140 | "afterSign": "./scripts/notarize.js",
141 | "directories": {
142 | "buildResources": "build",
143 | "output": "dist"
144 | },
145 | "files": [
146 | "src/main/*"
147 | ],
148 | "extraResources": [
149 | "assets/"
150 | ],
151 | "dmg": {
152 | "icon": "build/disk-image.icns",
153 | "sign": false
154 | },
155 | "mac": {
156 | "mergeASARs": false,
157 | "target": [
158 | {
159 | "target": "dmg",
160 | "arch": [
161 | "universal"
162 | ]
163 | },
164 | {
165 | "target": "zip",
166 | "arch": [
167 | "universal"
168 | ]
169 | }
170 | ],
171 | "x64ArchFiles": "**/static/bin/*",
172 | "category": "public.app-category.education",
173 | "hardenedRuntime": true,
174 | "entitlements": "public/entitlements.mac.inherit.plist",
175 | "entitlementsInherit": "public/entitlements.mac.inherit.plist",
176 | "extraResources": [
177 | {
178 | "from": "static/bin/Mac",
179 | "to": "static/bin"
180 | },
181 | {
182 | "from": "static/example-files/fasta",
183 | "to": "static/example-files",
184 | "filter": [
185 | "*.txt"
186 | ]
187 | }
188 | ]
189 | },
190 | "win": {
191 | "target": [
192 | "nsis"
193 | ],
194 | "extraResources": [
195 | {
196 | "from": "static/bin/Windows",
197 | "to": "static/bin"
198 | }
199 | ]
200 | },
201 | "linux": {
202 | "target": [
203 | "AppImage"
204 | ],
205 | "category": "Education",
206 | "extraResources": [
207 | {
208 | "from": "static/bin/Linux",
209 | "to": "static/bin"
210 | }
211 | ]
212 | },
213 | "publish": {
214 | "provider": "github"
215 | }
216 | }
217 | }
218 |
--------------------------------------------------------------------------------
/patches/electron-webpack+2.8.2.patch:
--------------------------------------------------------------------------------
1 | diff --git a/node_modules/electron-webpack/out/targets/BaseTarget.js b/node_modules/electron-webpack/out/targets/BaseTarget.js
2 | index e4c6b00..8eea68c 100644
3 | --- a/node_modules/electron-webpack/out/targets/BaseTarget.js
4 | +++ b/node_modules/electron-webpack/out/targets/BaseTarget.js
5 | @@ -156,7 +156,7 @@ class BaseTarget {
6 | plugins.push(new (_WebpackRemoveOldAssetsPlugin().WebpackRemoveOldAssetsPlugin)(dllManifest));
7 | }
8 |
9 | - optimization.noEmitOnErrors = true;
10 | + optimization.emitOnErrors = false;
11 | const additionalEnvironmentVariables = Object.keys(process.env).filter(it => it.startsWith("ELECTRON_WEBPACK_"));
12 |
13 | if (additionalEnvironmentVariables.length > 0) {
14 | @@ -185,7 +185,7 @@ function isAncestor(file, dir) {
15 |
16 | function configureDevelopmentPlugins(configurator) {
17 | const plugins = configurator.plugins;
18 | - configurator.config.optimization.namedModules = true;
19 | + configurator.config.optimization.moduleIds = "named";
20 | plugins.push(new (_webpack().DefinePlugin)({
21 | __static: `"${path.join(configurator.projectDir, configurator.staticSourceDirectory).replace(/\\/g, "\\\\")}"`,
22 | "process.env.NODE_ENV": configurator.isProduction ? "\"production\"" : "\"development\""
23 | diff --git a/node_modules/electron-webpack/readme.md b/node_modules/electron-webpack/readme.md
24 | deleted file mode 100644
25 | index 2504278..0000000
26 | --- a/node_modules/electron-webpack/readme.md
27 | +++ /dev/null
28 | @@ -1,45 +0,0 @@
29 | -# electron-webpack [](https://npmjs.org/package/electron-webpack)
30 | -
31 | -> Because setting up `webpack` in the `electron` environment shouldn't be difficult.
32 | -
33 | -## Overview
34 | -Modern web development practices today require a lot of setup with things like `webpack` to bundle your code, `babel` for transpiling, `eslint` for linting, and so much more that the list just goes on. Unfortunately when creating `electron` applications, all of that setup just became much more difficult. The primary aim of `electron-webpack` is to eliminate all preliminary setup with one simple install so you can get back to developing your application.
35 | -
36 | -> Why create a module and not a full boilerplate?
37 | -
38 | -If you've been in the JavaScript world for even a short period of time, you are very aware that things are always changing, and development setup is no exclusion. Putting all development scripts into a single **updatable** module just makes sense. Sure a full featured boilerplate works too, but doing also involves needing to manually update those pesky `webpack` configuration files that some may call *magic* when something new comes out.
39 | -
40 | -Here are some of the awesome features you'll find using `electron-webpack`...
41 | -
42 | -* Detailed [documentation](https://webpack.electron.build)
43 | -* Use of [`webpack`](https://webpack.js.org/) for source code bundling
44 | -* Use of [`webpack-dev-server`](https://github.com/webpack/webpack-dev-server) for development
45 | -* HMR for both `renderer` and `main` processes
46 | -* Use of [`@babel/preset-env`](https://github.com/babel/babel/tree/master/packages/babel-preset-env) that is automatically configured based on your `electron` version
47 | -* Ability to add custom `webpack` loaders, plugins, etc.
48 | -* [Add-ons](https://webpack.electron.build/add-ons) to support items like [TypeScript](http://www.typescriptlang.org/), [Less](http://lesscss.org/), [EJS](http://www.embeddedjs.com/), etc.
49 | -
50 | -## Quick Start
51 | -Get started fast with [electron-webpack-quick-start](https://github.com/electron-userland/electron-webpack-quick-start).
52 | -```bash
53 | -# create a directory of your choice, and copy template using curl
54 | -mkdir my-project && cd my-project
55 | -curl -fsSL https://github.com/electron-userland/electron-webpack-quick-start/archive/master.tar.gz | tar -xz --strip-components 1
56 | -
57 | -# or copy template using git clone
58 | -git clone https://github.com/electron-userland/electron-webpack-quick-start.git
59 | -cd electron-webpack-quick-start
60 | -rm -rf .git
61 | -
62 | -# install dependencies
63 | -yarn
64 | -```
65 | -
66 | -If you already have an existing project, or are looking for a custom approach outside of the quick start template, make sure to read over the [Core Concepts](https://webpack.electron.build/core-concepts), [Project Structure](https://webpack.electron.build/project-structure), and [Development](https://webpack.electron.build/development) sections of `electron-webpack`'s documentation.
67 | -
68 | -### Next Steps
69 | -Make sure to take advantage of the detailed [documentation](https://webpack.electron.build) that `electron-webpack` provides. It covers everything from how things work internally, adding custom configurations, and building your application.
70 | -
71 | -### Contributing
72 | -Feel free to grab an issue and fix it or to share your features and improvements - PRs are always welcome!
73 | -However, in order for your contribution to be property included in the automatically generated release notes, please use our [standard format](https://gist.github.com/develar/273e2eb938792cf5f86451fbac2bcd51) for your commit messages.
74 |
--------------------------------------------------------------------------------
/public/disk-image.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AntonelliLab/raxmlGUI/f5b59126ea6c34e84e89a1c2c07b966e07afd216/public/disk-image.icns
--------------------------------------------------------------------------------
/public/entitlements.mac.inherit.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.cs.allow-jit
6 |
7 | com.apple.security.cs.allow-unsigned-executable-memory
8 |
9 | com.apple.security.cs.allow-dyld-environment-variables
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AntonelliLab/raxmlGUI/f5b59126ea6c34e84e89a1c2c07b966e07afd216/public/favicon.ico
--------------------------------------------------------------------------------
/public/icon.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AntonelliLab/raxmlGUI/f5b59126ea6c34e84e89a1c2c07b966e07afd216/public/icon.icns
--------------------------------------------------------------------------------
/public/icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AntonelliLab/raxmlGUI/f5b59126ea6c34e84e89a1c2c07b966e07afd216/public/icon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
14 |
15 |
16 |
17 |
26 | raxmlGUI 2.0
27 |
28 |
29 |
32 |
33 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | }
10 | ],
11 | "start_url": "./index.html",
12 | "display": "standalone",
13 | "theme_color": "#000000",
14 | "background_color": "#ffffff"
15 | }
16 |
--------------------------------------------------------------------------------
/scripts/download-binaries.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs').promises;
2 | const path = require('path');
3 | const download = require('download');
4 |
5 | const osName = (() => {
6 | switch (process.platform) {
7 | case 'darwin':
8 | return 'Mac';
9 | case 'win32':
10 | return 'Windows';
11 | default:
12 | return 'Linux';
13 | }
14 | })();
15 |
16 | const binariesBaseDir =
17 | 'https://github.com/AntonelliLab/raxmlGUI-binaries/releases/download/v24.09.28';
18 | const binariesUrl = `${binariesBaseDir}/${osName}.zip`;
19 |
20 | const binPath = path.join(__dirname, '..', 'static', 'bin');
21 | const raxmlNgPath = path.join(binPath, 'raxml-ng');
22 |
23 | (async () => {
24 | console.log('Check binaries...');
25 | let exist = true;
26 | try {
27 | await fs.access(raxmlNgPath);
28 | } catch (_) {
29 | exist = false;
30 | }
31 |
32 | if (exist) {
33 | console.log('Binaries exist!');
34 | return;
35 | }
36 |
37 | console.log(`Binaries missing, downloading from '${binariesUrl}'...`);
38 |
39 | await download(binariesUrl, binPath, {
40 | extract: true,
41 | });
42 | console.log('Done!');
43 | })();
44 |
--------------------------------------------------------------------------------
/scripts/notarize.js:
--------------------------------------------------------------------------------
1 | require('dotenv').config();
2 | const { notarize } = require('@electron/notarize');
3 |
4 | exports.default = async function notarizing(context) {
5 | const { electronPlatformName, appOutDir } = context;
6 | if (electronPlatformName !== 'darwin') {
7 | return;
8 | }
9 |
10 | const appleId = process.env.APPLEID;
11 | const appleIdPassword = process.env.APPLEIDPASS;
12 | const teamId = process.env.APPLEIDTEAM;
13 |
14 | if (!appleId) {
15 | console.log(
16 | 'Johannes: Skipping notarization of app because no AppleID is given.'
17 | );
18 | console.log('Johannes: This binary is not ready for release.');
19 | return;
20 | }
21 | if (!appleIdPassword) {
22 | console.log(
23 | 'Johannes: Skipping notarization of app because no AppleID password is given.'
24 | );
25 | console.log('Johannes: This binary is not ready for release.');
26 | return;
27 | }
28 | if (!teamId) {
29 | console.log(
30 | 'Johannes: Skipping notarization of app because no AppleID team number is given.'
31 | );
32 | console.log('Johannes: This binary is not ready for release.');
33 | return;
34 | }
35 |
36 | const appName = context.packager.appInfo.productFilename;
37 | console.log(`Notarizing ${appName} found at ${appOutDir}`);
38 |
39 | return await notarize({
40 | appBundleId: 'org.jtklein.raxmlGUI2',
41 | appPath: `${appOutDir}/${appName}.app`,
42 | appleId,
43 | appleIdPassword,
44 | teamId,
45 | });
46 | };
47 |
--------------------------------------------------------------------------------
/sentry-symbols.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | let SentryCli;
4 | let download;
5 |
6 | try {
7 | SentryCli = require('@sentry/cli');
8 | download = require('electron-download');
9 | } catch (e) {
10 | console.error('ERROR: Missing required packages, please run:');
11 | console.error('npm install --save-dev @sentry/cli electron-download');
12 | process.exit(1);
13 | }
14 |
15 | const VERSION = /\bv?(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)\.(?:0|[1-9]\d*)(?:-[\da-z-]+(?:\.[\da-z-]+)*)?(?:\+[\da-z-]+(?:\.[\da-z-]+)*)?\b/i;
16 | const SYMBOL_CACHE_FOLDER = '.electron-symbols';
17 | const package = require('./package.json');
18 | const sentryCli = new SentryCli('./sentry.properties');
19 |
20 | async function main() {
21 | let version = getElectronVersion();
22 | if (!version) {
23 | console.error('Cannot detect electron version, check package.json');
24 | return;
25 | }
26 |
27 | console.log('We are starting to download all possible electron symbols');
28 | console.log('We need it in order to symbolicate native crashes');
29 | console.log(
30 | 'This step is only needed once whenever you update your electron version',
31 | );
32 | console.log('Just call this script again it should do everything for you.');
33 |
34 | let zipPath = await downloadSymbols({
35 | version,
36 | platform: 'darwin',
37 | arch: 'x64',
38 | dsym: true,
39 | });
40 | await sentryCli.execute(['upload-dif', '-t', 'dsym', zipPath], true);
41 |
42 | zipPath = await downloadSymbols({
43 | version,
44 | platform: 'win32',
45 | arch: 'ia32',
46 | symbols: true,
47 | });
48 | await sentryCli.execute(['upload-dif', '-t', 'breakpad', zipPath], true);
49 |
50 | zipPath = await downloadSymbols({
51 | version,
52 | platform: 'win32',
53 | arch: 'x64',
54 | symbols: true,
55 | });
56 | await sentryCli.execute(['upload-dif', '-t', 'breakpad', zipPath], true);
57 |
58 | zipPath = await downloadSymbols({
59 | version,
60 | platform: 'linux',
61 | arch: 'x64',
62 | symbols: true,
63 | });
64 | await sentryCli.execute(['upload-dif', '-t', 'breakpad', zipPath], true);
65 |
66 | console.log('Finished downloading and uploading to Sentry');
67 | console.log(`Feel free to delete the ${SYMBOL_CACHE_FOLDER}`);
68 | }
69 |
70 | function getElectronVersion() {
71 | if (!package) {
72 | return false;
73 | }
74 |
75 | let electronVersion =
76 | (package.dependencies && package.dependencies.electron) ||
77 | (package.devDependencies && package.devDependencies.electron);
78 |
79 | if (!electronVersion) {
80 | return false;
81 | }
82 |
83 | const matches = VERSION.exec(electronVersion);
84 | return matches ? matches[0] : false;
85 | }
86 |
87 | async function downloadSymbols(options) {
88 | return new Promise((resolve, reject) => {
89 | download(
90 | {
91 | ...options,
92 | cache: SYMBOL_CACHE_FOLDER,
93 | },
94 | (err, zipPath) => {
95 | if (err) {
96 | reject(err);
97 | } else {
98 | resolve(zipPath);
99 | }
100 | },
101 | );
102 | });
103 | }
104 |
105 | main().catch(e => console.error(e));
106 |
--------------------------------------------------------------------------------
/src/app/App.css:
--------------------------------------------------------------------------------
1 |
2 | .AppContent {
3 | display: flex;
4 | flex-direction: row;
5 | justify-content: space-between;
6 | height: 100vh;
7 | overflow-y: auto;
8 | }
9 |
10 | .alignment {
11 | width: 550px;
12 | height: 200px;
13 | }
14 |
15 | .alignment + .alignment {
16 | margin-left: 10px;
17 | }
18 |
19 | .Resizer {
20 | background: #000;
21 | opacity: .2;
22 | z-index: 1;
23 | -moz-box-sizing: border-box;
24 | -webkit-box-sizing: border-box;
25 | box-sizing: border-box;
26 | -moz-background-clip: padding;
27 | -webkit-background-clip: padding;
28 | background-clip: padding-box;
29 | }
30 |
31 | .Resizer:hover {
32 | -webkit-transition: all 2s ease;
33 | transition: all 2s ease;
34 | }
35 |
36 | .Resizer.horizontal {
37 | height: 11px;
38 | margin: -5px 0;
39 | border-top: 5px solid rgba(255, 255, 255, 0);
40 | border-bottom: 5px solid rgba(255, 255, 255, 0);
41 | cursor: row-resize;
42 | width: 100%;
43 | }
44 |
45 | .Resizer.horizontal:hover {
46 | border-top: 5px solid rgba(0, 0, 0, 0.5);
47 | border-bottom: 5px solid rgba(0, 0, 0, 0.5);
48 | }
49 |
50 | .Resizer.vertical {
51 | width: 11px;
52 | margin: 0 -5px;
53 | border-left: 5px solid rgba(255, 255, 255, 0);
54 | border-right: 5px solid rgba(255, 255, 255, 0);
55 | cursor: col-resize;
56 | }
57 |
58 | .Resizer.vertical:hover {
59 | border-left: 5px solid rgba(0, 0, 0, 0.5);
60 | border-right: 5px solid rgba(0, 0, 0, 0.5);
61 | }
62 | .Resizer.disabled {
63 | cursor: not-allowed;
64 | }
65 | .Resizer.disabled:hover {
66 | border-color: transparent;
67 | }
68 |
--------------------------------------------------------------------------------
/src/app/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import App from './App';
4 |
5 | it('renders without crashing', () => {
6 | const div = document.createElement('div');
7 | ReactDOM.render(, div);
8 | });
9 |
--------------------------------------------------------------------------------
/src/app/AstralTreeCard.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { observer } from 'mobx-react';
3 | import PropTypes from 'prop-types';
4 | import { makeStyles } from '@mui/styles';
5 | import IconButton from '@mui/material/IconButton';
6 | import MoreVertIcon from '@mui/icons-material/MoreVert';
7 | import DeleteForeverIcon from '@mui/icons-material/DeleteForever';
8 | import classNames from 'classnames';
9 | import CircularProgress from '@mui/material/CircularProgress';
10 | import Chip from '@mui/material/Chip';
11 | import Menu from '@mui/material/Menu';
12 | import MenuItem from '@mui/material/MenuItem';
13 | import Tooltip from '@mui/material/Tooltip';
14 | import Card from '@mui/material/Card';
15 | import CardHeader from '@mui/material/CardHeader';
16 | import CardContent from '@mui/material/CardContent';
17 | import CardActions from '@mui/material/CardActions';
18 | import Box from '@mui/material/Box';
19 |
20 | // const useStyles = makeStyles(theme => ({
21 | const useStyles = makeStyles((theme) => {
22 | return {
23 | AstralTreeCard: {
24 | backgroundColor: theme.palette.input.light,
25 | border: `1px solid ${theme.palette.input.border}`,
26 | },
27 | cardHeaderRoot: {
28 | overflow: "hidden"
29 | },
30 | cardHeaderContent: {
31 | overflow: "hidden"
32 | },
33 | content: {
34 | display: 'flex',
35 | alignItems: 'center',
36 | marginLeft: '-10px',
37 | },
38 | chip: {
39 | height: '30px',
40 | color: theme.palette.input.contrastText,
41 | backgroundColor: theme.palette.input.main,
42 | border: `1px solid ${theme.palette.input.darker}`,
43 | },
44 | };
45 | });
46 |
47 | function AstralTreeCard({ className, astralTree }) {
48 | const { } = astralTree;
49 |
50 | const classes = useStyles();
51 | const [anchorEl, setAnchorEl] = React.useState(null);
52 |
53 | function handleMenuClick(event) {
54 | setAnchorEl(event.currentTarget);
55 | }
56 |
57 | function handleMenuClose() {
58 | setAnchorEl(null);
59 | }
60 |
61 | function closeMenuAndRun(callback) {
62 | return () => {
63 | callback();
64 | setAnchorEl(null);
65 | };
66 | }
67 |
68 | const Content = (
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | );
77 |
78 | return (
79 |
80 |
91 | }
92 | action={
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
105 |
106 |
107 |
108 |
124 |
125 | }
126 | title={astralTree.filename}
127 | subheader={'Input trees'}
128 | style={{ paddingBottom: 4 }}
129 | />
130 | {Content}
131 |
132 |
133 | );
134 | }
135 |
136 | AstralTreeCard.propTypes = {
137 | astralTree: PropTypes.object.isRequired,
138 | className: PropTypes.string,
139 | };
140 |
141 | const AstralTreeCardObserver = observer(AstralTreeCard);
142 |
143 | export default AstralTreeCardObserver;
144 |
--------------------------------------------------------------------------------
/src/app/CitationModal.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { observer } from 'mobx-react';
3 | import PropTypes from 'prop-types';
4 | import { makeStyles } from '@mui/styles';
5 | import Button from '@mui/material/Button';
6 | import Card from '@mui/material/Card';
7 | import CardContent from '@mui/material/CardContent';
8 | import CardActions from '@mui/material/CardActions';
9 | import Typography from '@mui/material/Typography';
10 | import Box from '@mui/material/Box';
11 | import ToggleButton from '@mui/material/ToggleButton';
12 | import ToggleButtonGroup from '@mui/material/ToggleButtonGroup';
13 |
14 | import CodeHighlight from './components/CodeHighlight';
15 |
16 | const useStyles = makeStyles(theme => ({
17 | CitationModal: {
18 | backgroundColor: theme.palette.output.background,
19 | display: 'flex',
20 | flexDirection: 'column',
21 | alignItems: 'center',
22 | maxWidth: '700px'
23 | },
24 | content: {
25 | maxHeight: '600px',
26 | overflowY: 'auto'
27 | },
28 | code: {
29 | backgroundColor: theme.palette.console.background,
30 | borderRadius: '4px',
31 | padding: '4px'
32 | }
33 | }));
34 |
35 | function CitationModal({ citation }) {
36 | const classes = useStyles();
37 |
38 | return (
39 |
40 |
41 | How to cite?
42 |
43 | Please include the following references in your preferred format:
44 |
45 |
46 | citation.setFormat(format)}
50 | aria-label="text format"
51 | size="small"
52 | >
53 | {citation.formats.map(format => (
54 |
59 | {format.name}
60 |
61 | ))}
62 |
63 |
64 | {citation.content.map(article => (
65 |
66 | {article.name}
67 |
72 |
73 | ))}
74 |
75 |
76 |
77 |
86 |
89 |
90 |
91 |
92 | );
93 | }
94 |
95 | CitationModal.propTypes = {
96 | citation: PropTypes.object.isRequired
97 | };
98 |
99 | export default observer(CitationModal);
100 |
--------------------------------------------------------------------------------
/src/app/Console.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { observer } from 'mobx-react';
3 | import PropTypes from 'prop-types';
4 | import { withStyles } from '@mui/styles';
5 | import clsx from 'clsx';
6 |
7 |
8 | const styles = theme => ({
9 | Console: {
10 | color: theme.palette.console.contrastText,
11 | background: theme.palette.console.background,
12 | // flexGrow: 1,
13 | // padding: '0 4px',
14 | padding: '10px',
15 | width: '100% ',
16 | height: '100%',
17 | },
18 | stdoutContainer: {
19 | overflowY: 'auto',
20 | height: '100%',
21 | position: 'relative',
22 | },
23 | code: {
24 | color: theme.palette.console.contrastText,
25 | fontFamily: 'Consolas, "Liberation Mono", Menlo, Courier, monospace',
26 | fontSize: '12px',
27 | height: '100%',
28 | position: 'absolute',
29 | width: '100%',
30 | // overflowWrap: 'anywhere', // currently not available in Chrome
31 | whiteSpace: 'pre-wrap',
32 | wordBreak: 'break-all',
33 | }
34 | });
35 |
36 | @observer
37 | class Console extends React.Component {
38 | keepToBottom = true;
39 |
40 | onMountStdoutContainer = el => {
41 | this.stdoutContainer = el;
42 | };
43 |
44 | componentDidUpdate() {
45 | if (this.keepToBottom) {
46 | this.scrollConsoleToBottom();
47 | }
48 | }
49 |
50 | isAtBottom = () => {
51 | const { scrollTop, scrollHeight, clientHeight } = this.stdoutContainer;
52 | const diff = scrollHeight - clientHeight;
53 | const scrollIsAtBottom = scrollTop === diff;
54 | return scrollIsAtBottom;
55 | };
56 |
57 | scrollConsoleToBottom = () => {
58 | const { scrollHeight, clientHeight } = this.stdoutContainer;
59 | const diff = scrollHeight - clientHeight;
60 | this.stdoutContainer.scrollTop = diff;
61 | };
62 |
63 | render() {
64 | const { run, classes } = this.props;
65 | return (
66 |
70 |
71 | {run.stdout && {run.stdout}
}
72 | {run.stderr && {run.stderr}
}
73 |
74 |
75 | );
76 | }
77 | }
78 |
79 | Console.propTypes = {
80 | run: PropTypes.object.isRequired
81 | };
82 |
83 | export default withStyles(styles)(Console);
84 |
--------------------------------------------------------------------------------
/src/app/Model.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { observer } from 'mobx-react';
3 | import PropTypes from 'prop-types';
4 | import { makeStyles } from '@mui/styles';
5 | import Box from '@mui/material/Box';
6 | import OptionSelect from './components/OptionSelect';
7 | import OptionCheck from './components/OptionCheck';
8 | import TextField from '@mui/material/TextField';
9 | import Typography from '@mui/material/Typography';
10 |
11 | const useStyles = makeStyles(theme => ({
12 | Model: {
13 | padding: '10px',
14 | display: 'flex',
15 | flexDirection: 'column',
16 | },
17 | form: {
18 | '& > *': {
19 | marginRight: '10px',
20 | }
21 | },
22 | }));
23 |
24 | const Model = ({ run }) => {
25 |
26 | const classes = useStyles();
27 |
28 | // TODO: Check marginTop: 2 hack, doesn't seem exactly aligned to top
29 | if (run.usesModeltestNg) {
30 | return (
31 |
32 |
33 | Select the best-fit model of evolution for a single DNA or protein
34 | alignment
35 |
36 |
37 | );
38 | }
39 | if (run.usesAstral) {
40 | return (
41 |
42 |
43 | Calculate species tree from a set of gene trees
44 |
45 |
46 | );
47 | }
48 | return (
49 |
50 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
79 |
80 | {run.haveRandomSeed ? (
81 | run.setRandomSeed(e.target.value)} />
88 | ) : null}
89 |
90 |
100 |
101 |
102 |
103 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 | );
121 | };
122 |
123 |
124 | Model.propTypes = {
125 | run: PropTypes.object.isRequired,
126 | };
127 |
128 | export default observer(Model);
129 |
--------------------------------------------------------------------------------
/src/app/Output.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { observer } from 'mobx-react';
3 | import PropTypes from 'prop-types';
4 | import { makeStyles } from '@mui/styles';
5 | import Box from '@mui/material/Box';
6 | import TextField from '@mui/material/TextField';
7 | import Button from '@mui/material/Button';
8 | import { Link, Typography } from '@mui/material';
9 | import FileIcon from '@mui/icons-material/InsertDriveFileSharp';
10 | import { join } from 'path';
11 |
12 | const useStyles = makeStyles((theme) => ({
13 | Output: {
14 | width: '100%',
15 | padding: '10px',
16 | },
17 | form: {
18 | width: '100%',
19 | '& > *:not(:first-child)': {
20 | marginTop: theme.spacing(3),
21 | },
22 | },
23 | formItem: {},
24 | result: {
25 | // maxHeight: 200,
26 | // overflowY: 'auto',
27 | },
28 | resultFilenameRow: {
29 | color: theme.palette.primary.contrastText,
30 | display: 'flex',
31 | alignItems: 'flex-end',
32 | cursor: 'pointer',
33 | },
34 | resultFilename: {
35 | color: theme.palette.primary.contrastText,
36 | },
37 | }));
38 |
39 | const Output = ({ run }) => {
40 |
41 | const classes = useStyles();
42 |
43 | const { resultFilenames } = run;
44 | const haveResult = resultFilenames.length > 0;
45 |
46 | return (
47 | (
48 |
49 |
62 | run.setOutputName(e.target.value)}
70 | error={!run.outputNameOk} />
71 |
72 |
73 | { haveResult ? Result for output id '{run.outputName}' : null }
74 | { resultFilenames.map(filename =>
75 | run.openFile(join(run.outputDir, filename))}
79 | underline="hover">
80 |
81 | {filename}
82 |
83 | )}
84 |
85 | { run.haveAlignments || haveResult ? (
86 |
87 |
88 |
89 | ) : null }
90 |
)
91 | );
92 | };
93 |
94 | Output.propTypes = {
95 | run: PropTypes.object.isRequired,
96 | };
97 |
98 | export default observer(Output);
99 |
--------------------------------------------------------------------------------
/src/app/PartitionFileCard.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { observer } from 'mobx-react';
3 | import PropTypes from 'prop-types';
4 | import { makeStyles } from '@mui/styles';
5 | import DeleteForeverIcon from '@mui/icons-material/DeleteForever';
6 | import classNames from 'classnames';
7 | import Chip from '@mui/material/Chip';
8 | import Card from '@mui/material/Card';
9 | import CardHeader from '@mui/material/CardHeader';
10 | import CardContent from '@mui/material/CardContent';
11 |
12 | // const useStyles = makeStyles(theme => ({
13 | const useStyles = makeStyles((theme) => {
14 | return {
15 | PartitionFileCard: {
16 | backgroundColor: theme.palette.input.light,
17 | border: `1px solid ${theme.palette.input.border}`,
18 | height: '200px',
19 | display: 'flex',
20 | flexDirection: 'column',
21 | },
22 | chip: {
23 | height: '30px',
24 | color: theme.palette.input.contrastText,
25 | backgroundColor: theme.palette.input.main,
26 | border: `1px solid ${theme.palette.input.darker}`,
27 | },
28 | deleteChip: {
29 | backgroundColor: 'transparent',
30 | border: 'none',
31 | marginRight: -5,
32 | },
33 | deleteChipIcon: {
34 | opacity: 1,
35 | },
36 | partitionFileContainer: {
37 | overflowY: 'auto',
38 | height: '150px',
39 | },
40 | partitionFileContent: {
41 | color: theme.palette.primary.contrastText,
42 | fontFamily: 'Consolas, "Liberation Mono", Menlo, Courier, monospace',
43 | fontSize: '12px',
44 | height: '100%',
45 | overflowWrap: 'break-word',
46 | whiteSpace: 'pre-wrap',
47 | },
48 | path: {
49 | cursor: 'pointer',
50 | color: theme.palette.secondary.main,
51 | marginLeft: 4,
52 | },
53 | };
54 | });
55 |
56 |
57 | function PartitionFileCard({ className, run }) {
58 | const classes = useStyles();
59 |
60 | if (!run.havePartitionFile) {
61 | return null;
62 | }
63 |
64 | return (
65 |
66 |
73 | }
74 | action={
75 |
76 | }
82 | onDelete={run.removePartitionFile}
83 | title="Remove partition"
84 | />
85 |
86 | }
87 | title={run.partitionFileName}
88 | style={{ paddingBottom: 4 }}
89 | />
90 |
91 |
92 |
93 | { run.partitionFileContent }
94 |
95 |
96 |
97 |
98 | );
99 | }
100 |
101 | PartitionFileCard.propTypes = {
102 | run: PropTypes.object.isRequired,
103 | className: PropTypes.string,
104 | };
105 |
106 | const PartitionFileCardObserver = observer(PartitionFileCard);
107 |
108 | export default PartitionFileCardObserver;
109 |
--------------------------------------------------------------------------------
/src/app/Raxml.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { clipboard } from 'electron';
3 | import { observer } from 'mobx-react';
4 | import PropTypes from 'prop-types';
5 | import Button from '@mui/material/Button';
6 | import { withStyles } from '@mui/styles';
7 | import OptionSelect from './components/OptionSelect';
8 | import Box from '@mui/material/Box';
9 | import Typography from '@mui/material/Typography';
10 | import Tooltip from '@mui/material/Tooltip';
11 | import IconButton from '@mui/material/IconButton';
12 | import FileCopyIcon from '@mui/icons-material/FileCopy';
13 | import { FormHelperText } from '@mui/material';
14 |
15 | const styles = (theme) => ({
16 | Raxml: {
17 | padding: '10px',
18 | width: '100%',
19 | flexShrink: 0,
20 | },
21 | form: {
22 | // '& > *:not(:first-child)': {
23 | '& > *+*': {
24 | marginLeft: '20px',
25 | },
26 | },
27 | formItem: {
28 | // marginRight: '20px',
29 | },
30 | button: {
31 | marginRight: theme.spacing(1),
32 | },
33 | run: {
34 | marginTop: '20px',
35 | display: 'flex',
36 | alignItems: 'center',
37 | },
38 | code: {
39 | color: theme.palette.console.contrastText,
40 | fontFamily: 'Consolas, "Liberation Mono", Menlo, Courier, monospace',
41 | fontSize: '12px',
42 | height: '100%',
43 | width: '100%',
44 | // overflowWrap: 'anywhere', // currently not available in Chrome
45 | whiteSpace: 'pre-wrap',
46 | wordBreak: 'break-all',
47 | },
48 | });
49 |
50 | @observer
51 | class Raxml extends React.Component {
52 | copyCommand = () => {
53 | const { run, store } = this.props;
54 | clipboard.writeText(run.command);
55 | store.setAppSnack();
56 | };
57 |
58 | render() {
59 | const { classes, run } = this.props;
60 |
61 | return (
62 |
63 |
73 |
74 |
75 | {run.modelTestIsRunningOnAlignment ? (
76 |
83 | ) : null}
84 | {run.running ? (
85 |
88 | ) : null}
89 |
99 |
100 |
101 |
102 |
103 |
104 |
109 |
110 |
111 |
112 | {run.command}
113 |
114 | Command
115 |
116 |
117 | );
118 | }
119 | }
120 |
121 | Raxml.propTypes = {
122 | classes: PropTypes.object.isRequired,
123 | run: PropTypes.object.isRequired,
124 | };
125 |
126 | export default withStyles(styles)(Raxml);
127 |
--------------------------------------------------------------------------------
/src/app/TreeCard.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { observer } from 'mobx-react';
3 | import PropTypes from 'prop-types';
4 | import { makeStyles } from '@mui/styles';
5 | import IconButton from '@mui/material/IconButton';
6 | import MoreVertIcon from '@mui/icons-material/MoreVert';
7 | import classNames from 'classnames';
8 | import CircularProgress from "@mui/material/CircularProgress";
9 | import Chip from "@mui/material/Chip";
10 | import Menu from '@mui/material/Menu';
11 | import MenuItem from '@mui/material/MenuItem';
12 | import Card from '@mui/material/Card';
13 | import CardHeader from '@mui/material/CardHeader';
14 | import CardContent from '@mui/material/CardContent';
15 |
16 | const useStyles = makeStyles(theme => ({
17 | TreeCard: {
18 | backgroundColor: theme.palette.input.main,
19 | border: `1px solid ${theme.palette.input.light}`,
20 | },
21 | heading: {
22 | display: 'flex',
23 | alignItems: 'center',
24 | },
25 | content: {
26 | display: 'flex',
27 | alignItems: 'center',
28 | },
29 | name: {
30 | marginRight: theme.spacing(1),
31 | },
32 | chip: {
33 | height: '30px',
34 | backgroundColor: theme.palette.input.dark,
35 | border: `1px solid ${theme.palette.input.light}`,
36 | },
37 | link: {
38 | cursor: 'pointer',
39 | color: theme.palette.secondary.main
40 | },
41 | secondaryText: {
42 | color: theme.palette.input.secondaryText,
43 | },
44 | divider: {
45 | margin: '0 4px',
46 | },
47 | fileInfo: {
48 | color: '#ccc',
49 | fontSize: '0.75em',
50 | marginTop: '0.25em',
51 | overflowWrap: 'break-word',
52 | },
53 | path: {
54 | cursor: 'pointer',
55 | color: theme.palette.secondary.main,
56 | marginLeft: 4,
57 | },
58 | button: {
59 | margin: theme.spacing(1),
60 | },
61 | rightIcon: {
62 | marginLeft: theme.spacing(1),
63 | },
64 | iconSmall: {
65 | fontSize: 20,
66 | },
67 | outputButton: {
68 | marginLeft: theme.spacing(1),
69 | },
70 | loading: {
71 | marginLeft: '10px',
72 | },
73 | remove: {
74 | flexGrow: 1,
75 | display: 'flex',
76 | justifyContent: 'flex-end',
77 | }
78 |
79 | }));
80 |
81 | function TreeCard({ className, tree }) {
82 |
83 | const classes = useStyles();
84 | const [anchorEl, setAnchorEl] = React.useState(null);
85 |
86 | function handleMenuClick(event) {
87 | setAnchorEl(event.currentTarget);
88 | }
89 |
90 | function handleMenuClose() {
91 | setAnchorEl(null);
92 | }
93 |
94 | function closeMenuAndRun(callback) {
95 | return () => {
96 | callback();
97 | setAnchorEl(null);
98 | }
99 | }
100 |
101 | return (
102 |
103 |
106 | }
107 | action={
108 |
109 |
114 |
115 |
116 |
117 |
122 |
123 | }
124 | title={ tree.name }
125 | subheader={ '' }
126 | />
127 |
128 | { tree.loading ? (
129 |
130 |
131 |
132 | ) : null }
133 |
134 |
135 |
136 |
137 | );
138 | };
139 | // {tree.name}
140 |
141 |
142 | TreeCard.propTypes = {
143 | tree: PropTypes.object.isRequired,
144 | className: PropTypes.string,
145 | };
146 |
147 | export default observer(TreeCard);
148 |
--------------------------------------------------------------------------------
/src/app/bootstrap.js:
--------------------------------------------------------------------------------
1 | import { ipcRenderer } from 'electron';
2 | import * as ipc from '../constants/ipc';
3 | import store from './store';
4 | import path from 'path';
5 |
6 | if (process.env.NODE_ENV === 'development') {
7 | console.log('\n========= Bootstrapping initial state... =========\n');
8 | ipcRenderer.send(ipc.ALIGNMENT_EXAMPLE_FILES_GET_REQUEST);
9 | }
10 |
11 | ipcRenderer.on(ipc.ALIGNMENT_EXAMPLE_FILES_GET_SUCCESS, (event, exampleFiles) => {
12 | initDev(exampleFiles);
13 | });
14 |
15 | function initDev(exampleFiles) {
16 | // if (exampleFiles.length === 0) {
17 | // return;
18 | // }
19 | // const exampleFilesDir = path.dirname(exampleFiles[0].path);
20 | const exampleFilesDir = exampleFiles.dir;
21 | // const useFiles = exampleFiles.filter(file => exampleFilenames.includes(file.name));
22 | const useFastaFiles = [
23 | // 'aminoacid.txt',
24 | // 'bin1.txt',
25 | // 'bin2.txt',
26 | // 'binary.txt',
27 | // 'dna.txt',
28 | // 'mixed_data.txt',
29 | // 'multistate.txt',
30 | 'nucleotide.txt',
31 | ].map(filename => ({ path: path.join(exampleFilesDir, 'fasta', filename) }));
32 | const usePhylipFiles = [
33 | // 'AA.txt',
34 | // 'align_allvariant.txt',
35 | // 'aminoacid.txt',
36 | // 'binary.txt',
37 | // 'dna_interleaved_relaxed.txt',
38 | // 'dna_interleaved.txt',
39 | // 'dna_sequential_relaxed.txt',
40 | // 'dna_sequential.txt',
41 | // 'mixed_data.txt',
42 | // 'multistate.txt',
43 | // 'nucleotide.txt',
44 | // 'fail_duplicate_taxon.txt',
45 | // 'fail_bad_base_at_site.txt',
46 | // 'fail_bad_name.txt',
47 | // 'test_invariant_sites.txt',
48 | // 'test_lower_case_bases.txt',
49 | ].map(filename => ({ path: path.join(exampleFilesDir, 'phylip', filename) }));
50 | const useFiles = [].concat(useFastaFiles, usePhylipFiles);
51 | store.activeRun.addAlignments(useFiles);
52 | store.activeRun.setOutputDir(exampleFiles.outdir);
53 | setTimeout(() => {
54 | // store.activeRun.alignments[0].setShowPartition();
55 | // store.citation.show();
56 | }, 1000);
57 | }
58 |
--------------------------------------------------------------------------------
/src/app/components/CodeHighlight.js:
--------------------------------------------------------------------------------
1 | import React, { useRef, useEffect } from 'react';
2 | import PropTypes from 'prop-types';
3 | import { makeStyles } from '@mui/styles';
4 | import Prism from 'prismjs';
5 | import 'prismjs-bibtex';
6 | import 'prismjs/themes/prism.css';
7 | import 'prismjs/themes/prism-okaidia.css'; // coy, dark, funky, okaidia, solarizedlight, tomorrow, twilight
8 |
9 | const useStyles = makeStyles(() => ({
10 | code: {
11 | fontSize: 10,
12 | overflowWrap: 'break-word',
13 | whiteSpace: 'pre-wrap',
14 | }
15 | }));
16 |
17 | function CodeHighlight({ code, language, className }) {
18 | const codeNode = useRef(null);
19 | const classes = useStyles();
20 |
21 | useEffect(() => {
22 | // const code = codeNode.current.textContent;
23 | if (Prism.languages.hasOwnProperty(language)) {
24 | const highlightHTML = Prism.highlight(code, Prism.languages[language], language);
25 | codeNode.current.innerHTML = highlightHTML;
26 | }
27 | }, [code, language]);
28 |
29 | return (
30 |
31 |
32 | { code }
33 |
34 |
35 | );
36 | }
37 |
38 | CodeHighlight.propTypes = {
39 | code: PropTypes.string.isRequired,
40 | language: PropTypes.string.isRequired,
41 | className: PropTypes.string,
42 | };
43 |
44 | export default CodeHighlight;
45 |
--------------------------------------------------------------------------------
/src/app/components/ErrorBoundary.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { Box } from '@mui/material';
3 | import Typography from '@mui/material/Typography';
4 | import ErrorDialog from './ErrorDialog';
5 |
6 | class ErrorBoundary extends React.Component {
7 | constructor(props) {
8 | super(props);
9 |
10 | this.state = {
11 | error: null,
12 | };
13 | }
14 |
15 | static getDerivedStateFromError(error) {
16 | return { error };
17 | }
18 |
19 | componentDidCatch(error, info) {
20 | console.log('Error catched at React boundary:', error, info);
21 | }
22 |
23 | handleClose = () => {
24 | this.setState({ error: null });
25 | }
26 |
27 | render() {
28 | const { error } = this.state;
29 | // const error = new Error(`Minified React error #31; visit https://reactjs.org/docs/error-decoder.html?invariant=31&args[]=object%20with%20keys%20%7Bcmd%2C%20code%2C%20killed%2C%20message%2C%20name%2C%20signal%2C%20stack%2C%20stderr%2C%20stdout%7D&args[]= for the full message or use the non-minified dev environment for full errors and additional helpful warnings.`);
30 | if (!error) {
31 | return this.props.children;
32 | }
33 |
34 | return (
35 |
36 |
37 | Oops! Something went wrong.
38 |
39 |
40 |
41 | );
42 | }
43 | }
44 |
45 | export default ErrorBoundary;
46 |
--------------------------------------------------------------------------------
/src/app/components/ErrorDialog.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import { Box } from '@mui/material';
4 | import Dialog from '@mui/material/Dialog';
5 | import DialogTitle from '@mui/material/DialogTitle';
6 | import DialogContent from '@mui/material/DialogContent';
7 | import DialogActions from '@mui/material/DialogActions';
8 | import DialogContentText from '@mui/material/DialogContentText';
9 | import Accordion from '@mui/material/Accordion';
10 | import AccordionSummary from '@mui/material/AccordionSummary';
11 | import AccordionDetails from '@mui/material/AccordionDetails';
12 | import Typography from '@mui/material/Typography';
13 | import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
14 | import Button from '@mui/material/Button';
15 | import Alert from '@mui/material/Alert';
16 | import { ipcRenderer } from 'electron';
17 | import { reportIssueToGitHub, getMailtoLinkToReportError } from '../../common/utils';
18 | import * as ipc from '../../constants/ipc';
19 |
20 | const handleReload = () => {
21 | ipcRenderer.send(ipc.RELOAD);
22 | }
23 |
24 | export default function ErrorDialog({ error, onClose, needReload, title }) {
25 | const [reported, setReported] = React.useState(false);
26 |
27 | if (!error) {
28 | return null;
29 | }
30 |
31 | const handleReportToGithub = () => {
32 | reportIssueToGitHub(error);
33 | setReported(true);
34 | }
35 |
36 | const handleReportToMail = () => {
37 | setReported(true);
38 | }
39 |
40 | const mailtoContent = getMailtoLinkToReportError(error);
41 |
42 | const closeMessage = needReload ? (
43 | reported ? 'Reload' : 'Ignore and reload'
44 | ) : 'Close';
45 |
46 | const resetAndClose = () => {
47 | setReported(false);
48 | onClose();
49 | };
50 |
51 | const closeHandler = needReload ? handleReload : resetAndClose;
52 |
53 | const CloseAction = (
54 |
55 |
58 |
59 | );
60 |
61 | const Actions = reported ? (
62 | CloseAction
63 | ) : (
64 |
65 |
74 |
82 |
85 |
86 | );
87 |
88 | const Message = !reported ? (
89 |
90 | Please help us solve the issue by reporting it.
91 |
92 | ) : (
93 |
97 | Thanks for reporting the issue!
98 |
99 | );
100 |
101 | const GenericErrorDialog = (
102 |
137 | );
138 |
139 | const UserFixErrorDialog = (
140 |
156 | );
157 |
158 | let returnDialog = GenericErrorDialog;
159 | if (error.isUserFix) {
160 | returnDialog = UserFixErrorDialog;
161 | }
162 |
163 | return returnDialog;
164 | }
165 |
166 | ErrorDialog.propTypes = {
167 | error: PropTypes.object,
168 | onClose: PropTypes.func.isRequired,
169 | needReload: PropTypes.bool,
170 | title: PropTypes.string,
171 | }
172 |
--------------------------------------------------------------------------------
/src/app/components/ModifiedDialog.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import PropTypes from 'prop-types';
3 | import { Box } from '@mui/material';
4 | import Dialog from '@mui/material/Dialog';
5 | import DialogTitle from '@mui/material/DialogTitle';
6 | import DialogContent from '@mui/material/DialogContent';
7 | import DialogActions from '@mui/material/DialogActions';
8 | import DialogContentText from '@mui/material/DialogContentText';
9 | import Accordion from '@mui/material/Accordion';
10 | import AccordionSummary from '@mui/material/AccordionSummary';
11 | import AccordionDetails from '@mui/material/AccordionDetails';
12 | import Typography from '@mui/material/Typography';
13 | import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
14 | import Button from '@mui/material/Button';
15 |
16 | export default function ModifiedDialog({ show, onClose, messages }) {
17 | if (!show) {
18 | return null;
19 | }
20 |
21 | const GenericDialog = (
22 |
53 | );
54 |
55 | let returnDialog = GenericDialog;
56 | return returnDialog;
57 | }
58 |
59 | ModifiedDialog.propTypes = {
60 | error: PropTypes.object,
61 | onClose: PropTypes.func.isRequired,
62 | }
63 |
--------------------------------------------------------------------------------
/src/app/components/OptionCheck.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { observer } from 'mobx-react';
3 | import PropTypes from 'prop-types';
4 | import FormControlLabel from '@mui/material/FormControlLabel';
5 | import Checkbox from '@mui/material/Checkbox';
6 | import { FormControl } from '@mui/material';
7 |
8 |
9 | const OptionCheck = observer(({ option, className }) => {
10 | if (option.notAvailable) {
11 | return null;
12 | }
13 | return (
14 |
15 | option.setValue(e.target.checked)}
21 | value={option.title}
22 | color="primary"
23 | />
24 | }
25 | label={option.title}
26 | />
27 |
28 | );
29 | });
30 |
31 | OptionCheck.propTypes = {
32 | option: PropTypes.object.isRequired,
33 | className: PropTypes.string,
34 | };
35 |
36 | export default OptionCheck;
37 |
--------------------------------------------------------------------------------
/src/app/components/OptionSelect.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { observer } from 'mobx-react';
3 | import PropTypes from 'prop-types';
4 | import FormControl from '@mui/material/FormControl';
5 | import FormHelperText from '@mui/material/FormHelperText';
6 | import Select from '@mui/material/Select';
7 | import MenuItem from '@mui/material/MenuItem';
8 | import TextField from '@mui/material/TextField';
9 |
10 |
11 | const OptionSelect = observer(({ option, className }) => {
12 | if (option.notAvailable || option.options.length === 0) {
13 | return null;
14 | }
15 | if (option.options.length === 1) {
16 | // No options to change to, render as a text field instead.
17 | return (
18 | ()
31 | );
32 | }
33 |
34 | return (
35 |
36 |
51 | {option.title}
52 |
53 | );
54 | });
55 |
56 | OptionSelect.propTypes = {
57 | option: PropTypes.object.isRequired,
58 | className: PropTypes.string,
59 | };
60 |
61 | export default OptionSelect;
62 |
--------------------------------------------------------------------------------
/src/app/components/OptionTextField.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { observer } from 'mobx-react';
3 | import PropTypes from 'prop-types';
4 | import TextField from '@mui/material/TextField';
5 |
6 | const OptionTextField = observer(({ option, className }) => {
7 | if (option.notAvailable) {
8 | return null;
9 | }
10 | return (
11 | option.setValue(e.target.value)}
21 | error={option.haveError} />
22 | );
23 | });
24 |
25 | OptionTextField.propTypes = {
26 | option: PropTypes.object.isRequired,
27 | className: PropTypes.string,
28 | };
29 |
30 | export default OptionTextField;
31 |
--------------------------------------------------------------------------------
/src/app/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { observer } from 'mobx-react';
3 | import { StyledEngineProvider, ThemeProvider } from '@mui/material/styles';
4 | import * as Sentry from '@sentry/electron/renderer';
5 |
6 | import theme from './theme';
7 | import App from './App';
8 | import ErrorBoundary from './components/ErrorBoundary';
9 | import store from './store';
10 | import { is } from '../common/utils';
11 |
12 | import './bootstrap';
13 |
14 | is.development ? null : Sentry.init({
15 | dsn: 'https://d92efa46c2ba43f38250b202c791a2c2@o117148.ingest.sentry.io/6517975',
16 | });
17 |
18 | const Index = () => {
19 | const { light, dark } = theme;
20 | const muiTheme = store.config.isDarkMode ? dark : light;
21 | return (
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | );
30 | }
31 |
32 | export default observer(Index);
33 |
34 |
--------------------------------------------------------------------------------
/src/app/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "experimentalDecorators": true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/src/app/store/AppStore.js:
--------------------------------------------------------------------------------
1 | import { observable, computed, action } from 'mobx';
2 | import StoreBase from './StoreBase';
3 | import Citation from './Citation';
4 | import Config from './Config';
5 |
6 | class AppStore extends StoreBase {
7 | citation = new Citation();
8 | config = new Config();
9 |
10 | @observable version = undefined;
11 |
12 | @observable showAppSnack = false;
13 |
14 | @action setAppSnack = () => {
15 | this.showAppSnack = true;
16 | };
17 |
18 | @action clearAppSnack = () => {
19 | this.showAppSnack = false;
20 | };
21 |
22 | constructor() {
23 | super();
24 | }
25 | }
26 |
27 | export default AppStore;
28 |
--------------------------------------------------------------------------------
/src/app/store/AstralTree.js:
--------------------------------------------------------------------------------
1 | import { observable, computed, action, runInAction } from 'mobx';
2 |
3 | import InputFile from './InputFile';
4 |
5 |
6 | class AstralTree extends InputFile {
7 | constructor(run, path) {
8 | super(run, path);
9 | }
10 |
11 | @action
12 | remove = () => {
13 | this.run.removeAstralTree();
14 | };
15 | }
16 |
17 | export default AstralTree;
--------------------------------------------------------------------------------
/src/app/store/Citation.js:
--------------------------------------------------------------------------------
1 | import { observable, action, computed } from 'mobx';
2 | import { clipboard } from 'electron';
3 |
4 | export default class Citation {
5 | @observable visible = false;
6 |
7 | formats = [
8 | { value: 'txt', name: 'Plain text' },
9 | { value: 'ris', name: 'RIS/EndNote' },
10 | { value: 'bib', name: 'BibTeX' },
11 | ];
12 |
13 | @observable format = 'txt';
14 | @action setFormat = (format) => {
15 | this.format = format;
16 | };
17 |
18 | content = [
19 | {
20 | name: 'raxmlGUI',
21 | bib: `@article{https://doi.org/10.1111/2041-210X.13512,
22 | author = {Edler, Daniel and Klein, Johannes and Antonelli, Alexandre and Silvestro, Daniele},
23 | title = {raxmlGUI 2.0: A graphical interface and toolkit for phylogenetic analyses using RAxML},
24 | journal = {Methods in Ecology and Evolution},
25 | volume = {12},
26 | number = {2},
27 | pages = {373-377},
28 | keywords = {bioinformatics, evolutionary biology, molecular biology, phylogenetics, software},
29 | doi = {https://doi.org/10.1111/2041-210X.13512},
30 | url = {https://besjournals.onlinelibrary.wiley.com/doi/abs/10.1111/2041-210X.13512},
31 | eprint = {https://besjournals.onlinelibrary.wiley.com/doi/pdf/10.1111/2041-210X.13512},
32 | year = {2021}
33 | }`,
34 | ris: `
35 | TY - JOUR
36 | T1 - raxmlGUI 2.0: A graphical interface and toolkit for phylogenetic analyses using RAxML
37 | AU - Edler, Daniel
38 | AU - Klein, Johannes
39 | AU - Antonelli, Alexandre
40 | AU - Silvestro, Daniele
41 | Y1 - 2021/02/01
42 | PY - 2021
43 | DA - 2021/02/01
44 | N1 - https://doi.org/10.1111/2041-210X.13512
45 | DO - https://doi.org/10.1111/2041-210X.13512
46 | T2 - Methods in Ecology and Evolution
47 | JF - Methods in Ecology and Evolution
48 | JO - Methods in Ecology and Evolution
49 | JA - Methods Ecol Evol
50 | SP - 373
51 | EP - 377
52 | VL - 12
53 | IS - 2
54 | KW - bioinformatics
55 | KW - evolutionary biology
56 | KW - molecular biology
57 | KW - phylogenetics
58 | KW - software
59 | PB - John Wiley & Sons, Ltd
60 | SN - 2041-210X
61 | M3 - https://doi.org/10.1111/2041-210X.13512
62 | UR - https://doi.org/10.1111/2041-210X.13512
63 | Y2 - 2021/02/18
64 | ER -
65 | `,
66 | txt: `Edler, D, Klein, J, Antonelli, A, Silvestro, D. raxmlGUI 2.0: A graphical interface and toolkit for phylogenetic analyses using RAxML. Methods Ecol Evol. 2021; 12: 373– 377. https://doi.org/10.1111/2041-210X.13512`,
67 | },
68 | {
69 | name: 'RAxML',
70 | bib: `@article{10.1093/bioinformatics/btu033,
71 | author = {Stamatakis, Alexandros},
72 | title = "{RAxML version 8: a tool for phylogenetic analysis and post-analysis of large phylogenies}",
73 | journal = {Bioinformatics},
74 | volume = {30},
75 | number = {9},
76 | pages = {1312-1313},
77 | year = {2014},
78 | month = {01},
79 | issn = {1367-4803},
80 | doi = {10.1093/bioinformatics/btu033},
81 | url = {https://doi.org/10.1093/bioinformatics/btu033},
82 | eprint = {http://oup.prod.sis.lan/bioinformatics/article-pdf/30/9/1312/17345185/btu033.pdf},
83 | }`,
84 | ris: `Provider: Silverchair
85 | Database: Oxford University Press
86 | Content: text/plain; charset="UTF-8"
87 |
88 | TY - JOUR
89 | AU - Stamatakis, Alexandros
90 | T1 - RAxML version 8: a tool for phylogenetic analysis and post-analysis of large phylogenies
91 | T2 - Bioinformatics
92 | PY - 2014
93 | Y1 - 2014/01/21/
94 | DO - 10.1093/bioinformatics/btu033
95 | JO - Bioinformatics
96 | JA - bioinformatics
97 | VL - 30
98 | IS - 9
99 | SP - 1312
100 | EP - 1313
101 | SN - 1367-4803
102 | Y2 - 10/17/2019
103 | UR - https://doi.org/10.1093/bioinformatics/btu033
104 | ER - `,
105 | txt: `Alexandros Stamatakis, RAxML version 8: a tool for phylogenetic analysis and post-analysis of large phylogenies, Bioinformatics, Volume 30, Issue 9, 1 May 2014, Pages 1312–1313, https://doi.org/10.1093/bioinformatics/btu033`,
106 | },
107 | {
108 | name: 'RAxML-NG',
109 | bib: `@article{10.1093/bioinformatics/btz305,
110 | author = {Kozlov, Alexey M and Darriba, Diego and Flouri, Tomáš and Morel, Benoit and Stamatakis, Alexandros},
111 | title = "{RAxML-NG: a fast, scalable and user-friendly tool for maximum likelihood phylogenetic inference}",
112 | journal = {Bioinformatics},
113 | volume = {35},
114 | number = {21},
115 | pages = {4453-4455},
116 | year = {2019},
117 | month = {05},
118 | issn = {1367-4803},
119 | doi = {10.1093/bioinformatics/btz305},
120 | url = {https://doi.org/10.1093/bioinformatics/btz305},
121 | eprint = {https://academic.oup.com/bioinformatics/article-pdf/35/21/4453/30330793/btz305.pdf},
122 | }`,
123 | ris: `Provider: Silverchair
124 | Database: Oxford University Press
125 | Content: text/plain; charset="UTF-8"
126 |
127 | TY - JOUR
128 | AU - Kozlov, Alexey M
129 | AU - Darriba, Diego
130 | AU - Flouri, Tomáš
131 | AU - Morel, Benoit
132 | AU - Stamatakis, Alexandros
133 | T1 - RAxML-NG: a fast, scalable and user-friendly tool for maximum likelihood phylogenetic inference
134 | PY - 2019
135 | Y1 - 2019/05/09/
136 | DO - 10.1093/bioinformatics/btz305
137 | JO - Bioinformatics
138 | JA - Bioinformatics
139 | VL - 35
140 | IS - 21
141 | SP - 4453
142 | EP - 4455
143 | SN - 1367-4803
144 | Y2 - 7/17/2020
145 | UR - https://doi.org/10.1093/bioinformatics/btz305
146 | ER - `,
147 | txt: `Alexey M Kozlov, Diego Darriba, Tomáš Flouri, Benoit Morel, Alexandros Stamatakis, RAxML-NG: a fast, scalable and user-friendly tool for maximum likelihood phylogenetic inference, Bioinformatics, Volume 35, Issue 21, 1 November 2019, Pages 4453–4455, https://doi.org/10.1093/bioinformatics/btz305`,
148 | },
149 | {
150 | name: 'ModelTest-NG',
151 | bib: `@article{10.1093/molbev/msz189,
152 | author = {Darriba, Diego and Posada, David and Kozlov, Alexey M and Stamatakis, Alexandros and Morel, Benoit and Flouri, Tomas},
153 | title = "{ModelTest-NG: A New and Scalable Tool for the Selection of DNA and Protein Evolutionary Models}",
154 | journal = {Molecular Biology and Evolution},
155 | volume = {37},
156 | number = {1},
157 | pages = {291-294},
158 | year = {2019},
159 | month = {08},
160 | issn = {0737-4038},
161 | doi = {10.1093/molbev/msz189},
162 | url = {https://doi.org/10.1093/molbev/msz189},
163 | eprint = {https://academic.oup.com/mbe/article-pdf/37/1/291/32085561/msz189.pdf},
164 | }`,
165 | ris: `Provider: Silverchair
166 | Database: Oxford University Press
167 | Content: text/plain; charset="UTF-8"
168 |
169 | TY - JOUR
170 | AU - Darriba, Diego
171 | AU - Posada, David
172 | AU - Kozlov, Alexey M
173 | AU - Stamatakis, Alexandros
174 | AU - Morel, Benoit
175 | AU - Flouri, Tomas
176 | T1 - ModelTest-NG: A New and Scalable Tool for the Selection of DNA and Protein Evolutionary Models
177 | PY - 2020
178 | Y1 - 2020/01/01
179 | DO - 10.1093/molbev/msz189
180 | JO - Molecular Biology and Evolution
181 | JA - Mol Biol Evol
182 | VL - 37
183 | IS - 1
184 | SP - 291
185 | EP - 294
186 | SN - 0737-4038
187 | Y2 - 9/5/2020
188 | UR - https://doi.org/10.1093/molbev/msz189
189 | ER - `,
190 | txt: `Diego Darriba, David Posada, Alexey M Kozlov, Alexandros Stamatakis, Benoit Morel, Tomas Flouri, ModelTest-NG: A New and Scalable Tool for the Selection of DNA and Protein Evolutionary Models, Molecular Biology and Evolution, Volume 37, Issue 1, January 2020, Pages 291–294, https://doi.org/10.1093/molbev/msz189`,
191 | },
192 | ];
193 |
194 | @computed
195 | get allText() {
196 | return this.content.map((ref) => ref[this.format]).join('\n');
197 | }
198 |
199 | @action
200 | show = () => {
201 | this.visible = true;
202 | };
203 | @action
204 | hide = () => {
205 | this.visible = false;
206 | };
207 |
208 | copyToClipboard = () => {
209 | clipboard.writeText(this.allText);
210 | console.log('Copied citation to clipboard');
211 | };
212 | }
213 |
214 |
--------------------------------------------------------------------------------
/src/app/store/Config.js:
--------------------------------------------------------------------------------
1 | import { observable, action } from 'mobx';
2 | import * as ipc from '../../constants/ipc';
3 | import StoreBase from './StoreBase';
4 | import Store from 'electron-store';
5 |
6 | export const store = new Store();
7 |
8 | export default class Config extends StoreBase {
9 |
10 | constructor() {
11 | super();
12 | this.listen();
13 | }
14 |
15 | @observable isDarkMode = store.get('darkMode')
16 |
17 | @action
18 | setDarkMode = value => {
19 | value = !!value;
20 | store.set('darkMode', value);
21 | this.isDarkMode = value;
22 | }
23 |
24 | onLightMode = () => {
25 | this.setDarkMode(false);
26 | }
27 |
28 | onDarkMode = () => {
29 | this.setDarkMode(true);
30 | }
31 |
32 | listen = () => {
33 | this.listenTo(ipc.LIGHT_MODE, this.onLightMode);
34 | this.listenTo(ipc.DARK_MODE, this.onDarkMode);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/app/store/InputFile.js:
--------------------------------------------------------------------------------
1 | import { observable, computed, action, runInAction } from 'mobx';
2 | import { ipcRenderer } from 'electron';
3 | import parsePath from 'parse-filepath';
4 |
5 | import * as ipc from '../../constants/ipc';
6 | import StoreBase from './StoreBase';
7 |
8 | class InputFile extends StoreBase {
9 | run = null;
10 |
11 | constructor(run, path) {
12 | super();
13 | this.run = run;
14 | this.path = path;
15 | }
16 |
17 | // Observable because it may change on correcting errors or reformating of alignments
18 | @observable path = '';
19 |
20 | @computed
21 | get id() {
22 | return `${this.run.id}_${this.path}`;
23 | }
24 |
25 | @computed
26 | get name() {
27 | return parsePath(this.path).name;
28 | }
29 |
30 | @computed
31 | get dir() {
32 | return parsePath(this.path).dir;
33 | }
34 |
35 | @computed
36 | get base() {
37 | return parsePath(this.path).base;
38 | }
39 |
40 | @computed
41 | get filename() {
42 | return parsePath(this.path).base;
43 | }
44 |
45 | @computed
46 | get ok() {
47 | return this.path !== '';
48 | }
49 |
50 | @action
51 | openFile = () => {
52 | ipcRenderer.send(ipc.FILE_OPEN, this.path);
53 | };
54 |
55 | @action
56 | showFileInFolder = () => {
57 | ipcRenderer.send(ipc.FILE_SHOW_IN_FOLDER, this.path);
58 | };
59 | }
60 |
61 | export default InputFile;
--------------------------------------------------------------------------------
/src/app/store/Option.js:
--------------------------------------------------------------------------------
1 | import { observable, computed, action } from 'mobx';
2 | import { mixed } from 'yup';
3 |
4 | class Option {
5 | /**
6 | * Reactive option with optional validation
7 | * @param {Object} run
8 | * @param {*} defaultValue
9 | * @param {String} title
10 | * @param {String} description
11 | * @param {String} hoverInfo
12 | * @param {yup|undefined} schema
13 | */
14 | constructor(run, defaultValue, title, description, hoverInfo, {
15 | schema = undefined,
16 | allowOnlyValidChange = false,
17 | helperText = '',
18 | } = {}) {
19 | this.run = run;
20 | this.defaultValue = defaultValue;
21 | this.title = title;
22 | this.description = description;
23 | this.hoverInfo = hoverInfo;
24 | this.schema = schema ? schema : mixed();
25 | this.allowOnlyValidChange = allowOnlyValidChange;
26 | this.helperText = helperText;
27 | }
28 | @observable value = this.defaultValue;
29 | @action setValue = (value) => {
30 | const isValid = this.schema.isValidSync(value);
31 | if (!this.allowOnlyValidChange || isValid) {
32 | this.value = isValid ? this.schema.cast(value) : value;
33 | }
34 | }
35 | @action reset() { this.value = this.defaultValue; }
36 | @computed get isDefault() { return this.value === this.defaultValue; }
37 | @computed get error() {
38 | try {
39 | this.schema.validateSync(this.value);
40 | return null;
41 | } catch (err) {
42 | return err;
43 | }
44 | }
45 | @computed get haveError() { return this.error !== null; }
46 | @computed get errorMessage() { return this.haveError ? this.error.message : '' }
47 | }
48 |
49 | export { Option as default };
50 |
--------------------------------------------------------------------------------
/src/app/store/RunList.js:
--------------------------------------------------------------------------------
1 | import { observable, computed, action } from 'mobx';
2 | import Run from './Run';
3 | import * as ipc from '../../constants/ipc';
4 | import AppStore from './AppStore';
5 |
6 | class RunList extends AppStore {
7 | @observable runs = [];
8 | @observable activeIndex = 0;
9 |
10 | constructor() {
11 | super();
12 | this.addRun();
13 | this.listen();
14 | }
15 |
16 | @observable error = null;
17 | @action
18 | clearError = () => {
19 | this.error = null;
20 | };
21 |
22 | @computed
23 | get activeRun() {
24 | return this.runs[this.activeIndex];
25 | }
26 |
27 | @action
28 | addRun = () => {
29 | let maxId = 0;
30 | this.runs.forEach((run) => (maxId = Math.max(run.id, maxId)));
31 | this.runs.push(new Run(this, maxId + 1));
32 | this.activeIndex = this.runs.length - 1;
33 | };
34 |
35 | @action
36 | deleteRun = (run) => {
37 | run.dispose();
38 | const runIndex = this.runs.findIndex((m) => m.id === run.id);
39 | this.runs.splice(runIndex, 1);
40 | if (this.runs.length === 0) {
41 | this.runs.push(new Run(this, 1));
42 | }
43 | this.activeIndex = Math.min(this.runs.length - 1, this.activeIndex);
44 | };
45 |
46 | @action
47 | setActive = (index) => {
48 | this.activeIndex = index;
49 | };
50 |
51 | @action
52 | deleteActive = () => {
53 | this.deleteRun(this.activeRun);
54 | };
55 |
56 | @action
57 | onError = (error) => {
58 | this.error = error;
59 | };
60 |
61 | @action
62 | onUnhandledError = (event, { error }) => {
63 | console.log(`Unhandled error:`, error);
64 | this.error = error;
65 | };
66 |
67 | @action
68 | onBackboneConstraint = (event, params) => {
69 | this.activeRun.useBackboneConstraint =
70 | !this.activeRun.useBackboneConstraint;
71 | };
72 |
73 | @action
74 | onMultifurcatingConstraint = (event, params) => {
75 | this.activeRun.useMultifurcatingConstraint =
76 | !this.activeRun.useMultifurcatingConstraint;
77 | };
78 |
79 | listen = () => {
80 | this.listenTo(ipc.UNHANDLED_ERROR, this.onUnhandledError);
81 | this.listenTo(ipc.ADD_RUN, this.addRun);
82 | this.listenTo(ipc.REMOVE_RUN, this.deleteActive);
83 | this.listenTo(ipc.TOGGLE_BACKBONE_CONSTRAINT, this.onBackboneConstraint);
84 | this.listenTo(
85 | ipc.TOGGLE_MULTIFURCATING_CONSTRAINT,
86 | this.onMultifurcatingConstraint
87 | );
88 | };
89 |
90 | generateReport = ({ maxStdoutLength = 1000 } = {}) => {
91 | return this.activeRun.generateReport({ maxStdoutLength });
92 | };
93 | }
94 |
95 | export default RunList;
96 |
--------------------------------------------------------------------------------
/src/app/store/StoreBase.js:
--------------------------------------------------------------------------------
1 | import { ipcRenderer } from 'electron';
2 |
3 | import * as ipc from '../../constants/ipc';
4 |
5 | export default class StoreBase {
6 | listeners = [];
7 |
8 | constructor() {
9 | this._init();
10 | this._listen();
11 | }
12 |
13 | listenTo = (channel, listener) => {
14 | ipcRenderer.on(channel, listener);
15 | this.listeners.push([channel, listener]);
16 | };
17 |
18 | unlisten = () => {
19 | while (!this.listeners.length > 0) {
20 | const [channel, listener] = this.listeners.pop();
21 | ipcRenderer.removeListener(channel, listener);
22 | }
23 | };
24 |
25 | dispose = () => {
26 | this.unlisten();
27 | };
28 |
29 | _init = () => {
30 | ipcRenderer.send(ipc.INIT_APP_STATE);
31 | };
32 |
33 | _listen = () => {
34 | this.listenTo(ipc.INIT_APP_STATE_RECEIVED, this._initAppState);
35 | };
36 |
37 | _initAppState = (event, { version }) => {
38 | this.version = version;
39 | };
40 | }
41 |
--------------------------------------------------------------------------------
/src/app/store/index.js:
--------------------------------------------------------------------------------
1 | import RunList from './RunList';
2 |
3 | const store = new RunList();
4 |
5 | window.store = store;
6 | export default store;
7 |
--------------------------------------------------------------------------------
/src/app/theme/index.js:
--------------------------------------------------------------------------------
1 | import { createTheme } from '@mui/material/styles';
2 |
3 | const darkTheme = {
4 | palette: {
5 | mode: 'dark',
6 | primary: {
7 | background: 'hsl(29, 5%, 5%)',
8 | main: 'hsl(0, 0%, 100%)',
9 | contrastText: '#ddd',
10 | },
11 | secondary: {
12 | main: 'hsl(0, 0%, 76%)',
13 | contrastText: '#333',
14 | },
15 | model: {
16 | background: 'hsla(33, 27%, 10%, 1)',
17 | border: 'hsla(33, 27%, 30%, 1)',
18 | lighter: 'hsla(33, 27%, 43%, 1)',
19 | light: 'hsla(33, 27%, 27%, 1)',
20 | main: 'hsla(33, 27%, 23%, 1)',
21 | dark: 'hsla(33, 27%, 18%, 1)',
22 | darker: 'hsla(33, 27%, 12%, 1)',
23 | secondaryText: 'hsla(33, 9%, 54%, 1)',
24 | contrastText: '#fefefe',
25 | shadow: 'hsla(33, 2%, 20%, 1)',
26 | },
27 | input: {
28 | background: 'hsla(92, 27%, 10%, 1)',
29 | border: 'hsla(92, 27%, 30%, 1)',
30 | lighter: 'hsla(92, 27%, 43%, 1)',
31 | light: 'hsla(92, 27%, 27%, 1)',
32 | main: 'hsla(92, 27%, 23%, 1)',
33 | dark: 'hsla(92, 27%, 18%, 1)',
34 | darker: 'hsla(92, 27%, 12%, 1)',
35 | secondaryText: 'hsla(92, 9%, 54%, 1)',
36 | contrastText: '#fefefe',
37 | shadow: 'hsla(92, 2%, 20%, 1)',
38 | },
39 | output: {
40 | background: 'hsla(211, 27%, 10%, 1)',
41 | border: 'hsla(211, 27%, 30%, 1)',
42 | lighter: 'hsla(211, 27%, 43%, 1)',
43 | light: 'hsla(211, 27%, 27%, 1)',
44 | main: 'hsla(211, 27%, 23%, 1)',
45 | dark: 'hsla(211, 27%, 18%, 1)',
46 | darker: 'hsla(211, 27%, 12%, 1)',
47 | secondaryText: 'hsla(211, 9%, 54%, 1)',
48 | contrastText: '#fefefe',
49 | shadow: 'hsla(211, 2%, 20%, 1)',
50 | },
51 | raxml: {
52 | border: 'hsla(211, 0%, 28%, 1)',
53 | background: 'hsla(211, 0%, 10%, 1)',
54 | lighter: 'hsla(211, 0%, 12%, 1)',
55 | light: 'hsla(211, 0%, 18%, 1)',
56 | main: 'hsla(211, 0%, 23%, 1)',
57 | dark: 'hsla(211, 0%, 35%, 1)',
58 | darker: 'hsla(211, 0%, 41%, 1)',
59 | secondaryText: 'hsla(211, 0%, 54%, 1)',
60 | contrastText: '#fefefe',
61 | shadow: 'hsla(211, 2%, 10%, 1)',
62 | },
63 | console: {
64 | border: 'hsla(211, 0%, 28%, 1)',
65 | background: 'hsla(211, 0%, 10%, 1)',
66 | lighter: 'hsla(211, 0%, 12%, 1)',
67 | light: 'hsla(211, 0%, 18%, 1)',
68 | main: 'hsla(211, 0%, 23%, 1)',
69 | dark: 'hsla(211, 0%, 35%, 1)',
70 | darker: 'hsla(211, 0%, 41%, 1)',
71 | secondaryText: 'hsla(211, 0%, 54%, 1)',
72 | contrastText: '#fefefe',
73 | shadow: 'hsla(211, 2%, 10%, 1)',
74 | },
75 | status: {
76 | border: 'hsla(211, 0%, 28%, 1)',
77 | background: 'hsla(211, 0%, 10%, 1)',
78 | lighter: 'hsla(211, 0%, 12%, 1)',
79 | light: 'hsla(211, 0%, 18%, 1)',
80 | main: 'hsla(211, 0%, 23%, 1)',
81 | dark: 'hsla(211, 0%, 35%, 1)',
82 | darker: 'hsla(211, 0%, 41%, 1)',
83 | secondaryText: 'hsla(211, 0%, 54%, 1)',
84 | contrastText: '#fefefe',
85 | shadow: 'hsla(211, 2%, 10%, 1)',
86 | },
87 | // error: amber,
88 | error: {
89 | main: '#f2401b',
90 | },
91 | // Used by `getContrastText()` to maximize the contrast between the background and
92 | // the text.
93 | contrastThreshold: 3,
94 | // Used by the functions below to shift a color's luminance by approximately
95 | // two indexes within its tonal palette.
96 | // E.g., shift from Red 500 to Red 300 or Red 700.
97 | tonalOffset: 0.2,
98 | },
99 | // Migration to typography v2
100 | typography: {
101 | useNextVariants: true,
102 | },
103 | };
104 |
105 | const lightTheme = {
106 | palette: {
107 | mode: 'light',
108 | primary: {
109 | background: 'hsl(29, 99%, 99%)',
110 | border: 'hsl(0, 0%, 0%)',
111 | main: 'hsl(0, 0%, 0%)',
112 | contrastText: '#333',
113 | },
114 | secondary: {
115 | main: 'hsl(0, 0%, 76%)',
116 | contrastText: '#333',
117 | },
118 | model: {
119 | background: 'hsla(33, 34%, 98%, 1)',
120 | border: 'hsla(33, 34%, 73%, 1)',
121 | lighter: 'hsla(33, 34%, 93%, 1)',
122 | light: 'hsla(33, 34%, 87%, 1)',
123 | main: 'hsla(33, 34%, 83%, 1)',
124 | dark: 'hsla(33, 34%, 77%, 1)',
125 | darker: 'hsla(33, 34%, 41%, 1)',
126 | secondaryText: 'hsla(33, 9%, 54%, 1)',
127 | contrastText: '#333',
128 | shadow: 'hsla(33, 2%, 64%, 1)',
129 | },
130 | input: {
131 | background: 'hsla(92, 34%, 98%, 1)',
132 | border: 'hsla(92, 34%, 73%, 1)',
133 | lighter: 'hsla(92, 34%, 93%, 1)',
134 | light: 'hsla(92, 34%, 87%, 1)',
135 | main: 'hsla(92, 34%, 83%, 1)',
136 | dark: 'hsla(92, 34%, 77%, 1)',
137 | darker: 'hsla(92, 34%, 41%, 1)',
138 | secondaryText: 'hsla(92, 9%, 54%, 1)',
139 | contrastText: '#333',
140 | shadow: 'hsla(92, 2%, 64%, 1)',
141 | },
142 | output: {
143 | background: 'hsla(211, 34%, 98%, 1)',
144 | border: 'hsla(211, 34%, 73%, 1)',
145 | lighter: 'hsla(211, 34%, 93%, 1)',
146 | light: 'hsla(211, 34%, 87%, 1)',
147 | main: 'hsla(211, 34%, 83%, 1)',
148 | dark: 'hsla(211, 34%, 77%, 1)',
149 | darker: 'hsla(211, 34%, 41%, 1)',
150 | secondaryText: 'hsla(211, 9%, 54%, 1)',
151 | contrastText: '#333',
152 | shadow: 'hsla(211, 2%, 64%, 1)',
153 | },
154 | raxml: {
155 | border: 'hsla(211, 0%, 10%, 1)',
156 | background: 'hsla(211, 0%, 98%, 1)',
157 | lighter: 'hsla(211, 0%, 96%, 1)',
158 | light: 'hsla(211, 0%, 96%, 1)',
159 | main: 'hsla(211, 0%, 90%, 1)',
160 | dark: 'hsla(211, 0%, 77%, 1)',
161 | darker: 'hsla(211, 0%, 41%, 1)',
162 | secondaryText: 'hsla(211, 0%, 54%, 1)',
163 | contrastText: '#333',
164 | shadow: 'hsla(211, 2%, 64%, 1)',
165 | },
166 | console: {
167 | border: 'hsla(211, 0%, 10%, 1)',
168 | background: 'hsla(211, 0%, 98%, 1)',
169 | lighter: 'hsla(211, 0%, 96%, 1)',
170 | light: 'hsla(211, 0%, 96%, 1)',
171 | main: 'hsla(211, 0%, 90%, 1)',
172 | dark: 'hsla(211, 0%, 77%, 1)',
173 | darker: 'hsla(211, 0%, 41%, 1)',
174 | secondaryText: 'hsla(211, 0%, 54%, 1)',
175 | contrastText: '#333',
176 | shadow: 'hsla(211, 2%, 64%, 1)',
177 | },
178 | status: {
179 | border: 'hsla(211, 0%, 73%, 1)',
180 | background: 'hsla(211, 0%, 98%, 1)',
181 | lighter: 'hsla(211, 0%, 96%, 1)',
182 | light: 'hsla(211, 0%, 96%, 1)',
183 | main: 'hsla(211, 0%, 90%, 1)',
184 | dark: 'hsla(211, 0%, 77%, 1)',
185 | darker: 'hsla(211, 0%, 41%, 1)',
186 | secondaryText: 'hsla(211, 0%, 54%, 1)',
187 | contrastText: '#333',
188 | shadow: 'hsla(211, 2%, 64%, 1)',
189 | },
190 | // error: amber,
191 | error: {
192 | main: '#f2401b',
193 | },
194 | // Used by `getContrastText()` to maximize the contrast between the background and
195 | // the text.
196 | contrastThreshold: 3,
197 | // Used by the functions below to shift a color's luminance by approximately
198 | // two indexes within its tonal palette.
199 | // E.g., shift from Red 500 to Red 300 or Red 700.
200 | tonalOffset: 0.2
201 | },
202 | // Migration to typography v2
203 | typography: {
204 | useNextVariants: true
205 | }
206 | };
207 |
208 | export default {
209 | light: createTheme(lightTheme),
210 | dark: createTheme(darkTheme)
211 | };
212 |
--------------------------------------------------------------------------------
/src/common/errors.js:
--------------------------------------------------------------------------------
1 | export default class UserFixError extends Error {
2 | constructor(message) {
3 | super(message);
4 | this.name = "UserFixError";
5 | this.isUserFix = true;
6 | }
7 | }
8 |
9 |
--------------------------------------------------------------------------------
/src/common/fastaParser.js:
--------------------------------------------------------------------------------
1 | import UserFixError from "./errors";
2 |
3 | export const isFasta = (lines) => {
4 | for (let i = 0; i < lines.length; ++i) {
5 | const line = lines[0].trim();
6 | if (line.length === 0 || line[0] === '#') {
7 | continue;
8 | }
9 | if (line[0] === '>') {
10 | return true;
11 | }
12 | }
13 | return false;
14 | }
15 |
16 | export const parse = (lines) => {
17 |
18 | if (!isFasta(lines)) {
19 | throw new Error(`Could not parse the file as a FASTA file`);
20 | }
21 |
22 | let lineIndex = 0;
23 |
24 | const parseTaxon = (line) => {
25 | if (line[0] !== '>') {
26 | throw new Error(`Expected a '>' to start a taxon line`);
27 | }
28 | const taxon = line.substring(1);
29 | if (!taxon) {
30 | throw new Error(`Empty taxon at line ${lineIndex + 1}`);
31 | }
32 | return taxon;
33 | }
34 | const parseCode = (line) => {
35 | const code = line.replace(/\s+/g, '');
36 | if (!code) {
37 | throw new Error(`Empty sequence at line ${lineIndex + 1}`);
38 | }
39 | return code;
40 | }
41 |
42 | const sequences = [];
43 | let taxon = '';
44 | let codeLines = [];
45 |
46 | const addSequence = () => {
47 | const code = codeLines.join('');
48 | sequences.push({ taxon, code });
49 | codeLines = [];
50 | }
51 |
52 | for (; lineIndex < lines.length; ++lineIndex) {
53 | const line = lines[lineIndex];
54 | if (line.length === 0 || line[0] === '#') {
55 | continue;
56 | }
57 | if (line[0] === '>') {
58 | if (taxon) {
59 | addSequence();
60 | codeLines = [];
61 | }
62 | taxon = parseTaxon(line);
63 | }
64 | else {
65 | if (!taxon) {
66 | throw new Error(`'No taxon line found before line ${lineIndex+1} ('${line}')`);
67 | }
68 | codeLines.push(parseCode(line));
69 | }
70 | }
71 | addSequence();
72 |
73 | const numSequences = sequences.length;
74 | const length = sequences[0].code.length;
75 | // Check that all sequnces have the same length;
76 | for (let seq of sequences) {
77 | if (seq.code.length !== length) {
78 | throw new UserFixError(`Sequence '${seq.taxon}' has different length (${seq.code.length}) than previous taxons (${length})`);
79 | }
80 | }
81 |
82 | // console.log('Sequences:', sequences);
83 | const alignment = {
84 | sequences,
85 | numSequences,
86 | length,
87 | fileFormat: 'FASTA',
88 | };
89 |
90 | return alignment;
91 |
92 | }
93 |
94 | export default {
95 | isFasta,
96 | parse,
97 | };
98 |
--------------------------------------------------------------------------------
/src/common/io.js:
--------------------------------------------------------------------------------
1 | import fs from 'fs';
2 | import readline from 'readline';
3 | import util from 'util';
4 |
5 | import phylipParser from './phylipParser';
6 | import fastaParser from './fastaParser';
7 | import typecheckAlignment from './typecheckAlignment';
8 | import UserFixError from './errors';
9 |
10 | export const parseAlignment = async (filePath) => {
11 |
12 | return new Promise((resolve, reject) => {
13 |
14 | const rl = readline.createInterface({
15 | input: fs.createReadStream(filePath),
16 | terminal: false,
17 | });
18 |
19 | const lines = [];
20 | let error = null;
21 | let alignment = null;
22 |
23 | rl.on('line', (line) => {
24 | lines.push(line);
25 |
26 | }).on('close', () => {
27 | try {
28 | if (phylipParser.isPhylip(lines)) {
29 | alignment = phylipParser.parse(lines);
30 | } else if (fastaParser.isFasta(lines)) {
31 | alignment = fastaParser.parse(lines);
32 | } else {
33 | throw new UserFixError("Unrecognized input format. RaxmlGUI2 supports the following input types at the moment: 'clustal', 'fasta', 'nbrf', 'nexus', 'mega', 'phylip'.");
34 | }
35 | }
36 | catch (err) {
37 | error = err;
38 | error.message = `Error parsing file ${filePath}: ${error.message}.`;
39 | }
40 | if (error) {
41 | reject(error);
42 | } else {
43 |
44 | if (alignment.sequences.length === 0) {
45 | return reject(new Error(`Couldn't parse any sequences from file ${filePath}`))
46 | }
47 |
48 | try {
49 | typecheckAlignment(alignment);
50 | } catch (err) {
51 | console.error('Error checking data type:', err);
52 | return reject(err);
53 | }
54 |
55 | const alignmentRestricted = Object.assign({}, alignment, { sequences: alignment.sequences.slice(0,2) });
56 | console.log('Alignment with first two sequences:', alignmentRestricted);
57 | resolve(alignment);
58 | }
59 | });
60 | });
61 | }
62 |
63 | export const writeAlignment = async (filePath, alignment) => {
64 | console.log(`Write alignment in FASTA format to ${filePath}`);
65 | console.log(alignment);
66 | const writeStream = fs.createWriteStream(filePath);
67 | const write = util.promisify(writeStream.write);
68 | const end = util.promisify(writeStream.end);
69 | for (let i = 0; i < alignment.sequences.length; ++i) {
70 | const prefix = i === 0 ? '>' : '\n>';
71 | const sequence = alignment.sequences[i];
72 | await write.call(writeStream, `${prefix}${sequence.taxon}\n`);
73 | await write.call(writeStream, sequence.code);
74 | }
75 | await end.call(writeStream);
76 | }
77 |
78 | export default {
79 | parseAlignment,
80 | writeAlignment,
81 | }
82 |
--------------------------------------------------------------------------------
/src/common/typecheckAlignment.js:
--------------------------------------------------------------------------------
1 | import UserFixError from './errors';
2 |
3 | export const getFinalDataType = (dataTypes) => {
4 | const notUndefinedTypes = dataTypes.filter((d) => d !== undefined);
5 | if (notUndefinedTypes.length === 0) {
6 | return undefined;
7 | }
8 | let firstType = notUndefinedTypes[0];
9 | for (let i = 1; i < notUndefinedTypes.length; ++i) {
10 | const type = notUndefinedTypes[i];
11 | if (type !== firstType) {
12 | if (
13 | (type === 'binary' && firstType === 'multistate') ||
14 | (type === 'multistate' && firstType === 'binary')
15 | ) {
16 | firstType = 'multistate';
17 | } else {
18 | return 'mixed';
19 | }
20 | }
21 | }
22 | return firstType;
23 | };
24 |
25 | // Valid characters taken from Standard-RAxML (axml.c)
26 | const reInvalidBinary = /[^01-?]/g;
27 | const reInvalidDNA = /[^ABCDGHKMRSTUVWYNOX?-]/gi;
28 | const reInvalidAA = /[^ARNDCQEGHILKMFPSTWYVBZX*?-]/gi;
29 | const reInvalidGeneric = /[^0123456789ABCDEFGHIJKLMNOPQRSTU?-]/gi;
30 | const reInvalidMixed = /[^0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ*?-]/gi;
31 |
32 | export function findInvalidCharacter(code, dataType) {
33 | // Returns the index of the invalid character if found, else -1
34 | switch (dataType) {
35 | case 'protein':
36 | return reInvalidAA.test(code) ? reInvalidAA.lastIndex - 1 : -1;
37 | case 'nucleotide':
38 | return reInvalidDNA.test(code) ? reInvalidDNA.lastIndex - 1 : -1;
39 | case 'multistate':
40 | return reInvalidGeneric.test(code) ? reInvalidGeneric.lastIndex - 1 : -1;
41 | case 'binary':
42 | return reInvalidBinary.test(code) ? reInvalidBinary.lastIndex - 1 : -1;
43 | case 'unknown':
44 | case 'mixed':
45 | default:
46 | return reInvalidMixed.test(code) ? reInvalidMixed.lastIndex - 1 : -1;
47 | }
48 | }
49 |
50 | function hasInvariantSites(length, sequences) {
51 | for (let i = 0; i < length; i++) {
52 | const variantsAtPosition = [];
53 | for (const sequence of sequences) {
54 | const site = sequence.code[i];
55 | if (!variantsAtPosition.includes(site)) {
56 | variantsAtPosition.push(site)
57 | }
58 | }
59 | if (variantsAtPosition.length <= 1) {
60 | return true;
61 | }
62 | }
63 | return false;
64 | }
65 |
66 | export default function typecheckAlignment(alignment) {
67 | const acgMatch = /[ACGN?]/i; // Include 'N' and '?' as symbols for missing characters in DNA
68 | // const proteinMatch = /[RNDEQHILKMFPSWYVXBZJ]/i;
69 | const proteinMatch = /[EFJIJLOPQZX]/i;
70 | const binaryMatch = /[01]/;
71 | const multistateMatch = /2/;
72 | const unknownMatch = /^[N?]+$/i;
73 | const sequenceDataTypes = [];
74 | const dataTypes = new Set();
75 | let numSequencesTypechecked = 0;
76 | alignment.sequences.forEach((sequence, index) => {
77 | const { code } = sequence;
78 | let dataType = undefined;
79 | if (proteinMatch.test(code)) {
80 | dataType = 'protein';
81 | } else if (acgMatch.test(code)) {
82 | // const numT = (code.match(/T/ig) || []).length;
83 | // const numU = (code.match(/U/ig) || []).length;
84 | // if (numT > numU) {
85 | // dataType = 'dna';
86 | // } else {
87 | // dataType = 'rna';
88 | // }
89 | if (/[ACG]/i.test(code)) {
90 | // Check that it don't have only N or ?
91 | dataType = 'nucleotide';
92 | } else {
93 | dataType = 'unknown';
94 | }
95 | }
96 |
97 | if (!dataType || dataType === 'unknown') {
98 | if (multistateMatch.test(code)) {
99 | dataType = 'multistate';
100 | } else if (binaryMatch.test(code)) {
101 | dataType = 'binary';
102 | } else if (unknownMatch.test(code)) {
103 | dataType = 'unknown';
104 | }
105 | } else if (binaryMatch.test(code) || multistateMatch.test(code)) {
106 | dataType = 'mixed';
107 | }
108 | dataTypes.add(dataType);
109 | sequence.dataType = dataType;
110 | ++numSequencesTypechecked;
111 | sequenceDataTypes.push(sequence.dataType);
112 | });
113 |
114 | if (dataTypes.delete('unknown')) {
115 | console.log('At least one sequence have only unknown characters');
116 | if (dataTypes.size === 0) {
117 | throw new Error(
118 | `Invalid alignment: cannot determine data type because all ${numSequencesTypechecked} sequences are of type unknown`
119 | );
120 | }
121 | }
122 | let dataType = dataTypes.values().next().value;
123 | if (dataTypes.size > 1) {
124 | // Only valid case with different types is binary and multistate as [01] is a subset of [012].
125 | const isMultistate = !sequenceDataTypes.find(
126 | (type) => type !== 'binary' && type !== 'multistate'
127 | );
128 | if (isMultistate) {
129 | dataType = 'multistate';
130 | } else {
131 | dataType = 'invalid';
132 | console.log(
133 | 'Illegal mix of data types among sequences:',
134 | sequenceDataTypes
135 | );
136 | throw new UserFixError(
137 | `Your alignment is a mix of different data types, namely = ${Array.from(
138 | dataTypes.keys()
139 | )}.
140 | Please use only the same type for one alignment or combine several files.`
141 | );
142 | }
143 | }
144 | alignment.sequences.forEach((seq, index) => {
145 | const invalidSiteIndex = findInvalidCharacter(seq.code, dataType);
146 | if (invalidSiteIndex !== -1) {
147 | const sample =
148 | seq.code.length <= 8
149 | ? `'${seq.code}'`
150 | : `'${seq.code.substring(0, 8)}'...`;
151 | throw new UserFixError(
152 | `Invalid character '${seq.code[invalidSiteIndex]}' at site ${
153 | invalidSiteIndex + 1
154 | } in sequence ${
155 | index + 1
156 | } (${sample}) for inferred data type '${dataType}'`
157 | );
158 | }
159 | });
160 | alignment.hasInvariantSites = hasInvariantSites(alignment.length, alignment.sequences);
161 | alignment.dataType = dataType;
162 | alignment.typecheckingComplete = true;
163 | return alignment;
164 | }
165 |
--------------------------------------------------------------------------------
/src/common/utils.js:
--------------------------------------------------------------------------------
1 | import electron from 'electron';
2 | import { serializeError } from 'serialize-error';
3 | import cleanStack from 'clean-stack';
4 | import * as ipc from 'electron-better-ipc';
5 |
6 | import { activeWindow } from '../main/utils/utils';
7 |
8 | function newGithubIssueUrl(options = {}) {
9 | let repoUrl;
10 | if (options.repoUrl) {
11 | repoUrl = options.repoUrl;
12 | } else if (options.user && options.repo) {
13 | repoUrl = `https://github.com/${options.user}/${options.repo}`;
14 | } else {
15 | throw new Error(
16 | 'You need to specify either the `repoUrl` option or both the `user` and `repo` options'
17 | );
18 | }
19 |
20 | const url = new URL(`${repoUrl}/issues/new`);
21 |
22 | const types = [
23 | 'body',
24 | 'title',
25 | 'labels',
26 | 'template',
27 | 'milestone',
28 | 'assignee',
29 | 'projects',
30 | ];
31 |
32 | for (const type of types) {
33 | let value = options[type];
34 | if (value === undefined) {
35 | continue;
36 | }
37 |
38 | if (type === 'labels' || type === 'projects') {
39 | if (!Array.isArray(value)) {
40 | throw new TypeError(`The \`${type}\` option should be an array`);
41 | }
42 |
43 | value = value.join(',');
44 | }
45 |
46 | url.searchParams.set(type, value);
47 | }
48 |
49 | return url.toString();
50 | }
51 |
52 | export const is = {
53 | macos: process.platform === 'darwin',
54 | linux: process.platform === 'linux',
55 | windows: process.platform === 'win32',
56 | main: process.type === 'browser',
57 | renderer: process.type === 'renderer',
58 | development: process.env.NODE_ENV === 'development',
59 | macAppStore: process.mas === true,
60 | windowsStore: process.windowsStore === true,
61 | };
62 |
63 | export const platform = (object) => {
64 | let { platform } = process;
65 | if (is.macos) {
66 | platform = 'macos';
67 | } else if (is.windows) {
68 | platform = 'windows';
69 | }
70 | const fn = platform in object ? object[platform] : object.default;
71 | return typeof fn === 'function' ? fn() : fn;
72 | };
73 |
74 | // TODO: Had to replace this debug info on renderer, because electron remote module is no longer available.
75 | // If needed, one would need to use the context bridge
76 | export const debugInfo = () =>
77 | is.main
78 | ? `${electron.app.getName()} ${electron.app.getVersion()}
79 | Electron ${node.electronVersion}
80 | ${process.platform} ${os.release()}
81 | Locale: ${electron.app.getLocale()}
82 | `.trim()
83 | : `Debug info not available in renderer.`;
84 |
85 | if (is.renderer) {
86 | ipc.ipcRenderer.answerMain('get-state-report', async () => {
87 | const storeModule = await import('../app/store');
88 | const store = storeModule.default;
89 | const report = store.generateReport();
90 | return report;
91 | });
92 | }
93 |
94 | const getActiveState = async () => {
95 | if (is.renderer) {
96 | return window.store.generateReport();
97 | }
98 | const win = activeWindow();
99 | const report = await ipc.ipcMain.callRenderer(win, 'get-state-report');
100 | return report;
101 | }
102 |
103 | const getActiveStateSync = () => {
104 | if (is.renderer) {
105 | return window.store.generateReport();
106 | }
107 | return `Current state not available on synchronous call from main`;
108 | }
109 |
110 | const serializeAndCleanError = (error) => {
111 | const err = serializeError(error);
112 | err.stack = cleanStack(error.stack);
113 | return err;
114 | }
115 |
116 | export function timeout(ms) {
117 | return new Promise(resolve => setTimeout(resolve, ms));
118 | }
119 |
120 | export const quote = dir => is.windows ? `"${dir}"` : dir;
121 |
122 | const stringify = json => JSON.stringify(json, null, ' ');
123 |
124 | const stringifyToGithubMarkdown = (json) => `\`\`\`json
125 | ${stringify(json)}
126 | \`\`\``;
127 |
128 | const createReportBodyForGithub = (error, activeState) => `Autogenerated report:
129 | ${stringifyToGithubMarkdown(serializeAndCleanError(error))}
130 |
131 | Active state:
132 | ${stringifyToGithubMarkdown(activeState)}
133 |
134 | ---
135 |
136 | Process: ${is.renderer ? 'renderer' : 'main'}
137 | ${debugInfo()}`;
138 |
139 | const createReportBodyForMail = (error, activeState) => encodeURI(`Autogenerated report:
140 | ${stringify(serializeAndCleanError(error))}
141 |
142 | Active state:
143 | ${stringify(activeState)}
144 |
145 | ---
146 |
147 | Process: ${is.renderer ? 'renderer' : 'main'}
148 | ${debugInfo()}`);
149 |
150 | const openNewGitHubIssue = (options) => {
151 | const url = newGithubIssueUrl(options);
152 | electron.shell.openExternal(url);
153 | };
154 |
155 | export const reportIssueToGitHub = async (error) => {
156 | const activeState = await getActiveState();
157 | openNewGitHubIssue({
158 | user: 'AntonelliLab',
159 | repo: 'raxmlGUI',
160 | title: error.name,
161 | body: createReportBodyForGithub(error, activeState),
162 | });
163 | }
164 |
165 | export const getMailtoLinkToReportError = (error) => {
166 | const activeState = getActiveStateSync();
167 | const mailtoLinkContent = `mailto:raxmlgui.help@googlemail.com?subject=${encodeURI(error.name)}&body=${createReportBodyForMail(error, activeState)}`;
168 | return mailtoLinkContent;
169 | }
170 |
--------------------------------------------------------------------------------
/src/constants/ipc.js:
--------------------------------------------------------------------------------
1 | /*
2 | Strings for ipc
3 | */
4 | export const INIT_APP_STATE = 'INIT_APP_STATE';
5 | export const INIT_APP_STATE_RECEIVED = 'INIT_APP_STATE_RECEIVED';
6 | export const OUTPUT_DIR_SELECT = 'OUTPUT_DIR_SELECT';
7 | export const OUTPUT_DIR_SELECTED = 'OUTPUT_DIR_SELECTED';
8 | export const TREE_SELECT = 'TREE_SELECT';
9 | export const TREE_SELECTED = 'TREE_SELECTED';
10 | export const PARTITION_FILE_SELECT = 'PARTITION_FILE_SELECT';
11 | export const PARTITION_FILE_SELECTED = 'PARTITION_FILE_SELECTED';
12 | export const RUN_START = 'RUN_START';
13 | export const RUN_STDOUT = 'RUN_STDOUT';
14 | export const RUN_STDERR = 'RUN_STDERR';
15 | export const RUN_FINISHED = 'RUN_FINISHED';
16 | export const RUN_ERROR = 'RUN_ERROR';
17 | export const RUN_CANCEL = 'RUN_CANCEL';
18 | export const FILE_OPEN = 'FILE_OPEN';
19 | export const FILE_SHOW_IN_FOLDER = 'FILE_SHOW_IN_FOLDER';
20 | export const FOLDER_OPEN = 'FOLDER_OPEN';
21 | export const OUTPUT_CHECK = 'OUTPUT_CHECK';
22 | export const OUTPUT_CHECKED = 'OUTPUT_CHECKED';
23 | export const ALIGNMENT_SELECT = 'ALIGNMENT_SELECT';
24 | export const ALIGNMENT_SELECTED = 'ALIGNMENT_SELECTED';
25 | export const ALIGNMENT_PARSE_REQUEST = 'ALIGNMENT_PARSE_REQUEST';
26 | export const ALIGNMENT_PARSE_SUCCESS = 'ALIGNMENT_PARSE_SUCCESS';
27 | export const ALIGNMENT_PARSE_FAILURE = 'ALIGNMENT_PARSE_FAILURE';
28 | export const ALIGNMENT_PARSE_CHANGED_PATH = 'ALIGNMENT_PARSE_CHANGED_PATH';
29 | export const ALIGNMENT_EXAMPLE_FILES_GET_REQUEST = 'ALIGNMENT_EXAMPLE_FILES_GET_REQUEST';
30 | export const ALIGNMENT_EXAMPLE_FILES_GET_SUCCESS = 'ALIGNMENT_EXAMPLE_FILES_GET_SUCCESS';
31 | export const ALIGNMENT_MODEL_SELECTION_REQUEST = 'ALIGNMENT_MODEL_SELECTION_REQUEST';
32 | export const ALIGNMENT_MODEL_SELECTION_CANCEL = 'ALIGNMENT_MODEL_SELECTION_CANCEL';
33 | export const ALIGNMENT_MODEL_SELECTION_SUCCESS = 'ALIGNMENT_MODEL_SELECTION_SUCCESS';
34 | export const ALIGNMENT_MODEL_SELECTION_FAILURE = 'ALIGNMENT_MODEL_SELECTION_FAILURE';
35 | export const UNHANDLED_ERROR = 'UNHANDLED_ERROR';
36 | export const TOGGLE_BACKBONE_CONSTRAINT = 'TOGGLE_BACKBONE_CONSTRAINT';
37 | export const TOGGLE_MULTIFURCATING_CONSTRAINT = 'TOGGLE_MULTIFURCATING_CONSTRAINT';
38 | export const ADD_RUN = 'ADD_RUN';
39 | export const REMOVE_RUN = 'REMOVE_RUN';
40 | export const LIGHT_MODE = 'LIGHT_MODE';
41 | export const DARK_MODE = 'DARK_MODE';
42 | export const RELOAD = 'RELOAD';
43 | export const ASTRAL_REQUEST = 'ASTRAL_REQUEST';
44 | export const ASTRAL_SUCCESS = 'ASTRAL_SUCCESS';
45 | export const ASTRAL_FILE_SELECT = 'ASTRAL_FILE_SELECT';
46 | export const ASTRAL_FILE_SELECTED = 'ASTRAL_FILE_SELECTED';
47 |
--------------------------------------------------------------------------------
/src/electron.js:
--------------------------------------------------------------------------------
1 | const electron = require('electron');
2 | const proc = require('child_process');
3 |
4 | // spawn Electron
5 | const child = proc.spawn(electron, process.argv.slice(2), { stdio: 'inherit' });
6 |
7 | child.on('close', (code) => {
8 | console.log(`Electron child process exited with code ${code}`);
9 | });
10 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | margin: 0;
3 | padding: 0;
4 | overflow: hidden;
5 | height: 100%
6 | }
7 | body {
8 | font-family: Roboto, sans-serif;
9 | }
10 | pre, code, .pre, .code {
11 | font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace !important;
12 | }
13 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { createRoot } from 'react-dom/client';
3 |
4 | import App from './app/';
5 | import registerServiceWorker from './registerServiceWorker';
6 | import './index.css';
7 |
8 | const container = document.getElementById('root');
9 | const root = createRoot(container);
10 | root.render();
11 |
12 | registerServiceWorker();
13 |
--------------------------------------------------------------------------------
/src/main/menu/index.js:
--------------------------------------------------------------------------------
1 | import { app, Menu } from 'electron';
2 |
3 | import subMenuFile from './subMenuFile';
4 | import subMenuAnalysis from './subMenuAnalysis';
5 | import subMenuDeveloper from './subMenuDeveloper';
6 | import saveScreenshot from '../utils/saveScreenshot';
7 |
8 | const menuTemplate = [
9 | subMenuFile,
10 | subMenuAnalysis,
11 | {
12 | role: 'window',
13 | submenu: [
14 | { role: 'minimize' },
15 | { role: 'close' },
16 | {
17 | label: 'Save screenshot',
18 | accelerator: 'CmdOrCtrl+S',
19 | click() {
20 | saveScreenshot();
21 | }
22 | },
23 | ]
24 | },
25 | ];
26 |
27 | export default class MenuBuilder {
28 | constructor(mainWindow) {
29 | this.mainWindow = mainWindow;
30 | }
31 |
32 | buildMenu() {
33 | if (
34 | process.env.NODE_ENV === 'development' ||
35 | process.env.DEBUG_PROD === 'true'
36 | ) {
37 | menuTemplate.push(subMenuDeveloper);
38 | this.setupDevelopmentEnvironment();
39 | }
40 |
41 | if (process.platform === 'darwin') {
42 | menuTemplate.unshift({
43 | label: app.name,
44 | submenu: [
45 | { role: 'about' },
46 | { type: 'separator' },
47 | { role: 'services' },
48 | { type: 'separator' },
49 | { role: 'hide' },
50 | { role: 'hideothers' },
51 | { role: 'unhide' },
52 | { type: 'separator' },
53 | { role: 'quit' }
54 | ]
55 | });
56 | }
57 |
58 | const menu = Menu.buildFromTemplate(menuTemplate);
59 | Menu.setApplicationMenu(menu);
60 |
61 | return menu;
62 | }
63 |
64 | setupDevelopmentEnvironment() {
65 | this.mainWindow.openDevTools();
66 | this.mainWindow.webContents.on('context-menu', (e, props) => {
67 | const { x, y } = props;
68 | Menu.buildFromTemplate([
69 | {
70 | label: 'Inspect element',
71 | click: () => {
72 | this.mainWindow.inspectElement(x, y);
73 | }
74 | }
75 | ]).popup(this.mainWindow);
76 | });
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/main/menu/subMenuAnalysis.js:
--------------------------------------------------------------------------------
1 | import { BrowserWindow } from 'electron';
2 |
3 | import * as ipc from '../../constants/ipc';
4 |
5 | const subMenuAnalysis = {
6 | label: 'Analysis',
7 | submenu: [
8 | {
9 | label: 'Enforce constraint...',
10 | submenu: [
11 | {
12 | label: 'Use backbone constraint',
13 | type: 'checkbox',
14 | checked: false,
15 | click() {
16 | BrowserWindow.getFocusedWindow().webContents.send(
17 | ipc.TOGGLE_BACKBONE_CONSTRAINT
18 | );
19 | }
20 | },
21 | {
22 | label: 'Use multifurcating constraint',
23 | type: 'checkbox',
24 | checked: false,
25 | click() {
26 | BrowserWindow.getFocusedWindow().webContents.send(
27 | ipc.TOGGLE_MULTIFURCATING_CONSTRAINT
28 | );
29 | }
30 | }
31 | ]
32 | }
33 | ]
34 | };
35 |
36 | export default subMenuAnalysis;
37 |
--------------------------------------------------------------------------------
/src/main/menu/subMenuDeveloper.js:
--------------------------------------------------------------------------------
1 | const subMenuDeveloper = {
2 | // If you see this menu in production sth is wrong
3 | label: 'DEVELOPER!!!',
4 | submenu: [
5 | {
6 | label: 'Force Error',
7 | click() {
8 | throw new Error('Testing Error');
9 | }
10 | },
11 | { type: 'separator' },
12 | { role: 'toggledevtools' },
13 | { role: 'reload' },
14 | { role: 'forcereload' },
15 | { type: 'separator' },
16 | { role: 'resetzoom' },
17 | { role: 'zoomin' },
18 | { role: 'zoomout' },
19 | { type: 'separator' },
20 | { role: 'togglefullscreen' }
21 | ]
22 | };
23 |
24 | export default subMenuDeveloper;
25 |
--------------------------------------------------------------------------------
/src/main/menu/subMenuFile.js:
--------------------------------------------------------------------------------
1 | import { BrowserWindow } from 'electron';
2 |
3 | import * as ipc from '../../constants/ipc';
4 | import { store } from '../../app/store/Config';
5 |
6 | const subMenuFile = {
7 | label: 'File',
8 | submenu: [
9 | {
10 | label: 'New Tab',
11 | accelerator: 'CmdOrCtrl+T',
12 | click() {
13 | BrowserWindow.getFocusedWindow().webContents.send(ipc.ADD_RUN);
14 | }
15 | },
16 | {
17 | label: 'Close Tab',
18 | accelerator: 'CmdOrCtrl+W',
19 | click() {
20 | BrowserWindow.getFocusedWindow().webContents.send(ipc.REMOVE_RUN);
21 | }
22 | },
23 | {
24 | label: 'Theme',
25 | submenu: [
26 | {
27 | label: 'Light mode',
28 | type: 'radio',
29 | checked: !store.get('darkMode'),
30 | click() {
31 | BrowserWindow.getFocusedWindow().webContents.send(ipc.LIGHT_MODE);
32 | }
33 | },
34 | {
35 | label: 'Dark mode',
36 | type: 'radio',
37 | checked: store.get('darkMode'),
38 | click() {
39 | BrowserWindow.getFocusedWindow().webContents.send(ipc.DARK_MODE);
40 | }
41 | }
42 | ]
43 | }
44 | ],
45 | };
46 |
47 | export default subMenuFile;
48 |
--------------------------------------------------------------------------------
/src/main/utils/saveScreenshot.js:
--------------------------------------------------------------------------------
1 | import { BrowserWindow, dialog } from 'electron';
2 | import fs from 'fs';
3 | import util from 'util';
4 | const writeFile = util.promisify(fs.writeFile);
5 |
6 | const saveScreenshot = async () => {
7 | console.log('Save screenshot...');
8 | const win = BrowserWindow.getFocusedWindow();
9 | const img = await win.webContents.capturePage()
10 | try {
11 | const file = await dialog.showSaveDialog({
12 | title: "Select the File Path to save",
13 | buttonLabel: "Save",
14 | // Restricting the user to only Image Files.
15 | filters: [
16 | {
17 | name: "Image Files",
18 | extensions: ["png", "jpeg", "jpg"],
19 | },
20 | ],
21 | properties: [],
22 | });
23 |
24 | if (!file.canceled) {
25 | console.log(`Save screenshot to '${file.filePath}'...`);
26 | // Creating and Writing to the image.png file
27 | // Can save the File as a jpeg file as well,
28 | // by simply using img.toJPEG(100);
29 | await writeFile(file.filePath.toString(), img.toPNG(), "base64");
30 | console.log('Saved!');
31 | }
32 | }
33 | catch (err) {
34 | console.log(err);
35 | }
36 | }
37 |
38 | export default saveScreenshot;
39 |
--------------------------------------------------------------------------------
/src/main/utils/utils.js:
--------------------------------------------------------------------------------
1 | import electron from 'electron';
2 |
3 | export const activeWindow = () => electron.BrowserWindow.getFocusedWindow();
4 |
--------------------------------------------------------------------------------
/src/registerServiceWorker.js:
--------------------------------------------------------------------------------
1 | // In production, we register a service worker to serve assets from local cache.
2 |
3 | // This lets the app load faster on subsequent visits in production, and gives
4 | // it offline capabilities. However, it also means that developers (and users)
5 | // will only see deployed updates on the "N+1" visit to a page, since previously
6 | // cached resources are updated in the background.
7 |
8 | // To learn more about the benefits of this model, read https://goo.gl/KwvDNy.
9 | // This link also includes instructions on opting out of this behavior.
10 |
11 | const isLocalhost = Boolean(
12 | window.location.hostname === 'localhost' ||
13 | // [::1] is the IPv6 localhost address.
14 | window.location.hostname === '[::1]' ||
15 | // 127.0.0.1/8 is considered localhost for IPv4.
16 | window.location.hostname.match(
17 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
18 | )
19 | );
20 |
21 | export default function register() {
22 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
23 | // The URL constructor is available in all browsers that support SW.
24 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
25 | if (publicUrl.origin !== window.location.origin) {
26 | // Our service worker won't work if PUBLIC_URL is on a different origin
27 | // from what our page is served on. This might happen if a CDN is used to
28 | // serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
29 | return;
30 | }
31 |
32 | window.addEventListener('load', () => {
33 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
34 |
35 | if (isLocalhost) {
36 | // This is running on localhost. Lets check if a service worker still exists or not.
37 | checkValidServiceWorker(swUrl);
38 | } else {
39 | // Is not local host. Just register service worker
40 | registerValidSW(swUrl);
41 | }
42 | });
43 | }
44 | }
45 |
46 | function registerValidSW(swUrl) {
47 | navigator.serviceWorker
48 | .register(swUrl)
49 | .then(registration => {
50 | registration.onupdatefound = () => {
51 | const installingWorker = registration.installing;
52 | installingWorker.onstatechange = () => {
53 | if (installingWorker.state === 'installed') {
54 | if (navigator.serviceWorker.controller) {
55 | // At this point, the old content will have been purged and
56 | // the fresh content will have been added to the cache.
57 | // It's the perfect time to display a "New content is
58 | // available; please refresh." message in your web app.
59 | console.log('New content is available; please refresh.');
60 | } else {
61 | // At this point, everything has been precached.
62 | // It's the perfect time to display a
63 | // "Content is cached for offline use." message.
64 | console.log('Content is cached for offline use.');
65 | }
66 | }
67 | };
68 | };
69 | })
70 | .catch(error => {
71 | console.error('Error during service worker registration:', error);
72 | });
73 | }
74 |
75 | function checkValidServiceWorker(swUrl) {
76 | // Check if the service worker can be found. If it can't reload the page.
77 | fetch(swUrl)
78 | .then(response => {
79 | // Ensure service worker exists, and that we really are getting a JS file.
80 | if (
81 | response.status === 404 ||
82 | response.headers.get('content-type').indexOf('javascript') === -1
83 | ) {
84 | // No service worker found. Probably a different app. Reload the page.
85 | navigator.serviceWorker.ready.then(registration => {
86 | registration.unregister().then(() => {
87 | window.location.reload();
88 | });
89 | });
90 | } else {
91 | // Service worker found. Proceed as normal.
92 | registerValidSW(swUrl);
93 | }
94 | })
95 | .catch(() => {
96 | console.log(
97 | 'No internet connection found. App is running in offline mode.'
98 | );
99 | });
100 | }
101 |
102 | export function unregister() {
103 | if ('serviceWorker' in navigator) {
104 | navigator.serviceWorker.ready.then(registration => {
105 | registration.unregister();
106 | });
107 | }
108 | }
109 |
--------------------------------------------------------------------------------
/src/settings/raxmlng.js:
--------------------------------------------------------------------------------
1 | // --model
2 | export const binarySubstitutionModelOptions = {
3 | default: 'BIN',
4 | options: [
5 | 'BIN'
6 | ]
7 | };
8 |
9 | // --model
10 | export const nucleotideSubstitutionModelOptions = {
11 | default: 'GTR',
12 | options: [
13 | 'JC',
14 | 'K80',
15 | 'F81',
16 | 'HKY',
17 | 'TN93ef',
18 | 'TN93',
19 | 'K81',
20 | 'K81uf',
21 | 'TPM2',
22 | 'TPM2uf',
23 | 'TPM3',
24 | 'TPM3uf',
25 | 'TIM1',
26 | 'TIM1uf',
27 | 'TIM2',
28 | 'TIM2uf',
29 | 'TIM3',
30 | 'TIM3uf',
31 | 'TVMef',
32 | 'TVM',
33 | 'SYM',
34 | 'GTR'
35 | ]
36 | };
37 |
38 | // --model
39 | export const multistateSubstitutionModelOptions = {
40 | default: 'MULTIx_GTR',
41 | options: [
42 | 'MULTIx_MK',
43 | 'MULTIx_GTR'
44 | ]
45 | };
46 |
47 | // --model
48 | export const aminoAcidSubstitutionModelOptions = {
49 | default: 'Blosum62',
50 | options: [
51 | 'Blosum62',
52 | 'cpREV',
53 | 'Dayhoff',
54 | 'DCMut',
55 | 'DEN',
56 | 'FLU',
57 | 'HIVb',
58 | 'HIVw',
59 | 'JTT',
60 | 'JTT-DCMut',
61 | 'LG',
62 | 'mtART',
63 | 'mtMAM',
64 | 'mtREV',
65 | 'mtZOA',
66 | 'PMB',
67 | 'rtREV',
68 | 'stmtREV',
69 | 'VT',
70 | 'WAG',
71 | 'LG4M',
72 | 'LG4X',
73 | 'PROTGTR'
74 | ]
75 | };
76 |
77 | // --model
78 | export const stationaryFrequenciesOptions = {
79 | options: [
80 | {
81 | value: '+F',
82 | label: '+F (empirical)'
83 | },
84 | {
85 | value: '+FO',
86 | label: '+FO (ML estimate)'
87 | },
88 | {
89 | value: '+FE',
90 | label: '+FE (equal)'
91 | },
92 | // Also posibble are user defined values
93 | // +FU{f1/f2/../fn} (user-defined: f1 f2 ... fn)
94 | // +FU{freqs.txt} (user-defined from file)
95 | ]
96 | };
97 |
98 | // --model
99 | export const proportionOfInvariantSitesOptions = {
100 | options: [
101 | {
102 | value: '+I',
103 | label: '+I (ML estimate)'
104 | },
105 | {
106 | value: '+IC',
107 | label: '+IC (empirical)'
108 | },
109 | // Also posibble are user defined values
110 | // +IU{p} (user-defined: p)
111 | ]
112 | };
113 |
114 | // --model
115 | export const amongsiteRateHeterogeneityModelOptions = {
116 | options: [
117 | {
118 | value: '+G',
119 | label:
120 | '+GAMMA (mean)'
121 | },
122 | {
123 | value: '+GA',
124 | label:
125 | '+GAMMA (median)'
126 | }
127 | // Also posibble are user defined values
128 | // +Gn (discrete GAMMA with n categories', 'ML estimate of alpha)
129 | // +Gn{a} (discrete GAMMA with n categories and user-defined alpha a)
130 | // +Rn (FreeRate with n categories', 'ML estimate of rates and weights)
131 | // +Rn{r1/r2/../rn}{w1/w2/../wn} (FreeRate with n categories', 'user-defined rates r1 r2 ... rn and weights w1 w2 ... wn)
132 | ]
133 | };
134 |
135 | // --model
136 | export const ascertainmentBiasCorrectionOptions = {
137 | options: [
138 | {
139 | value: '+ASC_LEWIS',
140 | label: "Lewis' method"
141 | },
142 | // Also posibble are user defined values
143 | // +ASC_FELS{w} (Felsenstein's method with total number of invariable sites w)
144 | // +ASC_STAM{w1/w2/../wn} (Stamatakis' method with per-state invariable site numbers w1 w2 ... wn)
145 | ]
146 | };
147 |
148 |
149 | export const modelOptions = {
150 | 'protein': aminoAcidSubstitutionModelOptions,
151 | 'binary': binarySubstitutionModelOptions,
152 | 'multistate': multistateSubstitutionModelOptions,
153 | 'dna': nucleotideSubstitutionModelOptions,
154 | 'rna': nucleotideSubstitutionModelOptions,
155 | 'nucleotide': nucleotideSubstitutionModelOptions,
156 | };
157 |
--------------------------------------------------------------------------------
/static/example-files/example_data_raxmlGUI.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AntonelliLab/raxmlGUI/f5b59126ea6c34e84e89a1c2c07b966e07afd216/static/example-files/example_data_raxmlGUI.zip
--------------------------------------------------------------------------------
/static/example-files/fasta/aminoacid.txt:
--------------------------------------------------------------------------------
1 | >TAXON_1
2 | VPPYRWVAGVFITQYMNNIVYDDRISDLCKPVFLINPCHCAPFSGKTIGQ
3 | >TAXON_2
4 | WKEPTYIISEFFYVKTAWYWEVESSSSNFIKECIEACEQPYNHSGCKKFE
5 | >TAXON_3
6 | EGPRSPINHSAEHMVSQLISDCKMWEHPYTTCRGKEVFWFTIKPWACKIH
7 | >TAXON_4
8 | GRHFCWCSTRDAANPVRLCHKVQNCDDVKGQANSCLWSIMEKFERMIIEP
9 | >TAXON_5
10 | DEDCSHPPVYDSPDDSISDHQDGNNEFDTLGMWGMVYPRWSCAWMIAKKN
11 | >TAXON_6
12 | CAWCKDKPWPRSHTISKLYHHDFYKHFMTRSWTIILCQYSEAKPSFTQIS
13 | >TAXON_7
14 | YCINQMANLHEWNVVGNARSKRSCRIGRCNSKEMRSKAREMESESGFRVQ
15 | >TAXON_8
16 | QQPMSHMLWFTHEECWDHVGSHTPRYEKKRPQCTVPHLDKIDPLRLALHG
17 | >TAXON_9
18 | PAQNMDTFQKGRLAWRMFDYQWNQKGDIHKASTVGAKLGESGTAGGFSYP
19 | >TAXON_10
20 | YENFLWSGCWGHLFGATWMRGEKKMDHQVDYHHHLPCFFPDTIWFVDEEF
21 | >TAXON_11
22 | LEYHMCCMAHESGKCCTIAKWAHCSSIIWMQPGQLSANHFDEEKSVIADQ
23 | >TAXON_13
24 | TVNYNLFWIFVFWLYASDNYYTPFLNEKPQEFQGAWYGYHWFDYQPHIVP
25 | >TAXON_14
26 | FAKVELIGVKILDFYGKFMDFFNDCDDEITQRFLTLHSVHPQASSIHKWH
27 | >TAXON_15
28 | GNARGVCQKKCSFMRMVEHIQFDKTFMALSVRRECLLDAATSRLIDAPFM
29 | >TAXON_16
30 | ICYAEFTKIVKGINGVDDWYKGQWCGMVRTPKMHPHNGLSWCKMNRGNEH
31 | >TAXON_17
32 | ACPYEMRHNGVWKIHDYRICMMRVTWPTHNTRFDFPKFEYQESPGAQFQE
33 | >TAXON_18
34 | IEVWKEVRYDYLLFPEIANCTQGWFSHHYIKDIGCKPGISIACHMDSLSD
35 | >TAXON_19
36 | LVTKVVQEYKNYTRMFTYDVLQQYCMTEWTYDLFNHYGWVFYTASSFKWI
--------------------------------------------------------------------------------
/static/example-files/fasta/bin1.txt:
--------------------------------------------------------------------------------
1 | >TAXON_1
2 | 1010101011010
3 | >TAXON_2
4 | 1010101010110
5 | >TAXON_3
6 | 1010101010110
7 | >TAXON_4
8 | 1010101010110
9 | >TAXON_5
10 | 1010101010110
11 | >TAXON_6
12 | 1010101010110
13 | >TAXON_7
14 | 1010101010111
15 | >TAXON_8
16 | 1010101010111
17 | >TAXON_9
18 | 1010101010110
19 | >TAXON_10
20 | 1010101011011
21 |
--------------------------------------------------------------------------------
/static/example-files/fasta/bin2.txt:
--------------------------------------------------------------------------------
1 | >TAXON_11
2 | 1011110111
3 | >TAXON_2
4 | 1010110111
5 | >TAXON_23
6 | 1010101111
7 | >TAXON_4
8 | 1010011111
9 | >TAXON_15
10 | 1010011110
11 | >TAXON_6
12 | 1001011110
13 | >TAXON_27
14 | 1101011110
15 | >TAXON_8
16 | 1101011110
17 | >TAXON_19
18 | 1001011110
19 | >TAXON_10
20 | 1101011110
21 |
--------------------------------------------------------------------------------
/static/example-files/fasta/binary.txt:
--------------------------------------------------------------------------------
1 | >TAXON_1
2 | 1010101011010111101110110011010111111010110101011110
3 | >TAXON_2
4 | 1010101010110101101110110110110110111010110100111110
5 | >TAXON_3
6 | 1010101010110101011110110110101110111010110100111101
7 | >TAXON_4
8 | 1010101010110100111110110110101110111010110010111100
9 | >TAXON_5
10 | 1010101010110100111101010110101101101010111010111100
11 | >TAXON_6
12 | 1010101010110010111100110110100100011010111010111100
13 | >TAXON_7
14 | 1010101010111010111100110110100010111010111101101101
15 | >TAXON_8
16 | 1010101010111010111100101110100010111001111101101101
17 | >TAXON_9
18 | 1010101010110010111100101110100001011001111010101101
19 | >TAXON_10
20 | 1010101011011010111100101110100010110101111001101101
21 | >TAXON_11
22 | 1010101010110101010111101101101011101101101101011101
23 | >TAXON_13
24 | 1010101010110101001111101101101011101101101101011101
25 | >TAXON_14
26 | 1010101010110101001111010101101011011010101101011011
27 | >TAXON_15
28 | 1010101010010111101111001101101001000001101101001000
29 | >TAXON_16
30 | 1010101010010111101111001101101000101001101101000101
31 | >TAXON_17
32 | 1010101010010111101111001011101000101001011101000101
33 | >TAXON_18
34 | 1010101010010111101111001011101000010001011101000010
35 | >TAXON_19
36 | 1010101010010111101111001011101000101001011101000101
--------------------------------------------------------------------------------
/static/example-files/fasta/dna.txt:
--------------------------------------------------------------------------------
1 | >Turkey
2 | AAGCTNGGGC ATTTCAGGGT GAGCCCGGGC AATACAGGGT AT
3 | >Salmo gair
4 | AAGCCTTGGC AGTGCAGGGT GAGCCGTGGC CGGGCACGGT AT
5 | >H. Sapiens
6 | ACCGGTTGGC CGTTCAGGGT ACAGGTTGGC CGTTCAGGGT AA
7 | >Chimp
8 | AAACCCTTGC CGTTACGCTT AAACCGAGGC CGGGACACTC AT
9 | >Gorilla
10 | AAACCCTTGC CGGTACGCTT AAACCATTGC CGGTACGCTT AA
11 |
--------------------------------------------------------------------------------
/static/example-files/fasta/multistate.txt:
--------------------------------------------------------------------------------
1 | >TAXON_1
2 | 10101010110101111011102222210131311110101101010111
3 | >TAXON_2
4 | 10101010101101011011102222210131301110101101001111
5 | >TAXON_3
6 | 12222210101101010111102222201131301110101101001111
7 | >TAXON_4
8 | 12222210101101001111102222201131301110101100101111
9 | >TAXON_5
10 | 12222210101101001111012222201130311010101110101111
11 | >TAXON_6
12 | 12222210101100101111002222200130300110101110101111
13 | >TAXON_7
14 | 12222210101110101111002222200031301110101111011011
15 | >TAXON_8
16 | 12222210101110101111002222200031301110011111011011
17 | >TAXON_9
18 | 12222210101100101111002222200030310110011110121011
19 | >TAXON_10
20 | 12222210110110101111002222200021201101011110021011
21 | >TAXON_11
22 | 12222210101101010101112222201021211011011011020111
23 | >TAXON_13
24 | 12333310101101010011112222201021211011011011020111
25 | >TAXON_14
26 | 12333310101101010011110101011010110110101011020110
27 | >TAXON_15
28 | 12333310100101111011110011011010010000011011020010
29 | >TAXON_16
30 | 12333310100101111011110011011010001010011011020001
31 | >TAXON_17
32 | 12333310100101111011110010111010001010010111020001
33 | >TAXON_18
34 | 10101010100101111011110010111010000100010111010000
35 | >TAXON_19
36 | 10101010100101111011110010111010001010010111010001
--------------------------------------------------------------------------------
/static/example-files/fasta/partition_file.txt:
--------------------------------------------------------------------------------
1 | DNA, gene1 = 1-3676
2 | BIN, morph = 3677-3851
--------------------------------------------------------------------------------
/static/example-files/fasta/test.fa:
--------------------------------------------------------------------------------
1 | >Cow
2 | ATGGCATATCCCATACAACTAGGATTCCAAGATGCAACATCACCAATCATAGAAGAACTA
3 | CTTCACTTTCATGACCACACGCTAATAATTGTCTTCTTAATTAGCTCATTAGTACTTTAC
4 | ATTATTTCACTAATACTAACGACAAAGCTGACCCATACAAGCACGATAGATGCACAAGAA
5 | GTAGAGACAATCTGAACCATTCTGCCCGCCATCATCTTAATTCTAATTGCTCTTCCTTCT
6 | TTACGAATTCTATACATAATAGATGAAATCAATAACCCATCTCTTACAGTAAAAACCATA
7 | GGACATCAGTGATACTGAAGCTATGAGTATACAGATTATGAGGACTTAAGCTTCGACTCC
8 | TACATAATTCCAACATCAGAATTAAAGCCAGGGGAGCTACGACTATTAGAAGTCGATAAT
9 | CGAGTTGTACTACCAATAGAAATAACAATCCGAATGTTAGTCTCCTCTGAAGACGTATTA
10 | CACTCATGAGCTGTGCCCTCTCTAGGACTAAAAACAGACGCAATCCCAGGCCGTCTAAAC
11 | CAAACAACCCTTATATCGTCCCGTCCAGGCTTATATTACGGTCAATGCTCAGAAATTTGC
12 | GGGTCAAACCACAGTTTCATACCCATTGTCCTTGAGTTAGTCCCACTAAAGTACTTTGAA
13 | AAATGATCTGCGTCAATATTA---------------------TAA
14 | >Chicken
15 | ATGGCCAACCACTCCCAACTAGGCTTTCAAGACGCCTCATCCCCCATCATAGAAGAGCTC
16 | GTTGAATTCCACGACCACGCCCTGATAGTCGCACTAGCAATTTGCAGCTTAGTACTCTAC
17 | CTTCTAACTCTTATACTTATAGAAAAACTATCA---TCAAACACCGTAGATGCCCAAGAA
18 | GTTGAACTAATCTGAACCATCCTACCCGCTATTGTCCTAGTCCTGCTTGCCCTCCCCTCC
19 | CTCCAAATCCTCTACATAATAGACGAAATCGACGAACCTGATCTCACCCTAAAAGCCATC
20 | GGACACCAATGATACTGAACCTATGAATACACAGACTTCAAGGACCTCTCATTTGACTCC
21 | TACATAACCCCAACAACAGACCTCCCCCTAGGCCACTTCCGCCTACTAGAAGTCGACCAT
22 | CGCATTGTAATCCCCATAGAATCCCCCATTCGAGTAATCATCACCGCTGATGACGTCCTC
23 | CACTCATGAGCCGTACCCGCCCTCGGGGTAAAAACAGACGCAATCCCTGGACGACTAAAT
24 | CAAACCTCCTTCATCACCACTCGACCAGGAGTGTTTTACGGACAATGCTCAGAAATCTGC
25 | GGAGCTAACCACAGCTACATACCCATTGTAGTAGAGTCTACCCCCCTAAAACACTTTGAA
26 | GCCTGATCCTCACTA------------------CTGTCATCTTAA
27 | >Human
28 | ATGGCACATGCAGCGCAAGTAGGTCTACAAGACGCTACTTCCCCTATCATAGAAGAGCTT
29 | ATCACCTTTCATGATCACGCCCTCATAATCATTTTCCTTATCTGCTTCCTAGTCCTGTAT
30 | GCCCTTTTCCTAACACTCACAACAAAACTAACTAATACTAACATCTCAGACGCTCAGGAA
31 | ATAGAAACCGTCTGAACTATCCTGCCCGCCATCATCCTAGTCCTCATCGCCCTCCCATCC
32 | CTACGCATCCTTTACATAACAGACGAGGTCAACGATCCCTCCCTTACCATCAAATCAATT
33 | GGCCACCAATGGTACTGAACCTACGAGTACACCGACTACGGCGGACTAATCTTCAACTCC
34 | TACATACTTCCCCCATTATTCCTAGAACCAGGCGACCTGCGACTCCTTGACGTTGACAAT
35 | CGAGTAGTACTCCCGATTGAAGCCCCCATTCGTATAATAATTACATCACAAGACGTCTTG
36 | CACTCATGAGCTGTCCCCACATTAGGCTTAAAAACAGATGCAATTCCCGGACGTCTAAAC
37 | CAAACCACTTTCACCGCTACACGACCGGGGGTATACTACGGTCAATGCTCTGAAATCTGT
38 | GGAGCAAACCACAGTTTCATGCCCATCGTCCTAGAATTAATTCCCCTAAAAATCTTTGAA
39 | ATA---------------------GGGCCCGTATTTACCCTATAG
40 | >Loach
41 | ATGGCACATCCCACACAATTAGGATTCCAAGACGCGGCCTCACCCGTAATAGAAGAACTT
42 | CTTCACTTCCATGACCATGCCCTAATAATTGTATTTTTGATTAGCGCCCTAGTACTTTAT
43 | GTTATTATTACAACCGTCTCAACAAAACTCACTAACATATATATTTTGGACTCACAAGAA
44 | ATTGAAATCGTATGAACTGTGCTCCCTGCCCTAATCCTCATTTTAATCGCCCTCCCCTCA
45 | CTACGAATTCTATATCTTATAGACGAGATTAATGACCCCCACCTAACAATTAAGGCCATG
46 | GGGCACCAATGATACTGAAGCTACGAGTATACTGATTATGAAAACTTAAGTTTTGACTCC
47 | TACATAATCCCCACCCAGGACCTAACCCCTGGACAATTCCGGCTACTAGAGACAGACCAC
48 | CGAATGGTTGTTCCCATAGAATCCCCTATTCGCATTCTTGTTTCCGCCGAAGATGTACTA
49 | CACTCCTGGGCCCTTCCAGCCATGGGGGTAAAGATAGACGCGGTCCCAGGACGCCTTAAC
50 | CAAACCGCCTTTATTGCCTCCCGCCCCGGGGTATTCTATGGGCAATGCTCAGAAATCTGT
51 | GGAGCAAACCACAGCTTTATACCCATCGTAGTAGAAGCGGTCCCACTATCTCACTTCGAA
52 | AACTGGTCCACCCTTATACTAAAAGACGCCTCACTAGGAAGCTAA
53 | >Mouse
54 | ATGGCCTACCCATTCCAACTTGGTCTACAAGACGCCACATCCCCTATTATAGAAGAGCTA
55 | ATAAATTTCCATGATCACACACTAATAATTGTTTTCCTAATTAGCTCCTTAGTCCTCTAT
56 | ATCATCTCGCTAATATTAACAACAAAACTAACACATACAAGCACAATAGATGCACAAGAA
57 | GTTGAAACCATTTGAACTATTCTACCAGCTGTAATCCTTATCATAATTGCTCTCCCCTCT
58 | CTACGCATTCTATATATAATAGACGAAATCAACAACCCCGTATTAACCGTTAAAACCATA
59 | GGGCACCAATGATACTGAAGCTACGAATATACTGACTATGAAGACCTATGCTTTGATTCA
60 | TATATAATCCCAACAAACGACCTAAAACCTGGTGAACTACGACTGCTAGAAGTTGATAAC
61 | CGAGTCGTTCTGCCAATAGAACTTCCAATCCGTATATTAATTTCATCTGAAGACGTCCTC
62 | CACTCATGAGCAGTCCCCTCCCTAGGACTTAAAACTGATGCCATCCCAGGCCGACTAAAT
63 | CAAGCAACAGTAACATCAAACCGACCAGGGTTATTCTATGGCCAATGCTCTGAAATTTGT
64 | GGATCTAACCATAGCTTTATGCCCATTGTCCTAGAAATGGTTCCACTAAAATATTTCGAA
65 | AACTGATCTGCTTCAATAATT---------------------TAA
66 | >Seal
67 | ATGGCATACCCCCTACAAATAGGCCTACAAGATGCAACCTCTCCCATTATAGAGGAGTTA
68 | CTACACTTCCATGACCACACATTAATAATTGTGTTCCTAATTAGCTCATTAGTACTCTAC
69 | ATTATCTCACTTATACTAACCACGAAACTCACCCACACAAGTACAATAGACGCACAAGAA
70 | GTGGAAACGGTGTGAACGATCCTACCCGCTATCATTTTAATTCTCATTGCCCTACCATCA
71 | TTACGAATCCTCTACATAATGGACGAGATCAATAACCCTTCCTTGACCGTAAAAACTATA
72 | GGACATCAGTGATACTGAAGCTATGAGTACACAGACTACGAAGACCTGAACTTTGACTCA
73 | TATATGATCCCCACACAAGAACTAAAGCCCGGAGAACTACGACTGCTAGAAGTAGACAAT
74 | CGAGTAGTCCTCCCAATAGAAATAACAATCCGCATACTAATCTCATCAGAAGATGTACTC
75 | CACTCATGAGCCGTACCGTCCCTAGGACTAAAAACTGATGCTATCCCAGGACGACTAAAC
76 | CAAACAACCCTAATAACCATACGACCAGGACTGTACTACGGTCAATGCTCAGAAATCTGT
77 | GGTTCAAACCACAGCTTCATACCTATTGTCCTCGAATTGGTCCCACTATCCCACTTCGAG
78 | AAATGATCTACCTCAATGCTT---------------------TAA
79 | >Whale
80 | ATGGCATATCCATTCCAACTAGGTTTCCAAGATGCAGCATCACCCATCATAGAAGAGCTC
81 | CTACACTTTCACGATCATACACTAATAATCGTTTTTCTAATTAGCTCTTTAGTTCTCTAC
82 | ATTATTACCCTAATGCTTACAACCAAATTAACACATACTAGTACAATAGACGCCCAAGAA
83 | GTAGAAACTGTCTGAACTATCCTCCCAGCCATTATCTTAATTTTAATTGCCTTGCCTTCA
84 | TTACGGATCCTTTACATAATAGACGAAGTCAATAACCCCTCCCTCACTGTAAAAACAATA
85 | GGTCACCAATGATATTGAAGCTATGAGTATACCGACTACGAAGACCTAAGCTTCGACTCC
86 | TATATAATCCCAACATCAGACCTAAAGCCAGGAGAACTACGATTATTAGAAGTAGATAAC
87 | CGAGTTGTCTTACCTATAGAAATAACAATCCGAATATTAGTCTCATCAGAAGACGTACTC
88 | CACTCATGGGCCGTACCCTCCTTGGGCCTAAAAACAGATGCAATCCCAGGACGCCTAAAC
89 | CAAACAACCTTAATATCAACACGACCAGGCCTATTTTATGGACAATGCTCAGAGATCTGC
90 | GGCTCAAACCACAGTTTCATACCAATTGTCCTAGAACTAGTACCCCTAGAAGTCTTTGAA
91 | AAATGATCTGTATCAATACTA---------------------TAA
92 | >Frog
93 | ATGGCACACCCATCACAATTAGGTTTTCAAGACGCAGCCTCTCCAATTATAGAAGAATTA
94 | CTTCACTTCCACGACCATACCCTCATAGCCGTTTTTCTTATTAGTACGCTAGTTCTTTAC
95 | ATTATTACTATTATAATAACTACTAAACTAACTAATACAAACCTAATGGACGCACAAGAG
96 | ATCGAAATAGTGTGAACTATTATACCAGCTATTAGCCTCATCATAATTGCCCTTCCATCC
97 | CTTCGTATCCTATATTTAATAGATGAAGTTAATGATCCACACTTAACAATTAAAGCAATC
98 | GGCCACCAATGATACTGAAGCTACGAATATACTAACTATGAGGATCTCTCATTTGACTCT
99 | TATATAATTCCAACTAATGACCTTACCCCTGGACAATTCCGGCTGCTAGAAGTTGATAAT
100 | CGAATAGTAGTCCCAATAGAATCTCCAACCCGACTTTTAGTTACAGCCGAAGACGTCCTC
101 | CACTCGTGAGCTGTACCCTCCTTGGGTGTCAAAACAGATGCAATCCCAGGACGACTTCAT
102 | CAAACATCATTTATTGCTACTCGTCCGGGAGTATTTTACGGACAATGTTCAGAAATTTGC
103 | GGAGCAAACCACAGCTTTATACCAATTGTAGTTGAAGCAGTACCGCTAACCGACTTTGAA
104 | AACTGATCTTCATCAATACTA---GAAGCATCACTA------AGA
--------------------------------------------------------------------------------
/static/example-files/nexus/aminoacid.nex:
--------------------------------------------------------------------------------
1 | #NEXUS
2 |
3 | Begin data;
4 | Dimensions ntax=10 nchar=234;
5 | Format datatype=protein gap=- interleave;
6 | Matrix
7 | Cow MAYPMQLGFQDATSPIMEELLHFHDHTLMIVFLISSLVLYIISLMLTTKLTHTSTMDAQE
8 | Carp MAHPTQLGFKDAAMPVMEELLHFHDHALMIVLLISTLVLYIITAMVSTKLTNKYILDSQE
9 | Chicken MANHSQLGFQDASSPIMEELVEFHDHALMVALAICSLVLYLLTLMLMEKLS-SNTVDAQE
10 | Human MAHAAQVGLQDATSPIMEELITFHDHALMIIFLICFLVLYALFLTLTTKLTNTNISDAQE
11 | Loach MAHPTQLGFQDAASPVMEELLHFHDHALMIVFLISALVLYVIITTVSTKLTNMYILDSQE
12 | Mouse MAYPFQLGLQDATSPIMEELMNFHDHTLMIVFLISSLVLYIISLMLTTKLTHTSTMDAQE
13 | Rat MAYPFQLGLQDATSPIMEELTNFHDHTLMIVFLISSLVLYIISLMLTTKLTHTSTMDAQE
14 | Seal MAYPLQMGLQDATSPIMEELLHFHDHTLMIVFLISSLVLYIISLMLTTKLTHTSTMDAQE
15 | Whale MAYPFQLGFQDAASPIMEELLHFHDHTLMIVFLISSLVLYIITLMLTTKLTHTSTMDAQE
16 | Frog MAHPSQLGFQDAASPIMEELLHFHDHTLMAVFLISTLVLYIITIMMTTKLTNTNLMDAQE
17 |
18 | Cow VETIWTILPAIILILIALPSLRILYMMDEINNPSLTVKTMGHQWYWSYEYTDYEDLSFDS
19 | Carp IEIVWTILPAVILVLIALPSLRILYLMDEINDPHLTIKAMGHQWYWSYEYTDYENLGFDS
20 | Chicken VELIWTILPAIVLVLLALPSLQILYMMDEIDEPDLTLKAIGHQWYWTYEYTDFKDLSFDS
21 | Human METVWTILPAIILVLIALPSLRILYMTDEVNDPSLTIKSIGHQWYWTYEYTDYGGLIFNS
22 | Loach IEIVWTVLPALILILIALPSLRILYLMDEINDPHLTIKAMGHQWYWSYEYTDYENLSFDS
23 | Mouse VETIWTILPAVILIMIALPSLRILYMMDEINNPVLTVKTMGHQWYWSYEYTDYEDLCFDS
24 | Rat VETIWTILPAVILILIALPSLRILYMMDEINNPVLTVKTMGHQWYWSYEYTDYEDLCFDS
25 | Seal VETVWTILPAIILILIALPSLRILYMMDEINNPSLTVKTMGHQWYWSYEYTDYEDLNFDS
26 | Whale VETVWTILPAIILILIALPSLRILYMMDEVNNPSLTVKTMGHQWYWSYEYTDYEDLSFDS
27 | Frog IEMVWTIMPAISLIMIALPSLRILYLMDEVNDPHLTIKAIGHQWYWSYEYTNYEDLSFDS
28 |
29 | Cow YMIPTSELKPGELRLLEVDNRVVLPMEMTIRMLVSSEDVLHSWAVPSLGLKTDAIPGRLN
30 | Carp YMVPTQDLAPGQFRLLETDHRMVVPMESPVRVLVSAEDVLHSWAVPSLGVKMDAVPGRLN
31 | Chicken YMTPTTDLPLGHFRLLEVDHRIVIPMESPIRVIITADDVLHSWAVPALGVKTDAIPGRLN
32 | Human YMLPPLFLEPGDLRLLDVDNRVVLPIEAPIRMMITSQDVLHSWAVPTLGLKTDAIPGRLN
33 | Loach YMIPTQDLTPGQFRLLETDHRMVVPMESPIRILVSAEDVLHSWALPAMGVKMDAVPGRLN
34 | Mouse YMIPTNDLKPGELRLLEVDNRVVLPMELPIRMLISSEDVLHSWAVPSLGLKTDAIPGRLN
35 | Rat YMIPTNDLKPGELRLLEVDNRVVLPMELPIRMLISSEDVLHSWAIPSLGLKTDAIPGRLN
36 | Seal YMIPTQELKPGELRLLEVDNRVVLPMEMTIRMLISSEDVLHSWAVPSLGLKTDAIPGRLN
37 | Whale YMIPTSDLKPGELRLLEVDNRVVLPMEMTIRMLVSSEDVLHSWAVPSLGLKTDAIPGRLN
38 | Frog YMIPTNDLTPGQFRLLEVDNRMVVPMESPTRLLVTAEDVLHSWAVPSLGVKTDAIPGRLH
39 |
40 | Cow QTTLMSSRPGLYYGQCSEICGSNHSFMPIVLELVPLKYFEKWSASML-------
41 | Carp QAAFIASRPGVFYGQCSEICGANHSFMPIVVEAVPLEHFENWSSLMLEDASLGS
42 | Chicken QTSFITTRPGVFYGQCSEICGANHSYMPIVVESTPLKHFEAWSSL------LSS
43 | Human QTTFTATRPGVYYGQCSEICGANHSFMPIVLELIPLKIFEM-------GPVFTL
44 | Loach QTAFIASRPGVFYGQCSEICGANHSFMPIVVEAVPLSHFENWSTLMLKDASLGS
45 | Mouse QATVTSNRPGLFYGQCSEICGSNHSFMPIVLEMVPLKYFENWSASMI-------
46 | Rat QATVTSNRPGLFYGQCSEICGSNHSFMPIVLEMVPLKYFENWSASMI-------
47 | Seal QTTLMTMRPGLYYGQCSEICGSNHSFMPIVLELVPLSHFEKWSTSML-------
48 | Whale QTTLMSTRPGLFYGQCSEICGSNHSFMPIVLELVPLEVFEKWSVSML-------
49 | Frog QTSFIATRPGVFYGQCSEICGANHSFMPIVVEAVPLTDFENWSSSML-EASL--
50 | ;
51 | End;
52 |
--------------------------------------------------------------------------------
/static/example-files/phylip/AA.txt:
--------------------------------------------------------------------------------
1 | 20 100
2 | taxon_1 VPPYRWVAGVFITQYMNNIVYDDRISDLCKPVFLINPCHCAPFSGKTIGQ
3 | taxon_2 WKEPTYIISEFFYVKTAWYWEVESSSSNFIKECIEACEQPYNHSGCKKFE
4 | taxon_3 EGPRSPINHSAEHMVSQLISDCKMWEHPYTTCRGKEVFWFTIKPWACKIH
5 | taxon_4 GRHFCWCSTRDAANPVRLCHKVQNCDDVKGQANSCLWSIMEKFERMIIEP
6 | taxon_5 DEDCSHPPVYDSPDDSISDHQDGNNEFDTLGMWGMVYPRWSCAWMIAKKN
7 | taxon_6 CAWCKDKPWPRSHTISKLYHHDFYKHFMTRSWTIILCQYSEAKPSFTQIS
8 | taxon_7 YCINQMANLHEWNVVGNARSKRSCRIGRCNSKEMRSKAREMESESGFRVQ
9 | taxon_8 QQPMSHMLWFTHEECWDHVGSHTPRYEKKRPQCTVPHLDKIDPLRLALHG
10 | taxon_9 PAQNMDTFQKGRLAWRMFDYQWNQKGDIHKASTVGAKLGESGTAGGFSYP
11 | taxon_10 YENFLWSGCWGHLFGATWMRGEKKMDHQVDYHHHLPCFFPDTIWFVDEEF
12 | taxon_11 LEYHMCCMAHESGKCCTIAKWAHCSSIIWMQPGQLSANHFDEEKSVIADQ
13 | taxon_12 TVNYNLFWIFVFWLYASDNYYTPFLNEKPQEFQGAWYGYHWFDYQPHIVP
14 | taxon_13 FAKVELIGVKILDFYGKFMDFFNDCDDEITQRFLTLHSVHPQASSIHKWH
15 | taxon_14 GNARGVCQKKCSFMRMVEHIQFDKTFMALSVRRECLLDAATSRLIDAPFM
16 | taxon_15 ICYAEFTKIVKGINGVDDWYKGQWCGMVRTPKMHPHNGLSWCKMNRGNEH
17 | taxon_16 ACPYEMRHNGVWKIHDYRICMMRVTWPTHNTRFDFPKFEYQESPGAQFQE
18 | taxon_17 IEVWKEVRYDYLLFPEIANCTQGWFSHHYIKDIGCKPGISIACHMDSLSD
19 | taxon_18 LVTKVVQEYKNYTRMFTYDVLQQYCMTEWTYDLFNHYGWVFYTASSFKWI
20 | taxon_19 YYVKYPMNWSRATHDHNKWSSTVQIVAMGHIWIQFFQRDSRFVHIAVMRD
21 | taxon_20 KVIHKWKKHLVNEKYHSEMYLAIGTSSWVTFWEDCMWQFDCCFPDNGTVC
22 |
23 | DLSSTILQGDMTIDDSWINSDRGEMMFVRIRRCNDIWVFAMRMYYQWSSQ
24 | ESCVKFVTYEADWPKVGFSQCKESKAVTAVHIPCNQIVQGNKPIHLHWEF
25 | QWYICIIREHNFSWQWCMNLFNKNWWCNVVKRSCWHAHGFPRCNACNWRI
26 | GNETAMNKVGTNGKGATQKKFRNNLYNFFFAWQSMCHMHMLTAYHTYCAY
27 | FNNHPHLGIHFCEPIGLDTNANFNVQGHIRMLLTHPMIDSVQTDFSPCTW
28 | HIAMDPNTPVYLCIAEGTTIKANCNEFWWWSVRDLRFKMATPYHQQSPKK
29 | EACHEIEFALFGAQGHEVGNYLMCFIWKGMWFERLWNKHQIYKGCDTSAP
30 | GDWKMCWRNTYGGEISHVGKEFPKPLPYYSIYEGSDHKSTQILKHIELTC
31 | RSKTDKFLRLFANIPYSEWCDIAEEEDSGCCHAHTPYGMFLFAITESFTL
32 | VQASVIAFYPHMRCGHPRVPTIGSNCCWVGAFDPTREPRLRYILYSYIDF
33 | GYPMVECCSCKIIAGDEWKDSLQRPGSSFGDYLTSVRGVTGNCQWNNCFY
34 | SWFHGKFMKRGGKNLVNSQISRNVIRFMHHSGLCKIDFMSVEFVSMATNW
35 | GTVTQINPISLQRKMNTIFSIEDHTIDSFVQHASPINLPVGWVNTDTYKA
36 | LNNKHPLNERTDFMLKLKYNQDCSPEWGYADGAGIKRVAFEYIAHRPPNQ
37 | AVAIINTKWEWCIELECYKHQRYLHTEVQLRIQMKQAIAHKMKITWFRRA
38 | SHRGMVQHDRVTPYNQFSVPVDYVKFRTMALEDNYGELRTIPMMLCEFNK
39 | LWEEMKHQIMYHESEFEYGIIYKPVECIWYCTLWTRDMNSYRFSDLAVYP
40 | DCNNSAYGAANDENQSSDRAVMCTHVGQNMHERCACHGWCGKMNCLFYCG
41 | PYFKQGFIQIRVMHARFAHCILWAMATWKEAHLHKSNWHGLYEQPLMKCM
42 | RHLQYPWDDCLYMSLMADQFPVGMQMQLWQIFAVVCERDHGYCGTHNARV
43 |
--------------------------------------------------------------------------------
/static/example-files/phylip/aminoacid.txt:
--------------------------------------------------------------------------------
1 | 18 50
2 |
3 | TAXON_1 VPPYRWVAGVFITQYMNNIVYDDRISDLCKPVFLINPCHCAPFSGKTIGQ
4 | TAXON_2 WKEPTYIISEFFYVKTAWYWEVESSSSNFIKECIEACEQPYNHSGCKKFE
5 | TAXON_3 EGPRSPINHSAEHMVSQLISDCKMWEHPYTTCRGKEVFWFTIKPWACKIH
6 | TAXON_4 GRHFCWCSTRDAANPVRLCHKVQNCDDVKGQANSCLWSIMEKFERMIIEP
7 | TAXON_5 DEDCSHPPVYDSPDDSISDHQDGNNEFDTLGMWGMVYPRWSCAWMIAKKN
8 | TAXON_6 CAWCKDKPWPRSHTISKLYHHDFYKHFMTRSWTIILCQYSEAKPSFTQIS
9 | TAXON_7 YCINQMANLHEWNVVGNARSKRSCRIGRCNSKEMRSKAREMESESGFRVQ
10 | TAXON_8 QQPMSHMLWFTHEECWDHVGSHTPRYEKKRPQCTVPHLDKIDPLRLALHG
11 | TAXON_9 PAQNMDTFQKGRLAWRMFDYQWNQKGDIHKASTVGAKLGESGTAGGFSYP
12 | TAXON_10 YENFLWSGCWGHLFGATWMRGEKKMDHQVDYHHHLPCFFPDTIWFVDEEF
13 | TAXON_11 LEYHMCCMAHESGKCCTIAKWAHCSSIIWMQPGQLSANHFDEEKSVIADQ
14 | TAXON_13 TVNYNLFWIFVFWLYASDNYYTPFLNEKPQEFQGAWYGYHWFDYQPHIVP
15 | TAXON_14 FAKVELIGVKILDFYGKFMDFFNDCDDEITQRFLTLHSVHPQASSIHKWH
16 | TAXON_15 GNARGVCQKKCSFMRMVEHIQFDKTFMALSVRRECLLDAATSRLIDAPFM
17 | TAXON_16 ICYAEFTKIVKGINGVDDWYKGQWCGMVRTPKMHPHNGLSWCKMNRGNEH
18 | TAXON_17 ACPYEMRHNGVWKIHDYRICMMRVTWPTHNTRFDFPKFEYQESPGAQFQE
19 | TAXON_18 IEVWKEVRYDYLLFPEIANCTQGWFSHHYIKDIGCKPGISIACHMDSLSD
20 | TAXON_19 LVTKVVQEYKNYTRMFTYDVLQQYCMTEWTYDLFNHYGWVFYTASSFKWI
21 |
--------------------------------------------------------------------------------
/static/example-files/phylip/binary.txt:
--------------------------------------------------------------------------------
1 | 18 52
2 | TAXON_1 1010101011010111101110110011010111111010110101011110
3 | TAXON_2 1010101010110101101110110110110110111010110100111110
4 | TAXON_3 1010101010110101011110110110101110111010110100111101
5 | TAXON_4 1010101010110100111110110110101110111010110010111100
6 | TAXON_5 1010101010110100111101010110101101101010111010111100
7 | TAXON_6 1010101010110010111100110110100100011010111010111100
8 | TAXON_7 1010101010111010111100110110100010111010111101101101
9 | TAXON_8 1010101010111010111100101110100010111001111101101101
10 | TAXON_9 1010101010110010111100101110100001011001111010101101
11 | TAXON_10 1010101011011010111100101110100010110101111001101101
12 | TAXON_11 1010101010110101010111101101101011101101101101011101
13 | TAXON_13 1010101010110101001111101101101011101101101101011101
14 | TAXON_14 1010101010110101001111010101101011011010101101011011
15 | TAXON_15 1010101010010111101111001101101001000001101101001000
16 | TAXON_16 1010101010010111101111001101101000101001101101000101
17 | TAXON_17 1010101010010111101111001011101000101001011101000101
18 | TAXON_18 1010101010010111101111001011101000010001011101000010
19 | TAXON_19 1010101010010111101111001011101000101001011101000101
20 |
--------------------------------------------------------------------------------
/static/example-files/phylip/dna_interleaved.txt:
--------------------------------------------------------------------------------
1 | 5 42
2 | Turkey AAGCTNGGGC ATTTCAGGGT
3 | Salmo_gairAAGCCTTGGC AGTGCAGGGT
4 | H_Sapiens ACCGGTTGGC CGTTCAGGGT
5 | Chimp AAACCCTTGC CGTTACGCTT
6 | Gorilla AAACCCTTGC CGGTACGCTT
7 |
8 | GAGCCCGGGC AATACAGGGT AT
9 | GAGCCGTGGC CGGGCACGGT AT
10 | ACAGGTTGGC CGTTCAGGGT AA
11 | AAACCGAGGC CGGGACACTC AT
12 | AAACCATTGC CGGTACGCTT AA
13 |
--------------------------------------------------------------------------------
/static/example-files/phylip/dna_interleaved_relaxed.txt:
--------------------------------------------------------------------------------
1 | 5 42
2 | Turkey AAGCTNGGGC ATTTCAGGGT
3 | Salmo_gair AAGCCTTGGC AGTGCAGGGT
4 | H_Sapiens ACCGGTTGGC CGTTCAGGGT
5 | Chimp AAACCCTTGC CGTTACGCTT
6 | Gorilla AAACCCTTGC CGGTACGCTT
7 |
8 | GAGCCCGGGC AATACAGGGT AT
9 | GAGCCGTGGC CGGGCACGGT AT
10 | ACAGGTTGGC CGTTCAGGGT AA
11 | AAACCGAGGC CGGGACACTC AT
12 | AAACCATTGC CGGTACGCTT AA
13 |
--------------------------------------------------------------------------------
/static/example-files/phylip/dna_sequential.txt:
--------------------------------------------------------------------------------
1 | 5 42
2 | Turkey AAGCTNGGGC ATTTCAGGGT
3 | GAGCCCGGGC AATACAGGGT AT
4 | Salmo gairAAGCCTTGGC AGTGCAGGGT
5 | GAGCCGTGGC CGGGCACGGT AT
6 | H. SapiensACCGGTTGGC CGTTCAGGGT
7 | ACAGGTTGGC CGTTCAGGGT AA
8 | Chimp AAACCCTTGC CGTTACGCTT
9 | AAACCGAGGC CGGGACACTC AT
10 | Gorilla AAACCCTTGC CGGTACGCTT
11 | AAACCATTGC CGGTACGCTT AA
12 |
--------------------------------------------------------------------------------
/static/example-files/phylip/dna_sequential_relaxed.txt:
--------------------------------------------------------------------------------
1 | 5 42
2 | Turkey AAGCTNGGGC ATTTCAGGGT
3 | GAGCCCGGGC AATACAGGGT AT
4 | Salmo_gair AAGCCTTGGC AGTGCAGGGT
5 | GAGCCGTGGC CGGGCACGGT AT
6 | H_Sapiens ACCGGTTGGC CGTTCAGGGT
7 | ACAGGTTGGC CGTTCAGGGT AA
8 | Chimp AAACCCTTGC CGTTACGCTT
9 | AAACCGAGGC CGGGACACTC AT
10 | Gorilla AAACCCTTGC CGGTACGCTT
11 | AAACCATTGC CGGTACGCTT AA
12 |
--------------------------------------------------------------------------------
/static/example-files/phylip/multistate.txt:
--------------------------------------------------------------------------------
1 | 18 50
2 | TAXON_1 10101010110101111011102222210131311110101101010111
3 | TAXON_2 10101010101101011011102222210131301110101101001111
4 | TAXON_3 12222210101101010111102222201131301110101101001111
5 | TAXON_4 12222210101101001111102222201131301110101100101111
6 | TAXON_5 12222210101101001111012222201130311010101110101111
7 | TAXON_6 12222210101100101111002222200130300110101110101111
8 | TAXON_7 12222210101110101111002222200031301110101111011011
9 | TAXON_8 12222210101110101111002222200031301110011111011011
10 | TAXON_9 12222210101100101111002222200030310110011110121011
11 | TAXON_10 12222210110110101111002222200021201101011110021011
12 | TAXON_11 12222210101101010101112222201021211011011011020111
13 | TAXON_13 12333310101101010011112222201021211011011011020111
14 | TAXON_14 12333310101101010011110101011010110110101011020110
15 | TAXON_15 12333310100101111011110011011010010000011011020010
16 | TAXON_16 12333310100101111011110011011010001010011011020001
17 | TAXON_17 12333310100101111011110010111010001010010111020001
18 | TAXON_18 10101010100101111011110010111010000100010111010000
19 | TAXON_19 10101010100101111011110010111010001010010111010001
20 |
--------------------------------------------------------------------------------
/static/example-files/phylip/partition_file.txt:
--------------------------------------------------------------------------------
1 | DNA, gene1 = 1-3676
2 | BIN, morph = 3677-3851
--------------------------------------------------------------------------------
/static/example-files/tree/backboneConstraint/backboneConstraint.txt:
--------------------------------------------------------------------------------
1 | (Mouse, Rat, (Human, Whale));
2 |
--------------------------------------------------------------------------------
/static/example-files/tree/backboneConstraint/dna.phy:
--------------------------------------------------------------------------------
1 | 10 60
2 | Cow ATGGCATATCCCATACAACTAGGATTCCAAGATGCAACATCACCAATCATAGAAGAACTA
3 | Carp ATGGCACACCCAACGCAACTAGGTTTCAAGGACGCGGCCATACCCGTTATAGAGGAACTT
4 | Chicken ATGGCCAACCACTCCCAACTAGGCTTTCAAGACGCCTCATCCCCCATCATAGAAGAGCTC
5 | Human ATGGCACATGCAGCGCAAGTAGGTCTACAAGACGCTACTTCCCCTATCATAGAAGAGCTT
6 | Loach ATGGCACATCCCACACAATTAGGATTCCAAGACGCGGCCTCACCCGTAATAGAAGAACTT
7 | Mouse ATGGCCTACCCATTCCAACTTGGTCTACAAGACGCCACATCCCCTATTATAGAAGAGCTA
8 | Rat ATGGCTTACCCATTTCAACTTGGCTTACAAGACGCTACATCACCTATCATAGAAGAACTT
9 | Seal ATGGCATACCCCCTACAAATAGGCCTACAAGATGCAACCTCTCCCATTATAGAGGAGTTA
10 | Whale ATGGCATATCCATTCCAACTAGGTTTCCAAGATGCAGCATCACCCATCATAGAAGAGCTC
11 | Frog ATGGCACACCCATCACAATTAGGTTTTCAAGACGCAGCCTCTCCAATTATAGAAGAATTA
12 |
--------------------------------------------------------------------------------
/static/example-files/tree/multifurcatingConstraint/dna.phy:
--------------------------------------------------------------------------------
1 | 10 60
2 | Cow ATGGCATATCCCATACAACTAGGATTCCAAGATGCAACATCACCAATCATAGAAGAACTA
3 | Carp ATGGCACACCCAACGCAACTAGGTTTCAAGGACGCGGCCATACCCGTTATAGAGGAACTT
4 | Chicken ATGGCCAACCACTCCCAACTAGGCTTTCAAGACGCCTCATCCCCCATCATAGAAGAGCTC
5 | Human ATGGCACATGCAGCGCAAGTAGGTCTACAAGACGCTACTTCCCCTATCATAGAAGAGCTT
6 | Loach ATGGCACATCCCACACAATTAGGATTCCAAGACGCGGCCTCACCCGTAATAGAAGAACTT
7 | Mouse ATGGCCTACCCATTCCAACTTGGTCTACAAGACGCCACATCCCCTATTATAGAAGAGCTA
8 | Rat ATGGCTTACCCATTTCAACTTGGCTTACAAGACGCTACATCACCTATCATAGAAGAACTT
9 | Seal ATGGCATACCCCCTACAAATAGGCCTACAAGATGCAACCTCTCCCATTATAGAGGAGTTA
10 | Whale ATGGCATATCCATTCCAACTAGGTTTCCAAGATGCAGCATCACCCATCATAGAAGAGCTC
11 | Frog ATGGCACACCCATCACAATTAGGTTTTCAAGACGCAGCCTCTCCAATTATAGAAGAATTA
12 |
--------------------------------------------------------------------------------
/static/example-files/tree/multifurcatingConstraint/multifurcatingConstraint.txt:
--------------------------------------------------------------------------------
1 | (Mouse, Rat, Frog, Loach, (Human, Whale,Carp));
2 |
--------------------------------------------------------------------------------
/static/example-files/tree/test.tre:
--------------------------------------------------------------------------------
1 | ((Seal:0.100000,Cow:0.100000):0.100000,(Mouse:0.100000,(((Frog:0.100000,Whale:0.100000):0.100000,Loach:0.100000):0.100000,Chicken:0.100000):0.100000):0.100000,Human:0.100000):0.0;
2 |
--------------------------------------------------------------------------------
/static/test-files/fail_bad_base_at_site.txt:
--------------------------------------------------------------------------------
1 | 5 52
2 | TAXON_1 1010101011010111101110110011010111111010110101011110
3 | TAXON_2 1010101,101_0101101110110110110110111010110100111110
4 | TAXON_3 10101010!!!10101011110110110101110111010110100111101
5 | TAXON_4 1010101010110100111110110110101110111010110010111100
6 | TAXON_5 1010101010110100111101010110101101101010111010111100
7 |
--------------------------------------------------------------------------------
/static/test-files/fail_bad_name.txt:
--------------------------------------------------------------------------------
1 | 5 20
2 | Turkey AAGCTNGGGC ATTTCAGGGT
3 | Salmo_gair AAGCCTTGGC AGTGCAGGGT
4 | H.Sapiens. ACCGGTTGGC CGTTCAGGGT
5 | Chimp: AAACCCTTGC CGTTACGCTT
6 | Gorilla AAACCCTTGC CGGTACGCTT
7 |
--------------------------------------------------------------------------------
/static/test-files/fail_duplicate_taxon.fas:
--------------------------------------------------------------------------------
1 | >TAXON_1
2 | 1010101011010111101110110011010111111010110101011110
3 | >TAXON_2
4 | 1010101010110101101110110110110110111010110100111110
5 | >TAXON_2
6 | 1010101010110101011110110110101110111010110100111101
7 | >TAXON_4
8 | 1010101010110100111110110110101110111010110010111100
9 | >TAXON_5
10 | 1010101010110100111101010110101101101010111010111100
11 |
--------------------------------------------------------------------------------
/static/test-files/fail_duplicate_taxon.phy:
--------------------------------------------------------------------------------
1 | 5 52
2 | TAXON_1 1010101011010111101110110011010111111010110101011110
3 | TAXON_2 1010101010110101101110110110110110111010110100111110
4 | TAXON_2 1010101010110101011110110110101110111010110100111101
5 | TAXON_4 1010101010110100111110110110101110111010110010111100
6 | TAXON_5 1010101010110100111101010110101101101010111010111100
7 |
--------------------------------------------------------------------------------
/static/test-files/fail_too_few_sequences_modeltest.txt:
--------------------------------------------------------------------------------
1 | 2 20
2 | H_Sapiens ACCGGTTGGC CGTTCAGGGT
3 | Chimp AAACCCTTGC CGTTACGCTT
4 |
--------------------------------------------------------------------------------
/static/test-files/fail_too_few_sequences_raxml.txt:
--------------------------------------------------------------------------------
1 | 3 20
2 | H_Sapiens ACCGGTTGGC CGTTCAGGGT
3 | Chimp AAACCCTTGC CGTTACGCTT
4 | Gorilla AAACCCTTGC CGGTACGCTT
5 |
--------------------------------------------------------------------------------
/static/test-files/fail_unequal_sequence_length.fas:
--------------------------------------------------------------------------------
1 | >TAXON_1
2 | 1010101011010111101110110011010111111010110101011110
3 | >TAXON_2
4 | 1010101010110101101110110110110110111010110100111110
5 | >TAXON_3
6 | 101010101011010101111011011010111011101011010011110
7 | >TAXON_4
8 | 1010101010110100111110110110101110111010110010111100
9 | >TAXON_5
10 | 1010101010110100111101010110101101101010111010111100
11 |
--------------------------------------------------------------------------------
/static/test-files/fail_unequal_sequence_length.phy:
--------------------------------------------------------------------------------
1 | 5 52
2 | TAXON_1 1010101011010111101110110011010111111010110101011110
3 | TAXON_2 1010101010110101101110110110110110111010110100111110
4 | TAXON_3 101010101011010101111011011010111011101011010011110
5 | TAXON_4 1010101010110100111110110110101110111010110010111100
6 | TAXON_5 1010101010110100111101010110101101101010111010111100
7 |
--------------------------------------------------------------------------------
/static/test-files/test_ambiguous_nucleotide.txt:
--------------------------------------------------------------------------------
1 | 5 20
2 | Turkey AAGCTYGGGC ATTTCAGGGT
3 | Salmo_gair AAGCCTTGGC AGTGCAGGGT
4 | H_Sapiens ACCGGTTGGC CGTTCAGGGT
5 | Chimp AAACCCTTGC CGTTACGCTT
6 | Gorilla AAACCCTTGC CGGTACGCTT
7 |
--------------------------------------------------------------------------------
/static/test-files/test_interleaved.txt:
--------------------------------------------------------------------------------
1 | >gi|161085638|dbj|AB305033.1|
2 | ATATGCCTGAAAGTGGCGGACGGGTGAGTAACACGTGGGTGACCTGCCTCGGAGTGGGGGATAACCATGG
3 | GAAACTGTGGCTAATACCGCATGGGCTTGTTGGCTTTGGCGGCCAACGAGTAAAGCTTTAGTGCTTCGAG
4 | AGGGGCCTGCGTCCGATTAGGTAGTTGGTGAGGTAATGGCTCACCAAGCCGATGATCGGTAGCTGGTCTG
5 | >gi|161085638|dbj|AB305644.1|
6 | ATATGCCTGAAAGTGGCGGACGGGTGAGTAACACGTGGGTGACCTGCCTCGGAGTGGGGGATAACCATGG
7 | GAAACTGTGGCTAATACCGCATGGGCTTGTTGGCTTTGGCGGCCAACGAGTAAAGCTTTAGTGCTTCGAG
8 | AGGGGCCTGCGTCCGATTAGGTAGTTGGTGAGGTAATGGCTCACCAAGCCGATGATCGGTAGCTGGTCTG
9 |
--------------------------------------------------------------------------------
/static/test-files/test_invariant_sites.txt:
--------------------------------------------------------------------------------
1 | 6 20
2 | Turkey AAGCTNGGGC ATTTCAGGGT
3 | Salmo_gair AAGCCTTGGC AGTGCAGGGT
4 | H_Sapiens ACCGGTTGGC CGTTCAGGGT
5 | Chimp AAACCCTTGC CGTTACGCTT
6 | Gorilla AAACCCTTGC CGGTACGCTT
7 | Invariant GGGGGGGGGG GGGGGGGGGG
8 |
--------------------------------------------------------------------------------
/static/test-files/test_lower_case_bases.txt:
--------------------------------------------------------------------------------
1 | 5 20
2 | Turkey AAGCTNGGGC ATTTCAGGGT
3 | Salmo_gair aagccttggc AGTGCAGGGT
4 | H_Sapiens ACCGGTTGGC CGTTCAGGGT
5 | Chimp AAACCCTTGC CGTTACGCTT
6 | Gorilla AAACCCTTGC CGGTACGCTT
7 |
--------------------------------------------------------------------------------
/static/test-files/test_questionmark_nucleotide.txt:
--------------------------------------------------------------------------------
1 | 5 20
2 | Turkey AAGCT?GGGC ATTTCAGGGT
3 | Salmo_gair AAGCCTTGGC AGTGCAGGGT
4 | H_Sapiens ACCGGTTGGC CGTTCAGGGT
5 | Chimp AAACCCTTGC CGTTACGCTT
6 | Gorilla AAACCCTTGC CGGTACGCTT
7 |
--------------------------------------------------------------------------------
/static/test-files/wrong_site_count.txt:
--------------------------------------------------------------------------------
1 | 5 19
2 | Turkey AAGCTNGGGC ATTTCAGGGT
3 | Salmo_gair AAGCCTTGGC AGTGCAGGGT
4 | H.Sapiens. ACCGGTTGGC CGTTCAGGGT
5 | Chimp: AAACCCTTGC CGTTACGCTT
6 | Gorilla AAACCCTTGC CGGTACGCTT
7 |
--------------------------------------------------------------------------------
/static/test-files/wrong_taxa_count.txt:
--------------------------------------------------------------------------------
1 | 6 20
2 | Turkey AAGCTNGGGC ATTTCAGGGT
3 | Salmo_gair AAGCCTTGGC AGTGCAGGGT
4 | H.Sapiens. ACCGGTTGGC CGTTCAGGGT
5 | Chimp: AAACCCTTGC CGTTACGCTT
6 | Gorilla AAACCCTTGC CGGTACGCTT
7 |
--------------------------------------------------------------------------------
/static/test-results/ASTRAL_simulated_14taxon.gene.tre:
--------------------------------------------------------------------------------
1 | (9,(5,(((6,(11,0)0.5:0.07283732395226637)0.38:0.0,(2,((1,13)0.6:0.16788087263916016,(12,8)0.62:0.1518805312927191)0.51:0.07878087785311434)0.43:0.05049616401453223)0.46:0.04652001563489282,((10,7)0.92:0.4555629450909413,(4,3)0.79:0.315333603782291)0.51:0.0852051579461301)0.47:0.05548868561765336):0.0);
2 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const SentryWebpackPlugin = require('@sentry/webpack-plugin');
2 |
3 | const package = require('./package.json');
4 |
5 | module.exports = {
6 | // other webpack configuration
7 | devtool: 'source-map',
8 | plugins: [
9 | new SentryWebpackPlugin({
10 | // sentry-cli configuration - can also be done directly through sentry-cli
11 | // see https://docs.sentry.io/product/cli/configuration/ for details
12 | authToken: process.env.SENTRY_AUTH_TOKEN,
13 | org: process.env.SENTRY_ORG,
14 | project: process.env.SENTRY_PROJECT,
15 | release: `${package.productName}@${package.version}`,
16 |
17 | // other SentryWebpackPlugin configuration
18 | include: '.',
19 | ignore: ['node_modules', 'webpack.config.js'],
20 | }),
21 | ],
22 | };
23 |
--------------------------------------------------------------------------------