xxxxxxxxxx
<meta charset="utf-8">
<head>
<link rel="stylesheet" type="text/css" href="molecules.css">
<script src="molecules.min.js"></script>
<script src="d3.min.js"></script>
<script async src="https://www.googletagmanager.com/gtag/js?id=ua-55320412-6"></script>
</head>
<style>
* {
box-sizing: border-box;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
}
html {
height: 100%;
}
body {
height: 96%;
font-family: arial, helvetica, sans-serif;
font-size: 12px;
}
#wrapper {
position: relative;
min-width: 200px;
min-height: 300px;
width: 98%;
height: 98%;
margin: auto;
padding: 0px;
border: 0px solid #999;
box-shadow: 0 0 5px rgba(159,159,159,0.8);
-o-box-shadow: 0 0 25px rgba(159,159,159,0.8);
-webkit-box-shadow: 0 0 25px rgba(159,159,159,0.8);
-moz-box-shadow: 0 0 25px rgba(159,159,159,0.8);
}
#header {
position: absolute;
top: 0;
width: 100%;
min-height: 85px;
margin: auto;
padding: 0px;
border: 0px solid #bbb;
}
#user-input {
width: auto;
height: auto;
margin: auto;
padding: 5px;
padding-top: 25px;
border: 0px solid #bbb;
}
#content-main {
position: relative;
top: 95px;
width: 100%;
height: 70%;
margin: 0px;
padding: 0px;
border: 0px solid #bbb;
}
#content-box {
width: 100%;
height: auto;
margin: 0px;
padding: 0px;
border: 0px solid #bbb;
}
#plot {
height: 100%;
width: 70%;
margin: 0px;
float: left;
overflow: hidden;
border: 0px solid #bbb;
}
#sidebar {
height: 100%;
width: 30%;
margin: 0px;
float: right;
padding-right: 1%;
overflow: hidden;
border: 0px solid #000;
}
#footer {
position: absolute;
bottom: 0;
width: 100%;
height: auto;
min-height: 40px;
margin: 0px;
padding: 0px;
border: 0px solid #bbb;
}
#content-source {
width: auto;
height: auto;
min-height: 40px;
margin: 0px;
padding: 10px;
overflow: hidden;
float: right;
border: 0px solid #bbb;
}
#content-source a {
text-align: center;
font-size: 14px;
font-weight: normal;
color: #53B2C8;
}
#content-info {
width: auto;
min-height: 10px;
margin: 0px;
padding: 10px;
float: left;
overflow: hidden;
border: 0px solid #bbb;
}
.background {
fill: #eee;
}
.group {
position: relative;
margin-bottom: 5px;
}
.examples {
color: #999;
margin-top: 0px;
padding-left: 15px;
font-size: 12px;
font-weight: normal;
font-family: 'Lucida Sans Unicode';
}
.examples a:link {
color: #53B2C8;
font-weight: bold;
}
.examples a:visited {
color: #53B2C8;
font-weight: bold;
}
.examples a:hover {
color: #53B2C8;
font-weight: bold;
}
.examples a:active {
color: #53B2C8;
font-weight: bold;
}
input {
width: 100%;
font-size: 16px;
padding: 10px 10px 10px 5px;
display: block;
border: none;
border-bottom: 1px solid #757575;
}
input:focus {
outline: none;
}
input:focus ~ label, input:valid ~ label {
top: -15px;
font-size: 13px;
color: #5264AE;
}
label {
color: #999;
font-size: 16px;
font-weight: normal;
position: absolute;
pointer-events: none;
left: 5px;
top: 10px;
transition: 0.2s ease all;
-moz-transition: 0.2s ease all;
-webkit-transition: 0.2s ease all;
}
other {
color: #999;
font-size: 14px;
font-weight: normal;
vertical-align: middle;
}
section {
color: #555;
font-size: 16px;
font-weight: normal;
vertical-align: middle;
}
.bar {
position: relative;
display: block;
width: 100%;
}
.bar:before, .bar:after {
content: '';
height: 2px;
width: 0px;
bottom: 0px;
position: absolute;
background: #5264AE;
transition: 0.2s ease all;
-moz-transition: 0.2s ease all;
-webkit-transition: 0.2s ease all;
}
.bar:before { left: 50%; }
.bar:after { right: 50%; }
input:focus ~ .bar:before, input:focus ~ .bar:after { width: 50%; }
.highlight {
position: absolute;
height: 60%;
width: 100px;
top: 25%;
left: 0%;
pointer-events: none;
opacity: 0.5;
}
input:focus ~ .highlight {
-webkit-animation:inputHighlighter 0.3s ease;
-moz-animation:inputHighlighter 0.3s ease;
animation:inputHighlighter 0.3s ease;
}
@-webkit-keyframes inputHighlighter {
from { background: #5264AE; }
to { width: 0; background: transparent; }
}
@-moz-keyframes inputHighlighter {
from { background: #5264AE; }
to { width: 0; background: transparent; }
}
@keyframes inputHighlighter {
from { background: #5264AE; }
to { width: 0; background: transparent; }
}
.svg-container {
display: inline-block;
position: absolute;
width: 100%;
height: auto;
padding-bottom: 0%;
bottom: 0px;
vertical-align: top;
overflow: hidden;
}
.svg-container-responsive {
display: inline-block;
position: relative;
padding: 0%;
width: 100%;
height: auto;
top: 0px;
left: 0px;
overflow: hidden;
}
</style>
<body>
<div id="wrapper">
<div id="header">
<div id="user-input"><form onsubmit="return false"><div id="user" class="group">
<input type="text" required value="CC(N)CC=O" onpaste="parseInput(this.value)" onkeyup="keyboardCallback(event)">
<span class="highlight"></span>
<span class="bar"></span>
<label id="textbox">Input SMILES notation...</label>
</div></form></div>
<div id="examples">
<p class="examples"><i>examples: </i>
<a href="#" onclick="parseInput('NC(CCC(N)=O)C(O)=O')">glutamine</a>,
<a href="#" onclick="parseInput('c1ccccc1')">benzene</a>,
<a href="#" onclick="parseInput('O[C@H]1[C@H](O)[C@H](O[C@]1(O)CO)CO')">fructose</a>,
<a href="#" onclick="parseInput('C=C(C)C=C')">isoprene</a>,
<a href="#" onclick="parseInput('CCO')">ethanol</a>,
<a href="#" onclick="parseInput('C#N')">cyanide</a>,
<a href="#" onclick="parseInput(randomMolecule[Math.floor(Math.random()*randomMolecule.length)].name)">random</a>
</p>
</div>
</div>
<div id="content-main">
<div id="plot"></div>
<div id="sidebar">
<section><div id="formatOptions"></div></section>
</div>
</div>
<div id="footer">
<div id="content-info">
<other><div id="molecularFormula"></div></other>
<other><div id="molecularWeight"></div></other>
</div>
<div id="content-source">
<br>
<a href="https://github.com/chemplexity/molecules" target="_blank">source</a>
</div>
</div>
</div>
</body>
<script>
//
// Global
//
var userInput = document.getElementsByTagName("input")[0].value;
var userExample = 'CC(N)CC=O';
//
// Keyboard Callback
//
var keyboardCallback = function(event) {
//var input = document.getElementsByTagName("input")[0].value;
// 0-9
//if (event.keyCode >= 48 && event.keyCode <= 57) { parseInput(input); }
// 'backspace'
//else if (event.keyCode === 8) { parseInput(input); }
// 'enter'
if (event.keyCode === 13) {
var input = document.getElementsByTagName("input")[0].value;
parseInput(input);
}
else {
return null;
}
// '-', '=', '.'
//else if (event.keyCode === 189 || event.keyCode === 187 || event.keyCode === 190) { return null; }
// non-alphabet
//else if (event.keyCode < 65 || event.keyCode > 90) { return null; }
// alphabet
//else { parseInput(input); }
};
//
// Input Callback
//
var parseInput = function(input) {
if (userInput === input && userInput !== userExample) { return null; }
document.getElementsByTagName("input")[0].value = input;
if (typeof input !== 'string' || input.length === 0 || input.length > 1000 ) { return null; }
var molecule = Molecules.parse.smiles(input);
if (typeof molecule === 'object') { update(molecule); }
userInput = input;
};
//
// molecules.js --> d3.js
//
function convertMolecule(molecule) {
var atoms = Object.keys(molecule.atoms);
var bonds = Object.keys(molecule.bonds);
var nodes = [];
var links = [];
for (var i = 0; i < atoms.length; i++) {
nodes.push({
id: molecule.atoms[atoms[i]].id,
name: molecule.atoms[atoms[i]].name,
protons: molecule.atoms[atoms[i]].protons,
neutrons: molecule.atoms[atoms[i]].neutrons,
electrons: molecule.atoms[atoms[i]].electrons,
bonds: molecule.atoms[atoms[i]].bonds,
properties: molecule.atoms[atoms[i]].properties
})
}
for (var i = 0; i < bonds.length; i++) {
links.push({
id: molecule.bonds[bonds[i]].id,
name: molecule.bonds[bonds[i]].name,
value: molecule.bonds[bonds[i]].value,
source: atoms.indexOf(molecule.bonds[bonds[i]].atoms[0]),
target: atoms.indexOf(molecule.bonds[bonds[i]].atoms[1]),
order: molecule.bonds[bonds[i]].order
})
}
return {nodes: nodes, links: links};
}
//
// HTML Elements
//
var topPanel = document.getElementById("header");
var centerPanel = document.getElementById("plot");
var sidePanel = document.getElementById("sidebar");
var bottomPanel = document.getElementById("footer");
//
// Display Properties
//
var mainPanelPadding = 0;
var mainPanelHeight = bottomPanel.offsetTop - topPanel.offsetHeight - mainPanelPadding;
var mainPanelWidth = centerPanel.offsetWidth;
var mainPanel = d3.select("#plot")
.append("div")
.classed("svg-container-responsive", true)
.append("svg")
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", "0 0 " + mainPanelWidth + " " + mainPanelHeight + "")
.classed("svg-content-responsive", true)
var supportPanel = d3.select("#sidebar")
.append("div")
.classed("svg-container-responsive", true)
.append("svg")
.attr("preserveAspectRatio", "xMinYMin meet")
.attr("viewBox", "0 0 " + sidebar.offsetWidth + " " + mainPanelHeight + "")
.classed("svg-content-responsive", true)
//
// Initialize d3.js
//
var forceProperties = {
size : [mainPanelWidth, mainPanelHeight],
charge : -1200,
chargeDistance : 800,
linkStrength : 1.9,
linkDistance : -40,
gravity : 1.6,
friction : 0.85
}
var force = d3.layout.force()
.size(forceProperties.size)
.charge(forceProperties.charge)
.chargeDistance(forceProperties.chargeDistance)
.linkStrength(forceProperties.linkStrength)
.linkDistance(forceProperties.linkDistance)
.gravity(forceProperties.gravity)
.friction(forceProperties.friction);
//
// Update d3.js
//
function update(molecule) {
//
// Molecule Properties
//
var graph = convertMolecule(molecule);
var nodes = force.nodes(graph.nodes);
var links = force.links(graph.links);
d3.selectAll(".node").remove();
d3.selectAll(".separator").remove()
//
// Bond Properties
//
var bondMuliplier = 3;
var piBond = {
stroke: '#FFFFFF',
strokeWidth: '2px'
};
var aromaticBond = {
stroke: '#696969',
strokeWidth: '3px',
strokeDashArray: ("3,3")
};
var bond = mainPanel.selectAll("line.link")
.data(graph.links, function(d) { return d.source + "-" + d.target; } )
.enter();
var singleBond = bond.append("svg:line")
.filter(function (d) { return d.order == 1 | d.order == 2 | d.order == 3 })
.attr("class", "link")
.style("stroke-width", function(d) { return (d.order * bondMuliplier - 1) * (bondMuliplier/2) + "px"; })
var doubleBond = bond.append("svg:line")
.filter(function (d) { return d.order == 2 })
.attr("class", "separator")
.style("stroke-width", piBond.strokeWidth)
.style("stroke", piBond.stroke)
var aromaticBond_1 = bond.append("svg:line")
.filter(function (d) { return d.order == 1.5 })
.attr("class", "separator")
.style("stroke-width", aromaticBond.strokeWidth)
.style("stroke", aromaticBond.stroke)
var aromaticBond_2 = bond.append("svg:line")
.filter(function (d) { return d.order == 1.5 })
.attr("class", "link")
.style("stroke-width", aromaticBond.strokeWidth)
.style("stroke", aromaticBond.stroke)
.style("stroke-dasharray", aromaticBond.strokeDashArray)
var tripleBond_1 = bond.append("svg:line")
.filter(function (d) { return d.order == 3 })
.attr("class", "separator")
.style("stroke-width", piBond.strokeWidth)
.style("stroke", piBond.stroke)
var tripleBond_2 = bond.append("svg:line")
.filter(function (d) { return d.order == 3 })
.attr("class", "separator")
.style("stroke-width", piBond.strokeWidth)
.style("stroke", piBond.stroke)
mainPanel.selectAll("line.link")
.data(graph.links, function(d) { return d.source + "-" + d.target; } )
.exit().remove();
//
// Atom Properties
//
var maxProtons = 11;
var maxRadius = 11;
var minRadius = 3;
var atomMultiplier = 3;
var atom = mainPanel.selectAll("circle")
.data(graph.nodes, function(d) { return Math.random(); });
atom.enter()
.append("circle")
.attr("class", "node")
.attr("class", function(d) { return 'atom-' + d.name; })
.attr("r", function(d) { return (d.protons < maxProtons) ? (Math.sqrt(d.protons + minRadius) * atomMultiplier) : maxRadius; })
.call(force.drag);
atom.exit()
.remove();
//
// XY Coordinates
//
var atomRadius = 9;
var bondOffset = 2;
force.start();
force.on("tick", function () {
singleBond
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
doubleBond
.attr("x1", function(d) { return d.source.x; })
.attr("y1", function(d) { return d.source.y; })
.attr("x2", function(d) { return d.target.x; })
.attr("y2", function(d) { return d.target.y; });
aromaticBond_1
.attr("x1", function(d) { return d.source.x - xOffset(bondOffset, d.source, d.target) })
.attr("y1", function(d) { return d.source.y - yOffset(bondOffset, d.source, d.target) })
.attr("x2", function(d) { return d.target.x - xOffset(bondOffset, d.source, d.target) })
.attr("y2", function(d) { return d.target.y - yOffset(bondOffset, d.source, d.target) });
aromaticBond_2
.attr("x1", function(d) { return d.source.x - xOffset(-bondOffset, d.source, d.target) })
.attr("y1", function(d) { return d.source.y - yOffset(-bondOffset, d.source, d.target) })
.attr("x2", function(d) { return d.target.x - xOffset(-bondOffset, d.source, d.target) })
.attr("y2", function(d) { return d.target.y - yOffset(-bondOffset, d.source, d.target) });
tripleBond_1
.attr("x1", function(d) { return d.source.x - xOffset(bondOffset, d.source, d.target) })
.attr("y1", function(d) { return d.source.y - yOffset(bondOffset, d.source, d.target) })
.attr("x2", function(d) { return d.target.x - xOffset(bondOffset, d.source, d.target) })
.attr("y2", function(d) { return d.target.y - yOffset(bondOffset, d.source, d.target) });
tripleBond_2
.attr("x1", function(d) { return d.source.x - xOffset(-bondOffset, d.source, d.target) })
.attr("y1", function(d) { return d.source.y - yOffset(-bondOffset, d.source, d.target) })
.attr("x2", function(d) { return d.target.x - xOffset(-bondOffset, d.source, d.target) })
.attr("y2", function(d) { return d.target.y - yOffset(-bondOffset, d.source, d.target) });
atom
.attr("cx", function(d) { return d.x = Math.max(atomRadius, Math.min(mainPanelWidth - atomRadius, d.x)); })
.attr("cy", function(d) { return d.y = Math.max(atomRadius, Math.min(mainPanelHeight - atomRadius, d.y)); });
});
// Update text
if (typeof molecule === 'object') {
updateMolecularWeight(molecule);
updateMolecularFormula(molecule);
}
}
//
// Helper Functions
//
function xOffset(offset, source, target) {
var dx = target.x - source.x;
var dy = target.y - source.y;
if (dy === 0 || Math.abs(dx/dy) > 1) { return offset * (dy/dx); }
else { return offset; }
}
function yOffset(offset, source, target) {
var dx = target.x - source.x;
var dy = target.y - source.y;
if (dy === 0 || Math.abs(dx/dy) > 1) { return -offset; }
else { return offset * -(dx/dy); }
}
//
// Text Functions
//
function updateMolecularWeight(molecule) {
var decimalPoints = Math.pow(10, 2);
var molecularWeight = (Math.round(molecule.properties.mass * decimalPoints) / decimalPoints) + ' g/mol';
document.getElementById("molecularWeight").innerHTML = molecularWeight;
}
function updateMolecularFormula(molecule) {
var molecularFormula = [];
var atoms = Object.keys(molecule.properties.formula).sort();
function updateFormula(atomName) {
var atomCount = molecule.properties.formula[atomName];
if (atomCount === 1) { molecularFormula.push(atomName); }
else { molecularFormula.push(atomName + atomCount); }
atoms.splice(atoms.indexOf(atomName), 1);
}
if (atoms.indexOf('Li') !== -1) { updateFormula('Li'); }
if (atoms.indexOf('Na') !== -1) { updateFormula('Na'); }
if (atoms.indexOf('Mg') !== -1) { updateFormula('Mg'); }
if (atoms.indexOf('K') !== -1) { updateFormula('K'); }
if (atoms.indexOf('Ca') !== -1) { updateFormula('Ca'); }
if (atoms.indexOf('C') !== -1) { updateFormula('C'); }
if (atoms.indexOf('H') !== -1) { updateFormula('H'); }
while (atoms.length > 0) { updateFormula(atoms[0]); }
document.getElementById("molecularFormula").innerHTML = molecularFormula.join('').replace(/(\d+)/g, '<sub>$1</sub>');
}
function updateZoom(graph) {
//var zoom = d3.behavior.zoom();
//console.log(zoom);
///main.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
//console.log(main);
//zoom.scale(4);
//main.call(zoom);
}
//
// Topology Functions
//
function getTopology(molecule) {
var adjacent = Molecules.topology.adjacency(molecule);
var distance = Molecules.topology.distance(molecule);
return {
header: adjacent.header,
adjacent: adjacent.matrix,
distance: distance.matrix
};
}
function formatMatrix(input) {
var output = [];
for (var i = 0; i < input.length; i++) {
output[i] = [];
for (var j = 0; j < input[0].length; j++) {
output[i][j] = { x: j, y: i, z: input[i][j] };
}
}
return output;
}
function updateMatrix(input) {
var matrix = document.getElementById("matrix");
var height = footer.offsetTop - 10 - header.offsetHeight;
var width = matrix.offsetWidth;
var distance = formatMatrix(input.distance);
support.append("rect")
.attr("class", "background")
.attr("width", width * 2)
.attr("height", height)
.attr("x", width*2);
var x = d3.scale.ordinal().rangeBands([0, width*0.85]);
var z = d3.scale.linear().domain([0, distance.length]).clamp(true);
var c = d3.scale.linear().range(["red", "steelblue"]).interpolate(d3.interpolateHcl);
c.domain(d3.range(distance.length));
x.domain(d3.range(input.header.length));
var row = support.selectAll(".row")
.data(distance)
.enter().append("g")
.attr("class", "row")
.attr("transform", function(d, i) { return "translate(" + (width * 0.1) + "," + (x(i) + height * 0.1) + ")"; })
.each(row);
row.append("line")
.attr("x2", -width);
row.append("text")
.attr("x", (x.rangeBand() / 2) - (x.rangeBand()/1.5))
.attr("y", x.rangeBand() / 2)
.attr("dy", ".32em")
.attr("text-anchor", "end")
.text(function(d, i) { return input.header[i]; });
var column = support.selectAll(".column")
.data(distance)
.enter().append("g")
.attr("class", "column")
.attr("transform", function(d, i) { return "translate(" + x(i) + ")rotate(0)"; });
column.append("line")
.attr("x1", -width);
column.append("text")
.attr("x", x.rangeBand())
.attr("y", (x.rangeBand() / 1.5))
.attr("dy", ".32em")
.attr("text-anchor", "start")
.text(function(d, i) { return input.header[i]; });
function row(row) {
var cell = d3.select(this).selectAll(".cell")
.data(row.filter(function(d) { return d.z; }))
.enter().append("rect")
.attr("class", "cell")
.attr("x", function(d) { return x(d.x); })
.attr("width", x.rangeBand()*0.97)
.attr("height", x.rangeBand()*0.97)
.style("fill-opacity", function(d) { return z(d.z)+0.4; })
.style("fill", function(d) { return c(d.z-1); });
}
}
//
// Initialization
//
parseInput(userExample);
//
// SMILES Examples
//
var randomMolecule = [
{mass: 72.151, formula: {C:5, H:12}, name: 'CCCCC', category: 'Alkane', type: 'Primary'},
{mass: 72.151, formula: {C:5, H:12}, name: 'CC(C)CC', category: 'Alkane', type: 'Secondary'},
{mass: 72.151, formula: {C:5, H:12}, name: 'CC(C)(C)C', category: 'Alkane', type: 'Tertiary'},
{mass: 56.108, formula: {C:4, H:8}, name: 'CC=CC', category: 'Alkene', type: 'Internal'},
{mass: 56.108, formula: {C:4, H:8}, name: 'C=CCC', category: 'Alkene', type: 'Terminal'},
{mass: 56.108, formula: {C:4, H:8}, name: 'C/C=C\C', category: 'Alkene', type: 'Cis'},
{mass: 56.108, formula: {C:4, H:8}, name: 'C/C=C/C', category: 'Alkene', type: 'Trans'},
{mass: 54.092, formula: {C:4, H:6}, name: 'C=CC=C', category: 'Alkene', type: 'Conjugated'},
{mass: 54.092, formula: {C:4, H:6}, name: 'C=C=CC', category: 'Alkene', type: 'Allene'},
{mass: 54.092, formula: {C:4, H:6}, name: 'CC#CC', category: 'Alkyne', type: 'Internal'},
{mass: 54.092, formula: {C:4, H:6}, name: 'C#CCC', category: 'Alkyne', type: 'Terminal'},
{mass: 74.123, formula: {C:4, H:10, O:1}, name: 'OCCCC', category: 'Alcohol', type: 'Primary'},
{mass: 74.123, formula: {C:4, H:10, O:1}, name: 'CC(O)CC', category: 'Alcohol', type: 'Secondary'},
{mass: 74.123, formula: {C:4, H:10, O:1}, name: 'CC(O)(C)C', category: 'Alcohol', type: 'Tertiary'},
{mass: 72.107, formula: {C:4, H:8, O:1}, name: 'C(=O)CCC', category: 'Carbonyl', type:'Aldehyde'},
{mass: 72.107, formula: {C:4, H:8, O:1}, name: 'CC(=O)CC', category: 'Carbonyl', type:'Ketone'},
{mass: 88.106, formula: {C:4, H:8, O:2}, name: 'OC(CCC)=O', category: 'Carbonyl', type:'Carboxylic Acid'},
{mass: 88.106, formula: {C:4, H:8, O:2}, name: 'O=C(CC)OC', category: 'Carbonyl', type:'Ester'},
{mass: 87.122, formula: {C:4, H:9, O:1, N:1}, name: 'NC(CCC)=O', category: 'Carbonyl', type:'Amide'},
{mass: 104.105, formula: {C:4, H:8, O:3}, name: 'O=C(CCC)OO', category: 'Carbonyl', type:'Peroxy Acid'},
{mass: 106.549, formula: {C:4, H:7, O:1, Cl:1}, name: 'ClC(CCC)=O', category: 'Carbonyl', type:'Acid Halide'},
{mass: 116.116, formula: {C:5, H:8, O:3}, name: 'O=C(CC)OC(C)=O', category: 'Carbonyl', type:'Acid Anhydride'},
{mass: 84.162, formula: {C:6, H:12}, name: 'C1CCCCC1', category: 'Cycloalkane', type: 'Basic'},
{mass: 166.308, formula: {C:12, H:22}, name: 'C1CCCCC1C2CCCCC2', category: 'Cycloalkane', type: 'Intermediate'},
{mass: 152.281, formula: {C:11, H:20}, name: 'C12(CCCCC1)CCCCC2', category: 'Cycloalkane', type: 'Advanced'},
{mass: 80.130, formula: {C:6, H:8}, name: 'C1C=CCC=C1', category: 'Cycloalkene', type: 'Basic'},
{mass: 104.152, formula: {C:8, H:8}, name: '[C@H]1=[C@@H][C@@H]=[C@@H][C@@H]=[C@@H][C@@H]=[C@@H]1', category: 'Cycloalkene', type: 'Advanced'},
{mass: 78.114, formula: {C:6, H:6}, name: 'c1ccccc1', category: 'Aromatic', type: 'Basic'},
{mass: 108.140, formula: {C:7, H:8, O:1}, name: 'OCc1ccccc1', category: 'Aromatic', type: 'Substituted'},
{mass: 154.212, formula: {C:12, H:10}, name: 'c1ccccc1-c2ccccc2', category: 'Aromatic', type: 'Advanced'},
{mass: 178.223, formula: {C:14, H:10}, name: 'C12=CC=CC=C1C3=C(C=CC=C3)C=C2', category: 'Aromatic', type: 'Polycyclic'},
{mass: 67.091, formula: {C:4, H:5, N:1}, name: 'C1=CC=CN1', category: 'Heteroaromatic', type: 'N'},
{mass: 68.075, formula: {C:4, H:4, O:1}, name: 'c1occc1', category: 'Heteroaromatic', type: 'O'},
{mass: 84.136, formula: {C:4, H:4, S:1}, name: 'c1sccc1', category: 'Heteroaromatic', type: 'S'},
{mass: 15.036, formula: {C:1, H:3}, name: '[CH3+]', category: 'Charge', type: 'Cation'},
{mass: 15.036, formula: {C:1, H:3}, name: '[CH3-]', category: 'Charge', type: 'Anion'},
{mass: 58.440, formula: {Na:1, Cl:1}, name: '[Na+].[Cl-]', category: 'Salt', type: 'Basic'},
{mass: 148.195, formula: {N:2, O:3, H:8, S:2}, name: '[NH4+].[NH4+].[O-]S(=O)(=O)[S-]', category: 'Salt', type: 'Advanced'},
{mass: 59.116, formula: {C:4, H:10}, name: 'C[13CH](C)C', category: 'Isotope', type: '13C'},
{mass: 60.116, formula: {C:4, H:10}, name: 'C[14CH](C)C', category: 'Isotope', type: '14C'},
{mass: 391.694, formula: {C:13, H:25, Cl:1, I:1, N:1, O:2}, name: 'CCOC(Cl)C1C[14C](I)C1NOCC(C)CCC', category: 'Isotope', type: '14C'},
{mass: 143.408, formula: {C:2, H:4, Br:1, Cl:1}, name: 'C[C@@H](Br)Cl', category: 'Chiral', type: 'Clockwise'},
{mass: 143.408, formula: {C:2, H:4, Br:1, Cl:1}, name: 'C[C@H](Br)Cl', category: 'Chiral', type: 'Anti-Clockwise'},
{mass: 180.156, formula: {C:6, H:12, O:6}, name: 'O[C@@]([H])(O1)[C@@](O)([H])[C@@]([H])(O)[C@]1([C@@](CO)(O)[H])[H]', category: 'Chiral', type: 'Mixed'},
{mass: 89.094, formula: {C:3, H:7, N:1, O:2}, name: 'NC(C)C(O)=O', category: 'Amino Acids', type: 'ALA'},
{mass: 174.204, formula: {C:6, H:14, N:4, O:2}, name: 'NC(CCCNC(N)=N)C(O)=O', category: 'Amino Acids', type: 'ARG'},
{mass: 132.119, formula: {C:4, H:8, N:2, O:3}, name: 'NC(CC(N)=O)C(O)=O', category: 'Amino Acids', type: 'ASN'},
{mass: 133.103, formula: {C:4, H:7, N:1, O:4}, name: 'NC(CC(O)=O)C(O)=O', category: 'Amino Acids', type: 'ASP'},
{mass: 121.154, formula: {C:3, H:7, N:1, O:2, S:1}, name: 'NC(CS)C(O)=O', category: 'Amino Acids', type: 'CYS'},
{mass: 147.130, formula: {C:5, H:9, N:1, O:4}, name: 'NC(CCC(O)=O)C(O)=O', category: 'Amino Acids', type: 'GLU'},
{mass: 146.146, formula: {C:5, H:10, N:2, O:3}, name: 'NC(CCC(N)=O)C(O)=O', category: 'Amino Acids', type: 'GLA'},
{mass: 75.067, formula: {C:2, H:5, N:1, O:2}, name: 'NC([H])C(O)=O', category: 'Amino Acids', type: 'GLY'},
{mass: 155.157, formula: {C:6, H:9, N:3, O:2}, name: 'NC(CC1=CNC=N1)C(O)=O', category: 'Amino Acids', type: 'HIS'},
{mass: 131.175, formula: {C:6, H:13, N:1, O:2}, name: 'NC(C(CC)C)C(O)=O', category: 'Amino Acids', type: 'ILE'},
{mass: 46.069, formula: {C:2, H:6, O:1}, name: 'C((C))O', category: 'Relaxed', type: 'Extra Parentheses'},
{mass: 85.150, formula: {C:5, H:11, N:1}, name: '(N1CCCCC1)', category: 'Relaxed', type: 'Extra Parentheses'},
{mass: 310.610, formula: {C:22, H:46}, name: 'C(C(C(C(C(C(C(C(C(C(C(C(C(C(C(C(C(C(C(C(C))))))))))))))))))))C', category: 'Relaxed', type: 'Extra Parentheses'},
{mass: 188.695, formula: {C:10, H:17, Cl:1, O:1}, name: 'CC(=O)C(Cl)CC(C(C)C)C=C', category: 'Other', type: 'Advanced'},
{mass: 154.209, formula: {C:9, H:14, O:2}, name: 'C2C(=O)C1COCCC1CC2', category: 'Other', type: 'Advanced'},
{mass: 150.646, formula: {C:7, H:15, Cl:1, O:1}, name: 'CC(CC(Cl)CCO)C', category: 'Other', type: 'Advanced'},
{mass: 170.252, formula: {C:10, H:18, O:2}, name: 'CC1C(CC(CC1C)CCO)=O', category: 'Other', type: 'Advanced'},
{mass: 131.175, formula: {C:6, H:13, N:1, O:2}, name: 'NC(C(CC)C)C(O)=O', category: 'Other', type: 'Advanced'},
{mass: 372.447, formula: {C:23, H:22, N:3, O:2}, name: 'c1ccccc1[C@]2(C(=O)N(C)C(N)=[NH+]2)c3cc(ccc3)-c4ccc(cc4)OC', category: 'Other', type: 'Advanced'}
];
</script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'UA-55320412-6');
</script>
Updated missing url https://www.googletagmanager.com/gtag/js?id=UA-55320412-6 to https://www.googletagmanager.com/gtag/js?id=ua-55320412-6
https://www.googletagmanager.com/gtag/js?id=UA-55320412-6