psdi-data-conversion 0.0.38__py3-none-any.whl → 0.0.39__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (26) hide show
  1. psdi_data_conversion/app.py +39 -15
  2. psdi_data_conversion/converter.py +7 -7
  3. psdi_data_conversion/converters/base.py +24 -20
  4. psdi_data_conversion/converters/c2x.py +13 -0
  5. psdi_data_conversion/converters/openbabel.py +2 -1
  6. psdi_data_conversion/database.py +29 -5
  7. psdi_data_conversion/dist.py +2 -1
  8. psdi_data_conversion/file_io.py +1 -2
  9. psdi_data_conversion/log_utility.py +1 -1
  10. psdi_data_conversion/main.py +3 -3
  11. psdi_data_conversion/static/content/index-versions/psdi-common-footer.html +12 -8
  12. psdi_data_conversion/static/content/psdi-common-footer.html +12 -8
  13. psdi_data_conversion/static/data/data.json +617 -3
  14. psdi_data_conversion/static/javascript/convert.js +54 -6
  15. psdi_data_conversion/static/javascript/convert_common.js +16 -2
  16. psdi_data_conversion/static/javascript/data.js +18 -0
  17. psdi_data_conversion/static/styles/format.css +7 -0
  18. psdi_data_conversion/testing/conversion_callbacks.py +2 -2
  19. psdi_data_conversion/testing/conversion_test_specs.py +17 -5
  20. psdi_data_conversion/testing/gui.py +18 -12
  21. psdi_data_conversion/testing/utils.py +3 -3
  22. {psdi_data_conversion-0.0.38.dist-info → psdi_data_conversion-0.0.39.dist-info}/METADATA +1 -1
  23. {psdi_data_conversion-0.0.38.dist-info → psdi_data_conversion-0.0.39.dist-info}/RECORD +26 -26
  24. {psdi_data_conversion-0.0.38.dist-info → psdi_data_conversion-0.0.39.dist-info}/WHEEL +0 -0
  25. {psdi_data_conversion-0.0.38.dist-info → psdi_data_conversion-0.0.39.dist-info}/entry_points.txt +0 -0
  26. {psdi_data_conversion-0.0.38.dist-info → psdi_data_conversion-0.0.39.dist-info}/licenses/LICENSE +0 -0
@@ -7,7 +7,9 @@
7
7
 
8
8
 
9
9
  import { getInputFlags, getOutputFlags, getInputArgFlags, getOutputArgFlags } from "./data.js";
10
- import { commonConvertReady, convertFile, getExtCheck, splitArchiveExt, isArchiveExt } from "./convert_common.js"
10
+ import {
11
+ SAFE_CHAR_REGEX, commonConvertReady, convertFile, getExtCheck, splitArchiveExt, isArchiveExt
12
+ } from "./convert_common.js"
11
13
 
12
14
  var token = "",
13
15
  in_ext = "",
@@ -51,8 +53,24 @@ function enterArgument(event) {
51
53
  }
52
54
  }
53
55
 
56
+
57
+ /**
58
+ * Validate the input for a format option - if invalid, display the error message, if valid, hide it
59
+ *
60
+ * @param {*} event
61
+ */
62
+ function validateInput(event) {
63
+ var err_id = this.id.replace('text', 'err')
64
+ if (this.validity.patternMismatch) {
65
+ $('#' + err_id).css({ display: "block" })
66
+ } else {
67
+ $('#' + err_id).css({ display: "none" })
68
+ }
69
+ }
70
+
54
71
  // Uploads a user-supplied file
55
72
  function submitFile() {
73
+
56
74
  const file = $("#fileToUpload")[0].files[0],
57
75
  [fname, ext] = splitArchiveExt(file.name);
58
76
 
@@ -78,9 +96,16 @@ function submitFile() {
78
96
  const checked_in = $('input[name=in_arg_check]:checked'),
79
97
  checked_out = $('input[name=out_arg_check]:checked');
80
98
 
99
+ let security_passed = true;
100
+
81
101
  checked_in.each(function () {
82
102
  read_arg_flags += $("#" + this.id).val()[0];
83
- const arg = $("#in_arg_text" + this.id.substring(this.id.length - 1, this.id.length)).val();
103
+ const e = $("#in_arg_text" + this.id.substring(this.id.length - 1, this.id.length));
104
+ const arg = e.val();
105
+
106
+ if (e[0].validity.patternMismatch) {
107
+ security_passed = false;
108
+ }
84
109
 
85
110
  if (/\S/.test(arg)) {
86
111
  read_args += arg.trim() + '£';
@@ -92,7 +117,12 @@ function submitFile() {
92
117
 
93
118
  checked_out.each(function () {
94
119
  write_arg_flags += $("#" + this.id).val()[0];
95
- const arg = $("#out_arg_text" + this.id.substring(this.id.length - 1, this.id.length)).val();
120
+ const e = $("#out_arg_text" + this.id.substring(this.id.length - 1, this.id.length));
121
+ const arg = e.val();
122
+
123
+ if (e[0].validity.patternMismatch) {
124
+ security_passed = false;
125
+ }
96
126
 
97
127
  if (/\S/.test(arg)) {
98
128
  write_args += arg.trim() + '£';
@@ -102,9 +132,21 @@ function submitFile() {
102
132
  }
103
133
  })
104
134
 
135
+ let alert_msg = '';
136
+
137
+ if (!security_passed) {
138
+ alert_msg += 'ERROR: One or more ticked options contains invalid characters. They must match the regex /' +
139
+ SAFE_CHAR_REGEX + '/ .\n';
140
+ }
141
+
105
142
  if (!all_args_entered) {
106
- alert('All ticked option flags need additional information to be entered into the associated text box.');
107
- return;
143
+ alert_msg += 'ERROR: All ticked options need additional information to be entered into the associated ' +
144
+ 'text box.\n';
145
+ }
146
+
147
+ if (alert_msg) {
148
+ alert(alert_msg);
149
+ return
108
150
  }
109
151
 
110
152
  const coordinates = $('input[name="coordinates"]:checked').val(),
@@ -216,11 +258,17 @@ function addCheckboxes(argFlags, type) {
216
258
  <tr>
217
259
  <td><input type='checkbox' id="${type}_check${flagCount}" name=${type}_check value="${flag}"></input></td>
218
260
  <td><label for="${type}_check${flagCount}">${flag} [${brief}]: ${description}<label></td>
219
- <td><input type='text' id=${type}_text${flagCount} placeholder='-- type info. here --'></input></td>
261
+ <td><input type='text' id="${type}_text${flagCount}" placeholder='-- type info. here --'
262
+ pattern='` + SAFE_CHAR_REGEX + `'></input>
263
+ <p class="init-hidden" id="${type}_err${flagCount}"><strong>ERROR:</strong> Input contains
264
+ invalid characters; it must match the regex
265
+ <code class="secondary">/` + SAFE_CHAR_REGEX + `/</code></p>
266
+ </td>
220
267
  <td><span id= ${type}_label${flagCount}>${furtherInfo}</span></td>
221
268
  </tr>`);
222
269
 
223
270
  $(`#${type}_text${flagCount}`).hide();
271
+ $(`#${type}_text${flagCount}`).on('input', validateInput);
224
272
  $(`#${type}_label${flagCount}`).hide();
225
273
  $(`#${type}_check${flagCount}`).change(enterArgument);
226
274
 
@@ -18,6 +18,20 @@ const TARGZ_EXT = "tar.gz"
18
18
  const TARBZ_EXT = "tar.bz"
19
19
  const TARXZ_EXT = "tar.xz"
20
20
 
21
+ // Short list of safe allowed characters:
22
+ // \w: All letters and digits
23
+ // \s: All whitespace characters
24
+ // .: Period
25
+ // \-: Hyphen
26
+ // :: Colon
27
+ // +: Plus symbol
28
+ // *: Asterisk
29
+ // =: Equals sign
30
+ // $: Dollar sign
31
+ // /: Forward-slash
32
+ // \\: Backslash
33
+ export const SAFE_CHAR_REGEX = "[\\w\\s.\\-:+*=$\\/\\\\]*"
34
+
21
35
  // Whether or not file extensions will be checked
22
36
  let extCheck = true;
23
37
 
@@ -271,10 +285,10 @@ function checkFile(event) {
271
285
  }
272
286
 
273
287
  /**
274
- * Allow the file upload to only accept the expected type of file
288
+ * Allow the file upload to only accept the expected type of file, plus archives
275
289
  */
276
290
  function limitFileType() {
277
- $("#fileToUpload")[0].accept = "." + in_ext;
291
+ $("#fileToUpload")[0].accept = "." + in_ext + ", .zip, .tar, .tar.gz, .tar.xz, .tar.bz";
278
292
  }
279
293
 
280
294
  /**
@@ -63,6 +63,24 @@ export async function getOutputFormats() {
63
63
  return outFormats.sort((a, b) => compare([a.extension, b.extension], [a.note, b.note]))
64
64
  }
65
65
 
66
+ /**
67
+ * Gets the ID for a format, given its extension and note
68
+ *
69
+ * @param {string} extension - The extension of the format, e.g. 'pdb'
70
+ * @param {string} note - The note of the format, e.g. 'Protein Databank'
71
+ * @returns {(int|null)} - The ID of the format if found, or else null
72
+ */
73
+ export async function getFormatId(extension, note) {
74
+
75
+ var format = (data.formats.filter(format => (format.extension === extension) && (format.note === note)));
76
+
77
+ if (format === undefined) {
78
+ return null;
79
+ }
80
+
81
+ return format[0].id;
82
+ }
83
+
66
84
  export async function getOutputFormatsForInputFormat(inExtension, inNote) {
67
85
 
68
86
  const inputFormat = (data.formats.filter(format => (format.extension === inExtension) && (format.note === inNote)))[0];
@@ -44,6 +44,13 @@ form {
44
44
  }
45
45
  }
46
46
 
47
+ /* Invalid input fields switch to alternate background */
48
+
49
+ input:invalid {
50
+ background-color: var(--ifm-color-primary);
51
+ color : var(--ifm-hero-text-color);
52
+ }
53
+
47
54
  /* Converter details, user input and file conversion initially not displayed. */
48
55
  .init-hidden {
49
56
  display: none
@@ -6,10 +6,10 @@ conversion test, run with the functions and classes defined in the `utils.py` mo
6
6
  """
7
7
 
8
8
  import abc
9
- from collections.abc import Callable, Iterable
10
- from dataclasses import dataclass, field
11
9
  import os
12
10
  import re
11
+ from collections.abc import Callable, Iterable
12
+ from dataclasses import dataclass, field
13
13
  from tempfile import TemporaryDirectory
14
14
 
15
15
  from psdi_data_conversion.constants import DATETIME_RE_RAW
@@ -13,10 +13,11 @@ from psdi_data_conversion.converters.base import (FileConverterAbortException, F
13
13
  from psdi_data_conversion.converters.c2x import CONVERTER_C2X
14
14
  from psdi_data_conversion.converters.openbabel import CONVERTER_OB, COORD_GEN_KEY, COORD_GEN_QUAL_KEY
15
15
  from psdi_data_conversion.database import FileConverterDatabaseException
16
- from psdi_data_conversion.testing.conversion_callbacks import (CheckArchiveContents, CheckException, CheckLogContents,
17
- CheckLogContentsSuccess, CheckFileStatus,
16
+ from psdi_data_conversion.testing.conversion_callbacks import (CheckArchiveContents, CheckException, CheckFileStatus,
17
+ CheckLogContents, CheckLogContentsSuccess,
18
18
  CheckStderrContents, CheckStdoutContents,
19
- MatchOutputFile, MultiCallback as MCB)
19
+ MatchOutputFile)
20
+ from psdi_data_conversion.testing.conversion_callbacks import MultiCallback as MCB
20
21
  from psdi_data_conversion.testing.utils import ConversionTestSpec as Spec
21
22
 
22
23
  l_all_test_specs: list[Spec] = []
@@ -39,7 +40,7 @@ l_all_test_specs.append(Spec(name="Standard Multiple Tests",
39
40
  to_format=["pdb-0",
40
41
  "cif", "mol2", "xyz",
41
42
  "cif", "xyz", "xyz",
42
- "cif", "xyz", "xyz",
43
+ "cif", "xyz-0", "xyz-0",
43
44
  "cml"],
44
45
  from_format=[None,
45
46
  None, None, None,
@@ -57,6 +58,17 @@ l_all_test_specs.append(Spec(name="Standard Multiple Tests",
57
58
  """A basic set of test conversions which we expect to succeed without issue, running conversions with each of the
58
59
  Open Babel, Atomsk, and c2x converters"""
59
60
 
61
+ l_all_test_specs.append(Spec(name="c2x Formats Tests",
62
+ to_format=["res", "abi", "POSCAR", "cml"],
63
+ converter_name=CONVERTER_C2X,
64
+ callback=MCB(CheckFileStatus(),
65
+ CheckLogContentsSuccess()),
66
+ compatible_with_gui=False,
67
+ ))
68
+ """Test converting with c2x to a few different formats which require special input. This test isn't run in the GUI
69
+ solely to save on resources, since there are unlikely to be an GUI-specific issues raised by this test that aren't
70
+ caught in others."""
71
+
60
72
  archive_callback = MCB(CheckFileStatus(),
61
73
  CheckArchiveContents(l_filename_bases=["caffeine-no-flags",
62
74
  "caffeine-ia",
@@ -209,7 +221,7 @@ Not compatible with the GUI, since the GUI can't forcibly delete files uploaded
209
221
 
210
222
  l_all_test_specs.append(Spec(name="Failed conversion - bad input file",
211
223
  filename=["quartz_err.xyz", "cyclopropane_err.mol"],
212
- to_format=["inchi", "xyz"],
224
+ to_format=["inchi", "xyz-0"],
213
225
  from_format=[None, "mol-0"],
214
226
  expect_success=False,
215
227
  converter_name=[CONVERTER_OB, CONVERTER_C2X],
@@ -6,10 +6,10 @@ Utilities to aid in testing of the GUI
6
6
 
7
7
  import os
8
8
  import shutil
9
- from tempfile import TemporaryDirectory
10
-
11
9
  import time
12
10
  from dataclasses import dataclass
11
+ from tempfile import TemporaryDirectory
12
+
13
13
  import pytest
14
14
  from selenium.common.exceptions import TimeoutException
15
15
  from selenium.webdriver.common.alert import Alert
@@ -45,6 +45,11 @@ def wait_and_find_element(root: WebDriver | EC.WebElement, xpath: str, by=By.XPA
45
45
  return root.find_element(by, xpath)
46
46
 
47
47
 
48
+ def wait_for_cover_hidden(root: WebDriver):
49
+ """Wait until the page cover is removed"""
50
+ WebDriverWait(root, TIMEOUT).until(EC.invisibility_of_element((By.XPATH, "//div[@id='cover']")))
51
+
52
+
48
53
  @dataclass
49
54
  class GuiTestSpecRunner():
50
55
  """Class which provides an interface to run test conversions through the GUI
@@ -253,25 +258,30 @@ class GuiSingleTestSpecRunner:
253
258
  4. Click the "Yes" button to confirm and go to the convert page
254
259
  """
255
260
 
256
- # Get the homepage
261
+ # Get the homepage and wait for the cover to be removed
257
262
  self.driver.get(f"{self.origin}/")
263
+ wait_for_cover_hidden(self.driver)
258
264
 
259
265
  wait_for_element(self.driver, "//select[@id='fromList']/option")
260
266
 
261
267
  # Select from_format from the 'from' list.
268
+ full_from_format = f"{self._from_format_info.name}: {self._from_format_info.note}"
262
269
  self.driver.find_element(
263
- By.XPATH, f"//select[@id='fromList']/option[starts-with(.,'{self._from_format_info.name}:')]").click()
270
+ By.XPATH, f"//select[@id='fromList']/option[starts-with(.,'{full_from_format}')]").click()
264
271
 
265
272
  # Select to_format from the 'to' list.
273
+ full_to_format = f"{self._to_format_info.name}: {self._to_format_info.note}"
266
274
  self.driver.find_element(
267
- By.XPATH, f"//select[@id='toList']/option[starts-with(.,'{self._to_format_info.name}:')]").click()
275
+ By.XPATH, f"//select[@id='toList']/option[starts-with(.,'{full_to_format}')]").click()
268
276
 
269
277
  # Select converter from the available conversion options list.
270
278
  self.driver.find_element(
271
279
  By.XPATH, f"//select[@id='success']/option[contains(.,'{self.single_test_spec.converter_name}')]").click()
272
280
 
273
- # Click on the "Yes" button to accept the converter and go to the conversion page
281
+ # Click on the "Yes" button to accept the converter and go to the conversion page, and wait for the cover to be
282
+ # removed there
274
283
  self.driver.find_element(By.XPATH, "//input[@id='yesButton']").click()
284
+ wait_for_cover_hidden(self.driver)
275
285
 
276
286
  def _set_conversion_settings(self):
277
287
  """Set settings on the convert page appropriately for the desired conversion
@@ -315,13 +325,11 @@ class GuiSingleTestSpecRunner:
315
325
  continue
316
326
  flags_select = Select(wait_and_find_element(self.driver, f"//select[@id='{select_id}']"))
317
327
  for flag in l_flags:
318
- found = False
319
328
  for option in flags_select.options:
320
329
  if option.text.startswith(f"{flag}:"):
321
330
  flags_select.select_by_visible_text(option.text)
322
- found = True
323
331
  break
324
- if not found:
332
+ else:
325
333
  raise ValueError(f"Flag {flag} was not found in {select_id} selection box for conversion from "
326
334
  f"{self._from_format_info.name} to {self._to_format_info.name} with "
327
335
  f"converter {self.single_test_spec.converter_name}")
@@ -343,7 +351,6 @@ class GuiSingleTestSpecRunner:
343
351
 
344
352
  # Look for and set each option
345
353
  for option in l_options:
346
- found = False
347
354
  for row in l_rows:
348
355
  l_items = row.find_elements(By.XPATH, "./td")
349
356
  label = l_items[1]
@@ -357,10 +364,9 @@ class GuiSingleTestSpecRunner:
357
364
  input_box = wait_and_find_element(l_items[2], "./input")
358
365
  input_box.send_keys(option[1:])
359
366
 
360
- found = True
361
367
  break
362
368
 
363
- if not found:
369
+ else:
364
370
  raise ValueError(f"Option {option} was not found in {table_id} options table for conversion from "
365
371
  f"{self._from_format_info.name} to {self._to_format_info.name} with "
366
372
  f"converter {self.single_test_spec.converter_name}")
@@ -6,12 +6,12 @@ This module defines general classes and methods used for unit tests.
6
6
 
7
7
  from __future__ import annotations
8
8
 
9
- from dataclasses import dataclass, field
10
- from collections.abc import Callable, Iterable
11
- from math import isclose
12
9
  import os
13
10
  import shlex
14
11
  import sys
12
+ from collections.abc import Callable, Iterable
13
+ from dataclasses import dataclass, field
14
+ from math import isclose
15
15
  from tempfile import TemporaryDirectory
16
16
  from typing import Any
17
17
  from unittest.mock import patch
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: psdi_data_conversion
3
- Version: 0.0.38
3
+ Version: 0.0.39
4
4
  Summary: Chemistry file format conversion service, provided by PSDI
5
5
  Project-URL: Homepage, https://data-conversion.psdi.ac.uk/
6
6
  Project-URL: Documentation, https://psdi-uk.github.io/psdi-data-conversion/
@@ -1,12 +1,12 @@
1
1
  psdi_data_conversion/__init__.py,sha256=urMsTqsTHTch1q4rMT9dgGnrvdPFMP9B8r-6Kr8H5sE,404
2
- psdi_data_conversion/app.py,sha256=Ef8gXALojMrHaEWp1VJqEJ9CqYPWnXKFyObzlorNy9A,13253
2
+ psdi_data_conversion/app.py,sha256=A1TUVYuHUJKbtBXC0MbCDwyNcZgCYLDWyt_2lPLETK0,14212
3
3
  psdi_data_conversion/constants.py,sha256=JWYC2gXsEi6bBl_NdEBh5nLZ7qX2LZZV_DutfEHJ8qo,7390
4
- psdi_data_conversion/converter.py,sha256=wgh13gzkzouEyEg1cXZ8KfIUXerXFF8VU-a4WgSO9ZE,23185
5
- psdi_data_conversion/database.py,sha256=CmV-yPBMa1Y9Uq_6h_C_dgIq9yi-qRvZCXlnLHNfxd4,55170
6
- psdi_data_conversion/dist.py,sha256=Ju6BcEuLrB738diTbK6HX6ZBiZ40Ctq1exj44nSCMlE,2292
7
- psdi_data_conversion/file_io.py,sha256=UXxNxTl_EabQ96UrLp4b38ctkYhXV_KIHJeTuyRBVpM,8857
8
- psdi_data_conversion/log_utility.py,sha256=WIgQp0pMsFtJJZKgIhStBNnjLzC6gEIodQAoXji5ht0,8789
9
- psdi_data_conversion/main.py,sha256=LBGTj2K_tx_YSPe-9I2biN0XEUpEiCnqhHa0kox0kHU,41791
4
+ psdi_data_conversion/converter.py,sha256=A9u_xnzQ_OFp_rttttBNwZNA4d56Fdbm9FpjgyCroUA,23211
5
+ psdi_data_conversion/database.py,sha256=tgqUxW75eaWiEsiHNI7pUfMTIKmB23zrprSZ3ZDpO3Y,55967
6
+ psdi_data_conversion/dist.py,sha256=LOcKEP7H7JA9teX1m-5awuBi69gmdhtUit7yxtCTOZ8,2293
7
+ psdi_data_conversion/file_io.py,sha256=LvdPmnYL_7Xlcr-7LJjUbbky4gKiqTTvPRzdbtvQaJo,8794
8
+ psdi_data_conversion/log_utility.py,sha256=CHAq-JvBnTKaE0SHK5hM5j2dTbfSli4iUc3hsf6dBhc,8789
9
+ psdi_data_conversion/main.py,sha256=NaV5Pqe-8qYn7ybgok3t6RuRK1H_9ip68UWpV7DRgO0,41773
10
10
  psdi_data_conversion/security.py,sha256=wjdrMre29TpkF2NqrsXJ5sschSAnDzqLYTLUcNR21Qw,902
11
11
  psdi_data_conversion/bin/LICENSE_ATOMSK,sha256=-Ay6SFTAf9x-OaRAiOgMNoutfUMLHx5jQQA1HqZ6p7I,34886
12
12
  psdi_data_conversion/bin/LICENSE_C2X,sha256=-Ay6SFTAf9x-OaRAiOgMNoutfUMLHx5jQQA1HqZ6p7I,34886
@@ -16,9 +16,9 @@ psdi_data_conversion/bin/mac/atomsk,sha256=pqExRdkR8NSqSasHZjE74R_CiM6Dkr_yvfyak
16
16
  psdi_data_conversion/bin/mac/c2x,sha256=dI-bBoQ6uqc6KMYKJaq0x7ejJgOf_wysTxQA5BrF8AY,2581960
17
17
  psdi_data_conversion/converters/__init__.py,sha256=15Ldt06eyZ0bgNPB4qg419U0Zcjt6TUCTzjCBo8EIzM,210
18
18
  psdi_data_conversion/converters/atomsk.py,sha256=_V33me1e4HW0-YXvdE-z6PdwtSK2gYV6QZf5d8aPqH4,1523
19
- psdi_data_conversion/converters/base.py,sha256=K6Zwfj6VHC_aEnuflqjGf0xF5kX24v_smTAQiyE0pzs,35892
20
- psdi_data_conversion/converters/c2x.py,sha256=9eSg85-FEhZ4Xj_yEAmbmq75Zg8woaplSfvDygZVbb0,1539
21
- psdi_data_conversion/converters/openbabel.py,sha256=Y0PN5BwlZaekUrt8dM6IuEtrvpmXYgvwnkLFlENDNoE,13223
19
+ psdi_data_conversion/converters/base.py,sha256=gYZ-2f693_YBgJdlXFUZOpjVhB8PAbkbLFkOS9BFg9Q,36022
20
+ psdi_data_conversion/converters/c2x.py,sha256=jDA84H8Jpz--ajTWNWX6K6oMfOMMbMxkA31-VnGi0gU,2019
21
+ psdi_data_conversion/converters/openbabel.py,sha256=OYppOMfnvxmVgRY5vUkcVokWn-bQSSeG8MOFqN1MCIY,13224
22
22
  psdi_data_conversion/scripts/atomsk.sh,sha256=N_NMO5q8sI3Lt1TerC-xcKbMI0kfscAudy5UAbY0uR0,804
23
23
  psdi_data_conversion/scripts/c2x.sh,sha256=F48jhgtgouKKZDQ9p6tCCNBN5bPuidBq2GcTurdWzQc,770
24
24
  psdi_data_conversion/static/content/accessibility.htm,sha256=5mzlPM-d5KBoOuvuBTmer5QEI9lWQSd7FPH1KFn_7B0,14187
@@ -29,13 +29,13 @@ psdi_data_conversion/static/content/documentation.htm,sha256=1GiEjlDCP0kJ3CKkx3l
29
29
  psdi_data_conversion/static/content/download.htm,sha256=DQKWEuq_Bjv2TyV6DnPXnHrSOBvGYRHOU-m6YOwfsh4,4727
30
30
  psdi_data_conversion/static/content/feedback.htm,sha256=fZrhn4Egs9g6ygqPzV6ZG9ndYK02VdALNVNXRsZ716k,1788
31
31
  psdi_data_conversion/static/content/header-links.html,sha256=7B2bHa7dLfSZ4hPMvVJ3kR0niVAOO3FtHJo0K6m1oP4,693
32
- psdi_data_conversion/static/content/psdi-common-footer.html,sha256=CM9F6AXM1LVMLvTP51xTzOicEelSXlyXQyN-BjrQAJk,3933
32
+ psdi_data_conversion/static/content/psdi-common-footer.html,sha256=Qo6ecItnjqngIu1Kyg8YOptqjraMFxyJTYu3wiW5Wuw,4080
33
33
  psdi_data_conversion/static/content/psdi-common-header.html,sha256=vRAgLGKE_RhXgBUQnarxnpkGl9j2Qeedqqo3VNDVGdk,1825
34
34
  psdi_data_conversion/static/content/report.htm,sha256=CRwlF7a7QvAjHsajuehWOtLxbo-JAjqrS_Q-I4BWxzs,4549
35
35
  psdi_data_conversion/static/content/index-versions/header-links.html,sha256=WN9oZL7hLtH_yv5PvX3Ky7_YGrNvQL_RQ5eU8DB50Rg,764
36
- psdi_data_conversion/static/content/index-versions/psdi-common-footer.html,sha256=zzizo_YEPhvH3_jNPFkFoKZA0TnIG6EXzQOsgooU1K8,3989
36
+ psdi_data_conversion/static/content/index-versions/psdi-common-footer.html,sha256=nFZtEObp-X73p95oTOAvqzoPwjsEJD5dKUDhUPDCcj4,4136
37
37
  psdi_data_conversion/static/content/index-versions/psdi-common-header.html,sha256=IXmvdlArY-60b7HgvKjcNF3eSmEmTImX7Hdasswyi5s,1907
38
- psdi_data_conversion/static/data/data.json,sha256=_3o3BFEmnWGhoGMaviJsu-U9dJnk_tH9Wf0g-eDVWuU,3630027
38
+ psdi_data_conversion/static/data/data.json,sha256=1nljosxtwbLRfIIIa6-GHJnhvzhB759oEGvVQ18QP_4,3647095
39
39
  psdi_data_conversion/static/img/colormode-toggle-dm.svg,sha256=Q85ODwU67chZ77lyT9gITtnmqzJEycFmz35dJuqaPXE,502
40
40
  psdi_data_conversion/static/img/colormode-toggle-lm.svg,sha256=sIKXsNmLIXU4fSuuqrN0r-J4Hd3NIqoiXNT3mdq5-Fo,1155
41
41
  psdi_data_conversion/static/img/psdi-icon-dark.svg,sha256=-hYXxegsw67i0qqAOYCx-I-ZPyG04wG0aBVTKoZQlL0,69747
@@ -62,26 +62,26 @@ psdi_data_conversion/static/img/ukri-logo-darktext.png,sha256=3UgghERAmFdnre0Ffc
62
62
  psdi_data_conversion/static/img/ukri-logo-lighttext.png,sha256=ptIQwIGGdVsO2rTximo9QjtJFH9DpkJcAs1glwKFjwo,25579
63
63
  psdi_data_conversion/static/javascript/accessibility.js,sha256=kbnWHeBNPrTLrnYRjMEUmiOcCXM2bORYIRfzUB03TAE,7208
64
64
  psdi_data_conversion/static/javascript/common.js,sha256=3YZdwfq54OPl-xIImTwjbXqxKqlrAaEbeac0cAHvScU,1720
65
- psdi_data_conversion/static/javascript/convert.js,sha256=UfrqaO7VNiLeed-d92O_jpKXRa63-0tCb_e-rqjTdFM,9074
66
- psdi_data_conversion/static/javascript/convert_common.js,sha256=o4KHIlYToC3AfOa8MTzbPaNDjPEesyvUy50AVgTRxvI,11000
65
+ psdi_data_conversion/static/javascript/convert.js,sha256=xWd0V9wyPD6t2ltTbaAQqqnvneU6_VEdMhVyg7UUo6c,10453
66
+ psdi_data_conversion/static/javascript/convert_common.js,sha256=nr0UTAPv2hahqCjl_JzxoOAtsyKIsk6qDXO6cItmChg,11369
67
67
  psdi_data_conversion/static/javascript/convertato.js,sha256=faSvfm9HWT3i8piqEDq8OfekiPo3jCV2vKT_VjdzwmE,3555
68
68
  psdi_data_conversion/static/javascript/convertc2x.js,sha256=TTqC9B2FD_q3RcPE2GJh6yAhocQyJLRfQsbSWzm2g3U,3550
69
- psdi_data_conversion/static/javascript/data.js,sha256=JNJLzMLyC6ke2vDzK-dgeMH2Z4LmB6R3DQ4ykMzjnK0,6376
69
+ psdi_data_conversion/static/javascript/data.js,sha256=ZM5PkPqiq8aUaB0ARWLK4TVSuxJKAFAAxlF1-7BsJ1g,6915
70
70
  psdi_data_conversion/static/javascript/format.js,sha256=S-ovNuqOSfS-RYDhFxxCDpTKFKdxOWAYvJuzeEPcXB0,21260
71
71
  psdi_data_conversion/static/javascript/load_accessibility.js,sha256=jTLfmubEmko2bJ_MKWMkmYxUeBxotozc-0-ua69CYJo,3265
72
72
  psdi_data_conversion/static/javascript/psdi-common.js,sha256=I0QqGQ7l_rA4KEfenQTfPc-uOXXp8sxMh_NHL3EkFm4,6231
73
73
  psdi_data_conversion/static/javascript/report.js,sha256=BHH5UOhXJtB6J_xk_y6woquNKt5W9hCrQapxKtGG1eA,12470
74
- psdi_data_conversion/static/styles/format.css,sha256=HKgKkepZtY0NCtKm4JlsuchDL_vymBQ0pRnmfVE8L30,3097
74
+ psdi_data_conversion/static/styles/format.css,sha256=PaQkUVxQfXI9nbJ-7YsN1tNIcLXfwXk8wJC-zht8nRA,3269
75
75
  psdi_data_conversion/static/styles/psdi-common.css,sha256=09VY-lldoZCrohuqPKnd9fvDget5g9ybi6uh13pYeY0,17249
76
76
  psdi_data_conversion/templates/index.htm,sha256=wuHECSzTwVwmaGg55RnYunsaSFCYBmxf6_P4OygTNEQ,6824
77
77
  psdi_data_conversion/testing/__init__.py,sha256=Xku7drtLTYLLPsd403eC0LIEa_iohVifyeyAITy2w7U,135
78
78
  psdi_data_conversion/testing/constants.py,sha256=BtIafruSobZ9cFY0VW5Bu209eiftnN8b3ObouZBrFQU,521
79
- psdi_data_conversion/testing/conversion_callbacks.py,sha256=FeRcS06ynLzQOWwqf2QiIR5EaM-icKGolvrVI88ZOOg,18858
80
- psdi_data_conversion/testing/conversion_test_specs.py,sha256=vsNj2YKX1ZYglAPVN4smuLn6fjZKYMfaxuwkyLDj39g,24878
81
- psdi_data_conversion/testing/gui.py,sha256=I44QeLztcnt-37Zf2nOvrqjo_y6a40VhjehdVwGejW0,18708
82
- psdi_data_conversion/testing/utils.py,sha256=ZuwB5rEW-eB-38xQb3ZvJpSzuI4ocbFUNAc-uiC4vW4,26134
83
- psdi_data_conversion-0.0.38.dist-info/METADATA,sha256=eIHXKGbPOKrQgYQGA5uIrP9xGgaSNoec6UN_KulmhBE,48116
84
- psdi_data_conversion-0.0.38.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
85
- psdi_data_conversion-0.0.38.dist-info/entry_points.txt,sha256=xL7XTzaPRr2E67WhOD1M1Q-76hB8ausQlnNiHzuZQPA,123
86
- psdi_data_conversion-0.0.38.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
87
- psdi_data_conversion-0.0.38.dist-info/RECORD,,
79
+ psdi_data_conversion/testing/conversion_callbacks.py,sha256=ATR-_BsYCUN8KyOyUjfdWCELzySxLN5jOI0JyrQnmHQ,18858
80
+ psdi_data_conversion/testing/conversion_test_specs.py,sha256=jFik-m-jxNZzZhyfiJVIj7CT4ML8pM4dm7Trs2d0hgg,25602
81
+ psdi_data_conversion/testing/gui.py,sha256=ul7ixYANIzmOG2ZNOZmQO6wsHmGHdiBGAlw-KuoN0j8,19085
82
+ psdi_data_conversion/testing/utils.py,sha256=YrFxjyiIx1seph0j7jCUgAVm6HvXY9QJjx0MvNJRbfw,26134
83
+ psdi_data_conversion-0.0.39.dist-info/METADATA,sha256=QVdwrTA_MdZyiQNOgE2cuVEUh_zA_zs3s9LxQFVY9r4,48116
84
+ psdi_data_conversion-0.0.39.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
85
+ psdi_data_conversion-0.0.39.dist-info/entry_points.txt,sha256=xL7XTzaPRr2E67WhOD1M1Q-76hB8ausQlnNiHzuZQPA,123
86
+ psdi_data_conversion-0.0.39.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
87
+ psdi_data_conversion-0.0.39.dist-info/RECORD,,