Spaces:
Running
Running
Add 2 files
Browse files- README.md +7 -5
- index.html +1149 -19
README.md
CHANGED
@@ -1,10 +1,12 @@
|
|
1 |
---
|
2 |
-
title:
|
3 |
-
emoji:
|
4 |
-
colorFrom:
|
5 |
-
colorTo:
|
6 |
sdk: static
|
7 |
pinned: false
|
|
|
|
|
8 |
---
|
9 |
|
10 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
1 |
---
|
2 |
+
title: adv
|
3 |
+
emoji: 🐳
|
4 |
+
colorFrom: blue
|
5 |
+
colorTo: blue
|
6 |
sdk: static
|
7 |
pinned: false
|
8 |
+
tags:
|
9 |
+
- deepsite
|
10 |
---
|
11 |
|
12 |
+
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
index.html
CHANGED
@@ -1,19 +1,1149 @@
|
|
1 |
-
<!
|
2 |
-
<html>
|
3 |
-
|
4 |
-
|
5 |
-
|
6 |
-
|
7 |
-
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
|
14 |
-
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
|
19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html lang="en">
|
3 |
+
<head>
|
4 |
+
<meta charset="UTF-8">
|
5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
6 |
+
<title>ChemCalc Pro | Advanced Chemical Calculator</title>
|
7 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
8 |
+
<style>
|
9 |
+
:root {
|
10 |
+
--primary: #3a7bd5;
|
11 |
+
--secondary: #00d2ff;
|
12 |
+
--dark: #1a1a2e;
|
13 |
+
--light: #f5f7fa;
|
14 |
+
--success: #28a745;
|
15 |
+
--danger: #dc3545;
|
16 |
+
--warning: #fd7e14;
|
17 |
+
--info: #17a2b8;
|
18 |
+
}
|
19 |
+
|
20 |
+
* {
|
21 |
+
margin: 0;
|
22 |
+
padding: 0;
|
23 |
+
box-sizing: border-box;
|
24 |
+
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
25 |
+
}
|
26 |
+
|
27 |
+
body {
|
28 |
+
background: linear-gradient(135deg, #f5f7fa 0%, #e4e6e9 100%);
|
29 |
+
min-height: 100vh;
|
30 |
+
color: var(--dark);
|
31 |
+
}
|
32 |
+
|
33 |
+
.container {
|
34 |
+
max-width: 1200px;
|
35 |
+
margin: 0 auto;
|
36 |
+
padding: 20px;
|
37 |
+
}
|
38 |
+
|
39 |
+
header {
|
40 |
+
text-align: center;
|
41 |
+
margin-bottom: 30px;
|
42 |
+
padding: 20px;
|
43 |
+
background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
|
44 |
+
color: white;
|
45 |
+
border-radius: 10px;
|
46 |
+
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
|
47 |
+
}
|
48 |
+
|
49 |
+
h1 {
|
50 |
+
font-size: 2.5rem;
|
51 |
+
margin-bottom: 10px;
|
52 |
+
}
|
53 |
+
|
54 |
+
h1 i {
|
55 |
+
margin-right: 15px;
|
56 |
+
}
|
57 |
+
|
58 |
+
.subtitle {
|
59 |
+
font-size: 1.1rem;
|
60 |
+
opacity: 0.9;
|
61 |
+
}
|
62 |
+
|
63 |
+
.tabs {
|
64 |
+
display: flex;
|
65 |
+
flex-wrap: wrap;
|
66 |
+
background: white;
|
67 |
+
border-radius: 10px;
|
68 |
+
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
|
69 |
+
margin-bottom: 30px;
|
70 |
+
overflow: hidden;
|
71 |
+
}
|
72 |
+
|
73 |
+
.tab-button {
|
74 |
+
flex: 1;
|
75 |
+
padding: 15px 20px;
|
76 |
+
text-align: center;
|
77 |
+
cursor: pointer;
|
78 |
+
transition: all 0.3s ease;
|
79 |
+
font-weight: 600;
|
80 |
+
border-bottom: 3px solid transparent;
|
81 |
+
}
|
82 |
+
|
83 |
+
.tab-button:hover {
|
84 |
+
background: rgba(0, 0, 0, 0.05);
|
85 |
+
}
|
86 |
+
|
87 |
+
.tab-button.active {
|
88 |
+
background: rgba(58, 123, 213, 0.1);
|
89 |
+
border-bottom: 3px solid var(--primary);
|
90 |
+
color: var(--primary);
|
91 |
+
}
|
92 |
+
|
93 |
+
.tab-content {
|
94 |
+
display: none;
|
95 |
+
padding: 30px;
|
96 |
+
background: white;
|
97 |
+
border-radius: 0 0 10px 10px;
|
98 |
+
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
|
99 |
+
}
|
100 |
+
|
101 |
+
.tab-content.active {
|
102 |
+
display: block;
|
103 |
+
animation: fadeIn 0.5s ease;
|
104 |
+
}
|
105 |
+
|
106 |
+
@keyframes fadeIn {
|
107 |
+
from { opacity: 0; transform: translateY(10px); }
|
108 |
+
to { opacity: 1; transform: translateY(0); }
|
109 |
+
}
|
110 |
+
|
111 |
+
.calculator-form {
|
112 |
+
display: grid;
|
113 |
+
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
|
114 |
+
gap: 20px;
|
115 |
+
}
|
116 |
+
|
117 |
+
.form-group {
|
118 |
+
margin-bottom: 20px;
|
119 |
+
}
|
120 |
+
|
121 |
+
label {
|
122 |
+
display: block;
|
123 |
+
margin-bottom: 8px;
|
124 |
+
font-weight: 600;
|
125 |
+
color: #555;
|
126 |
+
}
|
127 |
+
|
128 |
+
input, select {
|
129 |
+
width: 100%;
|
130 |
+
padding: 12px 15px;
|
131 |
+
border: 1px solid #ddd;
|
132 |
+
border-radius: 6px;
|
133 |
+
font-size: 16px;
|
134 |
+
transition: border 0.3s ease;
|
135 |
+
}
|
136 |
+
|
137 |
+
input:focus, select:focus {
|
138 |
+
border-color: var(--primary);
|
139 |
+
outline: none;
|
140 |
+
box-shadow: 0 0 0 3px rgba(58, 123, 213, 0.2);
|
141 |
+
}
|
142 |
+
|
143 |
+
.btn {
|
144 |
+
display: inline-block;
|
145 |
+
padding: 12px 24px;
|
146 |
+
background: linear-gradient(135deg, var(--primary) 0%, var(--secondary) 100%);
|
147 |
+
color: white;
|
148 |
+
border: none;
|
149 |
+
border-radius: 6px;
|
150 |
+
cursor: pointer;
|
151 |
+
font-size: 16px;
|
152 |
+
font-weight: 600;
|
153 |
+
transition: all 0.3s ease;
|
154 |
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
155 |
+
}
|
156 |
+
|
157 |
+
.btn:hover {
|
158 |
+
transform: translateY(-2px);
|
159 |
+
box-shadow: 0 6px 8px rgba(0, 0, 0, 0.15);
|
160 |
+
}
|
161 |
+
|
162 |
+
.btn-calculate {
|
163 |
+
grid-column: 1 / -1;
|
164 |
+
justify-self: center;
|
165 |
+
margin-top: 20px;
|
166 |
+
min-width: 200px;
|
167 |
+
}
|
168 |
+
|
169 |
+
.result-container {
|
170 |
+
margin-top: 30px;
|
171 |
+
padding: 20px;
|
172 |
+
background: rgba(58, 123, 213, 0.1);
|
173 |
+
border-radius: 8px;
|
174 |
+
border-left: 4px solid var(--primary);
|
175 |
+
display: none;
|
176 |
+
}
|
177 |
+
|
178 |
+
.result-container.show {
|
179 |
+
display: block;
|
180 |
+
animation: fadeIn 0.5s ease;
|
181 |
+
}
|
182 |
+
|
183 |
+
.result-title {
|
184 |
+
font-weight: 700;
|
185 |
+
margin-bottom: 10px;
|
186 |
+
color: var(--primary);
|
187 |
+
}
|
188 |
+
|
189 |
+
.result-value {
|
190 |
+
font-size: 1.2rem;
|
191 |
+
font-weight: 600;
|
192 |
+
}
|
193 |
+
|
194 |
+
.periodic-table {
|
195 |
+
margin-top: 30px;
|
196 |
+
}
|
197 |
+
|
198 |
+
.periodic-table h3 {
|
199 |
+
margin-bottom: 15px;
|
200 |
+
color: var(--primary);
|
201 |
+
}
|
202 |
+
|
203 |
+
.elements-grid {
|
204 |
+
display: grid;
|
205 |
+
grid-template-columns: repeat(18, 1fr);
|
206 |
+
gap: 5px;
|
207 |
+
margin-bottom: 30px;
|
208 |
+
}
|
209 |
+
|
210 |
+
.element {
|
211 |
+
padding: 10px 5px;
|
212 |
+
background: white;
|
213 |
+
border-radius: 4px;
|
214 |
+
text-align: center;
|
215 |
+
cursor: pointer;
|
216 |
+
transition: all 0.3s ease;
|
217 |
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
218 |
+
}
|
219 |
+
|
220 |
+
.element:hover {
|
221 |
+
transform: scale(1.05);
|
222 |
+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
223 |
+
z-index: 1;
|
224 |
+
}
|
225 |
+
|
226 |
+
.element-symbol {
|
227 |
+
font-weight: 700;
|
228 |
+
font-size: 0.9rem;
|
229 |
+
}
|
230 |
+
|
231 |
+
.element-number {
|
232 |
+
font-size: 0.6rem;
|
233 |
+
opacity: 0.7;
|
234 |
+
}
|
235 |
+
|
236 |
+
.nonmetal { background-color: #ade8af; }
|
237 |
+
.alkali { background-color: #ffb7b3; }
|
238 |
+
.alkaline { background-color: #ffdfba; }
|
239 |
+
.transition { background-color: #ffc8dd; }
|
240 |
+
.post-transition { background-color: #b8d0eb; }
|
241 |
+
.metalloid { background-color: #c2e0c6; }
|
242 |
+
.halogen { background-color: #caffbf; }
|
243 |
+
.noble { background-color: #cddafd; }
|
244 |
+
.lanthanide { background-color: #eac4d5; }
|
245 |
+
.actinide { background-color: #f1c0e8; }
|
246 |
+
|
247 |
+
.history-container {
|
248 |
+
margin-top: 30px;
|
249 |
+
max-height: 300px;
|
250 |
+
overflow-y: auto;
|
251 |
+
}
|
252 |
+
|
253 |
+
.history-item {
|
254 |
+
padding: 10px 15px;
|
255 |
+
margin-bottom: 10px;
|
256 |
+
background: white;
|
257 |
+
border-radius: 6px;
|
258 |
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
259 |
+
font-size: 0.9rem;
|
260 |
+
}
|
261 |
+
|
262 |
+
.history-item .time {
|
263 |
+
font-size: 0.8rem;
|
264 |
+
color: #777;
|
265 |
+
}
|
266 |
+
|
267 |
+
footer {
|
268 |
+
text-align: center;
|
269 |
+
margin-top: 50px;
|
270 |
+
padding: 20px;
|
271 |
+
color: #777;
|
272 |
+
font-size: 0.9rem;
|
273 |
+
}
|
274 |
+
|
275 |
+
@media (max-width: 768px) {
|
276 |
+
.elements-grid {
|
277 |
+
grid-template-columns: repeat(9, 1fr);
|
278 |
+
}
|
279 |
+
|
280 |
+
.tab-button {
|
281 |
+
flex: 0 0 50%;
|
282 |
+
}
|
283 |
+
}
|
284 |
+
|
285 |
+
@media (max-width: 480px) {
|
286 |
+
.tab-button {
|
287 |
+
flex: 0 0 100%;
|
288 |
+
}
|
289 |
+
|
290 |
+
.elements-grid {
|
291 |
+
grid-template-columns: repeat(6, 1fr);
|
292 |
+
}
|
293 |
+
}
|
294 |
+
|
295 |
+
/* Special styling for specific calculator types */
|
296 |
+
.concentration-controls, .reaction-controls {
|
297 |
+
display: flex;
|
298 |
+
gap: 15px;
|
299 |
+
align-items: center;
|
300 |
+
}
|
301 |
+
|
302 |
+
.reaction-arrow {
|
303 |
+
font-size: 1.5rem;
|
304 |
+
color: #777;
|
305 |
+
padding: 0 10px;
|
306 |
+
}
|
307 |
+
|
308 |
+
.formula-display {
|
309 |
+
font-size: 1.2rem;
|
310 |
+
font-family: 'Courier New', monospace;
|
311 |
+
padding: 10px;
|
312 |
+
background: #f5f5f5;
|
313 |
+
border-radius: 4px;
|
314 |
+
margin: 15px 0;
|
315 |
+
word-break: break-all;
|
316 |
+
}
|
317 |
+
|
318 |
+
.advanced-options {
|
319 |
+
margin-top: 20px;
|
320 |
+
padding-top: 20px;
|
321 |
+
border-top: 1px solid #eee;
|
322 |
+
}
|
323 |
+
|
324 |
+
.toggle-advanced {
|
325 |
+
background: none;
|
326 |
+
border: none;
|
327 |
+
color: var(--primary);
|
328 |
+
cursor: pointer;
|
329 |
+
font-weight: 600;
|
330 |
+
display: flex;
|
331 |
+
align-items: center;
|
332 |
+
margin-bottom: 10px;
|
333 |
+
}
|
334 |
+
|
335 |
+
.toggle-advanced i {
|
336 |
+
margin-right: 5px;
|
337 |
+
transition: transform 0.3s ease;
|
338 |
+
}
|
339 |
+
|
340 |
+
.toggle-advanced.collapsed i {
|
341 |
+
transform: rotate(-90deg);
|
342 |
+
}
|
343 |
+
</style>
|
344 |
+
</head>
|
345 |
+
<body>
|
346 |
+
<div class="container">
|
347 |
+
<header>
|
348 |
+
<h1><i class="fas fa-atom"></i> ChemCalc Pro</h1>
|
349 |
+
<p class="subtitle">Advanced Chemical Calculations for Professionals</p>
|
350 |
+
</header>
|
351 |
+
|
352 |
+
<div class="tabs">
|
353 |
+
<div class="tab-button active" data-tab="molar-mass"><i class="fas fa-weight-hanging"></i> Molar Mass</div>
|
354 |
+
<div class="tab-button" data-tab="concentration"><i class="fas fa-flask"></i> Concentration</div>
|
355 |
+
<div class="tab-button" data-tab="stoichiometry"><i class="fas fa-balance-scale"></i> Stoichiometry</div>
|
356 |
+
<div class="tab-button" data-tab="gas-laws"><i class="fas fa-wind"></i> Gas Laws</div>
|
357 |
+
<div class="tab-button" data-tab="thermochemistry"><i class="fas fa-temperature-high"></i> Thermochemistry</div>
|
358 |
+
<div class="tab-button" data-tab="redox"><i class="fas fa-bolt"></i> Redox</div>
|
359 |
+
</div>
|
360 |
+
|
361 |
+
<!-- Molar Mass Calculator -->
|
362 |
+
<div id="molar-mass" class="tab-content active">
|
363 |
+
<h2><i class="fas fa-weight-hanging"></i> Molar Mass Calculator</h2>
|
364 |
+
<p>Calculate the molar mass of any chemical compound by entering its formula.</p>
|
365 |
+
|
366 |
+
<div class="calculator-form">
|
367 |
+
<div class="form-group">
|
368 |
+
<label for="compound-formula">Chemical Formula</label>
|
369 |
+
<input type="text" id="compound-formula" placeholder="e.g. H2O, C6H12O6, Ca(OH)2">
|
370 |
+
</div>
|
371 |
+
|
372 |
+
<div class="form-group">
|
373 |
+
<label for="compound-mass">Mass (optional)</label>
|
374 |
+
<div class="concentration-controls">
|
375 |
+
<input type="number" id="compound-mass" placeholder="e.g. 5">
|
376 |
+
<select id="mass-unit">
|
377 |
+
<option value="g">g</option>
|
378 |
+
<option value="mg">mg</option>
|
379 |
+
<option value="kg">kg</option>
|
380 |
+
</select>
|
381 |
+
</div>
|
382 |
+
</div>
|
383 |
+
|
384 |
+
<button id="calculate-mass" class="btn btn-calculate">Calculate Molar Mass</button>
|
385 |
+
</div>
|
386 |
+
|
387 |
+
<div id="mass-result" class="result-container">
|
388 |
+
<div class="result-title">Results</div>
|
389 |
+
<div id="mass-value" class="result-value"></div>
|
390 |
+
<div id="moles-value" class="result-value" style="margin-top: 10px;"></div>
|
391 |
+
<div id="composition" style="margin-top: 15px;"></div>
|
392 |
+
</div>
|
393 |
+
|
394 |
+
<div class="periodic-table">
|
395 |
+
<h3>Periodic Table</h3>
|
396 |
+
<p>Click on elements to add them to the formula</p>
|
397 |
+
<div class="elements-grid" id="periodic-elements"></div>
|
398 |
+
</div>
|
399 |
+
</div>
|
400 |
+
|
401 |
+
<!-- Concentration Calculator -->
|
402 |
+
<div id="concentration" class="tab-content">
|
403 |
+
<h2><i class="fas fa-flask"></i> Concentration Calculator</h2>
|
404 |
+
<p>Calculate concentration, mass, volume, or dilution of solutions.</p>
|
405 |
+
|
406 |
+
<div class="calculator-form">
|
407 |
+
<div class="form-group">
|
408 |
+
<label>Calculation Type</label>
|
409 |
+
<select id="concentration-type" class="form-control">
|
410 |
+
<option value="conc-from-mass">Concentration from Mass</option>
|
411 |
+
<option value="mass-from-conc">Mass from Concentration</option>
|
412 |
+
<option value="dilution">Dilution</option>
|
413 |
+
<option value="mole-fraction">Mole Fraction</option>
|
414 |
+
</select>
|
415 |
+
</div>
|
416 |
+
|
417 |
+
<div id="conc-inputs">
|
418 |
+
<div class="form-group">
|
419 |
+
<label for="solute-formula">Solute Formula</label>
|
420 |
+
<input type="text" id="solute-formula" placeholder="e.g. NaCl">
|
421 |
+
</div>
|
422 |
+
|
423 |
+
<div class="form-group">
|
424 |
+
<label for="solute-mass">Mass of Solute</label>
|
425 |
+
<input type="number" id="solute-mass" placeholder="in grams">
|
426 |
+
</div>
|
427 |
+
|
428 |
+
<div class="form-group">
|
429 |
+
<label for="solution-volume">Solution Volume</label>
|
430 |
+
<div class="concentration-controls">
|
431 |
+
<input type="number" id="solution-volume" placeholder="e.g. 250">
|
432 |
+
<select id="vol-unit">
|
433 |
+
<option value="L">L</option>
|
434 |
+
<option value="mL">mL</option>
|
435 |
+
</select>
|
436 |
+
</div>
|
437 |
+
</div>
|
438 |
+
</div>
|
439 |
+
|
440 |
+
<div id="dilution-inputs" style="display: none;">
|
441 |
+
<div class="form-group">
|
442 |
+
<label for="initial-conc">Initial Concentration</label>
|
443 |
+
<div class="concentration-controls">
|
444 |
+
<input type="number" id="initial-conc">
|
445 |
+
<select id="initial-conc-unit">
|
446 |
+
<option value="M">M</option>
|
447 |
+
<option value="mM">mM</option>
|
448 |
+
</select>
|
449 |
+
</div>
|
450 |
+
</div>
|
451 |
+
|
452 |
+
<div class="form-group">
|
453 |
+
<label for="initial-vol">Initial Volume</label>
|
454 |
+
<div class="concentration-controls">
|
455 |
+
<input type="number" id="initial-vol">
|
456 |
+
<select id="initial-vol-unit">
|
457 |
+
<option value="L">L</option>
|
458 |
+
<option value="mL">mL</option>
|
459 |
+
</select>
|
460 |
+
</div>
|
461 |
+
</div>
|
462 |
+
</div>
|
463 |
+
|
464 |
+
<div id="conc-advanced" class="advanced-options" style="display: none;">
|
465 |
+
<div class="form-group">
|
466 |
+
<label for="solution-density">Solution Density (g/mL)</label>
|
467 |
+
<input type="number" id="solution-density" placeholder="Optional">
|
468 |
+
</div>
|
469 |
+
|
470 |
+
<div class="form-group">
|
471 |
+
<label for="solvent-mass">Solvent Mass (g)</label>
|
472 |
+
<input type="number" id="solvent-mass" placeholder="Optional">
|
473 |
+
</div>
|
474 |
+
|
475 |
+
<div class="form-group">
|
476 |
+
<label for="solution-temp">Temperature (°C)</label>
|
477 |
+
<input type="number" id="solution-temp" placeholder="25">
|
478 |
+
</div>
|
479 |
+
</div>
|
480 |
+
|
481 |
+
<button type="button" class="toggle-advanced" id="toggle-conc-advanced">
|
482 |
+
<i class="fas fa-chevron-down"></i> Advanced Options
|
483 |
+
</button>
|
484 |
+
|
485 |
+
<button id="calculate-conc" class="btn btn-calculate">Calculate</button>
|
486 |
+
</div>
|
487 |
+
|
488 |
+
<div id="conc-result" class="result-container">
|
489 |
+
<div class="result-title">Results</div>
|
490 |
+
<div id="conc-value" class="result-value"></div>
|
491 |
+
<div id="conc-details" style="margin-top: 15px;"></div>
|
492 |
+
</div>
|
493 |
+
</div>
|
494 |
+
|
495 |
+
<!-- Stoichiometry Calculator -->
|
496 |
+
<div id="stoichiometry" class="tab-content">
|
497 |
+
<h2><i class="fas fa-balance-scale"></i> Stoichiometry Calculator</h2>
|
498 |
+
<p>Balance chemical equations and perform stoichiometric calculations.</p>
|
499 |
+
|
500 |
+
<div class="calculator-form">
|
501 |
+
<div class="form-group">
|
502 |
+
<label>Reaction Type</label>
|
503 |
+
<select id="reaction-type" class="form-control">
|
504 |
+
<option value="balance">Balance Equation</option>
|
505 |
+
<option value="limiting-reactant">Limiting Reactant</option>
|
506 |
+
<option value="product-yield">Product Yield</option>
|
507 |
+
</select>
|
508 |
+
</div>
|
509 |
+
|
510 |
+
<div id="reaction-inputs">
|
511 |
+
<div class="form-group balanced-equation">
|
512 |
+
<label>Enter Chemical Equation</label>
|
513 |
+
<div class="formula-display" id="equation-display"></div>
|
514 |
+
<div class="reaction-controls">
|
515 |
+
<input type="text" id="reactant1" placeholder="Reactant 1 (e.g. H2)">
|
516 |
+
<div class="reaction-arrow">+</div>
|
517 |
+
<input type="text" id="reactant2" placeholder="Reactant 2 (e.g. O2)">
|
518 |
+
<div class="reaction-arrow">
|
519 |
+
<select id="reaction-direction">
|
520 |
+
<option value="→">→</option>
|
521 |
+
<option value="↔">↔</option>
|
522 |
+
</select>
|
523 |
+
</div>
|
524 |
+
<input type="text" id="product1" placeholder="Product 1 (e.g. H2O)">
|
525 |
+
<div class="reaction-arrow">+</div>
|
526 |
+
<input type="text" id="product2" placeholder="Product 2 (optional)">
|
527 |
+
</div>
|
528 |
+
</div>
|
529 |
+
|
530 |
+
<div id="stoich-inputs" style="display: none;">
|
531 |
+
<div class="form-group">
|
532 |
+
<label for="given-quantity">Given Quantity</label>
|
533 |
+
<input type="number" id="given-quantity" placeholder="Amount">
|
534 |
+
</div>
|
535 |
+
|
536 |
+
<div class="form-group">
|
537 |
+
<label for="given-compound">Given Compound</label>
|
538 |
+
<input type="text" id="given-compound" placeholder="Formula">
|
539 |
+
</div>
|
540 |
+
|
541 |
+
<div class="form-group">
|
542 |
+
<label for="desired-compound">Desired Compound</label>
|
543 |
+
<input type="text" id="desired-compound" placeholder="Formula">
|
544 |
+
</div>
|
545 |
+
</div>
|
546 |
+
</div>
|
547 |
+
|
548 |
+
<button id="balance-reaction" class="btn btn-calculate">Balance Equation</button>
|
549 |
+
|
550 |
+
<div id="stoich-result" class="result-container">
|
551 |
+
<div class="result-title">Results</div>
|
552 |
+
<div id="balanced-equation" class="result-value"></div>
|
553 |
+
<div id="stoich-details" style="margin-top: 15px;"></div>
|
554 |
+
</div>
|
555 |
+
</div>
|
556 |
+
</div>
|
557 |
+
|
558 |
+
<!-- Gas Laws Calculator -->
|
559 |
+
<div id="gas-laws" class="tab-content">
|
560 |
+
<h2><i class="fas fa-wind"></i> Gas Laws Calculator</h2>
|
561 |
+
<p>Perform calculations using the ideal gas law and other gas equations.</p>
|
562 |
+
|
563 |
+
<div class="calculator-form">
|
564 |
+
<div class="form-group">
|
565 |
+
<label>Gas Law</label>
|
566 |
+
<select id="gas-law" class="form-control">
|
567 |
+
<option value="ideal-gas">Ideal Gas Law (PV=nRT)</option>
|
568 |
+
<option value="boyles">Boyle's Law (P₁V₁=P₂V₂)</option>
|
569 |
+
<option value="charles">Charles's Law (V₁/T₁=V₂/T₂)</option>
|
570 |
+
<option value="gay-lussac">Gay-Lussac's Law (P₁/T₁=P₂/T₂)</option>
|
571 |
+
<option value="combined">Combined Gas Law (P₁V₁/T₁=P₂V₂/T₂)</option>
|
572 |
+
<option value="density">Gas Density (d=PM/RT)</option>
|
573 |
+
</select>
|
574 |
+
</div>
|
575 |
+
|
576 |
+
<div id="ideal-gas-inputs">
|
577 |
+
<div class="form-group">
|
578 |
+
<label for="gas-pressure">Pressure (P)</label>
|
579 |
+
<div class="concentration-controls">
|
580 |
+
<input type="number" id="gas-pressure" placeholder="e.g. 1">
|
581 |
+
<select id="pressure-unit">
|
582 |
+
<option value="atm">atm</option>
|
583 |
+
<option value="mmHg">mmHg</option>
|
584 |
+
<option value="kPa">kPa</option>
|
585 |
+
<option value="bar">bar</option>
|
586 |
+
</select>
|
587 |
+
</div>
|
588 |
+
</div>
|
589 |
+
|
590 |
+
<div class="form-group">
|
591 |
+
<label for="gas-volume">Volume (V)</label>
|
592 |
+
<div class="concentration-controls">
|
593 |
+
<input type="number" id="gas-volume" placeholder="e.g. 22.4">
|
594 |
+
<select id="volume-unit">
|
595 |
+
<option value="L">L</option>
|
596 |
+
<option value="mL">mL</option>
|
597 |
+
</select>
|
598 |
+
</div>
|
599 |
+
</div>
|
600 |
+
|
601 |
+
<div class="form-group">
|
602 |
+
<label for="gas-moles">Moles (n)</label>
|
603 |
+
<input type="number" id="gas-moles" placeholder="e.g. 1">
|
604 |
+
</div>
|
605 |
+
|
606 |
+
<div class="form-group">
|
607 |
+
<label for="gas-temp">Temperature (T)</label>
|
608 |
+
<div class="concentration-controls">
|
609 |
+
<input type="number" id="gas-temp" placeholder="e.g. 273">
|
610 |
+
<select id="temp-unit">
|
611 |
+
<option value="K">K</option>
|
612 |
+
<option value="°C">°C</option>
|
613 |
+
</select>
|
614 |
+
</div>
|
615 |
+
</div>
|
616 |
+
</div>
|
617 |
+
|
618 |
+
<button id="calculate-gas" class="btn btn-calculate">Calculate</button>
|
619 |
+
|
620 |
+
<div id="gas-result" class="result-container">
|
621 |
+
<div class="result-title">Results</div>
|
622 |
+
<div id="gas-value" class="result-value"></div>
|
623 |
+
<div id="gas-details" style="margin-top: 15px;"></div>
|
624 |
+
</div>
|
625 |
+
</div>
|
626 |
+
</div>
|
627 |
+
|
628 |
+
<!-- Thermochemistry Calculator -->
|
629 |
+
<div id="thermochemistry" class="tab-content">
|
630 |
+
<h2><i class="fas fa-temperature-high"></i> Thermochemistry Calculator</h2>
|
631 |
+
<p>Calculate enthalpy, heat transfer, and other thermochemical properties.</p>
|
632 |
+
|
633 |
+
<div class="calculator-form">
|
634 |
+
<div class="form-group">
|
635 |
+
<label>Calculation Type</label>
|
636 |
+
<select id="thermo-type" class="form-control">
|
637 |
+
<option value="enthalpy">Enthalpy Change</option>
|
638 |
+
<option value="heat">Heat Transfer (q=mcΔT)</option>
|
639 |
+
<option value="hess">Hess's Law</option>
|
640 |
+
<option value="calorimetry">Calorimetry</option>
|
641 |
+
</select>
|
642 |
+
</div>
|
643 |
+
|
644 |
+
<!-- Enthalpy inputs -->
|
645 |
+
<div id="enthalpy-inputs">
|
646 |
+
<div class="form-group">
|
647 |
+
<label for="reaction-enthalpy">Reaction Enthalpy (ΔH°)</label>
|
648 |
+
<div class="concentration-controls">
|
649 |
+
<input type="number" id="reaction-enthalpy" placeholder="kJ/mol">
|
650 |
+
</div>
|
651 |
+
</div>
|
652 |
+
|
653 |
+
<div class="form-group">
|
654 |
+
<label for="moles-reacted">Moles Reacted</label>
|
655 |
+
<input type="number" id="moles-reacted" placeholder="mol">
|
656 |
+
</div>
|
657 |
+
</div>
|
658 |
+
|
659 |
+
<!-- Heat inputs -->
|
660 |
+
<div id="heat-inputs" style="display: none;">
|
661 |
+
<div class="form-group">
|
662 |
+
<label for="thermo-mass">Mass</label>
|
663 |
+
<div class="concentration-controls">
|
664 |
+
<input type="number" id="thermo-mass" placeholder="g">
|
665 |
+
</div>
|
666 |
+
</div>
|
667 |
+
|
668 |
+
<div class="form-group">
|
669 |
+
<label for="specific-heat">Specific Heat Capacity (c)</label>
|
670 |
+
<div class="concentration-controls">
|
671 |
+
<input type="number" id="specific-heat" placeholder="J/g°C (4.18 for water)">
|
672 |
+
</div>
|
673 |
+
</div>
|
674 |
+
|
675 |
+
<div class="form-group">
|
676 |
+
<label for="temp-change">Temperature Change (ΔT)</label>
|
677 |
+
<div class="concentration-controls">
|
678 |
+
<input type="number" id="temp-change" placeholder="°C">
|
679 |
+
</div>
|
680 |
+
</div>
|
681 |
+
</div>
|
682 |
+
|
683 |
+
<button id="calculate-thermo" class="btn btn-calculate">Calculate</button>
|
684 |
+
|
685 |
+
<div id="thermo-result" class="result-container">
|
686 |
+
<div class="result-title">Results</div>
|
687 |
+
<div id="thermo-value" class="result-value"></div>
|
688 |
+
<div id="thermo-details" style="margin-top: 15px;"></div>
|
689 |
+
</div>
|
690 |
+
</div>
|
691 |
+
</div>
|
692 |
+
|
693 |
+
<!-- Redox Calculator -->
|
694 |
+
<div id="redox" class="tab-content">
|
695 |
+
<h2><i class="fas fa-bolt"></i> Redox Reaction Calculator</h2>
|
696 |
+
<p>Balance redox reactions and calculate electrochemical properties.</p>
|
697 |
+
|
698 |
+
<div class="calculator-form">
|
699 |
+
<div class="form-group">
|
700 |
+
<label>Calculation Type</label>
|
701 |
+
<select id="redox-type" class="form-control">
|
702 |
+
<option value="balance-redox">Balance Redox Reaction</option>
|
703 |
+
<option value="cell-potential">Cell Potential</option>
|
704 |
+
<option value="nernst">Nernst Equation</option>
|
705 |
+
</select>
|
706 |
+
</div>
|
707 |
+
|
708 |
+
<div id="redox-reaction-inputs">
|
709 |
+
<div class="form-group">
|
710 |
+
<label>Redox Reaction (Half-Reactions)</label>
|
711 |
+
<div class="reaction-controls">
|
712 |
+
<input type="text" id="redox-reactant1" placeholder="Oxidation (e.g. Fe → Fe²⁺)">
|
713 |
+
<div class="reaction-arrow">+</div>
|
714 |
+
<input type="text" id="redox-reactant2" placeholder="Reduction (e.g. O2 + 4e⁻ → 2O²⁻)">
|
715 |
+
</div>
|
716 |
+
</div>
|
717 |
+
</div>
|
718 |
+
|
719 |
+
<div id="redox-advanced" class="advanced-options" style="display: none;">
|
720 |
+
<div class="form-group">
|
721 |
+
<label for="redox-medium">Medium</label>
|
722 |
+
<select id="redox-medium">
|
723 |
+
<option value="acidic">Acidic</option>
|
724 |
+
<option value="basic">Basic</option>
|
725 |
+
<option value="neutral">Neutral</option>
|
726 |
+
</select>
|
727 |
+
</div>
|
728 |
+
|
729 |
+
<div class="form-group">
|
730 |
+
<label for="redox-temp">Temperature (°C)</label>
|
731 |
+
<input type="number" id="redox-temp" value="25">
|
732 |
+
</div>
|
733 |
+
</div>
|
734 |
+
|
735 |
+
<button type="button" class="toggle-advanced" id="toggle-redox-advanced">
|
736 |
+
<i class="fas fa-chevron-down"></i> Advanced Options
|
737 |
+
</button>
|
738 |
+
|
739 |
+
<button id="calculate-redox" class="btn btn-calculate">Balance Reaction</button>
|
740 |
+
|
741 |
+
<div id="redox-result" class="result-container">
|
742 |
+
<div class="result-title">Results</div>
|
743 |
+
<div id="redox-value" class="result-value"></div>
|
744 |
+
<div id="redox-details" style="margin-top: 15px;"></div>
|
745 |
+
</div>
|
746 |
+
</div>
|
747 |
+
</div>
|
748 |
+
|
749 |
+
<div class="history-container">
|
750 |
+
<h3>Calculation History</h3>
|
751 |
+
<div id="history-list"></div>
|
752 |
+
</div>
|
753 |
+
|
754 |
+
<footer>
|
755 |
+
<p>ChemCalc Pro © 2023 | Advanced Chemical Calculator for Professionals</p>
|
756 |
+
<p>Disclaimer: Results should be verified with experimental data.</p>
|
757 |
+
</footer>
|
758 |
+
</div>
|
759 |
+
|
760 |
+
<script>
|
761 |
+
document.addEventListener('DOMContentLoaded', function() {
|
762 |
+
// Tab functionality
|
763 |
+
const tabButtons = document.querySelectorAll('.tab-button');
|
764 |
+
const tabContents = document.querySelectorAll('.tab-content');
|
765 |
+
|
766 |
+
tabButtons.forEach(button => {
|
767 |
+
button.addEventListener('click', () => {
|
768 |
+
const tabId = button.getAttribute('data-tab');
|
769 |
+
|
770 |
+
// Update active tab button
|
771 |
+
tabButtons.forEach(btn => btn.classList.remove('active'));
|
772 |
+
button.classList.add('active');
|
773 |
+
|
774 |
+
// Show corresponding content
|
775 |
+
tabContents.forEach(content => {
|
776 |
+
content.classList.remove('active');
|
777 |
+
if(content.id === tabId) {
|
778 |
+
content.classList.add('active');
|
779 |
+
}
|
780 |
+
});
|
781 |
+
});
|
782 |
+
});
|
783 |
+
|
784 |
+
// Advanced options toggle
|
785 |
+
const toggleConcAdvanced = document.getElementById('toggle-conc-advanced');
|
786 |
+
const concAdvanced = document.getElementById('conc-advanced');
|
787 |
+
|
788 |
+
toggleConcAdvanced.addEventListener('click', () => {
|
789 |
+
concAdvanced.style.display = concAdvanced.style.display === 'none' ? 'block' : 'none';
|
790 |
+
toggleConcAdvanced.classList.toggle('collapsed');
|
791 |
+
});
|
792 |
+
|
793 |
+
const toggleRedoxAdvanced = document.getElementById('toggle-redox-advanced');
|
794 |
+
const redoxAdvanced = document.getElementById('redox-advanced');
|
795 |
+
|
796 |
+
toggleRedoxAdvanced.addEventListener('click', () => {
|
797 |
+
redoxAdvanced.style.display = redoxAdvanced.style.display === 'none' ? 'block' : 'none';
|
798 |
+
toggleRedoxAdvanced.classList.toggle('collapsed');
|
799 |
+
});
|
800 |
+
|
801 |
+
// Periodic table elements
|
802 |
+
const periodicElements = document.getElementById('periodic-elements');
|
803 |
+
const compoundFormula = document.getElementById('compound-formula');
|
804 |
+
|
805 |
+
const elements = [
|
806 |
+
{ symbol: 'H', name: 'Hydrogen', number: 1, group: 'nonmetal' },
|
807 |
+
{ symbol: 'He', name: 'Helium', number: 2, group: 'noble' },
|
808 |
+
{ symbol: 'Li', name: 'Lithium', number: 3, group: 'alkali' },
|
809 |
+
{ symbol: 'Be', name: 'Beryllium', number: 4, group: 'alkaline' },
|
810 |
+
{ symbol: 'B', name: 'Boron', number: 5, group: 'metalloid' },
|
811 |
+
{ symbol: 'C', name: 'Carbon', number: 6, group: 'nonmetal' },
|
812 |
+
{ symbol: 'N', name: 'Nitrogen', number: 7, group: 'nonmetal' },
|
813 |
+
{ symbol: 'O', name: 'Oxygen', number: 8, group: 'nonmetal' },
|
814 |
+
{ symbol: 'F', name: 'Fluorine', number: 9, group: 'halogen' },
|
815 |
+
{ symbol: 'Ne', name: 'Neon', number: 10, group: 'noble' },
|
816 |
+
{ symbol: 'Na', name: 'Sodium', number: 11, group: 'alkali' },
|
817 |
+
{ symbol: 'Mg', name: 'Magnesium', number: 12, group: 'alkaline' },
|
818 |
+
{ symbol: 'Al', name: 'Aluminum', number: 13, group: 'post-transition' },
|
819 |
+
{ symbol: 'Si', name: 'Silicon', number: 14, group: 'metalloid' },
|
820 |
+
{ symbol: 'P', name: 'Phosphorus', number: 15, group: 'nonmetal' },
|
821 |
+
{ symbol: 'S', name: 'Sulfur', number: 16, group: 'nonmetal' },
|
822 |
+
{ symbol: 'Cl', name: 'Chlorine', number: 17, group: 'halogen' },
|
823 |
+
{ symbol: 'Ar', name: 'Argon', number: 18, group: 'noble' },
|
824 |
+
{ symbol: 'K', name: 'Potassium', number: 19, group: 'alkali' },
|
825 |
+
{ symbol: 'Ca', name: 'Calcium', number: 20, group: 'alkaline' },
|
826 |
+
{ symbol: 'Sc', name: 'Scandium', number: 21, group: 'transition' },
|
827 |
+
{ symbol: 'Ti', name: 'Titanium', number: 22, group: 'transition' },
|
828 |
+
{ symbol: 'V', name: 'Vanadium', number: 23, group: 'transition' },
|
829 |
+
{ symbol: 'Cr', name: 'Chromium', number: 24, group: 'transition' },
|
830 |
+
{ symbol: 'Mn', name: 'Manganese', number: 25, group: 'transition' },
|
831 |
+
{ symbol: 'Fe', name: 'Iron', number: 26, group: 'transition' },
|
832 |
+
{ symbol: 'Co', name: 'Cobalt', number: 27, group: 'transition' },
|
833 |
+
{ symbol: 'Ni', name: 'Nickel', number: 28, group: 'transition' },
|
834 |
+
{ symbol: 'Cu', name: 'Copper', number: 29, group: 'transition' },
|
835 |
+
{ symbol: 'Zn', name: 'Zinc', number: 30, group: 'transition' },
|
836 |
+
{ symbol: 'Ga', name: 'Gallium', number: 31, group: 'post-transition' },
|
837 |
+
{ symbol: 'Ge', name: 'Germanium', number: 32, group: 'metalloid' },
|
838 |
+
{ symbol: 'As', name: 'Arsenic', number: 33, group: 'metalloid' },
|
839 |
+
{ symbol: 'Se', name: 'Selenium', number: 34, group: 'nonmetal' },
|
840 |
+
{ symbol: 'Br', name: 'Bromine', number: 35, group: 'halogen' },
|
841 |
+
{ symbol: 'Kr', name: 'Krypton', number: 36, group: 'noble' },
|
842 |
+
{ symbol: 'Rb', name: 'Rubidium', number: 37, group: 'alkali' },
|
843 |
+
{ symbol: 'Sr', name: 'Strontium', number: 38, group: 'alkaline' },
|
844 |
+
{ symbol: 'Y', name: 'Yttrium', number: 39, group: 'transition' },
|
845 |
+
{ symbol: 'Zr', name: 'Zirconium', number: 40, group: 'transition' },
|
846 |
+
{ symbol: 'Nb', name: 'Niobium', number: 41, group: 'transition' },
|
847 |
+
{ symbol: 'Mo', name: 'Molybdenum', number: 42, group: 'transition' },
|
848 |
+
{ symbol: 'Tc', name: 'Technetium', number: 43, group: 'transition' },
|
849 |
+
{ symbol: 'Ru', name: 'Ruthenium', number: 44, group: 'transition' },
|
850 |
+
{ symbol: 'Rh', name: 'Rhodium', number: 45, group: 'transition' },
|
851 |
+
{ symbol: 'Pd', name: 'Palladium', number: 46, group: 'transition' },
|
852 |
+
{ symbol: 'Ag', name: 'Silver', number: 47, group: 'transition' },
|
853 |
+
{ symbol: 'Cd', name: 'Cadmium', number: 48, group: 'transition' },
|
854 |
+
{ symbol: 'In', name: 'Indium', number: 49, group: 'post-transition' },
|
855 |
+
{ symbol: 'Sn', name: 'Tin', number: 50, group: 'post-transition' },
|
856 |
+
{ symbol: 'Sb', name: 'Antimony', number: 51, group: 'metalloid' },
|
857 |
+
{ symbol: 'Te', name: 'Tellurium', number: 52, group: 'metalloid' },
|
858 |
+
{ symbol: 'I', name: 'Iodine', number: 53, group: 'halogen' },
|
859 |
+
{ symbol: 'Xe', name: 'Xenon', number: 54, group: 'noble' },
|
860 |
+
{ symbol: 'Cs', name: 'Cesium', number: 55, group: 'alkali' },
|
861 |
+
{ symbol: 'Ba', name: 'Barium', number: 56, group: 'alkaline' },
|
862 |
+
{ symbol: 'La', name: 'Lanthanum', number: 57, group: 'lanthanide' },
|
863 |
+
{ symbol: 'Ce', name: 'Cerium', number: 58, group: 'lanthanide' },
|
864 |
+
{ symbol: 'Pr', name: 'Praseodymium', number: 59, group: 'lanthanide' },
|
865 |
+
{ symbol: 'Nd', name: 'Neodymium', number: 60, group: 'lanthanide' },
|
866 |
+
{ symbol: 'Pm', name: 'Promethium', number: 61, group: 'lanthanide' },
|
867 |
+
{ symbol: 'Sm', name: 'Samarium', number: 62, group: 'lanthanide' },
|
868 |
+
{ symbol: 'Eu', name: 'Europium', number: 63, group: 'lanthanide' },
|
869 |
+
{ symbol: 'Gd', name: 'Gadolinium', number: 64, group: 'lanthanide' },
|
870 |
+
{ symbol: 'Tb', name: 'Terbium', number: 65, group: 'lanthanide' },
|
871 |
+
{ symbol: 'Dy', name: 'Dysprosium', number: 66, group: 'lanthanide' },
|
872 |
+
{ symbol: 'Ho', name: 'Holmium', number: 67, group: 'lanthanide' },
|
873 |
+
{ symbol: 'Er', name: 'Erbium', number: 68, group: 'lanthanide' },
|
874 |
+
{ symbol: 'Tm', name: 'Thulium', number: 69, group: 'lanthanide' },
|
875 |
+
{ symbol: 'Yb', name: 'Ytterbium', number: 70, group: 'lanthanide' },
|
876 |
+
{ symbol: 'Lu', name: 'Lutetium', number: 71, group: 'lanthanide' },
|
877 |
+
{ symbol: 'Hf', name: 'Hafnium', number: 72, group: 'transition' },
|
878 |
+
{ symbol: 'Ta', name: 'Tantalum', number: 73, group: 'transition' },
|
879 |
+
{ symbol: 'W', name: 'Tungsten', number: 74, group: 'transition' },
|
880 |
+
{ symbol: 'Re', name: 'Rhenium', number: 75, group: 'transition' },
|
881 |
+
{ symbol: 'Os', name: 'Osmium', number: 76, group: 'transition' },
|
882 |
+
{ symbol: 'Ir', name: 'Iridium', number: 77, group: 'transition' },
|
883 |
+
{ symbol: 'Pt', name: 'Platinum', number: 78, group: 'transition' },
|
884 |
+
{ symbol: 'Au', name: 'Gold', number: 79, group: 'transition' },
|
885 |
+
{ symbol: 'Hg', name: 'Mercury', number: 80, group: 'transition' },
|
886 |
+
{ symbol: 'Tl', name: 'Thallium', number: 81, group: 'post-transition' },
|
887 |
+
{ symbol: 'Pb', name: 'Lead', number: 82, group: 'post-transition' },
|
888 |
+
{ symbol: 'Bi', name: 'Bismuth', number: 83, group: 'post-transition' },
|
889 |
+
{ symbol: 'Po', name: 'Polonium', number: 84, group: 'metalloid' },
|
890 |
+
{ symbol: 'At', name: 'Astatine', number: 85, group: 'halogen' },
|
891 |
+
{ symbol: 'Rn', name: 'Radon', number: 86, group: 'noble' },
|
892 |
+
{ symbol: 'Fr', name: 'Francium', number: 87, group: 'alkali' },
|
893 |
+
{ symbol: 'Ra', name: 'Radium', number: 88, group: 'alkaline' },
|
894 |
+
{ symbol: 'Ac', name: 'Actinium', number: 89, group: 'actinide' },
|
895 |
+
{ symbol: 'Th', name: 'Thorium', number: 90, group: 'actinide' },
|
896 |
+
{ symbol: 'Pa', name: 'Protactinium', number: 91, group: 'actinide' },
|
897 |
+
{ symbol: 'U', name: 'Uranium', number: 92, group: 'actinide' },
|
898 |
+
{ symbol: 'Np', name: 'Neptunium', number: 93, group: 'actinide' },
|
899 |
+
{ symbol: 'Pu', name: 'Plutonium', number: 94, group: 'actinide' },
|
900 |
+
// ... more elements if needed
|
901 |
+
];
|
902 |
+
|
903 |
+
// Create periodic table
|
904 |
+
elements.forEach(element => {
|
905 |
+
const elementDiv = document.createElement('div');
|
906 |
+
elementDiv.className = `element ${element.group}`;
|
907 |
+
elementDiv.innerHTML = `
|
908 |
+
<div class="element-symbol">${element.symbol}</div>
|
909 |
+
<div class="element-number">${element.number}</div>
|
910 |
+
`;
|
911 |
+
elementDiv.title = element.name;
|
912 |
+
|
913 |
+
elementDiv.addEventListener('click', () => {
|
914 |
+
if (compoundFormula) {
|
915 |
+
compoundFormula.value += element.symbol;
|
916 |
+
compoundFormula.focus();
|
917 |
+
}
|
918 |
+
});
|
919 |
+
|
920 |
+
periodicElements.appendChild(elementDiv);
|
921 |
+
});
|
922 |
+
|
923 |
+
// Molar mass calculation
|
924 |
+
const molarMasses = {
|
925 |
+
'H': 1.008, 'He': 4.0026, 'Li': 6.94, 'Be': 9.0122, 'B': 10.81,
|
926 |
+
'C': 12.011, 'N': 14.007, 'O': 15.999, 'F': 18.998, 'Ne': 20.180,
|
927 |
+
'Na': 22.990, 'Mg': 24.305, 'Al': 26.982, 'Si': 28.085, 'P': 30.974,
|
928 |
+
'S': 32.06, 'Cl': 35.45, 'Ar': 39.948, 'K': 39.098, 'Ca': 40.078,
|
929 |
+
'Sc': 44.956, 'Ti': 47.867, 'V': 50.942, 'Cr': 51.996, 'Mn': 54.938,
|
930 |
+
'Fe': 55.845, 'Co': 58.933, 'Ni': 58.693, 'Cu': 63.546, 'Zn': 65.38,
|
931 |
+
'Ga': 69.723, 'Ge': 72.630, 'As': 74.922, 'Se': 78.971, 'Br': 79.904,
|
932 |
+
'Kr': 83.798, 'Rb': 85.468, 'Sr': 87.62, 'Y': 88.906, 'Zr': 91.224,
|
933 |
+
'Nb': 92.906, 'Mo': 95.95, 'Tc': 98, 'Ru': 101.07, 'Rh': 102.91,
|
934 |
+
'Pd': 106.42, 'Ag': 107.87, 'Cd': 112.41, 'In': 114.82, 'Sn': 118.71,
|
935 |
+
'Sb': 121.76, 'Te': 127.60, 'I': 126.90, 'Xe': 131.29, 'Cs': 132.91,
|
936 |
+
'Ba': 137.33, 'La': 138.91, 'Ce': 140.12, 'Pr': 140.91, 'Nd': 144.24,
|
937 |
+
'Pm': 145, 'Sm': 150.36, 'Eu': 151.96, 'Gd': 157.25, 'Tb': 158.93,
|
938 |
+
'Dy': 162.50, 'Ho': 164.93, 'Er': 167.26, 'Tm': 168.93, 'Yb': 173.05,
|
939 |
+
'Lu': 174.97, 'Hf': 178.49, 'Ta': 180.95, 'W': 183.84, 'Re': 186.21,
|
940 |
+
'Os': 190.23, 'Ir': 192.22, 'Pt': 195.08, 'Au': 196.97, 'Hg': 200.59,
|
941 |
+
'Tl': 204.38, 'Pb': 207.2, 'Bi': 208.98, 'Po': 209, 'At': 210, 'Rn': 222,
|
942 |
+
'Fr': 223, 'Ra': 226, 'Ac': 227, 'Th': 232.04, 'Pa': 231.04, 'U': 238.03,
|
943 |
+
'Np': 237, 'Pu': 244
|
944 |
+
};
|
945 |
+
|
946 |
+
document.getElementById('calculate-mass').addEventListener('click', calculateMolarMass);
|
947 |
+
|
948 |
+
function calculateMolarMass() {
|
949 |
+
const formula = document.getElementById('compound-formula').value.trim();
|
950 |
+
const massStr = document.getElementById('compound-mass').value;
|
951 |
+
const massUnit = document.getElementById('mass-unit').value;
|
952 |
+
|
953 |
+
if (!formula) {
|
954 |
+
alert('Please enter a chemical formula');
|
955 |
+
return;
|
956 |
+
}
|
957 |
+
|
958 |
+
try {
|
959 |
+
// Parse the chemical formula
|
960 |
+
const parsedFormula = parseFormula(formula);
|
961 |
+
let totalMass = 0;
|
962 |
+
let compositionHTML = '<div>Elemental Composition:</div><ul>';
|
963 |
+
|
964 |
+
// Calculate molar mass
|
965 |
+
for (const element in parsedFormula) {
|
966 |
+
const count = parsedFormula[element];
|
967 |
+
const elementMass = molarMasses[element] || 0;
|
968 |
+
totalMass += elementMass * count;
|
969 |
+
|
970 |
+
// Add to composition list
|
971 |
+
const elementObj = elements.find(e => e.symbol === element);
|
972 |
+
const percent = ((elementMass * count) / totalMass * 100).toFixed(2);
|
973 |
+
compositionHTML += `<li>${element} (${elementObj?.name || 'Unknown'}): ${count} atom${count > 1 ? 's' : ''} (${percent}%)</li>`;
|
974 |
+
}
|
975 |
+
|
976 |
+
compositionHTML += '</ul>';
|
977 |
+
|
978 |
+
// Display results
|
979 |
+
const resultDiv = document.getElementById('mass-result');
|
980 |
+
document.getElementById('mass-value').textContent = `Molar Mass: ${totalMass.toFixed(4)} g/mol`;
|
981 |
+
|
982 |
+
// Calculate moles if mass was provided
|
983 |
+
if (massStr) {
|
984 |
+
const mass = parseFloat(massStr);
|
985 |
+
let convertedMass = mass;
|
986 |
+
|
987 |
+
// Convert units if needed
|
988 |
+
switch(massUnit) {
|
989 |
+
case 'mg': convertedMass = mass / 1000; break;
|
990 |
+
case 'kg': convertedMass = mass * 1000; break;
|
991 |
+
}
|
992 |
+
|
993 |
+
const moles = convertedMass / totalMass;
|
994 |
+
document.getElementById('moles-value').textContent = `Moles: ${moles.toFixed(6)} mol`;
|
995 |
+
} else {
|
996 |
+
document.getElementById('moles-value').textContent = '';
|
997 |
+
}
|
998 |
+
|
999 |
+
document.getElementById('composition').innerHTML = compositionHTML;
|
1000 |
+
resultDiv.classList.add('show');
|
1001 |
+
|
1002 |
+
// Add to history
|
1003 |
+
addToHistory(`Calculated molar mass for ${formula}: ${totalMass.toFixed(4)} g/mol`);
|
1004 |
+
} catch (error) {
|
1005 |
+
alert('Error parsing formula: ' + error.message);
|
1006 |
+
}
|
1007 |
+
}
|
1008 |
+
|
1009 |
+
// Helper function to parse chemical formulas
|
1010 |
+
function parseFormula(formula) {
|
1011 |
+
const elements = {};
|
1012 |
+
let currentElement = '';
|
1013 |
+
let currentCount = 0;
|
1014 |
+
let i = 0;
|
1015 |
+
|
1016 |
+
while (i < formula.length) {
|
1017 |
+
const c = formula[i];
|
1018 |
+
|
1019 |
+
// Check for uppercase letter (new element)
|
1020 |
+
if (c === c.toUpperCase() && c !== c.toLowerCase()) {
|
1021 |
+
// If we have a current element, add it to the result
|
1022 |
+
if (currentElement) {
|
1023 |
+
elements[currentElement] = (elements[currentElement] || 0) + (currentCount || 1);
|
1024 |
+
}
|
1025 |
+
|
1026 |
+
// Start new element
|
1027 |
+
currentElement = c;
|
1028 |
+
i++;
|
1029 |
+
|
1030 |
+
// Check for lowercase letters (element symbol with 2 letters)
|
1031 |
+
while (i < formula.length && formula[i] === formula[i].toLowerCase() && formula[i] !== formula[i].toUpperCase()) {
|
1032 |
+
currentElement += formula[i];
|
1033 |
+
i++;
|
1034 |
+
}
|
1035 |
+
|
1036 |
+
currentCount = 0;
|
1037 |
+
}
|
1038 |
+
// Check for digits (count of atoms)
|
1039 |
+
else if (c >= '0' && c <= '9') {
|
1040 |
+
currentCount = currentCount * 10 + parseInt(c);
|
1041 |
+
i++;
|
1042 |
+
}
|
1043 |
+
// Check for parentheses (grouping)
|
1044 |
+
else if (c === '(') {
|
1045 |
+
// If we have a current element, add it to the result
|
1046 |
+
if (currentElement) {
|
1047 |
+
elements[currentElement] = (elements[currentElement] || 0) + (currentCount || 1);
|
1048 |
+
}
|
1049 |
+
|
1050 |
+
// Parse the group inside parentheses
|
1051 |
+
const groupEnd = findMatchingClosingParenthesis(formula, i);
|
1052 |
+
const groupContent = formula.substring(i + 1, groupEnd);
|
1053 |
+
const parsedGroup = parseFormula(groupContent);
|
1054 |
+
|
1055 |
+
// Parse the count after the group
|
1056 |
+
let groupCount = 0;
|
1057 |
+
let j = groupEnd + 1;
|
1058 |
+
while (j < formula.length && formula[j] >= '0' && formula[j] <= '9') {
|
1059 |
+
groupCount = groupCount * 10 + parseInt(formula[j]);
|
1060 |
+
j++;
|
1061 |
+
}
|
1062 |
+
|
1063 |
+
groupCount = groupCount || 1;
|
1064 |
+
|
1065 |
+
// Add all elements from the group to the result
|
1066 |
+
for (const element in parsedGroup) {
|
1067 |
+
elements[element] = (elements[element] || 0) + parsedGroup[element] * groupCount;
|
1068 |
+
}
|
1069 |
+
|
1070 |
+
i = j;
|
1071 |
+
currentElement = '';
|
1072 |
+
currentCount = 0;
|
1073 |
+
}
|
1074 |
+
else {
|
1075 |
+
throw new Error(`Invalid character in formula: ${c}`);
|
1076 |
+
}
|
1077 |
+
}
|
1078 |
+
|
1079 |
+
// Add the last element if it exists
|
1080 |
+
if (currentElement) {
|
1081 |
+
elements[currentElement] = (elements[currentElement] || 0) + (currentCount || 1);
|
1082 |
+
}
|
1083 |
+
|
1084 |
+
return elements;
|
1085 |
+
}
|
1086 |
+
|
1087 |
+
function findMatchingClosingParenthesis(str, pos) {
|
1088 |
+
let depth = 1;
|
1089 |
+
for (let i = pos + 1; i < str.length; i++) {
|
1090 |
+
if (str[i] === '(') depth++;
|
1091 |
+
else if (str[i] === ')') depth--;
|
1092 |
+
|
1093 |
+
if (depth === 0) return i;
|
1094 |
+
}
|
1095 |
+
throw new Error('No matching closing parenthesis found');
|
1096 |
+
}
|
1097 |
+
|
1098 |
+
// Concentration calculator
|
1099 |
+
const concTypeSelect = document.getElementById('concentration-type');
|
1100 |
+
concTypeSelect.addEventListener('change', updateConcInputs);
|
1101 |
+
|
1102 |
+
function updateConcInputs() {
|
1103 |
+
const type = concTypeSelect.value;
|
1104 |
+
const concInputs = document.getElementById('conc-inputs');
|
1105 |
+
const dilutionInputs = document.getElementById('dilution-inputs');
|
1106 |
+
|
1107 |
+
if (type === 'dilution') {
|
1108 |
+
concInputs.style.display = 'none';
|
1109 |
+
dilutionInputs.style.display = 'block';
|
1110 |
+
} else {
|
1111 |
+
concInputs.style.display = 'block';
|
1112 |
+
dilutionInputs.style.display = 'none';
|
1113 |
+
}
|
1114 |
+
}
|
1115 |
+
|
1116 |
+
document.getElementById('calculate-conc').addEventListener('click', calculateConcentration);
|
1117 |
+
|
1118 |
+
function calculateConcentration() {
|
1119 |
+
const type = concTypeSelect.value;
|
1120 |
+
const resultDiv = document.getElementById('conc-result');
|
1121 |
+
|
1122 |
+
try {
|
1123 |
+
if (type === 'dilution') {
|
1124 |
+
const initialConc = parseFloat(document.getElementById('initial-conc').value);
|
1125 |
+
const initialConcUnit = document.getElementById('initial-conc-unit').value;
|
1126 |
+
const initialVol = parseFloat(document.getElementById('initial-vol').value);
|
1127 |
+
const initialVolUnit = document.getElementById('initial-vol-unit').value;
|
1128 |
+
|
1129 |
+
if (!initialConc || !initialVol) {
|
1130 |
+
alert('Please enter both initial concentration and volume');
|
1131 |
+
return;
|
1132 |
+
}
|
1133 |
+
|
1134 |
+
// Convert units if needed
|
1135 |
+
let conc = initialConc;
|
1136 |
+
if (initialConcUnit === 'mM') conc = conc / 1000;
|
1137 |
+
|
1138 |
+
let vol = initialVol;
|
1139 |
+
if (initialVolUnit === 'mL') vol = vol / 1000;
|
1140 |
+
|
1141 |
+
// Calculate dilution (M1V1 = M2V2) assuming final volume is known
|
1142 |
+
// For simplicity, we'll calculate final concentration based on assuming final volume is known from dilution
|
1143 |
+
// In a real app, you'd want more detailed inputs
|
1144 |
+
const finalConc = (conc * vol) / (vol + vol); // Assuming doubling volume
|
1145 |
+
|
1146 |
+
document.getElementById('conc-value').innerHTML = `
|
1147 |
+
<div>Initial Concentration: ${initialConc} ${initialConcUnit}</div>
|
1148 |
+
<div>Final Concentration: ${finalConc.toFixed(6)} M</div
|
1149 |
+
</html>
|