diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index c787ccb..6759cea 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -74,12 +74,12 @@ jobs: - name: 📏 Check bundle size run: | - # Get bundle size in KB - SIZE=$(du -k dist | cut -f1) + # Check generated app assets only; public/ model files are runtime assets copied to dist. + SIZE=$(du -k dist/assets | cut -f1) echo "Bundle size: ${SIZE}KB" - # Threshold: 1000KB (configurable) - THRESHOLD=1000 + # Threshold: 5000KB (configurable) + THRESHOLD=5000 if [ "$SIZE" -gt "$THRESHOLD" ]; then echo "❌ Bundle size ${SIZE}KB exceeds threshold ${THRESHOLD}KB" diff --git a/.gitignore b/.gitignore index d6b00ff..9b04b43 100644 --- a/.gitignore +++ b/.gitignore @@ -37,4 +37,8 @@ Thumbs.db # 3D Assets Cache (drei, GLTFJSX) .drei/ -.glitchdrei-cache/ \ No newline at end of file +.glitchdrei-cache/ + +# Temporaire +.backend/ +backend/ diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 0000000..d135def --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +22.12.0 \ No newline at end of file diff --git a/docs/technical/architecture.md b/docs/technical/architecture.md index 769575d..61ec7b2 100644 --- a/docs/technical/architecture.md +++ b/docs/technical/architecture.md @@ -4,13 +4,16 @@ This document describes the code that exists today in the repository. ## Runtime Structure -- `src/App.tsx` mounts the `Canvas`, the 3D `World`, the debug perf overlay, and the HTML overlays. +- `src/main.tsx` mounts React and wraps the app in `BrowserRouter`. +- `src/App.tsx` declares the top-level routes: + - `/` mounts the playable 3D scene, debug perf overlay, and HTML overlays. + - `/editor` mounts the map editor page. - `src/world/World.tsx` composes the active scene, including: - environment and lighting - debug helpers and debug camera mode - either the map scene or the debug physics test scene - the player rig when the active camera mode is `player` -- `src/world/Map.tsx` loads the main map model and builds the collision octree. +- `src/world/GameMap.tsx` loads map nodes from `public/map.json`, resolves available models, and builds the collision octree. - `src/world/debug/TestScene.tsx` provides a debug-oriented interaction and physics scene. - `src/world/player/PlayerComponent.tsx` mounts the camera and controller. - `src/world/player/PlayerController.tsx` owns pointer lock movement, jump handling, and interaction input. @@ -38,10 +41,31 @@ This document describes the code that exists today in the repository. - `src/utils/debug/scene/DebugHelpers.tsx` mounts debug helpers. - `src/utils/debug/scene/DebugCameraControls.tsx` mounts the free debug camera. +## Editor System + +- `src/pages/editor/EditorPage.tsx` is the route-level editor page for `/editor`. +- `src/components/editor/EditorControls.tsx` renders the HTML editor control panel. +- `src/components/editor/scene/EditorScene.tsx` composes the editor canvas scene, camera controls, lights, shortcuts, and map rendering. +- `src/components/editor/scene/EditorMap.tsx` renders map nodes, fallback cubes, selection highlighting, and transform controls. +- `src/controls/editor/FlyController.tsx` provides player-style editor navigation. +- `src/hooks/editor/useEditorSceneData.ts` loads scene data and handles folder upload fallback. +- `src/hooks/editor/useEditorHistory.ts` owns editor undo and redo state. +- `src/utils/editor/loadEditorScene.ts` handles editor-only folder upload parsing. +- `src/utils/loadMapSceneData.ts` is shared by the game scene and editor to load `public/map.json` and resolve model URLs. +- `src/types/editor.ts` contains the shared `MapNode`, `SceneData`, and `TransformMode` types. + +## Map Data + +- `public/map.json` is expected to be a `MapNode[]`. +- Each map node `name` maps to `public/models/{name}/model.gltf`. +- The editor renders a fallback cube for missing models. +- The game scene filters out nodes whose model cannot be resolved. + ## Current Limitations -- The repository is still a prototype, not the full intended game runtime. -- `src/world/debug/TestScene.tsx` is still part of the active scene composition. -- There is no central gameplay orchestrator such as `GameManager` yet. +- The repository is a prototype, not the full intended game runtime. +- `src/world/debug/TestScene.tsx` is part of the active scene composition. +- There is no central gameplay orchestrator such as `GameManager`. - Missions, zones, cinematics, and dialogue systems are not implemented. - The player uses octree collision and simple movement rules, not a complete gameplay physics stack. +- Editor save-to-server is implemented as a Vite dev-server plugin, not a production backend API. diff --git a/docs/technical/editor.md b/docs/technical/editor.md new file mode 100644 index 0000000..fd0e8cb --- /dev/null +++ b/docs/technical/editor.md @@ -0,0 +1,144 @@ +# Editor Technical Notes + +This document describes the map editor that exists in the current codebase. + +## Purpose + +The editor is a React route used to inspect and adjust the `public/map.json` scene data from inside the La-Fabrik app. It shares the same `MapNode` data format as the game scene and uses React Three Fiber for rendering. + +## Routing + +- `/` renders the playable La-Fabrik scene. +- `/editor` renders the map editor. +- `src/App.tsx` mounts TanStack Router through `RouterProvider`. +- `src/router.tsx` defines the `/editor` route and imports `EditorPage` from `src/pages/editor/page.tsx`. + +## File Structure + +```txt +src/ +├── pages/ +│ └── editor/ +│ └── page.tsx +├── components/ +│ └── editor/ +│ ├── EditorControls.tsx +│ └── scene/ +│ ├── EditorMap.tsx +│ └── EditorScene.tsx +├── controls/ +│ └── editor/ +│ └── FlyController.tsx +├── hooks/ +│ └── editor/ +│ ├── useEditorHistory.ts +│ └── useEditorSceneData.ts +├── types/ +│ └── editor.ts +└── utils/ + ├── editor/ + │ └── loadEditorScene.ts + └── loadMapSceneData.ts +``` + +## Responsibilities + +`src/pages/editor/page.tsx` is the route-level composition component. It owns route-specific state such as selected object, hovered object, transform mode, and player-mode toggle. + +`src/hooks/editor/useEditorSceneData.ts` loads the default map data and handles folder uploads. + +`src/hooks/editor/useEditorHistory.ts` owns editor undo and redo history. + +`src/components/editor/scene/EditorScene.tsx` composes the editor canvas scene, camera controls, lights, keyboard shortcuts, and `EditorMap`. + +`src/components/editor/scene/EditorMap.tsx` renders map nodes, fallback cubes, selection highlighting, and transform controls. + +`src/components/editor/EditorControls.tsx` renders the HTML control panel outside the canvas. + +`src/controls/editor/FlyController.tsx` provides editor movement controls for player-style navigation. + +`src/utils/loadMapSceneData.ts` is shared by the game map and editor. It loads `/map.json` and resolves available `public/models/{name}/model.gltf` files. + +`src/utils/editor/loadEditorScene.ts` contains editor-only upload handling for user-selected folders. + +## Data Format + +The shared editor type lives in `src/types/editor.ts`. + +```ts +interface MapNode { + name: string; + type: string; + position: [number, number, number]; + rotation: [number, number, number]; + scale: [number, number, number]; +} +``` + +`public/map.json` is expected to be a `MapNode[]`. + +```json +[ + { + "name": "pylone", + "type": "Mesh", + "position": [0, 5, 0], + "rotation": [0, 1.57, 0], + "scale": [1, 1, 1] + } +] +``` + +Each node `name` maps to a model folder: + +```txt +public/ +├── map.json +└── models/ + └── pylone/ + └── model.gltf +``` + +If a model is missing, the editor renders a fallback cube so the node can still be selected and transformed. + +## Editor Flow + +1. `EditorPage` mounts on `/editor`. +2. `useEditorSceneData` calls `loadMapSceneData()`. +3. `loadMapSceneData()` loads `/map.json` and available model URLs. +4. If `/map.json` is missing, the page displays a folder-upload flow. +5. `EditorScene` renders the grid, lights, camera controls, and map nodes. +6. `EditorControls` exposes transform mode, history actions, export, save, and selection info. + +## Controls + +- Click: select a node. +- `Esc`: clear selection. +- `T`: translate mode. +- `R`: rotate mode. +- `S`: scale mode. +- `Ctrl+Z` or `Cmd+Z`: undo. +- `Ctrl+Y` or `Cmd+Y`: redo. +- `WASD`, `ZQSD`, or arrow keys: move in player-controller mode. +- `Space`: move upward in player-controller mode. +- `Shift`: move downward in player-controller mode. + +## Saving And Exporting + +The editor supports two output paths: + +- Export JSON downloads the current `MapNode[]` as `map.json`. +- Save to Server posts the current `MapNode[]` to `/api/save-map`. + +The dev-only `/api/save-map` endpoint is implemented by the Vite plugin in `vite.config.ts`. It writes to `public/map.json` and enforces a maximum payload size. + +## Styling + +Editor styles are in `src/index.css` under the `/* Editor page */` section. Classes are prefixed with `editor-` to avoid collisions with the game UI. + +## Known Limitations + +- Uploaded model object URLs are not currently revoked after replacement or unmount. +- Large `map.json` files are not virtualized, culled, or LOD-managed. +- There is no snap-to-grid, duplication, material editing, or object creation workflow. +- Save to Server is a Vite dev-server helper, not a production backend API. diff --git a/docs/technical/target-architecture.md b/docs/technical/target-architecture.md index 9ad9c0e..80efa9f 100644 --- a/docs/technical/target-architecture.md +++ b/docs/technical/target-architecture.md @@ -5,7 +5,7 @@ This document describes the intended medium-term architecture for the project. ## Relationship To The Current Code - `docs/technical/architecture.md` is the source of truth for what exists now. -- This document is intentionally aspirational. +- This document describes intended direction, not implemented behavior. - If this document conflicts with the current implementation, the current implementation wins. ## Goals @@ -40,12 +40,12 @@ This document describes the intended medium-term architecture for the project. - performance overlay - scene helpers - free camera and calibration controls - - temporary test scenes used during development + - debug test scenes used during development ### UI Layer - `src/components/ui/` should contain player-facing HTML overlays. -- Expected future examples: +- Candidate examples: - crosshair - loading flow - mission HUD @@ -54,7 +54,7 @@ This document describes the intended medium-term architecture for the project. ### Gameplay Layer - As the project grows, gameplay state can move toward a clearer orchestration layer. -- Likely future concerns: +- Likely concerns: - missions - zones - cinematics @@ -67,4 +67,4 @@ This document describes the intended medium-term architecture for the project. - Prefer direct, working code over speculative scaffolding. - Shared types should stay close to their domain until they have multiple real consumers. - Avoid creating new managers or service layers without an active runtime need. -- Debug-only runtime paths should be clearly marked and easy to remove later. +- Debug-only runtime paths should be clearly marked and easy to remove when obsolete. diff --git a/docs/user/editor.md b/docs/user/editor.md new file mode 100644 index 0000000..1c92b74 --- /dev/null +++ b/docs/user/editor.md @@ -0,0 +1,83 @@ +# Editor User Guide + +The map editor is available at `/editor`. It is a browser-based tool for inspecting and adjusting the objects listed in `public/map.json`. + +## Purpose + +Use the editor when you need to move, rotate, or scale existing map objects without editing JSON by hand. + +The editor reads the same map data as the runtime scene: + +- `public/map.json` contains the object list. +- `public/models/{name}/model.gltf` contains the matching 3D model for each object name. +- Missing models are displayed as gray fallback cubes, so incomplete maps remain editable. + +## Map Node Format + +Each entry in `public/map.json` represents one object: + +| Field | Description | +| ---------- | ------------------------------------------------- | +| `name` | Model folder name in `public/models/{name}` | +| `type` | Object category | +| `position` | Object position as `[x, y, z]` | +| `rotation` | Object rotation as `[x, y, z]`, expressed radians | +| `scale` | Object scale as `[x, y, z]` | + +## Editing Workflow + +1. Open `/editor` in the local app. +2. Click an object in the scene to select it. +3. Choose a transform mode: translate, rotate, or scale. +4. Drag the transform gizmo in the 3D view. +5. Check the JSON inspector if you need exact values. +6. Use undo or redo if the transform is not correct. +7. Export the JSON or save it to the dev server. + +## Controls + +| Action | Input | +| -------------------- | -------------------------- | +| Select object | Click object | +| Deselect | `Esc` or click empty space | +| Translate mode | `T` | +| Rotate mode | `R` | +| Scale mode | `S` | +| Undo | `Ctrl+Z` | +| Redo | `Ctrl+Y` | +| Locked view movement | `WASD`, `ZQSD`, arrows | +| Move up | `Space` | +| Move down | `Shift` | + +## View Mode + +The `Lock view` action switches the editor into a movement mode closer to the runtime player camera. Use it to navigate larger scenes while keeping the transform tools available. + +## JSON Inspector + +The side panel includes a raw JSON inspector: + +- When no object is selected, it shows the full map node list. +- When an object is selected, it highlights the JSON lines for that object. + +This is useful for checking numeric transform values before saving or exporting. + +## Saving Changes + +### Export JSON + +`Export JSON` downloads the current map node list as `map.json`. Use this when you want to manually replace `public/map.json`. + +### Save To Server + +`Save to server` is available only during local development. It writes the edited map back to `public/map.json` through the Vite dev-server endpoint. + +The button is hidden in production builds because production persistence is not implemented. + +## Current Limitations + +- The editor only modifies existing nodes. +- It does not create or delete objects. +- It does not edit model files or textures. +- It does not provide production persistence. +- Fallback cubes indicate missing models; they are editor placeholders, not exported assets. diff --git a/docs/user/features.md b/docs/user/features.md index 133c126..a04fb80 100644 --- a/docs/user/features.md +++ b/docs/user/features.md @@ -5,7 +5,7 @@ This document lists features that are implemented in the current codebase. ## Scene - Fullscreen React Three Fiber scene -- Main map scene loaded from `public/models/map/model.gltf` +- Main map scene loaded from `public/map.json` and matching `public/models/{name}/model.gltf` assets - Debug physics test scene selectable from the debug panel - Ambient and directional lighting - Environment background setup @@ -38,6 +38,20 @@ This document lists features that are implemented in the current codebase. - Free debug camera - `r3f-perf` overlay +## Map Editor + +- `/editor` route for inspecting and editing `public/map.json` +- Automatic loading of `public/map.json` when available +- Folder upload fallback when `map.json` is missing +- Rendering of available `public/models/{name}/model.gltf` assets +- Fallback cubes for nodes whose model is missing +- Object selection by click +- Transform modes for translate, rotate, and scale +- Keyboard shortcuts for `T`, `R`, `S`, `Esc`, undo, and redo +- Player-style navigation mode with `WASD`, `ZQSD`, arrow keys, `Space`, and `Shift` +- JSON export for downloading the edited map +- Dev-server save endpoint for writing changes back to `public/map.json` + ## Not Implemented Yet - mission system @@ -47,3 +61,4 @@ This document lists features that are implemented in the current codebase. - loading flow - minimap and mission HUD - full production separation between gameplay and debug scenes +- production backend persistence for editor saves diff --git a/nixpacks.toml b/nixpacks.toml new file mode 100644 index 0000000..893fc4a --- /dev/null +++ b/nixpacks.toml @@ -0,0 +1,2 @@ +[phases.setup] +nixPkgs = ["nodejs"] \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 4fbc348..aa6d43a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,11 +12,15 @@ "@react-three/fiber": "^9.6.0", "@react-three/postprocessing": "^3.0.4", "@react-three/rapier": "^2.2.0", + "@tanstack/react-router": "^1.168.25", "gsap": "^3.15.0", "lil-gui": "^0.21.0", + "lucide-react": "^1.11.0", "r3f-perf": "^7.2.3", "react": "^19.2.4", "react-dom": "^19.2.4", + "react-markdown": "^10.1.0", + "remark-gfm": "^4.0.1", "three": "^0.183.2" }, "devDependencies": { @@ -35,6 +39,9 @@ "typescript": "~6.0.2", "typescript-eslint": "^8.58.0", "vite": "^8.0.4" + }, + "engines": { + "node": ">=20.19.0 || >=22.12.0" } }, "node_modules/@babel/code-frame": { @@ -668,18 +675,6 @@ "react": "^16.x || ^17.x || ^18.x || ^19.0.0 || ^19.0.0-rc" } }, - "node_modules/@react-spring/rafz": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/@react-spring/rafz/-/rafz-9.7.5.tgz", - "integrity": "sha512-5ZenDQMC48wjUzPAm1EtwQ5Ot3bLIAwwqP2w2owG5KoNdNHpEJV263nGhCeKKmuA3vG2zLLOdu3or6kuDjA6Aw==", - "license": "MIT" - }, - "node_modules/@react-spring/types": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/@react-spring/types/-/types-9.7.5.tgz", - "integrity": "sha512-HVj7LrZ4ReHWBimBvu2SKND3cDVUPWKLqRTmWe/fNY6o1owGOX0cAHbdPDTMelgBlVbrTKrre6lFkhqGZErK/g==", - "license": "MIT" - }, "node_modules/@react-three/drei": { "version": "10.7.7", "resolved": "https://registry.npmjs.org/@react-three/drei/-/drei-10.7.7.tgz", @@ -902,9 +897,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -922,9 +914,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -942,9 +931,6 @@ "ppc64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -962,9 +948,6 @@ "s390x" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -982,9 +965,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MIT", "optional": true, "os": [ @@ -1002,9 +982,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MIT", "optional": true, "os": [ @@ -1100,6 +1077,92 @@ "react": ">= 16.3.0" } }, + "node_modules/@tanstack/history": { + "version": "1.161.6", + "resolved": "https://registry.npmjs.org/@tanstack/history/-/history-1.161.6.tgz", + "integrity": "sha512-NaOGLRrddszbQj9upGat6HG/4TKvXLvu+osAIgfxPYA+eIvYKv8GKDJOrY2D3/U9MRnKfMWD7bU4jeD4xmqyIg==", + "license": "MIT", + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-router": { + "version": "1.168.25", + "resolved": "https://registry.npmjs.org/@tanstack/react-router/-/react-router-1.168.25.tgz", + "integrity": "sha512-4U/E76dc+fYuLixjV1RLNfqrkQoexSL8MqGNpIHOodtvY3fMPGaALrvDVtBDQYBEU4z5r5fHaV6+kclWAVFP9A==", + "license": "MIT", + "dependencies": { + "@tanstack/history": "1.161.6", + "@tanstack/react-store": "^0.9.3", + "@tanstack/router-core": "1.168.17", + "isbot": "^5.1.22" + }, + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=18.0.0 || >=19.0.0", + "react-dom": ">=18.0.0 || >=19.0.0" + } + }, + "node_modules/@tanstack/react-store": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@tanstack/react-store/-/react-store-0.9.3.tgz", + "integrity": "sha512-y2iHd/N9OkoQbFJLUX1T9vbc2O9tjH0pQRgTcx1/Nz4IlwLvkgpuglXUx+mXt0g5ZDFrEeDnONPqkbfxXJKwRg==", + "license": "MIT", + "dependencies": { + "@tanstack/store": "0.9.3", + "use-sync-external-store": "^1.6.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@tanstack/router-core": { + "version": "1.168.17", + "resolved": "https://registry.npmjs.org/@tanstack/router-core/-/router-core-1.168.17.tgz", + "integrity": "sha512-VDq7HCqRK3sdpxoETwYoTXTaYi+OVQC197g1fdzaiZBUmhntfjn+PQc15OzTqNNhf8Menk6r6ftmuphybMKdig==", + "license": "MIT", + "dependencies": { + "@tanstack/history": "1.161.6", + "cookie-es": "^3.0.0", + "seroval": "^1.5.0", + "seroval-plugins": "^1.5.0" + }, + "bin": { + "intent": "bin/intent.js" + }, + "engines": { + "node": ">=20.19" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/store": { + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/@tanstack/store/-/store-0.9.3.tgz", + "integrity": "sha512-8reSzl/qGWGGVKhBoxXPMWzATSbZLZFWhwBAFO9NAyp0TxzfBP0mIrGb8CP8KrQTmvzXlR/vFPPUrHTLBGyFyw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, "node_modules/@tweenjs/tween.js": { "version": "23.1.3", "resolved": "https://registry.npmjs.org/@tweenjs/tween.js/-/tween.js-23.1.3.tgz", @@ -1117,6 +1180,15 @@ "tslib": "^2.4.0" } }, + "node_modules/@types/debug": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.13.tgz", + "integrity": "sha512-KSVgmQmzMwPlmtljOomayoR89W4FynCAi3E8PPs7vmDVPe84hT+vGPKkJfThkmXs0x0jAaa9U8uW8bbfyS2fWw==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/draco3d": { "version": "1.4.10", "resolved": "https://registry.npmjs.org/@types/draco3d/-/draco3d-1.4.10.tgz", @@ -1127,9 +1199,26 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", - "dev": true, "license": "MIT" }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "license": "MIT", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -1137,6 +1226,21 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/mdast": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz", + "integrity": "sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, "node_modules/@types/node": { "version": "24.12.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-24.12.2.tgz", @@ -1207,6 +1311,12 @@ "integrity": "sha512-uekIGetywIgopfD97oDL5PfeezkFpNhwlzlaEYNOA0N6ghdsOvh/HYjSMek5Q2O1PYvRSDFcqFVJl4r4ZBwOow==", "license": "Apache-2.0" }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==", + "license": "MIT" + }, "node_modules/@types/webxr": { "version": "0.5.24", "resolved": "https://registry.npmjs.org/@types/webxr/-/webxr-0.5.24.tgz", @@ -1214,17 +1324,17 @@ "license": "MIT" }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.0.tgz", - "integrity": "sha512-HyAZtpdkgZwpq8Sz3FSUvCR4c+ScbuWa9AksK2Jweub7w4M3yTz4O11AqVJzLYjy/B9ZWPyc81I+mOdJU/bDQw==", + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.59.1.tgz", + "integrity": "sha512-BOziFIfE+6osHO9FoJG4zjoHUcvI7fTNBSpdAwrNH0/TLvzjsk2oo8XSSOT2HhqUyhZPfHv4UOffoJ9oEEQ7Ag==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", - "@typescript-eslint/scope-manager": "8.59.0", - "@typescript-eslint/type-utils": "8.59.0", - "@typescript-eslint/utils": "8.59.0", - "@typescript-eslint/visitor-keys": "8.59.0", + "@typescript-eslint/scope-manager": "8.59.1", + "@typescript-eslint/type-utils": "8.59.1", + "@typescript-eslint/utils": "8.59.1", + "@typescript-eslint/visitor-keys": "8.59.1", "ignore": "^7.0.5", "natural-compare": "^1.4.0", "ts-api-utils": "^2.5.0" @@ -1237,7 +1347,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.59.0", + "@typescript-eslint/parser": "^8.59.1", "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } @@ -1253,16 +1363,16 @@ } }, "node_modules/@typescript-eslint/parser": { - "version": "8.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.0.tgz", - "integrity": "sha512-TI1XGwKbDpo9tRW8UDIXCOeLk55qe9ZFGs8MTKU6/M08HWTw52DD/IYhfQtOEhEdPhLMT26Ka/x7p70nd3dzDg==", + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.59.1.tgz", + "integrity": "sha512-HDQH9O/47Dxi1ceDhBXdaldtf/WV9yRYMjbjCuNk3qnaTD564qwv61Y7+gTxwxRKzSrgO5uhtw584igXVuuZkA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/scope-manager": "8.59.0", - "@typescript-eslint/types": "8.59.0", - "@typescript-eslint/typescript-estree": "8.59.0", - "@typescript-eslint/visitor-keys": "8.59.0", + "@typescript-eslint/scope-manager": "8.59.1", + "@typescript-eslint/types": "8.59.1", + "@typescript-eslint/typescript-estree": "8.59.1", + "@typescript-eslint/visitor-keys": "8.59.1", "debug": "^4.4.3" }, "engines": { @@ -1278,14 +1388,14 @@ } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.0.tgz", - "integrity": "sha512-Lw5ITrR5s5TbC19YSvlr63ZfLaJoU6vtKTHyB0GQOpX0W7d5/Ir6vUahWi/8Sps/nOukZQ0IB3SmlxZnjaKVnw==", + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.59.1.tgz", + "integrity": "sha512-+MuHQlHiEr00Of/IQbE/MmEoi44znZHbR/Pz7Opq4HryUOlRi+/44dro9Ycy8Fyo+/024IWtw8m4JUMCGTYxDg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.59.0", - "@typescript-eslint/types": "^8.59.0", + "@typescript-eslint/tsconfig-utils": "^8.59.1", + "@typescript-eslint/types": "^8.59.1", "debug": "^4.4.3" }, "engines": { @@ -1300,14 +1410,14 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.0.tgz", - "integrity": "sha512-UzR16Ut8IpA3Mc4DbgAShlPPkVm8xXMWafXxB0BocaVRHs8ZGakAxGRskF7FId3sdk9lgGD73GSFaWmWFDE4dg==", + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.59.1.tgz", + "integrity": "sha512-LwuHQI4pDOYVKvmH2dkaJo6YZCSgouVgnS/z7yBPKBMvgtBvyLqiLy9Z6b7+m/TRcX1NFYUqZetI5Y+aT4GEfg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.59.0", - "@typescript-eslint/visitor-keys": "8.59.0" + "@typescript-eslint/types": "8.59.1", + "@typescript-eslint/visitor-keys": "8.59.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1318,9 +1428,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.0.tgz", - "integrity": "sha512-91Sbl3s4Kb3SybliIY6muFBmHVv+pYXfybC4Oolp3dvk8BvIE3wOPc+403CWIT7mJNkfQRGtdqghzs2+Z91Tqg==", + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.59.1.tgz", + "integrity": "sha512-/0nEyPbX7gRsk0Uwfe4ALwwgxuA66d/l2mhRDNlAvaj4U3juhUtJNq0DsY8M2AYwwb9rEq2hrC3IcIcEt++iJA==", "dev": true, "license": "MIT", "engines": { @@ -1335,15 +1445,15 @@ } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.0.tgz", - "integrity": "sha512-3TRiZaQSltGqGeNrJzzr1+8YcEobKH9rHnqIp/1psfKFmhRQDNMGP5hBufanYTGznwShzVLs3Mz+gDN7HkWfXg==", + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.59.1.tgz", + "integrity": "sha512-klWPBR2ciQHS3f++ug/mVnWKPjBUo7icEL3FAO1lhAR1Z1i5NQYZ1EannMSRYcq5qCv5wNALlXr6fksRHyYl7w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.59.0", - "@typescript-eslint/typescript-estree": "8.59.0", - "@typescript-eslint/utils": "8.59.0", + "@typescript-eslint/types": "8.59.1", + "@typescript-eslint/typescript-estree": "8.59.1", + "@typescript-eslint/utils": "8.59.1", "debug": "^4.4.3", "ts-api-utils": "^2.5.0" }, @@ -1360,9 +1470,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "8.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.0.tgz", - "integrity": "sha512-nLzdsT1gdOgFxxxwrlNVUBzSNBEEHJ86bblmk4QAS6stfig7rcJzWKqCyxFy3YRRHXDWEkb2NralA1nOYkkm/A==", + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.59.1.tgz", + "integrity": "sha512-ZDCjgccSdYPw5Bxh+my4Z0lJU96ZDN7jbBzvmEn0FZx3RtU1C7VWl6NbDx94bwY3V5YsgwRzJPOgeY2Q/nLG8A==", "dev": true, "license": "MIT", "engines": { @@ -1374,16 +1484,16 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.0.tgz", - "integrity": "sha512-O9Re9P1BmBLFJyikRbQpLku/QA3/AueZNO9WePLBwQrvkixTmDe8u76B6CYUAITRl/rHawggEqUGn5QIkVRLMw==", + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.59.1.tgz", + "integrity": "sha512-OUd+vJS05sSkOip+BkZ/2NS8RMxrAAJemsC6vU3kmfLyeaJT0TftHkV9mcx2107MmsBVXXexhVu4F0TZXyMl4g==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.59.0", - "@typescript-eslint/tsconfig-utils": "8.59.0", - "@typescript-eslint/types": "8.59.0", - "@typescript-eslint/visitor-keys": "8.59.0", + "@typescript-eslint/project-service": "8.59.1", + "@typescript-eslint/tsconfig-utils": "8.59.1", + "@typescript-eslint/types": "8.59.1", + "@typescript-eslint/visitor-keys": "8.59.1", "debug": "^4.4.3", "minimatch": "^10.2.2", "semver": "^7.7.3", @@ -1454,16 +1564,16 @@ } }, "node_modules/@typescript-eslint/utils": { - "version": "8.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.0.tgz", - "integrity": "sha512-I1R/K7V07XsMJ12Oaxg/O9GfrysGTmCRhvZJBv0RE0NcULMzjqVpR5kRRQjHsz3J/bElU7HwCO7zkqL+MSUz+g==", + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.59.1.tgz", + "integrity": "sha512-3pIeoXhCeYH9FSCBI8P3iNwJlGuzPlYKkTlen2O9T1DSeeg8UG8jstq6BLk+Mda0qup7mgk4z4XL4OzRaxZ8LA==", "dev": true, "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", - "@typescript-eslint/scope-manager": "8.59.0", - "@typescript-eslint/types": "8.59.0", - "@typescript-eslint/typescript-estree": "8.59.0" + "@typescript-eslint/scope-manager": "8.59.1", + "@typescript-eslint/types": "8.59.1", + "@typescript-eslint/typescript-estree": "8.59.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -1478,13 +1588,13 @@ } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.59.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.0.tgz", - "integrity": "sha512-/uejZt4dSere1bx12WLlPfv8GktzcaDtuJ7s42/HEZ5zGj9oxRaD4bj7qwSunXkf+pbAhFt2zjpHYUiT5lHf0Q==", + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.59.1.tgz", + "integrity": "sha512-LdDNl6C5iJExcM0Yh0PwAIBb9PrSiCsWamF/JyEZawm3kFDnRoaq3LGE4bpyRao/fWeGKKyw7icx0YxrLFC5Cg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.59.0", + "@typescript-eslint/types": "8.59.1", "eslint-visitor-keys": "^5.0.0" }, "engines": { @@ -1508,6 +1618,12 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@ungap/structured-clone": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.3.0.tgz", + "integrity": "sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==", + "license": "ISC" + }, "node_modules/@use-gesture/core": { "version": "10.3.1", "resolved": "https://registry.npmjs.org/@use-gesture/core/-/core-10.3.1.tgz", @@ -1632,6 +1748,16 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/bail": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -1794,6 +1920,16 @@ ], "license": "CC-BY-4.0" }, + "node_modules/ccount": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -1811,6 +1947,46 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/character-entities": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -1831,6 +2007,16 @@ "dev": true, "license": "MIT" }, + "node_modules/comma-separated-tokens": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -1845,6 +2031,12 @@ "dev": true, "license": "MIT" }, + "node_modules/cookie-es": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/cookie-es/-/cookie-es-3.1.1.tgz", + "integrity": "sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==", + "license": "MIT" + }, "node_modules/cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", @@ -1887,7 +2079,6 @@ "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -1901,6 +2092,19 @@ } } }, + "node_modules/decode-named-character-reference": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.3.0.tgz", + "integrity": "sha512-GtpQYB283KrPp6nRw50q3U9/VfOutZOe103qlN7BPP6Ad27xYnOIWv4lPzo8HCAL+mMZofJ9KEy30fq6MfaK6Q==", + "license": "MIT", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -1908,6 +2112,15 @@ "dev": true, "license": "MIT" }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/detect-gpu": { "version": "5.0.70", "resolved": "https://registry.npmjs.org/detect-gpu/-/detect-gpu-5.0.70.tgz", @@ -1927,6 +2140,19 @@ "node": ">=8" } }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/draco3d": { "version": "1.5.7", "resolved": "https://registry.npmjs.org/draco3d/-/draco3d-1.5.7.tgz", @@ -2184,6 +2410,16 @@ "node": ">=4.0" } }, + "node_modules/estree-util-is-identifier-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-3.0.0.tgz", + "integrity": "sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", @@ -2200,6 +2436,12 @@ "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", "license": "MIT" }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "license": "MIT" + }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -2376,6 +2618,46 @@ "node": ">=8" } }, + "node_modules/hast-util-to-jsx-runtime": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.6.tgz", + "integrity": "sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==", + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "estree-util-is-identifier-name": "^3.0.0", + "hast-util-whitespace": "^3.0.0", + "mdast-util-mdx-expression": "^2.0.0", + "mdast-util-mdx-jsx": "^3.0.0", + "mdast-util-mdxjs-esm": "^2.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-js": "^1.0.0", + "unist-util-position": "^5.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-whitespace": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", + "integrity": "sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hermes-estree": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/hermes-estree/-/hermes-estree-0.25.1.tgz", @@ -2399,6 +2681,16 @@ "integrity": "sha512-VSIRpLfRwlAAdGL4wiTucx2ScRipo0ed1FBatWkyt832jC4CReKstga6yIhYVwGu9LOBjuX9wzmRMeQdBJtzEA==", "license": "Apache-2.0" }, + "node_modules/html-url-attributes": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-url-attributes/-/html-url-attributes-3.0.1.tgz", + "integrity": "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", @@ -2462,6 +2754,46 @@ "node": ">=0.8.19" } }, + "node_modules/inline-style-parser": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/inline-style-parser/-/inline-style-parser-0.2.7.tgz", + "integrity": "sha512-Nb2ctOyNR8DqQoR0OwRG95uNWIC0C1lCgf5Naz5H6Ji72KZ8OcFZLz2P5sNgwlyoJ8Yif11oMuYs5pBQa86csA==", + "license": "MIT" + }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -2485,12 +2817,43 @@ "node": ">=0.10.0" } }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/is-promise": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", "license": "MIT" }, + "node_modules/isbot": { + "version": "5.1.39", + "resolved": "https://registry.npmjs.org/isbot/-/isbot-5.1.39.tgz", + "integrity": "sha512-obH0yYahGXdzNxo+djmHhBYThUKDkz565cxkIlt2L9hXfv1NlaLKoDBHo6KxXsYrIXx2RK3x5vY36CfZcobxEw==", + "license": "Unlicense", + "engines": { + "node": ">=18" + } + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -2513,6 +2876,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, "license": "MIT" }, "node_modules/js-yaml": { @@ -2751,9 +3115,6 @@ "arm64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -2775,9 +3136,6 @@ "arm64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -2799,9 +3157,6 @@ "x64" ], "dev": true, - "libc": [ - "glibc" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -2823,9 +3178,6 @@ "x64" ], "dev": true, - "libc": [ - "musl" - ], "license": "MPL-2.0", "optional": true, "os": [ @@ -2910,16 +3262,14 @@ "dev": true, "license": "MIT" }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "node_modules/longest-streak": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", "license": "MIT", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, "node_modules/lru-cache": { @@ -2932,6 +3282,15 @@ "yallist": "^3.0.2" } }, + "node_modules/lucide-react": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.11.0.tgz", + "integrity": "sha512-UOhjdztXCgdBReRcIhsvz2siIBogfv/lhJEIViCpLt924dO+GDms9T7DNoucI23s6kEPpe988m5N0D2ajnzb2g==", + "license": "ISC", + "peerDependencies": { + "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, "node_modules/maath": { "version": "0.10.8", "resolved": "https://registry.npmjs.org/maath/-/maath-0.10.8.tgz", @@ -2942,6 +3301,298 @@ "three": ">=0.134.0" } }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-find-and-replace": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-3.0.2.tgz", + "integrity": "sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "escape-string-regexp": "^5.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-find-and-replace/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mdast-util-from-markdown": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-2.0.3.tgz", + "integrity": "sha512-W4mAWTvSlKvf8L6J+VN9yLSqQ9AOAAvHuoDAmPkz4dHf553m5gVj2ejadHJhoJmcmxEnOv6Pa8XJhpxE93kb8Q==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark": "^4.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", + "integrity": "sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-3.2.0.tgz", + "integrity": "sha512-lj/z8v0r6ZtsN/cGNNtemmmfoLAFZnjMbNyLzBafjzikOM+glrjNHPlf6lQDOTccj9n5b0PPihEBbhneMyGs1Q==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "ccount": "^2.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-stringify-position": "^4.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-2.0.1.tgz", + "integrity": "sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==", + "license": "MIT", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-4.1.0.tgz", + "integrity": "sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-13.2.1.tgz", + "integrity": "sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "@ungap/structured-clone": "^1.0.0", + "devlop": "^1.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "trim-lines": "^3.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-2.1.2.tgz", + "integrity": "sha512-xj68wMTvGXVOKonmog6LwyJKrYXZPvlwabaryTjLh9LuvovB/KAH+kvi8Gjj+7rJjsFi23nkUxRQv1KqSroMqA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "@types/unist": "^3.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^4.0.0", + "mdast-util-to-string": "^4.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-decode-string": "^2.0.0", + "unist-util-visit": "^5.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-4.0.0.tgz", + "integrity": "sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/meshline": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/meshline/-/meshline-3.3.1.tgz", @@ -2957,6 +3608,569 @@ "integrity": "sha512-oRFNWJRDA/WTrVj7NWvqa5HqE1t9MYDj2VaWirQCzCCrAd2GHrqR/sQezCxiWATPNlKTcRaPRHPJwIRoPBAp5g==", "license": "MIT" }, + "node_modules/micromark": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.2.tgz", + "integrity": "sha512-zpe98Q6kvavpCr1NPVSCMebCKfD7CA2NqZ+rykeNhONIJBpc1tFKt9hucLGwha3jNTNI8lHpctWJWoimVF4PfA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.3.tgz", + "integrity": "sha512-RDBrHEMSxVFLg6xvnXmb1Ayr2WzLAWjeSATAoxwKYJV94TeNavgoIdA0a9ytzDSVzBy2YKFK+emCPOEibLeCrg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-decode-string": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-2.0.1.tgz", + "integrity": "sha512-nDV/77Fj6eH1ynwscYTOsbK7rR//Uj0bZXBwJZRfaLEJ1iGBR6kIfNmlNqaqJf649EP0F3NWNdeJi03elllNUQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, "node_modules/minimatch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", @@ -2974,7 +4188,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/n8ao": { @@ -3020,15 +4233,6 @@ "dev": true, "license": "MIT" }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -3092,6 +4296,31 @@ "node": ">=6" } }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/parse-entities/node_modules/@types/unist": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", + "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==", + "license": "MIT" + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -3224,15 +4453,14 @@ "lie": "^3.0.2" } }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", "license": "MIT", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, "node_modules/punycode": { @@ -3275,168 +4503,6 @@ } } }, - "node_modules/r3f-perf/node_modules/@react-three/drei": { - "version": "9.122.0", - "resolved": "https://registry.npmjs.org/@react-three/drei/-/drei-9.122.0.tgz", - "integrity": "sha512-SEO/F/rBCTjlLez7WAlpys+iGe9hty4rNgjZvgkQeXFSiwqD4Hbk/wNHMAbdd8vprO2Aj81mihv4dF5bC7D0CA==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.26.0", - "@mediapipe/tasks-vision": "0.10.17", - "@monogrid/gainmap-js": "^3.0.6", - "@react-spring/three": "~9.7.5", - "@use-gesture/react": "^10.3.1", - "camera-controls": "^2.9.0", - "cross-env": "^7.0.3", - "detect-gpu": "^5.0.56", - "glsl-noise": "^0.0.0", - "hls.js": "^1.5.17", - "maath": "^0.10.8", - "meshline": "^3.3.1", - "react-composer": "^5.0.3", - "stats-gl": "^2.2.8", - "stats.js": "^0.17.0", - "suspend-react": "^0.1.3", - "three-mesh-bvh": "^0.7.8", - "three-stdlib": "^2.35.6", - "troika-three-text": "^0.52.0", - "tunnel-rat": "^0.1.2", - "utility-types": "^3.11.0", - "zustand": "^5.0.1" - }, - "peerDependencies": { - "@react-three/fiber": "^8", - "react": "^18", - "react-dom": "^18", - "three": ">=0.137" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - } - } - }, - "node_modules/r3f-perf/node_modules/@react-three/drei/node_modules/@react-spring/three": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/@react-spring/three/-/three-9.7.5.tgz", - "integrity": "sha512-RxIsCoQfUqOS3POmhVHa1wdWS0wyHAUway73uRLp3GAL5U2iYVNdnzQsep6M2NZ994BlW8TcKuMtQHUqOsy6WA==", - "license": "MIT", - "dependencies": { - "@react-spring/animated": "~9.7.5", - "@react-spring/core": "~9.7.5", - "@react-spring/shared": "~9.7.5", - "@react-spring/types": "~9.7.5" - }, - "peerDependencies": { - "@react-three/fiber": ">=6.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "three": ">=0.126" - } - }, - "node_modules/r3f-perf/node_modules/@react-three/drei/node_modules/@react-spring/three/node_modules/@react-spring/animated": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/@react-spring/animated/-/animated-9.7.5.tgz", - "integrity": "sha512-Tqrwz7pIlsSDITzxoLS3n/v/YCUHQdOIKtOJf4yL6kYVSDTSmVK1LI1Q3M/uu2Sx4X3pIWF3xLUhlsA6SPNTNg==", - "license": "MIT", - "dependencies": { - "@react-spring/shared": "~9.7.5", - "@react-spring/types": "~9.7.5" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/r3f-perf/node_modules/@react-three/drei/node_modules/@react-spring/three/node_modules/@react-spring/core": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/@react-spring/core/-/core-9.7.5.tgz", - "integrity": "sha512-rmEqcxRcu7dWh7MnCcMXLvrf6/SDlSokLaLTxiPlAYi11nN3B5oiCUAblO72o+9z/87j2uzxa2Inm8UbLjXA+w==", - "license": "MIT", - "dependencies": { - "@react-spring/animated": "~9.7.5", - "@react-spring/shared": "~9.7.5", - "@react-spring/types": "~9.7.5" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/react-spring/donate" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/r3f-perf/node_modules/@react-three/drei/node_modules/@react-spring/three/node_modules/@react-spring/shared": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/@react-spring/shared/-/shared-9.7.5.tgz", - "integrity": "sha512-wdtoJrhUeeyD/PP/zo+np2s1Z820Ohr/BbuVYv+3dVLW7WctoiN7std8rISoYoHpUXtbkpesSKuPIw/6U1w1Pw==", - "license": "MIT", - "dependencies": { - "@react-spring/rafz": "~9.7.5", - "@react-spring/types": "~9.7.5" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/r3f-perf/node_modules/@react-three/drei/node_modules/react-composer": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/react-composer/-/react-composer-5.0.3.tgz", - "integrity": "sha512-1uWd07EME6XZvMfapwZmc7NgCZqDemcvicRi3wMJzXsQLvZ3L7fTHVyPy1bZdnWXM4iPjYuNE+uJ41MLKeTtnA==", - "license": "MIT", - "dependencies": { - "prop-types": "^15.6.0" - }, - "peerDependencies": { - "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/r3f-perf/node_modules/@react-three/drei/node_modules/zustand": { - "version": "5.0.12", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.12.tgz", - "integrity": "sha512-i77ae3aZq4dhMlRhJVCYgMLKuSiZAaUPAct2AksxQ+gOtimhGMdXljRT21P5BNpeT4kXlLIckvkPM029OljD7g==", - "license": "MIT", - "engines": { - "node": ">=12.20.0" - }, - "peerDependencies": { - "@types/react": ">=18.0.0", - "immer": ">=9.0.6", - "react": ">=18.0.0", - "use-sync-external-store": ">=1.2.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "immer": { - "optional": true - }, - "react": { - "optional": true - }, - "use-sync-external-store": { - "optional": true - } - } - }, - "node_modules/r3f-perf/node_modules/camera-controls": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/camera-controls/-/camera-controls-2.10.1.tgz", - "integrity": "sha512-KnaKdcvkBJ1Irbrzl8XD6WtZltkRjp869Jx8c0ujs9K+9WD+1D7ryBsCiVqJYUqt6i/HR5FxT7RLASieUD+Q5w==", - "license": "MIT", - "peerDependencies": { - "three": ">=0.126.1" - } - }, - "node_modules/r3f-perf/node_modules/three-mesh-bvh": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/three-mesh-bvh/-/three-mesh-bvh-0.7.8.tgz", - "integrity": "sha512-BGEZTOIC14U0XIRw3tO4jY7IjP7n7v24nv9JXS1CyeVRWOCkcOMhRnmENUjuV39gktAw4Ofhr0OvIAiTspQrrw==", - "deprecated": "Deprecated due to three.js version incompatibility. Please use v0.8.0, instead.", - "license": "MIT", - "peerDependencies": { - "three": ">= 0.151.0" - } - }, "node_modules/r3f-perf/node_modules/zustand": { "version": "4.5.7", "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz", @@ -3486,11 +4552,32 @@ "react": "^19.2.5" } }, - "node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "license": "MIT" + "node_modules/react-markdown": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-10.1.0.tgz", + "integrity": "sha512-qKxVopLT/TyA6BX3Ue5NwabOsAzm0Q7kAPwq6L+wWDwisYs7R8vZ0nRXqq6rkueboxpkjvLGU9fWifiX/ZZFxQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "hast-util-to-jsx-runtime": "^2.0.0", + "html-url-attributes": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "remark-parse": "^11.0.0", + "remark-rehype": "^11.0.0", + "unified": "^11.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=18", + "react": ">=18" + } }, "node_modules/react-use-measure": { "version": "2.1.7", @@ -3507,6 +4594,72 @@ } } }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-parse": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", + "integrity": "sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "micromark-util-types": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-rehype": { + "version": "11.1.2", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-11.1.2.tgz", + "integrity": "sha512-Dh7l57ianaEoIpzbp0PC9UKAdCSVklD8E5Rpw7ETfbTl3FqcOOgq5q2LVDhgGCkaBv7p24JXikPdvhhmHvKMsw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/mdast": "^4.0.0", + "mdast-util-to-hast": "^13.0.0", + "unified": "^11.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/require-from-string": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", @@ -3583,6 +4736,27 @@ "semver": "bin/semver.js" } }, + "node_modules/seroval": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/seroval/-/seroval-1.5.2.tgz", + "integrity": "sha512-xcRN39BdsnO9Tf+VzsE7b3JyTJASItIV1FVFewJKCFcW4s4haIKS3e6vj8PGB9qBwC7tnuOywQMdv5N4qkzi7Q==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/seroval-plugins": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/seroval-plugins/-/seroval-plugins-1.5.2.tgz", + "integrity": "sha512-qpY0Cl+fKYFn4GOf3cMiq6l72CpuVaawb6ILjubOQ+diJ54LfOWaSSPsaswN8DRPIPW4Yq+tE1k5aKd7ILyaFg==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "seroval": "^1.0" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -3614,6 +4788,16 @@ "node": ">=0.10.0" } }, + "node_modules/space-separated-tokens": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/stats-gl": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/stats-gl/-/stats-gl-2.4.2.tgz", @@ -3640,6 +4824,20 @@ "integrity": "sha512-hNKz8phvYLPEcRkeG1rsGmV5ChMjKDAWU7/OJJdDErPBNChQXxCo3WZurGpnWc6gZhAzEPFad1aVgyOANH1sMw==", "license": "MIT" }, + "node_modules/stringify-entities": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", + "license": "MIT", + "dependencies": { + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -3653,6 +4851,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/style-to-js": { + "version": "1.1.21", + "resolved": "https://registry.npmjs.org/style-to-js/-/style-to-js-1.1.21.tgz", + "integrity": "sha512-RjQetxJrrUJLQPHbLku6U/ocGtzyjbJMP9lCNK7Ag0CNh690nSH8woqWH9u16nMjYBAok+i7JO1NP2pOy8IsPQ==", + "license": "MIT", + "dependencies": { + "style-to-object": "1.0.14" + } + }, + "node_modules/style-to-object": { + "version": "1.0.14", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-1.0.14.tgz", + "integrity": "sha512-LIN7rULI0jBscWQYaSswptyderlarFkjQ+t79nzty8tcIAceVomEVlLzH5VP4Cmsv6MtKhs7qaAiwlcp+Mgaxw==", + "license": "MIT", + "dependencies": { + "inline-style-parser": "0.2.7" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -3746,6 +4962,16 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/troika-three-text": { "version": "0.52.4", "resolved": "https://registry.npmjs.org/troika-three-text/-/troika-three-text-0.52.4.tgz", @@ -3776,6 +5002,16 @@ "integrity": "sha512-W1CpvTHykaPH5brv5VHLfQo9D1OYuo0cSBEUQFFT/nBUzM8iD6Lq2/tgG/f1OelbAS1WtaTPQzE5uM49egnngw==", "license": "MIT" }, + "node_modules/trough": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/ts-api-utils": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", @@ -3862,16 +5098,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.59.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.59.0.tgz", - "integrity": "sha512-BU3ONW9X+v90EcCH9ZS6LMackcVtxRLlI3XrYyqZIwVSHIk7Qf7bFw1z0M9Q0IUxhTMZCf8piY9hTYaNEIASrw==", + "version": "8.59.1", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.59.1.tgz", + "integrity": "sha512-xqDcFVBmlrltH64lklOVp1wYxgJr6LVdg3NamBgH2OOQDLFdTKfIZXF5PfghrnXQKXZGTQs8tr1vL7fJvq8CTQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.59.0", - "@typescript-eslint/parser": "8.59.0", - "@typescript-eslint/typescript-estree": "8.59.0", - "@typescript-eslint/utils": "8.59.0" + "@typescript-eslint/eslint-plugin": "8.59.1", + "@typescript-eslint/parser": "8.59.1", + "@typescript-eslint/typescript-estree": "8.59.1", + "@typescript-eslint/utils": "8.59.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3892,6 +5128,93 @@ "dev": true, "license": "MIT" }, + "node_modules/unified": { + "version": "11.0.5", + "resolved": "https://registry.npmjs.org/unified/-/unified-11.0.5.tgz", + "integrity": "sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "bail": "^2.0.0", + "devlop": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-6.0.1.tgz", + "integrity": "sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-position": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-5.0.0.tgz", + "integrity": "sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-4.0.0.tgz", + "integrity": "sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-5.1.0.tgz", + "integrity": "sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0", + "unist-util-visit-parents": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-6.0.2.tgz", + "integrity": "sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-is": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/update-browserslist-db": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.2.3.tgz", @@ -3951,6 +5274,34 @@ "node": ">= 4" } }, + "node_modules/vfile": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-6.0.3.tgz", + "integrity": "sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile-message": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.3.tgz", + "integrity": "sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "unist-util-stringify-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vite": { "version": "8.0.10", "resolved": "https://registry.npmjs.org/vite/-/vite-8.0.10.tgz", @@ -4136,6 +5487,16 @@ "optional": true } } + }, + "node_modules/zwitch": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } } } } diff --git a/package.json b/package.json index 3a737f0..e9c0ac5 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,9 @@ "private": true, "version": "0.0.1", "type": "module", + "engines": { + "node": ">=20.19.0 || >=22.12.0" + }, "scripts": { "dev": "vite", "build": "tsc -b && vite build", @@ -18,11 +21,15 @@ "@react-three/fiber": "^9.6.0", "@react-three/postprocessing": "^3.0.4", "@react-three/rapier": "^2.2.0", + "@tanstack/react-router": "^1.168.25", "gsap": "^3.15.0", "lil-gui": "^0.21.0", + "lucide-react": "^1.11.0", "r3f-perf": "^7.2.3", "react": "^19.2.4", "react-dom": "^19.2.4", + "react-markdown": "^10.1.0", + "remark-gfm": "^4.0.1", "three": "^0.183.2" }, "devDependencies": { @@ -41,5 +48,10 @@ "typescript": "~6.0.2", "typescript-eslint": "^8.58.0", "vite": "^8.0.4" + }, + "overrides": { + "r3f-perf": { + "@react-three/drei": "$@react-three/drei" + } } } diff --git a/public/map.json b/public/map.json index 0711cd5..25619f0 100644 --- a/public/map.json +++ b/public/map.json @@ -1,12428 +1,4587 @@ [ { - "name": "terrain", - "type": "Mesh", - "position": [ - -0.6455, - 0, - 5.6812 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "zone_ecole", + "name": "Neutre", "type": "Object3D", - "position": [ - 3.7017, - 28.0335, - 28.3142 - ], - "rotation": [ - 0.1129, - -1.4525, - 0.1096 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "terrainarbresecole", - "type": "Object3D", - "position": [ - -0.6455, - 0, - 5.6812 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "panneau", - "type": "Mesh", - "position": [ - 1.3128, - 26.9637, - 34.1952 - ], - "rotation": [ - 0.0126, - -0.5805, - 0.0154 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbres", - "type": "Object3D", - "position": [ - -0.8061, - 24.8656, - 24.8498 - ], - "rotation": [ - 0, - -0.7007, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - 13.7329, - 23.9356, - 47.3633 - ], - "rotation": [ - 3.1416, - -0.5734, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - 6.2307, - 23.9356, - 50.7095 - ], - "rotation": [ - 3.1416, - -0.2657, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - -1.9326, - 23.9356, - 51.6261 - ], - "rotation": [ - 3.1416, - 0.042, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - -9.9901, - 23.9356, - 50.0271 - ], - "rotation": [ - 3.1416, - 0.3498, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - -17.1848, - 23.9356, - 46.0625 - ], - "rotation": [ - 3.1416, - 0.6575, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - -22.8406, - 23.9356, - 40.105 - ], - "rotation": [ - -3.1416, - 0.9652, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - -26.4262, - 23.9356, - 32.7143 - ], - "rotation": [ - -3.1416, - 1.273, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - -27.6048, - 23.9356, - 24.5846 - ], - "rotation": [ - 0, - 1.5609, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - -26.2655, - 23.9356, - 16.4799 - ], - "rotation": [ - 0, - 1.2532, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - -22.5343, - 23.9356, - 9.1615 - ], - "rotation": [ - 0, - 0.9454, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - -16.7617, - 23.9356, - 3.3171 - ], - "rotation": [ - 0, - 0.6377, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - -9.49, - 23.9356, - -0.5042 - ], - "rotation": [ - 0, - 0.33, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - -1.4024, - 23.9356, - -1.9435 - ], - "rotation": [ - 0, - 0.0223, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - 6.7412, - 23.9356, - -0.8655 - ], - "rotation": [ - 0, - -0.2855, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - 14.1757, - 23.9356, - 2.6285 - ], - "rotation": [ - 0, - -0.5932, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - 20.2026, - 23.9356, - 8.2103 - ], - "rotation": [ - 0, - -0.9009, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - 24.2557, - 23.9356, - 15.3554 - ], - "rotation": [ - 0, - -1.2087, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - 25.9543, - 23.9356, - 23.3925 - ], - "rotation": [ - 0, - -1.5164, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - 25.1386, - 23.9356, - 31.5665 - ], - "rotation": [ - 3.1416, - -1.3175, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbres", - "type": "Object3D", - "position": [ - -0.8061, - 24.8656, - 24.8498 - ], - "rotation": [ - 0, - -0.7007, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - 9.5123, - 26.3756, - 40.8277 - ], - "rotation": [ - -3.1416, - -0.5734, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - 4.1879, - 26.3756, - 43.2025 - ], - "rotation": [ - -3.1416, - -0.2657, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - -1.6056, - 26.3756, - 43.853 - ], - "rotation": [ - -3.1416, - 0.042, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - -7.324, - 26.3756, - 42.7182 - ], - "rotation": [ - -3.1416, - 0.3498, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - -12.4301, - 26.3756, - 39.9045 - ], - "rotation": [ - -3.1416, - 0.6575, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - -16.444, - 26.3756, - 35.6765 - ], - "rotation": [ - -3.1416, - 0.9652, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - -18.9887, - 26.3756, - 30.4312 - ], - "rotation": [ - -3.1416, - 1.273, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - -19.8252, - 26.3756, - 24.6616 - ], - "rotation": [ - 0, - 1.5609, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - -18.8747, - 26.3756, - 18.9097 - ], - "rotation": [ - 0, - 1.2532, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - -16.2267, - 26.3756, - 13.7158 - ], - "rotation": [ - 0, - 0.9454, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - -12.1298, - 26.3756, - 9.568 - ], - "rotation": [ - 0, - 0.6377, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - -6.9691, - 26.3756, - 6.856 - ], - "rotation": [ - 0, - 0.33, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - -1.2293, - 26.3756, - 5.8345 - ], - "rotation": [ - 0, - 0.0223, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - 4.5502, - 26.3756, - 6.5996 - ], - "rotation": [ - 0, - -0.2855, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - 9.8265, - 26.3756, - 9.0793 - ], - "rotation": [ - 0, - -0.5932, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - 14.1038, - 26.3756, - 13.0407 - ], - "rotation": [ - 0, - -0.9009, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - 16.9803, - 26.3756, - 18.1116 - ], - "rotation": [ - 0, - -1.2087, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - 18.1858, - 26.3756, - 23.8156 - ], - "rotation": [ - 0, - -1.5164, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - 17.6069, - 26.3756, - 29.6167 - ], - "rotation": [ - 3.1416, - -1.3175, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbres-école", - "type": "Object3D", - "position": [ - 17.2143, - 27.7146, - 29.0483 - ], - "rotation": [ - 0.1129, - -1.4525, - 0.1096 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbres_1", - "type": "Object3D", - "position": [ - 4.0735, - 27.5587, - 31.7711 - ], - "rotation": [ - 0.0133, - -0.6214, - 0.0159 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin_0", - "type": "Mesh", - "position": [ - 20.1553, - 24.2993, - 42.4409 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin_1", - "type": "Mesh", - "position": [ - 7.5375, - 27.2128, - 33.2893 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin_2", - "type": "Mesh", - "position": [ - 24.758, - 24.3496, - 35.4002 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre_3", - "type": "Mesh", - "position": [ - 9.41, - 27.2123, - 30.5578 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin_4", - "type": "Mesh", - "position": [ - 14.607, - 26.6674, - 32.4709 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin_5", - "type": "Mesh", - "position": [ - 19.5845, - 25.7627, - 34.0445 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre_6", - "type": "Mesh", - "position": [ - 16.0263, - 25.6963, - 39.6732 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre_7", - "type": "Mesh", - "position": [ - 11.8387, - 26.6517, - 36.6584 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "lecole", - "type": "Object3D", - "position": [ - -0.3871, - 30.9693, - 26.172 - ], - "rotation": [ - 0.0126, - -0.5805, - 0.0154 - ], - "scale": [ - 1, - 2, - 1 - ] - }, - { - "name": "bati-ecole", - "type": "Mesh", - "position": [ - -7.1777, - 30.3365, - 36.5318 - ], - "rotation": [ - 0.0126, - -0.5805, - 0.0154 - ], - "scale": [ - 1, - 2, - 1 - ] - }, - { - "name": "bati-ecole", - "type": "Mesh", - "position": [ - 6.4132, - 30.5965, - 15.813 - ], - "rotation": [ - 0.0126, - -0.5805, - 0.0154 - ], - "scale": [ - 1, - 2, - 1 - ] - }, - { - "name": "bati-ecole", - "type": "Mesh", - "position": [ - -0.3968, - 31.9749, - 26.1711 - ], - "rotation": [ - 0.0126, - -0.5805, - 0.0154 - ], - "scale": [ - 1, - 2, - 1 - ] - }, - { - "name": "zone_fabrik", - "type": "Object3D", - "position": [ - 35.6417, - 8.9438, - 51.2707 - ], - "rotation": [ - 0, - -1.5519, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "bati-fabrik", - "type": "Mesh", - "position": [ - 47.4907, - 11.1375, - 63.8349 - ], - "rotation": [ - -3.1416, - -0.6297, - -3.1416 - ], - "scale": [ - 1, - 2, - 1 - ] - }, - { - "name": "Groupe1", - "type": "Object3D", - "position": [ - 30.2688, - 4.9268, - 89.1765 - ], - "rotation": [ - -3.1416, - -0.7879, - -3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble", - "type": "Mesh", - "position": [ - 32.7856, - 3.9426, - 86.6943 - ], - "rotation": [ - 3.1416, - -0.7879, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble", - "type": "Mesh", - "position": [ - 27.7519, - 5.9109, - 91.6587 - ], - "rotation": [ - -3.1416, - -0.7879, - -3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble", - "type": "Mesh", - "position": [ - 72.2157, - 4.1055, - 54.7221 - ], - "rotation": [ - -3.1416, - -0.35, - -3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_2", - "type": "Mesh", - "position": [ - 18.9151, - 13.8995, - 66.8272 - ], - "rotation": [ - 3.1416, - -1.0563, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Groupe", - "type": "Object3D", - "position": [ - 50.8106, - 15.3193, - 42.1115 - ], - "rotation": [ - 3.1416, - -0.5678, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_2", - "type": "Mesh", - "position": [ - 53.8087, - 14.3351, - 40.2387 - ], - "rotation": [ - 3.1416, - -0.5678, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - 47.8126, - 16.3034, - 43.9843 - ], - "rotation": [ - 3.1416, - -0.5678, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "zone_energie", - "type": "Object3D", - "position": [ - -38.5694, - 21.397, - 50.3786 - ], - "rotation": [ - 3.1416, - -1.1286, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "panneaux_solaires_", - "type": "Object3D", - "position": [ - -48.6802, - 22.897, - 32.2311 - ], - "rotation": [ - -3.1416, - -0.0649, - -3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre", - "type": "Mesh", - "position": [ - -70.4558, - 20.086, - 34.4879 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre", - "type": "Mesh", - "position": [ - -71.9487, - 16.01, - 24.3689 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre", - "type": "Mesh", - "position": [ - -60.0322, - 21.2231, - 32.7426 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre", - "type": "Mesh", - "position": [ - -60.2651, - 18.9485, - 24.041 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre", - "type": "Mesh", - "position": [ - -50.148, - 22.724, - 32.715 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre", - "type": "Mesh", - "position": [ - -50.2549, - 22.2507, - 25.653 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre", - "type": "Mesh", - "position": [ - -42.6015, - 24.6195, - 33.6543 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre", - "type": "Mesh", - "position": [ - -43.5134, - 25.004, - 26.3826 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "panneaux_solaires", - "type": "Object3D", - "position": [ - -28.1161, - 22.0484, - 66.7736 - ], - "rotation": [ - -3.1416, - -0.9294, - -3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_0", - "type": "Mesh", - "position": [ - -34.345, - 19.9921, - 75.3957 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_1", - "type": "Mesh", - "position": [ - -20.2017, - 25.2104, - 56.4639 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_2", - "type": "Mesh", - "position": [ - -23.5978, - 14.8881, - 79.7071 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_3", - "type": "Mesh", - "position": [ - -14.252, - 24.6604, - 59.324 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_4", - "type": "Mesh", - "position": [ - -17.5336, - 20.6605, - 65.6909 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_5", - "type": "Mesh", - "position": [ - -20.6537, - 17.5371, - 72.1844 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_6", - "type": "Mesh", - "position": [ - -29.8252, - 21.3349, - 68.2666 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_7", - "type": "Mesh", - "position": [ - -24.9035, - 22.779, - 61.9872 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "éoliennes", - "type": "Object3D", - "position": [ - -67.1528, - 25.397, - 68.0941 - ], - "rotation": [ - -3.1416, - -0.5658, - -3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_0", - "type": "Mesh", - "position": [ - -92.0412, - 16.0117, - 33.8493 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_1", - "type": "Mesh", - "position": [ - -86.0049, - 16.7563, - 32.0059 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_2", - "type": "Mesh", - "position": [ - -79.8545, - 22.1436, - 59.5407 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_3", - "type": "Mesh", - "position": [ - -74.8473, - 22.7176, - 55.9935 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_4", - "type": "Mesh", - "position": [ - -60.6625, - 22.1436, - 80.5695 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_5", - "type": "Mesh", - "position": [ - -57.0062, - 22.7176, - 75.7209 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_6", - "type": "Mesh", - "position": [ - -35.9614, - 15.9655, - 95.0568 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_7", - "type": "Mesh", - "position": [ - -33.8614, - 16.6976, - 89.3578 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "générateur", - "type": "Mesh", - "position": [ - -48.5737, - 21.4281, - 54.5311 - ], - "rotation": [ - 3.1416, - -1.1286, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "zone_domaine", - "type": "Object3D", - "position": [ - -16.0844, - 5.1349, - -46.2022 - ], - "rotation": [ - 0, - -1.3459, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "champ2", - "type": "Object3D", - "position": [ - 3.4286, - 16.0553, - -30.2701 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - 11.4121, - 3.9653, - -66.3569 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -70.8139, - 0.3267, - -62.2507 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -14.3249, - 3.5365, - -68.212 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - 24.0599, - 4.8852, - -59.538 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -52.9323, - 4.7206, - -42.7644 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -31.704, - 4.6976, - -57.309 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -25.9223, - 3.5026, - -65.0315 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -5.4992, - 4.7648, - -63.6341 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -40.2304, - 0.7972, - -75.3914 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -38.3843, - 1.4111, - -71.7936 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -37.0816, - 0.7509, - -76.9614 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -34.1436, - 0.7514, - -78.1219 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -29.7402, - 1.313, - -75.8371 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -30.9037, - 0.7698, - -79.306 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -16.8479, - 0.7778, - -83.3324 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -16.1993, - 1.345, - -79.5906 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -13.4224, - 0.7561, - -83.8093 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -10.2307, - 0.754, - -84.0774 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -6.5395, - 1.2827, - -80.7849 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -6.5723, - 0.7644, - -84.3157 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -2.4983, - 0.4448, - -88.0723 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -2.4407, - 0.7758, - -84.5676 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -6.5447, - 0.4457, - -87.7718 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -6.6798, - 0.3279, - -91.2671 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -10.2825, - 0.4466, - -87.4858 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -10.4639, - 0.328, - -90.9794 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -14.1131, - 0.3277, - -90.6931 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -17.854, - 0.3273, - -90.3823 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -21.9187, - 0.3273, - -89.8092 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -26.0047, - 0.3278, - -88.6636 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -29.7266, - 0.3282, - -87.23 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -33.1971, - 0.3284, - -85.8711 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -36.5348, - 0.3283, - -84.5591 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -39.8565, - 0.3279, - -83.2413 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -43.3585, - 0.3276, - -81.8413 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -47.1477, - 0.3277, - -80.111 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -50.9789, - 0.3277, - -77.9043 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -54.6075, - 0.3281, - -75.352 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -58.015, - 0.3286, - -72.6911 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -61.2668, - 0.3291, - -70.0898 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -64.4716, - 0.3293, - -67.5244 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -67.6622, - 0.3286, - -64.9362 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -62.1519, - 0.4755, - -64.6412 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -65.1778, - 0.4774, - -62.0524 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -62.5731, - 0.8884, - -59.2255 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -65.2583, - 0.9221, - -56.6381 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -68.0021, - 0.4844, - -59.3904 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -62.6398, - 1.5402, - -53.9245 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -60.1295, - 2.2225, - -51.1926 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -57.6942, - 2.9614, - -48.4318 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -55.3051, - 3.7904, - -45.6226 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -55.0285, - 2.9288, - -50.7766 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -52.6408, - 3.7656, - -47.8775 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -49.9983, - 3.7437, - -50.0915 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -47.6432, - 4.6824, - -47.0805 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -50.2744, - 4.6994, - -44.9432 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -45.0479, - 4.6733, - -49.1549 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -42.5034, - 4.6771, - -51.1238 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -40.0021, - 4.6962, - -52.9499 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -37.4182, - 4.7118, - -54.5714 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -34.6659, - 4.7103, - -55.9908 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -36.3713, - 3.801, - -59.4048 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -39.3483, - 3.7876, - -57.8793 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -41.2833, - 2.9441, - -61.2257 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -42.1287, - 3.7586, - -56.1669 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -44.2741, - 2.8999, - -59.453 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -46.3307, - 2.1209, - -62.8234 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -47.0518, - 2.8696, - -57.4896 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -49.3098, - 2.0824, - -60.781 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -51.471, - 1.3905, - -63.9422 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -52.1045, - 2.0956, - -58.4714 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -54.4709, - 1.4066, - -61.4374 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -56.7543, - 0.8449, - -64.3148 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -57.2765, - 1.4443, - -58.9232 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -59.7579, - 0.8624, - -61.7795 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -54.7976, - 2.1355, - -56.0498 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -57.4656, - 2.1801, - -53.6207 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -59.9754, - 1.4918, - -56.428 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -55.7722, - 0.4691, - -69.7848 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -53.5905, - 0.8371, - -66.8875 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -58.9988, - 0.4715, - -67.199 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -52.4153, - 0.467, - -72.3871 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -50.2966, - 0.8397, - -69.3921 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -46.9317, - 0.8543, - -71.5878 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -45.0136, - 1.4625, - -68.1254 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -48.2887, - 1.4158, - -66.2071 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -41.7242, - 1.4734, - -69.9029 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -39.8703, - 2.205, - -66.2953 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -43.1555, - 2.1795, - -64.6226 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -36.5275, - 2.1843, - -67.9115 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -34.8539, - 2.9593, - -64.334 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -38.1084, - 2.9689, - -62.8268 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -33.248, - 3.7921, - -60.8149 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -43.5975, - 0.8525, - -73.4912 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -45.4034, - 0.4645, - -76.8627 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -48.9279, - 0.4658, - -74.8171 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -49.7218, - 2.8713, - -55.3626 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -52.3728, - 2.8954, - -53.1058 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -44.7745, - 3.7336, - -54.2644 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -47.382, - 3.7303, - -52.2273 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -41.8617, - 0.4583, - -78.548 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -38.4801, - 0.4512, - -79.9867 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -35.2796, - 0.449, - -81.2835 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -31.9888, - 0.4499, - -82.5702 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -28.5374, - 0.4485, - -83.9109 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -24.8823, - 0.4458, - -85.2594 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -23.9168, - 0.7906, - -81.7579 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -27.4483, - 0.7856, - -80.5556 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -23.0257, - 1.347, - -78.1146 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -26.3784, - 1.3319, - -77.0358 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -22.0995, - 2.0236, - -74.3895 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -25.2687, - 2.0056, - -73.3753 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -24.1384, - 2.7357, - -69.717 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -27.1911, - 2.7231, - -68.6173 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -28.4527, - 1.999, - -72.195 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -21.1282, - 2.7564, - -70.6683 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -20.1171, - 3.5359, - -67.0021 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -22.9884, - 3.5156, - -66.085 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -17.281, - 3.5474, - -67.7013 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -18.0783, - 2.7729, - -71.3947 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -15.5468, - 2.0461, - -75.6822 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -14.9242, - 2.7669, - -71.94 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -18.8661, - 2.0465, - -75.1275 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -19.6373, - 1.3657, - -78.91 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -20.3814, - 0.7975, - -82.654 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -21.1303, - 0.4462, - -86.2784 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -17.4084, - 0.4483, - -86.8292 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -13.7939, - 0.4485, - -87.1824 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - 17.1237, - 1.8611, - -75.7969 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - 23.493, - 2.606, - -70.255 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - 19.8781, - 2.545, - -71.3996 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - 27.0851, - 2.6732, - -69.0737 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - 26.0441, - 3.3494, - -65.8794 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - 22.5075, - 3.284, - -67.0215 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - 25.0415, - 4.0826, - -62.7099 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - 5.6979, - 1.2772, - -81.2456 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - 1.6222, - 1.2936, - -81.239 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - 1.597, - 1.9083, - -77.7099 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -2.3509, - 1.9098, - -77.5042 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -2.4034, - 1.2957, - -81.0285 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -2.2823, - 2.5523, - -74.0563 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -6.1525, - 2.5503, - -73.7771 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -6.3502, - 1.9081, - -77.2279 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -5.9449, - 3.2322, - -70.373 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -5.7289, - 3.9722, - -66.9965 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -2.2046, - 3.2338, - -70.6485 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -2.1182, - 3.9748, - -67.2496 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - 1.3889, - 3.9849, - -67.383 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - 1.3115, - 4.7827, - -63.9926 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -2.011, - 4.7703, - -63.8656 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - 4.5112, - 4.7923, - -63.9186 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - 7.6364, - 4.787, - -63.5674 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - 10.7761, - 4.7752, - -62.9861 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - 14.0162, - 4.774, - -62.2665 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - 17.3227, - 4.7909, - -61.4448 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - 20.6662, - 4.8285, - -60.5336 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - 21.572, - 4.0223, - -63.7816 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - 18.1432, - 3.9811, - -64.7571 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - 18.9813, - 3.231, - -68.0901 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - 14.7627, - 3.9635, - -65.6126 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - 15.4971, - 3.2048, - -69.012 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - 16.2679, - 2.507, - -72.4232 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - 12.031, - 3.2046, - -69.7865 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - 12.6499, - 2.5008, - -73.2628 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - 13.2941, - 1.85, - -76.7185 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - 9.003, - 2.5182, - -73.8935 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - 9.4167, - 1.8628, - -77.4042 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - 5.3267, - 2.5415, - -74.2282 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - 5.5209, - 1.8889, - -77.7351 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - 5.063, - 3.2371, - -70.7487 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - 1.4814, - 3.2376, - -70.8132 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - 1.5601, - 2.5524, - -74.247 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - 8.557, - 3.2215, - -70.3955 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - 8.0938, - 3.9809, - -66.947 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - 4.7769, - 3.9917, - -67.2987 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - 9.8319, - 1.2611, - -80.8477 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "champ1", - "type": "Object3D", - "position": [ - 3.4286, - 16.0553, - -30.2701 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_0", - "type": "Mesh", - "position": [ - 21.9129, - 7.0614, - -52.1148 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_1", - "type": "Mesh", - "position": [ - 14.67, - 16.8504, - -24.9758 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_2", - "type": "Mesh", - "position": [ - -4.1759, - 16.8338, - -27.1377 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_3", - "type": "Mesh", - "position": [ - -5.6179, - 7.0424, - -55.3704 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_4", - "type": "Mesh", - "position": [ - -5.4166, - 7.9551, - -52.5529 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_5", - "type": "Mesh", - "position": [ - -5.233, - 8.8832, - -49.7254 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_6", - "type": "Mesh", - "position": [ - -5.0653, - 9.8424, - -46.9005 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_7", - "type": "Mesh", - "position": [ - -4.9172, - 10.8242, - -44.0908 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_8", - "type": "Mesh", - "position": [ - -4.7873, - 11.8151, - -41.2835 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_9", - "type": "Mesh", - "position": [ - -4.6704, - 12.8175, - -38.4752 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_10", - "type": "Mesh", - "position": [ - -4.5659, - 13.8223, - -35.671 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_11", - "type": "Mesh", - "position": [ - -4.4628, - 14.8249, - -32.8511 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_12", - "type": "Mesh", - "position": [ - -4.3386, - 15.8289, - -30.0009 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_13", - "type": "Mesh", - "position": [ - -1.8656, - 14.8461, - -32.9701 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_14", - "type": "Mesh", - "position": [ - -1.8353, - 15.84, - -30.1425 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_15", - "type": "Mesh", - "position": [ - 0.652, - 15.8554, - -30.2211 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_16", - "type": "Mesh", - "position": [ - 0.61, - 16.8412, - -27.4298 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_17", - "type": "Mesh", - "position": [ - -1.7309, - 16.8364, - -27.3029 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_18", - "type": "Mesh", - "position": [ - 2.8703, - 16.8403, - -27.3634 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_19", - "type": "Mesh", - "position": [ - 5.1088, - 16.8341, - -27.063 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_20", - "type": "Mesh", - "position": [ - 7.3875, - 16.8324, - -26.6201 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_21", - "type": "Mesh", - "position": [ - 9.7701, - 16.8341, - -26.0953 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_22", - "type": "Mesh", - "position": [ - 12.2114, - 16.839, - -25.5469 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_23", - "type": "Mesh", - "position": [ - 12.8382, - 15.8459, - -28.2976 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_24", - "type": "Mesh", - "position": [ - 10.3482, - 15.8312, - -28.8839 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_25", - "type": "Mesh", - "position": [ - 10.8975, - 14.8278, - -31.665 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_26", - "type": "Mesh", - "position": [ - 7.9139, - 15.826, - -29.4276 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_27", - "type": "Mesh", - "position": [ - 8.37, - 14.8169, - -32.2443 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_28", - "type": "Mesh", - "position": [ - 8.7977, - 13.7982, - -35.0653 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_29", - "type": "Mesh", - "position": [ - 5.8653, - 14.8316, - -32.6886 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_30", - "type": "Mesh", - "position": [ - 6.1799, - 13.8139, - -35.5349 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_31", - "type": "Mesh", - "position": [ - 6.4862, - 12.7916, - -38.3722 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_32", - "type": "Mesh", - "position": [ - 3.5377, - 13.864, - -35.7712 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_33", - "type": "Mesh", - "position": [ - 3.7249, - 12.8501, - -38.6076 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_34", - "type": "Mesh", - "position": [ - 3.909, - 11.8411, - -41.4432 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_35", - "type": "Mesh", - "position": [ - 0.9278, - 12.8715, - -38.657 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_36", - "type": "Mesh", - "position": [ - 1.0171, - 11.8654, - -41.4879 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_37", - "type": "Mesh", - "position": [ - 1.1031, - 10.8645, - -44.3329 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_38", - "type": "Mesh", - "position": [ - -1.8864, - 11.8368, - -41.4212 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_39", - "type": "Mesh", - "position": [ - -1.9082, - 10.8411, - -44.2483 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_40", - "type": "Mesh", - "position": [ - 4.2939, - 9.8522, - -47.1238 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_41", - "type": "Mesh", - "position": [ - 4.0966, - 10.838, - -44.2907 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_42", - "type": "Mesh", - "position": [ - 1.1699, - 9.8746, - -47.185 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_43", - "type": "Mesh", - "position": [ - 1.2294, - 8.9124, - -50.0335 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_44", - "type": "Mesh", - "position": [ - -1.9519, - 9.8553, - -47.0793 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_45", - "type": "Mesh", - "position": [ - -2.0139, - 8.8935, - -49.9197 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_46", - "type": "Mesh", - "position": [ - 4.7517, - 7.97, - -52.7667 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_47", - "type": "Mesh", - "position": [ - 4.5126, - 8.8984, - -49.938 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_48", - "type": "Mesh", - "position": [ - 1.2983, - 7.9774, - -52.8974 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_49", - "type": "Mesh", - "position": [ - 1.3272, - 7.051, - -55.8159 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_50", - "type": "Mesh", - "position": [ - -2.0914, - 7.9602, - -52.7724 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_51", - "type": "Mesh", - "position": [ - -2.2051, - 7.0431, - -55.616 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_52", - "type": "Mesh", - "position": [ - 4.9794, - 7.0489, - -55.6562 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_53", - "type": "Mesh", - "position": [ - 8.6356, - 7.0384, - -55.0814 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_54", - "type": "Mesh", - "position": [ - 12.1483, - 7.037, - -54.3652 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_55", - "type": "Mesh", - "position": [ - 11.625, - 7.9392, - -51.6356 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_56", - "type": "Mesh", - "position": [ - 8.2227, - 7.9454, - -52.3055 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_57", - "type": "Mesh", - "position": [ - 11.1259, - 8.8565, - -48.8917 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_58", - "type": "Mesh", - "position": [ - 7.8345, - 8.866, - -49.5271 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_59", - "type": "Mesh", - "position": [ - 10.6221, - 9.8029, - -46.154 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_60", - "type": "Mesh", - "position": [ - 7.4572, - 9.8088, - -46.7716 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_61", - "type": "Mesh", - "position": [ - 10.1298, - 10.778, - -43.4129 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_62", - "type": "Mesh", - "position": [ - 7.1095, - 10.7832, - -44 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_63", - "type": "Mesh", - "position": [ - 9.6719, - 11.7716, - -40.6454 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_64", - "type": "Mesh", - "position": [ - 6.7926, - 11.7815, - -41.1878 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_65", - "type": "Mesh", - "position": [ - 12.5261, - 11.8016, - -39.937 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_66", - "type": "Mesh", - "position": [ - 11.9779, - 12.8073, - -37.1885 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_67", - "type": "Mesh", - "position": [ - 9.2319, - 12.7794, - -37.865 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_68", - "type": "Mesh", - "position": [ - 14.7089, - 12.8482, - -36.4744 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_69", - "type": "Mesh", - "position": [ - 14.0837, - 13.8538, - -33.7567 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_70", - "type": "Mesh", - "position": [ - 11.4354, - 13.8193, - -34.4327 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_71", - "type": "Mesh", - "position": [ - 16.7472, - 13.8935, - -33.0643 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_72", - "type": "Mesh", - "position": [ - 16.0544, - 14.8874, - -30.3714 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_73", - "type": "Mesh", - "position": [ - 13.4646, - 14.853, - -31.0333 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_74", - "type": "Mesh", - "position": [ - 15.3574, - 15.8734, - -27.6679 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_75", - "type": "Mesh", - "position": [ - 17.4423, - 12.8936, - -35.747 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_76", - "type": "Mesh", - "position": [ - 18.1474, - 11.8961, - -38.4316 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_77", - "type": "Mesh", - "position": [ - 18.8646, - 10.9073, - -41.1207 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_78", - "type": "Mesh", - "position": [ - 19.595, - 9.9238, - -43.818 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_79", - "type": "Mesh", - "position": [ - 20.3535, - 8.9572, - -46.5394 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_80", - "type": "Mesh", - "position": [ - 21.1388, - 8.0082, - -49.3067 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_81", - "type": "Mesh", - "position": [ - 17.3672, - 8.9059, - -47.3638 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_82", - "type": "Mesh", - "position": [ - 18.0703, - 7.9654, - -50.1244 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_83", - "type": "Mesh", - "position": [ - 18.7235, - 7.0449, - -52.8776 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_84", - "type": "Mesh", - "position": [ - 14.906, - 7.9444, - -50.8933 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_85", - "type": "Mesh", - "position": [ - 15.488, - 7.0391, - -53.6161 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_86", - "type": "Mesh", - "position": [ - 14.308, - 8.8686, - -48.1541 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_87", - "type": "Mesh", - "position": [ - 16.6617, - 9.8732, - -44.6197 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_88", - "type": "Mesh", - "position": [ - 13.6882, - 9.828, - -45.4074 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_89", - "type": "Mesh", - "position": [ - 15.9923, - 10.8561, - -41.9015 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_90", - "type": "Mesh", - "position": [ - 13.0896, - 10.8098, - -42.6729 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_91", - "type": "Mesh", - "position": [ - 15.3455, - 11.8465, - -39.1897 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_92", - "type": "Mesh", - "position": [ - -1.8737, - 12.8415, - -38.6004 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_93", - "type": "Mesh", - "position": [ - 0.8385, - 13.8775, - -35.8359 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_94", - "type": "Mesh", - "position": [ - -1.867, - 13.8471, - -35.7865 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_95", - "type": "Mesh", - "position": [ - 3.3283, - 14.8668, - -32.9433 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_96", - "type": "Mesh", - "position": [ - 0.736, - 14.8722, - -33.0245 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_97", - "type": "Mesh", - "position": [ - 5.5185, - 15.833, - -29.8703 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_98", - "type": "Mesh", - "position": [ - 3.1096, - 15.8529, - -30.1424 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_99", - "type": "Mesh", - "position": [ - -48.1453, - 7.0266, - -36.6113 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_100", - "type": "Mesh", - "position": [ - -33.0347, - 16.8004, - -14.704 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_101", - "type": "Mesh", - "position": [ - -16.4865, - 16.8879, - -24.3421 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_102", - "type": "Mesh", - "position": [ - -24.6472, - 7.0777, - -50.9985 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_103", - "type": "Mesh", - "position": [ - -27.9084, - 7.0688, - -49.7732 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_104", - "type": "Mesh", - "position": [ - -31.2571, - 7.0698, - -48.4518 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_105", - "type": "Mesh", - "position": [ - -34.5056, - 7.0627, - -46.7514 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_106", - "type": "Mesh", - "position": [ - -37.5152, - 7.0447, - -44.6891 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_107", - "type": "Mesh", - "position": [ - -40.3646, - 7.0348, - -42.5789 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_108", - "type": "Mesh", - "position": [ - -43.0557, - 7.0312, - -40.52 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_109", - "type": "Mesh", - "position": [ - -45.6294, - 7.029, - -38.5433 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_110", - "type": "Mesh", - "position": [ - -41.5311, - 7.9215, - -38.4189 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_111", - "type": "Mesh", - "position": [ - -44.0943, - 7.9131, - -36.4774 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_112", - "type": "Mesh", - "position": [ - -46.6055, - 7.9043, - -34.5707 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_113", - "type": "Mesh", - "position": [ - -42.5958, - 8.8101, - -34.3776 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_114", - "type": "Mesh", - "position": [ - -45.0878, - 8.7914, - -32.5179 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_115", - "type": "Mesh", - "position": [ - -43.6043, - 9.7125, - -30.4406 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_116", - "type": "Mesh", - "position": [ - -42.1392, - 10.6664, - -28.3315 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_117", - "type": "Mesh", - "position": [ - -40.682, - 11.6354, - -26.1926 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_118", - "type": "Mesh", - "position": [ - -39.2229, - 12.631, - -24.0008 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_119", - "type": "Mesh", - "position": [ - -37.7376, - 13.656, - -21.7488 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_120", - "type": "Mesh", - "position": [ - -36.2206, - 14.6921, - -19.4472 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_121", - "type": "Mesh", - "position": [ - -34.6597, - 15.7371, - -17.0928 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_122", - "type": "Mesh", - "position": [ - -34.0276, - 14.7253, - -20.9862 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_123", - "type": "Mesh", - "position": [ - -32.4957, - 15.766, - -18.6283 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_124", - "type": "Mesh", - "position": [ - -30.3881, - 15.7807, - -20.1706 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_125", - "type": "Mesh", - "position": [ - -28.805, - 16.8165, - -17.8519 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_126", - "type": "Mesh", - "position": [ - -30.8774, - 16.8124, - -16.2965 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_127", - "type": "Mesh", - "position": [ - -26.8283, - 16.8209, - -19.3325 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_128", - "type": "Mesh", - "position": [ - -24.945, - 16.8329, - -20.6418 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_129", - "type": "Mesh", - "position": [ - -23.0352, - 16.8559, - -21.7511 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_130", - "type": "Mesh", - "position": [ - -20.9621, - 16.8724, - -22.687 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_131", - "type": "Mesh", - "position": [ - -18.753, - 16.8786, - -23.5178 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_132", - "type": "Mesh", - "position": [ - -21.9378, - 15.9357, - -25.1001 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_133", - "type": "Mesh", - "position": [ - -19.6334, - 15.959, - -25.9432 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_134", - "type": "Mesh", - "position": [ - -20.4666, - 15.0268, - -28.4174 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_135", - "type": "Mesh", - "position": [ - -18.016, - 15.0846, - -29.1732 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_136", - "type": "Mesh", - "position": [ - -17.2806, - 15.9942, - -26.7251 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_137", - "type": "Mesh", - "position": [ - -18.7262, - 14.134, - -31.7247 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_138", - "type": "Mesh", - "position": [ - -19.4452, - 13.1457, - -34.354 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_139", - "type": "Mesh", - "position": [ - -20.1963, - 12.1317, - -37.0465 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_140", - "type": "Mesh", - "position": [ - -20.9938, - 11.106, - -39.7867 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_141", - "type": "Mesh", - "position": [ - -21.8426, - 10.0757, - -42.5596 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_142", - "type": "Mesh", - "position": [ - -22.7282, - 9.0569, - -45.3578 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_143", - "type": "Mesh", - "position": [ - -23.6575, - 8.0608, - -48.1799 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_144", - "type": "Mesh", - "position": [ - -26.8236, - 8.0304, - -47.0553 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_145", - "type": "Mesh", - "position": [ - -25.7939, - 9.0113, - -44.3233 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_146", - "type": "Mesh", - "position": [ - -28.8249, - 8.9852, - -43.1821 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_147", - "type": "Mesh", - "position": [ - -24.8051, - 10.0266, - -41.5784 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_148", - "type": "Mesh", - "position": [ - -27.7093, - 9.9936, - -40.5203 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_149", - "type": "Mesh", - "position": [ - -30.5427, - 9.9297, - -39.2823 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_150", - "type": "Mesh", - "position": [ - -26.6726, - 11.0161, - -37.8459 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_151", - "type": "Mesh", - "position": [ - -29.4226, - 10.9336, - -36.713 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_152", - "type": "Mesh", - "position": [ - -32.1298, - 10.8228, - -35.3214 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_153", - "type": "Mesh", - "position": [ - -28.3773, - 11.9379, - -34.1323 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_154", - "type": "Mesh", - "position": [ - -30.9822, - 11.8199, - -32.8411 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_155", - "type": "Mesh", - "position": [ - -33.4911, - 11.7443, - -31.2829 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_156", - "type": "Mesh", - "position": [ - -29.8479, - 12.825, - -30.3637 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_157", - "type": "Mesh", - "position": [ - -32.2576, - 12.7464, - -28.8854 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_158", - "type": "Mesh", - "position": [ - -34.6048, - 12.701, - -27.2649 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_159", - "type": "Mesh", - "position": [ - -31.0163, - 13.7596, - -26.4742 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_160", - "type": "Mesh", - "position": [ - -33.2633, - 13.7202, - -24.9117 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_161", - "type": "Mesh", - "position": [ - -29.7227, - 14.778, - -24.0562 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_162", - "type": "Mesh", - "position": [ - -31.8647, - 14.7496, - -22.5374 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_163", - "type": "Mesh", - "position": [ - -27.5462, - 14.8319, - -25.4367 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_164", - "type": "Mesh", - "position": [ - -26.305, - 15.8294, - -23.0074 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_165", - "type": "Mesh", - "position": [ - -28.3423, - 15.7959, - -21.6622 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_166", - "type": "Mesh", - "position": [ - -25.264, - 14.919, - -26.5971 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_167", - "type": "Mesh", - "position": [ - -24.174, - 15.89, - -24.1421 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_168", - "type": "Mesh", - "position": [ - -26.3048, - 13.9381, - -29.0867 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_169", - "type": "Mesh", - "position": [ - -23.8108, - 14.0185, - -30.0877 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_170", - "type": "Mesh", - "position": [ - -22.8914, - 14.9865, - -27.5703 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_171", - "type": "Mesh", - "position": [ - -24.7415, - 13.0277, - -32.638 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_172", - "type": "Mesh", - "position": [ - -22.1047, - 13.0775, - -33.5466 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé_173", - "type": "Mesh", - "position": [ - -21.2769, - 14.0671, - -30.9553 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol_174", - "type": "Mesh", - "position": [ - -25.6933, - 12.0254, - -35.2193 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja_175", - "type": "Mesh", - "position": [ - -22.9608, - 12.0702, - -36.1809 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -27.3388, - 12.9411, - -31.596 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -28.7111, - 13.8315, - -27.896 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -38.3133, - 11.6684, - -27.8836 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -35.9252, - 11.7011, - -29.5866 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -36.9157, - 12.6672, - -25.6275 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -39.7159, - 10.6948, - -30.0846 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -37.2643, - 10.7232, - -31.8548 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -38.6358, - 9.763, - -34.0729 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -36.0583, - 9.7975, - -35.9129 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -34.7547, - 10.7587, - -33.6372 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -37.4266, - 8.8588, - -38.1564 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -34.6681, - 8.9017, - -40.0286 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -33.3446, - 9.8492, - -37.7142 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -36.0646, - 7.9667, - -42.375 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -33.1048, - 8.004, - -44.2353 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -31.789, - 8.9496, - -41.7689 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -38.8688, - 7.938, - -40.3989 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -40.0542, - 8.8274, - -36.2638 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "tournesol", - "type": "Mesh", - "position": [ - -41.1398, - 9.7386, - -32.2455 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -35.494, - 13.6905, - -23.3247 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "blé", - "type": "Mesh", - "position": [ - -23.8565, - 11.0527, - -38.8595 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "soja", - "type": "Mesh", - "position": [ - -29.9994, - 8.0221, - -45.7926 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buissons", - "type": "Object3D", - "position": [ - -20.2246, - 3.1095, - -70.1386 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -14.1379, - 5.834, - -59.1492 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -13.2719, - 5.7979, - -59.6663 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -12.4487, - 5.7453, - -60.2479 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -11.6734, - 5.6764, - -60.8906 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -10.9509, - 5.5916, - -61.5902 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -10.2855, - 5.4916, - -62.3426 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -9.6814, - 5.3769, - -63.143 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -9.1424, - 5.2481, - -63.9865 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -8.6716, - 5.1063, - -64.868 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -8.2721, - 4.9521, - -65.782 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -7.9463, - 4.7865, - -66.7228 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -7.6961, - 4.6106, - -67.6847 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -7.5232, - 4.4254, - -68.6617 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -7.4286, - 4.2322, - -69.6478 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -7.413, - 4.032, - -70.637 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -7.4762, - 3.8261, - -71.6231 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -7.6181, - 3.6158, - -72.6 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -7.8378, - 3.4024, - -73.5617 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -8.1337, - 3.1872, - -74.5024 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -8.5043, - 2.9715, - -75.4161 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -8.9471, - 2.7566, - -76.2973 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -9.4594, - 2.5439, - -77.1406 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -10.0381, - 2.3347, - -77.9406 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -10.6796, - 2.1303, - -78.6926 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -11.3799, - 1.932, - -79.3918 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -12.1348, - 1.7408, - -80.034 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -12.9395, - 1.5582, - -80.6151 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -13.7892, - 1.385, - -81.1317 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -14.6785, - 1.2226, - -81.5805 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -15.6021, - 1.0717, - -81.9588 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -16.5541, - 0.9334, - -82.2641 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -17.5287, - 0.8086, - -82.4948 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -18.52, - 0.6979, - -82.6492 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -19.5218, - 0.6021, - -82.7265 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -20.5279, - 0.5217, - -82.7262 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -21.5322, - 0.4573, - -82.6483 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -22.5284, - 0.4093, - -82.4933 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -23.5104, - 0.3779, - -82.262 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -24.4721, - 0.3633, - -81.9561 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -25.4076, - 0.3657, - -81.5773 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -26.3112, - 0.3849, - -81.128 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -27.1773, - 0.421, - -80.6109 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -28.0005, - 0.4737, - -80.0292 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -28.7757, - 0.5426, - -79.3866 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -29.4983, - 0.6273, - -78.6869 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -30.1636, - 0.7274, - -77.9346 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -30.7677, - 0.8421, - -77.1342 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -31.3068, - 0.9708, - -76.2906 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -31.7775, - 1.1127, - -75.4091 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -32.1771, - 1.2669, - -74.4952 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -32.5029, - 1.4325, - -73.5543 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -32.753, - 1.6084, - -72.5924 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -32.9259, - 1.7935, - -71.6154 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -33.0205, - 1.9868, - -70.6293 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -33.0362, - 2.187, - -69.6402 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -32.9729, - 2.3928, - -68.6541 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -32.831, - 2.6031, - -67.6771 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -32.6114, - 2.8166, - -66.7154 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -32.3154, - 3.0318, - -65.7748 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -31.9449, - 3.2475, - -64.861 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -31.5021, - 3.4623, - -63.9798 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -30.9898, - 3.675, - -63.1366 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -30.4111, - 3.8842, - -62.3365 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -29.7696, - 4.0886, - -61.5846 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -29.0692, - 4.287, - -60.8853 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -28.3144, - 4.4781, - -60.2432 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -27.5096, - 4.6608, - -59.662 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -26.66, - 4.8339, - -59.1454 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -25.7706, - 4.9964, - -58.6966 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -24.8471, - 5.1472, - -58.3184 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -23.8951, - 5.2855, - -58.013 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -22.9204, - 5.4104, - -57.7824 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -21.9291, - 5.5211, - -57.6279 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -20.9273, - 5.6169, - -57.5506 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -19.9212, - 5.6972, - -57.5509 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "buisson", - "type": "Mesh", - "position": [ - -15.0415, - 5.8533, - -58.6998 - ], - "rotation": [ - 0.1394, - -1.3403, - 0.3489 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbres", - "type": "Object3D", - "position": [ - 4.6185, - 12.2303, - -52.5395 - ], - "rotation": [ - 0, - -1.3459, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbres", - "type": "Object3D", - "position": [ - 12.6294, - 12.2056, - -51.0727 - ], - "rotation": [ - 3.1416, - -1.2064, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_0", - "type": "Mesh", - "position": [ - 13.5023, - 8.8974, - -51.6228 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_1", - "type": "Mesh", - "position": [ - 12.2232, - 11.4636, - -44.1262 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_2", - "type": "Mesh", - "position": [ - 10.9763, - 14.2168, - -36.5025 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_3", - "type": "Mesh", - "position": [ - 9.7295, - 17.0247, - -28.7199 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_4", - "type": "Mesh", - "position": [ - -5.3958, - 8.8974, - -53.0006 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_5", - "type": "Mesh", - "position": [ - -4.9669, - 11.4636, - -45.3693 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_6", - "type": "Mesh", - "position": [ - -4.5494, - 14.2168, - -37.6189 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre_7", - "type": "Mesh", - "position": [ - -4.1326, - 17.0247, - -29.7158 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre", - "type": "Mesh", - "position": [ - -23.8928, - 8.8974, - -48.8971 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre", - "type": "Mesh", - "position": [ - -21.7962, - 11.4636, - -41.6663 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre", - "type": "Mesh", - "position": [ - -19.7509, - 14.2168, - -34.2931 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre", - "type": "Mesh", - "position": [ - -17.7039, - 17.0247, - -26.7489 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre", - "type": "Mesh", - "position": [ - -40.4273, - 8.8974, - -39.6637 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre", - "type": "Mesh", - "position": [ - -36.858, - 11.4636, - -33.3286 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre", - "type": "Mesh", - "position": [ - -33.3621, - 14.2168, - -26.8015 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Cylindre", - "type": "Mesh", - "position": [ - -29.8487, - 17.0247, - -20.0648 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "ferme_verti", - "type": "Mesh", - "position": [ - -20.5518, - 8.1225, - -70.6352 - ], - "rotation": [ - 3.1416, - -1.1848, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeubles", - "type": "Object3D", - "position": [ - 58.3738, - -0.4334, - -15.1953 - ], - "rotation": [ - -3.1416, - 1.1456, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Groupe2", - "type": "Object3D", - "position": [ - 93.8738, - 4.1985, - -8.5653 - ], - "rotation": [ - 3.1416, - 1.2256, - -3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_2", - "type": "Mesh", - "position": [ - 95.0387, - 3.2144, - -5.2279 - ], - "rotation": [ - -3.1416, - 1.2255, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - 92.709, - 5.1827, - -11.9028 - ], - "rotation": [ - 3.1416, - 1.2256, - -3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Groupe2", - "type": "Object3D", - "position": [ - 34.1654, - 9.4199, - -51.5725 - ], - "rotation": [ - 0, - 1.4871, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_2", - "type": "Mesh", - "position": [ - 33.8368, - 8.4357, - -48.0529 - ], - "rotation": [ - 0, - 1.4871, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - 34.4941, - 10.404, - -55.0921 - ], - "rotation": [ - 0, - 1.4871, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_22", - "type": "Mesh", - "position": [ - 69.7762, - 9.4199, - 18.3362 - ], - "rotation": [ - -3.1416, - 1.1906, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Groupe2", - "type": "Object3D", - "position": [ - 41.9036, - 19.8047, - -4.3543 - ], - "rotation": [ - 0, - 1.4051, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_2", - "type": "Mesh", - "position": [ - 41.2876, - 18.8206, - -0.8735 - ], - "rotation": [ - 0, - 1.4051, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - 42.5195, - 20.7889, - -7.8352 - ], - "rotation": [ - 0, - 1.4051, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - 69.1598, - 9.4199, - -2.3765 - ], - "rotation": [ - -3.1416, - 1.4482, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - 93.8789, - 4.1985, - 19.927 - ], - "rotation": [ - 3.1416, - 0.3786, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - 69.4247, - 4.1985, - -59.3345 - ], - "rotation": [ - -3.1416, - 1.5089, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Groupe2", - "type": "Object3D", - "position": [ - 50.5352, - 9.4199, - -38.8631 - ], - "rotation": [ - -3.1416, - 0.8956, - -3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_2", - "type": "Mesh", - "position": [ - 52.7187, - 8.4357, - -36.0832 - ], - "rotation": [ - -3.1416, - 0.8956, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - 48.3518, - 10.404, - -41.6431 - ], - "rotation": [ - -3.1416, - 0.8956, - -3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - 46.4293, - 19.8047, - 8.6568 - ], - "rotation": [ - 3.1416, - 1.3224, - -3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Groupe2", - "type": "Object3D", - "position": [ - 33.7611, - 19.8047, - -15.4911 - ], - "rotation": [ - 3.1416, - 0.809, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_2", - "type": "Mesh", - "position": [ - 36.1767, - 18.8206, - -12.9102 - ], - "rotation": [ - 3.1416, - 0.809, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - 31.3456, - 20.7889, - -18.0719 - ], - "rotation": [ - 3.1416, - 0.809, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Groupe2", - "type": "Object3D", - "position": [ - 62.5434, - 9.4199, - -21.9889 - ], - "rotation": [ - 3.1416, - 0.9129, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_2", - "type": "Mesh", - "position": [ - 64.6785, - 8.4357, - -19.1716 - ], - "rotation": [ - 3.1416, - 0.9128, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - 60.4084, - 10.404, - -24.8062 - ], - "rotation": [ - 3.1416, - 0.9129, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Groupe2", - "type": "Object3D", - "position": [ - 46.879, - 19.8047, - 22.4645 - ], - "rotation": [ - -3.1416, - 0.9771, - -3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_2", - "type": "Mesh", - "position": [ - 48.8288, - 18.8206, - 25.4131 - ], - "rotation": [ - 3.1416, - 0.9771, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - 44.9291, - 20.7889, - 19.516 - ], - "rotation": [ - -3.1416, - 0.9771, - -3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Groupe2", - "type": "Object3D", - "position": [ - 22.7244, - 19.8047, - -23.8431 - ], - "rotation": [ - 3.1416, - 0.6712, - -3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_2", - "type": "Mesh", - "position": [ - 25.4717, - 18.8206, - -21.6186 - ], - "rotation": [ - -3.1416, - 0.6712, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - 19.9772, - 20.7889, - -26.0676 - ], - "rotation": [ - 3.1416, - 0.6712, - -3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - 85.4754, - 4.1985, - -35.7925 - ], - "rotation": [ - -3.1416, - 1.3009, - 3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeubles", - "type": "Object3D", - "position": [ - -3.8031, - 9.4131, - 71.852 - ], - "rotation": [ - 3.1416, - 0.1131, - -3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Groupe2_0", - "type": "Object3D", - "position": [ - -3.8544, - 22.5511, - 59.6426 - ], - "rotation": [ - 0, - 0.0613, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_2", - "type": "Mesh", - "position": [ - -7.3845, - 21.5669, - 59.8259 - ], - "rotation": [ - 0, - 0.0613, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - -0.3242, - 23.5352, - 59.4593 - ], - "rotation": [ - 0, - 0.0613, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Groupe2_1", - "type": "Object3D", - "position": [ - -7.4612, - 5.0001, - 95.492 - ], - "rotation": [ - 0, - 0.0402, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_2", - "type": "Mesh", - "position": [ - -10.9945, - 4.0159, - 95.6007 - ], - "rotation": [ - 0, - 0.0402, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - -3.928, - 5.9843, - 95.3834 - ], - "rotation": [ - 0, - 0.0402, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_22_2", - "type": "Mesh", - "position": [ - -5.7841, - 11.9398, - 75.0631 - ], - "rotation": [ - 0, - -0.0411, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeubles", - "type": "Object3D", - "position": [ - -62.3322, - 8.2405, - -10.6914 - ], - "rotation": [ - -3.1416, - -1.1003, - -3.1416 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - -42.2765, - 22.5511, - 18.1635 - ], - "rotation": [ - 0, - 1.2167, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "Groupe2_1", - "type": "Object3D", - "position": [ - -74.1764, - 4.7725, - -44.3093 - ], - "rotation": [ - 0, - 1.0979, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_2", - "type": "Mesh", - "position": [ - -75.8161, - 3.7884, - -41.1777 - ], - "rotation": [ - 0, - 1.0979, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - -72.5368, - 5.7567, - -47.441 - ], - "rotation": [ - 0, - 1.0979, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - -62.3173, - 11.6774, - -9.3092 - ], - "rotation": [ - 0, - 1.0595, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - -85.6865, - 4.7725, - -20.4085 - ], - "rotation": [ - 0, - 1.5621, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1_4", - "type": "Mesh", - "position": [ - -65.7762, - 12.2088, - 9.2812 - ], - "rotation": [ - 0, - 0.8527, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_22", - "type": "Mesh", - "position": [ - -53.6087, - 11.6774, - -26.0884 - ], - "rotation": [ - 0, - 0.7698, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_22", - "type": "Mesh", - "position": [ - -40.1599, - 22.5511, - 6.2908 - ], - "rotation": [ - 0, - 1.2682, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1", - "type": "Mesh", - "position": [ - -34.6253, - 22.5511, - -4.4192 - ], - "rotation": [ - 0, - 1.423, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "immeuble_1_8", - "type": "Mesh", - "position": [ - -89.7126, - 5.0587, - 5.8019 - ], - "rotation": [ - 0, - 1.0307, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "mc", - "type": "Mesh", - "position": [ - 46.9851, - 3.9982, - 69.8056 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbres_quartier", - "type": "Object3D", - "position": [ - -0.699, - 8.2885, - 12.0707 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbres_quartier", - "type": "Object3D", - "position": [ - -0.8061, - 24.8656, - 24.8498 - ], - "rotation": [ - 0, - -0.7007, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - 64.2046, - 1.3963, - -66.2457 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - -77.4301, - 1.3912, - -56.435 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - 94.0948, - 1.396, - -13.7286 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - 9.1941, - 10.2941, - 72.1876 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - 85.6336, - 2.3645, - 16.4202 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - -72.396, - 5.1429, - -14.0848 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - 27.9832, - 6.8786, - -54.0086 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - -8.7053, - 20.947, - 57.5741 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - -89.8978, - 1.4012, - -25.8285 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - 51.8989, - 4.3513, - -50.0921 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - 33.235, - 12.6737, - 58.6656 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - -17.6706, - 6.3797, - 81.7969 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - 34.9999, - 1.4037, - 93.9609 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - -61.8401, - 11.0729, - 13.0361 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - 38.7701, - 19.0344, - 0.8338 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - 59.3076, - 6.5206, - 49.1125 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - -89.2687, - 2.6346, - 16.7745 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - 17.8449, - 19.0217, - -19.9902 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - 69.5646, - 5.8304, - -13.2384 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - -39.7419, - 20.8513, - 23.7226 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - 70.7249, - 3.0111, - -37.8449 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - 38.1303, - 19.7136, - 34.2969 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - -31.6587, - 20.5164, - -4.8425 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - 65.6865, - 1.3944, - 77.4458 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - 54.0114, - 13.5402, - 21.5344 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - -49.1702, - 11.9546, - -18.5196 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - 41.9237, - 12.5818, - -23.4932 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "arbre", - "type": "Mesh", - "position": [ - -1.7275, - 1.4007, - 102.2273 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] - }, - { - "name": "sapin", - "type": "Mesh", - "position": [ - 88.0982, - 1.3938, - 45.9656 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] + "position": [-0.6455, 0, 5.6812], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] }, { "name": "lac", "type": "Mesh", - "position": [ - -0.6455, - 0, - 5.6812 - ], - "rotation": [ - 0, - 0, - 0 - ], - "scale": [ - 1, - 1, - 1 - ] + "position": [-0.6455, 0, 5.6812], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "arbres_quartier", + "type": "Object3D", + "position": [-0.699, 8.2885, 12.0707], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "arbres_quartier", + "type": "Object3D", + "position": [-0.8061, 24.8656, 24.8498], + "rotation": [0, -0.7007, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [64.2046, 1.3963, -66.2457], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [-77.4301, 1.3912, -56.435], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [94.0948, 1.396, -13.7286], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [9.1941, 10.2941, 72.1876], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [85.6336, 2.3645, 16.4202], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [-72.396, 5.1429, -14.0848], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [27.9832, 6.8786, -54.0086], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [-8.7053, 20.947, 57.5741], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [-89.8978, 1.4012, -25.8285], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [51.8989, 4.3513, -50.0921], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [33.235, 12.6737, 58.6656], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [-17.6706, 6.3797, 81.7969], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [34.9999, 1.4037, 93.9609], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [-61.8401, 11.0729, 13.0361], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [38.7701, 19.0344, 0.8338], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [59.3076, 6.5206, 49.1125], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [-89.2687, 2.6346, 16.7745], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [17.8449, 19.0217, -19.9902], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [69.5646, 5.8304, -13.2384], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [-39.7419, 20.8513, 23.7226], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [70.7249, 3.0111, -37.8449], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [38.1303, 19.7136, 34.2969], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [-31.6587, 20.5164, -4.8425], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [65.6865, 1.3944, 77.4458], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [54.0114, 13.5402, 21.5344], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [-49.1702, 11.9546, -18.5196], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [41.9237, 12.5818, -23.4932], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [-1.7275, 1.4007, 102.2273], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [88.0982, 1.3938, 45.9656], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "mc", + "type": "Mesh", + "position": [46.9851, 3.9982, 69.8056], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeubles", + "type": "Object3D", + "position": [-62.3322, 8.2405, -10.6914], + "rotation": [-3.1416, -1.1003, -3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [-42.2765, 22.5511, 18.1635], + "rotation": [0, 1.2167, 0], + "scale": [1, 1, 1] + }, + { + "name": "Groupe2", + "type": "Object3D", + "position": [-74.1764, 4.7725, -44.3093], + "rotation": [0, 1.0979, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeuble", + "type": "Mesh", + "position": [-75.8161, 3.7884, -41.1777], + "rotation": [0, 1.0979, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeuble", + "type": "Mesh", + "position": [-72.5368, 5.7567, -47.441], + "rotation": [0, 1.0979, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [-62.3173, 11.6774, -9.3092], + "rotation": [0, 1.0595, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [-85.6865, 4.7725, -20.4085], + "rotation": [0, 1.5621, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [-65.7762, 12.2088, 9.2812], + "rotation": [0, 0.8527, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_22", + "type": "Mesh", + "position": [-53.6087, 11.6774, -26.0884], + "rotation": [0, 0.7698, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_22", + "type": "Mesh", + "position": [-40.1599, 22.5511, 6.2908], + "rotation": [0, 1.2682, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [-34.6253, 22.5511, -4.4192], + "rotation": [0, 1.423, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [-89.7126, 5.0587, 5.8019], + "rotation": [0, 1.0307, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeubles", + "type": "Object3D", + "position": [-3.8031, 9.4131, 71.852], + "rotation": [3.1416, 0.1131, -3.1416], + "scale": [1, 1, 1] + }, + { + "name": "Groupe2", + "type": "Object3D", + "position": [-3.8544, 22.5511, 59.6426], + "rotation": [0, 0.0613, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_2", + "type": "Mesh", + "position": [-7.3845, 21.5669, 59.8259], + "rotation": [0, 0.0613, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [-0.3242, 23.5352, 59.4593], + "rotation": [0, 0.0613, 0], + "scale": [1, 1, 1] + }, + { + "name": "Groupe2_1", + "type": "Object3D", + "position": [-7.4612, 5.0001, 95.492], + "rotation": [0, 0.0402, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_2", + "type": "Mesh", + "position": [-10.9945, 4.0159, 95.6007], + "rotation": [0, 0.0402, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [-3.928, 5.9843, 95.3834], + "rotation": [0, 0.0402, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_22", + "type": "Mesh", + "position": [-5.7841, 11.9398, 75.0631], + "rotation": [0, -0.0411, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeubles", + "type": "Object3D", + "position": [58.3738, -0.4334, -15.1953], + "rotation": [-3.1416, 1.1456, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "Groupe2_0", + "type": "Object3D", + "position": [93.8738, 4.1985, -8.5653], + "rotation": [-3.1416, 1.2256, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_2", + "type": "Mesh", + "position": [95.0387, 3.2144, -5.2279], + "rotation": [3.1416, 1.2255, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [92.709, 5.1827, -11.9028], + "rotation": [-3.1416, 1.2256, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "Groupe2_1", + "type": "Object3D", + "position": [34.1654, 9.4199, -51.5725], + "rotation": [0, 1.4871, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_2", + "type": "Mesh", + "position": [33.8368, 8.4357, -48.0529], + "rotation": [0, 1.4871, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [34.4941, 10.404, -55.0921], + "rotation": [0, 1.4871, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_22_2", + "type": "Mesh", + "position": [69.7762, 9.4199, 18.3362], + "rotation": [-3.1416, 1.1906, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "Groupe2", + "type": "Object3D", + "position": [41.9036, 19.8047, -4.3543], + "rotation": [0, 1.4051, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_2", + "type": "Mesh", + "position": [41.2876, 18.8206, -0.8735], + "rotation": [0, 1.4051, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [42.5195, 20.7889, -7.8352], + "rotation": [0, 1.4051, 0], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1_4", + "type": "Mesh", + "position": [69.1598, 9.4199, -2.3765], + "rotation": [-3.1416, 1.4482, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [93.8789, 4.1985, 19.927], + "rotation": [3.1416, 0.3786, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [69.4247, 4.1985, -59.3345], + "rotation": [-3.1416, 1.5089, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "Groupe2", + "type": "Object3D", + "position": [50.5352, 9.4199, -38.8631], + "rotation": [3.1416, 0.8956, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_2", + "type": "Mesh", + "position": [52.7187, 8.4357, -36.0832], + "rotation": [3.1416, 0.8956, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [48.3518, 10.404, -41.6431], + "rotation": [3.1416, 0.8956, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1_8", + "type": "Mesh", + "position": [46.4293, 19.8047, 8.6568], + "rotation": [-3.1416, 1.3224, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "Groupe2", + "type": "Object3D", + "position": [33.7611, 19.8047, -15.4911], + "rotation": [3.1416, 0.809, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_2", + "type": "Mesh", + "position": [36.1767, 18.8206, -12.9102], + "rotation": [3.1416, 0.809, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [31.3456, 20.7889, -18.0719], + "rotation": [3.1416, 0.809, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "Groupe2", + "type": "Object3D", + "position": [62.5434, 9.4199, -21.9889], + "rotation": [3.1416, 0.9129, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_2", + "type": "Mesh", + "position": [64.6785, 8.4357, -19.1716], + "rotation": [3.1416, 0.9128, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [60.4084, 10.404, -24.8062], + "rotation": [3.1416, 0.9129, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "Groupe2", + "type": "Object3D", + "position": [46.879, 19.8047, 22.4645], + "rotation": [3.1416, 0.9771, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_2", + "type": "Mesh", + "position": [48.8288, 18.8206, 25.4131], + "rotation": [3.1416, 0.9771, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [44.9291, 20.7889, 19.516], + "rotation": [3.1416, 0.9771, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "Groupe2", + "type": "Object3D", + "position": [22.7244, 19.8047, -23.8431], + "rotation": [3.1416, 0.6712, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_2", + "type": "Mesh", + "position": [25.4717, 18.8206, -21.6186], + "rotation": [3.1416, 0.6712, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [19.9772, 20.7889, -26.0676], + "rotation": [3.1416, 0.6712, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [85.4754, 4.1985, -35.7925], + "rotation": [-3.1416, 1.3009, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "zone_domaine", + "type": "Object3D", + "position": [-16.0844, 5.1349, -46.2022], + "rotation": [0, -1.3459, 0], + "scale": [1, 1, 1] + }, + { + "name": "champ2", + "type": "Object3D", + "position": [3.4286, 16.0553, -30.2701], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [11.4121, 3.9653, -66.3569], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-70.8139, 0.3267, -62.2507], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-14.3249, 3.5365, -68.212], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [24.0599, 4.8852, -59.538], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-52.9323, 4.7206, -42.7644], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-31.704, 4.6976, -57.309], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-25.9223, 3.5026, -65.0315], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-5.4992, 4.7648, -63.6341], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-40.2304, 0.7972, -75.3914], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-38.3843, 1.4111, -71.7936], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-37.0816, 0.7509, -76.9614], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-34.1436, 0.7514, -78.1219], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-29.7402, 1.313, -75.8371], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-30.9037, 0.7698, -79.306], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-16.8479, 0.7778, -83.3324], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-16.1993, 1.345, -79.5906], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-13.4224, 0.7561, -83.8093], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-10.2307, 0.754, -84.0774], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-6.5395, 1.2827, -80.7849], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-6.5723, 0.7644, -84.3157], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-2.4983, 0.4448, -88.0723], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-2.4407, 0.7758, -84.5676], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-6.5447, 0.4457, -87.7718], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-6.6798, 0.3279, -91.2671], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-10.2825, 0.4466, -87.4858], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-10.4639, 0.328, -90.9794], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-14.1131, 0.3277, -90.6931], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-17.854, 0.3273, -90.3823], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-21.9187, 0.3273, -89.8092], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-26.0047, 0.3278, -88.6636], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-29.7266, 0.3282, -87.23], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-33.1971, 0.3284, -85.8711], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-36.5348, 0.3283, -84.5591], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-39.8565, 0.3279, -83.2413], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-43.3585, 0.3276, -81.8413], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-47.1477, 0.3277, -80.111], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-50.9789, 0.3277, -77.9043], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-54.6075, 0.3281, -75.352], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-58.015, 0.3286, -72.6911], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-61.2668, 0.3291, -70.0898], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-64.4716, 0.3293, -67.5244], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-67.6622, 0.3286, -64.9362], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-62.1519, 0.4755, -64.6412], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-65.1778, 0.4774, -62.0524], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-62.5731, 0.8884, -59.2255], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-65.2583, 0.9221, -56.6381], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-68.0021, 0.4844, -59.3904], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-62.6398, 1.5402, -53.9245], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-60.1295, 2.2225, -51.1926], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-57.6942, 2.9614, -48.4318], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-55.3051, 3.7904, -45.6226], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-55.0285, 2.9288, -50.7766], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-52.6408, 3.7656, -47.8775], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-49.9983, 3.7437, -50.0915], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-47.6432, 4.6824, -47.0805], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-50.2744, 4.6994, -44.9432], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-45.0479, 4.6733, -49.1549], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-42.5034, 4.6771, -51.1238], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-40.0021, 4.6962, -52.9499], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-37.4182, 4.7118, -54.5714], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-34.6659, 4.7103, -55.9908], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-36.3713, 3.801, -59.4048], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-39.3483, 3.7876, -57.8793], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-41.2833, 2.9441, -61.2257], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-42.1287, 3.7586, -56.1669], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-44.2741, 2.8999, -59.453], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-46.3307, 2.1209, -62.8234], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-47.0518, 2.8696, -57.4896], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-49.3098, 2.0824, -60.781], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-51.471, 1.3905, -63.9422], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-52.1045, 2.0956, -58.4714], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-54.4709, 1.4066, -61.4374], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-56.7543, 0.8449, -64.3148], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-57.2765, 1.4443, -58.9232], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-59.7579, 0.8624, -61.7795], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-54.7976, 2.1355, -56.0498], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-57.4656, 2.1801, -53.6207], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-59.9754, 1.4918, -56.428], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-55.7722, 0.4691, -69.7848], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-53.5905, 0.8371, -66.8875], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-58.9988, 0.4715, -67.199], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-52.4153, 0.467, -72.3871], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-50.2966, 0.8397, -69.3921], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-46.9317, 0.8543, -71.5878], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-45.0136, 1.4625, -68.1254], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-48.2887, 1.4158, -66.2071], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-41.7242, 1.4734, -69.9029], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-39.8703, 2.205, -66.2953], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-43.1555, 2.1795, -64.6226], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-36.5275, 2.1843, -67.9115], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-34.8539, 2.9593, -64.334], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-38.1084, 2.9689, -62.8268], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-33.248, 3.7921, -60.8149], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-43.5975, 0.8525, -73.4912], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-45.4034, 0.4645, -76.8627], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-48.9279, 0.4658, -74.8171], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-49.7218, 2.8713, -55.3626], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-52.3728, 2.8954, -53.1058], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-44.7745, 3.7336, -54.2644], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-47.382, 3.7303, -52.2273], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-41.8617, 0.4583, -78.548], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-38.4801, 0.4512, -79.9867], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-35.2796, 0.449, -81.2835], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-31.9888, 0.4499, -82.5702], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-28.5374, 0.4485, -83.9109], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-24.8823, 0.4458, -85.2594], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-23.9168, 0.7906, -81.7579], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-27.4483, 0.7856, -80.5556], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-23.0257, 1.347, -78.1146], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-26.3784, 1.3319, -77.0358], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-22.0995, 2.0236, -74.3895], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-25.2687, 2.0056, -73.3753], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-24.1384, 2.7357, -69.717], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-27.1911, 2.7231, -68.6173], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-28.4527, 1.999, -72.195], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-21.1282, 2.7564, -70.6683], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-20.1171, 3.5359, -67.0021], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-22.9884, 3.5156, -66.085], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-17.281, 3.5474, -67.7013], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-18.0783, 2.7729, -71.3947], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-15.5468, 2.0461, -75.6822], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-14.9242, 2.7669, -71.94], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-18.8661, 2.0465, -75.1275], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-19.6373, 1.3657, -78.91], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-20.3814, 0.7975, -82.654], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-21.1303, 0.4462, -86.2784], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-17.4084, 0.4483, -86.8292], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-13.7939, 0.4485, -87.1824], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [17.1237, 1.8611, -75.7969], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [23.493, 2.606, -70.255], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [19.8781, 2.545, -71.3996], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [27.0851, 2.6732, -69.0737], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [26.0441, 3.3494, -65.8794], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [22.5075, 3.284, -67.0215], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [25.0415, 4.0826, -62.7099], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [5.6979, 1.2772, -81.2456], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [1.6222, 1.2936, -81.239], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [1.597, 1.9083, -77.7099], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-2.3509, 1.9098, -77.5042], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-2.4034, 1.2957, -81.0285], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-2.2823, 2.5523, -74.0563], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-6.1525, 2.5503, -73.7771], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-6.3502, 1.9081, -77.2279], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-5.9449, 3.2322, -70.373], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-5.7289, 3.9722, -66.9965], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-2.2046, 3.2338, -70.6485], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-2.1182, 3.9748, -67.2496], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [1.3889, 3.9849, -67.383], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [1.3115, 4.7827, -63.9926], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-2.011, 4.7703, -63.8656], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [4.5112, 4.7923, -63.9186], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [7.6364, 4.787, -63.5674], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [10.7761, 4.7752, -62.9861], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [14.0162, 4.774, -62.2665], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [17.3227, 4.7909, -61.4448], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [20.6662, 4.8285, -60.5336], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [21.572, 4.0223, -63.7816], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [18.1432, 3.9811, -64.7571], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [18.9813, 3.231, -68.0901], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [14.7627, 3.9635, -65.6126], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [15.4971, 3.2048, -69.012], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [16.2679, 2.507, -72.4232], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [12.031, 3.2046, -69.7865], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [12.6499, 2.5008, -73.2628], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [13.2941, 1.85, -76.7185], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [9.003, 2.5182, -73.8935], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [9.4167, 1.8628, -77.4042], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [5.3267, 2.5415, -74.2282], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [5.5209, 1.8889, -77.7351], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [5.063, 3.2371, -70.7487], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [1.4814, 3.2376, -70.8132], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [1.5601, 2.5524, -74.247], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [8.557, 3.2215, -70.3955], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [8.0938, 3.9809, -66.947], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [4.7769, 3.9917, -67.2987], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [9.8319, 1.2611, -80.8477], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "champ1", + "type": "Object3D", + "position": [3.4286, 16.0553, -30.2701], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_0", + "type": "Mesh", + "position": [21.9129, 7.0614, -52.1148], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_1", + "type": "Mesh", + "position": [14.67, 16.8504, -24.9758], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_2", + "type": "Mesh", + "position": [-4.1759, 16.8338, -27.1377], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_3", + "type": "Mesh", + "position": [-5.6179, 7.0424, -55.3704], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_4", + "type": "Mesh", + "position": [-5.4166, 7.9551, -52.5529], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_5", + "type": "Mesh", + "position": [-5.233, 8.8832, -49.7254], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_6", + "type": "Mesh", + "position": [-5.0653, 9.8424, -46.9005], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_7", + "type": "Mesh", + "position": [-4.9172, 10.8242, -44.0908], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_8", + "type": "Mesh", + "position": [-4.7873, 11.8151, -41.2835], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_9", + "type": "Mesh", + "position": [-4.6704, 12.8175, -38.4752], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_10", + "type": "Mesh", + "position": [-4.5659, 13.8223, -35.671], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_11", + "type": "Mesh", + "position": [-4.4628, 14.8249, -32.8511], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_12", + "type": "Mesh", + "position": [-4.3386, 15.8289, -30.0009], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_13", + "type": "Mesh", + "position": [-1.8656, 14.8461, -32.9701], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_14", + "type": "Mesh", + "position": [-1.8353, 15.84, -30.1425], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_15", + "type": "Mesh", + "position": [0.652, 15.8554, -30.2211], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_16", + "type": "Mesh", + "position": [0.61, 16.8412, -27.4298], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_17", + "type": "Mesh", + "position": [-1.7309, 16.8364, -27.3029], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_18", + "type": "Mesh", + "position": [2.8703, 16.8403, -27.3634], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_19", + "type": "Mesh", + "position": [5.1088, 16.8341, -27.063], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_20", + "type": "Mesh", + "position": [7.3875, 16.8324, -26.6201], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_21", + "type": "Mesh", + "position": [9.7701, 16.8341, -26.0953], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_22", + "type": "Mesh", + "position": [12.2114, 16.839, -25.5469], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_23", + "type": "Mesh", + "position": [12.8382, 15.8459, -28.2976], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_24", + "type": "Mesh", + "position": [10.3482, 15.8312, -28.8839], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_25", + "type": "Mesh", + "position": [10.8975, 14.8278, -31.665], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_26", + "type": "Mesh", + "position": [7.9139, 15.826, -29.4276], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_27", + "type": "Mesh", + "position": [8.37, 14.8169, -32.2443], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_28", + "type": "Mesh", + "position": [8.7977, 13.7982, -35.0653], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_29", + "type": "Mesh", + "position": [5.8653, 14.8316, -32.6886], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_30", + "type": "Mesh", + "position": [6.1799, 13.8139, -35.5349], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_31", + "type": "Mesh", + "position": [6.4862, 12.7916, -38.3722], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_32", + "type": "Mesh", + "position": [3.5377, 13.864, -35.7712], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_33", + "type": "Mesh", + "position": [3.7249, 12.8501, -38.6076], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_34", + "type": "Mesh", + "position": [3.909, 11.8411, -41.4432], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_35", + "type": "Mesh", + "position": [0.9278, 12.8715, -38.657], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_36", + "type": "Mesh", + "position": [1.0171, 11.8654, -41.4879], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_37", + "type": "Mesh", + "position": [1.1031, 10.8645, -44.3329], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_38", + "type": "Mesh", + "position": [-1.8864, 11.8368, -41.4212], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_39", + "type": "Mesh", + "position": [-1.9082, 10.8411, -44.2483], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_40", + "type": "Mesh", + "position": [4.2939, 9.8522, -47.1238], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_41", + "type": "Mesh", + "position": [4.0966, 10.838, -44.2907], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_42", + "type": "Mesh", + "position": [1.1699, 9.8746, -47.185], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_43", + "type": "Mesh", + "position": [1.2294, 8.9124, -50.0335], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_44", + "type": "Mesh", + "position": [-1.9519, 9.8553, -47.0793], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_45", + "type": "Mesh", + "position": [-2.0139, 8.8935, -49.9197], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_46", + "type": "Mesh", + "position": [4.7517, 7.97, -52.7667], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_47", + "type": "Mesh", + "position": [4.5126, 8.8984, -49.938], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_48", + "type": "Mesh", + "position": [1.2983, 7.9774, -52.8974], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_49", + "type": "Mesh", + "position": [1.3272, 7.051, -55.8159], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_50", + "type": "Mesh", + "position": [-2.0914, 7.9602, -52.7724], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_51", + "type": "Mesh", + "position": [-2.2051, 7.0431, -55.616], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_52", + "type": "Mesh", + "position": [4.9794, 7.0489, -55.6562], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_53", + "type": "Mesh", + "position": [8.6356, 7.0384, -55.0814], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_54", + "type": "Mesh", + "position": [12.1483, 7.037, -54.3652], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_55", + "type": "Mesh", + "position": [11.625, 7.9392, -51.6356], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_56", + "type": "Mesh", + "position": [8.2227, 7.9454, -52.3055], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_57", + "type": "Mesh", + "position": [11.1259, 8.8565, -48.8917], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_58", + "type": "Mesh", + "position": [7.8345, 8.866, -49.5271], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_59", + "type": "Mesh", + "position": [10.6221, 9.8029, -46.154], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_60", + "type": "Mesh", + "position": [7.4572, 9.8088, -46.7716], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_61", + "type": "Mesh", + "position": [10.1298, 10.778, -43.4129], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_62", + "type": "Mesh", + "position": [7.1095, 10.7832, -44], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_63", + "type": "Mesh", + "position": [9.6719, 11.7716, -40.6454], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_64", + "type": "Mesh", + "position": [6.7926, 11.7815, -41.1878], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_65", + "type": "Mesh", + "position": [12.5261, 11.8016, -39.937], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_66", + "type": "Mesh", + "position": [11.9779, 12.8073, -37.1885], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_67", + "type": "Mesh", + "position": [9.2319, 12.7794, -37.865], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_68", + "type": "Mesh", + "position": [14.7089, 12.8482, -36.4744], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_69", + "type": "Mesh", + "position": [14.0837, 13.8538, -33.7567], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_70", + "type": "Mesh", + "position": [11.4354, 13.8193, -34.4327], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_71", + "type": "Mesh", + "position": [16.7472, 13.8935, -33.0643], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_72", + "type": "Mesh", + "position": [16.0544, 14.8874, -30.3714], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_73", + "type": "Mesh", + "position": [13.4646, 14.853, -31.0333], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_74", + "type": "Mesh", + "position": [15.3574, 15.8734, -27.6679], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_75", + "type": "Mesh", + "position": [17.4423, 12.8936, -35.747], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_76", + "type": "Mesh", + "position": [18.1474, 11.8961, -38.4316], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_77", + "type": "Mesh", + "position": [18.8646, 10.9073, -41.1207], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_78", + "type": "Mesh", + "position": [19.595, 9.9238, -43.818], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_79", + "type": "Mesh", + "position": [20.3535, 8.9572, -46.5394], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_80", + "type": "Mesh", + "position": [21.1388, 8.0082, -49.3067], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_81", + "type": "Mesh", + "position": [17.3672, 8.9059, -47.3638], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_82", + "type": "Mesh", + "position": [18.0703, 7.9654, -50.1244], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_83", + "type": "Mesh", + "position": [18.7235, 7.0449, -52.8776], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_84", + "type": "Mesh", + "position": [14.906, 7.9444, -50.8933], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_85", + "type": "Mesh", + "position": [15.488, 7.0391, -53.6161], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_86", + "type": "Mesh", + "position": [14.308, 8.8686, -48.1541], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_87", + "type": "Mesh", + "position": [16.6617, 9.8732, -44.6197], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_88", + "type": "Mesh", + "position": [13.6882, 9.828, -45.4074], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_89", + "type": "Mesh", + "position": [15.9923, 10.8561, -41.9015], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_90", + "type": "Mesh", + "position": [13.0896, 10.8098, -42.6729], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_91", + "type": "Mesh", + "position": [15.3455, 11.8465, -39.1897], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_92", + "type": "Mesh", + "position": [-1.8737, 12.8415, -38.6004], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_93", + "type": "Mesh", + "position": [0.8385, 13.8775, -35.8359], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_94", + "type": "Mesh", + "position": [-1.867, 13.8471, -35.7865], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_95", + "type": "Mesh", + "position": [3.3283, 14.8668, -32.9433], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_96", + "type": "Mesh", + "position": [0.736, 14.8722, -33.0245], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_97", + "type": "Mesh", + "position": [5.5185, 15.833, -29.8703], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_98", + "type": "Mesh", + "position": [3.1096, 15.8529, -30.1424], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_99", + "type": "Mesh", + "position": [-48.1453, 7.0266, -36.6113], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_100", + "type": "Mesh", + "position": [-33.0347, 16.8004, -14.704], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_101", + "type": "Mesh", + "position": [-16.4865, 16.8879, -24.3421], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_102", + "type": "Mesh", + "position": [-24.6472, 7.0777, -50.9985], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_103", + "type": "Mesh", + "position": [-27.9084, 7.0688, -49.7732], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_104", + "type": "Mesh", + "position": [-31.2571, 7.0698, -48.4518], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_105", + "type": "Mesh", + "position": [-34.5056, 7.0627, -46.7514], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_106", + "type": "Mesh", + "position": [-37.5152, 7.0447, -44.6891], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_107", + "type": "Mesh", + "position": [-40.3646, 7.0348, -42.5789], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_108", + "type": "Mesh", + "position": [-43.0557, 7.0312, -40.52], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_109", + "type": "Mesh", + "position": [-45.6294, 7.029, -38.5433], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_110", + "type": "Mesh", + "position": [-41.5311, 7.9215, -38.4189], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_111", + "type": "Mesh", + "position": [-44.0943, 7.9131, -36.4774], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_112", + "type": "Mesh", + "position": [-46.6055, 7.9043, -34.5707], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_113", + "type": "Mesh", + "position": [-42.5958, 8.8101, -34.3776], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_114", + "type": "Mesh", + "position": [-45.0878, 8.7914, -32.5179], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_115", + "type": "Mesh", + "position": [-43.6043, 9.7125, -30.4406], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_116", + "type": "Mesh", + "position": [-42.1392, 10.6664, -28.3315], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_117", + "type": "Mesh", + "position": [-40.682, 11.6354, -26.1926], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_118", + "type": "Mesh", + "position": [-39.2229, 12.631, -24.0008], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_119", + "type": "Mesh", + "position": [-37.7376, 13.656, -21.7488], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_120", + "type": "Mesh", + "position": [-36.2206, 14.6921, -19.4472], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_121", + "type": "Mesh", + "position": [-34.6597, 15.7371, -17.0928], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_122", + "type": "Mesh", + "position": [-34.0276, 14.7253, -20.9862], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_123", + "type": "Mesh", + "position": [-32.4957, 15.766, -18.6283], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_124", + "type": "Mesh", + "position": [-30.3881, 15.7807, -20.1706], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_125", + "type": "Mesh", + "position": [-28.805, 16.8165, -17.8519], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_126", + "type": "Mesh", + "position": [-30.8774, 16.8124, -16.2965], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_127", + "type": "Mesh", + "position": [-26.8283, 16.8209, -19.3325], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_128", + "type": "Mesh", + "position": [-24.945, 16.8329, -20.6418], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_129", + "type": "Mesh", + "position": [-23.0352, 16.8559, -21.7511], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_130", + "type": "Mesh", + "position": [-20.9621, 16.8724, -22.687], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_131", + "type": "Mesh", + "position": [-18.753, 16.8786, -23.5178], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_132", + "type": "Mesh", + "position": [-21.9378, 15.9357, -25.1001], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_133", + "type": "Mesh", + "position": [-19.6334, 15.959, -25.9432], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_134", + "type": "Mesh", + "position": [-20.4666, 15.0268, -28.4174], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_135", + "type": "Mesh", + "position": [-18.016, 15.0846, -29.1732], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_136", + "type": "Mesh", + "position": [-17.2806, 15.9942, -26.7251], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_137", + "type": "Mesh", + "position": [-18.7262, 14.134, -31.7247], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_138", + "type": "Mesh", + "position": [-19.4452, 13.1457, -34.354], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_139", + "type": "Mesh", + "position": [-20.1963, 12.1317, -37.0465], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_140", + "type": "Mesh", + "position": [-20.9938, 11.106, -39.7867], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_141", + "type": "Mesh", + "position": [-21.8426, 10.0757, -42.5596], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_142", + "type": "Mesh", + "position": [-22.7282, 9.0569, -45.3578], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_143", + "type": "Mesh", + "position": [-23.6575, 8.0608, -48.1799], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_144", + "type": "Mesh", + "position": [-26.8236, 8.0304, -47.0553], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_145", + "type": "Mesh", + "position": [-25.7939, 9.0113, -44.3233], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_146", + "type": "Mesh", + "position": [-28.8249, 8.9852, -43.1821], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_147", + "type": "Mesh", + "position": [-24.8051, 10.0266, -41.5784], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_148", + "type": "Mesh", + "position": [-27.7093, 9.9936, -40.5203], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_149", + "type": "Mesh", + "position": [-30.5427, 9.9297, -39.2823], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_150", + "type": "Mesh", + "position": [-26.6726, 11.0161, -37.8459], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_151", + "type": "Mesh", + "position": [-29.4226, 10.9336, -36.713], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_152", + "type": "Mesh", + "position": [-32.1298, 10.8228, -35.3214], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_153", + "type": "Mesh", + "position": [-28.3773, 11.9379, -34.1323], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_154", + "type": "Mesh", + "position": [-30.9822, 11.8199, -32.8411], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_155", + "type": "Mesh", + "position": [-33.4911, 11.7443, -31.2829], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_156", + "type": "Mesh", + "position": [-29.8479, 12.825, -30.3637], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_157", + "type": "Mesh", + "position": [-32.2576, 12.7464, -28.8854], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_158", + "type": "Mesh", + "position": [-34.6048, 12.701, -27.2649], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_159", + "type": "Mesh", + "position": [-31.0163, 13.7596, -26.4742], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_160", + "type": "Mesh", + "position": [-33.2633, 13.7202, -24.9117], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_161", + "type": "Mesh", + "position": [-29.7227, 14.778, -24.0562], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_162", + "type": "Mesh", + "position": [-31.8647, 14.7496, -22.5374], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_163", + "type": "Mesh", + "position": [-27.5462, 14.8319, -25.4367], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_164", + "type": "Mesh", + "position": [-26.305, 15.8294, -23.0074], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_165", + "type": "Mesh", + "position": [-28.3423, 15.7959, -21.6622], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_166", + "type": "Mesh", + "position": [-25.264, 14.919, -26.5971], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_167", + "type": "Mesh", + "position": [-24.174, 15.89, -24.1421], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_168", + "type": "Mesh", + "position": [-26.3048, 13.9381, -29.0867], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_169", + "type": "Mesh", + "position": [-23.8108, 14.0185, -30.0877], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_170", + "type": "Mesh", + "position": [-22.8914, 14.9865, -27.5703], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_171", + "type": "Mesh", + "position": [-24.7415, 13.0277, -32.638], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_172", + "type": "Mesh", + "position": [-22.1047, 13.0775, -33.5466], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé_173", + "type": "Mesh", + "position": [-21.2769, 14.0671, -30.9553], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol_174", + "type": "Mesh", + "position": [-25.6933, 12.0254, -35.2193], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja_175", + "type": "Mesh", + "position": [-22.9608, 12.0702, -36.1809], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-27.3388, 12.9411, -31.596], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-28.7111, 13.8315, -27.896], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-38.3133, 11.6684, -27.8836], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-35.9252, 11.7011, -29.5866], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-36.9157, 12.6672, -25.6275], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-39.7159, 10.6948, -30.0846], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-37.2643, 10.7232, -31.8548], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-38.6358, 9.763, -34.0729], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-36.0583, 9.7975, -35.9129], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-34.7547, 10.7587, -33.6372], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-37.4266, 8.8588, -38.1564], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-34.6681, 8.9017, -40.0286], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-33.3446, 9.8492, -37.7142], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-36.0646, 7.9667, -42.375], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-33.1048, 8.004, -44.2353], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-31.789, 8.9496, -41.7689], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-38.8688, 7.938, -40.3989], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-40.0542, 8.8274, -36.2638], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "tournesol", + "type": "Mesh", + "position": [-41.1398, 9.7386, -32.2455], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-35.494, 13.6905, -23.3247], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "blé", + "type": "Mesh", + "position": [-23.8565, 11.0527, -38.8595], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "soja", + "type": "Mesh", + "position": [-29.9994, 8.0221, -45.7926], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "buissons", + "type": "Object3D", + "position": [-20.2246, 3.1095, -70.1386], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-14.1379, 5.834, -59.1492], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-13.2719, 5.7979, -59.6663], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-12.4487, 5.7453, -60.2479], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-11.6734, 5.6764, -60.8906], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-10.9509, 5.5916, -61.5902], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-10.2855, 5.4916, -62.3426], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-9.6814, 5.3769, -63.143], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-9.1424, 5.2481, -63.9865], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-8.6716, 5.1063, -64.868], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-8.2721, 4.9521, -65.782], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-7.9463, 4.7865, -66.7228], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-7.6961, 4.6106, -67.6847], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-7.5232, 4.4254, -68.6617], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-7.4286, 4.2322, -69.6478], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-7.413, 4.032, -70.637], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-7.4762, 3.8261, -71.6231], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-7.6181, 3.6158, -72.6], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-7.8378, 3.4024, -73.5617], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-8.1337, 3.1872, -74.5024], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-8.5043, 2.9715, -75.4161], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-8.9471, 2.7566, -76.2973], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-9.4594, 2.5439, -77.1406], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-10.0381, 2.3347, -77.9406], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-10.6796, 2.1303, -78.6926], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-11.3799, 1.932, -79.3918], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-12.1348, 1.7408, -80.034], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-12.9395, 1.5582, -80.6151], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-13.7892, 1.385, -81.1317], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-14.6785, 1.2226, -81.5805], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-15.6021, 1.0717, -81.9588], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-16.5541, 0.9334, -82.2641], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-17.5287, 0.8086, -82.4948], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-18.52, 0.6979, -82.6492], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-19.5218, 0.6021, -82.7265], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-20.5279, 0.5217, -82.7262], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-21.5322, 0.4573, -82.6483], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-22.5284, 0.4093, -82.4933], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-23.5104, 0.3779, -82.262], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-24.4721, 0.3633, -81.9561], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-25.4076, 0.3657, -81.5773], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-26.3112, 0.3849, -81.128], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-27.1773, 0.421, -80.6109], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-28.0005, 0.4737, -80.0292], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-28.7757, 0.5426, -79.3866], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-29.4983, 0.6273, -78.6869], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-30.1636, 0.7274, -77.9346], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-30.7677, 0.8421, -77.1342], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-31.3068, 0.9708, -76.2906], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-31.7775, 1.1127, -75.4091], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-32.1771, 1.2669, -74.4952], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-32.5029, 1.4325, -73.5543], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-32.753, 1.6084, -72.5924], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-32.9259, 1.7935, -71.6154], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-33.0205, 1.9868, -70.6293], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-33.0362, 2.187, -69.6402], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-32.9729, 2.3928, -68.6541], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-32.831, 2.6031, -67.6771], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-32.6114, 2.8166, -66.7154], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-32.3154, 3.0318, -65.7748], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-31.9449, 3.2475, -64.861], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-31.5021, 3.4623, -63.9798], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-30.9898, 3.675, -63.1366], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-30.4111, 3.8842, -62.3365], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-29.7696, 4.0886, -61.5846], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-29.0692, 4.287, -60.8853], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-28.3144, 4.4781, -60.2432], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-27.5096, 4.6608, -59.662], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-26.66, 4.8339, -59.1454], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-25.7706, 4.9964, -58.6966], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-24.8471, 5.1472, -58.3184], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-23.8951, 5.2855, -58.013], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-22.9204, 5.4104, -57.7824], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-21.9291, 5.5211, -57.6279], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-20.9273, 5.6169, -57.5506], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-19.9212, 5.6972, -57.5509], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "buisson", + "type": "Mesh", + "position": [-15.0415, 5.8533, -58.6998], + "rotation": [0.1394, -1.3403, 0.3489], + "scale": [1, 1, 1] + }, + { + "name": "arbres", + "type": "Object3D", + "position": [4.6185, 12.2303, -52.5395], + "rotation": [0, -1.3459, 0], + "scale": [1, 1, 1] + }, + { + "name": "arbres", + "type": "Object3D", + "position": [12.6294, 12.2056, -51.0727], + "rotation": [3.1416, -1.2064, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre", + "type": "Mesh", + "position": [13.5023, 8.8974, -51.6228], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre", + "type": "Mesh", + "position": [12.2232, 11.4636, -44.1262], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre", + "type": "Mesh", + "position": [10.9763, 14.2168, -36.5025], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre", + "type": "Mesh", + "position": [9.7295, 17.0247, -28.7199], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre", + "type": "Mesh", + "position": [-5.3958, 8.8974, -53.0006], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre", + "type": "Mesh", + "position": [-4.9669, 11.4636, -45.3693], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre", + "type": "Mesh", + "position": [-4.5494, 14.2168, -37.6189], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre", + "type": "Mesh", + "position": [-4.1326, 17.0247, -29.7158], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre", + "type": "Mesh", + "position": [-23.8928, 8.8974, -48.8971], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre", + "type": "Mesh", + "position": [-21.7962, 11.4636, -41.6663], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre", + "type": "Mesh", + "position": [-19.7509, 14.2168, -34.2931], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre", + "type": "Mesh", + "position": [-17.7039, 17.0247, -26.7489], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre", + "type": "Mesh", + "position": [-40.4273, 8.8974, -39.6637], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre", + "type": "Mesh", + "position": [-36.858, 11.4636, -33.3286], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre", + "type": "Mesh", + "position": [-33.3621, 14.2168, -26.8015], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre", + "type": "Mesh", + "position": [-29.8487, 17.0247, -20.0648], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "ferme_verti", + "type": "Mesh", + "position": [-20.5518, 8.1225, -70.6352], + "rotation": [3.1416, -1.1848, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "zone_energie", + "type": "Object3D", + "position": [-38.5694, 21.397, 50.3786], + "rotation": [3.1416, -1.1286, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "panneaux_solaires_", + "type": "Object3D", + "position": [-48.6802, 22.897, 32.2311], + "rotation": [-3.1416, -0.0649, -3.1416], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_0", + "type": "Mesh", + "position": [-70.4558, 20.086, 34.4879], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_1", + "type": "Mesh", + "position": [-71.9487, 16.01, 24.3689], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_2", + "type": "Mesh", + "position": [-60.0322, 21.2231, 32.7426], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_3", + "type": "Mesh", + "position": [-60.2651, 18.9485, 24.041], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_4", + "type": "Mesh", + "position": [-50.148, 22.724, 32.715], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_5", + "type": "Mesh", + "position": [-50.2549, 22.2507, 25.653], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_6", + "type": "Mesh", + "position": [-42.6015, 24.6195, 33.6543], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_7", + "type": "Mesh", + "position": [-43.5134, 25.004, 26.3826], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "panneaux_solaires", + "type": "Object3D", + "position": [-28.1161, 22.0484, 66.7736], + "rotation": [-3.1416, -0.9294, -3.1416], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_0", + "type": "Mesh", + "position": [-34.345, 19.9921, 75.3957], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_1", + "type": "Mesh", + "position": [-20.2017, 25.2104, 56.4639], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_2", + "type": "Mesh", + "position": [-23.5978, 14.8881, 79.7071], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_3", + "type": "Mesh", + "position": [-14.252, 24.6604, 59.324], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_4", + "type": "Mesh", + "position": [-17.5336, 20.6605, 65.6909], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_5", + "type": "Mesh", + "position": [-20.6537, 17.5371, 72.1844], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_6", + "type": "Mesh", + "position": [-29.8252, 21.3349, 68.2666], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_7", + "type": "Mesh", + "position": [-24.9035, 22.779, 61.9872], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "éoliennes", + "type": "Object3D", + "position": [-67.1528, 25.397, 68.0941], + "rotation": [-3.1416, -0.5658, -3.1416], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_0", + "type": "Mesh", + "position": [-92.0412, 16.0117, 33.8493], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_1", + "type": "Mesh", + "position": [-86.0049, 16.7563, 32.0059], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_2", + "type": "Mesh", + "position": [-79.8545, 22.1436, 59.5407], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_3", + "type": "Mesh", + "position": [-74.8473, 22.7176, 55.9935], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_4", + "type": "Mesh", + "position": [-60.6625, 22.1436, 80.5695], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_5", + "type": "Mesh", + "position": [-57.0062, 22.7176, 75.7209], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_6", + "type": "Mesh", + "position": [-35.9614, 15.9655, 95.0568], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "Cylindre_7", + "type": "Mesh", + "position": [-33.8614, 16.6976, 89.3578], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "générateur", + "type": "Mesh", + "position": [-48.5737, 21.4281, 54.5311], + "rotation": [3.1416, -1.1286, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "zone_fabrik", + "type": "Object3D", + "position": [35.6417, 8.9438, 51.2707], + "rotation": [0, -1.5519, 0], + "scale": [1, 1, 1] + }, + { + "name": "bati-fabrik", + "type": "Mesh", + "position": [47.4907, 11.1375, 63.8349], + "rotation": [-3.1416, -0.6297, -3.1416], + "scale": [1, 2, 1] + }, + { + "name": "Groupe1", + "type": "Object3D", + "position": [30.2688, 4.9268, 89.1765], + "rotation": [-3.1416, -0.7879, -3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_2", + "type": "Mesh", + "position": [32.7856, 3.9426, 86.6943], + "rotation": [3.1416, -0.7879, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [27.7519, 5.9109, 91.6587], + "rotation": [-3.1416, -0.7879, -3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble", + "type": "Mesh", + "position": [72.2157, 4.1055, 54.7221], + "rotation": [-3.1416, -0.35, -3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_2", + "type": "Mesh", + "position": [18.9151, 13.8995, 66.8272], + "rotation": [3.1416, -1.0563, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "Groupe", + "type": "Object3D", + "position": [50.8106, 15.3193, 42.1115], + "rotation": [3.1416, -0.5678, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_2", + "type": "Mesh", + "position": [53.8087, 14.3351, 40.2387], + "rotation": [3.1416, -0.5678, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "immeuble_1", + "type": "Mesh", + "position": [47.8126, 16.3034, 43.9843], + "rotation": [3.1416, -0.5678, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "zone_ecole", + "type": "Object3D", + "position": [3.7017, 28.0335, 28.3142], + "rotation": [0.1129, -1.4525, 0.1096], + "scale": [1, 1, 1] + }, + { + "name": "terrainarbresecole", + "type": "Object3D", + "position": [-0.6455, 0, 5.6812], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "panneau", + "type": "Mesh", + "position": [1.3128, 26.9637, 34.1952], + "rotation": [0.0126, -0.5805, 0.0154], + "scale": [1, 1, 1] + }, + { + "name": "arbres", + "type": "Object3D", + "position": [-0.8061, 24.8656, 24.8498], + "rotation": [0, -0.7007, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [13.7329, 23.9356, 47.3633], + "rotation": [3.1416, -0.5734, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [6.2307, 23.9356, 50.7095], + "rotation": [3.1416, -0.2657, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [-1.9326, 23.9356, 51.6261], + "rotation": [3.1416, 0.042, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [-9.9901, 23.9356, 50.0271], + "rotation": [3.1416, 0.3498, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [-17.1848, 23.9356, 46.0625], + "rotation": [3.1416, 0.6575, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [-22.8406, 23.9356, 40.105], + "rotation": [-3.1416, 0.9652, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [-26.4262, 23.9356, 32.7143], + "rotation": [-3.1416, 1.273, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [-27.6048, 23.9356, 24.5846], + "rotation": [0, 1.5609, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [-26.2655, 23.9356, 16.4799], + "rotation": [0, 1.2532, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [-22.5343, 23.9356, 9.1615], + "rotation": [0, 0.9454, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [-16.7617, 23.9356, 3.3171], + "rotation": [0, 0.6377, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [-9.49, 23.9356, -0.5042], + "rotation": [0, 0.33, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [-1.4024, 23.9356, -1.9435], + "rotation": [0, 0.0223, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [6.7412, 23.9356, -0.8655], + "rotation": [0, -0.2855, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [14.1757, 23.9356, 2.6285], + "rotation": [0, -0.5932, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [20.2026, 23.9356, 8.2103], + "rotation": [0, -0.9009, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [24.2557, 23.9356, 15.3554], + "rotation": [0, -1.2087, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [25.9543, 23.9356, 23.3925], + "rotation": [0, -1.5164, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [25.1386, 23.9356, 31.5665], + "rotation": [3.1416, -1.3175, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "arbres", + "type": "Object3D", + "position": [-0.8061, 24.8656, 24.8498], + "rotation": [0, -0.7007, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [9.5123, 26.3756, 40.8277], + "rotation": [-3.1416, -0.5734, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [4.1879, 26.3756, 43.2025], + "rotation": [-3.1416, -0.2657, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [-1.6056, 26.3756, 43.853], + "rotation": [-3.1416, 0.042, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [-7.324, 26.3756, 42.7182], + "rotation": [-3.1416, 0.3498, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [-12.4301, 26.3756, 39.9045], + "rotation": [-3.1416, 0.6575, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [-16.444, 26.3756, 35.6765], + "rotation": [-3.1416, 0.9652, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [-18.9887, 26.3756, 30.4312], + "rotation": [-3.1416, 1.273, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [-19.8252, 26.3756, 24.6616], + "rotation": [0, 1.5609, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [-18.8747, 26.3756, 18.9097], + "rotation": [0, 1.2532, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [-16.2267, 26.3756, 13.7158], + "rotation": [0, 0.9454, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [-12.1298, 26.3756, 9.568], + "rotation": [0, 0.6377, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [-6.9691, 26.3756, 6.856], + "rotation": [0, 0.33, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [-1.2293, 26.3756, 5.8345], + "rotation": [0, 0.0223, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [4.5502, 26.3756, 6.5996], + "rotation": [0, -0.2855, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [9.8265, 26.3756, 9.0793], + "rotation": [0, -0.5932, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin", + "type": "Mesh", + "position": [14.1038, 26.3756, 13.0407], + "rotation": [0, -0.9009, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [16.9803, 26.3756, 18.1116], + "rotation": [0, -1.2087, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [18.1858, 26.3756, 23.8156], + "rotation": [0, -1.5164, 0], + "scale": [1, 1, 1] + }, + { + "name": "pylone", + "type": "Mesh", + "position": [17.6069, 26.3756, 29.6167], + "rotation": [3.1416, -1.3175, 3.1416], + "scale": [1, 1, 1] + }, + { + "name": "arbres-école", + "type": "Object3D", + "position": [17.2143, 27.7146, 29.0483], + "rotation": [0.1129, -1.4525, 0.1096], + "scale": [1, 1, 1] + }, + { + "name": "arbres_1", + "type": "Object3D", + "position": [4.0735, 27.5587, 31.7711], + "rotation": [0.0133, -0.6214, 0.0159], + "scale": [1, 1, 1] + }, + { + "name": "sapin_0", + "type": "Mesh", + "position": [20.1553, 24.2993, 42.4409], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin_1", + "type": "Mesh", + "position": [7.5375, 27.2128, 33.2893], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin_2", + "type": "Mesh", + "position": [24.758, 24.3496, 35.4002], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "arbre_3", + "type": "Mesh", + "position": [9.41, 27.2123, 30.5578], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin_4", + "type": "Mesh", + "position": [14.607, 26.6674, 32.4709], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "sapin_5", + "type": "Mesh", + "position": [19.5845, 25.7627, 34.0445], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "arbre_6", + "type": "Mesh", + "position": [16.0263, 25.6963, 39.6732], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "arbre_7", + "type": "Mesh", + "position": [11.8387, 26.6517, 36.6584], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] + }, + { + "name": "lecole", + "type": "Object3D", + "position": [-0.3871, 30.9693, 26.172], + "rotation": [0.0126, -0.5805, 0.0154], + "scale": [1, 2, 1] + }, + { + "name": "bati-ecole", + "type": "Mesh", + "position": [-7.1777, 30.3365, 36.5318], + "rotation": [0.0126, -0.5805, 0.0154], + "scale": [1, 2, 1] + }, + { + "name": "bati-ecole", + "type": "Mesh", + "position": [6.4132, 30.5965, 15.813], + "rotation": [0.0126, -0.5805, 0.0154], + "scale": [1, 2, 1] + }, + { + "name": "bati-ecole", + "type": "Mesh", + "position": [-0.3968, 31.9749, 26.1711], + "rotation": [0.0126, -0.5805, 0.0154], + "scale": [1, 2, 1] + }, + { + "name": "terrain", + "type": "Mesh", + "position": [-0.6455, 0, 5.6812], + "rotation": [0, 0, 0], + "scale": [1, 1, 1] } -] \ No newline at end of file +] diff --git a/public/models/pylone/cable1_base_color.png b/public/models/pylone/cable1_base_color.png new file mode 100644 index 0000000..f1c5101 --- /dev/null +++ b/public/models/pylone/cable1_base_color.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e855a105690f232494d5f3959d8fd6e8512de53de6d1b8a7e13e79d44b455635 +size 170284 diff --git a/public/models/pylone/cable1_height.png b/public/models/pylone/cable1_height.png new file mode 100644 index 0000000..713980d --- /dev/null +++ b/public/models/pylone/cable1_height.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:208daeea7306a6a576fbe1098c66d59571dd984635d7fb6c017fd767cde531ed +size 3178 diff --git a/public/models/pylone/cable1_metallic.png b/public/models/pylone/cable1_metallic.png new file mode 100644 index 0000000..b46e54a --- /dev/null +++ b/public/models/pylone/cable1_metallic.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60041773ef2d493f3547aa1b0fbdf5b1bb548a3da39164384293ef5292b2c5b3 +size 1118 diff --git a/public/models/pylone/cable1_mixed_ao.png b/public/models/pylone/cable1_mixed_ao.png new file mode 100644 index 0000000..b21d620 --- /dev/null +++ b/public/models/pylone/cable1_mixed_ao.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2d3210319fea926e024d9d64c9440319550e548a7147f0998610293d05351411 +size 106768 diff --git a/public/models/pylone/cable1_normal.png b/public/models/pylone/cable1_normal.png new file mode 100644 index 0000000..707fa61 --- /dev/null +++ b/public/models/pylone/cable1_normal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d2d01588d749aa5fc4ca2598db56250d22381ca2cb5d4acf22f7e2075d9ee69f +size 145554 diff --git a/public/models/pylone/cable1_normal_opengl.png b/public/models/pylone/cable1_normal_opengl.png new file mode 100644 index 0000000..7fdc9e2 --- /dev/null +++ b/public/models/pylone/cable1_normal_opengl.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:700e5261c9513fe08bf918e8e73c82b390bcd5b220427ae8a061150ace2bb39d +size 146495 diff --git a/public/models/pylone/cable1_roughness.png b/public/models/pylone/cable1_roughness.png new file mode 100644 index 0000000..59ffd1c --- /dev/null +++ b/public/models/pylone/cable1_roughness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6fee20587280c1bee1ed7a251c9584a48b4e159d45f674b6aabe58783c17049a +size 53738 diff --git a/public/models/pylone/cable2_base_color.png b/public/models/pylone/cable2_base_color.png new file mode 100644 index 0000000..67aeedd --- /dev/null +++ b/public/models/pylone/cable2_base_color.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fef27c0cae8e434723a7a200f6a490b96349a002af0e2ba583ab689a7501bb58 +size 152980 diff --git a/public/models/pylone/cable2_height.png b/public/models/pylone/cable2_height.png new file mode 100644 index 0000000..713980d --- /dev/null +++ b/public/models/pylone/cable2_height.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:208daeea7306a6a576fbe1098c66d59571dd984635d7fb6c017fd767cde531ed +size 3178 diff --git a/public/models/pylone/cable2_metallic.png b/public/models/pylone/cable2_metallic.png new file mode 100644 index 0000000..b46e54a --- /dev/null +++ b/public/models/pylone/cable2_metallic.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60041773ef2d493f3547aa1b0fbdf5b1bb548a3da39164384293ef5292b2c5b3 +size 1118 diff --git a/public/models/pylone/cable2_mixed_ao.png b/public/models/pylone/cable2_mixed_ao.png new file mode 100644 index 0000000..d0c5f78 --- /dev/null +++ b/public/models/pylone/cable2_mixed_ao.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:00fcdce71383ed2081696921fa6ef9592e653560bb7c3058f7d0ac4da6427a8c +size 100588 diff --git a/public/models/pylone/cable2_normal.png b/public/models/pylone/cable2_normal.png new file mode 100644 index 0000000..0aeb96a --- /dev/null +++ b/public/models/pylone/cable2_normal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6187d87bcb23afd869017739161862832c6520754a0670c460cd326d85357c0f +size 145219 diff --git a/public/models/pylone/cable2_normal_opengl.png b/public/models/pylone/cable2_normal_opengl.png new file mode 100644 index 0000000..0b68af5 --- /dev/null +++ b/public/models/pylone/cable2_normal_opengl.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:22660de1a0682b1abd1684f7e3fb5e2589b483eabe301f72f3e9d821fe82226e +size 146306 diff --git a/public/models/pylone/cable2_roughness.png b/public/models/pylone/cable2_roughness.png new file mode 100644 index 0000000..bdad05d --- /dev/null +++ b/public/models/pylone/cable2_roughness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:603aa4f5dc13de2d56a150a3ebaf555b50d87e6928cb8f9f97d372035caf0123 +size 52660 diff --git a/public/models/pylone/chap_base_color.png b/public/models/pylone/chap_base_color.png new file mode 100644 index 0000000..747833f --- /dev/null +++ b/public/models/pylone/chap_base_color.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:92723a60f4f0fe39a6309fb3faec588c0178a67cf765c52646a776134d5086b6 +size 86318 diff --git a/public/models/pylone/chap_height.png b/public/models/pylone/chap_height.png new file mode 100644 index 0000000..713980d --- /dev/null +++ b/public/models/pylone/chap_height.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:208daeea7306a6a576fbe1098c66d59571dd984635d7fb6c017fd767cde531ed +size 3178 diff --git a/public/models/pylone/chap_metallic.png b/public/models/pylone/chap_metallic.png new file mode 100644 index 0000000..b46e54a --- /dev/null +++ b/public/models/pylone/chap_metallic.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60041773ef2d493f3547aa1b0fbdf5b1bb548a3da39164384293ef5292b2c5b3 +size 1118 diff --git a/public/models/pylone/chap_mixed_ao.png b/public/models/pylone/chap_mixed_ao.png new file mode 100644 index 0000000..ae16438 --- /dev/null +++ b/public/models/pylone/chap_mixed_ao.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:08db27428a9262caa0f45d814fe4e72e813cebe3ea2139417c34c749782b5071 +size 200657 diff --git a/public/models/pylone/chap_normal.png b/public/models/pylone/chap_normal.png new file mode 100644 index 0000000..a7fdf27 --- /dev/null +++ b/public/models/pylone/chap_normal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:81c90f031b04c4376d8d715f4b7087fba8174539e79270155c7ff56d3b5be726 +size 187794 diff --git a/public/models/pylone/chap_normal_opengl.png b/public/models/pylone/chap_normal_opengl.png new file mode 100644 index 0000000..a31b821 --- /dev/null +++ b/public/models/pylone/chap_normal_opengl.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7d9a52a596c1cafc8e299efcaf215b8d4501ae9ab09ed84ca36729451797ede0 +size 188092 diff --git a/public/models/pylone/chap_roughness.png b/public/models/pylone/chap_roughness.png new file mode 100644 index 0000000..1588b9f --- /dev/null +++ b/public/models/pylone/chap_roughness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cbccc4f4042014922faab436e859024a6e66656eb1b3a7aa2f80c4c48f112e76 +size 78815 diff --git a/public/models/pylone/lampe_base_color.png b/public/models/pylone/lampe_base_color.png new file mode 100644 index 0000000..de93f3e --- /dev/null +++ b/public/models/pylone/lampe_base_color.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3b1df0d30023f3f9be05c310f1d2c3fe2b80c9cc79b631f8ceee7df17bb0d7d6 +size 435213 diff --git a/public/models/pylone/lampe_height.png b/public/models/pylone/lampe_height.png new file mode 100644 index 0000000..713980d --- /dev/null +++ b/public/models/pylone/lampe_height.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:208daeea7306a6a576fbe1098c66d59571dd984635d7fb6c017fd767cde531ed +size 3178 diff --git a/public/models/pylone/lampe_metallic.png b/public/models/pylone/lampe_metallic.png new file mode 100644 index 0000000..a2a6ea5 --- /dev/null +++ b/public/models/pylone/lampe_metallic.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73f0f1f9a2449135c3786b1e2a8b0308d91ce0b17e8ab419d42dbe12f6cd49ad +size 119101 diff --git a/public/models/pylone/lampe_mixed_ao.png b/public/models/pylone/lampe_mixed_ao.png new file mode 100644 index 0000000..129ce8e --- /dev/null +++ b/public/models/pylone/lampe_mixed_ao.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79a620d8bf89c36ac579e361a0383f2e00cc0a46bd20af3866a272fbdb66cf44 +size 333234 diff --git a/public/models/pylone/lampe_normal.png b/public/models/pylone/lampe_normal.png new file mode 100644 index 0000000..3fbc93b --- /dev/null +++ b/public/models/pylone/lampe_normal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:670b8083516218cfa7fee2abfc4b5647bc7c97c513b6ffda6c81544078b190d1 +size 416583 diff --git a/public/models/pylone/lampe_normal_opengl.png b/public/models/pylone/lampe_normal_opengl.png new file mode 100644 index 0000000..ce6b274 --- /dev/null +++ b/public/models/pylone/lampe_normal_opengl.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:16f4756e77ffb2b96b4964dbf3ba1a455cc551ab04eedbad5f9b25476652e064 +size 420113 diff --git a/public/models/pylone/lampe_opacity.png b/public/models/pylone/lampe_opacity.png new file mode 100644 index 0000000..377c715 --- /dev/null +++ b/public/models/pylone/lampe_opacity.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d3bdaa1be72aa14047f2a4c50e112e9e428a088bbbaa5153ad40ae2897decf2b +size 3179 diff --git a/public/models/pylone/lampe_roughness.png b/public/models/pylone/lampe_roughness.png new file mode 100644 index 0000000..f25e00b --- /dev/null +++ b/public/models/pylone/lampe_roughness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:23a8670ac6eb007f98005bf66c49168f20dbb89957478da0254a568e93b71b35 +size 176715 diff --git a/public/models/pylone/model.gltf b/public/models/pylone/model.gltf new file mode 100644 index 0000000..05d147d --- /dev/null +++ b/public/models/pylone/model.gltf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a4beb235d9ce60f1a59a8e73b9e1bcdb44f45c6a2017fc6e912a29cee5f249ec +size 3588015 diff --git a/public/models/pylone/panneaux_base_color.png b/public/models/pylone/panneaux_base_color.png new file mode 100644 index 0000000..4b9de68 --- /dev/null +++ b/public/models/pylone/panneaux_base_color.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:86cd37f97c5a3f6d381c8aefee406e784e7827cd895d870354624384fe1b79e7 +size 156525 diff --git a/public/models/pylone/panneaux_height.png b/public/models/pylone/panneaux_height.png new file mode 100644 index 0000000..713980d --- /dev/null +++ b/public/models/pylone/panneaux_height.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:208daeea7306a6a576fbe1098c66d59571dd984635d7fb6c017fd767cde531ed +size 3178 diff --git a/public/models/pylone/panneaux_metallic.png b/public/models/pylone/panneaux_metallic.png new file mode 100644 index 0000000..b46e54a --- /dev/null +++ b/public/models/pylone/panneaux_metallic.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60041773ef2d493f3547aa1b0fbdf5b1bb548a3da39164384293ef5292b2c5b3 +size 1118 diff --git a/public/models/pylone/panneaux_mixed_ao.png b/public/models/pylone/panneaux_mixed_ao.png new file mode 100644 index 0000000..e2ac5c4 --- /dev/null +++ b/public/models/pylone/panneaux_mixed_ao.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a73fc0135fbacb8be5a64251dabe071e402d48c9d0f4c2bd25fc033c92eafbc6 +size 237957 diff --git a/public/models/pylone/panneaux_normal.png b/public/models/pylone/panneaux_normal.png new file mode 100644 index 0000000..d910f65 --- /dev/null +++ b/public/models/pylone/panneaux_normal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:54f044e90f7a96a9d9218733b9a4136c164f0c60f4389baa4d0f14b2cbef8270 +size 83209 diff --git a/public/models/pylone/panneaux_normal_opengl.png b/public/models/pylone/panneaux_normal_opengl.png new file mode 100644 index 0000000..2956cf0 --- /dev/null +++ b/public/models/pylone/panneaux_normal_opengl.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:537b66ad9e53107bc4b577877ce2282d612de6e38241f5911a2f330ef9ed4c22 +size 86378 diff --git a/public/models/pylone/panneaux_roughness.png b/public/models/pylone/panneaux_roughness.png new file mode 100644 index 0000000..3848015 --- /dev/null +++ b/public/models/pylone/panneaux_roughness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a4c3430448c893a4c9b13c24b6ba450d2a54ecc19fe73f8a6e07244499f4f13 +size 47993 diff --git a/public/models/pylone/pied_base_color.png b/public/models/pylone/pied_base_color.png new file mode 100644 index 0000000..bf377ef --- /dev/null +++ b/public/models/pylone/pied_base_color.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d0175ecfec561cc3614884bfd2a06095715c799f148d20e86c136ef6a3b0d022 +size 220660 diff --git a/public/models/pylone/pied_height.png b/public/models/pylone/pied_height.png new file mode 100644 index 0000000..713980d --- /dev/null +++ b/public/models/pylone/pied_height.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:208daeea7306a6a576fbe1098c66d59571dd984635d7fb6c017fd767cde531ed +size 3178 diff --git a/public/models/pylone/pied_metallic.png b/public/models/pylone/pied_metallic.png new file mode 100644 index 0000000..b46e54a --- /dev/null +++ b/public/models/pylone/pied_metallic.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60041773ef2d493f3547aa1b0fbdf5b1bb548a3da39164384293ef5292b2c5b3 +size 1118 diff --git a/public/models/pylone/pied_mixed_ao.png b/public/models/pylone/pied_mixed_ao.png new file mode 100644 index 0000000..e0b72f3 --- /dev/null +++ b/public/models/pylone/pied_mixed_ao.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cf789a1fdd11527c58d70fe288ad149f5f032e677805e914e8142a83895b6b63 +size 268116 diff --git a/public/models/pylone/pied_normal.png b/public/models/pylone/pied_normal.png new file mode 100644 index 0000000..8b3b7bd --- /dev/null +++ b/public/models/pylone/pied_normal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1070e5d8ae0b38b979bf34f80c03e00a628b21b53bfe64e2a801fccfb976847f +size 259296 diff --git a/public/models/pylone/pied_normal_opengl.png b/public/models/pylone/pied_normal_opengl.png new file mode 100644 index 0000000..648434d --- /dev/null +++ b/public/models/pylone/pied_normal_opengl.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:77678fa53d89918eefc61f1a6942075cb73e38ff30f9ace95d7916e250d20af3 +size 261233 diff --git a/public/models/pylone/pied_roughness.png b/public/models/pylone/pied_roughness.png new file mode 100644 index 0000000..2d705d1 --- /dev/null +++ b/public/models/pylone/pied_roughness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:919f981e76f106cf597b90ff0f0d175a3bb61beee039a92b370445f463d52516 +size 104005 diff --git a/public/models/pylone/puces_base_color.png b/public/models/pylone/puces_base_color.png new file mode 100644 index 0000000..566ec43 --- /dev/null +++ b/public/models/pylone/puces_base_color.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e1b5e8e6c40fd84b7d1220990653359933880e478f9dd5122d2f8359d12fb97 +size 343406 diff --git a/public/models/pylone/puces_height.png b/public/models/pylone/puces_height.png new file mode 100644 index 0000000..713980d --- /dev/null +++ b/public/models/pylone/puces_height.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:208daeea7306a6a576fbe1098c66d59571dd984635d7fb6c017fd767cde531ed +size 3178 diff --git a/public/models/pylone/puces_metallic.png b/public/models/pylone/puces_metallic.png new file mode 100644 index 0000000..b46e54a --- /dev/null +++ b/public/models/pylone/puces_metallic.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60041773ef2d493f3547aa1b0fbdf5b1bb548a3da39164384293ef5292b2c5b3 +size 1118 diff --git a/public/models/pylone/puces_mixed_ao.png b/public/models/pylone/puces_mixed_ao.png new file mode 100644 index 0000000..7c4ea3c --- /dev/null +++ b/public/models/pylone/puces_mixed_ao.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c217f278d763ba946e5133c85d45295090cd9a790650af6f084bdd8d169bb5ab +size 262622 diff --git a/public/models/pylone/puces_normal.png b/public/models/pylone/puces_normal.png new file mode 100644 index 0000000..addb846 --- /dev/null +++ b/public/models/pylone/puces_normal.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d4f066202057a3edcdf154c9174f1520ec44bf4ce9bab75a24c515b4c4cd3b52 +size 129597 diff --git a/public/models/pylone/puces_normal_opengl.png b/public/models/pylone/puces_normal_opengl.png new file mode 100644 index 0000000..fb4e86d --- /dev/null +++ b/public/models/pylone/puces_normal_opengl.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4f4e1e08446160b90a55c8f3f7b478cbcf7ea2084add0ad406fe25c1f3b92175 +size 133187 diff --git a/public/models/pylone/puces_roughness.png b/public/models/pylone/puces_roughness.png new file mode 100644 index 0000000..50a2a9b --- /dev/null +++ b/public/models/pylone/puces_roughness.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:814dccc984084f46d5e09a62f5001441d96aa6aa928f3dcbf2b14e73ad975cb6 +size 63405 diff --git a/src/App.tsx b/src/App.tsx index 5879bcd..c6ccffa 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,23 +1,8 @@ -import { Suspense } from "react"; -import { Canvas } from "@react-three/fiber"; -import { Crosshair } from "@/components/ui/Crosshair"; -import { InteractPrompt } from "@/components/ui/InteractPrompt"; -import { DebugPerf } from "@/utils/debug/DebugPerf"; -import { World } from "@/world/World"; +import { RouterProvider } from "@tanstack/react-router"; +import { router } from "@/router"; function App(): React.JSX.Element { - return ( - <> - - - - - - - - - - ); + return ; } export default App; diff --git a/src/utils/debug/DebugPerf.tsx b/src/components/debug/DebugPerf.tsx similarity index 100% rename from src/utils/debug/DebugPerf.tsx rename to src/components/debug/DebugPerf.tsx diff --git a/src/utils/debug/scene/DebugCameraControls.tsx b/src/components/debug/scene/DebugCameraControls.tsx similarity index 77% rename from src/utils/debug/scene/DebugCameraControls.tsx rename to src/components/debug/scene/DebugCameraControls.tsx index 9fc5f99..11acdb0 100644 --- a/src/utils/debug/scene/DebugCameraControls.tsx +++ b/src/components/debug/scene/DebugCameraControls.tsx @@ -3,17 +3,18 @@ import { DEBUG_CAMERA_DAMPING_FACTOR, DEBUG_CAMERA_MAX_DISTANCE, DEBUG_CAMERA_MIN_DISTANCE, -} from "@/data/debugConfig"; +} from "@/data/debug/debugConfig"; import { PLAYER_EYE_HEIGHT, PLAYER_SPAWN_POSITION_GAME, -} from "@/data/playerConfig"; +} from "@/data/player/playerConfig"; +import type { Vector3Tuple } from "@/types/three"; -const DEBUG_CAMERA_TARGET = [ +const DEBUG_CAMERA_TARGET: Vector3Tuple = [ PLAYER_SPAWN_POSITION_GAME[0], PLAYER_EYE_HEIGHT, PLAYER_SPAWN_POSITION_GAME[2], -] as const; +]; export function DebugCameraControls(): React.JSX.Element { return ( diff --git a/src/utils/debug/scene/DebugHelpers.tsx b/src/components/debug/scene/DebugHelpers.tsx similarity index 94% rename from src/utils/debug/scene/DebugHelpers.tsx rename to src/components/debug/scene/DebugHelpers.tsx index 738c46e..17b50ac 100644 --- a/src/utils/debug/scene/DebugHelpers.tsx +++ b/src/components/debug/scene/DebugHelpers.tsx @@ -5,7 +5,7 @@ import { DEBUG_GRID_SECONDARY_COLOR, DEBUG_GRID_SIZE, DEBUG_GRID_Y, -} from "@/data/debugConfig"; +} from "@/data/debug/debugConfig"; import { Debug } from "@/utils/debug/Debug"; export function DebugHelpers(): React.JSX.Element | null { diff --git a/src/components/docs/DocsDocument.tsx b/src/components/docs/DocsDocument.tsx new file mode 100644 index 0000000..379dbb9 --- /dev/null +++ b/src/components/docs/DocsDocument.tsx @@ -0,0 +1,51 @@ +import ReactMarkdown from "react-markdown"; +import remarkGfm from "remark-gfm"; +import { useDocsLanguage } from "@/hooks/docs/useDocsLanguage"; + +interface DocsDocumentProps { + title: string; + meta: string; + content: string; + frContent: string; +} + +export function DocsDocument({ + title, + meta, + content, + frContent, +}: DocsDocumentProps): React.JSX.Element { + const { language, toggleLanguage } = useDocsLanguage(); + const translatedContent = language === "fr" ? frContent : content; + + return ( +
+
+ {title} + +
+ +
+
+ {title} + {meta} +
+ + {translatedContent} + +
+
+ ); +} diff --git a/src/components/docs/DocsLayout.tsx b/src/components/docs/DocsLayout.tsx new file mode 100644 index 0000000..65fc3a5 --- /dev/null +++ b/src/components/docs/DocsLayout.tsx @@ -0,0 +1,53 @@ +import { Link, Outlet } from "@tanstack/react-router"; +import { Home } from "lucide-react"; +import { docGroups } from "@/data/docs/docsSections"; +import { DocsLanguageProvider } from "@/providers/docs/DocsLanguageProvider"; + +export function DocsLayout(): React.JSX.Element { + return ( + +
+ + + +
+
+ ); +} diff --git a/src/components/editor/EditorControls.tsx b/src/components/editor/EditorControls.tsx new file mode 100644 index 0000000..e68cd70 --- /dev/null +++ b/src/components/editor/EditorControls.tsx @@ -0,0 +1,309 @@ +import { + Box, + Braces, + Download, + Expand, + Keyboard, + Lock, + MousePointer2, + Move3D, + Redo2, + RotateCw, + Save, + Undo2, +} from "lucide-react"; +import type { MapNode, TransformMode } from "@/types/editor"; + +interface EditorControlsProps { + transformMode: TransformMode; + onTransformModeChange: (mode: TransformMode) => void; + selectedNodeIndex: number | null; + mapNodes: MapNode[]; + nodesCount: number; + selectedNodeName: string | null; + undoCount: number; + redoCount: number; + onUndo: () => void; + onRedo: () => void; + onExportJson: () => void; + onSaveToServer?: (() => void | Promise) | undefined; + onPlayerMode?: (() => void) | undefined; + isPlayerMode?: boolean; +} + +const TRANSFORM_OPTIONS = [ + { mode: "translate", label: "Translate", shortcut: "T", Icon: Move3D }, + { mode: "rotate", label: "Rotate", shortcut: "R", Icon: RotateCw }, + { mode: "scale", label: "Scale", shortcut: "S", Icon: Expand }, +] as const; + +const EDITOR_SHORTCUTS = [ + ["Click", "Select object"], + ["T / R / S", "Transform mode"], + ["Ctrl Z / Y", "Undo / redo"], + ["Esc", "Deselect"], + ["WASD", "Move when locked"], +] as const; + +export function EditorControls({ + transformMode, + onTransformModeChange, + selectedNodeIndex, + mapNodes, + nodesCount, + selectedNodeName, + undoCount, + redoCount, + onUndo, + onRedo, + onExportJson, + onSaveToServer, + onPlayerMode, + isPlayerMode, +}: EditorControlsProps): React.JSX.Element { + const viewModeLabel = isPlayerMode ? "View locked" : "Lock view"; + const jsonPreview = getJsonPreview(mapNodes, selectedNodeIndex); + + return ( + <> + + + ); +} + +interface JsonPreviewLine { + number: number; + content: string; + isSelected: boolean; +} + +interface JsonPreview { + label: string; + lines: JsonPreviewLine[]; +} + +function getJsonPreview( + mapNodes: MapNode[], + selectedNodeIndex: number | null, +): JsonPreview { + const { lines, ranges } = formatMapNodesWithRanges(mapNodes); + + if (selectedNodeIndex === null || !ranges[selectedNodeIndex]) { + return { + label: `${lines.length} raw lines`, + lines: lines.map((content, index) => ({ + number: index + 1, + content, + isSelected: false, + })), + }; + } + + const range = ranges[selectedNodeIndex]; + const selectedLines = lines.slice(range.start - 1, range.end); + + return { + label: `Lines ${range.start}-${range.end}`, + lines: selectedLines.map((content, index) => ({ + number: range.start + index, + content, + isSelected: true, + })), + }; +} + +function formatMapNodesWithRanges(mapNodes: MapNode[]): { + lines: string[]; + ranges: Array<{ start: number; end: number }>; +} { + const lines = ["["]; + const ranges: Array<{ start: number; end: number }> = []; + + mapNodes.forEach((node, index) => { + const objectLines = JSON.stringify(node, null, 2) + .split("\n") + .map((line) => ` ${line}`); + + if (index < mapNodes.length - 1) { + objectLines[objectLines.length - 1] += ","; + } + + const start = lines.length + 1; + lines.push(...objectLines); + ranges.push({ start, end: lines.length }); + }); + + lines.push("]"); + + return { lines, ranges }; +} diff --git a/src/components/editor/scene/EditorMap.tsx b/src/components/editor/scene/EditorMap.tsx new file mode 100644 index 0000000..8b94718 --- /dev/null +++ b/src/components/editor/scene/EditorMap.tsx @@ -0,0 +1,364 @@ +import { useMemo, useRef, useEffect, useState } from "react"; +import { Grid, TransformControls, useGLTF } from "@react-three/drei"; +import type { ThreeEvent } from "@react-three/fiber"; +import * as THREE from "three"; + +import type { SceneData, MapNode, TransformMode } from "@/types/editor"; + +interface EditorMapProps { + sceneData: SceneData; + selectedNodeIndex: number | null; + onSelectNode: (index: number | null) => void; + hoveredNodeIndex: number | null; + onHoverNode: (index: number | null) => void; + transformMode: TransformMode; + onTransformStart: () => void; + onTransformEnd: () => void; + onNodeTransform: (nodeIndex: number, transform: MapNode) => void; +} + +type EditorNodeObjectRef = React.RefObject>; + +interface EditorNodeCommonProps { + index: number; + node: MapNode; + isSelected: boolean; + isHovered: boolean; + objectsMapRef: EditorNodeObjectRef; + onSelectNode: (index: number | null) => void; + onHoverNode: (index: number | null) => void; +} + +interface EditorNodePointerHandlers { + onClick: (event: ThreeEvent) => void; + onPointerEnter: (event: ThreeEvent) => void; + onPointerLeave: (event: ThreeEvent) => void; +} + +function applyNodeTransform(object: THREE.Object3D, node: MapNode): void { + object.position.set(...node.position); + object.rotation.set(...node.rotation); + object.scale.set(...node.scale); +} + +function useRegisteredEditorNode( + objectRef: React.RefObject, + index: number, + node: MapNode, + objectsMapRef: EditorNodeObjectRef, +): void { + useEffect(() => { + const object = objectRef.current; + if (object) { + applyNodeTransform(object, node); + object.userData = { nodeIndex: index, nodeName: node.name }; + objectsMapRef.current.set(index, object); + } + + const currentMap = objectsMapRef.current; + const currentIndex = index; + return () => { + currentMap.delete(currentIndex); + }; + }, [index, node, objectRef, objectsMapRef]); + + useEffect(() => { + const object = objectRef.current; + if (object) { + applyNodeTransform(object, node); + } + }, [node, objectRef]); +} + +function disposeMaterial(material: THREE.Material | THREE.Material[]): void { + if (Array.isArray(material)) { + material.forEach((item) => item.dispose()); + return; + } + + material.dispose(); +} + +function cloneHighlightedMaterial( + material: THREE.Material | THREE.Material[], + color: string, +): THREE.Material | THREE.Material[] { + if (Array.isArray(material)) { + return material.map((item) => cloneHighlightedMaterial(item, color)).flat(); + } + + const clone = material.clone(); + if (clone instanceof THREE.MeshStandardMaterial) { + clone.color.set(color); + } + return clone; +} + +function getNodeHighlightColor( + isSelected: boolean, + isHovered: boolean, +): string | null { + if (isSelected) return "#ffffff"; + if (isHovered) return "#b8b8b8"; + return null; +} + +function createEditorNodePointerHandlers( + index: number, + onSelectNode: (index: number | null) => void, + onHoverNode: (index: number | null) => void, +): EditorNodePointerHandlers { + return { + onClick: (event) => { + event.stopPropagation(); + onSelectNode(index); + }, + onPointerEnter: (event) => { + event.stopPropagation(); + onHoverNode(index); + }, + onPointerLeave: (event) => { + event.stopPropagation(); + onHoverNode(null); + }, + }; +} + +export function EditorMap({ + sceneData, + selectedNodeIndex, + onSelectNode, + hoveredNodeIndex, + onHoverNode, + transformMode, + onTransformStart, + onTransformEnd, + onNodeTransform, +}: EditorMapProps): React.JSX.Element { + const objectsMapRef = useRef>(new Map()); + + const handleTransformMouseDown = () => { + onTransformStart?.(); + }; + + const handleTransformMouseUp = () => { + if (selectedNodeIndex !== null) { + const obj = objectsMapRef.current.get(selectedNodeIndex); + if (!obj) return; + const node = sceneData.mapNodes[selectedNodeIndex]; + if (node) { + const updatedNode: MapNode = { + ...node, + position: [obj.position.x, obj.position.y, obj.position.z], + rotation: [obj.rotation.x, obj.rotation.y, obj.rotation.z], + scale: [obj.scale.x, obj.scale.y, obj.scale.z], + }; + onNodeTransform?.(selectedNodeIndex, updatedNode); + } + } + onTransformEnd?.(); + }; + + const [selectedObject, setSelectedObject] = useState( + null, + ); + + useEffect(() => { + if (selectedNodeIndex !== null) { + const obj = objectsMapRef.current.get(selectedNodeIndex); + setSelectedObject(obj || null); + } else { + setSelectedObject(null); + } + }, [selectedNodeIndex]); + + return ( + <> + + + + ) => { + e.stopPropagation(); + onSelectNode(null); + }} + > + {sceneData.mapNodes.map((node, index) => { + const modelUrl = sceneData.models.get(node.name); + + if (modelUrl) { + return ( + + ); + } else { + return ( + + ); + } + })} + + + {selectedObject && ( + + )} + + ); +} + +function EditorModelNode({ + index, + node, + modelUrl, + isSelected, + isHovered, + objectsMapRef, + onSelectNode, + onHoverNode, +}: EditorNodeCommonProps & { + modelUrl: string; +}) { + const groupRef = useRef(null); + const originalMaterialsRef = useRef( + new Map(), + ); + const { scene } = useGLTF(modelUrl); + + const sceneInstance = useMemo(() => scene.clone(true), [scene]); + const pointerHandlers = createEditorNodePointerHandlers( + index, + onSelectNode, + onHoverNode, + ); + useRegisteredEditorNode(groupRef, index, node, objectsMapRef); + + useEffect(() => { + if (!groupRef.current) return; + const highlightColor = getNodeHighlightColor(isSelected, isHovered); + + groupRef.current.traverse((child) => { + if (!(child instanceof THREE.Mesh)) { + return; + } + + const originalMaterial = originalMaterialsRef.current.get(child); + + if (!originalMaterial) { + originalMaterialsRef.current.set(child, child.material); + } + + if (child.material !== originalMaterial && originalMaterial) { + disposeMaterial(child.material); + } + + if (highlightColor) { + child.material = cloneHighlightedMaterial( + originalMaterial ?? child.material, + highlightColor, + ); + } else if (originalMaterial) { + child.material = originalMaterial; + } + }); + }, [isSelected, isHovered]); + + useEffect(() => { + const group = groupRef.current; + const originalMaterials = originalMaterialsRef.current; + + return () => { + if (!group) return; + + group.traverse((child) => { + if (!(child instanceof THREE.Mesh)) { + return; + } + + const originalMaterial = originalMaterials.get(child); + if (originalMaterial && child.material !== originalMaterial) { + disposeMaterial(child.material); + child.material = originalMaterial; + } + }); + }; + }, []); + + return ( + + ); +} + +function EditorFallbackNode({ + index, + node, + isSelected, + isHovered, + objectsMapRef, + onSelectNode, + onHoverNode, +}: EditorNodeCommonProps) { + const meshRef = useRef(null); + const pointerHandlers = createEditorNodePointerHandlers( + index, + onSelectNode, + onHoverNode, + ); + useRegisteredEditorNode(meshRef, index, node, objectsMapRef); + + const color = getNodeHighlightColor(isSelected, isHovered) ?? "#6f6f6f"; + + return ( + + + + + ); +} diff --git a/src/components/editor/scene/EditorScene.tsx b/src/components/editor/scene/EditorScene.tsx new file mode 100644 index 0000000..000b681 --- /dev/null +++ b/src/components/editor/scene/EditorScene.tsx @@ -0,0 +1,108 @@ +import { useEffect } from "react"; +import { OrbitControls } from "@react-three/drei"; +import { EditorMap } from "@/components/editor/scene/EditorMap"; +import { FlyController } from "@/controls/editor/FlyController"; +import type { MapNode, TransformMode, SceneData } from "@/types/editor"; + +interface EditorSceneProps { + sceneData: SceneData; + selectedNodeIndex: number | null; + onSelectNode: (index: number | null) => void; + hoveredNodeIndex: number | null; + onHoverNode: (index: number | null) => void; + transformMode: TransformMode; + onTransformModeChange: (mode: TransformMode) => void; + onTransformStart: () => void; + onTransformEnd: () => void; + onNodeTransform: (nodeIndex: number, transform: MapNode) => void; + onUndo: () => void; + onRedo: () => void; + isPlayerMode?: boolean; +} + +export function EditorScene({ + sceneData, + selectedNodeIndex, + onSelectNode, + hoveredNodeIndex, + onHoverNode, + transformMode, + onTransformModeChange, + onTransformStart, + onTransformEnd, + onNodeTransform, + onUndo, + onRedo, + isPlayerMode = false, +}: EditorSceneProps): React.JSX.Element { + useEffect(() => { + const handleKeyDown = (e: KeyboardEvent) => { + if (e.ctrlKey || e.metaKey) { + if (e.key === "z" || e.key === "Z") { + e.preventDefault(); + onUndo(); + return; + } + if (e.key === "y" || e.key === "Y") { + e.preventDefault(); + onRedo(); + return; + } + } + + if (selectedNodeIndex !== null) { + switch (e.key.toLowerCase()) { + case "escape": + onSelectNode(null); + break; + case "t": + onTransformModeChange("translate"); + break; + case "r": + onTransformModeChange("rotate"); + break; + case "s": + onTransformModeChange("scale"); + break; + } + } + }; + + window.addEventListener("keydown", handleKeyDown); + return () => window.removeEventListener("keydown", handleKeyDown); + }, [selectedNodeIndex, onSelectNode, onTransformModeChange, onUndo, onRedo]); + + return ( + <> + {isPlayerMode ? ( + + ) : ( + + )} + + + + + + + + ); +} diff --git a/src/components/3d/AnimatedModel.tsx b/src/components/three/AnimatedModel.tsx similarity index 100% rename from src/components/3d/AnimatedModel.tsx rename to src/components/three/AnimatedModel.tsx diff --git a/src/components/3d/GrabbableObject.tsx b/src/components/three/GrabbableObject.tsx similarity index 95% rename from src/components/3d/GrabbableObject.tsx rename to src/components/three/GrabbableObject.tsx index 0499484..abd580e 100644 --- a/src/components/3d/GrabbableObject.tsx +++ b/src/components/three/GrabbableObject.tsx @@ -3,7 +3,7 @@ import { useFrame, useThree } from "@react-three/fiber"; import { RigidBody } from "@react-three/rapier"; import type { RapierRigidBody } from "@react-three/rapier"; import * as THREE from "three"; -import { InteractableObject } from "@/components/3d/InteractableObject"; +import { InteractableObject } from "@/components/three/InteractableObject"; import { GRAB_DEFAULT_COLLIDERS, GRAB_DEFAULT_LABEL, @@ -19,9 +19,9 @@ import { GRAB_THROW_BOOST_MAX, GRAB_THROW_BOOST_MIN, GRAB_THROW_BOOST_STEP, -} from "@/data/grabConfig"; +} from "@/data/interaction/grabConfig"; import { useDebugFolder } from "@/hooks/debug/useDebugFolder"; -import type { ColliderShape, Vector3Tuple } from "@/types/3d"; +import type { ColliderShape, Vector3Tuple } from "@/types/three"; interface GrabbableObjectProps { position: Vector3Tuple; diff --git a/src/components/3d/InteractableObject.tsx b/src/components/three/InteractableObject.tsx similarity index 71% rename from src/components/3d/InteractableObject.tsx rename to src/components/three/InteractableObject.tsx index 4403579..bcca255 100644 --- a/src/components/3d/InteractableObject.tsx +++ b/src/components/three/InteractableObject.tsx @@ -8,13 +8,13 @@ import { INTERACTION_DEBUG_SPHERE_COLOR, INTERACTION_DEBUG_SPHERE_OPACITY, INTERACTION_DEBUG_SPHERE_SEGMENTS, -} from "@/data/debugConfig"; +} from "@/data/debug/debugConfig"; import { Debug } from "@/utils/debug/Debug"; import { useDebugFolder } from "@/hooks/debug/useDebugFolder"; -import { InteractionManager } from "@/stateManager/InteractionManager"; -import { INTERACTION_RADIUS } from "@/data/interactionConfig"; -import type { Vector3Tuple } from "@/types/3d"; -import type { InteractableHandle, InteractableKind } from "@/types/interaction"; +import { InteractionManager } from "@/managers/InteractionManager"; +import { INTERACTION_RADIUS } from "@/data/interaction/interactionConfig"; +import type { Vector3Tuple } from "@/types/three"; +import type { InteractableHandle } from "@/types/interaction"; interface InteractableObjectBaseProps { label: string; @@ -37,46 +37,67 @@ type InteractableObjectProps = | TriggerInteractableObjectProps | GrabInteractableObjectProps; -type MutableInteractableHandle = { - kind: InteractableKind; - label: string; - onPress: () => void; - onRelease?: () => void; -}; - const _cameraPos = new THREE.Vector3(); const _cameraDir = new THREE.Vector3(); const _objectPos = new THREE.Vector3(); const _raycaster = new THREE.Raycaster(); +function createInteractableHandle( + props: InteractableObjectProps, +): InteractableHandle { + if (props.kind === "grab") { + return { + kind: props.kind, + label: props.label, + onPress: props.onPress, + onRelease: props.onRelease, + }; + } + + return { + kind: props.kind, + label: props.label, + onPress: props.onPress, + }; +} + export function InteractableObject( props: InteractableObjectProps, ): React.JSX.Element { const { kind, label, position, bodyRef, onPress, children } = props; - const onRelease = props.kind === "grab" ? props.onRelease : undefined; + const onRelease = props.kind === "grab" ? props.onRelease : null; const camera = useThree((state) => state.camera); const groupRef = useRef(null); const debugSphereRef = useRef(null); - const handle = useRef( - props.kind === "grab" - ? { kind: props.kind, label, onPress, onRelease: props.onRelease } - : { kind: props.kind, label, onPress }, - ); + const handle = useRef(createInteractableHandle(props)); useEffect(() => { - const current = handle.current as MutableInteractableHandle; - current.kind = kind; - current.label = label; - current.onPress = onPress; + const currentHandle = handle.current; + + if (currentHandle.kind === kind) { + currentHandle.label = label; + currentHandle.onPress = onPress; + + if (currentHandle.kind === "grab") { + if (!onRelease) return; + currentHandle.onRelease = onRelease; + } - if (kind === "grab" && onRelease) { - current.onRelease = onRelease; return; } - delete current.onRelease; - return undefined; + if (kind === "grab") { + if (!onRelease) return; + handle.current = { kind, label, onPress, onRelease }; + } else { + handle.current = { kind, label, onPress }; + } + + const manager = InteractionManager.getInstance(); + if (manager.getState().focused === currentHandle) { + manager.setFocused(handle.current); + } }, [kind, label, onPress, onRelease]); const setupInteractionDebugFolder = useCallback((folder: GUI) => { diff --git a/src/components/3d/SimpleModel.tsx b/src/components/three/SimpleModel.tsx similarity index 100% rename from src/components/3d/SimpleModel.tsx rename to src/components/three/SimpleModel.tsx diff --git a/src/components/3d/TriggerObject.tsx b/src/components/three/TriggerObject.tsx similarity index 90% rename from src/components/3d/TriggerObject.tsx rename to src/components/three/TriggerObject.tsx index 937dfae..4e11c96 100644 --- a/src/components/3d/TriggerObject.tsx +++ b/src/components/three/TriggerObject.tsx @@ -1,15 +1,15 @@ import { useState } from "react"; import { useGLTF } from "@react-three/drei"; import { RigidBody } from "@react-three/rapier"; -import { InteractableObject } from "@/components/3d/InteractableObject"; +import { InteractableObject } from "@/components/three/InteractableObject"; import { TRIGGER_DEFAULT_COLLIDERS, TRIGGER_DEFAULT_LABEL, TRIGGER_DEFAULT_SOUND_VOLUME, TRIGGER_DEFAULT_SPAWN_OFFSET, -} from "@/data/triggerConfig"; -import { AudioManager } from "@/stateManager/AudioManager"; -import type { ColliderShape, Vector3Tuple } from "@/types/3d"; +} from "@/data/interaction/triggerConfig"; +import { AudioManager } from "@/managers/AudioManager"; +import type { ColliderShape, Vector3Tuple } from "@/types/three"; interface SpawnedModel { id: number; diff --git a/src/components/3d/index.ts b/src/components/three/index.ts similarity index 100% rename from src/components/3d/index.ts rename to src/components/three/index.ts diff --git a/src/components/ui/InteractPrompt.tsx b/src/components/ui/InteractPrompt.tsx index 4c86b21..70b09db 100644 --- a/src/components/ui/InteractPrompt.tsx +++ b/src/components/ui/InteractPrompt.tsx @@ -1,4 +1,4 @@ -import { INTERACT_KEY } from "@/data/keybindings"; +import { INTERACT_KEY } from "@/data/input/keybindings"; import { useCameraMode } from "@/hooks/debug/useCameraMode"; import { useInteraction } from "@/hooks/useInteraction"; diff --git a/src/contexts/docs/DocsLanguageContext.ts b/src/contexts/docs/DocsLanguageContext.ts new file mode 100644 index 0000000..60e6865 --- /dev/null +++ b/src/contexts/docs/DocsLanguageContext.ts @@ -0,0 +1,11 @@ +import { createContext } from "react"; + +export type DocsLanguage = "en" | "fr"; + +interface DocsLanguageContextValue { + language: DocsLanguage; + toggleLanguage: () => void; +} + +export const DocsLanguageContext = + createContext(null); diff --git a/src/controls/editor/FlyController.tsx b/src/controls/editor/FlyController.tsx new file mode 100644 index 0000000..329b415 --- /dev/null +++ b/src/controls/editor/FlyController.tsx @@ -0,0 +1,126 @@ +import { + useRef, + useEffect, + useCallback, + forwardRef, + useImperativeHandle, + type ElementRef, +} from "react"; +import { useFrame, useThree } from "@react-three/fiber"; +import { OrbitControls } from "@react-three/drei"; +import * as THREE from "three"; + +type OrbitControlsRef = ElementRef; + +interface FlyControllerProps { + speed?: number; + verticalSpeed?: number; + onPositionChange?: (position: THREE.Vector3) => void; + disabled?: boolean; +} + +interface FlyControllerRef { + controls: OrbitControlsRef | null; +} + +export const FlyController = forwardRef( + ( + { speed = 10, verticalSpeed = 5, onPositionChange, disabled = false }, + ref, + ) => { + const { camera: rawCamera } = useThree(); + const cameraRef = useRef(rawCamera); + const keys = useRef<{ [key: string]: boolean }>({}); + const controlsRef = useRef(null); + const lastPosition = useRef(new THREE.Vector3()); + + useImperativeHandle(ref, () => ({ + controls: controlsRef.current, + })); + + const handleKeyDown = useCallback((e: KeyboardEvent) => { + keys.current[e.code] = true; + }, []); + + const handleKeyUp = useCallback((e: KeyboardEvent) => { + keys.current[e.code] = false; + }, []); + + useEffect(() => { + window.addEventListener("keydown", handleKeyDown); + window.addEventListener("keyup", handleKeyUp); + return () => { + window.removeEventListener("keydown", handleKeyDown); + window.removeEventListener("keyup", handleKeyUp); + }; + }, [handleKeyDown, handleKeyUp]); + + useFrame((_, delta) => { + // Disabled mode keeps OrbitControls active without keyboard movement. + if (disabled) { + return; + } + + // Supports AZERTY, QWERTY, and arrow-key movement. + const isForward = + keys.current["KeyW"] || keys.current["KeyZ"] || keys.current["ArrowUp"]; + const isBackward = keys.current["KeyS"] || keys.current["ArrowDown"]; + const isLeft = + keys.current["KeyQ"] || + keys.current["KeyA"] || + keys.current["ArrowLeft"]; + const isRight = keys.current["KeyD"] || keys.current["ArrowRight"]; + + const direction = new THREE.Vector3(); + const frontVector = new THREE.Vector3( + 0, + 0, + Number(isBackward) - Number(isForward), + ); + const sideVector = new THREE.Vector3( + Number(isRight) - Number(isLeft), + 0, + 0, + ); + + direction.subVectors(frontVector, sideVector); + if (direction.lengthSq() > 0) { + direction.normalize().multiplyScalar(speed * delta); + direction.applyQuaternion(cameraRef.current.quaternion); + cameraRef.current.position.add(direction); + } + + // Space moves up; Shift moves down. + if (keys.current["Space"]) { + cameraRef.current.position.y += verticalSpeed * delta; + } + if (keys.current["ShiftLeft"] || keys.current["ShiftRight"]) { + cameraRef.current.position.y -= verticalSpeed * delta; + } + + if ( + onPositionChange && + !cameraRef.current.position.equals(lastPosition.current) + ) { + lastPosition.current.copy(cameraRef.current.position); + onPositionChange(cameraRef.current.position); + } + }); + + return ( + + ); + }, +); + +FlyController.displayName = "FlyController"; diff --git a/src/data/debugConfig.ts b/src/data/debug/debugConfig.ts similarity index 91% rename from src/data/debugConfig.ts rename to src/data/debug/debugConfig.ts index 6f5e4fc..618ddc6 100644 --- a/src/data/debugConfig.ts +++ b/src/data/debug/debugConfig.ts @@ -2,8 +2,6 @@ export const INTERACTION_DEBUG_SPHERE_SEGMENTS = 16; export const INTERACTION_DEBUG_SPHERE_COLOR = "#facc15"; export const INTERACTION_DEBUG_SPHERE_OPACITY = 0.25; -export const MAP_DEBUG_BOX_HELPER_COLOR = 0x00ff88; - export const DEBUG_CAMERA_DAMPING_FACTOR = 0.05; export const DEBUG_CAMERA_MIN_DISTANCE = 100; export const DEBUG_CAMERA_MAX_DISTANCE = 1000; diff --git a/src/data/testSceneConfig.ts b/src/data/debug/testSceneConfig.ts similarity index 94% rename from src/data/testSceneConfig.ts rename to src/data/debug/testSceneConfig.ts index 0cd23bf..da1edc2 100644 --- a/src/data/testSceneConfig.ts +++ b/src/data/debug/testSceneConfig.ts @@ -1,4 +1,4 @@ -import type { Vector3Tuple } from "@/types/3d"; +import type { Vector3Tuple } from "@/types/three"; export const TEST_SCENE_FLOOR_POSITION: Vector3Tuple = [0, -0.5, 0]; export const TEST_SCENE_FLOOR_SIZE: Vector3Tuple = [200, 1, 200]; diff --git a/src/data/docs/docsSections.ts b/src/data/docs/docsSections.ts new file mode 100644 index 0000000..2fd4f9e --- /dev/null +++ b/src/data/docs/docsSections.ts @@ -0,0 +1,60 @@ +interface DocSection { + path: string; + title: string; + subtitle: string; + meta: string; +} + +interface DocGroup { + label: string; + sections: DocSection[]; +} + +export const docGroups: DocGroup[] = [ + { + label: "Technical", + sections: [ + { + path: "/docs", + title: "README", + subtitle: "Project overview", + meta: "01", + }, + { + path: "/docs/architecture", + title: "Current Architecture", + subtitle: "Runtime structure", + meta: "02", + }, + { + path: "/docs/target-architecture", + title: "Target Architecture", + subtitle: "Next direction", + meta: "03", + }, + { + path: "/docs/technical-editor", + title: "Editor Technical Notes", + subtitle: "Implementation details", + meta: "04", + }, + ], + }, + { + label: "User", + sections: [ + { + path: "/docs/features", + title: "Features", + subtitle: "Implemented scope", + meta: "05", + }, + { + path: "/docs/editor", + title: "Editor User Guide", + subtitle: "Editing workflow", + meta: "06", + }, + ], + }, +]; diff --git a/src/data/docs/docsTranslations.ts b/src/data/docs/docsTranslations.ts new file mode 100644 index 0000000..82d45ec --- /dev/null +++ b/src/data/docs/docsTranslations.ts @@ -0,0 +1,329 @@ +export const readmeFr = `# La-Fabrik + +Une expérience web 3D interactive pour La Fabrik Durable, un service low-tech de réparation et de transformation situé à Altera, une ville post-capitaliste reconstruite en 2039. Les joueurs incarnent un technicien fraîchement intégré et vivent une journée de service : réparer un vélo électrique, remettre en état un réseau d'énergie et améliorer le système d'irrigation d'une ferme verticale. + +Construit avec React, Three.js et Vite. Fonctionne dans le navigateur, sans installation côté utilisateur. + +## Stack technique + +### Build et langage + +| Package | +| -------------------------------------------------- | +| [TypeScript](https://www.typescriptlang.org/docs/) | +| [React](https://react.dev/learn) | +| [Vite](https://vite.dev/guide/) | +| [ESLint](https://eslint.org/docs/latest/) | +| [Prettier](https://prettier.io/docs/) | + +### Moteur 3D + +| Package | +| ----------------------------------------------------------------------------------------- | +| [Three.js](https://threejs.org/docs/) | +| [@react-three/fiber](https://docs.pmnd.rs/react-three-fiber/getting-started/introduction) | +| [@react-three/drei](https://pmndrs.github.io/drei) | +| [@react-three/rapier](https://rapier.rs/docs/) | +| [@react-three/postprocessing](https://github.com/pmndrs/postprocessing) | +| [GSAP](https://gsap.com/docs/v3/Installation/) | + +### Performance et effets + +| Package | +| --------------------------------------------------------------------------- | +| [r3f-perf](https://github.com/utsuboco/r3f-perf) | +| [AnimationMixer](https://threejs.org/docs/#api/en/animation/AnimationMixer) | + +## Structure du projet + +\`\`\` +la-fabrik/ +├── public/ +│ ├── models/ +│ │ ├── map/ # Carte de base, chargée au démarrage +│ │ ├── workshop/ +│ │ ├── powerGrid/ +│ │ └── farm/ +│ ├── textures/ +│ └── sounds/ +│ +└── src/ + ├── world/ # Monde 3D persistant + │ ├── World.tsx # Composition principale de la scène + │ ├── Map.tsx # Carte de base, toujours montée + │ ├── Lighting.tsx # Lumières ambiante, directionnelle et ponctuelles + │ ├── Environment.tsx # HDRI, brouillard, ciel + │ ├── PostFX.tsx # Bloom, SSAO, aberration chromatique + │ ├── zones/ # Zones spatiales, LOD par zone + │ └── player/ # Contrôleur joueur et caméra + │ + ├── components/ + │ ├── 3d/ # Éléments 3D réutilisables + │ └── ui/ # Overlays HTML hors Canvas + │ + ├── managers/ # Logique, état et orchestration + ├── hooks/ # Hooks React autour des managers + ├── data/ # Configuration statique + ├── shaders/ # Shaders GLSL + └── utils/ # Utilitaires partagés et debug +\`\`\` + +## Démarrage + +\`\`\`bash +git clone https://github.com/La-Fabrik-Durable/La-Fabrik.git +cd La-Fabrik +npm install +npm run dev +\`\`\` + +- application : \`http://localhost:5173\` +- mode debug : \`http://localhost:5173?debug\` + +## Licence + +Voir le fichier [LICENSE](./LICENSE). +`; + +export const architectureFr = `# Architecture actuelle + +Ce document décrit le code réellement présent aujourd'hui dans le dépôt. + +## Structure runtime + +- \`src/App.tsx\` monte le \`RouterProvider\`, qui pilote l'affichage des vues de l'application. +- \`src/pages/page.tsx\` monte le \`Canvas\`, le \`World\` 3D, l'overlay de performance debug et les overlays HTML. +- \`src/world/World.tsx\` compose la scène active avec : + - l'environnement et l'éclairage + - les helpers debug et le mode caméra debug + - soit la carte principale, soit la scène de test physique debug + - le rig joueur quand le mode caméra actif est \`player\` +- \`src/world/GameMap.tsx\` charge les modèles de carte disponibles et construit l'octree de collision. +- \`src/world/debug/TestScene.tsx\` fournit une scène orientée debug pour les interactions et la physique. +- \`src/world/player/Player.tsx\` monte la caméra et le contrôleur. +- \`src/world/player/PlayerController.tsx\` gère le mouvement pointer lock, le saut et les inputs d'interaction. + +## Modèle d'interaction + +- \`src/managers/InteractionManager.ts\` est la source d'état actuelle des interactions. +- \`src/components/three/InteractableObject.tsx\` gère la détection de focus par distance et raycasting. +- \`src/components/three/TriggerObject.tsx\` implémente les interactions de type trigger. +- \`src/components/three/GrabbableObject.tsx\` implémente les interactions saisir / relâcher. +- \`src/hooks/useInteraction.ts\` expose un snapshot d'interaction à l'UI React. +- \`src/components/ui/InteractPrompt.tsx\` affiche le prompt \`E\` pour les interactions trigger. + +## Audio + +- \`src/managers/AudioManager.ts\` fournit actuellement une lecture de sons one-shot avec pool. +- Les interactions trigger peuvent lancer directement un son via \`AudioManager\`. + +## Système debug + +- Le mode debug est activé avec \`?debug\`. +- \`src/utils/debug/Debug.ts\` possède l'instance \`lil-gui\` et les contrôles debug. +- \`src/hooks/debug/useCameraMode.ts\` et \`src/hooks/debug/useSceneMode.ts\` s'abonnent à l'état debug. +- \`src/components/debug/DebugPerf.tsx\` monte \`r3f-perf\` en lazy uniquement en mode debug. +- \`src/components/debug/scene/DebugHelpers.tsx\` monte les helpers debug. +- \`src/components/debug/scene/DebugCameraControls.tsx\` monte la caméra libre debug. + +## Limites actuelles + +- Le dépôt est encore un prototype, pas le runtime complet du jeu. +- \`src/world/debug/TestScene.tsx\` fait encore partie de la composition active. +- Il n'existe pas encore d'orchestrateur gameplay central comme \`GameManager\`. +- Les systèmes de missions, zones, cinématiques et dialogues ne sont pas implémentés. +- Le joueur utilise une collision octree et des règles simples, pas une pile physique gameplay complète. +`; + +export const targetArchitectureFr = `# Architecture cible + +Ce document décrit l'architecture visée à moyen terme pour le projet. + +## Relation avec le code actuel + +- \`docs/technical/architecture.md\` reste la source de vérité de ce qui existe maintenant. +- Ce document est volontairement aspirational. +- Si ce document contredit l'implémentation actuelle, l'implémentation actuelle gagne. + +## Objectifs + +- Garder \`App.tsx\` petit et centré sur l'orchestration. +- Séparer le code de production du monde des chemins runtime uniquement debug. +- Garder une source de vérité claire par responsabilité. +- Faire grandir les systèmes gameplay progressivement, sans préconstruire une architecture vide. + +## Couches prévues + +### Couche App + +- \`App.tsx\` monte la scène canvas et les overlays HTML de premier niveau. +- Il doit rester fin et éviter la logique gameplay. + +### Couche World + +- \`src/world/\` doit contenir la composition de scène de production et les objets de scène de production. +- Responsabilités attendues : + - composition du monde + - carte, environnement, éclairage + - contrôleur joueur + - ancres d'interaction de production + - post-processing de production si nécessaire + +### Couche Debug + +- Les scènes et outils uniquement debug doivent être isolés du chemin de production. +- Responsabilités attendues : + - \`lil-gui\` + - overlay de performance + - helpers de scène + - caméra libre et contrôles de calibration + - scènes temporaires de test utilisées pendant le développement + +### Couche UI + +- \`src/components/ui/\` doit contenir les overlays HTML visibles par le joueur. +- Exemples futurs : + - crosshair + - flow de chargement + - HUD de mission + - overlays narratifs + +### Couche Gameplay + +- À mesure que le projet grandit, l'état gameplay peut évoluer vers une couche d'orchestration plus claire. +- Sujets probables : + - missions + - zones + - cinématiques + - dialogues + - audio + - interactions + +## Règles + +- Préférer du code direct et fonctionnel plutôt qu'un échafaudage spéculatif. +- Les types partagés doivent rester proches de leur domaine jusqu'à avoir plusieurs vrais consommateurs. +- Éviter de créer de nouveaux managers ou services sans besoin runtime actif. +- Les chemins runtime uniquement debug doivent être clairement marqués et faciles à retirer plus tard. +`; + +export const featuresFr = `# Fonctionnalités implémentées + +Ce document liste les fonctionnalités présentes dans le code actuel. + +## Scène + +- Scène React Three Fiber plein écran +- Carte principale chargée depuis \`public/models/map/model.gltf\` +- Scène de test physique debug sélectionnable depuis le panneau debug +- Éclairage ambiant et directionnel +- Configuration de l'environnement de fond + +## Joueur + +- Mode caméra joueur +- Orientation souris avec pointer lock +- Déplacement avec \`ZQSD\` +- Saut +- Collision basée sur une octree contre la carte chargée + +## Interactions + +- Détection de focus par distance et raycast +- Interactions trigger activées avec \`E\` +- Interactions grab activées avec le bouton principal de la souris +- Prompt d'interaction affiché pour les interactions trigger + +## Audio + +- Lecture de sons one-shot pour les interactions trigger +- Pool simple par son via \`AudioManager\` + +## Outils debug + +- Le paramètre \`?debug\` active le panneau debug +- Contrôles \`lil-gui\` pour le mode caméra, le mode scène et les sphères d'interaction +- Helpers de scène debug +- Caméra libre debug +- Overlay \`r3f-perf\` + +## Pas encore implémenté + +- système de missions +- système de zones +- système de cinématiques +- système de dialogues +- flow de chargement +- minimap et HUD de mission +- séparation complète production / debug pour les scènes gameplay +`; + +export const editorFr = `# Éditeur de carte + +L'éditeur de carte est disponible sur "/editor". Il permet d'inspecter et d'ajuster les objets déclarés dans "/public/map.json" directement depuis le navigateur. + +## Ce qui est édité + +L'éditeur travaille sur la liste de nodes stockée dans "/public/map.json". + +Chaque node décrit un objet de la scène : + +- "name" : nom du dossier modèle dans "/public/models/{name}/model.gltf" +- "type" : catégorie de l'objet +- "position" : "[x, y, z]" +- "rotation" : "[x, y, z]" +- "scale" : "[x, y, z]" + +Les modèles sont chargés depuis "/public/models". Si un modèle manque, l'éditeur affiche un cube gris de remplacement pour que le node reste sélectionnable et déplaçable. + +## Workflow de base + +1. Ouvrir "/editor". +2. Sélectionner un objet dans la vue 3D. +3. Choisir un mode de transformation : translation, rotation ou scale. +4. Déplacer la gizmo de transformation. +5. Utiliser undo ou redo si nécessaire. +6. Exporter le JSON mis à jour ou le sauvegarder sur le serveur de dev. + +## Contrôles + +| Action | Input | +| --- | --- | +| Sélectionner un objet | Clic sur l'objet | +| Désélectionner | "Esc" ou clic dans le vide | +| Mode translation | "T" | +| Mode rotation | "R" | +| Mode scale | "S" | +| Undo | "Ctrl+Z" | +| Redo | "Ctrl+Y" | +| Déplacement en vue verrouillée | "WASD", "ZQSD", flèches | +| Monter / descendre | "Space", "Shift" | + +## Actions fichier + +### Export JSON + +"Export JSON" télécharge la liste actuelle des nodes sous le nom "map.json". À utiliser pour remplacer manuellement "/public/map.json". + +### Save to server + +"Save to server" est disponible uniquement en développement local. L'action écrit la carte modifiée dans "/public/map.json" via l'endpoint du serveur de dev Vite. + +Cette action est masquée dans les builds de production car il n'existe pas encore d'API de persistance production. + +## Inspecteur JSON + +Le panneau latéral affiche le JSON brut de la carte : + +- sans sélection, il affiche toute la liste des nodes +- avec un objet sélectionné, il met en évidence les lignes du node sélectionné + +Utilise-le pour vérifier les valeurs numériques exactes avant export ou sauvegarde. + +## Limites actuelles + +- L'éditeur modifie uniquement les nodes existants. +- Il n'y a pas encore d'interface pour créer ou supprimer des objets. +- La sauvegarde production n'est pas implémentée. +- Les modèles manquants s'affichent comme cubes de fallback au lieu de bloquer tout l'éditeur. +`; diff --git a/src/data/keybindings.ts b/src/data/input/keybindings.ts similarity index 100% rename from src/data/keybindings.ts rename to src/data/input/keybindings.ts diff --git a/src/data/grabConfig.ts b/src/data/interaction/grabConfig.ts similarity index 100% rename from src/data/grabConfig.ts rename to src/data/interaction/grabConfig.ts diff --git a/src/data/interactionConfig.ts b/src/data/interaction/interactionConfig.ts similarity index 100% rename from src/data/interactionConfig.ts rename to src/data/interaction/interactionConfig.ts diff --git a/src/data/triggerConfig.ts b/src/data/interaction/triggerConfig.ts similarity index 80% rename from src/data/triggerConfig.ts rename to src/data/interaction/triggerConfig.ts index 304ef82..46bf396 100644 --- a/src/data/triggerConfig.ts +++ b/src/data/interaction/triggerConfig.ts @@ -1,4 +1,4 @@ -import type { Vector3Tuple } from "@/types/3d"; +import type { Vector3Tuple } from "@/types/three"; export const TRIGGER_DEFAULT_COLLIDERS = "ball"; export const TRIGGER_DEFAULT_LABEL = "Interagir"; diff --git a/src/data/playerConfig.ts b/src/data/player/playerConfig.ts similarity index 90% rename from src/data/playerConfig.ts rename to src/data/player/playerConfig.ts index 43e183e..a8b60ea 100644 --- a/src/data/playerConfig.ts +++ b/src/data/player/playerConfig.ts @@ -1,4 +1,4 @@ -import type { Vector3Tuple } from "@/types/3d"; +import type { Vector3Tuple } from "@/types/three"; export const PLAYER_EYE_HEIGHT = 1.75; export const PLAYER_CAPSULE_RADIUS = 0.35; diff --git a/src/data/environmentConfig.ts b/src/data/world/environmentConfig.ts similarity index 100% rename from src/data/environmentConfig.ts rename to src/data/world/environmentConfig.ts diff --git a/src/data/lightingConfig.ts b/src/data/world/lightingConfig.ts similarity index 100% rename from src/data/lightingConfig.ts rename to src/data/world/lightingConfig.ts diff --git a/src/hooks/docs/useDocsLanguage.ts b/src/hooks/docs/useDocsLanguage.ts new file mode 100644 index 0000000..664b68d --- /dev/null +++ b/src/hooks/docs/useDocsLanguage.ts @@ -0,0 +1,12 @@ +import { useContext } from "react"; +import { DocsLanguageContext } from "@/contexts/docs/DocsLanguageContext"; + +export function useDocsLanguage() { + const context = useContext(DocsLanguageContext); + + if (!context) { + throw new Error("useDocsLanguage must be used inside DocsLanguageProvider"); + } + + return context; +} diff --git a/src/hooks/editor/useEditorHistory.ts b/src/hooks/editor/useEditorHistory.ts new file mode 100644 index 0000000..275bcad --- /dev/null +++ b/src/hooks/editor/useEditorHistory.ts @@ -0,0 +1,164 @@ +import { useCallback, useRef, useState } from "react"; +import type { MapNode, SceneData } from "@/types/editor"; + +interface ObjectTransform { + uuid: string; + position: { x: number; y: number; z: number }; + rotation: { x: number; y: number; z: number }; + scale: { x: number; y: number; z: number }; +} + +class HistoryManager { + private history: ObjectTransform[][] = []; + private currentIndex = -1; + private maxSize: number; + + constructor(maxSize = 50) { + this.maxSize = maxSize; + } + + saveSnapshot(objects: ObjectTransform[]): void { + if (this.currentIndex < this.history.length - 1) { + this.history = this.history.slice(0, this.currentIndex + 1); + } + + this.history.push(objects.map((object) => ({ ...object }))); + this.currentIndex = this.history.length - 1; + + if (this.history.length > this.maxSize) { + this.history.shift(); + this.currentIndex--; + } + } + + undo(): ObjectTransform[] | undefined { + if (this.currentIndex <= 0) return undefined; + + this.currentIndex--; + return this.history[this.currentIndex]; + } + + redo(): ObjectTransform[] | undefined { + if (this.currentIndex >= this.history.length - 1) return undefined; + + this.currentIndex++; + return this.history[this.currentIndex]; + } + + getUndoCount(): number { + return this.currentIndex; + } + + getRedoCount(): number { + return this.history.length - 1 - this.currentIndex; + } +} + +interface UseEditorHistoryResult { + undoCount: number; + redoCount: number; + handleUndo: () => void; + handleRedo: () => void; + handleTransformStart: () => void; + handleTransformEnd: () => void; +} + +export function useEditorHistory( + sceneData: SceneData | null, + setSceneData: React.Dispatch>, +): UseEditorHistoryResult { + const [undoCount, setUndoCount] = useState(0); + const [redoCount, setRedoCount] = useState(0); + const historyManager = useRef(new HistoryManager(50)); + + const updateHistoryCounts = useCallback(() => { + setUndoCount(historyManager.current.getUndoCount()); + setRedoCount(historyManager.current.getRedoCount()); + }, []); + + const applySnapshot = useCallback( + (snapshot: ObjectTransform[]): void => { + setSceneData((prev) => { + if (!prev) return null; + + const mapNodes = prev.mapNodes.map((node, index) => { + const transform = snapshot.find( + (item) => item.uuid === `node-${index}`, + ); + if (!transform) return node; + + return { + ...node, + position: [ + transform.position.x, + transform.position.y, + transform.position.z, + ], + rotation: [ + transform.rotation.x, + transform.rotation.y, + transform.rotation.z, + ], + scale: [transform.scale.x, transform.scale.y, transform.scale.z], + } satisfies MapNode; + }); + + return { ...prev, mapNodes }; + }); + }, + [setSceneData], + ); + + const handleUndo = useCallback(() => { + const snapshot = historyManager.current.undo(); + if (!snapshot) return; + + applySnapshot(snapshot); + updateHistoryCounts(); + }, [applySnapshot, updateHistoryCounts]); + + const handleRedo = useCallback(() => { + const snapshot = historyManager.current.redo(); + if (!snapshot) return; + + applySnapshot(snapshot); + updateHistoryCounts(); + }, [applySnapshot, updateHistoryCounts]); + + const handleTransformStart = useCallback(() => { + if (!sceneData) return; + historyManager.current.saveSnapshot(createSnapshot(sceneData)); + }, [sceneData]); + + const handleTransformEnd = useCallback(() => { + if (!sceneData) return; + historyManager.current.saveSnapshot(createSnapshot(sceneData)); + updateHistoryCounts(); + }, [sceneData, updateHistoryCounts]); + + return { + undoCount, + redoCount, + handleUndo, + handleRedo, + handleTransformStart, + handleTransformEnd, + }; +} + +function createSnapshot(sceneData: SceneData): ObjectTransform[] { + return sceneData.mapNodes.map((node, index) => ({ + uuid: `node-${index}`, + position: { + x: node.position[0], + y: node.position[1], + z: node.position[2], + }, + rotation: { + x: node.rotation[0], + y: node.rotation[1], + z: node.rotation[2], + }, + scale: { x: node.scale[0], y: node.scale[1], z: node.scale[2] }, + })); +} diff --git a/src/hooks/editor/useEditorSceneData.ts b/src/hooks/editor/useEditorSceneData.ts new file mode 100644 index 0000000..ffdab7b --- /dev/null +++ b/src/hooks/editor/useEditorSceneData.ts @@ -0,0 +1,65 @@ +import { useCallback, useEffect, useState } from "react"; +import { createSceneDataFromFiles } from "@/utils/editor/loadEditorScene"; +import { loadMapSceneData } from "@/utils/loadMapSceneData"; +import type { SceneData } from "@/types/editor"; + +interface UseEditorSceneDataResult { + hasMapJson: boolean; + isMapLoading: boolean; + sceneData: SceneData | null; + setSceneData: React.Dispatch>; + handleFolderUpload: ( + event: React.ChangeEvent, + ) => Promise; +} + +export function useEditorSceneData(): UseEditorSceneDataResult { + const [hasMapJson, setHasMapJson] = useState(false); + const [isMapLoading, setIsMapLoading] = useState(true); + const [sceneData, setSceneData] = useState(null); + + useEffect(() => { + const loadScene = async (): Promise => { + setIsMapLoading(true); + + try { + const loadedSceneData = await loadMapSceneData(); + setSceneData(loadedSceneData); + setHasMapJson(Boolean(loadedSceneData)); + } catch (error) { + console.error("Error loading map data:", error); + setHasMapJson(false); + } finally { + setIsMapLoading(false); + } + }; + + loadScene(); + }, []); + + const handleFolderUpload = useCallback( + async (event: React.ChangeEvent): Promise => { + const files = event.target.files; + if (!files) return; + + try { + const uploadedSceneData = await createSceneDataFromFiles(files); + setSceneData(uploadedSceneData); + setHasMapJson(true); + } catch (error) { + const message = error instanceof Error ? error.message : "Erreur"; + console.error("Error processing upload:", error); + alert(message); + } + }, + [], + ); + + return { + hasMapJson, + isMapLoading, + sceneData, + setSceneData, + handleFolderUpload, + }; +} diff --git a/src/hooks/useInteraction.ts b/src/hooks/useInteraction.ts index 58fabc2..34a2a86 100644 --- a/src/hooks/useInteraction.ts +++ b/src/hooks/useInteraction.ts @@ -1,5 +1,5 @@ import { useSyncExternalStore } from "react"; -import { InteractionManager } from "@/stateManager/InteractionManager"; +import { InteractionManager } from "@/managers/InteractionManager"; import type { InteractionSnapshot } from "@/types/interaction"; const manager = InteractionManager.getInstance(); diff --git a/src/hooks/useOctreeGraphNode.ts b/src/hooks/useOctreeGraphNode.ts index c03458c..3a4f3a3 100644 --- a/src/hooks/useOctreeGraphNode.ts +++ b/src/hooks/useOctreeGraphNode.ts @@ -2,14 +2,19 @@ import { useEffect, useRef } from "react"; import type { RefObject } from "react"; import type { Object3D } from "three"; import { Octree } from "three/addons/math/Octree.js"; -import type { OctreeReadyHandler } from "@/types/3d"; +import type { OctreeReadyHandler } from "@/types/three"; export function useOctreeGraphNode( graphNodeRef: RefObject, onOctreeReady: OctreeReadyHandler, + rebuildKey: string | number = 0, ): void { const octreeBuilt = useRef(false); + useEffect(() => { + octreeBuilt.current = false; + }, [rebuildKey]); + useEffect(() => { const graphNode = graphNodeRef.current; if (octreeBuilt.current || !graphNode) return; @@ -20,5 +25,5 @@ export function useOctreeGraphNode( const octree = new Octree(); octree.fromGraphNode(graphNode); onOctreeReady(octree); - }, [graphNodeRef, onOctreeReady]); + }, [graphNodeRef, onOctreeReady, rebuildKey]); } diff --git a/src/index.css b/src/index.css index 8e0c2e2..a32c152 100644 --- a/src/index.css +++ b/src/index.css @@ -1,6 +1,8 @@ +@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"); + :root { color-scheme: dark; - font-family: Inter; + font-family: "Helvetica Neue", Helvetica, Inter, Arial, sans-serif; } html, @@ -27,6 +29,315 @@ canvas { display: block; } +.docs-page { + display: grid; + grid-template-columns: 300px minmax(0, 1fr); + width: 100vw; + height: 100vh; + overflow: hidden; + background: #050505; + color: #f4efe7; + font-family: "Helvetica Neue", Helvetica, Inter, Arial, sans-serif; +} + +.docs-sidebar { + border-right: 2px solid #d8d0c4; + background: #050505; + overflow-y: auto; +} + +.docs-sidebar__header, +.docs-content__header { + display: flex; + align-items: center; + justify-content: space-between; + min-height: 78px; + padding: 0 18px; + border-bottom: 2px solid #d8d0c4; +} + +.docs-sidebar__header h1, +.docs-content__header span { + margin: 0; + color: #f4efe7; + font-size: 21px; + font-weight: 700; + letter-spacing: -0.04em; +} + +.docs-sidebar nav { + display: grid; +} + +.docs-nav-group { + display: grid; + border-bottom: 2px solid #d8d0c4; +} + +.docs-nav-group h2 { + margin: 0; + padding: 13px 16px 8px; + color: #a9a196; + font-size: 10px; + font-weight: 800; + letter-spacing: 0.14em; + text-transform: uppercase; +} + +.docs-sidebar a { + color: #f4efe7; + text-decoration: none; +} + +.docs-nav-item { + display: flex; + align-items: center; + justify-content: space-between; + min-height: 46px; + padding: 0 16px; + border-top: 1px solid rgba(216, 208, 196, 0.35); + color: #f4efe7; + transition: + background 160ms ease, + color 160ms ease; +} + +.docs-home-link { + display: grid; + place-items: center; + width: 34px; + height: 34px; + border: 2px solid currentColor; + border-radius: 999px; + transition: + background 160ms ease, + color 160ms ease; +} + +.docs-nav-item span:first-child { + display: grid; + gap: 2px; +} + +.docs-nav-item strong { + font-size: 13px; + font-weight: 700; + letter-spacing: -0.03em; +} + +.docs-nav-item small, +.docs-nav-item__meta { + color: #a9a196; + font-size: 11px; + font-weight: 600; + letter-spacing: -0.01em; +} + +.docs-sidebar a:hover, +.docs-sidebar a:focus-visible, +.docs-nav-item--active { + background: #f4efe7; + color: #050505; + outline: none; +} + +.docs-sidebar a:hover small, +.docs-sidebar a:hover .docs-nav-item__meta, +.docs-sidebar a:focus-visible small, +.docs-sidebar a:focus-visible .docs-nav-item__meta, +.docs-nav-item--active small, +.docs-nav-item--active .docs-nav-item__meta { + color: #050505; +} + +.docs-content { + overflow-y: auto; + scroll-behavior: smooth; + background: #050505; +} + +.docs-content__header { + position: sticky; + top: 0; + z-index: 2; + background: #050505; +} + +.docs-language-toggle { + display: inline-flex; + align-items: center; + gap: 0; + padding: 2px; + border: 2px solid #d8d0c4; + border-radius: 999px; + background: transparent; + color: #f4efe7; + cursor: pointer; +} + +.docs-language-toggle span { + display: grid; + place-items: center; + min-width: 36px; + min-height: 26px; + border-radius: 999px; + color: #a9a196; + font-size: 11px; + font-weight: 700; + letter-spacing: 0.04em; +} + +.docs-language-toggle .is-active { + background: #f4efe7; + color: #050505; +} + +.docs-language-toggle:hover, +.docs-language-toggle:focus-visible { + outline: none; + background: rgba(216, 208, 196, 0.1); +} + +.docs-section { + max-width: 920px; + margin: 0 auto; + padding: 34px clamp(18px, 4vw, 56px) 48px; +} + +.docs-section__eyebrow { + display: flex; + justify-content: space-between; + margin-bottom: 22px; + color: #a9a196; + font-size: 11px; + font-weight: 700; + letter-spacing: 0.12em; + text-transform: uppercase; +} + +.docs-section h1, +.docs-section h2, +.docs-section h3 { + color: #f4efe7; + letter-spacing: -0.06em; + line-height: 1.05; +} + +.docs-section h1 { + margin-top: 0; + margin-bottom: 20px; + font-size: clamp(46px, 7vw, 88px); + font-weight: 700; +} + +.docs-section h2 { + margin-top: 44px; + margin-bottom: 12px; + padding-bottom: 10px; + border-bottom: 2px solid #d8d0c4; + font-size: clamp(28px, 4vw, 44px); + font-weight: 700; +} + +.docs-section h3 { + margin-top: 30px; + margin-bottom: 10px; + font-size: 18px; + font-weight: 700; + letter-spacing: -0.03em; +} + +.docs-section p, +.docs-section li { + color: #d8d0c4; + font-family: Inter, "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 15px; + line-height: 1.75; +} + +.docs-section ul, +.docs-section ol { + padding-left: 24px; +} + +.docs-section a { + color: #f4efe7; + text-underline-offset: 4px; +} + +.docs-section code { + border: 0; + border-radius: 2px; + padding: 2px 5px; + background: rgba(216, 208, 196, 0.22); + color: #f4efe7; + font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace; + font-size: 0.92em; +} + +.docs-section pre { + overflow-x: auto; + padding: 18px; + border: 0; + border-radius: 0; + background: #0d0d0d; +} + +.docs-section pre code { + display: block; + padding: 0; + border: 0; + background: transparent; + color: #f4efe7; + line-height: 1.45; + white-space: pre; +} + +.docs-section table { + display: block; + width: 100%; + margin: 20px 0; + overflow-x: auto; + border-collapse: collapse; +} + +.docs-section th, +.docs-section td { + padding: 10px 12px; + border: 2px solid #d8d0c4; + text-align: left; +} + +.docs-section th { + background: #111; + color: #f4efe7; + font-weight: 700; +} + +.docs-section blockquote { + margin-left: 0; + padding-left: 18px; + border-left: 2px solid #d8d0c4; + color: #a9a196; +} + +@media (max-width: 760px) { + .docs-page { + display: block; + overflow-y: auto; + } + + .docs-sidebar { + border-right: 0; + border-bottom: 2px solid #d8d0c4; + } + + .docs-content { + overflow: visible; + padding: 24px 16px; + } +} + .crosshair { position: fixed; top: 50%; @@ -79,3 +390,573 @@ canvas { color: rgba(255, 255, 255, 0.85); letter-spacing: 0.03em; } + +/* Editor page */ +.editor-container { + position: fixed; + top: 0; + left: 0; + width: 100vw; + height: 100vh; + background: #050505; + color: #f8f8f8; + font-family: + Inter, + ui-sans-serif, + system-ui, + -apple-system, + BlinkMacSystemFont, + "Segoe UI", + sans-serif; + overflow: hidden; +} + +.editor-loading, +.editor-error { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + height: 100%; + color: #f8f8f8; + text-align: center; + padding: 2rem; +} + +.editor-loading h2 { + font-size: clamp(1.8rem, 4vw, 3rem); + color: #ffffff; + margin: 0 0 0.75rem; + letter-spacing: -0.05em; +} + +.editor-loading p { + font-size: 1rem; + color: #9b9b9b; +} + +.editor-error h2 { + font-size: clamp(1.8rem, 4vw, 3rem); + color: #ffffff; + margin: 0 0 0.75rem; + letter-spacing: -0.05em; +} + +.editor-error p { + font-size: 1.1rem; + color: #b7b7b7; + margin: 0 0 2rem; + max-width: 600px; +} + +.editor-container code { + background: #171717; + padding: 0.2rem 0.4rem; + border-radius: 4px; + color: #ffffff; + font-family: "SFMono-Regular", "Courier New", monospace; +} + +.editor-upload-section { + width: min(520px, calc(100vw - 2rem)); + background: #0d0d0d; + border-radius: 24px; + padding: 1.25rem; + border: 1px solid #2a2a2a; + box-shadow: 0 24px 80px rgba(0, 0, 0, 0.45); +} + +.editor-upload-section h3 { + color: #ffffff; + margin: 0 0 1rem; + font-size: 0.9rem; + font-weight: 650; + letter-spacing: -0.02em; +} + +.editor-drop-zone { + display: flex; + align-items: center; + justify-content: center; + width: 100%; + min-height: 116px; + padding: 1.25rem; + border: 1px dashed #5b5b5b; + border-radius: 18px; + background: #111111; + color: #f8f8f8; + font-weight: 650; + text-align: center; + cursor: pointer; + transition: + background 160ms ease, + border-color 160ms ease, + transform 160ms ease; + font-size: 0.95rem; + margin-bottom: 1rem; +} + +.editor-drop-zone:hover { + background: #181818; + border-color: #ffffff; + transform: translateY(-1px); +} + +.editor-folder-input { + display: none; +} + +.editor-folder-structure { + background: #080808; + border: 1px solid #202020; + border-radius: 16px; + padding: 1rem; +} + +.editor-folder-structure h4 { + color: #ffffff; + margin: 0 0 0.5rem; + font-size: 0.78rem; + text-transform: uppercase; + letter-spacing: 0.08em; +} + +.editor-folder-structure pre { + margin: 0; + background: transparent; + color: #a7a7a7; + font-family: "SFMono-Regular", "Courier New", monospace; + font-size: 0.78rem; + line-height: 1.55; + overflow-x: auto; + white-space: pre-wrap; +} + +.editor-camera-info { + position: absolute; + top: 16px; + left: 16px; + display: flex; + align-items: center; + gap: 10px; + z-index: 2; + background: rgba(5, 5, 5, 0.78); + color: #f8f8f8; + padding: 8px 10px; + border-radius: 999px; + border: 1px solid rgba(255, 255, 255, 0.12); + box-shadow: 0 16px 50px rgba(0, 0, 0, 0.35); + backdrop-filter: blur(18px); + font-size: 11px; + line-height: 1; +} + +.editor-camera-info span { + color: #9b9b9b; +} + +.editor-camera-info strong { + color: #ffffff; + font-weight: 600; +} + +.editor-controls-panel { + position: absolute; + right: 16px; + top: 16px; + bottom: 16px; + width: min(340px, calc(100vw - 32px)); + background: rgba(8, 8, 8, 0.88); + padding: 14px; + color: #f8f8f8; + border: 1px solid rgba(255, 255, 255, 0.1); + border-radius: 28px; + box-shadow: 0 24px 90px rgba(0, 0, 0, 0.45); + overflow-y: auto; + display: flex; + flex-direction: column; + backdrop-filter: blur(22px); + scrollbar-width: thin; + scrollbar-color: #3a3a3a transparent; +} + +.editor-controls-panel::-webkit-scrollbar { + width: 6px; +} + +.editor-controls-panel::-webkit-scrollbar-thumb { + background: #3a3a3a; + border-radius: 999px; +} + +.editor-panel-header { + padding: 12px 12px 16px; +} + +.editor-panel-kicker { + color: #8f8f8f; + font-size: 0.7rem; + font-weight: 700; + letter-spacing: 0.16em; + text-transform: uppercase; +} + +.editor-panel-header h2 { + margin: 0.35rem 0 0.45rem; + color: #ffffff; + font-size: 1.55rem; + font-weight: 720; + letter-spacing: -0.06em; +} + +.editor-panel-header p { + margin: 0; + color: #a3a3a3; + font-size: 0.84rem; + line-height: 1.45; +} + +.editor-control-section { + padding: 14px 12px; + border-top: 1px solid rgba(255, 255, 255, 0.09); +} + +.editor-section-heading { + display: flex; + align-items: center; + justify-content: space-between; + gap: 12px; + margin-bottom: 10px; +} + +.editor-section-heading h3 { + margin: 0; + color: #ffffff; + font-size: 0.78rem; + font-weight: 700; + letter-spacing: 0.12em; + text-transform: uppercase; +} + +.editor-section-heading span, +.editor-section-heading svg { + color: #777777; + font-size: 0.74rem; +} + +.editor-transform-buttons { + display: grid; + grid-template-columns: 1fr; + gap: 6px; +} + +.editor-transform-button { + display: grid; + grid-template-columns: 18px 1fr auto; + align-items: center; + gap: 10px; + width: 100%; + padding: 10px 11px; + background: #101010; + color: #d9d9d9; + border: 1px solid #242424; + border-radius: 14px; + cursor: pointer; + font-size: 0.88rem; + font-weight: 620; + text-align: left; + transition: + background 160ms ease, + border-color 160ms ease, + color 160ms ease, + transform 160ms ease; +} + +.editor-transform-button.active { + background: #ffffff; + color: #050505; + border-color: #ffffff; +} + +.editor-transform-button:hover { + background: #191919; + border-color: #5c5c5c; + color: #ffffff; + transform: translateY(-1px); +} + +.editor-transform-button.active:hover { + background: #ffffff; + color: #050505; +} + +.editor-transform-button kbd { + min-width: 22px; + padding: 3px 6px; + border-radius: 7px; + background: rgba(0, 0, 0, 0.08); + color: currentColor; + font-family: inherit; + font-size: 0.7rem; + font-weight: 720; + text-align: center; +} + +.editor-history-buttons { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 8px; + margin-top: 8px; +} + +.editor-history-button { + display: flex; + align-items: center; + justify-content: center; + gap: 7px; + padding: 9px; + background: #101010; + color: #f2f2f2; + border: 1px solid #242424; + border-radius: 13px; + cursor: pointer; + font-size: 0.78rem; + font-weight: 650; +} + +.editor-history-button span { + color: #8e8e8e; +} + +.editor-history-button:disabled { + cursor: not-allowed; + opacity: 0.38; +} + +.editor-action-button, +.editor-player-button { + display: flex; + align-items: center; + justify-content: center; + gap: 9px; + width: 100%; + padding: 11px 12px; + background: #101010; + color: #f2f2f2; + border: 1px solid #242424; + border-radius: 14px; + cursor: pointer; + font-size: 0.88rem; + font-weight: 680; + transition: + background 160ms ease, + border-color 160ms ease, + color 160ms ease, + transform 160ms ease; +} + +.editor-action-button + .editor-action-button { + margin-top: 8px; +} + +.editor-action-button:hover, +.editor-player-button:hover { + background: #191919; + border-color: #5c5c5c; + color: #ffffff; + transform: translateY(-1px); +} + +.editor-action-button-primary, +.editor-player-button.active { + background: #ffffff; + color: #050505; + border-color: #ffffff; +} + +.editor-action-button-primary:hover, +.editor-player-button.active:hover { + background: #ffffff; + color: #050505; +} + +.editor-selected-info { + display: flex; + align-items: center; + gap: 11px; + background: #ffffff; + border: 1px solid #ffffff; + border-radius: 16px; + padding: 12px; + color: #050505; +} + +.editor-selected-info strong, +.editor-selected-info span { + display: block; +} + +.editor-selected-info strong { + font-size: 0.92rem; + line-height: 1.2; +} + +.editor-selected-info span { + color: #555555; + font-size: 0.75rem; + margin-top: 2px; +} + +.editor-no-selection { + display: flex; + align-items: center; + gap: 10px; + background: #101010; + border: 1px dashed #363636; + border-radius: 16px; + padding: 12px; + color: #8f8f8f; + font-size: 0.86rem; +} + +.editor-shortcuts-list { + display: grid; + gap: 7px; + margin: 0; +} + +.editor-shortcuts-list div { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + padding: 7px 0; + border-bottom: 1px solid rgba(255, 255, 255, 0.06); +} + +.editor-shortcuts-list div:last-child { + border-bottom: 0; +} + +.editor-shortcuts-list dt, +.editor-shortcuts-list dd { + margin: 0; + font-size: 0.76rem; +} + +.editor-shortcuts-list dt { + color: #ffffff; + font-weight: 700; +} + +.editor-shortcuts-list dd { + color: #8d8d8d; + text-align: right; +} + +.editor-json-section { + display: flex; + flex-direction: column; + min-height: 240px; + padding: 14px 12px 12px; + border-top: 1px solid rgba(255, 255, 255, 0.09); +} + +.editor-json-view { + flex: 1; + max-height: 320px; + margin: 0; + padding: 8px 0; + overflow: auto; + background: #050505; + border: 1px solid #1f1f1f; + border-radius: 16px; + color: #d7d7d7; + font-family: "SFMono-Regular", "Courier New", monospace; + font-size: 0.72rem; + line-height: 1.55; + scrollbar-width: thin; + scrollbar-color: #3a3a3a transparent; +} + +.editor-json-view::-webkit-scrollbar { + width: 6px; + height: 6px; +} + +.editor-json-view::-webkit-scrollbar-thumb { + background: #3a3a3a; + border-radius: 999px; +} + +.editor-json-view code { + display: grid; + grid-template-columns: 34px max-content; + gap: 10px; + min-width: 100%; + padding: 0 12px; + background: transparent; + color: inherit; + font-family: inherit; + white-space: pre; +} + +.editor-json-view code span { + color: #5f5f5f; + text-align: right; + user-select: none; +} + +.editor-json-view code.is-selected { + background: #111111; + color: #f2f2f2; +} + +.editor-json-view code.is-selected * { + color: #f2f2f2; +} + +.editor-json-view code.is-selected span { + color: #8a8a8a; +} + +.editor-json-hint { + display: flex; + align-items: center; + gap: 7px; + margin-top: 8px; + color: #8d8d8d; + font-size: 0.74rem; +} + +@media (max-width: 768px) { + .editor-error h2 { + font-size: 1.5rem; + } + + .editor-upload-section { + padding: 1.5rem; + } + + .editor-drop-zone { + padding: 1.5rem 1rem; + } + + .editor-camera-info { + display: none; + } + + .editor-controls-panel { + top: auto; + right: 10px; + bottom: 10px; + left: 10px; + width: auto; + max-height: 46vh; + border-radius: 22px; + } + + .editor-json-section { + min-height: 180px; + } +} diff --git a/src/main.tsx b/src/main.tsx index ef474bf..c2a145c 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,6 +1,6 @@ import { StrictMode } from "react"; import { createRoot } from "react-dom/client"; -import App from "./App.tsx"; +import App from "./App"; import "./index.css"; createRoot(document.getElementById("root")!).render( diff --git a/src/stateManager/AudioManager.ts b/src/managers/AudioManager.ts similarity index 100% rename from src/stateManager/AudioManager.ts rename to src/managers/AudioManager.ts diff --git a/src/stateManager/InteractionManager.ts b/src/managers/InteractionManager.ts similarity index 100% rename from src/stateManager/InteractionManager.ts rename to src/managers/InteractionManager.ts diff --git a/src/pages/docs/architecture/page.tsx b/src/pages/docs/architecture/page.tsx new file mode 100644 index 0000000..f876316 --- /dev/null +++ b/src/pages/docs/architecture/page.tsx @@ -0,0 +1,14 @@ +import architecture from "../../../../docs/technical/architecture.md?raw"; +import { DocsDocument } from "@/components/docs/DocsDocument"; +import { architectureFr } from "@/data/docs/docsTranslations"; + +export function DocsArchitecturePage(): React.JSX.Element { + return ( + + ); +} diff --git a/src/pages/docs/editor/page.tsx b/src/pages/docs/editor/page.tsx new file mode 100644 index 0000000..53c7236 --- /dev/null +++ b/src/pages/docs/editor/page.tsx @@ -0,0 +1,14 @@ +import editor from "../../../../docs/user/editor.md?raw"; +import { DocsDocument } from "@/components/docs/DocsDocument"; +import { editorFr } from "@/data/docs/docsTranslations"; + +export function DocsEditorPage(): React.JSX.Element { + return ( + + ); +} diff --git a/src/pages/docs/features/page.tsx b/src/pages/docs/features/page.tsx new file mode 100644 index 0000000..4b41580 --- /dev/null +++ b/src/pages/docs/features/page.tsx @@ -0,0 +1,14 @@ +import features from "../../../../docs/user/features.md?raw"; +import { DocsDocument } from "@/components/docs/DocsDocument"; +import { featuresFr } from "@/data/docs/docsTranslations"; + +export function DocsFeaturesPage(): React.JSX.Element { + return ( + + ); +} diff --git a/src/pages/docs/page.tsx b/src/pages/docs/page.tsx new file mode 100644 index 0000000..c1f4380 --- /dev/null +++ b/src/pages/docs/page.tsx @@ -0,0 +1,14 @@ +import readme from "../../../README.md?raw"; +import { DocsDocument } from "@/components/docs/DocsDocument"; +import { readmeFr } from "@/data/docs/docsTranslations"; + +export function DocsReadmePage(): React.JSX.Element { + return ( + + ); +} diff --git a/src/pages/docs/target-architecture/page.tsx b/src/pages/docs/target-architecture/page.tsx new file mode 100644 index 0000000..b99c6d1 --- /dev/null +++ b/src/pages/docs/target-architecture/page.tsx @@ -0,0 +1,14 @@ +import targetArchitecture from "../../../../docs/technical/target-architecture.md?raw"; +import { DocsDocument } from "@/components/docs/DocsDocument"; +import { targetArchitectureFr } from "@/data/docs/docsTranslations"; + +export function DocsTargetArchitecturePage(): React.JSX.Element { + return ( + + ); +} diff --git a/src/pages/docs/technical-editor/page.tsx b/src/pages/docs/technical-editor/page.tsx new file mode 100644 index 0000000..f03c609 --- /dev/null +++ b/src/pages/docs/technical-editor/page.tsx @@ -0,0 +1,13 @@ +import technicalEditor from "../../../../docs/technical/editor.md?raw"; +import { DocsDocument } from "@/components/docs/DocsDocument"; + +export function DocsTechnicalEditorPage(): React.JSX.Element { + return ( + + ); +} diff --git a/src/pages/editor/page.tsx b/src/pages/editor/page.tsx new file mode 100644 index 0000000..e06cc51 --- /dev/null +++ b/src/pages/editor/page.tsx @@ -0,0 +1,201 @@ +import { useCallback, useState } from "react"; +import { Canvas } from "@react-three/fiber"; +import { EditorControls } from "@/components/editor/EditorControls"; +import { EditorScene } from "@/components/editor/scene/EditorScene"; +import { useEditorHistory } from "@/hooks/editor/useEditorHistory"; +import { useEditorSceneData } from "@/hooks/editor/useEditorSceneData"; +import type { MapNode, SceneData, TransformMode } from "@/types/editor"; + +const SAVE_ERROR_MESSAGE = "Erreur lors de l'enregistrement"; + +function serializeMapNodes(sceneData: SceneData): string { + return JSON.stringify(sceneData.mapNodes, null, 2); +} + +export function EditorPage(): React.JSX.Element { + const { + hasMapJson, + isMapLoading, + sceneData, + setSceneData, + handleFolderUpload, + } = useEditorSceneData(); + + const [selectedNodeIndex, setSelectedNodeIndex] = useState( + null, + ); + const [hoveredNodeIndex, setHoveredNodeIndex] = useState(null); + const [transformMode, setTransformMode] = + useState("translate"); + const [isPlayerMode, setIsPlayerMode] = useState(false); + + const { + undoCount, + redoCount, + handleUndo, + handleRedo, + handleTransformStart, + handleTransformEnd, + } = useEditorHistory(sceneData, setSceneData); + + const handleSelectNode = useCallback((index: number | null) => { + setSelectedNodeIndex(index); + }, []); + + const handleHoverNode = useCallback((index: number | null) => { + setHoveredNodeIndex(index); + }, []); + + const handleTransformModeChange = useCallback((mode: TransformMode) => { + setTransformMode(mode); + }, []); + + const handleSaveToServer = useCallback(async () => { + if (!sceneData) return; + const json = serializeMapNodes(sceneData); + + try { + const response = await fetch("/api/save-map", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: json, + }); + + if (response.ok) { + alert("Map enregistrée avec succès!"); + } else { + alert(SAVE_ERROR_MESSAGE); + } + } catch (err) { + console.error("Error saving map:", err); + alert(SAVE_ERROR_MESSAGE); + } + }, [sceneData]); + + const handleExportJson = useCallback(() => { + if (!sceneData) return; + const json = serializeMapNodes(sceneData); + const blob = new Blob([json], { type: "application/json" }); + const url = URL.createObjectURL(blob); + const a = document.createElement("a"); + a.href = url; + a.download = "map.json"; + a.click(); + window.setTimeout(() => URL.revokeObjectURL(url), 0); + }, [sceneData]); + + const handlePlayerMode = useCallback(() => { + setIsPlayerMode((prev) => !prev); + }, []); + + const handleNodeTransform = useCallback( + (nodeIndex: number, updatedNode: MapNode) => { + setSceneData((prev) => { + if (!prev) return null; + const newMapNodes = [...prev.mapNodes]; + newMapNodes[nodeIndex] = updatedNode; + return { ...prev, mapNodes: newMapNodes }; + }); + }, + [setSceneData], + ); + + if (isMapLoading) { + return ( +
+
+

Chargement de l'éditeur...

+

Vérification de map.json dans public/

+
+
+ ); + } + + if (!hasMapJson) { + return ( +
+
+

Erreur : map.json introuvable

+

+ Le fichier map.json est requis dans le dossier public/. +

+ +
+

Télécharger un dossier contenant map.json

+ + + +
+

Structure requise :

+
+                public/ ├── map.json (à la racine) └── models/
+                ├── arbre/ │ └── model.gltf ├── building/ │ └── model.gltf └──
+                ...
+              
+
+
+
+
+ ); + } + + return ( +
+ { + gl.setClearColor("#050505"); + }} + > + + + + {sceneData && ( + + )} +
+ ); +} diff --git a/src/pages/page.tsx b/src/pages/page.tsx new file mode 100644 index 0000000..2635e63 --- /dev/null +++ b/src/pages/page.tsx @@ -0,0 +1,21 @@ +import { Suspense } from "react"; +import { Canvas } from "@react-three/fiber"; +import { Crosshair } from "@/components/ui/Crosshair"; +import { InteractPrompt } from "@/components/ui/InteractPrompt"; +import { DebugPerf } from "@/components/debug/DebugPerf"; +import { World } from "@/world/World"; + +export function HomePage(): React.JSX.Element { + return ( + <> + + + + + + + + + + ); +} diff --git a/src/providers/docs/DocsLanguageProvider.tsx b/src/providers/docs/DocsLanguageProvider.tsx new file mode 100644 index 0000000..0f081a2 --- /dev/null +++ b/src/providers/docs/DocsLanguageProvider.tsx @@ -0,0 +1,25 @@ +import { useState } from "react"; +import { + DocsLanguageContext, + type DocsLanguage, +} from "@/contexts/docs/DocsLanguageContext"; + +interface DocsLanguageProviderProps { + children: React.ReactNode; +} + +export function DocsLanguageProvider({ + children, +}: DocsLanguageProviderProps): React.JSX.Element { + const [language, setLanguage] = useState("en"); + + function toggleLanguage(): void { + setLanguage((currentLanguage) => (currentLanguage === "en" ? "fr" : "en")); + } + + return ( + + {children} + + ); +} diff --git a/src/router.tsx b/src/router.tsx new file mode 100644 index 0000000..4bb68a2 --- /dev/null +++ b/src/router.tsx @@ -0,0 +1,68 @@ +import { + Outlet, + createRootRoute, + createRoute, + createRouter, +} from "@tanstack/react-router"; +import { HomePage } from "@/pages/page"; +import { EditorPage } from "@/pages/editor/page"; +import { + DocsArchitectureRoute, + DocsEditorRoute, + DocsFeaturesRoute, + DocsLayoutRoute, + DocsReadmeRoute, + DocsTargetArchitectureRoute, + DocsTechnicalEditorRoute, +} from "@/routes/docs/DocsRouteComponents"; + +const rootRoute = createRootRoute({ + component: Outlet, +}); + +const indexRoute = createRoute({ + getParentRoute: () => rootRoute, + path: "/", + component: HomePage, +}); + +const editorRoute = createRoute({ + getParentRoute: () => rootRoute, + path: "/editor", + component: EditorPage, +}); + +const docsRoute = createRoute({ + getParentRoute: () => rootRoute, + path: "/docs", + component: DocsLayoutRoute, +}); + +const docsChildRoutes = [ + { path: "/", component: DocsReadmeRoute }, + { path: "architecture", component: DocsArchitectureRoute }, + { path: "target-architecture", component: DocsTargetArchitectureRoute }, + { path: "technical-editor", component: DocsTechnicalEditorRoute }, + { path: "features", component: DocsFeaturesRoute }, + { path: "editor", component: DocsEditorRoute }, +].map(({ path, component }) => + createRoute({ + getParentRoute: () => docsRoute, + path, + component, + }), +); + +const routeTree = rootRoute.addChildren([ + indexRoute, + editorRoute, + docsRoute.addChildren(docsChildRoutes), +]); + +export const router = createRouter({ routeTree }); + +declare module "@tanstack/react-router" { + interface Register { + router: typeof router; + } +} diff --git a/src/routes/docs/DocsRouteComponents.tsx b/src/routes/docs/DocsRouteComponents.tsx new file mode 100644 index 0000000..01ef28c --- /dev/null +++ b/src/routes/docs/DocsRouteComponents.tsx @@ -0,0 +1,99 @@ +import { Suspense, lazy } from "react"; + +const LazyDocsLayout = lazy(() => + import("@/components/docs/DocsLayout").then((module) => ({ + default: module.DocsLayout, + })), +); + +const LazyDocsReadmePage = lazy(() => + import("@/pages/docs/page").then((module) => ({ + default: module.DocsReadmePage, + })), +); + +const LazyDocsArchitecturePage = lazy(() => + import("@/pages/docs/architecture/page").then((module) => ({ + default: module.DocsArchitecturePage, + })), +); + +const LazyDocsTargetArchitecturePage = lazy(() => + import("@/pages/docs/target-architecture/page").then((module) => ({ + default: module.DocsTargetArchitecturePage, + })), +); + +const LazyDocsTechnicalEditorPage = lazy(() => + import("@/pages/docs/technical-editor/page").then((module) => ({ + default: module.DocsTechnicalEditorPage, + })), +); + +const LazyDocsFeaturesPage = lazy(() => + import("@/pages/docs/features/page").then((module) => ({ + default: module.DocsFeaturesPage, + })), +); + +const LazyDocsEditorPage = lazy(() => + import("@/pages/docs/editor/page").then((module) => ({ + default: module.DocsEditorPage, + })), +); + +export function DocsLayoutRoute(): React.JSX.Element { + return ( + + + + ); +} + +export function DocsReadmeRoute(): React.JSX.Element { + return ( + + + + ); +} + +export function DocsArchitectureRoute(): React.JSX.Element { + return ( + + + + ); +} + +export function DocsTargetArchitectureRoute(): React.JSX.Element { + return ( + + + + ); +} + +export function DocsTechnicalEditorRoute(): React.JSX.Element { + return ( + + + + ); +} + +export function DocsFeaturesRoute(): React.JSX.Element { + return ( + + + + ); +} + +export function DocsEditorRoute(): React.JSX.Element { + return ( + + + + ); +} diff --git a/src/types/editor.ts b/src/types/editor.ts new file mode 100644 index 0000000..73306c4 --- /dev/null +++ b/src/types/editor.ts @@ -0,0 +1,16 @@ +import type { Vector3Tuple } from "./three"; + +export interface MapNode { + name: string; + type: string; + position: Vector3Tuple; + rotation: Vector3Tuple; + scale: Vector3Tuple; +} + +export interface SceneData { + mapNodes: MapNode[]; + models: Map; +} + +export type TransformMode = "translate" | "rotate" | "scale"; diff --git a/src/types/interaction.ts b/src/types/interaction.ts index 986bed9..5e65bf6 100644 --- a/src/types/interaction.ts +++ b/src/types/interaction.ts @@ -1,6 +1,6 @@ export type InteractableKind = "grab" | "trigger"; -export interface TriggerInteractableHandle { +interface TriggerInteractableHandle { kind: "trigger"; label: string; onPress: () => void; diff --git a/src/types/logger.ts b/src/types/logger.ts index 3eb022a..7384c4c 100644 --- a/src/types/logger.ts +++ b/src/types/logger.ts @@ -1,6 +1,6 @@ export type LogLevel = "debug" | "info" | "warn" | "error"; -export type LogValue = +type LogValue = | string | number | boolean diff --git a/src/types/3d.ts b/src/types/three.ts similarity index 100% rename from src/types/3d.ts rename to src/types/three.ts diff --git a/src/utils/editor/loadEditorScene.ts b/src/utils/editor/loadEditorScene.ts new file mode 100644 index 0000000..62e8e4c --- /dev/null +++ b/src/utils/editor/loadEditorScene.ts @@ -0,0 +1,42 @@ +import type { SceneData } from "@/types/editor"; +import { parseMapNodes } from "@/utils/mapNodeValidation"; + +const MAP_JSON_PATH = "/map.json"; + +export async function createSceneDataFromFiles( + files: FileList, +): Promise { + const fileMap = new Map(); + + for (const file of Array.from(files)) { + fileMap.set(getProjectRelativePath(file), file); + } + + const mapFile = fileMap.get(MAP_JSON_PATH); + if (!mapFile) { + throw new Error("Fichier map.json manquant à la racine du dossier"); + } + + const mapNodes = parseMapNodes(JSON.parse(await mapFile.text())); + const models = new Map(); + + for (const [path, file] of fileMap.entries()) { + const modelMatch = path.match(/^\/models\/(.+)\/model\.gltf$/); + if (modelMatch?.[1]) { + models.set(modelMatch[1], URL.createObjectURL(file)); + } + } + + return { mapNodes, models }; +} + +function getProjectRelativePath(file: File): string { + const relativePath = file.webkitRelativePath || file.name; + + if (!relativePath.includes("/")) { + return `/${relativePath}`; + } + + const [, ...pathParts] = relativePath.split("/"); + return `/${pathParts.join("/")}`; +} diff --git a/src/utils/loadMapSceneData.ts b/src/utils/loadMapSceneData.ts new file mode 100644 index 0000000..4735f07 --- /dev/null +++ b/src/utils/loadMapSceneData.ts @@ -0,0 +1,43 @@ +import type { MapNode, SceneData } from "@/types/editor"; +import { parseMapNodes } from "@/utils/mapNodeValidation"; + +const MAP_JSON_PATH = "/map.json"; +const MODEL_FILE_NAME = "model.gltf"; +type ModelEntry = [modelName: string, modelUrl: string]; + +export async function loadMapSceneData(): Promise { + const response = await fetch(MAP_JSON_PATH); + + if (!response.ok) { + return null; + } + + const mapNodes = parseMapNodes(await response.json()); + return createSceneData(mapNodes); +} + +async function createSceneData(mapNodes: MapNode[]): Promise { + const models = await loadMapModelUrls(mapNodes); + return { mapNodes, models }; +} + +async function loadMapModelUrls( + mapNodes: MapNode[], +): Promise> { + const uniqueModelNames = [...new Set(mapNodes.map((node) => node.name))]; + const modelEntries = await Promise.all( + uniqueModelNames.map(async (modelName) => { + const modelUrl = `/models/${modelName}/${MODEL_FILE_NAME}`; + + try { + const response = await fetch(modelUrl, { method: "HEAD" }); + const modelEntry: ModelEntry = [modelName, modelUrl]; + return response.ok ? modelEntry : null; + } catch { + return null; + } + }), + ); + + return new Map(modelEntries.filter((entry) => entry !== null)); +} diff --git a/src/utils/mapNodeValidation.ts b/src/utils/mapNodeValidation.ts new file mode 100644 index 0000000..cbe8973 --- /dev/null +++ b/src/utils/mapNodeValidation.ts @@ -0,0 +1,32 @@ +import type { MapNode } from "../types/editor"; + +function isVector3Tuple(value: unknown): value is [number, number, number] { + return ( + Array.isArray(value) && + value.length === 3 && + value.every((item) => typeof item === "number" && Number.isFinite(item)) + ); +} + +export function isMapNode(value: unknown): value is MapNode { + if (typeof value !== "object" || value === null) { + return false; + } + + const node = value as Record; + return ( + typeof node.name === "string" && + typeof node.type === "string" && + isVector3Tuple(node.position) && + isVector3Tuple(node.rotation) && + isVector3Tuple(node.scale) + ); +} + +export function parseMapNodes(value: unknown): MapNode[] { + if (!Array.isArray(value) || !value.every(isMapNode)) { + throw new Error("Invalid map node data"); + } + + return value; +} diff --git a/src/world/Environment.tsx b/src/world/Environment.tsx index 72c12b6..b81a4ef 100644 --- a/src/world/Environment.tsx +++ b/src/world/Environment.tsx @@ -2,7 +2,7 @@ import { Environment as DreiEnvironment } from "@react-three/drei"; import { GAME_SCENE_SKYBOX_PATH, PHYSICS_SCENE_BACKGROUND_COLOR, -} from "@/data/environmentConfig"; +} from "@/data/world/environmentConfig"; import { useSceneMode } from "@/hooks/debug/useSceneMode"; export function Environment(): React.JSX.Element { diff --git a/src/world/GameMap.tsx b/src/world/GameMap.tsx new file mode 100644 index 0000000..c870183 --- /dev/null +++ b/src/world/GameMap.tsx @@ -0,0 +1,126 @@ +import type { ReactNode } from "react"; +import { Component } from "react"; +import { useEffect, useMemo, useRef, useState } from "react"; +import { useGLTF } from "@react-three/drei"; +import * as THREE from "three"; +import { useOctreeGraphNode } from "@/hooks/useOctreeGraphNode"; +import { loadMapSceneData } from "@/utils/loadMapSceneData"; +import type { OctreeReadyHandler } from "@/types/three"; +import type { MapNode } from "@/types/editor"; + +interface ErrorBoundaryProps { + children: ReactNode; + fallback?: ReactNode; +} + +interface ErrorBoundaryState { + hasError: boolean; +} + +class ModelErrorBoundary extends Component< + ErrorBoundaryProps, + ErrorBoundaryState +> { + constructor(props: ErrorBoundaryProps) { + super(props); + this.state = { hasError: false }; + } + + static getDerivedStateFromError(_error: Error): ErrorBoundaryState { + return { hasError: true }; + } + + componentDidCatch(_error: Error): void { + console.warn(`Failed to load model`); + } + + render(): ReactNode { + if (this.state.hasError) { + return this.props.fallback ?? null; + } + return this.props.children; + } +} + +interface GameMapProps { + onOctreeReady: OctreeReadyHandler; +} + +export function GameMap({ onOctreeReady }: GameMapProps): React.JSX.Element { + const [mapNodes, setMapNodes] = useState([]); + const [isLoading, setIsLoading] = useState(true); + const groupRef = useRef(null); + + useOctreeGraphNode(groupRef, onOctreeReady, mapNodes.length); + + useEffect(() => { + const loadMap = async () => { + try { + const sceneData = await loadMapSceneData(); + if (!sceneData) { + console.warn("map.json not found"); + setIsLoading(false); + return; + } + + const loadedMapNodes = sceneData.mapNodes.filter((node) => + sceneData.models.has(node.name), + ); + const missingModelCount = + sceneData.mapNodes.length - loadedMapNodes.length; + + if (missingModelCount > 0) { + console.warn( + `${missingModelCount} map nodes were skipped because their model files are missing.`, + ); + } + + setMapNodes(loadedMapNodes); + } catch (error) { + console.error("Error loading map:", error); + } finally { + setIsLoading(false); + } + }; + + loadMap(); + }, []); + + return ( + + {!isLoading && + mapNodes.map((node, index) => ( + + + + ))} + + ); +} + +function ModelInstance({ node }: { node: MapNode }): React.JSX.Element | null { + const modelPath = `/models/${node.name}/model.gltf`; + + const groupRef = useRef(null); + const { scene } = useGLTF(modelPath); + const sceneInstance = useMemo(() => scene.clone(true), [scene]); + const { position, rotation, scale } = node; + + useEffect(() => { + if (groupRef.current) { + groupRef.current.position.set(...position); + groupRef.current.rotation.set(...rotation); + groupRef.current.scale.set(...scale); + } + }, [position, rotation, scale]); + + return ( + + ); +} diff --git a/src/world/Lighting.tsx b/src/world/Lighting.tsx index 37be86f..a7905b3 100644 --- a/src/world/Lighting.tsx +++ b/src/world/Lighting.tsx @@ -20,7 +20,7 @@ import { SUN_Z_MAX, SUN_Z_MIN, SUN_Z_STEP, -} from "@/data/lightingConfig"; +} from "@/data/world/lightingConfig"; import { useDebugFolder } from "@/hooks/debug/useDebugFolder"; type LightingState = { diff --git a/src/world/Map.tsx b/src/world/Map.tsx deleted file mode 100644 index 17a7d8f..0000000 --- a/src/world/Map.tsx +++ /dev/null @@ -1,55 +0,0 @@ -import { useEffect, useRef } from "react"; -import { useThree } from "@react-three/fiber"; -import { useGLTF } from "@react-three/drei"; -import * as THREE from "three"; -import { MAP_DEBUG_BOX_HELPER_COLOR } from "@/data/debugConfig"; -import { useOctreeGraphNode } from "@/hooks/useOctreeGraphNode"; -import type { OctreeReadyHandler } from "@/types/3d"; -import { Debug } from "@/utils/debug/Debug"; - -const MAP_PATH = "/models/map/model.gltf"; - -interface MapProps { - onOctreeReady: OctreeReadyHandler; -} - -export function Map({ onOctreeReady }: MapProps): React.JSX.Element { - const { scene: gltfScene } = useGLTF(MAP_PATH); - const groupRef = useRef(null); - const boxHelpersRef = useRef([]); - const { scene } = useThree(); - - useOctreeGraphNode(groupRef, onOctreeReady); - - useEffect(() => { - const debug = Debug.getInstance(); - if (!debug.active || !groupRef.current) return; - - const helpers: THREE.BoxHelper[] = []; - - groupRef.current.traverse((child) => { - if (!(child instanceof THREE.Mesh)) return; - const helper = new THREE.BoxHelper(child, MAP_DEBUG_BOX_HELPER_COLOR); - scene.add(helper); - helpers.push(helper); - }); - - boxHelpersRef.current = helpers; - - return () => { - helpers.forEach((h) => { - scene.remove(h); - h.dispose(); - }); - boxHelpersRef.current = []; - }; - }, [scene]); - - return ( - - - - ); -} - -useGLTF.preload(MAP_PATH); diff --git a/src/world/World.tsx b/src/world/World.tsx index af7c39f..b945c38 100644 --- a/src/world/World.tsx +++ b/src/world/World.tsx @@ -3,15 +3,15 @@ import type { Octree } from "three/addons/math/Octree.js"; import { PLAYER_SPAWN_POSITION_GAME, PLAYER_SPAWN_POSITION_PHYSICS, -} from "@/data/playerConfig"; +} from "@/data/player/playerConfig"; import { useCameraMode } from "@/hooks/debug/useCameraMode"; import { useSceneMode } from "@/hooks/debug/useSceneMode"; -import { DebugCameraControls } from "@/utils/debug/scene/DebugCameraControls"; -import { DebugHelpers } from "@/utils/debug/scene/DebugHelpers"; +import { DebugCameraControls } from "@/components/debug/scene/DebugCameraControls"; +import { DebugHelpers } from "@/components/debug/scene/DebugHelpers"; import { Environment } from "@/world/Environment"; import { Lighting } from "@/world/Lighting"; -import { Map } from "@/world/Map"; -import { PlayerComponent } from "@/world/player/PlayerComponent"; +import { GameMap } from "@/world/GameMap"; +import { Player } from "@/world/player/Player"; import { TestScene } from "@/world/debug/TestScene"; export function World(): React.JSX.Element { @@ -31,13 +31,13 @@ export function World(): React.JSX.Element { {cameraMode === "debug" ? : null} {sceneMode === "game" ? ( - + ) : ( )} {cameraMode !== "debug" ? ( - + ) : null} ); diff --git a/src/world/debug/TestScene.tsx b/src/world/debug/TestScene.tsx index 7452329..c3bd528 100644 --- a/src/world/debug/TestScene.tsx +++ b/src/world/debug/TestScene.tsx @@ -1,9 +1,9 @@ import { useRef } from "react"; import * as THREE from "three"; import { Physics, RigidBody, CuboidCollider } from "@react-three/rapier"; -import { GrabbableObject } from "@/components/3d/GrabbableObject"; -import { TriggerObject } from "@/components/3d/TriggerObject"; -import { AnimatedModel } from "@/components/3d"; +import { GrabbableObject } from "@/components/three/GrabbableObject"; +import { TriggerObject } from "@/components/three/TriggerObject"; +import { AnimatedModel } from "@/components/three/AnimatedModel"; import { TEST_SCENE_FLOOR_COLLIDER_HALF_EXTENTS, TEST_SCENE_FLOOR_POSITION, @@ -20,9 +20,9 @@ import { TEST_SCENE_TRIGGER_ROUGHNESS, TEST_SCENE_TRIGGER_SEGMENTS, TEST_SCENE_TRIGGER_SOUND_PATH, -} from "@/data/testSceneConfig"; +} from "@/data/debug/testSceneConfig"; import { useOctreeGraphNode } from "@/hooks/useOctreeGraphNode"; -import type { OctreeReadyHandler } from "@/types/3d"; +import type { OctreeReadyHandler } from "@/types/three"; interface TestSceneProps { onOctreeReady: OctreeReadyHandler; diff --git a/src/world/player/PlayerComponent.tsx b/src/world/player/Player.tsx similarity index 79% rename from src/world/player/PlayerComponent.tsx rename to src/world/player/Player.tsx index 3b950e0..8fdc489 100644 --- a/src/world/player/PlayerComponent.tsx +++ b/src/world/player/Player.tsx @@ -1,19 +1,19 @@ import { useEffect } from "react"; import { useThree } from "@react-three/fiber"; import type { Octree } from "three/addons/math/Octree.js"; -import type { Vector3Tuple } from "@/types/3d"; +import type { Vector3Tuple } from "@/types/three"; import { PlayerCamera } from "@/world/player/PlayerCamera"; import { PlayerController } from "@/world/player/PlayerController"; -interface PlayerComponentProps { +interface PlayerProps { octree: Octree | null; spawnPosition: Vector3Tuple; } -export function PlayerComponent({ +export function Player({ spawnPosition, octree, -}: PlayerComponentProps): React.JSX.Element { +}: PlayerProps): React.JSX.Element { const camera = useThree((state) => state.camera); useEffect(() => { diff --git a/src/world/player/PlayerController.tsx b/src/world/player/PlayerController.tsx index 341c6d9..b9b714b 100644 --- a/src/world/player/PlayerController.tsx +++ b/src/world/player/PlayerController.tsx @@ -11,7 +11,7 @@ import { MOVE_LEFT_KEY, MOVE_RIGHT_KEY, PRIMARY_INTERACT_MOUSE_BUTTON, -} from "@/data/keybindings"; +} from "@/data/input/keybindings"; import { PLAYER_ACCELERATION_MULTIPLIER, PLAYER_AIR_CONTROL_FACTOR, @@ -22,9 +22,9 @@ import { PLAYER_MAX_DELTA, PLAYER_WALK_SPEED, PLAYER_XZ_DAMPING_FACTOR, -} from "@/data/playerConfig"; -import { InteractionManager } from "@/stateManager/InteractionManager"; -import type { Vector3Tuple } from "@/types/3d"; +} from "@/data/player/playerConfig"; +import { InteractionManager } from "@/managers/InteractionManager"; +import type { Vector3Tuple } from "@/types/three"; type Keys = { forward: boolean; @@ -54,6 +54,25 @@ const _up = new THREE.Vector3(0, 1, 0); const _translateVec = new THREE.Vector3(); const _collisionCorrection = new THREE.Vector3(); +function setMovementKey(keys: Keys, key: string, pressed: boolean): boolean { + switch (key.toLowerCase()) { + case MOVE_FORWARD_KEY: + keys.forward = pressed; + return true; + case MOVE_BACKWARD_KEY: + keys.backward = pressed; + return true; + case MOVE_LEFT_KEY: + keys.left = pressed; + return true; + case MOVE_RIGHT_KEY: + keys.right = pressed; + return true; + default: + return false; + } +} + export function PlayerController({ octree, spawnPosition, @@ -89,51 +108,29 @@ export function PlayerController({ const interaction = InteractionManager.getInstance(); const handleKeyDown = (event: KeyboardEvent): void => { - switch (event.key.toLowerCase()) { - case MOVE_FORWARD_KEY: - keys.current.forward = true; - break; - case MOVE_BACKWARD_KEY: - keys.current.backward = true; - break; - case MOVE_LEFT_KEY: - keys.current.left = true; - break; - case MOVE_RIGHT_KEY: - keys.current.right = true; - break; - case JUMP_KEY: - wantsJump.current = true; - break; - case INTERACT_KEY: - if (interaction.getState().focused?.kind === "trigger") { - interaction.pressInteract(); - } - break; - default: - return; + if (setMovementKey(keys.current, event.key, true)) { + event.preventDefault(); + return; + } + + if (event.key === JUMP_KEY) { + wantsJump.current = true; + event.preventDefault(); + return; + } + + if (event.key.toLowerCase() === INTERACT_KEY) { + if (interaction.getState().focused?.kind === "trigger") { + interaction.pressInteract(); + } + event.preventDefault(); } - event.preventDefault(); }; const handleKeyUp = (event: KeyboardEvent): void => { - switch (event.key.toLowerCase()) { - case MOVE_FORWARD_KEY: - keys.current.forward = false; - break; - case MOVE_BACKWARD_KEY: - keys.current.backward = false; - break; - case MOVE_LEFT_KEY: - keys.current.left = false; - break; - case MOVE_RIGHT_KEY: - keys.current.right = false; - break; - default: - return; + if (setMovementKey(keys.current, event.key, false)) { + event.preventDefault(); } - event.preventDefault(); }; const handleMouseDown = (event: MouseEvent): void => { diff --git a/vite.config.ts b/vite.config.ts index a8b3919..4a65037 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,9 +1,78 @@ import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; +import path from "node:path"; +import fs from "node:fs"; import { fileURLToPath } from "node:url"; +import type { ServerResponse } from "node:http"; +import type { Plugin } from "vite"; +import { parseMapNodes } from "./src/utils/mapNodeValidation"; + +const __dirname = fileURLToPath(new URL(".", import.meta.url)); + +const MAX_MAP_PAYLOAD_BYTES = 1024 * 1024; +const JSON_HEADERS = { "Content-Type": "application/json" }; + +function sendJson( + res: ServerResponse, + status: number, + body: unknown, + headers: Record = {}, +): void { + res + .writeHead(status, { ...JSON_HEADERS, ...headers }) + .end(JSON.stringify(body)); +} + +const saveMapPlugin = (): Plugin => ({ + name: "save-map-api", + configureServer(server) { + server.middlewares.use("/api/save-map", async (req, res) => { + if (req.method !== "POST") { + sendJson(res, 405, { error: "Method not allowed" }, { Allow: "POST" }); + return; + } + + const chunks: Buffer[] = []; + let size = 0; + + for await (const chunk of req) { + const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk); + size += buffer.length; + if (size > MAX_MAP_PAYLOAD_BYTES) { + sendJson(res, 413, { error: "Payload too large" }); + req.destroy(); + return; + } + chunks.push(buffer); + } + + try { + const data = JSON.parse(Buffer.concat(chunks).toString()); + try { + parseMapNodes(data); + } catch { + sendJson(res, 400, { error: "Invalid map payload" }); + return; + } + + const mapPath = path.resolve(__dirname, "public/map.json"); + await fs.promises.writeFile( + mapPath, + JSON.stringify(data, null, 2), + "utf8", + ); + sendJson(res, 200, { success: true }); + } catch (err) { + const status = err instanceof SyntaxError ? 400 : 500; + const message = err instanceof Error ? err.message : "Unknown error"; + sendJson(res, status, { error: message }); + } + }); + }, +}); export default defineConfig({ - plugins: [react()], + plugins: [react(), saveMapPlugin()], resolve: { alias: { "@": fileURLToPath(new URL("./src", import.meta.url)),