diff --git a/PKG-INFO b/PKG-INFO index cbf97da8..01ce6dad 100644 --- a/PKG-INFO +++ b/PKG-INFO @@ -1,10 +1,10 @@ Metadata-Version: 1.0 Name: swh.web -Version: 0.0.153 +Version: 0.0.154 Summary: Software Heritage Web UI Home-page: https://forge.softwareheritage.org/diffusion/DWUI/ Author: Software Heritage developers Author-email: swh-devel@inria.fr License: UNKNOWN Description: UNKNOWN Platform: UNKNOWN diff --git a/swh.web.egg-info/PKG-INFO b/swh.web.egg-info/PKG-INFO index cbf97da8..01ce6dad 100644 --- a/swh.web.egg-info/PKG-INFO +++ b/swh.web.egg-info/PKG-INFO @@ -1,10 +1,10 @@ Metadata-Version: 1.0 Name: swh.web -Version: 0.0.153 +Version: 0.0.154 Summary: Software Heritage Web UI Home-page: https://forge.softwareheritage.org/diffusion/DWUI/ Author: Software Heritage developers Author-email: swh-devel@inria.fr License: UNKNOWN Description: UNKNOWN Platform: UNKNOWN diff --git a/swh.web.egg-info/SOURCES.txt b/swh.web.egg-info/SOURCES.txt index c3ecbc0a..95a1dc2f 100644 --- a/swh.web.egg-info/SOURCES.txt +++ b/swh.web.egg-info/SOURCES.txt @@ -1,364 +1,365 @@ .gitignore AUTHORS CONTRIBUTORS LICENSE MANIFEST.in Makefile Makefile.local README.md package-lock.json package.json requirements-swh.txt requirements.txt setup.py version.txt yarn.lock debian/changelog debian/compat debian/control debian/copyright debian/postinst debian/rules debian/source/format docs/.gitignore docs/Makefile docs/conf.py docs/developers-info.rst docs/index.rst docs/uri-scheme-api-content.rst docs/uri-scheme-api-directory.rst docs/uri-scheme-api-identifiers.rst docs/uri-scheme-api-origin.rst docs/uri-scheme-api-person.rst docs/uri-scheme-api-release.rst docs/uri-scheme-api-revision.rst docs/uri-scheme-api-snapshot.rst docs/uri-scheme-api-stat.rst docs/uri-scheme-api-vault.rst docs/uri-scheme-api.rst docs/uri-scheme-browse-content.rst docs/uri-scheme-browse-directory.rst docs/uri-scheme-browse-origin.rst docs/uri-scheme-browse-person.rst docs/uri-scheme-browse-release.rst docs/uri-scheme-browse-revision.rst docs/uri-scheme-browse-snapshot.rst docs/uri-scheme-browse.rst docs/uri-scheme-identifiers.rst docs/_static/.placeholder docs/_templates/.placeholder swh/__init__.py swh.web.egg-info/PKG-INFO swh.web.egg-info/SOURCES.txt swh.web.egg-info/dependency_links.txt swh.web.egg-info/requires.txt swh.web.egg-info/top_level.txt swh/web/__init__.py swh/web/config.py swh/web/doc_config.py swh/web/manage.py swh/web/urls.py swh/web/wsgi.py swh/web/admin/__init__.py swh/web/admin/adminurls.py swh/web/admin/origin_save.py swh/web/admin/urls.py swh/web/api/__init__.py swh/web/api/apidoc.py swh/web/api/apiresponse.py swh/web/api/apiurls.py swh/web/api/renderers.py swh/web/api/urls.py swh/web/api/utils.py swh/web/api/views/__init__.py swh/web/api/views/content.py swh/web/api/views/directory.py swh/web/api/views/entity.py swh/web/api/views/identifiers.py swh/web/api/views/origin.py swh/web/api/views/origin_save.py swh/web/api/views/person.py swh/web/api/views/release.py swh/web/api/views/revision.py swh/web/api/views/snapshot.py swh/web/api/views/stat.py swh/web/api/views/utils.py swh/web/api/views/vault.py swh/web/assets/config/.bootstraprc swh/web/assets/config/.eslintrc swh/web/assets/config/bootstrap-pre-customize.scss swh/web/assets/config/webpack.config.development.js swh/web/assets/config/webpack.config.production.js swh/web/assets/config/webpack-plugins/remove-source-map-url-webpack-plugin.js swh/web/assets/src/bundles/admin/index.js swh/web/assets/src/bundles/admin/origin-save.js swh/web/assets/src/bundles/browse/breadcrumbs.css swh/web/assets/src/bundles/browse/browse-utils.js swh/web/assets/src/bundles/browse/browse.css swh/web/assets/src/bundles/browse/content.css swh/web/assets/src/bundles/browse/index.js swh/web/assets/src/bundles/browse/origin-save.js swh/web/assets/src/bundles/browse/origin-search.js swh/web/assets/src/bundles/browse/snapshot-navigation.css swh/web/assets/src/bundles/browse/snapshot-navigation.js swh/web/assets/src/bundles/browse/swh-ids-utils.js swh/web/assets/src/bundles/origin/index.js swh/web/assets/src/bundles/origin/visits-calendar.js swh/web/assets/src/bundles/origin/visits-histogram.js swh/web/assets/src/bundles/origin/visits-reporting.css swh/web/assets/src/bundles/origin/visits-reporting.js swh/web/assets/src/bundles/revision/diff-utils.js swh/web/assets/src/bundles/revision/index.js swh/web/assets/src/bundles/revision/revision.css swh/web/assets/src/bundles/vault/index.js swh/web/assets/src/bundles/vault/vault-create-tasks.js swh/web/assets/src/bundles/vault/vault-ui.js swh/web/assets/src/bundles/vault/vault.css swh/web/assets/src/bundles/vendors/datatables.css swh/web/assets/src/bundles/vendors/index.js swh/web/assets/src/bundles/webapp/breadcrumbs.css swh/web/assets/src/bundles/webapp/code-highlighting.js swh/web/assets/src/bundles/webapp/index.js swh/web/assets/src/bundles/webapp/markdown-rendering.js swh/web/assets/src/bundles/webapp/pdf-rendering.js swh/web/assets/src/bundles/webapp/webapp-utils.js swh/web/assets/src/bundles/webapp/webapp.css swh/web/assets/src/utils/functions.js swh/web/assets/src/utils/heaps-permute.js swh/web/assets/src/utils/highlightjs.css swh/web/assets/src/utils/highlightjs.js swh/web/assets/src/utils/jquery.tabSlideOut.css swh/web/assets/src/utils/jquery.tabSlideOut.js swh/web/assets/src/utils/showdown.css swh/web/assets/src/utils/showdown.js swh/web/browse/__init__.py swh/web/browse/browseurls.py swh/web/browse/identifiers.py swh/web/browse/urls.py swh/web/browse/utils.py swh/web/browse/views/__init__.py swh/web/browse/views/content.py swh/web/browse/views/directory.py swh/web/browse/views/origin.py swh/web/browse/views/origin_save.py swh/web/browse/views/person.py swh/web/browse/views/release.py swh/web/browse/views/revision.py swh/web/browse/views/snapshot.py swh/web/browse/views/utils/__init__.py swh/web/browse/views/utils/snapshot_context.py swh/web/common/__init__.py swh/web/common/apps.py swh/web/common/converters.py swh/web/common/exc.py swh/web/common/highlightjs.py swh/web/common/middlewares.py swh/web/common/models.py swh/web/common/origin_save.py swh/web/common/query.py swh/web/common/service.py swh/web/common/swh_templatetags.py swh/web/common/throttling.py swh/web/common/urlsindex.py swh/web/common/utils.py swh/web/common/migrations/0001_initial.py swh/web/common/migrations/0002_saveoriginrequest_visit_date.py +swh/web/common/migrations/0003_saveoriginrequest_loading_task_status.py swh/web/common/migrations/__init__.py swh/web/settings/__init__.py swh/web/settings/common.py swh/web/settings/development.py swh/web/settings/production.py swh/web/settings/tests.py swh/web/static/robots.txt swh/web/static/webpack-stats.json -swh/web/static/css/browse.92378aae87894b0d9972.css -swh/web/static/css/browse.92378aae87894b0d9972.css.map +swh/web/static/css/browse.cec637f91d68ef766e5f.css +swh/web/static/css/browse.cec637f91d68ef766e5f.css.map swh/web/static/css/highlightjs.8999b6ccd00337cba3b8.css swh/web/static/css/highlightjs.8999b6ccd00337cba3b8.css.map swh/web/static/css/origin.c9b9c6c34c7967dc9329.css swh/web/static/css/origin.c9b9c6c34c7967dc9329.css.map swh/web/static/css/revision.fb503b9a29a646435e5d.css swh/web/static/css/revision.fb503b9a29a646435e5d.css.map swh/web/static/css/showdown.5000791dba563908850c.css swh/web/static/css/showdown.5000791dba563908850c.css.map swh/web/static/css/vault.154f0be768ca9bac8b6c.css swh/web/static/css/vault.154f0be768ca9bac8b6c.css.map swh/web/static/css/vendors.2694d5473acd0a553474.css swh/web/static/css/vendors.2694d5473acd0a553474.css.map swh/web/static/css/webapp.97895616b93bddb8d6b1.css swh/web/static/css/webapp.97895616b93bddb8d6b1.css.map swh/web/static/fonts/alegreya-latin-400.woff swh/web/static/fonts/alegreya-latin-400.woff2 swh/web/static/fonts/alegreya-latin-400italic.woff swh/web/static/fonts/alegreya-latin-400italic.woff2 swh/web/static/fonts/alegreya-latin-500.woff swh/web/static/fonts/alegreya-latin-500.woff2 swh/web/static/fonts/alegreya-latin-500italic.woff swh/web/static/fonts/alegreya-latin-500italic.woff2 swh/web/static/fonts/alegreya-latin-700.woff swh/web/static/fonts/alegreya-latin-700.woff2 swh/web/static/fonts/alegreya-latin-700italic.woff swh/web/static/fonts/alegreya-latin-700italic.woff2 swh/web/static/fonts/alegreya-latin-800.woff swh/web/static/fonts/alegreya-latin-800.woff2 swh/web/static/fonts/alegreya-latin-800italic.woff swh/web/static/fonts/alegreya-latin-800italic.woff2 swh/web/static/fonts/alegreya-latin-900.woff swh/web/static/fonts/alegreya-latin-900.woff2 swh/web/static/fonts/alegreya-latin-900italic.woff swh/web/static/fonts/alegreya-latin-900italic.woff2 swh/web/static/fonts/alegreya-sans-latin-100.woff swh/web/static/fonts/alegreya-sans-latin-100.woff2 swh/web/static/fonts/alegreya-sans-latin-100italic.woff swh/web/static/fonts/alegreya-sans-latin-100italic.woff2 swh/web/static/fonts/alegreya-sans-latin-300.woff swh/web/static/fonts/alegreya-sans-latin-300.woff2 swh/web/static/fonts/alegreya-sans-latin-300italic.woff swh/web/static/fonts/alegreya-sans-latin-300italic.woff2 swh/web/static/fonts/alegreya-sans-latin-400.woff swh/web/static/fonts/alegreya-sans-latin-400.woff2 swh/web/static/fonts/alegreya-sans-latin-400italic.woff swh/web/static/fonts/alegreya-sans-latin-400italic.woff2 swh/web/static/fonts/alegreya-sans-latin-500.woff swh/web/static/fonts/alegreya-sans-latin-500.woff2 swh/web/static/fonts/alegreya-sans-latin-500italic.woff swh/web/static/fonts/alegreya-sans-latin-500italic.woff2 swh/web/static/fonts/alegreya-sans-latin-700.woff swh/web/static/fonts/alegreya-sans-latin-700.woff2 swh/web/static/fonts/alegreya-sans-latin-700italic.woff swh/web/static/fonts/alegreya-sans-latin-700italic.woff2 swh/web/static/fonts/alegreya-sans-latin-800.woff swh/web/static/fonts/alegreya-sans-latin-800.woff2 swh/web/static/fonts/alegreya-sans-latin-800italic.woff swh/web/static/fonts/alegreya-sans-latin-800italic.woff2 swh/web/static/fonts/alegreya-sans-latin-900.woff swh/web/static/fonts/alegreya-sans-latin-900.woff2 swh/web/static/fonts/alegreya-sans-latin-900italic.woff swh/web/static/fonts/alegreya-sans-latin-900italic.woff2 swh/web/static/fonts/fontawesome-webfont.eot swh/web/static/fonts/fontawesome-webfont.svg swh/web/static/fonts/fontawesome-webfont.ttf swh/web/static/fonts/fontawesome-webfont.woff swh/web/static/fonts/fontawesome-webfont.woff2 swh/web/static/fonts/octicons.eot swh/web/static/fonts/octicons.svg swh/web/static/fonts/octicons.ttf swh/web/static/fonts/octicons.woff swh/web/static/fonts/octicons.woff2 swh/web/static/img/arrow-up-small.png swh/web/static/img/swh-api.png swh/web/static/img/swh-browse.png swh/web/static/img/swh-logo.png swh/web/static/img/swh-logo.svg swh/web/static/img/swh-spinner-small.gif swh/web/static/img/swh-spinner.gif swh/web/static/img/swh-vault.png swh/web/static/img/icons/swh-logo-32x32.png swh/web/static/img/icons/swh-logo-archive-180x180.png swh/web/static/img/icons/swh-logo-archive-192x192.png swh/web/static/img/icons/swh-logo-archive-270x270.png swh/web/static/js/admin.a1e42404ef1ac75a42f4.js swh/web/static/js/admin.a1e42404ef1ac75a42f4.js.map -swh/web/static/js/browse.92378aae87894b0d9972.js -swh/web/static/js/browse.92378aae87894b0d9972.js.map +swh/web/static/js/browse.cec637f91d68ef766e5f.js +swh/web/static/js/browse.cec637f91d68ef766e5f.js.map swh/web/static/js/highlightjs.8999b6ccd00337cba3b8.js swh/web/static/js/highlightjs.8999b6ccd00337cba3b8.js.map swh/web/static/js/origin.c9b9c6c34c7967dc9329.js swh/web/static/js/origin.c9b9c6c34c7967dc9329.js.map swh/web/static/js/pdf.worker.min.js swh/web/static/js/pdfjs.a916084c8aca9b766bd3.js swh/web/static/js/pdfjs.a916084c8aca9b766bd3.js.map swh/web/static/js/revision.fb503b9a29a646435e5d.js swh/web/static/js/revision.fb503b9a29a646435e5d.js.map swh/web/static/js/showdown.5000791dba563908850c.js swh/web/static/js/showdown.5000791dba563908850c.js.map swh/web/static/js/vault.154f0be768ca9bac8b6c.js swh/web/static/js/vault.154f0be768ca9bac8b6c.js.map swh/web/static/js/vendors.2694d5473acd0a553474.js swh/web/static/js/vendors.2694d5473acd0a553474.js.map swh/web/static/js/webapp.97895616b93bddb8d6b1.js swh/web/static/js/webapp.97895616b93bddb8d6b1.js.map swh/web/templates/error.html swh/web/templates/homepage.html swh/web/templates/layout.html swh/web/templates/login.html swh/web/templates/logout.html swh/web/templates/admin/origin-save.html swh/web/templates/api/api.html swh/web/templates/api/apidoc.html swh/web/templates/api/endpoints.html swh/web/templates/browse/branches.html swh/web/templates/browse/browse.html swh/web/templates/browse/content.html swh/web/templates/browse/directory.html swh/web/templates/browse/help.html swh/web/templates/browse/layout.html swh/web/templates/browse/origin-save.html swh/web/templates/browse/origin-visits.html swh/web/templates/browse/person.html swh/web/templates/browse/release.html swh/web/templates/browse/releases.html swh/web/templates/browse/revision-log.html swh/web/templates/browse/revision.html swh/web/templates/browse/search.html swh/web/templates/browse/vault-ui.html swh/web/templates/includes/apidoc-header.html swh/web/templates/includes/apidoc-header.md swh/web/templates/includes/breadcrumbs.html swh/web/templates/includes/content-display.html swh/web/templates/includes/directory-display.html swh/web/templates/includes/global-modals.html swh/web/templates/includes/http-error.html swh/web/templates/includes/readme-display.html swh/web/templates/includes/show-metadata.html swh/web/templates/includes/show-swh-ids.html swh/web/templates/includes/snapshot-context.html swh/web/templates/includes/top-navigation.html swh/web/templates/includes/vault-create-tasks.html swh/web/tests/__init__.py swh/web/tests/testcase.py swh/web/tests/admin/__init__.py swh/web/tests/admin/test_origin_save.py swh/web/tests/api/__init__.py swh/web/tests/api/test_api_lookup.py swh/web/tests/api/test_apidoc.py swh/web/tests/api/test_apiresponse.py swh/web/tests/api/test_utils.py swh/web/tests/api/views/__init__.py swh/web/tests/api/views/test_content.py swh/web/tests/api/views/test_directory.py swh/web/tests/api/views/test_entity.py swh/web/tests/api/views/test_identifiers.py swh/web/tests/api/views/test_origin.py swh/web/tests/api/views/test_origin_save.py swh/web/tests/api/views/test_person.py swh/web/tests/api/views/test_release.py swh/web/tests/api/views/test_revision.py swh/web/tests/api/views/test_stat.py swh/web/tests/api/views/test_vault.py swh/web/tests/browse/__init__.py swh/web/tests/browse/test_utils.py swh/web/tests/browse/views/__init__.py swh/web/tests/browse/views/test_content.py swh/web/tests/browse/views/test_directory.py swh/web/tests/browse/views/test_identifiers.py swh/web/tests/browse/views/test_origin.py swh/web/tests/browse/views/test_person.py swh/web/tests/browse/views/test_release.py swh/web/tests/browse/views/test_revision.py swh/web/tests/browse/views/data/__init__.py swh/web/tests/browse/views/data/content_test_data.py swh/web/tests/browse/views/data/directory_test_data.py swh/web/tests/browse/views/data/iso-8859-1_encoded_content swh/web/tests/browse/views/data/origin_test_data.py swh/web/tests/browse/views/data/release_test_data.py swh/web/tests/browse/views/data/revision_test_data.py swh/web/tests/browse/views/data/swh-logo.png swh/web/tests/common/__init__.py swh/web/tests/common/test_converters.py swh/web/tests/common/test_highlightjs.py swh/web/tests/common/test_query.py swh/web/tests/common/test_service.py swh/web/tests/common/test_templatetags.py swh/web/tests/common/test_throttling.py swh/web/tests/common/test_utils.py \ No newline at end of file diff --git a/swh/web/assets/src/bundles/browse/origin-save.js b/swh/web/assets/src/bundles/browse/origin-save.js index 19133cf4..8f6cfc48 100644 --- a/swh/web/assets/src/bundles/browse/origin-save.js +++ b/swh/web/assets/src/bundles/browse/origin-save.js @@ -1,178 +1,187 @@ /** * Copyright (C) 2018 The Software Heritage developers * See the AUTHORS file at the top-level directory of this distribution * License: GNU Affero General Public License version 3, or any later version * See top-level LICENSE file for more information */ import {handleFetchError, csrfPost, isGitRepoUrl} from 'utils/functions'; import {validate} from 'validate.js'; let saveRequestsTable; export function initOriginSave() { $(document).ready(() => { fetch(Urls.browse_origin_save_types_list()) .then(response => response.json()) .then(data => { for (let originType of data) { $('#swh-input-origin-type').append(``); } }); saveRequestsTable = $('#swh-origin-save-requests').DataTable({ serverSide: true, ajax: Urls.browse_origin_save_requests_list('all'), columns: [ { data: 'save_request_date', name: 'request_date', render: (data, type, row) => { if (type === 'display') { let date = new Date(data); return date.toLocaleString(); } return data; } }, { data: 'origin_type', name: 'origin_type' }, { data: 'origin_url', name: 'origin_url', render: (data, type, row) => { if (type === 'display') { return `${data}`; } return data; } }, { data: 'save_request_status', name: 'status' }, { data: 'save_task_status', name: 'save_task_status', render: (data, type, row) => { if (data === 'succeed') { let browseOriginUrl = Urls.browse_origin(row.origin_url); if (row.visit_date) { browseOriginUrl += `visit/${row.visit_date}/`; } return `${data}`; } return data; } } ], scrollY: '50vh', scrollCollapse: true, order: [[0, 'desc']] }); setInterval(() => { saveRequestsTable.ajax.reload(null, false); }, 5000); $('#swh-origin-save-requests-list-tab').on('shown.bs.tab', () => { saveRequestsTable.draw(); }); $('#swh-save-origin-form').submit(event => { event.preventDefault(); event.stopPropagation(); if (event.target.checkValidity()) { $(event.target).removeClass('was-validated'); let originType = $('#swh-input-origin-type').val(); let originUrl = $('#swh-input-origin-url').val(); let addSaveOriginRequestUrl = Urls.browse_origin_save_request(originType, originUrl); let grecaptchaData = {'g-recaptcha-response': grecaptcha.getResponse()}; let headers = { 'Accept': 'application/json', 'Content-Type': 'application/json' }; let body = JSON.stringify(grecaptchaData); csrfPost(addSaveOriginRequestUrl, headers, body) .then(handleFetchError) .then(response => response.json()) .then(data => { if (data.save_request_status === 'accepted') { $('#swh-origin-save-request-status').css('color', 'green'); $('#swh-origin-save-request-status').text( 'The "save code now" request has been accepted and will be processed as soon as possible.'); } else { $('#swh-origin-save-request-status').css('color', '#fecd1b'); $('#swh-origin-save-request-status').text( 'The "save code now" request has been put in pending state and may be accepted for processing after manual review.'); } grecaptcha.reset(); }) .catch(response => { if (response.status === 403) { $('#swh-origin-save-request-status').css('color', 'red'); $('#swh-origin-save-request-status').text( 'The "save code now" request has been rejected because the reCAPTCHA could not be validated or the provided origin url is blacklisted.'); } grecaptcha.reset(); }); } else { $(event.target).addClass('was-validated'); } }); $('#swh-show-origin-save-requests-list').on('click', (event) => { event.preventDefault(); $('.nav-tabs a[href="#swh-origin-save-requests-list"]').tab('show'); }); $('#swh-input-origin-url').on('input', function(event) { - let originUrl = $(this).val(); + let originUrl = $(this).val().trim(); + $(this).val(originUrl); $('#swh-input-origin-type option').each(function() { let val = $(this).val(); if (val && originUrl.includes(val)) { $(this).prop('selected', true); } }); }); }); } export function validateSaveOriginUrl(input) { let validUrl = validate({website: input.value}, { website: { url: { schemes: ['http', 'https', 'svn', 'git'] } } }) === undefined; let originType = $('#swh-input-origin-type').val(); if (originType === 'git' && validUrl) { // additional checks for well known code hosting providers let githubIdx = input.value.indexOf('://github.com'); - let gitlabIdx = input.value.indexOf('://gitlab.com'); + let gitlabIdx = input.value.indexOf('://gitlab.'); let gitSfIdx = input.value.indexOf('://git.code.sf.net'); let bitbucketIdx = input.value.indexOf('://bitbucket.org'); if (githubIdx !== -1 && githubIdx <= 5) { validUrl = isGitRepoUrl(input.value, 'github.com'); } else if (gitlabIdx !== -1 && gitlabIdx <= 5) { - validUrl = isGitRepoUrl(input.value, 'gitlab.com'); + let startIdx = gitlabIdx + 3; + let idx = input.value.indexOf('/', startIdx); + if (idx !== -1) { + let gitlabDomain = input.value.substr(startIdx, idx - startIdx); + // GitLab repo url needs to be suffixed by '.git' in order to be successfully loaded + validUrl = isGitRepoUrl(input.value, gitlabDomain) && input.value.endsWith('.git'); + } else { + validUrl = false; + } } else if (gitSfIdx !== -1 && gitSfIdx <= 5) { validUrl = isGitRepoUrl(input.value, 'git.code.sf.net/p'); } else if (bitbucketIdx !== -1 && bitbucketIdx <= 5) { validUrl = isGitRepoUrl(input.value, 'bitbucket.org'); } } if (validUrl) { input.setCustomValidity(''); } else { input.setCustomValidity('The origin url is not valid or does not reference a code repository'); } } diff --git a/swh/web/assets/src/bundles/browse/origin-search.js b/swh/web/assets/src/bundles/browse/origin-search.js index aaa3036c..6c7df1b3 100644 --- a/swh/web/assets/src/bundles/browse/origin-search.js +++ b/swh/web/assets/src/bundles/browse/origin-search.js @@ -1,223 +1,223 @@ /** * Copyright (C) 2018 The Software Heritage developers * See the AUTHORS file at the top-level directory of this distribution * License: GNU Affero General Public License version 3, or any later version * See top-level LICENSE file for more information */ import {heapsPermute} from 'utils/heaps-permute'; import {handleFetchError} from 'utils/functions'; let originPatterns; let perPage = 20; let limit = perPage * 10; let offset = 0; let currentData = null; let inSearch = false; function fixTableRowsStyle() { setTimeout(() => { $('#origin-search-results tbody tr').removeAttr('style'); }); } function clearOriginSearchResultsTable() { $('#origin-search-results tbody tr').remove(); } function populateOriginSearchResultsTable(data, offset) { let localOffset = offset % limit; if (data.length > 0) { $('#swh-origin-search-results').show(); $('#swh-no-result').hide(); clearOriginSearchResultsTable(); let table = $('#origin-search-results tbody'); for (let i = localOffset; i < localOffset + perPage && i < data.length; ++i) { let elem = data[i]; let tableRow = ''; tableRow += '' + elem.type + ''; let browseUrl = Urls.browse_origin(elem.url); tableRow += '' + browseUrl + ''; tableRow += ''; tableRow += ''; table.append(tableRow); // get async latest visit snapshot and update visit status icon let latestSnapshotUrl = Urls.browse_origin_latest_snapshot(elem.id); fetch(latestSnapshotUrl) .then(response => response.json()) .then(data => { let originId = elem.id; $('#visit-status-origin-' + originId).children().remove(); if (data) { $('#visit-status-origin-' + originId).append(''); } else { $('#visit-status-origin-' + originId).append(''); } }); } fixTableRowsStyle(); } else { $('#swh-origin-search-results').hide(); $('#swh-no-result').text('No origins matching the search criteria were found.'); $('#swh-no-result').show(); } if (data.length - localOffset < perPage || (data.length < limit && (localOffset + perPage) === data.length)) { $('#origins-next-results-button').addClass('disabled'); } else { $('#origins-next-results-button').removeClass('disabled'); } if (offset > 0) { $('#origins-prev-results-button').removeClass('disabled'); } else { $('#origins-prev-results-button').addClass('disabled'); } inSearch = false; if (typeof Storage !== 'undefined') { sessionStorage.setItem('last-swh-origin-search-offset', offset); } setTimeout(() => { window.scrollTo(0, 0); }); } function escapeStringRegexp(str) { let matchOperatorsRe = /[|\\{}()[\]^$+*?.]/g; return str.replace(matchOperatorsRe, '\\\\\\$&'); } function searchOrigins(patterns, limit, searchOffset, offset) { originPatterns = patterns; let patternsArray = patterns.trim().replace(/\s+/g, ' ').split(' '); for (let i = 0; i < patternsArray.length; ++i) { patternsArray[i] = escapeStringRegexp(patternsArray[i]); } let patternsPermut = []; heapsPermute(patternsArray, p => patternsPermut.push(p.join('.*'))); let regex = patternsPermut.join('|'); let withVisit = $('#swh-search-origins-with-visit').prop('checked'); let searchUrl = Urls.browse_origin_search(regex) + `?limit=${limit}&offset=${searchOffset}®exp=true&with_visit=${withVisit}`; clearOriginSearchResultsTable(); $('.swh-loading').addClass('show'); fetch(searchUrl) .then(handleFetchError) .then(response => response.json()) .then(data => { currentData = data; if (typeof Storage !== 'undefined') { sessionStorage.setItem('last-swh-origin-url-patterns', patterns); sessionStorage.setItem('last-swh-origin-search-results', JSON.stringify(data)); sessionStorage.setItem('last-swh-origin-search-offset', offset); } $('.swh-loading').removeClass('show'); populateOriginSearchResultsTable(data, offset); }) .catch(response => { $('.swh-loading').removeClass('show'); inSearch = false; $('#swh-origin-search-results').hide(); response.text().then(errorDescription => { $('#swh-no-result').text(`Error ${response.status}: ${response.statusText}.\n${errorDescription}`); $('#swh-no-result').show(); }); }); } export function initOriginSearch() { $(document).ready(() => { if (typeof Storage !== 'undefined') { originPatterns = sessionStorage.getItem('last-swh-origin-url-patterns'); let data = sessionStorage.getItem('last-swh-origin-search-results'); offset = sessionStorage.getItem('last-swh-origin-search-offset'); if (data) { $('#origins-url-patterns').val(originPatterns); offset = parseInt(offset); currentData = JSON.parse(data); populateOriginSearchResultsTable(currentData, offset); } let withVisit = sessionStorage.getItem('last-swh-origin-with-visit'); if (withVisit !== null) { $('#swh-search-origins-with-visit').prop('checked', JSON.parse(withVisit)); } } - $('#search_origins').submit(event => { + $('#swh-search-origins').submit(event => { event.preventDefault(); $('#swh-no-result').hide(); let patterns = $('#origins-url-patterns').val(); offset = 0; inSearch = true; // first try to resolve a swh persistent identifier let resolvePidUrl = Urls.resolve_swh_pid(patterns); fetch(resolvePidUrl) .then(handleFetchError) .then(response => response.json()) .then(data => { // pid has been successfully resolved, // so redirect to browse page window.location = data.browse_url; }) .catch(response => { // pid resolving failed if (patterns.startsWith('swh:')) { // display a useful error message if the input // looks like a swh pid response.json().then(data => { $('#swh-origin-search-results').hide(); $('.swh-search-pagination').hide(); $('#swh-no-result').text(data.reason); $('#swh-no-result').show(); }); } else { // otherwise, proceed with origins search $('#swh-origin-search-results').show(); $('.swh-search-pagination').show(); searchOrigins(patterns, limit, offset, offset); } }); }); $('#origins-next-results-button').click(event => { if ($('#origins-next-results-button').hasClass('disabled') || inSearch) { return; } inSearch = true; offset += perPage; if (!currentData || (offset >= limit && offset % limit === 0)) { searchOrigins(originPatterns, limit, offset, offset); } else { populateOriginSearchResultsTable(currentData, offset); } event.preventDefault(); }); $('#origins-prev-results-button').click(event => { if ($('#origins-prev-results-button').hasClass('disabled') || inSearch) { return; } inSearch = true; offset -= perPage; if (!currentData || (offset > 0 && (offset + perPage) % limit === 0)) { searchOrigins(originPatterns, limit, (offset + perPage) - limit, offset); } else { populateOriginSearchResultsTable(currentData, offset); } event.preventDefault(); }); $(document).on('shown.bs.tab', 'a[data-toggle="tab"]', e => { if (e.currentTarget.text.trim() === 'Search') { fixTableRowsStyle(); } }); $(window).on('unload', () => { if (typeof Storage !== 'undefined') { sessionStorage.setItem('last-swh-origin-with-visit', JSON.stringify($('#swh-search-origins-with-visit').prop('checked'))); } }); }); } diff --git a/swh/web/common/migrations/0002_saveoriginrequest_visit_date.py b/swh/web/common/migrations/0002_saveoriginrequest_visit_date.py index b347cb9a..0847505e 100644 --- a/swh/web/common/migrations/0002_saveoriginrequest_visit_date.py +++ b/swh/web/common/migrations/0002_saveoriginrequest_visit_date.py @@ -1,20 +1,23 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.10.7 on 2018-09-11 14:53 +# Copyright (C) 2018 The Software Heritage developers +# See the AUTHORS file at the top-level directory of this distribution +# License: GNU Affero General Public License version 3, or any later version +# See top-level LICENSE file for more information + from __future__ import unicode_literals from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ('swh.web.common', '0001_initial'), ] operations = [ migrations.AddField( model_name='saveoriginrequest', name='visit_date', field=models.DateTimeField(null=True), ), ] diff --git a/swh/web/common/migrations/0003_saveoriginrequest_loading_task_status.py b/swh/web/common/migrations/0003_saveoriginrequest_loading_task_status.py new file mode 100644 index 00000000..5b32752a --- /dev/null +++ b/swh/web/common/migrations/0003_saveoriginrequest_loading_task_status.py @@ -0,0 +1,44 @@ +# Copyright (C) 2018 The Software Heritage developers +# See the AUTHORS file at the top-level directory of this distribution +# License: GNU Affero General Public License version 3, or any later version +# See top-level LICENSE file for more information + +# flake8: noqa + +from __future__ import unicode_literals + +from django.db import migrations, models + +from swh.web.config import scheduler + +def _remove_archived_tasks_with_no_saved_status(apps, schema_editor): + """ + Scheduler tasks are archived on a regular basis so their completion + state could not be known anymore as previous to this migration, + the loading task status was not stored in the database. + So remove the rows associated to already archived tasks as + the loading status can not be retrieved anymore. + """ + SaveOriginRequest = apps.get_model('swh.web.common', 'SaveOriginRequest') + no_saved_status_tasks = [] + for sor in SaveOriginRequest.objects.all(): + tasks = scheduler().get_tasks([sor.loading_task_id]) + if not tasks: + no_saved_status_tasks.append(sor.loading_task_id) + SaveOriginRequest.objects.filter(loading_task_id__in=no_saved_status_tasks).delete() + + +class Migration(migrations.Migration): + + dependencies = [ + ('swh.web.common', '0002_saveoriginrequest_visit_date'), + ] + + operations = [ + migrations.AddField( + model_name='saveoriginrequest', + name='loading_task_status', + field=models.TextField(choices=[('not created', 'not created'), ('not yet scheduled', 'not yet scheduled'), ('scheduled', 'scheduled'), ('succeed', 'succeed'), ('failed', 'failed')], default='not created'), + ), + migrations.RunPython(_remove_archived_tasks_with_no_saved_status) + ] diff --git a/swh/web/common/models.py b/swh/web/common/models.py index 3852bc8b..297c322b 100644 --- a/swh/web/common/models.py +++ b/swh/web/common/models.py @@ -1,74 +1,90 @@ # Copyright (C) 2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from django.db import models class SaveAuthorizedOrigin(models.Model): """ Model table holding origin urls authorized to be loaded into the archive. """ url = models.CharField(max_length=200, null=False) class Meta: app_label = 'swh.web.common' db_table = 'save_authorized_origin' def __str__(self): return self.url class SaveUnauthorizedOrigin(models.Model): """ Model table holding origin urls not authorized to be loaded into the archive. """ url = models.CharField(max_length=200, null=False) class Meta: app_label = 'swh.web.common' db_table = 'save_unauthorized_origin' def __str__(self): return self.url SAVE_REQUEST_ACCEPTED = 'accepted' SAVE_REQUEST_REJECTED = 'rejected' SAVE_REQUEST_PENDING = 'pending' SAVE_REQUEST_STATUS = [ (SAVE_REQUEST_ACCEPTED, SAVE_REQUEST_ACCEPTED), (SAVE_REQUEST_REJECTED, SAVE_REQUEST_REJECTED), (SAVE_REQUEST_PENDING, SAVE_REQUEST_PENDING) ] +SAVE_TASK_NOT_CREATED = 'not created' +SAVE_TASK_NOT_YET_SCHEDULED = 'not yet scheduled' +SAVE_TASK_SCHEDULED = 'scheduled' +SAVE_TASK_SUCCEED = 'succeed' +SAVE_TASK_FAILED = 'failed' + +SAVE_TASK_STATUS = [ + (SAVE_TASK_NOT_CREATED, SAVE_TASK_NOT_CREATED), + (SAVE_TASK_NOT_YET_SCHEDULED, SAVE_TASK_NOT_YET_SCHEDULED), + (SAVE_TASK_SCHEDULED, SAVE_TASK_SCHEDULED), + (SAVE_TASK_SUCCEED, SAVE_TASK_SUCCEED), + (SAVE_TASK_FAILED, SAVE_TASK_FAILED) +] + class SaveOriginRequest(models.Model): """ Model table holding all the save origin requests issued by users. """ id = models.BigAutoField(primary_key=True) request_date = models.DateTimeField(auto_now_add=True) origin_type = models.CharField(max_length=200, null=False) origin_url = models.CharField(max_length=200, null=False) status = models.TextField(choices=SAVE_REQUEST_STATUS, default=SAVE_REQUEST_PENDING) loading_task_id = models.IntegerField(default=-1) visit_date = models.DateTimeField(null=True) + loading_task_status = models.TextField(choices=SAVE_TASK_STATUS, + default=SAVE_TASK_NOT_CREATED) class Meta: app_label = 'swh.web.common' db_table = 'save_origin_request' ordering = ['-id'] def __str__(self): return str({'id': self.id, 'request_date': self.request_date, 'origin_type': self.origin_type, 'origin_url': self.origin_url, 'status': self.status, 'loading_task_id': self.loading_task_id, 'visit_date': self.visit_date}) diff --git a/swh/web/common/origin_save.py b/swh/web/common/origin_save.py index 2b229856..87f7278c 100644 --- a/swh/web/common/origin_save.py +++ b/swh/web/common/origin_save.py @@ -1,351 +1,349 @@ # Copyright (C) 2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from bisect import bisect_right from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ValidationError from django.core.validators import URLValidator from swh.web import config from swh.web.common import service from swh.web.common.exc import BadInputExc, ForbiddenExc from swh.web.common.models import ( SaveUnauthorizedOrigin, SaveAuthorizedOrigin, SaveOriginRequest, - SAVE_REQUEST_ACCEPTED, SAVE_REQUEST_REJECTED, SAVE_REQUEST_PENDING + SAVE_REQUEST_ACCEPTED, SAVE_REQUEST_REJECTED, SAVE_REQUEST_PENDING, + SAVE_TASK_NOT_YET_SCHEDULED, SAVE_TASK_SCHEDULED, + SAVE_TASK_SUCCEED, SAVE_TASK_FAILED ) from swh.web.common.utils import get_origin_visits, parse_timestamp from swh.scheduler.utils import create_oneshot_task_dict scheduler = config.scheduler() def get_origin_save_authorized_urls(): """ Get the list of origin url prefixes authorized to be immediately loaded into the archive (whitelist). Returns: list: The list of authorized origin url prefix """ return [origin.url for origin in SaveAuthorizedOrigin.objects.all()] def get_origin_save_unauthorized_urls(): """ Get the list of origin url prefixes forbidden to be loaded into the archive (blacklist). Returns: list: the list of unauthorized origin url prefix """ return [origin.url for origin in SaveUnauthorizedOrigin.objects.all()] def can_save_origin(origin_url): """ Check if a software origin can be saved into the archive. Based on the origin url, the save request will be either: * immediately accepted if the url is whitelisted * rejected if the url is blacklisted * put in pending state for manual review otherwise Args: origin_url (str): the software origin url to check Returns: str: the origin save request status, either *accepted*, *rejected* or *pending* """ # origin url may be blacklisted for url_prefix in get_origin_save_unauthorized_urls(): if origin_url.startswith(url_prefix): return SAVE_REQUEST_REJECTED # if the origin url is in the white list, it can be immediately saved for url_prefix in get_origin_save_authorized_urls(): if origin_url.startswith(url_prefix): return SAVE_REQUEST_ACCEPTED # otherwise, the origin url needs to be manually verified return SAVE_REQUEST_PENDING # map origin type to scheduler task # TODO: do not hardcode the task name here # TODO: unlock hg and svn loading once the scheduler # loading tasks are available in production _origin_type_task = { 'git': 'origin-update-git', # 'hg': 'origin-load-hg', # 'svn': 'origin-load-svn' } -SAVE_TASK_NOT_CREATED = 'not created' -SAVE_TASK_NOT_YET_SCHEDULED = 'not yet scheduled' -SAVE_TASK_SCHEDULED = 'scheduled' -SAVE_TASK_SUCCEED = 'succeed' -SAVE_TASK_FAILED = 'failed' # map scheduler task status to origin save status _save_task_status = { 'next_run_not_scheduled': SAVE_TASK_NOT_YET_SCHEDULED, 'next_run_scheduled': SAVE_TASK_SCHEDULED, 'completed': SAVE_TASK_SUCCEED, 'disabled': SAVE_TASK_FAILED } def get_savable_origin_types(): return sorted(list(_origin_type_task.keys())) def _check_origin_type_savable(origin_type): """ Get the list of software origin types that can be loaded through a save request. Returns: list: the list of savable origin types """ allowed_origin_types = ', '.join(get_savable_origin_types()) if origin_type not in _origin_type_task: raise BadInputExc('Origin of type %s can not be saved! ' 'Allowed types are the following: %s' % (origin_type, allowed_origin_types)) _validate_url = URLValidator(schemes=['http', 'https', 'svn', 'git']) def _check_origin_url_valid(origin_url): try: _validate_url(origin_url) except ValidationError: raise BadInputExc('The provided origin url (%s) is not valid!' % origin_url) def _get_visit_date_for_save_request(save_request): visit_date = None try: origin = {'type': save_request.origin_type, 'url': save_request.origin_url} origin_info = service.lookup_origin(origin) origin_visits = get_origin_visits(origin_info) visit_dates = [parse_timestamp(v['date']) for v in origin_visits] i = bisect_right(visit_dates, save_request.request_date) if i != len(visit_dates): save_request.visit_date = visit_dates[i] save_request.save() visit_date = visit_dates[i] except Exception: pass return visit_date def _save_request_dict(save_request, task=None): - save_task_status = SAVE_TASK_NOT_CREATED visit_date = save_request.visit_date if task: save_task_status = _save_task_status[task['status']] if save_task_status in (SAVE_TASK_FAILED, SAVE_TASK_SUCCEED) \ and not visit_date: visit_date = _get_visit_date_for_save_request(save_request) # Ensure last origin visit is available in database # before reporting the task execution as successful if save_task_status == SAVE_TASK_SUCCEED and not visit_date: save_task_status = SAVE_TASK_SCHEDULED + save_request.loading_task_status = save_task_status + save_request.save() + else: + save_task_status = save_request.loading_task_status return {'origin_type': save_request.origin_type, 'origin_url': save_request.origin_url, 'save_request_date': save_request.request_date.isoformat(), 'save_request_status': save_request.status, 'save_task_status': save_task_status, 'visit_date': visit_date.isoformat() if visit_date else None} def create_save_origin_request(origin_type, origin_url): """ Create a loading task to save a software origin into the archive. This function aims to create a software origin loading task trough the use of the swh-scheduler component. First, some checks are performed to see if the origin type and url are valid but also if the the save request can be accepted. If those checks passed, the loading task is then created. Otherwise, the save request is put in pending or rejected state. All the submitted save requests are logged into the swh-web database to keep track of them. Args: origin_type (str): the type of origin to save (*git*, *hg*, *svn*, ...) origin_url (str): the url of the origin to save Raises: BadInputExc: the origin type or url is invalid ForbiddenExc: the provided origin url is blacklisted Returns: dict: A dict describing the save request with the following keys: * **origin_type**: the type of the origin to save * **origin_url**: the url of the origin * **save_request_date**: the date the request was submitted * **save_request_status**: the request status, either *accepted*, *rejected* or *pending* * **save_task_status**: the origin loading task status, either *not created*, *not yet scheduled*, *scheduled*, *succeed* or *failed* """ _check_origin_type_savable(origin_type) _check_origin_url_valid(origin_url) save_request_status = can_save_origin(origin_url) task = None # if the origin save request is accepted, create a scheduler # task to load it into the archive if save_request_status == SAVE_REQUEST_ACCEPTED: # create a task with high priority kwargs = {'priority': 'high'} # set task parameters according to the origin type if origin_type == 'git': kwargs['repo_url'] = origin_url elif origin_type == 'hg': kwargs['origin_url'] = origin_url elif origin_type == 'svn': kwargs['origin_url'] = origin_url kwargs['svn_url'] = origin_url sor = None # get list of previously sumitted save requests current_sors = \ list(SaveOriginRequest.objects.filter(origin_type=origin_type, origin_url=origin_url)) can_create_task = False # if no save requests previously submitted, create the scheduler task if not current_sors: can_create_task = True else: # get the latest submitted save request sor = current_sors[0] # if it was in pending state, we need to create the scheduler task # and update the save request info in the database if sor.status == SAVE_REQUEST_PENDING: can_create_task = True # a task has already been created to load the origin elif sor.loading_task_id != -1: # get the scheduler task and its status task = scheduler.get_tasks([sor.loading_task_id])[0] save_task_status = _save_task_status[task['status']] # create a new scheduler task only if the previous one has been # already executed if save_task_status == SAVE_TASK_FAILED or \ save_task_status == SAVE_TASK_SUCCEED: can_create_task = True sor = None else: can_create_task = False if can_create_task: # effectively create the scheduler task task_dict = create_oneshot_task_dict( _origin_type_task[origin_type], **kwargs) task = scheduler.create_tasks([task_dict])[0] # pending save request has been accepted if sor: sor.status = SAVE_REQUEST_ACCEPTED sor.loading_task_id = task['id'] sor.save() else: sor = SaveOriginRequest.objects.create(origin_type=origin_type, origin_url=origin_url, status=save_request_status, # noqa loading_task_id=task['id']) # noqa # save request must be manually reviewed for acceptation elif save_request_status == SAVE_REQUEST_PENDING: # check if there is already such a save request already submitted, # no need to add it to the database in that case try: sor = SaveOriginRequest.objects.get(origin_type=origin_type, origin_url=origin_url, status=save_request_status) # if not add it to the database except ObjectDoesNotExist: sor = SaveOriginRequest.objects.create(origin_type=origin_type, origin_url=origin_url, status=save_request_status) # origin can not be saved as its url is blacklisted, # log the request to the database anyway else: sor = SaveOriginRequest.objects.create(origin_type=origin_type, origin_url=origin_url, status=save_request_status) if save_request_status == SAVE_REQUEST_REJECTED: raise ForbiddenExc('The origin url is blacklisted and will not be ' 'loaded into the archive.') return _save_request_dict(sor, task) def get_save_origin_requests_from_queryset(requests_queryset): """ Get all save requests from a SaveOriginRequest queryset. Args: requests_queryset (django.db.models.QuerySet): input SaveOriginRequest queryset Returns: list: A list of save origin requests dict as described in :func:`swh.web.common.origin_save.create_save_origin_request` """ requests = [] for sor in requests_queryset: - # rejected saving task or pending for acceptation - if sor.loading_task_id == -1: - requests.append(_save_request_dict(sor)) - continue - task = scheduler.get_tasks([sor.loading_task_id]) - # loading task may have been archived, do not return - # save request info in that case - if task: - requests.append(_save_request_dict(sor, task[0])) + task = None + # save task has not been created, no need to query + # the scheduler API + if sor.loading_task_id != -1: + tasks = scheduler.get_tasks([sor.loading_task_id]) + task = tasks[0] if tasks else None + requests.append(_save_request_dict(sor, task)) return requests def get_save_origin_requests(origin_type, origin_url): """ Get all save requests for a given software origin. Args: origin_type (str): the type of the origin origin_url (str): the url of the origin Raises: BadInputExc: the origin type or url is invalid Returns: list: A list of save origin requests dict as described in :func:`swh.web.common.origin_save.create_save_origin_request` """ _check_origin_type_savable(origin_type) _check_origin_url_valid(origin_url) sors = SaveOriginRequest.objects.filter(origin_type=origin_type, origin_url=origin_url) return get_save_origin_requests_from_queryset(sors) diff --git a/swh/web/static/css/browse.92378aae87894b0d9972.css b/swh/web/static/css/browse.cec637f91d68ef766e5f.css similarity index 100% rename from swh/web/static/css/browse.92378aae87894b0d9972.css rename to swh/web/static/css/browse.cec637f91d68ef766e5f.css diff --git a/swh/web/static/css/browse.92378aae87894b0d9972.css.map b/swh/web/static/css/browse.cec637f91d68ef766e5f.css.map similarity index 98% rename from swh/web/static/css/browse.92378aae87894b0d9972.css.map rename to swh/web/static/css/browse.cec637f91d68ef766e5f.css.map index c23c9931..846d159a 100644 --- a/swh/web/static/css/browse.92378aae87894b0d9972.css.map +++ b/swh/web/static/css/browse.cec637f91d68ef766e5f.css.map @@ -1 +1 @@ -{"version":3,"sources":["/home/ndandrim/work/swh-environment/swh-web/swh/web/assets/src/bundles/browse/browse.css","/home/ndandrim/work/swh-environment/swh-web/swh/web/assets/src/bundles/browse/breadcrumbs.css","/home/ndandrim/work/swh-environment/swh-web/swh/web/assets/src/bundles/browse/content.css","/home/ndandrim/work/swh-environment/swh-web/swh/web/assets/src/bundles/browse/snapshot-navigation.css","/home/ndandrim/work/swh-environment/swh-web/swh/web/assets/src/utils/jquery.tabSlideOut.css"],"names":[],"mappings":"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","file":"browse.92378aae87894b0d9972.css","sourcesContent":["/**\n * Copyright (C) 2018 The Software Heritage developers\n * See the AUTHORS file at the top-level directory of this distribution\n * License: GNU Affero General Public License version 3, or any later version\n * See top-level LICENSE file for more information\n */\n\n.swh-browse-nav li a {\n border-radius: 4px;\n}\n\n.scrollable-menu {\n max-height: 180px;\n overflow-x: hidden;\n}\n\n.swh-corner-ribbon {\n width: 200px;\n background: #fecd1b;\n color: #e20026;\n position: absolute;\n text-align: center;\n line-height: 50px;\n letter-spacing: 1px;\n box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);\n top: 55px;\n right: -50px;\n left: auto;\n transform: rotate(45deg);\n z-index: 2000;\n}\n\n.swh-loading {\n display: none;\n text-align: center;\n margin-top: 10px;\n}\n\n.swh-loading.show {\n display: block;\n}\n\n.swh-metadata-table-row {\n border-top: 1px solid #ddd !important;\n}\n\n.swh-metadata-table-key {\n min-width: 200px;\n max-width: 200px;\n width: 200px;\n}\n\n.swh-metadata-table-value pre {\n white-space: pre-wrap;\n}\n\n.swh-table-even-odd th {\n border-top: none;\n}\n\n.swh-table-even-odd tr:nth-child(even) {\n background-color: #f5f5f5;\n}\n\n.swh-table-even-odd tr:nth-child(odd) {\n background-color: #fff;\n}\n\n.swh-table-cell-text-overflow {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.swh-directory-table {\n margin-bottom: 0;\n}\n\n.swh-directory-table td {\n border-top: 1px solid #ddd !important;\n}\n\n.swh-title-color {\n color: #e20026;\n}\n\n.swh-log-entry-message {\n min-width: 460px;\n max-width: 460px;\n width: 460px;\n}\n\n.swh-popover {\n max-height: 50vh;\n max-width: 80vw;\n overflow-y: auto;\n overflow-x: auto;\n padding: 0;\n padding-right: 1.4em;\n}\n\n.swh-search-pagination {\n margin-top: 5px;\n}\n\n.ui-slideouttab-panel {\n z-index: 30000;\n}\n\n#swh-identifiers {\n width: 70vw;\n top: 0;\n border: 1px solid #e20026;\n}\n\n#swh-identifiers .handle {\n background-color: #e20026;\n border: 1px solid #e20026;\n color: white;\n padding-top: 0.1em;\n padding-bottom: 0.1em;\n}\n\n#swh-identifiers-content {\n height: 100%;\n overflow: auto;\n}\n","/**\n * Copyright (C) 2018 The Software Heritage developers\n * See the AUTHORS file at the top-level directory of this distribution\n * License: GNU Affero General Public License version 3, or any later version\n * See top-level LICENSE file for more information\n */\n\n.swh-browse-bread-crumbs {\n font-size: inherit;\n vertical-align: text-top;\n margin-bottom: 1px;\n}\n\n.swh-browse-bread-crumbs li:nth-child(n+2)::before {\n content: \"\";\n display: inline-block;\n margin: 0 2px;\n}\n","/**\n * Copyright (C) 2018 The Software Heritage developers\n * See the AUTHORS file at the top-level directory of this distribution\n * License: GNU Affero General Public License version 3, or any later version\n * See top-level LICENSE file for more information\n */\n\n.swh-content {\n background-image: none;\n border: none;\n background-color: white;\n padding: 0;\n}\n\n.swh-content pre,\n.swh-content pre code {\n margin: 0;\n padding: 0;\n}\n","/**\n * Copyright (C) 2018 The Software Heritage developers\n * See the AUTHORS file at the top-level directory of this distribution\n * License: GNU Affero General Public License version 3, or any later version\n * See top-level LICENSE file for more information\n */\n\n.swh-browse-top-navigation {\n border-bottom: 1px solid #ddd;\n min-height: 40px;\n padding: 4px 5px 0 5px;\n}\n\n.swh-branches-releases {\n min-width: 200px;\n}\n\n.swh-branches-switch,\n.swh-releases-switch {\n padding: 5px 15px !important;\n}\n\nli.swh-branch:hover,\nli.swh-release:hover {\n background-color: #e8e8e8;\n}\n\n.nav a,\n.swh-branch a,\n.swh-release a {\n outline: none;\n}\n\n.swh-branch a:hover,\n.swh-release a:hover {\n text-decoration: none;\n}\n\n.swh-origin-visit-details,\n.swh-snapshot-details {\n text-align: center;\n}\n\n.swh-origin-visit-details ul,\n.swh-snapshot-details ul {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.swh-origin-visit-details li,\n.swh-snapshot-details li {\n display: inline-block;\n vertical-align: middle;\n margin-left: 10px;\n margin-right: 10px;\n}\n","/*\n tabSlideOUt v2.4\n\n By Michael Fielding\n License: GPL v3.0\n*/\n\n.ui-slideouttab-panel,\n.ui-slideouttab-handle {\n background-color: white;\n padding: 0.4em;\n box-sizing: border-box;\n}\n\n.ui-slideouttab-panel {\n display: block;\n position: fixed;\n border: 2px solid grey;\n}\n\n/* This class is added after the tabs are initialised, otherwise the user sees the\n tabs slide out of the way when the page is initialised. */\n.ui-slideouttab-ready {\n transition: transform 0.5s ease 0s;\n}\n\n/* Hide tabs and panels when printed. */\n@media print {\n .ui-slideouttab-panel {\n display: none;\n }\n}\n\n/* Tab handles */\n.ui-slideouttab-handle {\n display: block;\n position: absolute;\n cursor: pointer;\n color: white;\n background-color: grey;\n}\n\n.ui-slideouttab-handle-image {\n transform: rotate(0);\n}\n\n/* Right */\n.ui-slideouttab-right {\n right: 0;\n transform: translateX(100%);\n border-right: none;\n}\n\n.ui-slideouttab-right.ui-slideouttab-open {\n transform: translateX(0%);\n}\n\n.ui-slideouttab-right .ui-slideouttab-handle {\n transform-origin: 0% 0%;\n transform: rotate(-90deg) translate(-100%, -100%);\n}\n\n.ui-slideouttab-right .ui-slideouttab-handle-reverse {\n transform-origin: 0% 100%;\n transform: rotate(-90deg);\n}\n\n/* Left */\n.ui-slideouttab-left {\n left: 0;\n transform: translateX(-100%);\n border-left: none;\n}\n\n.ui-slideouttab-left.ui-slideouttab-open {\n transform: translateX(0%);\n}\n\n.ui-slideouttab-left .ui-slideouttab-handle {\n transform-origin: 100% 0%;\n transform: rotate(-90deg);\n}\n\n.ui-slideouttab-left .ui-slideouttab-handle-reverse {\n transform-origin: 100% 100%;\n transform: rotate(-90deg) translate(100%, 100%);\n}\n\n/* Top */\n.ui-slideouttab-top {\n top: 0;\n transform: translateY(-100%);\n border-top: none;\n}\n\n.ui-slideouttab-top.ui-slideouttab-open {\n transform: translateY(0%);\n}\n\n/* Bottom */\n.ui-slideouttab-bottom {\n bottom: 0;\n transform: translateY(100%);\n border-bottom: none;\n}\n\n.ui-slideouttab-bottom.ui-slideouttab-open {\n transform: translateY(0%);\n}\n\n/* turn font awesome icon in a tab upright */\n.ui-slideouttab-left .ui-slideouttab-handle > .fa-icon,\n.ui-slideouttab-right .ui-slideouttab-handle > .fa-icon {\n transform: rotate(90deg);\n}\n\n.ui-slideouttab-handle > .fa-icon {\n margin-left: 0.5em;\n}\n\n/* apply rounded corners if handle has the -rounded class */\n.ui-slideouttab-top .ui-slideouttab-handle-rounded,\n.ui-slideouttab-left .ui-slideouttab-handle-rounded {\n border-radius: 0 0 4px 4px;\n}\n\n.ui-slideouttab-right .ui-slideouttab-handle-rounded,\n.ui-slideouttab-bottom .ui-slideouttab-handle-rounded {\n border-radius: 4px 4px 0 0;\n}\n"]} \ No newline at end of file +{"version":3,"sources":["/home/ndandrim/work/swh-environment/swh-web/swh/web/assets/src/bundles/browse/browse.css","/home/ndandrim/work/swh-environment/swh-web/swh/web/assets/src/bundles/browse/breadcrumbs.css","/home/ndandrim/work/swh-environment/swh-web/swh/web/assets/src/bundles/browse/content.css","/home/ndandrim/work/swh-environment/swh-web/swh/web/assets/src/bundles/browse/snapshot-navigation.css","/home/ndandrim/work/swh-environment/swh-web/swh/web/assets/src/utils/jquery.tabSlideOut.css"],"names":[],"mappings":"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","file":"browse.cec637f91d68ef766e5f.css","sourcesContent":["/**\n * Copyright (C) 2018 The Software Heritage developers\n * See the AUTHORS file at the top-level directory of this distribution\n * License: GNU Affero General Public License version 3, or any later version\n * See top-level LICENSE file for more information\n */\n\n.swh-browse-nav li a {\n border-radius: 4px;\n}\n\n.scrollable-menu {\n max-height: 180px;\n overflow-x: hidden;\n}\n\n.swh-corner-ribbon {\n width: 200px;\n background: #fecd1b;\n color: #e20026;\n position: absolute;\n text-align: center;\n line-height: 50px;\n letter-spacing: 1px;\n box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);\n top: 55px;\n right: -50px;\n left: auto;\n transform: rotate(45deg);\n z-index: 2000;\n}\n\n.swh-loading {\n display: none;\n text-align: center;\n margin-top: 10px;\n}\n\n.swh-loading.show {\n display: block;\n}\n\n.swh-metadata-table-row {\n border-top: 1px solid #ddd !important;\n}\n\n.swh-metadata-table-key {\n min-width: 200px;\n max-width: 200px;\n width: 200px;\n}\n\n.swh-metadata-table-value pre {\n white-space: pre-wrap;\n}\n\n.swh-table-even-odd th {\n border-top: none;\n}\n\n.swh-table-even-odd tr:nth-child(even) {\n background-color: #f5f5f5;\n}\n\n.swh-table-even-odd tr:nth-child(odd) {\n background-color: #fff;\n}\n\n.swh-table-cell-text-overflow {\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n\n.swh-directory-table {\n margin-bottom: 0;\n}\n\n.swh-directory-table td {\n border-top: 1px solid #ddd !important;\n}\n\n.swh-title-color {\n color: #e20026;\n}\n\n.swh-log-entry-message {\n min-width: 460px;\n max-width: 460px;\n width: 460px;\n}\n\n.swh-popover {\n max-height: 50vh;\n max-width: 80vw;\n overflow-y: auto;\n overflow-x: auto;\n padding: 0;\n padding-right: 1.4em;\n}\n\n.swh-search-pagination {\n margin-top: 5px;\n}\n\n.ui-slideouttab-panel {\n z-index: 30000;\n}\n\n#swh-identifiers {\n width: 70vw;\n top: 0;\n border: 1px solid #e20026;\n}\n\n#swh-identifiers .handle {\n background-color: #e20026;\n border: 1px solid #e20026;\n color: white;\n padding-top: 0.1em;\n padding-bottom: 0.1em;\n}\n\n#swh-identifiers-content {\n height: 100%;\n overflow: auto;\n}\n","/**\n * Copyright (C) 2018 The Software Heritage developers\n * See the AUTHORS file at the top-level directory of this distribution\n * License: GNU Affero General Public License version 3, or any later version\n * See top-level LICENSE file for more information\n */\n\n.swh-browse-bread-crumbs {\n font-size: inherit;\n vertical-align: text-top;\n margin-bottom: 1px;\n}\n\n.swh-browse-bread-crumbs li:nth-child(n+2)::before {\n content: \"\";\n display: inline-block;\n margin: 0 2px;\n}\n","/**\n * Copyright (C) 2018 The Software Heritage developers\n * See the AUTHORS file at the top-level directory of this distribution\n * License: GNU Affero General Public License version 3, or any later version\n * See top-level LICENSE file for more information\n */\n\n.swh-content {\n background-image: none;\n border: none;\n background-color: white;\n padding: 0;\n}\n\n.swh-content pre,\n.swh-content pre code {\n margin: 0;\n padding: 0;\n}\n","/**\n * Copyright (C) 2018 The Software Heritage developers\n * See the AUTHORS file at the top-level directory of this distribution\n * License: GNU Affero General Public License version 3, or any later version\n * See top-level LICENSE file for more information\n */\n\n.swh-browse-top-navigation {\n border-bottom: 1px solid #ddd;\n min-height: 40px;\n padding: 4px 5px 0 5px;\n}\n\n.swh-branches-releases {\n min-width: 200px;\n}\n\n.swh-branches-switch,\n.swh-releases-switch {\n padding: 5px 15px !important;\n}\n\nli.swh-branch:hover,\nli.swh-release:hover {\n background-color: #e8e8e8;\n}\n\n.nav a,\n.swh-branch a,\n.swh-release a {\n outline: none;\n}\n\n.swh-branch a:hover,\n.swh-release a:hover {\n text-decoration: none;\n}\n\n.swh-origin-visit-details,\n.swh-snapshot-details {\n text-align: center;\n}\n\n.swh-origin-visit-details ul,\n.swh-snapshot-details ul {\n list-style: none;\n margin: 0;\n padding: 0;\n}\n\n.swh-origin-visit-details li,\n.swh-snapshot-details li {\n display: inline-block;\n vertical-align: middle;\n margin-left: 10px;\n margin-right: 10px;\n}\n","/*\n tabSlideOUt v2.4\n\n By Michael Fielding\n License: GPL v3.0\n*/\n\n.ui-slideouttab-panel,\n.ui-slideouttab-handle {\n background-color: white;\n padding: 0.4em;\n box-sizing: border-box;\n}\n\n.ui-slideouttab-panel {\n display: block;\n position: fixed;\n border: 2px solid grey;\n}\n\n/* This class is added after the tabs are initialised, otherwise the user sees the\n tabs slide out of the way when the page is initialised. */\n.ui-slideouttab-ready {\n transition: transform 0.5s ease 0s;\n}\n\n/* Hide tabs and panels when printed. */\n@media print {\n .ui-slideouttab-panel {\n display: none;\n }\n}\n\n/* Tab handles */\n.ui-slideouttab-handle {\n display: block;\n position: absolute;\n cursor: pointer;\n color: white;\n background-color: grey;\n}\n\n.ui-slideouttab-handle-image {\n transform: rotate(0);\n}\n\n/* Right */\n.ui-slideouttab-right {\n right: 0;\n transform: translateX(100%);\n border-right: none;\n}\n\n.ui-slideouttab-right.ui-slideouttab-open {\n transform: translateX(0%);\n}\n\n.ui-slideouttab-right .ui-slideouttab-handle {\n transform-origin: 0% 0%;\n transform: rotate(-90deg) translate(-100%, -100%);\n}\n\n.ui-slideouttab-right .ui-slideouttab-handle-reverse {\n transform-origin: 0% 100%;\n transform: rotate(-90deg);\n}\n\n/* Left */\n.ui-slideouttab-left {\n left: 0;\n transform: translateX(-100%);\n border-left: none;\n}\n\n.ui-slideouttab-left.ui-slideouttab-open {\n transform: translateX(0%);\n}\n\n.ui-slideouttab-left .ui-slideouttab-handle {\n transform-origin: 100% 0%;\n transform: rotate(-90deg);\n}\n\n.ui-slideouttab-left .ui-slideouttab-handle-reverse {\n transform-origin: 100% 100%;\n transform: rotate(-90deg) translate(100%, 100%);\n}\n\n/* Top */\n.ui-slideouttab-top {\n top: 0;\n transform: translateY(-100%);\n border-top: none;\n}\n\n.ui-slideouttab-top.ui-slideouttab-open {\n transform: translateY(0%);\n}\n\n/* Bottom */\n.ui-slideouttab-bottom {\n bottom: 0;\n transform: translateY(100%);\n border-bottom: none;\n}\n\n.ui-slideouttab-bottom.ui-slideouttab-open {\n transform: translateY(0%);\n}\n\n/* turn font awesome icon in a tab upright */\n.ui-slideouttab-left .ui-slideouttab-handle > .fa-icon,\n.ui-slideouttab-right .ui-slideouttab-handle > .fa-icon {\n transform: rotate(90deg);\n}\n\n.ui-slideouttab-handle > .fa-icon {\n margin-left: 0.5em;\n}\n\n/* apply rounded corners if handle has the -rounded class */\n.ui-slideouttab-top .ui-slideouttab-handle-rounded,\n.ui-slideouttab-left .ui-slideouttab-handle-rounded {\n border-radius: 0 0 4px 4px;\n}\n\n.ui-slideouttab-right .ui-slideouttab-handle-rounded,\n.ui-slideouttab-bottom .ui-slideouttab-handle-rounded {\n border-radius: 4px 4px 0 0;\n}\n"]} \ No newline at end of file diff --git a/swh/web/static/js/browse.92378aae87894b0d9972.js.map b/swh/web/static/js/browse.92378aae87894b0d9972.js.map deleted file mode 100644 index 29508274..00000000 --- a/swh/web/static/js/browse.92378aae87894b0d9972.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["webpack://swh.[name]/webpack/universalModuleDefinition","webpack://swh.[name]/webpack/bootstrap","webpack://swh.[name]/./node_modules/core-js/library/modules/_global.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_wks.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_core.js","webpack://swh.[name]/./swh/web/assets/src/utils/functions.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_an-object.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_hide.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_export.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_descriptors.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_is-object.js","webpack://swh.[name]/./node_modules/@babel/runtime-corejs2/core-js/parse-int.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_iterators.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_has.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_object-dp.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_defined.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_ctx.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_a-function.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_fails.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_cof.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_dom-create.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_to-iobject.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_to-integer.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_shared-key.js","webpack://swh.[name]/./node_modules/@babel/runtime-corejs2/core-js/json/stringify.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_library.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_set-to-string-tag.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_property-desc.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_string-ws.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_iter-define.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_shared.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_uid.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_enum-bug-keys.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_to-length.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_html.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_classof.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_ie8-dom-define.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_to-primitive.js","webpack://swh.[name]/./node_modules/core-js/library/fn/parse-int.js","webpack://swh.[name]/./node_modules/core-js/library/modules/es6.parse-int.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_parse-int.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_string-trim.js","webpack://swh.[name]/./node_modules/core-js/library/modules/web.dom.iterable.js","webpack://swh.[name]/./node_modules/core-js/library/modules/es6.array.iterator.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_add-to-unscopables.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_iter-step.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_iobject.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_redefine.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_iter-create.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_object-create.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_object-dps.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_object-keys.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_object-keys-internal.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_array-includes.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_to-absolute-index.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_object-gpo.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_to-object.js","webpack://swh.[name]/./node_modules/core-js/library/modules/es6.string.iterator.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_string-at.js","webpack://swh.[name]/./node_modules/core-js/library/modules/core.get-iterator-method.js","webpack://swh.[name]/./node_modules/core-js/library/fn/json/stringify.js","webpack://swh.[name]/./node_modules/clipboard/dist/clipboard.js","webpack://swh.[name]/./swh/web/assets/src/bundles/browse/snapshot-navigation.js","webpack://swh.[name]/./swh/web/assets/src/bundles/browse/browse-utils.js","webpack://swh.[name]/./swh/web/assets/src/bundles/browse/origin-save.js","webpack://swh.[name]/(webpack)/buildin/amd-define.js","webpack://swh.[name]/./swh/web/assets/src/utils/heaps-permute.js","webpack://swh.[name]/./swh/web/assets/src/bundles/browse/origin-search.js","webpack://swh.[name]/./swh/web/assets/src/utils/jquery.tabSlideOut.js","webpack://swh.[name]/./swh/web/assets/src/bundles/browse/swh-ids-utils.js","webpack://swh.[name]/./node_modules/@babel/runtime-corejs2/core-js/get-iterator.js","webpack://swh.[name]/./node_modules/@babel/runtime-corejs2/core-js/array/is-array.js","webpack://swh.[name]/./node_modules/validate.js/validate.js","webpack://swh.[name]/(webpack)/buildin/module.js","webpack://swh.[name]/./swh/web/assets/src/bundles/browse/index.js","webpack://swh.[name]/./node_modules/core-js/library/fn/get-iterator.js","webpack://swh.[name]/./node_modules/core-js/library/modules/core.get-iterator.js","webpack://swh.[name]/./node_modules/core-js/library/fn/array/is-array.js","webpack://swh.[name]/./node_modules/core-js/library/modules/es6.array.is-array.js","webpack://swh.[name]/./node_modules/core-js/library/modules/_is-array.js"],"names":["root","factory","exports","module","define","amd","window","installedModules","__webpack_require__","moduleId","i","l","modules","call","m","c","d","name","getter","o","Object","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","prototype","hasOwnProperty","p","s","global","Math","self","Function","__g","store","uid","USE_SYMBOL","core","version","__e","handleFetchError","response","ok","handleFetchErrors","responses","length","staticAsset","asset","csrfPost","url","headers","body","Cookies","fetch","credentials","method","isGitRepoUrl","domain","RegExp","test","__webpack_exports__","isObject","it","TypeError","dP","createDesc","f","ctx","hide","has","$export","type","source","own","out","IS_FORCED","F","IS_GLOBAL","G","IS_STATIC","S","IS_PROTO","P","IS_BIND","B","IS_WRAP","W","expProto","target","undefined","C","a","b","this","arguments","apply","virtual","R","U","anObject","IE8_DOM_DEFINE","toPrimitive","O","Attributes","e","aFunction","fn","that","exec","toString","slice","document","is","createElement","IObject","defined","ceil","floor","isNaN","shared","def","TAG","tag","stat","configurable","bitmap","writable","LIBRARY","redefine","Iterators","$iterCreate","setToStringTag","getPrototypeOf","ITERATOR","BUGGY","keys","returnThis","Base","NAME","Constructor","next","DEFAULT","IS_SET","FORCED","methods","IteratorPrototype","getMethod","kind","proto","DEF_VALUES","VALUES_BUG","$native","$default","$entries","$anyNative","entries","values","push","copyright","id","px","random","concat","split","toInteger","min","documentElement","cof","ARG","T","tryGet","callee","val","valueOf","parseInt","$parseInt","$trim","trim","ws","hex","str","radix","string","String","fails","spaces","space","ltrim","rtrim","exporter","KEY","ALIAS","exp","FORCE","TYPE","replace","TO_STRING_TAG","DOMIterables","Collection","Array","addToUnscopables","step","toIObject","iterated","_t","_i","_k","index","Arguments","done","propertyIsEnumerable","descriptor","dPs","enumBugKeys","IE_PROTO","Empty","createDict","iframeDocument","iframe","style","display","appendChild","src","contentWindow","open","write","lt","close","Properties","result","getKeys","defineProperties","$keys","arrayIndexOf","names","toLength","toAbsoluteIndex","IS_INCLUDES","$this","el","fromIndex","max","toObject","ObjectProto","constructor","$at","point","TO_STRING","pos","charCodeAt","charAt","classof","getIteratorMethod","$JSON","JSON","stringify","__WEBPACK_AMD_DEFINE_FACTORY__","__WEBPACK_AMD_DEFINE_ARRAY__","__WEBPACK_AMD_DEFINE_RESULT__","_select","_select2","obj","default","_interopRequireDefault","_typeof","iterator","_createClass","props","protoProps","staticProps","ClipboardAction","options","instance","_classCallCheck","resolveOptions","initSelection","action","container","emitter","text","trigger","selectedText","selectFake","selectTarget","_this","isRTL","getAttribute","removeFake","fakeHandlerCallback","fakeHandler","addEventListener","fakeElem","fontSize","border","padding","margin","position","yPosition","pageYOffset","scrollTop","top","setAttribute","copyText","removeEventListener","removeChild","succeeded","execCommand","err","handleResult","emit","clearSelection","focus","getSelection","removeAllRanges","set","_action","Error","nodeType","hasAttribute","_target","delegate","callback","node","destroy","listenNode","nodeList","forEach","listenNodeList","selector","listenSelector","E","on","once","listener","off","_","data","evtArr","len","evts","liveEvents","_clipboardAction","_tinyEmitter","_goodListener","_clipboardAction2","_tinyEmitter2","_goodListener2","Clipboard","_Emitter","ReferenceError","_possibleConstructorReturn","__proto__","listenClick","subClass","superClass","setPrototypeOf","_inherits","defaultAction","defaultTarget","defaultText","_this2","onClick","delegateTarget","currentTarget","clipboardAction","getAttributeValue","querySelector","actions","support","queryCommandSupported","suffix","element","attribute","DOCUMENT_NODE_TYPE","Element","matches","matchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector","webkitMatchesSelector","parentNode","closest","_delegate","useCapture","listenerFn","elements","querySelectorAll","map","HTMLElement","nodeName","isReadOnly","select","setSelectionRange","removeAttribute","selection","range","createRange","selectNodeContents","addRange","initSnapshotNavigation","snapshotContext","branch","setBranchesTabActive","$","removeClass","addClass","setReleasesTabActive","ready","click","stopPropagation","dropdownResized","dropdownWidth","width","toggle","css","blur","preventDefault","popover","boundary","html","template","content","attr","children","remove","title","offset","parents","saveRequestsTable","initOriginSave","Urls","browse_origin_save_types_list","then","json","_iterator","_isArray","_babel_runtime_corejs2_core_js_array_is_array__WEBPACK_IMPORTED_MODULE_2___default","_babel_runtime_corejs2_core_js_get_iterator__WEBPACK_IMPORTED_MODULE_1___default","_ref","originType","append","DataTable","serverSide","ajax","browse_origin_save_requests_list","columns","render","row","Date","toLocaleString","browseOriginUrl","browse_origin","origin_url","visit_date","scrollY","scrollCollapse","order","setInterval","reload","draw","submit","event","checkValidity","originUrl","addSaveOriginRequestUrl","browse_origin_save_request","grecaptchaData","g-recaptcha-response","grecaptcha","getResponse","_babel_runtime_corejs2_core_js_json_stringify__WEBPACK_IMPORTED_MODULE_0___default","utils_functions__WEBPACK_IMPORTED_MODULE_3__","Accept","Content-Type","save_request_status","reset","catch","status","tab","each","includes","prop","validateSaveOriginUrl","input","validUrl","validate_js__WEBPACK_IMPORTED_MODULE_4__","website","schemes","githubIdx","indexOf","gitlabIdx","gitSfIdx","bitbucketIdx","setCustomValidity","swap","array","pos1","pos2","temp","originPatterns","perPage","origin_search_limit","origin_search_offset","currentData","inSearch","fixTableRowsStyle","setTimeout","removeAttr","clearOriginSearchResultsTable","populateOriginSearchResultsTable","localOffset","show","table","_loop","elem","tableRow","browseUrl","latestSnapshotUrl","browse_origin_latest_snapshot","originId","Storage","sessionStorage","setItem","scrollTo","escapeStringRegexp","searchOrigins","patterns","limit","searchOffset","patternsArray","patternsPermut","heapsPermute","output","join","regex","withVisit","searchUrl","browse_origin_search","functions","stringify_default","errorDescription","statusText","initOriginSearch","getItem","parse_int_default","parse","resolvePidUrl","resolve_swh_pid","location","browse_url","startsWith","reason","hasClass","tabSlideOut","callerSettings","heightAsString","outerHeight","calculatePanelSize","available","height","edge","settings","otherOffset","panel","isOpen","extend","tabLocation","tabHandle","hoverTimeout","offsetReverse","handleOffset","handleOffsetReverse","bounceDistance","bounceTimes","bounceSpeed","tabImage","tabImageHeight","tabImageWidth","onLoadSlideOut","clickScreenToClose","clickScreenToCloseFilters","onOpen","onClose","handle","toggleButton","imageHeight","imageWidth","img","Image","naturalHeight","naturalWidth","background","panelOffsetFrom","handleOffsetFrom","borderWidth","resize","bottom","right","left","moveIn","moveOut","contains","clicked","filter","timer","hover","animate","bounceIn","bounceOut","jQuery","swhIdObjectTypeToggled","swhIdOptionOriginToggled","swhIdElt","find","originPart","currentSwhId","setIdLinesPart","elt","lines","linesPart","linesRegexp","line","hash","swhIdOptionLinesToggled","clipboard_default","swhId","origin","innerWidth","tabSlideOptions","innerHeight","validate","attributes","constraints","v","results","runValidations","some","isPromise","error","processValidationResults","major","minor","patch","metadata","format","isEmpty","Promise","EMPTY_STRING_REGEXP","validatorName","validators","validator","validatorOptions","isDomElement","isJqueryElement","collectFormValues","getDeepObjectValue","globalOptions","errors","pruneEmptyErrors","expandMultipleErrors","convertErrorMessages","formatters","async","WrapErrors","wrapErrors","cleanAttributes","resolve","reject","waitForResults","single","fullMessages","reduce","memo","args","isNumber","isFunction","isInteger","isBoolean","isDate","isDefined","isString","jquery","isArray","vals","FORMAT_REGEXP","m0","m1","m2","prettify","parseFloat","round","toFixed","toLowerCase","stringifyValue","isHash","unique","forEachKeyInKeypath","keypath","escape","form","j","inputs","option","item","sanitizeFormValue","checked","multiple","selected","_val","selectedIndex","nullify","capitalize","toUpperCase","ret","msg","errorInfo","groupErrorsByAttribute","list","flattenErrorsToArray","whitelist","whitelistCreator","last","cleanRecursive","w","ow","buildObjectWhitelist","exposeModule","warn","console","presence","allowEmpty","message","maximum","minimum","tokenizer","wrongLength","count","tooShort","tooLong","notValid","numericality","checks","greaterThan","greaterThanOrEqualTo","equalTo","lessThan","lessThanOrEqualTo","divisibleBy","strict","pattern","onlyInteger","noStrings","notInteger","odd","notOdd","even","notEven","datetime","earliest","NaN","latest","dateOnly","tooEarly","date","tooLate","match","flags","inclusion","within","exclusion","email","PATTERN","equality","otherValue","comparator","v1","v2","allowLocal","tld","detailed","flat","grouped","constraint","sort","webpackPolyfill","deprecate","paths","_snapshot_navigation__WEBPACK_IMPORTED_MODULE_4__","_origin_search__WEBPACK_IMPORTED_MODULE_5__","_browse_utils__WEBPACK_IMPORTED_MODULE_6__","__WEBPACK_IMPORT_KEY__","_swh_ids_utils__WEBPACK_IMPORTED_MODULE_7__","_origin_save__WEBPACK_IMPORTED_MODULE_8__","getIterator","iterFn","arg"],"mappings":"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","file":"js/browse.92378aae87894b0d9972.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"browse\"] = factory();\n\telse\n\t\troot[\"swh\"] = root[\"swh\"] || {}, root[\"swh\"][\"browse\"] = factory();\n})(window, function() {\nreturn "," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"/static/\";\n\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(__webpack_require__.s = 213);\n","// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028\nvar global = module.exports = typeof window != 'undefined' && window.Math == Math\n ? window : typeof self != 'undefined' && self.Math == Math ? self\n // eslint-disable-next-line no-new-func\n : Function('return this')();\nif (typeof __g == 'number') __g = global; // eslint-disable-line no-undef\n","var store = require('./_shared')('wks');\nvar uid = require('./_uid');\nvar Symbol = require('./_global').Symbol;\nvar USE_SYMBOL = typeof Symbol == 'function';\n\nvar $exports = module.exports = function (name) {\n return store[name] || (store[name] =\n USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : uid)('Symbol.' + name));\n};\n\n$exports.store = store;\n","var core = module.exports = { version: '2.5.7' };\nif (typeof __e == 'number') __e = core; // eslint-disable-line no-undef\n","/**\n * Copyright (C) 2018 The Software Heritage developers\n * See the AUTHORS file at the top-level directory of this distribution\n * License: GNU Affero General Public License version 3, or any later version\n * See top-level LICENSE file for more information\n */\n\n// utility functions\n\nexport function handleFetchError(response) {\n if (!response.ok) {\n throw response;\n }\n return response;\n}\n\nexport function handleFetchErrors(responses) {\n for (let i = 0; i < responses.length; ++i) {\n if (!responses[i].ok) {\n throw responses[i];\n }\n }\n return responses;\n}\n\nexport function staticAsset(asset) {\n return `${__STATIC__}${asset}`;\n}\n\nexport function csrfPost(url, headers = {}, body = null) {\n headers['X-CSRFToken'] = Cookies.get('csrftoken');\n return fetch(url, {\n credentials: 'include',\n headers: headers,\n method: 'POST',\n body: body\n });\n}\n\nexport function isGitRepoUrl(url, domain) {\n let endOfPattern = '\\\\/[\\\\w\\\\.-]+\\\\/?(?!=.git)(?:\\\\.git(?:\\\\/?|\\\\#[\\\\w\\\\.\\\\-_]+)?)?$';\n let pattern = `(?:git|https?|git@)(?:\\\\:\\\\/\\\\/)?${domain}[/|:][A-Za-z0-9-]+?` + endOfPattern;\n let re = new RegExp(pattern);\n return re.test(url);\n};\n","var isObject = require('./_is-object');\nmodule.exports = function (it) {\n if (!isObject(it)) throw TypeError(it + ' is not an object!');\n return it;\n};\n","var dP = require('./_object-dp');\nvar createDesc = require('./_property-desc');\nmodule.exports = require('./_descriptors') ? function (object, key, value) {\n return dP.f(object, key, createDesc(1, value));\n} : function (object, key, value) {\n object[key] = value;\n return object;\n};\n","var global = require('./_global');\nvar core = require('./_core');\nvar ctx = require('./_ctx');\nvar hide = require('./_hide');\nvar has = require('./_has');\nvar PROTOTYPE = 'prototype';\n\nvar $export = function (type, name, source) {\n var IS_FORCED = type & $export.F;\n var IS_GLOBAL = type & $export.G;\n var IS_STATIC = type & $export.S;\n var IS_PROTO = type & $export.P;\n var IS_BIND = type & $export.B;\n var IS_WRAP = type & $export.W;\n var exports = IS_GLOBAL ? core : core[name] || (core[name] = {});\n var expProto = exports[PROTOTYPE];\n var target = IS_GLOBAL ? global : IS_STATIC ? global[name] : (global[name] || {})[PROTOTYPE];\n var key, own, out;\n if (IS_GLOBAL) source = name;\n for (key in source) {\n // contains in native\n own = !IS_FORCED && target && target[key] !== undefined;\n if (own && has(exports, key)) continue;\n // export native or passed\n out = own ? target[key] : source[key];\n // prevent global pollution for namespaces\n exports[key] = IS_GLOBAL && typeof target[key] != 'function' ? source[key]\n // bind timers to global for call from export context\n : IS_BIND && own ? ctx(out, global)\n // wrap global constructors for prevent change them in library\n : IS_WRAP && target[key] == out ? (function (C) {\n var F = function (a, b, c) {\n if (this instanceof C) {\n switch (arguments.length) {\n case 0: return new C();\n case 1: return new C(a);\n case 2: return new C(a, b);\n } return new C(a, b, c);\n } return C.apply(this, arguments);\n };\n F[PROTOTYPE] = C[PROTOTYPE];\n return F;\n // make static versions for prototype methods\n })(out) : IS_PROTO && typeof out == 'function' ? ctx(Function.call, out) : out;\n // export proto methods to core.%CONSTRUCTOR%.methods.%NAME%\n if (IS_PROTO) {\n (exports.virtual || (exports.virtual = {}))[key] = out;\n // export proto methods to core.%CONSTRUCTOR%.prototype.%NAME%\n if (type & $export.R && expProto && !expProto[key]) hide(expProto, key, out);\n }\n }\n};\n// type bitmap\n$export.F = 1; // forced\n$export.G = 2; // global\n$export.S = 4; // static\n$export.P = 8; // proto\n$export.B = 16; // bind\n$export.W = 32; // wrap\n$export.U = 64; // safe\n$export.R = 128; // real proto method for `library`\nmodule.exports = $export;\n","// Thank's IE8 for his funny defineProperty\nmodule.exports = !require('./_fails')(function () {\n return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;\n});\n","module.exports = function (it) {\n return typeof it === 'object' ? it !== null : typeof it === 'function';\n};\n","module.exports = require(\"core-js/library/fn/parse-int\");","module.exports = {};\n","var hasOwnProperty = {}.hasOwnProperty;\nmodule.exports = function (it, key) {\n return hasOwnProperty.call(it, key);\n};\n","var anObject = require('./_an-object');\nvar IE8_DOM_DEFINE = require('./_ie8-dom-define');\nvar toPrimitive = require('./_to-primitive');\nvar dP = Object.defineProperty;\n\nexports.f = require('./_descriptors') ? Object.defineProperty : function defineProperty(O, P, Attributes) {\n anObject(O);\n P = toPrimitive(P, true);\n anObject(Attributes);\n if (IE8_DOM_DEFINE) try {\n return dP(O, P, Attributes);\n } catch (e) { /* empty */ }\n if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');\n if ('value' in Attributes) O[P] = Attributes.value;\n return O;\n};\n","// 7.2.1 RequireObjectCoercible(argument)\nmodule.exports = function (it) {\n if (it == undefined) throw TypeError(\"Can't call method on \" + it);\n return it;\n};\n","// optional / simple context binding\nvar aFunction = require('./_a-function');\nmodule.exports = function (fn, that, length) {\n aFunction(fn);\n if (that === undefined) return fn;\n switch (length) {\n case 1: return function (a) {\n return fn.call(that, a);\n };\n case 2: return function (a, b) {\n return fn.call(that, a, b);\n };\n case 3: return function (a, b, c) {\n return fn.call(that, a, b, c);\n };\n }\n return function (/* ...args */) {\n return fn.apply(that, arguments);\n };\n};\n","module.exports = function (it) {\n if (typeof it != 'function') throw TypeError(it + ' is not a function!');\n return it;\n};\n","module.exports = function (exec) {\n try {\n return !!exec();\n } catch (e) {\n return true;\n }\n};\n","var toString = {}.toString;\n\nmodule.exports = function (it) {\n return toString.call(it).slice(8, -1);\n};\n","var isObject = require('./_is-object');\nvar document = require('./_global').document;\n// typeof document.createElement is 'object' in old IE\nvar is = isObject(document) && isObject(document.createElement);\nmodule.exports = function (it) {\n return is ? document.createElement(it) : {};\n};\n","// to indexed object, toObject with fallback for non-array-like ES3 strings\nvar IObject = require('./_iobject');\nvar defined = require('./_defined');\nmodule.exports = function (it) {\n return IObject(defined(it));\n};\n","// 7.1.4 ToInteger\nvar ceil = Math.ceil;\nvar floor = Math.floor;\nmodule.exports = function (it) {\n return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);\n};\n","var shared = require('./_shared')('keys');\nvar uid = require('./_uid');\nmodule.exports = function (key) {\n return shared[key] || (shared[key] = uid(key));\n};\n","module.exports = require(\"core-js/library/fn/json/stringify\");","module.exports = true;\n","var def = require('./_object-dp').f;\nvar has = require('./_has');\nvar TAG = require('./_wks')('toStringTag');\n\nmodule.exports = function (it, tag, stat) {\n if (it && !has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag });\n};\n","module.exports = function (bitmap, value) {\n return {\n enumerable: !(bitmap & 1),\n configurable: !(bitmap & 2),\n writable: !(bitmap & 4),\n value: value\n };\n};\n","module.exports = '\\x09\\x0A\\x0B\\x0C\\x0D\\x20\\xA0\\u1680\\u180E\\u2000\\u2001\\u2002\\u2003' +\n '\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200A\\u202F\\u205F\\u3000\\u2028\\u2029\\uFEFF';\n","'use strict';\nvar LIBRARY = require('./_library');\nvar $export = require('./_export');\nvar redefine = require('./_redefine');\nvar hide = require('./_hide');\nvar Iterators = require('./_iterators');\nvar $iterCreate = require('./_iter-create');\nvar setToStringTag = require('./_set-to-string-tag');\nvar getPrototypeOf = require('./_object-gpo');\nvar ITERATOR = require('./_wks')('iterator');\nvar BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next`\nvar FF_ITERATOR = '@@iterator';\nvar KEYS = 'keys';\nvar VALUES = 'values';\n\nvar returnThis = function () { return this; };\n\nmodule.exports = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) {\n $iterCreate(Constructor, NAME, next);\n var getMethod = function (kind) {\n if (!BUGGY && kind in proto) return proto[kind];\n switch (kind) {\n case KEYS: return function keys() { return new Constructor(this, kind); };\n case VALUES: return function values() { return new Constructor(this, kind); };\n } return function entries() { return new Constructor(this, kind); };\n };\n var TAG = NAME + ' Iterator';\n var DEF_VALUES = DEFAULT == VALUES;\n var VALUES_BUG = false;\n var proto = Base.prototype;\n var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT];\n var $default = $native || getMethod(DEFAULT);\n var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined;\n var $anyNative = NAME == 'Array' ? proto.entries || $native : $native;\n var methods, key, IteratorPrototype;\n // Fix native\n if ($anyNative) {\n IteratorPrototype = getPrototypeOf($anyNative.call(new Base()));\n if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) {\n // Set @@toStringTag to native iterators\n setToStringTag(IteratorPrototype, TAG, true);\n // fix for some old engines\n if (!LIBRARY && typeof IteratorPrototype[ITERATOR] != 'function') hide(IteratorPrototype, ITERATOR, returnThis);\n }\n }\n // fix Array#{values, @@iterator}.name in V8 / FF\n if (DEF_VALUES && $native && $native.name !== VALUES) {\n VALUES_BUG = true;\n $default = function values() { return $native.call(this); };\n }\n // Define iterator\n if ((!LIBRARY || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) {\n hide(proto, ITERATOR, $default);\n }\n // Plug for library\n Iterators[NAME] = $default;\n Iterators[TAG] = returnThis;\n if (DEFAULT) {\n methods = {\n values: DEF_VALUES ? $default : getMethod(VALUES),\n keys: IS_SET ? $default : getMethod(KEYS),\n entries: $entries\n };\n if (FORCED) for (key in methods) {\n if (!(key in proto)) redefine(proto, key, methods[key]);\n } else $export($export.P + $export.F * (BUGGY || VALUES_BUG), NAME, methods);\n }\n return methods;\n};\n","var core = require('./_core');\nvar global = require('./_global');\nvar SHARED = '__core-js_shared__';\nvar store = global[SHARED] || (global[SHARED] = {});\n\n(module.exports = function (key, value) {\n return store[key] || (store[key] = value !== undefined ? value : {});\n})('versions', []).push({\n version: core.version,\n mode: require('./_library') ? 'pure' : 'global',\n copyright: '© 2018 Denis Pushkarev (zloirock.ru)'\n});\n","var id = 0;\nvar px = Math.random();\nmodule.exports = function (key) {\n return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));\n};\n","// IE 8- don't enum bug keys\nmodule.exports = (\n 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf'\n).split(',');\n","// 7.1.15 ToLength\nvar toInteger = require('./_to-integer');\nvar min = Math.min;\nmodule.exports = function (it) {\n return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991\n};\n","var document = require('./_global').document;\nmodule.exports = document && document.documentElement;\n","// getting tag from 19.1.3.6 Object.prototype.toString()\nvar cof = require('./_cof');\nvar TAG = require('./_wks')('toStringTag');\n// ES3 wrong here\nvar ARG = cof(function () { return arguments; }()) == 'Arguments';\n\n// fallback for IE11 Script Access Denied error\nvar tryGet = function (it, key) {\n try {\n return it[key];\n } catch (e) { /* empty */ }\n};\n\nmodule.exports = function (it) {\n var O, T, B;\n return it === undefined ? 'Undefined' : it === null ? 'Null'\n // @@toStringTag case\n : typeof (T = tryGet(O = Object(it), TAG)) == 'string' ? T\n // builtinTag case\n : ARG ? cof(O)\n // ES3 arguments fallback\n : (B = cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B;\n};\n","module.exports = !require('./_descriptors') && !require('./_fails')(function () {\n return Object.defineProperty(require('./_dom-create')('div'), 'a', { get: function () { return 7; } }).a != 7;\n});\n","// 7.1.1 ToPrimitive(input [, PreferredType])\nvar isObject = require('./_is-object');\n// instead of the ES6 spec version, we didn't implement @@toPrimitive case\n// and the second argument - flag - preferred type is a string\nmodule.exports = function (it, S) {\n if (!isObject(it)) return it;\n var fn, val;\n if (S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;\n if (typeof (fn = it.valueOf) == 'function' && !isObject(val = fn.call(it))) return val;\n if (!S && typeof (fn = it.toString) == 'function' && !isObject(val = fn.call(it))) return val;\n throw TypeError(\"Can't convert object to primitive value\");\n};\n","require('../modules/es6.parse-int');\nmodule.exports = require('../modules/_core').parseInt;\n","var $export = require('./_export');\nvar $parseInt = require('./_parse-int');\n// 18.2.5 parseInt(string, radix)\n$export($export.G + $export.F * (parseInt != $parseInt), { parseInt: $parseInt });\n","var $parseInt = require('./_global').parseInt;\nvar $trim = require('./_string-trim').trim;\nvar ws = require('./_string-ws');\nvar hex = /^[-+]?0[xX]/;\n\nmodule.exports = $parseInt(ws + '08') !== 8 || $parseInt(ws + '0x16') !== 22 ? function parseInt(str, radix) {\n var string = $trim(String(str), 3);\n return $parseInt(string, (radix >>> 0) || (hex.test(string) ? 16 : 10));\n} : $parseInt;\n","var $export = require('./_export');\nvar defined = require('./_defined');\nvar fails = require('./_fails');\nvar spaces = require('./_string-ws');\nvar space = '[' + spaces + ']';\nvar non = '\\u200b\\u0085';\nvar ltrim = RegExp('^' + space + space + '*');\nvar rtrim = RegExp(space + space + '*$');\n\nvar exporter = function (KEY, exec, ALIAS) {\n var exp = {};\n var FORCE = fails(function () {\n return !!spaces[KEY]() || non[KEY]() != non;\n });\n var fn = exp[KEY] = FORCE ? exec(trim) : spaces[KEY];\n if (ALIAS) exp[ALIAS] = fn;\n $export($export.P + $export.F * FORCE, 'String', exp);\n};\n\n// 1 -> String#trimLeft\n// 2 -> String#trimRight\n// 3 -> String#trim\nvar trim = exporter.trim = function (string, TYPE) {\n string = String(defined(string));\n if (TYPE & 1) string = string.replace(ltrim, '');\n if (TYPE & 2) string = string.replace(rtrim, '');\n return string;\n};\n\nmodule.exports = exporter;\n","require('./es6.array.iterator');\nvar global = require('./_global');\nvar hide = require('./_hide');\nvar Iterators = require('./_iterators');\nvar TO_STRING_TAG = require('./_wks')('toStringTag');\n\nvar DOMIterables = ('CSSRuleList,CSSStyleDeclaration,CSSValueList,ClientRectList,DOMRectList,DOMStringList,' +\n 'DOMTokenList,DataTransferItemList,FileList,HTMLAllCollection,HTMLCollection,HTMLFormElement,HTMLSelectElement,' +\n 'MediaList,MimeTypeArray,NamedNodeMap,NodeList,PaintRequestList,Plugin,PluginArray,SVGLengthList,SVGNumberList,' +\n 'SVGPathSegList,SVGPointList,SVGStringList,SVGTransformList,SourceBufferList,StyleSheetList,TextTrackCueList,' +\n 'TextTrackList,TouchList').split(',');\n\nfor (var i = 0; i < DOMIterables.length; i++) {\n var NAME = DOMIterables[i];\n var Collection = global[NAME];\n var proto = Collection && Collection.prototype;\n if (proto && !proto[TO_STRING_TAG]) hide(proto, TO_STRING_TAG, NAME);\n Iterators[NAME] = Iterators.Array;\n}\n","'use strict';\nvar addToUnscopables = require('./_add-to-unscopables');\nvar step = require('./_iter-step');\nvar Iterators = require('./_iterators');\nvar toIObject = require('./_to-iobject');\n\n// 22.1.3.4 Array.prototype.entries()\n// 22.1.3.13 Array.prototype.keys()\n// 22.1.3.29 Array.prototype.values()\n// 22.1.3.30 Array.prototype[@@iterator]()\nmodule.exports = require('./_iter-define')(Array, 'Array', function (iterated, kind) {\n this._t = toIObject(iterated); // target\n this._i = 0; // next index\n this._k = kind; // kind\n// 22.1.5.2.1 %ArrayIteratorPrototype%.next()\n}, function () {\n var O = this._t;\n var kind = this._k;\n var index = this._i++;\n if (!O || index >= O.length) {\n this._t = undefined;\n return step(1);\n }\n if (kind == 'keys') return step(0, index);\n if (kind == 'values') return step(0, O[index]);\n return step(0, [index, O[index]]);\n}, 'values');\n\n// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7)\nIterators.Arguments = Iterators.Array;\n\naddToUnscopables('keys');\naddToUnscopables('values');\naddToUnscopables('entries');\n","module.exports = function () { /* empty */ };\n","module.exports = function (done, value) {\n return { value: value, done: !!done };\n};\n","// fallback for non-array-like ES3 and non-enumerable old V8 strings\nvar cof = require('./_cof');\n// eslint-disable-next-line no-prototype-builtins\nmodule.exports = Object('z').propertyIsEnumerable(0) ? Object : function (it) {\n return cof(it) == 'String' ? it.split('') : Object(it);\n};\n","module.exports = require('./_hide');\n","'use strict';\nvar create = require('./_object-create');\nvar descriptor = require('./_property-desc');\nvar setToStringTag = require('./_set-to-string-tag');\nvar IteratorPrototype = {};\n\n// 25.1.2.1.1 %IteratorPrototype%[@@iterator]()\nrequire('./_hide')(IteratorPrototype, require('./_wks')('iterator'), function () { return this; });\n\nmodule.exports = function (Constructor, NAME, next) {\n Constructor.prototype = create(IteratorPrototype, { next: descriptor(1, next) });\n setToStringTag(Constructor, NAME + ' Iterator');\n};\n","// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties])\nvar anObject = require('./_an-object');\nvar dPs = require('./_object-dps');\nvar enumBugKeys = require('./_enum-bug-keys');\nvar IE_PROTO = require('./_shared-key')('IE_PROTO');\nvar Empty = function () { /* empty */ };\nvar PROTOTYPE = 'prototype';\n\n// Create object with fake `null` prototype: use iframe Object with cleared prototype\nvar createDict = function () {\n // Thrash, waste and sodomy: IE GC bug\n var iframe = require('./_dom-create')('iframe');\n var i = enumBugKeys.length;\n var lt = '<';\n var gt = '>';\n var iframeDocument;\n iframe.style.display = 'none';\n require('./_html').appendChild(iframe);\n iframe.src = 'javascript:'; // eslint-disable-line no-script-url\n // createDict = iframe.contentWindow.Object;\n // html.removeChild(iframe);\n iframeDocument = iframe.contentWindow.document;\n iframeDocument.open();\n iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt);\n iframeDocument.close();\n createDict = iframeDocument.F;\n while (i--) delete createDict[PROTOTYPE][enumBugKeys[i]];\n return createDict();\n};\n\nmodule.exports = Object.create || function create(O, Properties) {\n var result;\n if (O !== null) {\n Empty[PROTOTYPE] = anObject(O);\n result = new Empty();\n Empty[PROTOTYPE] = null;\n // add \"__proto__\" for Object.getPrototypeOf polyfill\n result[IE_PROTO] = O;\n } else result = createDict();\n return Properties === undefined ? result : dPs(result, Properties);\n};\n","var dP = require('./_object-dp');\nvar anObject = require('./_an-object');\nvar getKeys = require('./_object-keys');\n\nmodule.exports = require('./_descriptors') ? Object.defineProperties : function defineProperties(O, Properties) {\n anObject(O);\n var keys = getKeys(Properties);\n var length = keys.length;\n var i = 0;\n var P;\n while (length > i) dP.f(O, P = keys[i++], Properties[P]);\n return O;\n};\n","// 19.1.2.14 / 15.2.3.14 Object.keys(O)\nvar $keys = require('./_object-keys-internal');\nvar enumBugKeys = require('./_enum-bug-keys');\n\nmodule.exports = Object.keys || function keys(O) {\n return $keys(O, enumBugKeys);\n};\n","var has = require('./_has');\nvar toIObject = require('./_to-iobject');\nvar arrayIndexOf = require('./_array-includes')(false);\nvar IE_PROTO = require('./_shared-key')('IE_PROTO');\n\nmodule.exports = function (object, names) {\n var O = toIObject(object);\n var i = 0;\n var result = [];\n var key;\n for (key in O) if (key != IE_PROTO) has(O, key) && result.push(key);\n // Don't enum bug & hidden keys\n while (names.length > i) if (has(O, key = names[i++])) {\n ~arrayIndexOf(result, key) || result.push(key);\n }\n return result;\n};\n","// false -> Array#indexOf\n// true -> Array#includes\nvar toIObject = require('./_to-iobject');\nvar toLength = require('./_to-length');\nvar toAbsoluteIndex = require('./_to-absolute-index');\nmodule.exports = function (IS_INCLUDES) {\n return function ($this, el, fromIndex) {\n var O = toIObject($this);\n var length = toLength(O.length);\n var index = toAbsoluteIndex(fromIndex, length);\n var value;\n // Array#includes uses SameValueZero equality algorithm\n // eslint-disable-next-line no-self-compare\n if (IS_INCLUDES && el != el) while (length > index) {\n value = O[index++];\n // eslint-disable-next-line no-self-compare\n if (value != value) return true;\n // Array#indexOf ignores holes, Array#includes - not\n } else for (;length > index; index++) if (IS_INCLUDES || index in O) {\n if (O[index] === el) return IS_INCLUDES || index || 0;\n } return !IS_INCLUDES && -1;\n };\n};\n","var toInteger = require('./_to-integer');\nvar max = Math.max;\nvar min = Math.min;\nmodule.exports = function (index, length) {\n index = toInteger(index);\n return index < 0 ? max(index + length, 0) : min(index, length);\n};\n","// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O)\nvar has = require('./_has');\nvar toObject = require('./_to-object');\nvar IE_PROTO = require('./_shared-key')('IE_PROTO');\nvar ObjectProto = Object.prototype;\n\nmodule.exports = Object.getPrototypeOf || function (O) {\n O = toObject(O);\n if (has(O, IE_PROTO)) return O[IE_PROTO];\n if (typeof O.constructor == 'function' && O instanceof O.constructor) {\n return O.constructor.prototype;\n } return O instanceof Object ? ObjectProto : null;\n};\n","// 7.1.13 ToObject(argument)\nvar defined = require('./_defined');\nmodule.exports = function (it) {\n return Object(defined(it));\n};\n","'use strict';\nvar $at = require('./_string-at')(true);\n\n// 21.1.3.27 String.prototype[@@iterator]()\nrequire('./_iter-define')(String, 'String', function (iterated) {\n this._t = String(iterated); // target\n this._i = 0; // next index\n// 21.1.5.2.1 %StringIteratorPrototype%.next()\n}, function () {\n var O = this._t;\n var index = this._i;\n var point;\n if (index >= O.length) return { value: undefined, done: true };\n point = $at(O, index);\n this._i += point.length;\n return { value: point, done: false };\n});\n","var toInteger = require('./_to-integer');\nvar defined = require('./_defined');\n// true -> String#at\n// false -> String#codePointAt\nmodule.exports = function (TO_STRING) {\n return function (that, pos) {\n var s = String(defined(that));\n var i = toInteger(pos);\n var l = s.length;\n var a, b;\n if (i < 0 || i >= l) return TO_STRING ? '' : undefined;\n a = s.charCodeAt(i);\n return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff\n ? TO_STRING ? s.charAt(i) : a\n : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;\n };\n};\n","var classof = require('./_classof');\nvar ITERATOR = require('./_wks')('iterator');\nvar Iterators = require('./_iterators');\nmodule.exports = require('./_core').getIteratorMethod = function (it) {\n if (it != undefined) return it[ITERATOR]\n || it['@@iterator']\n || Iterators[classof(it)];\n};\n","var core = require('../../modules/_core');\nvar $JSON = core.JSON || (core.JSON = { stringify: JSON.stringify });\nmodule.exports = function stringify(it) { // eslint-disable-line no-unused-vars\n return $JSON.stringify.apply($JSON, arguments);\n};\n","/*!\n * clipboard.js v2.0.1\n * https://zenorocha.github.io/clipboard.js\n * \n * Licensed MIT © Zeno Rocha\n */\n(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"ClipboardJS\"] = factory();\n\telse\n\t\troot[\"ClipboardJS\"] = factory();\n})(this, function() {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId]) {\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/ \t\t}\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\ti: moduleId,\n/******/ \t\t\tl: false,\n/******/ \t\t\texports: {}\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.l = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// identity function for calling harmony imports with the correct context\n/******/ \t__webpack_require__.i = function(value) { return value; };\n/******/\n/******/ \t// define getter function for harmony exports\n/******/ \t__webpack_require__.d = function(exports, name, getter) {\n/******/ \t\tif(!__webpack_require__.o(exports, name)) {\n/******/ \t\t\tObject.defineProperty(exports, name, {\n/******/ \t\t\t\tconfigurable: false,\n/******/ \t\t\t\tenumerable: true,\n/******/ \t\t\t\tget: getter\n/******/ \t\t\t});\n/******/ \t\t}\n/******/ \t};\n/******/\n/******/ \t// getDefaultExport function for compatibility with non-harmony modules\n/******/ \t__webpack_require__.n = function(module) {\n/******/ \t\tvar getter = module && module.__esModule ?\n/******/ \t\t\tfunction getDefault() { return module['default']; } :\n/******/ \t\t\tfunction getModuleExports() { return module; };\n/******/ \t\t__webpack_require__.d(getter, 'a', getter);\n/******/ \t\treturn getter;\n/******/ \t};\n/******/\n/******/ \t// Object.prototype.hasOwnProperty.call\n/******/ \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(__webpack_require__.s = 3);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function (global, factory) {\n if (true) {\n !(__WEBPACK_AMD_DEFINE_ARRAY__ = [module, __webpack_require__(7)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?\n\t\t\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n } else if (typeof exports !== \"undefined\") {\n factory(module, require('select'));\n } else {\n var mod = {\n exports: {}\n };\n factory(mod, global.select);\n global.clipboardAction = mod.exports;\n }\n})(this, function (module, _select) {\n 'use strict';\n\n var _select2 = _interopRequireDefault(_select);\n\n function _interopRequireDefault(obj) {\n return obj && obj.__esModule ? obj : {\n default: obj\n };\n }\n\n var _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n };\n\n function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n }\n\n var _createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);\n if (staticProps) defineProperties(Constructor, staticProps);\n return Constructor;\n };\n }();\n\n var ClipboardAction = function () {\n /**\n * @param {Object} options\n */\n function ClipboardAction(options) {\n _classCallCheck(this, ClipboardAction);\n\n this.resolveOptions(options);\n this.initSelection();\n }\n\n /**\n * Defines base properties passed from constructor.\n * @param {Object} options\n */\n\n\n _createClass(ClipboardAction, [{\n key: 'resolveOptions',\n value: function resolveOptions() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n this.action = options.action;\n this.container = options.container;\n this.emitter = options.emitter;\n this.target = options.target;\n this.text = options.text;\n this.trigger = options.trigger;\n\n this.selectedText = '';\n }\n }, {\n key: 'initSelection',\n value: function initSelection() {\n if (this.text) {\n this.selectFake();\n } else if (this.target) {\n this.selectTarget();\n }\n }\n }, {\n key: 'selectFake',\n value: function selectFake() {\n var _this = this;\n\n var isRTL = document.documentElement.getAttribute('dir') == 'rtl';\n\n this.removeFake();\n\n this.fakeHandlerCallback = function () {\n return _this.removeFake();\n };\n this.fakeHandler = this.container.addEventListener('click', this.fakeHandlerCallback) || true;\n\n this.fakeElem = document.createElement('textarea');\n // Prevent zooming on iOS\n this.fakeElem.style.fontSize = '12pt';\n // Reset box model\n this.fakeElem.style.border = '0';\n this.fakeElem.style.padding = '0';\n this.fakeElem.style.margin = '0';\n // Move element out of screen horizontally\n this.fakeElem.style.position = 'absolute';\n this.fakeElem.style[isRTL ? 'right' : 'left'] = '-9999px';\n // Move element to the same position vertically\n var yPosition = window.pageYOffset || document.documentElement.scrollTop;\n this.fakeElem.style.top = yPosition + 'px';\n\n this.fakeElem.setAttribute('readonly', '');\n this.fakeElem.value = this.text;\n\n this.container.appendChild(this.fakeElem);\n\n this.selectedText = (0, _select2.default)(this.fakeElem);\n this.copyText();\n }\n }, {\n key: 'removeFake',\n value: function removeFake() {\n if (this.fakeHandler) {\n this.container.removeEventListener('click', this.fakeHandlerCallback);\n this.fakeHandler = null;\n this.fakeHandlerCallback = null;\n }\n\n if (this.fakeElem) {\n this.container.removeChild(this.fakeElem);\n this.fakeElem = null;\n }\n }\n }, {\n key: 'selectTarget',\n value: function selectTarget() {\n this.selectedText = (0, _select2.default)(this.target);\n this.copyText();\n }\n }, {\n key: 'copyText',\n value: function copyText() {\n var succeeded = void 0;\n\n try {\n succeeded = document.execCommand(this.action);\n } catch (err) {\n succeeded = false;\n }\n\n this.handleResult(succeeded);\n }\n }, {\n key: 'handleResult',\n value: function handleResult(succeeded) {\n this.emitter.emit(succeeded ? 'success' : 'error', {\n action: this.action,\n text: this.selectedText,\n trigger: this.trigger,\n clearSelection: this.clearSelection.bind(this)\n });\n }\n }, {\n key: 'clearSelection',\n value: function clearSelection() {\n if (this.trigger) {\n this.trigger.focus();\n }\n\n window.getSelection().removeAllRanges();\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.removeFake();\n }\n }, {\n key: 'action',\n set: function set() {\n var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'copy';\n\n this._action = action;\n\n if (this._action !== 'copy' && this._action !== 'cut') {\n throw new Error('Invalid \"action\" value, use either \"copy\" or \"cut\"');\n }\n },\n get: function get() {\n return this._action;\n }\n }, {\n key: 'target',\n set: function set(target) {\n if (target !== undefined) {\n if (target && (typeof target === 'undefined' ? 'undefined' : _typeof(target)) === 'object' && target.nodeType === 1) {\n if (this.action === 'copy' && target.hasAttribute('disabled')) {\n throw new Error('Invalid \"target\" attribute. Please use \"readonly\" instead of \"disabled\" attribute');\n }\n\n if (this.action === 'cut' && (target.hasAttribute('readonly') || target.hasAttribute('disabled'))) {\n throw new Error('Invalid \"target\" attribute. You can\\'t cut text from elements with \"readonly\" or \"disabled\" attributes');\n }\n\n this._target = target;\n } else {\n throw new Error('Invalid \"target\" value, use a valid Element');\n }\n }\n },\n get: function get() {\n return this._target;\n }\n }]);\n\n return ClipboardAction;\n }();\n\n module.exports = ClipboardAction;\n});\n\n/***/ }),\n/* 1 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar is = __webpack_require__(6);\nvar delegate = __webpack_require__(5);\n\n/**\n * Validates all params and calls the right\n * listener function based on its target type.\n *\n * @param {String|HTMLElement|HTMLCollection|NodeList} target\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listen(target, type, callback) {\n if (!target && !type && !callback) {\n throw new Error('Missing required arguments');\n }\n\n if (!is.string(type)) {\n throw new TypeError('Second argument must be a String');\n }\n\n if (!is.fn(callback)) {\n throw new TypeError('Third argument must be a Function');\n }\n\n if (is.node(target)) {\n return listenNode(target, type, callback);\n }\n else if (is.nodeList(target)) {\n return listenNodeList(target, type, callback);\n }\n else if (is.string(target)) {\n return listenSelector(target, type, callback);\n }\n else {\n throw new TypeError('First argument must be a String, HTMLElement, HTMLCollection, or NodeList');\n }\n}\n\n/**\n * Adds an event listener to a HTML element\n * and returns a remove listener function.\n *\n * @param {HTMLElement} node\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNode(node, type, callback) {\n node.addEventListener(type, callback);\n\n return {\n destroy: function() {\n node.removeEventListener(type, callback);\n }\n }\n}\n\n/**\n * Add an event listener to a list of HTML elements\n * and returns a remove listener function.\n *\n * @param {NodeList|HTMLCollection} nodeList\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenNodeList(nodeList, type, callback) {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.addEventListener(type, callback);\n });\n\n return {\n destroy: function() {\n Array.prototype.forEach.call(nodeList, function(node) {\n node.removeEventListener(type, callback);\n });\n }\n }\n}\n\n/**\n * Add an event listener to a selector\n * and returns a remove listener function.\n *\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Object}\n */\nfunction listenSelector(selector, type, callback) {\n return delegate(document.body, selector, type, callback);\n}\n\nmodule.exports = listen;\n\n\n/***/ }),\n/* 2 */\n/***/ (function(module, exports) {\n\nfunction E () {\n // Keep this empty so it's easier to inherit from\n // (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)\n}\n\nE.prototype = {\n on: function (name, callback, ctx) {\n var e = this.e || (this.e = {});\n\n (e[name] || (e[name] = [])).push({\n fn: callback,\n ctx: ctx\n });\n\n return this;\n },\n\n once: function (name, callback, ctx) {\n var self = this;\n function listener () {\n self.off(name, listener);\n callback.apply(ctx, arguments);\n };\n\n listener._ = callback\n return this.on(name, listener, ctx);\n },\n\n emit: function (name) {\n var data = [].slice.call(arguments, 1);\n var evtArr = ((this.e || (this.e = {}))[name] || []).slice();\n var i = 0;\n var len = evtArr.length;\n\n for (i; i < len; i++) {\n evtArr[i].fn.apply(evtArr[i].ctx, data);\n }\n\n return this;\n },\n\n off: function (name, callback) {\n var e = this.e || (this.e = {});\n var evts = e[name];\n var liveEvents = [];\n\n if (evts && callback) {\n for (var i = 0, len = evts.length; i < len; i++) {\n if (evts[i].fn !== callback && evts[i].fn._ !== callback)\n liveEvents.push(evts[i]);\n }\n }\n\n // Remove event from queue to prevent memory leak\n // Suggested by https://github.com/lazd\n // Ref: https://github.com/scottcorgan/tiny-emitter/commit/c6ebfaa9bc973b33d110a84a307742b7cf94c953#commitcomment-5024910\n\n (liveEvents.length)\n ? e[name] = liveEvents\n : delete e[name];\n\n return this;\n }\n};\n\nmodule.exports = E;\n\n\n/***/ }),\n/* 3 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;(function (global, factory) {\n if (true) {\n !(__WEBPACK_AMD_DEFINE_ARRAY__ = [module, __webpack_require__(0), __webpack_require__(2), __webpack_require__(1)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?\n\t\t\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n } else if (typeof exports !== \"undefined\") {\n factory(module, require('./clipboard-action'), require('tiny-emitter'), require('good-listener'));\n } else {\n var mod = {\n exports: {}\n };\n factory(mod, global.clipboardAction, global.tinyEmitter, global.goodListener);\n global.clipboard = mod.exports;\n }\n})(this, function (module, _clipboardAction, _tinyEmitter, _goodListener) {\n 'use strict';\n\n var _clipboardAction2 = _interopRequireDefault(_clipboardAction);\n\n var _tinyEmitter2 = _interopRequireDefault(_tinyEmitter);\n\n var _goodListener2 = _interopRequireDefault(_goodListener);\n\n function _interopRequireDefault(obj) {\n return obj && obj.__esModule ? obj : {\n default: obj\n };\n }\n\n var _typeof = typeof Symbol === \"function\" && typeof Symbol.iterator === \"symbol\" ? function (obj) {\n return typeof obj;\n } : function (obj) {\n return obj && typeof Symbol === \"function\" && obj.constructor === Symbol && obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n };\n\n function _classCallCheck(instance, Constructor) {\n if (!(instance instanceof Constructor)) {\n throw new TypeError(\"Cannot call a class as a function\");\n }\n }\n\n var _createClass = function () {\n function defineProperties(target, props) {\n for (var i = 0; i < props.length; i++) {\n var descriptor = props[i];\n descriptor.enumerable = descriptor.enumerable || false;\n descriptor.configurable = true;\n if (\"value\" in descriptor) descriptor.writable = true;\n Object.defineProperty(target, descriptor.key, descriptor);\n }\n }\n\n return function (Constructor, protoProps, staticProps) {\n if (protoProps) defineProperties(Constructor.prototype, protoProps);\n if (staticProps) defineProperties(Constructor, staticProps);\n return Constructor;\n };\n }();\n\n function _possibleConstructorReturn(self, call) {\n if (!self) {\n throw new ReferenceError(\"this hasn't been initialised - super() hasn't been called\");\n }\n\n return call && (typeof call === \"object\" || typeof call === \"function\") ? call : self;\n }\n\n function _inherits(subClass, superClass) {\n if (typeof superClass !== \"function\" && superClass !== null) {\n throw new TypeError(\"Super expression must either be null or a function, not \" + typeof superClass);\n }\n\n subClass.prototype = Object.create(superClass && superClass.prototype, {\n constructor: {\n value: subClass,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;\n }\n\n var Clipboard = function (_Emitter) {\n _inherits(Clipboard, _Emitter);\n\n /**\n * @param {String|HTMLElement|HTMLCollection|NodeList} trigger\n * @param {Object} options\n */\n function Clipboard(trigger, options) {\n _classCallCheck(this, Clipboard);\n\n var _this = _possibleConstructorReturn(this, (Clipboard.__proto__ || Object.getPrototypeOf(Clipboard)).call(this));\n\n _this.resolveOptions(options);\n _this.listenClick(trigger);\n return _this;\n }\n\n /**\n * Defines if attributes would be resolved using internal setter functions\n * or custom functions that were passed in the constructor.\n * @param {Object} options\n */\n\n\n _createClass(Clipboard, [{\n key: 'resolveOptions',\n value: function resolveOptions() {\n var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};\n\n this.action = typeof options.action === 'function' ? options.action : this.defaultAction;\n this.target = typeof options.target === 'function' ? options.target : this.defaultTarget;\n this.text = typeof options.text === 'function' ? options.text : this.defaultText;\n this.container = _typeof(options.container) === 'object' ? options.container : document.body;\n }\n }, {\n key: 'listenClick',\n value: function listenClick(trigger) {\n var _this2 = this;\n\n this.listener = (0, _goodListener2.default)(trigger, 'click', function (e) {\n return _this2.onClick(e);\n });\n }\n }, {\n key: 'onClick',\n value: function onClick(e) {\n var trigger = e.delegateTarget || e.currentTarget;\n\n if (this.clipboardAction) {\n this.clipboardAction = null;\n }\n\n this.clipboardAction = new _clipboardAction2.default({\n action: this.action(trigger),\n target: this.target(trigger),\n text: this.text(trigger),\n container: this.container,\n trigger: trigger,\n emitter: this\n });\n }\n }, {\n key: 'defaultAction',\n value: function defaultAction(trigger) {\n return getAttributeValue('action', trigger);\n }\n }, {\n key: 'defaultTarget',\n value: function defaultTarget(trigger) {\n var selector = getAttributeValue('target', trigger);\n\n if (selector) {\n return document.querySelector(selector);\n }\n }\n }, {\n key: 'defaultText',\n value: function defaultText(trigger) {\n return getAttributeValue('text', trigger);\n }\n }, {\n key: 'destroy',\n value: function destroy() {\n this.listener.destroy();\n\n if (this.clipboardAction) {\n this.clipboardAction.destroy();\n this.clipboardAction = null;\n }\n }\n }], [{\n key: 'isSupported',\n value: function isSupported() {\n var action = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ['copy', 'cut'];\n\n var actions = typeof action === 'string' ? [action] : action;\n var support = !!document.queryCommandSupported;\n\n actions.forEach(function (action) {\n support = support && !!document.queryCommandSupported(action);\n });\n\n return support;\n }\n }]);\n\n return Clipboard;\n }(_tinyEmitter2.default);\n\n /**\n * Helper function to retrieve attribute value.\n * @param {String} suffix\n * @param {Element} element\n */\n function getAttributeValue(suffix, element) {\n var attribute = 'data-clipboard-' + suffix;\n\n if (!element.hasAttribute(attribute)) {\n return;\n }\n\n return element.getAttribute(attribute);\n }\n\n module.exports = Clipboard;\n});\n\n/***/ }),\n/* 4 */\n/***/ (function(module, exports) {\n\nvar DOCUMENT_NODE_TYPE = 9;\n\n/**\n * A polyfill for Element.matches()\n */\nif (typeof Element !== 'undefined' && !Element.prototype.matches) {\n var proto = Element.prototype;\n\n proto.matches = proto.matchesSelector ||\n proto.mozMatchesSelector ||\n proto.msMatchesSelector ||\n proto.oMatchesSelector ||\n proto.webkitMatchesSelector;\n}\n\n/**\n * Finds the closest parent that matches a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @return {Function}\n */\nfunction closest (element, selector) {\n while (element && element.nodeType !== DOCUMENT_NODE_TYPE) {\n if (typeof element.matches === 'function' &&\n element.matches(selector)) {\n return element;\n }\n element = element.parentNode;\n }\n}\n\nmodule.exports = closest;\n\n\n/***/ }),\n/* 5 */\n/***/ (function(module, exports, __webpack_require__) {\n\nvar closest = __webpack_require__(4);\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction _delegate(element, selector, type, callback, useCapture) {\n var listenerFn = listener.apply(this, arguments);\n\n element.addEventListener(type, listenerFn, useCapture);\n\n return {\n destroy: function() {\n element.removeEventListener(type, listenerFn, useCapture);\n }\n }\n}\n\n/**\n * Delegates event to a selector.\n *\n * @param {Element|String|Array} [elements]\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @param {Boolean} useCapture\n * @return {Object}\n */\nfunction delegate(elements, selector, type, callback, useCapture) {\n // Handle the regular Element usage\n if (typeof elements.addEventListener === 'function') {\n return _delegate.apply(null, arguments);\n }\n\n // Handle Element-less usage, it defaults to global delegation\n if (typeof type === 'function') {\n // Use `document` as the first parameter, then apply arguments\n // This is a short way to .unshift `arguments` without running into deoptimizations\n return _delegate.bind(null, document).apply(null, arguments);\n }\n\n // Handle Selector-based usage\n if (typeof elements === 'string') {\n elements = document.querySelectorAll(elements);\n }\n\n // Handle Array-like based usage\n return Array.prototype.map.call(elements, function (element) {\n return _delegate(element, selector, type, callback, useCapture);\n });\n}\n\n/**\n * Finds closest match and invokes callback.\n *\n * @param {Element} element\n * @param {String} selector\n * @param {String} type\n * @param {Function} callback\n * @return {Function}\n */\nfunction listener(element, selector, type, callback) {\n return function(e) {\n e.delegateTarget = closest(e.target, selector);\n\n if (e.delegateTarget) {\n callback.call(element, e);\n }\n }\n}\n\nmodule.exports = delegate;\n\n\n/***/ }),\n/* 6 */\n/***/ (function(module, exports) {\n\n/**\n * Check if argument is a HTML element.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.node = function(value) {\n return value !== undefined\n && value instanceof HTMLElement\n && value.nodeType === 1;\n};\n\n/**\n * Check if argument is a list of HTML elements.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.nodeList = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return value !== undefined\n && (type === '[object NodeList]' || type === '[object HTMLCollection]')\n && ('length' in value)\n && (value.length === 0 || exports.node(value[0]));\n};\n\n/**\n * Check if argument is a string.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.string = function(value) {\n return typeof value === 'string'\n || value instanceof String;\n};\n\n/**\n * Check if argument is a function.\n *\n * @param {Object} value\n * @return {Boolean}\n */\nexports.fn = function(value) {\n var type = Object.prototype.toString.call(value);\n\n return type === '[object Function]';\n};\n\n\n/***/ }),\n/* 7 */\n/***/ (function(module, exports) {\n\nfunction select(element) {\n var selectedText;\n\n if (element.nodeName === 'SELECT') {\n element.focus();\n\n selectedText = element.value;\n }\n else if (element.nodeName === 'INPUT' || element.nodeName === 'TEXTAREA') {\n var isReadOnly = element.hasAttribute('readonly');\n\n if (!isReadOnly) {\n element.setAttribute('readonly', '');\n }\n\n element.select();\n element.setSelectionRange(0, element.value.length);\n\n if (!isReadOnly) {\n element.removeAttribute('readonly');\n }\n\n selectedText = element.value;\n }\n else {\n if (element.hasAttribute('contenteditable')) {\n element.focus();\n }\n\n var selection = window.getSelection();\n var range = document.createRange();\n\n range.selectNodeContents(element);\n selection.removeAllRanges();\n selection.addRange(range);\n\n selectedText = selection.toString();\n }\n\n return selectedText;\n}\n\nmodule.exports = select;\n\n\n/***/ })\n/******/ ]);\n});","/**\n * Copyright (C) 2018 The Software Heritage developers\n * See the AUTHORS file at the top-level directory of this distribution\n * License: GNU Affero General Public License version 3, or any later version\n * See top-level LICENSE file for more information\n */\n\nexport function initSnapshotNavigation(snapshotContext, branch) {\n\n function setBranchesTabActive() {\n $('.swh-releases-switch').removeClass('active');\n $('.swh-branches-switch').addClass('active');\n $('#swh-tab-releases').removeClass('active');\n $('#swh-tab-branches').addClass('active');\n }\n\n function setReleasesTabActive() {\n $('.swh-branches-switch').removeClass('active');\n $('.swh-releases-switch').addClass('active');\n $('#swh-tab-branches').removeClass('active');\n $('#swh-tab-releases').addClass('active');\n }\n\n $(document).ready(() => {\n $('.dropdown-menu a.swh-branches-switch').click(e => {\n setBranchesTabActive();\n e.stopPropagation();\n });\n\n $('.dropdown-menu a.swh-releases-switch').click(e => {\n setReleasesTabActive();\n e.stopPropagation();\n });\n\n let dropdownResized = false;\n\n // hack to resize the branches/releases dropdown content,\n // taking icons into account, in order to make the whole names readable\n $('#swh-branches-releases-dd').on('show.bs.dropdown', () => {\n if (dropdownResized) return;\n let dropdownWidth = $('.swh-branches-releases').width();\n $('.swh-branches-releases').width(dropdownWidth + 25);\n dropdownResized = true;\n });\n\n if (snapshotContext) {\n if (branch) {\n setBranchesTabActive();\n } else {\n setReleasesTabActive();\n }\n }\n\n });\n\n}\n","/**\n * Copyright (C) 2018 The Software Heritage developers\n * See the AUTHORS file at the top-level directory of this distribution\n * License: GNU Affero General Public License version 3, or any later version\n * See top-level LICENSE file for more information\n */\n\n$(document).ready(() => {\n\n $('.dropdown-submenu a.dropdown-item').on('click', e => {\n $(e.target).next('div').toggle();\n if ($(e.target).next('div').css('display') !== 'none') {\n $(e.target).focus();\n } else {\n $(e.target).blur();\n }\n e.stopPropagation();\n e.preventDefault();\n });\n\n $('.swh-popover-toggler').popover({\n boundary: 'viewport',\n container: 'body',\n html: true,\n template: `
\n
\n

\n
\n
`,\n content: function() {\n var content = $(this).attr('data-popover-content');\n return $(content).children('.popover-body').remove().html();\n },\n title: function() {\n var title = $(this).attr('data-popover-content');\n return $(title).children('.popover-heading').html();\n },\n offset: '50vh'\n });\n\n $('.swh-vault-menu a.dropdown-item').on('click', e => {\n $('.swh-popover-toggler').popover('hide');\n });\n\n $('.swh-popover-toggler').on('show.bs.popover', (e) => {\n $(`.swh-popover-toggler:not(#${e.currentTarget.id})`).popover('hide');\n $('.swh-vault-menu .dropdown-menu').hide();\n });\n\n $('.swh-actions-dropdown').on('hide.bs.dropdown', () => {\n $('.swh-vault-menu .dropdown-menu').hide();\n $('.swh-popover-toggler').popover('hide');\n });\n\n $('body').on('click', e => {\n if ($(e.target).parents('.swh-popover').length) {\n e.stopPropagation();\n }\n });\n\n});\n","/**\n * Copyright (C) 2018 The Software Heritage developers\n * See the AUTHORS file at the top-level directory of this distribution\n * License: GNU Affero General Public License version 3, or any later version\n * See top-level LICENSE file for more information\n */\n\nimport {handleFetchError, csrfPost, isGitRepoUrl} from 'utils/functions';\nimport {validate} from 'validate.js';\n\nlet saveRequestsTable;\n\nexport function initOriginSave() {\n\n $(document).ready(() => {\n\n fetch(Urls.browse_origin_save_types_list())\n .then(response => response.json())\n .then(data => {\n for (let originType of data) {\n $('#swh-input-origin-type').append(``);\n }\n });\n\n saveRequestsTable = $('#swh-origin-save-requests').DataTable({\n serverSide: true,\n ajax: Urls.browse_origin_save_requests_list('all'),\n columns: [\n {\n data: 'save_request_date',\n name: 'request_date',\n render: (data, type, row) => {\n if (type === 'display') {\n let date = new Date(data);\n return date.toLocaleString();\n }\n return data;\n }\n },\n {\n data: 'origin_type',\n name: 'origin_type'\n\n },\n {\n data: 'origin_url',\n name: 'origin_url',\n render: (data, type, row) => {\n if (type === 'display') {\n return `${data}`;\n }\n return data;\n }\n },\n {\n data: 'save_request_status',\n name: 'status'\n },\n {\n data: 'save_task_status',\n name: 'save_task_status',\n render: (data, type, row) => {\n if (data === 'succeed') {\n let browseOriginUrl = Urls.browse_origin(row.origin_url);\n if (row.visit_date) {\n browseOriginUrl += `visit/${row.visit_date}/`;\n }\n return `${data}`;\n }\n return data;\n }\n }\n ],\n scrollY: '50vh',\n scrollCollapse: true,\n order: [[0, 'desc']]\n });\n\n setInterval(() => {\n saveRequestsTable.ajax.reload(null, false);\n }, 5000);\n\n $('#swh-origin-save-requests-list-tab').on('shown.bs.tab', () => {\n saveRequestsTable.draw();\n });\n\n $('#swh-save-origin-form').submit(event => {\n event.preventDefault();\n event.stopPropagation();\n if (event.target.checkValidity()) {\n $(event.target).removeClass('was-validated');\n let originType = $('#swh-input-origin-type').val();\n let originUrl = $('#swh-input-origin-url').val();\n let addSaveOriginRequestUrl = Urls.browse_origin_save_request(originType, originUrl);\n let grecaptchaData = {'g-recaptcha-response': grecaptcha.getResponse()};\n let headers = {\n 'Accept': 'application/json',\n 'Content-Type': 'application/json'\n };\n let body = JSON.stringify(grecaptchaData);\n csrfPost(addSaveOriginRequestUrl, headers, body)\n .then(handleFetchError)\n .then(response => response.json())\n .then(data => {\n if (data.save_request_status === 'accepted') {\n $('#swh-origin-save-request-status').css('color', 'green');\n $('#swh-origin-save-request-status').text(\n 'The \"save code now\" request has been accepted and will be processed as soon as possible.');\n } else {\n $('#swh-origin-save-request-status').css('color', '#fecd1b');\n $('#swh-origin-save-request-status').text(\n 'The \"save code now\" request has been put in pending state and may be accepted for processing after manual review.');\n }\n grecaptcha.reset();\n })\n .catch(response => {\n if (response.status === 403) {\n $('#swh-origin-save-request-status').css('color', 'red');\n $('#swh-origin-save-request-status').text(\n 'The \"save code now\" request has been rejected because the reCAPTCHA could not be validated or the provided origin url is blacklisted.');\n }\n grecaptcha.reset();\n });\n } else {\n $(event.target).addClass('was-validated');\n }\n });\n\n $('#swh-show-origin-save-requests-list').on('click', (event) => {\n event.preventDefault();\n $('.nav-tabs a[href=\"#swh-origin-save-requests-list\"]').tab('show');\n });\n\n $('#swh-input-origin-url').on('input', function(event) {\n let originUrl = $(this).val();\n $('#swh-input-origin-type option').each(function() {\n let val = $(this).val();\n if (val && originUrl.includes(val)) {\n $(this).prop('selected', true);\n }\n });\n });\n\n });\n\n}\n\nexport function validateSaveOriginUrl(input) {\n let validUrl = validate({website: input.value}, {\n website: {\n url: {\n schemes: ['http', 'https', 'svn', 'git']\n }\n }\n }) === undefined;\n let originType = $('#swh-input-origin-type').val();\n if (originType === 'git' && validUrl) {\n // additional checks for well known code hosting providers\n let githubIdx = input.value.indexOf('://github.com');\n let gitlabIdx = input.value.indexOf('://gitlab.com');\n let gitSfIdx = input.value.indexOf('://git.code.sf.net');\n let bitbucketIdx = input.value.indexOf('://bitbucket.org');\n if (githubIdx !== -1 && githubIdx <= 5) {\n validUrl = isGitRepoUrl(input.value, 'github.com');\n } else if (gitlabIdx !== -1 && gitlabIdx <= 5) {\n validUrl = isGitRepoUrl(input.value, 'gitlab.com');\n } else if (gitSfIdx !== -1 && gitSfIdx <= 5) {\n validUrl = isGitRepoUrl(input.value, 'git.code.sf.net/p');\n } else if (bitbucketIdx !== -1 && bitbucketIdx <= 5) {\n validUrl = isGitRepoUrl(input.value, 'bitbucket.org');\n }\n }\n if (validUrl) {\n input.setCustomValidity('');\n } else {\n input.setCustomValidity('The origin url is not valid or does not reference a code repository');\n }\n}\n","module.exports = function() {\n\tthrow new Error(\"define cannot be used indirect\");\n};\n","/**\n * Copyright (C) 2018 The Software Heritage developers\n * See the AUTHORS file at the top-level directory of this distribution\n * License: GNU Affero General Public License version 3, or any later version\n * See top-level LICENSE file for more information\n */\n\n// http://dsernst.com/2014/12/14/heaps-permutation-algorithm-in-javascript/\n\nfunction swap(array, pos1, pos2) {\n let temp = array[pos1];\n array[pos1] = array[pos2];\n array[pos2] = temp;\n}\n\nexport function heapsPermute(array, output, n) {\n n = n || array.length; // set n default to array.length\n if (n === 1) {\n output(array);\n } else {\n for (let i = 1; i <= n; i += 1) {\n heapsPermute(array, output, n - 1);\n let j;\n if (n % 2) {\n j = 1;\n } else {\n j = i;\n }\n swap(array, j - 1, n - 1); // -1 to account for javascript zero-indexing\n }\n }\n}\n","/**\n * Copyright (C) 2018 The Software Heritage developers\n * See the AUTHORS file at the top-level directory of this distribution\n * License: GNU Affero General Public License version 3, or any later version\n * See top-level LICENSE file for more information\n */\n\nimport {heapsPermute} from 'utils/heaps-permute';\nimport {handleFetchError} from 'utils/functions';\n\nlet originPatterns;\nlet perPage = 20;\nlet limit = perPage * 10;\nlet offset = 0;\nlet currentData = null;\nlet inSearch = false;\n\nfunction fixTableRowsStyle() {\n setTimeout(() => {\n $('#origin-search-results tbody tr').removeAttr('style');\n });\n}\n\nfunction clearOriginSearchResultsTable() {\n $('#origin-search-results tbody tr').remove();\n}\n\nfunction populateOriginSearchResultsTable(data, offset) {\n let localOffset = offset % limit;\n if (data.length > 0) {\n $('#swh-origin-search-results').show();\n $('#swh-no-result').hide();\n clearOriginSearchResultsTable();\n let table = $('#origin-search-results tbody');\n for (let i = localOffset; i < localOffset + perPage && i < data.length; ++i) {\n let elem = data[i];\n let tableRow = '';\n tableRow += '' + elem.type + '';\n let browseUrl = Urls.browse_origin(elem.url);\n tableRow += '' + browseUrl + '';\n tableRow += '';\n tableRow += '';\n table.append(tableRow);\n // get async latest visit snapshot and update visit status icon\n let latestSnapshotUrl = Urls.browse_origin_latest_snapshot(elem.id);\n fetch(latestSnapshotUrl)\n .then(response => response.json())\n .then(data => {\n let originId = elem.id;\n $('#visit-status-origin-' + originId).children().remove();\n if (data) {\n $('#visit-status-origin-' + originId).append('');\n } else {\n $('#visit-status-origin-' + originId).append('');\n }\n });\n }\n fixTableRowsStyle();\n } else {\n $('#swh-origin-search-results').hide();\n $('#swh-no-result').text('No origins matching the search criteria were found.');\n $('#swh-no-result').show();\n }\n if (data.length - localOffset < perPage ||\n (data.length < limit && (localOffset + perPage) === data.length)) {\n $('#origins-next-results-button').addClass('disabled');\n } else {\n $('#origins-next-results-button').removeClass('disabled');\n }\n if (offset > 0) {\n $('#origins-prev-results-button').removeClass('disabled');\n } else {\n $('#origins-prev-results-button').addClass('disabled');\n }\n inSearch = false;\n if (typeof Storage !== 'undefined') {\n sessionStorage.setItem('last-swh-origin-search-offset', offset);\n }\n setTimeout(() => {\n window.scrollTo(0, 0);\n });\n}\n\nfunction escapeStringRegexp(str) {\n let matchOperatorsRe = /[|\\\\{}()[\\]^$+*?.]/g;\n return str.replace(matchOperatorsRe, '\\\\\\\\\\\\$&');\n}\n\nfunction searchOrigins(patterns, limit, searchOffset, offset) {\n originPatterns = patterns;\n let patternsArray = patterns.trim().replace(/\\s+/g, ' ').split(' ');\n for (let i = 0; i < patternsArray.length; ++i) {\n patternsArray[i] = escapeStringRegexp(patternsArray[i]);\n }\n let patternsPermut = [];\n heapsPermute(patternsArray, p => patternsPermut.push(p.join('.*')));\n let regex = patternsPermut.join('|');\n let withVisit = $('#swh-search-origins-with-visit').prop('checked');\n let searchUrl = Urls.browse_origin_search(regex) + `?limit=${limit}&offset=${searchOffset}®exp=true&with_visit=${withVisit}`;\n\n clearOriginSearchResultsTable();\n $('.swh-loading').addClass('show');\n fetch(searchUrl)\n .then(handleFetchError)\n .then(response => response.json())\n .then(data => {\n currentData = data;\n if (typeof Storage !== 'undefined') {\n sessionStorage.setItem('last-swh-origin-url-patterns', patterns);\n sessionStorage.setItem('last-swh-origin-search-results', JSON.stringify(data));\n sessionStorage.setItem('last-swh-origin-search-offset', offset);\n }\n $('.swh-loading').removeClass('show');\n populateOriginSearchResultsTable(data, offset);\n })\n .catch(response => {\n $('.swh-loading').removeClass('show');\n inSearch = false;\n $('#swh-origin-search-results').hide();\n response.text().then(errorDescription => {\n $('#swh-no-result').text(`Error ${response.status}: ${response.statusText}.\\n${errorDescription}`);\n $('#swh-no-result').show();\n });\n });\n}\n\nexport function initOriginSearch() {\n $(document).ready(() => {\n if (typeof Storage !== 'undefined') {\n originPatterns = sessionStorage.getItem('last-swh-origin-url-patterns');\n let data = sessionStorage.getItem('last-swh-origin-search-results');\n offset = sessionStorage.getItem('last-swh-origin-search-offset');\n if (data) {\n $('#origins-url-patterns').val(originPatterns);\n offset = parseInt(offset);\n currentData = JSON.parse(data);\n populateOriginSearchResultsTable(currentData, offset);\n }\n let withVisit = sessionStorage.getItem('last-swh-origin-with-visit');\n if (withVisit !== null) {\n $('#swh-search-origins-with-visit').prop('checked', JSON.parse(withVisit));\n }\n }\n\n $('#search_origins').submit(event => {\n event.preventDefault();\n $('#swh-no-result').hide();\n let patterns = $('#origins-url-patterns').val();\n offset = 0;\n inSearch = true;\n // first try to resolve a swh persistent identifier\n let resolvePidUrl = Urls.resolve_swh_pid(patterns);\n fetch(resolvePidUrl)\n .then(handleFetchError)\n .then(response => response.json())\n .then(data => {\n // pid has been successfully resolved,\n // so redirect to browse page\n window.location = data.browse_url;\n })\n .catch(response => {\n // pid resolving failed\n if (patterns.startsWith('swh:')) {\n // display a useful error message if the input\n // looks like a swh pid\n response.json().then(data => {\n $('#swh-origin-search-results').hide();\n $('.swh-search-pagination').hide();\n $('#swh-no-result').text(data.reason);\n $('#swh-no-result').show();\n });\n } else {\n // otherwise, proceed with origins search\n $('#swh-origin-search-results').show();\n $('.swh-search-pagination').show();\n searchOrigins(patterns, limit, offset, offset);\n }\n });\n });\n\n $('#origins-next-results-button').click(event => {\n if ($('#origins-next-results-button').hasClass('disabled') || inSearch) {\n return;\n }\n inSearch = true;\n offset += perPage;\n if (!currentData || (offset >= limit && offset % limit === 0)) {\n searchOrigins(originPatterns, limit, offset, offset);\n } else {\n populateOriginSearchResultsTable(currentData, offset);\n }\n event.preventDefault();\n });\n\n $('#origins-prev-results-button').click(event => {\n if ($('#origins-prev-results-button').hasClass('disabled') || inSearch) {\n return;\n }\n inSearch = true;\n offset -= perPage;\n if (!currentData || (offset > 0 && (offset + perPage) % limit === 0)) {\n searchOrigins(originPatterns, limit, (offset + perPage) - limit, offset);\n } else {\n populateOriginSearchResultsTable(currentData, offset);\n }\n event.preventDefault();\n });\n\n $(document).on('shown.bs.tab', 'a[data-toggle=\"tab\"]', e => {\n if (e.currentTarget.text.trim() === 'Search') {\n fixTableRowsStyle();\n }\n });\n\n $(window).on('unload', () => {\n if (typeof Storage !== 'undefined') {\n sessionStorage.setItem('last-swh-origin-with-visit',\n JSON.stringify($('#swh-search-origins-with-visit').prop('checked')));\n }\n });\n\n });\n}\n","/*\n tabSlideOUt v2.4\n\n Originally by William Paoli: http://code.google.com/p/tab-slide-out\n Maintained by Michael Fielding: https://github.com/hawk-ip/jquery.tabSlideOut.js\n License: GPL v3.0\n\n To use this you need an element for the tab panel content ('panel'), and inside it an element for the\n tab which will stick out from the window edge and be clickable ('handle'). By default the selector\n for handles is '.handle'.\n\n example HTML:\n\n
Click meHello World
\n\n example JavaScript (puts the tab on the right, and opens it on hover rather than click):\n\n $('#my-tab').tabSlideOut( {'tabLocation':'right','action':'hover'} );\n\n Style the tab panel and handle using CSS. Add the class ui-slideouttab-handle-rounded to handles to give them\n rounded outer corners.\n\n You can use some methods to programmatically interact with tabs. Methods except 'isOpen' are chainable.\n\n $('#my-tab').tabSlideOut('isOpen'); // return true or false\n $('#my-tab').tabSlideOut('open'); // opens it\n $('#my-tab').tabSlideOut('close'); // closes it\n $('#my-tab').tabSlideOut('toggle'); // toggles it\n $('#my-tab').tabSlideOut('bounce'); // bounces the tab\n\n You can also send JQuery events to initiate actions:\n\n $('#my-tab').trigger('open'); // opens it\n $('#my-tab').trigger('close'); // closes it\n $('#my-tab').trigger('toggle'); // toggles it\n $('#my-tab').trigger('bounce'); // bounces the tab\n\n Three events are defined and can be caught when tabs open and close:\n\n $(document).on('slideouttabopen slideouttabclose slideouttabbounce',function(event){\n var $panel = $(event.target);\n var eventType = event.type;\n // your code here\n });\n\n Features are demonstrated on the related demo page.\n*/\n(function($) {\n $.fn.tabSlideOut = function(callerSettings) {\n\n /**\n * @param node Element to get the height of.\n * @return string e.g. '123px'\n */\n function heightAsString(node) {\n return parseInt(node.outerHeight() + 1, 10) + 'px';\n }\n\n /*\n * Get the width of the given border, in pixels.\n *\n * @param node element\n * @param string edge\n * @returns int\n */\n function borderWidth(element, edge) {\n return parseInt(element.css('border-' + edge + '-width'), 10);\n }\n\n /**\n * Return the desired height of the panel to maintain both offsets.\n */\n function calculatePanelSize() {\n var available = $(window).height();\n if (edge === 'top' || edge === 'bottom') {\n available = $(window).width();\n }\n return available - parseInt(settings.otherOffset) - parseInt(settings.offset);\n }\n\n var panel = this;\n\n /**\n * True if the tab is open.\n *\n * @returns boolean\n */\n function isOpen() {\n return panel.hasClass('ui-slideouttab-open');\n }\n\n if (typeof callerSettings === 'string') {\n // param is a string, use command mode\n switch (callerSettings) {\n case 'open':\n this.trigger('open');\n return this;\n case 'close':\n this.trigger('close');\n return this;\n case 'isOpen':\n return isOpen();\n case 'toggle':\n this.trigger('toggle');\n return this;\n case 'bounce':\n this.trigger('bounce');\n return this;\n default:\n throw new Error('Invalid tabSlideOut command');\n }\n } else {\n // param is an object, it's initialisation mode\n var settings = $.extend({\n tabLocation: 'left', // left, right, top or bottom\n tabHandle: '.handle', // JQuery selector for the tab, can use any JQuery selector\n action: 'click', // action which will open the panel, e.g. 'hover'\n hoverTimeout: 5000, // ms to keep tab open after no longer hovered - only if action = 'hover'\n offset: '200px', // panel dist from top or left (bottom or right if offsetReverse is true)\n offsetReverse: false, // if true, panel is offset from right or bottom of window instead of left or top\n otherOffset: null, // if set, panel size is also set to maintain this dist from bottom or right of view port (top or left if offsetReverse)\n handleOffset: null, // e.g. '10px'. If null, detects panel border to align handle nicely on edge\n handleOffsetReverse: false, // if true, handle is offset from right or bottom of panel instead of left or top\n bounceDistance: '50px', // how far bounce event will move everything\n bounceTimes: 4, // how many bounces when 'bounce' is called\n bounceSpeed: 300, // time to animate bounces\n tabImage: null, // optional image to show in the tab\n tabImageHeight: null, // optional IE8 and lower only, else autodetected size\n tabImageWidth: null, // optional IE8 and lower only, else autodetected size\n onLoadSlideOut: false, // slide out after DOM load\n clickScreenToClose: true, // close tab when somewhere outside the tab is clicked\n clickScreenToCloseFilters: ['.ui-slideouttab-panel'], // if click target or parents match any of these, click won't close this tab\n onOpen: function() {}, // handler called after opening\n onClose: function() {} // handler called after closing\n }, callerSettings || {});\n\n var edge = settings.tabLocation;\n var handle = settings.tabHandle = $(settings.tabHandle, panel);\n\n panel.addClass('ui-slideouttab-panel')\n .addClass('ui-slideouttab-' + edge);\n if (settings.offsetReverse) {\n panel.addClass('ui-slideouttab-panel-reverse');\n }\n handle.addClass('ui-slideouttab-handle'); // need this to find it later\n if (settings.handleOffsetReverse) {\n handle.addClass('ui-slideouttab-handle-reverse');\n }\n settings.toggleButton = $(settings.toggleButton);\n\n // apply an image to the tab if one is defined\n if (settings.tabImage !== null) {\n var imageHeight = 0;\n var imageWidth = 0;\n if (settings.tabImageHeight !== null && settings.tabImageWidth !== null) {\n imageHeight = settings.tabImageHeight;\n imageWidth = settings.tabImageWidth;\n } else {\n var img = new Image();\n img.src = settings.tabImage;\n imageHeight = img.naturalHeight;\n imageWidth = img.naturalWidth;\n }\n\n handle.addClass('ui-slideouttab-handle-image');\n handle.css({\n 'background': 'url(' + settings.tabImage + ') no-repeat',\n 'width': imageWidth,\n 'height': imageHeight\n });\n }\n\n // determine whether panel and handle are positioned from top, bottom, left, or right\n if (edge === 'top' || edge === 'bottom') {\n settings.panelOffsetFrom =\n settings.offsetReverse ? 'right' : 'left';\n settings.handleOffsetFrom =\n settings.handleOffsetReverse ? 'right' : 'left';\n } else {\n settings.panelOffsetFrom =\n settings.offsetReverse ? 'bottom' : 'top';\n settings.handleOffsetFrom =\n settings.handleOffsetReverse ? 'bottom' : 'top';\n }\n\n /* autodetect the correct offset for the handle using appropriate panel border */\n if (settings.handleOffset === null) {\n settings.handleOffset = '-' + borderWidth(panel, settings.handleOffsetFrom) + 'px';\n }\n\n if (edge === 'top' || edge === 'bottom') {\n /* set left or right edges */\n panel.css(settings.panelOffsetFrom, settings.offset);\n handle.css(settings.handleOffsetFrom, settings.handleOffset);\n\n // possibly drive the panel size\n if (settings.otherOffset !== null) {\n panel.css('width', calculatePanelSize() + 'px');\n // install resize handler\n $(window).resize(function() {\n panel.css('width', calculatePanelSize() + 'px');\n });\n }\n\n if (edge === 'top') {\n handle.css({'bottom': '-' + heightAsString(handle)});\n } else {\n handle.css({'top': '-' + heightAsString(handle)});\n }\n } else {\n /* set top or bottom edge */\n panel.css(settings.panelOffsetFrom, settings.offset);\n handle.css(settings.handleOffsetFrom, settings.handleOffset);\n\n // possibly drive the panel size\n if (settings.otherOffset !== null) {\n panel.css('height', calculatePanelSize() + 'px');\n // install resize handler\n $(window).resize(function() {\n panel.css('height', calculatePanelSize() + 'px');\n });\n }\n\n if (edge === 'left') {\n handle.css({'right': '0'});\n } else {\n handle.css({'left': '0'});\n }\n }\n\n handle.click(function(event) {\n event.preventDefault();\n });\n settings.toggleButton.click(function(event) {\n event.preventDefault();\n });\n\n // now everything is set up, add the class which enables CSS tab animation\n panel.addClass('ui-slideouttab-ready');\n\n var close = function() {\n panel.removeClass('ui-slideouttab-open').trigger('slideouttabclose');\n settings.onClose();\n };\n\n var open = function() {\n panel.addClass('ui-slideouttab-open').trigger('slideouttabopen');\n settings.onOpen();\n };\n\n var toggle = function() {\n if (isOpen()) {\n close();\n } else {\n open();\n }\n };\n\n // animate the tab in and out when 'bounced'\n var moveIn = [];\n moveIn[edge] = '-=' + settings.bounceDistance;\n var moveOut = [];\n moveOut[edge] = '+=' + settings.bounceDistance;\n\n var bounceIn = function() {\n var temp = panel;\n for (var i = 0; i < settings.bounceTimes; i++) {\n temp = temp.animate(moveIn, settings.bounceSpeed)\n .animate(moveOut, settings.bounceSpeed);\n }\n panel.trigger('slideouttabbounce');\n };\n\n var bounceOut = function() {\n var temp = panel;\n for (var i = 0; i < settings.bounceTimes; i++) {\n temp = temp.animate(moveOut, settings.bounceSpeed)\n .animate(moveIn, settings.bounceSpeed);\n }\n panel.trigger('slideouttabbounce');\n };\n\n // handle clicks in rest of document to close tabs if they're open\n if (settings.clickScreenToClose) {\n // install a click handler to close tab if anywhere outside the tab is clicked,\n // that isn't filtered out by the configured filters\n $(document).click(function(event) {\n // first check the tab is open and the click isn't inside it\n if (isOpen() && !panel[0].contains(event.target)) {\n // something other than this panel was clicked\n var clicked = $(event.target);\n\n // check to see if any filters return true\n for (var i = 0; i < settings.clickScreenToCloseFilters.length; i++) {\n var filter = settings.clickScreenToCloseFilters[i];\n if (typeof filter === 'string') {\n // checked clicked element itself, and all parents\n if (clicked.is(filter) || clicked.parents().is(filter)) {\n return; // don't close the tab\n }\n } else if (typeof filter === 'function') {\n // call custom filter\n if (filter.call(panel, event)) {\n return;\n } // don't close the tab\n }\n }\n\n // we haven't returned true from any filter, so close the tab\n close();\n }\n });\n };\n\n // choose which type of action to bind\n if (settings.action === 'click') {\n handle.click(function(event) {\n toggle();\n });\n } else if (settings.action === 'hover') {\n var timer = null;\n panel.hover(\n function() {\n if (!isOpen()) {\n open();\n }\n timer = null; // eliminate the timer, ensure we don't close now\n },\n function() {\n if (isOpen() && timer === null) {\n timer = setTimeout(function() {\n if (timer) {\n close();\n }\n timer = null;\n }, settings.hoverTimeout);\n }\n });\n\n handle.click(function(event) {\n if (isOpen()) {\n close();\n }\n });\n }\n\n if (settings.onLoadSlideOut) {\n open();\n setTimeout(open, 500);\n }\n\n // custom event handlers -------\n panel.on('open', function(event) {\n if (!isOpen()) {\n open();\n }\n });\n panel.on('close', function(event) {\n if (isOpen()) {\n close();\n }\n });\n panel.on('toggle', function(event) {\n toggle();\n });\n panel.on('bounce', function(event) {\n if (isOpen()) {\n bounceIn();\n } else {\n bounceOut();\n }\n });\n\n }\n return this;\n };\n})(jQuery);\n","/**\n * Copyright (C) 2018 The Software Heritage developers\n * See the AUTHORS file at the top-level directory of this distribution\n * License: GNU Affero General Public License version 3, or any later version\n * See top-level LICENSE file for more information\n */\n\nimport ClipboardJS from 'clipboard';\nimport 'utils/jquery.tabSlideOut';\nimport 'utils/jquery.tabSlideOut.css';\n\nexport function swhIdObjectTypeToggled(event) {\n event.preventDefault();\n $(event.target).tab('show');\n}\n\nexport function swhIdOptionOriginToggled(event) {\n event.stopPropagation();\n let swhIdElt = $(event.target).closest('.swh-id-ui').find('.swh-id');\n let originPart = ';origin=' + $(event.target).data('swh-origin');\n let currentSwhId = swhIdElt.text();\n if ($(event.target).prop('checked')) {\n currentSwhId += originPart;\n } else {\n currentSwhId = currentSwhId.replace(originPart, '');\n }\n swhIdElt.text(currentSwhId);\n swhIdElt.attr('href', '/' + currentSwhId + '/');\n}\n\nfunction setIdLinesPart(elt) {\n let swhIdElt = $(elt).closest('.swh-id-ui').find('.swh-id');\n let currentSwhId = swhIdElt.text();\n let lines = [];\n let linesPart = ';lines=';\n let linesRegexp = new RegExp(/L(\\d+)/g);\n let line = linesRegexp.exec(window.location.hash);\n while (line) {\n lines.push(parseInt(line[1]));\n line = linesRegexp.exec(window.location.hash);\n }\n if (lines.length > 0) {\n linesPart += lines[0];\n }\n if (lines.length > 1) {\n linesPart += '-' + lines[1];\n }\n if ($(elt).prop('checked')) {\n currentSwhId = currentSwhId.replace(/;lines=\\d+-*\\d*/g, '');\n currentSwhId += linesPart;\n } else {\n currentSwhId = currentSwhId.replace(linesPart, '');\n }\n swhIdElt.text(currentSwhId);\n swhIdElt.attr('href', '/' + currentSwhId + '/');\n}\n\nexport function swhIdOptionLinesToggled(event) {\n event.stopPropagation();\n if (!window.location.hash) {\n return;\n }\n setIdLinesPart(event.target);\n}\n\n$(document).ready(() => {\n new ClipboardJS('.btn-swh-id-copy', {\n text: trigger => {\n let swhId = $(trigger).closest('.swh-id-ui').find('.swh-id').text();\n return swhId;\n }\n });\n\n new ClipboardJS('.btn-swh-id-url-copy', {\n text: trigger => {\n let swhId = $(trigger).closest('.swh-id-ui').find('.swh-id').text();\n return window.location.origin + '/' + swhId + '/';\n }\n });\n\n if (window.innerWidth * 0.7 > 1000) {\n $('#swh-identifiers').css('width', '1000px');\n }\n\n let tabSlideOptions = {\n tabLocation: 'right'\n };\n // ensure tab scrolling on small screens\n if (window.innerHeight < 600 || window.innerWidth < 500) {\n tabSlideOptions['otherOffset'] = '20px';\n }\n\n // initiate the sliding identifiers tab\n $('#swh-identifiers').tabSlideOut(tabSlideOptions);\n\n // set the tab visible once the close animation is terminated\n setTimeout(() => {\n $('#swh-identifiers').css('visibility', 'visible');\n $('.swh-id-option-origin').trigger('click');\n $('.swh-id-option-lines').trigger('click');\n });\n\n $(window).on('hashchange', () => {\n setIdLinesPart('.swh-id-option-lines');\n });\n\n});\n","module.exports = require(\"core-js/library/fn/get-iterator\");","module.exports = require(\"core-js/library/fn/array/is-array\");","/*!\n * validate.js 0.12.0\n *\n * (c) 2013-2017 Nicklas Ansman, 2013 Wrapp\n * Validate.js may be freely distributed under the MIT license.\n * For all details and documentation:\n * http://validatejs.org/\n */\n\n(function(exports, module, define) {\n \"use strict\";\n\n // The main function that calls the validators specified by the constraints.\n // The options are the following:\n // - format (string) - An option that controls how the returned value is formatted\n // * flat - Returns a flat array of just the error messages\n // * grouped - Returns the messages grouped by attribute (default)\n // * detailed - Returns an array of the raw validation data\n // - fullMessages (boolean) - If `true` (default) the attribute name is prepended to the error.\n //\n // Please note that the options are also passed to each validator.\n var validate = function(attributes, constraints, options) {\n options = v.extend({}, v.options, options);\n\n var results = v.runValidations(attributes, constraints, options)\n , attr\n , validator;\n\n if (results.some(function(r) { return v.isPromise(r.error); })) {\n throw new Error(\"Use validate.async if you want support for promises\");\n }\n return validate.processValidationResults(results, options);\n };\n\n var v = validate;\n\n // Copies over attributes from one or more sources to a single destination.\n // Very much similar to underscore's extend.\n // The first argument is the target object and the remaining arguments will be\n // used as sources.\n v.extend = function(obj) {\n [].slice.call(arguments, 1).forEach(function(source) {\n for (var attr in source) {\n obj[attr] = source[attr];\n }\n });\n return obj;\n };\n\n v.extend(validate, {\n // This is the version of the library as a semver.\n // The toString function will allow it to be coerced into a string\n version: {\n major: 0,\n minor: 12,\n patch: 0,\n metadata: null,\n toString: function() {\n var version = v.format(\"%{major}.%{minor}.%{patch}\", v.version);\n if (!v.isEmpty(v.version.metadata)) {\n version += \"+\" + v.version.metadata;\n }\n return version;\n }\n },\n\n // Below is the dependencies that are used in validate.js\n\n // The constructor of the Promise implementation.\n // If you are using Q.js, RSVP or any other A+ compatible implementation\n // override this attribute to be the constructor of that promise.\n // Since jQuery promises aren't A+ compatible they won't work.\n Promise: typeof Promise !== \"undefined\" ? Promise : /* istanbul ignore next */ null,\n\n EMPTY_STRING_REGEXP: /^\\s*$/,\n\n // Runs the validators specified by the constraints object.\n // Will return an array of the format:\n // [{attribute: \"\", error: \"\"}, ...]\n runValidations: function(attributes, constraints, options) {\n var results = []\n , attr\n , validatorName\n , value\n , validators\n , validator\n , validatorOptions\n , error;\n\n if (v.isDomElement(attributes) || v.isJqueryElement(attributes)) {\n attributes = v.collectFormValues(attributes);\n }\n\n // Loops through each constraints, finds the correct validator and run it.\n for (attr in constraints) {\n value = v.getDeepObjectValue(attributes, attr);\n // This allows the constraints for an attribute to be a function.\n // The function will be called with the value, attribute name, the complete dict of\n // attributes as well as the options and constraints passed in.\n // This is useful when you want to have different\n // validations depending on the attribute value.\n validators = v.result(constraints[attr], value, attributes, attr, options, constraints);\n\n for (validatorName in validators) {\n validator = v.validators[validatorName];\n\n if (!validator) {\n error = v.format(\"Unknown validator %{name}\", {name: validatorName});\n throw new Error(error);\n }\n\n validatorOptions = validators[validatorName];\n // This allows the options to be a function. The function will be\n // called with the value, attribute name, the complete dict of\n // attributes as well as the options and constraints passed in.\n // This is useful when you want to have different\n // validations depending on the attribute value.\n validatorOptions = v.result(validatorOptions, value, attributes, attr, options, constraints);\n if (!validatorOptions) {\n continue;\n }\n results.push({\n attribute: attr,\n value: value,\n validator: validatorName,\n globalOptions: options,\n attributes: attributes,\n options: validatorOptions,\n error: validator.call(validator,\n value,\n validatorOptions,\n attr,\n attributes,\n options)\n });\n }\n }\n\n return results;\n },\n\n // Takes the output from runValidations and converts it to the correct\n // output format.\n processValidationResults: function(errors, options) {\n errors = v.pruneEmptyErrors(errors, options);\n errors = v.expandMultipleErrors(errors, options);\n errors = v.convertErrorMessages(errors, options);\n\n var format = options.format || \"grouped\";\n\n if (typeof v.formatters[format] === 'function') {\n errors = v.formatters[format](errors);\n } else {\n throw new Error(v.format(\"Unknown format %{format}\", options));\n }\n\n return v.isEmpty(errors) ? undefined : errors;\n },\n\n // Runs the validations with support for promises.\n // This function will return a promise that is settled when all the\n // validation promises have been completed.\n // It can be called even if no validations returned a promise.\n async: function(attributes, constraints, options) {\n options = v.extend({}, v.async.options, options);\n\n var WrapErrors = options.wrapErrors || function(errors) {\n return errors;\n };\n\n // Removes unknown attributes\n if (options.cleanAttributes !== false) {\n attributes = v.cleanAttributes(attributes, constraints);\n }\n\n var results = v.runValidations(attributes, constraints, options);\n\n return new v.Promise(function(resolve, reject) {\n v.waitForResults(results).then(function() {\n var errors = v.processValidationResults(results, options);\n if (errors) {\n reject(new WrapErrors(errors, options, attributes, constraints));\n } else {\n resolve(attributes);\n }\n }, function(err) {\n reject(err);\n });\n });\n },\n\n single: function(value, constraints, options) {\n options = v.extend({}, v.single.options, options, {\n format: \"flat\",\n fullMessages: false\n });\n return v({single: value}, {single: constraints}, options);\n },\n\n // Returns a promise that is resolved when all promises in the results array\n // are settled. The promise returned from this function is always resolved,\n // never rejected.\n // This function modifies the input argument, it replaces the promises\n // with the value returned from the promise.\n waitForResults: function(results) {\n // Create a sequence of all the results starting with a resolved promise.\n return results.reduce(function(memo, result) {\n // If this result isn't a promise skip it in the sequence.\n if (!v.isPromise(result.error)) {\n return memo;\n }\n\n return memo.then(function() {\n return result.error.then(function(error) {\n result.error = error || null;\n });\n });\n }, new v.Promise(function(r) { r(); })); // A resolved promise\n },\n\n // If the given argument is a call: function the and: function return the value\n // otherwise just return the value. Additional arguments will be passed as\n // arguments to the function.\n // Example:\n // ```\n // result('foo') // 'foo'\n // result(Math.max, 1, 2) // 2\n // ```\n result: function(value) {\n var args = [].slice.call(arguments, 1);\n if (typeof value === 'function') {\n value = value.apply(null, args);\n }\n return value;\n },\n\n // Checks if the value is a number. This function does not consider NaN a\n // number like many other `isNumber` functions do.\n isNumber: function(value) {\n return typeof value === 'number' && !isNaN(value);\n },\n\n // Returns false if the object is not a function\n isFunction: function(value) {\n return typeof value === 'function';\n },\n\n // A simple check to verify that the value is an integer. Uses `isNumber`\n // and a simple modulo check.\n isInteger: function(value) {\n return v.isNumber(value) && value % 1 === 0;\n },\n\n // Checks if the value is a boolean\n isBoolean: function(value) {\n return typeof value === 'boolean';\n },\n\n // Uses the `Object` function to check if the given argument is an object.\n isObject: function(obj) {\n return obj === Object(obj);\n },\n\n // Simply checks if the object is an instance of a date\n isDate: function(obj) {\n return obj instanceof Date;\n },\n\n // Returns false if the object is `null` of `undefined`\n isDefined: function(obj) {\n return obj !== null && obj !== undefined;\n },\n\n // Checks if the given argument is a promise. Anything with a `then`\n // function is considered a promise.\n isPromise: function(p) {\n return !!p && v.isFunction(p.then);\n },\n\n isJqueryElement: function(o) {\n return o && v.isString(o.jquery);\n },\n\n isDomElement: function(o) {\n if (!o) {\n return false;\n }\n\n if (!o.querySelectorAll || !o.querySelector) {\n return false;\n }\n\n if (v.isObject(document) && o === document) {\n return true;\n }\n\n // http://stackoverflow.com/a/384380/699304\n /* istanbul ignore else */\n if (typeof HTMLElement === \"object\") {\n return o instanceof HTMLElement;\n } else {\n return o &&\n typeof o === \"object\" &&\n o !== null &&\n o.nodeType === 1 &&\n typeof o.nodeName === \"string\";\n }\n },\n\n isEmpty: function(value) {\n var attr;\n\n // Null and undefined are empty\n if (!v.isDefined(value)) {\n return true;\n }\n\n // functions are non empty\n if (v.isFunction(value)) {\n return false;\n }\n\n // Whitespace only strings are empty\n if (v.isString(value)) {\n return v.EMPTY_STRING_REGEXP.test(value);\n }\n\n // For arrays we use the length property\n if (v.isArray(value)) {\n return value.length === 0;\n }\n\n // Dates have no attributes but aren't empty\n if (v.isDate(value)) {\n return false;\n }\n\n // If we find at least one property we consider it non empty\n if (v.isObject(value)) {\n for (attr in value) {\n return false;\n }\n return true;\n }\n\n return false;\n },\n\n // Formats the specified strings with the given values like so:\n // ```\n // format(\"Foo: %{foo}\", {foo: \"bar\"}) // \"Foo bar\"\n // ```\n // If you want to write %{...} without having it replaced simply\n // prefix it with % like this `Foo: %%{foo}` and it will be returned\n // as `\"Foo: %{foo}\"`\n format: v.extend(function(str, vals) {\n if (!v.isString(str)) {\n return str;\n }\n return str.replace(v.format.FORMAT_REGEXP, function(m0, m1, m2) {\n if (m1 === '%') {\n return \"%{\" + m2 + \"}\";\n } else {\n return String(vals[m2]);\n }\n });\n }, {\n // Finds %{key} style patterns in the given string\n FORMAT_REGEXP: /(%?)%\\{([^\\}]+)\\}/g\n }),\n\n // \"Prettifies\" the given string.\n // Prettifying means replacing [.\\_-] with spaces as well as splitting\n // camel case words.\n prettify: function(str) {\n if (v.isNumber(str)) {\n // If there are more than 2 decimals round it to two\n if ((str * 100) % 1 === 0) {\n return \"\" + str;\n } else {\n return parseFloat(Math.round(str * 100) / 100).toFixed(2);\n }\n }\n\n if (v.isArray(str)) {\n return str.map(function(s) { return v.prettify(s); }).join(\", \");\n }\n\n if (v.isObject(str)) {\n return str.toString();\n }\n\n // Ensure the string is actually a string\n str = \"\" + str;\n\n return str\n // Splits keys separated by periods\n .replace(/([^\\s])\\.([^\\s])/g, '$1 $2')\n // Removes backslashes\n .replace(/\\\\+/g, '')\n // Replaces - and - with space\n .replace(/[_-]/g, ' ')\n // Splits camel cased words\n .replace(/([a-z])([A-Z])/g, function(m0, m1, m2) {\n return \"\" + m1 + \" \" + m2.toLowerCase();\n })\n .toLowerCase();\n },\n\n stringifyValue: function(value, options) {\n var prettify = options && options.prettify || v.prettify;\n return prettify(value);\n },\n\n isString: function(value) {\n return typeof value === 'string';\n },\n\n isArray: function(value) {\n return {}.toString.call(value) === '[object Array]';\n },\n\n // Checks if the object is a hash, which is equivalent to an object that\n // is neither an array nor a function.\n isHash: function(value) {\n return v.isObject(value) && !v.isArray(value) && !v.isFunction(value);\n },\n\n contains: function(obj, value) {\n if (!v.isDefined(obj)) {\n return false;\n }\n if (v.isArray(obj)) {\n return obj.indexOf(value) !== -1;\n }\n return value in obj;\n },\n\n unique: function(array) {\n if (!v.isArray(array)) {\n return array;\n }\n return array.filter(function(el, index, array) {\n return array.indexOf(el) == index;\n });\n },\n\n forEachKeyInKeypath: function(object, keypath, callback) {\n if (!v.isString(keypath)) {\n return undefined;\n }\n\n var key = \"\"\n , i\n , escape = false;\n\n for (i = 0; i < keypath.length; ++i) {\n switch (keypath[i]) {\n case '.':\n if (escape) {\n escape = false;\n key += '.';\n } else {\n object = callback(object, key, false);\n key = \"\";\n }\n break;\n\n case '\\\\':\n if (escape) {\n escape = false;\n key += '\\\\';\n } else {\n escape = true;\n }\n break;\n\n default:\n escape = false;\n key += keypath[i];\n break;\n }\n }\n\n return callback(object, key, true);\n },\n\n getDeepObjectValue: function(obj, keypath) {\n if (!v.isObject(obj)) {\n return undefined;\n }\n\n return v.forEachKeyInKeypath(obj, keypath, function(obj, key) {\n if (v.isObject(obj)) {\n return obj[key];\n }\n });\n },\n\n // This returns an object with all the values of the form.\n // It uses the input name as key and the value as value\n // So for example this:\n // \n // would return:\n // {email: \"foo@bar.com\"}\n collectFormValues: function(form, options) {\n var values = {}\n , i\n , j\n , input\n , inputs\n , option\n , value;\n\n if (v.isJqueryElement(form)) {\n form = form[0];\n }\n\n if (!form) {\n return values;\n }\n\n options = options || {};\n\n inputs = form.querySelectorAll(\"input[name], textarea[name]\");\n for (i = 0; i < inputs.length; ++i) {\n input = inputs.item(i);\n\n if (v.isDefined(input.getAttribute(\"data-ignored\"))) {\n continue;\n }\n\n name = input.name.replace(/\\./g, \"\\\\\\\\.\");\n value = v.sanitizeFormValue(input.value, options);\n if (input.type === \"number\") {\n value = value ? +value : null;\n } else if (input.type === \"checkbox\") {\n if (input.attributes.value) {\n if (!input.checked) {\n value = values[name] || null;\n }\n } else {\n value = input.checked;\n }\n } else if (input.type === \"radio\") {\n if (!input.checked) {\n value = values[name] || null;\n }\n }\n values[name] = value;\n }\n\n inputs = form.querySelectorAll(\"select[name]\");\n for (i = 0; i < inputs.length; ++i) {\n input = inputs.item(i);\n if (v.isDefined(input.getAttribute(\"data-ignored\"))) {\n continue;\n }\n\n if (input.multiple) {\n value = [];\n for (j in input.options) {\n option = input.options[j];\n if (option && option.selected) {\n value.push(v.sanitizeFormValue(option.value, options));\n }\n }\n } else {\n var _val = typeof input.options[input.selectedIndex] !== 'undefined' ? input.options[input.selectedIndex].value : '';\n value = v.sanitizeFormValue(_val, options);\n }\n values[input.name] = value;\n }\n\n return values;\n },\n\n sanitizeFormValue: function(value, options) {\n if (options.trim && v.isString(value)) {\n value = value.trim();\n }\n\n if (options.nullify !== false && value === \"\") {\n return null;\n }\n return value;\n },\n\n capitalize: function(str) {\n if (!v.isString(str)) {\n return str;\n }\n return str[0].toUpperCase() + str.slice(1);\n },\n\n // Remove all errors who's error attribute is empty (null or undefined)\n pruneEmptyErrors: function(errors) {\n return errors.filter(function(error) {\n return !v.isEmpty(error.error);\n });\n },\n\n // In\n // [{error: [\"err1\", \"err2\"], ...}]\n // Out\n // [{error: \"err1\", ...}, {error: \"err2\", ...}]\n //\n // All attributes in an error with multiple messages are duplicated\n // when expanding the errors.\n expandMultipleErrors: function(errors) {\n var ret = [];\n errors.forEach(function(error) {\n // Removes errors without a message\n if (v.isArray(error.error)) {\n error.error.forEach(function(msg) {\n ret.push(v.extend({}, error, {error: msg}));\n });\n } else {\n ret.push(error);\n }\n });\n return ret;\n },\n\n // Converts the error mesages by prepending the attribute name unless the\n // message is prefixed by ^\n convertErrorMessages: function(errors, options) {\n options = options || {};\n\n var ret = []\n , prettify = options.prettify || v.prettify;\n errors.forEach(function(errorInfo) {\n var error = v.result(errorInfo.error,\n errorInfo.value,\n errorInfo.attribute,\n errorInfo.options,\n errorInfo.attributes,\n errorInfo.globalOptions);\n\n if (!v.isString(error)) {\n ret.push(errorInfo);\n return;\n }\n\n if (error[0] === '^') {\n error = error.slice(1);\n } else if (options.fullMessages !== false) {\n error = v.capitalize(prettify(errorInfo.attribute)) + \" \" + error;\n }\n error = error.replace(/\\\\\\^/g, \"^\");\n error = v.format(error, {\n value: v.stringifyValue(errorInfo.value, options)\n });\n ret.push(v.extend({}, errorInfo, {error: error}));\n });\n return ret;\n },\n\n // In:\n // [{attribute: \"\", ...}]\n // Out:\n // {\"\": [{attribute: \"\", ...}]}\n groupErrorsByAttribute: function(errors) {\n var ret = {};\n errors.forEach(function(error) {\n var list = ret[error.attribute];\n if (list) {\n list.push(error);\n } else {\n ret[error.attribute] = [error];\n }\n });\n return ret;\n },\n\n // In:\n // [{error: \"\", ...}, {error: \"\", ...}]\n // Out:\n // [\"\", \"\"]\n flattenErrorsToArray: function(errors) {\n return errors\n .map(function(error) { return error.error; })\n .filter(function(value, index, self) {\n return self.indexOf(value) === index;\n });\n },\n\n cleanAttributes: function(attributes, whitelist) {\n function whitelistCreator(obj, key, last) {\n if (v.isObject(obj[key])) {\n return obj[key];\n }\n return (obj[key] = last ? true : {});\n }\n\n function buildObjectWhitelist(whitelist) {\n var ow = {}\n , lastObject\n , attr;\n for (attr in whitelist) {\n if (!whitelist[attr]) {\n continue;\n }\n v.forEachKeyInKeypath(ow, attr, whitelistCreator);\n }\n return ow;\n }\n\n function cleanRecursive(attributes, whitelist) {\n if (!v.isObject(attributes)) {\n return attributes;\n }\n\n var ret = v.extend({}, attributes)\n , w\n , attribute;\n\n for (attribute in attributes) {\n w = whitelist[attribute];\n\n if (v.isObject(w)) {\n ret[attribute] = cleanRecursive(ret[attribute], w);\n } else if (!w) {\n delete ret[attribute];\n }\n }\n return ret;\n }\n\n if (!v.isObject(whitelist) || !v.isObject(attributes)) {\n return {};\n }\n\n whitelist = buildObjectWhitelist(whitelist);\n return cleanRecursive(attributes, whitelist);\n },\n\n exposeModule: function(validate, root, exports, module, define) {\n if (exports) {\n if (module && module.exports) {\n exports = module.exports = validate;\n }\n exports.validate = validate;\n } else {\n root.validate = validate;\n if (validate.isFunction(define) && define.amd) {\n define([], function () { return validate; });\n }\n }\n },\n\n warn: function(msg) {\n if (typeof console !== \"undefined\" && console.warn) {\n console.warn(\"[validate.js] \" + msg);\n }\n },\n\n error: function(msg) {\n if (typeof console !== \"undefined\" && console.error) {\n console.error(\"[validate.js] \" + msg);\n }\n }\n });\n\n validate.validators = {\n // Presence validates that the value isn't empty\n presence: function(value, options) {\n options = v.extend({}, this.options, options);\n if (options.allowEmpty !== false ? !v.isDefined(value) : v.isEmpty(value)) {\n return options.message || this.message || \"can't be blank\";\n }\n },\n length: function(value, options, attribute) {\n // Empty values are allowed\n if (!v.isDefined(value)) {\n return;\n }\n\n options = v.extend({}, this.options, options);\n\n var is = options.is\n , maximum = options.maximum\n , minimum = options.minimum\n , tokenizer = options.tokenizer || function(val) { return val; }\n , err\n , errors = [];\n\n value = tokenizer(value);\n var length = value.length;\n if(!v.isNumber(length)) {\n v.error(v.format(\"Attribute %{attr} has a non numeric value for `length`\", {attr: attribute}));\n return options.message || this.notValid || \"has an incorrect length\";\n }\n\n // Is checks\n if (v.isNumber(is) && length !== is) {\n err = options.wrongLength ||\n this.wrongLength ||\n \"is the wrong length (should be %{count} characters)\";\n errors.push(v.format(err, {count: is}));\n }\n\n if (v.isNumber(minimum) && length < minimum) {\n err = options.tooShort ||\n this.tooShort ||\n \"is too short (minimum is %{count} characters)\";\n errors.push(v.format(err, {count: minimum}));\n }\n\n if (v.isNumber(maximum) && length > maximum) {\n err = options.tooLong ||\n this.tooLong ||\n \"is too long (maximum is %{count} characters)\";\n errors.push(v.format(err, {count: maximum}));\n }\n\n if (errors.length > 0) {\n return options.message || errors;\n }\n },\n numericality: function(value, options, attribute, attributes, globalOptions) {\n // Empty values are fine\n if (!v.isDefined(value)) {\n return;\n }\n\n options = v.extend({}, this.options, options);\n\n var errors = []\n , name\n , count\n , checks = {\n greaterThan: function(v, c) { return v > c; },\n greaterThanOrEqualTo: function(v, c) { return v >= c; },\n equalTo: function(v, c) { return v === c; },\n lessThan: function(v, c) { return v < c; },\n lessThanOrEqualTo: function(v, c) { return v <= c; },\n divisibleBy: function(v, c) { return v % c === 0; }\n }\n , prettify = options.prettify ||\n (globalOptions && globalOptions.prettify) ||\n v.prettify;\n\n // Strict will check that it is a valid looking number\n if (v.isString(value) && options.strict) {\n var pattern = \"^-?(0|[1-9]\\\\d*)\";\n if (!options.onlyInteger) {\n pattern += \"(\\\\.\\\\d+)?\";\n }\n pattern += \"$\";\n\n if (!(new RegExp(pattern).test(value))) {\n return options.message ||\n options.notValid ||\n this.notValid ||\n this.message ||\n \"must be a valid number\";\n }\n }\n\n // Coerce the value to a number unless we're being strict.\n if (options.noStrings !== true && v.isString(value) && !v.isEmpty(value)) {\n value = +value;\n }\n\n // If it's not a number we shouldn't continue since it will compare it.\n if (!v.isNumber(value)) {\n return options.message ||\n options.notValid ||\n this.notValid ||\n this.message ||\n \"is not a number\";\n }\n\n // Same logic as above, sort of. Don't bother with comparisons if this\n // doesn't pass.\n if (options.onlyInteger && !v.isInteger(value)) {\n return options.message ||\n options.notInteger ||\n this.notInteger ||\n this.message ||\n \"must be an integer\";\n }\n\n for (name in checks) {\n count = options[name];\n if (v.isNumber(count) && !checks[name](value, count)) {\n // This picks the default message if specified\n // For example the greaterThan check uses the message from\n // this.notGreaterThan so we capitalize the name and prepend \"not\"\n var key = \"not\" + v.capitalize(name);\n var msg = options[key] ||\n this[key] ||\n this.message ||\n \"must be %{type} %{count}\";\n\n errors.push(v.format(msg, {\n count: count,\n type: prettify(name)\n }));\n }\n }\n\n if (options.odd && value % 2 !== 1) {\n errors.push(options.notOdd ||\n this.notOdd ||\n this.message ||\n \"must be odd\");\n }\n if (options.even && value % 2 !== 0) {\n errors.push(options.notEven ||\n this.notEven ||\n this.message ||\n \"must be even\");\n }\n\n if (errors.length) {\n return options.message || errors;\n }\n },\n datetime: v.extend(function(value, options) {\n if (!v.isFunction(this.parse) || !v.isFunction(this.format)) {\n throw new Error(\"Both the parse and format functions needs to be set to use the datetime/date validator\");\n }\n\n // Empty values are fine\n if (!v.isDefined(value)) {\n return;\n }\n\n options = v.extend({}, this.options, options);\n\n var err\n , errors = []\n , earliest = options.earliest ? this.parse(options.earliest, options) : NaN\n , latest = options.latest ? this.parse(options.latest, options) : NaN;\n\n value = this.parse(value, options);\n\n // 86400000 is the number of milliseconds in a day, this is used to remove\n // the time from the date\n if (isNaN(value) || options.dateOnly && value % 86400000 !== 0) {\n err = options.notValid ||\n options.message ||\n this.notValid ||\n \"must be a valid date\";\n return v.format(err, {value: arguments[0]});\n }\n\n if (!isNaN(earliest) && value < earliest) {\n err = options.tooEarly ||\n options.message ||\n this.tooEarly ||\n \"must be no earlier than %{date}\";\n err = v.format(err, {\n value: this.format(value, options),\n date: this.format(earliest, options)\n });\n errors.push(err);\n }\n\n if (!isNaN(latest) && value > latest) {\n err = options.tooLate ||\n options.message ||\n this.tooLate ||\n \"must be no later than %{date}\";\n err = v.format(err, {\n date: this.format(latest, options),\n value: this.format(value, options)\n });\n errors.push(err);\n }\n\n if (errors.length) {\n return v.unique(errors);\n }\n }, {\n parse: null,\n format: null\n }),\n date: function(value, options) {\n options = v.extend({}, options, {dateOnly: true});\n return v.validators.datetime.call(v.validators.datetime, value, options);\n },\n format: function(value, options) {\n if (v.isString(options) || (options instanceof RegExp)) {\n options = {pattern: options};\n }\n\n options = v.extend({}, this.options, options);\n\n var message = options.message || this.message || \"is invalid\"\n , pattern = options.pattern\n , match;\n\n // Empty values are allowed\n if (!v.isDefined(value)) {\n return;\n }\n if (!v.isString(value)) {\n return message;\n }\n\n if (v.isString(pattern)) {\n pattern = new RegExp(options.pattern, options.flags);\n }\n match = pattern.exec(value);\n if (!match || match[0].length != value.length) {\n return message;\n }\n },\n inclusion: function(value, options) {\n // Empty values are fine\n if (!v.isDefined(value)) {\n return;\n }\n if (v.isArray(options)) {\n options = {within: options};\n }\n options = v.extend({}, this.options, options);\n if (v.contains(options.within, value)) {\n return;\n }\n var message = options.message ||\n this.message ||\n \"^%{value} is not included in the list\";\n return v.format(message, {value: value});\n },\n exclusion: function(value, options) {\n // Empty values are fine\n if (!v.isDefined(value)) {\n return;\n }\n if (v.isArray(options)) {\n options = {within: options};\n }\n options = v.extend({}, this.options, options);\n if (!v.contains(options.within, value)) {\n return;\n }\n var message = options.message || this.message || \"^%{value} is restricted\";\n return v.format(message, {value: value});\n },\n email: v.extend(function(value, options) {\n options = v.extend({}, this.options, options);\n var message = options.message || this.message || \"is not a valid email\";\n // Empty values are fine\n if (!v.isDefined(value)) {\n return;\n }\n if (!v.isString(value)) {\n return message;\n }\n if (!this.PATTERN.exec(value)) {\n return message;\n }\n }, {\n PATTERN: /^[a-z0-9\\u007F-\\uffff!#$%&'*+\\/=?^_`{|}~-]+(?:\\.[a-z0-9\\u007F-\\uffff!#$%&'*+\\/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z]{2,}$/i\n }),\n equality: function(value, options, attribute, attributes, globalOptions) {\n if (!v.isDefined(value)) {\n return;\n }\n\n if (v.isString(options)) {\n options = {attribute: options};\n }\n options = v.extend({}, this.options, options);\n var message = options.message ||\n this.message ||\n \"is not equal to %{attribute}\";\n\n if (v.isEmpty(options.attribute) || !v.isString(options.attribute)) {\n throw new Error(\"The attribute must be a non empty string\");\n }\n\n var otherValue = v.getDeepObjectValue(attributes, options.attribute)\n , comparator = options.comparator || function(v1, v2) {\n return v1 === v2;\n }\n , prettify = options.prettify ||\n (globalOptions && globalOptions.prettify) ||\n v.prettify;\n\n if (!comparator(value, otherValue, options, attribute, attributes)) {\n return v.format(message, {attribute: prettify(options.attribute)});\n }\n },\n\n // A URL validator that is used to validate URLs with the ability to\n // restrict schemes and some domains.\n url: function(value, options) {\n if (!v.isDefined(value)) {\n return;\n }\n\n options = v.extend({}, this.options, options);\n\n var message = options.message || this.message || \"is not a valid url\"\n , schemes = options.schemes || this.schemes || ['http', 'https']\n , allowLocal = options.allowLocal || this.allowLocal || false;\n\n if (!v.isString(value)) {\n return message;\n }\n\n // https://gist.github.com/dperini/729294\n var regex =\n \"^\" +\n // protocol identifier\n \"(?:(?:\" + schemes.join(\"|\") + \")://)\" +\n // user:pass authentication\n \"(?:\\\\S+(?::\\\\S*)?@)?\" +\n \"(?:\";\n\n var tld = \"(?:\\\\.(?:[a-z\\\\u00a1-\\\\uffff]{2,}))\";\n\n if (allowLocal) {\n tld += \"?\";\n } else {\n regex +=\n // IP address exclusion\n // private & local networks\n \"(?!(?:10|127)(?:\\\\.\\\\d{1,3}){3})\" +\n \"(?!(?:169\\\\.254|192\\\\.168)(?:\\\\.\\\\d{1,3}){2})\" +\n \"(?!172\\\\.(?:1[6-9]|2\\\\d|3[0-1])(?:\\\\.\\\\d{1,3}){2})\";\n }\n\n regex +=\n // IP address dotted notation octets\n // excludes loopback network 0.0.0.0\n // excludes reserved space >= 224.0.0.0\n // excludes network & broacast addresses\n // (first & last IP address of each class)\n \"(?:[1-9]\\\\d?|1\\\\d\\\\d|2[01]\\\\d|22[0-3])\" +\n \"(?:\\\\.(?:1?\\\\d{1,2}|2[0-4]\\\\d|25[0-5])){2}\" +\n \"(?:\\\\.(?:[1-9]\\\\d?|1\\\\d\\\\d|2[0-4]\\\\d|25[0-4]))\" +\n \"|\" +\n // host name\n \"(?:(?:[a-z\\\\u00a1-\\\\uffff0-9]-*)*[a-z\\\\u00a1-\\\\uffff0-9]+)\" +\n // domain name\n \"(?:\\\\.(?:[a-z\\\\u00a1-\\\\uffff0-9]-*)*[a-z\\\\u00a1-\\\\uffff0-9]+)*\" +\n tld +\n \")\" +\n // port number\n \"(?::\\\\d{2,5})?\" +\n // resource path\n \"(?:[/?#]\\\\S*)?\" +\n \"$\";\n\n var PATTERN = new RegExp(regex, 'i');\n if (!PATTERN.exec(value)) {\n return message;\n }\n }\n };\n\n validate.formatters = {\n detailed: function(errors) {return errors;},\n flat: v.flattenErrorsToArray,\n grouped: function(errors) {\n var attr;\n\n errors = v.groupErrorsByAttribute(errors);\n for (attr in errors) {\n errors[attr] = v.flattenErrorsToArray(errors[attr]);\n }\n return errors;\n },\n constraint: function(errors) {\n var attr;\n errors = v.groupErrorsByAttribute(errors);\n for (attr in errors) {\n errors[attr] = errors[attr].map(function(result) {\n return result.validator;\n }).sort();\n }\n return errors;\n }\n };\n\n validate.exposeModule(validate, this, exports, module, define);\n}).call(this,\n typeof exports !== 'undefined' ? /* istanbul ignore next */ exports : null,\n typeof module !== 'undefined' ? /* istanbul ignore next */ module : null,\n typeof define !== 'undefined' ? /* istanbul ignore next */ define : null);\n","module.exports = function(module) {\n\tif (!module.webpackPolyfill) {\n\t\tmodule.deprecate = function() {};\n\t\tmodule.paths = [];\n\t\t// module.parent = undefined by default\n\t\tif (!module.children) module.children = [];\n\t\tObject.defineProperty(module, \"loaded\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.l;\n\t\t\t}\n\t\t});\n\t\tObject.defineProperty(module, \"id\", {\n\t\t\tenumerable: true,\n\t\t\tget: function() {\n\t\t\t\treturn module.i;\n\t\t\t}\n\t\t});\n\t\tmodule.webpackPolyfill = 1;\n\t}\n\treturn module;\n};\n","/**\n * Copyright (C) 2018 The Software Heritage developers\n * See the AUTHORS file at the top-level directory of this distribution\n * License: GNU Affero General Public License version 3, or any later version\n * See top-level LICENSE file for more information\n */\n\n// main bundle for the swh-web/browse application\n\nimport './browse.css';\nimport './breadcrumbs.css';\nimport './content.css';\nimport './snapshot-navigation.css';\n\nexport * from './snapshot-navigation';\nexport * from './origin-search';\nexport * from './browse-utils';\nexport * from './swh-ids-utils';\nexport * from './origin-save';\n","require('../modules/web.dom.iterable');\nrequire('../modules/es6.string.iterator');\nmodule.exports = require('../modules/core.get-iterator');\n","var anObject = require('./_an-object');\nvar get = require('./core.get-iterator-method');\nmodule.exports = require('./_core').getIterator = function (it) {\n var iterFn = get(it);\n if (typeof iterFn != 'function') throw TypeError(it + ' is not iterable!');\n return anObject(iterFn.call(it));\n};\n","require('../../modules/es6.array.is-array');\nmodule.exports = require('../../modules/_core').Array.isArray;\n","// 22.1.2.2 / 15.4.3.2 Array.isArray(arg)\nvar $export = require('./_export');\n\n$export($export.S, 'Array', { isArray: require('./_is-array') });\n","// 7.2.2 IsArray(argument)\nvar cof = require('./_cof');\nmodule.exports = Array.isArray || function isArray(arg) {\n return cof(arg) == 'Array';\n};\n"],"sourceRoot":""} \ No newline at end of file diff --git a/swh/web/static/js/browse.92378aae87894b0d9972.js b/swh/web/static/js/browse.cec637f91d68ef766e5f.js similarity index 78% rename from swh/web/static/js/browse.92378aae87894b0d9972.js rename to swh/web/static/js/browse.cec637f91d68ef766e5f.js index 970cac92..c0cf935e 100644 --- a/swh/web/static/js/browse.92378aae87894b0d9972.js +++ b/swh/web/static/js/browse.cec637f91d68ef766e5f.js @@ -1,18 +1,18 @@ !function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.browse=e():(t.swh=t.swh||{},t.swh.browse=e())}(window,function(){return function(t){var e={};function n(r){if(e[r])return e[r].exports;var i=e[r]={i:r,l:!1,exports:{}};return t[r].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=t,n.c=e,n.d=function(t,e,r){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var r=Object.create(null);if(n.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var i in t)n.d(r,i,function(e){return t[e]}.bind(null,i));return r},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="/static/",n(n.s=213)}([,function(t,e){var n=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(t,e,n){var r=n(46)("wks"),i=n(47),o=n(1).Symbol,s="function"==typeof o;(t.exports=function(t){return r[t]||(r[t]=s&&o[t]||(s?o:i)("Symbol."+t))}).store=r},function(t,e){var n=t.exports={version:"2.5.7"};"number"==typeof __e&&(__e=n)},function(t,e,n){"use strict";function r(t){if(!t.ok)throw t;return t}function i(t){for(var e=0;e0?r:n)(t)}},function(t,e,n){var r=n(46)("keys"),i=n(47);t.exports=function(t){return r[t]||(r[t]=i(t))}},function(t,e,n){t.exports=n(112)},function(t,e){t.exports=!0},function(t,e,n){var r=n(18).f,i=n(17),o=n(2)("toStringTag");t.exports=function(t,e,n){t&&!i(t=n?t:t.prototype,o)&&r(t,o,{configurable:!0,value:e})}},,function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},,,,,,,,function(t,e){t.exports="\t\n\v\f\r   ᠎              \u2028\u2029\ufeff"},function(t,e,n){"use strict";var r=n(33),i=n(10),o=n(82),s=n(9),a=n(16),u=n(83),c=n(34),f=n(90),l=n(2)("iterator"),d=!([].keys&&"next"in[].keys()),h=function(){return this};t.exports=function(t,e,n,p,g,v,m){u(n,e,p);var b,y,w,x=function(t){if(!d&&t in k)return k[t];switch(t){case"keys":case"values":return function(){return new n(this,t)}}return function(){return new n(this,t)}},S=e+" Iterator",O="values"==g,E=!1,k=t.prototype,$=k[l]||k["@@iterator"]||g&&k[g],T=$||x(g),_=g?O?x("entries"):T:void 0,j="Array"==e&&k.entries||$;if(j&&(w=f(j.call(new t)))!==Object.prototype&&w.next&&(c(w,S,!0),r||"function"==typeof w[l]||s(w,l,h)),O&&$&&"values"!==$.name&&(E=!0,T=function(){return $.call(this)}),r&&!m||!d&&!E&&k[l]||s(k,l,T),a[e]=T,a[S]=h,g)if(b={values:O?T:x("values"),keys:v?T:x("keys"),entries:_},m)for(y in b)y in k||o(k,y,b[y]);else i(i.P+i.F*(d||E),e,b);return b}},function(t,e,n){var r=n(3),i=n(1),o=i["__core-js_shared__"]||(i["__core-js_shared__"]={});(t.exports=function(t,e){return o[t]||(o[t]=void 0!==e?e:{})})("versions",[]).push({version:r.version,mode:n(33)?"pure":"global",copyright:"© 2018 Denis Pushkarev (zloirock.ru)"})},function(t,e){var n=0,r=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++n+r).toString(36))}},function(t,e){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},,,function(t,e,n){var r=n(30),i=Math.min;t.exports=function(t){return t>0?i(r(t),9007199254740991):0}},function(t,e,n){var r=n(1).document;t.exports=r&&r.documentElement},function(t,e,n){var r=n(24),i=n(2)("toStringTag"),o="Arguments"==r(function(){return arguments}());t.exports=function(t){var e,n,s;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(n=function(t,e){try{return t[e]}catch(t){}}(e=Object(t),i))?n:o?r(e):"Object"==(s=r(e))&&"function"==typeof e.callee?"Arguments":s}},,,,function(t,e,n){t.exports=!n(11)&&!n(23)(function(){return 7!=Object.defineProperty(n(28)("div"),"a",{get:function(){return 7}}).a})},function(t,e,n){var r=n(13);t.exports=function(t,e){if(!r(t))return t;var n,i;if(e&&"function"==typeof(n=t.toString)&&!r(i=n.call(t)))return i;if("function"==typeof(n=t.valueOf)&&!r(i=n.call(t)))return i;if(!e&&"function"==typeof(n=t.toString)&&!r(i=n.call(t)))return i;throw TypeError("Can't convert object to primitive value")}},,,,,,,,,,,,,,,function(t,e,n){n(74),t.exports=n(3).parseInt},function(t,e,n){var r=n(10),i=n(75);r(r.G+r.F*(parseInt!=i),{parseInt:i})},function(t,e,n){var r=n(1).parseInt,i=n(76).trim,o=n(44),s=/^[-+]?0[xX]/;t.exports=8!==r(o+"08")||22!==r(o+"0x16")?function(t,e){var n=i(String(t),3);return r(n,e>>>0||(s.test(n)?16:10))}:r},function(t,e,n){var r=n(10),i=n(19),o=n(23),s=n(44),a="["+s+"]",u=RegExp("^"+a+a+"*"),c=RegExp(a+a+"*$"),f=function(t,e,n){var i={},a=o(function(){return!!s[t]()||"​…"!="​…"[t]()}),u=i[t]=a?e(l):s[t];n&&(i[n]=u),r(r.P+r.F*a,"String",i)},l=f.trim=function(t,e){return t=String(i(t)),1&e&&(t=t.replace(u,"")),2&e&&(t=t.replace(c,"")),t};t.exports=f},function(t,e,n){n(78);for(var r=n(1),i=n(9),o=n(16),s=n(2)("toStringTag"),a="CSSRuleList,CSSStyleDeclaration,CSSValueList,ClientRectList,DOMRectList,DOMStringList,DOMTokenList,DataTransferItemList,FileList,HTMLAllCollection,HTMLCollection,HTMLFormElement,HTMLSelectElement,MediaList,MimeTypeArray,NamedNodeMap,NodeList,PaintRequestList,Plugin,PluginArray,SVGLengthList,SVGNumberList,SVGPathSegList,SVGPointList,SVGStringList,SVGTransformList,SourceBufferList,StyleSheetList,TextTrackCueList,TextTrackList,TouchList".split(","),u=0;u=t.length?(this._t=void 0,i(1)):i(0,"keys"==e?n:"values"==e?t[n]:[n,t[n]])},"values"),o.Arguments=o.Array,r("keys"),r("values"),r("entries")},function(t,e){t.exports=function(){}},function(t,e){t.exports=function(t,e){return{value:e,done:!!t}}},function(t,e,n){var r=n(24);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==r(t)?t.split(""):Object(t)}},function(t,e,n){t.exports=n(9)},function(t,e,n){"use strict";var r=n(84),i=n(36),o=n(34),s={};n(9)(s,n(2)("iterator"),function(){return this}),t.exports=function(t,e,n){t.prototype=r(s,{next:i(1,n)}),o(t,e+" Iterator")}},function(t,e,n){var r=n(5),i=n(85),o=n(48),s=n(31)("IE_PROTO"),a=function(){},u=function(){var t,e=n(28)("iframe"),r=o.length;for(e.style.display="none",n(52).appendChild(e),e.src="javascript:",(t=e.contentWindow.document).open(),t.write(" + {% endblock %} {% block navbar-content %}

Save code now

{% endblock %} {% block browse-content %}

You can contribute to extend the content of the Software Heritage archive by submitting an origin save request. To do so, fill the required info in the form below:

  • Origin type: the type of version control system the software origin is using.
    Currently, the only supported type is git, for origins using Git.
    Soon, the following origin types will also be available to save into the archive:
  • -
  • Origin url: the url of the remote repository for the software origin.
  • +
  • Origin url: the url of the remote repository for the software origin.
    + In order to avoid saving errors from Software Heritage, you should provide the clone/checkout url + as given by the provider hosting the software origin.
    It can easily be found in the + web interface used to browse the software origin. +

Once submitted, your save request can either be:

  • accepted: a visit to the provided origin will then be scheduled by Software Heritage in order to load its content into the archive as soon as possible
  • rejected: the provided origin url is blacklisted and no visit will be scheduled
  • put in pending state: a manual review will then be performed in order to determine if the origin can be safely loaded or not into the archive

Once a save request has been accepted, you can follow its current status in the submitted save requests list.

{% csrf_token %}
The origin type must be specified
The origin url is not valid or does not reference a code repository

Request date Origin type Origin url Request status Save task status
{% endblock %} \ No newline at end of file diff --git a/swh/web/templates/browse/search.html b/swh/web/templates/browse/search.html index bfd1653e..fd4627c1 100644 --- a/swh/web/templates/browse/search.html +++ b/swh/web/templates/browse/search.html @@ -1,66 +1,66 @@ {% extends "./layout.html" %} {% comment %} Copyright (C) 2017-2018 The Software Heritage developers See the AUTHORS file at the top-level directory of this distribution License: GNU Affero General Public License version 3, or any later version See top-level LICENSE file for more information {% endcomment %} {% load static %} {% block navbar-content %}

Search archived software

{% endblock %} {% block browse-content %} -
+

Searching origins ...

{% endblock %} diff --git a/swh/web/templates/includes/apidoc-header.html b/swh/web/templates/includes/apidoc-header.html index c45644ef..60028c27 100644 --- a/swh/web/templates/includes/apidoc-header.html +++ b/swh/web/templates/includes/apidoc-header.html @@ -1,187 +1,187 @@ {% comment %} Copyright (C) 2015-2018 The Software Heritage developers See the AUTHORS file at the top-level directory of this distribution License: GNU Affero General Public License version 3, or any later version See top-level LICENSE file for more information {% endcomment %}

Endpoint index

You can jump directly to the endpoint index , which lists all available API functionalities, or read on for more general information about the API.

Data model

The Software Heritage project harvests publicly available source code by tracking software distribution channels such as version control systems, tarball releases, and distribution packages.

All retrieved source code and related metadata are stored in the Software Heritage archive, that is conceptually a Merkle DAG. All nodes in the graph are content-addressable, i.e., their node identifiers are computed by hashing their content and, transitively, that of all nodes reachable from them; and no node or edge is ever removed from the graph: the Software Heritage archive is an append-only data structure.

The following types of objects (i.e., graph nodes) can be found in the Software Heritage archive (for more information see the Software Heritage glossary):

  • Content: a specific version of a file stored in the archive, identified by its cryptographic hashes (currently: SHA1, Git-like "salted" SHA1, SHA256). Note that content objects are nameless; their names are context-dependent and stored as part of directory entries (see below).
    Also known as: "blob"
  • Directory: a list of directory entries, where each entry can point to content objects ("file entries"), revisions ("revision entries"), or transitively to other directories ("directory entries"). All entries are associated to the local name of the entry (i.e., a relative path without any path separator) and permission metadata (e.g., chmod value or equivalent).
  • Revision: a point in time snapshot of the content of a directory, together with associated development metadata (e.g., author, timestamp, log message, etc).
    Also known as: "commit".
  • Release: a revision that has been marked as noteworthy with a specific name (e.g., a version number), together with associated development metadata (e.g., author, timestamp, etc).
    Also known as: "tag"
  • Origin: an Internet-based location from which a coherent set of objects (contents, revisions, releases, etc.) archived by Software Heritage has been obtained. Origins are currently identified by URLs.
  • Visit: the passage of Software Heritage on a given origin, to retrieve all source code and metadata available there at the time. A visit object stores the state of all visible branches (if any) available at the origin at visit time; each of them points to a revision object in the archive. Future visits of the same origin will create new visit objects, without removing previous ones.
  • Person: an entity referenced by a revision as either the author or the committer of the corresponding change. A person is associated to a full name and/or an email address.

Version

The current version of the API is v1.

Warning: this version of the API is not to be considered stable yet. Non-backward compatible changes might happen even without changing the API version number.

Schema

API access is over HTTPS.

All API endpoints are rooted at https://archive.softwareheritage.org/api/1/.

Data is sent and received as JSON by default.

Example:

  • from the command line:

    curl -i https://archive.softwareheritage.org/api/1/stat/counters/

Response format override

The response format can be overridden using the Accept request header. In particular, Accept: text/html (that web browsers send by default) requests HTML pretty-printing, whereas Accept: application/yaml requests YAML-encoded responses.

Example:

  • /api/1/stat/counters/
  • from the command line:

    curl -i -H 'Accept: application/yaml' https://archive.softwareheritage.org/api/1/stat/counters/

Parameters

Some API endpoints can be tweaked by passing optional parameters. For GET requests, optional parameters can be passed as an HTTP query string.

The optional parameter fields is accepted by all endpoints that return dictionaries and can be used to restrict the list of fields returned by the API, in case you are not interested in all of them. By default, all available fields are returned.

Example:

Errors

While API endpoints will return different kinds of errors depending on their own semantics, some error patterns are common across all endpoints.

Sending malformed data, including syntactically incorrect object identifiers, will result in a 400 Bad Request HTTP response. Example:

  • /api/1/content/deadbeef/ (client error: "deadbeef" is too short to be a syntactically valid object identifier)
  • from the command line:

    curl -i https://archive.softwareheritage.org/api/1/content/deadbeef/

Requesting non existent resources will result in a 404 Not Found HTTP response. Example:

Unavailability of the underlying storage backend will result in a 503 Service Unavailable HTTP response.

Pagination

Requests that might potentially return many items will be paginated.

Page size is set to a default (usually: 10 items), but might be overridden with the per_page query parameter up to a maximum (usually: 50 items). Example:

curl https://archive.softwareheritage.org/api/1/origin/1/visits/?per_page=2

To navigate through paginated results, a Link HTTP response header is available to link the current result page to the next one. Example:

curl -i https://archive.softwareheritage.org/api/1/origin/1/visits/?per_page=2 | grep ^Link:
 Link: </api/1/origin/1/visits/?last_visit=2&per_page=2>; rel="next",

Rate limiting

Due to limited resource availability on the back end side, API usage is currently rate limited. Furthermore, as API usage is currently entirely anonymous (i.e., without any authentication), API "users" are currently identified by their origin IP address.

Three HTTP response fields will inform you about the current state of limits that apply to your current rate limiting bucket:

  • X-RateLimit-Limit: maximum number of permitted requests per hour
  • X-RateLimit-Remaining: number of permitted requests remaining before the next reset
  • X-RateLimit-Reset: the time (expressed in Unix time seconds) at which the current rate limiting will expire, resetting to a fresh X-RateLimit-Limit

Example:

curl -i https://archive.softwareheritage.org/api/1/stat/counters/ | grep ^X-RateLimit
 X-RateLimit-Limit: 60
 X-RateLimit-Remaining: 54
 X-RateLimit-Reset: 1485794532
\ No newline at end of file diff --git a/swh/web/templates/layout.html b/swh/web/templates/layout.html index 2bac2cd4..981f3d79 100644 --- a/swh/web/templates/layout.html +++ b/swh/web/templates/layout.html @@ -1,175 +1,175 @@ {% comment %} Copyright (C) 2015-2018 The Software Heritage developers See the AUTHORS file at the top-level directory of this distribution License: GNU Affero General Public License version 3, or any later version See top-level LICENSE file for more information {% endcomment %} {% load static %} {% load render_bundle from webpack_loader %} {% block title %}{% endblock %} {% render_bundle 'vendors' %} {% render_bundle 'webapp' %} {% block header %}{% endblock %}
{% block content %}{% endblock %}
{% include "includes/global-modals.html" %}
Software Heritage — Copyright (C) 2015–{% now "Y" %}, The Software Heritage developers. License: GNU AGPLv3+.
The source code of Software Heritage itself is available on our development forge.
The source code files archived by Software Heritage are available under their own copyright and licenses.
Terms of use: Archive access - API, Contact.
back to top
diff --git a/swh/web/tests/admin/test_origin_save.py b/swh/web/tests/admin/test_origin_save.py index 55e80a7c..ee07005a 100644 --- a/swh/web/tests/admin/test_origin_save.py +++ b/swh/web/tests/admin/test_origin_save.py @@ -1,203 +1,204 @@ # Copyright (C) 2015-2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from urllib.parse import unquote from django.contrib.auth import get_user_model from nose.tools import istest, nottest from unittest.mock import patch from swh.web.common.models import ( SaveAuthorizedOrigin, SaveUnauthorizedOrigin ) -from swh.web.common.origin_save import ( - can_save_origin, SAVE_REQUEST_PENDING, SAVE_REQUEST_ACCEPTED, +from swh.web.common.origin_save import can_save_origin +from swh.web.common.models import ( + SAVE_REQUEST_PENDING, SAVE_REQUEST_ACCEPTED, SAVE_REQUEST_REJECTED, SAVE_TASK_NOT_YET_SCHEDULED ) from swh.web.common.utils import reverse from swh.web.tests.testcase import SWHWebTestCase _user_name = 'swh-web-admin' _user_mail = 'admin@swh-web.org' _user_password = '..34~pounds~BEAUTY~march~63..' _authorized_origin_url = 'https://scm.ourproject.org/anonscm/' _unauthorized_origin_url = 'https://www.softwareheritage.org/' class OriginSaveAdminTestCase(SWHWebTestCase): @classmethod def setUpTestData(cls): User = get_user_model() user = User.objects.create_user(_user_name, _user_mail, _user_password) user.is_staff = True user.save() SaveAuthorizedOrigin.objects.create(url=_authorized_origin_url) SaveUnauthorizedOrigin.objects.create(url=_unauthorized_origin_url) @nottest def check_not_login(self, url): login_url = reverse('login', query_params={'next': url}) response = self.client.post(url) self.assertEquals(response.status_code, 302) self.assertEquals(unquote(response.url), login_url) @istest def test_add_authorized_origin_url(self): authorized_url = 'https://scm.adullact.net/anonscm/' self.assertEquals(can_save_origin(authorized_url), SAVE_REQUEST_PENDING) url = reverse('admin-origin-save-add-authorized-url', kwargs={'origin_url': authorized_url}) self.check_not_login(url) self.assertEquals(can_save_origin(authorized_url), SAVE_REQUEST_PENDING) self.client.login(username=_user_name, password=_user_password) response = self.client.post(url) self.assertEquals(response.status_code, 200) self.assertEquals(can_save_origin(authorized_url), SAVE_REQUEST_ACCEPTED) @istest def test_remove_authorized_origin_url(self): self.assertEquals(can_save_origin(_authorized_origin_url), SAVE_REQUEST_ACCEPTED) url = reverse('admin-origin-save-remove-authorized-url', kwargs={'origin_url': _authorized_origin_url}) self.check_not_login(url) self.assertEquals(can_save_origin(_authorized_origin_url), SAVE_REQUEST_ACCEPTED) self.client.login(username=_user_name, password=_user_password) response = self.client.post(url) self.assertEquals(response.status_code, 200) self.assertEquals(can_save_origin(_authorized_origin_url), SAVE_REQUEST_PENDING) @istest def test_add_unauthorized_origin_url(self): unauthorized_url = 'https://www.yahoo./' self.assertEquals(can_save_origin(unauthorized_url), SAVE_REQUEST_PENDING) url = reverse('admin-origin-save-add-unauthorized-url', kwargs={'origin_url': unauthorized_url}) self.check_not_login(url) self.assertEquals(can_save_origin(unauthorized_url), SAVE_REQUEST_PENDING) self.client.login(username=_user_name, password=_user_password) response = self.client.post(url) self.assertEquals(response.status_code, 200) self.assertEquals(can_save_origin(unauthorized_url), SAVE_REQUEST_REJECTED) @istest def test_remove_unauthorized_origin_url(self): self.assertEquals(can_save_origin(_unauthorized_origin_url), SAVE_REQUEST_REJECTED) url = reverse('admin-origin-save-remove-unauthorized-url', kwargs={'origin_url': _unauthorized_origin_url}) self.check_not_login(url) self.assertEquals(can_save_origin(_unauthorized_origin_url), SAVE_REQUEST_REJECTED) self.client.login(username=_user_name, password=_user_password) response = self.client.post(url) self.assertEquals(response.status_code, 200) self.assertEquals(can_save_origin(_unauthorized_origin_url), SAVE_REQUEST_PENDING) @istest @patch('swh.web.common.origin_save.scheduler') def test_accept_pending_save_request(self, mock_scheduler): origin_type = 'git' origin_url = 'https://v2.pikacode.com/bthate/botlib.git' save_request_url = reverse('save-origin', kwargs={'origin_type': origin_type, 'origin_url': origin_url}) response = self.client.post(save_request_url, data={}, content_type='application/x-www-form-urlencoded') # noqa self.assertEquals(response.status_code, 200) self.assertEquals(response.data['save_request_status'], SAVE_REQUEST_PENDING) accept_request_url = reverse('admin-origin-save-request-accept', kwargs={'origin_type': origin_type, 'origin_url': origin_url}) self.check_not_login(accept_request_url) tasks_data = [ { 'priority': 'high', 'policy': 'oneshot', 'type': 'origin-update-git', 'arguments': { 'kwargs': { 'repo_url': origin_url }, 'args': [] }, 'status': 'next_run_not_scheduled', 'id': 1, } ] mock_scheduler.create_tasks.return_value = tasks_data mock_scheduler.get_tasks.return_value = tasks_data self.client.login(username=_user_name, password=_user_password) response = self.client.post(accept_request_url) self.assertEquals(response.status_code, 200) response = self.client.get(save_request_url) self.assertEquals(response.status_code, 200) self.assertEquals(response.data[0]['save_request_status'], SAVE_REQUEST_ACCEPTED) self.assertEquals(response.data[0]['save_task_status'], SAVE_TASK_NOT_YET_SCHEDULED) @istest def test_reject_pending_save_request(self): origin_type = 'git' origin_url = 'https://wikipedia.com' save_request_url = reverse('save-origin', kwargs={'origin_type': origin_type, 'origin_url': origin_url}) response = self.client.post(save_request_url, data={}, content_type='application/x-www-form-urlencoded') # noqa self.assertEquals(response.status_code, 200) self.assertEquals(response.data['save_request_status'], SAVE_REQUEST_PENDING) reject_request_url = reverse('admin-origin-save-request-reject', kwargs={'origin_type': origin_type, 'origin_url': origin_url}) self.check_not_login(reject_request_url) self.client.login(username=_user_name, password=_user_password) response = self.client.post(reject_request_url) self.assertEquals(response.status_code, 200) response = self.client.get(save_request_url) self.assertEquals(response.status_code, 200) self.assertEquals(response.data[0]['save_request_status'], SAVE_REQUEST_REJECTED) diff --git a/swh/web/tests/api/views/test_origin_save.py b/swh/web/tests/api/views/test_origin_save.py index b80ac111..4c714a41 100644 --- a/swh/web/tests/api/views/test_origin_save.py +++ b/swh/web/tests/api/views/test_origin_save.py @@ -1,244 +1,252 @@ # Copyright (C) 2018 The Software Heritage developers # See the AUTHORS file at the top-level directory of this distribution # License: GNU Affero General Public License version 3, or any later version # See top-level LICENSE file for more information from datetime import datetime, timedelta from nose.tools import istest, nottest from rest_framework.test import APITestCase from unittest.mock import patch from swh.web.common.utils import reverse from swh.web.common.models import ( SaveUnauthorizedOrigin, SaveOriginRequest, SAVE_REQUEST_ACCEPTED, SAVE_REQUEST_REJECTED, SAVE_REQUEST_PENDING ) -from swh.web.common.origin_save import ( +from swh.web.common.models import ( SAVE_TASK_NOT_CREATED, SAVE_TASK_NOT_YET_SCHEDULED, SAVE_TASK_SCHEDULED, SAVE_TASK_FAILED, SAVE_TASK_SUCCEED ) from swh.web.tests.testcase import SWHWebTestCase class SaveApiTestCase(SWHWebTestCase, APITestCase): @classmethod def setUpTestData(cls): SaveUnauthorizedOrigin.objects.create( url='https://github.com/user/illegal_repo') SaveUnauthorizedOrigin.objects.create( url='https://gitlab.com/user_to_exclude') @istest def invalid_origin_type(self): url = reverse('save-origin', kwargs={'origin_type': 'foo', 'origin_url': 'https://github.com/torvalds/linux'}) # noqa response = self.client.post(url) self.assertEquals(response.status_code, 400) @istest def invalid_origin_url(self): url = reverse('save-origin', kwargs={'origin_type': 'git', 'origin_url': 'bar'}) response = self.client.post(url) self.assertEquals(response.status_code, 400) @nottest def check_created_save_request_status(self, mock_scheduler, origin_url, scheduler_task_status, expected_request_status, expected_task_status=None): if not scheduler_task_status: mock_scheduler.get_tasks.return_value = [] else: mock_scheduler.get_tasks.return_value = \ [{ 'priority': 'high', 'policy': 'oneshot', 'type': 'origin-update-git', 'arguments': { 'kwargs': { 'repo_url': origin_url }, 'args': [] }, 'status': scheduler_task_status, 'id': 1, }] mock_scheduler.create_tasks.return_value = \ [{ 'priority': 'high', 'policy': 'oneshot', 'type': 'origin-update-git', 'arguments': { 'kwargs': { 'repo_url': origin_url }, 'args': [] }, 'status': 'next_run_not_scheduled', 'id': 1, }] url = reverse('save-origin', kwargs={'origin_type': 'git', 'origin_url': origin_url}) response = self.client.post(url) if expected_request_status != SAVE_REQUEST_REJECTED: self.assertEqual(response.status_code, 200) self.assertEqual(response.data['save_request_status'], expected_request_status) self.assertEqual(response.data['save_task_status'], expected_task_status) else: self.assertEqual(response.status_code, 403) @nottest def check_save_request_status(self, mock_scheduler, origin_url, expected_request_status, expected_task_status, scheduler_task_status='next_run_not_scheduled', # noqa visit_date=None): mock_scheduler.get_tasks.return_value = \ [{ 'priority': 'high', 'policy': 'oneshot', 'type': 'origin-update-git', 'arguments': { 'kwargs': { 'repo_url': origin_url }, 'args': [] }, 'status': scheduler_task_status, 'id': 1, }] url = reverse('save-origin', kwargs={'origin_type': 'git', 'origin_url': origin_url}) with patch('swh.web.common.origin_save._get_visit_date_for_save_request') as mock_visit_date: # noqa mock_visit_date.return_value = visit_date response = self.client.get(url) self.assertEqual(response.status_code, 200) - save_request_data = response.data[0] self.assertEqual(save_request_data['save_request_status'], expected_request_status) self.assertEqual(save_request_data['save_task_status'], expected_task_status) + # Check that save task status is still available when + # the scheduler task has been archived + mock_scheduler.get_tasks.return_value = [] + response = self.client.get(url) + self.assertEqual(response.status_code, 200) + save_request_data = response.data[0] + self.assertEqual(save_request_data['save_task_status'], + expected_task_status) + @istest @patch('swh.web.common.origin_save.scheduler') def save_request_rejected(self, mock_scheduler): origin_url = 'https://github.com/user/illegal_repo' self.check_created_save_request_status(mock_scheduler, origin_url, None, SAVE_REQUEST_REJECTED) self.check_save_request_status(mock_scheduler, origin_url, SAVE_REQUEST_REJECTED, SAVE_TASK_NOT_CREATED) @istest @patch('swh.web.common.origin_save.scheduler') def save_request_pending(self, mock_scheduler): origin_url = 'https://unkwownforge.com/user/repo' self.check_created_save_request_status(mock_scheduler, origin_url, None, SAVE_REQUEST_PENDING, SAVE_TASK_NOT_CREATED) self.check_save_request_status(mock_scheduler, origin_url, SAVE_REQUEST_PENDING, SAVE_TASK_NOT_CREATED) @istest @patch('swh.web.common.origin_save.scheduler') def save_request_succeed(self, mock_scheduler): origin_url = 'https://github.com/Kitware/CMake' self.check_created_save_request_status(mock_scheduler, origin_url, None, SAVE_REQUEST_ACCEPTED, SAVE_TASK_NOT_YET_SCHEDULED) self.check_save_request_status(mock_scheduler, origin_url, SAVE_REQUEST_ACCEPTED, SAVE_TASK_SCHEDULED, scheduler_task_status='next_run_scheduled') # noqa self.check_save_request_status(mock_scheduler, origin_url, SAVE_REQUEST_ACCEPTED, SAVE_TASK_SCHEDULED, scheduler_task_status='completed', visit_date=None) # noqa visit_date = datetime.now() + timedelta(hours=1) self.check_save_request_status(mock_scheduler, origin_url, SAVE_REQUEST_ACCEPTED, SAVE_TASK_SUCCEED, scheduler_task_status='completed', visit_date=visit_date) # noqa @istest @patch('swh.web.common.origin_save.scheduler') def save_request_failed(self, mock_scheduler): origin_url = 'https://gitlab.com/inkscape/inkscape' self.check_created_save_request_status(mock_scheduler, origin_url, None, SAVE_REQUEST_ACCEPTED, SAVE_TASK_NOT_YET_SCHEDULED) self.check_save_request_status(mock_scheduler, origin_url, SAVE_REQUEST_ACCEPTED, SAVE_TASK_SCHEDULED, scheduler_task_status='next_run_scheduled') # noqa self.check_save_request_status(mock_scheduler, origin_url, SAVE_REQUEST_ACCEPTED, SAVE_TASK_FAILED, scheduler_task_status='disabled') # noqa @istest @patch('swh.web.common.origin_save.scheduler') def create_save_request_only_when_needed(self, mock_scheduler): origin_url = 'https://gitlab.com/webpack/webpack' SaveOriginRequest.objects.create(origin_type='git', origin_url=origin_url, status=SAVE_REQUEST_ACCEPTED, # noqa loading_task_id=56) self.check_created_save_request_status(mock_scheduler, origin_url, 'next_run_not_scheduled', SAVE_REQUEST_ACCEPTED, SAVE_TASK_NOT_YET_SCHEDULED) sors = list(SaveOriginRequest.objects.filter(origin_type='git', origin_url=origin_url)) self.assertEquals(len(sors), 1) self.check_created_save_request_status(mock_scheduler, origin_url, 'next_run_scheduled', SAVE_REQUEST_ACCEPTED, SAVE_TASK_SCHEDULED) sors = list(SaveOriginRequest.objects.filter(origin_type='git', origin_url=origin_url)) self.assertEquals(len(sors), 1) self.check_created_save_request_status(mock_scheduler, origin_url, 'completed', SAVE_REQUEST_ACCEPTED, SAVE_TASK_NOT_YET_SCHEDULED) sors = list(SaveOriginRequest.objects.filter(origin_type='git', origin_url=origin_url)) self.assertEquals(len(sors), 2) self.check_created_save_request_status(mock_scheduler, origin_url, 'disabled', SAVE_REQUEST_ACCEPTED, SAVE_TASK_NOT_YET_SCHEDULED) sors = list(SaveOriginRequest.objects.filter(origin_type='git', origin_url=origin_url)) self.assertEquals(len(sors), 3) diff --git a/version.txt b/version.txt index 42b7ade8..84104f41 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -v0.0.153-0-g709b72d \ No newline at end of file +v0.0.154-0-g7319180 \ No newline at end of file