Skip to content

Commit cd2fc9d

Browse files
vanillaerWOW202509
authored andcommitted
Initial import
0 parents  commit cd2fc9d

30 files changed

Lines changed: 3273 additions & 0 deletions

.gitattributes

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
*.7z filter=lfs diff=lfs merge=lfs -text
2+
*.arrow filter=lfs diff=lfs merge=lfs -text
3+
*.bin filter=lfs diff=lfs merge=lfs -text
4+
*.bz2 filter=lfs diff=lfs merge=lfs -text
5+
*.ckpt filter=lfs diff=lfs merge=lfs -text
6+
*.ftz filter=lfs diff=lfs merge=lfs -text
7+
*.gz filter=lfs diff=lfs merge=lfs -text
8+
*.h5 filter=lfs diff=lfs merge=lfs -text
9+
*.joblib filter=lfs diff=lfs merge=lfs -text
10+
*.lfs.* filter=lfs diff=lfs merge=lfs -text
11+
*.lz4 filter=lfs diff=lfs merge=lfs -text
12+
*.mds filter=lfs diff=lfs merge=lfs -text
13+
*.mlmodel filter=lfs diff=lfs merge=lfs -text
14+
*.model filter=lfs diff=lfs merge=lfs -text
15+
*.msgpack filter=lfs diff=lfs merge=lfs -text
16+
*.npy filter=lfs diff=lfs merge=lfs -text
17+
*.npz filter=lfs diff=lfs merge=lfs -text
18+
*.onnx filter=lfs diff=lfs merge=lfs -text
19+
*.ot filter=lfs diff=lfs merge=lfs -text
20+
*.parquet filter=lfs diff=lfs merge=lfs -text
21+
*.pb filter=lfs diff=lfs merge=lfs -text
22+
*.pickle filter=lfs diff=lfs merge=lfs -text
23+
*.pkl filter=lfs diff=lfs merge=lfs -text
24+
*.pt filter=lfs diff=lfs merge=lfs -text
25+
*.pth filter=lfs diff=lfs merge=lfs -text
26+
*.rar filter=lfs diff=lfs merge=lfs -text
27+
*.safetensors filter=lfs diff=lfs merge=lfs -text
28+
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
29+
*.tar.* filter=lfs diff=lfs merge=lfs -text
30+
*.tar filter=lfs diff=lfs merge=lfs -text
31+
*.tflite filter=lfs diff=lfs merge=lfs -text
32+
*.tgz filter=lfs diff=lfs merge=lfs -text
33+
*.wasm filter=lfs diff=lfs merge=lfs -text
34+
*.xz filter=lfs diff=lfs merge=lfs -text
35+
*.zip filter=lfs diff=lfs merge=lfs -text
36+
*.zst filter=lfs diff=lfs merge=lfs -text
37+
*tfevents* filter=lfs diff=lfs merge=lfs -text
38+
# Audio files - uncompressed
39+
*.pcm filter=lfs diff=lfs merge=lfs -text
40+
*.sam filter=lfs diff=lfs merge=lfs -text
41+
*.raw filter=lfs diff=lfs merge=lfs -text
42+
# Audio files - compressed
43+
*.aac filter=lfs diff=lfs merge=lfs -text
44+
*.flac filter=lfs diff=lfs merge=lfs -text
45+
*.mp3 filter=lfs diff=lfs merge=lfs -text
46+
*.ogg filter=lfs diff=lfs merge=lfs -text
47+
*.wav filter=lfs diff=lfs merge=lfs -text
48+
# Image files - uncompressed
49+
*.bmp filter=lfs diff=lfs merge=lfs -text
50+
*.gif filter=lfs diff=lfs merge=lfs -text
51+
*.png filter=lfs diff=lfs merge=lfs -text
52+
*.tiff filter=lfs diff=lfs merge=lfs -text
53+
# Image files - compressed
54+
*.jpg filter=lfs diff=lfs merge=lfs -text
55+
*.jpeg filter=lfs diff=lfs merge=lfs -text
56+
*.webp filter=lfs diff=lfs merge=lfs -text
57+
# Video files - compressed
58+
*.mp4 filter=lfs diff=lfs merge=lfs -text
59+
*.webm filter=lfs diff=lfs merge=lfs -text
60+
# NEW added:
61+
*.glb filter=lfs diff=lfs merge=lfs -text
62+
scenes_glb/5ZKStnWn8Zo.glb filter=lfs diff=lfs merge=lfs -text
63+
scenes_glb/X7HyMhZNoso.glb filter=lfs diff=lfs merge=lfs -text

.github/workflows/deploy-pages.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
name: Deploy Pages
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
7+
permissions:
8+
contents: read
9+
pages: write
10+
id-token: write
11+
12+
concurrency:
13+
group: pages
14+
cancel-in-progress: true
15+
16+
jobs:
17+
build:
18+
runs-on: ubuntu-latest
19+
steps:
20+
- name: Checkout repository (with LFS)
21+
uses: actions/checkout@v4
22+
with:
23+
lfs: true
24+
- name: Configure Pages
25+
uses: actions/configure-pages@v4
26+
- name: Upload artifact
27+
uses: actions/upload-pages-artifact@v3
28+
with:
29+
path: .
30+
deploy:
31+
runs-on: ubuntu-latest
32+
needs: build
33+
environment:
34+
name: github-pages
35+
url: ${{ steps.deployment.outputs.page_url }}
36+
steps:
37+
- name: Deploy to GitHub Pages
38+
id: deployment
39+
uses: actions/deploy-pages@v4

.nojekyll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

assets/main.js

Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
(function(){
2+
const nav = document.getElementById('site-nav');
3+
const toggle = document.querySelector('.nav-toggle');
4+
const links = nav ? Array.from(nav.querySelectorAll('a[href^="#"]')) : [];
5+
6+
if (toggle && nav) {
7+
toggle.addEventListener('click', () => {
8+
const isOpen = nav.classList.toggle('open');
9+
toggle.setAttribute('aria-expanded', String(isOpen));
10+
});
11+
}
12+
13+
// Smooth scroll and close mobile menu
14+
links.forEach(link => {
15+
link.addEventListener('click', (e) => {
16+
const id = link.getAttribute('href');
17+
if (!id || id.length < 2) return;
18+
const target = document.querySelector(id);
19+
if (!target) return;
20+
e.preventDefault();
21+
target.scrollIntoView({ behavior: 'smooth', block: 'start' });
22+
nav.classList.remove('open');
23+
if (toggle) toggle.setAttribute('aria-expanded', 'false');
24+
history.replaceState(null, '', id);
25+
});
26+
});
27+
28+
// Active section highlighting (scroll spy)
29+
// Track intersection ratios and highlight the link for the section
30+
// that occupies the most space in the viewport.
31+
const sections = Array.from(document.querySelectorAll('main section[id]'))
32+
.filter(sec => links.some(a => a.getAttribute('href') === `#${sec.id}`));
33+
34+
const ratioById = Object.fromEntries(sections.map(s => [s.id, 0]));
35+
36+
const updateActive = () => {
37+
let bestId = null;
38+
let bestRatio = 0;
39+
for (const [id, r] of Object.entries(ratioById)) {
40+
if (r > bestRatio) { bestRatio = r; bestId = id; }
41+
}
42+
if (!bestId) return;
43+
const activeHref = `#${bestId}`;
44+
links.forEach(a => a.classList.toggle('active', a.getAttribute('href') === activeHref));
45+
};
46+
47+
const observer = new IntersectionObserver((entries) => {
48+
entries.forEach(entry => {
49+
const id = entry.target.getAttribute('id');
50+
ratioById[id] = entry.intersectionRatio;
51+
});
52+
updateActive();
53+
}, { root: null, rootMargin: '0px 0px -35% 0px', threshold: [0, 0.1, 0.25, 0.5, 0.75, 1] });
54+
55+
sections.forEach(sec => observer.observe(sec));
56+
57+
// Initialize once in case we load mid-page
58+
updateActive();
59+
60+
// Footer year
61+
const yearEl = document.getElementById('year');
62+
if (yearEl) yearEl.textContent = String(new Date().getFullYear());
63+
64+
// No slider needed now (single demo video placeholder)
65+
66+
// Auto-resize embedded iframes to fit their content (opt-in via data-auto-height="true")
67+
const embeddedIframes = Array.from(document.querySelectorAll('iframe.embedded-iframe[data-auto-height="true"]'));
68+
const computeDocHeight = (doc) => {
69+
try {
70+
if (!doc) return 0;
71+
const body = doc.body;
72+
const html = doc.documentElement;
73+
if (!body || !html) return 0;
74+
// Use scrollHeight to allow shrink as content collapses
75+
return Math.max(body.scrollHeight, html.scrollHeight);
76+
} catch { return 0; }
77+
};
78+
const setIframeHeight = (iframe, height) => {
79+
if (!iframe) return;
80+
const target = Math.max(0, Math.floor(height || 0));
81+
if (target > 0) iframe.style.height = `${target}px`;
82+
};
83+
84+
// Strategy 1: Listen for postMessage from subpages (works with file:// as well)
85+
window.addEventListener('message', (event) => {
86+
// Do not rely on origin; instead, verify the source matches one of our iframes
87+
const data = event.data;
88+
if (!data || typeof data !== 'object' || data.type !== 'subpage:height') return;
89+
const target = embeddedIframes.find((f) => {
90+
try { return f.contentWindow === event.source; } catch { return false; }
91+
});
92+
if (!target) return;
93+
const h = Number(data.height);
94+
if (Number.isFinite(h) && h > 0) setIframeHeight(target, h);
95+
});
96+
97+
// Strategy 2: Same-origin direct measurement with ResizeObserver
98+
embeddedIframes.forEach((iframe) => {
99+
const attachObservers = () => {
100+
let ro = null; let mo = null;
101+
try {
102+
const doc = iframe.contentDocument;
103+
const body = doc && doc.body;
104+
if (!body) return;
105+
// Initial set
106+
setIframeHeight(iframe, computeDocHeight(doc));
107+
// ResizeObserver for layout changes
108+
ro = new ResizeObserver(() => setIframeHeight(iframe, computeDocHeight(doc)));
109+
ro.observe(body);
110+
// MutationObserver as a fallback for DOM changes
111+
mo = new MutationObserver(() => setIframeHeight(iframe, computeDocHeight(doc)));
112+
mo.observe(body, { attributes:true, childList:true, subtree:true, characterData:true });
113+
// A couple of delayed reads to catch late layout
114+
setTimeout(() => setIframeHeight(iframe, computeDocHeight(doc)), 50);
115+
setTimeout(() => setIframeHeight(iframe, computeDocHeight(doc)), 250);
116+
} catch (_) {
117+
// Cross-origin: skip direct access
118+
}
119+
120+
// Cleanup on reload of iframe
121+
iframe.addEventListener('load', () => {
122+
if (ro) try { ro.disconnect(); } catch {}
123+
if (mo) try { mo.disconnect(); } catch {}
124+
// Re-attach for new document
125+
attachObservers();
126+
}, { once: true });
127+
};
128+
const docReady = () => {
129+
try {
130+
const rs = iframe.contentDocument && iframe.contentDocument.readyState;
131+
return rs === 'interactive' || rs === 'complete';
132+
} catch { return false; }
133+
};
134+
if (docReady()) attachObservers();
135+
else iframe.addEventListener('load', attachObservers, { once: true });
136+
});
137+
138+
// Copy BibTeX button
139+
const copyBtn = document.querySelector('.bibtex-copy-btn');
140+
if (copyBtn) {
141+
copyBtn.addEventListener('click', async () => {
142+
const pre = document.querySelector('.bibtex-wrap pre.bibtex');
143+
if (!pre) return;
144+
const text = pre.textContent || '';
145+
try {
146+
await navigator.clipboard.writeText(text);
147+
copyBtn.textContent = 'Copied';
148+
setTimeout(() => { copyBtn.textContent = 'Copy'; }, 1500);
149+
} catch (_) {
150+
// Fallback: select and copy
151+
const range = document.createRange();
152+
range.selectNodeContents(pre);
153+
const sel = window.getSelection();
154+
sel.removeAllRanges();
155+
sel.addRange(range);
156+
try { document.execCommand('copy'); copyBtn.textContent = 'Copied'; } catch {}
157+
setTimeout(() => { copyBtn.textContent = 'Copy'; sel.removeAllRanges(); }, 1500);
158+
}
159+
});
160+
}
161+
})();
162+

0 commit comments

Comments
 (0)