@datagrok/helm 3.0.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Helm changelog
2
2
 
3
+ ## 3.0.1 (2026-06-20)
4
+
5
+ * Migration to Datagrok Helm Web Editor
6
+ * Support for new Helm Service, editor, parsing and rendering
7
+ * Helm editor panes including molecular structure, composition and conversion
8
+
3
9
  ## 2.13.4 (2026-03-31)
4
10
 
5
11
  ### Features
package/css/helm.css CHANGED
@@ -1,3 +1,43 @@
1
1
  .d4-g-cell[semType="Macromolecule"] * {
2
2
  pointer-events: none !important;
3
3
  }
4
+
5
+ .hw-pane--extra>div[data-testid="extra-pane-content-molecular-structure"]>div.d4-accordion {
6
+ display: flex;
7
+ flex-direction: row;
8
+ gap: 24px;
9
+ }
10
+
11
+ .hw-pane--extra>div[data-testid="extra-pane-content-molecular-structure"]>div.d4-accordion>div.d4-accordion-pane[d4-title="Explore"] {
12
+ flex-grow: 1;
13
+ max-height: 280px;
14
+ overflow-y: scroll;
15
+ overflow-x: hidden;
16
+ max-width: calc(100% - 400px);
17
+ }
18
+
19
+ .hw-pane--extra>div[data-testid="extra-pane-content-molecular-structure"] {
20
+ height: 280px;
21
+ overflow: hidden;
22
+ }
23
+
24
+ .hw-pane--extra>div[data-testid="extra-pane-content-molecular-structure"]>div.d4-accordion>div.d4-accordion-pane[d4-title="Explore"] .d4-accordion-pane-header {
25
+ height: 30px;
26
+ }
27
+
28
+ .hw-pane--extra>div[data-testid="extra-pane-content-molecular-structure"]>div.d4-accordion>div.d4-accordion-pane[d4-title="Explore"] .d4-accordion {
29
+ width: 100%;
30
+ }
31
+
32
+ .hw-pane__extra>.macromolecule-cell-comp-analysis-host>table {
33
+ margin: 0;
34
+ }
35
+
36
+ .hw-pane__extra>.macromolecule-cell-comp-analysis-host>table>tbody {
37
+ width: 100%;
38
+ display: flex;
39
+ flex-direction: column;
40
+ flex-wrap: wrap;
41
+ max-height: 260px;
42
+ column-gap: 24px;
43
+ }
package/dist/137.js ADDED
@@ -0,0 +1,2 @@
1
+ "use strict";(self.webpackChunkhelm=self.webpackChunkhelm||[]).push([[137],{330(t,o,n){var e,s,a=n(94);!function(t){t[t.default=0]="default",t[t.continuous=1]="continuous"}(e||(e={})),function(t){t.Sequence="sequence",t.Helm="notation",t.Properties="properties",t.StructureView="structureview"}(s||(s={}));const i={V2K_RGP_SHIFT:8,V2K_RGP_LINE:"M RGP",V2K_A_LINE:"A ",V3K_COUNTS_SHIFT:14,V3K_IDX_SHIFT:7,V3K_HEADER_FIRST_LINE:"\nDatagrok macromolecule handler\n\n",V3K_HEADER_SECOND_LINE:" 0 0 0 0 0 0 999 V3000\n",V3K_BEGIN_CTAB_BLOCK:"M V30 BEGIN CTAB\n",V3K_END_CTAB_BLOCK:"M V30 END CTAB\n",V3K_BEGIN_COUNTS_LINE:"M V30 COUNTS ",V3K_COUNTS_LINE_ENDING:" 0 0 0\n",V3K_BEGIN_ATOM_BLOCK:"M V30 BEGIN ATOM\n",V3K_END_ATOM_BLOCK:"M V30 END ATOM\n",V3K_BEGIN_BOND_BLOCK:"M V30 BEGIN BOND\n",V3K_END_BOND_BLOCK:"M V30 END BOND\n",V3K_BOND_CONFIG:" CFG=",V3K_BEGIN_DATA_LINE:"M V30 ",V3K_END:"M END",PRECISION_FACTOR:1e4,DEOXYRIBOSE:{polymerType:a.kC.RNA,symbol:"d"},RIBOSE:{polymerType:a.kC.RNA,symbol:"r"},PHOSPHATE:{polymerType:a.kC.RNA,symbol:"p"},OXYGEN:"O",HYDROGEN:"H"};function r(t,o){return t[o.polymerType]?.[o.symbol]}var l;!function(t){t[t.SUGAR=0]="SUGAR",t[t.BASE=1]="BASE",t[t.PHOSPHATE=2]="PHOSPHATE",t[t.TERMINAL_5P=3]="TERMINAL_5P",t[t.TERMINAL_3P=4]="TERMINAL_3P"}(l||(l={}));class c extends Map{constructor(t){super(t)}}class h{constructor(t,o){this.molfile=t,this.monomers=o}static createEmpty(){return new h("",new c(null))}}const f=a.kC;var b,m,N;new RegExp("[rd]\\((\\w)\\)p?","g");class E{constructor(t,o,n){this.name=t,this.alphabet=o,this.cutoff=n}}!function(t){t.FASTA="fasta",t.SEPARATOR="separator",t.HELM="helm",t.CUSTOM="custom",t.BILN="biln"}(b||(b={})),function(t){t.DNA="DNA",t.RNA="RNA",t.PT="PT",t.UN="UN"}(m||(m={})),function(t){t.aligned="aligned",t.alphabet="alphabet",t.alphabetSize=".alphabetSize",t.alphabetIsMultichar=".alphabetIsMultichar",t.separator="separator",t.isHelmCompatible=".isHelmCompatible",t.positionNames=".positionNames",t.positionLabels=".positionLabels",t.regions=".regions",t.positionShift=".positionShift",t.selectedPosition=".selectedPosition",t.polymerTypeColumnName=".polymerTypeColumnName",t.annotations=".annotations",t.numberingScheme=".numberingScheme",t.annotationColumnName=".annotationColumnName"}(N||(N={}));const _=new class{constructor(){this.fasta={peptide:new Set(["G","L","Y","S","E","Q","D","N","F","A","K","R","H","C","V","P","W","I","M","T"]),dna:new Set(["A","C","G","T"]),rna:new Set(["A","C","G","U"])}}};function A(t){let o;switch(t){case a.oE.BASE:case a.oE.SUGAR:case a.oE.LINKER:case a.oE.NUCLEOTIDE:case"nucleotide":o=a.kC.RNA;break;case a.oE.AA:o=a.kC.PEPTIDE;break;case a.oE.CHEM:o=a.kC.CHEM;break;case a.oE.BLOB:o=a.kC.BLOB;break;default:o=a.kC.PEPTIDE,console.warn(`Unexpected HelmType '${t}'`)}return o}function p(t,o,n,e,s){if(0===t.length)return h.createEmpty();const a=e===f.RNA&&!!s&&s.length===t.length,{atomCount:b,bondCount:N,needsCapping:E}=function(t,o,n,e,s,a){let c=0,h=0,b=0,N=!0,E=null,_=null;for(let n=0;n<t.length;++n){const e=t[n];if(""!==e.symbol){if("*"==e.symbol)throw new Error("Gap canonical symbol is '', not '*");E=r(o,{symbol:e.symbol,polymerType:A(e.biotype)}),c+=E.atoms.x.length,h+=E.bonds.bondTypes.length,b++,s&&n%3==2&&(_=E)}}if(e===f.PEPTIDE)c+=1,h+=b,b>0&&((E?.meta?.rNodes?.length??0)<2||E?.terminalR2Atom?.toLowerCase()===i.HYDROGEN.toLowerCase())&&(N=!1,c-=1,h-=1);else if(s)h+=b,a&&a.length>0&&a[a.length-1]===l.TERMINAL_3P?(N=!1,h-=1):c+=1;else{const e=n===m.DNA?r(o,i.DEOXYRIBOSE):r(o,i.RIBOSE),s=r(o,i.PHOSPHATE);c+=(t.length-1)*s.atoms.x.length,c+=t.length*e.atoms.x.length,c+=1,h+=(t.length-1)*s.bonds.bondTypes.length,h+=t.length*e.bonds.bondTypes.length,h-=1,h+=3*t.length}return{atomCount:c,bondCount:h,needsCapping:N}}(t,o,n,e,a,s),_=new Array(b),p=new Array(N);let C,I=null,y=null;e===f.PEPTIDE?C=d:(C=u,a||(I=n===m.DNA?r(o,i.DEOXYRIBOSE):r(o,i.RIBOSE),y=r(o,i.PHOSPHATE)));const O={i:0,nodeShift:0,bondShift:0,backbonePositionShift:new Array(2).fill(0),branchPositionShift:new Array(2).fill(0),backboneAttachNode:0,branchAttachNode:0,flipFactor:1},B={sugar:I,phosphate:y,seqLength:a?Math.ceil(t.length/3):t.length,atomCount:b,bondCount:N},L=new c,D=[];let R,P=0;if(a)!function(t,o,n,e,s,a,i,c,h,f){for(let i=0;i<t.length;++i){const b=t[i];if(""===b.symbol)continue;const m=o[i],N=r(n,{symbol:b.symbol,polymerType:A(b.biotype)}),E=a.nodeShift,_=a.bondShift;a.i=i,m===l.BASE?T(N,e,s,a):S(N,e,s,a),N.stereoAtoms?.forEach(t=>h.push(t+P)),f(N.atoms.x.length);const p=[];for(let t=E;t<a.nodeShift;++t)p.push(t);const d=[];for(let t=_;t<a.bondShift;++t)d.push(t);c.set(i,{biotype:b.biotype,symbol:b.symbol,atoms:p,bonds:d})}}(t,s,o,_,p,O,0,L,D,t=>{P+=t});else for(O.i=0;O.i<B.seqLength;++O.i){const n=t[O.i];if(""===n.symbol)continue;const e=r(o,{symbol:n.symbol,polymerType:A(n.biotype)});R=e.terminalR2Atom;const s=O.nodeShift,a=O.bondShift;C(e,_,p,O,B),e.stereoAtoms?.forEach(t=>D.push(t+P)),P+=e.atoms.x.length;const i=O.nodeShift-s,l=new Array(i);for(let t=0;t<i;++t)l[t]=s+t;const c=O.bondShift-a,h=new Array(c);for(let t=0;t<c;++t)h[t]=a+t;L.set(O.i,{biotype:n.biotype,symbol:n.symbol,atoms:l,bonds:h})}E&&function(t,o,n,e,s=i.OXYGEN){const a=n.nodeShift+1;t[e.atomCount]=i.V3K_BEGIN_DATA_LINE+a+" "+(s??i.OXYGEN)+" "+g(n.backbonePositionShift[0])+" "+n.flipFactor*g(n.backbonePositionShift[1])+" 0.000000 0\n";const r=n.backboneAttachNode,l=a;o[e.bondCount]=i.V3K_BEGIN_DATA_LINE+n.bondShift+" 1 "+r+" "+l+"\n"}(_,p,O,B,R??i.OXYGEN);const V=i.V3K_BEGIN_COUNTS_LINE+b+" "+N+i.V3K_COUNTS_LINE_ENDING;let K="";return K+=i.V3K_HEADER_FIRST_LINE,K+=i.V3K_HEADER_SECOND_LINE,K+=i.V3K_BEGIN_CTAB_BLOCK,K+=V,K+=i.V3K_BEGIN_ATOM_BLOCK,K+=_.join(""),K+=i.V3K_END_ATOM_BLOCK,K+=i.V3K_BEGIN_BOND_BLOCK,K+=p.join(""),K+=i.V3K_END_BOND_BLOCK,D.length>0&&(K+=function(t){const o=[];let n=`M V30 MDLV30/STEABS ATOMS=(${t.length}`;for(let e=0;e<t.length;e++){const s=`${n} ${t[e]}`;s.length>76?(o.push(`${n} -\n`),n=`M V30 ${t[e]}`):n=s,e===t.length-1&&o.push(`${n})\n`)}return`M V30 BEGIN COLLECTION\n${o.join("")}M V30 END COLLECTION\n`}(D)),K+=i.V3K_END_CTAB_BLOCK,K+=i.V3K_END,{molfile:K,monomers:L}}function d(t,o,n,e){e.flipFactor=(-1)**(e.i%2),S(t,o,n,e)}function S(t,o,n,e){!function(t,o,n){for(let e=0;e<t.atoms.atomTypes.length;++e){const s=n.nodeShift+e+1;o[n.nodeShift+e]=i.V3K_BEGIN_DATA_LINE+s+" "+t.atoms.atomTypes[e]+" "+g(n.backbonePositionShift[0]+t.atoms.x[e])+" "+g(n.backbonePositionShift[1]+n.flipFactor*t.atoms.y[e])+" "+t.atoms.kwargs[e]}}(t,o,e),C(t,n,e),function(t,o,n){if(0!==n.backboneAttachNode){const e=n.bondShift,s=n.backboneAttachNode,a=t.meta.terminalNodes[0]+n.nodeShift;o[n.bondShift-1]=i.V3K_BEGIN_DATA_LINE+e+" 1 "+s+" "+a+"\n"}}(t,n,e),null!==t.meta.branchShift&&t.meta.terminalNodes.length>2&&function(t,o){o.branchAttachNode=o.nodeShift+t.meta.terminalNodes[2];for(let n=0;n<2;++n)o.branchPositionShift[n]=o.backbonePositionShift[n]+t.meta.branchShift[n]}(t,e),function(t,o){o.backboneAttachNode=o.nodeShift+t.meta.terminalNodes[1],o.bondShift+=t.bonds.atomPairs.length+1,o.nodeShift+=t.atoms.atomTypes.length,o.backbonePositionShift[0]+=t.meta.backboneShift?.[0]??0,o.backbonePositionShift[1]+=o.flipFactor*(t.meta.backboneShift?.[1]??0)}(t,e)}function u(t,o,n,e,s){if(0===e.i)S(s.sugar,o,n,e);else for(const t of[s.phosphate,s.sugar])S(t,o,n,e);T(t,o,n,e)}function T(t,o,n,e){!function(t,o,n){for(let e=0;e<t.atoms.atomTypes.length;++e){const s=n.nodeShift+e+1;o[n.nodeShift+e]=i.V3K_BEGIN_DATA_LINE+s+" "+t.atoms.atomTypes[e]+" "+g(n.branchPositionShift[0]+t.atoms.x[e])+" "+g(n.branchPositionShift[1]+n.flipFactor*t.atoms.y[e])+" "+t.atoms.kwargs[e]}}(t,o,e),C(t,n,e),function(t,o,n){const e=n.bondShift,s=n.branchAttachNode,a=t.meta.terminalNodes[0]+n.nodeShift;o[e-1]=i.V3K_BEGIN_DATA_LINE+e+" 1 "+s+" "+a+"\n"}(t,n,e);const s=e.bondShift,a=e.branchAttachNode,r=t.meta.terminalNodes[0]+e.nodeShift;n[s-1]=i.V3K_BEGIN_DATA_LINE+s+" 1 "+a+" "+r+"\n",e.bondShift+=t.bonds.atomPairs.length+1,e.nodeShift+=t.atoms.atomTypes.length}function C(t,o,n){for(let e=0;e<t.bonds.atomPairs.length;++e){const s=n.bondShift+e+1,a=t.bonds.atomPairs[e][0]+n.nodeShift,r=t.bonds.atomPairs[e][1]+n.nodeShift;let l="";if(t.bonds.bondConfiguration.has(e)){let o=t.bonds.bondConfiguration.get(e);n.flipFactor<0&&(o=1===o?3:1),l=" CFG="+o}const c=t.bonds.kwargs.has(e)?" "+t.bonds.kwargs.get(e):"";o[n.bondShift+e]=i.V3K_BEGIN_DATA_LINE+s+" "+t.bonds.bondTypes[e]+" "+a+" "+r+l+c+"\n"}}function g(t){return Math.round(i.PRECISION_FACTOR*t)/i.PRECISION_FACTOR}new E(m.PT,_.fasta.peptide,.5),new E(m.DNA,_.fasta.dna,.55),new E(m.RNA,_.fasta.rna,.55),b.FASTA,b.SEPARATOR,b.HELM,b.BILN,onmessage=t=>{const{seqList:o,rolesList:n,monomersDict:e,alphabet:s,polymerType:a,start:i,end:r}=t.data,l=new Array(r-i),c=new Array(0);for(let t=i;t<r;++t)try{const r=o[t],c=n?n[t]:void 0;l[t-i]=p(r,e,s,a,c)}catch(o){const n=`Cannot get molfile of row #${t}: ${o instanceof Error?o.message:o.toString()}.`;c.push(n)}postMessage({molfiles:l,warnings:c})}},782(){"object"==typeof performance&&performance&&"function"==typeof performance.now?performance:Date,new Set;const t="object"==typeof process&&process?process:{};let o=globalThis.AbortController,n=globalThis.AbortSignal;if(void 0===o){n=class{onabort;_onabort=[];reason;aborted=!1;addEventListener(t,o){this._onabort.push(o)}},o=class{constructor(){s()}signal=new n;abort(t){if(!this.signal.aborted){this.signal.reason=t,this.signal.aborted=!0;for(const o of this.signal._onabort)o(t);this.signal.onabort?.(t)}}};let e="1"!==t.env?.LRU_CACHE_IGNORE_AC_WARNING;const s=()=>{var o,n,a,i;e&&(e=!1,o="AbortController is not defined. If using lru-cache in node 14, load an AbortController polyfill from the `node-abort-controller` package. A minimal polyfill is provided for use by LRUCache.fetch(), but it should not be relied upon in other contexts (eg, passing it to other APIs that use AbortController/AbortSignal might have undesirable effects). You may disable this with LRU_CACHE_IGNORE_AC_WARNING=1 in the env.",n="NO_ABORT_CONTROLLER",a="ENOTSUP",i=s,"function"==typeof t.emitWarning?t.emitWarning(o,n,a,i):console.error(`[${a}] ${n}: ${o}`))}}Symbol("type"),Symbol.iterator,Symbol.toStringTag}}]);
2
+ //# sourceMappingURL=137.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"137.js","mappings":"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","sources":["webpack://helm/./node_modules/@datagrok-libraries/bio/src/helm/consts.js","webpack://helm/./node_modules/@datagrok-libraries/bio/src/monomer-works/consts.js","webpack://helm/./node_modules/@datagrok-libraries/bio/src/monomer-works/types.js","webpack://helm/./node_modules/@datagrok-libraries/bio/src/utils/const.js","webpack://helm/./node_modules/@datagrok-libraries/bio/src/utils/macromolecule/consts.js","webpack://helm/./node_modules/@datagrok-libraries/bio/src/utils/macromolecule/types.js","webpack://helm/./node_modules/@datagrok-libraries/bio/src/monomer-works/monomer-works.js","webpack://helm/./node_modules/@datagrok-libraries/bio/src/monomer-works/to-atomic-level-utils.js","webpack://helm/./node_modules/@datagrok-libraries/bio/src/monomer-works/seq-to-molfile-worker.js","webpack://helm/javascript/HELM/node_modules/lru-cache/dist/esm/index.js"],"sourcesContent":["// HELM type vocabulary is owned by `@datagrok-libraries/hwe` (the standalone\n// HELM editor) and re-exported here as the single source of truth. The string\n// values match the canonical Pistoia HELM Web Editor, except `NUCLEOTIDE` which\n// uses the corrected spelling `HELM_NUCLEOTIDE` (was `HELM_NUCLETIDE`).\nimport { HelmTypes, MonomerTypes, PolymerTypes } from '@datagrok-libraries/hwe';\nexport { HelmTypes, MonomerTypes, PolymerTypes };\n// hwe migration: these two small enums are not part of the hwe value vocabulary.\n// They are defined here locally (replicating the legacy HELM Web Editor values)\n// so `@datagrok-libraries/bio` no longer depends on\n// `@datagrok-libraries/helm-web-editor`.\nexport var MonomerNumberingTypes;\n(function (MonomerNumberingTypes) {\n MonomerNumberingTypes[MonomerNumberingTypes[\"default\"] = 0] = \"default\";\n MonomerNumberingTypes[MonomerNumberingTypes[\"continuous\"] = 1] = \"continuous\";\n})(MonomerNumberingTypes || (MonomerNumberingTypes = {}));\nexport var HelmTabKeys;\n(function (HelmTabKeys) {\n HelmTabKeys[\"Sequence\"] = \"sequence\";\n HelmTabKeys[\"Helm\"] = \"notation\";\n HelmTabKeys[\"Properties\"] = \"properties\";\n HelmTabKeys[\"StructureView\"] = \"structureview\";\n})(HelmTabKeys || (HelmTabKeys = {}));\n//# sourceMappingURL=consts.js.map","import { PolymerTypes } from '../helm/consts';\nexport const monomerWorksConsts = {\n // constants for parsing molfile V2000\n V2K_RGP_SHIFT: 8,\n V2K_RGP_LINE: 'M RGP',\n V2K_A_LINE: 'A ',\n // constants for parsing/reconstruction of molfile V3000\n V3K_COUNTS_SHIFT: 14,\n V3K_IDX_SHIFT: 7,\n V3K_HEADER_FIRST_LINE: '\\nDatagrok macromolecule handler\\n\\n',\n V3K_HEADER_SECOND_LINE: ' 0 0 0 0 0 0 999 V3000\\n',\n V3K_BEGIN_CTAB_BLOCK: 'M V30 BEGIN CTAB\\n',\n V3K_END_CTAB_BLOCK: 'M V30 END CTAB\\n',\n V3K_BEGIN_COUNTS_LINE: 'M V30 COUNTS ',\n V3K_COUNTS_LINE_ENDING: ' 0 0 0\\n',\n V3K_BEGIN_ATOM_BLOCK: 'M V30 BEGIN ATOM\\n',\n V3K_END_ATOM_BLOCK: 'M V30 END ATOM\\n',\n V3K_BEGIN_BOND_BLOCK: 'M V30 BEGIN BOND\\n',\n V3K_END_BOND_BLOCK: 'M V30 END BOND\\n',\n V3K_BOND_CONFIG: ' CFG=',\n V3K_BEGIN_DATA_LINE: 'M V30 ',\n V3K_END: 'M END',\n PRECISION_FACTOR: 10000, // HELMCoreLibrary has 4 significant digits after decimal point in atom coordinates\n // symbols for the corresponding monomers in HELM library\n DEOXYRIBOSE: { polymerType: PolymerTypes.RNA, symbol: 'd' },\n RIBOSE: { polymerType: PolymerTypes.RNA, symbol: 'r' },\n PHOSPHATE: { polymerType: PolymerTypes.RNA, symbol: 'p' },\n OXYGEN: 'O',\n HYDROGEN: 'H',\n};\n//# sourceMappingURL=consts.js.map","export function getMolGraph(dict, libKey) {\n return dict[libKey.polymerType]?.[libKey.symbol];\n}\nexport function hasMolGraph(dict, libKey) {\n return !!dict[libKey.polymerType]?.[libKey.symbol];\n}\nexport function setMolGraph(dict, libKey, value) {\n let pt = dict[libKey.polymerType];\n if (!pt)\n pt = dict[libKey.polymerType] = {};\n pt[libKey.symbol] = value;\n}\n/** Role of an entry in a HELM RNA splitted sequence.\n * SUGAR/BASE/PHOSPHATE are the standard triple positions.\n * TERMINAL_5P marks a 5'-end terminal modifier (e.g. Chol) — a monomer\n * with R2 only that takes the place of the leading sugar.\n * TERMINAL_3P marks a 3'-end terminal modifier (e.g. GalNAc) — a monomer\n * with R1 only that takes the place of the trailing phosphate. The OH cap\n * MUST be omitted when a TERMINAL_3P is present. */\nexport var NucleotideRole;\n(function (NucleotideRole) {\n NucleotideRole[NucleotideRole[\"SUGAR\"] = 0] = \"SUGAR\";\n NucleotideRole[NucleotideRole[\"BASE\"] = 1] = \"BASE\";\n NucleotideRole[NucleotideRole[\"PHOSPHATE\"] = 2] = \"PHOSPHATE\";\n NucleotideRole[NucleotideRole[\"TERMINAL_5P\"] = 3] = \"TERMINAL_5P\";\n NucleotideRole[NucleotideRole[\"TERMINAL_3P\"] = 4] = \"TERMINAL_3P\";\n})(NucleotideRole || (NucleotideRole = {}));\nexport class MonomerMap extends Map {\n constructor(entries) {\n super(entries);\n }\n}\n/** @property monomers key - helm seq position, */\nexport class MolfileWithMap {\n constructor(molfile, monomers) {\n this.molfile = molfile;\n this.monomers = monomers;\n }\n static createEmpty() { return new MolfileWithMap('', new MonomerMap(null)); }\n}\n//# sourceMappingURL=types.js.map","import { MonomerTypes, PolymerTypes } from '../helm/consts';\n// hwe exports the HELM type vocabulary as `as const` objects (value-only), not\n// TS enums, so we re-create the value+type duality the old `import X = Enum`\n// aliases provided — consumers use these both as a value (`.RNA`) and as a type.\nconst HELM_POLYMER_TYPE = PolymerTypes;\nconst HELM_MONOMER_TYPE = MonomerTypes;\nexport { HELM_POLYMER_TYPE, HELM_MONOMER_TYPE };\n// core fields of HELM library object used in toAtomicLevel function\nexport const HELM_CORE_FIELDS = [\n \"symbol\" /* HELM_FIELDS.SYMBOL */,\n \"molfile\" /* HELM_FIELDS.MOLFILE */,\n \"rgroups\" /* HELM_FIELDS.RGROUPS */,\n \"name\" /* HELM_FIELDS.NAME */,\n // HELM_FIELDS.MONOMER_TYPE, // add if terminal monomers for PEPTIDEs to be\n // supported\n];\nexport const SDF_MONOMER_NAME = 'MonomerName';\n// todo: ideally, keys should be expressed via constants\nexport const jsonSdfMonomerLibDict = {\n 'monomerType': null, // -> Backbone\n 'smiles': null,\n 'name': 'Name',\n 'author': null,\n 'molfile': 'molecule',\n 'naturalAnalog': 'MonomerNaturalAnalogCode',\n 'rgroups': 'MonomerCaps',\n 'createDate': null,\n 'id': null,\n 'polymerType': 'MonomerType',\n 'symbol': 'MonomerName'\n};\nexport const DUMMY_MONOMER = {\n 'monomerType': 'Backbone',\n 'smiles': '',\n 'name': '',\n 'author': 'Datagrok',\n 'molfile': '',\n 'naturalAnalog': '',\n 'rgroups': [],\n 'createDate': null,\n 'id': 0,\n 'polymerType': 'PEPTIDE',\n 'symbol': ''\n};\n// range of hex nubers used in PepSea library to endode monomers\nexport const MONOMER_ENCODE_MIN = 0x100;\nexport const MONOMER_ENCODE_MAX = 0x40A;\nexport const RIBOSE_SYMBOL = 'r';\nexport const DEOXYRIBOSE_SYMBOL = 'd';\nexport const PHOSPHATE_SYMBOL = 'p';\nexport const HELM_WRAPPERS_REGEXP = new RegExp(`[${RIBOSE_SYMBOL}${DEOXYRIBOSE_SYMBOL}]\\\\((\\\\w)\\\\)${PHOSPHATE_SYMBOL}?`, 'g');\n//# sourceMappingURL=const.js.map","import { CandidateType } from './types';\n/** enum type to simplify setting \"user-friendly\" notation if necessary */\nexport var NOTATION;\n(function (NOTATION) {\n NOTATION[\"FASTA\"] = \"fasta\";\n NOTATION[\"SEPARATOR\"] = \"separator\";\n NOTATION[\"HELM\"] = \"helm\";\n /* Requires notation handler */ NOTATION[\"CUSTOM\"] = \"custom\";\n /* Requires notation handler */ NOTATION[\"BILN\"] = \"biln\";\n})(NOTATION || (NOTATION = {}));\nexport var ALPHABET;\n(function (ALPHABET) {\n ALPHABET[\"DNA\"] = \"DNA\";\n ALPHABET[\"RNA\"] = \"RNA\";\n ALPHABET[\"PT\"] = \"PT\";\n /** Unknown */\n ALPHABET[\"UN\"] = \"UN\";\n})(ALPHABET || (ALPHABET = {}));\nexport var TAGS;\n(function (TAGS) {\n TAGS[\"aligned\"] = \"aligned\";\n TAGS[\"alphabet\"] = \"alphabet\";\n TAGS[\"alphabetSize\"] = \".alphabetSize\";\n TAGS[\"alphabetIsMultichar\"] = \".alphabetIsMultichar\";\n TAGS[\"separator\"] = \"separator\";\n TAGS[\"isHelmCompatible\"] = \".isHelmCompatible\";\n TAGS[\"positionNames\"] = \".positionNames\";\n TAGS[\"positionLabels\"] = \".positionLabels\";\n TAGS[\"regions\"] = \".regions\";\n TAGS[\"positionShift\"] = \".positionShift\";\n TAGS[\"selectedPosition\"] = \".selectedPosition\";\n TAGS[\"polymerTypeColumnName\"] = \".polymerTypeColumnName\";\n TAGS[\"annotations\"] = \".annotations\";\n TAGS[\"numberingScheme\"] = \".numberingScheme\";\n TAGS[\"annotationColumnName\"] = \".annotationColumnName\";\n})(TAGS || (TAGS = {}));\nexport { TAGS as BioTags };\nexport const positionSeparator = ', ';\nexport const monomerRe = /(?:\\[([A-Za-z0-9_\\-,()]+)\\])|([A-Za-z\\-])/g;\nexport const helmRe = /(PEPTIDE1|DNA1|RNA1)\\{([^}]+)}/g;\nexport const helmPp1Re = /\\[([^\\[\\]]+)]/g;\nexport const Alphabets = new class {\n constructor() {\n this.fasta = {\n peptide: new Set([\n 'G', 'L', 'Y', 'S', 'E', 'Q', 'D', 'N', 'F', 'A',\n 'K', 'R', 'H', 'C', 'V', 'P', 'W', 'I', 'M', 'T',\n ]),\n dna: new Set(['A', 'C', 'G', 'T']),\n rna: new Set(['A', 'C', 'G', 'U']),\n };\n }\n}();\nexport const candidateAlphabets = [\n new CandidateType(ALPHABET.PT, Alphabets.fasta.peptide, 0.50),\n new CandidateType(ALPHABET.DNA, Alphabets.fasta.dna, 0.55),\n new CandidateType(ALPHABET.RNA, Alphabets.fasta.rna, 0.55),\n];\n/** Canonical gap symbol */\nexport const GAP_SYMBOL = '';\nexport const GapOriginals = {\n [NOTATION.FASTA]: '-',\n [NOTATION.SEPARATOR]: '',\n [NOTATION.HELM]: '*',\n [NOTATION.BILN]: '',\n};\nexport const MONOMER_MOTIF_SPLITTER = ' , ';\n/** Tag on Monomer columns storing the nqName of a function that returns an IMonomerCanonicalizer.\n * The `.%` prefix ensures this tag is persisted with projects. */\nexport const MONOMER_CANONICALIZER_FUNC_TAG = '.%monomer-canonicalizer-func';\n/** Column temp key for the cached IMonomerCanonicalizer instance */\nexport const MONOMER_CANONICALIZER_TEMP = 'monomer-canonicalizer';\nexport const NOTATION_PROVIDER_CONSTRUCTOR_ROLE = 'notationProviderConstructor';\n//# sourceMappingURL=consts.js.map","import { NOTATION_PROVIDER_CONSTRUCTOR_ROLE } from './consts';\nexport class NotationProviderBase {\n /** Name of the custom notation */\n static get notationName() {\n return 'Custom';\n }\n ;\n /** flag to let bio know if this provider implements method for converting helm to it */\n static get implementsFromHelm() {\n return false;\n }\n ;\n /** Method for converting HELM to this notation */\n static convertFromHelm(helm, options) {\n throw new Error(`Method convertFromHelm not implemented for this notation provider`);\n }\n ;\n static async getProviderConstructors() {\n // this is terrible, I know, but otherwise this gets put in webworkers and fails due to DG resolution)))\n // @ts-ignore\n if (window?.DG) {\n // @ts-ignore\n const constFuncs = window.DG.Func.find({ meta: { role: NOTATION_PROVIDER_CONSTRUCTOR_ROLE } });\n return Promise.all(constFuncs.map((f) => f.apply({})));\n }\n return [];\n }\n}\n/** Alphabet candidate type */\nexport class CandidateType {\n constructor(name, alphabet, cutoff) {\n this.name = name;\n this.alphabet = alphabet;\n this.cutoff = cutoff;\n }\n}\n/** Alphabet candidate similarity type */\nexport class CandidateSimType extends CandidateType {\n constructor(candidate, freq, similarity) {\n super(candidate.name, candidate.alphabet, candidate.cutoff);\n this.freq = freq;\n this.similarity = similarity;\n }\n}\n//# sourceMappingURL=types.js.map","import { HelmTypes, PolymerTypes } from '../helm/consts';\nexport class MonomerWorks {\n //private molfileConverter: IMolfileConverter;\n constructor(monomerLib /*, molfileConverter: IMolfileConverter*/) {\n this.monomerLib = monomerLib;\n //this.molfileConverter = molfileConverter;\n }\n //types according to Monomer possible\n getCappedRotatedMonomer(monomerType, monomerName) {\n // TODO: Check type of monomerType arg\n const monomer = this.monomerLib.getMonomer(monomerType, monomerName);\n if (monomer)\n return monomer.molfile; //TODO cap\n return null;\n }\n}\nexport function helmTypeToPolymerType(helmType) {\n let polymerType = undefined;\n switch (helmType) {\n case HelmTypes.BASE:\n case HelmTypes.SUGAR: // r - ribose, d - deoxyribose\n case HelmTypes.LINKER: // p - phosphate\n case HelmTypes.NUCLEOTIDE:\n // @ts-ignore\n case 'nucleotide':\n polymerType = PolymerTypes.RNA;\n break;\n case HelmTypes.AA:\n polymerType = PolymerTypes.PEPTIDE;\n break;\n case HelmTypes.CHEM:\n polymerType = PolymerTypes.CHEM;\n break;\n case HelmTypes.BLOB:\n polymerType = PolymerTypes.BLOB;\n break;\n default:\n polymerType = PolymerTypes.PEPTIDE;\n console.warn(`Unexpected HelmType '${helmType}'`);\n }\n return polymerType;\n}\n//# sourceMappingURL=monomer-works.js.map","/* eslint-disable max-len */\nimport { monomerWorksConsts as C } from './consts';\nimport { getMolGraph, MolfileWithMap, MonomerMap, NucleotideRole } from './types';\nimport { HELM_CORE_FIELDS, HELM_POLYMER_TYPE, HELM_MONOMER_TYPE, } from '../utils/const';\nimport { ALPHABET, GAP_SYMBOL } from '../utils/macromolecule/consts';\nimport { helmTypeToPolymerType } from './monomer-works';\n/** Get a mapping of peptide symbols to HELM monomer library objects with selected fields.\n * @param {IMonomerLib} monomerLib - Monomer library\n * @param {HELM_POLYMER_TYPE} polymerType - Polymer type\n * @param {ALPHABET} alphabet - Alphabet of the column\n * @return {Map<string, any>} - Mapping of peptide symbols to HELM monomer library objects with selected fields*/\nexport function getFormattedMonomerLib(monomerLib, polymerType, alphabet) {\n const map = new Map();\n for (const monomerSymbol of monomerLib.getMonomerSymbolsByType(polymerType)) {\n const it = monomerLib.getMonomer(polymerType, monomerSymbol);\n if (\n // RNA: all branch monomers (bases) and all backbone monomers (sugars +\n // phosphates, including modified ones). Modifications are looked up by\n // symbol at assembly time, so they MUST be present in the formatted lib.\n polymerType === HELM_POLYMER_TYPE.RNA || (polymerType === HELM_POLYMER_TYPE.PEPTIDE &&\n it[\"monomerType\" /* HELM_FIELDS.MONOMER_TYPE */] !== HELM_MONOMER_TYPE.BRANCH)) {\n const monomerObject = {};\n HELM_CORE_FIELDS.forEach((field) => {\n //@ts-ignore\n monomerObject[field] = it[field];\n });\n map.set(monomerSymbol, monomerObject);\n }\n }\n return map;\n}\n/** Translate a sequence of monomer symbols into Molfile V3000\n * @param {ISeqMonomer[]} monomerSeq - Sequence of monomer symbols (canonical)\n * @param {MonomerMolGraphMap} monomersDict - Mapping of monomer symbols to MolGraph objects\n * @param {ALPHABET} alphabet - Alphabet of the column\n * @param {PolymerType} polymerType - Polymer type\n * @param {Array} roles - Optional per-position NucleotideRole tags. When set, RNA assembly\n * uses per-position sugars/phosphates from monomerSeq directly (HELM triples mode).\n * @return {MolfileWithMap} - Molfile V3000 + per-position monomer index map */\nexport function monomerSeqToMolfile(monomerSeq, monomersDict, alphabet, polymerType, roles) {\n if (monomerSeq.length === 0) {\n // throw new Error('monomerSeq is empty');\n return MolfileWithMap.createEmpty();\n }\n // Triples mode is on only when the caller flagged the row with roles\n // (built and validated by `buildRolesForHelmRna` in to-atomic-level.ts).\n // The roles array carries the per-position semantics — including\n // TERMINAL_5P / TERMINAL_3P for non-canonical chain ends — so we don't\n // re-validate the length here.\n const triplesMode = polymerType === HELM_POLYMER_TYPE.RNA && !!roles &&\n roles.length === monomerSeq.length;\n // define atom and bond counts, taking into account the bond type\n const { atomCount, bondCount, needsCapping } = getResultingAtomBondCounts(monomerSeq, monomersDict, alphabet, polymerType, triplesMode, roles);\n // create arrays to store lines of the resulting molfile\n const molfileAtomBlock = new Array(atomCount);\n const molfileBondBlock = new Array(bondCount);\n let addMonomerToMolblock;\n let sugar = null;\n let phosphate = null;\n if (polymerType === HELM_POLYMER_TYPE.PEPTIDE)\n addMonomerToMolblock = addAminoAcidToMolblock;\n else { // nucleotides\n addMonomerToMolblock = addNucleotideToMolblock;\n // Default sugar/phosphate are only consulted in bases-only mode. In\n // triples mode, every nucleotide carries its own.\n if (!triplesMode) {\n sugar = (alphabet === ALPHABET.DNA) ? getMolGraph(monomersDict, C.DEOXYRIBOSE) : getMolGraph(monomersDict, C.RIBOSE);\n phosphate = getMolGraph(monomersDict, C.PHOSPHATE);\n }\n }\n const v = {\n i: 0,\n nodeShift: 0,\n bondShift: 0,\n backbonePositionShift: new Array(2).fill(0),\n branchPositionShift: new Array(2).fill(0),\n backboneAttachNode: 0,\n branchAttachNode: 0,\n flipFactor: 1,\n };\n const LC = {\n sugar: sugar,\n phosphate: phosphate,\n // In triples mode, the \"logical\" sequence length is the nucleotide count.\n seqLength: triplesMode ? Math.ceil(monomerSeq.length / 3) : monomerSeq.length,\n atomCount: atomCount,\n bondCount: bondCount,\n };\n const monomers = new MonomerMap();\n const steabsCollection = [];\n let nAtoms = 0;\n let lastMonomerCappingAtom = undefined;\n if (triplesMode) {\n runTriplesAssembly(monomerSeq, roles, monomersDict, molfileAtomBlock, molfileBondBlock, v, LC, monomers, steabsCollection, (a) => { nAtoms += a; }, () => nAtoms);\n }\n else {\n for (v.i = 0; v.i < LC.seqLength; ++v.i) {\n const seqMonomer = monomerSeq[v.i];\n if (seqMonomer.symbol === GAP_SYMBOL)\n continue;\n const monomer = getMolGraph(monomersDict, { symbol: seqMonomer.symbol, polymerType: helmTypeToPolymerType(seqMonomer.biotype) });\n lastMonomerCappingAtom = monomer.terminalR2Atom;\n const mAtomFirst = v.nodeShift;\n const mBondFirst = v.bondShift;\n addMonomerToMolblock(monomer, molfileAtomBlock, molfileBondBlock, v, LC);\n //adding stereo atoms to array for further STEABS block generation\n monomer.stereoAtoms?.forEach((i) => steabsCollection.push(i + nAtoms));\n nAtoms += monomer.atoms.x.length;\n const mAtomCount = v.nodeShift - mAtomFirst;\n const mAtomList = new Array(mAtomCount);\n for (let maI = 0; maI < mAtomCount; ++maI)\n mAtomList[maI] = mAtomFirst + maI;\n const mBondCount = v.bondShift - mBondFirst;\n const mBondList = new Array(mBondCount);\n for (let mbI = 0; mbI < mBondCount; ++mbI)\n mBondList[mbI] = mBondFirst + mbI;\n monomers.set(v.i, {\n biotype: seqMonomer.biotype,\n symbol: seqMonomer.symbol,\n atoms: mAtomList, bonds: mBondList\n });\n }\n }\n // if the last monomer needs to be capped, add the terminal OH to the resulting molfile\n if (needsCapping)\n capResultingMolblock(molfileAtomBlock, molfileBondBlock, v, LC, lastMonomerCappingAtom ?? C.OXYGEN);\n const molfileCountsLine = C.V3K_BEGIN_COUNTS_LINE + atomCount + ' ' + bondCount + C.V3K_COUNTS_LINE_ENDING;\n // todo: possible optimization may be achieved by replacing .join('') with +=\n // since counterintuitively joining an array into a new string is reportedly\n // slower than using += as below\n let result = '';\n result += C.V3K_HEADER_FIRST_LINE;\n result += C.V3K_HEADER_SECOND_LINE;\n result += C.V3K_BEGIN_CTAB_BLOCK;\n result += molfileCountsLine;\n result += C.V3K_BEGIN_ATOM_BLOCK;\n result += molfileAtomBlock.join('');\n result += C.V3K_END_ATOM_BLOCK;\n result += C.V3K_BEGIN_BOND_BLOCK;\n result += molfileBondBlock.join('');\n result += C.V3K_END_BOND_BLOCK;\n if (steabsCollection.length > 0)\n result += getCollectionBlock(steabsCollection);\n result += C.V3K_END_CTAB_BLOCK;\n result += C.V3K_END;\n // return molfileParts.join('');\n return { molfile: result, monomers: monomers };\n}\nfunction getCollectionBlock(collection) {\n //one row in STEABS block can be no longer than 80 symbols\n //maxSymbols = 80 symbols minus ' -\\n' (4 symbols)\n const maxSymbols = 76;\n const rowsArray = [];\n let newCollectionRow = `M V30 MDLV30/STEABS ATOMS=(${collection.length}`;\n for (let i = 0; i < collection.length; i++) {\n const updatedRow = `${newCollectionRow} ${collection[i]}`;\n if (updatedRow.length > maxSymbols) {\n rowsArray.push(`${newCollectionRow} -\\n`);\n newCollectionRow = `M V30 ${collection[i]}`;\n }\n else\n newCollectionRow = updatedRow;\n //in case last atom was added - close the block\n if (i === collection.length - 1)\n rowsArray.push(`${newCollectionRow})\\n`);\n }\n return `M V30 BEGIN COLLECTION\\n${rowsArray.join('')}M V30 END COLLECTION\\n`;\n}\n/** Cap the resulting (after sewing up all the monomers) molfile with 'O'\n * @param {string[]} molfileAtomBlock - Array of lines of the resulting molfile atom block\n * @param {string[]} molfileBondBlock - Array of lines of the resulting molfile bond block\n * @param {LoopVariables} v - Loop variables\n * @param {LoopConstants} LC - Loop constants*/\nfunction capResultingMolblock(molfileAtomBlock, molfileBondBlock, v, LC, cappingAtomType = C.OXYGEN) {\n // add terminal oxygen\n const atomIdx = v.nodeShift + 1;\n molfileAtomBlock[LC.atomCount] = C.V3K_BEGIN_DATA_LINE + atomIdx + ' ' +\n (cappingAtomType ?? C.OXYGEN) + ' ' + keepPrecision(v.backbonePositionShift[0]) + ' ' +\n v.flipFactor * keepPrecision(v.backbonePositionShift[1]) + ' ' + '0.000000 0' + '\\n';\n // add terminal bond\n const firstAtom = v.backboneAttachNode;\n const secondAtom = atomIdx;\n molfileBondBlock[LC.bondCount] = C.V3K_BEGIN_DATA_LINE + v.bondShift + ' ' +\n 1 + ' ' + firstAtom + ' ' + secondAtom + '\\n';\n}\nfunction addAminoAcidToMolblock(monomer, molfileAtomBlock, molfileBondBlock, v) {\n v.flipFactor = (-1) ** (v.i % 2); // to flip every even monomer over OX\n addBackboneMonomerToMolblock(monomer, molfileAtomBlock, molfileBondBlock, v);\n}\nfunction addBackboneMonomerToMolblock(monomer, molfileAtomBlock, molfileBondBlock, v) {\n // todo: remove these comments to the docstrings of the corr. functions\n // construnct the lines of V3K molfile atom block\n fillAtomLines(monomer, molfileAtomBlock, v);\n // construct the lines of V3K molfile bond block\n fillBondLines(monomer, molfileBondBlock, v);\n // peptide bond\n fillChainExtendingBond(monomer, molfileBondBlock, v);\n // update branch variables if necessary\n if (monomer.meta.branchShift !== null && monomer.meta.terminalNodes.length > 2)\n updateBranchVariables(monomer, v);\n // update loop variables\n updateChainExtendingVariables(monomer, v);\n}\nfunction addNucleotideToMolblock(nucleobase, molfileAtomBlock, molfileBondBlock, v, LC) {\n // construnct the lines of V3K molfile atom block corresponding to phosphate\n // and sugar\n if (v.i === 0)\n addBackboneMonomerToMolblock(LC.sugar, molfileAtomBlock, molfileBondBlock, v);\n else {\n for (const monomer of [LC.phosphate, LC.sugar])\n addBackboneMonomerToMolblock(monomer, molfileAtomBlock, molfileBondBlock, v);\n }\n addBranchMonomerToMolblock(nucleobase, molfileAtomBlock, molfileBondBlock, v);\n}\nfunction addBranchMonomerToMolblock(monomer, molfileAtomBlock, molfileBondBlock, v) {\n fillBranchAtomLines(monomer, molfileAtomBlock, v);\n fillBondLines(monomer, molfileBondBlock, v);\n fillBackboneToBranchBond(monomer, molfileBondBlock, v);\n // C-N bond\n const bondIdx = v.bondShift;\n const firstAtom = v.branchAttachNode;\n const secondAtom = monomer.meta.terminalNodes[0] + v.nodeShift;\n molfileBondBlock[bondIdx - 1] = C.V3K_BEGIN_DATA_LINE + bondIdx + ' ' +\n 1 + ' ' + firstAtom + ' ' + secondAtom + '\\n';\n // update loop variables\n v.bondShift += monomer.bonds.atomPairs.length + 1;\n v.nodeShift += monomer.atoms.atomTypes.length;\n}\nfunction updateChainExtendingVariables(monomer, v) {\n v.backboneAttachNode = v.nodeShift + monomer.meta.terminalNodes[1];\n v.bondShift += monomer.bonds.atomPairs.length + 1;\n v.nodeShift += monomer.atoms.atomTypes.length;\n v.backbonePositionShift[0] += monomer.meta.backboneShift?.[0] ?? 0; // todo: non-null check\n v.backbonePositionShift[1] += v.flipFactor * (monomer.meta.backboneShift?.[1] ?? 0);\n}\nfunction updateBranchVariables(monomer, v) {\n v.branchAttachNode = v.nodeShift + monomer.meta.terminalNodes[2];\n for (let i = 0; i < 2; ++i)\n v.branchPositionShift[i] = v.backbonePositionShift[i] + monomer.meta.branchShift[i];\n}\nfunction fillAtomLines(monomer, molfileAtomBlock, v) {\n for (let j = 0; j < monomer.atoms.atomTypes.length; ++j) {\n const atomIdx = v.nodeShift + j + 1;\n molfileAtomBlock[v.nodeShift + j] = C.V3K_BEGIN_DATA_LINE + atomIdx + ' ' +\n monomer.atoms.atomTypes[j] + ' ' +\n keepPrecision(v.backbonePositionShift[0] + monomer.atoms.x[j]) + ' ' +\n keepPrecision(v.backbonePositionShift[1] + v.flipFactor * monomer.atoms.y[j]) +\n ' ' + monomer.atoms.kwargs[j];\n }\n}\n// todo: remove as quickfix\nfunction fillBranchAtomLines(monomer, molfileAtomBlock, v) {\n for (let j = 0; j < monomer.atoms.atomTypes.length; ++j) {\n const atomIdx = v.nodeShift + j + 1;\n molfileAtomBlock[v.nodeShift + j] = C.V3K_BEGIN_DATA_LINE + atomIdx + ' ' +\n monomer.atoms.atomTypes[j] + ' ' +\n keepPrecision(v.branchPositionShift[0] + monomer.atoms.x[j]) + ' ' +\n keepPrecision(v.branchPositionShift[1] + v.flipFactor * monomer.atoms.y[j]) +\n ' ' + monomer.atoms.kwargs[j];\n }\n}\nfunction fillBondLines(monomer, molfileBondBlock, v) {\n // construct the lines of V3K molfile bond block\n for (let j = 0; j < monomer.bonds.atomPairs.length; ++j) {\n const bondIdx = v.bondShift + j + 1;\n const firstAtom = monomer.bonds.atomPairs[j][0] + v.nodeShift;\n const secondAtom = monomer.bonds.atomPairs[j][1] + v.nodeShift;\n let bondCfg = '';\n if (monomer.bonds.bondConfiguration.has(j)) {\n // flip orientation when necessary\n let orientation = monomer.bonds.bondConfiguration.get(j);\n if (v.flipFactor < 0)\n orientation = (orientation === 1) ? 3 : 1;\n bondCfg = ' CFG=' + orientation;\n }\n const kwargs = monomer.bonds.kwargs.has(j) ?\n ' ' + monomer.bonds.kwargs.get(j) : '';\n molfileBondBlock[v.bondShift + j] = C.V3K_BEGIN_DATA_LINE + bondIdx + ' ' +\n monomer.bonds.bondTypes[j] + ' ' +\n firstAtom + ' ' + secondAtom + bondCfg + kwargs + '\\n';\n }\n}\nfunction fillChainExtendingBond(monomer, molfileBondBlock, v) {\n if (v.backboneAttachNode !== 0) {\n const bondIdx = v.bondShift;\n const firstAtom = v.backboneAttachNode;\n const secondAtom = monomer.meta.terminalNodes[0] + v.nodeShift;\n molfileBondBlock[v.bondShift - 1] = C.V3K_BEGIN_DATA_LINE + bondIdx + ' ' +\n 1 + ' ' + firstAtom + ' ' + secondAtom + '\\n';\n }\n}\n// todo: remove\nfunction fillBackboneToBranchBond(branchMonomer, molfileBondBlock, v) {\n const bondIdx = v.bondShift;\n const firstAtom = v.branchAttachNode;\n const secondAtom = branchMonomer.meta.terminalNodes[0] + v.nodeShift;\n molfileBondBlock[bondIdx - 1] = C.V3K_BEGIN_DATA_LINE + bondIdx + ' ' +\n 1 + ' ' + firstAtom + ' ' + secondAtom + '\\n';\n}\n/** Compute the atom/bond counts for the resulting molfile, depending on the\n * type of polymer (peptide/nucleotide)\n * @param {ISeqMonomer[]} monomerSeq - the sequence of monomers\n * @param {MonomerMolGraphMap} monomersDict - the dictionary of monomers\n * @param {ALPHABET} alphabet - the alphabet of the monomers\n * @param {PolymerType} polymerType - the type of polymer\n * @param {boolean} triplesMode - true when monomerSeq is a flat list of HELM RNA triples\n * @param {Array} roles - per-position role tags (only meaningful when triplesMode is true)\n * @return {Object} the atom/bond counts plus needsCapping flag */\nfunction getResultingAtomBondCounts(monomerSeq, monomersDict, alphabet, polymerType, triplesMode, roles) {\n let atomCount = 0;\n let bondCount = 0;\n let monomerCount = 0;\n let needsCapping = true;\n let lastMonomerGraph = null;\n let lastPhosphateGraph = null;\n // sum up all the atoms/nodes provided by the sequence\n for (let i = 0; i < monomerSeq.length; ++i) {\n const seqMonomer = monomerSeq[i];\n if (seqMonomer.symbol === GAP_SYMBOL)\n continue; // Skip for gap/empty monomer in MSA\n if (seqMonomer.symbol == '*')\n throw new Error(`Gap canonical symbol is '', not '*`);\n lastMonomerGraph = getMolGraph(monomersDict, { symbol: seqMonomer.symbol, polymerType: helmTypeToPolymerType(seqMonomer.biotype) });\n atomCount += lastMonomerGraph.atoms.x.length;\n bondCount += lastMonomerGraph.bonds.bondTypes.length;\n monomerCount++;\n // In triples mode, every 3rd entry (index 2 mod 3) is a phosphate. Track\n // the LAST one — its atoms/bonds are dropped at the 3'-terminus.\n if (triplesMode && i % 3 === 2)\n lastPhosphateGraph = lastMonomerGraph;\n }\n // add extra values depending on the polymer type\n if (polymerType === HELM_POLYMER_TYPE.PEPTIDE) {\n // add the rightmost/terminating cap group 'OH' (i.e. 'O')\n atomCount += 1;\n // add chain-extending bonds (C-NH per each monomer pair and terminal C-OH)\n bondCount += monomerCount;\n // if the last monomer is something like NH2, which only has R1, there is no need to cap it\n // although, this should never happen, but hey... in other bits of code, there is a chunk that adds pseudo-R2 as hydrogen\n // we should also check, if the R2 of the last monomer is not hydrogen, that case should also be omitted\n if (monomerCount > 0) {\n if ((lastMonomerGraph?.meta?.rNodes?.length ?? 0) < 2 || lastMonomerGraph?.terminalR2Atom?.toLowerCase() === C.HYDROGEN.toLowerCase()) {\n needsCapping = false;\n atomCount -= 1; // remove the last atom (the terminal 'O')\n bondCount -= 1; // remove the last bond (the terminal C-OH)\n }\n }\n }\n else if (triplesMode) { // nucleotides — HELM triples (per-position sugar/base/phosphate)\n void lastPhosphateGraph; // kept for symmetry; trailing P is now retained when HELM wrote it\n // Per-monomer-loop already summed sugars + bases + phosphates for every\n // entry in monomerSeq (terminals included). Reservation: each backbone\n // emit (sugar / phosphate / terminal) reserves +1 bond slot for the\n // chain-extending bond, each branch (base) reserves +1 for its branch\n // bond. Total reservations = monomerCount.\n bondCount += monomerCount;\n // OH cap atom rides on the 3'-end. Skip it when HELM specified a\n // 3'-terminal modifier (e.g. GalNAc) that IS the chain end.\n const has3pTerm = !!roles && roles.length > 0 &&\n roles[roles.length - 1] === NucleotideRole.TERMINAL_3P;\n if (has3pTerm) {\n needsCapping = false;\n // Mirror the peptide branch (which does both atomCount-- and bondCount--\n // when it skips the terminal cap). `bondCount += monomerCount` above\n // reserves one chain-extending slot per monomer; the LAST monomer's slot\n // is normally filled by the terminal OH cap bond. With a 3'-terminal\n // modifier there is no cap, so that last reserved slot stays empty —\n // leaving the declared bond count one higher than the emitted bond\n // lines. Drop it so the V3000 COUNTS line matches the bond block exactly\n // (otherwise the pre-OCL molfile is malformed and only survives because\n // the OCL chirality pass re-derives the counts).\n bondCount -= 1;\n }\n else\n atomCount += 1; // OH cap atom (rides on trailing P or on last sugar's R2)\n }\n else { // nucleotides — bases-only legacy path with default sugar/phosphate\n const sugar = (alphabet === ALPHABET.DNA) ?\n getMolGraph(monomersDict, C.DEOXYRIBOSE) : getMolGraph(monomersDict, C.RIBOSE);\n const phosphate = getMolGraph(monomersDict, C.PHOSPHATE);\n // add phosphate per each pair of nucleobase symbols\n atomCount += (monomerSeq.length - 1) * phosphate.atoms.x.length;\n // add sugar per each nucleobase symbol\n atomCount += monomerSeq.length * sugar.atoms.x.length;\n // add the leftmost cap group 'OH' (i.e. 'O')\n atomCount += 1;\n // add bonds from phosphate monomers\n bondCount += (monomerSeq.length - 1) * phosphate.bonds.bondTypes.length;\n // add bonds from sugar monomers\n bondCount += monomerSeq.length * sugar.bonds.bondTypes.length;\n // exclude the first chain-extending bond O-P (absent, no 'leftmost' phosphate)\n bondCount -= 1;\n // add chain-extending and branch bonds (O-P, C-O and C-N per each nucleotide)\n bondCount += monomerSeq.length * 3;\n }\n return { atomCount, bondCount, needsCapping };\n}\n// Role-driven RNA assembly. Walks the monomers in chain order and emits\n// each one according to its NucleotideRole (assigned by `buildRolesForHelmRna`\n// from the library, not from a fixed triple index):\n// - BASE → branch monomer, attached to the\n// branch point of the sugar most\n// recently emitted.\n// - SUGAR / PHOSPHATE / TERMINAL_5P / 3P → backbone monomer, chained to the\n// previous backbone unit.\n//\n// Because the role comes from chemistry, this transparently handles every\n// backbone layout — standard [sugar, base, phosphate] triples, a 5'-leading\n// phosphate, several phosphates / linkers in a row, a linker dropped in the\n// middle of the chain, missing trailing phosphate, and 5'/3' terminal\n// modifiers — without any index arithmetic. The first backbone monomer\n// naturally has no incoming chain bond (v.backboneAttachNode starts at 0),\n// and the trailing OH cap is added by the caller via needsCapping (skipped\n// when a TERMINAL_3P ends the chain).\nfunction runTriplesAssembly(monomerSeq, roles, monomersDict, molfileAtomBlock, molfileBondBlock, v, LC, monomers, steabsCollection, addAtoms, getAtoms) {\n void LC; // assembly is driven by per-monomer roles, not by LC.seqLength\n for (let i = 0; i < monomerSeq.length; ++i) {\n const sm = monomerSeq[i];\n if (sm.symbol === GAP_SYMBOL)\n continue;\n const role = roles[i];\n const mG = getMolGraph(monomersDict, { symbol: sm.symbol, polymerType: helmTypeToPolymerType(sm.biotype) });\n const aFirst = v.nodeShift;\n const bFirst = v.bondShift;\n v.i = i; // keep loop counter monotone (unused by nucleotide geometry)\n if (role === NucleotideRole.BASE)\n // Branch: attaches to v.branchAttachNode, set when the preceding sugar\n // was emitted. Does not advance the backbone, so the next backbone unit\n // still chains from that sugar's 3' side.\n addBranchMonomerToMolblock(mG, molfileAtomBlock, molfileBondBlock, v);\n else\n // Backbone: sugar / phosphate / linker / terminal modifier. Chains from\n // the previous backbone unit (none for the very first one) and, for a\n // sugar, sets up the branch attach point for the next base.\n addBackboneMonomerToMolblock(mG, molfileAtomBlock, molfileBondBlock, v);\n mG.stereoAtoms?.forEach((s) => steabsCollection.push(s + getAtoms()));\n addAtoms(mG.atoms.x.length);\n const aList = [];\n for (let a = aFirst; a < v.nodeShift; ++a)\n aList.push(a);\n const bList = [];\n for (let b = bFirst; b < v.bondShift; ++b)\n bList.push(b);\n monomers.set(i, { biotype: sm.biotype, symbol: sm.symbol, atoms: aList, bonds: bList });\n }\n}\n/** Keep precision upon floating point operations over atom coordinates\n * @param {number}x - the floating point number\n * @return {number} - the floating point number with the same precision\n */\nexport function keepPrecision(x) {\n return Math.round(C.PRECISION_FACTOR * x) / C.PRECISION_FACTOR;\n}\n//# sourceMappingURL=to-atomic-level-utils.js.map","import { monomerSeqToMolfile } from './to-atomic-level-utils';\nonmessage = (event) => {\n const { seqList, rolesList, monomersDict, alphabet, polymerType, start, end } = event.data;\n const resMolList = new Array(end - start);\n const molfileWarningList = new Array(0);\n for (let rowI = start; rowI < end; ++rowI) {\n try {\n const seq = seqList[rowI];\n const roles = rolesList ? rolesList[rowI] : undefined;\n resMolList[rowI - start] = monomerSeqToMolfile(seq, monomersDict, alphabet, polymerType, roles);\n }\n catch (err) {\n const errMsg = err instanceof Error ? err.message : err.toString();\n const msg = `Cannot get molfile of row #${rowI}: ${errMsg}.`;\n molfileWarningList.push(msg);\n }\n }\n postMessage({ molfiles: resMolList, warnings: molfileWarningList });\n};\n//# sourceMappingURL=seq-to-molfile-worker.js.map","/**\n * @module LRUCache\n */\nconst perf = typeof performance === 'object' &&\n performance &&\n typeof performance.now === 'function'\n ? performance\n : Date;\nconst warned = new Set();\n/* c8 ignore start */\nconst PROCESS = (typeof process === 'object' && !!process ? process : {});\n/* c8 ignore start */\nconst emitWarning = (msg, type, code, fn) => {\n typeof PROCESS.emitWarning === 'function'\n ? PROCESS.emitWarning(msg, type, code, fn)\n : console.error(`[${code}] ${type}: ${msg}`);\n};\nlet AC = globalThis.AbortController;\nlet AS = globalThis.AbortSignal;\n/* c8 ignore start */\nif (typeof AC === 'undefined') {\n //@ts-ignore\n AS = class AbortSignal {\n onabort;\n _onabort = [];\n reason;\n aborted = false;\n addEventListener(_, fn) {\n this._onabort.push(fn);\n }\n };\n //@ts-ignore\n AC = class AbortController {\n constructor() {\n warnACPolyfill();\n }\n signal = new AS();\n abort(reason) {\n if (this.signal.aborted)\n return;\n //@ts-ignore\n this.signal.reason = reason;\n //@ts-ignore\n this.signal.aborted = true;\n //@ts-ignore\n for (const fn of this.signal._onabort) {\n fn(reason);\n }\n this.signal.onabort?.(reason);\n }\n };\n let printACPolyfillWarning = PROCESS.env?.LRU_CACHE_IGNORE_AC_WARNING !== '1';\n const warnACPolyfill = () => {\n if (!printACPolyfillWarning)\n return;\n printACPolyfillWarning = false;\n emitWarning('AbortController is not defined. If using lru-cache in ' +\n 'node 14, load an AbortController polyfill from the ' +\n '`node-abort-controller` package. A minimal polyfill is ' +\n 'provided for use by LRUCache.fetch(), but it should not be ' +\n 'relied upon in other contexts (eg, passing it to other APIs that ' +\n 'use AbortController/AbortSignal might have undesirable effects). ' +\n 'You may disable this with LRU_CACHE_IGNORE_AC_WARNING=1 in the env.', 'NO_ABORT_CONTROLLER', 'ENOTSUP', warnACPolyfill);\n };\n}\n/* c8 ignore stop */\nconst shouldWarn = (code) => !warned.has(code);\nconst TYPE = Symbol('type');\nconst isPosInt = (n) => n && n === Math.floor(n) && n > 0 && isFinite(n);\n/* c8 ignore start */\n// This is a little bit ridiculous, tbh.\n// The maximum array length is 2^32-1 or thereabouts on most JS impls.\n// And well before that point, you're caching the entire world, I mean,\n// that's ~32GB of just integers for the next/prev links, plus whatever\n// else to hold that many keys and values. Just filling the memory with\n// zeroes at init time is brutal when you get that big.\n// But why not be complete?\n// Maybe in the future, these limits will have expanded.\nconst getUintArray = (max) => !isPosInt(max)\n ? null\n : max <= Math.pow(2, 8)\n ? Uint8Array\n : max <= Math.pow(2, 16)\n ? Uint16Array\n : max <= Math.pow(2, 32)\n ? Uint32Array\n : max <= Number.MAX_SAFE_INTEGER\n ? ZeroArray\n : null;\n/* c8 ignore stop */\nclass ZeroArray extends Array {\n constructor(size) {\n super(size);\n this.fill(0);\n }\n}\nclass Stack {\n heap;\n length;\n // private constructor\n static #constructing = false;\n static create(max) {\n const HeapCls = getUintArray(max);\n if (!HeapCls)\n return [];\n Stack.#constructing = true;\n const s = new Stack(max, HeapCls);\n Stack.#constructing = false;\n return s;\n }\n constructor(max, HeapCls) {\n /* c8 ignore start */\n if (!Stack.#constructing) {\n throw new TypeError('instantiate Stack using Stack.create(n)');\n }\n /* c8 ignore stop */\n this.heap = new HeapCls(max);\n this.length = 0;\n }\n push(n) {\n this.heap[this.length++] = n;\n }\n pop() {\n return this.heap[--this.length];\n }\n}\n/**\n * Default export, the thing you're using this module to get.\n *\n * The `K` and `V` types define the key and value types, respectively. The\n * optional `FC` type defines the type of the `context` object passed to\n * `cache.fetch()` and `cache.memo()`.\n *\n * Keys and values **must not** be `null` or `undefined`.\n *\n * All properties from the options object (with the exception of `max`,\n * `maxSize`, `fetchMethod`, `memoMethod`, `dispose` and `disposeAfter`) are\n * added as normal public members. (The listed options are read-only getters.)\n *\n * Changing any of these will alter the defaults for subsequent method calls.\n */\nexport class LRUCache {\n // options that cannot be changed without disaster\n #max;\n #maxSize;\n #dispose;\n #disposeAfter;\n #fetchMethod;\n #memoMethod;\n /**\n * {@link LRUCache.OptionsBase.ttl}\n */\n ttl;\n /**\n * {@link LRUCache.OptionsBase.ttlResolution}\n */\n ttlResolution;\n /**\n * {@link LRUCache.OptionsBase.ttlAutopurge}\n */\n ttlAutopurge;\n /**\n * {@link LRUCache.OptionsBase.updateAgeOnGet}\n */\n updateAgeOnGet;\n /**\n * {@link LRUCache.OptionsBase.updateAgeOnHas}\n */\n updateAgeOnHas;\n /**\n * {@link LRUCache.OptionsBase.allowStale}\n */\n allowStale;\n /**\n * {@link LRUCache.OptionsBase.noDisposeOnSet}\n */\n noDisposeOnSet;\n /**\n * {@link LRUCache.OptionsBase.noUpdateTTL}\n */\n noUpdateTTL;\n /**\n * {@link LRUCache.OptionsBase.maxEntrySize}\n */\n maxEntrySize;\n /**\n * {@link LRUCache.OptionsBase.sizeCalculation}\n */\n sizeCalculation;\n /**\n * {@link LRUCache.OptionsBase.noDeleteOnFetchRejection}\n */\n noDeleteOnFetchRejection;\n /**\n * {@link LRUCache.OptionsBase.noDeleteOnStaleGet}\n */\n noDeleteOnStaleGet;\n /**\n * {@link LRUCache.OptionsBase.allowStaleOnFetchAbort}\n */\n allowStaleOnFetchAbort;\n /**\n * {@link LRUCache.OptionsBase.allowStaleOnFetchRejection}\n */\n allowStaleOnFetchRejection;\n /**\n * {@link LRUCache.OptionsBase.ignoreFetchAbort}\n */\n ignoreFetchAbort;\n // computed properties\n #size;\n #calculatedSize;\n #keyMap;\n #keyList;\n #valList;\n #next;\n #prev;\n #head;\n #tail;\n #free;\n #disposed;\n #sizes;\n #starts;\n #ttls;\n #hasDispose;\n #hasFetchMethod;\n #hasDisposeAfter;\n /**\n * Do not call this method unless you need to inspect the\n * inner workings of the cache. If anything returned by this\n * object is modified in any way, strange breakage may occur.\n *\n * These fields are private for a reason!\n *\n * @internal\n */\n static unsafeExposeInternals(c) {\n return {\n // properties\n starts: c.#starts,\n ttls: c.#ttls,\n sizes: c.#sizes,\n keyMap: c.#keyMap,\n keyList: c.#keyList,\n valList: c.#valList,\n next: c.#next,\n prev: c.#prev,\n get head() {\n return c.#head;\n },\n get tail() {\n return c.#tail;\n },\n free: c.#free,\n // methods\n isBackgroundFetch: (p) => c.#isBackgroundFetch(p),\n backgroundFetch: (k, index, options, context) => c.#backgroundFetch(k, index, options, context),\n moveToTail: (index) => c.#moveToTail(index),\n indexes: (options) => c.#indexes(options),\n rindexes: (options) => c.#rindexes(options),\n isStale: (index) => c.#isStale(index),\n };\n }\n // Protected read-only members\n /**\n * {@link LRUCache.OptionsBase.max} (read-only)\n */\n get max() {\n return this.#max;\n }\n /**\n * {@link LRUCache.OptionsBase.maxSize} (read-only)\n */\n get maxSize() {\n return this.#maxSize;\n }\n /**\n * The total computed size of items in the cache (read-only)\n */\n get calculatedSize() {\n return this.#calculatedSize;\n }\n /**\n * The number of items stored in the cache (read-only)\n */\n get size() {\n return this.#size;\n }\n /**\n * {@link LRUCache.OptionsBase.fetchMethod} (read-only)\n */\n get fetchMethod() {\n return this.#fetchMethod;\n }\n get memoMethod() {\n return this.#memoMethod;\n }\n /**\n * {@link LRUCache.OptionsBase.dispose} (read-only)\n */\n get dispose() {\n return this.#dispose;\n }\n /**\n * {@link LRUCache.OptionsBase.disposeAfter} (read-only)\n */\n get disposeAfter() {\n return this.#disposeAfter;\n }\n constructor(options) {\n const { max = 0, ttl, ttlResolution = 1, ttlAutopurge, updateAgeOnGet, updateAgeOnHas, allowStale, dispose, disposeAfter, noDisposeOnSet, noUpdateTTL, maxSize = 0, maxEntrySize = 0, sizeCalculation, fetchMethod, memoMethod, noDeleteOnFetchRejection, noDeleteOnStaleGet, allowStaleOnFetchRejection, allowStaleOnFetchAbort, ignoreFetchAbort, } = options;\n if (max !== 0 && !isPosInt(max)) {\n throw new TypeError('max option must be a nonnegative integer');\n }\n const UintArray = max ? getUintArray(max) : Array;\n if (!UintArray) {\n throw new Error('invalid max value: ' + max);\n }\n this.#max = max;\n this.#maxSize = maxSize;\n this.maxEntrySize = maxEntrySize || this.#maxSize;\n this.sizeCalculation = sizeCalculation;\n if (this.sizeCalculation) {\n if (!this.#maxSize && !this.maxEntrySize) {\n throw new TypeError('cannot set sizeCalculation without setting maxSize or maxEntrySize');\n }\n if (typeof this.sizeCalculation !== 'function') {\n throw new TypeError('sizeCalculation set to non-function');\n }\n }\n if (memoMethod !== undefined &&\n typeof memoMethod !== 'function') {\n throw new TypeError('memoMethod must be a function if defined');\n }\n this.#memoMethod = memoMethod;\n if (fetchMethod !== undefined &&\n typeof fetchMethod !== 'function') {\n throw new TypeError('fetchMethod must be a function if specified');\n }\n this.#fetchMethod = fetchMethod;\n this.#hasFetchMethod = !!fetchMethod;\n this.#keyMap = new Map();\n this.#keyList = new Array(max).fill(undefined);\n this.#valList = new Array(max).fill(undefined);\n this.#next = new UintArray(max);\n this.#prev = new UintArray(max);\n this.#head = 0;\n this.#tail = 0;\n this.#free = Stack.create(max);\n this.#size = 0;\n this.#calculatedSize = 0;\n if (typeof dispose === 'function') {\n this.#dispose = dispose;\n }\n if (typeof disposeAfter === 'function') {\n this.#disposeAfter = disposeAfter;\n this.#disposed = [];\n }\n else {\n this.#disposeAfter = undefined;\n this.#disposed = undefined;\n }\n this.#hasDispose = !!this.#dispose;\n this.#hasDisposeAfter = !!this.#disposeAfter;\n this.noDisposeOnSet = !!noDisposeOnSet;\n this.noUpdateTTL = !!noUpdateTTL;\n this.noDeleteOnFetchRejection = !!noDeleteOnFetchRejection;\n this.allowStaleOnFetchRejection = !!allowStaleOnFetchRejection;\n this.allowStaleOnFetchAbort = !!allowStaleOnFetchAbort;\n this.ignoreFetchAbort = !!ignoreFetchAbort;\n // NB: maxEntrySize is set to maxSize if it's set\n if (this.maxEntrySize !== 0) {\n if (this.#maxSize !== 0) {\n if (!isPosInt(this.#maxSize)) {\n throw new TypeError('maxSize must be a positive integer if specified');\n }\n }\n if (!isPosInt(this.maxEntrySize)) {\n throw new TypeError('maxEntrySize must be a positive integer if specified');\n }\n this.#initializeSizeTracking();\n }\n this.allowStale = !!allowStale;\n this.noDeleteOnStaleGet = !!noDeleteOnStaleGet;\n this.updateAgeOnGet = !!updateAgeOnGet;\n this.updateAgeOnHas = !!updateAgeOnHas;\n this.ttlResolution =\n isPosInt(ttlResolution) || ttlResolution === 0\n ? ttlResolution\n : 1;\n this.ttlAutopurge = !!ttlAutopurge;\n this.ttl = ttl || 0;\n if (this.ttl) {\n if (!isPosInt(this.ttl)) {\n throw new TypeError('ttl must be a positive integer if specified');\n }\n this.#initializeTTLTracking();\n }\n // do not allow completely unbounded caches\n if (this.#max === 0 && this.ttl === 0 && this.#maxSize === 0) {\n throw new TypeError('At least one of max, maxSize, or ttl is required');\n }\n if (!this.ttlAutopurge && !this.#max && !this.#maxSize) {\n const code = 'LRU_CACHE_UNBOUNDED';\n if (shouldWarn(code)) {\n warned.add(code);\n const msg = 'TTL caching without ttlAutopurge, max, or maxSize can ' +\n 'result in unbounded memory consumption.';\n emitWarning(msg, 'UnboundedCacheWarning', code, LRUCache);\n }\n }\n }\n /**\n * Return the number of ms left in the item's TTL. If item is not in cache,\n * returns `0`. Returns `Infinity` if item is in cache without a defined TTL.\n */\n getRemainingTTL(key) {\n return this.#keyMap.has(key) ? Infinity : 0;\n }\n #initializeTTLTracking() {\n const ttls = new ZeroArray(this.#max);\n const starts = new ZeroArray(this.#max);\n this.#ttls = ttls;\n this.#starts = starts;\n this.#setItemTTL = (index, ttl, start = perf.now()) => {\n starts[index] = ttl !== 0 ? start : 0;\n ttls[index] = ttl;\n if (ttl !== 0 && this.ttlAutopurge) {\n const t = setTimeout(() => {\n if (this.#isStale(index)) {\n this.#delete(this.#keyList[index], 'expire');\n }\n }, ttl + 1);\n // unref() not supported on all platforms\n /* c8 ignore start */\n if (t.unref) {\n t.unref();\n }\n /* c8 ignore stop */\n }\n };\n this.#updateItemAge = index => {\n starts[index] = ttls[index] !== 0 ? perf.now() : 0;\n };\n this.#statusTTL = (status, index) => {\n if (ttls[index]) {\n const ttl = ttls[index];\n const start = starts[index];\n /* c8 ignore next */\n if (!ttl || !start)\n return;\n status.ttl = ttl;\n status.start = start;\n status.now = cachedNow || getNow();\n const age = status.now - start;\n status.remainingTTL = ttl - age;\n }\n };\n // debounce calls to perf.now() to 1s so we're not hitting\n // that costly call repeatedly.\n let cachedNow = 0;\n const getNow = () => {\n const n = perf.now();\n if (this.ttlResolution > 0) {\n cachedNow = n;\n const t = setTimeout(() => (cachedNow = 0), this.ttlResolution);\n // not available on all platforms\n /* c8 ignore start */\n if (t.unref) {\n t.unref();\n }\n /* c8 ignore stop */\n }\n return n;\n };\n this.getRemainingTTL = key => {\n const index = this.#keyMap.get(key);\n if (index === undefined) {\n return 0;\n }\n const ttl = ttls[index];\n const start = starts[index];\n if (!ttl || !start) {\n return Infinity;\n }\n const age = (cachedNow || getNow()) - start;\n return ttl - age;\n };\n this.#isStale = index => {\n const s = starts[index];\n const t = ttls[index];\n return !!t && !!s && (cachedNow || getNow()) - s > t;\n };\n }\n // conditionally set private methods related to TTL\n #updateItemAge = () => { };\n #statusTTL = () => { };\n #setItemTTL = () => { };\n /* c8 ignore stop */\n #isStale = () => false;\n #initializeSizeTracking() {\n const sizes = new ZeroArray(this.#max);\n this.#calculatedSize = 0;\n this.#sizes = sizes;\n this.#removeItemSize = index => {\n this.#calculatedSize -= sizes[index];\n sizes[index] = 0;\n };\n this.#requireSize = (k, v, size, sizeCalculation) => {\n // provisionally accept background fetches.\n // actual value size will be checked when they return.\n if (this.#isBackgroundFetch(v)) {\n return 0;\n }\n if (!isPosInt(size)) {\n if (sizeCalculation) {\n if (typeof sizeCalculation !== 'function') {\n throw new TypeError('sizeCalculation must be a function');\n }\n size = sizeCalculation(v, k);\n if (!isPosInt(size)) {\n throw new TypeError('sizeCalculation return invalid (expect positive integer)');\n }\n }\n else {\n throw new TypeError('invalid size value (must be positive integer). ' +\n 'When maxSize or maxEntrySize is used, sizeCalculation ' +\n 'or size must be set.');\n }\n }\n return size;\n };\n this.#addItemSize = (index, size, status) => {\n sizes[index] = size;\n if (this.#maxSize) {\n const maxSize = this.#maxSize - sizes[index];\n while (this.#calculatedSize > maxSize) {\n this.#evict(true);\n }\n }\n this.#calculatedSize += sizes[index];\n if (status) {\n status.entrySize = size;\n status.totalCalculatedSize = this.#calculatedSize;\n }\n };\n }\n #removeItemSize = _i => { };\n #addItemSize = (_i, _s, _st) => { };\n #requireSize = (_k, _v, size, sizeCalculation) => {\n if (size || sizeCalculation) {\n throw new TypeError('cannot set size without setting maxSize or maxEntrySize on cache');\n }\n return 0;\n };\n *#indexes({ allowStale = this.allowStale } = {}) {\n if (this.#size) {\n for (let i = this.#tail; true;) {\n if (!this.#isValidIndex(i)) {\n break;\n }\n if (allowStale || !this.#isStale(i)) {\n yield i;\n }\n if (i === this.#head) {\n break;\n }\n else {\n i = this.#prev[i];\n }\n }\n }\n }\n *#rindexes({ allowStale = this.allowStale } = {}) {\n if (this.#size) {\n for (let i = this.#head; true;) {\n if (!this.#isValidIndex(i)) {\n break;\n }\n if (allowStale || !this.#isStale(i)) {\n yield i;\n }\n if (i === this.#tail) {\n break;\n }\n else {\n i = this.#next[i];\n }\n }\n }\n }\n #isValidIndex(index) {\n return (index !== undefined &&\n this.#keyMap.get(this.#keyList[index]) === index);\n }\n /**\n * Return a generator yielding `[key, value]` pairs,\n * in order from most recently used to least recently used.\n */\n *entries() {\n for (const i of this.#indexes()) {\n if (this.#valList[i] !== undefined &&\n this.#keyList[i] !== undefined &&\n !this.#isBackgroundFetch(this.#valList[i])) {\n yield [this.#keyList[i], this.#valList[i]];\n }\n }\n }\n /**\n * Inverse order version of {@link LRUCache.entries}\n *\n * Return a generator yielding `[key, value]` pairs,\n * in order from least recently used to most recently used.\n */\n *rentries() {\n for (const i of this.#rindexes()) {\n if (this.#valList[i] !== undefined &&\n this.#keyList[i] !== undefined &&\n !this.#isBackgroundFetch(this.#valList[i])) {\n yield [this.#keyList[i], this.#valList[i]];\n }\n }\n }\n /**\n * Return a generator yielding the keys in the cache,\n * in order from most recently used to least recently used.\n */\n *keys() {\n for (const i of this.#indexes()) {\n const k = this.#keyList[i];\n if (k !== undefined &&\n !this.#isBackgroundFetch(this.#valList[i])) {\n yield k;\n }\n }\n }\n /**\n * Inverse order version of {@link LRUCache.keys}\n *\n * Return a generator yielding the keys in the cache,\n * in order from least recently used to most recently used.\n */\n *rkeys() {\n for (const i of this.#rindexes()) {\n const k = this.#keyList[i];\n if (k !== undefined &&\n !this.#isBackgroundFetch(this.#valList[i])) {\n yield k;\n }\n }\n }\n /**\n * Return a generator yielding the values in the cache,\n * in order from most recently used to least recently used.\n */\n *values() {\n for (const i of this.#indexes()) {\n const v = this.#valList[i];\n if (v !== undefined &&\n !this.#isBackgroundFetch(this.#valList[i])) {\n yield this.#valList[i];\n }\n }\n }\n /**\n * Inverse order version of {@link LRUCache.values}\n *\n * Return a generator yielding the values in the cache,\n * in order from least recently used to most recently used.\n */\n *rvalues() {\n for (const i of this.#rindexes()) {\n const v = this.#valList[i];\n if (v !== undefined &&\n !this.#isBackgroundFetch(this.#valList[i])) {\n yield this.#valList[i];\n }\n }\n }\n /**\n * Iterating over the cache itself yields the same results as\n * {@link LRUCache.entries}\n */\n [Symbol.iterator]() {\n return this.entries();\n }\n /**\n * A String value that is used in the creation of the default string\n * description of an object. Called by the built-in method\n * `Object.prototype.toString`.\n */\n [Symbol.toStringTag] = 'LRUCache';\n /**\n * Find a value for which the supplied fn method returns a truthy value,\n * similar to `Array.find()`. fn is called as `fn(value, key, cache)`.\n */\n find(fn, getOptions = {}) {\n for (const i of this.#indexes()) {\n const v = this.#valList[i];\n const value = this.#isBackgroundFetch(v)\n ? v.__staleWhileFetching\n : v;\n if (value === undefined)\n continue;\n if (fn(value, this.#keyList[i], this)) {\n return this.get(this.#keyList[i], getOptions);\n }\n }\n }\n /**\n * Call the supplied function on each item in the cache, in order from most\n * recently used to least recently used.\n *\n * `fn` is called as `fn(value, key, cache)`.\n *\n * If `thisp` is provided, function will be called in the `this`-context of\n * the provided object, or the cache if no `thisp` object is provided.\n *\n * Does not update age or recenty of use, or iterate over stale values.\n */\n forEach(fn, thisp = this) {\n for (const i of this.#indexes()) {\n const v = this.#valList[i];\n const value = this.#isBackgroundFetch(v)\n ? v.__staleWhileFetching\n : v;\n if (value === undefined)\n continue;\n fn.call(thisp, value, this.#keyList[i], this);\n }\n }\n /**\n * The same as {@link LRUCache.forEach} but items are iterated over in\n * reverse order. (ie, less recently used items are iterated over first.)\n */\n rforEach(fn, thisp = this) {\n for (const i of this.#rindexes()) {\n const v = this.#valList[i];\n const value = this.#isBackgroundFetch(v)\n ? v.__staleWhileFetching\n : v;\n if (value === undefined)\n continue;\n fn.call(thisp, value, this.#keyList[i], this);\n }\n }\n /**\n * Delete any stale entries. Returns true if anything was removed,\n * false otherwise.\n */\n purgeStale() {\n let deleted = false;\n for (const i of this.#rindexes({ allowStale: true })) {\n if (this.#isStale(i)) {\n this.#delete(this.#keyList[i], 'expire');\n deleted = true;\n }\n }\n return deleted;\n }\n /**\n * Get the extended info about a given entry, to get its value, size, and\n * TTL info simultaneously. Returns `undefined` if the key is not present.\n *\n * Unlike {@link LRUCache#dump}, which is designed to be portable and survive\n * serialization, the `start` value is always the current timestamp, and the\n * `ttl` is a calculated remaining time to live (negative if expired).\n *\n * Always returns stale values, if their info is found in the cache, so be\n * sure to check for expirations (ie, a negative {@link LRUCache.Entry#ttl})\n * if relevant.\n */\n info(key) {\n const i = this.#keyMap.get(key);\n if (i === undefined)\n return undefined;\n const v = this.#valList[i];\n const value = this.#isBackgroundFetch(v)\n ? v.__staleWhileFetching\n : v;\n if (value === undefined)\n return undefined;\n const entry = { value };\n if (this.#ttls && this.#starts) {\n const ttl = this.#ttls[i];\n const start = this.#starts[i];\n if (ttl && start) {\n const remain = ttl - (perf.now() - start);\n entry.ttl = remain;\n entry.start = Date.now();\n }\n }\n if (this.#sizes) {\n entry.size = this.#sizes[i];\n }\n return entry;\n }\n /**\n * Return an array of [key, {@link LRUCache.Entry}] tuples which can be\n * passed to {@link LRLUCache#load}.\n *\n * The `start` fields are calculated relative to a portable `Date.now()`\n * timestamp, even if `performance.now()` is available.\n *\n * Stale entries are always included in the `dump`, even if\n * {@link LRUCache.OptionsBase.allowStale} is false.\n *\n * Note: this returns an actual array, not a generator, so it can be more\n * easily passed around.\n */\n dump() {\n const arr = [];\n for (const i of this.#indexes({ allowStale: true })) {\n const key = this.#keyList[i];\n const v = this.#valList[i];\n const value = this.#isBackgroundFetch(v)\n ? v.__staleWhileFetching\n : v;\n if (value === undefined || key === undefined)\n continue;\n const entry = { value };\n if (this.#ttls && this.#starts) {\n entry.ttl = this.#ttls[i];\n // always dump the start relative to a portable timestamp\n // it's ok for this to be a bit slow, it's a rare operation.\n const age = perf.now() - this.#starts[i];\n entry.start = Math.floor(Date.now() - age);\n }\n if (this.#sizes) {\n entry.size = this.#sizes[i];\n }\n arr.unshift([key, entry]);\n }\n return arr;\n }\n /**\n * Reset the cache and load in the items in entries in the order listed.\n *\n * The shape of the resulting cache may be different if the same options are\n * not used in both caches.\n *\n * The `start` fields are assumed to be calculated relative to a portable\n * `Date.now()` timestamp, even if `performance.now()` is available.\n */\n load(arr) {\n this.clear();\n for (const [key, entry] of arr) {\n if (entry.start) {\n // entry.start is a portable timestamp, but we may be using\n // node's performance.now(), so calculate the offset, so that\n // we get the intended remaining TTL, no matter how long it's\n // been on ice.\n //\n // it's ok for this to be a bit slow, it's a rare operation.\n const age = Date.now() - entry.start;\n entry.start = perf.now() - age;\n }\n this.set(key, entry.value, entry);\n }\n }\n /**\n * Add a value to the cache.\n *\n * Note: if `undefined` is specified as a value, this is an alias for\n * {@link LRUCache#delete}\n *\n * Fields on the {@link LRUCache.SetOptions} options param will override\n * their corresponding values in the constructor options for the scope\n * of this single `set()` operation.\n *\n * If `start` is provided, then that will set the effective start\n * time for the TTL calculation. Note that this must be a previous\n * value of `performance.now()` if supported, or a previous value of\n * `Date.now()` if not.\n *\n * Options object may also include `size`, which will prevent\n * calling the `sizeCalculation` function and just use the specified\n * number if it is a positive integer, and `noDisposeOnSet` which\n * will prevent calling a `dispose` function in the case of\n * overwrites.\n *\n * If the `size` (or return value of `sizeCalculation`) for a given\n * entry is greater than `maxEntrySize`, then the item will not be\n * added to the cache.\n *\n * Will update the recency of the entry.\n *\n * If the value is `undefined`, then this is an alias for\n * `cache.delete(key)`. `undefined` is never stored in the cache.\n */\n set(k, v, setOptions = {}) {\n if (v === undefined) {\n this.delete(k);\n return this;\n }\n const { ttl = this.ttl, start, noDisposeOnSet = this.noDisposeOnSet, sizeCalculation = this.sizeCalculation, status, } = setOptions;\n let { noUpdateTTL = this.noUpdateTTL } = setOptions;\n const size = this.#requireSize(k, v, setOptions.size || 0, sizeCalculation);\n // if the item doesn't fit, don't do anything\n // NB: maxEntrySize set to maxSize by default\n if (this.maxEntrySize && size > this.maxEntrySize) {\n if (status) {\n status.set = 'miss';\n status.maxEntrySizeExceeded = true;\n }\n // have to delete, in case something is there already.\n this.#delete(k, 'set');\n return this;\n }\n let index = this.#size === 0 ? undefined : this.#keyMap.get(k);\n if (index === undefined) {\n // addition\n index = (this.#size === 0\n ? this.#tail\n : this.#free.length !== 0\n ? this.#free.pop()\n : this.#size === this.#max\n ? this.#evict(false)\n : this.#size);\n this.#keyList[index] = k;\n this.#valList[index] = v;\n this.#keyMap.set(k, index);\n this.#next[this.#tail] = index;\n this.#prev[index] = this.#tail;\n this.#tail = index;\n this.#size++;\n this.#addItemSize(index, size, status);\n if (status)\n status.set = 'add';\n noUpdateTTL = false;\n }\n else {\n // update\n this.#moveToTail(index);\n const oldVal = this.#valList[index];\n if (v !== oldVal) {\n if (this.#hasFetchMethod && this.#isBackgroundFetch(oldVal)) {\n oldVal.__abortController.abort(new Error('replaced'));\n const { __staleWhileFetching: s } = oldVal;\n if (s !== undefined && !noDisposeOnSet) {\n if (this.#hasDispose) {\n this.#dispose?.(s, k, 'set');\n }\n if (this.#hasDisposeAfter) {\n this.#disposed?.push([s, k, 'set']);\n }\n }\n }\n else if (!noDisposeOnSet) {\n if (this.#hasDispose) {\n this.#dispose?.(oldVal, k, 'set');\n }\n if (this.#hasDisposeAfter) {\n this.#disposed?.push([oldVal, k, 'set']);\n }\n }\n this.#removeItemSize(index);\n this.#addItemSize(index, size, status);\n this.#valList[index] = v;\n if (status) {\n status.set = 'replace';\n const oldValue = oldVal && this.#isBackgroundFetch(oldVal)\n ? oldVal.__staleWhileFetching\n : oldVal;\n if (oldValue !== undefined)\n status.oldValue = oldValue;\n }\n }\n else if (status) {\n status.set = 'update';\n }\n }\n if (ttl !== 0 && !this.#ttls) {\n this.#initializeTTLTracking();\n }\n if (this.#ttls) {\n if (!noUpdateTTL) {\n this.#setItemTTL(index, ttl, start);\n }\n if (status)\n this.#statusTTL(status, index);\n }\n if (!noDisposeOnSet && this.#hasDisposeAfter && this.#disposed) {\n const dt = this.#disposed;\n let task;\n while ((task = dt?.shift())) {\n this.#disposeAfter?.(...task);\n }\n }\n return this;\n }\n /**\n * Evict the least recently used item, returning its value or\n * `undefined` if cache is empty.\n */\n pop() {\n try {\n while (this.#size) {\n const val = this.#valList[this.#head];\n this.#evict(true);\n if (this.#isBackgroundFetch(val)) {\n if (val.__staleWhileFetching) {\n return val.__staleWhileFetching;\n }\n }\n else if (val !== undefined) {\n return val;\n }\n }\n }\n finally {\n if (this.#hasDisposeAfter && this.#disposed) {\n const dt = this.#disposed;\n let task;\n while ((task = dt?.shift())) {\n this.#disposeAfter?.(...task);\n }\n }\n }\n }\n #evict(free) {\n const head = this.#head;\n const k = this.#keyList[head];\n const v = this.#valList[head];\n if (this.#hasFetchMethod && this.#isBackgroundFetch(v)) {\n v.__abortController.abort(new Error('evicted'));\n }\n else if (this.#hasDispose || this.#hasDisposeAfter) {\n if (this.#hasDispose) {\n this.#dispose?.(v, k, 'evict');\n }\n if (this.#hasDisposeAfter) {\n this.#disposed?.push([v, k, 'evict']);\n }\n }\n this.#removeItemSize(head);\n // if we aren't about to use the index, then null these out\n if (free) {\n this.#keyList[head] = undefined;\n this.#valList[head] = undefined;\n this.#free.push(head);\n }\n if (this.#size === 1) {\n this.#head = this.#tail = 0;\n this.#free.length = 0;\n }\n else {\n this.#head = this.#next[head];\n }\n this.#keyMap.delete(k);\n this.#size--;\n return head;\n }\n /**\n * Check if a key is in the cache, without updating the recency of use.\n * Will return false if the item is stale, even though it is technically\n * in the cache.\n *\n * Check if a key is in the cache, without updating the recency of\n * use. Age is updated if {@link LRUCache.OptionsBase.updateAgeOnHas} is set\n * to `true` in either the options or the constructor.\n *\n * Will return `false` if the item is stale, even though it is technically in\n * the cache. The difference can be determined (if it matters) by using a\n * `status` argument, and inspecting the `has` field.\n *\n * Will not update item age unless\n * {@link LRUCache.OptionsBase.updateAgeOnHas} is set.\n */\n has(k, hasOptions = {}) {\n const { updateAgeOnHas = this.updateAgeOnHas, status } = hasOptions;\n const index = this.#keyMap.get(k);\n if (index !== undefined) {\n const v = this.#valList[index];\n if (this.#isBackgroundFetch(v) &&\n v.__staleWhileFetching === undefined) {\n return false;\n }\n if (!this.#isStale(index)) {\n if (updateAgeOnHas) {\n this.#updateItemAge(index);\n }\n if (status) {\n status.has = 'hit';\n this.#statusTTL(status, index);\n }\n return true;\n }\n else if (status) {\n status.has = 'stale';\n this.#statusTTL(status, index);\n }\n }\n else if (status) {\n status.has = 'miss';\n }\n return false;\n }\n /**\n * Like {@link LRUCache#get} but doesn't update recency or delete stale\n * items.\n *\n * Returns `undefined` if the item is stale, unless\n * {@link LRUCache.OptionsBase.allowStale} is set.\n */\n peek(k, peekOptions = {}) {\n const { allowStale = this.allowStale } = peekOptions;\n const index = this.#keyMap.get(k);\n if (index === undefined ||\n (!allowStale && this.#isStale(index))) {\n return;\n }\n const v = this.#valList[index];\n // either stale and allowed, or forcing a refresh of non-stale value\n return this.#isBackgroundFetch(v) ? v.__staleWhileFetching : v;\n }\n #backgroundFetch(k, index, options, context) {\n const v = index === undefined ? undefined : this.#valList[index];\n if (this.#isBackgroundFetch(v)) {\n return v;\n }\n const ac = new AC();\n const { signal } = options;\n // when/if our AC signals, then stop listening to theirs.\n signal?.addEventListener('abort', () => ac.abort(signal.reason), {\n signal: ac.signal,\n });\n const fetchOpts = {\n signal: ac.signal,\n options,\n context,\n };\n const cb = (v, updateCache = false) => {\n const { aborted } = ac.signal;\n const ignoreAbort = options.ignoreFetchAbort && v !== undefined;\n if (options.status) {\n if (aborted && !updateCache) {\n options.status.fetchAborted = true;\n options.status.fetchError = ac.signal.reason;\n if (ignoreAbort)\n options.status.fetchAbortIgnored = true;\n }\n else {\n options.status.fetchResolved = true;\n }\n }\n if (aborted && !ignoreAbort && !updateCache) {\n return fetchFail(ac.signal.reason);\n }\n // either we didn't abort, and are still here, or we did, and ignored\n const bf = p;\n if (this.#valList[index] === p) {\n if (v === undefined) {\n if (bf.__staleWhileFetching) {\n this.#valList[index] = bf.__staleWhileFetching;\n }\n else {\n this.#delete(k, 'fetch');\n }\n }\n else {\n if (options.status)\n options.status.fetchUpdated = true;\n this.set(k, v, fetchOpts.options);\n }\n }\n return v;\n };\n const eb = (er) => {\n if (options.status) {\n options.status.fetchRejected = true;\n options.status.fetchError = er;\n }\n return fetchFail(er);\n };\n const fetchFail = (er) => {\n const { aborted } = ac.signal;\n const allowStaleAborted = aborted && options.allowStaleOnFetchAbort;\n const allowStale = allowStaleAborted || options.allowStaleOnFetchRejection;\n const noDelete = allowStale || options.noDeleteOnFetchRejection;\n const bf = p;\n if (this.#valList[index] === p) {\n // if we allow stale on fetch rejections, then we need to ensure that\n // the stale value is not removed from the cache when the fetch fails.\n const del = !noDelete || bf.__staleWhileFetching === undefined;\n if (del) {\n this.#delete(k, 'fetch');\n }\n else if (!allowStaleAborted) {\n // still replace the *promise* with the stale value,\n // since we are done with the promise at this point.\n // leave it untouched if we're still waiting for an\n // aborted background fetch that hasn't yet returned.\n this.#valList[index] = bf.__staleWhileFetching;\n }\n }\n if (allowStale) {\n if (options.status && bf.__staleWhileFetching !== undefined) {\n options.status.returnedStale = true;\n }\n return bf.__staleWhileFetching;\n }\n else if (bf.__returned === bf) {\n throw er;\n }\n };\n const pcall = (res, rej) => {\n const fmp = this.#fetchMethod?.(k, v, fetchOpts);\n if (fmp && fmp instanceof Promise) {\n fmp.then(v => res(v === undefined ? undefined : v), rej);\n }\n // ignored, we go until we finish, regardless.\n // defer check until we are actually aborting,\n // so fetchMethod can override.\n ac.signal.addEventListener('abort', () => {\n if (!options.ignoreFetchAbort ||\n options.allowStaleOnFetchAbort) {\n res(undefined);\n // when it eventually resolves, update the cache.\n if (options.allowStaleOnFetchAbort) {\n res = v => cb(v, true);\n }\n }\n });\n };\n if (options.status)\n options.status.fetchDispatched = true;\n const p = new Promise(pcall).then(cb, eb);\n const bf = Object.assign(p, {\n __abortController: ac,\n __staleWhileFetching: v,\n __returned: undefined,\n });\n if (index === undefined) {\n // internal, don't expose status.\n this.set(k, bf, { ...fetchOpts.options, status: undefined });\n index = this.#keyMap.get(k);\n }\n else {\n this.#valList[index] = bf;\n }\n return bf;\n }\n #isBackgroundFetch(p) {\n if (!this.#hasFetchMethod)\n return false;\n const b = p;\n return (!!b &&\n b instanceof Promise &&\n b.hasOwnProperty('__staleWhileFetching') &&\n b.__abortController instanceof AC);\n }\n async fetch(k, fetchOptions = {}) {\n const { \n // get options\n allowStale = this.allowStale, updateAgeOnGet = this.updateAgeOnGet, noDeleteOnStaleGet = this.noDeleteOnStaleGet, \n // set options\n ttl = this.ttl, noDisposeOnSet = this.noDisposeOnSet, size = 0, sizeCalculation = this.sizeCalculation, noUpdateTTL = this.noUpdateTTL, \n // fetch exclusive options\n noDeleteOnFetchRejection = this.noDeleteOnFetchRejection, allowStaleOnFetchRejection = this.allowStaleOnFetchRejection, ignoreFetchAbort = this.ignoreFetchAbort, allowStaleOnFetchAbort = this.allowStaleOnFetchAbort, context, forceRefresh = false, status, signal, } = fetchOptions;\n if (!this.#hasFetchMethod) {\n if (status)\n status.fetch = 'get';\n return this.get(k, {\n allowStale,\n updateAgeOnGet,\n noDeleteOnStaleGet,\n status,\n });\n }\n const options = {\n allowStale,\n updateAgeOnGet,\n noDeleteOnStaleGet,\n ttl,\n noDisposeOnSet,\n size,\n sizeCalculation,\n noUpdateTTL,\n noDeleteOnFetchRejection,\n allowStaleOnFetchRejection,\n allowStaleOnFetchAbort,\n ignoreFetchAbort,\n status,\n signal,\n };\n let index = this.#keyMap.get(k);\n if (index === undefined) {\n if (status)\n status.fetch = 'miss';\n const p = this.#backgroundFetch(k, index, options, context);\n return (p.__returned = p);\n }\n else {\n // in cache, maybe already fetching\n const v = this.#valList[index];\n if (this.#isBackgroundFetch(v)) {\n const stale = allowStale && v.__staleWhileFetching !== undefined;\n if (status) {\n status.fetch = 'inflight';\n if (stale)\n status.returnedStale = true;\n }\n return stale ? v.__staleWhileFetching : (v.__returned = v);\n }\n // if we force a refresh, that means do NOT serve the cached value,\n // unless we are already in the process of refreshing the cache.\n const isStale = this.#isStale(index);\n if (!forceRefresh && !isStale) {\n if (status)\n status.fetch = 'hit';\n this.#moveToTail(index);\n if (updateAgeOnGet) {\n this.#updateItemAge(index);\n }\n if (status)\n this.#statusTTL(status, index);\n return v;\n }\n // ok, it is stale or a forced refresh, and not already fetching.\n // refresh the cache.\n const p = this.#backgroundFetch(k, index, options, context);\n const hasStale = p.__staleWhileFetching !== undefined;\n const staleVal = hasStale && allowStale;\n if (status) {\n status.fetch = isStale ? 'stale' : 'refresh';\n if (staleVal && isStale)\n status.returnedStale = true;\n }\n return staleVal ? p.__staleWhileFetching : (p.__returned = p);\n }\n }\n async forceFetch(k, fetchOptions = {}) {\n const v = await this.fetch(k, fetchOptions);\n if (v === undefined)\n throw new Error('fetch() returned undefined');\n return v;\n }\n memo(k, memoOptions = {}) {\n const memoMethod = this.#memoMethod;\n if (!memoMethod) {\n throw new Error('no memoMethod provided to constructor');\n }\n const { context, forceRefresh, ...options } = memoOptions;\n const v = this.get(k, options);\n if (!forceRefresh && v !== undefined)\n return v;\n const vv = memoMethod(k, v, {\n options,\n context,\n });\n this.set(k, vv, options);\n return vv;\n }\n /**\n * Return a value from the cache. Will update the recency of the cache\n * entry found.\n *\n * If the key is not found, get() will return `undefined`.\n */\n get(k, getOptions = {}) {\n const { allowStale = this.allowStale, updateAgeOnGet = this.updateAgeOnGet, noDeleteOnStaleGet = this.noDeleteOnStaleGet, status, } = getOptions;\n const index = this.#keyMap.get(k);\n if (index !== undefined) {\n const value = this.#valList[index];\n const fetching = this.#isBackgroundFetch(value);\n if (status)\n this.#statusTTL(status, index);\n if (this.#isStale(index)) {\n if (status)\n status.get = 'stale';\n // delete only if not an in-flight background fetch\n if (!fetching) {\n if (!noDeleteOnStaleGet) {\n this.#delete(k, 'expire');\n }\n if (status && allowStale)\n status.returnedStale = true;\n return allowStale ? value : undefined;\n }\n else {\n if (status &&\n allowStale &&\n value.__staleWhileFetching !== undefined) {\n status.returnedStale = true;\n }\n return allowStale ? value.__staleWhileFetching : undefined;\n }\n }\n else {\n if (status)\n status.get = 'hit';\n // if we're currently fetching it, we don't actually have it yet\n // it's not stale, which means this isn't a staleWhileRefetching.\n // If it's not stale, and fetching, AND has a __staleWhileFetching\n // value, then that means the user fetched with {forceRefresh:true},\n // so it's safe to return that value.\n if (fetching) {\n return value.__staleWhileFetching;\n }\n this.#moveToTail(index);\n if (updateAgeOnGet) {\n this.#updateItemAge(index);\n }\n return value;\n }\n }\n else if (status) {\n status.get = 'miss';\n }\n }\n #connect(p, n) {\n this.#prev[n] = p;\n this.#next[p] = n;\n }\n #moveToTail(index) {\n // if tail already, nothing to do\n // if head, move head to next[index]\n // else\n // move next[prev[index]] to next[index] (head has no prev)\n // move prev[next[index]] to prev[index]\n // prev[index] = tail\n // next[tail] = index\n // tail = index\n if (index !== this.#tail) {\n if (index === this.#head) {\n this.#head = this.#next[index];\n }\n else {\n this.#connect(this.#prev[index], this.#next[index]);\n }\n this.#connect(this.#tail, index);\n this.#tail = index;\n }\n }\n /**\n * Deletes a key out of the cache.\n *\n * Returns true if the key was deleted, false otherwise.\n */\n delete(k) {\n return this.#delete(k, 'delete');\n }\n #delete(k, reason) {\n let deleted = false;\n if (this.#size !== 0) {\n const index = this.#keyMap.get(k);\n if (index !== undefined) {\n deleted = true;\n if (this.#size === 1) {\n this.#clear(reason);\n }\n else {\n this.#removeItemSize(index);\n const v = this.#valList[index];\n if (this.#isBackgroundFetch(v)) {\n v.__abortController.abort(new Error('deleted'));\n }\n else if (this.#hasDispose || this.#hasDisposeAfter) {\n if (this.#hasDispose) {\n this.#dispose?.(v, k, reason);\n }\n if (this.#hasDisposeAfter) {\n this.#disposed?.push([v, k, reason]);\n }\n }\n this.#keyMap.delete(k);\n this.#keyList[index] = undefined;\n this.#valList[index] = undefined;\n if (index === this.#tail) {\n this.#tail = this.#prev[index];\n }\n else if (index === this.#head) {\n this.#head = this.#next[index];\n }\n else {\n const pi = this.#prev[index];\n this.#next[pi] = this.#next[index];\n const ni = this.#next[index];\n this.#prev[ni] = this.#prev[index];\n }\n this.#size--;\n this.#free.push(index);\n }\n }\n }\n if (this.#hasDisposeAfter && this.#disposed?.length) {\n const dt = this.#disposed;\n let task;\n while ((task = dt?.shift())) {\n this.#disposeAfter?.(...task);\n }\n }\n return deleted;\n }\n /**\n * Clear the cache entirely, throwing away all values.\n */\n clear() {\n return this.#clear('delete');\n }\n #clear(reason) {\n for (const index of this.#rindexes({ allowStale: true })) {\n const v = this.#valList[index];\n if (this.#isBackgroundFetch(v)) {\n v.__abortController.abort(new Error('deleted'));\n }\n else {\n const k = this.#keyList[index];\n if (this.#hasDispose) {\n this.#dispose?.(v, k, reason);\n }\n if (this.#hasDisposeAfter) {\n this.#disposed?.push([v, k, reason]);\n }\n }\n }\n this.#keyMap.clear();\n this.#valList.fill(undefined);\n this.#keyList.fill(undefined);\n if (this.#ttls && this.#starts) {\n this.#ttls.fill(0);\n this.#starts.fill(0);\n }\n if (this.#sizes) {\n this.#sizes.fill(0);\n }\n this.#head = 0;\n this.#tail = 0;\n this.#free.length = 0;\n this.#calculatedSize = 0;\n this.#size = 0;\n if (this.#hasDisposeAfter && this.#disposed) {\n const dt = this.#disposed;\n let task;\n while ((task = dt?.shift())) {\n this.#disposeAfter?.(...task);\n }\n }\n }\n}\n//# sourceMappingURL=index.js.map"],"names":["MonomerNumberingTypes","HelmTabKeys","monomerWorksConsts","V2K_RGP_SHIFT","V2K_RGP_LINE","V2K_A_LINE","V3K_COUNTS_SHIFT","V3K_IDX_SHIFT","V3K_HEADER_FIRST_LINE","V3K_HEADER_SECOND_LINE","V3K_BEGIN_CTAB_BLOCK","V3K_END_CTAB_BLOCK","V3K_BEGIN_COUNTS_LINE","V3K_COUNTS_LINE_ENDING","V3K_BEGIN_ATOM_BLOCK","V3K_END_ATOM_BLOCK","V3K_BEGIN_BOND_BLOCK","V3K_END_BOND_BLOCK","V3K_BOND_CONFIG","V3K_BEGIN_DATA_LINE","V3K_END","PRECISION_FACTOR","DEOXYRIBOSE","polymerType","dist","kC","RNA","symbol","RIBOSE","PHOSPHATE","OXYGEN","HYDROGEN","getMolGraph","dict","libKey","NucleotideRole","MonomerMap","Map","constructor","entries","super","MolfileWithMap","molfile","monomers","this","createEmpty","HELM_POLYMER_TYPE","NOTATION","ALPHABET","TAGS","RegExp","CandidateType","name","alphabet","cutoff","Alphabets","fasta","peptide","Set","dna","rna","helmTypeToPolymerType","helmType","oE","BASE","SUGAR","LINKER","NUCLEOTIDE","AA","PEPTIDE","CHEM","BLOB","console","warn","monomerSeqToMolfile","monomerSeq","monomersDict","roles","length","triplesMode","atomCount","bondCount","needsCapping","monomerCount","lastMonomerGraph","lastPhosphateGraph","i","seqMonomer","Error","biotype","atoms","x","bonds","bondTypes","meta","rNodes","terminalR2Atom","toLowerCase","TERMINAL_3P","sugar","DNA","phosphate","getResultingAtomBondCounts","molfileAtomBlock","Array","molfileBondBlock","addMonomerToMolblock","addAminoAcidToMolblock","addNucleotideToMolblock","v","nodeShift","bondShift","backbonePositionShift","fill","branchPositionShift","backboneAttachNode","branchAttachNode","flipFactor","LC","seqLength","Math","ceil","steabsCollection","lastMonomerCappingAtom","nAtoms","addAtoms","sm","role","mG","aFirst","bFirst","addBranchMonomerToMolblock","addBackboneMonomerToMolblock","stereoAtoms","forEach","s","push","aList","a","bList","b","set","runTriplesAssembly","monomer","mAtomFirst","mBondFirst","mAtomCount","mAtomList","maI","mBondCount","mBondList","mbI","cappingAtomType","atomIdx","keepPrecision","firstAtom","secondAtom","capResultingMolblock","molfileCountsLine","result","join","collection","rowsArray","newCollectionRow","updatedRow","getCollectionBlock","j","atomTypes","y","kwargs","fillAtomLines","fillBondLines","bondIdx","terminalNodes","fillChainExtendingBond","branchShift","updateBranchVariables","atomPairs","backboneShift","updateChainExtendingVariables","nucleobase","fillBranchAtomLines","branchMonomer","fillBackboneToBranchBond","bondCfg","bondConfiguration","has","orientation","get","round","PT","FASTA","SEPARATOR","HELM","BILN","onmessage","event","seqList","rolesList","start","end","data","resMolList","molfileWarningList","rowI","seq","undefined","err","msg","message","toString","postMessage","molfiles","warnings","performance","now","Date","PROCESS","process","AC","globalThis","AbortController","AS","AbortSignal","onabort","_onabort","reason","aborted","addEventListener","_","fn","warnACPolyfill","signal","abort","printACPolyfillWarning","env","LRU_CACHE_IGNORE_AC_WARNING","type","code","emitWarning","error","Symbol","iterator","toStringTag"],"sourceRoot":""}
package/dist/323.js ADDED
@@ -0,0 +1,2 @@
1
+ var helm;(()=>{"use strict";var t,o,e={323:(t,o,e)=>{var n,a,s=e(657);!function(t){t[t.default=0]="default",t[t.continuous=1]="continuous"}(n||(n={})),function(t){t.Sequence="sequence",t.Helm="notation",t.Properties="properties",t.StructureView="structureview"}(a||(a={}));const i={V2K_RGP_SHIFT:8,V2K_RGP_LINE:"M RGP",V2K_A_LINE:"A ",V3K_COUNTS_SHIFT:14,V3K_IDX_SHIFT:7,V3K_HEADER_FIRST_LINE:"\nDatagrok macromolecule handler\n\n",V3K_HEADER_SECOND_LINE:" 0 0 0 0 0 0 999 V3000\n",V3K_BEGIN_CTAB_BLOCK:"M V30 BEGIN CTAB\n",V3K_END_CTAB_BLOCK:"M V30 END CTAB\n",V3K_BEGIN_COUNTS_LINE:"M V30 COUNTS ",V3K_COUNTS_LINE_ENDING:" 0 0 0\n",V3K_BEGIN_ATOM_BLOCK:"M V30 BEGIN ATOM\n",V3K_END_ATOM_BLOCK:"M V30 END ATOM\n",V3K_BEGIN_BOND_BLOCK:"M V30 BEGIN BOND\n",V3K_END_BOND_BLOCK:"M V30 END BOND\n",V3K_BOND_CONFIG:" CFG=",V3K_BEGIN_DATA_LINE:"M V30 ",V3K_END:"M END",PRECISION_FACTOR:1e4,DEOXYRIBOSE:{polymerType:s.kC.RNA,symbol:"d"},RIBOSE:{polymerType:s.kC.RNA,symbol:"r"},PHOSPHATE:{polymerType:s.kC.RNA,symbol:"p"},OXYGEN:"O",HYDROGEN:"H"};function r(t,o){return t[o.polymerType]?.[o.symbol]}var l;!function(t){t[t.SUGAR=0]="SUGAR",t[t.BASE=1]="BASE",t[t.PHOSPHATE=2]="PHOSPHATE",t[t.TERMINAL_5P=3]="TERMINAL_5P",t[t.TERMINAL_3P=4]="TERMINAL_3P"}(l||(l={}));class c extends Map{constructor(t){super(t)}}class h{molfile;monomers;constructor(t,o){this.molfile=t,this.monomers=o}static createEmpty(){return new h("",new c(null))}}const f=s.kC;new RegExp("[rd]\\((\\w)\\)p?","g");class m{name;alphabet;cutoff;constructor(t,o,e){this.name=t,this.alphabet=o,this.cutoff=e}}var b,p,E;!function(t){t.FASTA="fasta",t.SEPARATOR="separator",t.HELM="helm",t.CUSTOM="custom",t.BILN="biln"}(b||(b={})),function(t){t.DNA="DNA",t.RNA="RNA",t.PT="PT",t.UN="UN"}(p||(p={})),function(t){t.aligned="aligned",t.alphabet="alphabet",t.alphabetSize=".alphabetSize",t.alphabetIsMultichar=".alphabetIsMultichar",t.separator="separator",t.isHelmCompatible=".isHelmCompatible",t.positionNames=".positionNames",t.positionLabels=".positionLabels",t.regions=".regions",t.positionShift=".positionShift",t.selectedPosition=".selectedPosition",t.polymerTypeColumnName=".polymerTypeColumnName",t.annotations=".annotations",t.numberingScheme=".numberingScheme",t.annotationColumnName=".annotationColumnName"}(E||(E={}));const N=new class{fasta={peptide:new Set(["G","L","Y","S","E","Q","D","N","F","A","K","R","H","C","V","P","W","I","M","T"]),dna:new Set(["A","C","G","T"]),rna:new Set(["A","C","G","U"])}};function u(t){let o;switch(t){case s.oE.BASE:case s.oE.SUGAR:case s.oE.LINKER:case s.oE.NUCLEOTIDE:case"nucleotide":o=s.kC.RNA;break;case s.oE.AA:o=s.kC.PEPTIDE;break;case s.oE.CHEM:o=s.kC.CHEM;break;case s.oE.BLOB:o=s.kC.BLOB;break;default:o=s.kC.PEPTIDE,console.warn(`Unexpected HelmType '${t}'`)}return o}function S(t,o,e,n,a){if(0===t.length)return h.createEmpty();const s=n===f.RNA&&!!a&&a.length===t.length,{atomCount:m,bondCount:b,needsCapping:E}=function(t,o,e,n,a,s){let c=0,h=0,m=0,b=!0,E=null,N=null;for(let e=0;e<t.length;++e){const n=t[e];if(""!==n.symbol){if("*"==n.symbol)throw new Error("Gap canonical symbol is '', not '*");E=r(o,{symbol:n.symbol,polymerType:u(n.biotype)}),c+=E.atoms.x.length,h+=E.bonds.bondTypes.length,m++,a&&e%3==2&&(N=E)}}if(n===f.PEPTIDE)c+=1,h+=m,m>0&&((E?.meta?.rNodes?.length??0)<2||E?.terminalR2Atom?.toLowerCase()===i.HYDROGEN.toLowerCase())&&(b=!1,c-=1,h-=1);else if(a)h+=m,s&&s.length>0&&s[s.length-1]===l.TERMINAL_3P?(b=!1,h-=1):c+=1;else{const n=e===p.DNA?r(o,i.DEOXYRIBOSE):r(o,i.RIBOSE),a=r(o,i.PHOSPHATE);c+=(t.length-1)*a.atoms.x.length,c+=t.length*n.atoms.x.length,c+=1,h+=(t.length-1)*a.bonds.bondTypes.length,h+=t.length*n.bonds.bondTypes.length,h-=1,h+=3*t.length}return{atomCount:c,bondCount:h,needsCapping:b}}(t,o,e,n,s,a),N=new Array(m),S=new Array(b);let g,y=null,C=null;n===f.PEPTIDE?g=_:(g=A,s||(y=e===p.DNA?r(o,i.DEOXYRIBOSE):r(o,i.RIBOSE),C=r(o,i.PHOSPHATE)));const I={i:0,nodeShift:0,bondShift:0,backbonePositionShift:new Array(2).fill(0),branchPositionShift:new Array(2).fill(0),backboneAttachNode:0,branchAttachNode:0,flipFactor:1},B={sugar:y,phosphate:C,seqLength:s?Math.ceil(t.length/3):t.length,atomCount:m,bondCount:b},P=new c,L=[];let D,V=0;if(s)!function(t,o,e,n,a,s,i,c,h,f){for(let i=0;i<t.length;++i){const m=t[i];if(""===m.symbol)continue;const b=o[i],p=r(e,{symbol:m.symbol,polymerType:u(m.biotype)}),E=s.nodeShift,N=s.bondShift;s.i=i,b===l.BASE?T(p,n,a,s):d(p,n,a,s),p.stereoAtoms?.forEach(t=>h.push(t+V)),f(p.atoms.x.length);const S=[];for(let t=E;t<s.nodeShift;++t)S.push(t);const _=[];for(let t=N;t<s.bondShift;++t)_.push(t);c.set(i,{biotype:m.biotype,symbol:m.symbol,atoms:S,bonds:_})}}(t,a,o,N,S,I,0,P,L,t=>{V+=t});else for(I.i=0;I.i<B.seqLength;++I.i){const e=t[I.i];if(""===e.symbol)continue;const n=r(o,{symbol:e.symbol,polymerType:u(e.biotype)});D=n.terminalR2Atom;const a=I.nodeShift,s=I.bondShift;g(n,N,S,I,B),n.stereoAtoms?.forEach(t=>L.push(t+V)),V+=n.atoms.x.length;const i=I.nodeShift-a,l=new Array(i);for(let t=0;t<i;++t)l[t]=a+t;const c=I.bondShift-s,h=new Array(c);for(let t=0;t<c;++t)h[t]=s+t;P.set(I.i,{biotype:e.biotype,symbol:e.symbol,atoms:l,bonds:h})}E&&function(t,o,e,n,a=i.OXYGEN){const s=e.nodeShift+1;t[n.atomCount]=i.V3K_BEGIN_DATA_LINE+s+" "+(a??i.OXYGEN)+" "+O(e.backbonePositionShift[0])+" "+e.flipFactor*O(e.backbonePositionShift[1])+" 0.000000 0\n";const r=e.backboneAttachNode,l=s;o[n.bondCount]=i.V3K_BEGIN_DATA_LINE+e.bondShift+" 1 "+r+" "+l+"\n"}(N,S,I,B,D??i.OXYGEN);const K=i.V3K_BEGIN_COUNTS_LINE+m+" "+b+i.V3K_COUNTS_LINE_ENDING;let R="";return R+=i.V3K_HEADER_FIRST_LINE,R+=i.V3K_HEADER_SECOND_LINE,R+=i.V3K_BEGIN_CTAB_BLOCK,R+=K,R+=i.V3K_BEGIN_ATOM_BLOCK,R+=N.join(""),R+=i.V3K_END_ATOM_BLOCK,R+=i.V3K_BEGIN_BOND_BLOCK,R+=S.join(""),R+=i.V3K_END_BOND_BLOCK,L.length>0&&(R+=function(t){const o=[];let e=`M V30 MDLV30/STEABS ATOMS=(${t.length}`;for(let n=0;n<t.length;n++){const a=`${e} ${t[n]}`;a.length>76?(o.push(`${e} -\n`),e=`M V30 ${t[n]}`):e=a,n===t.length-1&&o.push(`${e})\n`)}return`M V30 BEGIN COLLECTION\n${o.join("")}M V30 END COLLECTION\n`}(L)),R+=i.V3K_END_CTAB_BLOCK,R+=i.V3K_END,{molfile:R,monomers:P}}function _(t,o,e,n){n.flipFactor=(-1)**(n.i%2),d(t,o,e,n)}function d(t,o,e,n){!function(t,o,e){for(let n=0;n<t.atoms.atomTypes.length;++n){const a=e.nodeShift+n+1;o[e.nodeShift+n]=i.V3K_BEGIN_DATA_LINE+a+" "+t.atoms.atomTypes[n]+" "+O(e.backbonePositionShift[0]+t.atoms.x[n])+" "+O(e.backbonePositionShift[1]+e.flipFactor*t.atoms.y[n])+" "+t.atoms.kwargs[n]}}(t,o,n),g(t,e,n),function(t,o,e){if(0!==e.backboneAttachNode){const n=e.bondShift,a=e.backboneAttachNode,s=t.meta.terminalNodes[0]+e.nodeShift;o[e.bondShift-1]=i.V3K_BEGIN_DATA_LINE+n+" 1 "+a+" "+s+"\n"}}(t,e,n),null!==t.meta.branchShift&&t.meta.terminalNodes.length>2&&function(t,o){o.branchAttachNode=o.nodeShift+t.meta.terminalNodes[2];for(let e=0;e<2;++e)o.branchPositionShift[e]=o.backbonePositionShift[e]+t.meta.branchShift[e]}(t,n),function(t,o){o.backboneAttachNode=o.nodeShift+t.meta.terminalNodes[1],o.bondShift+=t.bonds.atomPairs.length+1,o.nodeShift+=t.atoms.atomTypes.length,o.backbonePositionShift[0]+=t.meta.backboneShift?.[0]??0,o.backbonePositionShift[1]+=o.flipFactor*(t.meta.backboneShift?.[1]??0)}(t,n)}function A(t,o,e,n,a){if(0===n.i)d(a.sugar,o,e,n);else for(const t of[a.phosphate,a.sugar])d(t,o,e,n);T(t,o,e,n)}function T(t,o,e,n){!function(t,o,e){for(let n=0;n<t.atoms.atomTypes.length;++n){const a=e.nodeShift+n+1;o[e.nodeShift+n]=i.V3K_BEGIN_DATA_LINE+a+" "+t.atoms.atomTypes[n]+" "+O(e.branchPositionShift[0]+t.atoms.x[n])+" "+O(e.branchPositionShift[1]+e.flipFactor*t.atoms.y[n])+" "+t.atoms.kwargs[n]}}(t,o,n),g(t,e,n),function(t,o,e){const n=e.bondShift,a=e.branchAttachNode,s=t.meta.terminalNodes[0]+e.nodeShift;o[n-1]=i.V3K_BEGIN_DATA_LINE+n+" 1 "+a+" "+s+"\n"}(t,e,n);const a=n.bondShift,s=n.branchAttachNode,r=t.meta.terminalNodes[0]+n.nodeShift;e[a-1]=i.V3K_BEGIN_DATA_LINE+a+" 1 "+s+" "+r+"\n",n.bondShift+=t.bonds.atomPairs.length+1,n.nodeShift+=t.atoms.atomTypes.length}function g(t,o,e){for(let n=0;n<t.bonds.atomPairs.length;++n){const a=e.bondShift+n+1,s=t.bonds.atomPairs[n][0]+e.nodeShift,r=t.bonds.atomPairs[n][1]+e.nodeShift;let l="";if(t.bonds.bondConfiguration.has(n)){let o=t.bonds.bondConfiguration.get(n);e.flipFactor<0&&(o=1===o?3:1),l=" CFG="+o}const c=t.bonds.kwargs.has(n)?" "+t.bonds.kwargs.get(n):"";o[e.bondShift+n]=i.V3K_BEGIN_DATA_LINE+a+" "+t.bonds.bondTypes[n]+" "+s+" "+r+l+c+"\n"}}function O(t){return Math.round(i.PRECISION_FACTOR*t)/i.PRECISION_FACTOR}new m(p.PT,N.fasta.peptide,.5),new m(p.DNA,N.fasta.dna,.55),new m(p.RNA,N.fasta.rna,.55),b.FASTA,b.SEPARATOR,b.HELM,b.BILN,onmessage=t=>{const{seqList:o,rolesList:e,monomersDict:n,alphabet:a,polymerType:s,start:i,end:r}=t.data,l=new Array(r-i),c=new Array(0);for(let t=i;t<r;++t)try{const r=o[t],c=e?e[t]:void 0;l[t-i]=S(r,n,a,s,c)}catch(o){const e=`Cannot get molfile of row #${t}: ${o instanceof Error?o.message:o.toString()}.`;c.push(e)}postMessage({molfiles:l,warnings:c})}}},n={};function a(t){var o=n[t];if(void 0!==o)return o.exports;var s=n[t]={exports:{}};return e[t](s,s.exports,a),s.exports}a.m=e,a.x=()=>{var t=a.O(void 0,[657],()=>a(323));return a.O(t)},t=[],a.O=(o,e,n,s)=>{if(!e){var i=1/0;for(h=0;h<t.length;h++){for(var[e,n,s]=t[h],r=!0,l=0;l<e.length;l++)(!1&s||i>=s)&&Object.keys(a.O).every(t=>a.O[t](e[l]))?e.splice(l--,1):(r=!1,s<i&&(i=s));if(r){t.splice(h--,1);var c=n();void 0!==c&&(o=c)}}return o}s=s||0;for(var h=t.length;h>0&&t[h-1][2]>s;h--)t[h]=t[h-1];t[h]=[e,n,s]},a.d=(t,o)=>{for(var e in o)a.o(o,e)&&!a.o(t,e)&&Object.defineProperty(t,e,{enumerable:!0,get:o[e]})},a.f={},a.e=t=>Promise.all(Object.keys(a.f).reduce((o,e)=>(a.f[e](t,o),o),[])),a.u=t=>t+".js",a.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),a.o=(t,o)=>Object.prototype.hasOwnProperty.call(t,o),(()=>{var t;a.g.importScripts&&(t=a.g.location+"");var o=a.g.document;if(!t&&o&&(o.currentScript&&"SCRIPT"===o.currentScript.tagName.toUpperCase()&&(t=o.currentScript.src),!t)){var e=o.getElementsByTagName("script");if(e.length)for(var n=e.length-1;n>-1&&(!t||!/^http(s?):/.test(t));)t=e[n--].src}if(!t)throw new Error("Automatic publicPath is not supported in this browser");t=t.replace(/^blob:/,"").replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),a.p=t})(),(()=>{var t={323:1};a.f.i=(o,e)=>{t[o]||importScripts(a.p+a.u(o))};var o=self.webpackChunkhelm=self.webpackChunkhelm||[],e=o.push.bind(o);o.push=o=>{var[n,s,i]=o;for(var r in s)a.o(s,r)&&(a.m[r]=s[r]);for(i&&i(a);n.length;)t[n.pop()]=1;e(o)}})(),o=a.x,a.x=()=>a.e(657).then(o);var s=a.x();helm=s})();
2
+ //# sourceMappingURL=323.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"323.js","mappings":"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","sources":["webpack://helm/webpack/runtime/chunk loaded","webpack://helm/webpack/runtime/startup chunk dependencies","webpack://helm/../../libraries/bio/src/helm/consts.ts","webpack://helm/../../libraries/bio/src/monomer-works/consts.ts","webpack://helm/../../libraries/bio/src/monomer-works/types.ts","webpack://helm/../../libraries/bio/src/utils/const.ts","webpack://helm/../../libraries/bio/src/utils/macromolecule/types.ts","webpack://helm/../../libraries/bio/src/utils/macromolecule/consts.ts","webpack://helm/../../libraries/bio/src/monomer-works/monomer-works.ts","webpack://helm/../../libraries/bio/src/monomer-works/to-atomic-level-utils.ts","webpack://helm/../../libraries/bio/src/monomer-works/seq-to-molfile-worker.ts","webpack://helm/webpack/bootstrap","webpack://helm/webpack/runtime/define property getters","webpack://helm/webpack/runtime/ensure chunk","webpack://helm/webpack/runtime/get javascript chunk filename","webpack://helm/webpack/runtime/global","webpack://helm/webpack/runtime/hasOwnProperty shorthand","webpack://helm/webpack/runtime/publicPath","webpack://helm/webpack/runtime/importScripts chunk loading","webpack://helm/webpack/startup"],"sourcesContent":["var deferred = [];\n__webpack_require__.O = (result, chunkIds, fn, priority) => {\n\tif(chunkIds) {\n\t\tpriority = priority || 0;\n\t\tfor(var i = deferred.length; i > 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar [chunkIds, fn, priority] = deferred[i];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every((key) => (__webpack_require__.O[key](chunkIds[j])))) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","var next = __webpack_require__.x;\n__webpack_require__.x = () => {\n\treturn __webpack_require__.e(657).then(next);\n};","// HELM type vocabulary is owned by `@datagrok-libraries/hwe` (the standalone\n// HELM editor) and re-exported here as the single source of truth. The string\n// values match the canonical Pistoia HELM Web Editor, except `NUCLEOTIDE` which\n// uses the corrected spelling `HELM_NUCLEOTIDE` (was `HELM_NUCLETIDE`).\nimport {HelmTypes, MonomerTypes, PolymerTypes} from '@datagrok-libraries/hwe';\n\nexport {HelmTypes, MonomerTypes, PolymerTypes};\n\n// hwe migration: these two small enums are not part of the hwe value vocabulary.\n// They are defined here locally (replicating the legacy HELM Web Editor values)\n// so `@datagrok-libraries/bio` no longer depends on\n// `@datagrok-libraries/helm-web-editor`.\nexport enum MonomerNumberingTypes {\n default = 0,\n continuous = 1,\n}\n\nexport enum HelmTabKeys {\n Sequence = 'sequence',\n Helm = 'notation',\n Properties = 'properties',\n StructureView = 'structureview',\n}\n","import {PolymerTypes} from '../helm/consts';\n\nexport const monomerWorksConsts = {\n// constants for parsing molfile V2000\n V2K_RGP_SHIFT: 8,\n V2K_RGP_LINE: 'M RGP',\n V2K_A_LINE: 'A ',\n // constants for parsing/reconstruction of molfile V3000\n V3K_COUNTS_SHIFT: 14,\n V3K_IDX_SHIFT: 7,\n V3K_HEADER_FIRST_LINE: '\\nDatagrok macromolecule handler\\n\\n',\n V3K_HEADER_SECOND_LINE: ' 0 0 0 0 0 0 999 V3000\\n',\n V3K_BEGIN_CTAB_BLOCK: 'M V30 BEGIN CTAB\\n',\n V3K_END_CTAB_BLOCK: 'M V30 END CTAB\\n',\n V3K_BEGIN_COUNTS_LINE: 'M V30 COUNTS ',\n V3K_COUNTS_LINE_ENDING: ' 0 0 0\\n',\n V3K_BEGIN_ATOM_BLOCK: 'M V30 BEGIN ATOM\\n',\n V3K_END_ATOM_BLOCK: 'M V30 END ATOM\\n',\n V3K_BEGIN_BOND_BLOCK: 'M V30 BEGIN BOND\\n',\n V3K_END_BOND_BLOCK: 'M V30 END BOND\\n',\n V3K_BOND_CONFIG: ' CFG=',\n V3K_BEGIN_DATA_LINE: 'M V30 ',\n V3K_END: 'M END',\n PRECISION_FACTOR: 10_000, // HELMCoreLibrary has 4 significant digits after decimal point in atom coordinates\n // symbols for the corresponding monomers in HELM library\n\n DEOXYRIBOSE: {polymerType: PolymerTypes.RNA, symbol: 'd'},\n RIBOSE: {polymerType: PolymerTypes.RNA, symbol: 'r'},\n PHOSPHATE: {polymerType: PolymerTypes.RNA, symbol: 'p'},\n\n OXYGEN: 'O',\n HYDROGEN: 'H',\n} as const;\n\n","// interface for typed arrays, like Float32Array and Uint32Array\nimport {ALPHABET} from '../utils/macromolecule';\nimport {HELM_POLYMER_TYPE} from '../utils/const';\nimport {HelmType, ISeqMonomer} from '../helm/types';\n\nexport interface ITypedArray {\n length: number;\n [key: number]: any;\n}\n\n/** Type for user settings of monomer library set to use. */\nexport type UserLibSettings = {\n exclude: string[],\n explicit: string[],\n /** Libraries might contain different monomers for same symbol. Object for monomer symbol to library name of choice*/\n duplicateMonomerPreferences: {[polymerType: string]: {[monomerSymbol: string]: string}}\n}\n\n/** Stores necessary data about atoms of a monomer parsed from Molfile */\nexport type Atoms = {\n /** Element symbols for monomer's atoms */\n atomTypes: string[],\n /** Cartesian coordiantes of monomer's atoms */\n x: Float32Array,\n y: Float32Array,\n /** V3K atom line may contain keyword args */\n kwargs: string[],\n }\n\n/** Stores necessary data about bonds of a monomer parsed from Molfile */\nexport type Bonds = {\n /** bond types for all lines of Molfile bond block */\n bondTypes: Uint32Array,\n /** Indices of all atom pairs, indexing starting from 1 */\n atomPairs: number[][],\n /** If a bond has CFG=... keyword argument, it is parsed and sotred as a\n * value of the map, with the key being the bond's index */\n bondConfiguration: Map<number, number>,\n /** V3K bond line may contain keyword args */\n kwargs: Map<number, string>,\n}\n\n/** Metadata associated with the monomer necessary to restore the resulting molfile */\nexport type MonomerMetadata = {\n /** terminal nodes: 0-th corresponds to the \"leftmost\" one, 1st, to the \"rightmost\",\n * e.g. N-terminus and C-terminus in peptides */\n terminalNodes: number[],\n /** r-group nodes: 0-th corresponds to the \"leftmost\" one, 1st, to the \"rightmost\" */\n rNodes: number[],\n /** shift from the origin to the next backbone, null for branch monomers */\n backboneShift: number[] | null,\n /** shift from the origin to the next branch, null for branch monomers */\n branchShift: number[] | null\n}\n\nexport type MolGraph = {\n atoms: Atoms,\n bonds: Bonds,\n meta: MonomerMetadata,\n stereoAtoms?: number[],\n terminalR2Atom?: string, // for peptides, store the removed R2 Atom type, if any\n}\n\nexport type MonomerMolGraphMap = { [polymerType: string]: { [symbol: string]: MolGraph } };\n\nexport type LibMonomerKey = { polymerType: string, symbol: string }\n\nexport function getMolGraph(dict: MonomerMolGraphMap, libKey: LibMonomerKey): MolGraph | undefined {\n return dict[libKey.polymerType]?.[libKey.symbol];\n}\n\nexport function hasMolGraph(dict: MonomerMolGraphMap, libKey: LibMonomerKey): boolean {\n return !!dict[libKey.polymerType]?.[libKey.symbol];\n}\n\nexport function setMolGraph(dict: MonomerMolGraphMap, libKey: LibMonomerKey, value: MolGraph): void {\n let pt = dict[libKey.polymerType];\n if (!pt)\n pt = dict[libKey.polymerType] = {};\n pt[libKey.symbol] = value;\n}\n\n// export function getMolGraph(\n// dict: MonomerMolGraphMap, polymerType: PolymerType, symbol: string\n// ): MolGraph | undefined {\n// return dict[polymerType]?.[symbol];\n// }\n\nexport type Point = {\n x: number,\n y: number\n}\n\n/** Helper structure wrapping common arguments to several functions */\nexport type LoopVariables = {\n i: number,\n nodeShift: number,\n bondShift: number,\n backbonePositionShift: number[],\n backboneAttachNode: number; // node to which the next backbone is attached\n branchPositionShift: number[],\n branchAttachNode: number,\n flipFactor: number,\n // todo: should we consider representations other than planar?\n}\n\n/** Helper structure wrapping common arguments to several functions */\nexport type LoopConstants = {\n sugar: MolGraph | null,\n phosphate: MolGraph | null,\n seqLength: number,\n atomCount: number,\n bondCount: number,\n}\n\n/** Helper structure to simulate pointer to number */\nexport type NumberWrapper = {\n value: number | null // null if there is no branch attach node\n}\n\n/** Role of an entry in a HELM RNA splitted sequence.\n * SUGAR/BASE/PHOSPHATE are the standard triple positions.\n * TERMINAL_5P marks a 5'-end terminal modifier (e.g. Chol) — a monomer\n * with R2 only that takes the place of the leading sugar.\n * TERMINAL_3P marks a 3'-end terminal modifier (e.g. GalNAc) — a monomer\n * with R1 only that takes the place of the trailing phosphate. The OH cap\n * MUST be omitted when a TERMINAL_3P is present. */\nexport enum NucleotideRole {\n SUGAR = 0,\n BASE = 1,\n PHOSPHATE = 2,\n TERMINAL_5P = 3,\n TERMINAL_3P = 4,\n}\n\nexport type MonomerMapValue = { biotype: HelmType, symbol: string, atoms: number[], bonds: number[] };\n\nexport class MonomerMap extends Map<number, MonomerMapValue> {\n constructor(entries?: [number, MonomerMapValue][] | null) {\n super(entries);\n }\n}\n\n/** @property monomers key - helm seq position, */\nexport class MolfileWithMap {\n constructor(\n public readonly molfile: string,\n public readonly monomers: MonomerMap,\n ) {}\n\n static createEmpty() { return new MolfileWithMap('', new MonomerMap(null)); }\n}\n\n/** Only simple types allowed for worker data, avoid classes with methods */\nexport type SeqToMolfileWorkerData = {\n seqList: ISeqMonomer[][],\n /** Per-row parallel array of NucleotideRole tags (only set for rows in\n * \"HELM RNA triples\" mode, where each nucleotide contributes 3 entries\n * sugar/base/phosphate). undefined for legacy bases-only rows. */\n rolesList?: (NucleotideRole[] | undefined)[],\n monomersDict: MonomerMolGraphMap,\n alphabet: ALPHABET,\n polymerType: HELM_POLYMER_TYPE,\n start: number,\n end: number,\n}\n\nexport type SeqToMolfileWorkerRes = {\n molfiles: MolfileWithMap[];\n warnings: string[]\n}\n","import {MonomerType, PolymerType} from '../helm/types';\nimport {MonomerTypes, PolymerTypes} from '../helm/consts';\nimport {RGroup} from '../types/monomer-library';\n\n// hwe exports the HELM type vocabulary as `as const` objects (value-only), not\n// TS enums, so we re-create the value+type duality the old `import X = Enum`\n// aliases provided — consumers use these both as a value (`.RNA`) and as a type.\nconst HELM_POLYMER_TYPE = PolymerTypes;\ntype HELM_POLYMER_TYPE = PolymerType;\nconst HELM_MONOMER_TYPE = MonomerTypes;\ntype HELM_MONOMER_TYPE = MonomerType;\n\nexport {HELM_POLYMER_TYPE, HELM_MONOMER_TYPE};\n\n/** Required HELM library monomer fields:\n * https://github.com/PistoiaHELM/HELMMonomerSets/blob/master/HELMmonomerSchema.json */\nexport const enum HELM_REQUIRED_FIELD {\n SYMBOL = 'symbol',\n NAME = 'name',\n MOLFILE = 'molfile',\n AUTHOR = 'author',\n ID = 'id',\n RGROUPS = 'rgroups',\n SMILES = 'smiles',\n POLYMER_TYPE = 'polymerType',\n MONOMER_TYPE = 'monomerType',\n CREATE_DATE = 'createDate',\n}\n\n// fields of \"rgroups\" sub-object in HELM library\nexport const enum HELM_RGROUP_FIELDS {\n CAP_GROUP_SMILES = 'capGroupSmiles',\n // WARNING: both capitalization variants coexist\n CAP_GROUP_SMILES_UPPERCASE = 'capGroupSMILES',\n ALTERNATE_ID = 'alternateId',\n CAP_GROUP_NAME = 'capGroupName',\n LABEL = 'label',\n}\n\nexport const enum HELM_OPTIONAL_FIELDS {\n NATURAL_ANALOG = 'naturalAnalog',\n META = 'meta', // for SequenceTranslator\n}\n\n// todo: remove\nexport const enum HELM_FIELDS {\n MONOMER_TYPE = 'monomerType',\n SMILES = 'smiles',\n NAME = 'name',\n AUTHOR = 'author',\n MOLFILE = 'molfile',\n NATURAL_ANALOG = 'naturalAnalog',\n RGROUPS = 'rgroups',\n CREATE_DATE = 'createDate',\n ID = 'id',\n POLYMER_TYPE = 'polymerType',\n SYMBOL = 'symbol'\n}\n\n// core fields of HELM library object used in toAtomicLevel function\nexport const HELM_CORE_FIELDS = [\n HELM_FIELDS.SYMBOL,\n HELM_FIELDS.MOLFILE,\n HELM_FIELDS.RGROUPS,\n HELM_FIELDS.NAME,\n // HELM_FIELDS.MONOMER_TYPE, // add if terminal monomers for PEPTIDEs to be\n // supported\n];\n\nexport const SDF_MONOMER_NAME = 'MonomerName';\n\n// todo: ideally, keys should be expressed via constants\nexport const jsonSdfMonomerLibDict = {\n 'monomerType': null, // -> Backbone\n 'smiles': null,\n 'name': 'Name',\n 'author': null,\n 'molfile': 'molecule',\n 'naturalAnalog': 'MonomerNaturalAnalogCode',\n 'rgroups': 'MonomerCaps',\n 'createDate': null,\n 'id': null,\n 'polymerType': 'MonomerType',\n 'symbol': 'MonomerName'\n};\n\nexport const DUMMY_MONOMER = {\n 'monomerType': 'Backbone' as MonomerType,\n 'smiles': '',\n 'name': '',\n 'author': 'Datagrok',\n 'molfile': '',\n 'naturalAnalog': '',\n 'rgroups': [] as RGroup[],\n 'createDate': null,\n 'id': 0,\n 'polymerType': 'PEPTIDE' as PolymerType,\n 'symbol': ''\n} as const;\n\n// range of hex nubers used in PepSea library to endode monomers\nexport const MONOMER_ENCODE_MIN = 0x100;\nexport const MONOMER_ENCODE_MAX = 0x40A;\n\nexport const RIBOSE_SYMBOL = 'r';\nexport const DEOXYRIBOSE_SYMBOL = 'd';\nexport const PHOSPHATE_SYMBOL = 'p';\nexport const HELM_WRAPPERS_REGEXP = new RegExp(\n `[${RIBOSE_SYMBOL}${DEOXYRIBOSE_SYMBOL}]\\\\((\\\\w)\\\\)${PHOSPHATE_SYMBOL}?`,\n 'g'\n);\n\n","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {CellRendererBackBase} from '../cell-renderer-back-base';\nimport {ISeqHandler} from './seq-handler';\nimport {PolymerType} from '../../helm/types';\nimport {NOTATION_PROVIDER_CONSTRUCTOR_ROLE} from './consts';\n\nexport type SeqSplittedBase = ArrayLike<string> & Iterable<string>;\n\nexport interface ISeqConnection {\n seq1Type: PolymerType;\n seq2Type: PolymerType;\n seqIndex1: number;\n seqIndex2: number;\n monomerIndex1: number;\n monomerIndex2: number;\n rGroup1: number;\n rGroup2: number;\n}\n\nexport interface ISeqGraphInfo {\n /** Connections between monomers with numbers - note that monomer numbers are 0-based*/\n connections: ISeqConnection[];\n /** Start positions of disjoint sequence parts in the original sequence */\n disjointSeqStarts: number[];\n /** Polimer types same as the indexes. only applicapble to helm */\n polymerTypes?: PolymerType[];\n}\n\nexport interface ISeqSplitted {\n\n graphInfo?: ISeqGraphInfo;\n\n isGap(posIdx: number): boolean;\n\n /** */\n getCanonical(posIdx: number): string;\n\n /** For fasta and Helm must not be enclosed to square brackets [meA].*/\n getOriginal(posIdx: number): string;\n\n // TODO: Get ISeqMonomer for seq position\n // get(posIdx: number): ISeqMonomer;\n\n length: number;\n\n /** Returns list of canonical monomers in the region specified */\n getCanonicalRegion(start: number, end: number): string[];\n\n /** Returns the list of original monomers in the region specified */\n getOriginalRegion(start: number, end: number): string[];\n\n get gapOriginal(): string;\n}\n\n/**\n * Extracts displayable monomer symbol(s) from a raw position value.\n * Used by the Monomer cell renderer when a notation provider needs custom\n * interpretation of split-to-monomer position values.\n *\n * For example, a Parabilis position `[VHL1379]*dLys` contains two monomers\n * (`VHL1379` and `dLys`). The canonicalizer separates them with\n * {@link MONOMER_MOTIF_SPLITTER} so the renderer can display/tooltip each one.\n */\nexport interface IMonomerCanonicalizer {\n /** Convert a raw position value to a displayable monomer string.\n * If the position contains multiple monomers, join them with\n * {@link MONOMER_MOTIF_SPLITTER} (` , `). */\n canonicalize(original: string): string;\n\n /** Returns true if the raw position value represents a gap in this notation. */\n isGap(original: string): boolean;\n}\n\nexport interface INotationProvider {\n get defaultGapOriginal(): string;\n\n /** Adjust {@link seqHandler} units, {@link seqHandler.column.tags} by {@link seqHandler} constructor */\n setUnits(seqHandler: ISeqHandler): void;\n\n get splitter(): SplitterFunc;\n\n /** Any Macromolecule can be presented as Helm notation */\n getHelm(seq: string, options: any): string;\n\n createCellRendererBack(gridCol: DG.GridColumn | null, tableCol: DG.Column<string>): CellRendererBackBase<string>;\n\n /** nqName of a registered function that returns an {@link IMonomerCanonicalizer} instance.\n * When set, split-to-monomers will tag Monomer columns with this function name so the\n * monomer cell renderer can resolve display symbols from raw position values.\n * Return null/undefined if no custom canonicalization is needed. */\n readonly monomerCanonicalizerFuncName?: string | null;\n}\n\nexport abstract class NotationProviderBase {\n /** Name of the custom notation */\n static get notationName(): string {\n return 'Custom';\n };\n\n /** flag to let bio know if this provider implements method for converting helm to it */\n static get implementsFromHelm(): boolean {\n return false;\n };\n\n /** Method for converting HELM to this notation */\n static convertFromHelm(helm: string, options: any): string {\n throw new Error(`Method convertFromHelm not implemented for this notation provider`);\n };\n\n static async getProviderConstructors(): Promise<typeof NotationProviderBase[]> {\n // this is terrible, I know, but otherwise this gets put in webworkers and fails due to DG resolution)))\n // @ts-ignore\n if (window?.DG) {\n // @ts-ignore\n const constFuncs: any[] = window.DG.Func.find({meta: {role: NOTATION_PROVIDER_CONSTRUCTOR_ROLE}});\n return Promise.all(constFuncs.map((f) => f.apply({})));\n }\n return [];\n }\n}\n\nexport type SeqColStats = { freq: MonomerFreqs, sameLength: boolean }\nexport type SplitterFunc = (seq: string) => ISeqSplitted;\nexport type MonomerFreqs = { [m: string]: number };\n\n/** Alphabet candidate type */\nexport class CandidateType {\n name: string;\n alphabet: Set<string>;\n cutoff: number;\n\n constructor(name: string, alphabet: Set<string>, cutoff: number) {\n this.name = name;\n this.alphabet = alphabet;\n this.cutoff = cutoff;\n }\n}\n\n/** Alphabet candidate similarity type */\nexport class CandidateSimType extends CandidateType {\n freq: MonomerFreqs;\n /** Cos, max = 1, min = 0 */\n similarity: number;\n\n constructor(candidate: CandidateType, freq: MonomerFreqs, similarity: number) {\n super(candidate.name, candidate.alphabet, candidate.cutoff);\n this.freq = freq;\n this.similarity = similarity;\n }\n}\n","import {CandidateType} from './types';\n\n/** enum type to simplify setting \"user-friendly\" notation if necessary */\nexport enum NOTATION {\n FASTA = 'fasta',\n SEPARATOR = 'separator',\n HELM = 'helm',\n /* Requires notation handler */ CUSTOM = 'custom',\n /* Requires notation handler */ BILN = 'biln',\n}\n\nexport const enum ALIGNMENT {\n SEQ_MSA = 'SEQ.MSA',\n SEQ = 'SEQ',\n}\n\nexport enum ALPHABET {\n DNA = 'DNA',\n RNA = 'RNA',\n PT = 'PT',\n /** Unknown */\n UN = 'UN',\n}\n\nexport enum TAGS {\n aligned = 'aligned',\n alphabet = 'alphabet',\n alphabetSize = '.alphabetSize',\n alphabetIsMultichar = '.alphabetIsMultichar',\n separator = 'separator',\n isHelmCompatible = '.isHelmCompatible',\n positionNames = '.positionNames',\n positionLabels = '.positionLabels',\n regions = '.regions',\n positionShift = '.positionShift',\n selectedPosition = '.selectedPosition',\n polymerTypeColumnName = '.polymerTypeColumnName',\n annotations = '.annotations',\n numberingScheme = '.numberingScheme',\n annotationColumnName = '.annotationColumnName',\n}\n\nexport {TAGS as BioTags};\n\nexport const positionSeparator: string = ', ';\n\nexport const monomerRe: RegExp = /(?:\\[([A-Za-z0-9_\\-,()]+)\\])|([A-Za-z\\-])/g;\n\nexport const helmRe: RegExp = /(PEPTIDE1|DNA1|RNA1)\\{([^}]+)}/g;\nexport const helmPp1Re: RegExp = /\\[([^\\[\\]]+)]/g;\n\nexport const Alphabets = new class {\n fasta = {\n peptide: new Set<string>([\n 'G', 'L', 'Y', 'S', 'E', 'Q', 'D', 'N', 'F', 'A',\n 'K', 'R', 'H', 'C', 'V', 'P', 'W', 'I', 'M', 'T',\n ]),\n dna: new Set<string>(['A', 'C', 'G', 'T']),\n rna: new Set<string>(['A', 'C', 'G', 'U']),\n };\n}();\n\nexport const candidateAlphabets: CandidateType[] = [\n new CandidateType(ALPHABET.PT, Alphabets.fasta.peptide, 0.50),\n new CandidateType(ALPHABET.DNA, Alphabets.fasta.dna, 0.55),\n new CandidateType(ALPHABET.RNA, Alphabets.fasta.rna, 0.55),\n];\n\n/** Canonical gap symbol */\nexport const GAP_SYMBOL: string = '' as const;\n\nexport const GapOriginals: {\n [units: string]: string\n} = {\n [NOTATION.FASTA]: '-',\n [NOTATION.SEPARATOR]: '',\n [NOTATION.HELM]: '*',\n [NOTATION.BILN]: '',\n};\n\nexport const MONOMER_MOTIF_SPLITTER = ' , ';\n\n/** Tag on Monomer columns storing the nqName of a function that returns an IMonomerCanonicalizer.\n * The `.%` prefix ensures this tag is persisted with projects. */\nexport const MONOMER_CANONICALIZER_FUNC_TAG = '.%monomer-canonicalizer-func';\n\n/** Column temp key for the cached IMonomerCanonicalizer instance */\nexport const MONOMER_CANONICALIZER_TEMP = 'monomer-canonicalizer';\nexport const NOTATION_PROVIDER_CONSTRUCTOR_ROLE = 'notationProviderConstructor';\n","import * as grok from 'datagrok-api/grok';\nimport * as ui from 'datagrok-api/ui';\nimport * as DG from 'datagrok-api/dg';\n\nimport {IMonomerLibBase} from '../types/monomer-library';\nimport {HelmType, PolymerType} from '../helm/types';\nimport {HelmTypes, PolymerTypes} from '../helm/consts';\n\n/** Hypothetical interface to convert mol block notation.\n * It should be placed in the chem-meta package, and have an implementation in the Chem package.\n * So dependency of MonomerWorks on molfile conversion operation becomes explicit.\n */\nexport interface IMolfileConverter {\n convertV2000toV3000(src: string): string;\n\n convertV3000toV2000(src: string): string;\n}\n\nexport class MonomerWorks {\n private monomerLib: IMonomerLibBase;\n\n //private molfileConverter: IMolfileConverter;\n\n constructor(monomerLib: IMonomerLibBase/*, molfileConverter: IMolfileConverter*/) {\n this.monomerLib = monomerLib;\n //this.molfileConverter = molfileConverter;\n }\n\n //types according to Monomer possible\n public getCappedRotatedMonomer(monomerType: PolymerType, monomerName: string): string | null {\n // TODO: Check type of monomerType arg\n const monomer = this.monomerLib.getMonomer(monomerType, monomerName);\n if (monomer)\n return monomer.molfile; //TODO cap\n\n return null;\n }\n}\n\nexport function helmTypeToPolymerType(helmType: HelmType): PolymerType {\n let polymerType: PolymerType | undefined = undefined;\n switch (helmType) {\n case HelmTypes.BASE:\n case HelmTypes.SUGAR: // r - ribose, d - deoxyribose\n case HelmTypes.LINKER: // p - phosphate\n case HelmTypes.NUCLEOTIDE:\n // @ts-ignore\n case 'nucleotide':\n polymerType = PolymerTypes.RNA;\n break;\n case HelmTypes.AA:\n polymerType = PolymerTypes.PEPTIDE;\n break;\n case HelmTypes.CHEM:\n polymerType = PolymerTypes.CHEM;\n break;\n case HelmTypes.BLOB:\n polymerType = PolymerTypes.BLOB;\n break;\n default:\n polymerType = PolymerTypes.PEPTIDE;\n console.warn(`Unexpected HelmType '${helmType}'`);\n }\n return polymerType;\n}\n","/* eslint-disable max-len */\nimport {monomerWorksConsts as C} from './consts';\nimport {getMolGraph, LoopConstants, LoopVariables, MolfileWithMap, MolGraph, MonomerMap, MonomerMolGraphMap,\n NucleotideRole} from './types';\nimport {HELM_FIELDS, HELM_CORE_FIELDS, HELM_POLYMER_TYPE, HELM_MONOMER_TYPE,} from '../utils/const';\nimport {ALPHABET, GAP_SYMBOL} from '../utils/macromolecule/consts';\nimport {IMonomerLibBase, Monomer} from '../types/monomer-library';\nimport {ISeqMonomer, PolymerType} from '../helm/types';\nimport {helmTypeToPolymerType} from './monomer-works';\n\n\n/** Get a mapping of peptide symbols to HELM monomer library objects with selected fields.\n * @param {IMonomerLib} monomerLib - Monomer library\n * @param {HELM_POLYMER_TYPE} polymerType - Polymer type\n * @param {ALPHABET} alphabet - Alphabet of the column\n * @return {Map<string, any>} - Mapping of peptide symbols to HELM monomer library objects with selected fields*/\nexport function getFormattedMonomerLib(\n monomerLib: IMonomerLibBase, polymerType: PolymerType, alphabet: ALPHABET\n): Map<string, any> {\n const map = new Map<string, any>();\n for (const monomerSymbol of monomerLib.getMonomerSymbolsByType(polymerType)) {\n const it: Monomer = monomerLib.getMonomer(polymerType, monomerSymbol)!;\n if (\n // RNA: all branch monomers (bases) and all backbone monomers (sugars +\n // phosphates, including modified ones). Modifications are looked up by\n // symbol at assembly time, so they MUST be present in the formatted lib.\n polymerType === HELM_POLYMER_TYPE.RNA || (\n polymerType === HELM_POLYMER_TYPE.PEPTIDE &&\n it[HELM_FIELDS.MONOMER_TYPE] !== HELM_MONOMER_TYPE.BRANCH\n )) {\n const monomerObject: { [key: string]: any } = {};\n HELM_CORE_FIELDS.forEach((field) => {\n //@ts-ignore\n monomerObject[field] = it[field];\n });\n map.set(monomerSymbol, monomerObject);\n }\n }\n return map;\n}\n\n/** Translate a sequence of monomer symbols into Molfile V3000\n * @param {ISeqMonomer[]} monomerSeq - Sequence of monomer symbols (canonical)\n * @param {MonomerMolGraphMap} monomersDict - Mapping of monomer symbols to MolGraph objects\n * @param {ALPHABET} alphabet - Alphabet of the column\n * @param {PolymerType} polymerType - Polymer type\n * @param {Array} roles - Optional per-position NucleotideRole tags. When set, RNA assembly\n * uses per-position sugars/phosphates from monomerSeq directly (HELM triples mode).\n * @return {MolfileWithMap} - Molfile V3000 + per-position monomer index map */\nexport function monomerSeqToMolfile(\n monomerSeq: ISeqMonomer[], monomersDict: MonomerMolGraphMap,\n alphabet: ALPHABET, polymerType: PolymerType,\n roles?: NucleotideRole[]\n): MolfileWithMap {\n if (monomerSeq.length === 0) {\n // throw new Error('monomerSeq is empty');\n return MolfileWithMap.createEmpty();\n }\n\n // Triples mode is on only when the caller flagged the row with roles\n // (built and validated by `buildRolesForHelmRna` in to-atomic-level.ts).\n // The roles array carries the per-position semantics — including\n // TERMINAL_5P / TERMINAL_3P for non-canonical chain ends — so we don't\n // re-validate the length here.\n const triplesMode = polymerType === HELM_POLYMER_TYPE.RNA && !!roles &&\n roles.length === monomerSeq.length;\n\n // define atom and bond counts, taking into account the bond type\n const {atomCount, bondCount, needsCapping} =\n getResultingAtomBondCounts(monomerSeq, monomersDict, alphabet, polymerType, triplesMode, roles);\n\n // create arrays to store lines of the resulting molfile\n const molfileAtomBlock = new Array<string>(atomCount);\n const molfileBondBlock = new Array<string>(bondCount);\n\n let addMonomerToMolblock: (monomer: MolGraph, molfileAtomBlock: string[], molfileBondBlock: string[], v: LoopVariables, LC: LoopConstants) => void;\n\n let sugar = null;\n let phosphate = null;\n\n if (polymerType === HELM_POLYMER_TYPE.PEPTIDE)\n addMonomerToMolblock = addAminoAcidToMolblock;\n else { // nucleotides\n addMonomerToMolblock = addNucleotideToMolblock;\n // Default sugar/phosphate are only consulted in bases-only mode. In\n // triples mode, every nucleotide carries its own.\n if (!triplesMode) {\n sugar = (alphabet === ALPHABET.DNA) ? getMolGraph(monomersDict, C.DEOXYRIBOSE) : getMolGraph(monomersDict, C.RIBOSE);\n phosphate = getMolGraph(monomersDict, C.PHOSPHATE);\n }\n }\n const v: LoopVariables = {\n i: 0,\n nodeShift: 0,\n bondShift: 0,\n backbonePositionShift: new Array<number>(2).fill(0),\n branchPositionShift: new Array<number>(2).fill(0),\n backboneAttachNode: 0,\n branchAttachNode: 0,\n flipFactor: 1,\n };\n\n const LC: LoopConstants = {\n sugar: sugar!,\n phosphate: phosphate!,\n // In triples mode, the \"logical\" sequence length is the nucleotide count.\n seqLength: triplesMode ? Math.ceil(monomerSeq.length / 3) : monomerSeq.length,\n atomCount: atomCount,\n bondCount: bondCount,\n };\n\n const monomers: MonomerMap = new MonomerMap();\n const steabsCollection: number [] = [];\n let nAtoms = 0;\n let lastMonomerCappingAtom: string | undefined = undefined;\n\n if (triplesMode) {\n runTriplesAssembly(\n monomerSeq, roles!, monomersDict, molfileAtomBlock, molfileBondBlock,\n v, LC, monomers, steabsCollection,\n (a) => { nAtoms += a; }, () => nAtoms);\n } else {\n for (v.i = 0; v.i < LC.seqLength; ++v.i) {\n const seqMonomer = monomerSeq[v.i];\n if (seqMonomer.symbol === GAP_SYMBOL) continue;\n const monomer = getMolGraph(monomersDict, {symbol: seqMonomer.symbol, polymerType: helmTypeToPolymerType(seqMonomer.biotype)})!;\n lastMonomerCappingAtom = monomer.terminalR2Atom;\n const mAtomFirst = v.nodeShift;\n const mBondFirst = v.bondShift;\n addMonomerToMolblock(monomer, molfileAtomBlock, molfileBondBlock, v, LC);\n //adding stereo atoms to array for further STEABS block generation\n monomer.stereoAtoms?.forEach((i) => steabsCollection.push(i + nAtoms));\n nAtoms += monomer.atoms.x.length;\n\n const mAtomCount = v.nodeShift - mAtomFirst;\n const mAtomList: number[] = new Array<number>(mAtomCount);\n for (let maI = 0; maI < mAtomCount; ++maI) mAtomList[maI] = mAtomFirst + maI;\n\n const mBondCount = v.bondShift - mBondFirst;\n const mBondList: number[] = new Array<number>(mBondCount);\n for (let mbI = 0; mbI < mBondCount; ++mbI) mBondList[mbI] = mBondFirst + mbI;\n\n monomers.set(v.i, {\n biotype: seqMonomer.biotype,\n symbol: seqMonomer.symbol,\n atoms: mAtomList, bonds: mBondList\n });\n }\n }\n\n // if the last monomer needs to be capped, add the terminal OH to the resulting molfile\n if (needsCapping)\n capResultingMolblock(molfileAtomBlock, molfileBondBlock, v, LC, lastMonomerCappingAtom ?? C.OXYGEN);\n\n const molfileCountsLine = C.V3K_BEGIN_COUNTS_LINE + atomCount + ' ' + bondCount + C.V3K_COUNTS_LINE_ENDING;\n\n // todo: possible optimization may be achieved by replacing .join('') with +=\n // since counterintuitively joining an array into a new string is reportedly\n // slower than using += as below\n\n let result = '';\n result += C.V3K_HEADER_FIRST_LINE;\n result += C.V3K_HEADER_SECOND_LINE;\n result += C.V3K_BEGIN_CTAB_BLOCK;\n result += molfileCountsLine;\n result += C.V3K_BEGIN_ATOM_BLOCK;\n result += molfileAtomBlock.join('');\n result += C.V3K_END_ATOM_BLOCK;\n result += C.V3K_BEGIN_BOND_BLOCK;\n result += molfileBondBlock.join('');\n result += C.V3K_END_BOND_BLOCK;\n if (steabsCollection.length > 0)\n result += getCollectionBlock(steabsCollection);\n result += C.V3K_END_CTAB_BLOCK;\n result += C.V3K_END;\n\n // return molfileParts.join('');\n return {molfile: result, monomers: monomers};\n}\n\n\nfunction getCollectionBlock(collection: number[]): string {\n //one row in STEABS block can be no longer than 80 symbols\n //maxSymbols = 80 symbols minus ' -\\n' (4 symbols)\n const maxSymbols = 76;\n const rowsArray = [];\n\n let newCollectionRow = `M V30 MDLV30/STEABS ATOMS=(${collection.length}`;\n for (let i = 0; i < collection.length; i++) {\n const updatedRow = `${newCollectionRow} ${collection[i]}`;\n if (updatedRow.length > maxSymbols) {\n rowsArray.push(`${newCollectionRow} -\\n`);\n newCollectionRow = `M V30 ${collection[i]}`;\n } else\n newCollectionRow = updatedRow;\n //in case last atom was added - close the block\n if (i === collection.length - 1)\n rowsArray.push(`${newCollectionRow})\\n`);\n }\n return `M V30 BEGIN COLLECTION\\n${rowsArray.join('')}M V30 END COLLECTION\\n`;\n}\n\n/** Cap the resulting (after sewing up all the monomers) molfile with 'O'\n * @param {string[]} molfileAtomBlock - Array of lines of the resulting molfile atom block\n * @param {string[]} molfileBondBlock - Array of lines of the resulting molfile bond block\n * @param {LoopVariables} v - Loop variables\n * @param {LoopConstants} LC - Loop constants*/\nfunction capResultingMolblock(\n molfileAtomBlock: string[], molfileBondBlock: string[],\n v: LoopVariables, LC: LoopConstants, cappingAtomType: string = C.OXYGEN\n): void {\n // add terminal oxygen\n const atomIdx = v.nodeShift + 1;\n molfileAtomBlock[LC.atomCount] = C.V3K_BEGIN_DATA_LINE + atomIdx + ' ' +\n (cappingAtomType ?? C.OXYGEN) + ' ' + keepPrecision(v.backbonePositionShift[0]) + ' ' +\n v.flipFactor * keepPrecision(v.backbonePositionShift[1]) + ' ' + '0.000000 0' + '\\n';\n\n // add terminal bond\n const firstAtom = v.backboneAttachNode;\n const secondAtom = atomIdx;\n molfileBondBlock[LC.bondCount] = C.V3K_BEGIN_DATA_LINE + v.bondShift + ' ' +\n 1 + ' ' + firstAtom + ' ' + secondAtom + '\\n';\n}\n\nfunction addAminoAcidToMolblock(monomer: MolGraph, molfileAtomBlock: string[],\n molfileBondBlock: string[], v: LoopVariables\n): void {\n v.flipFactor = (-1) ** (v.i % 2); // to flip every even monomer over OX\n addBackboneMonomerToMolblock(monomer, molfileAtomBlock, molfileBondBlock, v);\n}\n\nfunction addBackboneMonomerToMolblock(\n monomer: MolGraph, molfileAtomBlock: string[], molfileBondBlock: string[], v: LoopVariables\n): void {\n // todo: remove these comments to the docstrings of the corr. functions\n // construnct the lines of V3K molfile atom block\n fillAtomLines(monomer, molfileAtomBlock, v);\n\n // construct the lines of V3K molfile bond block\n fillBondLines(monomer, molfileBondBlock, v);\n\n // peptide bond\n fillChainExtendingBond(monomer, molfileBondBlock, v);\n\n // update branch variables if necessary\n if (monomer.meta.branchShift !== null && monomer.meta.terminalNodes.length > 2)\n updateBranchVariables(monomer, v);\n\n // update loop variables\n updateChainExtendingVariables(monomer, v);\n}\n\nfunction addNucleotideToMolblock(\n nucleobase: MolGraph, molfileAtomBlock: string[], molfileBondBlock: string[], v: LoopVariables, LC: LoopConstants\n): void {\n // construnct the lines of V3K molfile atom block corresponding to phosphate\n // and sugar\n if (v.i === 0)\n addBackboneMonomerToMolblock(LC.sugar!, molfileAtomBlock, molfileBondBlock, v);\n else {\n for (const monomer of [LC.phosphate, LC.sugar])\n addBackboneMonomerToMolblock(monomer!, molfileAtomBlock, molfileBondBlock, v);\n }\n\n addBranchMonomerToMolblock(nucleobase, molfileAtomBlock, molfileBondBlock, v);\n}\n\nfunction addBranchMonomerToMolblock(\n monomer: MolGraph, molfileAtomBlock: string[], molfileBondBlock: string[], v: LoopVariables\n): void {\n fillBranchAtomLines(monomer, molfileAtomBlock, v);\n fillBondLines(monomer, molfileBondBlock, v);\n fillBackboneToBranchBond(monomer, molfileBondBlock, v);\n\n // C-N bond\n const bondIdx = v.bondShift;\n const firstAtom = v.branchAttachNode;\n const secondAtom = monomer.meta.terminalNodes[0] + v.nodeShift;\n molfileBondBlock[bondIdx - 1] = C.V3K_BEGIN_DATA_LINE + bondIdx + ' ' +\n 1 + ' ' + firstAtom + ' ' + secondAtom + '\\n';\n\n // update loop variables\n v.bondShift += monomer.bonds.atomPairs.length + 1;\n v.nodeShift += monomer.atoms.atomTypes.length;\n}\n\nfunction updateChainExtendingVariables(monomer: MolGraph, v: LoopVariables): void {\n v.backboneAttachNode = v.nodeShift + monomer.meta.terminalNodes[1];\n v.bondShift += monomer.bonds.atomPairs.length + 1;\n\n v.nodeShift += monomer.atoms.atomTypes.length;\n v.backbonePositionShift[0] += monomer.meta.backboneShift?.[0] ?? 0; // todo: non-null check\n v.backbonePositionShift[1] += v.flipFactor * (monomer.meta.backboneShift?.[1] ?? 0);\n}\n\nfunction updateBranchVariables(monomer: MolGraph, v: LoopVariables): void {\n v.branchAttachNode = v.nodeShift + monomer.meta.terminalNodes[2];\n for (let i = 0; i < 2; ++i)\n v.branchPositionShift[i] = v.backbonePositionShift[i] + monomer.meta.branchShift![i];\n}\n\nfunction fillAtomLines(monomer: MolGraph, molfileAtomBlock: string[], v: LoopVariables): void {\n for (let j = 0; j < monomer.atoms.atomTypes.length; ++j) {\n const atomIdx = v.nodeShift + j + 1;\n molfileAtomBlock[v.nodeShift + j] = C.V3K_BEGIN_DATA_LINE + atomIdx + ' ' +\n monomer.atoms.atomTypes[j] + ' ' +\n keepPrecision(v.backbonePositionShift[0] + monomer.atoms.x[j]) + ' ' +\n keepPrecision(v.backbonePositionShift[1] + v.flipFactor * monomer.atoms.y[j]) +\n ' ' + monomer.atoms.kwargs[j];\n }\n}\n\n// todo: remove as quickfix\nfunction fillBranchAtomLines(monomer: MolGraph, molfileAtomBlock: string[], v: LoopVariables): void {\n for (let j = 0; j < monomer.atoms.atomTypes.length; ++j) {\n const atomIdx = v.nodeShift + j + 1;\n molfileAtomBlock[v.nodeShift + j] = C.V3K_BEGIN_DATA_LINE + atomIdx + ' ' +\n monomer.atoms.atomTypes[j] + ' ' +\n keepPrecision(v.branchPositionShift[0] + monomer.atoms.x[j]) + ' ' +\n keepPrecision(v.branchPositionShift[1] + v.flipFactor * monomer.atoms.y[j]) +\n ' ' + monomer.atoms.kwargs[j];\n }\n}\n\nfunction fillBondLines(monomer: MolGraph, molfileBondBlock: string[], v: LoopVariables): void {\n // construct the lines of V3K molfile bond block\n for (let j = 0; j < monomer.bonds.atomPairs.length; ++j) {\n const bondIdx = v.bondShift + j + 1;\n const firstAtom = monomer.bonds.atomPairs[j][0] + v.nodeShift;\n const secondAtom = monomer.bonds.atomPairs[j][1] + v.nodeShift;\n let bondCfg = '';\n if (monomer.bonds.bondConfiguration.has(j)) {\n // flip orientation when necessary\n let orientation = monomer.bonds.bondConfiguration.get(j);\n if (v.flipFactor < 0)\n orientation = (orientation === 1) ? 3 : 1;\n bondCfg = ' CFG=' + orientation;\n }\n const kwargs = monomer.bonds.kwargs.has(j) ?\n ' ' + monomer.bonds.kwargs.get(j) : '';\n molfileBondBlock[v.bondShift + j] = C.V3K_BEGIN_DATA_LINE + bondIdx + ' ' +\n monomer.bonds.bondTypes[j] + ' ' +\n firstAtom + ' ' + secondAtom + bondCfg + kwargs + '\\n';\n }\n}\n\nfunction fillChainExtendingBond(monomer: MolGraph, molfileBondBlock: string[], v: LoopVariables): void {\n if (v.backboneAttachNode !== 0) {\n const bondIdx = v.bondShift;\n const firstAtom = v.backboneAttachNode;\n const secondAtom = monomer.meta.terminalNodes[0] + v.nodeShift;\n molfileBondBlock[v.bondShift - 1] = C.V3K_BEGIN_DATA_LINE + bondIdx + ' ' +\n 1 + ' ' + firstAtom + ' ' + secondAtom + '\\n';\n }\n}\n\n// todo: remove\nfunction fillBackboneToBranchBond(branchMonomer: MolGraph, molfileBondBlock: string[], v: LoopVariables): void {\n const bondIdx = v.bondShift;\n const firstAtom = v.branchAttachNode;\n const secondAtom = branchMonomer.meta.terminalNodes[0] + v.nodeShift;\n molfileBondBlock[bondIdx - 1] = C.V3K_BEGIN_DATA_LINE + bondIdx + ' ' +\n 1 + ' ' + firstAtom + ' ' + secondAtom + '\\n';\n}\n\n/** Compute the atom/bond counts for the resulting molfile, depending on the\n * type of polymer (peptide/nucleotide)\n * @param {ISeqMonomer[]} monomerSeq - the sequence of monomers\n * @param {MonomerMolGraphMap} monomersDict - the dictionary of monomers\n * @param {ALPHABET} alphabet - the alphabet of the monomers\n * @param {PolymerType} polymerType - the type of polymer\n * @param {boolean} triplesMode - true when monomerSeq is a flat list of HELM RNA triples\n * @param {Array} roles - per-position role tags (only meaningful when triplesMode is true)\n * @return {Object} the atom/bond counts plus needsCapping flag */\nfunction getResultingAtomBondCounts(\n monomerSeq: ISeqMonomer[], monomersDict: MonomerMolGraphMap,\n alphabet: ALPHABET, polymerType: PolymerType,\n triplesMode: boolean, roles?: NucleotideRole[]\n): { atomCount: number, bondCount: number, needsCapping: boolean } {\n let atomCount = 0;\n let bondCount = 0;\n\n let monomerCount: number = 0;\n let needsCapping = true;\n let lastMonomerGraph: MolGraph | null = null;\n let lastPhosphateGraph: MolGraph | null = null;\n // sum up all the atoms/nodes provided by the sequence\n for (let i = 0; i < monomerSeq.length; ++i) {\n const seqMonomer = monomerSeq[i];\n if (seqMonomer.symbol === GAP_SYMBOL) continue; // Skip for gap/empty monomer in MSA\n if (seqMonomer.symbol == '*')\n throw new Error(`Gap canonical symbol is '', not '*`);\n lastMonomerGraph = getMolGraph(monomersDict, {symbol: seqMonomer.symbol, polymerType: helmTypeToPolymerType(seqMonomer.biotype)})!;\n atomCount += lastMonomerGraph.atoms.x.length;\n bondCount += lastMonomerGraph.bonds.bondTypes.length;\n monomerCount++;\n // In triples mode, every 3rd entry (index 2 mod 3) is a phosphate. Track\n // the LAST one — its atoms/bonds are dropped at the 3'-terminus.\n if (triplesMode && i % 3 === 2) lastPhosphateGraph = lastMonomerGraph;\n }\n\n // add extra values depending on the polymer type\n if (polymerType === HELM_POLYMER_TYPE.PEPTIDE) {\n // add the rightmost/terminating cap group 'OH' (i.e. 'O')\n atomCount += 1;\n // add chain-extending bonds (C-NH per each monomer pair and terminal C-OH)\n bondCount += monomerCount;\n // if the last monomer is something like NH2, which only has R1, there is no need to cap it\n // although, this should never happen, but hey... in other bits of code, there is a chunk that adds pseudo-R2 as hydrogen\n // we should also check, if the R2 of the last monomer is not hydrogen, that case should also be omitted\n if (monomerCount > 0) {\n if ((lastMonomerGraph?.meta?.rNodes?.length ?? 0) < 2 || lastMonomerGraph?.terminalR2Atom?.toLowerCase() === C.HYDROGEN.toLowerCase()) {\n needsCapping = false;\n atomCount -= 1; // remove the last atom (the terminal 'O')\n bondCount -= 1; // remove the last bond (the terminal C-OH)\n }\n }\n } else if (triplesMode) { // nucleotides — HELM triples (per-position sugar/base/phosphate)\n void lastPhosphateGraph; // kept for symmetry; trailing P is now retained when HELM wrote it\n\n // Per-monomer-loop already summed sugars + bases + phosphates for every\n // entry in monomerSeq (terminals included). Reservation: each backbone\n // emit (sugar / phosphate / terminal) reserves +1 bond slot for the\n // chain-extending bond, each branch (base) reserves +1 for its branch\n // bond. Total reservations = monomerCount.\n bondCount += monomerCount;\n\n // OH cap atom rides on the 3'-end. Skip it when HELM specified a\n // 3'-terminal modifier (e.g. GalNAc) that IS the chain end.\n const has3pTerm = !!roles && roles.length > 0 &&\n roles[roles.length - 1] === NucleotideRole.TERMINAL_3P;\n if (has3pTerm) {\n needsCapping = false;\n // Mirror the peptide branch (which does both atomCount-- and bondCount--\n // when it skips the terminal cap). `bondCount += monomerCount` above\n // reserves one chain-extending slot per monomer; the LAST monomer's slot\n // is normally filled by the terminal OH cap bond. With a 3'-terminal\n // modifier there is no cap, so that last reserved slot stays empty —\n // leaving the declared bond count one higher than the emitted bond\n // lines. Drop it so the V3000 COUNTS line matches the bond block exactly\n // (otherwise the pre-OCL molfile is malformed and only survives because\n // the OCL chirality pass re-derives the counts).\n bondCount -= 1;\n } else\n atomCount += 1; // OH cap atom (rides on trailing P or on last sugar's R2)\n } else { // nucleotides — bases-only legacy path with default sugar/phosphate\n const sugar = (alphabet === ALPHABET.DNA) ?\n getMolGraph(monomersDict, C.DEOXYRIBOSE)! : getMolGraph(monomersDict, C.RIBOSE)!;\n const phosphate = getMolGraph(monomersDict, C.PHOSPHATE)!;\n\n // add phosphate per each pair of nucleobase symbols\n atomCount += (monomerSeq.length - 1) * phosphate.atoms.x.length;\n\n // add sugar per each nucleobase symbol\n atomCount += monomerSeq.length * sugar.atoms.x.length;\n\n // add the leftmost cap group 'OH' (i.e. 'O')\n atomCount += 1;\n\n // add bonds from phosphate monomers\n bondCount += (monomerSeq.length - 1) * phosphate.bonds.bondTypes.length;\n\n // add bonds from sugar monomers\n bondCount += monomerSeq.length * sugar.bonds.bondTypes.length;\n\n // exclude the first chain-extending bond O-P (absent, no 'leftmost' phosphate)\n bondCount -= 1;\n\n // add chain-extending and branch bonds (O-P, C-O and C-N per each nucleotide)\n bondCount += monomerSeq.length * 3;\n }\n\n return {atomCount, bondCount, needsCapping};\n}\n\n// Role-driven RNA assembly. Walks the monomers in chain order and emits\n// each one according to its NucleotideRole (assigned by `buildRolesForHelmRna`\n// from the library, not from a fixed triple index):\n// - BASE → branch monomer, attached to the\n// branch point of the sugar most\n// recently emitted.\n// - SUGAR / PHOSPHATE / TERMINAL_5P / 3P → backbone monomer, chained to the\n// previous backbone unit.\n//\n// Because the role comes from chemistry, this transparently handles every\n// backbone layout — standard [sugar, base, phosphate] triples, a 5'-leading\n// phosphate, several phosphates / linkers in a row, a linker dropped in the\n// middle of the chain, missing trailing phosphate, and 5'/3' terminal\n// modifiers — without any index arithmetic. The first backbone monomer\n// naturally has no incoming chain bond (v.backboneAttachNode starts at 0),\n// and the trailing OH cap is added by the caller via needsCapping (skipped\n// when a TERMINAL_3P ends the chain).\nfunction runTriplesAssembly(\n monomerSeq: ISeqMonomer[], roles: NucleotideRole[],\n monomersDict: MonomerMolGraphMap,\n molfileAtomBlock: string[], molfileBondBlock: string[],\n v: LoopVariables, LC: LoopConstants,\n monomers: MonomerMap, steabsCollection: number[],\n addAtoms: (n: number) => void, getAtoms: () => number\n): void {\n void LC; // assembly is driven by per-monomer roles, not by LC.seqLength\n for (let i = 0; i < monomerSeq.length; ++i) {\n const sm = monomerSeq[i];\n if (sm.symbol === GAP_SYMBOL) continue;\n const role = roles[i];\n const mG = getMolGraph(monomersDict,\n {symbol: sm.symbol, polymerType: helmTypeToPolymerType(sm.biotype)})!;\n\n const aFirst = v.nodeShift;\n const bFirst = v.bondShift;\n v.i = i; // keep loop counter monotone (unused by nucleotide geometry)\n if (role === NucleotideRole.BASE)\n // Branch: attaches to v.branchAttachNode, set when the preceding sugar\n // was emitted. Does not advance the backbone, so the next backbone unit\n // still chains from that sugar's 3' side.\n addBranchMonomerToMolblock(mG, molfileAtomBlock, molfileBondBlock, v);\n else\n // Backbone: sugar / phosphate / linker / terminal modifier. Chains from\n // the previous backbone unit (none for the very first one) and, for a\n // sugar, sets up the branch attach point for the next base.\n addBackboneMonomerToMolblock(mG, molfileAtomBlock, molfileBondBlock, v);\n\n mG.stereoAtoms?.forEach((s) => steabsCollection.push(s + getAtoms()));\n addAtoms(mG.atoms.x.length);\n\n const aList: number[] = [];\n for (let a = aFirst; a < v.nodeShift; ++a) aList.push(a);\n const bList: number[] = [];\n for (let b = bFirst; b < v.bondShift; ++b) bList.push(b);\n monomers.set(i, {biotype: sm.biotype, symbol: sm.symbol, atoms: aList, bonds: bList});\n }\n}\n\n/** Keep precision upon floating point operations over atom coordinates\n * @param {number}x - the floating point number\n * @return {number} - the floating point number with the same precision\n */\nexport function keepPrecision(x: number): number {\n return Math.round(C.PRECISION_FACTOR * x) / C.PRECISION_FACTOR;\n}\n\n","import {monomerSeqToMolfile} from './to-atomic-level-utils';\nimport {MolfileWithMap, SeqToMolfileWorkerData, SeqToMolfileWorkerRes} from './types';\n\nonmessage = (event) => {\n const {seqList, rolesList, monomersDict, alphabet, polymerType, start, end}: SeqToMolfileWorkerData = event.data;\n const resMolList: MolfileWithMap[] = new Array<MolfileWithMap>(end - start);\n const molfileWarningList = new Array<string>(0);\n for (let rowI = start; rowI < end; ++rowI) {\n try {\n const seq = seqList[rowI];\n const roles = rolesList ? rolesList[rowI] : undefined;\n resMolList[rowI - start] = monomerSeqToMolfile(seq, monomersDict, alphabet, polymerType, roles);\n } catch (err: any) {\n const errMsg: string = err instanceof Error ? err.message : err.toString();\n const msg: string = `Cannot get molfile of row #${rowI}: ${errMsg}.`;\n molfileWarningList.push(msg);\n }\n }\n postMessage({molfiles: resMolList, warnings: molfileWarningList} as SeqToMolfileWorkerRes);\n};\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n// the startup function\n__webpack_require__.x = () => {\n\t// Load entry module and return exports\n\t// This entry module depends on other loaded chunks and execution need to be delayed\n\tvar __webpack_exports__ = __webpack_require__.O(undefined, [657], () => (__webpack_require__(323)))\n\t__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n\treturn __webpack_exports__;\n};\n\n","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.f = {};\n// This file contains only the entry chunk.\n// The chunk loading function for additional chunks\n__webpack_require__.e = (chunkId) => {\n\treturn Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key) => {\n\t\t__webpack_require__.f[key](chunkId, promises);\n\t\treturn promises;\n\t}, []));\n};","// This function allow to reference async chunks and chunks that the entrypoint depends on\n__webpack_require__.u = (chunkId) => {\n\t// return url for filenames based on template\n\treturn \"\" + chunkId + \".js\";\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","var scriptUrl;\nif (__webpack_require__.g.importScripts) scriptUrl = __webpack_require__.g.location + \"\";\nvar document = __webpack_require__.g.document;\nif (!scriptUrl && document) {\n\tif (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT')\n\t\tscriptUrl = document.currentScript.src;\n\tif (!scriptUrl) {\n\t\tvar scripts = document.getElementsByTagName(\"script\");\n\t\tif(scripts.length) {\n\t\t\tvar i = scripts.length - 1;\n\t\t\twhile (i > -1 && (!scriptUrl || !/^http(s?):/.test(scriptUrl))) scriptUrl = scripts[i--].src;\n\t\t}\n\t}\n}\n// When supporting browsers where an automatic publicPath is not supported you must specify an output.publicPath manually via configuration\n// or pass an empty string (\"\") and set the __webpack_public_path__ variable from your code to use your own logic.\nif (!scriptUrl) throw new Error(\"Automatic publicPath is not supported in this browser\");\nscriptUrl = scriptUrl.replace(/^blob:/, \"\").replace(/#.*$/, \"\").replace(/\\?.*$/, \"\").replace(/\\/[^\\/]+$/, \"/\");\n__webpack_require__.p = scriptUrl;","// no baseURI\n\n// object to store loaded chunks\n// \"1\" means \"already loaded\"\nvar installedChunks = {\n\t323: 1\n};\n\n// importScripts chunk loading\nvar installChunk = (data) => {\n\tvar [chunkIds, moreModules, runtime] = data;\n\tfor(var moduleId in moreModules) {\n\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t}\n\t}\n\tif(runtime) runtime(__webpack_require__);\n\twhile(chunkIds.length)\n\t\tinstalledChunks[chunkIds.pop()] = 1;\n\tparentChunkLoadingFunction(data);\n};\n__webpack_require__.f.i = (chunkId, promises) => {\n\t// \"1\" is the signal for \"already loaded\"\n\tif(!installedChunks[chunkId]) {\n\t\tif(true) { // all chunks have JS\n\t\t\timportScripts(__webpack_require__.p + __webpack_require__.u(chunkId));\n\t\t}\n\t}\n};\n\nvar chunkLoadingGlobal = self[\"webpackChunkhelm\"] = self[\"webpackChunkhelm\"] || [];\nvar parentChunkLoadingFunction = chunkLoadingGlobal.push.bind(chunkLoadingGlobal);\nchunkLoadingGlobal.push = installChunk;\n\n// no HMR\n\n// no HMR manifest","// run startup\nvar __webpack_exports__ = __webpack_require__.x();\n"],"names":["deferred","next","MonomerNumberingTypes","HelmTabKeys","monomerWorksConsts","V2K_RGP_SHIFT","V2K_RGP_LINE","V2K_A_LINE","V3K_COUNTS_SHIFT","V3K_IDX_SHIFT","V3K_HEADER_FIRST_LINE","V3K_HEADER_SECOND_LINE","V3K_BEGIN_CTAB_BLOCK","V3K_END_CTAB_BLOCK","V3K_BEGIN_COUNTS_LINE","V3K_COUNTS_LINE_ENDING","V3K_BEGIN_ATOM_BLOCK","V3K_END_ATOM_BLOCK","V3K_BEGIN_BOND_BLOCK","V3K_END_BOND_BLOCK","V3K_BOND_CONFIG","V3K_BEGIN_DATA_LINE","V3K_END","PRECISION_FACTOR","DEOXYRIBOSE","polymerType","RNA","symbol","RIBOSE","PHOSPHATE","OXYGEN","HYDROGEN","getMolGraph","dict","libKey","NucleotideRole","MonomerMap","Map","constructor","entries","super","MolfileWithMap","molfile","monomers","createEmpty","RegExp","CandidateType","name","alphabet","cutoff","this","NOTATION","ALPHABET","TAGS","Alphabets","fasta","peptide","Set","dna","rna","helmTypeToPolymerType","helmType","BASE","SUGAR","LINKER","NUCLEOTIDE","AA","PEPTIDE","CHEM","BLOB","console","warn","monomerSeqToMolfile","monomerSeq","monomersDict","roles","length","triplesMode","atomCount","bondCount","needsCapping","monomerCount","lastMonomerGraph","lastPhosphateGraph","i","seqMonomer","Error","biotype","atoms","x","bonds","bondTypes","meta","rNodes","terminalR2Atom","toLowerCase","TERMINAL_3P","sugar","DNA","phosphate","getResultingAtomBondCounts","molfileAtomBlock","Array","molfileBondBlock","addMonomerToMolblock","addAminoAcidToMolblock","addNucleotideToMolblock","v","nodeShift","bondShift","backbonePositionShift","fill","branchPositionShift","backboneAttachNode","branchAttachNode","flipFactor","LC","seqLength","Math","ceil","steabsCollection","lastMonomerCappingAtom","nAtoms","addAtoms","sm","role","mG","aFirst","bFirst","addBranchMonomerToMolblock","addBackboneMonomerToMolblock","stereoAtoms","forEach","s","push","aList","a","bList","b","set","runTriplesAssembly","monomer","mAtomFirst","mBondFirst","mAtomCount","mAtomList","maI","mBondCount","mBondList","mbI","cappingAtomType","atomIdx","keepPrecision","firstAtom","secondAtom","capResultingMolblock","molfileCountsLine","result","join","collection","rowsArray","newCollectionRow","updatedRow","getCollectionBlock","j","atomTypes","y","kwargs","fillAtomLines","fillBondLines","bondIdx","terminalNodes","fillChainExtendingBond","branchShift","updateBranchVariables","atomPairs","backboneShift","updateChainExtendingVariables","nucleobase","fillBranchAtomLines","branchMonomer","fillBackboneToBranchBond","bondCfg","bondConfiguration","has","orientation","get","round","PT","FASTA","SEPARATOR","HELM","BILN","onmessage","event","seqList","rolesList","start","end","data","resMolList","molfileWarningList","rowI","seq","undefined","err","msg","message","toString","postMessage","molfiles","warnings","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","exports","module","__webpack_modules__","m","__webpack_exports__","O","chunkIds","fn","priority","notFulfilled","Infinity","fulfilled","Object","keys","every","key","splice","r","d","definition","o","defineProperty","enumerable","f","e","chunkId","Promise","all","reduce","promises","u","g","globalThis","Function","window","obj","prop","prototype","hasOwnProperty","call","scriptUrl","importScripts","location","document","currentScript","tagName","toUpperCase","src","scripts","getElementsByTagName","test","replace","p","installedChunks","chunkLoadingGlobal","self","parentChunkLoadingFunction","bind","moreModules","runtime","pop","then"],"sourceRoot":""}