| <!DOCTYPE html>
|
| <html lang="en">
|
|
|
| <head>
|
| <meta charset="UTF-8">
|
| <meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| <title>Diamond AI / Pipeline</title>
|
| <link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
| </head>
|
|
|
| <body>
|
| <canvas id="canvas3d"></canvas>
|
| <div class="atmospheric-grain"></div>
|
|
|
| <div id="loader-overlay">
|
| <div class="loader-container">
|
| <div class="loader-line">
|
| <div class="loader-progress" id="js-loader-bar"></div>
|
| </div>
|
| <div class="loader-text">PROCS / ANALYZING DATA [0%]</div>
|
| </div>
|
| </div>
|
|
|
| {% with messages = get_flashed_messages() %}
|
| {% if messages %}
|
| <div class="flash-container">
|
| {% for message in messages %}
|
| <div class="flash-message">{{ message }}</div>
|
| {% endfor %}
|
| </div>
|
| {% endif %}
|
| {% endwith %}
|
|
|
| <div class="container animate-up">
|
| <nav>
|
| <div class="nav-logo">DIAMOND / AI</div>
|
| <div class="nav-meta">
|
| <span>SYSTEM V1.0</span>
|
| <span>2026</span>
|
| </div>
|
| </nav>
|
|
|
| <header>
|
| <p class="label-mini">Automated Grading Pipeline</p>
|
| <h1>DIAMOND<br /><span class="italic">INTELLIGENCE</span></h1>
|
| </header>
|
|
|
| <main>
|
| <div class="upload-card">
|
| <form id="upload-form" action="/upload" method="post" enctype="multipart/form-data">
|
| <div class="form-group">
|
| <label>01 / SELECT IMAGE BUNDLE (ZIP)</label>
|
| <input type="file" name="zip_file" accept=".zip" required>
|
| </div>
|
|
|
| <div class="form-group">
|
| <label>02 / SELECT DATA MANIFEST (EXCEL)</label>
|
| <input type="file" name="excel_file" accept=".xlsx, .xls" required>
|
| </div>
|
|
|
| <button type="submit" class="btn-launch">Execute Phase</button>
|
| </form>
|
|
|
| <div class="flush-section">
|
| <form id="flush-form" action="/flush" method="post" onsubmit="return confirmFlush()">
|
| <button type="submit" class="btn-flush-data">Flush System Data</button>
|
| </form>
|
| <p class="flush-hint">Resets all uploads and results to free up space.</p>
|
| </div>
|
| </div>
|
| </main>
|
| </div>
|
|
|
| <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
|
| <script>
|
|
|
| const vertexShader = `varying vec2 vUv; void main() { vUv = uv; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); }`;
|
| const fragmentShader = `
|
| uniform float uTime;
|
| varying vec2 vUv;
|
| // Simplex 2D noise
|
| vec3 permute(vec3 x) { return mod(((x*34.0)+1.0)*x, 289.0); }
|
| float snoise(vec2 v){
|
| const vec4 C = vec4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439);
|
| vec2 i = floor(v + dot(v, C.yy) );
|
| vec2 x0 = v - i + dot(i, C.xx);
|
| vec2 i1; i1 = (x0.x > x0.y) ? vec2(1.0, 0.0) : vec2(0.0, 1.0);
|
| vec4 x12 = x0.xyxy + C.xxzz;
|
| x12.xy -= i1;
|
| i = mod(i, 289.0);
|
| vec3 p = permute( permute( i.y + vec3(0.0, i1.y, 1.0 )) + i.x + vec3(0.0, i1.x, 1.0 ));
|
| vec3 m = max(0.5 - vec3(dot(x0,x0), dot(x12.xy,x12.xy), dot(x12.zw,x12.zw)), 0.0);
|
| m = m*m ; m = m*m ;
|
| vec3 x = 2.0 * fract(p * C.www) - 1.0;
|
| vec3 h = abs(x) - 0.5;
|
| vec3 ox = floor(x + 0.5);
|
| vec3 a0 = x - ox;
|
| m *= 1.79284291400159 - 0.85373472095314 * ( a0*a0 + h*h );
|
| vec3 g;
|
| g.x = a0.x * x0.x + h.x * x0.y;
|
| g.yz = a0.yz * x12.xz + h.yz * x12.yw;
|
| return 130.0 * dot(m, g);
|
| }
|
| void main() {
|
| vec2 uv = vUv;
|
| float n = snoise(uv * 1.5 + uTime * 0.05);
|
| vec3 color = mix(vec3(0.02, 0.02, 0.05), vec3(0.08, 0.04, 0.15), n * 0.5 + 0.5);
|
| gl_FragColor = vec4(color, 1.0);
|
| }
|
| `;
|
|
|
| const scene = new THREE.Scene();
|
| const camera = new THREE.OrthographicCamera(-1, 1, 1, -1, 0, 1);
|
| const renderer = new THREE.WebGLRenderer({ canvas: document.getElementById('canvas3d'), antialias: true });
|
| renderer.setSize(window.innerWidth, window.innerHeight);
|
|
|
| const geometry = new THREE.PlaneGeometry(2, 2);
|
| const uniforms = { uTime: { value: 0 } };
|
| const material = new THREE.ShaderMaterial({ vertexShader, fragmentShader, uniforms });
|
| scene.add(new THREE.Mesh(geometry, material));
|
|
|
| const animate = (t) => {
|
| uniforms.uTime.value = t * 0.001;
|
| renderer.render(scene, camera);
|
| requestAnimationFrame(animate);
|
| };
|
| requestAnimationFrame(animate);
|
|
|
| document.getElementById('upload-form').addEventListener('submit', function () {
|
| document.getElementById('loader-overlay').style.display = 'flex';
|
| const loaderBar = document.getElementById('js-loader-bar');
|
| const loaderText = document.querySelector('.loader-text');
|
| let p = 0;
|
| const itv = setInterval(() => {
|
| if (p < 92) {
|
|
|
| const increment = (92 - p) * 0.03 + 0.1;
|
| p += increment;
|
| }
|
| const displayP = Math.floor(p);
|
| loaderBar.style.width = displayP + '%';
|
|
|
| let phase = "ANALYZING";
|
| if (displayP > 25) phase = "INFERENCING";
|
| if (displayP > 60) phase = "GRADATING";
|
| if (displayP > 85) phase = "COMPILING REPORT";
|
|
|
| loaderText.innerText = `PROCS / ${phase} DATA [${displayP}%]`;
|
| }, 100);
|
| });
|
|
|
| function confirmFlush() {
|
| return confirm("Are you sure you want to flush all data? This will permanently delete all uploaded images and generated reports.");
|
| }
|
|
|
| window.onresize = () => renderer.setSize(window.innerWidth, window.innerHeight);
|
|
|
|
|
| setTimeout(() => {
|
| const flashes = document.querySelectorAll('.flash-message');
|
| flashes.forEach(f => f.style.opacity = '0');
|
| }, 3000);
|
| </script>
|
| </body>
|
|
|
| </html> |