diff --git a/run.py b/run.py
index f1e157a..a69516e 100644
--- a/run.py
+++ b/run.py
@@ -70,3 +70,444 @@ def main():
if __name__ == "__main__":
logging.basicConfig(level=logging.INFO)
main()
+import React, { useState, useEffect, useRef } from "react";
+import { Canvas } from "@react-three/fiber";
+import { OrbitControls, Stars, Html } from "@react-three/drei";
+import * as THREE from "three";
+import { VRButton } from "@react-three/xr";
+import { XR } from "@react-three/xr";
+
+const AIHelper = ({ position, text }) => {
+ const synthRef = useRef(null);
+
+ useEffect(() => {
+ if (!synthRef.current) {
+ synthRef.current = new SpeechSynthesisUtterance();
+ }
+ synthRef.current.text = text;
+ synthRef.current.lang = "fr-FR";
+
+ if (text.includes("Bienvenue")) {
+ synthRef.current.pitch = 1.2;
+ synthRef.current.rate = 1;
+ } else if (text.includes("écoute")) {
+ synthRef.current.pitch = 1.0;
+ synthRef.current.rate = 0.9;
+ } else {
+ synthRef.current.pitch = 1.5;
+ synthRef.current.rate = 1.1;
+ }
+
+ window.speechSynthesis.cancel();
+ window.speechSynthesis.speak(synthRef.current);
+ }, [text]);
+
+ return (
+
+
+
+
+
+ {text}
+
+
+
+ );
+};
+
+const computeGematria = (text) => {
+ return text
+ .toUpperCase()
+ .split("")
+ .filter(char => /[A-Z]/.test(char))
+ .reduce((sum, char) => sum + char.charCodeAt(0) - 64, 0);
+};
+
+const FloatingSymbols = ({ text }) => {
+ const gematriaValue = computeGematria(text);
+ return (
+
+
+ Gematria : {gematriaValue}
+
+
+ );
+};
+
+const EnergyPortal = ({ position }) => {
+ return (
+
+
+
+
+
+ "Portail énergétique - Traversez pour explorer une vibration supérieure."
+
+
+
+ );
+};
+
+const LumoraCity = () => {
+ const [frequencyData, setFrequencyData] = useState([]);
+ const [aiMessage, setAiMessage] = useState("Bienvenue à Lumora. Parle, et la ville écoutera.");
+ const pathwayPoints = [
+ [0, 0, -5], [1, 0, -4], [2, 0, -3], [3, 0, -2], [4, 0, -1],
+ [5, 0, 0], [4, 0, 1], [3, 0, 2], [2, 0, 3], [1, 0, 4], [0, 0, 5]
+ ];
+
+ useEffect(() => {
+ const analyser = new (window.AudioContext || window.webkitAudioContext)();
+ navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
+ const source = analyser.createMediaStreamSource(stream);
+ const analyserNode = analyser.createAnalyser();
+ source.connect(analyserNode);
+ analyserNode.fftSize = 256;
+ const bufferLength = analyserNode.frequencyBinCount;
+ const dataArray = new Uint8Array(bufferLength);
+
+ const updateFrequency = () => {
+ analyserNode.getByteFrequencyData(dataArray);
+ setFrequencyData([...dataArray]);
+
+ const avgFreq = dataArray.reduce((sum, val) => sum + val, 0) / dataArray.length;
+ if (avgFreq > 100) {
+ setAiMessage("Les vibrations sont fortes. Lumora répond.");
+ } else {
+ setAiMessage("Le silence est aussi une réponse. Écoute.");
+ }
+
+ requestAnimationFrame(updateFrequency);
+ };
+
+ updateFrequency();
+ });
+ }, []);
+
+ return (
+ <>
+
+
+ >
+ );
+};
+
+export default LumoraCity;
+import React, { useState, useEffect, useRef } from "react";
+import { Canvas } from "@react-three/fiber";
+import { OrbitControls, Stars, Html } from "@react-three/drei";
+import * as THREE from "three";
+import { VRButton } from "@react-three/xr";
+import { XR } from "@react-three/xr";
+
+const AIHelper = ({ position, text }) => {
+ const synthRef = useRef(null);
+
+ useEffect(() => {
+ if (!synthRef.current) {
+ synthRef.current = new SpeechSynthesisUtterance();
+ }
+ synthRef.current.text = text;
+ synthRef.current.lang = "fr-FR";
+
+ if (text.includes("Bienvenue")) {
+ synthRef.current.pitch = 1.2;
+ synthRef.current.rate = 1;
+ } else if (text.includes("écoute")) {
+ synthRef.current.pitch = 1.0;
+ synthRef.current.rate = 0.9;
+ } else {
+ synthRef.current.pitch = 1.5;
+ synthRef.current.rate = 1.1;
+ }
+
+ window.speechSynthesis.cancel();
+ window.speechSynthesis.speak(synthRef.current);
+ }, [text]);
+
+ return (
+
+
+
+
+
+ {text}
+
+
+
+ );
+};
+
+const computeGematria = (text) => {
+ return text
+ .toUpperCase()
+ .split("")
+ .filter(char => /[A-Z]/.test(char))
+ .reduce((sum, char) => sum + char.charCodeAt(0) - 64, 0);
+};
+
+const FloatingSymbols = ({ text }) => {
+ const gematriaValue = computeGematria(text);
+ return (
+
+
+ Gematria : {gematriaValue}
+
+
+ );
+};
+
+const EnergyPortal = ({ position }) => {
+ return (
+
+
+
+
+
+ "Portail énergétique - Traversez pour explorer une vibration supérieure."
+
+
+
+ );
+};
+
+const LumoraCity = () => {
+ const [frequencyData, setFrequencyData] = useState([]);
+ const [aiMessage, setAiMessage] = useState("Bienvenue à Lumora. Parle, et la ville écoutera.");
+ const pathwayPoints = [
+ [0, 0, -5], [1, 0, -4], [2, 0, -3], [3, 0, -2], [4, 0, -1],
+ [5, 0, 0], [4, 0, 1], [3, 0, 2], [2, 0, 3], [1, 0, 4], [0, 0, 5]
+ ];
+
+ useEffect(() => {
+ const analyser = new (window.AudioContext || window.webkitAudioContext)();
+ navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
+ const source = analyser.createMediaStreamSource(stream);
+ const analyserNode = analyser.createAnalyser();
+ source.connect(analyserNode);
+ analyserNode.fftSize = 256;
+ const bufferLength = analyserNode.frequencyBinCount;
+ const dataArray = new Uint8Array(bufferLength);
+
+ const updateFrequency = () => {
+ analyserNode.getByteFrequencyData(dataArray);
+ setFrequencyData([...dataArray]);
+
+ const avgFreq = dataArray.reduce((sum, val) => sum + val, 0) / dataArray.length;
+ if (avgFreq > 100) {
+ setAiMessage("Les vibrations sont fortes. Lumora répond.");
+ } else {
+ setAiMessage("Le silence est aussi une réponse. Écoute.");
+ }
+
+ requestAnimationFrame(updateFrequency);
+ };
+
+ updateFrequency();
+ });
+ }, []);
+
+ return (
+ <>
+
+
+ >
+ );
+};
+
+export default LumoraCity;
+import React, { useState, useEffect, useRef } from "react";
+import { Canvas } from "@react-three/fiber";
+import { OrbitControls, Stars, Html } from "@react-three/drei";
+import * as THREE from "three";
+import { VRButton } from "@react-three/xr";
+import { XR } from "@react-three/xr";
+
+const AIHelper = ({ position, text }) => {
+ const synthRef = useRef(null);
+
+ useEffect(() => {
+ if (!synthRef.current) {
+ synthRef.current = new SpeechSynthesisUtterance();
+ }
+ synthRef.current.text = text;
+ synthRef.current.lang = "fr-FR";
+
+ if (text.includes("Bienvenue")) {
+ synthRef.current.pitch = 1.2;
+ synthRef.current.rate = 1;
+ } else if (text.includes("écoute")) {
+ synthRef.current.pitch = 1.0;
+ synthRef.current.rate = 0.9;
+ } else {
+ synthRef.current.pitch = 1.5;
+ synthRef.current.rate = 1.1;
+ }
+
+ window.speechSynthesis.cancel();
+ window.speechSynthesis.speak(synthRef.current);
+ }, [text]);
+
+ return (
+
+
+
+
+
+ {text}
+
+
+
+ );
+};
+
+const computeGematria = (text) => {
+ return text
+ .toUpperCase()
+ .split("")
+ .filter(char => /[A-Z]/.test(char))
+ .reduce((sum, char) => sum + char.charCodeAt(0) - 64, 0);
+};
+
+const FloatingSymbols = ({ text }) => {
+ const gematriaValue = computeGematria(text);
+ return (
+
+
+ Gematria : {gematriaValue}
+
+
+ );
+};
+
+const EnergyPortal = ({ position }) => {
+ return (
+
+
+
+
+
+ "Portail énergétique - Traversez pour explorer une vibration supérieure."
+
+
+
+ );
+};
+
+const LumoraCity = () => {
+ const [frequencyData, setFrequencyData] = useState([]);
+ const [aiMessage, setAiMessage] = useState("Bienvenue à Lumora. Parle, et la ville écoutera.");
+ const pathwayPoints = [
+ [0, 0, -5], [1, 0, -4], [2, 0, -3], [3, 0, -2], [4, 0, -1],
+ [5, 0, 0], [4, 0, 1], [3, 0, 2], [2, 0, 3], [1, 0, 4], [0, 0, 5]
+ ];
+
+ useEffect(() => {
+ const analyser = new (window.AudioContext || window.webkitAudioContext)();
+ navigator.mediaDevices.getUserMedia({ audio: true }).then((stream) => {
+ const source = analyser.createMediaStreamSource(stream);
+ const analyserNode = analyser.createAnalyser();
+ source.connect(analyserNode);
+ analyserNode.fftSize = 256;
+ const bufferLength = analyserNode.frequencyBinCount;
+ const dataArray = new Uint8Array(bufferLength);
+
+ const updateFrequency = () => {
+ analyserNode.getByteFrequencyData(dataArray);
+ setFrequencyData([...dataArray]);
+
+ const avgFreq = dataArray.reduce((sum, val) => sum + val, 0) / dataArray.length;
+ if (avgFreq > 100) {
+ setAiMessage("Les vibrations sont fortes. Lumora répond.");
+ } else {
+ setAiMessage("Le silence est aussi une réponse. Écoute.");
+ }
+
+ requestAnimationFrame(updateFrequency);
+ };
+
+ updateFrequency();
+ });
+ }, []);
+
+ return (
+ <>
+
+
+ >
+ );
+};
+
+export default LumoraCity;