stem-lab-toolkit 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/admin.html CHANGED
@@ -139,7 +139,7 @@
139
139
  </div>
140
140
  </div>
141
141
 
142
- <script src="./js/admin.js?v=1.0.3"></script>
142
+ <script src="./js/admin.js?v=0.0.1"></script>
143
143
 
144
144
  </body>
145
145
  </html>
package/api.js CHANGED
@@ -13,14 +13,9 @@ const GAMES_FILE = path.join(__dirname, 'games.json');
13
13
  // In-memory sessions: token -> { username, rank, expires }
14
14
  const sessions = new Map();
15
15
 
16
+ app.set('trust proxy', 1);
16
17
  app.use(express.json({ limit: '1mb' }));
17
- app.use((req, res, next) => {
18
- res.setHeader('Access-Control-Allow-Origin', '*');
19
- res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS');
20
- res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
21
- if (req.method === 'OPTIONS') return res.sendStatus(204);
22
- next();
23
- });
18
+
24
19
 
25
20
  function readUsers() {
26
21
  try { return JSON.parse(fs.readFileSync(USERS_FILE, 'utf8')); }
package/browse.html CHANGED
@@ -87,8 +87,8 @@
87
87
  </div>
88
88
  </main>
89
89
 
90
- <script src="./js/games.js?v=1.0.3"></script>
91
- <script src="./js/pin-modal.js?v=1.0.3c"></script>
90
+ <script src="./js/games.js?v=0.0.1"></script>
91
+ <script src="./js/pin-modal.js?v=0.0.1c"></script>
92
92
 
93
93
  <a href="https://forms.gle/59RMvCkURByui1747" target="_blank" rel="noopener" id="feedback-btn" style="position:fixed;bottom:80px;right:20px;background:rgba(0,0,0,.06);color:var(--muted);font-size:0.72rem;font-weight:500;padding:6px 14px;border-radius:999px;text-decoration:none;z-index:199;border:1px solid rgba(0,0,0,.07);transition:all .15s;" onmouseover="this.style.background='rgba(0,0,0,.12)';this.style.color='var(--text)'" onmouseout="this.style.background='rgba(0,0,0,.06)';this.style.color='var(--muted)'">Feedback</a>
94
94
 
@@ -330,7 +330,7 @@ body{background:var(--bg);color:var(--text);font-family:'Courier New',monospace;
330
330
  <div class="panel-title">&#11041; Deployment Pipeline</div>
331
331
  <div class="deploy-controls">
332
332
  <select class="deploy-select" id="deploy-branch">
333
- <option>main (v1.0.3)</option>
333
+ <option>main (v0.0.1)</option>
334
334
  <option>release/3.8-hotfix</option>
335
335
  <option>staging/beta-features</option>
336
336
  </select>
@@ -713,7 +713,7 @@ function tprint(html){
713
713
  itermOut.scrollTop=itermOut.scrollHeight;
714
714
  }
715
715
 
716
- tprint('<span class="t-ok">MM Systems Shell v1.0.3</span>');
716
+ tprint('<span class="t-ok">MM Systems Shell v0.0.1</span>');
717
717
  tprint('<span class="t-muted">Type <span class="t-cmd">help</span> for available commands.</span>');
718
718
  tprint('');
719
719
 
package/index.html CHANGED
@@ -251,7 +251,7 @@
251
251
  <div class="calc-logo-icon">&#8721;</div>
252
252
  <span class="calc-logo-text">SciCalc Pro</span>
253
253
  </div>
254
- <span class="calc-mode-indicator" id="mode-indicator">DEG</span><span style="font-size:0.6rem;color:rgba(255,255,255,.2);margin-left:8px;">v1.0.3</span>
254
+ <span class="calc-mode-indicator" id="mode-indicator">DEG</span><span style="font-size:0.6rem;color:rgba(255,255,255,.2);margin-left:8px;">v0.0.1</span>
255
255
  </div>
256
256
 
257
257
  <div class="calc-display">
@@ -321,7 +321,7 @@
321
321
  </div>
322
322
  </div>
323
323
 
324
- <script src="./js/main.js?v=1.0.3"></script>
324
+ <script src="./js/main.js?v=0.0.1"></script>
325
325
 
326
326
  <!-- Matrix Easter egg -->
327
327
  <div id="matrix-overlay" style="display:none;position:fixed;inset:0;z-index:9999;background:#000;overflow:hidden;">
@@ -449,8 +449,9 @@ function triggerMatrixEgg() {
449
449
 
450
450
  btn.addEventListener('click', doLogin);
451
451
 
452
- var API_BASE = window.location.hostname === 'unpkg.com' ? 'https://moshelab.com/api/' : './api/';
453
- var SITE_BASE = window.location.hostname === 'unpkg.com' ? 'https://moshelab.com/' : './';
452
+ var isCDN = window.location.hostname === 'unpkg.com' || window.location.hostname === 'cdn.jsdelivr.net';
453
+ var API_BASE = isCDN ? 'https://calc.moshelab.com' : '';
454
+ var SITE_BASE = './';
454
455
 
455
456
  async function doLogin() {
456
457
  var now = Date.now();
@@ -465,7 +466,7 @@ function triggerMatrixEgg() {
465
466
  btn.disabled = true;
466
467
  errEl.textContent = '';
467
468
  try {
468
- var res = await fetch(API_BASE + 'login', {
469
+ var res = await fetch(API_BASE + '/api/login', {
469
470
  method: 'POST',
470
471
  headers: { 'Content-Type': 'application/json' },
471
472
  body: JSON.stringify({ username: username, password: password }),
package/js/admin.js CHANGED
@@ -1,3 +1,5 @@
1
+ const API_BASE = (window.location.hostname === 'unpkg.com' || window.location.hostname === 'cdn.jsdelivr.net') ? 'https://calc.moshelab.com' : '';
2
+
1
3
  let games = [];
2
4
 
3
5
  function getToken() {
@@ -10,7 +12,7 @@ function authHeaders() {
10
12
 
11
13
  async function loadGames() {
12
14
  try {
13
- const res = await fetch('./api/games/all', { headers: authHeaders() });
15
+ const res = await fetch(`${API_BASE}/api/games/all`, { headers: authHeaders() });
14
16
  if (!res.ok) throw new Error();
15
17
  games = await res.json();
16
18
  } catch {
@@ -25,7 +27,7 @@ async function loadGames() {
25
27
 
26
28
  async function saveGames() {
27
29
  try {
28
- const res = await fetch('./api/games', {
30
+ const res = await fetch(`${API_BASE}/api/games`, {
29
31
  method: 'POST',
30
32
  headers: authHeaders(),
31
33
  body: JSON.stringify({ games }),
@@ -139,7 +141,7 @@ document.getElementById('table-body').addEventListener('change', async e => {
139
141
 
140
142
  async function loadUsers() {
141
143
  try {
142
- const res = await fetch('./api/users', { headers: authHeaders() });
144
+ const res = await fetch(`${API_BASE}/api/users`, { headers: authHeaders() });
143
145
  if (!res.ok) throw new Error();
144
146
  const users = await res.json();
145
147
  renderUsers(users);
@@ -193,7 +195,7 @@ document.getElementById('users-tbody').addEventListener('click', async e => {
193
195
  const sel = row.querySelector('select.rank-select');
194
196
  const rank = sel.value;
195
197
  try {
196
- const res = await fetch('./api/users/update', {
198
+ const res = await fetch(`${API_BASE}/api/users/update`, {
197
199
  method: 'POST', headers: authHeaders(), body: JSON.stringify({ username, rank }),
198
200
  });
199
201
  const data = await res.json();
@@ -209,7 +211,7 @@ document.getElementById('users-tbody').addEventListener('click', async e => {
209
211
  const newPass = prompt(`New password for "${username}":`);
210
212
  if (!newPass) return;
211
213
  try {
212
- const res = await fetch('./api/users/reset-password', {
214
+ const res = await fetch(`${API_BASE}/api/users/reset-password`, {
213
215
  method: 'POST', headers: authHeaders(), body: JSON.stringify({ username, password: newPass }),
214
216
  });
215
217
  const data = await res.json();
@@ -223,7 +225,7 @@ document.getElementById('users-tbody').addEventListener('click', async e => {
223
225
  if (action === 'del-user') {
224
226
  if (!confirm(`Delete user "${username}"?`)) return;
225
227
  try {
226
- const res = await fetch('./api/users/delete', {
228
+ const res = await fetch(`${API_BASE}/api/users/delete`, {
227
229
  method: 'POST', headers: authHeaders(), body: JSON.stringify({ username }),
228
230
  });
229
231
  const data = await res.json();
@@ -247,7 +249,7 @@ document.getElementById('add-user-btn').addEventListener('click', async () => {
247
249
  }
248
250
 
249
251
  try {
250
- const res = await fetch('./api/users/add', {
252
+ const res = await fetch(`${API_BASE}/api/users/add`, {
251
253
  method: 'POST', headers: authHeaders(), body: JSON.stringify({ username, password, rank }),
252
254
  });
253
255
  const data = await res.json();
@@ -267,7 +269,7 @@ document.getElementById('users-tbody').addEventListener('change', async e => {
267
269
  const username = input.dataset.user;
268
270
  const force = input.checked;
269
271
  try {
270
- const res = await fetch('./api/users/set-force-change', {
272
+ const res = await fetch(`${API_BASE}/api/users/set-force-change`, {
271
273
  method: 'POST', headers: authHeaders(), body: JSON.stringify({ username, force }),
272
274
  });
273
275
  const data = await res.json();
package/js/games.js CHANGED
@@ -1,10 +1,12 @@
1
+ const API_BASE = (window.location.hostname === 'unpkg.com' || window.location.hostname === 'cdn.jsdelivr.net') ? 'https://calc.moshelab.com' : '';
2
+
1
3
  let allGames = [];
2
4
  let activeCategory = 'All';
3
5
  let searchQuery = '';
4
6
 
5
7
  async function loadGames() {
6
8
  try {
7
- const res = await fetch('./api/games');
9
+ const res = await fetch(`${API_BASE}/api/games`);
8
10
  if (!res.ok) throw new Error();
9
11
  allGames = await res.json();
10
12
  } catch {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stem-lab-toolkit",
3
- "version": "1.0.3",
3
+ "version": "1.0.5",
4
4
  "description": "STEM educational toolkit",
5
5
  "main": "index.html",
6
6
  "scripts": {
package/tool.html CHANGED
@@ -191,7 +191,7 @@
191
191
  <div class="game-actions">
192
192
  <button class="fullscreen-btn" id="fs-btn">
193
193
  <svg width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24">
194
- <path d="M8 3H5a2 2 0 00-2 2v1.0.3m18 0V5a2 2 0 00-2-2h-3m0 18h3a2 2 0 002-2v-3M3 16v1.0.3a2 2 0 002 2h3"/>
194
+ <path d="M8 3H5a2 2 0 00-2 2v0.0.1m18 0V5a2 2 0 00-2-2h-3m0 18h3a2 2 0 002-2v-3M3 16v0.0.1a2 2 0 002 2h3"/>
195
195
  </svg>
196
196
  Fullscreen
197
197
  </button>
@@ -219,7 +219,7 @@
219
219
  });
220
220
  })();
221
221
  </script>
222
- <script src="./js/pin-modal.js?v=1.0.3c"></script>
222
+ <script src="./js/pin-modal.js?v=0.0.1c"></script>
223
223
 
224
224
  <a href="https://forms.gle/59RMvCkURByui1747" target="_blank" rel="noopener" style="position:fixed;bottom:20px;right:20px;background:rgba(255,255,255,.08);color:rgba(255,255,255,.4);font-size:0.72rem;font-weight:500;padding:6px 14px;border-radius:999px;text-decoration:none;z-index:199;border:1px solid rgba(255,255,255,.1);transition:all .15s;" onmouseover="this.style.background='rgba(255,255,255,.16)';this.style.color='rgba(255,255,255,.8)'" onmouseout="this.style.background='rgba(255,255,255,.08)';this.style.color='rgba(255,255,255,.4)'">Feedback</a>
225
225
 
package/version.txt CHANGED
@@ -1 +1 @@
1
- v1.0.3
1
+ v0.0.1