UNPKG

biojs-vis-pdbviewer

Version:

A BioJS 2.0 component to view protein structures

1,122 lines (1,102 loc) 40.8 kB
Clazz.declarePackage ("JS"); Clazz.load (["JU.JmolMolecule", "JU.BS", "$.Lst", "JS.VTemp"], "JS.SmilesSearch", ["java.util.Arrays", "$.Hashtable", "JU.AU", "$.SB", "$.V3", "JS.SmilesAromatic", "$.SmilesAtom", "$.SmilesBond", "$.SmilesMeasure", "$.SmilesParser", "JU.BSUtil", "$.Logger"], function () { c$ = Clazz.decorateAsClass (function () { this.patternAtoms = null; this.pattern = null; this.jmolAtoms = null; this.smartsAtoms = null; this.bioAtoms = null; this.jmolAtomCount = 0; this.bsSelected = null; this.bsRequired = null; this.firstMatchOnly = false; this.matchAllAtoms = false; this.isSmarts = false; this.isSmilesFind = false; this.subSearches = null; this.haveSelected = false; this.haveBondStereochemistry = false; this.haveAtomStereochemistry = false; this.needRingData = false; this.needAromatic = true; this.needRingMemberships = false; this.ringDataMax = -2147483648; this.measures = null; this.flags = 0; this.ringSets = null; this.bsAromatic = null; this.bsAromatic5 = null; this.bsAromatic6 = null; this.lastChainAtom = null; this.asVector = false; this.getMaps = false; this.top = null; this.isSilent = false; this.isRingCheck = false; this.selectedAtomCount = 0; this.ringData = null; this.ringCounts = null; this.ringConnections = null; this.bsFound = null; this.htNested = null; this.nNested = 0; this.nestedBond = null; this.vReturn = null; this.bsReturn = null; this.ignoreStereochemistry = false; this.noAromatic = false; this.aromaticDouble = false; this.bsCheck = null; this.v = null; Clazz.instantialize (this, arguments); }, JS, "SmilesSearch", JU.JmolMolecule); Clazz.prepareFields (c$, function () { this.patternAtoms = new Array (16); this.measures = new JU.Lst (); this.bsAromatic = new JU.BS (); this.bsAromatic5 = new JU.BS (); this.bsAromatic6 = new JU.BS (); this.top = this; this.bsFound = new JU.BS (); this.bsReturn = new JU.BS (); this.v = new JS.VTemp (); }); Clazz.defineMethod (c$, "toString", function () { var sb = new JU.SB ().append (this.pattern); sb.append ("\nmolecular formula: " + this.getMolecularFormula (true)); return sb.toString (); }); Clazz.defineMethod (c$, "setSelected", function (bs) { if (bs == null) { bs = JU.BS.newN (this.jmolAtomCount); bs.setBits (0, this.jmolAtomCount); }this.bsSelected = bs; }, "JU.BS"); Clazz.defineMethod (c$, "setAtomArray", function () { if (this.patternAtoms.length > this.ac) this.patternAtoms = JU.AU.arrayCopyObject (this.patternAtoms, this.ac); this.nodes = this.patternAtoms; }); Clazz.defineMethod (c$, "addAtom", function () { if (this.ac >= this.patternAtoms.length) this.patternAtoms = JU.AU.doubleLength (this.patternAtoms); var sAtom = new JS.SmilesAtom ().setIndex (this.ac); this.patternAtoms[this.ac] = sAtom; this.ac++; return sAtom; }); Clazz.defineMethod (c$, "addNested", function (pattern) { if (this.top.htNested == null) this.top.htNested = new java.util.Hashtable (); this.setNested (++this.top.nNested, pattern); return this.top.nNested; }, "~S"); Clazz.defineMethod (c$, "clear", function () { this.bsReturn.clearAll (); this.nNested = 0; this.htNested = null; this.nestedBond = null; this.clearBsFound (-1); }); Clazz.defineMethod (c$, "setNested", function (iNested, o) { this.top.htNested.put ("_" + iNested, o); }, "~N,~O"); Clazz.defineMethod (c$, "getNested", function (iNested) { return this.top.htNested.get ("_" + iNested); }, "~N"); Clazz.defineMethod (c$, "getMissingHydrogenCount", function () { var n = 0; var nH; for (var i = 0; i < this.ac; i++) if ((nH = this.patternAtoms[i].missingHydrogenCount) >= 0) n += nH; return n; }); Clazz.defineMethod (c$, "setRingData", function (bsA) { if (this.needAromatic) this.needRingData = true; var noAromatic = ((this.flags & 1) != 0); this.needAromatic = new Boolean (this.needAromatic & ( new Boolean ((bsA == null) & !noAromatic).valueOf ())).valueOf (); if (!this.needAromatic) { this.bsAromatic.clearAll (); if (bsA != null) this.bsAromatic.or (bsA); if (!this.needRingMemberships && !this.needRingData) return; }this.getRingData (this.needRingData, this.flags, null); }, "JU.BS"); Clazz.defineMethod (c$, "getRingData", function (needRingData, flags, vRings) { var aromaticStrict = ((flags & 4) != 0); var aromaticDefined = ((flags & 8) != 0); if (aromaticStrict && vRings == null) vRings = JU.AU.createArrayOfArrayList (4); if (aromaticDefined && this.needAromatic) { this.bsAromatic = JS.SmilesAromatic.checkAromaticDefined (this.jmolAtoms, this.bsSelected); aromaticStrict = false; }if (this.ringDataMax < 0) this.ringDataMax = 8; if (aromaticStrict && this.ringDataMax < 6) this.ringDataMax = 6; if (needRingData) { this.ringCounts = Clazz.newIntArray (this.jmolAtomCount, 0); this.ringConnections = Clazz.newIntArray (this.jmolAtomCount, 0); this.ringData = new Array (this.ringDataMax + 1); }this.ringSets = new JU.SB (); var s = "****"; while (s.length < this.ringDataMax) s += s; var v5 = null; for (var i = 3; i <= this.ringDataMax; i++) { if (i > this.jmolAtomCount) continue; var smarts = "*1" + s.substring (0, i - 2) + "*1"; var search = JS.SmilesParser.getMolecule (smarts, true); var vR = this.subsearch (search, false, true); if (vRings != null && i <= 5) { var v = new JU.Lst (); for (var j = vR.size (); --j >= 0; ) v.addLast (vR.get (j)); vRings[i - 3] = v; }if (this.needAromatic) { if (!aromaticDefined && (!aromaticStrict || i == 5 || i == 6)) for (var r = vR.size (); --r >= 0; ) { var bs = vR.get (r); if (aromaticDefined || JS.SmilesAromatic.isFlatSp2Ring (this.jmolAtoms, this.bsSelected, bs, (aromaticStrict ? 0.1 : 0.01))) this.bsAromatic.or (bs); } if (aromaticStrict) { switch (i) { case 5: v5 = vR; break; case 6: if (aromaticDefined) this.bsAromatic = JS.SmilesAromatic.checkAromaticDefined (this.jmolAtoms, this.bsAromatic); else JS.SmilesAromatic.checkAromaticStrict (this.jmolAtoms, this.bsAromatic, v5, vR); vRings[3] = new JU.Lst (); this.setAromatic56 (v5, this.bsAromatic5, 5, vRings[3]); this.setAromatic56 (vR, this.bsAromatic6, 6, vRings[3]); break; } }}if (needRingData) { this.ringData[i] = new JU.BS (); for (var k = 0; k < vR.size (); k++) { var r = vR.get (k); this.ringData[i].or (r); for (var j = r.nextSetBit (0); j >= 0; j = r.nextSetBit (j + 1)) this.ringCounts[j]++; } }} if (needRingData) { for (var i = this.bsSelected.nextSetBit (0); i >= 0; i = this.bsSelected.nextSetBit (i + 1)) { var atom = this.jmolAtoms[i]; var bonds = atom.getEdges (); if (bonds != null) for (var k = bonds.length; --k >= 0; ) if (this.ringCounts[atom.getBondedAtomIndex (k)] > 0) this.ringConnections[i]++; } }}, "~B,~N,~A"); Clazz.defineMethod (c$, "setAromatic56", function (vRings, bs56, n56, vAromatic56) { for (var k = 0; k < vRings.size (); k++) { var r = vRings.get (k); this.v.bsTemp.clearAll (); this.v.bsTemp.or (r); this.v.bsTemp.and (this.bsAromatic); if (this.v.bsTemp.cardinality () == n56) { bs56.or (r); if (vAromatic56 != null) vAromatic56.addLast (r); }} }, "JU.Lst,JU.BS,~N,JU.Lst"); Clazz.defineMethod (c$, "subsearch", function (search, firstAtomOnly, isRingCheck) { search.ringSets = this.ringSets; search.jmolAtoms = this.jmolAtoms; search.jmolAtomCount = this.jmolAtomCount; search.bsSelected = this.bsSelected; search.htNested = this.htNested; search.isSmilesFind = this.isSmilesFind; search.bsCheck = this.bsCheck; search.isSmarts = true; search.bsAromatic = this.bsAromatic; search.bsAromatic5 = this.bsAromatic5; search.bsAromatic6 = this.bsAromatic6; search.ringData = this.ringData; search.ringCounts = this.ringCounts; search.ringConnections = this.ringConnections; if (firstAtomOnly) { search.bsRequired = null; search.firstMatchOnly = false; search.matchAllAtoms = false; } else if (isRingCheck) { search.bsRequired = null; search.isSilent = true; search.isRingCheck = true; search.asVector = true; search.matchAllAtoms = false; } else { search.haveSelected = this.haveSelected; search.bsRequired = this.bsRequired; search.firstMatchOnly = this.firstMatchOnly; search.matchAllAtoms = this.matchAllAtoms; search.getMaps = this.getMaps; search.asVector = this.asVector; search.vReturn = this.vReturn; search.bsReturn = this.bsReturn; }return search.search (firstAtomOnly); }, "JS.SmilesSearch,~B,~B"); Clazz.defineMethod (c$, "search", function (firstAtomOnly) { this.ignoreStereochemistry = ((this.flags & 2) != 0); this.noAromatic = ((this.flags & 1) != 0); this.aromaticDouble = ((this.flags & 16) != 0); if (JU.Logger.debugging && !this.isSilent) JU.Logger.debug ("SmilesSearch processing " + this.pattern); if (this.vReturn == null && (this.asVector || this.getMaps)) this.vReturn = new JU.Lst (); if (this.bsSelected == null) { this.bsSelected = JU.BS.newN (this.jmolAtomCount); this.bsSelected.setBits (0, this.jmolAtomCount); }this.selectedAtomCount = this.bsSelected.cardinality (); if (this.subSearches != null) { for (var i = 0; i < this.subSearches.length; i++) { if (this.subSearches[i] == null) continue; this.subsearch (this.subSearches[i], false, false); if (this.firstMatchOnly) { if (this.vReturn == null ? this.bsReturn.nextSetBit (0) >= 0 : this.vReturn.size () > 0) break; }} } else if (this.ac > 0) { this.checkMatch (null, -1, -1, firstAtomOnly); }return (this.asVector || this.getMaps ? this.vReturn : this.bsReturn); }, "~B"); Clazz.defineMethod (c$, "checkMatch", function (patternAtom, atomNum, iAtom, firstAtomOnly) { var jmolAtom; var jmolBonds; if (patternAtom == null) { if (this.nestedBond == null) { this.clearBsFound (-1); } else { this.bsReturn.clearAll (); }} else { if (this.bsFound.get (iAtom) || !this.bsSelected.get (iAtom)) return true; jmolAtom = this.jmolAtoms[iAtom]; if (!this.isRingCheck) { if (patternAtom.atomsOr != null) { for (var ii = 0; ii < patternAtom.nAtomsOr; ii++) if (!this.checkMatch (patternAtom.atomsOr[ii], atomNum, iAtom, firstAtomOnly)) return false; return true; }if (patternAtom.primitives == null) { if (!this.checkPrimitiveAtom (patternAtom, iAtom)) return true; } else { for (var i = 0; i < patternAtom.nPrimitives; i++) if (!this.checkPrimitiveAtom (patternAtom.primitives[i], iAtom)) return true; }}jmolBonds = jmolAtom.getEdges (); for (var i = patternAtom.getBondCount (); --i >= 0; ) { var patternBond = patternAtom.getBond (i); if (patternBond.getAtomIndex2 () != patternAtom.index) continue; var atom1 = patternBond.getAtom1 (); var matchingAtom = atom1.getMatchingAtom (); switch (patternBond.order) { case 96: case 112: if (!this.checkMatchBond (patternAtom, atom1, patternBond, iAtom, matchingAtom, null)) return true; break; default: var k = 0; for (; k < jmolBonds.length; k++) if ((jmolBonds[k].getAtomIndex1 () == matchingAtom || jmolBonds[k].getAtomIndex2 () == matchingAtom) && jmolBonds[k].isCovalent ()) break; if (k == jmolBonds.length) return true; if (!this.checkMatchBond (patternAtom, atom1, patternBond, iAtom, matchingAtom, jmolBonds[k])) return true; } } this.patternAtoms[patternAtom.index].setMatchingAtom (iAtom); if (JU.Logger.debugging && !this.isSilent) JU.Logger.debug ("pattern atom " + atomNum + " " + patternAtom); this.bsFound.set (iAtom); }if (!this.continueMatch (atomNum, iAtom, firstAtomOnly)) return false; if (iAtom >= 0) this.clearBsFound (iAtom); return true; }, "JS.SmilesAtom,~N,~N,~B"); Clazz.defineMethod (c$, "continueMatch", function (atomNum, iAtom, firstAtomOnly) { var jmolAtom; var jmolBonds; if (++atomNum < this.ac) { var newPatternAtom = this.patternAtoms[atomNum]; var newPatternBond = (iAtom >= 0 ? newPatternAtom.getBondTo (null) : atomNum == 0 ? this.nestedBond : null); if (newPatternBond == null) { var bs = JU.BSUtil.copy (this.bsFound); if (newPatternAtom.notBondedIndex >= 0) { var pa = this.patternAtoms[newPatternAtom.notBondedIndex]; var a = this.jmolAtoms[pa.getMatchingAtom ()]; if (pa.isBioAtom) { var ii = (a).getOffsetResidueAtom ("0", 1); if (ii >= 0) bs.set (ii); ii = (a).getOffsetResidueAtom ("0", -1); if (ii >= 0) bs.set (ii); } else { jmolBonds = a.getEdges (); for (var k = 0; k < jmolBonds.length; k++) bs.set (jmolBonds[k].getOtherAtomNode (a).getIndex ()); }}var skipGroup = (iAtom >= 0 && newPatternAtom.isBioAtom && (newPatternAtom.atomName == null || newPatternAtom.residueChar != null)); for (var j = this.bsSelected.nextSetBit (0); j >= 0; j = this.bsSelected.nextSetBit (j + 1)) { if (!bs.get (j) && !this.checkMatch (newPatternAtom, atomNum, j, firstAtomOnly)) return false; if (skipGroup) { var j1 = (this.jmolAtoms[j]).getOffsetResidueAtom (newPatternAtom.atomName, 1); if (j1 >= 0) j = j1 - 1; }} this.bsFound = bs; return true; }jmolAtom = this.jmolAtoms[newPatternBond.getAtom1 ().getMatchingAtom ()]; switch (newPatternBond.order) { case 96: var nextGroupAtom = (jmolAtom).getOffsetResidueAtom (newPatternAtom.atomName, 1); if (nextGroupAtom >= 0) { var bs = JU.BSUtil.copy (this.bsFound); (jmolAtom).getGroupBits (this.bsFound); if (!this.checkMatch (newPatternAtom, atomNum, nextGroupAtom, firstAtomOnly)) return false; this.bsFound = bs; }return true; case 112: var vLinks = new JU.Lst (); (jmolAtom).getCrossLinkLeadAtomIndexes (vLinks); var bs = JU.BSUtil.copy (this.bsFound); (jmolAtom).getGroupBits (this.bsFound); for (var j = 0; j < vLinks.size (); j++) if (!this.checkMatch (newPatternAtom, atomNum, vLinks.get (j).intValue (), firstAtomOnly)) return false; this.bsFound = bs; return true; } jmolBonds = jmolAtom.getEdges (); if (jmolBonds != null) for (var j = 0; j < jmolBonds.length; j++) if (!this.checkMatch (newPatternAtom, atomNum, jmolAtom.getBondedAtomIndex (j), firstAtomOnly)) return false; this.clearBsFound (iAtom); return true; }if (!this.ignoreStereochemistry && !this.checkStereochemistry ()) return true; var bs = new JU.BS (); var nMatch = 0; for (var j = 0; j < this.ac; j++) { var i = this.patternAtoms[j].getMatchingAtom (); if (!firstAtomOnly && this.top.haveSelected && !this.patternAtoms[j].selected) continue; nMatch++; bs.set (i); if (this.patternAtoms[j].isBioAtom && this.patternAtoms[j].atomName == null) (this.jmolAtoms[i]).getGroupBits (bs); if (firstAtomOnly) break; if (!this.isSmarts && this.patternAtoms[j].missingHydrogenCount > 0) this.getHydrogens (this.jmolAtoms[i], bs); } if (this.bsRequired != null && !this.bsRequired.intersects (bs)) return true; if (this.matchAllAtoms && bs.cardinality () != this.selectedAtomCount) return true; if (this.bsCheck != null) { if (firstAtomOnly) { this.bsCheck.clearAll (); for (var j = 0; j < this.ac; j++) { this.bsCheck.set (this.patternAtoms[j].getMatchingAtom ()); } if (this.bsCheck.cardinality () != this.ac) return true; } else { if (bs.cardinality () != this.ac) return true; }}this.bsReturn.or (bs); if (this.getMaps) { var map = Clazz.newIntArray (nMatch, 0); for (var j = 0, nn = 0; j < this.ac; j++) { if (!firstAtomOnly && this.top.haveSelected && !this.patternAtoms[j].selected) continue; map[nn++] = this.patternAtoms[j].getMatchingAtom (); } this.vReturn.addLast (map); return !this.firstMatchOnly; }if (this.asVector) { var isOK = true; for (var j = this.vReturn.size (); --j >= 0 && isOK; ) isOK = !((this.vReturn.get (j)).equals (bs)); if (!isOK) return true; this.vReturn.addLast (bs); }if (this.isRingCheck) { this.ringSets.append (" "); for (var k = atomNum * 3 + 2; --k > atomNum; ) this.ringSets.append ("-").appendI (this.patternAtoms[(k <= atomNum * 2 ? atomNum * 2 - k + 1 : k - 1) % atomNum].getMatchingAtom ()); this.ringSets.append ("- "); return true; }if (this.firstMatchOnly) return false; return (bs.cardinality () != this.selectedAtomCount); }, "~N,~N,~B"); Clazz.defineMethod (c$, "clearBsFound", function (iAtom) { if (iAtom < 0) { if (this.bsCheck == null) { this.bsFound.clearAll (); }} else this.bsFound.clear (iAtom); }, "~N"); Clazz.defineMethod (c$, "getHydrogens", function (atom, bsHydrogens) { var b = atom.getEdges (); var k = -1; for (var i = 0; i < b.length; i++) if (this.jmolAtoms[atom.getBondedAtomIndex (i)].getElementNumber () == 1) { k = atom.getBondedAtomIndex (i); if (bsHydrogens == null) break; bsHydrogens.set (k); } return (k >= 0 ? this.jmolAtoms[k] : null); }, "JU.Node,JU.BS"); Clazz.defineMethod (c$, "checkPrimitiveAtom", function (patternAtom, iAtom) { var atom = this.jmolAtoms[iAtom]; var foundAtom = patternAtom.not; while (true) { var n; if (patternAtom.iNested > 0) { var o = this.getNested (patternAtom.iNested); if (Clazz.instanceOf (o, JS.SmilesSearch)) { var search = o; if (patternAtom.isBioAtom) search.nestedBond = patternAtom.getBondTo (null); o = this.subsearch (search, true, false); if (o == null) o = new JU.BS (); if (!patternAtom.isBioAtom) this.setNested (patternAtom.iNested, o); }foundAtom = (patternAtom.not != ((o).get (iAtom))); break; }if (patternAtom.isBioAtom) { var a = atom; if (patternAtom.atomName != null && (patternAtom.isLeadAtom () ? !a.isLeadAtom () : !patternAtom.atomName.equals (a.getAtomName ().toUpperCase ()))) break; if (patternAtom.notCrossLinked && a.getCrossLinkLeadAtomIndexes (null)) break; if (patternAtom.residueName != null && !patternAtom.residueName.equals (a.getGroup3 (false).toUpperCase ())) break; if (patternAtom.residueChar != null) { if (patternAtom.isDna () && !a.isDna () || patternAtom.isRna () && !a.isRna () || patternAtom.isProtein () && !a.isProtein () || patternAtom.isNucleic () && !a.isNucleic ()) break; var s = a.getGroup1 ('\0').toUpperCase (); var isOK = patternAtom.residueChar.equals (s); switch (patternAtom.residueChar.charAt (0)) { case 'N': isOK = patternAtom.isNucleic () ? a.isNucleic () : isOK; break; case 'R': isOK = patternAtom.isNucleic () ? a.isPurine () : isOK; break; case 'Y': isOK = patternAtom.isNucleic () ? a.isPyrimidine () : isOK; break; } if (!isOK) break; }if (patternAtom.elementNumber >= 0 && patternAtom.elementNumber != atom.getElementNumber ()) break; } else { if (patternAtom.atomName != null && (!patternAtom.atomName.equals (atom.getAtomName ().toUpperCase ()))) break; if (patternAtom.jmolIndex >= 0 && atom.getIndex () != patternAtom.jmolIndex) break; if (patternAtom.atomType != null && !patternAtom.atomType.equals (atom.getAtomType ())) break; if (patternAtom.elementNumber >= 0 && patternAtom.elementNumber != atom.getElementNumber ()) break; var isAromatic = patternAtom.isAromatic (); if (!this.noAromatic && !patternAtom.aromaticAmbiguous && isAromatic != this.bsAromatic.get (iAtom)) break; if ((n = patternAtom.getAtomicMass ()) != -2147483648) { var isotope = atom.getIsotopeNumber (); if (n >= 0 && n != isotope || n < 0 && isotope != 0 && -n != isotope) { break; }}if ((n = patternAtom.getCharge ()) != -2147483648 && n != atom.getFormalCharge ()) break; n = patternAtom.getCovalentHydrogenCount () + patternAtom.missingHydrogenCount; if (n >= 0 && n != atom.getCovalentHydrogenCount ()) break; n = patternAtom.implicitHydrogenCount; if (n != -2147483648) { var nH = atom.getImplicitHydrogenCount (); if (n == -1 ? nH == 0 : n != nH) break; }if (patternAtom.degree > 0 && patternAtom.degree != atom.getCovalentBondCount ()) break; if (patternAtom.nonhydrogenDegree > 0 && patternAtom.nonhydrogenDegree != atom.getCovalentBondCount () - atom.getCovalentHydrogenCount ()) break; if (patternAtom.valence > 0 && patternAtom.valence != atom.getValence ()) break; if (patternAtom.connectivity > 0 && patternAtom.connectivity != atom.getCovalentBondCount () + atom.getImplicitHydrogenCount ()) break; if (this.ringData != null && patternAtom.ringSize >= -1) { if (patternAtom.ringSize <= 0) { if ((this.ringCounts[iAtom] == 0) != (patternAtom.ringSize == 0)) break; } else { var rd = this.ringData[patternAtom.ringSize == 500 ? 5 : patternAtom.ringSize == 600 ? 6 : patternAtom.ringSize]; if (rd == null || !rd.get (iAtom)) break; if (!this.noAromatic) if (patternAtom.ringSize == 500) { if (!this.bsAromatic5.get (iAtom)) break; } else if (patternAtom.ringSize == 600) { if (!this.bsAromatic6.get (iAtom)) break; }}}if (this.ringData != null && patternAtom.ringMembership >= -1) { if (patternAtom.ringMembership == -1 ? this.ringCounts[iAtom] == 0 : this.ringCounts[iAtom] != patternAtom.ringMembership) break; }if (patternAtom.ringConnectivity >= 0) { n = this.ringConnections[iAtom]; if (patternAtom.ringConnectivity == -1 && n == 0 || patternAtom.ringConnectivity != -1 && n != patternAtom.ringConnectivity) break; }}foundAtom = !foundAtom; break; } return foundAtom; }, "JS.SmilesAtom,~N"); Clazz.defineMethod (c$, "checkMatchBond", function (patternAtom, atom1, patternBond, iAtom, matchingAtom, bond) { if (patternBond.bondsOr != null) { for (var ii = 0; ii < patternBond.nBondsOr; ii++) if (this.checkMatchBond (patternAtom, atom1, patternBond.bondsOr[ii], iAtom, matchingAtom, bond)) return true; return false; }if (patternBond.primitives == null) { if (!this.checkPrimitiveBond (patternBond, iAtom, matchingAtom, bond)) return false; } else { for (var i = 0; i < patternBond.nPrimitives; i++) if (!this.checkPrimitiveBond (patternBond.primitives[i], iAtom, matchingAtom, bond)) return false; }patternBond.matchingBond = bond; return true; }, "JS.SmilesAtom,JS.SmilesAtom,JS.SmilesBond,~N,~N,JU.Edge"); Clazz.defineMethod (c$, "checkPrimitiveBond", function (patternBond, iAtom1, iAtom2, bond) { var bondFound = false; switch (patternBond.order) { case 96: return (patternBond.isNot != (this.bioAtoms[iAtom2].getOffsetResidueAtom ("0", 1) == this.bioAtoms[iAtom1].getOffsetResidueAtom ("0", 0))); case 112: return (patternBond.isNot != this.bioAtoms[iAtom1].isCrossLinked (this.bioAtoms[iAtom2])); } var isAromatic1 = (!this.noAromatic && this.bsAromatic.get (iAtom1)); var isAromatic2 = (!this.noAromatic && this.bsAromatic.get (iAtom2)); var order = bond.getCovalentOrder (); if (isAromatic1 && isAromatic2) { switch (patternBond.order) { case 17: case 65: bondFound = JS.SmilesSearch.isRingBond (this.ringSets, iAtom1, iAtom2); break; case 1: bondFound = !this.isSmarts || !JS.SmilesSearch.isRingBond (this.ringSets, iAtom1, iAtom2); break; case 2: bondFound = !this.isSmarts || this.aromaticDouble && (order == 2 || order == 514); break; case 769: case 1025: case 81: case -1: bondFound = true; break; } } else { switch (patternBond.order) { case 81: case -1: bondFound = true; break; case 1: case 257: case 513: bondFound = (order == 1 || order == 1041 || order == 1025); break; case 769: bondFound = (order == (this.isSmilesFind ? 33 : 1)); break; case 1025: bondFound = (order == (this.isSmilesFind ? 97 : 1)); break; case 2: bondFound = (order == 2); break; case 3: bondFound = (order == 3); break; case 65: bondFound = JS.SmilesSearch.isRingBond (this.ringSets, iAtom1, iAtom2); break; } }return bondFound != patternBond.isNot; }, "JS.SmilesBond,~N,~N,JU.Edge"); c$.isRingBond = Clazz.defineMethod (c$, "isRingBond", function (ringSets, i, j) { return (ringSets != null && ringSets.indexOf ("-" + i + "-" + j + "-") >= 0); }, "JU.SB,~N,~N"); Clazz.defineMethod (c$, "checkStereochemistry", function () { for (var i = 0; i < this.measures.size (); i++) if (!this.measures.get (i).check ()) return false; if (this.haveAtomStereochemistry) { if (JU.Logger.debugging) JU.Logger.debug ("checking stereochemistry..."); var atom1 = null; var atom2 = null; var atom3 = null; var atom4 = null; var atom5 = null; var atom6 = null; var sAtom1 = null; var sAtom2 = null; var jn; for (var i = 0; i < this.ac; i++) { var sAtom = this.patternAtoms[i]; var atom0 = this.jmolAtoms[sAtom.getMatchingAtom ()]; var nH = sAtom.missingHydrogenCount; if (nH < 0) nH = 0; var chiralClass = sAtom.getChiralClass (); if (chiralClass == -2147483648) continue; var order = sAtom.getChiralOrder (); if (this.isSmilesFind && (atom0.getAtomSite () >> 8) != chiralClass) return false; atom4 = null; if (JU.Logger.debugging) JU.Logger.debug ("...type " + chiralClass + " for pattern atom " + sAtom + " " + atom0); switch (chiralClass) { case 2: var isAllene = true; if (isAllene) { sAtom1 = sAtom.getBond (0).getOtherAtom (sAtom); sAtom2 = sAtom.getBond (1).getOtherAtom (sAtom); if (sAtom1 == null || sAtom2 == null) continue; var sAtom1a = sAtom; var sAtom2a = sAtom; while (sAtom1.getBondCount () == 2 && sAtom2.getBondCount () == 2 && sAtom1.getValence () == 4 && sAtom2.getValence () == 4) { var b = sAtom1.getBondNotTo (sAtom1a, true); sAtom1a = sAtom1; sAtom1 = b.getOtherAtom (sAtom1); b = sAtom2.getBondNotTo (sAtom2a, true); sAtom2a = sAtom2; sAtom2 = b.getOtherAtom (sAtom2); } sAtom = sAtom1; }jn = new Array (6); jn[4] = new JS.SmilesAtom ().setIndex (604); var nBonds = sAtom.getBondCount (); for (var k = 0; k < nBonds; k++) { sAtom1 = sAtom.bonds[k].getOtherAtom (sAtom); if (sAtom.bonds[k].matchingBond.getCovalentOrder () == 2) { if (sAtom2 == null) sAtom2 = sAtom1; } else if (jn[0] == null) { jn[0] = this.getJmolAtom (sAtom1.getMatchingAtom ()); } else { jn[1] = this.getJmolAtom (sAtom1.getMatchingAtom ()); }} if (sAtom2 == null) continue; nBonds = sAtom2.getBondCount (); if (nBonds < 2 || nBonds > 3) continue; for (var k = 0; k < nBonds; k++) { sAtom1 = sAtom2.bonds[k].getOtherAtom (sAtom2); if (sAtom2.bonds[k].matchingBond.getCovalentOrder () == 2) { } else if (jn[2] == null) { jn[2] = this.getJmolAtom (sAtom1.getMatchingAtom ()); } else { jn[3] = this.getJmolAtom (sAtom1.getMatchingAtom ()); }} if (this.isSmilesFind) { if (jn[1] == null) this.getX (sAtom, jn, 1, false, isAllene); if (jn[3] == null) this.getX (sAtom2, jn, 3, false, false); if (!this.setSmilesCoordinates (atom0, sAtom, sAtom2, jn)) return false; }if (jn[1] == null) this.getX (sAtom, jn, 1, true, false); if (jn[3] == null) this.getX (sAtom2, jn, 3, true, false); if (!JS.SmilesSearch.checkStereochemistryAll (sAtom.not, atom0, chiralClass, order, jn[0], jn[1], jn[2], jn[3], null, null, this.v)) return false; continue; case 4: case 8: case 5: case 6: atom1 = this.getJmolAtom (sAtom.getMatchingBondedAtom (0)); switch (nH) { case 0: atom2 = this.getJmolAtom (sAtom.getMatchingBondedAtom (1)); break; case 1: atom2 = this.getHydrogens (this.getJmolAtom (sAtom.getMatchingAtom ()), null); if (sAtom.isFirst) { var a = atom2; atom2 = atom1; atom1 = a; }break; default: continue; } atom3 = this.getJmolAtom (sAtom.getMatchingBondedAtom (2 - nH)); atom4 = this.getJmolAtom (sAtom.getMatchingBondedAtom (3 - nH)); atom5 = this.getJmolAtom (sAtom.getMatchingBondedAtom (4 - nH)); atom6 = this.getJmolAtom (sAtom.getMatchingBondedAtom (5 - nH)); if (this.isSmilesFind && !this.setSmilesCoordinates (atom0, sAtom, sAtom2, [atom1, atom2, atom3, atom4, atom5, atom6])) return false; if (!JS.SmilesSearch.checkStereochemistryAll (sAtom.not, atom0, chiralClass, order, atom1, atom2, atom3, atom4, atom5, atom6, this.v)) return false; continue; } } }if (this.haveBondStereochemistry) { for (var k = 0; k < this.ac; k++) { var sAtom1 = this.patternAtoms[k]; var sAtom2 = null; var sAtomDirected1 = null; var sAtomDirected2 = null; var dir1 = 0; var dir2 = 0; var bondType = 0; var b; var nBonds = sAtom1.getBondCount (); var isAtropisomer = false; for (var j = 0; j < nBonds; j++) { b = sAtom1.getBond (j); var isAtom2 = (b.getAtom2 () === sAtom1); var type = b.order; switch (type) { case 769: case 1025: case 2: if (isAtom2) continue; sAtom2 = b.getAtom2 (); bondType = type; isAtropisomer = (type != 2); if (isAtropisomer) dir1 = (b.isNot ? -1 : 1); break; case 257: case 513: sAtomDirected1 = (isAtom2 ? b.getAtom1 () : b.getAtom2 ()); dir1 = (isAtom2 != (type == 257) ? 1 : -1); break; } } if (isAtropisomer) { b = sAtom1.getBondNotTo (sAtom2, false); if (b == null) return false; sAtomDirected1 = b.getOtherAtom (sAtom1); b = sAtom2.getBondNotTo (sAtom1, false); if (b == null) return false; sAtomDirected2 = b.getOtherAtom (sAtom2); } else { if (sAtom2 == null || dir1 == 0) continue; nBonds = sAtom2.getBondCount (); for (var j = 0; j < nBonds && dir2 == 0; j++) { b = sAtom2.getBond (j); var isAtom2 = (b.getAtom2 () === sAtom2); var type = b.order; switch (type) { case 257: case 513: sAtomDirected2 = (isAtom2 ? b.getAtom1 () : b.getAtom2 ()); dir2 = (isAtom2 != (type == 257) ? 1 : -1); break; } } if (dir2 == 0) continue; }if (this.isSmilesFind) this.setSmilesBondCoordinates (sAtom1, sAtom2, bondType); var dbAtom1 = this.getJmolAtom (sAtom1.getMatchingAtom ()); var dbAtom2 = this.getJmolAtom (sAtom2.getMatchingAtom ()); var dbAtom1a = this.getJmolAtom (sAtomDirected1.getMatchingAtom ()); var dbAtom2a = this.getJmolAtom (sAtomDirected2.getMatchingAtom ()); if (dbAtom1a == null || dbAtom2a == null) return false; JS.SmilesMeasure.setTorsionData (dbAtom1a, dbAtom1, dbAtom2, dbAtom2a, this.v, isAtropisomer); if (isAtropisomer) { dir2 = (bondType == 769 ? 1 : -1); var f = this.v.vTemp1.dot (this.v.vTemp2); if (f < 0.05 || f > 0.95 || this.v.vNorm1.dot (this.v.vNorm2) * dir1 * dir2 > 0) return false; } else { if (this.v.vTemp1.dot (this.v.vTemp2) * dir1 * dir2 < 0) return false; }} }return true; }); Clazz.defineMethod (c$, "getX", function (sAtom, jn, pt, haveCoordinates, needHSwitch) { var atom = this.getJmolAtom (sAtom.getMatchingAtom ()); var doSwitch = sAtom.isFirst || pt == 3; if (haveCoordinates) { if (this.isSmarts) { var b = atom.getEdges (); for (var i = 0; i < b.length; i++) { if (b[i].getCovalentOrder () == 2) continue; var a = this.jmolAtoms[atom.getBondedAtomIndex (i)]; if (a === jn[pt - 1]) continue; jn[pt] = a; break; } }if (jn[pt] == null) { var v = new JU.V3 (); var n = 0; for (var i = 0; i < 4; i++) { if (jn[i] == null) continue; n++; v.sub (jn[i]); } if (v.length () == 0) { v.setT ((jn[4])); doSwitch = false; } else { v.scaleAdd2 (n + 1, this.getJmolAtom (sAtom.getMatchingAtom ()), v); doSwitch = this.isSmilesFind || doSwitch; }jn[pt] = new JS.SmilesAtom ().setIndex (-1); (jn[pt]).setT (v); }}if (jn[pt] == null) { jn[pt] = this.getHydrogens (atom, null); if (needHSwitch) doSwitch = true; }if (jn[pt] != null && doSwitch) { var a = jn[pt]; jn[pt] = jn[pt - 1]; jn[pt - 1] = a; }}, "JS.SmilesAtom,~A,~N,~B,~B"); c$.checkStereochemistryAll = Clazz.defineMethod (c$, "checkStereochemistryAll", function (isNot, atom0, chiralClass, order, atom1, atom2, atom3, atom4, atom5, atom6, v) { switch (chiralClass) { default: case 2: case 4: return (isNot == (JS.SmilesSearch.getHandedness (atom2, atom3, atom4, atom1, v) != order)); case 5: return (isNot == (!JS.SmilesSearch.isDiaxial (atom0, atom0, atom5, atom1, v, -0.95) || JS.SmilesSearch.getHandedness (atom2, atom3, atom4, atom1, v) != order)); case 6: if (isNot != (!JS.SmilesSearch.isDiaxial (atom0, atom0, atom6, atom1, v, -0.95))) return false; JS.SmilesSearch.getPlaneNormals (atom2, atom3, atom4, atom5, v); if (isNot != (v.vNorm1.dot (v.vNorm2) < 0 || v.vNorm2.dot (v.vNorm3) < 0)) return false; v.vNorm2.sub2 (atom0, atom1); return (isNot == ((v.vNorm1.dot (v.vNorm2) < 0 ? 2 : 1) == order)); case 8: JS.SmilesSearch.getPlaneNormals (atom1, atom2, atom3, atom4, v); return (v.vNorm1.dot (v.vNorm2) < 0 ? isNot == (order != 3) : v.vNorm2.dot (v.vNorm3) < 0 ? isNot == (order != 2) : isNot == (order != 1)); } }, "~B,JU.Node,~N,~N,JU.Node,JU.Node,JU.Node,JU.Node,JU.Node,JU.Node,JS.VTemp"); Clazz.defineMethod (c$, "getJmolAtom", function (i) { return (i < 0 || i >= this.jmolAtoms.length ? null : this.jmolAtoms[i]); }, "~N"); Clazz.defineMethod (c$, "setSmilesBondCoordinates", function (sAtom1, sAtom2, bondType) { var dbAtom1 = this.jmolAtoms[sAtom1.getMatchingAtom ()]; var dbAtom2 = this.jmolAtoms[sAtom2.getMatchingAtom ()]; dbAtom1.set (-1, 0, 0); dbAtom2.set (1, 0, 0); if (bondType == 2) { var nBonds = 0; var dir1 = 0; var bonds = dbAtom1.getEdges (); for (var k = bonds.length; --k >= 0; ) { var bond = bonds[k]; var atom = bond.getOtherAtomNode (dbAtom1); if (atom === dbAtom2) continue; atom.set (-1, (nBonds++ == 0) ? -1 : 1, 0); var mode = (bond.getAtomIndex2 () == dbAtom1.getIndex () ? nBonds : -nBonds); switch (bond.order) { case 1025: dir1 = mode; break; case 1041: dir1 = -mode; } } var dir2 = 0; nBonds = 0; var atoms = new Array (2); bonds = dbAtom2.getEdges (); for (var k = bonds.length; --k >= 0; ) { var bond = bonds[k]; var atom = bond.getOtherAtomNode (dbAtom2); if (atom === dbAtom1) continue; atoms[nBonds] = atom; atom.set (1, (nBonds++ == 0) ? 1 : -1, 0); var mode = (bond.getAtomIndex2 () == dbAtom2.getIndex () ? nBonds : -nBonds); switch (bond.order) { case 1025: dir2 = mode; break; case 1041: dir2 = -mode; } } if ((dir1 * dir2 > 0) == (Math.abs (dir1) % 2 == Math.abs (dir2) % 2)) { var y = (atoms[0]).y; (atoms[0]).y = (atoms[1]).y; (atoms[1]).y = y; }} else { var bonds = dbAtom1.getEdges (); var dir = 0; for (var k = bonds.length; --k >= 0; ) { var bond = bonds[k]; if (bond.getOtherAtomNode (dbAtom1) === dbAtom2) { dir = (bond.order == 33 ? 1 : -1); break; }} for (var k = bonds.length; --k >= 0; ) { var bond = bonds[k]; var atom = bond.getOtherAtomNode (dbAtom1); if (atom !== dbAtom2) atom.set (-1, 1, 0); } bonds = dbAtom2.getEdges (); for (var k = bonds.length; --k >= 0; ) { var bond = bonds[k]; var atom = bond.getOtherAtomNode (dbAtom2); if (atom !== dbAtom1) atom.set (1, 1, -dir / 2.0); } }}, "JS.SmilesAtom,JS.SmilesAtom,~N"); Clazz.defineMethod (c$, "setSmilesCoordinates", function (atom, sAtom, sAtom2, cAtoms) { var atomSite = atom.getAtomSite (); if (atomSite == -2147483648) return false; var chiralClass = atomSite >> 8; var chiralOrder = atomSite & 0xFF; var a2 = (chiralClass == 2 || chiralClass == 3 ? a2 = this.jmolAtoms[sAtom2.getMatchingAtom ()] : null); atom.set (0, 0, 0); atom = this.jmolAtoms[sAtom.getMatchingAtom ()]; atom.set (0, 0, 0); var map = this.getMappedAtoms (atom, a2, cAtoms); switch (chiralClass) { case 2: case 4: if (chiralOrder == 2) { var i = map[0]; map[0] = map[1]; map[1] = i; }cAtoms[map[0]].set (0, 0, 1); cAtoms[map[1]].set (1, 0, -1); cAtoms[map[2]].set (0, 1, -1); cAtoms[map[3]].set (-1, -1, -1); break; case 8: switch (chiralOrder) { case 1: cAtoms[map[0]].set (1, 0, 0); cAtoms[map[1]].set (0, 1, 0); cAtoms[map[2]].set (-1, 0, 0); cAtoms[map[3]].set (0, -1, 0); break; case 2: cAtoms[map[0]].set (1, 0, 0); cAtoms[map[1]].set (-1, 0, 0); cAtoms[map[2]].set (0, 1, 0); cAtoms[map[3]].set (0, -1, 0); break; case 3: cAtoms[map[0]].set (1, 0, 0); cAtoms[map[1]].set (0, 1, 0); cAtoms[map[2]].set (0, -1, 0); cAtoms[map[3]].set (-1, 0, 0); break; } break; case 5: case 6: var n = map.length; if (chiralOrder == 2) { var i = map[0]; map[0] = map[n - 1]; map[n - 1] = i; }cAtoms[map[0]].set (0, 0, 1); cAtoms[map[n - 1]].set (0, 0, -1); cAtoms[map[1]].set (1, 0, 0); cAtoms[map[2]].set (0, 1, 0); cAtoms[map[3]].set (-1, 0, 0); if (n == 6) cAtoms[map[4]].set (0, -1, 0); break; } return true; }, "JU.Node,JS.SmilesAtom,JS.SmilesAtom,~A"); Clazz.defineMethod (c$, "getMappedAtoms", function (atom, a2, cAtoms) { var map = Clazz.newIntArray (cAtoms[4] == null ? 4 : cAtoms[5] == null ? 5 : 6, 0); for (var i = 0; i < map.length; i++) map[i] = (cAtoms[i] == null ? 104 + i * 100 : cAtoms[i].getIndex ()); var k; var bonds = atom.getEdges (); var b2 = (a2 == null ? null : a2.getEdges ()); for (var i = 0; i < map.length; i++) { for (k = 0; k < bonds.length; k++) if (bonds[k].getOtherAtomNode (atom) === cAtoms[i]) break; if (k < bonds.length) { map[i] = (k * 10 + 100) + i; } else if (a2 != null) { for (k = 0; k < b2.length; k++) if (b2[k].getOtherAtomNode (a2) === cAtoms[i]) break; if (k < b2.length) map[i] = (k * 10 + 300) + i; }} java.util.Arrays.sort (map); for (var i = 0; i < map.length; i++) { map[i] = map[i] % 10; } return map; }, "JU.Node,JU.Node,~A"); c$.isDiaxial = Clazz.defineMethod (c$, "isDiaxial", function (atomA, atomB, atom1, atom2, v, f) { v.vA.sub2 (atomA, atom1); v.vB.sub2 (atomB, atom2); v.vA.normalize (); v.vB.normalize (); return (v.vA.dot (v.vB) < f); }, "JU.Node,JU.Node,JU.Node,JU.Node,JS.VTemp,~N"); c$.getHandedness = Clazz.defineMethod (c$, "getHandedness", function (a, b, c, pt, v) { var d = JS.SmilesAromatic.getNormalThroughPoints (a, b, c, v.vTemp, v.vA, v.vB); return (JS.SmilesSearch.distanceToPlane (v.vTemp, d, pt) > 0 ? 1 : 2); }, "JU.Node,JU.Node,JU.Node,JU.Node,JS.VTemp"); c$.getPlaneNormals = Clazz.defineMethod (c$, "getPlaneNormals", function (atom1, atom2, atom3, atom4, v) { JS.SmilesAromatic.getNormalThroughPoints (atom1, atom2, atom3, v.vNorm1, v.vTemp1, v.vTemp2); JS.SmilesAromatic.getNormalThroughPoints (atom2, atom3, atom4, v.vNorm2, v.vTemp1, v.vTemp2); JS.SmilesAromatic.getNormalThroughPoints (atom3, atom4, atom1, v.vNorm3, v.vTemp1, v.vTemp2); }, "JU.Node,JU.Node,JU.Node,JU.Node,JS.VTemp"); c$.distanceToPlane = Clazz.defineMethod (c$, "distanceToPlane", function (norm, w, pt) { return (norm == null ? NaN : (norm.x * pt.x + norm.y * pt.y + norm.z * pt.z + w) / Math.sqrt (norm.x * norm.x + norm.y * norm.y + norm.z * norm.z)); }, "JU.V3,~N,JU.P3"); Clazz.defineMethod (c$, "createTopoMap", function (bsAromatic) { if (bsAromatic == null) bsAromatic = new JU.BS (); var nAtomsMissing = this.getMissingHydrogenCount (); var atoms = new Array (this.ac + nAtomsMissing); this.jmolAtoms = atoms; var ptAtom = 0; var bsFixH = new JU.BS (); for (var i = 0; i < this.ac; i++) { var sAtom = this.patternAtoms[i]; var cclass = sAtom.getChiralClass (); var n = sAtom.missingHydrogenCount; if (n < 0) n = 0; var atom = atoms[ptAtom] = new JS.SmilesAtom ().setAll (0, ptAtom, cclass == -2147483648 ? cclass : (cclass << 8) + sAtom.getChiralOrder (), sAtom.elementNumber, sAtom.getCharge ()); atom.atomName = sAtom.atomName; atom.residueName = sAtom.residueName; atom.residueChar = sAtom.residueChar; atom.isBioAtom = sAtom.isBioAtom; atom.$isLeadAtom = sAtom.$isLeadAtom; atom.setAtomicMass (sAtom.getAtomicMass ()); if (sAtom.isAromatic ()) bsAromatic.set (ptAtom); if (!sAtom.isFirst && n == 1 && cclass > 0) bsFixH.set (ptAtom); sAtom.setMatchingAtom (ptAtom++); var bonds = new Array (sAtom.getBondCount () + n); atom.setBonds (bonds); while (--n >= 0) { var atomH = atoms[ptAtom] = new JS.SmilesAtom ().setAll (0, ptAtom, 0, 1, 0); ptAtom++; atomH.setBonds ( new Array (1)); var b = new JS.SmilesBond (atom, atomH, 1, false); JU.Logger.info ("" + b); } } for (var i = 0; i < this.ac; i++) { var sAtom = this.patternAtoms[i]; var i1 = sAtom.getMatchingAtom (); var atom1 = atoms[i1]; var n = sAtom.getBondCount (); for (var j = 0; j < n; j++) { var sBond = sAtom.getBond (j); var firstAtom = (sBond.getAtom1 () === sAtom); if (firstAtom) { var order = 1; switch (sBond.order) { case 769: order = 33; break; case 1025: order = 97; break; case 257: order = 1025; break; case 513: order = 1041; break; case 112: case 96: order = sBond.order; break; case 1: order = 1; break; case 17: order = 514; break; case 2: order = 2; break; case 3: order = 3; break; } var atom2 = atoms[sBond.getAtom2 ().getMatchingAtom ()]; var b = new JS.SmilesBond (atom1, atom2, order, false); atom2.bondCount--; JU.Logger.info ("" + b); } else { var atom2 = atoms[sBond.getAtom1 ().getMatchingAtom ()]; var b = atom2.getBondTo (atom1); atom1.addBond (b); }} } for (var i = bsFixH.nextSetBit (0); i >= 0; i = bsFixH.nextSetBit (i + 1)) { var bonds = atoms[i].getEdges (); var b = bonds[0]; bonds[0] = bonds[1]; bonds[1] = b; } }, "JU.BS"); Clazz.defineMethod (c$, "setTop", function (parent) { if (parent == null) this.top = this; else this.top = parent.getTop (); }, "JS.SmilesSearch"); Clazz.defineMethod (c$, "getTop", function () { return (this.top === this ? this : this.top.getTop ()); }); Clazz.defineMethod (c$, "getSelections", function () { var ht = this.top.htNested; if (ht == null || this.jmolAtoms.length == 0) return; var htNew = new java.util.Hashtable (); for (var entry, $entry = ht.entrySet ().iterator (); $entry.hasNext () && ((entry = $entry.next ()) || true);) { var key = entry.getValue ().toString (); if (key.startsWith ("select")) { var bs = (htNew.containsKey (key) ? htNew.get (key) : this.smartsAtoms[0].findAtomsLike (key.substring (6))); if (bs == null) bs = new JU.BS (); htNew.put (key, bs); entry.setValue (bs); }} }); Clazz.defineStatics (c$, "INITIAL_ATOMS", 16); });