!DOCTYPE html>
<html data-wf-domain="spiral-galaxy-gui.webflow.io" data-wf-page="62279224c08b1f2bc26f9814" data-wf-site="62279224c08b1f3cca6f9813" data-wf-status="1">
  <head>
    <meta charset="utf-8" />
    <title>Lumina AI - Existence Simulated</title>
    <meta content="Lumina AI Galaxy Simulation" property="og:title" />
    <meta content="Solana Token Lumina AI" property="og:description" />
    <meta content="Lumina AI Galaxy Simulation" property="twitter:title" />
    <link rel="icon" type="image/png" href="faveicon.png" />
    <meta content="Solana Token Lumina AI" property="twitter:description" />
    <meta property="og:type" content="website" />
    <meta content="summary_large_image" name="twitter:card" />
    <meta content="width=device-width, initial-scale=1" name="viewport" />
    <meta content="Webflow" name="generator" />
    <link href="https://assets.website-files.com/62279224c08b1f3cca6f9813/css/spiral-galaxy-gui.webflow.41d8e7b35.css" rel="stylesheet" type="text/css" />


    <script type="text/javascript">
      ! function(o, c) {
        var n = c.documentElement,
          t = " w-mod-";
        n.className += t + "js", ("ontouchstart" in o || o.DocumentTouch && c instanceof DocumentTouch) && (n.className += t + "touch")
      }(window, document);
    </script>
    <link href="" rel="shortcut icon" type="image/x-icon" />
    <link href="https://assets.website-files.com/62279224c08b1f3cca6f9813/62279224c08b1fa3126f981b_Webclip.png" rel="apple-touch-icon" />
  </head>
  <body>
    <a href="#" class="brand w-inline-block">
      <img src="https://i.postimg.cc/wB31jMTM/lumina2.png" loading="eager" alt="" class="image" />
    </a>
    <div class="nav-menu">
      <a href="https://t.me/luminaworldportal" class="link">Telegram</a>
      <a href="https://x.com/LuminaWorldAI" class="link">Twitter</a>
      <a href="#" class="link">SolScan</a>
      <a href="#" class="link">DexScreener</a>
      <font color="white"> - 60,000 Galaxy Spirits Soon To Be Explored in Lumina! - </font>
    </div>
    <div class="canvas w-embed">
      <canvas class="webgl"></canvas>
    </div>

    <script src="https://cdn.jsdelivr.net/npm/three@0.138.1/build/three.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/three@0.138.1/examples/js/controls/OrbitControls.js"></script>
    <script type="module">
      import * as lil from "https://cdn.jsdelivr.net/npm/three@0.138.1/examples/jsm/libs/lil-gui.module.min.js";

      // Canvas
      const canvas = document.querySelector("canvas.webgl");

      // Scene
      const scene = new THREE.Scene();

      // Galaxy Parameters
      const parameters = {
        count: 60000,
        size: 0.02,
        radius: 5,
        branches: 3,
        spin: 1,
        randomness: 0.2,
        randomnessPower: 3,
        insideColor: "#eb3700",
        outsideColor: "#4dbbcc",
      };

      let geometry = null;
      let material = null;
      let points = null;

      const generateGalaxy = () => {
        if (points !== null) {
          geometry.dispose();
          material.dispose();
          scene.remove(points);
        }

        geometry = new THREE.BufferGeometry();
        const positions = new Float32Array(parameters.count * 3);
        const colors = new Float32Array(parameters.count * 3);

        const colorInside = new THREE.Color(parameters.insideColor);
        const colorOutside = new THREE.Color(parameters.outsideColor);

        for (let i = 0; i < parameters.count; i++) {
          const i3 = i * 3;
          const radius = Math.random() * parameters.radius;
          const spinAngle = radius * parameters.spin;
          const branchAngle = ((i % parameters.branches) / parameters.branches) * Math.PI * 2;

          const randomX = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random() < 0.5 ? 1 : -1);
          const randomY = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random() < 0.5 ? 1 : -1);
          const randomZ = Math.pow(Math.random(), parameters.randomnessPower) * (Math.random() < 0.5 ? 1 : -1);

          positions[i3] = Math.cos(branchAngle + spinAngle) * radius + randomX;
          positions[i3 + 1] = randomY;
          positions[i3 + 2] = Math.sin(branchAngle + spinAngle) * radius + randomZ;

          const mixedColor = colorInside.clone();
          mixedColor.lerp(colorOutside, radius / parameters.radius);

          colors[i3] = mixedColor.r;
          colors[i3 + 1] = mixedColor.g;
          colors[i3 + 2] = mixedColor.b;
        }

        geometry.setAttribute("position", new THREE.BufferAttribute(positions, 3));
        geometry.setAttribute("color", new THREE.BufferAttribute(colors, 3));

        material = new THREE.PointsMaterial({
          size: parameters.size,
          sizeAttenuation: true,
          depthWrite: false,
          blending: THREE.AdditiveBlending,
          vertexColors: true,
        });

        points = new THREE.Points(geometry, material);
        scene.add(points);
      };

      generateGalaxy();

      // Sizes
      const sizes = {
        width: window.innerWidth,
        height: window.innerHeight,
      };

      window.addEventListener("resize", () => {
        sizes.width = window.innerWidth;
        sizes.height = window.innerHeight;

        camera.aspect = sizes.width / sizes.height;
        camera.updateProjectionMatrix();

        renderer.setSize(sizes.width, sizes.height);
        renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
      });

      // Camera
      const camera = new THREE.PerspectiveCamera(22, sizes.width / sizes.height, 0.3, 100);
      camera.position.set(1, 8, 14);
      scene.add(camera);

      // Controls
      const controls = new THREE.OrbitControls(camera, canvas);
      controls.enableDamping = true;

      // Renderer
      const renderer = new THREE.WebGLRenderer({ canvas: canvas });
      renderer.setSize(sizes.width, sizes.height);
      renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));

      // Raycaster
      const raycaster = new THREE.Raycaster();
      const mouse = new THREE.Vector2();

      window.addEventListener("click", (event) => {
        mouse.x = (event.clientX / sizes.width) * 2 - 1;
        mouse.y = -(event.clientY / sizes.height) * 2 + 1;

        if (points) {
          raycaster.setFromCamera(mouse, camera);
          const intersects = raycaster.intersectObject(points);

          if (intersects.length > 0) {
            const agentId = `agent-${Math.random().toString(36).substr(2, 9)}`;
            createChatWindow(agentId);
          }
        }
      });

      function createChatWindow(agentId) {
        const chatWindow = document.createElement("div");
        chatWindow.id = `chat-window-${agentId}`;
        chatWindow.style = `
          position: fixed; bottom: 20px; right: 20px; width: 300px; height: 400px;
          background: black; border: 1px solid black; z-index: 1000; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
          color: white;
        `;

        const closeButton = document.createElement("button");
        closeButton.innerText = "Close";
        closeButton.style = "position: absolute; top: 350px; right: 5px; background-color: gray;";
        closeButton.onclick = () => document.body.removeChild(chatWindow);

        const chatContent = document.createElement("div");
        chatContent.id = `chat-content-${agentId}`;
        chatContent.style = "flex: 1; overflow-y: auto; padding: 10px;";

        const chatInput = document.createElement("input");
        chatInput.type = "text";
        chatInput.placeholder = "Type your message...";
        chatInput.style = "width: calc(100% - 80px); margin: 10px; color: black; position: absolute; top: 340px;";
        chatInput.onkeypress = (e) => {
          if (e.key === "Enter") {
            sendMessage(agentId, chatInput.value);
            chatInput.value = "";
          }
        };

        chatWindow.append(closeButton, chatContent, chatInput);
        document.body.appendChild(chatWindow);
      }

      function sendMessage(agentId, message) {
        const chatContent = document.getElementById(`chat-content-${agentId}`);
        const userMessage = document.createElement("div");
        userMessage.style.textAlign = "right";
        userMessage.innerText = message;
        chatContent.appendChild(userMessage);

        fetch("https://lumina-sim.com/chat", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ agentId, message }),
        })
          .then((response) => response.json())
          .then((data) => {
            const aiMessage = document.createElement("div");
            aiMessage.style.textAlign = "left";
            aiMessage.innerText = `${data.reply}`;
            chatContent.appendChild(aiMessage);
          })
          .catch((error) => console.error("Error:", error));
      }

      // Animation Loop
      const clock = new THREE.Clock();

      const tick = () => {
        points.rotation.y += 0.002;
        controls.update();
        renderer.render(scene, camera);
        requestAnimationFrame(tick);
      };

      tick();
    </script>
  </body>
</html>
