Browse Source

Merge branch 'master' into forkdev

Alexander Rose 3 years ago
parent
commit
80d54afdd0
100 changed files with 4002 additions and 3693 deletions
  1. 11 1
      .eslintrc.json
  2. 13 11
      CHANGELOG.md
  3. 16 23
      data/cif-field-names/cif-core-field-names.csv
  4. 464 279
      package-lock.json
  5. 48 48
      package.json
  6. 1 1
      src/apps/viewer/index.ts
  7. 6 6
      src/cli/chem-comp-dict/create-ions.ts
  8. 8 8
      src/cli/chem-comp-dict/create-table.ts
  9. 6 6
      src/cli/cif2bcif/index.ts
  10. 23 23
      src/cli/cifschema/index.ts
  11. 20 21
      src/cli/cifschema/util/cif-dic.ts
  12. 1 1
      src/cli/cifschema/util/generate.ts
  13. 2 2
      src/cli/cifschema/util/helper.ts
  14. 1 1
      src/cli/cifschema/util/schema.ts
  15. 5 5
      src/cli/lipid-params/index.ts
  16. 15 15
      src/cli/structure-info/model.ts
  17. 5 5
      src/cli/structure-info/volume.ts
  18. 1 1
      src/examples/domain-annotation-server/server.ts
  19. 1 1
      src/examples/lighting/index.ts
  20. 32 13
      src/extensions/anvil/algorithm.ts
  21. 1 1
      src/extensions/anvil/behavior.ts
  22. 2 2
      src/extensions/cellpack/color/generate.ts
  23. 2 2
      src/extensions/cellpack/curve.ts
  24. 5 5
      src/extensions/cellpack/model.ts
  25. 2 2
      src/extensions/cellpack/state.ts
  26. 1 1
      src/extensions/dnatco/confal-pyramids/behavior.ts
  27. 2 2
      src/extensions/dnatco/confal-pyramids/color.ts
  28. 5 5
      src/extensions/geo-export/glb-exporter.ts
  29. 2 2
      src/extensions/geo-export/mesh-exporter.ts
  30. 1 1
      src/extensions/pdbe/structure-quality-report/behavior.ts
  31. 1 1
      src/extensions/pdbe/structure-quality-report/prop.ts
  32. 1 1
      src/extensions/rcsb/assembly-symmetry/behavior.ts
  33. 1 1
      src/extensions/rcsb/assembly-symmetry/prop.ts
  34. 10 9
      src/extensions/rcsb/graphql/codegen.yml
  35. 2861 2770
      src/extensions/rcsb/graphql/types.ts
  36. 1 1
      src/extensions/rcsb/validation-report/behavior.ts
  37. 5 5
      src/extensions/rcsb/validation-report/prop.ts
  38. 2 2
      src/extensions/rcsb/validation-report/representation.ts
  39. 4 4
      src/mol-canvas3d/canvas3d.ts
  40. 3 3
      src/mol-canvas3d/helper/interaction-events.ts
  41. 20 20
      src/mol-canvas3d/passes/multi-sample.ts
  42. 7 7
      src/mol-canvas3d/passes/postprocessing.ts
  43. 2 2
      src/mol-canvas3d/passes/smaa.ts
  44. 1 1
      src/mol-data/db/_spec/table.spec.ts
  45. 3 3
      src/mol-data/generic/_spec/linked-list.spec.ts
  46. 1 1
      src/mol-data/util/chunked-array.ts
  47. 2 2
      src/mol-geo/geometry/base.ts
  48. 1 1
      src/mol-geo/geometry/cylinders/cylinders.ts
  49. 1 1
      src/mol-geo/geometry/lines/lines.ts
  50. 33 1
      src/mol-geo/geometry/marker-data.ts
  51. 1 1
      src/mol-geo/geometry/mesh/builder/ribbon.ts
  52. 1 1
      src/mol-geo/geometry/mesh/builder/sheet.ts
  53. 2 2
      src/mol-geo/geometry/mesh/color-smoothing.ts
  54. 1 1
      src/mol-geo/geometry/points/points.ts
  55. 1 1
      src/mol-geo/geometry/size-data.ts
  56. 1 1
      src/mol-geo/geometry/texture-mesh/color-smoothing.ts
  57. 6 6
      src/mol-geo/primitive/cylinder.ts
  58. 1 1
      src/mol-geo/primitive/plane.ts
  59. 3 3
      src/mol-geo/primitive/polyhedron.ts
  60. 1 1
      src/mol-geo/primitive/torus.ts
  61. 2 2
      src/mol-geo/util/marching-cubes/builder.ts
  62. 12 12
      src/mol-geo/util/marching-cubes/tables.ts
  63. 6 6
      src/mol-gl/_spec/gl.shim.ts
  64. 2 2
      src/mol-gl/_spec/renderer.spec.ts
  65. 1 1
      src/mol-gl/webgl/resources.ts
  66. 1 1
      src/mol-gl/webgl/state.ts
  67. 19 19
      src/mol-io/common/binary-cif/decoder.ts
  68. 2 2
      src/mol-io/common/binary.ts
  69. 1 1
      src/mol-io/common/file-handle.ts
  70. 9 9
      src/mol-io/common/msgpack/encode.ts
  71. 4 4
      src/mol-io/common/typed-array.ts
  72. 7 6
      src/mol-io/common/utf8.ts
  73. 2 2
      src/mol-io/reader/_spec/ply.spec.ts
  74. 1 1
      src/mol-io/reader/ccp4/parser.ts
  75. 1 1
      src/mol-io/reader/cif/data-model.ts
  76. 1 1
      src/mol-io/reader/cif/schema/bird.ts
  77. 2 2
      src/mol-io/reader/cif/schema/ccd.ts
  78. 68 120
      src/mol-io/reader/cif/schema/cif-core.ts
  79. 72 37
      src/mol-io/reader/cif/schema/mmcif.ts
  80. 10 10
      src/mol-io/reader/cif/text/parser.ts
  81. 1 1
      src/mol-io/reader/common/text/column/fixed.ts
  82. 2 1
      src/mol-io/reader/common/text/number-parser.ts
  83. 1 1
      src/mol-io/reader/common/text/tokenizer.ts
  84. 1 1
      src/mol-io/reader/csv/parser.ts
  85. 1 1
      src/mol-io/reader/cube/parser.ts
  86. 2 2
      src/mol-io/reader/xtc/parser.ts
  87. 1 1
      src/mol-io/writer/cif/encoder/util.ts
  88. 4 4
      src/mol-math/geometry/boundary-helper.ts
  89. 1 1
      src/mol-math/geometry/gaussian-density/cpu.ts
  90. 5 5
      src/mol-math/geometry/gaussian-density/gpu.ts
  91. 3 3
      src/mol-math/geometry/molecular-surface.ts
  92. 2 2
      src/mol-math/geometry/primitives/box3d.ts
  93. 1 1
      src/mol-math/geometry/spacegroup/construction.ts
  94. 1 1
      src/mol-math/histogram.ts
  95. 26 34
      src/mol-math/linear-algebra/3d/mat4.ts
  96. 30 30
      src/mol-math/linear-algebra/3d/quat.ts
  97. 1 1
      src/mol-math/linear-algebra/3d/vec3.ts
  98. 3 3
      src/mol-math/linear-algebra/_spec/tensor.spec.ts
  99. 4 4
      src/mol-math/linear-algebra/_spec/vec3.spec.ts
  100. 9 9
      src/mol-math/linear-algebra/matrix/evd.ts

+ 11 - 1
.eslintrc.json

@@ -38,7 +38,17 @@
                 "selector": "ExportDefaultDeclaration",
                 "message": "Default exports are not allowed"
             }
-        ]
+        ],
+        "no-throw-literal": "error",
+        "key-spacing": "error",
+        "object-curly-spacing": ["error", "always"],
+        "array-bracket-spacing": "error",
+        "space-in-parens": "error",
+        "computed-property-spacing": "error",
+        "prefer-const": ["error", {
+            "destructuring": "all",
+            "ignoreReadBeforeAssign": false
+        }]
     },
     "overrides": [
         {

+ 13 - 11
CHANGELOG.md

@@ -4,28 +4,30 @@ All notable changes to this project will be documented in this file, following t
 Note that since we don't clearly distinguish between a public and private interfaces there will be changes in non-major versions that are potentially breaking. If we make breaking changes to less used interfaces we will highlight it in here.
 
 
-## [Unreleased]
+## [v2.3.0] - 2021-09-06
 
-
-## [v2.2.3] - 2021-08-25
-
-- Add ``invertCantorPairing`` helper function
-- Add ``Mesh`` processing helper ``.smoothEdges``
-- Smooth border of molecular-surface with ``includeParent`` enabled
-- Hide ``includeParent`` option from gaussian-surface visuals (not particularly useful)
-- Fix new ``TransformData`` issues (camera/bounding helper not showing up)
+- Take include/exclude flags into account when displaying aromatic bonds
 - Improve marking performance
-    - Avoid superfluous calls to ``StructureElement.Loci.isWholeStructure``
+    - Avoid unnecessary draw calls/ui updates when marking
     - Check if loci is superset of visual
     - Check if loci overlaps with unit visual
     - Ensure ``Interval`` is used for ranges instead of ``SortedArray``
-    - Inline ``StructureElement.Loci.size`` code
     - Add uniform marker type
     - Special case for reversing previous mark
 - Add optional marking pass
     - Outlines visible and hidden parts of highlighted/selected groups
     - Add highlightStrength/selectStrength renderer params
 
+## [v2.2.3] - 2021-08-25
+
+- Add ``invertCantorPairing`` helper function
+- Add ``Mesh`` processing helper ``.smoothEdges``
+- Smooth border of molecular-surface with ``includeParent`` enabled
+- Hide ``includeParent`` option from gaussian-surface visuals (not particularly useful)
+- Improved ``StructureElement.Loci.size`` performance (for marking large cellpack models)
+- Fix new ``TransformData`` issues (camera/bounding helper not showing up)
+- Improve marking performance (avoid superfluous calls to ``StructureElement.Loci.isWholeStructure``)
+
 ## [v2.2.2] - 2021-08-11
 
 - Fix ``TransformData`` issues [#133](https://github.com/molstar/molstar/issues/133)

+ 16 - 23
data/cif-field-names/cif-core-field-names.csv

@@ -2,11 +2,11 @@ audit.block_doi
 
 database_code.depnum_ccdc_archive
 database_code.depnum_ccdc_fiz
-database_code.ICSD
-database_code.MDF
-database_code.NBS
-database_code.CSD
-database_code.COD
+database_code.icsd
+database_code.mdf
+database_code.nbs
+database_code.csd
+database_code.cod
 
 chemical.name_systematic
 chemical.name_common
@@ -24,8 +24,8 @@ atom_type_scat.dispersion_imag
 atom_type_scat.source
 
 space_group.crystal_system
-space_group.name_H-M_full
-space_group.IT_number
+space_group.name_h-m_full
+space_group.it_number
 space_group_symop.operation_xyz
 
 cell.length_a
@@ -35,14 +35,14 @@ cell.angle_alpha
 cell.angle_beta
 cell.angle_gamma
 cell.volume
-cell.formula_units_Z
+cell.formula_units_z
 
 atom_site.label
 atom_site.type_symbol
 atom_site.fract_x
 atom_site.fract_y
 atom_site.fract_z
-atom_site.U_iso_or_equiv
+atom_site.u_iso_or_equiv
 atom_site.adp_type
 atom_site.occupancy
 atom_site.calc_flag
@@ -52,20 +52,13 @@ atom_site.disorder_group
 atom_site.site_symmetry_multiplicity
 
 atom_site_aniso.label
-atom_site_aniso.U
-atom_site_aniso.U_11
-atom_site_aniso.U_22
-atom_site_aniso.U_33
-atom_site_aniso.U_23
-atom_site_aniso.U_13
-atom_site_aniso.U_12
-atom_site_aniso.U_su
-atom_site_aniso.U_11_su
-atom_site_aniso.U_22_su
-atom_site_aniso.U_33_su
-atom_site_aniso.U_23_su
-atom_site_aniso.U_13_su
-atom_site_aniso.U_12_su
+atom_site_aniso.u
+atom_site_aniso.u_11
+atom_site_aniso.u_22
+atom_site_aniso.u_33
+atom_site_aniso.u_23
+atom_site_aniso.u_13
+atom_site_aniso.u_12
 
 geom_bond.atom_site_label_1
 geom_bond.atom_site_label_2

File diff suppressed because it is too large
+ 464 - 279
package-lock.json


+ 48 - 48
package.json

@@ -1,6 +1,6 @@
 {
   "name": "molstar",
-  "version": "2.2.3",
+  "version": "2.3.0",
   "description": "A comprehensive macromolecular library.",
   "homepage": "https://github.com/molstar/molstar#readme",
   "repository": {
@@ -88,68 +88,68 @@
   ],
   "license": "MIT",
   "devDependencies": {
-    "@graphql-codegen/add": "^2.0.2",
-    "@graphql-codegen/cli": "^1.19.4",
-    "@graphql-codegen/time": "^2.0.2",
-    "@graphql-codegen/typescript": "^1.19.0",
-    "@graphql-codegen/typescript-graphql-files-modules": "^1.18.1",
-    "@graphql-codegen/typescript-graphql-request": "^2.0.3",
-    "@graphql-codegen/typescript-operations": "^1.17.12",
-    "@types/cors": "^2.8.8",
-    "@typescript-eslint/eslint-plugin": "^4.9.1",
-    "@typescript-eslint/parser": "^4.9.1",
+    "@graphql-codegen/add": "^3.1.0",
+    "@graphql-codegen/cli": "^2.2.0",
+    "@graphql-codegen/time": "^3.1.0",
+    "@graphql-codegen/typescript": "^2.2.2",
+    "@graphql-codegen/typescript-graphql-files-modules": "^2.1.0",
+    "@graphql-codegen/typescript-graphql-request": "^4.1.4",
+    "@graphql-codegen/typescript-operations": "^2.1.4",
+    "@types/cors": "^2.8.12",
+    "@typescript-eslint/eslint-plugin": "^4.31.0",
+    "@typescript-eslint/parser": "^4.31.0",
     "benchmark": "^2.1.4",
-    "concurrently": "^5.3.0",
-    "cpx2": "^3.0.0",
+    "concurrently": "^6.2.1",
+    "cpx2": "^3.0.2",
     "crypto-browserify": "^3.12.0",
-    "css-loader": "^5.0.1",
-    "eslint": "^7.15.0",
+    "css-loader": "^6.2.0",
+    "eslint": "^7.32.0",
     "extra-watch-webpack-plugin": "^1.0.3",
     "file-loader": "^6.2.0",
-    "fs-extra": "^9.0.1",
-    "graphql": "^15.4.0",
-    "http-server": "^0.12.3",
-    "jest": "^26.6.3",
-    "mini-css-extract-plugin": "^1.3.2",
-    "node-sass": "^6.0.0",
+    "fs-extra": "^10.0.0",
+    "graphql": "^15.5.3",
+    "http-server": "^13.0.1",
+    "jest": "^27.1.1",
+    "mini-css-extract-plugin": "^2.3.0",
+    "node-sass": "^6.0.1",
     "path-browserify": "^1.0.1",
     "raw-loader": "^4.0.2",
-    "sass-loader": "^11.1.1",
-    "simple-git": "^2.25.0",
+    "sass-loader": "^12.1.0",
+    "simple-git": "^2.45.1",
     "stream-browserify": "^3.0.0",
-    "style-loader": "^2.0.0",
-    "ts-jest": "^26.4.4",
-    "typescript": "^4.2.4",
-    "webpack": "^5.37.1",
-    "webpack-cli": "^4.7.0",
+    "style-loader": "^3.2.1",
+    "ts-jest": "^27.0.5",
+    "typescript": "^4.4.3",
+    "webpack": "^5.52.1",
+    "webpack-cli": "^4.8.0",
     "webpack-version-file-plugin": "^0.4.0"
   },
   "dependencies": {
-    "@types/argparse": "^1.0.38",
-    "@types/benchmark": "^2.1.0",
-    "@types/compression": "1.7.0",
-    "@types/express": "^4.17.9",
-    "@types/jest": "^26.0.18",
-    "@types/node": "^14.14.11",
-    "@types/node-fetch": "^2.5.7",
-    "@types/react": "^17.0.0",
-    "@types/react-dom": "^17.0.0",
-    "@types/swagger-ui-dist": "3.30.0",
-    "argparse": "^1.0.10",
+    "@types/argparse": "^2.0.10",
+    "@types/benchmark": "^2.1.1",
+    "@types/compression": "1.7.2",
+    "@types/express": "^4.17.13",
+    "@types/jest": "^27.0.1",
+    "@types/node": "^16.9.1",
+    "@types/node-fetch": "^2.5.12",
+    "@types/react": "^17.0.20",
+    "@types/react-dom": "^17.0.9",
+    "@types/swagger-ui-dist": "3.30.1",
+    "argparse": "^2.0.1",
     "body-parser": "^1.19.0",
     "compression": "^1.7.4",
     "cors": "^2.8.5",
     "express": "^4.17.1",
     "h264-mp4-encoder": "^1.0.12",
-    "immer": "^8.0.1",
+    "immer": "^9.0.6",
     "immutable": "^3.8.2",
-    "node-fetch": "^2.6.1",
-    "react": "^17.0.1",
-    "react-dom": "^17.0.1",
-    "rxjs": "^6.6.6",
-    "swagger-ui-dist": "^3.37.2",
-    "tslib": "^2.1.0",
-    "util.promisify": "^1.0.1",
-    "xhr2": "^0.2.0"
+    "node-fetch": "^2.6.2",
+    "react": "^17.0.2",
+    "react-dom": "^17.0.2",
+    "rxjs": "^7.3.0",
+    "swagger-ui-dist": "^3.52.1",
+    "tslib": "^2.3.1",
+    "util.promisify": "^1.1.1",
+    "xhr2": "^0.2.1"
   }
 }

+ 1 - 1
src/apps/viewer/index.ts

@@ -325,7 +325,7 @@ export class Viewer {
     }
 
     handleResize() {
-        this.plugin.layout.events.updated.next();
+        this.plugin.layout.events.updated.next(void 0);
     }
 }
 

+ 6 - 6
src/cli/chem-comp-dict/create-ions.ts

@@ -19,7 +19,7 @@ import { ensureDataAvailable, readCCD } from './util';
 function extractIonNames(ccd: DatabaseCollection<CCD_Schema>) {
     const ionNames: string[] = [];
     for (const k in ccd) {
-        const {chem_comp} = ccd[k];
+        const { chem_comp } = ccd[k];
         if (chem_comp.name.value(0).toUpperCase().includes(' ION')) {
             ionNames.push(chem_comp.id.value(0));
         }
@@ -54,20 +54,20 @@ async function run(out: string, forceDownload = false) {
 }
 
 const parser = new argparse.ArgumentParser({
-    addHelp: true,
+    add_help: true,
     description: 'Extract and save IonNames from CCD.'
 });
-parser.addArgument('out', {
+parser.add_argument('out', {
     help: 'Generated file output path.'
 });
-parser.addArgument([ '--forceDownload', '-f' ], {
-    action: 'storeTrue',
+parser.add_argument('--forceDownload', '-f', {
+    action: 'store_true',
     help: 'Force download of CCD and PVCD.'
 });
 interface Args {
     out: string,
     forceDownload?: boolean,
 }
-const args: Args = parser.parseArgs();
+const args: Args = parser.parse_args();
 
 run(args.out, args.forceDownload);

+ 8 - 8
src/cli/chem-comp-dict/create-table.ts

@@ -265,21 +265,21 @@ const CCB_TABLE_NAME = 'CHEM_COMP_BONDS';
 const CCA_TABLE_NAME = 'CHEM_COMP_ATOMS';
 
 const parser = new argparse.ArgumentParser({
-    addHelp: true,
+    add_help: true,
     description: 'Create a cif file with one big table of all chem_comp_bond entries from the CCD and PVCD.'
 });
-parser.addArgument('out', {
+parser.add_argument('out', {
     help: 'Generated file output path.'
 });
-parser.addArgument([ '--forceDownload', '-f' ], {
-    action: 'storeTrue',
+parser.add_argument('--forceDownload', '-f', {
+    action: 'store_true',
     help: 'Force download of CCD and PVCD.'
 });
-parser.addArgument([ '--binary', '-b' ], {
-    action: 'storeTrue',
+parser.add_argument('--binary', '-b', {
+    action: 'store_true',
     help: 'Output as BinaryCIF.'
 });
-parser.addArgument(['--ccaOut', '-a'], {
+parser.add_argument('--ccaOut', '-a', {
     help: 'Optional generated file output path for chem_comp_atom data.',
     required: false
 });
@@ -289,6 +289,6 @@ interface Args {
     binary?: boolean,
     ccaOut?: string
 }
-const args: Args = parser.parseArgs();
+const args: Args = parser.parse_args();
 
 run(args.out, args.binary, args.forceDownload, args.ccaOut);

+ 6 - 6
src/cli/cif2bcif/index.ts

@@ -37,20 +37,20 @@ function run(args: Args) {
 }
 
 const parser = new argparse.ArgumentParser({
-    addHelp: true,
+    add_help: true,
     description: 'Convert any CIF file to a BCIF file'
 });
-parser.addArgument([ 'src' ], {
+parser.add_argument('src', {
     help: 'Source CIF path'
 });
-parser.addArgument([ 'out' ], {
+parser.add_argument('out', {
     help: 'Output BCIF path'
 });
-parser.addArgument([ '-c', '--config' ], {
+parser.add_argument('-c', '--config', {
     help: 'Optional encoding strategy/precision config path',
     required: false
 });
-parser.addArgument([ '-f', '--filter' ], {
+parser.add_argument('-f', '--filter', {
     help: 'Optional filter whitelist/blacklist path',
     required: false
 });
@@ -61,7 +61,7 @@ interface Args {
     config?: string
     filter?: string
 }
-const args: Args = parser.parseArgs();
+const args: Args = parser.parse_args();
 
 if (args) {
     run(args);

+ 23 - 23
src/cli/cifschema/index.ts

@@ -124,15 +124,15 @@ async function getFieldNamesFilter(fieldNamesPath: string): Promise<Filter> {
     const csvFile = parsed.result;
 
     const fieldNamesCol = csvFile.table.getColumn('0');
-    if (!fieldNamesCol) throw 'error getting fields columns';
+    if (!fieldNamesCol) throw new Error('error getting fields columns');
     const fieldNames = fieldNamesCol.toStringArray();
 
     const filter: Filter = {};
     fieldNames.forEach((name, i) => {
-        const [ category, field ] = name.split('.');
+        const [category, field] = name.split('.');
         // console.log(category, field)
-        if (!filter[ category ]) filter[ category ] = {};
-        filter[ category ][ field ] = true;
+        if (!filter[category]) filter[category] = {};
+        filter[category][field] = true;
     });
     return filter;
 }
@@ -178,44 +178,44 @@ const CIF_CORE_ATTR_PATH = `${DIC_DIR}/templ_attr.cif`;
 const CIF_CORE_ATTR_URL = 'https://raw.githubusercontent.com/COMCIFS/cif_core/master/templ_attr.cif';
 
 const parser = new argparse.ArgumentParser({
-    addHelp: true,
+    add_help: true,
     description: 'Create schema from mmcif dictionary (v50 plus IHM and entity_branch extensions, downloaded from wwPDB)'
 });
-parser.addArgument([ '--preset', '-p' ], {
-    defaultValue: '',
+parser.add_argument('--preset', '-p', {
+    default: '',
     choices: ['', 'mmCIF', 'CCD', 'BIRD', 'CifCore'],
     help: 'Preset name'
 });
-parser.addArgument([ '--name', '-n' ], {
-    defaultValue: '',
+parser.add_argument('--name', '-n', {
+    default: '',
     help: 'Schema name'
 });
-parser.addArgument([ '--out', '-o' ], {
+parser.add_argument('--out', '-o', {
     help: 'Generated schema output path, if not given printed to stdout'
 });
-parser.addArgument([ '--targetFormat', '-tf' ], {
-    defaultValue: 'typescript-molstar',
+parser.add_argument('--targetFormat', '-tf', {
+    default: 'typescript-molstar',
     choices: ['typescript-molstar', 'json-internal'],
     help: 'Target format'
 });
-parser.addArgument([ '--dicPath', '-d' ], {
-    defaultValue: '',
+parser.add_argument('--dicPath', '-d', {
+    default: '',
     help: 'Path to dictionary'
 });
-parser.addArgument([ '--fieldNamesPath', '-fn' ], {
-    defaultValue: '',
+parser.add_argument('--fieldNamesPath', '-fn', {
+    default: '',
     help: 'Field names to include'
 });
-parser.addArgument([ '--forceDicDownload', '-f' ], {
-    action: 'storeTrue',
+parser.add_argument('--forceDicDownload', '-f', {
+    action: 'store_true',
     help: 'Force download of dictionaries'
 });
-parser.addArgument([ '--moldataImportPath', '-mip' ], {
-    defaultValue: 'molstar/lib/mol-data',
+parser.add_argument('--moldataImportPath', '-mip', {
+    default: 'molstar/lib/mol-data',
     help: 'mol-data import path (for typescript target only)'
 });
-parser.addArgument([ '--addAliases', '-aa' ], {
-    action: 'storeTrue',
+parser.add_argument('--addAliases', '-aa', {
+    action: 'store_true',
     help: 'Add field name/path aliases'
 });
 interface Args {
@@ -230,7 +230,7 @@ interface Args {
     moldataImportPath: string
     addAliases: boolean
 }
-const args: Args = parser.parseArgs();
+const args: Args = parser.parse_args();
 
 const FORCE_DIC_DOWNLOAD = args.forceDicDownload;
 

+ 20 - 21
src/cli/cifschema/util/cif-dic.ts

@@ -34,6 +34,8 @@ export function getFieldType(type: string, description: string, values?: string[
         case 'seq-one-letter-code':
         case 'author':
         case 'orcid_id':
+        case 'pdbx_PDB_obsoleted_db_id':
+        case 'pdbx_related_db_id':
         case 'sequence_dep':
         case 'pdb_id':
         case 'emd_id':
@@ -79,7 +81,7 @@ export function getFieldType(type: string, description: string, values?: string[
         case 'List(Real,Real)':
         case 'List(Real,Real,Real,Real)':
         case 'Date':
-        case 'Datetime':
+        case 'DateTime':
         case 'Tag':
         case 'Implied':
             return wrapContainer('str', ',', description, container);
@@ -187,7 +189,7 @@ function getContainer(d: Data.CifFrame, imports: Imports, ctx: FrameData) {
 function getCode(d: Data.CifFrame, imports: Imports, ctx: FrameData): [string, string[] | undefined, string | undefined ] | undefined {
     const code = getField('item_type', 'code', d, imports, ctx) || getField('type', 'contents', d, imports, ctx);
     if (code) {
-        return [ code.str(0), getEnums(d, imports, ctx), getContainer(d, imports, ctx) ];
+        return [code.str(0), getEnums(d, imports, ctx), getContainer(d, imports, ctx)];
     } else {
         console.log(`item_type.code or type.contents not found for '${d.header}'`);
     }
@@ -232,29 +234,26 @@ const FORCE_INT_FIELDS = [
     '_struct_sheet_range.end_auth_seq_id',
 ];
 
+/**
+ * Note that name and mapped name must share a prefix. This is not always the case in
+ * the cifCore dictionary, but for downstream code to work a container field with the
+ * same prefix as the member fields must be given here and in the field names filter
+ * list.
+ */
 const FORCE_MATRIX_FIELDS_MAP: { [k: string]: string } = {
-    'atom_site_aniso.U_11': 'U',
-    'atom_site_aniso.U_22': 'U',
-    'atom_site_aniso.U_33': 'U',
-    'atom_site_aniso.U_23': 'U',
-    'atom_site_aniso.U_13': 'U',
-    'atom_site_aniso.U_12': 'U',
-    'atom_site_aniso.U_11_su': 'U_su',
-    'atom_site_aniso.U_22_su': 'U_su',
-    'atom_site_aniso.U_33_su': 'U_su',
-    'atom_site_aniso.U_23_su': 'U_su',
-    'atom_site_aniso.U_13_su': 'U_su',
-    'atom_site_aniso.U_12_su': 'U_su',
+    'atom_site_aniso.u_11': 'u', // is matrix_u in the the dic
+    'atom_site_aniso.u_22': 'u',
+    'atom_site_aniso.u_33': 'u',
+    'atom_site_aniso.u_23': 'u',
+    'atom_site_aniso.u_13': 'u',
+    'atom_site_aniso.u_12': 'u',
 };
 const FORCE_MATRIX_FIELDS = Object.keys(FORCE_MATRIX_FIELDS_MAP);
 
 const EXTRA_ALIASES: Database['aliases'] = {
-    'atom_site_aniso.U': [
-        'atom_site_anisotrop_U'
-    ],
-    'atom_site_aniso.U_su': [
-        'atom_site_aniso_U_esd',
-        'atom_site_anisotrop_U_esd',
+    'atom_site_aniso.matrix_u': [
+        'atom_site_anisotrop_U',
+        'atom_site_aniso.U'
     ],
 };
 
@@ -372,7 +371,7 @@ export function generateSchema(frames: CifFrame[], imports: Imports = new Map())
             const parent_name = item_linked.getField('parent_name');
             if (child_name && parent_name) {
                 for (let i = 0; i < item_linked.rowCount; ++i) {
-                    const childName = child_name.str(i);
+                    const childName: string = child_name.str(i);
                     const parentName = parent_name.str(i);
                     if (childName in links && links[childName] !== parentName) {
                         console.log(`${childName} linked to ${links[childName]}, ignoring link to ${parentName}`);

+ 1 - 1
src/cli/cifschema/util/generate.ts

@@ -128,7 +128,7 @@ export function generate (name: string, info: string, schema: Database, fields:
         codeLines.push('');
         codeLines.push(`export const ${name}_Aliases = {`);
         Object.keys(schema.aliases).forEach(path => {
-            const [ table, columnName ] = path.split('.');
+            const [table, columnName] = path.split('.');
             if (fields && !fields[table]) return;
             if (fields && !fields[table][columnName]) return;
 

+ 2 - 2
src/cli/cifschema/util/helper.ts

@@ -10,8 +10,8 @@ export function parseImportGet(s: string): Import[] {
     // [{'save':hi_ang_Fox_coeffs  'file':templ_attr.cif}   {'save':hi_ang_Fox_c0  'file':templ_enum.cif}]
     // [{"file":'templ_enum.cif' "save":'H_M_ref'}]
     return s.trim().substring(2, s.length - 2).split(/}[ \n\t]*{/g).map(s => {
-        const save = s.match(/('save'|"save"):([^ \t\n]+)/);
-        const file = s.match(/('file'|"file"):([^ \t\n]+)/);
+        const save = s.match(/('save'|"save"):([^ \t\n{}]+)/);
+        const file = s.match(/('file'|"file"):([^ \t\n{}]+)/);
         return {
             save: save ? save[0].substr(7).replace(/['"]/g, '') : undefined,
             file: file ? file[0].substr(7).replace(/['"]/g, '') : undefined

+ 1 - 1
src/cli/cifschema/util/schema.ts

@@ -57,7 +57,7 @@ export function mergeFilters (...filters: Filter[]) {
     const fields: Map<string, number> = new Map();
     filters.forEach(filter => {
         Object.keys(filter).forEach(category => {
-            Object.keys(filter[ category ]).forEach(field => {
+            Object.keys(filter[category]).forEach(field => {
                 const key = `${category}.${field}`;
                 const value = fields.get(key) || 0;
                 fields.set(key, value + 1);

+ 5 - 5
src/cli/lipid-params/index.ts

@@ -70,21 +70,21 @@ export const LipidNames = new Set(${lipidNames.replace(/"/g, "'").replace(/,/g,
 }
 
 const parser = new argparse.ArgumentParser({
-    addHelp: true,
+    add_help: true,
     description: 'Create lipid params (from martini lipids itp)'
 });
-parser.addArgument([ '--out', '-o' ], {
+parser.add_argument('--out', '-o', {
     help: 'Generated lipid params output path, if not given printed to stdout'
 });
-parser.addArgument([ '--forceDownload', '-f' ], {
-    action: 'storeTrue',
+parser.add_argument('--forceDownload', '-f', {
+    action: 'store_true',
     help: 'Force download of martini lipids itp'
 });
 interface Args {
     out: string
     forceDownload: boolean
 }
-const args: Args = parser.parseArgs();
+const args: Args = parser.parse_args();
 
 const FORCE_DOWNLOAD = args.forceDownload;
 

+ 15 - 15
src/cli/structure-info/model.ts

@@ -63,7 +63,7 @@ export function printSecStructure(model: Model) {
     const count = residues._rowCount;
     let rI = 0;
     while (rI < count) {
-        let start = rI;
+        const start = rI;
         while (rI < count && key[start] === key[rI]) rI++;
         rI--;
 
@@ -230,21 +230,21 @@ async function runFile(filename: string, args: Args) {
 }
 
 const parser = new argparse.ArgumentParser({
-    addHelp: true,
+    add_help: true,
     description: 'Print info about a structure, mainly to test and showcase the mol-model module'
 });
-parser.addArgument(['--download', '-d'], { help: 'Pdb entry id' });
-parser.addArgument(['--file', '-f'], { help: 'filename' });
-
-parser.addArgument(['--models'], { help: 'print models info', action: 'storeTrue' });
-parser.addArgument(['--seq'], { help: 'print sequence', action: 'storeTrue' });
-parser.addArgument(['--units'], { help: 'print units', action: 'storeTrue' });
-parser.addArgument(['--sym'], { help: 'print symmetry', action: 'storeTrue' });
-parser.addArgument(['--rings'], { help: 'print rings', action: 'storeTrue' });
-parser.addArgument(['--intraBonds'], { help: 'print intra unit bonds', action: 'storeTrue' });
-parser.addArgument(['--interBonds'], { help: 'print inter unit bonds', action: 'storeTrue' });
-parser.addArgument(['--mod'], { help: 'print modified residues', action: 'storeTrue' });
-parser.addArgument(['--sec'], { help: 'print secoundary structure', action: 'storeTrue' });
+parser.add_argument('--download', '-d', { help: 'Pdb entry id' });
+parser.add_argument('--file', '-f', { help: 'filename' });
+
+parser.add_argument('--models', { help: 'print models info', action: 'store_true' });
+parser.add_argument('--seq', { help: 'print sequence', action: 'store_true' });
+parser.add_argument('--units', { help: 'print units', action: 'store_true' });
+parser.add_argument('--sym', { help: 'print symmetry', action: 'store_true' });
+parser.add_argument('--rings', { help: 'print rings', action: 'store_true' });
+parser.add_argument('--intraBonds', { help: 'print intra unit bonds', action: 'store_true' });
+parser.add_argument('--interBonds', { help: 'print inter unit bonds', action: 'store_true' });
+parser.add_argument('--mod', { help: 'print modified residues', action: 'store_true' });
+parser.add_argument('--sec', { help: 'print secoundary structure', action: 'store_true' });
 interface Args {
     download?: string,
     file?: string,
@@ -260,7 +260,7 @@ interface Args {
     mod?: boolean,
     sec?: boolean,
 }
-const args: Args = parser.parseArgs();
+const args: Args = parser.parse_args();
 
 if (args.download) runDL(args.download, args);
 else if (args.file) runFile(args.file, args);

+ 5 - 5
src/cli/structure-info/volume.ts

@@ -38,7 +38,7 @@ function print(volume: Volume) {
 }
 
 async function doMesh(volume: Volume, filename: string) {
-    const mesh = await Task.create('', runtime => createVolumeIsosurfaceMesh({ runtime }, volume, Theme.createEmpty(), { isoValue: Volume.IsoValue.absolute(1.5) } )).run();
+    const mesh = await Task.create('', runtime => createVolumeIsosurfaceMesh({ runtime }, volume, Theme.createEmpty(), { isoValue: Volume.IsoValue.absolute(1.5) })).run();
     console.log({ vc: mesh.vertexCount, tc: mesh.triangleCount });
 
     // Export the mesh in OBJ format.
@@ -75,13 +75,13 @@ async function run(url: string, meshFilename: string) {
 }
 
 const parser = new argparse.ArgumentParser({
-    addHelp: true,
+    add_help: true,
     description: 'Info about VolumeData from mol-model module'
 });
-parser.addArgument([ '--emdb', '-e' ], {
+parser.add_argument('--emdb', '-e', {
     help: 'EMDB id, for example 8116',
 });
-parser.addArgument([ '--mesh' ], {
+parser.add_argument('--mesh', {
     help: 'Mesh filename',
     required: true
 });
@@ -89,6 +89,6 @@ interface Args {
     emdb?: string,
     mesh: string
 }
-const args: Args = parser.parseArgs();
+const args: Args = parser.parse_args();
 
 run(`https://ds.litemol.org/em/emd-${args.emdb}/cell?detail=4`, args.mesh);

+ 1 - 1
src/examples/domain-annotation-server/server.ts

@@ -15,7 +15,7 @@ async function getMappings(id: string) {
 };
 
 
-let PORT = process.env.port || 1338;
+const PORT = process.env.port || 1338;
 
 const app = express();
 

+ 1 - 1
src/examples/lighting/index.ts

@@ -105,7 +105,7 @@ class LightingDemo {
                 ...this.plugin.canvas3d!.props.postprocessing,
                 ...props.postprocessing
             },
-        }});
+        } });
     }
 
     async load({ url, format = 'mmcif', isBinary = true, assemblyId = '' }: LoadParams, radius: number, bias: number) {

+ 32 - 13
src/extensions/anvil/algorithm.ts

@@ -41,20 +41,32 @@ interface ANVILContext {
 export const ANVILParams = {
     numberOfSpherePoints: PD.Numeric(175, { min: 35, max: 700, step: 1 }, { description: 'Number of spheres/directions to test for membrane placement. Original value is 350.' }),
     stepSize: PD.Numeric(1, { min: 0.25, max: 4, step: 0.25 }, { description: 'Thickness of membrane slices that will be tested' }),
-    minThickness: PD.Numeric(20, { min: 10, max: 30, step: 1}, { description: 'Minimum membrane thickness used during refinement' }),
-    maxThickness: PD.Numeric(40, { min: 30, max: 50, step: 1}, { description: 'Maximum membrane thickness used during refinement' }),
+    minThickness: PD.Numeric(20, { min: 10, max: 30, step: 1 }, { description: 'Minimum membrane thickness used during refinement' }),
+    maxThickness: PD.Numeric(40, { min: 30, max: 50, step: 1 }, { description: 'Maximum membrane thickness used during refinement' }),
     asaCutoff: PD.Numeric(40, { min: 10, max: 100, step: 1 }, { description: 'Relative ASA cutoff above which residues will be considered' }),
-    adjust: PD.Numeric(14, { min: 0, max: 30, step: 1 }, { description: 'Minimum length of membrane-spanning regions (original values: 14 for alpha-helices and 5 for beta sheets). Set to 0 to not optimize membrane thickness.' })
+    adjust: PD.Numeric(14, { min: 0, max: 30, step: 1 }, { description: 'Minimum length of membrane-spanning regions (original values: 14 for alpha-helices and 5 for beta sheets). Set to 0 to not optimize membrane thickness.' }),
+    tmdetDefinition: PD.Boolean(false, { description: `Use TMDET's classification of membrane-favoring amino acids. TMDET's classification shows better performance on porins and other beta-barrel structures.` })
 };
 export type ANVILParams = typeof ANVILParams
 export type ANVILProps = PD.Values<ANVILParams>
 
+/** ANVIL-specific (not general) definition of membrane-favoring amino acids */
+const ANVIL_DEFINITION = new Set(['ALA', 'CYS', 'GLY', 'HIS', 'ILE', 'LEU', 'MET', 'PHE', 'SER', 'TRP', 'VAL']);
+/** TMDET-specific (not general) definition of membrane-favoring amino acids */
+const TMDET_DEFINITION = new Set(['LEU', 'ILE', 'VAL', 'PHE', 'MET', 'GLY', 'TRP', 'TYR']);
+
 /**
  * Implements:
  * Membrane positioning for high- and low-resolution protein structures through a binary classification approach
  * Guillaume Postic, Yassine Ghouzam, Vincent Guiraud, and Jean-Christophe Gelly
  * Protein Engineering, Design & Selection, 2015, 1–5
  * doi: 10.1093/protein/gzv063
+ *
+ * ANVIL is derived from TMDET, the corresponding classification of hydrophobic amino acids is provided as optional parameter:
+ * Gabor E. Tusnady, Zsuzsanna Dosztanyi and Istvan Simon
+ * Transmembrane proteins in the Protein Data Bank: identification and classification
+ * Bioinformatics, 2004, 2964-2972
+ * doi: 10.1093/bioinformatics/bth340
  */
 export function computeANVIL(structure: Structure, props: ANVILProps) {
     return Task.create('Compute Membrane Orientation', async runtime => {
@@ -87,6 +99,11 @@ async function initialize(structure: Structure, props: ANVILProps, accessibleSur
     const offsets = new Array<number>();
     const exposed = new Array<number>();
     const hydrophobic = new Array<boolean>();
+    const definition = props.tmdetDefinition ? TMDET_DEFINITION : ANVIL_DEFINITION;
+
+    function isPartOfEntity(l: StructureElement.Location): boolean {
+        return !Unit.isAtomic(l.unit) ? notAtomic() : l.unit.model.atomicHierarchy.residues.label_seq_id.valueKind(l.unit.residueIndex[l.element]) === 0;
+    }
 
     const vec = v3zero();
     for (let i = 0, il = structure.units.length; i < il; ++i) {
@@ -98,8 +115,8 @@ async function initialize(structure: Structure, props: ANVILProps, accessibleSur
             const eI = elements[j];
             l.element = eI;
 
-            // consider only amino acids
-            if (getElementMoleculeType(unit, eI) !== MoleculeType.Protein) {
+            // consider only amino acids in chains
+            if (getElementMoleculeType(unit, eI) !== MoleculeType.Protein || !isPartOfEntity(l)) {
                 continue;
             }
 
@@ -121,7 +138,7 @@ async function initialize(structure: Structure, props: ANVILProps, accessibleSur
             offsets.push(structure.serialMapping.getSerialIndex(l.unit, l.element));
             if (AccessibleSurfaceArea.getValue(l, accessibleSurfaceArea) / MaxAsa[label_comp_id(l)] > asaCutoff) {
                 exposed.push(structure.serialMapping.getSerialIndex(l.unit, l.element));
-                hydrophobic.push(isHydrophobic(label_comp_id(l)));
+                hydrophobic.push(isHydrophobic(definition, label_comp_id(l)));
             }
         }
     }
@@ -344,7 +361,7 @@ function membraneSegments(ctx: ANVILContext, membrane: MembraneCandidate): Array
     // collect all residues in membrane layer
     for (let k = 0, kl = offsets.length; k < kl; k++) {
         const unit = units[unitIndices[offsets[k]]];
-        if (!Unit.isAtomic(unit)) throw 'Property only available for atomic models.';
+        if (!Unit.isAtomic(unit)) notAtomic();
         const elementIndex = elementIndices[offsets[k]];
 
         authAsymId = unit.model.atomicHierarchy.chains.auth_asym_id.value(unit.chainIndex[elementIndex]);
@@ -365,7 +382,7 @@ function membraneSegments(ctx: ANVILContext, membrane: MembraneCandidate): Array
 
     for (let k = 0, kl = offsets.length; k < kl; k++) {
         const unit = units[unitIndices[offsets[k]]];
-        if (!Unit.isAtomic(unit)) throw 'Property only available for atomic models.';
+        if (!Unit.isAtomic(unit)) notAtomic();
         const elementIndex = elementIndices[offsets[k]];
 
         authAsymId = unit.model.atomicHierarchy.chains.auth_asym_id.value(unit.chainIndex[elementIndex]);
@@ -428,6 +445,10 @@ function membraneSegments(ctx: ANVILContext, membrane: MembraneCandidate): Array
     return refinedSegments;
 }
 
+function notAtomic(): never {
+    throw new Error('Property only available for atomic models.');
+}
+
 /** Filter for membrane residues and calculate the final extent of the membrane layer */
 function adjustExtent(ctx: ANVILContext, membrane: MembraneCandidate, centroid: Vec3): number {
     const { offsets, structure } = ctx;
@@ -566,11 +587,9 @@ namespace HphobHphil {
     }
 }
 
-/** ANVIL-specific (not general) definition of membrane-favoring amino acids */
-const HYDROPHOBIC_AMINO_ACIDS = new Set(['ALA', 'CYS', 'GLY', 'HIS', 'ILE', 'LEU', 'MET', 'PHE', 'SER', 'TRP', 'VAL']);
-/** Returns true if ANVIL considers this as amino acid that favors being embedded in a membrane */
-export function isHydrophobic(label_comp_id: string): boolean {
-    return HYDROPHOBIC_AMINO_ACIDS.has(label_comp_id);
+/** Returns true if the definition considers this as membrane-favoring amino acid */
+export function isHydrophobic(definition: Set<string>, label_comp_id: string): boolean {
+    return definition.has(label_comp_id);
 }
 
 /** Accessible surface area used for normalization. ANVIL uses 'Total-Side REL' values from NACCESS, from: Hubbard, S. J., & Thornton, J. M. (1993). naccess. Computer Program, Department of Biochemistry and Molecular Biology, University College London, 2(1). */

+ 1 - 1
src/extensions/anvil/behavior.ts

@@ -52,7 +52,7 @@ export const ANVILMembraneOrientation = PluginBehavior.create<{ autoAttach: bool
         }
 
         update(p: { autoAttach: boolean }) {
-            let updated = this.params.autoAttach !== p.autoAttach;
+            const updated = this.params.autoAttach !== p.autoAttach;
             this.params.autoAttach = p.autoAttach;
             this.ctx.customStructureProperties.setDefaultAutoAttach(this.provider.descriptor.name, this.params.autoAttach);
             return updated;

+ 2 - 2
src/extensions/cellpack/color/generate.ts

@@ -33,7 +33,7 @@ export function CellPackGenerateColorTheme(ctx: ThemeDataContext, props: PD.Valu
 
     if (ctx.structure && info) {
         const colors = distinctColors(info.packingsCount);
-        let hcl = Hcl.fromColor(Hcl(), colors[info.packingIndex]);
+        const hcl = Hcl.fromColor(Hcl(), colors[info.packingIndex]);
 
         const hue = [Math.max(0, hcl[0] - 35), Math.min(360, hcl[0] + 35)] as [number, number];
 
@@ -48,7 +48,7 @@ export function CellPackGenerateColorTheme(ctx: ThemeDataContext, props: PD.Valu
                 hue, chroma: [30, 80], luminance: [15, 85],
                 clusteringStepCount: 50, minSampleCount: 800, maxCount: 75
             }
-        }}, { minLabel: 'Min', maxLabel: 'Max' });
+        } }, { minLabel: 'Min', maxLabel: 'Max' });
         legend = palette.legend;
         const modelColor = new Map<number, Color>();
         for (let i = 0, il = models.length; i < il; ++i) {

+ 2 - 2
src/extensions/cellpack/curve.ts

@@ -49,7 +49,7 @@ function ResampleControlPoints(points: NumberArray, segmentLength: number) {
     // controlPoints.Insert(0, controlPoints[0] + (controlPoints[0] - controlPoints[1]) / 2.0f);
     // controlPoints.Add(controlPoints[nP - 1] + (controlPoints[nP - 1] - controlPoints[nP - 2]) / 2.0f);
 
-    let resampledControlPoints: Vec3[] = [];
+    const resampledControlPoints: Vec3[] = [];
     // resampledControlPoints.Add(controlPoints[0]);
     // resampledControlPoints.Add(controlPoints[1]);
 
@@ -211,7 +211,7 @@ export function getMatFromResamplePoints(points: NumberArray, segmentLength: num
         if (d >= segmentLength) {
             // use twist or random?
             const quat = Quat.rotationTo(Quat.zero(), Vec3.create(0, 0, 1), frames[i].t); // Quat.rotationTo(Quat.zero(), Vec3.create(0,0,1),new_normal[i]);//Quat.rotationTo(Quat.zero(), Vec3.create(0,0,1),direction);new_normal
-            const rq = Quat.setAxisAngle(Quat.zero(), frames[i].t, Math.random() * 3.60 ); // Quat.setAxisAngle(Quat.zero(),direction, Math.random()*3.60 );//Quat.identity();//
+            const rq = Quat.setAxisAngle(Quat.zero(), frames[i].t, Math.random() * 3.60); // Quat.setAxisAngle(Quat.zero(),direction, Math.random()*3.60 );//Quat.identity();//
             const m = Mat4.fromQuat(Mat4.zero(), Quat.multiply(Quat.zero(), rq, quat)); // Mat4.fromQuat(Mat4.zero(),Quat.multiply(Quat.zero(),quat1,quat2));//Mat4.fromQuat(Mat4.zero(),quat);//Mat4.identity();//Mat4.fromQuat(Mat4.zero(),Quat.multiply(Quat.zero(),rq,quat));
             // let pos:Vec3 = Vec3.add(Vec3.zero(),pti1,pti)
             // pos = Vec3.scale(pos,pos,1.0/2.0);

+ 5 - 5
src/extensions/cellpack/model.ts

@@ -51,7 +51,7 @@ async function getModel(plugin: PluginContext, id: string, ingredient: Ingredien
     let surface = (ingredient.ingtype) ? (ingredient.ingtype === 'transmembrane') : false;
     if (location === 'surface') surface = true;
     let trajectory = trajCache.get(id);
-    let assets: Asset.Wrapper[] = [];
+    const assets: Asset.Wrapper[] = [];
     if (!trajectory) {
         if (file) {
             if (file.name.endsWith('.cif')) {
@@ -185,7 +185,7 @@ function getCurveTransforms(ingredient: Ingredient) {
             continue;
         }
         // test for resampling
-        let distance: number = Vec3.distance(_points[0], _points[1]);
+        const distance: number = Vec3.distance(_points[0], _points[1]);
         if (distance >= segmentLength + 2.0) {
             console.info(distance);
             resampling = true;
@@ -204,7 +204,7 @@ function getAssembly(name: string, transforms: Mat4[], structure: Structure) {
 
     for (let i = 0, il = transforms.length; i < il; ++i) {
         const id = `${i + 1}`;
-        const op = SymmetryOperator.create(id, transforms[i], { assembly: { id, operId: i, operList: [ id ] } });
+        const op = SymmetryOperator.create(id, transforms[i], { assembly: { id, operId: i, operList: [id] } });
         for (const unit of units) {
             builder.addWithOperator(unit, op);
         }
@@ -417,7 +417,7 @@ export function createStructureFromCellPack(plugin: PluginContext, packing: Cell
         for (const s of structures) {
             if (ctx.shouldUpdate) await ctx.update(`${s.label}`);
             let maxInvariantId = 0;
-            let maxChainGroupId = 0;
+            const maxChainGroupId = 0;
             for (const u of s.units) {
                 const invariantId = u.invariantId + offsetInvariantId;
                 const chainGroupId = u.chainGroupId + offsetChainGroupId;
@@ -430,7 +430,7 @@ export function createStructureFromCellPack(plugin: PluginContext, packing: Cell
 
         if (ctx.shouldUpdate) await ctx.update(`${name} - structure`);
         const structure = Structure.create(units, {label: name + '.' + location});
-        for( let i = 0, il = structure.models.length; i < il; ++i) {
+        for(let i = 0, il = structure.models.length; i < il; ++i) {
             Model.TrajectoryInfo.set(structure.models[i], { size: il, index: i });
         }
         return { structure, assets, colors: colors };

+ 2 - 2
src/extensions/cellpack/state.ts

@@ -261,7 +261,7 @@ const StructureFromAssemblies = PluginStateTransform.BuiltIn({
             // TODO: optimze
             // TODO: think of ways how to fast-track changes to this for animations
             const model = a.data;
-            let initial_structure = Structure.ofModel(model);
+            const initial_structure = Structure.ofModel(model);
             const structures: Structure[] = [];
             let structure: Structure = initial_structure;
             // the list of asambly *?
@@ -283,7 +283,7 @@ const StructureFromAssemblies = PluginStateTransform.BuiltIn({
                     offsetInvariantId += maxInvariantId + 1;
                 }
                 structure = builder.getStructure();
-                for( let i = 0, il = structure.models.length; i < il; ++i) {
+                for(let i = 0, il = structure.models.length; i < il; ++i) {
                     Model.TrajectoryInfo.set(structure.models[i], { size: il, index: i });
                 }
             }

+ 1 - 1
src/extensions/dnatco/confal-pyramids/behavior.ts

@@ -41,7 +41,7 @@ export const DnatcoConfalPyramidsPreset = StructureRepresentationPresetProvider(
 
         let pyramidsRepr;
         if (representations)
-            pyramidsRepr = builder.buildRepresentation(update, pyramids,  { type: ConfalPyramidsRepresentationProvider, typeParams, color: ConfalPyramidsColorThemeProvider }, { tag: 'confal-pyramdis' } );
+            pyramidsRepr = builder.buildRepresentation(update, pyramids,  { type: ConfalPyramidsRepresentationProvider, typeParams, color: ConfalPyramidsColorThemeProvider }, { tag: 'confal-pyramdis' });
 
         await update.commit({ revertOnError: true });
         return  { components: { ...components, pyramids }, representations: { ...representations, pyramidsRepr } };

+ 2 - 2
src/extensions/dnatco/confal-pyramids/color.ts

@@ -165,8 +165,8 @@ export function ConfalPyramidsColorTheme(ctx: ThemeDataContext, props: PD.Values
         legend: TableLegend(iterableToArray(ColorMapping.entries()).map(([conformer, color]) => {
             return [conformer, color] as [string, Color];
         }).concat([
-            [ 'Error', ErrorColor ],
-            [ 'Unknown', DefaultColor ]
+            ['Error', ErrorColor],
+            ['Unknown', DefaultColor]
         ]))
     };
 }

+ 5 - 5
src/extensions/geo-export/glb-exporter.ts

@@ -53,7 +53,7 @@ export class GlbExporter extends MeshExporter<GlbData> {
                 max[j] = Math.max(a[i + j], max[j]);
             }
         }
-        return [ min, max ];
+        return [min, max];
     }
 
     private addBuffer(buffer: ArrayBuffer, componentType: number, type: string, count: number, target: number, min?: any, max?: any, normalized?: boolean) {
@@ -108,7 +108,7 @@ export class GlbExporter extends MeshExporter<GlbData> {
             indexArray = indices!.slice(0, drawCount);
         }
 
-        const [ vertexMin, vertexMax ] = GlbExporter.vec3MinMax(vertexArray);
+        const [vertexMin, vertexMax] = GlbExporter.vec3MinMax(vertexArray);
 
         let vertexBuffer = vertexArray.buffer;
         let normalBuffer = normalArray.buffer;
@@ -273,14 +273,14 @@ export class GlbExporter extends MeshExporter<GlbData> {
             if (padding) {
                 chunk.push(padding.buffer);
             }
-            return [ chunk, 8 + byteLength ];
+            return [chunk, 8 + byteLength];
         };
         const jsonString = JSON.stringify(gltf);
         const jsonBuffer = new Uint8Array(jsonString.length);
         asciiWrite(jsonBuffer, jsonString);
 
-        const [ jsonChunk, jsonChunkLength ] = createChunk(0x4E4F534A, [jsonBuffer.buffer], jsonBuffer.length, 0x20);
-        const [ binaryChunk, binaryChunkLength ] = createChunk(0x004E4942, this.binaryBuffer, binaryBufferLength, 0x00);
+        const [jsonChunk, jsonChunkLength] = createChunk(0x4E4F534A, [jsonBuffer.buffer], jsonBuffer.length, 0x20);
+        const [binaryChunk, binaryChunkLength] = createChunk(0x004E4942, this.binaryBuffer, binaryBufferLength, 0x00);
 
         const glbBufferLength = 12 + jsonChunkLength + binaryChunkLength;
         const header = new ArrayBuffer(12);

+ 2 - 2
src/extensions/geo-export/mesh-exporter.ts

@@ -102,7 +102,7 @@ export abstract class MeshExporter<D extends RenderObjectExportData> implements
         }
         const framebuffer = webgl.namedFramebuffers[GeoExportName];
 
-        const [ width, height ] = colorTexDim;
+        const [width, height] = colorTexDim;
         const colorGrid = new Uint8Array(width * height * 4);
 
         framebuffer.bind();
@@ -357,7 +357,7 @@ export abstract class MeshExporter<D extends RenderObjectExportData> implements
         }
         const framebuffer = webgl.namedFramebuffers[GeoExportName];
 
-        const [ width, height ] = values.uGeoTexDim.ref.value;
+        const [width, height] = values.uGeoTexDim.ref.value;
         const vertices = new Float32Array(width * height * 4);
         const normals = new Float32Array(width * height * 4);
         const groups = webgl.isWebGL2 ? new Uint8Array(width * height * 4) : new Float32Array(width * height * 4);

+ 1 - 1
src/extensions/pdbe/structure-quality-report/behavior.ts

@@ -52,7 +52,7 @@ export const PDBeStructureQualityReport = PluginBehavior.create<{ autoAttach: bo
         }
 
         update(p: { autoAttach: boolean, showTooltip: boolean }) {
-            let updated = this.params.autoAttach !== p.autoAttach;
+            const updated = this.params.autoAttach !== p.autoAttach;
             this.params.autoAttach = p.autoAttach;
             this.params.showTooltip = p.showTooltip;
             this.ctx.customModelProperties.setDefaultAutoAttach(this.provider.descriptor.name, this.params.autoAttach);

+ 1 - 1
src/extensions/pdbe/structure-quality-report/prop.ts

@@ -73,7 +73,7 @@ namespace StructureQualityReport {
     }
 
     export function fromCif(ctx: CustomProperty.Context, model: Model, props: StructureQualityReportProps): StructureQualityReport | undefined {
-        let info = PropertyWrapper.tryGetInfoFromCif('pdbe_structure_quality_report', model);
+        const info = PropertyWrapper.tryGetInfoFromCif('pdbe_structure_quality_report', model);
         if (!info) return;
         const data = getCifData(model);
         const issueMap = createIssueMapFromCif(model, data.residues, data.groups);

+ 1 - 1
src/extensions/rcsb/assembly-symmetry/behavior.ts

@@ -47,7 +47,7 @@ export const RCSBAssemblySymmetry = PluginBehavior.create<{ autoAttach: boolean
         }
 
         update(p: { autoAttach: boolean }) {
-            let updated = this.params.autoAttach !== p.autoAttach;
+            const updated = this.params.autoAttach !== p.autoAttach;
             this.params.autoAttach = p.autoAttach;
             this.ctx.customStructureProperties.setDefaultAutoAttach(this.provider.descriptor.name, this.params.autoAttach);
             return updated;

+ 1 - 1
src/extensions/rcsb/assembly-symmetry/prop.ts

@@ -130,7 +130,7 @@ export function getSymmetrySelectParam(structure?: Structure) {
             for (let i = 0, il = assemblySymmetryData.length; i < il; ++i) {
                 const { symbol, kind } = assemblySymmetryData[i];
                 if (symbol !== 'C1') {
-                    options.push([ i, `${i + 1}: ${symbol} ${kind}` ]);
+                    options.push([i, `${i + 1}: ${symbol} ${kind}`]);
                 }
             }
             if (options.length > 1) {

+ 10 - 9
src/extensions/rcsb/graphql/codegen.yml

@@ -1,12 +1,13 @@
 schema: https://data.rcsb.org/graphql
 documents: './src/extensions/rcsb/graphql/symmetry.gql.ts'
 generates:
-  './src/extensions/rcsb/graphql/types.ts':
-    plugins:
-      - add: '/* eslint-disable */'
-      - time
-      - typescript
-      - typescript-operations
-    config:
-      immutableTypes: true
-      skipTypename: true
+    './src/extensions/rcsb/graphql/types.ts':
+        plugins:
+            - add:
+                content: '/* eslint-disable */'
+            - time
+            - typescript
+            - typescript-operations
+        config:
+            immutableTypes: true
+            skipTypename: true

File diff suppressed because it is too large
+ 2861 - 2770
src/extensions/rcsb/graphql/types.ts


+ 1 - 1
src/extensions/rcsb/validation-report/behavior.ts

@@ -63,7 +63,7 @@ export const RCSBValidationReport = PluginBehavior.create<{ autoAttach: boolean,
         }
 
         update(p: { autoAttach: boolean, showTooltip: boolean }) {
-            let updated = this.params.autoAttach !== p.autoAttach;
+            const updated = this.params.autoAttach !== p.autoAttach;
             this.params.autoAttach = p.autoAttach;
             this.params.showTooltip = p.showTooltip;
             this.ctx.customStructureProperties.setDefaultAutoAttach(this.provider.descriptor.name, this.params.autoAttach);

+ 5 - 5
src/extensions/rcsb/validation-report/prop.ts

@@ -208,8 +208,8 @@ function createInterUnitClashes(structure: Structure, clashes: ValidationReport[
 
         for (let i = 0, il = clashes.edgeCount * 2; i < il; ++i) {
             // TODO create lookup
-            let indexA = SortedArray.indexOf(elementsA, a[i]);
-            let indexB = SortedArray.indexOf(elementsB, b[i]);
+            const indexA = SortedArray.indexOf(elementsA, a[i]);
+            const indexB = SortedArray.indexOf(elementsB, b[i]);
 
             if (indexA !== -1 && indexB !== -1) {
                 unitA.conformation.position(a[i], pA);
@@ -250,8 +250,8 @@ function createIntraUnitClashes(unit: Unit.Atomic, clashes: ValidationReport['cl
 
     for (let i = 0, il = edgeCount * 2; i < il; ++i) {
         // TODO create lookup
-        let indexA = SortedArray.indexOf(elements, a[i]);
-        let indexB = SortedArray.indexOf(elements, b[i]);
+        const indexA = SortedArray.indexOf(elements, a[i]);
+        const indexB = SortedArray.indexOf(elements, b[i]);
 
         if (indexA !== -1 && indexB !== -1) {
             unit.conformation.position(a[i], pA);
@@ -431,7 +431,7 @@ function parseValidationReportXml(xml: XMLDocument, model: Model): ValidationRep
 
     const groups = xml.getElementsByTagName('ModelledSubgroup');
     for (let i = 0, il = groups.length; i < il; ++i) {
-        const g = groups[ i ];
+        const g = groups[i];
         const ga = g.attributes;
 
         const pdbx_PDB_model_num = parseInt(getItem(ga, 'model'));

+ 2 - 2
src/extensions/rcsb/validation-report/representation.ts

@@ -125,7 +125,7 @@ function getIntraClashLoci(pickingId: PickingId, structureGroup: StructureGroup,
 }
 
 function eachIntraClash(loci: Loci, structureGroup: StructureGroup, apply: (interval: Interval) => boolean) {
-    let changed = false;
+    const changed = false;
     // TODO
     return changed;
 }
@@ -240,7 +240,7 @@ function getInterClashLoci(pickingId: PickingId, structure: Structure, id: numbe
 }
 
 function eachInterClash(loci: Loci, structure: Structure, apply: (interval: Interval) => boolean) {
-    let changed = false;
+    const changed = false;
     // TODO
     return changed;
 }

+ 4 - 4
src/mol-canvas3d/canvas3d.ts

@@ -230,7 +230,7 @@ interface Canvas3D {
     /** Sets drawPaused = false without starting the built in animation loop */
     resume(): void
     identify(x: number, y: number): PickData | undefined
-    mark(loci: Representation.Loci, action: MarkerAction): void
+    mark(loci: Representation.Loci, action: MarkerAction, noDraw?: boolean): void
     getLoci(pickingId: PickingId | undefined): Representation.Loci
 
     notifyDidDraw: boolean,
@@ -339,7 +339,7 @@ namespace Canvas3D {
             return { loci, repr };
         }
 
-        function mark(reprLoci: Representation.Loci, action: MarkerAction) {
+        function mark(reprLoci: Representation.Loci, action: MarkerAction, noDraw = false) {
             const { repr, loci } = reprLoci;
             let changed = false;
             if (repr) {
@@ -349,7 +349,7 @@ namespace Canvas3D {
                 changed = helper.camera.mark(loci, action) || changed;
                 reprRenderObjects.forEach((_, _repr) => { changed = _repr.mark(loci, action) || changed; });
             }
-            if (changed) {
+            if (changed && !noDraw) {
                 scene.update(void 0, true);
                 helper.handle.scene.update(void 0, true);
                 helper.camera.scene.update(void 0, true);
@@ -732,7 +732,7 @@ namespace Canvas3D {
             resized,
             setProps: (properties, doNotRequestDraw = false) => {
                 const props: PartialCanvas3DProps = typeof properties === 'function'
-                    ? produce(getProps(), properties)
+                    ? produce(getProps(), properties as any)
                     : properties;
 
                 const cameraState: Partial<Camera.Snapshot> = Object.create(null);

+ 3 - 3
src/mol-canvas3d/helper/interaction-events.ts

@@ -149,13 +149,13 @@ export class Canvas3dInteractionHelper {
     }
 
     constructor(private canvasIdentify: Canvas3D['identify'], private getLoci: Canvas3D['getLoci'], private input: InputObserver, private camera: Camera, private maxFps: number = 30) {
-        input.drag.subscribe(({x, y, buttons, button, modifiers }) => {
+        input.drag.subscribe(({ x, y, buttons, button, modifiers }) => {
             this.isInteracting = true;
             // console.log('drag');
             this.drag(x, y, buttons, button, modifiers);
         });
 
-        input.move.subscribe(({x, y, inside, buttons, button, modifiers }) => {
+        input.move.subscribe(({ x, y, inside, buttons, button, modifiers }) => {
             if (!inside || this.isInteracting) return;
             // console.log('move');
             this.move(x, y, buttons, button, modifiers);
@@ -166,7 +166,7 @@ export class Canvas3dInteractionHelper {
             this.leave();
         });
 
-        input.click.subscribe(({x, y, buttons, button, modifiers }) => {
+        input.click.subscribe(({ x, y, buttons, button, modifiers }) => {
             if (this.outsideViewport(x, y)) return;
             // console.log('click');
             this.click(x, y, buttons, button, modifiers);

+ 20 - 20
src/mol-canvas3d/passes/multi-sample.ts

@@ -123,7 +123,7 @@ export class MultiSamplePass {
         //
         // This manual approach to MSAA re-renders the scene once for
         // each sample with camera jitter and accumulates the results.
-        const offsetList = JitterVectors[ Math.max(0, Math.min(props.multiSample.sampleLevel, 5)) ];
+        const offsetList = JitterVectors[Math.max(0, Math.min(props.multiSample.sampleLevel, 5))];
 
         const { x, y, width, height } = camera.viewport;
         const baseSampleWeight = 1.0 / offsetList.length;
@@ -190,7 +190,7 @@ export class MultiSamplePass {
         //
         // This manual approach to MSAA re-renders the scene once for
         // each sample with camera jitter and accumulates the results.
-        const offsetList = JitterVectors[ Math.max(0, Math.min(props.multiSample.sampleLevel, 5)) ];
+        const offsetList = JitterVectors[Math.max(0, Math.min(props.multiSample.sampleLevel, 5))];
 
         if (sampleIndex === -2 || sampleIndex >= offsetList.length) return -2;
 
@@ -244,7 +244,7 @@ export class MultiSamplePass {
                 compose.render();
 
                 sampleIndex += 1;
-                if (sampleIndex >= offsetList.length ) break;
+                if (sampleIndex >= offsetList.length) break;
             }
         }
 
@@ -278,33 +278,33 @@ export class MultiSamplePass {
 
 const JitterVectors = [
     [
-        [ 0, 0 ]
+        [0, 0]
     ],
     [
-        [ 4, 4 ], [ -4, -4 ]
+        [4, 4], [-4, -4]
     ],
     [
-        [ -2, -6 ], [ 6, -2 ], [ -6, 2 ], [ 2, 6 ]
+        [-2, -6], [6, -2], [-6, 2], [2, 6]
     ],
     [
-        [ 1, -3 ], [ -1, 3 ], [ 5, 1 ], [ -3, -5 ],
-        [ -5, 5 ], [ -7, -1 ], [ 3, 7 ], [ 7, -7 ]
+        [1, -3], [-1, 3], [5, 1], [-3, -5],
+        [-5, 5], [-7, -1], [3, 7], [7, -7]
     ],
     [
-        [ 1, 1 ], [ -1, -3 ], [ -3, 2 ], [ 4, -1 ],
-        [ -5, -2 ], [ 2, 5 ], [ 5, 3 ], [ 3, -5 ],
-        [ -2, 6 ], [ 0, -7 ], [ -4, -6 ], [ -6, 4 ],
-        [ -8, 0 ], [ 7, -4 ], [ 6, 7 ], [ -7, -8 ]
+        [1, 1], [-1, -3], [-3, 2], [4, -1],
+        [-5, -2], [2, 5], [5, 3], [3, -5],
+        [-2, 6], [0, -7], [-4, -6], [-6, 4],
+        [-8, 0], [7, -4], [6, 7], [-7, -8]
     ],
     [
-        [ -4, -7 ], [ -7, -5 ], [ -3, -5 ], [ -5, -4 ],
-        [ -1, -4 ], [ -2, -2 ], [ -6, -1 ], [ -4, 0 ],
-        [ -7, 1 ], [ -1, 2 ], [ -6, 3 ], [ -3, 3 ],
-        [ -7, 6 ], [ -3, 6 ], [ -5, 7 ], [ -1, 7 ],
-        [ 5, -7 ], [ 1, -6 ], [ 6, -5 ], [ 4, -4 ],
-        [ 2, -3 ], [ 7, -2 ], [ 1, -1 ], [ 4, -1 ],
-        [ 2, 1 ], [ 6, 2 ], [ 0, 4 ], [ 4, 4 ],
-        [ 2, 5 ], [ 7, 5 ], [ 5, 6 ], [ 3, 7 ]
+        [-4, -7], [-7, -5], [-3, -5], [-5, -4],
+        [-1, -4], [-2, -2], [-6, -1], [-4, 0],
+        [-7, 1], [-1, 2], [-6, 3], [-3, 3],
+        [-7, 6], [-3, 6], [-5, 7], [-1, 7],
+        [5, -7], [1, -6], [6, -5], [4, -4],
+        [2, -3], [7, -2], [1, -1], [4, -1],
+        [2, 1], [6, 2], [0, 4], [4, 4],
+        [2, 5], [7, 5], [5, 6], [3, 7]
     ]
 ];
 

+ 7 - 7
src/mol-canvas3d/passes/postprocessing.ts

@@ -154,10 +154,10 @@ function getSsaoBlurRenderable(ctx: WebGLContext, ssaoDepthTexture: Texture, dir
 }
 
 function getBlurKernel(kernelSize: number): number[] {
-    let sigma = kernelSize / 3.0;
-    let halfKernelSize = Math.floor((kernelSize + 1) / 2);
+    const sigma = kernelSize / 3.0;
+    const halfKernelSize = Math.floor((kernelSize + 1) / 2);
 
-    let kernel = [];
+    const kernel = [];
     for (let x = 0; x < halfKernelSize; x++) {
         kernel.push((1.0 / ((Math.sqrt(2 * Math.PI)) * sigma)) * Math.exp(-x * x / (2 * sigma * sigma)));
     }
@@ -166,7 +166,7 @@ function getBlurKernel(kernelSize: number): number[] {
 }
 
 function getSamples(vectorSamples: Vec3[], nSamples: number): number[] {
-    let samples = [];
+    const samples = [];
     for (let i = 0; i < nSamples; i++) {
         let scale = (i * i + 2.0 * i + 1) / (nSamples * nSamples);
         scale = 0.1 + scale * (1.0 - 0.1);
@@ -241,7 +241,7 @@ function getPostprocessingRenderable(ctx: WebGLContext, colorTexture: Texture, d
 export const PostprocessingParams = {
     occlusion: PD.MappedStatic('on', {
         on: PD.Group({
-            samples: PD.Numeric(32, {min: 1, max: 256, step: 1}),
+            samples: PD.Numeric(32, { min: 1, max: 256, step: 1 }),
             radius: PD.Numeric(5, { min: 0, max: 10, step: 0.1 }, { description: 'Final radius is 2^x.' }),
             bias: PD.Numeric(0.8, { min: 0, max: 3, step: 0.1 }),
             blurKernelSize: PD.Numeric(15, { min: 1, max: 25, step: 2 }),
@@ -314,7 +314,7 @@ export class PostprocessingPass {
 
         this.randomHemisphereVector = [];
         for (let i = 0; i < 256; i++) {
-            let v = Vec3();
+            const v = Vec3();
             v[0] = Math.random() * 2.0 - 1.0;
             v[1] = Math.random() * 2.0 - 1.0;
             v[2] = Math.random();
@@ -376,7 +376,7 @@ export class PostprocessingPass {
         const outlinesEnabled = props.outline.name === 'on';
         const occlusionEnabled = props.occlusion.name === 'on';
 
-        let invProjection = Mat4.identity();
+        const invProjection = Mat4.identity();
         Mat4.invert(invProjection, camera.projection);
 
         if (props.occlusion.name === 'on') {

+ 2 - 2
src/mol-canvas3d/passes/smaa.ts

@@ -25,8 +25,8 @@ import { Viewport } from '../camera/util';
 import { isDebugMode } from '../../mol-util/debug';
 
 export const SmaaParams = {
-    edgeThreshold:PD.Numeric(0.1, { min: 0.05, max: 0.15, step: 0.01 }),
-    maxSearchSteps:PD.Numeric(16, { min: 0, max: 32, step: 1 }),
+    edgeThreshold: PD.Numeric(0.1, { min: 0.05, max: 0.15, step: 0.01 }),
+    maxSearchSteps: PD.Numeric(16, { min: 0, max: 32, step: 1 }),
 };
 export type SmaaProps = PD.Values<typeof SmaaParams>
 

+ 1 - 1
src/mol-data/db/_spec/table.spec.ts

@@ -100,7 +100,7 @@ describe('table', () => {
             n: Column.ofArray({ array: ['row1', 'row2'], schema: Column.Schema.str }),
         });
         const s = { x: Column.Schema.int, y: Column.Schema.int };
-        const picked = Table.pickColumns(s, t, { y: Column.ofArray({ array: [3, 4], schema: Column.Schema.int })});
+        const picked = Table.pickColumns(s, t, { y: Column.ofArray({ array: [3, 4], schema: Column.Schema.int }) });
         expect(picked._columns).toEqual(['x', 'y']);
         expect(picked._rowCount).toEqual(2);
         expect(picked.x.toArray()).toEqual([10, -1]);

+ 3 - 3
src/mol-data/generic/_spec/linked-list.spec.ts

@@ -35,19 +35,19 @@ describe('linked list', () => {
 
     it ('remove', () => {
         const list = create([1, 2, 3, 4]);
-        let fst = list.removeFirst();
+        const fst = list.removeFirst();
         expect(fst).toBe(1);
         expect(list.last!.value).toBe(4);
         expect(list.count).toBe(3);
         expect(toArray(list)).toEqual([2, 3, 4]);
 
-        let last = list.removeLast();
+        const last = list.removeLast();
         expect(last).toBe(4);
         expect(list.last!.value).toBe(3);
         expect(list.count).toBe(2);
         expect(toArray(list)).toEqual([2, 3]);
 
-        let n3 = list.find(3)!;
+        const n3 = list.find(3)!;
         list.remove(n3);
         expect(list.first!.value).toBe(2);
         expect(list.last!.value).toBe(2);

+ 1 - 1
src/mol-data/util/chunked-array.ts

@@ -36,7 +36,7 @@ namespace ChunkedArray {
     }
 
     function allocateNext(array: ChunkedArray<any, any>) {
-        let nextSize = array.growBy * array.elementSize;
+        const nextSize = array.growBy * array.elementSize;
         array.currentSize = nextSize;
         array.currentIndex = 0;
         array.currentChunk = new array.ctor(nextSize);

+ 2 - 2
src/mol-geo/geometry/base.ts

@@ -52,8 +52,8 @@ export namespace BaseGeometry {
         if (!transform) transform = createIdentityTransform();
         const locationIterator = LocationIterator(1, transform.instanceCount.ref.value, 1, () => NullLocation, false, () => false);
         const theme: Theme = {
-            color: UniformColorTheme({}, { value: colorValue}),
-            size: UniformSizeTheme({}, { value: sizeValue})
+            color: UniformColorTheme({}, { value: colorValue }),
+            size: UniformSizeTheme({}, { value: sizeValue })
         };
         return { transform, locationIterator, theme };
     }

+ 1 - 1
src/mol-geo/geometry/cylinders/cylinders.ts

@@ -6,7 +6,7 @@
 
 import { ValueCell } from '../../../mol-util';
 import { Mat4, Vec3, Vec4 } from '../../../mol-math/linear-algebra';
-import { transformPositionArray, GroupMapping, createGroupMapping} from '../../util';
+import { transformPositionArray, GroupMapping, createGroupMapping } from '../../util';
 import { GeometryUtils } from '../geometry';
 import { createColors } from '../color-data';
 import { createMarkers } from '../marker-data';

+ 1 - 1
src/mol-geo/geometry/lines/lines.ts

@@ -6,7 +6,7 @@
 
 import { ValueCell } from '../../../mol-util';
 import { Mat4, Vec3, Vec4 } from '../../../mol-math/linear-algebra';
-import { transformPositionArray, GroupMapping, createGroupMapping} from '../../util';
+import { transformPositionArray, GroupMapping, createGroupMapping } from '../../util';
 import { GeometryUtils } from '../geometry';
 import { createColors } from '../color-data';
 import { createMarkers } from '../marker-data';

+ 33 - 1
src/mol-geo/geometry/marker-data.ts

@@ -17,10 +17,42 @@ export type MarkerData = {
     markerStatus: ValueCell<number>
 }
 
+const MarkerCountLut = new Uint8Array(0x0303 + 1);
+MarkerCountLut[0x0001] = 1;
+MarkerCountLut[0x0002] = 1;
+MarkerCountLut[0x0003] = 1;
+MarkerCountLut[0x0100] = 1;
+MarkerCountLut[0x0200] = 1;
+MarkerCountLut[0x0300] = 1;
+MarkerCountLut[0x0101] = 2;
+MarkerCountLut[0x0201] = 2;
+MarkerCountLut[0x0301] = 2;
+MarkerCountLut[0x0102] = 2;
+MarkerCountLut[0x0202] = 2;
+MarkerCountLut[0x0302] = 2;
+MarkerCountLut[0x0103] = 2;
+MarkerCountLut[0x0203] = 2;
+MarkerCountLut[0x0303] = 2;
+
+/**
+ * Calculates the average number of entries that have any marker flag set.
+ *
+ * For alternative implementations and performance tests see
+ * `src\perf-tests\markers-average.ts`.
+ */
 export function getMarkersAverage(array: Uint8Array, count: number): number {
     if (count === 0) return 0;
+
+    const view = new Uint32Array(array.buffer, 0, array.buffer.byteLength >> 2);
+    const viewEnd = (count - 4) >> 2;
+    const backStart = 4 * viewEnd;
+
     let sum = 0;
-    for (let i = 0; i < count; ++i) {
+    for (let i = 0; i < viewEnd; ++i) {
+        const v = view[i];
+        sum += MarkerCountLut[v & 0xFFFF] + MarkerCountLut[v >> 16];
+    }
+    for (let i = backStart; i < count; ++i) {
         sum += array[i] && 1;
     }
     return sum / count;

+ 1 - 1
src/mol-geo/geometry/mesh/builder/ribbon.ts

@@ -36,7 +36,7 @@ const torsionVector = Vec3();
 export function addRibbon(state: MeshBuilder.State, controlPoints: ArrayLike<number>, normalVectors: ArrayLike<number>, binormalVectors: ArrayLike<number>, linearSegments: number, widthValues: ArrayLike<number>, heightValues: ArrayLike<number>, arrowHeight: number) {
     const { currentGroup, vertices, normals, indices, groups } = state;
 
-    let vertexCount = vertices.elementCount;
+    const vertexCount = vertices.elementCount;
     let offsetLength = 0;
 
     if (arrowHeight > 0) {

+ 1 - 1
src/mol-geo/geometry/mesh/builder/sheet.ts

@@ -85,7 +85,7 @@ function addCap(offset: number, state: MeshBuilder.State, controlPoints: ArrayLi
 export function addSheet(state: MeshBuilder.State, controlPoints: ArrayLike<number>, normalVectors: ArrayLike<number>, binormalVectors: ArrayLike<number>, linearSegments: number, widthValues: ArrayLike<number>, heightValues: ArrayLike<number>, arrowHeight: number, startCap: boolean, endCap: boolean) {
     const { currentGroup, vertices, normals, indices, groups } = state;
 
-    let vertexCount = vertices.elementCount;
+    const vertexCount = vertices.elementCount;
     let offsetLength = 0;
 
     if (arrowHeight > 0) {

+ 2 - 2
src/mol-geo/geometry/mesh/color-smoothing.ts

@@ -39,7 +39,7 @@ export function calcMeshColorSmoothing(input: ColorSmoothingInput, resolution: n
     Vec3.add(gridDim, gridDim, Vec3.create(2, 2, 2));
     const { min } = box;
 
-    const [ xn, yn ] = gridDim;
+    const [xn, yn] = gridDim;
     const { width, height } = getVolumeTexture2dLayout(gridDim);
     // console.log({ width, height, dim });
 
@@ -104,7 +104,7 @@ export function calcMeshColorSmoothing(input: ColorSmoothingInput, resolution: n
                         const d = Math.sqrt(dx * dx + dy * dy + dz * dz);
                         if (d > p) continue;
 
-                        let s = p - d;
+                        const s = p - d;
                         const index = getIndex(xi, yi, zi);
                         data[index] += r * s;
                         data[index + 1] += g * s;

+ 1 - 1
src/mol-geo/geometry/points/points.ts

@@ -6,7 +6,7 @@
 
 import { ValueCell } from '../../../mol-util';
 import { Mat4, Vec3, Vec4 } from '../../../mol-math/linear-algebra';
-import { transformPositionArray, GroupMapping, createGroupMapping} from '../../util';
+import { transformPositionArray, GroupMapping, createGroupMapping } from '../../util';
 import { GeometryUtils } from '../geometry';
 import { createColors } from '../color-data';
 import { createMarkers } from '../marker-data';

+ 1 - 1
src/mol-geo/geometry/size-data.ts

@@ -98,7 +98,7 @@ export function createTextureSize(sizes: TextureImage<Uint8Array>, type: SizeTyp
 
 /** Creates size texture with size for each instance/unit */
 export function createInstanceSize(locationIt: LocationIterator, sizeFn: LocationSize, sizeData?: SizeData): SizeData {
-    const { instanceCount} = locationIt;
+    const { instanceCount } = locationIt;
     const sizes = createTextureImage(Math.max(1, instanceCount), 3, Uint8Array, sizeData && sizeData.tSize.ref.value.array);
     locationIt.reset();
     while (locationIt.hasNext && !locationIt.isNextNewInstance) {

+ 1 - 1
src/mol-geo/geometry/texture-mesh/color-smoothing.ts

@@ -259,7 +259,7 @@ export function calcTextureMeshColorSmoothing(input: ColorSmoothingInput, resolu
     Vec3.add(gridDim, gridDim, Vec3.create(2, 2, 2));
     const { min } = box;
 
-    const [ dx, dy, dz ] = gridDim;
+    const [dx, dy, dz] = gridDim;
     const { texDimX: width, texDimY: height, texCols } = getTexture2dSize(gridDim);
     // console.log({ width, height, texCols, dim, resolution });
 

+ 6 - 6
src/mol-geo/primitive/cylinder.ts

@@ -89,10 +89,10 @@ export function Cylinder(props?: CylinderProps): Primitive {
 
             for (let y = 0; y < heightSegments; ++y) {
                 // we use the index array to access the correct indices
-                const a = indexArray[ y ][ x ];
-                const b = indexArray[ y + 1 ][ x ];
-                const c = indexArray[ y + 1 ][ x + 1 ];
-                const d = indexArray[ y ][ x + 1 ];
+                const a = indexArray[y][x];
+                const b = indexArray[y + 1][x];
+                const c = indexArray[y + 1][x + 1];
+                const d = indexArray[y][x + 1];
 
                 // faces
                 indices.push(a, b, d);
@@ -107,7 +107,7 @@ export function Cylinder(props?: CylinderProps): Primitive {
         const sign = (top === true) ? 1 : - 1;
 
         // save the index of the first center vertex
-        let centerIndexStart = index;
+        const centerIndexStart = index;
 
         // first we generate the center vertex data of the cap.
         // because the geometry needs one set of uvs per face,
@@ -125,7 +125,7 @@ export function Cylinder(props?: CylinderProps): Primitive {
         }
 
         // save the index of the last center vertex
-        let centerIndexEnd = index;
+        const centerIndexEnd = index;
 
         // now we generate the surrounding vertices, normals and uvs
         for (let x = 0; x <= radialSegments; ++x) {

+ 1 - 1
src/mol-geo/primitive/plane.ts

@@ -28,7 +28,7 @@ const plane: Primitive = {
 
 const planeCage: Cage = {
     vertices: plane.vertices,
-    edges: new Uint32Array([ 0, 1,  2, 3,  3, 1,  2, 0 ])
+    edges: new Uint32Array([0, 1,  2, 3,  3, 1,  2, 0])
 };
 
 export function Plane(): Primitive {

+ 3 - 3
src/mol-geo/primitive/polyhedron.ts

@@ -46,9 +46,9 @@ export function Polyhedron(_vertices: ArrayLike<number>, _indices: ArrayLike<num
         // iterate over all faces and apply a subdivison with the given detail value
         for (let i = 0; i < _indices.length; i += 3) {
             // get the vertices of the face
-            Vec3.fromArray(a, _vertices, _indices[ i + 0 ] * 3);
-            Vec3.fromArray(b, _vertices, _indices[ i + 1 ] * 3);
-            Vec3.fromArray(c, _vertices, _indices[ i + 2 ] * 3);
+            Vec3.fromArray(a, _vertices, _indices[i + 0] * 3);
+            Vec3.fromArray(b, _vertices, _indices[i + 1] * 3);
+            Vec3.fromArray(c, _vertices, _indices[i + 2] * 3);
 
             // perform subdivision
             subdivideFace(a, b, c, detail);

+ 1 - 1
src/mol-geo/primitive/torus.ts

@@ -47,7 +47,7 @@ export function Torus(props?: TorusProps): Primitive {
             vertices.push(...vertex);
 
             // normal
-            Vec3.set(center, radius * Math.cos(u), radius * Math.sin(u), 0 );
+            Vec3.set(center, radius * Math.cos(u), radius * Math.sin(u), 0);
             Vec3.sub(normal, vertex, center);
             Vec3.normalize(normal, normal);
             normals.push(...normal);

+ 2 - 2
src/mol-geo/util/marching-cubes/builder.ts

@@ -35,10 +35,10 @@ export function MarchinCubesMeshBuilder(vertexChunkSize: number, mesh?: Mesh): M
     return {
         addVertex: (x: number, y: number, z: number) => {
             ++vertexCount;
-            return ChunkedArray.add3(vertices, x, y, z );
+            return ChunkedArray.add3(vertices, x, y, z);
         },
         addNormal: (x: number, y: number, z: number) => {
-            ChunkedArray.add3(normals, x, y, z );
+            ChunkedArray.add3(normals, x, y, z);
         },
         addGroup: (group: number) => {
             ChunkedArray.add(groups, group);

+ 12 - 12
src/mol-geo/util/marching-cubes/tables.ts

@@ -440,16 +440,16 @@ export const TriTable = [
  * The line between edge 1 and 5 is always drawn as it's on the leading edge
  */
 export const AllowedContours = [
-    [ 0, 4, 4, 4, 2, 0, 0, 0, 2, 2, 0, 0 ], // 1 2 3 4 8 9
-    [ 4, 0, 4, 4, 0, 8, 0, 0, 0, 8, 8, 0 ], // 0 2 3 5 9 10
-    [ 4, 4, 0, 4, 0, 0, 8, 0, 0, 0, 8, 8 ], // 0 1 3 6 10 11
-    [ 4, 4, 4, 0, 0, 0, 0, 1, 1, 0, 0, 1 ], // 0 1 2 7 8 11
-    [ 2, 0, 0, 0, 0, 8, 8, 8, 2, 2, 0, 0 ], // 0 5 6 7 8 9
-    [ 0, 8, 0, 0, 8, 0, 8, 8, 0, 8, 8, 0 ], // And rotate it
-    [ 0, 0, 8, 0, 8, 8, 0, 8, 0, 0, 8, 8 ],
-    [ 0, 0, 0, 1, 8, 8, 8, 0, 1, 0, 0, 1 ],
-    [ 2, 0, 0, 1, 2, 0, 0, 1, 0, 2, 0, 1 ], // 0 3 4 7 9 11
-    [ 2, 8, 0, 0, 2, 8, 0, 0, 2, 0, 8, 0 ], // And rotate some more
-    [ 0, 8, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8 ],
-    [ 0, 0, 8, 1, 0, 0, 8, 1, 1, 0, 8, 0 ]
+    [0, 4, 4, 4, 2, 0, 0, 0, 2, 2, 0, 0], // 1 2 3 4 8 9
+    [4, 0, 4, 4, 0, 8, 0, 0, 0, 8, 8, 0], // 0 2 3 5 9 10
+    [4, 4, 0, 4, 0, 0, 8, 0, 0, 0, 8, 8], // 0 1 3 6 10 11
+    [4, 4, 4, 0, 0, 0, 0, 1, 1, 0, 0, 1], // 0 1 2 7 8 11
+    [2, 0, 0, 0, 0, 8, 8, 8, 2, 2, 0, 0], // 0 5 6 7 8 9
+    [0, 8, 0, 0, 8, 0, 8, 8, 0, 8, 8, 0], // And rotate it
+    [0, 0, 8, 0, 8, 8, 0, 8, 0, 0, 8, 8],
+    [0, 0, 0, 1, 8, 8, 8, 0, 1, 0, 0, 1],
+    [2, 0, 0, 1, 2, 0, 0, 1, 0, 2, 0, 1], // 0 3 4 7 9 11
+    [2, 8, 0, 0, 2, 8, 0, 0, 2, 0, 8, 0], // And rotate some more
+    [0, 8, 8, 0, 0, 8, 8, 0, 0, 8, 0, 8],
+    [0, 0, 8, 1, 0, 0, 8, 1, 1, 0, 8, 0]
 ];

+ 6 - 6
src/mol-gl/_spec/gl.shim.ts

@@ -476,10 +476,10 @@ export function createGl(width: number, height: number, contextAttributes: WebGL
                 // Int arrays
                 case gl.MAX_VIEWPORT_DIMS:
                 case gl.SCISSOR_BOX:
-                    return new Int32Array([ 0, 0, 4096, 4096 ]);
+                    return new Int32Array([0, 0, 4096, 4096]);
                 case gl.VIEWPORT:
                     const { x, y, width, height } = viewport;
-                    return new Int32Array([ x, y, width, height ]);
+                    return new Int32Array([x, y, width, height]);
 
                 // Float arrays
                 case gl.ALIASED_LINE_WIDTH_RANGE:
@@ -487,12 +487,12 @@ export function createGl(width: number, height: number, contextAttributes: WebGL
                 case gl.ALIASED_POINT_SIZE_RANGE:
                     return new Float32Array([0, 255]);
                 case gl.DEPTH_RANGE:
-                    return new Float32Array([ depthRange.zNear, depthRange.zFar ]);
+                    return new Float32Array([depthRange.zNear, depthRange.zFar]);
                 case gl.BLEND_COLOR:
                     return new Float32Array([0, 0, 0, 0]);
                 case gl.COLOR_CLEAR_VALUE:
                     const { r, g, b, a } = colorClearValue;
-                    return new Float32Array([ r, g, b, a ]);
+                    return new Float32Array([r, g, b, a]);
 
                 case gl.COLOR_WRITEMASK:
                     return 0;
@@ -601,7 +601,7 @@ export function createGl(width: number, height: number, contextAttributes: WebGL
             switch (pname) {
                 case gl.SHADER_TYPE: return items[shader as number].type;
                 case gl.COMPILE_STATUS: return true;
-                default: throw `getShaderParameter ${pname}`;
+                default: throw new Error(`getShaderParameter ${pname}`);
             }
         },
         shaderSource: function () { },
@@ -628,7 +628,7 @@ export function createGl(width: number, height: number, contextAttributes: WebGL
                 case gl.DELETE_STATUS: return false;
                 case gl.VALIDATE_STATUS: return true;
                 case gl.ATTACHED_SHADERS: return 2;
-                default: throw `getProgramParameter ${pname}`;
+                default: throw new Error(`getProgramParameter ${pname}`);
             }
         },
         deleteShader: function () { },

+ 2 - 2
src/mol-gl/_spec/renderer.spec.ts

@@ -104,7 +104,7 @@ function createPoints() {
 
 describe('renderer', () => {
     it('basic', () => {
-        const [ width, height ] = [ 32, 32 ];
+        const [width, height] = [32, 32];
         const gl = createGl(width, height, { preserveDrawingBuffer: true });
         const { ctx, renderer } = createRenderer(gl);
 
@@ -123,7 +123,7 @@ describe('renderer', () => {
     });
 
     it('points', async () => {
-        const [ width, height ] = [ 32, 32 ];
+        const [width, height] = [32, 32];
         const gl = createGl(width, height, { preserveDrawingBuffer: true });
         const { ctx } = createRenderer(gl);
         const scene = Scene.create(ctx);

+ 1 - 1
src/mol-gl/webgl/resources.ts

@@ -104,7 +104,7 @@ export function createResources(gl: GLRenderingContext, state: WebGLState, stats
 
     const programCache = createReferenceCache(
         (props: ProgramProps) => {
-            const array = [ props.shaderCode.id ];
+            const array = [props.shaderCode.id];
             Object.keys(props.defineValues).forEach(k => array.push(hashString(k), defineValueHash(props.defineValues[k].ref.value)));
             return hashFnv32a(array).toString();
         },

+ 1 - 1
src/mol-gl/webgl/state.ts

@@ -85,7 +85,7 @@ export function createState(gl: GLRenderingContext): WebGLState {
         currentRenderItemId: -1,
 
         enable: (cap: number) => {
-            if (enabledCapabilities[cap] !== true ) {
+            if (enabledCapabilities[cap] !== true) {
                 gl.enable(cap);
                 enabledCapabilities[cap] = true;
             }

+ 19 - 19
src/mol-io/common/binary-cif/decoder.ts

@@ -80,9 +80,9 @@ function float32(data: Uint8Array) { return view(data, 4, Float32Array); }
 function float64(data: Uint8Array) { return view(data, 8, Float64Array); }
 
 function fixedPoint(data: Int32Array, encoding: Encoding.FixedPoint) {
-    let n = data.length;
-    let output = getFloatArray(encoding.srcType, n);
-    let f = 1 / encoding.factor;
+    const n = data.length;
+    const output = getFloatArray(encoding.srcType, n);
+    const f = 1 / encoding.factor;
     for (let i = 0; i < n; i++) {
         output[i] = f * data[i];
     }
@@ -90,10 +90,10 @@ function fixedPoint(data: Int32Array, encoding: Encoding.FixedPoint) {
 }
 
 function intervalQuantization(data: Int32Array, encoding: Encoding.IntervalQuantization) {
-    let n = data.length;
-    let output = getFloatArray(encoding.srcType, n);
-    let delta = (encoding.max - encoding.min) / (encoding.numSteps - 1);
-    let min = encoding.min;
+    const n = data.length;
+    const output = getFloatArray(encoding.srcType, n);
+    const delta = (encoding.max - encoding.min) / (encoding.numSteps - 1);
+    const min = encoding.min;
     for (let i = 0; i < n; i++) {
         output[i] = min + delta * data[i];
     }
@@ -101,11 +101,11 @@ function intervalQuantization(data: Int32Array, encoding: Encoding.IntervalQuant
 }
 
 function runLength(data: Int32Array, encoding: Encoding.RunLength) {
-    let output = getIntArray(encoding.srcType, encoding.srcSize);
+    const output = getIntArray(encoding.srcType, encoding.srcSize);
     let dataOffset = 0;
     for (let i = 0, il = data.length; i < il; i += 2) {
-        let value = data[i];  // value to be repeated
-        let length = data[i + 1];  // number of repeats
+        const value = data[i];  // value to be repeated
+        const length = data[i + 1];  // number of repeats
         for (let j = 0; j < length; ++j) {
             output[dataOffset++] = value;
         }
@@ -114,8 +114,8 @@ function runLength(data: Int32Array, encoding: Encoding.RunLength) {
 }
 
 function delta(data: (Int8Array | Int16Array | Int32Array), encoding: Encoding.Delta) {
-    let n = data.length;
-    let output = getIntArray(encoding.srcType, n);
+    const n = data.length;
+    const output = getIntArray(encoding.srcType, n);
     if (!n) return data;
     output[0] = data[0] + (encoding.origin | 0);
     for (let i = 1; i < n; ++i) {
@@ -125,10 +125,10 @@ function delta(data: (Int8Array | Int16Array | Int32Array), encoding: Encoding.D
 }
 
 function integerPackingSigned(data: (Int8Array | Int16Array), encoding: Encoding.IntegerPacking) {
-    let upperLimit = encoding.byteCount === 1 ? 0x7F : 0x7FFF;
-    let lowerLimit = -upperLimit - 1;
-    let n = data.length;
-    let output = new Int32Array(encoding.srcSize);
+    const upperLimit = encoding.byteCount === 1 ? 0x7F : 0x7FFF;
+    const lowerLimit = -upperLimit - 1;
+    const n = data.length;
+    const output = new Int32Array(encoding.srcSize);
     let i = 0;
     let j = 0;
     while (i < n) {
@@ -147,9 +147,9 @@ function integerPackingSigned(data: (Int8Array | Int16Array), encoding: Encoding
 }
 
 function integerPackingUnsigned(data: (Int8Array | Int16Array), encoding: Encoding.IntegerPacking) {
-    let upperLimit = encoding.byteCount === 1 ? 0xFF : 0xFFFF;
-    let n = data.length;
-    let output = new Int32Array(encoding.srcSize);
+    const upperLimit = encoding.byteCount === 1 ? 0xFF : 0xFFFF;
+    const n = data.length;
+    const output = new Int32Array(encoding.srcSize);
     let i = 0;
     let j = 0;
     while (i < n) {

+ 2 - 2
src/mol-io/common/binary.ts

@@ -8,8 +8,8 @@
 export const IsNativeEndianLittle = new Uint16Array(new Uint8Array([0x12, 0x34]).buffer)[0] === 0x3412;
 
 export function flipByteOrder(data: Uint8Array, bytes: number) {
-    let buffer = new ArrayBuffer(data.length);
-    let ret = new Uint8Array(buffer);
+    const buffer = new ArrayBuffer(data.length);
+    const ret = new Uint8Array(buffer);
     for (let i = 0, n = data.length; i < n; i += bytes) {
         for (let j = 0; j < bytes; j++) {
             ret[i + bytes - j - 1] = data[i + j];

+ 1 - 1
src/mol-io/common/file-handle.ts

@@ -73,7 +73,7 @@ export namespace FileHandle {
                 console.error('.writeBuffer not implemented for FileHandle.fromBuffer');
                 return Promise.resolve(0);
             },
-            writeBufferSync: (position: number, buffer: SimpleBuffer, length?: number, ) => {
+            writeBufferSync: (position: number, buffer: SimpleBuffer, length?: number,) => {
                 length = defaults(length, buffer.length);
                 console.error('.writeSync not implemented for FileHandle.fromBuffer');
                 return 0;

+ 9 - 9
src/mol-io/common/msgpack/encode.ts

@@ -21,7 +21,7 @@ function encodedSize(value: any) {
 
     // Raw Bytes
     if (type === 'string') {
-        let length = utf8ByteCount(value);
+        const length = utf8ByteCount(value);
         if (length < 0x20) {
             return 1 + length;
         }
@@ -37,7 +37,7 @@ function encodedSize(value: any) {
     }
 
     if (value instanceof Uint8Array) {
-        let length = value.byteLength;
+        const length = value.byteLength;
         if (length < 0x100) {
             return 2 + length;
         }
@@ -89,10 +89,10 @@ function encodedSize(value: any) {
                 size += encodedSize(value[i]);
             }
         } else {
-            let keys = Object.keys(value);
+            const keys = Object.keys(value);
             length = keys.length;
             for (let i = 0; i < length; i++) {
-                let key = keys[i];
+                const key = keys[i];
                 size += encodedSize(key) + encodedSize(value[key]);
             }
         }
@@ -111,11 +111,11 @@ function encodedSize(value: any) {
 }
 
 function encodeInternal(value: any, view: DataView, bytes: Uint8Array, offset: number) {
-    let type = typeof value;
+    const type = typeof value;
 
     // Strings Bytes
     if (type === 'string') {
-        let length = utf8ByteCount(value);
+        const length = utf8ByteCount(value);
         // fix str
         if (length < 0x20) {
             view.setUint8(offset, length | 0xa0);
@@ -146,8 +146,8 @@ function encodeInternal(value: any, view: DataView, bytes: Uint8Array, offset: n
     }
 
     if (value instanceof Uint8Array) {
-        let length = value.byteLength;
-        let bytes = new Uint8Array(view.buffer);
+        const length = value.byteLength;
+        const bytes = new Uint8Array(view.buffer);
         // bin 8
         if (length < 0x100) {
             view.setUint8(offset, 0xc4);
@@ -251,7 +251,7 @@ function encodeInternal(value: any, view: DataView, bytes: Uint8Array, offset: n
     // Container Types
     if (type === 'object') {
         let length: number, size = 0;
-        let isArray = Array.isArray(value);
+        const isArray = Array.isArray(value);
         let keys: string[] | undefined;
 
         if (isArray) {

+ 4 - 4
src/mol-io/common/typed-array.ts

@@ -54,10 +54,10 @@ export function createTypedArray(type: TypedArrayValueType, size: number) {
 }
 
 export function createTypedArrayBufferContext(size: number, type: TypedArrayValueType): TypedArrayBufferContext {
-    let elementByteSize = getElementByteSize(type);
-    let arrayBuffer = new ArrayBuffer(elementByteSize * size);
-    let readBuffer = SimpleBuffer.fromArrayBuffer(arrayBuffer);
-    let valuesBuffer = SimpleBuffer.IsNativeEndianLittle ? arrayBuffer : new ArrayBuffer(elementByteSize * size);
+    const elementByteSize = getElementByteSize(type);
+    const arrayBuffer = new ArrayBuffer(elementByteSize * size);
+    const readBuffer = SimpleBuffer.fromArrayBuffer(arrayBuffer);
+    const valuesBuffer = SimpleBuffer.IsNativeEndianLittle ? arrayBuffer : new ArrayBuffer(elementByteSize * size);
     return {
         type,
         elementByteSize,

+ 7 - 6
src/mol-io/common/utf8.ts

@@ -8,7 +8,7 @@
 
 export function utf8Write(data: Uint8Array, offset: number, str: string) {
     for (let i = 0, l = str.length; i < l; i++) {
-        let codePoint = str.charCodeAt(i);
+        const codePoint = str.charCodeAt(i);
 
         // One byte of UTF-8
         if (codePoint < 0x80) {
@@ -44,7 +44,7 @@ export function utf8Write(data: Uint8Array, offset: number, str: string) {
 }
 
 const __chars = function () {
-    let data: string[] = [];
+    const data: string[] = [];
     for (let i = 0; i < 1024; i++) data[i] = String.fromCharCode(i);
     return data;
 }();
@@ -54,11 +54,12 @@ function throwError(err: string) {
 }
 
 function _utf8Read(data: Uint8Array, offset: number, length: number) {
-    let chars = __chars;
-    let str: string[] | undefined = void 0, chunk: string[] = [], chunkSize = 512, chunkOffset = 0;
+    const chars = __chars;
+    let str: string[] | undefined = void 0, chunkOffset = 0;
+    const chunk: string[] = [], chunkSize = 512;
 
     for (let i = offset, end = offset + length; i < end; i++) {
-        let byte = data[i];
+        const byte = data[i];
         if ((byte & 0x80) === 0x00) {
             // One byte character
             chunk[chunkOffset++] = chars[byte];
@@ -108,7 +109,7 @@ export function utf8Read(data: Uint8Array, offset: number, length: number) {
 export function utf8ByteCount(str: string) {
     let count = 0;
     for (let i = 0, l = str.length; i < l; i++) {
-        let codePoint = str.charCodeAt(i);
+        const codePoint = str.charCodeAt(i);
         if (codePoint < 0x80) {
             count += 1;
             continue;

+ 2 - 2
src/mol-io/reader/_spec/ply.spec.ts

@@ -123,8 +123,8 @@ describe('ply reader', () => {
 
         const face = plyFile.getElement('face') as PlyList;
         if (!face) return;
-        expect(face.value(0)).toEqual({ count: 3, entries: [0, 2, 1]});
-        expect(face.value(1)).toEqual({ count: 3, entries: [3, 5, 4]});
+        expect(face.value(0)).toEqual({ count: 3, entries: [0, 2, 1] });
+        expect(face.value(1)).toEqual({ count: 3, entries: [3, 5, 4] });
 
         expect.assertions(3);
     });

+ 1 - 1
src/mol-io/reader/ccp4/parser.ts

@@ -26,7 +26,7 @@ export async function readCcp4Header(file: FileHandle): Promise<{ header: Ccp4He
 
     // 54  MACHST      Machine stamp indicating machine type which wrote file
     //                 17 and 17 for big-endian or 68 and 65 for little-endian
-    const MACHST = [ buffer.readUInt8(53 * 4), buffer.readUInt8(53 * 4 + 1) ];
+    const MACHST = [buffer.readUInt8(53 * 4), buffer.readUInt8(53 * 4 + 1)];
     let littleEndian = false;
     if (MACHST[0] === 68 && MACHST[1] === 65) {
         littleEndian = true;

+ 1 - 1
src/mol-io/reader/cif/data-model.ts

@@ -37,7 +37,7 @@ export function CifBlock(categoryNames: string[], categories: CifCategories, hea
     return {
         categoryNames, header, categories, saveFrames,
         getField(name: string) {
-            const [ category, field ] = name.split('.');
+            const [category, field] = name.split('.');
             return categories[category].getField(field || '');
         }
     };

+ 1 - 1
src/mol-io/reader/cif/schema/bird.ts

@@ -1,7 +1,7 @@
 /**
  * Copyright (c) 2017-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
- * Code-generated 'BIRD' schema file. Dictionary versions: mmCIF 5.333, IHM 1.12, CARB draft.
+ * Code-generated 'BIRD' schema file. Dictionary versions: mmCIF 5.350, IHM 1.17, CARB draft.
  *
  * @author molstar/ciftools package
  */

+ 2 - 2
src/mol-io/reader/cif/schema/ccd.ts

@@ -1,7 +1,7 @@
 /**
  * Copyright (c) 2017-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
- * Code-generated 'CCD' schema file. Dictionary versions: mmCIF 5.333, IHM 1.12, CARB draft.
+ * Code-generated 'CCD' schema file. Dictionary versions: mmCIF 5.350, IHM 1.17, CARB draft.
  *
  * @author molstar/ciftools package
  */
@@ -352,7 +352,7 @@ export const CCD_Schema = {
         /**
          * This data item contains the descriptor type.
          */
-        type: Aliased<'SMILES_CANNONICAL' | 'SMILES_CANONICAL' | 'SMILES' | 'SMILES' | 'InChI' | 'InChI_MAIN' | 'InChI_MAIN_FORMULA' | 'InChI_MAIN_CONNECT' | 'InChI_MAIN_HATOM' | 'InChI_CHARGE' | 'InChI_STEREO' | 'InChI_ISOTOPE' | 'InChI_FIXEDH' | 'InChI_RECONNECT' | 'InChIKey'>(str),
+        type: Aliased<'SMILES_CANNONICAL' | 'SMILES_CANONICAL' | 'SMILES' | 'InChI' | 'InChI_MAIN' | 'InChI_MAIN_FORMULA' | 'InChI_MAIN_CONNECT' | 'InChI_MAIN_HATOM' | 'InChI_CHARGE' | 'InChI_STEREO' | 'InChI_ISOTOPE' | 'InChI_FIXEDH' | 'InChI_RECONNECT' | 'InChIKey'>(str),
         /**
          * This data item contains the name of the program
          * or library used to compute the descriptor.

+ 68 - 120
src/mol-io/reader/cif/schema/cif-core.ts

@@ -1,7 +1,7 @@
 /**
  * Copyright (c) 2017-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
- * Code-generated 'CifCore' schema file. Dictionary versions: CifCore 3.0.14.
+ * Code-generated 'CifCore' schema file. Dictionary versions: CifCore 3.1.0.
  *
  * @author molstar/ciftools package
  */
@@ -10,8 +10,8 @@ import { Database, Column } from '../../../../mol-data/db';
 
 import Schema = Column.Schema;
 
-const int = Schema.int;
 const float = Schema.float;
+const int = Schema.int;
 const str = Schema.str;
 const Matrix = Schema.Matrix;
 
@@ -21,16 +21,6 @@ export const CifCore_Schema = {
      * the crystal unit cell and their measurement.
      */
     cell: {
-        /**
-         * The number of the formula units in the unit cell as specified
-         * by _chemical_formula.structural, _chemical_formula.moiety or
-         * _chemical_formula.sum.
-         */
-        formula_units_Z: int,
-        /**
-         * Volume of the crystal unit cell.
-         */
-        volume: float,
         /**
          * The angle between the bounding cell axes.
          */
@@ -43,6 +33,12 @@ export const CifCore_Schema = {
          * The angle between the bounding cell axes.
          */
         angle_gamma: float,
+        /**
+         * The number of the formula units in the unit cell as specified
+         * by _chemical_formula.structural, _chemical_formula.moiety or
+         * _chemical_formula.sum.
+         */
+        formula_units_z: int,
         /**
          * The length of each cell axis.
          */
@@ -55,6 +51,10 @@ export const CifCore_Schema = {
          * The length of each cell axis.
          */
         length_c: float,
+        /**
+         * Volume of the crystal unit cell.
+         */
+        volume: float,
     },
     /**
      * The CATEGORY of data items which describe the composition and
@@ -184,12 +184,12 @@ export const CifCore_Schema = {
         crystal_system: str,
         /**
          * The number as assigned in International Tables for Crystallography
-         * Vol A, specifying the proper affine class (i.e. the orientation
+         * Vol. A, specifying the proper affine class (i.e. the orientation
          * preserving affine class) of space groups (crystallographic space
          * group type) to which the space group belongs. This number defines
          * the space group type but not the coordinate system expressed.
          */
-        IT_number: int,
+        it_number: int,
         /**
          * The full international Hermann-Mauguin space-group symbol as
          * defined in Section 2.2.3 and given as the second item of the
@@ -220,7 +220,7 @@ export const CifCore_Schema = {
          * Space-group symmetry, edited by Th. Hahn, 5th ed.
          * Dordrecht: Kluwer Academic Publishers.
          */
-        'name_H-M_full': str,
+        'name_h-m_full': str,
     },
     /**
      * The CATEGORY of data items used to describe symmetry equivalent sites
@@ -340,8 +340,8 @@ export const CifCore_Schema = {
         /**
          * The digital object identifier (DOI) registered to identify
          * the data set publication represented by the current
-         * datablock. This can be used as a unique identifier for
-         * the datablock so long as the code used is a valid DOI
+         * data block. This can be used as a unique identifier for
+         * the data block so long as the code used is a valid DOI
          * (i.e. begins with a valid publisher prefix assigned by a
          * Registration Agency and a suffix guaranteed to be unique
          * by the publisher) and has had its metadata deposited
@@ -354,8 +354,8 @@ export const CifCore_Schema = {
          * structured extensible way. A DOI is an implementation
          * of the Internet concepts of Uniform Resource Name and
          * Universal Resource Locator managed according to the
-         * specifications of the International DOI Foundation (see
-         * http://www.doi.org).
+         * specifications of the International DOI Foundation
+         * (see http://www.doi.org).
          */
         block_doi: str,
     },
@@ -366,13 +366,13 @@ export const CifCore_Schema = {
      */
     database_code: {
         /**
-         * Code assigned by Crystallography Open Database (COD).
+         * Code assigned by the Crystallography Open Database (COD).
          */
-        COD: str,
+        cod: str,
         /**
          * Code assigned by the Cambridge Structural Database.
          */
-        CSD: str,
+        csd: str,
         /**
          * Deposition numbers assigned by the Cambridge Crystallographic
          * Data Centre (CCDC) to files containing structural information
@@ -388,15 +388,15 @@ export const CifCore_Schema = {
         /**
          * Code assigned by the Inorganic Crystal Structure Database.
          */
-        ICSD: str,
+        icsd: str,
         /**
          * Code assigned in the Metals Data File.
          */
-        MDF: str,
+        mdf: str,
         /**
          * Code assigned by the NBS (NIST) Crystal Data Database.
          */
-        NBS: str,
+        nbs: str,
     },
     /**
      * The CATEGORY of data items used to describe atom site information
@@ -511,7 +511,7 @@ export const CifCore_Schema = {
          * a* = the reciprocal-space cell lengths
          * Ref: Fischer, R. X. & Tillmanns, E. (1988). Acta Cryst. C44, 775-776.
          */
-        U_iso_or_equiv: float,
+        u_iso_or_equiv: float,
     },
     /**
      * The CATEGORY of data items used to describe the anisotropic
@@ -537,7 +537,7 @@ export const CifCore_Schema = {
          *
          * The unique elements of the real symmetric matrix are entered by row.
          */
-        U_11: float,
+        u_11: float,
         /**
          * These are the standard anisotropic atomic displacement
          * components in angstroms squared which appear in the
@@ -550,21 +550,7 @@ export const CifCore_Schema = {
          *
          * The unique elements of the real symmetric matrix are entered by row.
          */
-        U: Matrix(3, 3),
-        /**
-         * These are the standard uncertainty values (SU) for the standard
-         * form of the Uij anisotropic atomic displacement components (see
-         * _aniso_UIJ. Because these values are TYPE measurand, the su values
-         * may in practice be auto generated as part of the Uij calculation.
-         */
-        U_11_su: float,
-        /**
-         * These are the standard uncertainty values (SU) for the standard
-         * form of the Uij anisotropic atomic displacement components (see
-         * _aniso_UIJ. Because these values are TYPE measurand, the su values
-         * may in practice be auto generated as part of the Uij calculation.
-         */
-        U_su: Matrix(3, 3),
+        u: Matrix(3, 3),
         /**
          * These are the standard anisotropic atomic displacement
          * components in angstroms squared which appear in the
@@ -577,14 +563,7 @@ export const CifCore_Schema = {
          *
          * The unique elements of the real symmetric matrix are entered by row.
          */
-        U_12: float,
-        /**
-         * These are the standard uncertainty values (SU) for the standard
-         * form of the Uij anisotropic atomic displacement components (see
-         * _aniso_UIJ. Because these values are TYPE measurand, the su values
-         * may in practice be auto generated as part of the Uij calculation.
-         */
-        U_12_su: float,
+        u_12: float,
         /**
          * These are the standard anisotropic atomic displacement
          * components in angstroms squared which appear in the
@@ -597,14 +576,7 @@ export const CifCore_Schema = {
          *
          * The unique elements of the real symmetric matrix are entered by row.
          */
-        U_13: float,
-        /**
-         * These are the standard uncertainty values (SU) for the standard
-         * form of the Uij anisotropic atomic displacement components (see
-         * _aniso_UIJ. Because these values are TYPE measurand, the su values
-         * may in practice be auto generated as part of the Uij calculation.
-         */
-        U_13_su: float,
+        u_13: float,
         /**
          * These are the standard anisotropic atomic displacement
          * components in angstroms squared which appear in the
@@ -617,14 +589,7 @@ export const CifCore_Schema = {
          *
          * The unique elements of the real symmetric matrix are entered by row.
          */
-        U_22: float,
-        /**
-         * These are the standard uncertainty values (SU) for the standard
-         * form of the Uij anisotropic atomic displacement components (see
-         * _aniso_UIJ. Because these values are TYPE measurand, the su values
-         * may in practice be auto generated as part of the Uij calculation.
-         */
-        U_22_su: float,
+        u_22: float,
         /**
          * These are the standard anisotropic atomic displacement
          * components in angstroms squared which appear in the
@@ -637,14 +602,7 @@ export const CifCore_Schema = {
          *
          * The unique elements of the real symmetric matrix are entered by row.
          */
-        U_23: float,
-        /**
-         * These are the standard uncertainty values (SU) for the standard
-         * form of the Uij anisotropic atomic displacement components (see
-         * _aniso_UIJ. Because these values are TYPE measurand, the su values
-         * may in practice be auto generated as part of the Uij calculation.
-         */
-        U_23_su: float,
+        u_23: float,
         /**
          * These are the standard anisotropic atomic displacement
          * components in angstroms squared which appear in the
@@ -657,14 +615,7 @@ export const CifCore_Schema = {
          *
          * The unique elements of the real symmetric matrix are entered by row.
          */
-        U_33: float,
-        /**
-         * These are the standard uncertainty values (SU) for the standard
-         * form of the Uij anisotropic atomic displacement components (see
-         * _aniso_UIJ. Because these values are TYPE measurand, the su values
-         * may in practice be auto generated as part of the Uij calculation.
-         */
-        U_33_su: float,
+        u_33: float,
     },
     /**
      * The CATEGORY of data items used to describe atomic type information
@@ -710,17 +661,14 @@ export const CifCore_Schema = {
 };
 
 export const CifCore_Aliases = {
-    'atom_site_aniso.U': [
-        'atom_site_anisotrop_U',
-    ],
-    'atom_site_aniso.U_su': [
-        'atom_site_aniso_U_esd',
-        'atom_site_anisotrop_U_esd',
+    'cell.formula_units_z': [
+        'cell_formula_units_Z',
     ],
-    'space_group.IT_number': [
+    'space_group.it_number': [
+        'space_group_IT_number',
         'symmetry_Int_Tables_number',
     ],
-    'space_group.name_H-M_full': [
+    'space_group.name_h-m_full': [
         'symmetry_space_group_name_H-M',
     ],
     'space_group_symop.operation_xyz': [
@@ -735,6 +683,21 @@ export const CifCore_Aliases = {
     'geom_bond.distance': [
         'geom_bond_dist',
     ],
+    'database_code.cod': [
+        'database_code_COD',
+    ],
+    'database_code.csd': [
+        'database_code_CSD',
+    ],
+    'database_code.icsd': [
+        'database_code_ICSD',
+    ],
+    'database_code.mdf': [
+        'database_code_MDF',
+    ],
+    'database_code.nbs': [
+        'database_code_NBS',
+    ],
     'atom_site.adp_type': [
         'atom_site_thermal_displace_type',
     ],
@@ -744,51 +707,36 @@ export const CifCore_Aliases = {
     'atom_site.site_symmetry_multiplicity': [
         'atom_site_symmetry_multiplicity',
     ],
+    'atom_site.u_iso_or_equiv': [
+        'atom_site_U_iso_or_equiv',
+    ],
     'atom_site_aniso.label': [
         'atom_site_anisotrop_id',
     ],
-    'atom_site_aniso.U_11': [
+    'atom_site_aniso.u_11': [
+        'atom_site_aniso_U_11',
         'atom_site_anisotrop_U_11',
     ],
-    'atom_site_aniso.U_11_su': [
-        'atom_site_aniso_U_11_esd',
-        'atom_site_anisotrop_U_11_esd',
-    ],
-    'atom_site_aniso.U_12': [
+    'atom_site_aniso.u_12': [
+        'atom_site_aniso_U_12',
         'atom_site_anisotrop_U_12',
     ],
-    'atom_site_aniso.U_12_su': [
-        'atom_site_aniso_U_12_esd',
-        'atom_site_anisotrop_U_12_esd',
-    ],
-    'atom_site_aniso.U_13': [
+    'atom_site_aniso.u_13': [
+        'atom_site_aniso_U_13',
         'atom_site_anisotrop_U_13',
     ],
-    'atom_site_aniso.U_13_su': [
-        'atom_site_aniso_U_13_esd',
-        'atom_site_anisotrop_U_13_esd',
-    ],
-    'atom_site_aniso.U_22': [
+    'atom_site_aniso.u_22': [
+        'atom_site_aniso_U_22',
         'atom_site_anisotrop_U_22',
     ],
-    'atom_site_aniso.U_22_su': [
-        'atom_site_aniso_U_22_esd',
-        'atom_site_anisotrop_U_22_esd',
-    ],
-    'atom_site_aniso.U_23': [
+    'atom_site_aniso.u_23': [
+        'atom_site_aniso_U_23',
         'atom_site_anisotrop_U_23',
     ],
-    'atom_site_aniso.U_23_su': [
-        'atom_site_aniso_U_23_esd',
-        'atom_site_anisotrop_U_23_esd',
-    ],
-    'atom_site_aniso.U_33': [
+    'atom_site_aniso.u_33': [
+        'atom_site_aniso_U_33',
         'atom_site_anisotrop_U_33',
     ],
-    'atom_site_aniso.U_33_su': [
-        'atom_site_aniso_U_33_esd',
-        'atom_site_anisotrop_U_33_esd',
-    ],
 };
 
 export type CifCore_Schema = typeof CifCore_Schema;

+ 72 - 37
src/mol-io/reader/cif/schema/mmcif.ts

@@ -1,7 +1,7 @@
 /**
  * Copyright (c) 2017-2020 mol* contributors, licensed under MIT, See LICENSE file for more info.
  *
- * Code-generated 'mmCIF' schema file. Dictionary versions: mmCIF 5.333, IHM 1.12, CARB draft.
+ * Code-generated 'mmCIF' schema file. Dictionary versions: mmCIF 5.350, IHM 1.17, CARB draft.
  *
  * @author molstar/ciftools package
  */
@@ -29,6 +29,11 @@ export const mmCIF_Schema = {
      * The data items for describing anisotropic atomic
      * displacement factors are only used if the corresponding items
      * are not given in the ATOM_SITE_ANISOTROP category.
+     *
+     * wwPDB recommends wwPDB-assigned residue number, residue ID,
+     * and chain ID, _atom_site.auth_seq_id _atom_site.auth_comp_id, and
+     * _atom_site.auth_asym_id, respectively, to be used for publication
+     * materials.
      */
     atom_site: {
         /**
@@ -808,39 +813,65 @@ export const mmCIF_Schema = {
          */
         pdbx_strand_id: List(',', x => x),
         /**
-         * Chemical sequence expressed as string of one-letter
-         * amino acid codes. Modifications and non-standard
-         * amino acids are coded as X.
+         * Sequence of protein or nucleic acid polymer in standard one-letter
+         * codes of amino acids or nucleotides. Non-standard amino
+         * acids/nucleotides are represented by their Chemical
+         * Component Dictionary (CCD) codes in
+         * parenthesis. Deoxynucleotides are represented by the
+         * specially-assigned 2-letter CCD codes in parenthesis,
+         * with 'D' prefix added to their ribonucleotide
+         * counterparts. For hybrid polymer, each residue is
+         * represented by the code of its individual type. A
+         * cyclic polymer is represented in linear sequence from
+         * the chosen start to end.
+         *
+         * A for Alanine or Adenosine-5'-monophosphate
+         * C for Cysteine or Cytidine-5'-monophosphate
+         * D for Aspartic acid
+         * E for Glutamic acid
+         * F for Phenylalanine
+         * G for Glycine or Guanosine-5'-monophosphate
+         * H for Histidine
+         * I for Isoleucine or Inosinic Acid
+         * L for Leucine
+         * K for Lysine
+         * M for Methionine
+         * N for Asparagine  or Unknown ribonucleotide
+         * O for Pyrrolysine
+         * P for Proline
+         * Q for Glutamine
+         * R for Arginine
+         * S for Serine
+         * T for Threonine
+         * U for Selenocysteine or Uridine-5'-monophosphate
+         * V for Valine
+         * W for Tryptophan
+         * Y for Tyrosine
+         * (DA) for 2'-deoxyadenosine-5'-monophosphate
+         * (DC) for 2'-deoxycytidine-5'-monophosphate
+         * (DG) for 2'-deoxyguanosine-5'-monophosphate
+         * (DT) for Thymidine-5'-monophosphate
+         * (MSE) for Selenomethionine
+         * (SEP) for Phosphoserine
+         * (PTO) for Phosphothreonine
+         * (PTR) for Phosphotyrosine
+         * (PCA) for Pyroglutamic acid
+         * (UNK) for Unknown amino acid
+         * (ACE) for Acetylation cap
+         * (NH2) for Amidation cap
          */
         pdbx_seq_one_letter_code: str,
         /**
-         * Cannonical chemical sequence expressed as string of
-         * one-letter amino acid codes. Modifications are coded
-         * as the parent amino acid where possible.
-         *
-         * A  for alanine or adenine
-         * B  for ambiguous asparagine/aspartic-acid
-         * R  for arginine
-         * N  for asparagine
-         * D  for aspartic-acid
-         * C  for cysteine or cystine or cytosine
-         * Q  for glutamine
-         * E  for glutamic-acid
-         * Z  for ambiguous glutamine/glutamic acid
-         * G  for glycine or guanine
-         * H  for histidine
-         * I  for isoleucine
-         * L  for leucine
-         * K  for lysine
-         * M  for methionine
-         * F  for phenylalanine
-         * P  for proline
-         * S  for serine
-         * T  for threonine or thymine
-         * W  for tryptophan
-         * Y  for tyrosine
-         * V  for valine
-         * U  for uracil
+         * Canonical sequence of protein or nucleic acid polymer in standard
+         * one-letter codes of amino acids or nucleotides,
+         * corresponding to the sequence in
+         * _entity_poly.pdbx_seq_one_letter_code. Non-standard
+         * amino acids/nucleotides are represented by the codes of
+         * their parents if parent is specified in
+         * _chem_comp.mon_nstd_parent_comp_id, or by letter 'X' if
+         * parent is not specified. Deoxynucleotides are
+         * represented by their canonical one-letter codes of A,
+         * C, G, or T.
          */
         pdbx_seq_one_letter_code_can: str,
         /**
@@ -1024,7 +1055,7 @@ export const mmCIF_Schema = {
          * This data item is a pointer to _struct_conf_type.id in the
          * STRUCT_CONF_TYPE category.
          */
-        conf_type_id: Aliased<'HELX_P' | 'HELX_OT_P' | 'HELX_RH_P' | 'HELX_RH_OT_P' | 'HELX_RH_AL_P' | 'HELX_RH_GA_P' | 'HELX_RH_OM_P' | 'HELX_RH_PI_P' | 'HELX_RH_27_P' | 'HELX_RH_3T_P' | 'HELX_RH_PP_P' | 'HELX_LH_P' | 'HELX_LH_OT_P' | 'HELX_LH_AL_P' | 'HELX_LH_GA_P' | 'HELX_LH_OM_P' | 'HELX_LH_PI_P' | 'HELX_LH_27_P' | 'HELX_LH_3T_P' | 'HELX_LH_PP_P' | 'HELX_N' | 'HELX_OT_N' | 'HELX_RH_N' | 'HELX_RH_OT_N' | 'HELX_RH_A_N' | 'HELX_RH_B_N' | 'HELX_RH_Z_N' | 'HELX_LH_N' | 'HELX_LH_OT_N' | 'HELX_LH_A_N' | 'HELX_LH_B_N' | 'HELX_LH_Z_N' | 'TURN_P' | 'TURN_OT_P' | 'TURN_TY1_P' | 'TURN_TY1P_P' | 'TURN_TY2_P' | 'TURN_TY2P_P' | 'TURN_TY3_P' | 'TURN_TY3P_P' | 'STRN'>(str),
+        conf_type_id: Aliased<'BEND' | 'HELX_P' | 'HELX_OT_P' | 'HELX_RH_P' | 'HELX_RH_OT_P' | 'HELX_RH_AL_P' | 'HELX_RH_GA_P' | 'HELX_RH_OM_P' | 'HELX_RH_PI_P' | 'HELX_RH_27_P' | 'HELX_RH_3T_P' | 'HELX_RH_PP_P' | 'HELX_LH_P' | 'HELX_LH_OT_P' | 'HELX_LH_AL_P' | 'HELX_LH_GA_P' | 'HELX_LH_OM_P' | 'HELX_LH_PI_P' | 'HELX_LH_27_P' | 'HELX_LH_3T_P' | 'HELX_LH_PP_P' | 'HELX_N' | 'HELX_OT_N' | 'HELX_RH_N' | 'HELX_RH_OT_N' | 'HELX_RH_A_N' | 'HELX_RH_B_N' | 'HELX_RH_Z_N' | 'HELX_LH_N' | 'HELX_LH_OT_N' | 'HELX_LH_A_N' | 'HELX_LH_B_N' | 'HELX_LH_Z_N' | 'TURN_P' | 'TURN_OT_P' | 'TURN_TY1_P' | 'TURN_TY1P_P' | 'TURN_TY2_P' | 'TURN_TY2P_P' | 'TURN_TY3_P' | 'TURN_TY3P_P' | 'STRN' | 'OTHER'>(str),
         /**
          * A description of special aspects of the conformation assignment.
          */
@@ -1759,7 +1790,7 @@ export const mmCIF_Schema = {
         /**
          * Code for status of NMR constraints file.
          */
-        status_code_mr: Aliased<'PROC' | 'WAIT' | 'REL' | 'HOLD' | 'HPUB' | 'OBS' | 'WDRN' | 'AUTH' | 'POLC' | 'REPL' | 'RMVD'>(str),
+        status_code_mr: Aliased<'PROC' | 'WAIT' | 'REL' | 'HOLD' | 'HPUB' | 'OBS' | 'WDRN' | 'AUTH' | 'POLC' | 'REPL' | 'AUCO' | 'RMVD'>(str),
         /**
          * The value of _pdbx_database_status.entry_id identifies the data block.
          */
@@ -1785,7 +1816,7 @@ export const mmCIF_Schema = {
         /**
          * Code for status of chemical shift data file.
          */
-        status_code_cs: Aliased<'PROC' | 'WAIT' | 'AUTH' | 'POLC' | 'REPL' | 'REL' | 'HOLD' | 'HPUB' | 'OBS' | 'RMVD' | 'WDRN'>(str),
+        status_code_cs: Aliased<'PROC' | 'WAIT' | 'AUTH' | 'POLC' | 'REPL' | 'AUCO' | 'REL' | 'HOLD' | 'HPUB' | 'OBS' | 'RMVD' | 'WDRN'>(str),
         /**
          * The methods development category in which this
          * entry has been placed.
@@ -1869,6 +1900,10 @@ export const mmCIF_Schema = {
          */
         content_type: Aliased<'minimized average structure' | 'representative structure' | 'ensemble' | 'derivative structure' | 'native structure' | 'associated EM volume' | 'other EM volume' | 'associated NMR restraints' | 'associated structure factors' | 'associated SAS data' | 'protein target sequence and/or protocol data' | 'split' | 're-refinement' | 'complete structure' | 'unspecified' | 'other'>(str),
     },
+    /**
+     * The PDBX_ENTITY_NONPOLY category provides a mapping between
+     * entity and the nonpolymer component
+     */
     pdbx_entity_nonpoly: {
         /**
          * This data item is a pointer to _entity.id in the ENTITY category.
@@ -2404,7 +2439,7 @@ export const mmCIF_Schema = {
      */
     pdbx_molecule_features: {
         /**
-         * The value of _pdbx_molecule_features.prd_id is the PDB accession code for this
+         * The value of _pdbx_molecule_features.prd_id is the accession code for this
          * reference molecule.
          */
         prd_id: str,
@@ -3603,7 +3638,7 @@ export const mmCIF_Schema = {
         /**
          * The name of the database containing the dataset entry.
          */
-        db_name: Aliased<'PDB' | 'PDB-Dev' | 'BMRB' | 'EMDB' | 'EMPIAR' | 'SASBDB' | 'PRIDE' | 'MODEL ARCHIVE' | 'MASSIVE' | 'BioGRID' | 'Other'>(str),
+        db_name: Aliased<'PDB' | 'PDB-Dev' | 'BMRB' | 'EMDB' | 'EMPIAR' | 'SASBDB' | 'PRIDE' | 'MODEL ARCHIVE' | 'MASSIVE' | 'BioGRID' | 'ProXL' | 'Other'>(str),
         /**
          * The accession code for the database entry.
          */
@@ -3930,7 +3965,7 @@ export const mmCIF_Schema = {
         /**
          * The type of crosslinker used.
          */
-        linker_type: Aliased<'EDC' | 'DSS' | 'EGS' | 'BS3' | 'BS2G' | 'DST' | 'sulfo-SDA' | 'sulfo-SMCC' | 'DSSO' | 'DSG' | 'BSP' | 'BMSO' | 'DHSO' | 'CYS' | 'SDA' | 'DSA' | 'Other'>(str),
+        linker_type: Aliased<'EDC' | 'DSS' | 'EGS' | 'BS3' | 'BS2G' | 'DST' | 'sulfo-SDA' | 'sulfo-SMCC' | 'DSSO' | 'DSG' | 'BSP' | 'BMSO' | 'DHSO' | 'CYS' | 'SDA' | 'DSA' | 'BrdU' | 'LCSDA' | 'CDI' | 'ADH' | 'Other'>(str),
         /**
          * Identifier to the crosslinking dataset.
          * This data item is a pointer to the _ihm_dataset_list.id in the

+ 10 - 10
src/mol-io/reader/cif/text/parser.ts

@@ -215,7 +215,7 @@ function eatImportGet(state: TokenizerState) {
  */
 function skipCommentLine(state: TokenizerState) {
     while (state.position < state.length) {
-        let c = state.data.charCodeAt(state.position);
+        const c = state.data.charCodeAt(state.position);
         if (c === 10 || c === 13) {
             return;
         }
@@ -230,7 +230,7 @@ function skipCommentLine(state: TokenizerState) {
 function skipWhitespace(state: TokenizerState): number {
     let prev = 10;
     while (state.position < state.length) {
-        let c = state.data.charCodeAt(state.position);
+        const c = state.data.charCodeAt(state.position);
         switch (c) {
             case 9: // '\t'
             case 32: // ' '
@@ -351,10 +351,10 @@ function isImportGet(state: TokenizerState): boolean {
  * Checks if the current token shares the namespace with string at <start,end).
  */
 function isNamespace(state: TokenizerState, start: number, end: number): boolean {
-    let i: number,
-        nsLen = end - start,
-        offset = state.tokenStart - start,
-        tokenLen = state.tokenEnd - state.tokenStart;
+    let i: number;
+    const nsLen = end - start;
+    const offset = state.tokenStart - start;
+    const tokenLen = state.tokenEnd - state.tokenStart;
 
     if (tokenLen < nsLen) return false;
 
@@ -410,7 +410,7 @@ function getTokenString(state: TokenizerState) {
  * Move to the next token.
  */
 function moveNextInternal(state: TokenizerState) {
-    let prev = skipWhitespace(state);
+    const prev = skipWhitespace(state);
 
     if (state.position >= state.length) {
         state.tokenType = CifTokenType.End;
@@ -421,7 +421,7 @@ function moveNextInternal(state: TokenizerState) {
     state.tokenEnd = state.position;
     state.isEscaped = false;
 
-    let c = state.data.charCodeAt(state.position);
+    const c = state.data.charCodeAt(state.position);
     switch (c) {
         case 35: // #, comment
             skipCommentLine(state);
@@ -712,7 +712,7 @@ async function parseInternal(data: string, runtimeCtx: RuntimeContext) {
     // the next three initial values are never used in valid files
     let saveFrames: Data.CifFrame[] = [];
     let saveCtx = FrameContext();
-    let saveFrame: Data.CifFrame = Data.CifSaveFrame(
+    const saveFrame: Data.CifFrame = Data.CifSaveFrame(
         saveCtx.categoryNames, CifCategories(saveCtx.categoryNames, saveCtx.categoryData), ''
     );
 
@@ -722,7 +722,7 @@ async function parseInternal(data: string, runtimeCtx: RuntimeContext) {
 
     moveNext(tokenizer);
     while (tokenizer.tokenType !== CifTokenType.End) {
-        let token = tokenizer.tokenType;
+        const token = tokenizer.tokenType;
 
         // Data block
         if (token === CifTokenType.Data) {

+ 1 - 1
src/mol-io/reader/common/text/column/fixed.ts

@@ -19,7 +19,7 @@ export function FixedColumn<T extends Column.Schema>(lines: Tokens, offset: numb
     const { valueType: type } = schema;
 
     const value: Column<T['T']>['value'] = type === 'str' ? row => {
-        let s = indices[2 * row] + offset, le = indices[2 * row + 1];
+        const s = indices[2 * row] + offset, le = indices[2 * row + 1];
         if (s >= le) return '';
         let e = s + width;
         if (e > le) e = le;

+ 2 - 1
src/mol-io/reader/common/text/number-parser.ts

@@ -112,7 +112,8 @@ function getNumberTypeScientific(str: string, start: number, end: number) {
 
 /** The whole range must match, otherwise returns NaN */
 export function getNumberType(str: string): NumberType {
-    let start = 0, end = str.length;
+    let start = 0;
+    const end = str.length;
 
     if (str.charCodeAt(start) === 45) { // -
         ++start;

+ 1 - 1
src/mol-io/reader/common/text/tokenizer.ts

@@ -206,7 +206,7 @@ namespace Tokenizer {
     export function skipWhitespace(state: Tokenizer): number {
         let prev = -1;
         while (state.position < state.length) {
-            let c = state.data.charCodeAt(state.position);
+            const c = state.data.charCodeAt(state.position);
             switch (c) {
                 case 9: // '\t'
                 case 32: // ' '

+ 1 - 1
src/mol-io/reader/csv/parser.ts

@@ -227,7 +227,7 @@ function readRecordsChunk(chunkSize: number, state: State) {
 }
 
 function readRecordsChunks(state: State) {
-    let newRecord = moveNext(state);
+    const newRecord = moveNext(state);
     if (newRecord) ++state.recordCount;
     return chunkedSubtask(state.runtimeCtx, 100000, state, readRecordsChunk,
         (ctx, state) => ctx.update({ message: 'Parsing...', current: state.tokenizer.position, max: state.data.length }));

+ 1 - 1
src/mol-io/reader/cube/parser.ts

@@ -52,7 +52,7 @@ const bohrToAngstromFactor = 0.529177210859;
 function readHeader(tokenizer: Tokenizer) {
     const headerLines = Tokenizer.readLines(tokenizer, 6);
     const h = (k: number, l: number) => {
-        const field = +headerLines[k].trim().split(/\s+/g)[ l ];
+        const field = +headerLines[k].trim().split(/\s+/g)[l];
         return Number.isNaN(field) ? 0 : field;
     };
     const basis = (i: number) => {

+ 2 - 2
src/mol-io/reader/xtc/parser.ts

@@ -111,7 +111,7 @@ namespace Decoder {
         // const mask = 0xff; // (1 << 8) - 1;
         // let lastBB0 = uint32view[1];
         let lastBB1 = uint32view[2];
-        let cnt = buf[0];
+        const cnt = buf[0];
 
         lastBB1 = (lastBB1 << 8) | cbuf[offset + cnt];
 
@@ -264,7 +264,7 @@ async function parseInternal(ctx: RuntimeContext, data: Uint8Array) {
 
             sizesmall[0] = sizesmall[1] = sizesmall[2] = MagicInts[smallidx];
 
-            let adz = Math.ceil(dv.getInt32(offset) / 4) * 4;
+            const adz = Math.ceil(dv.getInt32(offset) / 4) * 4;
             offset += 4;
 
             const invPrecision = 1.0 / precision;

+ 1 - 1
src/mol-io/writer/cif/encoder/util.ts

@@ -26,7 +26,7 @@ export interface CategoryInstanceData<Ctx = any> {
 
 export function getCategoryInstanceData<Ctx>(category: Category<Ctx>, ctx?: Ctx): CategoryInstanceData<Ctx> {
     const instance = category.instance(ctx as any);
-    let sources = instance.source.filter(s => s.rowCount > 0);
+    const sources = instance.source.filter(s => s.rowCount > 0);
     if (!sources.length) return { instance, rowCount: 0, source: [] };
 
     const rowCount = sources.reduce((a, c) => a + c.rowCount, 0);

+ 4 - 4
src/mol-math/geometry/boundary-helper.ts

@@ -121,10 +121,10 @@ type EposQuality = '6' | '14' | '26' | '98'
 function getEposDir(quality: EposQuality) {
     let dir: number[][];
     switch (quality) {
-        case '6': dir = [ ...Type001 ]; break;
-        case '14': dir = [ ...Type001, ...Type111 ]; break;
-        case '26': dir = [ ...Type001, ...Type111, ...Type011 ]; break;
-        case '98': dir = [ ...Type001, ...Type111, ...Type011, ...Type012, ...Type112, ...Type122 ]; break;
+        case '6': dir = [...Type001]; break;
+        case '14': dir = [...Type001, ...Type111]; break;
+        case '26': dir = [...Type001, ...Type111, ...Type011]; break;
+        case '98': dir = [...Type001, ...Type111, ...Type011, ...Type012, ...Type112, ...Type122]; break;
     }
     return dir.map(a => {
         const v = Vec3.create(a[0], a[1], a[2]);

+ 1 - 1
src/mol-math/geometry/gaussian-density/cpu.ts

@@ -42,7 +42,7 @@ export async function GaussianDensityCPU(ctx: RuntimeContext, position: Position
     idData.fill(-1);
     const idField = Tensor.create(space, idData);
 
-    const [ dimX, dimY, dimZ ] = dim;
+    const [dimX, dimY, dimZ] = dim;
     const iu = dimZ, iv = dimY, iuv = iu * iv;
 
     const gridx = fillGridDim(dim[0], min[0], resolution);

+ 5 - 5
src/mol-math/geometry/gaussian-density/gpu.ts

@@ -122,7 +122,7 @@ function calcGaussianDensityTexture2d(webgl: WebGLContext, position: PositionDat
     const { smoothness, resolution } = props;
 
     const { drawCount, positions, radii, groups, scale, expandedBox, dim, maxRadius } = prepareGaussianDensityData(position, box, radius, props);
-    const [ dx, dy, dz ] = dim;
+    const [dx, dy, dz] = dim;
     const { texDimX, texDimY, texCols, powerOfTwoSize } = getTexture2dSize(dim);
     // console.log({ texDimX, texDimY, texCols, powerOfTwoSize, dim });
     const gridTexDim = Vec3.create(texDimX, texDimY, 0);
@@ -207,7 +207,7 @@ function calcGaussianDensityTexture3d(webgl: WebGLContext, position: PositionDat
     const { smoothness, resolution } = props;
 
     const { drawCount, positions, radii, groups, scale, expandedBox, dim, maxRadius } = prepareGaussianDensityData(position, box, radius, props);
-    const [ dx, dy, dz ] = dim;
+    const [dx, dy, dz] = dim;
 
     const minDistTex = getTexture('min-dist-3d', webgl, 'volume-uint8', 'rgba', 'ubyte', 'nearest');
     minDistTex.define(dx, dy, dz);
@@ -431,8 +431,8 @@ function getTexture2dSize(gridDim: Vec3) {
 
 function fieldFromTexture2d(ctx: WebGLContext, texture: Texture, dim: Vec3, texDim: Vec3) {
     // console.time('fieldFromTexture2d')
-    const [ dx, dy, dz ] = dim;
-    const [ width, height ] = texDim;
+    const [dx, dy, dz] = dim;
+    const [width, height] = texDim;
     const fboTexCols = Math.floor(width / dx);
 
     const space = Tensor.Space(dim, [2, 1, 0], Float32Array);
@@ -454,7 +454,7 @@ function fieldFromTexture2d(ctx: WebGLContext, texture: Texture, dim: Vec3, texD
     let tmpCol = 0;
     let tmpRow = 0;
     for (let iz = 0; iz < dz; ++iz) {
-        if (tmpCol >= fboTexCols ) {
+        if (tmpCol >= fboTexCols) {
             tmpCol = 0;
             tmpRow += dy;
         }

+ 3 - 3
src/mol-math/geometry/molecular-surface.ts

@@ -41,7 +41,7 @@ function getAngleTables (probePositions: number): AnglesTables {
         sinTable[i] = Math.sin(theta);
         theta += step;
     }
-    return { cosTable, sinTable};
+    return { cosTable, sinTable };
 }
 
 //
@@ -330,12 +330,12 @@ export async function calcMolecularSurface(ctx: RuntimeContext, position: Requir
 
     const pad = maxRadius + resolution;
     const expandedBox = Box3D.expand(Box3D(), box, Vec3.create(pad, pad, pad));
-    const [ minX, minY, minZ ] = expandedBox.min;
+    const [minX, minY, minZ] = expandedBox.min;
     const scaledBox = Box3D.scale(Box3D(), expandedBox, scaleFactor);
     const dim = Box3D.size(Vec3(), scaledBox);
     Vec3.ceil(dim, dim);
 
-    const [ dimX, dimY, dimZ ] = dim;
+    const [dimX, dimY, dimZ] = dim;
     const iu = dimZ, iv = dimY, iuv = iu * iv;
 
     const { cosTable, sinTable } = getAngleTables(probePositions);

+ 2 - 2
src/mol-math/geometry/primitives/box3d.ts

@@ -107,8 +107,8 @@ namespace Box3D {
     const tmpTransformV = Vec3();
     /** Transform box with a Mat4 */
     export function transform(out: Box3D, box: Box3D, m: Mat4): Box3D {
-        const [ minX, minY, minZ ] = box.min;
-        const [ maxX, maxY, maxZ ] = box.max;
+        const [minX, minY, minZ] = box.min;
+        const [maxX, maxY, maxZ] = box.max;
         setEmpty(out);
         add(out, Vec3.transformMat4(tmpTransformV, Vec3.set(tmpTransformV, minX, minY, minZ), m));
         add(out, Vec3.transformMat4(tmpTransformV, Vec3.set(tmpTransformV, minX, minY, maxZ), m));

+ 1 - 1
src/mol-math/geometry/spacegroup/construction.ts

@@ -164,7 +164,7 @@ namespace Spacegroup {
     }
 
     function getRotation(x: number, y: number, z: number) {
-        let r: string[] = [];
+        const r: string[] = [];
         if (x > 0) r.push('+X');
         else if (x < 0) r.push('-X');
         if (y > 0) r.push('+Y');

+ 1 - 1
src/mol-math/histogram.ts

@@ -13,7 +13,7 @@ export interface Histogram {
     counts: Int32Array
 }
 
-export function calculateHistogram(data: ArrayLike<number>, binCount: number, options?: { min: number, max: number, } ): Histogram {
+export function calculateHistogram(data: ArrayLike<number>, binCount: number, options?: { min: number, max: number, }): Histogram {
     if (!options) {
         const [min, max] = arrayMinMax(data);
         return _calcHistogram(data, binCount, min, max);

+ 26 - 34
src/mol-math/linear-algebra/3d/mat4.ts

@@ -217,15 +217,15 @@ namespace Mat4 {
      * Returns the scaling factor component of a transformation matrix.
      */
     export function getScaling(out: Vec3, mat: Mat4) {
-        let m11 = mat[0];
-        let m12 = mat[1];
-        let m13 = mat[2];
-        let m21 = mat[4];
-        let m22 = mat[5];
-        let m23 = mat[6];
-        let m31 = mat[8];
-        let m32 = mat[9];
-        let m33 = mat[10];
+        const m11 = mat[0];
+        const m12 = mat[1];
+        const m13 = mat[2];
+        const m21 = mat[4];
+        const m22 = mat[5];
+        const m23 = mat[6];
+        const m31 = mat[8];
+        const m32 = mat[9];
+        const m33 = mat[10];
         out[0] = Math.sqrt(m11 * m11 + m12 * m12 + m13 * m13);
         out[1] = Math.sqrt(m21 * m21 + m22 * m22 + m23 * m23);
         out[2] = Math.sqrt(m31 * m31 + m32 * m32 + m33 * m33);
@@ -237,7 +237,7 @@ namespace Mat4 {
      */
     export function getRotation(out: Quat, mat: Mat4) {
         // Algorithm taken from http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToQuaternion/index.htm
-        let trace = mat[0] + mat[5] + mat[10];
+        const trace = mat[0] + mat[5] + mat[10];
         let S = 0;
 
         if (trace > 0) {
@@ -536,15 +536,8 @@ namespace Mat4 {
     }
 
     export function rotate(out: Mat4, a: Mat4, rad: number, axis: Vec3) {
-        let x = axis[0], y = axis[1], z = axis[2],
-            len = Math.sqrt(x * x + y * y + z * z),
-            s, c, t,
-            a00, a01, a02, a03,
-            a10, a11, a12, a13,
-            a20, a21, a22, a23,
-            b00, b01, b02,
-            b10, b11, b12,
-            b20, b21, b22;
+        let x = axis[0], y = axis[1], z = axis[2];
+        let len = Math.sqrt(x * x + y * y + z * z);
 
         if (Math.abs(len) < EPSILON) {
             return identity();
@@ -555,18 +548,18 @@ namespace Mat4 {
         y *= len;
         z *= len;
 
-        s = Math.sin(rad);
-        c = Math.cos(rad);
-        t = 1 - c;
+        const s = Math.sin(rad);
+        const c = Math.cos(rad);
+        const t = 1 - c;
 
-        a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3];
-        a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7];
-        a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11];
+        const a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3];
+        const a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7];
+        const a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11];
 
         // Construct the elements of the rotation matrix
-        b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s;
-        b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s;
-        b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c;
+        const b00 = x * x * t + c, b01 = y * x * t + z * s, b02 = z * x * t - y * s;
+        const b10 = x * y * t - z * s, b11 = y * y * t + c, b12 = z * y * t + x * s;
+        const b20 = x * z * t + y * s, b21 = y * z * t - x * s, b22 = z * z * t + c;
 
         // Perform rotation-specific matrix multiplication
         out[0] = a00 * b00 + a10 * b01 + a20 * b02;
@@ -592,9 +585,8 @@ namespace Mat4 {
     }
 
     export function fromRotation(out: Mat4, rad: number, axis: Vec3) {
-        let x = axis[0], y = axis[1], z = axis[2],
-            len = Math.sqrt(x * x + y * y + z * z),
-            s, c, t;
+        let x = axis[0], y = axis[1], z = axis[2];
+        let len = Math.sqrt(x * x + y * y + z * z);
 
         if (Math.abs(len) < EPSILON) { return setIdentity(out); }
 
@@ -603,9 +595,9 @@ namespace Mat4 {
         y *= len;
         z *= len;
 
-        s = Math.sin(rad);
-        c = Math.cos(rad);
-        t = 1 - c;
+        const s = Math.sin(rad);
+        const c = Math.cos(rad);
+        const t = 1 - c;
 
         // Perform rotation-specific matrix multiplication
         out[0] = x * x * t + c;

+ 30 - 30
src/mol-math/linear-algebra/3d/quat.ts

@@ -70,7 +70,7 @@ namespace Quat {
 
     export function setAxisAngle(out: Quat, axis: Vec3, rad: number) {
         rad = rad * 0.5;
-        let s = Math.sin(rad);
+        const s = Math.sin(rad);
         out[0] = s * axis[0];
         out[1] = s * axis[1];
         out[2] = s * axis[2];
@@ -89,8 +89,8 @@ namespace Quat {
      *  [0, 0, 1] and 270. This method favors the latter.
      */
     export function getAxisAngle(out_axis: Vec3, q: Quat) {
-        let rad = Math.acos(q[3]) * 2.0;
-        let s = Math.sin(rad / 2.0);
+        const rad = Math.acos(q[3]) * 2.0;
+        const s = Math.sin(rad / 2.0);
         if (s !== 0.0) {
             out_axis[0] = q[0] / s;
             out_axis[1] = q[1] / s;
@@ -105,8 +105,8 @@ namespace Quat {
     }
 
     export function multiply(out: Quat, a: Quat, b: Quat) {
-        let ax = a[0], ay = a[1], az = a[2], aw = a[3];
-        let bx = b[0], by = b[1], bz = b[2], bw = b[3];
+        const ax = a[0], ay = a[1], az = a[2], aw = a[3];
+        const bx = b[0], by = b[1], bz = b[2], bw = b[3];
 
         out[0] = ax * bw + aw * bx + ay * bz - az * by;
         out[1] = ay * bw + aw * by + az * bx - ax * bz;
@@ -118,8 +118,8 @@ namespace Quat {
     export function rotateX(out: Quat, a: Quat, rad: number) {
         rad *= 0.5;
 
-        let ax = a[0], ay = a[1], az = a[2], aw = a[3];
-        let bx = Math.sin(rad), bw = Math.cos(rad);
+        const ax = a[0], ay = a[1], az = a[2], aw = a[3];
+        const bx = Math.sin(rad), bw = Math.cos(rad);
 
         out[0] = ax * bw + aw * bx;
         out[1] = ay * bw + az * bx;
@@ -131,8 +131,8 @@ namespace Quat {
     export function rotateY(out: Quat, a: Quat, rad: number) {
         rad *= 0.5;
 
-        let ax = a[0], ay = a[1], az = a[2], aw = a[3];
-        let by = Math.sin(rad), bw = Math.cos(rad);
+        const ax = a[0], ay = a[1], az = a[2], aw = a[3];
+        const by = Math.sin(rad), bw = Math.cos(rad);
 
         out[0] = ax * bw - az * by;
         out[1] = ay * bw + aw * by;
@@ -144,8 +144,8 @@ namespace Quat {
     export function rotateZ(out: Quat, a: Quat, rad: number) {
         rad *= 0.5;
 
-        let ax = a[0], ay = a[1], az = a[2], aw = a[3];
-        let bz = Math.sin(rad), bw = Math.cos(rad);
+        const ax = a[0], ay = a[1], az = a[2], aw = a[3];
+        const bz = Math.sin(rad), bw = Math.cos(rad);
 
         out[0] = ax * bw + ay * bz;
         out[1] = ay * bw - ax * bz;
@@ -160,7 +160,7 @@ namespace Quat {
      * Any existing W component will be ignored.
      */
     export function calculateW(out: Quat, a: Quat) {
-        let x = a[0], y = a[1], z = a[2];
+        const x = a[0], y = a[1], z = a[2];
 
         out[0] = x;
         out[1] = y;
@@ -175,7 +175,7 @@ namespace Quat {
     export function slerp(out: Quat, a: Quat, b: Quat, t: number) {
         // benchmarks:
         //    http://jsperf.com/quaternion-slerp-implementations
-        let ax = a[0], ay = a[1], az = a[2], aw = a[3];
+        const ax = a[0], ay = a[1], az = a[2], aw = a[3];
         let bx = b[0], by = b[1], bz = b[2], bw = b[3];
 
         let omega, cosom, sinom, scale0, scale1;
@@ -183,7 +183,7 @@ namespace Quat {
         // calc cosine
         cosom = ax * bx + ay * by + az * bz + aw * bw;
         // adjust signs (if necessary)
-        if ( cosom < 0.0 ) {
+        if (cosom < 0.0) {
             cosom = -cosom;
             bx = - bx;
             by = - by;
@@ -191,7 +191,7 @@ namespace Quat {
             bw = - bw;
         }
         // calculate coefficients
-        if ( (1.0 - cosom) > 0.000001 ) {
+        if ((1.0 - cosom) > 0.000001) {
             // standard case (slerp)
             omega  = Math.acos(cosom);
             sinom  = Math.sin(omega);
@@ -213,9 +213,9 @@ namespace Quat {
     }
 
     export function invert(out: Quat, a: Quat) {
-        let a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3];
-        let dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3;
-        let invDot = dot ? 1.0 / dot : 0;
+        const a0 = a[0], a1 = a[1], a2 = a[2], a3 = a[3];
+        const dot = a0 * a0 + a1 * a1 + a2 * a2 + a3 * a3;
+        const invDot = dot ? 1.0 / dot : 0;
 
         // TODO: Would be faster to return [0,0,0,0] immediately if dot == 0
 
@@ -250,7 +250,7 @@ namespace Quat {
         const fTrace = m[0] + m[4] + m[8];
         let fRoot;
 
-        if ( fTrace > 0.0 ) {
+        if (fTrace > 0.0) {
             // |w| > 1/2, may as well choose w > 1/2
             fRoot = Math.sqrt(fTrace + 1.0);  // 2w
             out[3] = 0.5 * fRoot;
@@ -261,10 +261,10 @@ namespace Quat {
         } else {
             // |w| <= 1/2
             let i = 0;
-            if ( m[4] > m[0] ) i = 1;
-            if ( m[8] > m[i * 3 + i] ) i = 2;
-            let j = (i + 1) % 3;
-            let k = (i + 2) % 3;
+            if (m[4] > m[0]) i = 1;
+            if (m[8] > m[i * 3 + i]) i = 2;
+            const j = (i + 1) % 3;
+            const k = (i + 2) % 3;
 
             fRoot = Math.sqrt(m[i * 3 + i] - m[j * 3 + j] - m[k * 3 + k] + 1.0);
             out[i] = 0.5 * fRoot;
@@ -355,10 +355,10 @@ namespace Quat {
     }
 
     export function normalize(out: Quat, a: Quat) {
-        let x = a[0];
-        let y = a[1];
-        let z = a[2];
-        let w = a[3];
+        const x = a[0];
+        const y = a[1];
+        const z = a[2];
+        const w = a[3];
         let len = x * x + y * y + z * z + w * w;
         if (len > 0) {
             len = 1 / Math.sqrt(len);
@@ -380,7 +380,7 @@ namespace Quat {
     const rotTmpVec3UnitX = [1, 0, 0] as Vec3;
     const rotTmpVec3UnitY = [0, 1, 0] as Vec3;
     export function rotationTo(out: Quat, a: Vec3, b: Vec3) {
-        let dot = Vec3.dot(a, b);
+        const dot = Vec3.dot(a, b);
         if (dot < -0.999999) {
             Vec3.cross(rotTmpVec3, rotTmpVec3UnitX, a);
             if (Vec3.magnitude(rotTmpVec3) < 0.000001)
@@ -407,8 +407,8 @@ namespace Quat {
     /**
      * Performs a spherical linear interpolation with two control points
      */
-    let sqlerpTemp1 = zero();
-    let sqlerpTemp2 = zero();
+    const sqlerpTemp1 = zero();
+    const sqlerpTemp2 = zero();
     export function sqlerp(out: Quat, a: Quat, b: Quat, c: Quat, d: Quat, t: number) {
         slerp(sqlerpTemp1, a, d, t);
         slerp(sqlerpTemp2, b, c, t);

+ 1 - 1
src/mol-math/linear-algebra/3d/vec3.ts

@@ -545,7 +545,7 @@ namespace Vec3 {
         return add(out, scale(out, copy(out, vector), scalar), origin);
     }
 
-    export function projectOnVector(out: Vec3, p: Vec3, vector: Vec3 ) {
+    export function projectOnVector(out: Vec3, p: Vec3, vector: Vec3) {
         const scalar = dot(vector, p) / squaredMagnitude(vector);
         return scale(out, vector, scalar);
     }

+ 3 - 3
src/mol-math/linear-algebra/_spec/tensor.spec.ts

@@ -266,14 +266,14 @@ describe('tensor', () => {
 
     it('indexing', () => {
         function permutations<T>(inputArr: T[]): T[][] {
-            let result: T[][] = [];
+            const result: T[][] = [];
             function permute(arr: any, m: any = []) {
                 if (arr.length === 0) {
                     result.push(m);
                 } else {
                     for (let i = 0; i < arr.length; i++) {
-                        let curr = arr.slice();
-                        let next = curr.splice(i, 1);
+                        const curr = arr.slice();
+                        const next = curr.splice(i, 1);
                         permute(curr.slice(), m.concat(next));
                     }
                 }

+ 4 - 4
src/mol-math/linear-algebra/_spec/vec3.spec.ts

@@ -7,10 +7,10 @@
 import { Vec3 } from '../3d/vec3';
 
 describe('vec3', () => {
-    const vec1 = [ 1, 2, 3 ] as Vec3;
-    const vec2 = [ 2, 3, 1 ] as Vec3;
-    const orthVec1 = [ 0, 1, 0 ] as Vec3;
-    const orthVec2 = [ 1, 0, 0 ] as Vec3;
+    const vec1 = [1, 2, 3] as Vec3;
+    const vec2 = [2, 3, 1] as Vec3;
+    const orthVec1 = [0, 1, 0] as Vec3;
+    const orthVec2 = [1, 0, 0] as Vec3;
 
     it('angle calculation', () => {
         expect(Vec3.angle(vec1, vec1) * 360 / (2 * Math.PI)).toBe(0.0);

+ 9 - 9
src/mol-math/linear-algebra/matrix/evd.ts

@@ -46,7 +46,7 @@ function symmetricEigenDecomp(order: number, matrixEv: number[], vectorEv: numbe
         e[i] = 0.0;
     }
 
-    let om1 = order - 1;
+    const om1 = order - 1;
     for (let i = 0; i < order; i++) {
         d[i] = matrixEv[i * order + om1];
     }
@@ -119,7 +119,7 @@ function symmetricTridiagonalize(a: number[], d: number[], e: number[], order: n
                 f += e[j] * d[j];
             }
 
-            let hh = f / (h + h);
+            const hh = f / (h + h);
 
             for (let j = 0; j < i; j++) {
                 e[j] -= hh * d[j];
@@ -145,7 +145,7 @@ function symmetricTridiagonalize(a: number[], d: number[], e: number[], order: n
     for (let i = 0; i < order - 1; i++) {
         a[(i * order) + order - 1] = a[(i * order) + i];
         a[(i * order) + i] = 1.0;
-        let h = d[i + 1];
+        const h = d[i + 1];
         if (h !== 0.0) {
             for (let k = 0; k <= i; k++) {
                 d[k] = a[((i + 1) * order) + k] / h;
@@ -188,7 +188,7 @@ function symmetricDiagonalize(a: number[], d: number[], e: number[], order: numb
 
     let f = 0.0;
     let tst1 = 0.0;
-    let eps = Math.pow(2, -53); // DoubleWidth = 53
+    const eps = Math.pow(2, -53); // DoubleWidth = 53
     for (let l = 0; l < order; l++) {
         // Find small subdiagonal element
         tst1 = Math.max(tst1, Math.abs(d[l]) + Math.abs(e[l]));
@@ -219,7 +219,7 @@ function symmetricDiagonalize(a: number[], d: number[], e: number[], order: numb
                 d[l] = e[l] / (p + r);
                 d[l + 1] = e[l] * (p + r);
 
-                let dl1 = d[l + 1];
+                const dl1 = d[l + 1];
                 let h = g - d[l];
                 for (let i = l + 2; i < order; i++) {
                     d[i] -= h;
@@ -232,7 +232,7 @@ function symmetricDiagonalize(a: number[], d: number[], e: number[], order: numb
                 let c = 1.0;
                 let c2 = c;
                 let c3 = c;
-                let el1 = e[l + 1];
+                const el1 = e[l + 1];
                 let s = 0.0;
                 let s2 = 0.0;
                 for (let i = m - 1; i >= l; i--) {
@@ -263,7 +263,7 @@ function symmetricDiagonalize(a: number[], d: number[], e: number[], order: numb
                 // Check for convergence. If too many iterations have been performed,
                 // throw exception that Convergence Failed
                 if (iter >= maxiter) {
-                    throw 'SVD: Not converging.';
+                    throw new Error('SVD: Not converging.');
                 }
             } while (Math.abs(e[l]) > eps * tst1);
         }
@@ -297,12 +297,12 @@ function symmetricDiagonalize(a: number[], d: number[], e: number[], order: numb
 
 function hypotenuse(a: number, b: number) {
     if (Math.abs(a) > Math.abs(b)) {
-        let r = b / a;
+        const r = b / a;
         return Math.abs(a) * Math.sqrt(1 + (r * r));
     }
 
     if (b !== 0.0) {
-        let r = a / b;
+        const r = a / b;
         return Math.abs(b) * Math.sqrt(1 + (r * r));
     }
 

Some files were not shown because too many files changed in this diff