├── .codacy.yml ├── .dockerignore ├── .eslintrc.js ├── .github ├── actions │ ├── docker-build-env-setup │ │ └── action.yml │ ├── extract-gsm-secret-to-file │ │ └── action.yml │ └── setup-gcloud │ │ └── action.yml └── workflows │ ├── build-and-publish-docker-image.yml │ ├── delete-branch-on-merge-to-development.yml │ ├── delete-branch-on-merge-to-master.yml │ ├── deploy-to-production.yml │ ├── deploy-to-staging.yml │ ├── run-all-tests.yml │ └── run-orch-smoketest.yml ├── .gitignore ├── .rubocop.yml ├── Dockerfile ├── Gemfile ├── Gemfile.lock ├── LICENSE.txt ├── NON_CONTAINERIZED_DEV_README.md ├── Procfile.dev ├── README.md ├── Rakefile ├── app ├── assets │ ├── config │ │ └── manifest.js │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ ├── images │ │ ├── .keep │ │ ├── AdvancedSearchExample.gif │ │ ├── SCP-Header-resize.png │ │ ├── SCP-logo.png │ │ ├── SCP-white.png │ │ ├── broad-logo-white.png │ │ ├── broad-logo.png │ │ ├── cellarium.png │ │ ├── clippy.svg │ │ ├── covid19-banner.png │ │ ├── covid19-button.png │ │ ├── covid19-logo.png │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── icon.svg │ │ ├── metadata-convention-explainer-anndata.jpg │ │ ├── metadata-convention-explainer-anndata.png │ │ ├── metadata-convention-explainer.jpg │ │ ├── microbe-icon.png │ │ ├── microbe-icon.svg │ │ ├── scp_favicon.ico │ │ ├── ui-bg_diagonals-thick_8_333333_40x40.png │ │ ├── ui-bg_flat_65_ffffff_40x100.png │ │ ├── ui-bg_glass_40_111111_1x400.png │ │ ├── ui-bg_glass_55_1c1c1c_1x400.png │ │ ├── ui-bg_highlight-hard_100_f9f9f9_1x100.png │ │ ├── ui-bg_highlight-hard_40_aaaaaa_1x100.png │ │ ├── ui-bg_highlight-soft_50_aaaaaa_1x100.png │ │ ├── ui-bg_inset-hard_45_cd0a0a_1x100.png │ │ ├── ui-bg_inset-hard_55_ffeb80_1x100.png │ │ ├── ui-icons_222222_256x240.png │ │ ├── ui-icons_444444_256x240.png │ │ ├── ui-icons_4ca300_256x240.png │ │ ├── ui-icons_555555_256x240.png │ │ ├── ui-icons_777620_256x240.png │ │ ├── ui-icons_777777_256x240.png │ │ ├── ui-icons_bbbbbb_256x240.png │ │ ├── ui-icons_cc0000_256x240.png │ │ ├── ui-icons_ededed_256x240.png │ │ ├── ui-icons_ffcf29_256x240.png │ │ └── ui-icons_ffffff_256x240.png │ ├── javascripts │ │ ├── StackBlur.js │ │ ├── application.js │ │ ├── branding_groups.coffee │ │ ├── ckeditor.js │ │ ├── ckeditor.js.map │ │ ├── clipboard.min.js │ │ ├── echarts-gl.min.js │ │ ├── echarts.min.js │ │ ├── jquery.actual.min.js │ │ ├── jquery.bootstrap.wizard.js │ │ ├── jquery.stickyPanel.js │ │ ├── morpheus-external-r.js │ │ ├── morpheus-latest.min.js │ │ ├── papaparse.min.js │ │ ├── react_rails │ │ │ └── bulkDownloadClipboard.js │ │ ├── scp-react-rails.js │ │ └── tsne.js │ └── stylesheets │ │ ├── animate.css │ │ ├── application.css.scss │ │ ├── bootstrap-select.min.css │ │ ├── morpheus.css │ │ ├── morpheus.grid.css │ │ └── slick.grid.css ├── controllers │ ├── ab_tests_controller.rb │ ├── admin_configurations_controller.rb │ ├── analysis_configurations_controller.rb │ ├── api │ │ └── v1 │ │ │ ├── api_base_controller.rb │ │ │ ├── api_docs_controller.rb │ │ │ ├── bookmarks_controller.rb │ │ │ ├── bulk_download_controller.rb │ │ │ ├── concerns │ │ │ ├── api_caching.rb │ │ │ ├── authenticator.rb │ │ │ ├── content_type.rb │ │ │ ├── convention_schemas.rb │ │ │ ├── csp_header_bypass.rb │ │ │ ├── fire_cloud_status.rb │ │ │ ├── ingest_aware.rb │ │ │ └── study_aware.rb │ │ │ ├── current_user_controller.rb │ │ │ ├── directory_listings_controller.rb │ │ │ ├── exceptions_controller.rb │ │ │ ├── external_resources_controller.rb │ │ │ ├── metadata_schemas_controller.rb │ │ │ ├── publications_controller.rb │ │ │ ├── reports_controller.rb │ │ │ ├── schemas_controller.rb │ │ │ ├── search_controller.rb │ │ │ ├── site_controller.rb │ │ │ ├── status_controller.rb │ │ │ ├── studies_controller.rb │ │ │ ├── study_file_bundles_controller.rb │ │ │ ├── study_files_controller.rb │ │ │ ├── study_search_results_objects.rb │ │ │ ├── study_shares_controller.rb │ │ │ ├── taxons_controller.rb │ │ │ ├── user_annotations_controller.rb │ │ │ └── visualization │ │ │ ├── annotations_controller.rb │ │ │ ├── clusters_controller.rb │ │ │ ├── explore_controller.rb │ │ │ └── expression_controller.rb │ ├── application_controller.rb │ ├── billing_projects_controller.rb │ ├── branding_groups_controller.rb │ ├── concerns │ │ ├── .keep │ │ ├── devise_sign_out_patch.rb │ │ └── real_ip_logger.rb │ ├── exceptions_controller.rb │ ├── feature_announcements_controller.rb │ ├── feature_flag_options_controller.rb │ ├── preset_searches_controller.rb │ ├── profiles_controller.rb │ ├── reports_controller.rb │ ├── site_controller.rb │ ├── studies_controller.rb │ ├── taxons_controller.rb │ ├── user_annotations_controller.rb │ └── users │ │ └── omniauth_callbacks_controller.rb ├── helpers │ ├── admin_configurations_helper.rb │ ├── analysis_configurations_helper.rb │ ├── application_helper.rb │ ├── billing_projects_helper.rb │ ├── branding_groups_helper.rb │ ├── devise_helper.rb │ ├── feature_flag_options_helper.rb │ ├── preset_searches_helper.rb │ ├── profiles_helper.rb │ ├── reports_helper.rb │ ├── studies_helper.rb │ ├── taxons_helper.rb │ └── user_annotations_helper.rb ├── javascript │ ├── components │ │ ├── HomePageContent.jsx │ │ ├── bookmarks │ │ │ ├── BookmarkManager.jsx │ │ │ └── BookmarksList.jsx │ │ ├── download │ │ │ └── FileDownloadControl.jsx │ │ ├── explore │ │ │ ├── CellFilteringModal.jsx │ │ │ ├── CellFilteringPanel.jsx │ │ │ ├── DifferentialExpressionFilters.jsx │ │ │ ├── DifferentialExpressionModal.jsx │ │ │ ├── DifferentialExpressionPanel.jsx │ │ │ ├── ExploreDisplayPanelManager.jsx │ │ │ ├── ExploreDisplayTabs.jsx │ │ │ ├── ExploreTabRouter.jsx │ │ │ ├── ExploreView.jsx │ │ │ ├── FacetComponents.jsx │ │ │ ├── GenomeView.jsx │ │ │ ├── NumericCellFacet.jsx │ │ │ ├── PlotTabs.jsx │ │ │ ├── ScatterTab.jsx │ │ │ ├── StudyGeneField.jsx │ │ │ └── plot-data-cache.js │ │ ├── my-studies │ │ │ ├── MyStudiesPage.jsx │ │ │ └── StudyUsageInfo.jsx │ │ ├── search │ │ │ ├── controls │ │ │ │ ├── CombinedFacetControl.jsx │ │ │ │ ├── FacetControl.jsx │ │ │ │ ├── FacetsAccordion.jsx │ │ │ │ ├── FacetsPanel.jsx │ │ │ │ ├── FilterSlider.jsx │ │ │ │ ├── Filters.jsx │ │ │ │ ├── FiltersBox.jsx │ │ │ │ ├── FiltersBoxSearchable.jsx │ │ │ │ ├── FiltersSearchBar.jsx │ │ │ │ ├── KeywordSearch.jsx │ │ │ │ ├── MoreFacetsButton.jsx │ │ │ │ ├── SearchPanel.jsx │ │ │ │ ├── download │ │ │ │ │ ├── DownloadButton.jsx │ │ │ │ │ ├── DownloadCommand.jsx │ │ │ │ │ ├── DownloadSelectionModal.jsx │ │ │ │ │ └── DownloadSelectionTable.jsx │ │ │ │ └── slider │ │ │ │ │ └── components.js │ │ │ ├── genes │ │ │ │ ├── GeneKeyword.jsx │ │ │ │ ├── GeneSearchView.jsx │ │ │ │ └── StudyGeneExpressions.jsx │ │ │ └── results │ │ │ │ ├── PagingControl.jsx │ │ │ │ ├── ResultMetadataTable.jsx │ │ │ │ ├── ResultsPanel.jsx │ │ │ │ ├── SearchQueryDisplay.jsx │ │ │ │ ├── StudyResults.jsx │ │ │ │ └── StudySearchResult.jsx │ │ ├── upload │ │ │ ├── AnnDataExpressionStep.jsx │ │ │ ├── AnnDataFileForm.jsx │ │ │ ├── AnnDataStep.jsx │ │ │ ├── AnnDataUploadStep.jsx │ │ │ ├── ClusterAssociationSelect.jsx │ │ │ ├── ClusteringFileForm.jsx │ │ │ ├── ClusteringStep.jsx │ │ │ ├── CoordinateLabelFileForm.jsx │ │ │ ├── CoordinateLabelStep.jsx │ │ │ ├── DifferentialExpressionFileForm.jsx │ │ │ ├── DifferentialExpressionStep.jsx │ │ │ ├── ExpandableFileForm.jsx │ │ │ ├── ExpressionFileForm.jsx │ │ │ ├── FileUploadControl.jsx │ │ │ ├── GeneListFileForm.jsx │ │ │ ├── GeneListStep.jsx │ │ │ ├── MTXBundledFilesForm.jsx │ │ │ ├── MetadataStep.jsx │ │ │ ├── MiscellaneousFileForm.jsx │ │ │ ├── MiscellaneousStep.jsx │ │ │ ├── ProcessedExpressionStep.jsx │ │ │ ├── RawAssociationSelect.jsx │ │ │ ├── RawCountsStep.jsx │ │ │ ├── SequenceFileForm.jsx │ │ │ ├── SequenceFileStep.jsx │ │ │ ├── SeuratFileForm.jsx │ │ │ ├── SeuratStep.jsx │ │ │ ├── SpatialStep.jsx │ │ │ ├── StepTabHeader.jsx │ │ │ ├── UploadExperienceSplitter.jsx │ │ │ ├── UploadWizard.jsx │ │ │ ├── WizardNavPanel.jsx │ │ │ ├── form-components.jsx │ │ │ └── upload-utils.js │ │ ├── validation │ │ │ └── ValidationMessage.jsx │ │ └── visualization │ │ │ ├── DotPlot.jsx │ │ │ ├── DotPlotLegend.jsx │ │ │ ├── GeneListHeatmap.jsx │ │ │ ├── Heatmap.jsx │ │ │ ├── InferCNVIdeogram.jsx │ │ │ ├── Pathway.jsx │ │ │ ├── PlotDisplayControls.jsx │ │ │ ├── PlotTitle.jsx │ │ │ ├── RelatedGenesIdeogram.jsx │ │ │ ├── ScatterPlot.jsx │ │ │ ├── StudyViolinPlot.jsx │ │ │ ├── controls │ │ │ ├── AnnotationSelector.jsx │ │ │ ├── ClusterSelector.jsx │ │ │ ├── ConsensusSelector.jsx │ │ │ ├── CreateAnnotation.jsx │ │ │ ├── DifferentialExpressionGroupPicker.jsx │ │ │ ├── GeneListSelector.jsx │ │ │ ├── InferCNVIdeogramSelector.jsx │ │ │ ├── LabelSelector.jsx │ │ │ ├── ScatterPlotLegend.jsx │ │ │ ├── SpatialSelector.jsx │ │ │ └── SubsampleSelector.jsx │ │ │ └── plot-options.jsx │ ├── hooks │ │ ├── closeableModal.js │ │ ├── useResizeEffect.js │ │ └── useUpdate.js │ ├── lib │ │ ├── ErrorBoundary.jsx │ │ ├── InfoPopup.jsx │ │ ├── InstrumentedSelect.jsx │ │ ├── LoadingSpinner.jsx │ │ ├── MessageModal.jsx │ │ ├── cell-faceting.js │ │ ├── cluster-utils.js │ │ ├── error-message.jsx │ │ ├── error-utils.jsx │ │ ├── igv-utils.js │ │ ├── layout-utils.js │ │ ├── metrics-api.js │ │ ├── metrics-perf.js │ │ ├── morpheus-heatmap.js │ │ ├── pathway-expression.js │ │ ├── plot.js │ │ ├── scale-linear.js │ │ ├── scp-api-metrics.js │ │ ├── scp-api.jsx │ │ ├── search-metrics.js │ │ ├── search-utils.js │ │ ├── sentry-logging.js │ │ ├── service-worker-cache.js │ │ ├── stats.js │ │ ├── study-overview │ │ │ └── terra-profile-warning.jsx │ │ ├── validation │ │ │ ├── chunked-line-reader.js │ │ │ ├── expression-matrices-validation.js │ │ │ ├── io.js │ │ │ ├── log-validation.js │ │ │ ├── ontology-validation.js │ │ │ ├── shared-validation.js │ │ │ ├── validate-anndata.js │ │ │ ├── validate-differential-expression.js │ │ │ ├── validate-file-content.js │ │ │ ├── validate-file.js │ │ │ └── validate-study.js │ │ └── web-worker.js │ ├── packs │ │ └── application.js │ ├── providers │ │ ├── GeneSearchProvider.jsx │ │ ├── SCPContextProvider.jsx │ │ ├── SearchFacetProvider.jsx │ │ ├── SearchSelectionProvider.jsx │ │ ├── StudySearchProvider.jsx │ │ └── UserProvider.jsx │ ├── styles │ │ ├── _brand.scss │ │ ├── _cellFiltering.scss │ │ ├── _colors.scss │ │ ├── _differentialExpression.scss │ │ ├── _explore.scss │ │ ├── _forms.scss │ │ ├── _global.scss │ │ ├── _inferCNVIdeogram.scss │ │ ├── _keywordSearch.scss │ │ ├── _notifications.scss │ │ ├── _pathway.scss │ │ ├── _relatedGenesIdeogram.scss │ │ ├── _resultsPanel.scss │ │ ├── _scatterPlot.scss │ │ ├── _search.scss │ │ ├── _searchPanel.scss │ │ ├── _spin.scss │ │ ├── _studyOverview.scss │ │ ├── _uploadWizard.scss │ │ └── application.scss │ └── vite │ │ ├── application.js │ │ └── import-meta-hot.js ├── lib │ ├── active_record_utils.rb │ ├── annotation_viz_service.rb │ ├── azul_search_service.rb │ ├── bulk_download_service.rb │ ├── cluster_cache_service.rb │ ├── cluster_viz_service.rb │ ├── differential_expression_service.rb │ ├── download_quota_service.rb │ ├── expression_viz_service.rb │ ├── file_parse_service.rb │ ├── image_pipeline_service.rb │ ├── import_service.rb │ ├── indexer.rb │ ├── loggable.rb │ ├── metrics_service.rb │ ├── mixpanel_client.rb │ ├── reports_service.rb │ ├── request_utils.rb │ ├── search_facet_populator.rb │ ├── study_search_service.rb │ ├── study_sync_service.rb │ ├── summary_stats_utils.rb │ ├── synthetic_branding_group_populator.rb │ ├── synthetic_study_populator.rb │ ├── tdr_search_service.rb │ ├── terra_analysis_service.rb │ ├── user_annotation_service.rb │ └── user_asset_service.rb ├── mailers │ ├── .keep │ ├── application_mailer.rb │ └── single_cell_mailer.rb ├── models │ ├── .keep │ ├── ab_test.rb │ ├── ab_test_assignment.rb │ ├── admin_configuration.rb │ ├── analysis_configuration.rb │ ├── analysis_metadatum.rb │ ├── analysis_output_association.rb │ ├── analysis_parameter.rb │ ├── analysis_parameter_filter.rb │ ├── analysis_submission.rb │ ├── ann_data_file_info.rb │ ├── ann_data_ingest_parameters.rb │ ├── author.rb │ ├── batch_api_client.rb │ ├── big_query_client.rb │ ├── bookmark.rb │ ├── branding_group.rb │ ├── cache_removal_job.rb │ ├── cell_metadatum.rb │ ├── cluster_file_info.rb │ ├── cluster_group.rb │ ├── concerns │ │ ├── .keep │ │ ├── annotatable.rb │ │ ├── compute_scaling.rb │ │ ├── concatenatable.rb │ │ ├── feature_flaggable.rb │ │ ├── flat_id.rb │ │ └── parameterizable.rb │ ├── configuration_option.rb │ ├── data_array.rb │ ├── data_repo_client.rb │ ├── delete_queue_job.rb │ ├── deployment_notification.rb │ ├── differential_expression_file_info.rb │ ├── differential_expression_parameters.rb │ ├── differential_expression_result.rb │ ├── directory_listing.rb │ ├── download_acceptance.rb │ ├── download_agreement.rb │ ├── download_request.rb │ ├── expression_file_info.rb │ ├── external_resource.rb │ ├── feature_announcement.rb │ ├── feature_flag.rb │ ├── feature_flag_option.rb │ ├── fire_cloud_client.rb │ ├── fire_cloud_profile.rb │ ├── gene.rb │ ├── genome_annotation.rb │ ├── genome_assembly.rb │ ├── hca_azul_client.rb │ ├── heatmap_file_info.rb │ ├── history_tracker.rb │ ├── home_page_link.rb │ ├── image_pipeline_parameters.rb │ ├── import_service_config.rb │ ├── import_service_config │ │ ├── hca.rb │ │ └── nemo.rb │ ├── ingest_job.rb │ ├── nemo_client.rb │ ├── parse_utils.rb │ ├── precomputed_score.rb │ ├── preset_search.rb │ ├── publication.rb │ ├── render_expression_arrays_parameters.rb │ ├── report_time_point.rb │ ├── reviewer_access.rb │ ├── reviewer_access_session.rb │ ├── search_facet.rb │ ├── study.rb │ ├── study_accession.rb │ ├── study_detail.rb │ ├── study_file.rb │ ├── study_file_bundle.rb │ ├── study_share.rb │ ├── taxon.rb │ ├── tos_acceptance.rb │ ├── upload_cleanup_job.rb │ ├── user.rb │ ├── user_annotation.rb │ ├── user_annotation_share.rb │ └── user_data_array.rb ├── uploaders │ ├── branding_group_image_uploader.rb │ └── upload_uploader.rb └── views │ ├── ab_tests │ ├── _ab_test_form.html.erb │ ├── _ab_test_group_name_field.html.erb │ ├── edit.html.erb │ └── update.html.erb │ ├── admin_configurations │ ├── _config_value_select.html.erb │ ├── _config_value_text.html.erb │ ├── _configuration_option_fields.erb │ ├── _deployment.html.erb │ ├── _firecloud_api_status.html.erb │ ├── _firecloud_profile.html.erb │ ├── _form.html.erb │ ├── _user_group_sync_list.html.erb │ ├── compose_users_email.html.erb │ ├── deliver_users_email.js.erb │ ├── edit.html.erb │ ├── edit_user.html.erb │ ├── firecloud_api_status.js.erb │ ├── get_service_account_profile.js.erb │ ├── index.html.erb │ ├── index.json.jbuilder │ ├── new.html.erb │ ├── refresh_api_connections.js.erb │ ├── reset_user_download_quotas.js.erb │ ├── restart_locked_jobs.js.erb │ ├── show.html.erb │ ├── show.json.jbuilder │ ├── sync_portal_user_group.js.erb │ ├── update_service_account_profile.js.erb │ └── view_deployment.js.erb │ ├── api │ └── v1 │ │ ├── api_docs │ │ ├── oauth2_redirect.html │ │ └── swagger_ui.html.erb │ │ ├── bookmarks │ │ ├── _bookmark.json.jbuilder │ │ ├── index.json.jbuilder │ │ └── show.json.jbuilder │ │ ├── directory_listings │ │ ├── _directory_listing.json.jbuilder │ │ ├── index.json.jbuilder │ │ └── show.json.jbuilder │ │ ├── external_resources │ │ ├── _external_resource.json.jbuilder │ │ ├── index.json.jbuilder │ │ └── show.json.jbuilder │ │ ├── publications │ │ ├── _publication.json.jbuilder │ │ ├── index.json.jbuilder │ │ └── show.json.jbuilder │ │ ├── schemas │ │ ├── directory_listings.json.jbuilder │ │ ├── studies.json.jbuilder │ │ ├── study_file_bundles.json.jbuilder │ │ ├── study_files.json.jbuilder │ │ └── study_shares.json.jbuilder │ │ ├── search │ │ ├── _search_facet_config.json.jbuilder │ │ ├── facet_filters.json.jbuilder │ │ └── facets.json.jbuilder │ │ ├── site │ │ ├── _analysis.json.jbuilder │ │ ├── _analysis_in_list.json.jbuilder │ │ ├── _analysis_info.json.jbuilder │ │ ├── _directory_listing.json.jbuilder │ │ ├── _study.json.jbuilder │ │ ├── _study_file.json.jbuilder │ │ ├── _study_in_list.json.jbuilder │ │ ├── analyses.json.jbuilder │ │ ├── get_analysis.json.jbuilder │ │ ├── get_study_analysis_config.json.jbuilder │ │ ├── studies.json.jbuilder │ │ ├── sync_submission_outputs.json.jbuilder │ │ └── view_study.json.jbuilder │ │ ├── studies │ │ ├── _study.json.jbuilder │ │ ├── index.json.jbuilder │ │ ├── show.json.jbuilder │ │ └── sync_study.json.jbuilder │ │ ├── study_file_bundles │ │ ├── _study_file_bundle.json.jbuilder │ │ ├── index.json.jbuilder │ │ └── show.json.jbuilder │ │ ├── study_files │ │ ├── _study_file.json.jbuilder │ │ ├── _study_file_sync.json.jbuilder │ │ ├── index.json.jbuilder │ │ ├── missing_file_bundle.json.erb │ │ └── show.json.jbuilder │ │ ├── study_shares │ │ ├── _study_share.json.jbuilder │ │ ├── index.json.jbuilder │ │ └── show.json.jbuilder │ │ └── taxons │ │ ├── _genome_annotation.json.jbuilder │ │ ├── _genome_assembly.json.jbuilder │ │ ├── _taxon.json.jbuilder │ │ ├── index.json.jbuilder │ │ └── show.json.jbuilder │ ├── billing_projects │ ├── _compute_permissions_fields.html.erb │ ├── edit_workspace_computes.html.erb │ ├── index.html.erb │ ├── new_user.html.erb │ ├── storage_estimate.html.erb │ ├── update_workspace_computes.js.erb │ └── workspaces.html.erb │ ├── branding_groups │ ├── _branding_group.json.jbuilder │ ├── _form.html.erb │ ├── edit.html.erb │ ├── index.html.erb │ ├── index.json.jbuilder │ ├── list_navigate.html.erb │ ├── new.html.erb │ ├── show.html.erb │ └── show.json.jbuilder │ ├── devise │ ├── confirmations │ │ └── new.html.erb │ ├── mailer │ │ ├── confirmation_instructions.html.erb │ │ ├── password_change.html.erb │ │ ├── reset_password_instructions.html.erb │ │ └── unlock_instructions.html.erb │ ├── passwords │ │ ├── edit.html.erb │ │ └── new.html.erb │ ├── registrations │ │ ├── edit.html.erb │ │ └── new.html.erb │ ├── sessions │ │ └── new.html.erb │ ├── shared │ │ └── _links.html.erb │ └── unlocks │ │ └── new.html.erb │ ├── exceptions │ ├── render_error.html.erb │ └── terra_tos.html │ ├── feature_announcements │ ├── _feature_announcement_list.html.erb │ ├── _form.html.erb │ ├── edit.html.erb │ ├── index.html.erb │ ├── latest.html.erb │ ├── new.html.erb │ └── view_announcement.html.erb │ ├── feature_flag_options │ ├── _feature_flag_option_fields.html.erb │ ├── edit.html.erb │ └── index.html.erb │ ├── layouts │ ├── 422.html.erb │ ├── _breadcrumbs.html.erb │ ├── _contact_us.html.erb │ ├── _deployment_notification_banner.erb │ ├── _download_link.html.erb │ ├── _external_resources_view.html.erb │ ├── _generic_update_modal.html.erb │ ├── _multiselect_checkbox_field.html.erb │ ├── _nav.html.erb │ ├── _notices.html.erb │ ├── application.html.erb │ ├── firecloud_unavailable.js.erb │ ├── mailer.html.erb │ ├── mailer.text.erb │ ├── nightly_admin_report.html.erb │ └── session_expired.js.erb │ ├── preset_searches │ ├── _form.html.erb │ ├── _preset_search.json.jbuilder │ ├── edit.html.erb │ ├── index.html.erb │ ├── index.json.jbuilder │ ├── new.html.erb │ ├── show.html.erb │ └── show.json.jbuilder │ ├── profiles │ ├── _user_firecloud_profile.html.erb │ ├── accept_tos.html.erb │ ├── get_firecloud_profile.js.erb │ ├── show.html.erb │ ├── update.js.erb │ └── update_firecloud_profile.js.erb │ ├── reports │ ├── _contact_modal.html.erb │ ├── index.html.erb │ ├── report_request.html.erb │ └── report_request.js.erb │ ├── single_cell_mailer │ ├── admin_notification.html.erb │ ├── annot_share_update_notification.html.erb │ ├── annotation_publish_failure.html.erb │ ├── daily_disk_status.html.erb │ ├── data_retention_policy_report.html.erb │ ├── firecloud_api_notification.html.erb │ ├── nightly_admin_report.html.erb │ ├── notify_admin_parse_fail.html.erb │ ├── notify_admin_parse_launch_fail.html.erb │ ├── notify_admin_upload_fail.html.erb │ ├── notify_user_parse_complete.html.erb │ ├── notify_user_parse_complete.text.erb │ ├── notify_user_parse_fail.html.erb │ ├── notify_user_parse_fail.text.erb │ ├── notify_user_upload_fail.html.erb │ ├── share_annotation_notification.html.erb │ ├── share_notification.html.erb │ ├── share_update_notification.html.erb │ └── user_download_fail_notification.html.erb │ ├── site │ ├── _annotation_warning.js.erb │ ├── _author_fields.html.erb │ ├── _home_page_link.html.erb │ ├── _main_banner_content.html.erb │ ├── _missing_genes.html.erb │ ├── _publication_fields.html.erb │ ├── _reviewer_access_fields.html.erb │ ├── _search_help.html.erb │ ├── _study_description_edit.html.erb │ ├── _study_description_view.html.erb │ ├── _study_download_agreement.html.erb │ ├── _study_download_data.html.erb │ ├── _study_resources_sidebar.html.erb │ ├── _study_settings_authors.html.erb │ ├── _study_settings_form.html.erb │ ├── _study_settings_general.html.erb │ ├── _study_settings_resources.html.erb │ ├── _study_settings_sharing.html.erb │ ├── _study_settings_viz.html.erb │ ├── _study_tabs_nav.html.erb │ ├── _study_title_bar.html.erb │ ├── _study_visualize.html.erb │ ├── _subsample_warning.html.erb │ ├── _tos_content.html.erb │ ├── covid19.html.erb │ ├── edit_study_description.js.erb │ ├── genome │ │ └── _browse_igv_link.html.erb │ ├── get_new_annotations.js.erb │ ├── index.html.erb │ ├── notice.js.erb │ ├── privacy_policy.html.erb │ ├── record_download_acceptance.js.erb │ ├── reviewer_access.html.erb │ ├── study.html.erb │ ├── terms_of_service.html.erb │ └── update_study_settings.js.erb │ ├── studies │ ├── _bam_association_fields.html.erb │ ├── _block_processed_upload_content.html.erb │ ├── _cluster_axis_fields.html.erb │ ├── _color_profile.html.erb │ ├── _coord_labels_association_fields.html.erb │ ├── _deleted_bundle_message.html.erb │ ├── _directory_listing_form.html.erb │ ├── _error_modal.html.erb │ ├── _expression_file_fields.html.erb │ ├── _expression_file_info_fields.html.erb │ ├── _external_resource_fields.html.erb │ ├── _fileupload_templates.html.erb │ ├── _form.html.erb │ ├── _initialize_bundled_file_form.html.erb │ ├── _initialize_expression_form.html.erb │ ├── _initialize_labels_form.html.erb │ ├── _initialize_marker_genes_form.html.erb │ ├── _initialize_metadata_form.html.erb │ ├── _initialize_misc_form.html.erb │ ├── _initialize_ordinations_form.html.erb │ ├── _initialize_primary_data_form.html.erb │ ├── _initialize_study_label.html.erb │ ├── _metadata_convention_help_popover.html.erb │ ├── _metadata_file_fields.html.erb │ ├── _mm_coordinate_association_fields.html.erb │ ├── _orphaned_study_file_form.html.erb │ ├── _parse_modal_content.html.erb │ ├── _reference_anndata_notice.html.erb │ ├── _refresh_link.html.erb │ ├── _required_modal.html.erb │ ├── _reset_step_status.html.erb │ ├── _shared_sync_functions.js.erb │ ├── _step_completed.html.erb │ ├── _study_default_options_form.html.erb │ ├── _study_file_bundle_btns.html.erb │ ├── _study_file_errors.html.erb │ ├── _study_file_form.html.erb │ ├── _study_file_notices.html.erb │ ├── _study_share_fields.html.erb │ ├── _sync_notice_modal.html.erb │ ├── _synced_bundled_study_file_form.html.erb │ ├── _synced_study_file_form.html.erb │ ├── _taxon_fields.html.erb │ ├── _taxon_help_popover.html.erb │ ├── _upload_success_modal_content.html.erb │ ├── abort_delete_study_file.js.erb │ ├── delete_study_file.js.erb │ ├── deleted_bundle.js.erb │ ├── edit.html.erb │ ├── index.html.erb │ ├── index.json.jbuilder │ ├── initialize_bundled_file.js.erb │ ├── initialize_study.html.erb │ ├── load_annotation_options.js.erb │ ├── new.html.erb │ ├── new_study_file.js.erb │ ├── parse.js.erb │ ├── retrieve_wizard_upload.js.erb │ ├── show.html.erb │ ├── show.json.jbuilder │ ├── sync_action_fail.js.erb │ ├── sync_action_success.js.erb │ ├── sync_directory_listing.js.erb │ ├── sync_study.html.erb │ ├── sync_study_file.js.erb │ ├── update_default_options_fail.js.erb │ ├── update_default_options_success.js.erb │ ├── update_fail.js.erb │ ├── update_study_file.js.erb │ ├── update_study_file_from_sync.js.erb │ └── usage_stats.html.erb │ ├── taxons │ ├── _form.html.erb │ ├── _genome_annotation_fields.html.erb │ ├── _genome_assembly_fields.html.erb │ ├── _taxon.json.jbuilder │ ├── edit.html.erb │ ├── index.html.erb │ ├── index.json.jbuilder │ ├── new.html.erb │ ├── show.html.erb │ └── show.json.jbuilder │ └── user_annotations │ ├── _form.html.erb │ ├── _user_annotation_share_fields.html.erb │ ├── edit.html.erb │ ├── index.html.erb │ └── index.json.jbuilder ├── babel.config.js ├── bin ├── bash_utils.sh ├── boot_docker ├── boot_mongo ├── build_image.sh ├── bundle ├── burp_scan.sh ├── burp_start.sh ├── cycle_logs.rb ├── delayed_job ├── deploy-github.sh ├── docker-compose-cleanup.sh ├── docker-compose-setup.sh ├── docker_utils.sh ├── enable_maintenance.sh ├── github_releases.sh ├── job_monitor.rb ├── load_env_secrets.sh ├── rails ├── rake ├── remote_deploy.sh ├── remount_portal_source.sh ├── restart_portal_container.sh ├── run_orch_smoke_test.sh ├── run_rubocop.sh ├── run_tests.sh ├── setup ├── tunnel_gcloud.sh ├── update ├── vault-gsm-migration.sh ├── vite ├── webpack ├── webpack-dev-server └── yarn ├── cell-filtering-igv └── index.html ├── codecov.yml ├── config.ru ├── config ├── application.rb ├── boot.rb ├── certs │ ├── localhost.crt │ └── localhost.key ├── environment.rb ├── environments │ ├── development.rb │ ├── pentest.rb │ ├── production.rb │ ├── staging.rb │ └── test.rb ├── filebeat │ ├── filebeat-Dockerfile │ ├── filebeat.yml │ ├── nginx.yml │ └── rails.yml ├── initializers │ ├── application_controller_renderer.rb │ ├── assets.rb │ ├── backtrace_silencers.rb │ ├── content_security_policy.rb │ ├── cookies_serializer.rb │ ├── delayed_job_config.rb │ ├── devise.rb │ ├── field_with_errors.rb │ ├── filter_parameter_logging.rb │ ├── inflections.rb │ ├── mime_types.rb │ ├── minitest_rails.rb │ ├── mongoid_encrypted_fields.rb │ ├── mongoid_history.rb │ ├── new_framework_defaults_6_1.rb │ ├── permissions_policy.rb │ ├── secret_key_base.rb │ ├── sentry.rb │ ├── session_store.rb │ ├── will_paginate.rb │ └── wrap_parameters.rb ├── locales │ ├── devise.en.yml │ └── en.yml ├── mongoid.yml ├── puma.rb ├── routes.rb ├── secrets.yml ├── secrets │ └── .keep_this ├── spring.rb ├── vite.json └── webpacker.yml ├── db ├── migrate │ ├── 20171108152921_set_admin_email_delivery_for_users.rb │ ├── 20171108152939_set_deliver_emails_and_firecloud_project_for_study_shares.rb │ ├── 20171108152947_set_deliver_emails_for_studies.rb │ ├── 20180130203907_create_genes_and_cell_metadata.rb │ ├── 20180213163419_create_expression_matrix_cells.rb │ ├── 20180806192849_set_gene_id_on_genes.rb │ ├── 20181001173952_create_study_file_bundles_from_opts.rb │ ├── 20181004151831_auto_populate_species_info.rb │ ├── 20190301175359_assign_accessions_to_studies.rb │ ├── 20190409152825_add_submitter_to_analysis_metadatum.rb │ ├── 20190409171159_backfill_analysis_submissions.rb │ ├── 20190517171441_generate100_k_subsamples.rb │ ├── 20190522190416_set_source_resolution_for_user_annotations.rb │ ├── 20200103191405_set_subsampled_on_clusters.rb │ ├── 20200213205538_add_initial_facets.rb │ ├── 20200218194644_add_schema_facets.rb │ ├── 20200221193404_add_bq_organism_age_column.rb │ ├── 20200304203650_create_organism_age_facet_and_backfill_data.rb │ ├── 20200330164113_reset_default_annotations.rb │ ├── 20200413153338_add_metadata_convention_version_to_bq.rb │ ├── 20200413161403_add_biosample_type_and_preservation_method_to_bq.rb │ ├── 20200413211749_add_feature_flag_defaults.rb │ ├── 20200414002707_add_study_gene_filter_flag.rb │ ├── 20200511150433_add_u19_columns_to_bq.rb │ ├── 20200513190742_backup_user_assets.rb │ ├── 20200518190036_set_sa_group_owner_on_workspaces.rb │ ├── 20200716191055_set_visible_on_search_facets.rb │ ├── 20200720175116_create_synthetic_branding_groups.rb │ ├── 20200723152531_update_facet_links.rb │ ├── 20200731180439_create_study_detail_from_descriptions.rb │ ├── 20200916203521_remove_advanced_search_flag.rb │ ├── 20200925192339_update_coord_label_file_opts.rb │ ├── 20201021141827_clear_old_totats.rb │ ├── 20201102151221_add_spatial_feature_flag.rb │ ├── 20201118200308_add_convention_feature_flag.rb │ ├── 20210125191551_clean_up_orphaned_external_resources.rb │ ├── 20210222174820_add_react_explore_feature_flag.rb │ ├── 20210316203723_remove_spatial_feature_flag.rb │ ├── 20210318125925_remove_spatial_flag2.rb │ ├── 20210326153355_add_points_to_cluster_groups.rb │ ├── 20210329171940_clear_user_auth_tokens.rb │ ├── 20210405192922_remove_gene_study_filter_flag.rb │ ├── 20210415145652_remove_authentication_token_from_users.rb │ ├── 20210426191308_replace10_x_in_alexandria_convention.rb │ ├── 20210506205225_cache_all_study_defaults.rb │ ├── 20210512162401_rename_preset_search_fields.rb │ ├── 20210518152311_move_image_uploads_to_carrierwave_path.rb │ ├── 20210518160552_add_cross_dataset_search_backend_flag.rb │ ├── 20210518160838_add_cross_dataset_search_frontend_flag.rb │ ├── 20210521141041_update10x_labels_in_big_query.rb │ ├── 20210712154710_update_public_facet_filters.rb │ ├── 20210802150514_add_raw_counts_required_backend_feature_flag.rb │ ├── 20210803122404_add_clientside_validation_flag.rb │ ├── 20210813184203_add_raw_counts_required_frontend_feature_flag.rb │ ├── 20210817130514_update_correlation_plot.rb │ ├── 20210902182833_remove_covid_flag.rb │ ├── 20210907141202_remove_react_explore_feature_flag.rb │ ├── 20210908154924_remove_faceted_search_feature_flag.rb │ ├── 20210908185622_add_react_upload_flag.rb │ ├── 20210914171910_undo_covid19_flag_deletion.rb │ ├── 20211015144933_create_feature_flag_options.rb │ ├── 20211029175055_add_azul_facet_filters_to_search_facets.rb │ ├── 20211110220355_set_new_collection_associations.rb │ ├── 20220127212642_color_picker_cache_clear.rb │ ├── 20220204144540_add_ref_image_flag.rb │ ├── 20220216160604_remove_upload_wizard_feature_flag.rb │ ├── 20220304144348_retire_xdss_feature_flags.rb │ ├── 20220304183321_base64_encode_custom_color_values.rb │ ├── 20220401103323_encode_azul_files_names.rb │ ├── 20220421021151_string_encode_custom_colors.rb │ ├── 20220505130728_add_differential_expression_frontend_feature_flag.rb │ ├── 20220509171640_add_differential_expression_flags_to_annotations.rb │ ├── 20220613143906_create_differential_expression_results.rb │ ├── 20220616194822_set_de_computational_method.rb │ ├── 20220621202722_set_matrix_file_id_on_differential_expression_results.rb │ ├── 20220727025370_add_flag_for_seurat_and_anndata_upload.rb │ ├── 20220804164813_add_progressive_loading_flag.rb │ ├── 20220914121854_add_legend_search_flag.rb │ ├── 20221006124530_retire_anndata_and_seurat_feature_flag.rb │ ├── 20221006132730_update_misc_file_type_for_anndata_and_seurat.rb │ ├── 20221026145120_update_missed_file_type_for_seurat.rb │ ├── 20221110160637_feature_flag_for_ingesting_anndata.rb │ ├── 20221129150308_add_cell_type_custom_facet.rb │ ├── 20230215152445_add_feature_flag_for_explore_tab_ab_test.rb │ ├── 20230301214553_remove_non_cell_type_de_results.rb │ ├── 20230328175210_mark_ann_data_reference_files.rb │ ├── 20230411182505_rename_observed_values.rb │ ├── 20230510115847_add_flag_for_explore_tab_ux_updates.rb │ ├── 20230510164721_retire_explore_tab_default_feature_flag.rb │ ├── 20230530105311_add_flag_for_user_de_upload.rb │ ├── 20230530160051_retire_reference_image_upload_feature_flag.rb │ ├── 20230531163544_update_image_file_type_to_other.rb │ ├── 20230622173344_retire_show_explore_tab_ux_updates_feature_flag.rb │ ├── 20230724205457_create_cluster_index_arrays.rb │ ├── 20230907050143_add_flag_for_cell_facet_filtering.rb │ ├── 20230913140856_create_show_appcue_viz_tour_feature_flag.rb │ ├── 20230921192657_retire_appcue_pin_feature_flag.rb │ ├── 20240207162542_add_flag_for_numeric_cell_filtering.rb │ ├── 20240604150237_add_brain_modality_columns_to_big_query.rb │ ├── 20240605113800_add_flag_for_igv_multiome.rb │ ├── 20240709215119_create_subsampled_cluster_indices.rb │ ├── 20240718141220_remove_invalid_index_arrays.rb │ ├── 20240807161035_subsample_ann_data_files.rb │ ├── 20240819173109_sync_exp_file_info_for_ann_data.rb │ ├── 20240822072800_add_flag_for_pathway_expression.rb │ ├── 20241112195205_set_ann_data_expression_label.rb │ ├── 20250127092542_add_flag_for_default_pairwise_de_ui.rb │ ├── 20250401141733_set_raw_location_on_ann_data_files.rb │ ├── 20250501135335_add_morph_and_electro_facets.rb │ └── 20250528160832_set_relevant_default_annotations.rb ├── seed │ ├── bq_seeds.json │ ├── example_studies │ │ ├── human_milk_de_49k_cell │ │ │ └── study_info.json │ │ └── mouse_brain_1M_cell │ │ │ └── study_info.json │ ├── synthetic_branding_groups │ │ ├── human_group │ │ │ └── branding_group_info.json │ │ └── mouse_group │ │ │ └── branding_group_info.json │ └── synthetic_studies │ │ ├── README.md │ │ ├── array_cow_brain │ │ ├── metadata.tsv │ │ └── study_info.json │ │ ├── array_human_tb │ │ ├── metadata.tsv │ │ └── study_info.json │ │ ├── array_mouse_eye │ │ ├── cluster.tsv │ │ ├── expression_matrix.tsv │ │ ├── metadata.tsv │ │ └── study_info.json │ │ ├── bronchial_lymphoid │ │ ├── cluster.tsv │ │ ├── expression_matrix.tsv │ │ ├── metadata.tsv │ │ └── study_info.json │ │ ├── chicken_overplot │ │ ├── letters_overplot.txt │ │ ├── metadata.txt │ │ ├── processed_dense.txt │ │ └── study_info.json │ │ ├── chicken_raw_counts │ │ ├── README.txt │ │ ├── cluster_odd_labels.txt │ │ ├── cluster_square.txt │ │ ├── metadata.txt │ │ ├── raw2_chicken_40_cells_4_genes.cluster.txt │ │ ├── raw2_chicken_40_cells_4_genes.processed_dense.txt │ │ ├── raw2_chicken_40_cells_4_genes.raw_dense.txt │ │ ├── raw2_chicken_40_cells_4_genes.spatial.txt │ │ ├── spatial_square.txt │ │ ├── spatial_square_10.txt │ │ ├── spatial_square_11.txt │ │ ├── spatial_square_12.txt │ │ ├── spatial_square_13.txt │ │ ├── spatial_square_14.txt │ │ ├── spatial_square_15.txt │ │ ├── spatial_square_16.txt │ │ ├── spatial_square_17.txt │ │ ├── spatial_square_2.txt │ │ ├── spatial_square_3.txt │ │ ├── spatial_square_4.txt │ │ ├── spatial_square_5.txt │ │ ├── spatial_square_6.txt │ │ ├── spatial_square_7.txt │ │ ├── spatial_square_8.txt │ │ ├── spatial_square_9.txt │ │ ├── spatial_zigzag.txt │ │ └── study_info.json │ │ ├── cow_blood │ │ ├── expression_matrix.tsv │ │ ├── metadata.tsv │ │ └── study_info.json │ │ ├── cow_liver │ │ ├── marker_1_gene_list.txt │ │ └── study_info.json │ │ ├── human_all_genes │ │ ├── cluster.tsv │ │ ├── expression_processed.tsv │ │ ├── expression_raw.tsv │ │ ├── metadata.tsv │ │ └── study_info.json │ │ ├── human_blood │ │ ├── cluster.tsv │ │ ├── expression_matrix.tsv │ │ ├── metadata.tsv │ │ └── study_info.json │ │ ├── human_blood_no_metadata │ │ └── study_info.json │ │ ├── human_lymph_node │ │ ├── bullseye_cluster.tsv │ │ ├── cluster.tsv │ │ ├── cluster2.tsv │ │ ├── expression_matrix.tsv │ │ ├── expression_matrix_raw.tsv │ │ ├── metadata.tsv │ │ └── study_info.json │ │ ├── human_male_islet │ │ ├── metadata.tsv │ │ └── study_info.json │ │ ├── human_raw_counts │ │ ├── coordinate_labels.tsv │ │ ├── raw1_human_5k_cells_80_genes.barcodes.tsv │ │ ├── raw1_human_5k_cells_80_genes.cluster_2D.txt │ │ ├── raw1_human_5k_cells_80_genes.cluster_3D.txt │ │ ├── raw1_human_5k_cells_80_genes.genes.tsv │ │ ├── raw1_human_5k_cells_80_genes.metadata.txt │ │ ├── raw1_human_5k_cells_80_genes.processed_dense.txt │ │ ├── raw1_human_5k_cells_80_genes.processed_sparse.mtx │ │ ├── raw1_human_5k_cells_80_genes.raw_dense.txt │ │ ├── raw1_human_5k_cells_80_genes.raw_sparse.mtx │ │ └── study_info.json │ │ ├── human_retina │ │ └── study_info.json │ │ ├── monkey_correlations │ │ ├── cluster.tsv │ │ ├── expression_matrix.tsv │ │ ├── metadata.tsv │ │ └── study_info.json │ │ ├── mouse_brain │ │ ├── cluster.tsv │ │ ├── coordinate_labels.tsv │ │ ├── expression_matrix.tsv │ │ ├── metadata.tsv │ │ ├── raw_counts.tsv │ │ ├── sample1.bam │ │ ├── sample1.bam.bai │ │ ├── sample2.bam │ │ ├── sample2.bam.bai │ │ └── study_info.json │ │ ├── mouse_multilabel │ │ ├── cluster.tsv │ │ ├── expression_matrix.tsv │ │ ├── metadata.tsv │ │ └── study_info.json │ │ ├── mouse_salmonella │ │ ├── cluster.tsv │ │ ├── cluster_many_long_odd_labels.tsv │ │ ├── expression_matrix.tsv │ │ ├── metadata.tsv │ │ └── study_info.json │ │ └── mouse_stomach │ │ ├── cluster.tsv │ │ ├── expression_matrix.tsv │ │ ├── metadata.tsv │ │ └── study_info.json └── seeds.rb ├── docker-compose-dev.yaml ├── docs ├── img │ ├── Client-side_performance_monitoring_for_Single_Cell_Portal.png │ └── Web_vitals_and_client_hardware_Single_Cell_Portal.png └── observability.md ├── generate_dh_parameters.bash ├── hdf5-parser ├── .gitignore ├── dna-spinning.gif ├── hdf5-parser.js ├── index.html ├── package.json ├── sans59510.nxs.ngv └── yarn.lock ├── image-pipeline ├── .dockerignore ├── .gitignore ├── Dockerfile ├── README.md ├── expression-scatter-plots.js ├── package.json └── yarn.lock ├── jest.config.js ├── jsconfig.json ├── lib ├── api_helpers.rb ├── assets │ ├── .keep │ ├── default_species_assemblies.txt │ ├── metadata_schemas │ │ └── alexandria_convention │ │ │ ├── alexandria_convention_schema.json │ │ │ ├── alexandria_convention_schema.tsv │ │ │ └── snapshot │ │ │ ├── 1.1.3 │ │ │ ├── alexandria_convention_schema.json │ │ │ └── alexandria_convention_schema.tsv │ │ │ ├── 1.1.4 │ │ │ ├── alexandria_convention_schema.json │ │ │ └── alexandria_convention_schema.tsv │ │ │ ├── 1.1.5 │ │ │ ├── alexandria_convention_schema.json │ │ │ └── alexandria_convention_schema.tsv │ │ │ ├── 2.0.0 │ │ │ ├── alexandria_convention_schema.json │ │ │ └── alexandria_convention_schema.tsv │ │ │ ├── 2.0.1 │ │ │ ├── alexandria_convention_schema.json │ │ │ └── alexandria_convention_schema.tsv │ │ │ ├── 2.1.0 │ │ │ ├── alexandria_convention_schema.json │ │ │ └── alexandria_convention_schema.tsv │ │ │ ├── 2.1.1 │ │ │ ├── alexandria_convention_schema.json │ │ │ └── alexandria_convention_schema.tsv │ │ │ ├── 2.1.2 │ │ │ ├── alexandria_convention_schema.json │ │ │ └── alexandria_convention_schema.tsv │ │ │ ├── 2.1.3 │ │ │ ├── alexandria_convention_schema.json │ │ │ └── alexandria_convention_schema.tsv │ │ │ ├── 2.1.4 │ │ │ ├── alexandria_convention_schema.json │ │ │ └── alexandria_convention_schema.tsv │ │ │ ├── 2.1.5 │ │ │ ├── alexandria_convention_schema.json │ │ │ └── alexandria_convention_schema.tsv │ │ │ ├── 2.2.0 │ │ │ ├── alexandria_convention_schema.json │ │ │ └── alexandria_convention_schema.tsv │ │ │ ├── 2.2.1 │ │ │ ├── alexandria_convention_schema.json │ │ │ └── alexandria_convention_schema.tsv │ │ │ ├── 2.3.0 │ │ │ ├── alexandria_convention_schema.json │ │ │ └── alexandria_convention_schema.tsv │ │ │ └── 3.0.0 │ │ │ ├── alexandria_convention_schema.json │ │ │ └── alexandria_convention_schema.tsv │ ├── perl │ │ └── flamegraph.pl │ ├── python │ │ └── genomes │ │ │ └── organisms.tsv │ └── sql │ │ └── tdr_indexes │ │ └── query_w_analysis_file.sql ├── current.rb ├── delayed_job_accessor.rb ├── error_tracker.rb ├── facet_name_converter.rb ├── google_service_client.rb ├── label_sorter.rb ├── service_account_manager.rb ├── study_cleanup_tools.rb ├── tasks │ └── .keep ├── test_data_populator.rb └── validation_tools.rb ├── log └── .keep ├── nginx.conf ├── package.json ├── postcss.config.js ├── public ├── 404.html ├── 422.html ├── 500.html ├── favicon.ico ├── maintenance.html ├── mock_data │ ├── bulk_download │ │ └── auth_code.json │ └── search │ │ ├── annotated_scatter_plot │ │ ├── adcy5_human_all_genes.json │ │ └── study_human_all_genes.json │ │ ├── facet_filters_disease_tuberculosis.json │ │ ├── facets.json │ │ ├── select_search_results │ │ ├── blood_log_props.json │ │ └── blood_study.json │ │ └── violin_plot │ │ ├── cluster_all_small_intestinal_epithelium.json │ │ ├── expression_violin_api.json │ │ ├── expression_violin_mrpl15_small_intestinal_epithelium.json │ │ ├── study.json │ │ └── study_small_intestinal_epithelium.json ├── robots.txt └── single_cell │ ├── apple-touch-icon-precomposed.png │ └── apple-touch-icon.png ├── rails-dev-entrypoint.sh ├── rails_local_setup.rb ├── rails_startup.bash ├── set_user_permissions.bash ├── test ├── Dockerfile-test ├── api │ ├── api_base_controller_test.rb │ ├── api_site_controller_test.rb │ ├── bookmarks_controller_test.rb │ ├── bulk_download_controller_test.rb │ ├── directory_listings_controller_test.rb │ ├── exceptions_controller_test.rb │ ├── external_resources_controller_test.rb │ ├── generate_big_query_search_test.rb │ ├── metadata_schemas_controller_test.rb │ ├── publications_controller_test.rb │ ├── reports_controller_test.rb │ ├── search_controller_test.rb │ ├── studies_controller_test.rb │ ├── study_file_bundles_controller_test.rb │ ├── study_files_controller_test.rb │ ├── study_shares_controller_test.rb │ ├── user_annotations_controller_test.rb │ └── visualization │ │ ├── annotations_controller_test.rb │ │ ├── clusters_controller_test.rb │ │ ├── explore_controller_test.rb │ │ └── expression_controller_test.rb ├── api_test_helper.rb ├── big_query_helper.rb ├── bulk_download_helper.rb ├── controllers │ ├── ab_tests_controller_test.rb │ ├── branding_group_controller_test.rb │ ├── feature_announcements_controller_test.rb │ ├── feature_flag_options_controller_test.rb │ ├── preset_searches_controller_test.rb │ ├── profiles_controller_test.rb │ ├── site_controller_test.rb │ ├── taxons_controller_test.rb │ └── users │ │ └── omniauth_callbacks_controller_test.rb ├── detached_helper.rb ├── factories │ ├── authors.rb │ ├── bookmarks.rb │ ├── branding_group.rb │ ├── cell_metadatum.rb │ ├── cluster_group.rb │ ├── data_array.rb │ ├── differential_expression_results.rb │ ├── feature_announcements.rb │ ├── gene.rb │ ├── precomputed_score.rb │ ├── publications.rb │ ├── reviewer_access_sessions.rb │ ├── reviewer_accesses.rb │ ├── study.rb │ ├── study_file.rb │ └── user.rb ├── helper_tests │ └── application_helper_test.rb ├── includes_helper.rb ├── integration │ ├── external │ │ ├── data_repo_client_test.rb │ │ ├── fire_cloud_client_test.rb │ │ ├── hca_azul_client_test.rb │ │ ├── import_service_config │ │ │ ├── hca_test.rb │ │ │ └── nemo_test.rb │ │ ├── import_service_test.rb │ │ ├── nemo_client_test.rb │ │ ├── study_creation_test.rb │ │ └── study_validation_test.rb │ └── local │ │ ├── cache_management_test.rb │ │ ├── download_agreement_test.rb │ │ ├── reviewer_access_permission_test.rb │ │ ├── synthetic_study_populator_test.rb │ │ ├── tos_acceptance_test.rb │ │ └── upload_wizard_test.rb ├── integration_test_helper.rb ├── js │ ├── admin │ │ └── my-studies-page.test.js │ ├── download.test.js │ ├── download │ │ ├── download-button.test.js │ │ └── download-selection-modal.test.js │ ├── explore │ │ ├── bookmarks.test.js │ │ ├── cell-filtering-panel.test-data.js │ │ ├── cell-filtering-panel.test.js │ │ ├── create-annotations.test.js │ │ ├── differential-expression-panel.test-data.js │ │ ├── differential-expression-panel.test.js │ │ ├── explore-display-tabs.test.js │ │ ├── explore-tab-de-integration.test-data.js │ │ ├── explore-tab-router.test.js │ │ ├── genome-view.test.data.js │ │ ├── genome-view.test.js │ │ ├── plot-data-cache.test.js │ │ ├── plot-utils.test.js │ │ ├── precomputed-heatmaps.test.js │ │ ├── scatter-plot.test-data.js │ │ ├── scatter-tab.test.js │ │ └── study-gene-keyword.test.js │ ├── fetch │ │ └── scp-api.test.js │ ├── jest-mocks │ │ ├── file-mock.js │ │ └── igv-mock.js │ ├── keywordSearch.test.js │ ├── lib │ │ ├── MockRouter.js │ │ ├── cell-faceting.test-data.js │ │ ├── cell-faceting.test.js │ │ ├── chunked-line-reader.test.js │ │ ├── file-mock-utils.js │ │ ├── message-modal.test.js │ │ ├── node-web-api.js │ │ ├── ontology-validation.test.js │ │ ├── pathway-expression.test-data.js │ │ ├── pathway-expression.test.js │ │ ├── scp-api.test.js │ │ ├── search-utils.test.js │ │ ├── stats.test.js │ │ ├── validate-anndata.test.js │ │ ├── validate-file-content.test.js │ │ ├── validate-remote-file-content.test.js │ │ └── validate-study.test.js │ ├── metrics-api.test.js │ ├── metrics-perf.test.js │ ├── mock-performance.js │ ├── resultsPanel.test.js │ ├── search │ │ ├── annotated-scatter-plot.test.js │ │ ├── combined-facet.test.js │ │ ├── combined-search.test.js │ │ ├── facet-control.test.js │ │ ├── filter-slider.test.js │ │ ├── gene-keyword.test.js │ │ ├── gene-search-view.test.js │ │ ├── more-facets.test.js │ │ ├── result-metadata-table.test.js │ │ ├── search-query-display.test.js │ │ ├── study-violin-plot.test.js │ │ └── study.test.js │ ├── setup-tests.js │ ├── study-usage.test.js │ ├── study.test.js │ ├── studyResults.test.js │ ├── upload-wizard │ │ ├── file-info-responses.js │ │ ├── file-upload-cancel.test.js │ │ ├── file-upload-control.test.js │ │ ├── update-anndata-clustering.test.js │ │ ├── upload-expression-data.test.js │ │ ├── upload-file-format.test.js │ │ ├── upload-new-study.test.js │ │ ├── upload-seurat-h5ad-test.js │ │ ├── upload-wizard-test-utils.js │ │ ├── validations.test.js │ │ └── wizard-navigation.test.js │ └── visualization │ │ ├── pathway.test-data.js │ │ ├── pathway.test.js │ │ ├── scatter-plot.test-data.js │ │ ├── scatter-plot.test.js │ │ └── spatial-selector.test.js ├── lib │ ├── delayed_job_accessor_test.rb │ ├── facet_name_converter_test.rb │ ├── label_sorter_test.rb │ ├── request_utils_test.rb │ ├── search_facet_populator_test.rb │ ├── study_cleanup_tools_test.rb │ ├── study_search_results_objects_test.rb │ └── summary_stats_utils_test.rb ├── models │ ├── ab_test_assignment_test.rb │ ├── ab_test_test.rb │ ├── admin_configuration_test.rb │ ├── analysis_configuration_test.rb │ ├── analysis_parameter_filter_test.rb │ ├── analysis_parameter_test.rb │ ├── ann_data_file_info_test.rb │ ├── ann_data_ingest_parameters_test.rb │ ├── author_test.rb │ ├── batch_api_client_test.rb │ ├── big_query_client_test.rb │ ├── bookmark_test.rb │ ├── branding_group_test.rb │ ├── cell_metadatum_test.rb │ ├── cluster_file_info_test.rb │ ├── cluster_group_test.rb │ ├── data_array_test.rb │ ├── delete_queue_job_test.rb │ ├── differential_expression_file_info_test.rb │ ├── differential_expression_parameters_test.rb │ ├── differential_expression_result_test.rb │ ├── directory_listing_test.rb │ ├── download_request_test.rb │ ├── feature_announcement_test.rb │ ├── feature_flag_option_test.rb │ ├── feature_flag_test.rb │ ├── home_page_link_test.rb │ ├── image_pipeline_parameters_test.rb │ ├── ingest_job_test.rb │ ├── parse_utils_test.rb │ ├── precomputed_score_test.rb │ ├── preset_search_test.rb │ ├── publication_test.rb │ ├── render_expression_arrays_parameters_test.rb │ ├── report_time_point_test.rb │ ├── reviewer_access_session_test.rb │ ├── reviewer_access_test.rb │ ├── search_facet_test.rb │ ├── study_file_bundle_test.rb │ ├── study_file_test.rb │ ├── study_test.rb │ ├── synthetic_branding_group_populator_test.rb │ ├── upload_cleanup_job_test.rb │ ├── user_annotation_test.rb │ └── user_test.rb ├── rest_client_helper.rb ├── services │ ├── annotation_viz_service_test.rb │ ├── azul_search_service_test.rb │ ├── bulk_download_service_test.rb │ ├── cluster_cache_service_test.rb │ ├── cluster_viz_service_test.rb │ ├── differential_expression_service_test.rb │ ├── download_quota_service_test.rb │ ├── expression_viz_service_test.rb │ ├── file_parse_service_test.rb │ ├── image_pipeline_service_test.rb │ ├── metrics_service_test.rb │ ├── reports_service_test.rb │ ├── study_search_service_test.rb │ ├── study_sync_service_test.rb │ └── user_asset_service_test.rb ├── simplecov_helper.rb ├── test_data │ ├── 12_MB_file_with_space_in_filename 2.txt │ ├── GRCh38 │ │ ├── barcodes.tsv │ │ ├── genes.tsv │ │ ├── matrix.mtx │ │ ├── test_bad_matrix.mtx │ │ ├── test_genes.tsv │ │ └── test_matrix.mtx │ ├── R_format_text.txt │ ├── alexandria_convention │ │ └── metadata.v2-0-0.txt │ ├── anndata │ │ ├── invalid_annotation_name_period.h5ad │ │ ├── invalid_disease_id.h5ad │ │ ├── invalid_disease_label.h5ad │ │ ├── invalid_header_no_species.h5ad │ │ ├── valid.h5ad │ │ └── valid_with_colon.h5ad │ ├── azul │ │ ├── disease_hiv.json │ │ ├── human_tcell.json │ │ ├── human_thymus.json │ │ ├── pulmonary_fibrosis.json │ │ └── species_homo_sapiens.json │ ├── branding_groups │ │ ├── SCP-Header-resize-invert.png │ │ ├── SCP-logo-invert.png │ │ └── broad-logo-white-invert.png │ ├── cell_1_I1_001.fastq.gz │ ├── cell_1_R1_001.fastq.gz │ ├── cluster_2_example.txt │ ├── cluster_2_example_2.txt │ ├── cluster_2d_example.txt │ ├── cluster_PR_1850_ascii_only.txt │ ├── cluster_PR_1850_includes_non-ascii.txt │ ├── cluster_bad.txt │ ├── cluster_example.txt │ ├── cluster_example_2.txt │ ├── cluster_flat.tsv │ ├── coordinate_labels_1.txt │ ├── coordinate_labels_2.txt │ ├── default_participant.tsv │ ├── differential_expression │ │ └── All_Cells_UMAP--General_Celltype--manifest.tsv │ ├── expression_matrix_example.txt │ ├── expression_matrix_example_2.txt │ ├── expression_matrix_example_bad.txt │ ├── expression_matrix_example_gzipped.txt.gz │ ├── expression_matrix_example_human.txt │ ├── expression_matrix_quoted_example.txt │ ├── fixed_neurons_6days_2000_possorted_genome_bam_test_data.bam │ ├── fixed_neurons_6days_2000_possorted_genome_bam_test_data.bam.bai │ ├── human_author_de │ │ ├── cluster_umap_txt--General_Celltype--B_cells--CSN1S1_macrophages--study--wilcoxon.tsv │ │ ├── cluster_umap_txt--General_Celltype--B_cells--dendritic_cells--study--wilcoxon.tsv │ │ ├── cluster_umap_txt--General_Celltype--B_cells--study--wilcoxon.tsv │ │ ├── cluster_umap_txt--General_Celltype--CSN1S1_macrophages--study--wilcoxon.tsv │ │ ├── cluster_umap_txt--General_Celltype--dendritic_cells--study--wilcoxon.tsv │ │ ├── cluster_umap_txt--General_Celltype--eosinophils--CSN1S1_macrophages--study--wilcoxon.tsv │ │ └── cluster_umap_txt--General_Celltype--manifest.tsv │ ├── marker_1_gene_list.txt │ ├── marker_1_gene_list_bad.txt │ ├── marker_2_gene_list.txt │ ├── metadata_bad.txt │ ├── metadata_example.txt │ ├── metadata_example2.txt │ ├── metadata_example_bad_TYPE.txt │ ├── metadata_update.txt │ ├── mock_study_doc_upload(1).txt │ ├── mock_study_doc_upload.txt │ ├── search_genes.txt │ ├── sub_cluster_1_coordinates_example.txt │ ├── sub_cluster_1_coordinates_example_bad.txt │ ├── sub_cluster_2_coordinates_example.txt │ ├── table_1.xlsx │ ├── test-blank.loom │ ├── test_gene_list.txt │ ├── validation │ │ ├── cluster_bad_no_coordinates.txt │ │ ├── cluster_comma_delimited.csv │ │ ├── cluster_example.txt │ │ ├── cluster_example_with_periods.txt │ │ ├── cluster_valid_annotation_name_period.txt │ │ ├── dup_headers_v2.0.0.tsv │ │ ├── error_headers_v2.0.0.tsv │ │ ├── expression_matrix_example.txt │ │ ├── expression_matrix_example.txt.gz │ │ ├── expression_matrix_example_bad.txt │ │ ├── expression_matrix_example_bad.txt.gz │ │ ├── header_count_mismatch.tsv │ │ ├── metadata_bad_has_coordinates.txt │ │ ├── metadata_bad_no_ontology.txt │ │ ├── metadata_bad_type_header.txt │ │ ├── metadata_bad_v3-0-0.tsv │ │ ├── metadata_drag_error.tsv │ │ ├── metadata_good_v2-0-0.txt │ │ ├── metadata_good_v3-0-0.tsv │ │ ├── metadata_invalid_annotation_name_period.tsv │ │ ├── missing_gz_extension.rds │ │ └── missing_gz_extension.txt │ └── workspace_samples.tsv ├── test_helper.rb └── user_tokens_helper.rb ├── vendor └── assets │ ├── javascripts │ └── .keep │ └── stylesheets │ └── .keep ├── version.txt ├── vite-dev-entrypoint.sh ├── vite.config.ts ├── webapp.conf └── yarn.lock /.codacy.yml: -------------------------------------------------------------------------------- 1 | exclude_paths: 2 | - babel.config.js 3 | - config/webpack/** -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | public/* 2 | tmp/* 3 | data/* 4 | log/* 5 | data_bak 6 | config/*.json 7 | node_modules/* 8 | .git 9 | gha-creds-*.json 10 | -------------------------------------------------------------------------------- /Procfile.dev: -------------------------------------------------------------------------------- 1 | 2 | vite: bin/vite dev 3 | web: bin/rails s 4 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path('../config/application', __FILE__) 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | // app/assets/config/manifest.js 2 | // 3 | //= link_tree ../images 4 | 5 | //= link application.css 6 | //= link application.js 7 | -------------------------------------------------------------------------------- /app/assets/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /app/assets/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /app/assets/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /app/assets/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/.keep -------------------------------------------------------------------------------- /app/assets/images/AdvancedSearchExample.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/AdvancedSearchExample.gif -------------------------------------------------------------------------------- /app/assets/images/SCP-Header-resize.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/SCP-Header-resize.png -------------------------------------------------------------------------------- /app/assets/images/SCP-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/SCP-logo.png -------------------------------------------------------------------------------- /app/assets/images/SCP-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/SCP-white.png -------------------------------------------------------------------------------- /app/assets/images/broad-logo-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/broad-logo-white.png -------------------------------------------------------------------------------- /app/assets/images/broad-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/broad-logo.png -------------------------------------------------------------------------------- /app/assets/images/cellarium.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/cellarium.png -------------------------------------------------------------------------------- /app/assets/images/clippy.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/assets/images/covid19-banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/covid19-banner.png -------------------------------------------------------------------------------- /app/assets/images/covid19-button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/covid19-button.png -------------------------------------------------------------------------------- /app/assets/images/covid19-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/covid19-logo.png -------------------------------------------------------------------------------- /app/assets/images/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/favicon-16x16.png -------------------------------------------------------------------------------- /app/assets/images/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/favicon-32x32.png -------------------------------------------------------------------------------- /app/assets/images/metadata-convention-explainer-anndata.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/metadata-convention-explainer-anndata.jpg -------------------------------------------------------------------------------- /app/assets/images/metadata-convention-explainer-anndata.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/metadata-convention-explainer-anndata.png -------------------------------------------------------------------------------- /app/assets/images/metadata-convention-explainer.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/metadata-convention-explainer.jpg -------------------------------------------------------------------------------- /app/assets/images/microbe-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/microbe-icon.png -------------------------------------------------------------------------------- /app/assets/images/scp_favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/scp_favicon.ico -------------------------------------------------------------------------------- /app/assets/images/ui-bg_diagonals-thick_8_333333_40x40.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/ui-bg_diagonals-thick_8_333333_40x40.png -------------------------------------------------------------------------------- /app/assets/images/ui-bg_flat_65_ffffff_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/ui-bg_flat_65_ffffff_40x100.png -------------------------------------------------------------------------------- /app/assets/images/ui-bg_glass_40_111111_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/ui-bg_glass_40_111111_1x400.png -------------------------------------------------------------------------------- /app/assets/images/ui-bg_glass_55_1c1c1c_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/ui-bg_glass_55_1c1c1c_1x400.png -------------------------------------------------------------------------------- /app/assets/images/ui-bg_highlight-hard_100_f9f9f9_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/ui-bg_highlight-hard_100_f9f9f9_1x100.png -------------------------------------------------------------------------------- /app/assets/images/ui-bg_highlight-hard_40_aaaaaa_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/ui-bg_highlight-hard_40_aaaaaa_1x100.png -------------------------------------------------------------------------------- /app/assets/images/ui-bg_highlight-soft_50_aaaaaa_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/ui-bg_highlight-soft_50_aaaaaa_1x100.png -------------------------------------------------------------------------------- /app/assets/images/ui-bg_inset-hard_45_cd0a0a_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/ui-bg_inset-hard_45_cd0a0a_1x100.png -------------------------------------------------------------------------------- /app/assets/images/ui-bg_inset-hard_55_ffeb80_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/ui-bg_inset-hard_55_ffeb80_1x100.png -------------------------------------------------------------------------------- /app/assets/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /app/assets/images/ui-icons_444444_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/ui-icons_444444_256x240.png -------------------------------------------------------------------------------- /app/assets/images/ui-icons_4ca300_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/ui-icons_4ca300_256x240.png -------------------------------------------------------------------------------- /app/assets/images/ui-icons_555555_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/ui-icons_555555_256x240.png -------------------------------------------------------------------------------- /app/assets/images/ui-icons_777620_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/ui-icons_777620_256x240.png -------------------------------------------------------------------------------- /app/assets/images/ui-icons_777777_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/ui-icons_777777_256x240.png -------------------------------------------------------------------------------- /app/assets/images/ui-icons_bbbbbb_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/ui-icons_bbbbbb_256x240.png -------------------------------------------------------------------------------- /app/assets/images/ui-icons_cc0000_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/ui-icons_cc0000_256x240.png -------------------------------------------------------------------------------- /app/assets/images/ui-icons_ededed_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/ui-icons_ededed_256x240.png -------------------------------------------------------------------------------- /app/assets/images/ui-icons_ffcf29_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/ui-icons_ffcf29_256x240.png -------------------------------------------------------------------------------- /app/assets/images/ui-icons_ffffff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/assets/images/ui-icons_ffffff_256x240.png -------------------------------------------------------------------------------- /app/assets/javascripts/branding_groups.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/controllers/api/v1/concerns/csp_header_bypass.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | module Concerns 4 | module CspHeaderBypass 5 | extend ActiveSupport::Concern 6 | 7 | included do 8 | before_action :exclude_csp_headers! 9 | end 10 | 11 | # disable all CSP headers for API responses 12 | def exclude_csp_headers! 13 | SecureHeaders.opt_out_of_all_protection(request) 14 | end 15 | end 16 | end 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /app/controllers/api/v1/exceptions_controller.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | module V1 3 | # lightweight wrapper to intercept all uncaught API-based exceptions and render JSON response 4 | class ExceptionsController < ApiBaseController 5 | def render_error 6 | ::RequestUtils.log_exception(request, params, user: current_api_user, study: @study) 7 | render json: ::RequestUtils.exception_json(request), 8 | status: :internal_server_error 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /app/controllers/concerns/devise_sign_out_patch.rb: -------------------------------------------------------------------------------- 1 | module DeviseSignOutPatch 2 | extend ActiveSupport::Concern 3 | 4 | included do 5 | # DELETE /resource/sign_out 6 | def destroy 7 | # invalidate token and unset provider 8 | current_user.update(refresh_token: nil, access_token: nil, api_access_token: nil, provider: nil) 9 | signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)) 10 | set_flash_message! :notice, :signed_out if signed_out 11 | yield if block_given? 12 | respond_to_on_destroy 13 | end 14 | end 15 | 16 | end 17 | 18 | Devise::SessionsController.send(:include, DeviseSignOutPatch) 19 | -------------------------------------------------------------------------------- /app/controllers/concerns/real_ip_logger.rb: -------------------------------------------------------------------------------- 1 | module RealIpLogger 2 | extend ActiveSupport::Concern 3 | ## 4 | # real_ip_logger.rb: logs the actual client IP address set by the nginx X-Forwarded-For header, instead of load balancer ip 5 | ## 6 | 7 | included do 8 | around_action :log_real_ip 9 | end 10 | 11 | def log_real_ip 12 | real_ip = request.headers['HTTP_X_FORWARDED_FOR'] 13 | Rails.logger.info "Forwarded client IP: #{real_ip} for #{request.method} #{request.fullpath}" if real_ip.present? 14 | ensure 15 | yield # regardless of any issues/errors, request will always execute and render a response 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/controllers/exceptions_controller.rb: -------------------------------------------------------------------------------- 1 | # custom exceptions controller to render error views 2 | class ExceptionsController < ApplicationController 3 | layout 'application' 4 | 5 | def render_error 6 | RequestUtils.log_exception(request, params, user: current_user, study: @study) 7 | respond_to do |format| 8 | format.html { render action: 'render_error', status: :internal_server_error } 9 | format.json do 10 | render json: RequestUtils.exception_json(request), 11 | status: :internal_server_error 12 | end 13 | end 14 | end 15 | 16 | def terra_tos; end 17 | end 18 | -------------------------------------------------------------------------------- /app/helpers/feature_flag_options_helper.rb: -------------------------------------------------------------------------------- 1 | module FeatureFlagOptionsHelper 2 | # show a label when editing instance feature flags 3 | def get_instance_label(instance) 4 | label = "#{instance.class}: " 5 | case instance.class.name 6 | when 'Study' 7 | attribute = :accession 8 | when 'BrandingGroup' 9 | attribute = :name 10 | when 'User' 11 | attribute = :email 12 | else 13 | attribute = :id 14 | end 15 | label + instance.send(attribute).to_s 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /app/helpers/preset_searches_helper.rb: -------------------------------------------------------------------------------- 1 | module PresetSearchesHelper 2 | 3 | def facet_query_label(facet_data) 4 | labels = [] 5 | facet_data[:filters].each do |filter| 6 | label = "#{facet_data[:id]}: #{filter[:name]}" 7 | labels << label 8 | end 9 | labels.join(" ") 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/helpers/profiles_helper.rb: -------------------------------------------------------------------------------- 1 | module ProfilesHelper 2 | # render an on/off toggle for inline forms on profile page 3 | def render_toggle(form_id, input_id, boolean_field, text_array: %w[On Off]) 4 | toggle_state = boolean_field ? 'on' : 'off' 5 | toggle_text = boolean_field ? text_array.first : text_array.last 6 | content = "" \ 8 | "#{toggle_text} " 9 | content.html_safe 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /app/helpers/reports_helper.rb: -------------------------------------------------------------------------------- 1 | module ReportsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/taxons_helper.rb: -------------------------------------------------------------------------------- 1 | module TaxonsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/user_annotations_helper.rb: -------------------------------------------------------------------------------- 1 | module UserAnnotationsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/javascript/components/search/controls/FacetsAccordion.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | import PanelGroup from 'react-bootstrap/lib/PanelGroup' 3 | 4 | import FacetControl from './FacetControl' 5 | 6 | /** 7 | * Expandable sections for facets in "More facets" popup 8 | */ 9 | export default function FacetsAccordion(props) { 10 | return ( 11 | 12 | { 13 | props.facets.map((facet, i) => { 14 | return ( 15 | 16 | ) 17 | }) 18 | } 19 | 20 | ) 21 | } 22 | -------------------------------------------------------------------------------- /app/javascript/lib/igv-utils.js: -------------------------------------------------------------------------------- 1 | /** Render update to reflect newly-selected features in IGV track */ 2 | export function updateTrack(trackIndex, filteredFeatures, igv, igvBrowser) { 3 | igv.FeatureUtils.packFeatures(filteredFeatures) 4 | 5 | const range = igvBrowser.trackViews[trackIndex].track.featureSource.featureCache.range 6 | const newFeatureCache = new igv.FeatureCache(filteredFeatures, igvBrowser.genome, range) 7 | igvBrowser.trackViews[trackIndex].track.featureSource.featureCache = newFeatureCache 8 | 9 | igvBrowser.trackViews[trackIndex].track.clearCachedFeatures() 10 | igvBrowser.trackViews[trackIndex].track.updateViews() 11 | } 12 | -------------------------------------------------------------------------------- /app/javascript/lib/study-overview/terra-profile-warning.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react' 2 | 3 | export const profileWarning = 4 |
5 |

6 | This visualization is trying to fetch data from the study's private bucket, but it cannot as you have not 7 | completed your Terra profile. Please  8 | register for Terra, and then reload this page. 10 |

11 |
12 | 13 | -------------------------------------------------------------------------------- /app/javascript/packs/application.js: -------------------------------------------------------------------------------- 1 | // Nothing to see here, this file will be deleted once vite migration is confirmed 2 | -------------------------------------------------------------------------------- /app/javascript/styles/_colors.scss: -------------------------------------------------------------------------------- 1 | /* defines global colors */ 2 | 3 | /* color for primary buttons, links, and other indicators that something is a clickable action */ 4 | $action-color: #3D5A87; 5 | 6 | /* non-fatal errors -- color palette borrowed from Terra */ 7 | $warning-background-color: #feeed8; 8 | $warning-icon-color: #C45500; 9 | 10 | $danger-color: rgb(219, 50, 20); 11 | $success-color: #75b041; 12 | $options-color: #E5EFF5 13 | -------------------------------------------------------------------------------- /app/javascript/styles/_inferCNVIdeogram.scss: -------------------------------------------------------------------------------- 1 | #tracks-to-display { 2 | list-style-type: none; 3 | float: left; 4 | padding-left: 20px; 5 | } 6 | 7 | #tracks-to-display label { 8 | font-weight: normal; 9 | position: relative; 10 | top: 1px; 11 | } 12 | 13 | #tracks-to-display input { 14 | margin-right: 5px; 15 | } 16 | 17 | #_ideogramLegend { 18 | position: relative; 19 | left: 20px; 20 | } 21 | 22 | #ideogramTitle { 23 | margin-left: 110px; 24 | } 25 | 26 | #ideogram-container { 27 | padding-top: 35px; 28 | } 29 | -------------------------------------------------------------------------------- /app/javascript/styles/_relatedGenesIdeogram.scss: -------------------------------------------------------------------------------- 1 | #related-genes-ideogram-container { 2 | z-index: 1000; 3 | background: #FFF; 4 | 5 | &.hidden-related-genes-ideogram { 6 | visibility: hidden; 7 | 8 | #_ideogramMiddleWrap { 9 | height: 0 !important; 10 | } 11 | } 12 | 13 | &.show-related-genes-ideogram { 14 | 15 | visibility: visible; 16 | position: static !important; 17 | padding-bottom: 45px; 18 | 19 | ~ .expression-plot { 20 | position: relative; 21 | } 22 | 23 | #_ideogramMiddleWrap { 24 | border-bottom: 1px solid #EEE; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/javascript/styles/_spin.scss: -------------------------------------------------------------------------------- 1 | @keyframes spinner-line-fade-more { 2 | 0%, 100% { 3 | opacity: 0; /* minimum opacity */ 4 | } 5 | 1% { 6 | opacity: 1; 7 | } 8 | } 9 | 10 | @keyframes spinner-line-fade-quick { 11 | 0%, 39%, 100% { 12 | opacity: 0.25; /* minimum opacity */ 13 | } 14 | 40% { 15 | opacity: 1; 16 | } 17 | } 18 | 19 | @keyframes spinner-line-fade-default { 20 | 0%, 100% { 21 | opacity: 0.22; /* minimum opacity */ 22 | } 23 | 1% { 24 | opacity: 1; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/javascript/styles/application.scss: -------------------------------------------------------------------------------- 1 | @import 'react-notifications-component/dist/theme.css'; 2 | @import './_brand.scss'; 3 | @import './_global.scss'; 4 | @import './_forms.scss'; 5 | @import './_notifications.scss'; 6 | @import './_spin.scss'; 7 | @import './_search.scss'; 8 | @import './_keywordSearch.scss'; 9 | @import './_searchPanel.scss'; 10 | @import './_resultsPanel.scss'; 11 | @import './_studyOverview.scss'; 12 | @import './_explore.scss'; 13 | @import './_scatterPlot.scss'; 14 | @import './_relatedGenesIdeogram.scss'; 15 | @import './_inferCNVIdeogram.scss'; 16 | @import './_uploadWizard.scss'; 17 | @import './_differentialExpression.scss'; 18 | @import './cellFiltering.scss'; 19 | @import './pathway.scss'; 20 | -------------------------------------------------------------------------------- /app/javascript/vite/import-meta-hot.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Jest breaks on `import.meta.hot`, so enable mocking this in tests 3 | */ 4 | export default function importMetaHot() { 5 | return import.meta.hot 6 | } 7 | -------------------------------------------------------------------------------- /app/lib/active_record_utils.rb: -------------------------------------------------------------------------------- 1 | class ActiveRecordUtils 2 | # plucks the given attrs from the query, and returns a hash of attr=>value 3 | def self.pluck_to_hash(query, attrs) 4 | query.pluck(*attrs).map { |p| attrs.zip(p).to_h } 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/lib/indexer.rb: -------------------------------------------------------------------------------- 1 | # common methods for creating indexes of data 2 | module Indexer 3 | 4 | # convert an array of values to hash of indexes 5 | # e.g. ['a', 'b', 'c'] => { a: 0, b: 1, c: 2 } 6 | # can only be used with unique arrays like cell names 7 | def array_to_hashmap(array) 8 | array.index_with.with_index { |_, index| index } 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /app/lib/loggable.rb: -------------------------------------------------------------------------------- 1 | module Loggable 2 | extend ActiveSupport::Concern 3 | 4 | # shortcut to log to STDOUT and Rails log simultaneously 5 | def log_message(message, level: :info) 6 | puts message 7 | Rails.logger.send(level, message) 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /app/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/mailers/.keep -------------------------------------------------------------------------------- /app/mailers/application_mailer.rb: -------------------------------------------------------------------------------- 1 | class ApplicationMailer < ActionMailer::Base 2 | # default from: "from@example.com" 3 | layout 'mailer' 4 | end 5 | -------------------------------------------------------------------------------- /app/models/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/models/.keep -------------------------------------------------------------------------------- /app/models/cache_removal_job.rb: -------------------------------------------------------------------------------- 1 | class CacheRemovalJob < Struct.new(:cache_key) 2 | 3 | ### 4 | # 5 | # CacheRemovalJob: class to delete matching cache files in the background to avoid tying up processes/resources in the foreground 6 | # 7 | ### 8 | 9 | def perform 10 | Rails.logger.info "#{Time.zone.now}: Deleting caches for #{cache_key}" 11 | Rails.cache.delete_matched(/#{cache_key}/) 12 | Rails.logger.info "#{Time.zone.now}: caches successfully cleared" 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/app/models/concerns/.keep -------------------------------------------------------------------------------- /app/models/concerns/concatenatable.rb: -------------------------------------------------------------------------------- 1 | # main array concatenation module for both DataArray and UserDataArray classes 2 | module Concatenatable 3 | extend ActiveSupport::Concern 4 | 5 | # main query/concatenation method for array-based data 6 | # will retrieve documents from database w/o incurring MongoDB sort limit errors and 7 | # concatenate the values together into a single contiguous array 8 | def concatenate_arrays(query) 9 | arrays = where(query) 10 | ids = arrays.pluck(:id, :array_index).sort_by(&:last).map(&:first) 11 | ids.map { |id| find(id).values }.reduce([], :+) 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/models/concerns/flat_id.rb: -------------------------------------------------------------------------------- 1 | # module to flatten BSON::ObjectId entries into strings when calling :attributes 2 | module FlatId 3 | def flat_attributes 4 | attributes.map do |name, value| 5 | if name =~ /_id/ 6 | { name.to_sym => value.to_s } 7 | else 8 | { name.to_sym => value } 9 | end 10 | end.reduce({}, :merge!) 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /app/models/configuration_option.rb: -------------------------------------------------------------------------------- 1 | class ConfigurationOption 2 | include Mongoid::Document 3 | 4 | belongs_to :admin_configuration 5 | field :name, type: String 6 | field :value, type: String 7 | 8 | validates_format_of :name, with: ValidationTools::ALPHANUMERIC_ONLY, 9 | message: ValidationTools::ALPHANUMERIC_ONLY_ERROR 10 | validates_uniqueness_of :name, scope: :admin_configuration_id 11 | validates_format_of :value, with: ValidationTools::OBJECT_LABELS, 12 | message: ValidationTools::OBJECT_LABELS_ERROR 13 | 14 | end 15 | -------------------------------------------------------------------------------- /app/models/heatmap_file_info.rb: -------------------------------------------------------------------------------- 1 | class HeatmapFileInfo 2 | include Mongoid::Document 3 | 4 | embedded_in :study_file 5 | 6 | # if custom_scaling is false, color_min/max will be ignored 7 | field :custom_scaling, type: Boolean, default: false 8 | field :color_min, type: Float 9 | field :color_max, type: Float 10 | field :legend_label, type: String 11 | end 12 | -------------------------------------------------------------------------------- /app/models/history_tracker.rb: -------------------------------------------------------------------------------- 1 | # Collection for tracking changes to tracked entities. See https://github.com/mongoid/mongoid-history 2 | class HistoryTracker 3 | include Mongoid::History::Tracker 4 | 5 | # get history track objects for all actions (or one particular action) on given model objects, within the date range 6 | # actions are create, update, destroy 7 | def self.trackers_by_date(model, action: nil, start_time: 1.day.ago, end_time: 0.days.ago) 8 | trackers = HistoryTracker.where(scope: model.to_s.underscore, :created_at.gt => start_time, :created_at.lt => end_time) 9 | if action.present? 10 | trackers = trackers.where(action: action) 11 | end 12 | trackers 13 | end 14 | 15 | end 16 | -------------------------------------------------------------------------------- /app/views/ab_tests/_ab_test_group_name_field.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 | <%= f.text_field :group_names, name: 'ab_test[group_names][]', value: name, class: 'form-control group-name' %> 4 |
5 |
6 | <%= link_to "".html_safe, '#', class: 'btn btn-sm btn-danger remove-group-name' %> 7 | 8 |
9 |
10 | <% user_count = @ab_test.user_count(name) %> 11 |

<%= user_count %> <%= 'user'.pluralize(user_count) %>

12 |
13 |
14 | -------------------------------------------------------------------------------- /app/views/ab_tests/edit.html.erb: -------------------------------------------------------------------------------- 1 |

A/B test for '<%= @feature_flag.name %>'

2 | 3 | <% if @feature_flag.ab_test.nil? %> 4 |

No A/B test exists for this feature flag yet.

5 |

6 | <%= link_to " Create A/B Test".html_safe, 7 | create_feature_flag_ab_test_path, method: :post, class: 'btn btn-primary' %> 8 |

9 | <% else %> 10 | <%= render 'ab_test_form', ab_test: @ab_test %> 11 | <% end %> 12 | 13 |

14 | <%= link_to " Back".html_safe, 15 | feature_flag_options_path, class: 'btn btn-warning' %> 16 |

17 | -------------------------------------------------------------------------------- /app/views/ab_tests/update.html.erb: -------------------------------------------------------------------------------- 1 |

AbTests#update

2 |

Find me in app/views/ab_tests/update.html.erb

3 | -------------------------------------------------------------------------------- /app/views/admin_configurations/_config_value_select.html.erb: -------------------------------------------------------------------------------- 1 | <%= f.label :value %>
<%= f.select :value, options_for_select([['Yes', 1],['No', 0]], f.object.value), {}, class: 'form-control' %> -------------------------------------------------------------------------------- /app/views/admin_configurations/_config_value_text.html.erb: -------------------------------------------------------------------------------- 1 | <%= f.label :value %>
<%= f.text_field :value, class: 'form-control' %> -------------------------------------------------------------------------------- /app/views/admin_configurations/_user_group_sync_list.html.erb: -------------------------------------------------------------------------------- 1 |

<%= @new_users.size %> users have been added to the group:

2 |

<%= @new_users.join(', ') %>

-------------------------------------------------------------------------------- /app/views/admin_configurations/deliver_users_email.js.erb: -------------------------------------------------------------------------------- 1 | closeModalSpinner('#generic-modal-spinner', '#generic-modal', function () { 2 | showMessageModal("<%= @notice.present? ? @notice.html_safe : nil %>", "<%= @alert.present? ? @alert.html_safe : nil %>"); 3 | }); 4 | -------------------------------------------------------------------------------- /app/views/admin_configurations/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing '<%= @admin_configuration.config_type %>'

2 | 3 | <%= render 'form' %> 4 | 5 |

<%= link_to " Back".html_safe, admin_configurations_path, class: 'btn btn-warning' %>

-------------------------------------------------------------------------------- /app/views/admin_configurations/firecloud_api_status.js.erb: -------------------------------------------------------------------------------- 1 | closeModalSpinner('#working-modal-spinner', '#working-modal', function() { 2 | $('#generic-update-target').html("<%= escape_javascript(render partial: '/layouts/generic_update_modal') %>"); 3 | $('#generic-update-modal-title').html("FireCloud Services Status"); 4 | $('#generic-update-modal-body').html("<%= escape_javascript(render partial: 'firecloud_api_status') %>"); 5 | $("#generic-update-modal").modal("show");}); -------------------------------------------------------------------------------- /app/views/admin_configurations/get_service_account_profile.js.erb: -------------------------------------------------------------------------------- 1 | closeModalSpinner('#working-modal-spinner', '#working-modal', function () { 2 | $('#generic-update-target').empty(); 3 | $('#generic-update-target').html("<%= escape_javascript(render partial: '/layouts/generic_update_modal') %>"); 4 | $('#generic-update-modal-title').html("Service Account FireCloud Profile

<%= @portal_service_account %>"); 5 | $('#generic-update-modal-body').html("<%= escape_javascript(render partial: 'firecloud_profile') %>"); 6 | $('#generic-update-modal').modal('show') 7 | }); -------------------------------------------------------------------------------- /app/views/admin_configurations/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array!(@admin_configurations) do |admin_configuration| 2 | json.extract! admin_configuration, :id, :name, :value 3 | json.url admin_configuration_url(admin_configuration, format: :json) 4 | end 5 | -------------------------------------------------------------------------------- /app/views/admin_configurations/new.html.erb: -------------------------------------------------------------------------------- 1 |

New admin configuration

2 | 3 | <%= render 'form' %> 4 | 5 |

<%= link_to " Back".html_safe, admin_configurations_path, class: 'btn btn-warning' %>

6 | 7 | -------------------------------------------------------------------------------- /app/views/admin_configurations/refresh_api_connections.js.erb: -------------------------------------------------------------------------------- 1 | closeModalSpinner('#working-modal-spinner', '#working-modal', function() { 2 | showMessageModal("<%= @notice.present? ? @notice.html_safe : nil %>", "<%= @alert.present? ? @alert.html_safe : nil %>"); 3 | }); 4 | -------------------------------------------------------------------------------- /app/views/admin_configurations/reset_user_download_quotas.js.erb: -------------------------------------------------------------------------------- 1 | closeModalSpinner('#working-modal-spinner', '#working-modal', function() { 2 | showMessageModal("<%= @notice.present? ? @notice.html_safe : nil %>", "<%= @alert.present? ? @alert.html_safe : nil %>"); 3 | }); 4 | -------------------------------------------------------------------------------- /app/views/admin_configurations/restart_locked_jobs.js.erb: -------------------------------------------------------------------------------- 1 | closeModalSpinner('#working-modal-spinner', '#working-modal', function() { 2 | showMessageModal("<%= @notice.present? ? @notice.html_safe : nil %>", "<%= @alert.present? ? @alert.html_safe : nil %>"); 3 | }); 4 | -------------------------------------------------------------------------------- /app/views/admin_configurations/show.html.erb: -------------------------------------------------------------------------------- 1 |

<%= notice %>

2 | 3 |

4 | Name: 5 | <%= @admin_configuration.name %> 6 |

7 | 8 |

9 | Value: 10 | <%= @admin_configuration.value %> 11 |

12 | 13 |

14 | <%= link_to 'Edit', edit_admin_configuration_path(@admin_configuration) %> 15 | <%= link_to " Back".html_safe, studies_path, class: 'btn btn-warning' %> 16 |

-------------------------------------------------------------------------------- /app/views/admin_configurations/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! @admin_configuration, :id, :name, :value, :created_at, :updated_at 2 | -------------------------------------------------------------------------------- /app/views/admin_configurations/update_service_account_profile.js.erb: -------------------------------------------------------------------------------- 1 | showMessageModal("<%= @notice.present? ? @notice.html_safe : nil %>", "<%= @alert.present? ? @alert.html_safe : nil %>"); 2 | -------------------------------------------------------------------------------- /app/views/admin_configurations/view_deployment.js.erb: -------------------------------------------------------------------------------- 1 | $('#deployment').html("<%= escape_javascript(render partial: 'deployment') %>"); 2 | <% if @notice.present? %> 3 | $("
").html("<%= @notice %>").dialog(); 4 | <% end %> 5 | -------------------------------------------------------------------------------- /app/views/api/v1/bookmarks/_bookmark.json.jbuilder: -------------------------------------------------------------------------------- 1 | bookmark.flat_attributes.each do |name, value| 2 | json.set! name, value 3 | end 4 | -------------------------------------------------------------------------------- /app/views/api/v1/bookmarks/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @bookmarks, partial: 'api/v1/bookmarks/bookmark', as: :bookmark 2 | -------------------------------------------------------------------------------- /app/views/api/v1/bookmarks/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! 'api/v1/bookmarks/bookmark', locals: { bookmark: @bookmark } 2 | -------------------------------------------------------------------------------- /app/views/api/v1/directory_listings/_directory_listing.json.jbuilder: -------------------------------------------------------------------------------- 1 | directory_listing.attributes.each do |name, value| 2 | unless name == '_id' && !directory_listing.persisted? 3 | json.set! name, value 4 | end 5 | end -------------------------------------------------------------------------------- /app/views/api/v1/directory_listings/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @directory_listings, partial: 'api/v1/directory_listings/directory_listing', as: :directory_listing 2 | -------------------------------------------------------------------------------- /app/views/api/v1/directory_listings/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! 'api/v1/directory_listings/directory_listing', locals: {directory_listing: @directory_listing} -------------------------------------------------------------------------------- /app/views/api/v1/external_resources/_external_resource.json.jbuilder: -------------------------------------------------------------------------------- 1 | external_resource.attributes.each do |name, value| 2 | unless name == '_id' && !external_resource.persisted? 3 | json.set! name, value 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/views/api/v1/external_resources/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @external_resources, partial: 'api/v1/external_resources/external_resource', as: :external_resource 2 | -------------------------------------------------------------------------------- /app/views/api/v1/external_resources/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! 'api/v1/external_resources/external_resource', locals: {external_resource: @external_resource} 2 | -------------------------------------------------------------------------------- /app/views/api/v1/publications/_publication.json.jbuilder: -------------------------------------------------------------------------------- 1 | publication.attributes.each do |name, value| 2 | unless name == '_id' && !publication.persisted? 3 | json.set! name, value 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /app/views/api/v1/publications/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @publications, partial: 'api/v1/publications/publication', as: :publication 2 | -------------------------------------------------------------------------------- /app/views/api/v1/publications/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! 'api/v1/publications/publication', locals: {publication: @publication} 2 | -------------------------------------------------------------------------------- /app/views/api/v1/schemas/studies.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.fields do 2 | json.array! Study.attribute_names do |attribute| 3 | json.name attribute 4 | if Study.fields[attribute].options[:type].to_s =~ /Object/ 5 | json.type 'BSON::ObjectId' 6 | else 7 | json.type Study.fields[attribute].options[:type].to_s 8 | if Study.fields[attribute].default_val.to_s.present? 9 | json.default_value Study.fields[attribute].default_val 10 | end 11 | end 12 | if Study::REQUIRED_ATTRIBUTES.include? attribute 13 | json.required true 14 | end 15 | end 16 | end 17 | json.required_fields Study::REQUIRED_ATTRIBUTES -------------------------------------------------------------------------------- /app/views/api/v1/search/facet_filters.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.set! :facet, @search_facet.identifier 2 | json.set! :query, @query_string 3 | json.set! :filters, @matching_filters -------------------------------------------------------------------------------- /app/views/api/v1/search/facets.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @search_facets, partial: 'api/v1/search/search_facet_config', as: :search_facet_config 2 | -------------------------------------------------------------------------------- /app/views/api/v1/site/_analysis.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.set! :namespace, analysis.namespace 2 | json.set! :name, analysis.name 3 | json.set! :snapshot, analysis.snapshot 4 | json.set! :configuration_namespace, analysis.configuration_namespace 5 | json.set! :configuration_name, analysis.configuration_name 6 | json.set! :configuration_snapshot, analysis.configuration_snapshot 7 | json.set! :synopsis, analysis.synopsis 8 | json.set! :description, strip_tags(analysis.description) 9 | json.set! :entity_type, analysis.entity_type 10 | json.set! :required_inputs, analysis.required_inputs(true) 11 | -------------------------------------------------------------------------------- /app/views/api/v1/site/_analysis_in_list.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.set! :namespace, analysis.namespace 2 | json.set! :name, analysis.name 3 | json.set! :snapshot, analysis.snapshot 4 | json.set! :configuration_namespace, analysis.configuration_namespace 5 | json.set! :configuration_name, analysis.configuration_name 6 | json.set! :configuration_snapshot, analysis.configuration_snapshot 7 | json.set! :synopsis, analysis.synopsis 8 | json.set! :description, strip_tags(analysis.description) 9 | json.set! :entity_type, analysis.entity_type -------------------------------------------------------------------------------- /app/views/api/v1/site/_analysis_info.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.set! :namespace, analysis.namespace 2 | json.set! :name, analysis.name 3 | json.set! :snapshot, analysis.snapshot 4 | json.set! :description, strip_tags(analysis.description) 5 | json.set! :entity_type, analysis.entity_type -------------------------------------------------------------------------------- /app/views/api/v1/site/_directory_listing.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.set! :name, directory_listing.name 2 | json.set! :description, directory_listing.description 3 | json.set! :file_type, directory_listing.file_type 4 | json.set! :download_url, api_v1_bulk_download_generate_curl_config_url(accessions: directory_listing.study.accession, 5 | directory: directory_listing.name) 6 | json.set! :files, directory_listing.files 7 | -------------------------------------------------------------------------------- /app/views/api/v1/site/_study_file.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.set! :name, study_file.name 2 | json.set! :file_type, study_file.file_type 3 | json.set! :description, study_file.description 4 | json.set! :bucket_location, study_file.bucket_location 5 | json.set! :upload_file_size, study_file.upload_file_size 6 | if study_file.human_fastq_url.present? 7 | json.set! :download_url, study_file.human_fastq_url 8 | else 9 | json.set! :download_url, api_v1_site_study_download_data_url(accession: study.accession, filename: study_file.bucket_location) 10 | json.set! :media_url, api_v1_site_study_stream_data_url(accession: study.accession, filename: study_file.bucket_location) 11 | end 12 | -------------------------------------------------------------------------------- /app/views/api/v1/site/_study_in_list.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.set! :accession, study.accession 2 | json.set! :name, study.name 3 | json.set! :description, study.description 4 | json.set! :public, study.public 5 | json.set! :detached, study.detached 6 | json.set! :cell_count, study.cell_count 7 | json.set! :gene_count, study.gene_count 8 | -------------------------------------------------------------------------------- /app/views/api/v1/site/analyses.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @analyses, partial: 'api/v1/site/analysis_in_list', as: :analysis 2 | -------------------------------------------------------------------------------- /app/views/api/v1/site/get_analysis.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! 'api/v1/site/analysis', locals: {analysis: @analysis_configuration} 2 | -------------------------------------------------------------------------------- /app/views/api/v1/site/get_study_analysis_config.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.analysis @analysis_configuration, partial: 'api/v1/site/analysis_info', as: :analysis 2 | json.submission_inputs @submission_options -------------------------------------------------------------------------------- /app/views/api/v1/site/studies.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @studies, partial: 'api/v1/site/study_in_list', as: :study 2 | -------------------------------------------------------------------------------- /app/views/api/v1/site/sync_submission_outputs.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.submission_outputs do 2 | json.array! @unsynced_files, partial: 'api/v1/study_files/study_file_sync', as: :study_file 3 | end -------------------------------------------------------------------------------- /app/views/api/v1/site/view_study.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! 'api/v1/site/study', locals: {study: @study} 2 | -------------------------------------------------------------------------------- /app/views/api/v1/studies/_study.json.jbuilder: -------------------------------------------------------------------------------- 1 | study.attributes.each do |name, value| 2 | unless name == '_id' && !study.persisted? 3 | json.set! name, value 4 | end 5 | end 6 | json.set! :full_description, study.full_description if show_full_description 7 | json.set! :owner_email, @study_owner_emails[study._id.to_s] if @study_owner_emails 8 | -------------------------------------------------------------------------------- /app/views/api/v1/studies/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @studies, partial: 'api/v1/studies/study', as: :study, locals: {show_full_description: false} 2 | -------------------------------------------------------------------------------- /app/views/api/v1/studies/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! 'api/v1/studies/study', locals: {study: @study, show_full_description: true} 2 | -------------------------------------------------------------------------------- /app/views/api/v1/study_file_bundles/_study_file_bundle.json.jbuilder: -------------------------------------------------------------------------------- 1 | study_file_bundle.attributes.each do |name, value| 2 | unless name == '_id' && !study_file_bundle.persisted? 3 | json.set! name, value 4 | end 5 | end 6 | json.set! :study_files do 7 | json.array! study_file_bundle.study_files.to_a, partial: 'api/v1/study_files/study_file', as: :study_file 8 | end -------------------------------------------------------------------------------- /app/views/api/v1/study_file_bundles/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @study_file_bundles, partial: 'api/v1/study_file_bundles/study_file_bundle', as: :study_file_bundle 2 | -------------------------------------------------------------------------------- /app/views/api/v1/study_file_bundles/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! 'api/v1/study_file_bundles/study_file_bundle', locals: {study_file_bundle: @study_file_bundle} -------------------------------------------------------------------------------- /app/views/api/v1/study_files/_study_file.json.jbuilder: -------------------------------------------------------------------------------- 1 | study_file.attributes.each do |name, value| 2 | unless name == '_id' && !study_file.persisted? 3 | json.set! name, value 4 | end 5 | end 6 | 7 | json.set! 'expression_file_info', study_file.expression_file_info 8 | json.set! 'cluster_file_info', study_file.cluster_file_info 9 | -------------------------------------------------------------------------------- /app/views/api/v1/study_files/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @study_files, partial: 'api/v1/study_files/study_file', as: :study_file 2 | -------------------------------------------------------------------------------- /app/views/api/v1/study_files/missing_file_bundle.json.erb: -------------------------------------------------------------------------------- 1 | { 2 | "error" : "Files of type '<%= @study_file.file_type %>' require other files of the following types to be parsed. Please create a bundle at: <%= api_v1_study_study_files_bundle_files_path(@study.id) %>", 3 | "bundle_types" : <%= raw StudyFileBundle::PARSEABLE_BUNDLE_REQUIREMENTS.to_json %> 4 | } -------------------------------------------------------------------------------- /app/views/api/v1/study_files/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! 'api/v1/study_files/study_file', locals: {study_file: @study_file} -------------------------------------------------------------------------------- /app/views/api/v1/study_shares/_study_share.json.jbuilder: -------------------------------------------------------------------------------- 1 | study_share.attributes.each do |name, value| 2 | unless name == '_id' && !study_share.persisted? 3 | json.set! name, value 4 | end 5 | end -------------------------------------------------------------------------------- /app/views/api/v1/study_shares/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @study_shares, partial: 'api/v1/study_shares/study_share', as: :study_share 2 | -------------------------------------------------------------------------------- /app/views/api/v1/study_shares/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! 'api/v1/study_shares/study_share', locals: {study_share: @study_share} -------------------------------------------------------------------------------- /app/views/api/v1/taxons/_genome_annotation.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.(genome_annotation, :id, :name, :link, :release_date) -------------------------------------------------------------------------------- /app/views/api/v1/taxons/_genome_assembly.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.(genome_assembly, :id, :name, :alias, :release_date) 2 | json.genome_annotations genome_assembly.genome_annotations, partial: 'api/v1/taxons/genome_annotation', as: :genome_annotation -------------------------------------------------------------------------------- /app/views/api/v1/taxons/_taxon.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.(taxon, :id, :common_name, :scientific_name, :ncbi_taxid, :aliases, :notes) 2 | json.genome_assemblies taxon.genome_assemblies, partial: 'api/v1/taxons/genome_assembly', as: :genome_assembly 3 | -------------------------------------------------------------------------------- /app/views/api/v1/taxons/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @taxons, partial: 'api/v1/taxons/taxon', as: :taxon 2 | -------------------------------------------------------------------------------- /app/views/api/v1/taxons/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! 'api/v1/taxons/taxon', locals: {taxon: @taxon} -------------------------------------------------------------------------------- /app/views/billing_projects/update_workspace_computes.js.erb: -------------------------------------------------------------------------------- 1 | // reset button state 2 | var btn = $('#<%= @form_id %> .update-compute-permissions'); 3 | btn.removeClass('disabled'); 4 | 5 | <% if @error.nil? %> 6 | showMessageModal("Compute permissions for <%= @email %> successfully updated.", ""); 7 | <% else %> 8 | showMessageModal("", "Unable to update compute permissions for <%= @email %>: <%= @error %>"); 9 | <% end %> 10 | -------------------------------------------------------------------------------- /app/views/branding_groups/_branding_group.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! branding_group, :id, :name, :created_at, :updated_at 2 | json.url branding_group_url(branding_group, format: :json) 3 | -------------------------------------------------------------------------------- /app/views/branding_groups/edit.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |

<%= @branding_group.name %>

4 | 5 | <%= render 'form' %> 6 | 7 |

8 | <%= scp_link_to " Show".html_safe, branding_group_path(@branding_group), class: 'btn btn-info' %> 9 | <%= scp_link_to " Back".html_safe, 10 | current_user.admin ? branding_groups_path : collection_list_navigate_path, 11 | class: 'btn btn-warning' %>

12 |
13 |
14 | -------------------------------------------------------------------------------- /app/views/branding_groups/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @branding_groups, partial: 'branding_groups/branding_group', as: :branding_group 2 | -------------------------------------------------------------------------------- /app/views/branding_groups/new.html.erb: -------------------------------------------------------------------------------- 1 |

New collection

2 | 3 | <%= render 'form' %> 4 | 5 | <%= scp_link_to " Back".html_safe, branding_groups_path, class: 'btn btn-warning' %> 6 | -------------------------------------------------------------------------------- /app/views/branding_groups/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! "branding_groups/branding_group", branding_group: @branding_group 2 | -------------------------------------------------------------------------------- /app/views/devise/confirmations/new.html.erb: -------------------------------------------------------------------------------- 1 |

Resend confirmation instructions

2 | 3 | <%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %> 4 | <%= devise_error_messages! %> 5 | 6 |
7 | <%= f.label :email %>
8 | <%= f.email_field :email, autofocus: true, value: (resource.pending_reconfirmation? ? resource.unconfirmed_email : resource.email) %> 9 |
10 | 11 |
12 | <%= f.submit "Resend confirmation instructions" %> 13 |
14 | <% end %> 15 | 16 | <%= render "devise/shared/links" %> 17 | -------------------------------------------------------------------------------- /app/views/devise/mailer/confirmation_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Welcome <%= @email %>!

2 | 3 |

You can confirm your account email through the link below:

4 | 5 |

<%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %>

6 | -------------------------------------------------------------------------------- /app/views/devise/mailer/password_change.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

We're contacting you to notify you that your password has been changed.

4 | -------------------------------------------------------------------------------- /app/views/devise/mailer/reset_password_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

Someone has requested a link to change your password. You can do this through the link below.

4 | 5 |

<%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %>

6 | 7 |

If you didn't request this, please ignore this email.

8 |

Your password won't change until you access the link above and create a new one.

9 | -------------------------------------------------------------------------------- /app/views/devise/mailer/unlock_instructions.html.erb: -------------------------------------------------------------------------------- 1 |

Hello <%= @resource.email %>!

2 | 3 |

Your account has been locked due to an excessive number of unsuccessful sign in attempts.

4 | 5 |

Click the link below to unlock your account:

6 | 7 |

<%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %>

8 | -------------------------------------------------------------------------------- /app/views/devise/passwords/new.html.erb: -------------------------------------------------------------------------------- 1 |

Forgot your Password?

2 |
3 |
4 | <%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post, class: 'form' }) do |f| %> 5 | <%= devise_error_messages! %> 6 | 7 |
8 | <%= f.label :email %>
9 | <%= f.email_field :email, autofocus: true, class: 'form-control' %> 10 |
11 | 12 |
13 | <%= f.submit "Send me reset password instructions", class: 'btn btn-warning' %> 14 |
15 | <% end %> 16 | 17 | <%= render "devise/shared/links" %> 18 |
19 |
-------------------------------------------------------------------------------- /app/views/devise/sessions/new.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |
6 |

Please sign in using a Google account

7 |
8 |
9 |
10 |

<%= link_to "Sign in with ".html_safe, user_google_oauth2_omniauth_authorize_path, method: :post, class: 'btn btn-lg btn-danger', id: 'google-auth' %>

11 |
12 |
13 | -------------------------------------------------------------------------------- /app/views/devise/unlocks/new.html.erb: -------------------------------------------------------------------------------- 1 |

Resend unlock instructions

2 | 3 | <%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %> 4 | <%= devise_error_messages! %> 5 | 6 |
7 | <%= f.label :email %>
8 | <%= f.email_field :email, autofocus: true %> 9 |
10 | 11 |
12 | <%= f.submit "Resend unlock instructions" %> 13 |
14 | <% end %> 15 | 16 | <%= render "devise/shared/links" %> 17 | -------------------------------------------------------------------------------- /app/views/feature_announcements/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing '<%= @feature_announcement.title %>'

2 | 3 | <%= render 'form', feature_announcement: @feature_announcement %> 4 | 5 |

6 | <%= link_to " Back".html_safe, feature_announcements_path, class: 'btn btn-warning' %> 7 |

8 | -------------------------------------------------------------------------------- /app/views/feature_announcements/latest.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for(:html_title) { 'Latest features - Single Cell Portal' } %> 2 |

3 | <%= link_to "Home", site_path %> / Latest features 4 |

5 |
6 |
7 | <%= render partial: 'feature_announcement_list', locals: { feature_announcements: @latest } %> 8 |
9 |
10 |
11 | <% if @archived.any? %> 12 |

13 | Archives 14 |

15 |
16 |
17 | <%= render partial: 'feature_announcement_list', locals: { feature_announcements: @archived } %> 18 |
19 |
20 | <% end %> 21 | -------------------------------------------------------------------------------- /app/views/feature_announcements/new.html.erb: -------------------------------------------------------------------------------- 1 |

New feature announcement

2 | 3 | <%= render 'form', feature_announcement: @feature_announcement %> 4 | 5 |

6 | <%= link_to " Back".html_safe, feature_announcements_path, class: 'btn btn-warning' %> 7 |

8 | -------------------------------------------------------------------------------- /app/views/feature_announcements/view_announcement.html.erb: -------------------------------------------------------------------------------- 1 |

2 | <%= scp_link_to '<<', latest_feature_announcements_path %> 3 | <%= @feature_announcement.title %> 4 | <% if @feature_announcement.doc_link.present? %> 5 | <%= link_to "More info ".html_safe, @feature_announcement.doc_link, 6 | class: 'btn btn-default pull-right', target: :_blank, rel: 'noopener noreferrer' %> 7 | <% end %> 8 |

9 |

<%= @feature_announcement.display_date %>

10 |
11 | <%= @feature_announcement.content.html_safe %> 12 |
13 | -------------------------------------------------------------------------------- /app/views/layouts/422.html.erb: -------------------------------------------------------------------------------- 1 |
2 |

We're sorry, but the change you wanted was rejected by the server.

3 |

We were unable to verify the authenticity of your request. It is possible that your session has expired.

4 |

Try signing out and in again to refresh your session before continuing.

5 |
6 |

Please report an issue if this problem persists.

7 |
-------------------------------------------------------------------------------- /app/views/layouts/_breadcrumbs.html.erb: -------------------------------------------------------------------------------- 1 | <% if controller_name == 'site' && @study %> 2 |

3 | <%= @study.name %> 4 |

5 | <% else %> 6 | 11 | <% end %> 12 | -------------------------------------------------------------------------------- /app/views/layouts/_contact_us.html.erb: -------------------------------------------------------------------------------- 1 |

If you are experiencing issues using Single Cell Portal or would like to ask a question, 2 | please send an email to <%= mail_to 'scp-support@broadinstitute.zendesk.com', 'scp-support@broadinstitute.zendesk.com' %>.

3 |

You can also visit our <%= link_to 'documentation', 'https://singlecell.zendesk.com/hc/en-us', 4 | target: :_blank, rel: 'noopener noreferrer' %> 5 | to view common topics about using Single Cell Portal.

6 | -------------------------------------------------------------------------------- /app/views/layouts/_external_resources_view.html.erb: -------------------------------------------------------------------------------- 1 |

2 | <% instance.external_resources.each do |resource| %> 3 | <%= link_to "#{resource.title}#{resource.publication_url ? " " : nil}".html_safe, 4 | resource.url, class: 'btn btn-default navigation-form external-resource-link', target: :_blank, 5 | rel: 'noopener noreferrer', title: "#{resource.publication_url ? 'Publication: ': nil }#{resource.description}", 6 | data: {toggle: 'tooltip'} %> 7 | <% end %> 8 |

9 | -------------------------------------------------------------------------------- /app/views/layouts/_generic_update_modal.html.erb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/views/layouts/_multiselect_checkbox_field.html.erb: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /app/views/layouts/_notices.html.erb: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /app/views/layouts/firecloud_unavailable.js.erb: -------------------------------------------------------------------------------- 1 | $('.modal').modal('hide'); 2 | 3 | alert('Study workspaces are temporarily unavailable, so we cannot complete your request. Please try again later.'); -------------------------------------------------------------------------------- /app/views/layouts/mailer.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | <%= yield %> 4 | 5 | 6 | -------------------------------------------------------------------------------- /app/views/layouts/mailer.text.erb: -------------------------------------------------------------------------------- 1 | <%= yield %> 2 | -------------------------------------------------------------------------------- /app/views/layouts/session_expired.js.erb: -------------------------------------------------------------------------------- 1 | showMessageModal("<%= @notice.present? ? @notice.html_safe : nil %>", "<%= @alert.present? ? @alert.html_safe.gsub('"', '\'') : nil %>"); 2 | -------------------------------------------------------------------------------- /app/views/preset_searches/_preset_search.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! preset_search, :id, :name, :identifier, :accession_list, :search_terms, :facet_filters, :public, :created_at, :updated_at 2 | json.url preset_search_url(stored_search, format: :json) 3 | -------------------------------------------------------------------------------- /app/views/preset_searches/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing "<%= @preset_search.name %>"

2 | 3 | <%= render 'form', preset_search: @preset_search %> 4 | 5 |

6 | <%= scp_link_to " Info".html_safe, preset_search_path(@preset_search), class: 'btn btn-info' %> 7 | <%= scp_link_to " Back".html_safe, preset_searches_path, class: 'btn btn-warning' %> 8 |

9 | -------------------------------------------------------------------------------- /app/views/preset_searches/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @preset_searches, partial: 'preset_searches/preset_search', as: :preset_search 2 | -------------------------------------------------------------------------------- /app/views/preset_searches/new.html.erb: -------------------------------------------------------------------------------- 1 |

New preset search

2 | 3 | <%= render 'form', preset_search: @preset_search %> 4 | 5 |

<%= scp_link_to " Back".html_safe, preset_searches_path, class: 'btn btn-warning' %>

6 | -------------------------------------------------------------------------------- /app/views/preset_searches/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! "preset_searches/preset_search", preset_search: @preset_search 2 | -------------------------------------------------------------------------------- /app/views/profiles/get_firecloud_profile.js.erb: -------------------------------------------------------------------------------- 1 | $('#update-user-firecloud-profile').removeClass('disabled'); 2 | $('#profile-firecloud').html("<%= escape_javascript(render partial: 'user_firecloud_profile') %>") -------------------------------------------------------------------------------- /app/views/profiles/update.js.erb: -------------------------------------------------------------------------------- 1 | const isNoticePresent = <%= @notice.present? %> 2 | if (isNoticePresent) { 3 | // modal unnecessary as toggle has already changed 4 | console.log('<%= @notice %>') 5 | } else { 6 | // show error message 7 | const errorMsg = '<%= @alert %>' 8 | $('#generic-modal .modal-body').html(`

${errorMsg}

`) 9 | $('#generic-modal-spinner').remove('spinner-target') 10 | $('#generic-modal-title').html('Unable to save profile settings') 11 | $('#generic-modal-footer').remove() 12 | $('#generic-modal').modal('show') 13 | // reset toggle & form state 14 | const toggleId = "<%= @toggle_id %>" 15 | flipToggleSwitch($(`#${toggleId}`)) 16 | } 17 | -------------------------------------------------------------------------------- /app/views/profiles/update_firecloud_profile.js.erb: -------------------------------------------------------------------------------- 1 | showMessageModal("<%= @notice.present? ? @notice.html_safe : nil %>", "<%= @alert.present? ? @alert.html_safe : nil %>"); 2 | $('#profile-firecloud').html("<%= escape_javascript(render partial: 'user_firecloud_profile') %>") 3 | -------------------------------------------------------------------------------- /app/views/reports/report_request.js.erb: -------------------------------------------------------------------------------- 1 | $('#contact-modal').on('hidden.bs.modal', function() { 2 | $('#contact-modal').off('hidden.bs.modal'); // clear event to prevent queueing 3 | CKEDITOR.instances.report_request_message.setData(''); // clear contents of CKEditor 4 | showMessageModal("Your message has been successfully delivered.", ""); 5 | }); 6 | 7 | $('#contact-modal').modal('hide'); 8 | -------------------------------------------------------------------------------- /app/views/single_cell_mailer/admin_notification.html.erb: -------------------------------------------------------------------------------- 1 | <%= @message.html_safe %> -------------------------------------------------------------------------------- /app/views/single_cell_mailer/annot_share_update_notification.html.erb: -------------------------------------------------------------------------------- 1 |

The following annotation on the <%= link_to 'Single Cell Portal', studies_url %> has been updated:

2 |
3 |

Name: <%= @user_annotation.name %>

4 |

The following attributes were updated: <%= @changes.join(', ') %>

5 |

Please <%= link_to 'log in', studies_url %> to view the resulting changes.

-------------------------------------------------------------------------------- /app/views/single_cell_mailer/annotation_publish_failure.html.erb: -------------------------------------------------------------------------------- 1 |

Your annotation named '<%= @user_annotation.name %>' failed to publish back to the source study due to the following error:

2 |

<%= @error %>

-------------------------------------------------------------------------------- /app/views/single_cell_mailer/daily_disk_status.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | <% @table_header.each do |header| %> 5 | 6 | <% end %> 7 | 8 | 9 | 10 | 11 | <% @portal_row.each do |cell| %> 12 | 13 | <% end %> 14 | 15 | 16 | <% @data_disk_row.each do |cell| %> 17 | 18 | <% end %> 19 | 20 | 21 |
<%= header %>
<%= cell %>
<%= cell %>
-------------------------------------------------------------------------------- /app/views/single_cell_mailer/notify_admin_parse_fail.html.erb: -------------------------------------------------------------------------------- 1 | <%= @contents.html_safe %> 2 | -------------------------------------------------------------------------------- /app/views/single_cell_mailer/notify_user_parse_complete.html.erb: -------------------------------------------------------------------------------- 1 |

Your Single Cell Portal parse job has completed with the following results:

2 | <%= @message.join('
').html_safe %> 3 |

Study URL: <%= legacy_study_url(identifier: @study.accession) %>

-------------------------------------------------------------------------------- /app/views/single_cell_mailer/notify_user_parse_complete.text.erb: -------------------------------------------------------------------------------- 1 | Your Single Cell Portal parse job has completed with the following results: 2 | 3 | <%= @message.join("\n") %> 4 | 5 | Study URL: <%= legacy_study_url(identifier: @study.accession) %> -------------------------------------------------------------------------------- /app/views/single_cell_mailer/notify_user_parse_fail.html.erb: -------------------------------------------------------------------------------- 1 |

Your Single Cell Portal parse job has failed with the following error:

2 | 3 | <%= @error.html_safe %> 4 | 5 |

This file has been deleted from your study, and any child database records removed. 6 | If you have any questions about this error, you can contact the Single Cell Portal Team at 7 | <%= mail_to 'scp-support@broadinstitute.zendesk.com', 'scp-support@broadinstitute.zendesk.com', subject: "File Ingest Error" %>. 8 | Please copy and paste the "Details" section into the body of the email to help us diagnose your issue. 9 |

10 | 11 |

Study URL: <%= legacy_study_url(identifier: @study.accession) %>

-------------------------------------------------------------------------------- /app/views/single_cell_mailer/notify_user_parse_fail.text.erb: -------------------------------------------------------------------------------- 1 | Your Single Cell Portal parse job has failed with the following error: 2 | 3 | <%= @error %> 4 | 5 | This file has been deleted from your study, and any child database records removed. 6 | If you have any questions about this error, you can contact the Single Cell Portal Team at scp-support@broadinstitute.zendesk.com. 7 | Please copy and paste the "Details" section into the body of the email to help us diagnose your issue. 8 | 9 | Study URL: <%= legacy_study_url(identifier: @study.accession) %> -------------------------------------------------------------------------------- /app/views/single_cell_mailer/share_annotation_notification.html.erb: -------------------------------------------------------------------------------- 1 |

The following annotation on the <%= link_to 'Single Cell Portal', studies_url %> has been shared:

2 |
3 |

Name: <%= @user_annotation.name %>

4 |

Owner: <%= @user.email %>

5 |

Shared With: <%= @share.email %>

6 |

Granted Permission: <%= @share.permission %>

-------------------------------------------------------------------------------- /app/views/single_cell_mailer/share_notification.html.erb: -------------------------------------------------------------------------------- 1 |

2 | The study '<%= @study.name %>' 3 | (<%= link_to @study.accession, view_study_url(accession: @study.accession, study_name: @study.url_safe_name) %>) 4 | has been shared:

5 |
6 | 7 |

Shared With: <%= @share.email %>

8 |

Granted Permission: <%= @share.permission %>

9 | -------------------------------------------------------------------------------- /app/views/single_cell_mailer/share_update_notification.html.erb: -------------------------------------------------------------------------------- 1 |

2 | The study '<%= @study.name %>' 3 | (<%= link_to @study.accession, view_study_url(accession: @study.accession, study_name: @study.url_safe_name) %>) 4 | has had the following attributes updated.

5 |
6 |

<%= @changes.join(', ') %>

7 |

Please <%= link_to 'log in', study_url(@study) %> to view the resulting changes.

8 | -------------------------------------------------------------------------------- /app/views/single_cell_mailer/user_download_fail_notification.html.erb: -------------------------------------------------------------------------------- 1 |

A user attempted to download <%= @file_location %> from '<%= @study.name %>', but the file was missing 2 | from the study's storage bucket. Please check the workspace bucket to make sure the file has not been deleted:

3 | 4 |

<%= link_to @study.google_bucket_url, @study.google_bucket_url %>

5 | 6 |

If you have intentionally deleted this file from your workspace, please delete the corresponding file from your study 7 | in the portal.

-------------------------------------------------------------------------------- /app/views/site/_annotation_warning.js.erb: -------------------------------------------------------------------------------- 1 | // let user know if the requested annotation wasn't available 2 | var requestedAnnotation = '<%= params[:annotation] %>' 3 | var loadedAnnotation = '<%= @selected_annotation[:identifier] %>' 4 | var loadedAnnotationName = '<%= @selected_annotation[:name] %> (Study Wide)' 5 | var showAlert = requestedAnnotation !== loadedAnnotation; 6 | 7 | if (showAlert) { 8 | alert('The annotation that you selected is not available to view on this cluster. ' + 9 | 'We have defaulted back to the first available annotation: ' + loadedAnnotationName) 10 | } 11 | -------------------------------------------------------------------------------- /app/views/site/_home_page_link.html.erb: -------------------------------------------------------------------------------- 1 | <% image_link = @home_page_link.image.present? ? "#{image_tag(@home_page_link.image)}" : nil %> 2 | 7 | <%= 8 | link_to "#{image_link}#{@home_page_link.name}".html_safe, @home_page_link.href, title: @home_page_link.tooltip, 9 | data: { toggle: 'tooltip', placement: 'left'}, class: @home_page_link.css_class, 10 | id: 'home-page-link', target: :_blank 11 | %> 12 | -------------------------------------------------------------------------------- /app/views/site/_missing_genes.html.erb: -------------------------------------------------------------------------------- 1 | <% if !@not_found.nil? && !@not_found.empty? %> 2 | <%= link_to "#{@not_found.size} not found", '#', 'data-toggle' => 'popover', 'data-trigger' => 'hover', 'data-content' => "#{@not_found.map {|g| g['name']}.join(', ')}", class: 'btn btn-danger more-genes', id: 'missing-genes' %> 3 | <% end %> -------------------------------------------------------------------------------- /app/views/site/_search_help.html.erb: -------------------------------------------------------------------------------- 1 |

Use the search box to the left to filter studies by name/description. Each separate term is queried using 'and' logic.

2 |

You may quote multiple terms for an exact match. This cannot not be combined with another search term.

3 |

You may also use the minus (-) sign to negate a term, but only if you have provided another term to search for (you cannot perform only a negative search).

4 |

You may also use the 'Most Recent' and 'Most Popular' filters to re-order results by either creation date or view count, respectively. These can be used in conjunction with search terms.

-------------------------------------------------------------------------------- /app/views/site/_study_title_bar.html.erb: -------------------------------------------------------------------------------- 1 | 2 | <% if @study.public? %> 3 | <% content_for(:html_title) { "#{@study.name } - Single Cell Portal" } %> 4 | <% else %> 5 | <% content_for(:html_title) { "#{@study.accession} - Single Cell Portal" } %> 6 | <% end %> 7 | -------------------------------------------------------------------------------- /app/views/site/_subsample_warning.html.erb: -------------------------------------------------------------------------------- 1 | <% if cluster.is_subsampling? %> 2 |

Subsamples are still being processed for this plot.

3 | <% end %> 4 | -------------------------------------------------------------------------------- /app/views/site/edit_study_description.js.erb: -------------------------------------------------------------------------------- 1 | $('#study-description-content').html('<%= escape_javascript(render partial: 'study_description_edit') %>'); 2 | 3 | ClassicEditor 4 | .create( document.querySelector( '#study_study_detail_attributes_full_description' ), 5 | fullCKEditorConfig 6 | ); 7 | -------------------------------------------------------------------------------- /app/views/site/genome/_browse_igv_link.html.erb: -------------------------------------------------------------------------------- 1 | <% if study_file.generation %> 2 | <%= link_to 'Browse in genome', '#study-visualize', data: {filename: ERB::Util.url_encode(study_file.upload_file_name)}, class: 'track-browse-genome btn btn-primary dl-link other-file' %> 3 | <% else %> 4 | Awaiting remote file 5 | <% end %> 6 | -------------------------------------------------------------------------------- /app/views/site/notice.js.erb: -------------------------------------------------------------------------------- 1 | closeModalSpinner("#" + OPEN_MODAL + ' div.spinner-target', '#' + OPEN_MODAL, function() { 2 | // update modal content 3 | $('#notice-content').html("<%= !@notice.blank? ? @notice.html_safe : nil %>"); 4 | $('#alert-content').html("<%= !@alert.blank? ? @alert.html_safe : nil %>"); 5 | 6 | $("#message_modal").modal("show"); 7 | 8 | // don't timeout alert messages 9 | if (<%= alert.nil? %>) { 10 | setTimeout(function() { 11 | $("#message_modal").modal("hide"); 12 | }, 3000); 13 | } 14 | }); 15 | -------------------------------------------------------------------------------- /app/views/site/record_download_acceptance.js.erb: -------------------------------------------------------------------------------- 1 | setElementsEnabled($('.dl-link')); 2 | setElementsEnabled($('#download-help')); 3 | $('#download-agreement-submit').replaceWith("<%= j(button_tag "Accepted", type: 'button', class: 'btn btn-lg btn-default', disabled: true) %>") 4 | showMessageModal("Thank you for accepting - you may now download data from this study.") 5 | -------------------------------------------------------------------------------- /app/views/site/terms_of_service.html.erb: -------------------------------------------------------------------------------- 1 | <% content_for(:html_title) { 'Terms of service - Single Cell Portal' } %> 2 | 3 |

Terms of service

4 | <%= render :partial => 'tos_content' %> 5 | -------------------------------------------------------------------------------- /app/views/studies/_bam_association_fields.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 | <%= f.fields_for :options do |opts| %> 4 | <%= opts.label :bam_id, 'BAM Target' %> 
5 | <%= opts.select :bam_id, options_for_select([]), {include_blank: 'Please select a BAM file...'}, class: 'form-control bam-file-select bundle-select' %> 6 | <% end %> 7 |
8 |
-------------------------------------------------------------------------------- /app/views/studies/_color_profile.html.erb: -------------------------------------------------------------------------------- 1 | <%= label_tag :color_profile, 'Color profile' %> <%= select_tag :color_profile, options_for_select(SiteController::COLORSCALE_THEMES, @study.default_color_profile), class: 'form-control' %> -------------------------------------------------------------------------------- /app/views/studies/_coord_labels_association_fields.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 | <%= f.fields_for :options do |opts| %> 4 | <%= opts.label :cluster_file_id, 'Cluster Target' %> 
5 | <%= opts.select :cluster_file_id, options_for_select([]), {include_blank: 'Please select a Cluster file...'}, class: 'form-control cluster-file-select bundle-select' %> 6 | <% end %> 7 |
8 |
9 | -------------------------------------------------------------------------------- /app/views/studies/_deleted_bundle_message.html.erb: -------------------------------------------------------------------------------- 1 |

2 | The file '<%= file_name %>' (<%= file_type %>) is missing the required pairing to a 3 | <%= missing_file_type %> file. This may have happened due to the associated file failing to ingest 4 | properly and subsequently being automatically deleted while this upload was in process. Please re-upload the 5 | <%= missing_file_type %> file, and once that file has ingested properly, you may re-upload this file. 6 |

7 | -------------------------------------------------------------------------------- /app/views/studies/_mm_coordinate_association_fields.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 | <%= f.fields_for :options do |opts| %> 4 | <%= opts.label :matrix_id, 'MM Coordinate Matrix Pair' %> 
5 | <%= opts.select :matrix_id, options_for_select([]), {include_blank: 'Please select a matrix...'}, class: 'form-control matrix-file-select bundle-select' %> 6 | <% end %> 7 |
8 |
-------------------------------------------------------------------------------- /app/views/studies/_parse_modal_content.html.erb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/views/studies/_reference_anndata_notice.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 |

Note: only reference AnnData files are supported for sync. No data will be ingested from this file.

4 |
5 |
6 | -------------------------------------------------------------------------------- /app/views/studies/_refresh_link.html.erb: -------------------------------------------------------------------------------- 1 | <%= link_to " Refresh".html_safe, "javascript:refreshUpload('#{study_file.upload_file_name}', '##{study_file._id}');", class: 'btn btn-warning loading' %> -------------------------------------------------------------------------------- /app/views/studies/_reset_step_status.html.erb: -------------------------------------------------------------------------------- 1 | <% if required == true %> 2 | Required 3 | <% else %> 4 | Optional 5 | <% end %> -------------------------------------------------------------------------------- /app/views/studies/_step_completed.html.erb: -------------------------------------------------------------------------------- 1 | Completed -------------------------------------------------------------------------------- /app/views/studies/_study_file_bundle_btns.html.erb: -------------------------------------------------------------------------------- 1 | <% if StudyFileBundle::BUNDLE_TYPES.include?(file_type) %> 2 |
3 |
4 | <% StudyFileBundle::BUNDLE_REQUIREMENTS[file_type].each do |bundled_file_type| %> 5 | <%= link_to " Bundle a #{bundled_file_type} with this #{file_type}".html_safe, '#/', class: 'btn btn-sm btn-info initialize-bundled-file', data: {file_type: bundled_file_type, study_file_id: study_file_id} %> 6 | <% end %> 7 |
8 |
9 | <% end %> 10 | -------------------------------------------------------------------------------- /app/views/studies/_study_file_errors.html.erb: -------------------------------------------------------------------------------- 1 | <% if study_file.errors.any? %> 2 |
3 |

<%= pluralize(study_file.errors.count, "error") %> prohibited this study from being saved:

4 | 5 | 10 |
11 | <% end %> -------------------------------------------------------------------------------- /app/views/studies/_study_file_notices.html.erb: -------------------------------------------------------------------------------- 1 | 13 | 14 | -------------------------------------------------------------------------------- /app/views/studies/_sync_notice_modal.html.erb: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/views/studies/_taxon_help_popover.html.erb: -------------------------------------------------------------------------------- 1 | 4 | Need Help? 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/views/studies/abort_delete_study_file.js.erb: -------------------------------------------------------------------------------- 1 | function closeOpenModal() { 2 | if (OPEN_MODAL !== '') { 3 | $('#' + OPEN_MODAL).modal('hide'); 4 | } 5 | } 6 | // delete modal may open before or after alert message, so check both times 7 | closeOpenModal(); 8 | 9 | alert('This file is still being processed and cannot be deleted yet. You will receive an email when all parsing and ' + 10 | 'optional subsampling has completed.' 11 | ) 12 | 13 | closeOpenModal(); 14 | -------------------------------------------------------------------------------- /app/views/studies/deleted_bundle.js.erb: -------------------------------------------------------------------------------- 1 | $('<%= params[:modal_target]%>').modal('hide'); 2 | $('<%= params[:selector] %>').remove(); 3 | 4 | $('#generic-update-target').html("<%= j(render partial: '/layouts/generic_update_modal') %>"); 5 | $('#generic-update-modal-title').html("Upload of <%= @file_name %> cancelled"); 6 | $('#generic-update-modal-body').html("<%= j(render partial: 'deleted_bundle_message', locals: {file_name: @file_name, file_type: @file_type, missing_file_type: @missing_file_type})%>"); 7 | $("#generic-update-modal").modal("show"); 8 | -------------------------------------------------------------------------------- /app/views/studies/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing '<%= @study.name %>'

2 | 3 | <%= render 'form' %> 4 | 5 |

<%= scp_link_to " Upload/Edit data".html_safe, upload_study_path(@study), class: 'btn btn-success' %> 6 | <%= scp_link_to " Back".html_safe, studies_path, class: 'btn btn-warning' %>

7 | -------------------------------------------------------------------------------- /app/views/studies/index.html.erb: -------------------------------------------------------------------------------- 1 |
2 | 5 | -------------------------------------------------------------------------------- /app/views/studies/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array!(@studies) do |study| 2 | json.extract! study, :id 3 | json.url study_url(study, format: :json) 4 | end 5 | -------------------------------------------------------------------------------- /app/views/studies/initialize_bundled_file.js.erb: -------------------------------------------------------------------------------- 1 | $('#<%= @target %>').append("<%= j(render partial: 'initialize_bundled_file_form', locals: {study_file: @study_file}) %>"); -------------------------------------------------------------------------------- /app/views/studies/initialize_study.html.erb: -------------------------------------------------------------------------------- 1 |
2 |
3 | 10 | -------------------------------------------------------------------------------- /app/views/studies/load_annotation_options.js.erb: -------------------------------------------------------------------------------- 1 | $("#study_default_options_annotation").html("<%= escape_javascript(select_tag :annotation, grouped_options_for_select(@default_cluster_annotations, set_annotation_value(@study, {})), class: 'form-control' )%>"); -------------------------------------------------------------------------------- /app/views/studies/new_study_file.js.erb: -------------------------------------------------------------------------------- 1 | $('<%= params[:target] %>').append("
<%= escape_javascript(render partial: params[:form],locals: { study_file: @study_file, allow_only: @allow_only }) %>
"); 2 | 3 | // get instance of new form as ID has changed 4 | var wizForm = $('.<%= params[:form] %>').slice(-1)[0]; 5 | 6 | $(wizForm).find('[data-toggle="tooltip"]').tooltip({container: 'body'}); 7 | -------------------------------------------------------------------------------- /app/views/studies/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! @study, :id, :created_at, :updated_at 2 | -------------------------------------------------------------------------------- /app/views/studies/sync_directory_listing.js.erb: -------------------------------------------------------------------------------- 1 | $('#sync-notices').html("<%= escape_javascript(render partial: 'sync_notice_modal', locals: {message: @message}) %>"); 2 | $('#sync-notice-modal').modal('show'); 3 | $("<%= @form %>").remove(); 4 | 5 | // now append synced study file to synced data panel 6 | $('#synced-directory-listings').append("<%= escape_javascript(render partial: 'directory_listing_form', locals: {directory: @directory}) %>"); 7 | 8 | // close any empty panels 9 | $('.unsynced').each(function() { 10 | if ($(this).find('.unsynced-content').html().trim() == "") { 11 | $(this).collapse('hide'); 12 | } 13 | }); 14 | -------------------------------------------------------------------------------- /app/views/studies/update_default_options_fail.js.erb: -------------------------------------------------------------------------------- 1 | $('#default-study-options-form').replaceWith("<%= escape_javascript(render partial: 'study_default_options_form') %>"); 2 | 3 | // show success modal 4 | $('#notice-target').html("<%= escape_javascript(render partial: 'study_file_notices', locals: {message: 'Study default options successfully saved.'}) %>"); -------------------------------------------------------------------------------- /app/views/studies/update_default_options_success.js.erb: -------------------------------------------------------------------------------- 1 | $('#default-study-options-form').replaceWith("<%= escape_javascript(render partial: 'study_default_options_form') %>"); 2 | 3 | // show success modal 4 | $('#notice-target').html("<%= escape_javascript(render partial: 'study_file_notices', locals: {message: 'Study default view options successfully saved.'}) %>"); -------------------------------------------------------------------------------- /app/views/studies/update_fail.js.erb: -------------------------------------------------------------------------------- 1 | $('<%= @selector %>').replaceWith("<%= escape_javascript(render partial: @partial, locals: {study_file: @study_file, allow_only: params[:allow_only] || 'all' }) %>"); 2 | -------------------------------------------------------------------------------- /app/views/studies/usage_stats.html.erb: -------------------------------------------------------------------------------- 1 |
2 | 7 | -------------------------------------------------------------------------------- /app/views/taxons/_taxon.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract! taxon, :id, :created_at, :updated_at 2 | json.url taxon_url(taxon, format: :json) 3 | -------------------------------------------------------------------------------- /app/views/taxons/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing '<%= @taxon.common_name %>'

2 | 3 | <%= render 'form', taxon: @taxon %> 4 | 5 |

6 | <%= link_to " Details".html_safe, taxon_path(@taxon), class: 'btn btn-info' %> 7 | <%= link_to " Back".html_safe, taxons_path, class: 'btn btn-warning' %> 8 |

9 | -------------------------------------------------------------------------------- /app/views/taxons/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array! @taxons, partial: 'taxons/taxon', as: :taxon 2 | -------------------------------------------------------------------------------- /app/views/taxons/new.html.erb: -------------------------------------------------------------------------------- 1 |

New species

2 | 3 | <%= render 'form', taxon: @taxon %> 4 | 5 |

<%= link_to " Back".html_safe, taxons_path, class: 'btn btn-warning' %>

6 | -------------------------------------------------------------------------------- /app/views/taxons/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial! "taxons/taxon", taxon: @taxon 2 | -------------------------------------------------------------------------------- /app/views/user_annotations/edit.html.erb: -------------------------------------------------------------------------------- 1 |

Editing '<%= @user_annotation.name %>'

2 |

<%= @user_annotation.subsampled_at %>

3 | 4 | <%= render 'form' %> 5 | 6 |

<%= scp_link_to " Back".html_safe, user_annotations_path, {class: 'btn btn-warning'} %>

7 | -------------------------------------------------------------------------------- /app/views/user_annotations/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array!(@user_annotations) do |user_annotation| 2 | json.extract! user_annotation, :id 3 | json.url user_annotation_url(user_annotation, format: :json) 4 | end 5 | -------------------------------------------------------------------------------- /bin/burp_start.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -eu 4 | 5 | # Burp private Docker image URL 6 | IMAGE="$1" 7 | 8 | # Base64-encoded Service Account Key JSON to pull the image from container registry 9 | BASE64_KEY="$2" 10 | 11 | # Authenticate with container registry 12 | REGISTRY=$(echo "${IMAGE}" | awk -F/ '{print $1}') 13 | echo "${BASE64_KEY}" | docker login -u _json_key_base64 --password-stdin "https://${REGISTRY}" 14 | 15 | # Start Burp container in the background 16 | CONTAINER="burp" 17 | docker run --rm -d --net host --name "${CONTAINER}" "${IMAGE}" 18 | 19 | # Wait until startup 20 | ( docker logs "${CONTAINER}" -f & ) | grep -q "Started BurpApplication" 21 | -------------------------------------------------------------------------------- /bin/delayed_job: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | ENV['RAILS_ENV'] = ARGV[1].nil? ? 'development' : ARGV[1] 4 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment')) 5 | require 'delayed/command' 6 | Delayed::Command.new(ARGV).daemonize 7 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path('../config/application', __dir__) 3 | require_relative "../config/boot" 4 | require "rails/commands" 5 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative "../config/boot" 3 | require "rake" 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /bin/webpack: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development" 4 | ENV["NODE_ENV"] ||= "development" 5 | 6 | require "pathname" 7 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", 8 | Pathname.new(__FILE__).realpath) 9 | 10 | require "bundler/setup" 11 | 12 | require "webpacker" 13 | require "webpacker/webpack_runner" 14 | 15 | APP_ROOT = File.expand_path("..", __dir__) 16 | Dir.chdir(APP_ROOT) do 17 | Webpacker::WebpackRunner.run(ARGV) 18 | end 19 | -------------------------------------------------------------------------------- /bin/webpack-dev-server: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | ENV["RAILS_ENV"] ||= ENV["RACK_ENV"] || "development" 4 | ENV["NODE_ENV"] ||= "development" 5 | 6 | require "pathname" 7 | ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", 8 | Pathname.new(__FILE__).realpath) 9 | 10 | require "bundler/setup" 11 | 12 | require "webpacker" 13 | require "webpacker/dev_server_runner" 14 | 15 | APP_ROOT = File.expand_path("..", __dir__) 16 | Dir.chdir(APP_ROOT) do 17 | Webpacker::DevServerRunner.run(ARGV) 18 | end 19 | -------------------------------------------------------------------------------- /bin/yarn: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_ROOT = File.expand_path('..', __dir__) 3 | Dir.chdir(APP_ROOT) do 4 | yarn = ENV["PATH"].split(File::PATH_SEPARATOR). 5 | select { |dir| File.expand_path(dir) != __dir__ }. 6 | product(["yarn", "yarn.cmd", "yarn.ps1"]). 7 | map { |dir, file| File.expand_path(file, dir) }. 8 | find { |file| File.executable?(file) } 9 | 10 | if yarn 11 | exec yarn, *ARGV 12 | else 13 | $stderr.puts "Yarn executable was not detected in the system." 14 | $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install" 15 | exit 1 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | codecov: 2 | require_ci_to_pass: no 3 | comment: 4 | layout: "reach, diff, files" 5 | behavior: default 6 | coverage: 7 | status: 8 | project: 9 | default: 10 | threshold: 0.1% 11 | patch: off 12 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require_relative "config/environment" 4 | 5 | run Rails.application 6 | Rails.application.load_server 7 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) 2 | 3 | require "bundler/setup" # Set up gems listed in the Gemfile. 4 | require "bootsnap/setup" # Speed up boot time by caching expensive operations. 5 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require_relative "application" 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /config/filebeat/filebeat-Dockerfile: -------------------------------------------------------------------------------- 1 | FROM docker.elastic.co/beats/filebeat:5.6.14 2 | USER root 3 | RUN mkdir /var/log/rails 4 | RUN chown root:filebeat -R /var/log/rails 5 | COPY config/filebeat/filebeat.yml /usr/share/filebeat/filebeat.yml 6 | RUN chown root:filebeat /usr/share/filebeat/filebeat.yml 7 | RUN mkdir /usr/share/filebeat/conf.d 8 | COPY config/filebeat/nginx.yml config/filebeat/rails.yml /usr/share/filebeat/conf.d/ 9 | RUN chown root:filebeat -R /usr/share/filebeat/conf.d 10 | RUN usermod -o -u 1004 filebeat 11 | USER filebeat -------------------------------------------------------------------------------- /config/filebeat/filebeat.yml: -------------------------------------------------------------------------------- 1 | filebeat: 2 | config_dir: /usr/share/filebeat/conf.d 3 | 4 | output.logstash: 5 | hosts: 6 | - ${LOGSTASH_HOST} 7 | loadbalance: true 8 | ssl: 9 | enabled: true 10 | worker: 2 11 | -------------------------------------------------------------------------------- /config/filebeat/nginx.yml: -------------------------------------------------------------------------------- 1 | filebeat.prospectors: 2 | - type: log 3 | enabled: true 4 | paths: 5 | - /var/log/rails/nginx/*.log 6 | fields: 7 | type: nginx-access 8 | app_id: single-cell-portal 9 | fields_under_root: true 10 | encoding: utf-8 11 | exclude_files: [".gz"] -------------------------------------------------------------------------------- /config/filebeat/rails.yml: -------------------------------------------------------------------------------- 1 | filebeat.prospectors: 2 | - type: log 3 | enabled: true 4 | paths: 5 | - /var/log/rails/${PASSENGER_APP_ENV}.log 6 | fields: 7 | type: rails 8 | app_id: single-cell-portal 9 | fields_under_root: true 10 | include_lines: 11 | encoding: utf-8 12 | multiline: 13 | pattern: '.*Started (GET|POST|PUT|PATCH|OPTIONS|HEAD|DELETE)' 14 | negate: true 15 | match: after 16 | tail_files: false -------------------------------------------------------------------------------- /config/initializers/application_controller_renderer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # ActiveSupport::Reloader.to_prepare do 4 | # ApplicationController.renderer.defaults.merge!( 5 | # http_host: 'example.org', 6 | # https: false 7 | # ) 8 | # end 9 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| /my_noisy_library/.match?(line) } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code 7 | # by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'". 8 | Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"] 9 | -------------------------------------------------------------------------------- /config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Specify a serializer for the signed and encrypted cookie jars. 4 | # Valid options are :json, :marshal, and :hybrid. 5 | Rails.application.config.action_dispatch.cookies_serializer = :json 6 | -------------------------------------------------------------------------------- /config/initializers/delayed_job_config.rb: -------------------------------------------------------------------------------- 1 | Delayed::Worker.destroy_failed_jobs = true 2 | Delayed::Worker.max_attempts = 1 3 | Delayed::Worker.max_run_time = 24.hours 4 | Delayed::Worker.read_ahead = 10 5 | Delayed::Worker.logger = Logger.new(File.join(Rails.root, 'log', "delayed_job.#{Rails.env}.log")) 6 | Delayed::Worker.default_queue_name = :default 7 | 8 | if Rails.env.test? || Rails.env.development? # save a little time in testing/dev 9 | Delayed::Worker.sleep_delay = 5 # seconds 10 | end 11 | -------------------------------------------------------------------------------- /config/initializers/field_with_errors.rb: -------------------------------------------------------------------------------- 1 | ActionView::Base.field_error_proc = Proc.new do |html_tag, instance| 2 | html = %(#{html_tag}).html_safe 3 | # add nokogiri gem to Gemfile 4 | 5 | form_fields = %w(textarea input select) 6 | 7 | elements = Nokogiri::HTML::DocumentFragment.parse(html_tag).css "label, " + form_fields.join(', ') 8 | 9 | elements.each do |e| 10 | if form_fields.include? e.node_name 11 | html = %(
#{html_tag}
).html_safe 12 | end 13 | end 14 | html 15 | end -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | # update: only filter values that end with _key to preserve things like obsm_key-name, which is not a secret 5 | Rails.application.config.filter_parameters += [ 6 | :password, :passw, :secret, :token, /_key$/, :crypt, :salt, :certificate, :otp, :ssn 7 | ] 8 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /config/initializers/minitest_rails.rb: -------------------------------------------------------------------------------- 1 | # https://github.com/rails/rails/issues/31324 2 | if ActionPack::VERSION::STRING >= "5.2.0" 3 | Minitest::Rails::TestUnit = Rails::TestUnit 4 | end -------------------------------------------------------------------------------- /config/initializers/mongoid_encrypted_fields.rb: -------------------------------------------------------------------------------- 1 | # configure AES encryption for user refresh tokens 2 | Mongoid::EncryptedFields.cipher = Gibberish::AES.new(ENV['SECRET_KEY_BASE']) -------------------------------------------------------------------------------- /config/initializers/mongoid_history.rb: -------------------------------------------------------------------------------- 1 | # initializer for mongoid-history 2 | # per the documentation this declaration is optional, 3 | # but https://github.com/mongoid/mongoid-history/issues/192 indicates it's not 4 | Mongoid::History.tracker_class_name = :history_tracker 5 | -------------------------------------------------------------------------------- /config/initializers/permissions_policy.rb: -------------------------------------------------------------------------------- 1 | # Define an application-wide HTTP permissions policy. For further 2 | # information see https://developers.google.com/web/updates/2018/06/feature-policy 3 | # 4 | # Rails.application.config.permissions_policy do |f| 5 | # f.camera :none 6 | # f.gyroscope :none 7 | # f.microphone :none 8 | # f.usb :none 9 | # f.fullscreen :self 10 | # f.payment :self, "https://secure.example.com" 11 | # end 12 | -------------------------------------------------------------------------------- /config/initializers/secret_key_base.rb: -------------------------------------------------------------------------------- 1 | module Rails 2 | class Application < Engine 3 | def secret_key_base 4 | ENV['SECRET_KEY_BASE'] 5 | end 6 | end 7 | end -------------------------------------------------------------------------------- /config/initializers/sentry.rb: -------------------------------------------------------------------------------- 1 | Sentry.init do |config| 2 | config.dsn = ENV['SENTRY_DSN'] 3 | # Add data like request headers and IP for users, if applicable; 4 | # see https://docs.sentry.io/platforms/ruby/data-management/data-collected/ for more info 5 | config.send_default_pii = true 6 | end 7 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.session_store :cookie_store, key: "_single_cell_portal_session" -------------------------------------------------------------------------------- /config/initializers/will_paginate.rb: -------------------------------------------------------------------------------- 1 | require 'will_paginate/array' 2 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] 9 | end 10 | -------------------------------------------------------------------------------- /config/secrets/.keep_this: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/config/secrets/.keep_this -------------------------------------------------------------------------------- /config/spring.rb: -------------------------------------------------------------------------------- 1 | %w[ 2 | .ruby-version 3 | .rbenv-vars 4 | tmp/restart.txt 5 | tmp/caching-dev.txt 6 | ].each { |path| Spring.watch(path) } 7 | -------------------------------------------------------------------------------- /config/vite.json: -------------------------------------------------------------------------------- 1 | { 2 | "all": { 3 | "sourceCodeDir": "app/javascript", 4 | "entrypointsDir": "vite", 5 | "watchAdditionalPaths": [] 6 | }, 7 | "development": { 8 | "autoBuild": true, 9 | "publicOutputDir": "vite-dev", 10 | "port": 3036, 11 | "host": "127.0.0.1", 12 | "devServerConnectTimeout": 1.0 13 | }, 14 | "test": { 15 | "autoBuild": true, 16 | "publicOutputDir": "vite-test", 17 | "port": 3037 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /db/migrate/20171108152921_set_admin_email_delivery_for_users.rb: -------------------------------------------------------------------------------- 1 | # set profile option for admin email delivery (opt-in/out for getting emails from administrators) 2 | class SetAdminEmailDeliveryForUsers < Mongoid::Migration 3 | def self.up 4 | User.update_all(admin_email_delivery: true) 5 | end 6 | 7 | def self.down 8 | User.all.unset(:admin_email_delivery) 9 | end 10 | end -------------------------------------------------------------------------------- /db/migrate/20171108152939_set_deliver_emails_and_firecloud_project_for_study_shares.rb: -------------------------------------------------------------------------------- 1 | # set default firecloud project for all study shares and deliver_emails flag 2 | class SetDeliverEmailsAndFirecloudProjectForStudyShares < Mongoid::Migration 3 | def self.up 4 | StudyShare.all.each do |share| 5 | project = share.study.firecloud_project 6 | share.update!(firecloud_project: project, deliver_emails: true) 7 | end 8 | end 9 | 10 | def self.down 11 | StudyShare.all.unset(:deliver_emails) 12 | StudyShare.all.unset(:firecloud_project) 13 | end 14 | end -------------------------------------------------------------------------------- /db/migrate/20171108152947_set_deliver_emails_for_studies.rb: -------------------------------------------------------------------------------- 1 | # set default deliver emails flag for studies 2 | class SetDeliverEmailsForStudies < Mongoid::Migration 3 | def self.up 4 | Study.all.each do |study| 5 | opts = study.default_options 6 | study.update!(default_options: opts.merge(deliver_emails: true)) 7 | end 8 | end 9 | 10 | def self.down 11 | Study.all.each do |study| 12 | opts = study.default_options 13 | opts.delete(:deliver_emails) 14 | study.update!(default_options: opts) 15 | end 16 | end 17 | end -------------------------------------------------------------------------------- /db/migrate/20180130203907_create_genes_and_cell_metadata.rb: -------------------------------------------------------------------------------- 1 | class CreateGenesAndCellMetadata < Mongoid::Migration 2 | def self.up 3 | ClusterGroup.delay.generate_new_data_arrays 4 | # Gene.delay.generate_new_entries 5 | CellMetadatum.delay.generate_new_entries 6 | end 7 | 8 | def self.down 9 | Gene.delete_all 10 | CellMetadatum.delete_all 11 | DataArray.where(:linear_data_type.in => %w(Gene CellMetadatum ClusterGroup Study)).delete_all 12 | end 13 | end -------------------------------------------------------------------------------- /db/migrate/20180806192849_set_gene_id_on_genes.rb: -------------------------------------------------------------------------------- 1 | class SetGeneIdOnGenes < Mongoid::Migration 2 | def self.up 3 | Gene.delay.add_gene_ids_to_genes # done as a background process to boot portal faster 4 | end 5 | 6 | def self.down 7 | Gene.delay.remove_gene_ids_from_genes 8 | end 9 | end -------------------------------------------------------------------------------- /db/migrate/20181004151831_auto_populate_species_info.rb: -------------------------------------------------------------------------------- 1 | class AutoPopulateSpeciesInfo < Mongoid::Migration 2 | def self.up 3 | admin_user = User.where(admin: true).first 4 | path = Rails.root.join('lib', 'assets', 'default_species_assemblies.txt') 5 | if File.exist?(path) && admin_user.present? 6 | Taxon.parse_from_file(path, admin_user) 7 | end 8 | end 9 | 10 | def self.down 11 | Taxon.destroy_all 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /db/migrate/20190301175359_assign_accessions_to_studies.rb: -------------------------------------------------------------------------------- 1 | class AssignAccessionsToStudies < Mongoid::Migration 2 | def self.up 3 | StudyAccession.assign_accessions 4 | end 5 | 6 | def self.down 7 | Study.update_all(accession: nil) 8 | StudyAccession.destroy_all 9 | end 10 | end -------------------------------------------------------------------------------- /db/migrate/20190522190416_set_source_resolution_for_user_annotations.rb: -------------------------------------------------------------------------------- 1 | class SetSourceResolutionForUserAnnotations < Mongoid::Migration 2 | def self.up 3 | UserAnnotation.each do |annot| 4 | resolution = annot.subsampled_at 5 | if resolution == 'All Cells' 6 | annot.update(source_resolution: nil) 7 | else 8 | annot.update(source_resolution: resolution.to_i) 9 | end 10 | end 11 | end 12 | 13 | def self.down 14 | UserAnnotation.all.each {|annot| annot.unset(:source_resolution)} 15 | end 16 | end -------------------------------------------------------------------------------- /db/migrate/20200103191405_set_subsampled_on_clusters.rb: -------------------------------------------------------------------------------- 1 | class SetSubsampledOnClusters < Mongoid::Migration 2 | def self.up 3 | ClusterGroup.all.each do |cluster| 4 | if cluster.points > 1000 5 | cluster.update(subsampled: true) 6 | end 7 | end 8 | end 9 | 10 | def self.down 11 | ClusterGroup.all.each do |cluster| 12 | cluster.remove_attribute(:subsampled) 13 | end 14 | end 15 | end -------------------------------------------------------------------------------- /db/migrate/20200213205538_add_initial_facets.rb: -------------------------------------------------------------------------------- 1 | class AddInitialFacets < Mongoid::Migration 2 | def self.up 3 | SearchFacetPopulator.populate_from_schema 4 | end 5 | 6 | def self.down 7 | SearchFacet.destroy_all 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20200218194644_add_schema_facets.rb: -------------------------------------------------------------------------------- 1 | class AddSchemaFacets < Mongoid::Migration 2 | def self.up 3 | SearchFacet.destroy_all 4 | SearchFacetPopulator.populate_from_schema 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/migrate/20200413161403_add_biosample_type_and_preservation_method_to_bq.rb: -------------------------------------------------------------------------------- 1 | class AddBiosampleTypeAndPreservationMethodToBq < Mongoid::Migration 2 | def self.up 3 | client = BigQueryClient.new.client 4 | [CellMetadatum::BIGQUERY_DATASET, 'cell_metadata_test'].each do |dataset_name| 5 | dataset = client.dataset(dataset_name) 6 | if dataset.present? # ensure test dataset exists to avoid migration failure 7 | table = dataset.table(CellMetadatum::BIGQUERY_TABLE) 8 | table.schema {|s| s.string('biosample_type', mode: :nullable)} 9 | table.schema {|s| s.string('preservation_method', mode: :nullable)} 10 | end 11 | end 12 | end 13 | 14 | def self.down 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /db/migrate/20200513190742_backup_user_assets.rb: -------------------------------------------------------------------------------- 1 | class BackupUserAssets < Mongoid::Migration 2 | def self.up 3 | UserAssetService.push_assets_to_remote 4 | end 5 | 6 | def self.down 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /db/migrate/20200716191055_set_visible_on_search_facets.rb: -------------------------------------------------------------------------------- 1 | class SetVisibleOnSearchFacets < Mongoid::Migration 2 | def self.up 3 | SearchFacet.update_all(visible: true) 4 | end 5 | 6 | def self.down 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /db/migrate/20200720175116_create_synthetic_branding_groups.rb: -------------------------------------------------------------------------------- 1 | class CreateSyntheticBrandingGroups < Mongoid::Migration 2 | def self.up 3 | unless Rails.env.production? 4 | SyntheticBrandingGroupPopulator.populate_all 5 | end 6 | end 7 | 8 | def self.down 9 | unless Rails.env.production? 10 | SyntheticBrandingGroupPopulator.remove_all 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /db/migrate/20200723152531_update_facet_links.rb: -------------------------------------------------------------------------------- 1 | class UpdateFacetLinks < Mongoid::Migration 2 | def self.up 3 | SearchFacetPopulator.populate_from_schema 4 | end 5 | 6 | def self.down 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /db/migrate/20200925192339_update_coord_label_file_opts.rb: -------------------------------------------------------------------------------- 1 | class UpdateCoordLabelFileOpts < Mongoid::Migration 2 | def self.up 3 | StudyFile.where(file_type: 'Coordinate Labels').each do |file| 4 | cluster_id = file.options['cluster_group_id'] 5 | if cluster_id.present? 6 | cluster = ClusterGroup.find(cluster_id) 7 | file.options['cluster_file_id'] = cluster.study_file_id.to_s 8 | file.save! 9 | end 10 | end 11 | end 12 | 13 | def self.down 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /db/migrate/20201021141827_clear_old_totats.rb: -------------------------------------------------------------------------------- 1 | class ClearOldTotats < Mongoid::Migration 2 | # mirror of FeatureFlag.rb, so this migration won't error if that class is renamed/altered 3 | class UserMigrator 4 | include Mongoid::Document 5 | store_in collection: 'users' 6 | field :totat_t_ti, type: String 7 | field :totat 8 | end 9 | 10 | def self.up 11 | UserMigrator.where(:totat.exists => true).each do |user| 12 | user.update(totat: nil, totat_t_ti: nil) 13 | end 14 | end 15 | 16 | def self.down 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /db/migrate/20210318125925_remove_spatial_flag2.rb: -------------------------------------------------------------------------------- 1 | class RemoveSpatialFlag2 < Mongoid::Migration 2 | def self.up 3 | FeatureFlaggable.remove_flag_from_model(User, 'spatial_transcriptomics') 4 | FeatureFlaggable.remove_flag_from_model(BrandingGroup, 'spatial_transcriptomics') 5 | end 6 | 7 | def self.down 8 | # we're not remembering which users had this feature, so there's no way to undo 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20210326153355_add_points_to_cluster_groups.rb: -------------------------------------------------------------------------------- 1 | class AddPointsToClusterGroups < Mongoid::Migration 2 | def self.up 3 | # run in background to prevent delays on starting server after deployment 4 | ClusterGroup.delay.set_all_point_counts! 5 | end 6 | 7 | def self.down 8 | ClusterGroup.all.each {|cluster| cluster.unset(:points) } 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20210329171940_clear_user_auth_tokens.rb: -------------------------------------------------------------------------------- 1 | class ClearUserAuthTokens < Mongoid::Migration 2 | def self.up 3 | # clear user tokens one last time in preparation for storing refresh tokens indefinitely 4 | User.update_all(refresh_token: nil, access_token: nil, api_access_token: nil) 5 | end 6 | 7 | def self.down 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20210415145652_remove_authentication_token_from_users.rb: -------------------------------------------------------------------------------- 1 | class RemoveAuthenticationTokenFromUsers < Mongoid::Migration 2 | def self.up 3 | User.all.each {|user| user.unset(:authentication_token)} 4 | end 5 | 6 | def self.down 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /db/migrate/20210506205225_cache_all_study_defaults.rb: -------------------------------------------------------------------------------- 1 | class CacheAllStudyDefaults < Mongoid::Migration 2 | def self.up 3 | ClusterCacheService.delay(queue: :cache).cache_all_defaults 4 | end 5 | 6 | def self.down 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /db/migrate/20210512162401_rename_preset_search_fields.rb: -------------------------------------------------------------------------------- 1 | class RenamePresetSearchFields < Mongoid::Migration 2 | def self.up 3 | PresetSearch.all.each do |search| 4 | search.rename(accession_whitelist: :accession_list) 5 | end 6 | end 7 | 8 | def self.down 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20210712154710_update_public_facet_filters.rb: -------------------------------------------------------------------------------- 1 | class UpdatePublicFacetFilters < Mongoid::Migration 2 | def self.up 3 | SearchFacet.update_all_facet_filters 4 | end 5 | 6 | def self.down 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /db/migrate/20210907141202_remove_react_explore_feature_flag.rb: -------------------------------------------------------------------------------- 1 | class RemoveReactExploreFeatureFlag < Mongoid::Migration 2 | def self.up 3 | FeatureFlag.retire_feature_flag('react_explore') 4 | end 5 | 6 | def self.down 7 | FeatureFlag.create!(name: 'react_explore', 8 | default_value: false, 9 | description: 'whether the explore tab should use the new React functionality') 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20210908154924_remove_faceted_search_feature_flag.rb: -------------------------------------------------------------------------------- 1 | class RemoveFacetedSearchFeatureFlag < Mongoid::Migration 2 | def self.up 3 | FeatureFlag.retire_feature_flag('faceted_search') 4 | end 5 | 6 | def self.down 7 | FeatureFlag.create!(name: 'faceted_search', 8 | default_value: false, 9 | description: 'whether to show the facet controls in the advanced search') 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20211015144933_create_feature_flag_options.rb: -------------------------------------------------------------------------------- 1 | class CreateFeatureFlagOptions < Mongoid::Migration 2 | def self.up 3 | [User, BrandingGroup].each do |model| 4 | model.all.each do |instance| 5 | instance.feature_flags.each do |flag_name, flag_value| 6 | feature_flag = FeatureFlag.find_by(name: flag_name) 7 | next if feature_flag.nil? 8 | 9 | flag_option = instance.feature_flag_options.build(feature_flag: feature_flag, value: flag_value) 10 | flag_option.save! 11 | end 12 | end 13 | end 14 | end 15 | 16 | def self.down 17 | FeatureFlagOption.delete_all 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /db/migrate/20211029175055_add_azul_facet_filters_to_search_facets.rb: -------------------------------------------------------------------------------- 1 | class AddAzulFacetFiltersToSearchFacets < Mongoid::Migration 2 | def self.up 3 | SearchFacet.update_all_facet_filters 4 | end 5 | 6 | def self.down 7 | # calling :update_filter_values! w/o passing in external Azul results will revert back to BigQuery only 8 | SearchFacet.all.map(&:update_filter_values!) 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20220127212642_color_picker_cache_clear.rb: -------------------------------------------------------------------------------- 1 | class ColorPickerCacheClear < Mongoid::Migration 2 | def self.up 3 | # clear the cache since this makes changes to the clusters API signature -- editing colors cannot work if the cluster 4 | # file id is not included in the response 5 | Rails.cache.clear 6 | end 7 | 8 | def self.down 9 | end 10 | end -------------------------------------------------------------------------------- /db/migrate/20220216160604_remove_upload_wizard_feature_flag.rb: -------------------------------------------------------------------------------- 1 | class RemoveUploadWizardFeatureFlag < Mongoid::Migration 2 | def self.up 3 | FeatureFlag.retire_feature_flag('react_upload_wizard') 4 | end 5 | 6 | def self.down 7 | FeatureFlag.create!(name: 'react_upload_wizard', 8 | default_value: false, 9 | description: 'show the react upload wizard component') 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20220401103323_encode_azul_files_names.rb: -------------------------------------------------------------------------------- 1 | class EncodeAzulFilesNames < Mongoid::Migration 2 | def self.up 3 | download_reqs = DownloadRequest.where(:azul_files.ne => nil) 4 | download_reqs.each do |req| 5 | encoded_azul_files = ActiveSupport::JSON.encode(req.azul_files) 6 | req.update(azul_files: encoded_azul_files) 7 | end 8 | end 9 | 10 | def self.down 11 | download_reqs = DownloadRequest.where(:azul_files.ne => nil) 12 | download_reqs.each do |req| 13 | azul_files_as_hash = ActiveSupport::JSON.decode(req.azul_files.gsub('=>', ':')) 14 | req.update(azul_files: azul_files_as_hash) 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /db/migrate/20220505130728_add_differential_expression_frontend_feature_flag.rb: -------------------------------------------------------------------------------- 1 | class AddDifferentialExpressionFrontendFeatureFlag < Mongoid::Migration 2 | def self.up 3 | FeatureFlag.create!(name: 'differential_expression_frontend', 4 | default_value: false, 5 | description: 'Whether DE UX is enabled') 6 | end 7 | 8 | def self.down 9 | FeatureFlagMigrator.find_by(name: 'differential_expression_frontend').destroy 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20220616194822_set_de_computational_method.rb: -------------------------------------------------------------------------------- 1 | class SetDeComputationalMethod < Mongoid::Migration 2 | def self.up 3 | DifferentialExpressionResult.update_all(computational_method: 'wilcoxon') 4 | end 5 | 6 | def self.down 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /db/migrate/20220621202722_set_matrix_file_id_on_differential_expression_results.rb: -------------------------------------------------------------------------------- 1 | class SetMatrixFileIdOnDifferentialExpressionResults < Mongoid::Migration 2 | def self.up 3 | DifferentialExpressionResult.all.each do |result| 4 | matrix = ClusterVizService.raw_matrix_for_cluster_cells(result.study, result.cluster_group) 5 | result.update!(matrix_file_id: matrix.id) 6 | end 7 | end 8 | 9 | def self.down 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20220804164813_add_progressive_loading_flag.rb: -------------------------------------------------------------------------------- 1 | class AddProgressiveLoadingFlag < Mongoid::Migration 2 | def self.up 3 | FeatureFlag.create!(name: 'progressive_loading', 4 | default_value: false, 5 | description: 'enable loading expression scatter plots as static image first, then interactive') 6 | end 7 | 8 | def self.down 9 | FeatureFlag.find_by(name: 'progressive_loading').destroy 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20220914121854_add_legend_search_flag.rb: -------------------------------------------------------------------------------- 1 | class AddLegendSearchFlag < Mongoid::Migration 2 | def self.up 3 | FeatureFlag.create!(name: 'legend_search', 4 | default_value: false, 5 | description: 'enable legend search') 6 | end 7 | 8 | def self.down 9 | FeatureFlag.find_by(name: 'legend_search').destroy 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20221006124530_retire_anndata_and_seurat_feature_flag.rb: -------------------------------------------------------------------------------- 1 | class RetireAnndataAndSeuratFeatureFlag < Mongoid::Migration 2 | def self.up 3 | FeatureFlag.retire_feature_flag('upload_seurat_and_anndata') 4 | end 5 | 6 | def self.down 7 | FeatureFlag.create!(name: 'upload_seurat_and_anndata', 8 | default_value: false, 9 | description: 'allow AnnData and seurat file uploads in the upload wizard') 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20221006132730_update_misc_file_type_for_anndata_and_seurat.rb: -------------------------------------------------------------------------------- 1 | class UpdateMiscFileTypeForAnndataAndSeurat < Mongoid::Migration 2 | def self.up 3 | # For AnnData 4 | StudyFile.where(:file_type.in => ['Other', 'Documentation', 'Analysis Output'], upload_file_name: /\.(h5ad|h5)$/).update_all(file_type: 'AnnData') 5 | 6 | # For Seurat 7 | StudyFile.where(:file_type.in => ['Documentation', 'Other', 'Analysis Output'], upload_file_name: /\.(rda|Rda|rds|Rds|Rdata$)/).update_all(file_type: 'Seurat') 8 | 9 | end 10 | 11 | def self.down 12 | # intentially left blank 13 | end 14 | end -------------------------------------------------------------------------------- /db/migrate/20221026145120_update_missed_file_type_for_seurat.rb: -------------------------------------------------------------------------------- 1 | class UpdateMissedFileTypeForSeurat < Mongoid::Migration 2 | def self.up 3 | 4 | # Missed migrating .RDS in the first migration so fixing that here 5 | StudyFile.where(:file_type.in => ['Documentation', 'Other', 'Analysis Output'], upload_file_name: /\.(RDS$)/).update_all(file_type: 'Seurat') 6 | 7 | end 8 | 9 | def self.down 10 | # intentially left blank 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /db/migrate/20230215152445_add_feature_flag_for_explore_tab_ab_test.rb: -------------------------------------------------------------------------------- 1 | class AddFeatureFlagForExploreTabAbTest < Mongoid::Migration 2 | def self.up 3 | FeatureFlag.create!(name: 'explore_tab_default', 4 | default_value: false, 5 | description: 'show the explore tab in study overview by default') 6 | end 7 | 8 | def self.down 9 | FeatureFlag.find_by(name: 'explore_tab_default')&.destroy 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20230411182505_rename_observed_values.rb: -------------------------------------------------------------------------------- 1 | class RenameObservedValues < Mongoid::Migration 2 | def self.up 3 | DifferentialExpressionResult.all.each do |result| 4 | result.rename(observed_values: :one_vs_rest_comparisons) 5 | end 6 | end 7 | 8 | def self.down 9 | DifferentialExpressionResult.all.each do |result| 10 | result.rename(one_vs_rest_comparisons: :observed_values) 11 | end 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /db/migrate/20230510115847_add_flag_for_explore_tab_ux_updates.rb: -------------------------------------------------------------------------------- 1 | class AddFlagForExploreTabUxUpdates < Mongoid::Migration 2 | def self.up 3 | FeatureFlag.create!(name: 'show_explore_tab_ux_updates', 4 | default_value: false, 5 | description: 'show the "Update the Explore Tab" epic changes') 6 | end 7 | 8 | def self.down 9 | FeatureFlag.find_by(name: 'show_explore_tab_ux_updates')&.destroy 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20230510164721_retire_explore_tab_default_feature_flag.rb: -------------------------------------------------------------------------------- 1 | class RetireExploreTabDefaultFeatureFlag < Mongoid::Migration 2 | def self.up 3 | FeatureFlag.retire_feature_flag('explore_tab_default') 4 | end 5 | 6 | def self.down 7 | FeatureFlag.create!(name: 'explore_tab_default', 8 | default_value: false, 9 | description: 'show the explore tab in study overview by default') 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20230530105311_add_flag_for_user_de_upload.rb: -------------------------------------------------------------------------------- 1 | class AddFlagForUserDeUpload < Mongoid::Migration 2 | def self.up 3 | FeatureFlag.create!(name: 'show_de_upload', 4 | default_value: false, 5 | description: 'show the differential expression upload tab in the upload wizard') 6 | end 7 | 8 | def self.down 9 | FeatureFlag.find_by(name: 'show_de_upload')&.destroy 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20230530160051_retire_reference_image_upload_feature_flag.rb: -------------------------------------------------------------------------------- 1 | class RetireReferenceImageUploadFeatureFlag < Mongoid::Migration 2 | def self.up 3 | FeatureFlag.retire_feature_flag('reference_image_upload') 4 | end 5 | 6 | def self.down 7 | FeatureFlagMigrator.create!(name: 'reference_image_upload', 8 | default_value: false, 9 | description: 'allow reference image upload in the upload wizard') 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20230531163544_update_image_file_type_to_other.rb: -------------------------------------------------------------------------------- 1 | class UpdateImageFileTypeToOther < Mongoid::Migration 2 | def self.up 3 | 4 | StudyFile.where(:file_type => 'Image').update_all(file_type: 'Other') 5 | 6 | end 7 | 8 | def self.down 9 | # intentially left blank 10 | end 11 | end -------------------------------------------------------------------------------- /db/migrate/20230622173344_retire_show_explore_tab_ux_updates_feature_flag.rb: -------------------------------------------------------------------------------- 1 | class RetireShowExploreTabUxUpdatesFeatureFlag < Mongoid::Migration 2 | def self.up 3 | FeatureFlag.retire_feature_flag('show_explore_tab_ux_updates') 4 | end 5 | 6 | def self.down 7 | FeatureFlag.create!(name: 'show_explore_tab_ux_updates', 8 | default_value: false, 9 | description: 'show the "Update the Explore Tab" epic changes') 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20230907050143_add_flag_for_cell_facet_filtering.rb: -------------------------------------------------------------------------------- 1 | class AddFlagForCellFacetFiltering < Mongoid::Migration 2 | def self.up 3 | FeatureFlag.create!(name: 'show_cell_facet_filtering', 4 | default_value: false, 5 | description: 'show the cell facet filtering button') 6 | end 7 | 8 | def self.down 9 | FeatureFlag.find_by(name: 'show_cell_facet_filtering')&.destroy 10 | end 11 | end -------------------------------------------------------------------------------- /db/migrate/20230913140856_create_show_appcue_viz_tour_feature_flag.rb: -------------------------------------------------------------------------------- 1 | class CreateShowAppcueVizTourFeatureFlag < Mongoid::Migration 2 | def self.up 3 | FeatureFlag.create!(name: 'show_appcue_viz_tour', 4 | default_value: false, 5 | description: "show the 'Take a tour of SCP's visualization tools' Appcue") 6 | end 7 | 8 | def self.down 9 | FeatureFlag.retire_feature_flag('show_appcue_viz_tour') 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20230921192657_retire_appcue_pin_feature_flag.rb: -------------------------------------------------------------------------------- 1 | class RetireAppcuePinFeatureFlag < Mongoid::Migration 2 | def self.up 3 | FeatureFlag.retire_feature_flag('show_appcue_viz_tour') 4 | end 5 | 6 | def self.down 7 | FeatureFlag.create!(name: 'show_appcue_viz_tour', 8 | default_value: false, 9 | description: "show the 'Take a tour of SCP's visualization tools' Appcue") 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20240207162542_add_flag_for_numeric_cell_filtering.rb: -------------------------------------------------------------------------------- 1 | class AddFlagForNumericCellFiltering < Mongoid::Migration 2 | def self.up 3 | FeatureFlag.create!(name: 'show_numeric_cell_filtering', 4 | default_value: false, 5 | description: 'show numeric cell filtering') 6 | end 7 | 8 | def self.down 9 | FeatureFlag.find_by(name: 'show_numeric_cell_filtering')&.destroy 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20240605113800_add_flag_for_igv_multiome.rb: -------------------------------------------------------------------------------- 1 | class AddFlagForIgvMultiome < Mongoid::Migration 2 | def self.up 3 | FeatureFlag.create!(name: 'show_igv_multiome', 4 | default_value: false, 5 | description: 'show features related to IGV multiome') 6 | end 7 | 8 | def self.down 9 | FeatureFlag.find_by(name: 'show_igv_multiome')&.destroy 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20240819173109_sync_exp_file_info_for_ann_data.rb: -------------------------------------------------------------------------------- 1 | class SyncExpFileInfoForAnnData < Mongoid::Migration 2 | def self.up 3 | StudyFile.where(file_type: 'AnnData').each do |study_file| 4 | study_file.ann_data_file_info.update_expression_file_info 5 | end 6 | end 7 | 8 | def self.down 9 | # non-reversible 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20240822072800_add_flag_for_pathway_expression.rb: -------------------------------------------------------------------------------- 1 | class AddFlagForPathwayExpression < Mongoid::Migration 2 | def self.up 3 | FeatureFlag.create!(name: 'show_pathway_expression', 4 | default_value: true, 5 | description: 'show expression overlay in pathway diagrams') 6 | end 7 | 8 | def self.down 9 | FeatureFlag.find_by(name: 'show_pathway_expression')&.destroy 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20241112195205_set_ann_data_expression_label.rb: -------------------------------------------------------------------------------- 1 | class SetAnnDataExpressionLabel < Mongoid::Migration 2 | def self.up 3 | study_files = StudyFile.where(file_type: 'AnnData', 'ann_data_file_info.reference_file' => false) 4 | study_files.each do |study_file| 5 | expression_label = study_file.ann_data_file_info.expression_axis_label 6 | next if expression_label.blank? 7 | 8 | study = study_file.study 9 | Rails.logger.info "Setting expression axis label to #{expression_label} in #{study.accession}" 10 | study.default_options[:expression_label] = expression_label 11 | study.save 12 | end 13 | end 14 | 15 | def self.down 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /db/migrate/20250127092542_add_flag_for_default_pairwise_de_ui.rb: -------------------------------------------------------------------------------- 1 | class AddFlagForDefaultPairwiseDeUi < Mongoid::Migration 2 | def self.up 3 | FeatureFlag.create!(name: 'default_pairwise_de_ui', 4 | default_value: false, 5 | description: 'show pairwise differential expression UI by default') 6 | end 7 | 8 | def self.down 9 | FeatureFlag.retire_feature_flag('default_pairwise_de_ui') 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20250528160832_set_relevant_default_annotations.rb: -------------------------------------------------------------------------------- 1 | class SetRelevantDefaultAnnotations < Mongoid::Migration 2 | def self.up 3 | accessions = Study.where(queued_for_deletion: false).pluck(:accession) 4 | accessions.each do |accession| 5 | study = Study.find_by(accession:) 6 | begin 7 | ClusterCacheService.configure_default_annotation(study) 8 | rescue => e 9 | ErrorTracker.report_exception(e, nil,{ study: }) 10 | end 11 | end 12 | end 13 | 14 | def self.down 15 | # default annotations can be reset manually if needed 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /db/seed/synthetic_branding_groups/human_group/branding_group_info.json: -------------------------------------------------------------------------------- 1 | { 2 | "branding_group": { 3 | "name" : "Human Research Group", 4 | "tag_line": "Synthetic branding group containing only human synthetic studies", 5 | "background_color": "lightgray", 6 | "facet_list": ["organ", "disease"], 7 | "external_link_url": "https://en.wikipedia.org/wiki/Human", 8 | "external_link_description": "Human wiki" 9 | }, 10 | "images": { 11 | "splash_image": "SCP-logo-invert.png" 12 | }, 13 | "study_title_regex": "human" 14 | } 15 | -------------------------------------------------------------------------------- /db/seed/synthetic_branding_groups/mouse_group/branding_group_info.json: -------------------------------------------------------------------------------- 1 | { 2 | "branding_group": { 3 | "name" : "Mouse Research Group", 4 | "tag_line": "Synthetic branding group containing only mouse synthetic studies", 5 | "background_color": "lightblue", 6 | "facet_list": ["species", "sex"] 7 | }, 8 | "images": { 9 | "splash_image": "SCP-logo-invert.png" 10 | }, 11 | "study_title_regex": "(mouse|murine)" 12 | } 13 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_overplot/letters_overplot.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -4 2 4 | AB -4 3 5 | AC -4 4 6 | AD -4 5 7 | AE -3 6 8 | AF -2 5 9 | AG -2 4 10 | AH -2 3 11 | AI -2 2 12 | AJ -3 4 13 | BA 2 2 14 | BB 2 3 15 | BC 2 4 16 | BD 2 5 17 | BE 2 6 18 | BF 3 6 19 | BG 4 5 20 | BH 3 4 21 | BI 4 3 22 | BJ 3 2 23 | CA -4 -6 24 | CB -4 -5 25 | CC -4 -4 26 | CD -4 -3 27 | CE -4 -2 28 | CF -3 -2 29 | CG -2 -2 30 | CH -2 -3 31 | CI -2 -6 32 | CJ -3 -6 33 | DA -4 2 34 | DB -4 3 35 | DC -4 4 36 | DD -4 5 37 | DE -3 6 38 | DF -2 5 39 | DG -2 4 40 | DH -2 3 41 | DI -2 2 42 | DJ -3 4 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/README.txt: -------------------------------------------------------------------------------- 1 | This synthetic raw counts dataset provides quick visual feedback for expected visualizations 2 | Synthetic gene "foo" shows a "gradient" of gene expression 3 | Synthetic gene "bar" gene expression is pinned for each cluster 4 | 5 | Reference screenshots of expected visualizations can be found at: 6 | https://github.com/broadinstitute/single_cell_portal_core/pull/772 7 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/cluster_square.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -2 5 4 | AB -1 5 5 | AC -0 5 6 | AD 1 5 7 | AE 2 5 8 | AF -2 4 9 | AG -1 4 10 | AH 0 4 11 | AI 1 4 12 | AJ 2 4 13 | BA -2 3 14 | BB -1 3 15 | BC 0 3 16 | BD 1 3 17 | BE 2 3 18 | BF -2 2 19 | BG -1 2 20 | BH 0 2 21 | BI 1 2 22 | BJ 2 2 23 | CA -2 1 24 | CB -1 1 25 | CC 0 1 26 | CD 1 1 27 | CE 2 1 28 | CF -2 0 29 | CG -1 0 30 | CH 0 0 31 | CI 1 0 32 | CJ 2 0 33 | DA -2 1 34 | DB -1 1 35 | DC 0 1 36 | DD 1 1 37 | DE 2 1 38 | DF -2 2 39 | DG -1 2 40 | DH 0 2 41 | DI 1 2 42 | DJ 2 2 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/raw2_chicken_40_cells_4_genes.cluster.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -2 3 4 | AB -3 2 5 | AC -3 3 6 | AD -4 4 7 | AE -5 5 8 | AF -4 3 9 | AG -2 2 10 | AH -2 1 11 | AI -1 2 12 | AJ -1 1 13 | BA 1 2 14 | BB 2 2 15 | BC 2 3 16 | BD 3 4 17 | BE 5 5 18 | BF 4 4 19 | BG 3 3 20 | BH 3 2 21 | BI 1 1 22 | BJ 2 1 23 | CA -2 -3 24 | CB -1 -1 25 | CC -2 -2 26 | CD -3 -4 27 | CE -5 -5 28 | CF -4 -4 29 | CG -3 -3 30 | CH -3 -2 31 | CI -1 -2 32 | CJ -2 -1 33 | DA 3 -2 34 | DB 2 -3 35 | DC 2 -2 36 | DD 4 -3 37 | DE 5 -5 38 | DF 4 -4 39 | DG 3 -3 40 | DH 1 -1 41 | DI 1 -2 42 | DJ 2 -1 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/raw2_chicken_40_cells_4_genes.raw_dense.txt: -------------------------------------------------------------------------------- 1 | AA AB AC AD AE AF AG AH AI AJ BA BB BC BD BE BF BG BH BI BJ CA CB CC CD CE CF CG CH CI CJ DA DB DC DD DE DF DG DH DI DJ 2 | Foo 1 2 3 4 5 4 3 2 1 3 1 2 3 4 5 5 4 3 2 1 1 2 3 4 5 5 5 4 1 1 1 2 3 4 5 5 4 3 2 1 3 | Bar 2 2 2 2 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 4 4 4 4 4 4 4 4 4 4 5 5 5 5 5 5 5 5 5 5 4 | Baz 3 3 2 1 1 2 3 4 4 5 4 4 3 2 1 1 2 3 5 5 4 5 4 2 1 1 2 3 5 5 3 3 4 2 1 1 2 5 5 4 5 | Qux 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 5 6 | RAD51 6 7 8 9 0 0 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 6 7 | DMC1 7 6 5 4 0 0 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 7 8 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/raw2_chicken_40_cells_4_genes.spatial.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -4 2 4 | AB -4 3 5 | AC -4 4 6 | AD -4 5 7 | AE -3 6 8 | AF -2 5 9 | AG -2 4 10 | AH -2 3 11 | AI -2 2 12 | AJ -3 4 13 | BA 2 2 14 | BB 2 3 15 | BC 2 4 16 | BD 2 5 17 | BE 2 6 18 | BF 3 6 19 | BG 4 5 20 | BH 3 4 21 | BI 4 3 22 | BJ 3 2 23 | CA -4 -6 24 | CB -4 -5 25 | CC -4 -4 26 | CD -4 -3 27 | CE -4 -2 28 | CF -3 -2 29 | CG -2 -2 30 | CH -2 -3 31 | CI -2 -6 32 | CJ -3 -6 33 | DA 2 -6 34 | DB 2 -5 35 | DC 2 -4 36 | DD 2 -3 37 | DE 2 -2 38 | DF 3 -2 39 | DG 4 -3 40 | DH 4 -4 41 | DI 4 -5 42 | DJ 3 -6 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/spatial_square.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -3 3 4 | AB -2 3 5 | AC -1 3 6 | AD 1 3 7 | AE 2 3 8 | AF 3 3 9 | AG 3 2 10 | AH 2 2 11 | AI 1 2 12 | AJ -1 2 13 | BA -2 2 14 | BB -3 2 15 | BC -3 1 16 | BD -2 1 17 | BE -1 1 18 | BF 1 1 19 | BG 2 1 20 | BH 3 1 21 | BI 3 -1 22 | BJ 2 -1 23 | CA 1 -1 24 | CB -1 -1 25 | CC -2 -1 26 | CD -3 -1 27 | CE -3 -2 28 | CF -2 -2 29 | CG -1 -2 30 | CH 1 -2 31 | CI 2 -2 32 | CJ 3 -2 33 | DA 3 -3 34 | DB 2 -3 35 | DC 1 -3 36 | DD -1 -3 37 | DE -2 -3 38 | DF -3 -3 39 | DG -2 0 40 | DH -1 0 41 | DI 1 0 42 | DJ 2 0 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/spatial_square_10.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -3 3 4 | AB -2 3 5 | AC -1 3 6 | AD 1 3 7 | AE 2 3 8 | AF 3 3 9 | AG 3 2 10 | AH 2 2 11 | AI 1 2 12 | AJ -1 2 13 | BA -2 2 14 | BB -3 2 15 | BC -3 1 16 | BD -2 1 17 | BE -1 1 18 | BF 1 1 19 | BG 2 1 20 | BH 3 1 21 | BI 3 -1 22 | BJ 2 -1 23 | CA 1 -1 24 | CB -1 -1 25 | CC -2 -1 26 | CD -3 -1 27 | CE -3 -2 28 | CF -2 -2 29 | CG -1 -2 30 | CH 1 -2 31 | CI 2 -2 32 | CJ 3 -2 33 | DA 3 -3 34 | DB 2 -3 35 | DC 1 -3 36 | DD -1 -3 37 | DE -2 -3 38 | DF -3 -3 39 | DG -2 0 40 | DH -1 0 41 | DI 1 0 42 | DJ 2 0 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/spatial_square_11.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -3 3 4 | AB -2 3 5 | AC -1 3 6 | AD 1 3 7 | AE 2 3 8 | AF 3 3 9 | AG 3 2 10 | AH 2 2 11 | AI 1 2 12 | AJ -1 2 13 | BA -2 2 14 | BB -3 2 15 | BC -3 1 16 | BD -2 1 17 | BE -1 1 18 | BF 1 1 19 | BG 2 1 20 | BH 3 1 21 | BI 3 -1 22 | BJ 2 -1 23 | CA 1 -1 24 | CB -1 -1 25 | CC -2 -1 26 | CD -3 -1 27 | CE -3 -2 28 | CF -2 -2 29 | CG -1 -2 30 | CH 1 -2 31 | CI 2 -2 32 | CJ 3 -2 33 | DA 3 -3 34 | DB 2 -3 35 | DC 1 -3 36 | DD -1 -3 37 | DE -2 -3 38 | DF -3 -3 39 | DG -2 0 40 | DH -1 0 41 | DI 1 0 42 | DJ 2 0 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/spatial_square_12.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -3 3 4 | AB -2 3 5 | AC -1 3 6 | AD 1 3 7 | AE 2 3 8 | AF 3 3 9 | AG 3 2 10 | AH 2 2 11 | AI 1 2 12 | AJ -1 2 13 | BA -2 2 14 | BB -3 2 15 | BC -3 1 16 | BD -2 1 17 | BE -1 1 18 | BF 1 1 19 | BG 2 1 20 | BH 3 1 21 | BI 3 -1 22 | BJ 2 -1 23 | CA 1 -1 24 | CB -1 -1 25 | CC -2 -1 26 | CD -3 -1 27 | CE -3 -2 28 | CF -2 -2 29 | CG -1 -2 30 | CH 1 -2 31 | CI 2 -2 32 | CJ 3 -2 33 | DA 3 -3 34 | DB 2 -3 35 | DC 1 -3 36 | DD -1 -3 37 | DE -2 -3 38 | DF -3 -3 39 | DG -2 0 40 | DH -1 0 41 | DI 1 0 42 | DJ 2 0 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/spatial_square_13.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -3 3 4 | AB -2 3 5 | AC -1 3 6 | AD 1 3 7 | AE 2 3 8 | AF 3 3 9 | AG 3 2 10 | AH 2 2 11 | AI 1 2 12 | AJ -1 2 13 | BA -2 2 14 | BB -3 2 15 | BC -3 1 16 | BD -2 1 17 | BE -1 1 18 | BF 1 1 19 | BG 2 1 20 | BH 3 1 21 | BI 3 -1 22 | BJ 2 -1 23 | CA 1 -1 24 | CB -1 -1 25 | CC -2 -1 26 | CD -3 -1 27 | CE -3 -2 28 | CF -2 -2 29 | CG -1 -2 30 | CH 1 -2 31 | CI 2 -2 32 | CJ 3 -2 33 | DA 3 -3 34 | DB 2 -3 35 | DC 1 -3 36 | DD -1 -3 37 | DE -2 -3 38 | DF -3 -3 39 | DG -2 0 40 | DH -1 0 41 | DI 1 0 42 | DJ 2 0 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/spatial_square_14.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -3 3 4 | AB -2 3 5 | AC -1 3 6 | AD 1 3 7 | AE 2 3 8 | AF 3 3 9 | AG 3 2 10 | AH 2 2 11 | AI 1 2 12 | AJ -1 2 13 | BA -2 2 14 | BB -3 2 15 | BC -3 1 16 | BD -2 1 17 | BE -1 1 18 | BF 1 1 19 | BG 2 1 20 | BH 3 1 21 | BI 3 -1 22 | BJ 2 -1 23 | CA 1 -1 24 | CB -1 -1 25 | CC -2 -1 26 | CD -3 -1 27 | CE -3 -2 28 | CF -2 -2 29 | CG -1 -2 30 | CH 1 -2 31 | CI 2 -2 32 | CJ 3 -2 33 | DA 3 -3 34 | DB 2 -3 35 | DC 1 -3 36 | DD -1 -3 37 | DE -2 -3 38 | DF -3 -3 39 | DG -2 0 40 | DH -1 0 41 | DI 1 0 42 | DJ 2 0 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/spatial_square_15.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -3 3 4 | AB -2 3 5 | AC -1 3 6 | AD 1 3 7 | AE 2 3 8 | AF 3 3 9 | AG 3 2 10 | AH 2 2 11 | AI 1 2 12 | AJ -1 2 13 | BA -2 2 14 | BB -3 2 15 | BC -3 1 16 | BD -2 1 17 | BE -1 1 18 | BF 1 1 19 | BG 2 1 20 | BH 3 1 21 | BI 3 -1 22 | BJ 2 -1 23 | CA 1 -1 24 | CB -1 -1 25 | CC -2 -1 26 | CD -3 -1 27 | CE -3 -2 28 | CF -2 -2 29 | CG -1 -2 30 | CH 1 -2 31 | CI 2 -2 32 | CJ 3 -2 33 | DA 3 -3 34 | DB 2 -3 35 | DC 1 -3 36 | DD -1 -3 37 | DE -2 -3 38 | DF -3 -3 39 | DG -2 0 40 | DH -1 0 41 | DI 1 0 42 | DJ 2 0 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/spatial_square_16.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -3 3 4 | AB -2 3 5 | AC -1 3 6 | AD 1 3 7 | AE 2 3 8 | AF 3 3 9 | AG 3 2 10 | AH 2 2 11 | AI 1 2 12 | AJ -1 2 13 | BA -2 2 14 | BB -3 2 15 | BC -3 1 16 | BD -2 1 17 | BE -1 1 18 | BF 1 1 19 | BG 2 1 20 | BH 3 1 21 | BI 3 -1 22 | BJ 2 -1 23 | CA 1 -1 24 | CB -1 -1 25 | CC -2 -1 26 | CD -3 -1 27 | CE -3 -2 28 | CF -2 -2 29 | CG -1 -2 30 | CH 1 -2 31 | CI 2 -2 32 | CJ 3 -2 33 | DA 3 -3 34 | DB 2 -3 35 | DC 1 -3 36 | DD -1 -3 37 | DE -2 -3 38 | DF -3 -3 39 | DG -2 0 40 | DH -1 0 41 | DI 1 0 42 | DJ 2 0 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/spatial_square_17.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -3 3 4 | AB -2 3 5 | AC -1 3 6 | AD 1 3 7 | AE 2 3 8 | AF 3 3 9 | AG 3 2 10 | AH 2 2 11 | AI 1 2 12 | AJ -1 2 13 | BA -2 2 14 | BB -3 2 15 | BC -3 1 16 | BD -2 1 17 | BE -1 1 18 | BF 1 1 19 | BG 2 1 20 | BH 3 1 21 | BI 3 -1 22 | BJ 2 -1 23 | CA 1 -1 24 | CB -1 -1 25 | CC -2 -1 26 | CD -3 -1 27 | CE -3 -2 28 | CF -2 -2 29 | CG -1 -2 30 | CH 1 -2 31 | CI 2 -2 32 | CJ 3 -2 33 | DA 3 -3 34 | DB 2 -3 35 | DC 1 -3 36 | DD -1 -3 37 | DE -2 -3 38 | DF -3 -3 39 | DG -2 0 40 | DH -1 0 41 | DI 1 0 42 | DJ 2 0 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/spatial_square_2.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -3 3 4 | AB -2 3 5 | AC -1 3 6 | AD 1 3 7 | AE 2 3 8 | AF 3 3 9 | AG 3 2 10 | AH 2 2 11 | AI 1 2 12 | AJ -1 2 13 | BA -2 2 14 | BB -3 2 15 | BC -3 1 16 | BD -2 1 17 | BE -1 1 18 | BF 1 1 19 | BG 2 1 20 | BH 3 1 21 | BI 3 -1 22 | BJ 2 -1 23 | CA 1 -1 24 | CB -1 -1 25 | CC -2 -1 26 | CD -3 -1 27 | CE -3 -2 28 | CF -2 -2 29 | CG -1 -2 30 | CH 1 -2 31 | CI 2 -2 32 | CJ 3 -2 33 | DA 3 -3 34 | DB 2 -3 35 | DC 1 -3 36 | DD -1 -3 37 | DE -2 -3 38 | DF -3 -3 39 | DG -2 0 40 | DH -1 0 41 | DI 1 0 42 | DJ 2 0 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/spatial_square_3.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -3 3 4 | AB -2 3 5 | AC -1 3 6 | AD 1 3 7 | AE 2 3 8 | AF 3 3 9 | AG 3 2 10 | AH 2 2 11 | AI 1 2 12 | AJ -1 2 13 | BA -2 2 14 | BB -3 2 15 | BC -3 1 16 | BD -2 1 17 | BE -1 1 18 | BF 1 1 19 | BG 2 1 20 | BH 3 1 21 | BI 3 -1 22 | BJ 2 -1 23 | CA 1 -1 24 | CB -1 -1 25 | CC -2 -1 26 | CD -3 -1 27 | CE -3 -2 28 | CF -2 -2 29 | CG -1 -2 30 | CH 1 -2 31 | CI 2 -2 32 | CJ 3 -2 33 | DA 3 -3 34 | DB 2 -3 35 | DC 1 -3 36 | DD -1 -3 37 | DE -2 -3 38 | DF -3 -3 39 | DG -2 0 40 | DH -1 0 41 | DI 1 0 42 | DJ 2 0 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/spatial_square_4.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -3 3 4 | AB -2 3 5 | AC -1 3 6 | AD 1 3 7 | AE 2 3 8 | AF 3 3 9 | AG 3 2 10 | AH 2 2 11 | AI 1 2 12 | AJ -1 2 13 | BA -2 2 14 | BB -3 2 15 | BC -3 1 16 | BD -2 1 17 | BE -1 1 18 | BF 1 1 19 | BG 2 1 20 | BH 3 1 21 | BI 3 -1 22 | BJ 2 -1 23 | CA 1 -1 24 | CB -1 -1 25 | CC -2 -1 26 | CD -3 -1 27 | CE -3 -2 28 | CF -2 -2 29 | CG -1 -2 30 | CH 1 -2 31 | CI 2 -2 32 | CJ 3 -2 33 | DA 3 -3 34 | DB 2 -3 35 | DC 1 -3 36 | DD -1 -3 37 | DE -2 -3 38 | DF -3 -3 39 | DG -2 0 40 | DH -1 0 41 | DI 1 0 42 | DJ 2 0 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/spatial_square_5.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -3 3 4 | AB -2 3 5 | AC -1 3 6 | AD 1 3 7 | AE 2 3 8 | AF 3 3 9 | AG 3 2 10 | AH 2 2 11 | AI 1 2 12 | AJ -1 2 13 | BA -2 2 14 | BB -3 2 15 | BC -3 1 16 | BD -2 1 17 | BE -1 1 18 | BF 1 1 19 | BG 2 1 20 | BH 3 1 21 | BI 3 -1 22 | BJ 2 -1 23 | CA 1 -1 24 | CB -1 -1 25 | CC -2 -1 26 | CD -3 -1 27 | CE -3 -2 28 | CF -2 -2 29 | CG -1 -2 30 | CH 1 -2 31 | CI 2 -2 32 | CJ 3 -2 33 | DA 3 -3 34 | DB 2 -3 35 | DC 1 -3 36 | DD -1 -3 37 | DE -2 -3 38 | DF -3 -3 39 | DG -2 0 40 | DH -1 0 41 | DI 1 0 42 | DJ 2 0 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/spatial_square_6.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -3 3 4 | AB -2 3 5 | AC -1 3 6 | AD 1 3 7 | AE 2 3 8 | AF 3 3 9 | AG 3 2 10 | AH 2 2 11 | AI 1 2 12 | AJ -1 2 13 | BA -2 2 14 | BB -3 2 15 | BC -3 1 16 | BD -2 1 17 | BE -1 1 18 | BF 1 1 19 | BG 2 1 20 | BH 3 1 21 | BI 3 -1 22 | BJ 2 -1 23 | CA 1 -1 24 | CB -1 -1 25 | CC -2 -1 26 | CD -3 -1 27 | CE -3 -2 28 | CF -2 -2 29 | CG -1 -2 30 | CH 1 -2 31 | CI 2 -2 32 | CJ 3 -2 33 | DA 3 -3 34 | DB 2 -3 35 | DC 1 -3 36 | DD -1 -3 37 | DE -2 -3 38 | DF -3 -3 39 | DG -2 0 40 | DH -1 0 41 | DI 1 0 42 | DJ 2 0 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/spatial_square_7.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -3 3 4 | AB -2 3 5 | AC -1 3 6 | AD 1 3 7 | AE 2 3 8 | AF 3 3 9 | AG 3 2 10 | AH 2 2 11 | AI 1 2 12 | AJ -1 2 13 | BA -2 2 14 | BB -3 2 15 | BC -3 1 16 | BD -2 1 17 | BE -1 1 18 | BF 1 1 19 | BG 2 1 20 | BH 3 1 21 | BI 3 -1 22 | BJ 2 -1 23 | CA 1 -1 24 | CB -1 -1 25 | CC -2 -1 26 | CD -3 -1 27 | CE -3 -2 28 | CF -2 -2 29 | CG -1 -2 30 | CH 1 -2 31 | CI 2 -2 32 | CJ 3 -2 33 | DA 3 -3 34 | DB 2 -3 35 | DC 1 -3 36 | DD -1 -3 37 | DE -2 -3 38 | DF -3 -3 39 | DG -2 0 40 | DH -1 0 41 | DI 1 0 42 | DJ 2 0 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/spatial_square_8.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -3 3 4 | AB -2 3 5 | AC -1 3 6 | AD 1 3 7 | AE 2 3 8 | AF 3 3 9 | AG 3 2 10 | AH 2 2 11 | AI 1 2 12 | AJ -1 2 13 | BA -2 2 14 | BB -3 2 15 | BC -3 1 16 | BD -2 1 17 | BE -1 1 18 | BF 1 1 19 | BG 2 1 20 | BH 3 1 21 | BI 3 -1 22 | BJ 2 -1 23 | CA 1 -1 24 | CB -1 -1 25 | CC -2 -1 26 | CD -3 -1 27 | CE -3 -2 28 | CF -2 -2 29 | CG -1 -2 30 | CH 1 -2 31 | CI 2 -2 32 | CJ 3 -2 33 | DA 3 -3 34 | DB 2 -3 35 | DC 1 -3 36 | DD -1 -3 37 | DE -2 -3 38 | DF -3 -3 39 | DG -2 0 40 | DH -1 0 41 | DI 1 0 42 | DJ 2 0 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/spatial_square_9.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -3 3 4 | AB -2 3 5 | AC -1 3 6 | AD 1 3 7 | AE 2 3 8 | AF 3 3 9 | AG 3 2 10 | AH 2 2 11 | AI 1 2 12 | AJ -1 2 13 | BA -2 2 14 | BB -3 2 15 | BC -3 1 16 | BD -2 1 17 | BE -1 1 18 | BF 1 1 19 | BG 2 1 20 | BH 3 1 21 | BI 3 -1 22 | BJ 2 -1 23 | CA 1 -1 24 | CB -1 -1 25 | CC -2 -1 26 | CD -3 -1 27 | CE -3 -2 28 | CF -2 -2 29 | CG -1 -2 30 | CH 1 -2 31 | CI 2 -2 32 | CJ 3 -2 33 | DA 3 -3 34 | DB 2 -3 35 | DC 1 -3 36 | DD -1 -3 37 | DE -2 -3 38 | DF -3 -3 39 | DG -2 0 40 | DH -1 0 41 | DI 1 0 42 | DJ 2 0 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/chicken_raw_counts/spatial_zigzag.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | AA -2 5 4 | AB -1 5 5 | AC -0 5 6 | AD 1 5 7 | AE 2 5 8 | AF -2 5 9 | AG -1 5 10 | AH 0 5 11 | AI 1 5 12 | AJ 2 5 13 | BA -2 4 14 | BB -1 3 15 | BC 0 2 16 | BD 1 1 17 | BE 2 0 18 | BF -2 -1 19 | BG -1 -2 20 | BH 0 -3 21 | BI 1 -4 22 | BJ 2 -5 23 | CA -2 -5 24 | CB -1 -5 25 | CC 0 -5 26 | CD 1 -5 27 | CE 2 -5 28 | CF -2 -5 29 | CG -1 -5 30 | CH 0 -5 31 | CI 1 -5 32 | CJ 2 -5 33 | DA -2 -4 34 | DB -1 -3 35 | DC 0 -2 36 | DD 1 -1 37 | DE 2 0 38 | DF -2 1 39 | DG -1 2 40 | DH 0 3 41 | DI 1 4 42 | DJ 2 5 43 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/cow_liver/marker_1_gene_list.txt: -------------------------------------------------------------------------------- 1 | GENE NAMES CLST_A CLST_B CLST_C 2 | Fam71e2 6.39 1.96 0.18 3 | Eif2b2 2.98 0.81 0.18 4 | Mks1 6.66 2.05 0 5 | Gm14444 6.14 3.03 0.39 6 | Vps28 3.54 1.11 0.08 7 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/human_all_genes/cluster.tsv: -------------------------------------------------------------------------------- 1 | NAME X Y Category Intensity 2 | TYPE numeric numeric group numeric 3 | AE_1 7.532146662 14.82605751 A 1 4 | AE_2 58.61765538 7.621239758 A 1 5 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/human_blood_no_metadata/study_info.json: -------------------------------------------------------------------------------- 1 | { 2 | "study": { 3 | "name": "Human Blood Study with no metadata", 4 | "description": "Some studies do not have metadata at all, much less convention compliant data. We sought to identify whether those studies could be found correctly via faceted or regular search. This study in particular should appear for searches on blood. It should also appear on searches for Homo sapiens. We found the presence of this study in those search results was positively correlated with the correct functioning of inferred search, and text search more generally

", 5 | "data_dir": "test" 6 | }, 7 | "files": [] 8 | } 9 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/human_raw_counts/coordinate_labels.tsv: -------------------------------------------------------------------------------- 1 | X Y Z LABELS 2 | 0 0 0 Origin 3 | 0.9 0.9 0.9 Quadrant 1 4 | -0.5 -0.5 -0.5 Negative 0.5 everything 5 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/monkey_correlations/expression_matrix.tsv: -------------------------------------------------------------------------------- 1 | GENE AE_1 AE_2 AE_3 AE_4 AE_5 AE_6 AE_7 AE_8 AE_9 AE_10 AE_11 AE_12 AE_13 AE_14 AE_15 AE_16 AE_17 AE_18 AE_19 AE_20 2 | ADCY5 86 97 99 100 101 103 106 110 112 113 0 0 0 0 0 0 0 0 0 0 3 | AGPAT2 2 20 28 27 50 29 7 17 6 12 0 0 0 0 0 0 0 0 0 0 4 | AGTR1 1 2 3 4 5 6 7 8 9 10 0 0 0 0 0 0 0 0 0 0 5 | AIFM1 11 12 13 14 15 16 17 18 19 20 0 0 0 0 0 0 0 0 0 0 6 | APEX1 21 10 23 9 24 7 26 6 28 5 0 0 0 0 0 0 0 0 0 0 7 | APOC3 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 8 | APOE 5 5 5 5 5 5 5 5 5 5 0 0 0 0 0 0 0 0 0 0 9 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/mouse_brain/coordinate_labels.tsv: -------------------------------------------------------------------------------- 1 | X Y LABELS 2 | 20 20 Lower left 3 | 140 140 Upper right 4 | 30 130 Upper left 5 | 120 33 Lower right 6 | -------------------------------------------------------------------------------- /db/seed/synthetic_studies/mouse_brain/sample1.bam: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/db/seed/synthetic_studies/mouse_brain/sample1.bam -------------------------------------------------------------------------------- /db/seed/synthetic_studies/mouse_brain/sample1.bam.bai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/db/seed/synthetic_studies/mouse_brain/sample1.bam.bai -------------------------------------------------------------------------------- /db/seed/synthetic_studies/mouse_brain/sample2.bam: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/db/seed/synthetic_studies/mouse_brain/sample2.bam -------------------------------------------------------------------------------- /db/seed/synthetic_studies/mouse_brain/sample2.bam.bai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/db/seed/synthetic_studies/mouse_brain/sample2.bam.bai -------------------------------------------------------------------------------- /docs/img/Client-side_performance_monitoring_for_Single_Cell_Portal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/docs/img/Client-side_performance_monitoring_for_Single_Cell_Portal.png -------------------------------------------------------------------------------- /docs/img/Web_vitals_and_client_hardware_Single_Cell_Portal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/docs/img/Web_vitals_and_client_hardware_Single_Cell_Portal.png -------------------------------------------------------------------------------- /generate_dh_parameters.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo generating diffie-hellman parameters... 4 | export RANDFILE=~/.rnd 5 | DIR=/usr/local/share/ca-certificates 6 | openssl dhparam -dsaparam -out $DIR/dhparam.pem 4096 7 | echo ...done -------------------------------------------------------------------------------- /hdf5-parser/.gitignore: -------------------------------------------------------------------------------- 1 | .oauth-token.js 2 | -------------------------------------------------------------------------------- /hdf5-parser/dna-spinning.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/hdf5-parser/dna-spinning.gif -------------------------------------------------------------------------------- /hdf5-parser/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@single-cell-portal/hdf5-parser", 3 | "version": "0.0.1", 4 | "type": "module", 5 | "private": true, 6 | "dependencies": { 7 | "jsfive": "0.3.13" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /hdf5-parser/sans59510.nxs.ngv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/hdf5-parser/sans59510.nxs.ngv -------------------------------------------------------------------------------- /hdf5-parser/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | jsfive@0.3.13: 6 | version "0.3.13" 7 | resolved "https://registry.yarnpkg.com/jsfive/-/jsfive-0.3.13.tgz#0a407adf898d764e56925077775b54c8f852bceb" 8 | integrity sha512-aLOL52kk7j4Yj6tdrz237gL5wDYVyWq2/1wVCD0aoxWbPSJ2QiHwbIu0k2veI2cEis7WJ+ouCo2C21bwmc/VBQ== 9 | dependencies: 10 | pako "^2.0.4" 11 | 12 | pako@^2.0.4: 13 | version "2.0.4" 14 | resolved "https://registry.yarnpkg.com/pako/-/pako-2.0.4.tgz#6cebc4bbb0b6c73b0d5b8d7e8476e2b2fbea576d" 15 | integrity sha512-v8tweI900AUkZN6heMU/4Uy4cXRc2AYNRggVmTR+dEncawDJgCdLMximOVA2p4qO57WMynangsfGRb5WD6L1Bg== 16 | -------------------------------------------------------------------------------- /image-pipeline/.dockerignore: -------------------------------------------------------------------------------- 1 | # Ignore Node runtime assets 2 | node_modules/ 3 | 4 | # Ignore editor configuration 5 | .idea/ 6 | .vscode/ 7 | 8 | # Ignore other detritus 9 | *.log 10 | .DS_Store 11 | .git/ 12 | -------------------------------------------------------------------------------- /image-pipeline/.gitignore: -------------------------------------------------------------------------------- 1 | images 2 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "allowSyntheticDefaultImports": false, 5 | "baseUrl": "./", 6 | "paths": { 7 | "~/*": ["app/javascript/*"] 8 | } 9 | }, 10 | "exclude": ["node_modules", "dist"] 11 | } 12 | -------------------------------------------------------------------------------- /lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/lib/assets/.keep -------------------------------------------------------------------------------- /lib/assets/python/genomes/organisms.tsv: -------------------------------------------------------------------------------- 1 | # scientific_name common_name taxid 2 | Homo sapiens human 9606 3 | Mus musculus mouse 10090 4 | Danio rerio zebrafish 7955 5 | Gallus gallus chicken 9031 6 | Rattus norvegicus rat 10116 7 | Macaca fascicularis macaque 9541 8 | Bos taurus cow 9913 9 | Sus scrofa pig 9823 10 | Canis lupus familiaris dog 9615 11 | Felis catus cat 9685 12 | Drosophila melanogaster fruit fly 7227 13 | -------------------------------------------------------------------------------- /lib/current.rb: -------------------------------------------------------------------------------- 1 | # module to access Devise current_user object outside of ActionControllers 2 | module Current 3 | thread_mattr_accessor :user 4 | end -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/lib/tasks/.keep -------------------------------------------------------------------------------- /log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/log/.keep -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [ 3 | require('postcss-import'), 4 | require('autoprefixer'), 5 | require('postcss-flexbugs-fixes'), 6 | require('postcss-preset-env')({ 7 | autoprefixer: { 8 | flexbox: 'no-2009' 9 | }, 10 | stage: 3 11 | }) 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/public/favicon.ico -------------------------------------------------------------------------------- /public/mock_data/bulk_download/auth_code.json: -------------------------------------------------------------------------------- 1 | { 2 | "auth_code": 123456, 3 | "time_interval": 1800 4 | } 5 | -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /public/single_cell/apple-touch-icon-precomposed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/public/single_cell/apple-touch-icon-precomposed.png -------------------------------------------------------------------------------- /public/single_cell/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/public/single_cell/apple-touch-icon.png -------------------------------------------------------------------------------- /rails-dev-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | bundle install 4 | bin/rails db:migrate 5 | bin/delayed_job start development --pool=default:6, --pool=cache:2 6 | RUBYOPT=--disable-frozen-string-literal bin/rails s 7 | -------------------------------------------------------------------------------- /set_user_permissions.bash: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [[ $PASSENGER_APP_ENV = "production" ]] || [[ $PASSENGER_APP_ENV = "staging" ]] || [[ $PASSENGER_APP_ENV = "pentest" ]] 3 | then 4 | set -e # fail on any error 5 | 6 | echo '*** SETTING UID AND GID TO MATCH HOST VOLUMES ***' 7 | TARGET_UID=$(stat -c "%u" /home/app/webapp) 8 | echo '-- Setting app user to use uid '$TARGET_UID 9 | usermod -o -u $TARGET_UID app || true 10 | TARGET_GID=$(stat -c "%g" /home/app/webapp) 11 | echo '-- Setting app group to use gid '$TARGET_GID 12 | groupmod -o -g $TARGET_GID app || true 13 | fi 14 | -------------------------------------------------------------------------------- /test/Dockerfile-test: -------------------------------------------------------------------------------- 1 | # use SCP base Rails image, configure only project-specific items here 2 | FROM gcr.io/broad-singlecellportal-staging/single-cell-portal:development 3 | 4 | # Set ruby version as this may have changed 5 | RUN bash -lc 'rvm --default use ruby-3.4.2' 6 | RUN bash -lc 'rvm rvmrc warning ignore /home/app/webapp/Gemfile' 7 | 8 | # run any gem/package updates that may have been introduced by this PR 9 | WORKDIR /home/app/webapp 10 | COPY Gemfile /home/app/webapp/Gemfile 11 | COPY Gemfile.lock /home/app/webapp/Gemfile.lock 12 | COPY package.json /home/app/webapp/package.json 13 | COPY yarn.lock /home/app/webapp/yarn.lock 14 | 15 | RUN bundle install 16 | RUN yarn install 17 | -------------------------------------------------------------------------------- /test/controllers/users/omniauth_callbacks_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class User::OmniauthCallbacksControllerTest < ActiveSupport::TestCase 4 | 5 | setup do 6 | @google_params = { scope: SingleCellPortal::Application::BASIC_GOOGLE_SCOPES.join(' ') } 7 | end 8 | 9 | test 'should validate basic scopes from params' do 10 | assert_nothing_raised do 11 | Users::OmniauthCallbacksController.validate_scopes_from_params(@google_params) 12 | end 13 | 14 | @google_params[:scope] += ' devstorage.readonly' 15 | 16 | assert_raise SecurityError do 17 | Users::OmniauthCallbacksController.validate_scopes_from_params(@google_params) 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /test/factories/authors.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :author do 3 | first_name { 'John' } 4 | last_name { 'Doe' } 5 | email { "#{first_name}.#{last_name}@test.edu" } 6 | institution { 'Test University' } 7 | corresponding { false } 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /test/factories/bookmarks.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :bookmark do 3 | name {} 4 | path {} 5 | study_accession {} 6 | description {} 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/factories/branding_group.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | # create a branding_group (collection) to assign users & studies to 3 | factory :branding_group do 4 | transient do 5 | user_list { [] } # pass in a list of users to assign as curators 6 | end 7 | name { "FactoryBot Collection #{SecureRandom.alphanumeric(5)}" } 8 | user_ids { user_list.map(&:id) } 9 | font_family { 'Helvetica Neue, sans-serif' } 10 | background_color { '#FFFFFF' } 11 | public { true } 12 | facet_list { [] } 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /test/factories/differential_expression_results.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :differential_expression_result do 3 | one_vs_rest_comparisons { [] } 4 | cluster_name { cluster.name } 5 | annotation_name { } 6 | annotation_scope { } 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/factories/feature_announcements.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :feature_announcement do 3 | title { "MyString" } 4 | content { "MyString" } 5 | doc_link { "MyString" } 6 | published { false } 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /test/factories/precomputed_score.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | # create a precomputed_score (i.e "gene list") 3 | factory :precomputed_score do 4 | study { study_file.study } 5 | name { } 6 | clusters { } 7 | gene_scores { } 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /test/factories/publications.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :publication do 3 | title { 'My Single-cell Paper' } 4 | journal { 'Nature' } 5 | pmcid { 'PMC1234567' } 6 | url { "https://www.ncbi.nlm.nih.gov/pmc/articles/#{pmcid}" } 7 | citation { } 8 | preprint { false } 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /test/factories/reviewer_access_sessions.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :reviewer_access_session do 3 | session_key { "MyString" } 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /test/factories/reviewer_accesses.rb: -------------------------------------------------------------------------------- 1 | FactoryBot.define do 2 | factory :reviewer_access do 3 | access_code { "MyString" } 4 | pin { 1 } 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /test/includes_helper.rb: -------------------------------------------------------------------------------- 1 | require 'api_test_helper' 2 | 3 | class ActionDispatch::IntegrationTest 4 | include ::Minitest::Hooks 5 | include ::SelfCleaningSuite 6 | include ::TestInstrumentor 7 | include ::Devise::Test::IntegrationHelpers 8 | include ::Requests::JsonHelpers 9 | include ::Requests::HttpHelpers 10 | end 11 | 12 | class ActionController::TestCase 13 | include ::Minitest::Hooks 14 | include ::SelfCleaningSuite 15 | include ::TestInstrumentor 16 | include ::Devise::Test::ControllerHelpers 17 | end 18 | -------------------------------------------------------------------------------- /test/js/jest-mocks/file-mock.js: -------------------------------------------------------------------------------- 1 | /** This is a mock transformer so that jest can import image and other non-js files. 2 | * See: https://stackoverflow.com/questions/46898638/importing-images-breaks-jest-test 3 | * */ 4 | export default '' 5 | -------------------------------------------------------------------------------- /test/js/jest-mocks/igv-mock.js: -------------------------------------------------------------------------------- 1 | export default { 2 | GenomeUtils: { 3 | getKnownGenomes: () => {} 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/models/big_query_client_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class BigQueryClientTest < ActiveSupport::TestCase 4 | 5 | test 'should instantiate client and assign attributes' do 6 | @bq = BigQueryClient.new 7 | assert_not_nil @bq 8 | assert_not_nil @bq.client 9 | assert_equal @bq.project, ENV['GOOGLE_CLOUD_PROJECT'] 10 | assert_equal @bq.service_account_credentials, ENV['SERVICE_ACCOUNT_KEY'] 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /test/rest_client_helper.rb: -------------------------------------------------------------------------------- 1 | require 'rest_client' 2 | RestClient::Exception.module_eval do 3 | def http_code 4 | if @response 5 | @response.try(:code)&.to_i || @response.try(:http_code)&.to_i || @response 6 | else 7 | @initial_response_code 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /test/simplecov_helper.rb: -------------------------------------------------------------------------------- 1 | require 'simplecov' 2 | require 'simplecov-lcov' 3 | SimpleCov.formatter = SimpleCov::Formatter::LcovFormatter 4 | SimpleCov.start 'rails' 5 | -------------------------------------------------------------------------------- /test/test_data/GRCh38/barcodes.tsv: -------------------------------------------------------------------------------- 1 | AACGTTGGTTAAAGTG-1 2 | AGTAGTCAGAGCTATA-1 3 | ATCTGCCCATACTCTT-1 4 | ATGCGATCAAGTTGTC-1 5 | ATTTCTGTCCTTTCGG-1 6 | CAGTAACGTAAACACA-1 7 | CCAATCCCATGAAGTA-1 8 | CGTAGGCCAGCGAACA-1 9 | CTAACTTGTTCCATGA-1 10 | CTCCTAGGTCTCATCC-1 11 | CTCGGAGTCGTAGGAG-1 12 | CTGAAACAGGGAAACA-1 13 | GACTACAGTAACGCGA-1 14 | GCATACAGTACCGTTA-1 15 | GCGAGAACAAGAGGCT-1 16 | GCTTCCACAGCTGTAT-1 17 | GCTTGAAAGAGCTGCA-1 18 | GGACGTCGTTAAAGAC-1 19 | GTACTCCCACTGTTAG-1 20 | GTCACAAAGTAAGTAC-1 21 | TAGCCGGAGAGACGAA-1 22 | TCAACGACACAGCCCA-1 23 | TCGGGACGTCTCAACA-1 24 | TCTCTAACATGCTGGC-1 25 | TGAGCCGGTGATAAGT-1 26 | -------------------------------------------------------------------------------- /test/test_data/GRCh38/matrix.mtx: -------------------------------------------------------------------------------- 1 | %%MatrixMarket matrix coordinate integer general 2 | % 3 | 33694 25 25 4 | 16011 1 1 5 | 14895 2 1 6 | 31764 3 1 7 | 30584 4 1 8 | 27598 5 1 9 | 18124 6 1 10 | 5717 7 1 11 | 26539 8 1 12 | 33656 9 1 13 | 23774 10 1 14 | 15690 11 1 15 | 30264 12 1 16 | 12691 13 1 17 | 12658 14 1 18 | 2873 15 1 19 | 9819 16 1 20 | 557 17 1 21 | 22254 18 1 22 | 3448 19 1 23 | 8207 20 1 24 | 15413 21 1 25 | 21031 22 1 26 | 14382 23 1 27 | 20287 24 1 28 | 24695 25 1 29 | -------------------------------------------------------------------------------- /test/test_data/GRCh38/test_bad_matrix.mtx: -------------------------------------------------------------------------------- 1 | %%MatrixMarket matrix coordinate integer general 2 | % 3 | 100 25 25 4 | 37 13 10 5 | 40 10 11 6 | 42 5 12 7 | 47 19 13 8 | 56 20 14 9 | 61 4 15 10 | 63 15 16 11 | 64 11 17 12 | 3 6 1 13 | 6 9 2 14 | 8 18 3 15 | 16 16 4 16 | 21 8 5 17 | 23 17 6 18 | 30 14 7 19 | 31 1 8 20 | 36 7 9 21 | 66 21 18 22 | 69 24 19 23 | 72 12 20 24 | 75 25 21 25 | 85 22 22 26 | 96 2 23 27 | 98 23 24 28 | 100 3 25 29 | -------------------------------------------------------------------------------- /test/test_data/GRCh38/test_matrix.mtx: -------------------------------------------------------------------------------- 1 | %%MatrixMarket matrix coordinate integer general 2 | % 3 | 100 25 25 4 | 3 6 1 5 | 6 9 2 6 | 8 18 3 7 | 16 16 4 8 | 21 8 5 9 | 23 17 6 10 | 30 14 7 11 | 31 1 8 12 | 36 7 9 13 | 37 13 10 14 | 40 10 11 15 | 42 5 12 16 | 47 19 13 17 | 56 20 14 18 | 61 4 15 19 | 63 15 16 20 | 64 11 17 21 | 66 21 18 22 | 69 24 19 23 | 72 12 20 24 | 75 25 21 25 | 85 22 22 26 | 96 2 23 27 | 98 23 24 28 | 100 3 25 29 | -------------------------------------------------------------------------------- /test/test_data/R_format_text.txt: -------------------------------------------------------------------------------- 1 | "x" "y" "x.1" 2 | "1" 1 11 21 3 | "2" 2 12 22 4 | "3" 3 13 23 5 | "4" 4 14 24 6 | "5" 5 15 25 7 | "6" 6 16 26 8 | "7" 7 17 27 9 | "8" 8 18 28 10 | "9" 9 19 29 11 | "10" 10 20 30 12 | -------------------------------------------------------------------------------- /test/test_data/anndata/invalid_annotation_name_period.h5ad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/test/test_data/anndata/invalid_annotation_name_period.h5ad -------------------------------------------------------------------------------- /test/test_data/anndata/invalid_disease_id.h5ad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/test/test_data/anndata/invalid_disease_id.h5ad -------------------------------------------------------------------------------- /test/test_data/anndata/invalid_disease_label.h5ad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/test/test_data/anndata/invalid_disease_label.h5ad -------------------------------------------------------------------------------- /test/test_data/anndata/invalid_header_no_species.h5ad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/test/test_data/anndata/invalid_header_no_species.h5ad -------------------------------------------------------------------------------- /test/test_data/anndata/valid.h5ad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/test/test_data/anndata/valid.h5ad -------------------------------------------------------------------------------- /test/test_data/anndata/valid_with_colon.h5ad: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/test/test_data/anndata/valid_with_colon.h5ad -------------------------------------------------------------------------------- /test/test_data/branding_groups/SCP-Header-resize-invert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/test/test_data/branding_groups/SCP-Header-resize-invert.png -------------------------------------------------------------------------------- /test/test_data/branding_groups/SCP-logo-invert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/test/test_data/branding_groups/SCP-logo-invert.png -------------------------------------------------------------------------------- /test/test_data/branding_groups/broad-logo-white-invert.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/test/test_data/branding_groups/broad-logo-white-invert.png -------------------------------------------------------------------------------- /test/test_data/cell_1_I1_001.fastq.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/test/test_data/cell_1_I1_001.fastq.gz -------------------------------------------------------------------------------- /test/test_data/cell_1_R1_001.fastq.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/test/test_data/cell_1_R1_001.fastq.gz -------------------------------------------------------------------------------- /test/test_data/cluster_2_example.txt: -------------------------------------------------------------------------------- 1 | NAME X Y Z Sub-Group 2 | TYPE numeric numeric numeric group 3 | CELL_0001 1.43 0.455 1.885 Group 3 4 | CELL_0002 4.72 1.593 6.313 Group 3 5 | CELL_0003 4.348 -9.848 -5.5 Group 1 6 | CELL_0004 -0.214 1.902 1.688 Group 3 7 | CELL_0005 0.516 -1.881 -1.365 Group 3 8 | CELL_0006 -2.731 -5.704 -8.435 Group 2 9 | CELL_0007 2.91 0.264 3.174 Group 3 10 | CELL_0008 -0.26 7.701 7.441 Group 5 11 | CELL_0009 2.383 -0.168 2.215 Group 3 12 | CELL_00010 0.545 -3.383 -2.838 Group 2 13 | CELL_00011 -3.668 5.497 1.829 Group 4 14 | CELL_00012 3.576 -1.297 2.279 Group 3 15 | CELL_00013 0.633 7.341 7.974 Group 5 16 | CELL_00014 -0.538 5.867 5.329 Group 5 17 | CELL_00015 -0.915 6.138 5.223 Group 5 -------------------------------------------------------------------------------- /test/test_data/cluster_2d_example.txt: -------------------------------------------------------------------------------- 1 | NAME X Y Sub-Group 2 | TYPE numeric numeric group 3 | CELL_0001 1.43 0.455 Group 3 4 | CELL_0002 4.72 1.593 Group 3 5 | CELL_0003 4.348 -9.848 Group 1 6 | CELL_0004 -0.214 1.902 Group 3 7 | CELL_0005 0.516 -1.881 Group 3 8 | CELL_0006 -2.731 -5.704 Group 2 9 | CELL_0007 2.91 0.264 Group 3 10 | CELL_0008 -0.26 7.701 Group 5 11 | CELL_0009 2.383 -0.168 Group 3 12 | CELL_00010 0.545 -3.383 Group 2 13 | CELL_00011 -3.668 5.497 Group 4 14 | CELL_00012 3.576 -1.297 Group 3 15 | CELL_00013 0.633 7.341 Group 5 16 | CELL_00014 -0.538 5.867 Group 5 17 | CELL_00015 -0.915 6.138 Group 5 -------------------------------------------------------------------------------- /test/test_data/cluster_bad.txt: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | CELL_0001 34.472 32.211 3 | CELL_0002 15.975 10.043 4 | CELL_0003 -11.688 -53.645 5 | CELL_0004 30.04 31.138 6 | CELL_0005 23.862 33.092 7 | CELL_0006 -39.07 -14.64 8 | CELL_0007 40.039 27.206 9 | CELL_0008 28.755 27.187 10 | CELL_0009 -48.601 -13.512 11 | CELL_00010 14.653 27.832 12 | CELL_00011 20.603 32.071 13 | CELL_00012 -10.333 -51.733 14 | CELL_00013 -52.966 -12.484 15 | CELL_00014 38.513 26.969 16 | CELL_00015 12.838 13.047 -------------------------------------------------------------------------------- /test/test_data/cluster_flat.tsv: -------------------------------------------------------------------------------- 1 | NAME X Y 2 | TYPE numeric numeric 3 | CELL_0001 34.472 32.211 4 | CELL_0002 15.975 10.043 5 | CELL_0003 -11.688 -53.645 6 | CELL_0004 30.04 31.138 7 | CELL_0005 23.862 33.092 8 | CELL_0006 -39.07 -14.64 9 | CELL_0007 40.039 27.206 10 | CELL_0008 28.755 27.187 11 | CELL_0009 -48.601 -13.512 12 | CELL_00010 14.653 27.832 13 | CELL_00011 20.603 32.071 14 | CELL_00012 -10.333 -51.733 15 | CELL_00013 -52.966 -12.484 16 | CELL_00014 38.513 26.969 17 | CELL_00015 12.838 13.047 18 | -------------------------------------------------------------------------------- /test/test_data/coordinate_labels_1.txt: -------------------------------------------------------------------------------- 1 | X Y Z LABELS 2 | 35.472 33.211 61.035 Region 1 3 | -10.688 -52.645 -57.374 Region 2 4 | 31.04 32.138 34.597 Region 3 5 | 24.862 34.092 27.904 Region 4 6 | -47.601 -12.512 -50.659 Region 5 7 | 15.653 28.832 29.586 Region 6 8 | 21.603 33.071 46.484 Region 7 9 | -9.333 -50.733 -25.631 Region 8 -------------------------------------------------------------------------------- /test/test_data/coordinate_labels_2.txt: -------------------------------------------------------------------------------- 1 | X Y Z LABELS 2 | 4.72 1.593 6.313 Group A 3 | 4.348 -9.848 -5.5 Group B 4 | -2.731 -5.704 -8.435 Group C 5 | -0.538 5.867 5.329 Group D 6 | -0.915 6.138 5.223 Group E -------------------------------------------------------------------------------- /test/test_data/default_participant.tsv: -------------------------------------------------------------------------------- 1 | entity:participant_id 2 | default_participant -------------------------------------------------------------------------------- /test/test_data/expression_matrix_example_gzipped.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/test/test_data/expression_matrix_example_gzipped.txt.gz -------------------------------------------------------------------------------- /test/test_data/fixed_neurons_6days_2000_possorted_genome_bam_test_data.bam: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/test/test_data/fixed_neurons_6days_2000_possorted_genome_bam_test_data.bam -------------------------------------------------------------------------------- /test/test_data/fixed_neurons_6days_2000_possorted_genome_bam_test_data.bam.bai: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/test/test_data/fixed_neurons_6days_2000_possorted_genome_bam_test_data.bam.bai -------------------------------------------------------------------------------- /test/test_data/human_author_de/cluster_umap_txt--General_Celltype--manifest.tsv: -------------------------------------------------------------------------------- 1 | B cells 2 | CSN1S1 macrophages 3 | dendritic cells 4 | B cells CSN1S1 macrophages 5 | B cells dendritic cells 6 | eosinophils CSN1S1 macrophages 7 | -------------------------------------------------------------------------------- /test/test_data/marker_1_gene_list.txt: -------------------------------------------------------------------------------- 1 | GENE NAMES CLST_A CLST_B CLST_C 2 | Fam71e2 6.39 1.96 0.18 3 | Eif2b2 2.98 0.81 0.18 4 | Mks1 6.66 2.05 0 5 | Gm14444 6.14 3.03 0.39 6 | Vps28 3.54 1.11 0.08 7 | -------------------------------------------------------------------------------- /test/test_data/marker_1_gene_list_bad.txt: -------------------------------------------------------------------------------- 1 | GENE NAMES CLST_A CLST_B CLST_C 2 | Fam71e2 6.39 1.96 0.18 3 | Eif2b2 2.98 0.81 0.18 4 | Mks1 6.66 2.05 0 5 | Mks1 6.66 2.05 0 6 | Gm14444 6.14 3.03 0.39 7 | Vps28 3.54 1.11 0.08 8 | -------------------------------------------------------------------------------- /test/test_data/marker_2_gene_list.txt: -------------------------------------------------------------------------------- 1 | GENE NAMES CLST_A CLST_B CLST_C 2 | Itm2a 6.39 1.96 0.18 3 | Sergef 2.98 0.81 0.18 4 | Chil5 6.66 2.05 0 5 | Fam109a 6.14 3.03 0.39 6 | Dhx9 3.54 1.11 0.08 7 | -------------------------------------------------------------------------------- /test/test_data/metadata_bad.txt: -------------------------------------------------------------------------------- 1 | NAME CLUSTER SUB-CLUSTER 2 | CELL_0001 CLST_A CLST_A_1 3 | CELL_0002 CLST_A CLST_A_1 4 | CELL_0003 CLST_A CLST_A_1 5 | CELL_0004 CLST_A CLST_A_2 6 | CELL_0005 CLST_A CLST_A_2 7 | CELL_0006 CLST_B CLST_B_1 8 | CELL_0007 CLST_B CLST_B_1 9 | CELL_0008 CLST_B CLST_B_2 10 | CELL_0009 CLST_B CLST_B_2 11 | CELL_00010 CLST_B CLST_B_2 12 | CELL_00011 CLST_C CLST_C_1 13 | CELL_00012 CLST_C CLST_C_1 14 | CELL_00013 CLST_C CLST_C_1 15 | CELL_00014 CLST_C CLST_C_2 16 | CELL_00015 CLST_C CLST_C_2 -------------------------------------------------------------------------------- /test/test_data/metadata_example.txt: -------------------------------------------------------------------------------- 1 | NAME Cluster Subcluster Average_Intensity 2 | TYPE group group numeric 3 | CELL_0001 CLST_A CLST_A_1 7.742 4 | CELL_0002 CLST_A CLST_A_1 -13.745 5 | CELL_0003 CLST_A CLST_A_1 -0.375 6 | CELL_0004 CLST_A CLST_A_2 9.188 7 | CELL_0005 CLST_A CLST_A_2 9.652 8 | CELL_0006 CLST_B CLST_B_1 -4.125 9 | CELL_0007 CLST_B CLST_B_1 -2.275 10 | CELL_0008 CLST_B CLST_B_2 -12.606 11 | CELL_0009 CLST_B CLST_B_2 3.675 12 | CELL_00010 CLST_B CLST_B_2 -2.116 13 | CELL_00011 CLST_C CLST_C_1 0.638 14 | CELL_00012 CLST_C CLST_C_1 8.888 15 | CELL_00013 CLST_C CLST_C_1 -2.27 16 | CELL_00014 CLST_C CLST_C_2 -2.606 17 | CELL_00015 CLST_C CLST_C_2 -9.089 18 | -------------------------------------------------------------------------------- /test/test_data/metadata_example_bad_TYPE.txt: -------------------------------------------------------------------------------- 1 | NAME Cluster Sub-Cluster Average Intensity 2 | notTYPE group group numeric 3 | CELL_0001 CLST_A CLST_A_1 7.742 4 | CELL_0002 CLST_A CLST_A_1 -13.745 5 | CELL_0003 CLST_A CLST_A_1 -0.375 6 | CELL_0004 CLST_A CLST_A_2 9.188 7 | CELL_0005 CLST_A CLST_A_2 9.652 8 | CELL_0006 CLST_B CLST_B_1 -4.125 9 | CELL_0007 CLST_B CLST_B_1 -2.275 10 | CELL_0008 CLST_B CLST_B_2 -12.606 11 | CELL_0009 CLST_B CLST_B_2 3.675 12 | CELL_00010 CLST_B CLST_B_2 -2.116 13 | CELL_00011 CLST_C CLST_C_1 0.638 14 | CELL_00012 CLST_C CLST_C_1 8.888 15 | CELL_00013 CLST_C CLST_C_1 -2.27 16 | CELL_00014 CLST_C CLST_C_2 -2.606 17 | CELL_00015 CLST_C CLST_C_2 -9.089 -------------------------------------------------------------------------------- /test/test_data/metadata_update.txt: -------------------------------------------------------------------------------- 1 | NAME Label Sub-Label Average Intensity 2 | TYPE group group numeric 3 | CELL_0001 LABEL_A LABEL_A_1 7.742 4 | CELL_0002 LABEL_A LABEL_A_1 -13.745 5 | CELL_0003 LABEL_A LABEL_A_1 -0.375 6 | CELL_0004 LABEL_A LABEL_A_2 9.188 7 | CELL_0005 LABEL_A LABEL_A_2 9.652 8 | CELL_0006 LABEL_B LABEL_B_1 -4.125 9 | CELL_0007 LABEL_B LABEL_B_1 -2.275 10 | CELL_0008 LABEL_B LABEL_B_2 -12.606 11 | CELL_0009 LABEL_B LABEL_B_2 3.675 12 | CELL_00010 LABEL_B LABEL_B_2 -2.116 13 | CELL_00011 LABEL_C LABEL_C_1 0.638 14 | CELL_00012 LABEL_C LABEL_C_1 8.888 15 | CELL_00013 LABEL_C LABEL_C_1 -2.27 16 | CELL_00014 LABEL_C LABEL_C_2 -2.606 17 | CELL_00015 LABEL_C LABEL_C_2 -9.089 18 | -------------------------------------------------------------------------------- /test/test_data/mock_study_doc_upload(1).txt: -------------------------------------------------------------------------------- 1 | This is an example readme file -------------------------------------------------------------------------------- /test/test_data/mock_study_doc_upload.txt: -------------------------------------------------------------------------------- 1 | This is an example readme file -------------------------------------------------------------------------------- /test/test_data/search_genes.txt: -------------------------------------------------------------------------------- 1 | Fam71e2 2 | Eif2b2 3 | Mks1 4 | Gm14444 5 | Vps28 -------------------------------------------------------------------------------- /test/test_data/sub_cluster_1_coordinates_example.txt: -------------------------------------------------------------------------------- 1 | CELL_NAME X Y 2 | CELL_0001 34.472 32.211 3 | CELL_0002 15.975 10.043 4 | CELL_0003 -11.688 -53.645 5 | CELL_0004 30.04 31.138 6 | CELL_0005 23.862 33.092 7 | CELL_0006 -39.07 -14.64 8 | CELL_0007 40.039 27.206 9 | CELL_0008 28.755 27.187 10 | CELL_0009 -48.601 -13.512 11 | CELL_00010 14.653 27.832 12 | CELL_00011 20.603 32.071 13 | CELL_00012 -10.333 -51.733 14 | CELL_00013 -52.966 -12.484 15 | CELL_00014 38.513 26.969 16 | CELL_00015 12.838 13.047 -------------------------------------------------------------------------------- /test/test_data/sub_cluster_1_coordinates_example_bad.txt: -------------------------------------------------------------------------------- 1 | CELL_NAME X Y 2 | CELL_0001 34.472 32.211 3 | CELL_0002 15.975 10.043 4 | CELL_0003 -11.688 -53.645 5 | CELL_0004 30.04 31.138 6 | CELL_0005 23.862 33.092 7 | CELL_0006 -39.07 -14.64 8 | CELL_0007 40.039 27.206 9 | CELL_0008 28.755 27.187 10 | CELL_0009 -48.601 -13.512 11 | CELL_00010 14.653 27.832 12 | CELL_00011 20.603 32.071 13 | CELL_00012 -10.333 -51.733 14 | CELL_00012 -13.333 -11.733 15 | CELL_00013 -52.966 -12.484 16 | CELL_00014 38.513 26.969 17 | CELL_00015 12.838 13.047 -------------------------------------------------------------------------------- /test/test_data/sub_cluster_2_coordinates_example.txt: -------------------------------------------------------------------------------- 1 | CELL_NAME X Y 2 | CELL_0001 34.472 32.211 3 | CELL_0002 15.975 10.043 4 | CELL_0003 -11.688 -53.645 5 | CELL_0004 30.04 31.138 6 | CELL_0005 23.862 33.092 7 | CELL_0006 -39.07 -14.64 8 | CELL_0007 40.039 27.206 9 | CELL_0008 28.755 27.187 10 | CELL_0009 -48.601 -13.512 11 | CELL_00010 14.653 27.832 12 | CELL_00011 20.603 32.071 13 | CELL_00012 -10.333 -51.733 14 | CELL_00013 -52.966 -12.484 15 | CELL_00014 38.513 26.969 16 | CELL_00015 12.838 13.047 -------------------------------------------------------------------------------- /test/test_data/table_1.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/test/test_data/table_1.xlsx -------------------------------------------------------------------------------- /test/test_data/test-blank.loom: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/test/test_data/test-blank.loom -------------------------------------------------------------------------------- /test/test_data/test_gene_list.txt: -------------------------------------------------------------------------------- 1 | apex1 2 | apoe 3 | agpat2 4 | -------------------------------------------------------------------------------- /test/test_data/validation/cluster_bad_no_coordinates.txt: -------------------------------------------------------------------------------- 1 | NAME X 2 | TYPE group 3 | CELL_0001 34.472 4 | CELL_0002 15.975 5 | CELL_0003 -11.688 6 | CELL_0004 30.04 7 | CELL_0005 23.862 8 | CELL_0006 -39.07 9 | CELL_0007 40.039 10 | CELL_0008 28.755 11 | CELL_0009 -48.601 12 | CELL_00010 14.653 13 | CELL_00011 20.603 14 | CELL_00012 -10.333 15 | CELL_00013 -52.966 16 | CELL_00014 38.513 17 | CELL_00015 12.838 18 | -------------------------------------------------------------------------------- /test/test_data/validation/expression_matrix_example.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/test/test_data/validation/expression_matrix_example.txt.gz -------------------------------------------------------------------------------- /test/test_data/validation/expression_matrix_example_bad.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/test/test_data/validation/expression_matrix_example_bad.txt.gz -------------------------------------------------------------------------------- /test/test_data/validation/header_count_mismatch.tsv: -------------------------------------------------------------------------------- 1 | NAME Cluster Subcluster Average_Intensity 2 | TYPE group group 3 | CELL_0001 CLST_A CLST_A_1 7.742 4 | CELL_0002 CLST_A CLST_A_1 -13.745 5 | CELL_0003 CLST_A CLST_A_1 -0.375 6 | CELL_0004 CLST_A CLST_A_2 9.188 7 | CELL_0005 CLST_A CLST_A_2 9.652 8 | CELL_0006 CLST_B CLST_B_1 -4.125 9 | CELL_0007 CLST_B CLST_B_1 -2.275 10 | CELL_0008 CLST_B CLST_B_2 -12.606 11 | CELL_0009 CLST_B CLST_B_2 3.675 12 | CELL_00010 CLST_B CLST_B_2 -2.116 13 | CELL_00011 CLST_C CLST_C_1 0.638 14 | CELL_00012 CLST_C CLST_C_1 8.888 15 | CELL_00013 CLST_C CLST_C_1 -2.27 16 | CELL_00014 CLST_C CLST_C_2 -2.606 17 | CELL_00015 CLST_C CLST_C_2 -9.089 18 | -------------------------------------------------------------------------------- /test/test_data/validation/metadata_bad_has_coordinates.txt: -------------------------------------------------------------------------------- 1 | NAME CLUSTER SUBCLUSTER x 2 | TYPE group group numeric 3 | CELL_0001 CLST_A CLST_A_1 1 4 | CELL_0002 CLST_A CLST_A_1 2 5 | CELL_0003 CLST_A CLST_A_1 3 6 | CELL_0004 CLST_A CLST_A_2 4 7 | CELL_0005 CLST_A CLST_A_2 5 8 | CELL_0006 CLST_B CLST_B_1 6 9 | CELL_0007 CLST_B CLST_B_1 7 10 | CELL_0008 CLST_B CLST_B_2 8 11 | CELL_0009 CLST_B CLST_B_2 9 12 | CELL_00010 CLST_B CLST_B_2 10 13 | CELL_00011 CLST_C CLST_C_1 11 14 | CELL_00012 CLST_C CLST_C_1 12 15 | CELL_00013 CLST_C CLST_C_1 13 16 | CELL_00014 CLST_C CLST_C_2 14 17 | CELL_00015 CLST_C CLST_C_2 15 18 | -------------------------------------------------------------------------------- /test/test_data/validation/metadata_bad_type_header.txt: -------------------------------------------------------------------------------- 1 | NAME Cluster Subcluster Average_Intensity 2 | notTYPE group group numeric 3 | CELL_0001 CLST_A CLST_A_1 7.742 4 | CELL_0002 CLST_A CLST_A_1 -13.745 5 | CELL_0003 CLST_A CLST_A_1 -0.375 6 | CELL_0004 CLST_A CLST_A_2 9.188 7 | CELL_0005 CLST_A CLST_A_2 9.652 8 | CELL_0006 CLST_B CLST_B_1 -4.125 9 | CELL_0007 CLST_B CLST_B_1 -2.275 10 | CELL_0008 CLST_B CLST_B_2 -12.606 11 | CELL_0009 CLST_B CLST_B_2 3.675 12 | CELL_00010 CLST_B CLST_B_2 -2.116 13 | CELL_00011 CLST_C CLST_C_1 0.638 14 | CELL_00012 CLST_C CLST_C_1 8.888 15 | CELL_00013 CLST_C CLST_C_1 -2.27 16 | CELL_00014 CLST_C CLST_C_2 -2.606 17 | CELL_00015 CLST_C CLST_C_2 -9.089 18 | -------------------------------------------------------------------------------- /test/test_data/validation/missing_gz_extension.rds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/test/test_data/validation/missing_gz_extension.rds -------------------------------------------------------------------------------- /test/test_data/validation/missing_gz_extension.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/test/test_data/validation/missing_gz_extension.txt -------------------------------------------------------------------------------- /test/test_data/workspace_samples.tsv: -------------------------------------------------------------------------------- 1 | entity:sample_id participant_id attribute_1 attribute_2 attribute_3 2 | sample_1 default_participant attribute_1_value attribute_2_value attribute_3_value 3 | sample_2 default_participant attribute_1_value attribute_2_value attribute_3_value 4 | sample_3 default_participant attribute_1_value attribute_2_value attribute_3_value 5 | sample_4 default_participant attribute_1_value attribute_2_value attribute_3_value 6 | sample_5 default_participant attribute_1_value attribute_2_value attribute_3_value -------------------------------------------------------------------------------- /test/user_tokens_helper.rb: -------------------------------------------------------------------------------- 1 | # helper to restore user access tokens on test teardown to prevent successive downstream failures 2 | def reset_user_tokens 3 | User.all.each do |user| 4 | token = { access_token: SecureRandom.uuid, expires_in: 3600, expires_at: Time.zone.now + 1.hour } 5 | user.update!(access_token: token, api_access_token: token) 6 | user.update_last_access_at! 7 | end 8 | end 9 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/vendor/assets/javascripts/.keep -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/broadinstitute/single_cell_portal_core/12c20c06a5c9360e4e71b0637a0733cd65051e7c/vendor/assets/stylesheets/.keep -------------------------------------------------------------------------------- /version.txt: -------------------------------------------------------------------------------- 1 | "1.20.0" 2 | -------------------------------------------------------------------------------- /vite-dev-entrypoint.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # set SCP_VERSION to current branch name + short commit SHA 4 | # e.g. my-feature-branch:f4e377a60 5 | SCP_VERSION="$(git branch --show-current):$(git rev-parse --short HEAD)" 6 | 7 | yarn install 8 | SCP_VERSION="\"$SCP_VERSION\"" bin/vite dev 9 | --------------------------------------------------------------------------------