@vgai/editor 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +661 -0
- package/README.md +35 -0
- package/dist/a/b/c/test-nested.json +1 -0
- package/dist/assets/CCDIKSolver-Dz-ysxZF.js +1 -0
- package/dist/assets/SelectionBox-BXsv_6aH.js +1 -0
- package/dist/assets/browser-project-scripts-DOru4L1x.js +2 -0
- package/dist/assets/browserAll-CEkWYlFk.js +1 -0
- package/dist/assets/collision-world-DniMB0qq.glb +0 -0
- package/dist/assets/create-runtime-DYIWr3va.js +1 -0
- package/dist/assets/data-asset-Bb9sIM7i.js +5 -0
- package/dist/assets/esbuild-BHljloGq.wasm +0 -0
- package/dist/assets/fake-three-BMTQ9rl_.js +1 -0
- package/dist/assets/game-8SDZPPgH.js +1 -0
- package/dist/assets/game-BI111o5f.js +10 -0
- package/dist/assets/game-CevorxyV.js +1 -0
- package/dist/assets/game-Di1H0gFj.js +1 -0
- package/dist/assets/game-Di7XlywD.js +1 -0
- package/dist/assets/game-DjnCaw8R.js +1 -0
- package/dist/assets/game-Q9A0aXSV.js +1 -0
- package/dist/assets/game-pt_1lQLv.js +1 -0
- package/dist/assets/game-source-CvidN7AB.js +1 -0
- package/dist/assets/game-xsOho_wg.js +83 -0
- package/dist/assets/index-Bp5cecD6.js +12 -0
- package/dist/assets/index-CPVV6pjw.js +1 -0
- package/dist/assets/index-CpOnYyeD.js +213 -0
- package/dist/assets/index-Cs8xwv3e.js +1 -0
- package/dist/assets/index-DL7RcQ0n.js +27 -0
- package/dist/assets/index-Dr8H_6Rl.js +1 -0
- package/dist/assets/index-_bCaipUk.js +13650 -0
- package/dist/assets/ingest-siblings-Dz8eEqrV.js +1 -0
- package/dist/assets/mount-manifest-Bhk0ohsl.js +1 -0
- package/dist/assets/recast-navigation.wasm-compat-CvP4UGK6.js +1 -0
- package/dist/assets/scene-query-BivAHhJu.js +1 -0
- package/dist/assets/stats.module--VATS4Kh.js +1 -0
- package/dist/assets/webworkerAll-BLrH0F6F.js +1 -0
- package/dist/assets/xstate-animation-binding-1NGLmw6y.js +1 -0
- package/dist/assets/xstate.esm-BgUD33nl.js +3 -0
- package/dist/index.html +37 -0
- package/dist/ingest/racing-game/UPSTREAM.md +68 -0
- package/dist/ingest/racing-game/a/Inter-Black.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-Black.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-BlackItalic.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-BlackItalic.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-Bold.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-Bold.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-BoldItalic.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-BoldItalic.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-ExtraBold.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-ExtraBold.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-ExtraBoldItalic.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-ExtraBoldItalic.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-ExtraLight.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-ExtraLight.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-ExtraLightItalic.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-ExtraLightItalic.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-Italic.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-Italic.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-Light.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-Light.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-LightItalic.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-LightItalic.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-Medium.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-Medium.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-MediumItalic.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-MediumItalic.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-Regular.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-Regular.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-SemiBold.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-SemiBold.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-SemiBoldItalic.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-SemiBoldItalic.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-Thin.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-Thin.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-ThinItalic.woff +0 -0
- package/dist/ingest/racing-game/a/Inter-ThinItalic.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-italic.var.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter-roman.var.woff2 +0 -0
- package/dist/ingest/racing-game/a/Inter.var.woff2 +0 -0
- package/dist/ingest/racing-game/a/index.css +1 -0
- package/dist/ingest/racing-game/images/bronze.png +0 -0
- package/dist/ingest/racing-game/images/gold.png +0 -0
- package/dist/ingest/racing-game/images/silver.png +0 -0
- package/dist/ingest/racing-game/index.html +15 -0
- package/dist/ingest/racing-game/models/chassis-draco.glb +0 -0
- package/dist/ingest/racing-game/models/track-draco.glb +0 -0
- package/dist/ingest/racing-game/models/wheel-draco.glb +0 -0
- package/dist/ingest/racing-game/rg-entry.js +1 -0
- package/dist/ingest/racing-game/sounds/accelerate.mp3 +0 -0
- package/dist/ingest/racing-game/sounds/boost.mp3 +0 -0
- package/dist/ingest/racing-game/sounds/crash.mp3 +0 -0
- package/dist/ingest/racing-game/sounds/engine.mp3 +0 -0
- package/dist/ingest/racing-game/sounds/honk.mp3 +0 -0
- package/dist/ingest/racing-game/sounds/tire-brake.mp3 +0 -0
- package/dist/ingest/racing-game/sounds/train.mp3 +0 -0
- package/dist/ingest/racing-game/sounds/water.mp3 +0 -0
- package/dist/ingest/racing-game/textures/cursor.svg +3 -0
- package/dist/ingest/racing-game/textures/dikhololo_night_1k.hdr +0 -0
- package/dist/ingest/racing-game/textures/heightmap_1024.png +0 -0
- package/dist/ingest/racing-game/textures/mask.svg +11 -0
- package/dist/ingest/racing-game/textures/no_sound.png +0 -0
- package/dist/ingest/racing-game/three-r139.module.js +50617 -0
- package/dist/ingest/racing-game/vendor.js +179 -0
- package/dist/ingest/racing-game/vgai.game.json +20 -0
- package/dist/ingest/simcity/UPSTREAM.md +65 -0
- package/dist/ingest/simcity/favicon.ico +0 -0
- package/dist/ingest/simcity/fonts/Bebas-Regular.otf +0 -0
- package/dist/ingest/simcity/fonts/Digitalt.otf +0 -0
- package/dist/ingest/simcity/fonts/Stanberry.ttf +0 -0
- package/dist/ingest/simcity/icons/bulldozer-color.png +0 -0
- package/dist/ingest/simcity/icons/bulldozer.png +0 -0
- package/dist/ingest/simcity/icons/calendar.png +0 -0
- package/dist/ingest/simcity/icons/factory-color.png +0 -0
- package/dist/ingest/simcity/icons/factory.png +0 -0
- package/dist/ingest/simcity/icons/house-color.png +0 -0
- package/dist/ingest/simcity/icons/house.png +0 -0
- package/dist/ingest/simcity/icons/job.png +0 -0
- package/dist/ingest/simcity/icons/office.png +0 -0
- package/dist/ingest/simcity/icons/pause-color.png +0 -0
- package/dist/ingest/simcity/icons/pause.png +0 -0
- package/dist/ingest/simcity/icons/person.png +0 -0
- package/dist/ingest/simcity/icons/play-color.png +0 -0
- package/dist/ingest/simcity/icons/play.png +0 -0
- package/dist/ingest/simcity/icons/power-color.png +0 -0
- package/dist/ingest/simcity/icons/power-line-color.png +0 -0
- package/dist/ingest/simcity/icons/power.png +0 -0
- package/dist/ingest/simcity/icons/road-color.png +0 -0
- package/dist/ingest/simcity/icons/road.png +0 -0
- package/dist/ingest/simcity/icons/select-color.png +0 -0
- package/dist/ingest/simcity/icons/select.png +0 -0
- package/dist/ingest/simcity/icons/store-color.png +0 -0
- package/dist/ingest/simcity/index.html +94 -0
- package/dist/ingest/simcity/index.js +58 -0
- package/dist/ingest/simcity/main.css +233 -0
- package/dist/ingest/simcity/models/armored-truck.glb +0 -0
- package/dist/ingest/simcity/models/building-block-4floor-corner.glb +0 -0
- package/dist/ingest/simcity/models/building-block-4floor-short.glb +0 -0
- package/dist/ingest/simcity/models/building-block-5floor.glb +0 -0
- package/dist/ingest/simcity/models/building-burger-joint.glb +0 -0
- package/dist/ingest/simcity/models/building-cafe.glb +0 -0
- package/dist/ingest/simcity/models/building-casino.glb +0 -0
- package/dist/ingest/simcity/models/building-cinema.glb +0 -0
- package/dist/ingest/simcity/models/building-house-block-big.glb +0 -0
- package/dist/ingest/simcity/models/building-house-family-large.glb +0 -0
- package/dist/ingest/simcity/models/building-house-family-small.glb +0 -0
- package/dist/ingest/simcity/models/building-office-balcony.glb +0 -0
- package/dist/ingest/simcity/models/building-office-big.glb +0 -0
- package/dist/ingest/simcity/models/building-office-pyramid.glb +0 -0
- package/dist/ingest/simcity/models/building-office-tall.glb +0 -0
- package/dist/ingest/simcity/models/building-office.glb +0 -0
- package/dist/ingest/simcity/models/building-restaurant.glb +0 -0
- package/dist/ingest/simcity/models/building-skyscraper.glb +0 -0
- package/dist/ingest/simcity/models/car-ambulance-pickup.glb +0 -0
- package/dist/ingest/simcity/models/car-baywatch.glb +0 -0
- package/dist/ingest/simcity/models/car-hippie-van.glb +0 -0
- package/dist/ingest/simcity/models/car-passenger-race.glb +0 -0
- package/dist/ingest/simcity/models/car-passenger.glb +0 -0
- package/dist/ingest/simcity/models/car-police.glb +0 -0
- package/dist/ingest/simcity/models/car-taxi.glb +0 -0
- package/dist/ingest/simcity/models/car-tow-truck.glb +0 -0
- package/dist/ingest/simcity/models/car-truck-dump.glb +0 -0
- package/dist/ingest/simcity/models/car-veteran.glb +0 -0
- package/dist/ingest/simcity/models/construction-small.glb +0 -0
- package/dist/ingest/simcity/models/data-center.glb +0 -0
- package/dist/ingest/simcity/models/industry-factory-old.glb +0 -0
- package/dist/ingest/simcity/models/industry-factory.glb +0 -0
- package/dist/ingest/simcity/models/industry-refinery.glb +0 -0
- package/dist/ingest/simcity/models/industry-warehouse.glb +0 -0
- package/dist/ingest/simcity/models/power_line_pole_modified.glb +0 -0
- package/dist/ingest/simcity/models/tile-plain_grass.glb +0 -0
- package/dist/ingest/simcity/models/tile-road-curve.glb +0 -0
- package/dist/ingest/simcity/models/tile-road-end.glb +0 -0
- package/dist/ingest/simcity/models/tile-road-intersection-t.glb +0 -0
- package/dist/ingest/simcity/models/tile-road-intersection.glb +0 -0
- package/dist/ingest/simcity/models/tile-road-straight.glb +0 -0
- package/dist/ingest/simcity/models/truck.glb +0 -0
- package/dist/ingest/simcity/statusIcons/no-power.png +0 -0
- package/dist/ingest/simcity/statusIcons/no-road-access.png +0 -0
- package/dist/ingest/simcity/textures/base.png +0 -0
- package/dist/ingest/simcity/textures/grid.png +0 -0
- package/dist/ingest/simcity/textures/specular.png +0 -0
- package/dist/ingest/simcity/three-r155.module.js +51466 -0
- package/dist/ingest/simcity/vgai.game.json +20 -0
- package/dist/ingest/tanks/UPSTREAM.md +69 -0
- package/dist/ingest/tanks/index.html +214 -0
- package/dist/ingest/tanks/models/pixelTank.fbx +0 -0
- package/dist/ingest/tanks/tanks-entry.js +92 -0
- package/dist/ingest/tanks/three-r170.module.js +54571 -0
- package/dist/ingest/tanks/vgai.game.json +20 -0
- package/dist/inputmaps/default.inputmap.json +41 -0
- package/dist/jsm/libs/draco/gltf/draco_decoder.js +33 -0
- package/dist/jsm/libs/draco/gltf/draco_decoder.wasm +0 -0
- package/dist/jsm/libs/draco/gltf/draco_wasm_wrapper.js +116 -0
- package/dist/scenes/untitled.vscn.json +29 -0
- package/dist/textures/waternormals.jpg +0 -0
- package/dist-server/packaged.mjs +18155 -0
- package/package.json +36 -0
- package/server/asset-library-routes.ts +833 -0
- package/server/canonical-path.ts +50 -0
- package/server/cloud-asset-catalog.ts +101 -0
- package/server/dev.ts +350 -0
- package/server/editor-server.ts +1537 -0
- package/server/editor-sse.ts +73 -0
- package/server/game-globals-shadow.ts +58 -0
- package/server/local-asset-catalog.ts +163 -0
- package/server/packaged.ts +571 -0
- package/server/prod.ts +75 -0
- package/server/project-optimize-deps-entries.ts +149 -0
- package/server/project-view.ts +65 -0
- package/server/server-utils.ts +430 -0
- package/server/session-registry.ts +93 -0
- package/src/EditorContext.tsx +87 -0
- package/src/achieved-tier.ts +126 -0
- package/src/action-registry.ts +268 -0
- package/src/adapter-resolver.ts +1858 -0
- package/src/asset-events.ts +100 -0
- package/src/authoring/active-adapter.ts +98 -0
- package/src/authoring/active-systems.ts +50 -0
- package/src/authoring/boundary-authoring-adapter.ts +178 -0
- package/src/authoring/composite-authoring-adapter.ts +891 -0
- package/src/authoring/design-time-layers.ts +776 -0
- package/src/authoring/edit-mode-authoring.ts +643 -0
- package/src/authoring/embed-only-adapter.ts +57 -0
- package/src/authoring/ephemeral-persistence.ts +26 -0
- package/src/authoring/eyedropper-session.ts +69 -0
- package/src/authoring/first-party-hierarchy-menu.ts +74 -0
- package/src/authoring/first-party-inspector/AddSectionMenu.tsx +118 -0
- package/src/authoring/first-party-inspector/EnvironmentSection.tsx +550 -0
- package/src/authoring/first-party-inspector/HeaderSection.tsx +329 -0
- package/src/authoring/first-party-inspector/is-first-party-selection.ts +44 -0
- package/src/authoring/first-party-inspector/register.tsx +108 -0
- package/src/authoring/ingest-authoring-adapter.ts +475 -0
- package/src/authoring/ingest-capture.ts +94 -0
- package/src/authoring/ingest-game-adapter.ts +291 -0
- package/src/authoring/ingest-iframe-adapter.ts +38 -0
- package/src/authoring/ingest-iframe-reachable-adapter.ts +401 -0
- package/src/authoring/ingest-overlay.ts +193 -0
- package/src/authoring/layered-pick.ts +87 -0
- package/src/authoring/mount-failure-report.ts +112 -0
- package/src/authoring/overlay-report.ts +52 -0
- package/src/authoring/project-scenes.ts +111 -0
- package/src/authoring/react-dom-authoring-adapter.ts +795 -0
- package/src/authoring/react-inspector-section.tsx +1041 -0
- package/src/authoring/react-world-authoring-adapter.ts +2400 -0
- package/src/authoring/root-activation.ts +61 -0
- package/src/authoring/scene-ui-layer.ts +485 -0
- package/src/authoring/story-overlay.ts +48 -0
- package/src/authoring/ui-authoring-adapter.ts +325 -0
- package/src/authoring/ui-hierarchy-menu.ts +40 -0
- package/src/authoring/ui-inspector-sections.tsx +156 -0
- package/src/authoring/undo-timeline.ts +145 -0
- package/src/authoring/vgai-scene-authoring-adapter.ts +746 -0
- package/src/authoring/viewport-pick-context.ts +31 -0
- package/src/authoring/viewport-raycast.ts +80 -0
- package/src/authoring/world-overlay.ts +76 -0
- package/src/authoring/world-pan-state.ts +115 -0
- package/src/authoring/world-session-state.ts +102 -0
- package/src/authoring/world2d-authoring-adapter.ts +313 -0
- package/src/browser-external-watch.ts +98 -0
- package/src/browser-play-entry.ts +112 -0
- package/src/browser-project-scripts.ts +112 -0
- package/src/browser-transpile.ts +246 -0
- package/src/browser-watch-reload.ts +100 -0
- package/src/command-listener.ts +326 -0
- package/src/components/AlignToolbar.tsx +189 -0
- package/src/components/AppRoot.tsx +73 -0
- package/src/components/AssetBrowser.tsx +502 -0
- package/src/components/BottomPanel.tsx +326 -0
- package/src/components/BuildPanel.tsx +455 -0
- package/src/components/CameraInfo.tsx +56 -0
- package/src/components/CommandPalette.tsx +265 -0
- package/src/components/ConsolePanel.tsx +272 -0
- package/src/components/DataPanel.tsx +1268 -0
- package/src/components/DefaultEditorLayout.tsx +509 -0
- package/src/components/FolderTree.tsx +179 -0
- package/src/components/GameHierarchy.tsx +1349 -0
- package/src/components/Inspector.tsx +671 -0
- package/src/components/InspectorToolSection.tsx +74 -0
- package/src/components/MountFailureBanner.tsx +110 -0
- package/src/components/NetworkSection.tsx +109 -0
- package/src/components/OnlineAssetBrowser.tsx +448 -0
- package/src/components/OverlayReportBanner.tsx +122 -0
- package/src/components/PlayBar.tsx +356 -0
- package/src/components/PrefabSaveDialog.tsx +201 -0
- package/src/components/ProjectHeader.tsx +174 -0
- package/src/components/ProjectScreen.tsx +1004 -0
- package/src/components/RightPanel.tsx +166 -0
- package/src/components/RootActivateDialog.tsx +105 -0
- package/src/components/SaveDialog.tsx +197 -0
- package/src/components/SaveStatus.tsx +69 -0
- package/src/components/StatsOverlay.tsx +35 -0
- package/src/components/ToolHost.tsx +80 -0
- package/src/components/Toolbar.tsx +307 -0
- package/src/components/ViewportOverlay.tsx +234 -0
- package/src/components/ViewportPanel.tsx +369 -0
- package/src/components/WorldContextMenu.tsx +257 -0
- package/src/components/WorldSelectionOverlay.tsx +2003 -0
- package/src/components/WorldTextEditor.tsx +86 -0
- package/src/components/asset-viewers/AssetViewer.tsx +38 -0
- package/src/components/asset-viewers/AudioViewer.tsx +149 -0
- package/src/components/asset-viewers/GenericJsonViewer.tsx +77 -0
- package/src/components/asset-viewers/ImageViewer.tsx +65 -0
- package/src/components/asset-viewers/InputMapViewer.tsx +206 -0
- package/src/components/asset-viewers/ModelViewer.tsx +180 -0
- package/src/components/asset-viewers/OnlineAssetDetail.tsx +236 -0
- package/src/components/data-csv.ts +301 -0
- package/src/components/entity-name-commit.ts +18 -0
- package/src/components/inspector-property-grouping.ts +65 -0
- package/src/components/inspector-widgets/AlignmentGrid.tsx +188 -0
- package/src/components/inspector-widgets/BorderEditor.tsx +305 -0
- package/src/components/inspector-widgets/ColorPicker.tsx +548 -0
- package/src/components/inspector-widgets/FilterEditor.tsx +108 -0
- package/src/components/inspector-widgets/FontPicker.tsx +196 -0
- package/src/components/inspector-widgets/GradientEditor.tsx +277 -0
- package/src/components/inspector-widgets/ScrubbableInput.tsx +152 -0
- package/src/components/inspector-widgets/ShadowEditor.tsx +332 -0
- package/src/components/inspector-widgets/color-utils.ts +202 -0
- package/src/components/inspector-widgets/gallery-main.tsx +167 -0
- package/src/components/inspector-widgets/index.ts +22 -0
- package/src/components/inspector-widgets/shared.tsx +135 -0
- package/src/components/inspectors/AnimationSection.tsx +143 -0
- package/src/components/inspectors/AudioSection.tsx +215 -0
- package/src/components/inspectors/BoneAttachmentSection.tsx +82 -0
- package/src/components/inspectors/CameraSection.tsx +105 -0
- package/src/components/inspectors/ComponentsSection.tsx +358 -0
- package/src/components/inspectors/JointsSection.tsx +255 -0
- package/src/components/inspectors/LightSection.tsx +116 -0
- package/src/components/inspectors/MaterialSection.tsx +1189 -0
- package/src/components/inspectors/MeshSection.tsx +99 -0
- package/src/components/inspectors/NavigationSection.tsx +58 -0
- package/src/components/inspectors/ParticleSection.tsx +681 -0
- package/src/components/inspectors/PhysicsSection.tsx +326 -0
- package/src/components/inspectors/PostProcessingSection.tsx +1290 -0
- package/src/components/inspectors/RenderingSection.tsx +109 -0
- package/src/components/inspectors/ShadowSection.tsx +84 -0
- package/src/components/inspectors/SplineSection.tsx +191 -0
- package/src/components/inspectors/TransformSection.tsx +191 -0
- package/src/components/inspectors/json-schema-fields.ts +281 -0
- package/src/components/inspectors/multi-edit-utils.ts +49 -0
- package/src/components/inspectors/zod-fields.ts +184 -0
- package/src/components/primitives/ColorInput.tsx +109 -0
- package/src/components/primitives/JsonInput.tsx +98 -0
- package/src/components/primitives/NumberInput.tsx +164 -0
- package/src/components/primitives/Panel.tsx +68 -0
- package/src/components/primitives/SectionHeader.tsx +45 -0
- package/src/components/primitives/Tooltip.tsx +82 -0
- package/src/components/primitives/Vec3Input.tsx +62 -0
- package/src/components/world-overlay-gestures.ts +1438 -0
- package/src/doctor/data-checks.ts +285 -0
- package/src/doctor/report.ts +386 -0
- package/src/editor-api.ts +700 -0
- package/src/editor-console.ts +194 -0
- package/src/editor-hotkeys.ts +441 -0
- package/src/editor-layers.ts +2 -0
- package/src/editor-mode.ts +28 -0
- package/src/editor-store.ts +2225 -0
- package/src/editor-viewport.ts +1924 -0
- package/src/entity-factory.ts +221 -0
- package/src/game-globals-prelude.ts +27 -0
- package/src/gated-globals.ts +131 -0
- package/src/generated/setup-by-example.generated.ts +53 -0
- package/src/gizmo-registry.ts +608 -0
- package/src/handle-system.ts +221 -0
- package/src/hierarchy-menu-registry.ts +70 -0
- package/src/hierarchy-rows.ts +73 -0
- package/src/hosted-example.ts +160 -0
- package/src/hotkeys.ts +142 -0
- package/src/ingest/discovery-react.ts +132 -0
- package/src/ingest/discovery.ts +205 -0
- package/src/ingest/discovery2d.ts +204 -0
- package/src/ingest/esm-entry-resolution.ts +102 -0
- package/src/ingest/games/bloom-composer/game.js +99 -0
- package/src/ingest/games/bloom-composer/vgai.game.json +21 -0
- package/src/ingest/games/embed-bundle/embed.html +10 -0
- package/src/ingest/games/embed-bundle/vgai.game.json +21 -0
- package/src/ingest/games/games-fps/assets/collision-world.glb +0 -0
- package/src/ingest/games/games-fps/game.js +479 -0
- package/src/ingest/games/games-fps/vgai.game.json +24 -0
- package/src/ingest/games/iframe-reachable/game-source.js +58 -0
- package/src/ingest/games/iframe-reachable/vgai.game.json +21 -0
- package/src/ingest/games/interactive-cubes/game.js +139 -0
- package/src/ingest/games/interactive-cubes/vgai.game.json +21 -0
- package/src/ingest/games/mismatched-three/fake-three.js +38 -0
- package/src/ingest/games/mismatched-three/game.js +10 -0
- package/src/ingest/games/mismatched-three/vgai.game.json +22 -0
- package/src/ingest/games/own-three-bundled/game.js +43 -0
- package/src/ingest/games/own-three-bundled/vgai.game.json +21 -0
- package/src/ingest/games/pointerlock-maze/game.js +288 -0
- package/src/ingest/games/pointerlock-maze/vgai.game.json +22 -0
- package/src/ingest/games-2d/_fixtures/first-party-scene.scn2d.json +124 -0
- package/src/ingest/games-2d/bubbo-bubbo/vgai.game.json +25 -0
- package/src/ingest/games-2d/bunnymark/game.ts +88 -0
- package/src/ingest/games-2d/bunnymark/vgai.game.json +21 -0
- package/src/ingest/games-2d/flappy/game.ts +148 -0
- package/src/ingest/games-2d/flappy/vgai.game.json +21 -0
- package/src/ingest/games-2d/flappy-pixi/vgai.game.json +25 -0
- package/src/ingest/games-2d/puzzling-potions/vgai.game.json +25 -0
- package/src/ingest/games-2d/tilemap-camera/game.ts +115 -0
- package/src/ingest/games-2d/tilemap-camera/vgai.game.json +21 -0
- package/src/ingest/games-react/react-rpg/entry.tsx +185 -0
- package/src/ingest/games-react/react-rpg/shims.d.ts +26 -0
- package/src/ingest/games-react/react-rpg/src/ui/game-state.tsx +129 -0
- package/src/ingest/games-react/react-rpg/vgai.game.json +21 -0
- package/src/ingest/host-namespace-registry.ts +196 -0
- package/src/ingest/types.ts +127 -0
- package/src/ingest-hierarchy-rows.ts +207 -0
- package/src/ingest-mode.ts +2092 -0
- package/src/ingest-siblings.ts +466 -0
- package/src/initial-scene.ts +194 -0
- package/src/inspector-section-registry.ts +117 -0
- package/src/interactive-edit-scope.ts +34 -0
- package/src/main.tsx +23 -0
- package/src/manifest-project.ts +43 -0
- package/src/model-thumbnail.ts +156 -0
- package/src/module-mode.ts +513 -0
- package/src/navmesh-handler.ts +94 -0
- package/src/packaged-runtime.ts +49 -0
- package/src/play-mode.ts +1148 -0
- package/src/playground/main.ts +206 -0
- package/src/project-manager.ts +173 -0
- package/src/scene-diff.ts +112 -0
- package/src/scene-serializer.ts +144 -0
- package/src/scene-sync.ts +587 -0
- package/src/scene-ui-mode/active-scene-ui.ts +58 -0
- package/src/scene-ui-mode/scene-ui-palette-panel.tsx +152 -0
- package/src/scene-ui-mode/scene-ui-timeline-tab.tsx +29 -0
- package/src/scene-ui-mode/ui-prefab-dialog-host.tsx +74 -0
- package/src/scene-ui-mode/ui-prefab-hierarchy-menu.ts +49 -0
- package/src/scene-ui-mode/ui-prefab-io.ts +76 -0
- package/src/script-loader.ts +143 -0
- package/src/storage/fsa-storage.ts +55 -0
- package/src/storage/handle-storage.ts +150 -0
- package/src/storage/handle-store.ts +116 -0
- package/src/storage/http-storage.ts +137 -0
- package/src/storage/index.ts +147 -0
- package/src/storage/mem-storage.ts +135 -0
- package/src/storage/opfs-storage.ts +25 -0
- package/src/storage/paths.ts +26 -0
- package/src/storage/seed.ts +106 -0
- package/src/storage/types.ts +110 -0
- package/src/tool-loader.ts +291 -0
- package/src/ui-editor/inspector.tsx +563 -0
- package/src/ui-editor/node-ops.ts +266 -0
- package/src/ui-editor/overlay.tsx +380 -0
- package/src/ui-editor/palette.tsx +114 -0
- package/src/ui-editor/react-store.ts +78 -0
- package/src/ui-editor/timeline-panel.tsx +443 -0
- package/src/ui-editor/ui-edit-store.ts +552 -0
- package/src/ui-editor/ui-prefab.ts +95 -0
- package/src/ui-source/inspect.ts +544 -0
- package/src/ui-source/oid-transform.ts +133 -0
- package/src/ui-source/source-write-backend.ts +203 -0
- package/src/ui-source/tailwind-map.ts +174 -0
- package/src/ui-source/writer.ts +1175 -0
- package/src/widgets/index.ts +73 -0
- package/template/.claude/skills/editor/SKILL.md +252 -0
- package/template/CLAUDE.md +512 -0
- package/template/LICENSE +30 -0
- package/template/emit-schemas.ts +42 -0
- package/template/index.html +17 -0
- package/template/package.json +53 -0
- package/template/project.json +9 -0
- package/template/public/audio/ambient-arena.wav +0 -0
- package/template/public/audio/ambient-music.wav +0 -0
- package/template/public/audio/ambient-nature.wav +0 -0
- package/template/public/audio/ambient-wind.wav +0 -0
- package/template/public/inputmaps/default.inputmap.json +41 -0
- package/template/public/jsm/libs/draco/gltf/draco_decoder.js +33 -0
- package/template/public/jsm/libs/draco/gltf/draco_decoder.wasm +0 -0
- package/template/public/jsm/libs/draco/gltf/draco_encoder.js +33 -0
- package/template/public/jsm/libs/draco/gltf/draco_wasm_wrapper.js +116 -0
- package/template/public/scenes/default.vscn.json +43 -0
- package/template/public/scenes/untitled.vscn.json +29 -0
- package/template/public/textures/waternormals.jpg +0 -0
- package/template/server/colyseus-setup.ts +85 -0
- package/template/server/main.ts +34 -0
- package/template/server/rooms/arena-room.ts +420 -0
- package/template/server/rooms/game-room.ts +162 -0
- package/template/server/rooms.ts +15 -0
- package/template/server/tsconfig.json +19 -0
- package/template/src/data/README.md +40 -0
- package/template/src/data/assets.ts +31 -0
- package/template/src/data/tuning.data.json +5 -0
- package/template/src/data/tuning.schema.json +21 -0
- package/template/src/data/tuning.schema.ts +34 -0
- package/template/src/data/tuning.ts +24 -0
- package/template/src/main.ts +157 -0
- package/template/src/scripts/components/data-spinner.ts +45 -0
- package/template/src/scripts/components/scene-camera.ts +40 -0
- package/template/src/scripts/main.ts +94 -0
- package/template/src/scripts/registry.ts +46 -0
- package/template/src/tools/README.md +14 -0
- package/template/src/tools/example.tool.tsx +91 -0
- package/template/src/tools/spin.tool.tsx +101 -0
- package/template/src/ui/Button.tsx +27 -0
- package/template/src/ui/DefaultHud.tsx +40 -0
- package/template/src/ui/KeyHint.tsx +25 -0
- package/template/src/ui/Panel.tsx +52 -0
- package/template/src/ui/RebindPanel.tsx +129 -0
- package/template/src/ui/Slider.tsx +28 -0
- package/template/src/ui/StatusDot.tsx +22 -0
- package/template/src/ui/Toggle.tsx +19 -0
- package/template/src/ui/game-state.tsx +37 -0
- package/template/src/ui/index.ts +7 -0
- package/template/src/ui/mount-default-hud.tsx +19 -0
- package/template/src/ui/mount-ui.ts +15 -0
- package/template/tsconfig.json +36 -0
- package/template/validate-asset-content.ts +78 -0
- package/template/validate-manifest.ts +55 -0
- package/template/validate-scenes.ts +211 -0
- package/template/vgai.game.json +21 -0
- package/template/vite.config.ts +128 -0
- package/vite-plugin-example-assets.ts +60 -0
- package/vite-plugin-game-globals.ts +46 -0
- package/vite-plugin-game-static.ts +71 -0
- package/vite-plugin-project-game-static.ts +84 -0
- package/vite-plugin-react-game-static.ts +98 -0
- package/vite-plugin-react-world-provider.ts +81 -0
- package/vite-plugin-react-world-runtime.ts +76 -0
- package/vite-plugin-ui-oid.ts +561 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"manifestVersion": 1,
|
|
3
|
+
"name": "pmndrs/racing-game (vendored bundle)",
|
|
4
|
+
"version": "0.1.0",
|
|
5
|
+
"engine": {
|
|
6
|
+
"version": "0.1.0"
|
|
7
|
+
},
|
|
8
|
+
"worlds": [
|
|
9
|
+
{
|
|
10
|
+
"id": "racing-game",
|
|
11
|
+
"kind": "threejs",
|
|
12
|
+
"description": "REAL, UNMODIFIED marquee game (pmndrs/racing-game — React 18 + @react-three/fiber + three r0.139) ingested at the zero-source-diff bar. See UPSTREAM.md. Mounted today via the dedicated marquee-proof.html capture harness, not the generic resolver (docs/CLI-ON-FOLDER-DESIGN.md §1H — a stretch goal, not this manifest's job).",
|
|
13
|
+
"adapter": {
|
|
14
|
+
"ingest": {
|
|
15
|
+
"strategy": "iframe-reachable"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
]
|
|
20
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# dgreenheck/simcity-threejs-clone — vendored bundle (scale ingest #2)
|
|
2
|
+
|
|
3
|
+
A REAL, UNMODIFIED single-player three.js game ingested through the VGAI adapter
|
|
4
|
+
primitives, at the zero-source-diff bar. Second structurally-different game (after
|
|
5
|
+
pmndrs/racing-game) proving the approach scales.
|
|
6
|
+
|
|
7
|
+
## Upstream
|
|
8
|
+
|
|
9
|
+
- Repo: https://github.com/dgreenheck/simcity-threejs-clone
|
|
10
|
+
- Commit: **`9116cf680f677c3476f8159d5bbc7a4cfda00654`**
|
|
11
|
+
- Stack: **vanilla three.js r0.155** (no React), Vite, GLTFLoader (three/addons), single-player
|
|
12
|
+
- License: **MIT** — see the upstream `LICENSE`.
|
|
13
|
+
|
|
14
|
+
## Zero source diff (the bar) — reproducible, not asserted
|
|
15
|
+
|
|
16
|
+
Game `src/` is byte-for-byte upstream. Run `scripts/verify-unmodified-ingest.sh simcity`:
|
|
17
|
+
it clones the pinned upstream (the commit SHA is a cryptographic hash of the exact source
|
|
18
|
+
tree) and sha256-checks the vendored assets + the game's own three module against it →
|
|
19
|
+
`RESULT: PASS`. No game file was edited.
|
|
20
|
+
|
|
21
|
+
## Build (host-supplied — no game edits)
|
|
22
|
+
|
|
23
|
+
Built by the game's OWN Vite (v4.4.9) with one host-supplied externalization:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
root: './src', base: '/ingest/simcity/'
|
|
27
|
+
external: (id) => id === 'three'
|
|
28
|
+
output.paths: { three: '/ingest/simcity/three-r155.module.js' }
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
So the bundle's `import … from "three"` becomes `import … from "/ingest/simcity/three-r155.module.js"` —
|
|
32
|
+
self-resolving three to the vendored r155 module, no importmap.
|
|
33
|
+
|
|
34
|
+
## Vendored files
|
|
35
|
+
|
|
36
|
+
| File | What |
|
|
37
|
+
|---|---|
|
|
38
|
+
| `index.js` | the built bundle (artifact of the unmodified source) |
|
|
39
|
+
| `three-r155.module.js` | the game's OWN three (r0.155) — its native renderer |
|
|
40
|
+
| `models/` (42) | ONLY the models the game's `assets/models.js` catalog references (the other ~217 glb files in upstream are never requested by the game) — upstream-verbatim |
|
|
41
|
+
| `textures/`, `icons/`, `fonts/`, `statusIcons/` | upstream assets, verbatim |
|
|
42
|
+
| `index.html`, `main.css` | upstream DOM + styles (the harness reuses the DOM) |
|
|
43
|
+
|
|
44
|
+
## How it is hosted (through the adapter)
|
|
45
|
+
|
|
46
|
+
`/simcity-proof.html` + `/simcity-proof.ts` (served by the editor's own Vite):
|
|
47
|
+
|
|
48
|
+
1. import the served r155 module into the page realm,
|
|
49
|
+
2. install the **engine `installSceneCapture`** render-accessor trap on it,
|
|
50
|
+
3. install a `DefaultLoadingManager` URL modifier redirecting the game's original
|
|
51
|
+
`/simcity-threejs-clone/...` asset paths to the served bundle dir,
|
|
52
|
+
4. append the unmodified bundle; it gates render on `window.onload` + its AssetManager
|
|
53
|
+
loading every catalog model, so the harness fires `onload` once the module executes,
|
|
54
|
+
5. wait for the scene to settle, then author the live `Object3D` tree through the editor
|
|
55
|
+
`IngestAuthoringAdapter`,
|
|
56
|
+
6. recolor + move a live mesh (a terrain `tile-plain_grass`) through the adapter.
|
|
57
|
+
|
|
58
|
+
Proven by `packages/editor/e2e/tests/15-ingest-simcity.spec.ts` (rev 155, ~257 meshes
|
|
59
|
+
captured, live recolor `#ff2090` + move, recorded screenshot, zero errors). PASSES.
|
|
60
|
+
|
|
61
|
+
### Single-realm rationale
|
|
62
|
+
|
|
63
|
+
Same as racing-game: a bundle pinned to a non-host three runs single-realm on its OWN
|
|
64
|
+
served three (the trap + adapter are type-only over three → version-agnostic), sidestepping
|
|
65
|
+
the editor-r170 renderer/cross-realm walls. See racing-game/UPSTREAM.md.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
|
|
4
|
+
<head>
|
|
5
|
+
<meta charset="utf-8">
|
|
6
|
+
<link rel="stylesheet" href="/ingest/simcity/main.css">
|
|
7
|
+
<link rel="icon" type="image/x-icon" href="/ingest/simcity/favicon.ico">
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
<script type="module" crossorigin src="/ingest/simcity/index.js"></script>
|
|
11
|
+
</head>
|
|
12
|
+
|
|
13
|
+
<body>
|
|
14
|
+
<div id="root-window">
|
|
15
|
+
<!-- Three.js adds a `canvas` element to this element-->
|
|
16
|
+
<div id="render-target"></div>
|
|
17
|
+
<div id="loading" class="text-overlay">
|
|
18
|
+
<div>
|
|
19
|
+
LOADING...
|
|
20
|
+
</div>
|
|
21
|
+
</div>
|
|
22
|
+
<div id="paused-text" class="text-overlay" style="visibility: hidden;">
|
|
23
|
+
<div>
|
|
24
|
+
PAUSED
|
|
25
|
+
</div>
|
|
26
|
+
</div>
|
|
27
|
+
<div id="ui">
|
|
28
|
+
<div id="title-bar">
|
|
29
|
+
<div class="title-bar-left-items title-bar-items">
|
|
30
|
+
$1000
|
|
31
|
+
</div>
|
|
32
|
+
<div class="title-bar-center-items title-bar-items">
|
|
33
|
+
<span id="city-name">My City</span>
|
|
34
|
+
<span> - </span>
|
|
35
|
+
<span id="sim-time">1/1/2023</span>
|
|
36
|
+
</div>
|
|
37
|
+
<div class="title-bar-right-items title-bar-items">
|
|
38
|
+
<img id="population-icon" src="/ingest/simcity/icons/person.png">
|
|
39
|
+
<span id="population-counter">0</span>
|
|
40
|
+
</div>
|
|
41
|
+
</div>
|
|
42
|
+
<div id="ui-toolbar" class="container">
|
|
43
|
+
<button id='button-select' class="ui-button selected" data-type="select"
|
|
44
|
+
onclick="ui.onToolSelected(event)">
|
|
45
|
+
<img class="toolbar-icon" src="/ingest/simcity/icons/select-color.png">
|
|
46
|
+
</button>
|
|
47
|
+
<button id='button-bulldoze' class="ui-button" data-type="bulldoze"
|
|
48
|
+
onclick="ui.onToolSelected(event)">
|
|
49
|
+
<img class="toolbar-icon" src="/ingest/simcity/icons/bulldozer-color.png">
|
|
50
|
+
</button>
|
|
51
|
+
<button id='button-residential' class="ui-button" data-type="residential"
|
|
52
|
+
onclick="ui.onToolSelected(event)">
|
|
53
|
+
<img class="toolbar-icon" src="/ingest/simcity/icons/house-color.png">
|
|
54
|
+
</button>
|
|
55
|
+
<button id='button-commercial' class="ui-button" data-type="commercial"
|
|
56
|
+
onclick="ui.onToolSelected(event)">
|
|
57
|
+
<img class="toolbar-icon" src="/ingest/simcity/icons/store-color.png">
|
|
58
|
+
</button>
|
|
59
|
+
<button id='button-industrial' class="ui-button" data-type="industrial"
|
|
60
|
+
onclick="ui.onToolSelected(event)">
|
|
61
|
+
<img class="toolbar-icon" src="/ingest/simcity/icons/factory-color.png">
|
|
62
|
+
</button>
|
|
63
|
+
<button id='button-road' class="ui-button" data-type="road"
|
|
64
|
+
onclick="ui.onToolSelected(event)">
|
|
65
|
+
<img class="toolbar-icon" src="/ingest/simcity/icons/road-color.png">
|
|
66
|
+
</button>
|
|
67
|
+
<button id='button-power-plant' class="ui-button" data-type="power-plant"
|
|
68
|
+
onclick="ui.onToolSelected(event)">
|
|
69
|
+
<img class="toolbar-icon" src="/ingest/simcity/icons/power-color.png">
|
|
70
|
+
</button>
|
|
71
|
+
<button id='button-power-line' class="ui-button" data-type="power-line"
|
|
72
|
+
onclick="ui.onToolSelected(event)">
|
|
73
|
+
<img class="toolbar-icon" src="/ingest/simcity/icons/power-line-color.png">
|
|
74
|
+
</button>
|
|
75
|
+
<button id='button-pause' class="ui-button" onclick="ui.togglePause()">
|
|
76
|
+
<img id='pause-button-icon' class="toolbar-icon" src="/ingest/simcity/icons/pause-color.png">
|
|
77
|
+
</button>
|
|
78
|
+
</div>
|
|
79
|
+
<div id="info-panel" class="container">
|
|
80
|
+
</div>
|
|
81
|
+
<div id="instructions">
|
|
82
|
+
INTERACT - Left Mouse<br>
|
|
83
|
+
ROTATE - Right Mouse<br>
|
|
84
|
+
PAN - Control + Right Mouse<br>
|
|
85
|
+
ZOOM - Scroll
|
|
86
|
+
</div>
|
|
87
|
+
<div id="version">
|
|
88
|
+
v0.3.0
|
|
89
|
+
</div>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
</body>
|
|
93
|
+
|
|
94
|
+
</html>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
var Xt=Object.defineProperty;var $t=(l,t,e)=>t in l?Xt(l,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):l[t]=e;var A=(l,t,e)=>($t(l,typeof t!="symbol"?t+"":t,e),e),Ge=(l,t,e)=>{if(!t.has(l))throw TypeError("Cannot "+e)};var g=(l,t,e)=>(Ge(l,t,"read from private field"),e?e.call(l):t.get(l)),L=(l,t,e)=>{if(t.has(l))throw TypeError("Cannot add the same private member more than once");t instanceof WeakSet?t.add(l):t.set(l,e)},D=(l,t,e,s)=>(Ge(l,t,"write to private field"),s?s.call(l,e):t.set(l,e),e);var ze=(l,t,e,s)=>({set _(i){D(l,t,i,e)},get _(){return g(l,t,s)}}),M=(l,t,e)=>(Ge(l,t,"access private method"),e);import*as p from"/ingest/simcity/three-r155.module.js";import{TrianglesDrawMode as qt,TriangleFanDrawMode as $e,TriangleStripDrawMode as Rt,Loader as Yt,LoaderUtils as qe,FileLoader as Et,Color as ce,SpotLight as Jt,PointLight as Qt,DirectionalLight as Zt,MeshBasicMaterial as we,SRGBColorSpace as be,MeshPhysicalMaterial as Z,Vector2 as Lt,Matrix4 as Le,Vector3 as de,Quaternion as St,InstancedMesh as es,Object3D as vt,TextureLoader as ts,ImageBitmapLoader as ss,BufferAttribute as je,InterleavedBuffer as is,InterleavedBufferAttribute as ns,LinearFilter as _t,LinearMipmapLinearFilter as It,RepeatWrapping as Ye,PointsMaterial as os,Material as Ve,LineBasicMaterial as rs,MeshStandardMaterial as Nt,DoubleSide as as,PropertyBinding as cs,BufferGeometry as ls,SkinnedMesh as hs,Mesh as us,LineSegments as ds,Line as fs,LineLoop as ps,Points as ms,Group as Ue,PerspectiveCamera as gs,MathUtils as ws,OrthographicCamera as Ts,Skeleton as As,AnimationClip as bs,Bone as ys,InterpolateLinear as Ct,NearestFilter as Ms,NearestMipmapNearestFilter as xs,LinearMipmapNearestFilter as Rs,NearestMipmapLinearFilter as Es,ClampToEdgeWrapping as Ls,MirroredRepeatWrapping as Ss,InterpolateDiscrete as vs,FrontSide as _s,Texture as nt,VectorKeyframeTrack as ot,NumberKeyframeTrack as rt,QuaternionKeyframeTrack as at,Box3 as Is,Sphere as Ns,Interpolant as Cs}from"/ingest/simcity/three-r155.module.js";(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const i of document.querySelectorAll('link[rel="modulepreload"]'))s(i);new MutationObserver(i=>{for(const n of i)if(n.type==="childList")for(const o of n.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&s(o)}).observe(document,{childList:!0,subtree:!0});function e(i){const n={};return i.integrity&&(n.integrity=i.integrity),i.referrerPolicy&&(n.referrerPolicy=i.referrerPolicy),i.crossOrigin==="use-credentials"?n.credentials="include":i.crossOrigin==="anonymous"?n.credentials="omit":n.credentials="same-origin",n}function s(i){if(i.ep)return;i.ep=!0;const n=e(i);fetch(i.href,n)}})();function ct(l,t){if(t===qt)return console.warn("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Geometry already defined as triangles."),l;if(t===$e||t===Rt){let e=l.getIndex();if(e===null){const o=[],a=l.getAttribute("position");if(a!==void 0){for(let r=0;r<a.count;r++)o.push(r);l.setIndex(o),e=l.getIndex()}else return console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Undefined position attribute. Processing not possible."),l}const s=e.count-2,i=[];if(t===$e)for(let o=1;o<=s;o++)i.push(e.getX(0)),i.push(e.getX(o)),i.push(e.getX(o+1));else for(let o=0;o<s;o++)o%2===0?(i.push(e.getX(o)),i.push(e.getX(o+1)),i.push(e.getX(o+2))):(i.push(e.getX(o+2)),i.push(e.getX(o+1)),i.push(e.getX(o)));i.length/3!==s&&console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unable to generate correct amount of triangles.");const n=l.clone();return n.setIndex(i),n.clearGroups(),n}else return console.error("THREE.BufferGeometryUtils.toTrianglesDrawMode(): Unknown draw mode:",t),l}class Os extends Yt{constructor(t){super(t),this.dracoLoader=null,this.ktx2Loader=null,this.meshoptDecoder=null,this.pluginCallbacks=[],this.register(function(e){return new Bs(e)}),this.register(function(e){return new Ks(e)}),this.register(function(e){return new Xs(e)}),this.register(function(e){return new $s(e)}),this.register(function(e){return new Gs(e)}),this.register(function(e){return new zs(e)}),this.register(function(e){return new js(e)}),this.register(function(e){return new Vs(e)}),this.register(function(e){return new Hs(e)}),this.register(function(e){return new Us(e)}),this.register(function(e){return new Fs(e)}),this.register(function(e){return new Ws(e)}),this.register(function(e){return new Ds(e)}),this.register(function(e){return new qs(e)}),this.register(function(e){return new Ys(e)})}load(t,e,s,i){const n=this;let o;this.resourcePath!==""?o=this.resourcePath:this.path!==""?o=this.path:o=qe.extractUrlBase(t),this.manager.itemStart(t);const a=function(c){i?i(c):console.error(c),n.manager.itemError(t),n.manager.itemEnd(t)},r=new Et(this.manager);r.setPath(this.path),r.setResponseType("arraybuffer"),r.setRequestHeader(this.requestHeader),r.setWithCredentials(this.withCredentials),r.load(t,function(c){try{n.parse(c,o,function(u){e(u),n.manager.itemEnd(t)},a)}catch(u){a(u)}},s,a)}setDRACOLoader(t){return this.dracoLoader=t,this}setDDSLoader(){throw new Error('THREE.GLTFLoader: "MSFT_texture_dds" no longer supported. Please update to "KHR_texture_basisu".')}setKTX2Loader(t){return this.ktx2Loader=t,this}setMeshoptDecoder(t){return this.meshoptDecoder=t,this}register(t){return this.pluginCallbacks.indexOf(t)===-1&&this.pluginCallbacks.push(t),this}unregister(t){return this.pluginCallbacks.indexOf(t)!==-1&&this.pluginCallbacks.splice(this.pluginCallbacks.indexOf(t),1),this}parse(t,e,s,i){let n;const o={},a={},r=new TextDecoder;if(typeof t=="string")n=JSON.parse(t);else if(t instanceof ArrayBuffer)if(r.decode(new Uint8Array(t,0,4))===Ot){try{o[R.KHR_BINARY_GLTF]=new Js(t)}catch(h){i&&i(h);return}n=JSON.parse(o[R.KHR_BINARY_GLTF].content)}else n=JSON.parse(r.decode(t));else n=t;if(n.asset===void 0||n.asset.version[0]<2){i&&i(new Error("THREE.GLTFLoader: Unsupported asset. glTF versions >=2.0 are supported."));return}const c=new hi(n,{path:e||this.resourcePath||"",crossOrigin:this.crossOrigin,requestHeader:this.requestHeader,manager:this.manager,ktx2Loader:this.ktx2Loader,meshoptDecoder:this.meshoptDecoder});c.fileLoader.setRequestHeader(this.requestHeader);for(let u=0;u<this.pluginCallbacks.length;u++){const h=this.pluginCallbacks[u](c);a[h.name]=h,o[h.name]=!0}if(n.extensionsUsed)for(let u=0;u<n.extensionsUsed.length;++u){const h=n.extensionsUsed[u],d=n.extensionsRequired||[];switch(h){case R.KHR_MATERIALS_UNLIT:o[h]=new ks;break;case R.KHR_DRACO_MESH_COMPRESSION:o[h]=new Qs(n,this.dracoLoader);break;case R.KHR_TEXTURE_TRANSFORM:o[h]=new Zs;break;case R.KHR_MESH_QUANTIZATION:o[h]=new ei;break;default:d.indexOf(h)>=0&&a[h]===void 0&&console.warn('THREE.GLTFLoader: Unknown extension "'+h+'".')}}c.setExtensions(o),c.setPlugins(a),c.parse(s,i)}parseAsync(t,e){const s=this;return new Promise(function(i,n){s.parse(t,e,i,n)})}}function Ps(){let l={};return{get:function(t){return l[t]},add:function(t,e){l[t]=e},remove:function(t){delete l[t]},removeAll:function(){l={}}}}const R={KHR_BINARY_GLTF:"KHR_binary_glTF",KHR_DRACO_MESH_COMPRESSION:"KHR_draco_mesh_compression",KHR_LIGHTS_PUNCTUAL:"KHR_lights_punctual",KHR_MATERIALS_CLEARCOAT:"KHR_materials_clearcoat",KHR_MATERIALS_IOR:"KHR_materials_ior",KHR_MATERIALS_SHEEN:"KHR_materials_sheen",KHR_MATERIALS_SPECULAR:"KHR_materials_specular",KHR_MATERIALS_TRANSMISSION:"KHR_materials_transmission",KHR_MATERIALS_IRIDESCENCE:"KHR_materials_iridescence",KHR_MATERIALS_ANISOTROPY:"KHR_materials_anisotropy",KHR_MATERIALS_UNLIT:"KHR_materials_unlit",KHR_MATERIALS_VOLUME:"KHR_materials_volume",KHR_TEXTURE_BASISU:"KHR_texture_basisu",KHR_TEXTURE_TRANSFORM:"KHR_texture_transform",KHR_MESH_QUANTIZATION:"KHR_mesh_quantization",KHR_MATERIALS_EMISSIVE_STRENGTH:"KHR_materials_emissive_strength",EXT_TEXTURE_WEBP:"EXT_texture_webp",EXT_TEXTURE_AVIF:"EXT_texture_avif",EXT_MESHOPT_COMPRESSION:"EXT_meshopt_compression",EXT_MESH_GPU_INSTANCING:"EXT_mesh_gpu_instancing"};class Ds{constructor(t){this.parser=t,this.name=R.KHR_LIGHTS_PUNCTUAL,this.cache={refs:{},uses:{}}}_markDefs(){const t=this.parser,e=this.parser.json.nodes||[];for(let s=0,i=e.length;s<i;s++){const n=e[s];n.extensions&&n.extensions[this.name]&&n.extensions[this.name].light!==void 0&&t._addNodeRef(this.cache,n.extensions[this.name].light)}}_loadLight(t){const e=this.parser,s="light:"+t;let i=e.cache.get(s);if(i)return i;const n=e.json,r=((n.extensions&&n.extensions[this.name]||{}).lights||[])[t];let c;const u=new ce(16777215);r.color!==void 0&&u.fromArray(r.color);const h=r.range!==void 0?r.range:0;switch(r.type){case"directional":c=new Zt(u),c.target.position.set(0,0,-1),c.add(c.target);break;case"point":c=new Qt(u),c.distance=h;break;case"spot":c=new Jt(u),c.distance=h,r.spot=r.spot||{},r.spot.innerConeAngle=r.spot.innerConeAngle!==void 0?r.spot.innerConeAngle:0,r.spot.outerConeAngle=r.spot.outerConeAngle!==void 0?r.spot.outerConeAngle:Math.PI/4,c.angle=r.spot.outerConeAngle,c.penumbra=1-r.spot.innerConeAngle/r.spot.outerConeAngle,c.target.position.set(0,0,-1),c.add(c.target);break;default:throw new Error("THREE.GLTFLoader: Unexpected light type: "+r.type)}return c.position.set(0,0,0),c.decay=2,q(c,r),r.intensity!==void 0&&(c.intensity=r.intensity),c.name=e.createUniqueName(r.name||"light_"+t),i=Promise.resolve(c),e.cache.add(s,i),i}getDependency(t,e){if(t==="light")return this._loadLight(e)}createNodeAttachment(t){const e=this,s=this.parser,n=s.json.nodes[t],a=(n.extensions&&n.extensions[this.name]||{}).light;return a===void 0?null:this._loadLight(a).then(function(r){return s._getNodeRef(e.cache,a,r)})}}class ks{constructor(){this.name=R.KHR_MATERIALS_UNLIT}getMaterialType(){return we}extendParams(t,e,s){const i=[];t.color=new ce(1,1,1),t.opacity=1;const n=e.pbrMetallicRoughness;if(n){if(Array.isArray(n.baseColorFactor)){const o=n.baseColorFactor;t.color.fromArray(o),t.opacity=o[3]}n.baseColorTexture!==void 0&&i.push(s.assignTexture(t,"map",n.baseColorTexture,be))}return Promise.all(i)}}class Hs{constructor(t){this.parser=t,this.name=R.KHR_MATERIALS_EMISSIVE_STRENGTH}extendMaterialParams(t,e){const i=this.parser.json.materials[t];if(!i.extensions||!i.extensions[this.name])return Promise.resolve();const n=i.extensions[this.name].emissiveStrength;return n!==void 0&&(e.emissiveIntensity=n),Promise.resolve()}}class Bs{constructor(t){this.parser=t,this.name=R.KHR_MATERIALS_CLEARCOAT}getMaterialType(t){const s=this.parser.json.materials[t];return!s.extensions||!s.extensions[this.name]?null:Z}extendMaterialParams(t,e){const s=this.parser,i=s.json.materials[t];if(!i.extensions||!i.extensions[this.name])return Promise.resolve();const n=[],o=i.extensions[this.name];if(o.clearcoatFactor!==void 0&&(e.clearcoat=o.clearcoatFactor),o.clearcoatTexture!==void 0&&n.push(s.assignTexture(e,"clearcoatMap",o.clearcoatTexture)),o.clearcoatRoughnessFactor!==void 0&&(e.clearcoatRoughness=o.clearcoatRoughnessFactor),o.clearcoatRoughnessTexture!==void 0&&n.push(s.assignTexture(e,"clearcoatRoughnessMap",o.clearcoatRoughnessTexture)),o.clearcoatNormalTexture!==void 0&&(n.push(s.assignTexture(e,"clearcoatNormalMap",o.clearcoatNormalTexture)),o.clearcoatNormalTexture.scale!==void 0)){const a=o.clearcoatNormalTexture.scale;e.clearcoatNormalScale=new Lt(a,a)}return Promise.all(n)}}class Fs{constructor(t){this.parser=t,this.name=R.KHR_MATERIALS_IRIDESCENCE}getMaterialType(t){const s=this.parser.json.materials[t];return!s.extensions||!s.extensions[this.name]?null:Z}extendMaterialParams(t,e){const s=this.parser,i=s.json.materials[t];if(!i.extensions||!i.extensions[this.name])return Promise.resolve();const n=[],o=i.extensions[this.name];return o.iridescenceFactor!==void 0&&(e.iridescence=o.iridescenceFactor),o.iridescenceTexture!==void 0&&n.push(s.assignTexture(e,"iridescenceMap",o.iridescenceTexture)),o.iridescenceIor!==void 0&&(e.iridescenceIOR=o.iridescenceIor),e.iridescenceThicknessRange===void 0&&(e.iridescenceThicknessRange=[100,400]),o.iridescenceThicknessMinimum!==void 0&&(e.iridescenceThicknessRange[0]=o.iridescenceThicknessMinimum),o.iridescenceThicknessMaximum!==void 0&&(e.iridescenceThicknessRange[1]=o.iridescenceThicknessMaximum),o.iridescenceThicknessTexture!==void 0&&n.push(s.assignTexture(e,"iridescenceThicknessMap",o.iridescenceThicknessTexture)),Promise.all(n)}}class Gs{constructor(t){this.parser=t,this.name=R.KHR_MATERIALS_SHEEN}getMaterialType(t){const s=this.parser.json.materials[t];return!s.extensions||!s.extensions[this.name]?null:Z}extendMaterialParams(t,e){const s=this.parser,i=s.json.materials[t];if(!i.extensions||!i.extensions[this.name])return Promise.resolve();const n=[];e.sheenColor=new ce(0,0,0),e.sheenRoughness=0,e.sheen=1;const o=i.extensions[this.name];return o.sheenColorFactor!==void 0&&e.sheenColor.fromArray(o.sheenColorFactor),o.sheenRoughnessFactor!==void 0&&(e.sheenRoughness=o.sheenRoughnessFactor),o.sheenColorTexture!==void 0&&n.push(s.assignTexture(e,"sheenColorMap",o.sheenColorTexture,be)),o.sheenRoughnessTexture!==void 0&&n.push(s.assignTexture(e,"sheenRoughnessMap",o.sheenRoughnessTexture)),Promise.all(n)}}class zs{constructor(t){this.parser=t,this.name=R.KHR_MATERIALS_TRANSMISSION}getMaterialType(t){const s=this.parser.json.materials[t];return!s.extensions||!s.extensions[this.name]?null:Z}extendMaterialParams(t,e){const s=this.parser,i=s.json.materials[t];if(!i.extensions||!i.extensions[this.name])return Promise.resolve();const n=[],o=i.extensions[this.name];return o.transmissionFactor!==void 0&&(e.transmission=o.transmissionFactor),o.transmissionTexture!==void 0&&n.push(s.assignTexture(e,"transmissionMap",o.transmissionTexture)),Promise.all(n)}}class js{constructor(t){this.parser=t,this.name=R.KHR_MATERIALS_VOLUME}getMaterialType(t){const s=this.parser.json.materials[t];return!s.extensions||!s.extensions[this.name]?null:Z}extendMaterialParams(t,e){const s=this.parser,i=s.json.materials[t];if(!i.extensions||!i.extensions[this.name])return Promise.resolve();const n=[],o=i.extensions[this.name];e.thickness=o.thicknessFactor!==void 0?o.thicknessFactor:0,o.thicknessTexture!==void 0&&n.push(s.assignTexture(e,"thicknessMap",o.thicknessTexture)),e.attenuationDistance=o.attenuationDistance||1/0;const a=o.attenuationColor||[1,1,1];return e.attenuationColor=new ce(a[0],a[1],a[2]),Promise.all(n)}}class Vs{constructor(t){this.parser=t,this.name=R.KHR_MATERIALS_IOR}getMaterialType(t){const s=this.parser.json.materials[t];return!s.extensions||!s.extensions[this.name]?null:Z}extendMaterialParams(t,e){const i=this.parser.json.materials[t];if(!i.extensions||!i.extensions[this.name])return Promise.resolve();const n=i.extensions[this.name];return e.ior=n.ior!==void 0?n.ior:1.5,Promise.resolve()}}class Us{constructor(t){this.parser=t,this.name=R.KHR_MATERIALS_SPECULAR}getMaterialType(t){const s=this.parser.json.materials[t];return!s.extensions||!s.extensions[this.name]?null:Z}extendMaterialParams(t,e){const s=this.parser,i=s.json.materials[t];if(!i.extensions||!i.extensions[this.name])return Promise.resolve();const n=[],o=i.extensions[this.name];e.specularIntensity=o.specularFactor!==void 0?o.specularFactor:1,o.specularTexture!==void 0&&n.push(s.assignTexture(e,"specularIntensityMap",o.specularTexture));const a=o.specularColorFactor||[1,1,1];return e.specularColor=new ce(a[0],a[1],a[2]),o.specularColorTexture!==void 0&&n.push(s.assignTexture(e,"specularColorMap",o.specularColorTexture,be)),Promise.all(n)}}class Ws{constructor(t){this.parser=t,this.name=R.KHR_MATERIALS_ANISOTROPY}getMaterialType(t){const s=this.parser.json.materials[t];return!s.extensions||!s.extensions[this.name]?null:Z}extendMaterialParams(t,e){const s=this.parser,i=s.json.materials[t];if(!i.extensions||!i.extensions[this.name])return Promise.resolve();const n=[],o=i.extensions[this.name];return o.anisotropyStrength!==void 0&&(e.anisotropy=o.anisotropyStrength),o.anisotropyRotation!==void 0&&(e.anisotropyRotation=o.anisotropyRotation),o.anisotropyTexture!==void 0&&n.push(s.assignTexture(e,"anisotropyMap",o.anisotropyTexture)),Promise.all(n)}}class Ks{constructor(t){this.parser=t,this.name=R.KHR_TEXTURE_BASISU}loadTexture(t){const e=this.parser,s=e.json,i=s.textures[t];if(!i.extensions||!i.extensions[this.name])return null;const n=i.extensions[this.name],o=e.options.ktx2Loader;if(!o){if(s.extensionsRequired&&s.extensionsRequired.indexOf(this.name)>=0)throw new Error("THREE.GLTFLoader: setKTX2Loader must be called before loading KTX2 textures");return null}return e.loadTextureImage(t,n.source,o)}}class Xs{constructor(t){this.parser=t,this.name=R.EXT_TEXTURE_WEBP,this.isSupported=null}loadTexture(t){const e=this.name,s=this.parser,i=s.json,n=i.textures[t];if(!n.extensions||!n.extensions[e])return null;const o=n.extensions[e],a=i.images[o.source];let r=s.textureLoader;if(a.uri){const c=s.options.manager.getHandler(a.uri);c!==null&&(r=c)}return this.detectSupport().then(function(c){if(c)return s.loadTextureImage(t,o.source,r);if(i.extensionsRequired&&i.extensionsRequired.indexOf(e)>=0)throw new Error("THREE.GLTFLoader: WebP required by asset but unsupported.");return s.loadTexture(t)})}detectSupport(){return this.isSupported||(this.isSupported=new Promise(function(t){const e=new Image;e.src="data:image/webp;base64,UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",e.onload=e.onerror=function(){t(e.height===1)}})),this.isSupported}}class $s{constructor(t){this.parser=t,this.name=R.EXT_TEXTURE_AVIF,this.isSupported=null}loadTexture(t){const e=this.name,s=this.parser,i=s.json,n=i.textures[t];if(!n.extensions||!n.extensions[e])return null;const o=n.extensions[e],a=i.images[o.source];let r=s.textureLoader;if(a.uri){const c=s.options.manager.getHandler(a.uri);c!==null&&(r=c)}return this.detectSupport().then(function(c){if(c)return s.loadTextureImage(t,o.source,r);if(i.extensionsRequired&&i.extensionsRequired.indexOf(e)>=0)throw new Error("THREE.GLTFLoader: AVIF required by asset but unsupported.");return s.loadTexture(t)})}detectSupport(){return this.isSupported||(this.isSupported=new Promise(function(t){const e=new Image;e.src="data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAABcAAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAEAAAABAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQAMAAAAABNjb2xybmNseAACAAIABoAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAAB9tZGF0EgAKCBgABogQEDQgMgkQAAAAB8dSLfI=",e.onload=e.onerror=function(){t(e.height===1)}})),this.isSupported}}class qs{constructor(t){this.name=R.EXT_MESHOPT_COMPRESSION,this.parser=t}loadBufferView(t){const e=this.parser.json,s=e.bufferViews[t];if(s.extensions&&s.extensions[this.name]){const i=s.extensions[this.name],n=this.parser.getDependency("buffer",i.buffer),o=this.parser.options.meshoptDecoder;if(!o||!o.supported){if(e.extensionsRequired&&e.extensionsRequired.indexOf(this.name)>=0)throw new Error("THREE.GLTFLoader: setMeshoptDecoder must be called before loading compressed files");return null}return n.then(function(a){const r=i.byteOffset||0,c=i.byteLength||0,u=i.count,h=i.byteStride,d=new Uint8Array(a,r,c);return o.decodeGltfBufferAsync?o.decodeGltfBufferAsync(u,h,d,i.mode,i.filter).then(function(f){return f.buffer}):o.ready.then(function(){const f=new ArrayBuffer(u*h);return o.decodeGltfBuffer(new Uint8Array(f),u,h,d,i.mode,i.filter),f})})}else return null}}class Ys{constructor(t){this.name=R.EXT_MESH_GPU_INSTANCING,this.parser=t}createNodeMesh(t){const e=this.parser.json,s=e.nodes[t];if(!s.extensions||!s.extensions[this.name]||s.mesh===void 0)return null;const i=e.meshes[s.mesh];for(const c of i.primitives)if(c.mode!==H.TRIANGLES&&c.mode!==H.TRIANGLE_STRIP&&c.mode!==H.TRIANGLE_FAN&&c.mode!==void 0)return null;const o=s.extensions[this.name].attributes,a=[],r={};for(const c in o)a.push(this.parser.getDependency("accessor",o[c]).then(u=>(r[c]=u,r[c])));return a.length<1?null:(a.push(this.parser.createNodeMesh(t)),Promise.all(a).then(c=>{const u=c.pop(),h=u.isGroup?u.children:[u],d=c[0].count,f=[];for(const m of h){const y=new Le,w=new de,b=new St,S=new de(1,1,1),N=new es(m.geometry,m.material,d);for(let E=0;E<d;E++)r.TRANSLATION&&w.fromBufferAttribute(r.TRANSLATION,E),r.ROTATION&&b.fromBufferAttribute(r.ROTATION,E),r.SCALE&&S.fromBufferAttribute(r.SCALE,E),N.setMatrixAt(E,y.compose(w,b,S));for(const E in r)E!=="TRANSLATION"&&E!=="ROTATION"&&E!=="SCALE"&&m.geometry.setAttribute(E,r[E]);vt.prototype.copy.call(N,m),this.parser.assignFinalMaterial(N),f.push(N)}return u.isGroup?(u.clear(),u.add(...f),u):f[0]}))}}const Ot="glTF",ge=12,lt={JSON:1313821514,BIN:5130562};class Js{constructor(t){this.name=R.KHR_BINARY_GLTF,this.content=null,this.body=null;const e=new DataView(t,0,ge),s=new TextDecoder;if(this.header={magic:s.decode(new Uint8Array(t.slice(0,4))),version:e.getUint32(4,!0),length:e.getUint32(8,!0)},this.header.magic!==Ot)throw new Error("THREE.GLTFLoader: Unsupported glTF-Binary header.");if(this.header.version<2)throw new Error("THREE.GLTFLoader: Legacy binary file detected.");const i=this.header.length-ge,n=new DataView(t,ge);let o=0;for(;o<i;){const a=n.getUint32(o,!0);o+=4;const r=n.getUint32(o,!0);if(o+=4,r===lt.JSON){const c=new Uint8Array(t,ge+o,a);this.content=s.decode(c)}else if(r===lt.BIN){const c=ge+o;this.body=t.slice(c,c+a)}o+=a}if(this.content===null)throw new Error("THREE.GLTFLoader: JSON content not found.")}}class Qs{constructor(t,e){if(!e)throw new Error("THREE.GLTFLoader: No DRACOLoader instance provided.");this.name=R.KHR_DRACO_MESH_COMPRESSION,this.json=t,this.dracoLoader=e,this.dracoLoader.preload()}decodePrimitive(t,e){const s=this.json,i=this.dracoLoader,n=t.extensions[this.name].bufferView,o=t.extensions[this.name].attributes,a={},r={},c={};for(const u in o){const h=Je[u]||u.toLowerCase();a[h]=o[u]}for(const u in t.attributes){const h=Je[u]||u.toLowerCase();if(o[u]!==void 0){const d=s.accessors[t.attributes[u]],f=fe[d.componentType];c[h]=f.name,r[h]=d.normalized===!0}}return e.getDependency("bufferView",n).then(function(u){return new Promise(function(h){i.decodeDracoFile(u,function(d){for(const f in d.attributes){const m=d.attributes[f],y=r[f];y!==void 0&&(m.normalized=y)}h(d)},a,c)})})}}class Zs{constructor(){this.name=R.KHR_TEXTURE_TRANSFORM}extendTexture(t,e){return(e.texCoord===void 0||e.texCoord===t.channel)&&e.offset===void 0&&e.rotation===void 0&&e.scale===void 0||(t=t.clone(),e.texCoord!==void 0&&(t.channel=e.texCoord),e.offset!==void 0&&t.offset.fromArray(e.offset),e.rotation!==void 0&&(t.rotation=e.rotation),e.scale!==void 0&&t.repeat.fromArray(e.scale),t.needsUpdate=!0),t}}class ei{constructor(){this.name=R.KHR_MESH_QUANTIZATION}}class Pt extends Cs{constructor(t,e,s,i){super(t,e,s,i)}copySampleValue_(t){const e=this.resultBuffer,s=this.sampleValues,i=this.valueSize,n=t*i*3+i;for(let o=0;o!==i;o++)e[o]=s[n+o];return e}interpolate_(t,e,s,i){const n=this.resultBuffer,o=this.sampleValues,a=this.valueSize,r=a*2,c=a*3,u=i-e,h=(s-e)/u,d=h*h,f=d*h,m=t*c,y=m-c,w=-2*f+3*d,b=f-d,S=1-w,N=b-d+h;for(let E=0;E!==a;E++){const V=o[y+E+a],F=o[y+E+r]*u,O=o[m+E+a],K=o[m+E]*u;n[E]=S*V+N*F+w*O+b*K}return n}}const ti=new St;class si extends Pt{interpolate_(t,e,s,i){const n=super.interpolate_(t,e,s,i);return ti.fromArray(n).normalize().toArray(n),n}}const H={FLOAT:5126,FLOAT_MAT3:35675,FLOAT_MAT4:35676,FLOAT_VEC2:35664,FLOAT_VEC3:35665,FLOAT_VEC4:35666,LINEAR:9729,REPEAT:10497,SAMPLER_2D:35678,POINTS:0,LINES:1,LINE_LOOP:2,LINE_STRIP:3,TRIANGLES:4,TRIANGLE_STRIP:5,TRIANGLE_FAN:6,UNSIGNED_BYTE:5121,UNSIGNED_SHORT:5123},fe={5120:Int8Array,5121:Uint8Array,5122:Int16Array,5123:Uint16Array,5125:Uint32Array,5126:Float32Array},ht={9728:Ms,9729:_t,9984:xs,9985:Rs,9986:Es,9987:It},ut={33071:Ls,33648:Ss,10497:Ye},We={SCALAR:1,VEC2:2,VEC3:3,VEC4:4,MAT2:4,MAT3:9,MAT4:16},Je={POSITION:"position",NORMAL:"normal",TANGENT:"tangent",TEXCOORD_0:"uv",TEXCOORD_1:"uv1",TEXCOORD_2:"uv2",TEXCOORD_3:"uv3",COLOR_0:"color",WEIGHTS_0:"skinWeight",JOINTS_0:"skinIndex"},X={scale:"scale",translation:"position",rotation:"quaternion",weights:"morphTargetInfluences"},ii={CUBICSPLINE:void 0,LINEAR:Ct,STEP:vs},Ke={OPAQUE:"OPAQUE",MASK:"MASK",BLEND:"BLEND"};function ni(l){return l.DefaultMaterial===void 0&&(l.DefaultMaterial=new Nt({color:16777215,emissive:0,metalness:1,roughness:1,transparent:!1,depthTest:!0,side:_s})),l.DefaultMaterial}function ee(l,t,e){for(const s in e.extensions)l[s]===void 0&&(t.userData.gltfExtensions=t.userData.gltfExtensions||{},t.userData.gltfExtensions[s]=e.extensions[s])}function q(l,t){t.extras!==void 0&&(typeof t.extras=="object"?Object.assign(l.userData,t.extras):console.warn("THREE.GLTFLoader: Ignoring primitive type .extras, "+t.extras))}function oi(l,t,e){let s=!1,i=!1,n=!1;for(let c=0,u=t.length;c<u;c++){const h=t[c];if(h.POSITION!==void 0&&(s=!0),h.NORMAL!==void 0&&(i=!0),h.COLOR_0!==void 0&&(n=!0),s&&i&&n)break}if(!s&&!i&&!n)return Promise.resolve(l);const o=[],a=[],r=[];for(let c=0,u=t.length;c<u;c++){const h=t[c];if(s){const d=h.POSITION!==void 0?e.getDependency("accessor",h.POSITION):l.attributes.position;o.push(d)}if(i){const d=h.NORMAL!==void 0?e.getDependency("accessor",h.NORMAL):l.attributes.normal;a.push(d)}if(n){const d=h.COLOR_0!==void 0?e.getDependency("accessor",h.COLOR_0):l.attributes.color;r.push(d)}}return Promise.all([Promise.all(o),Promise.all(a),Promise.all(r)]).then(function(c){const u=c[0],h=c[1],d=c[2];return s&&(l.morphAttributes.position=u),i&&(l.morphAttributes.normal=h),n&&(l.morphAttributes.color=d),l.morphTargetsRelative=!0,l})}function ri(l,t){if(l.updateMorphTargets(),t.weights!==void 0)for(let e=0,s=t.weights.length;e<s;e++)l.morphTargetInfluences[e]=t.weights[e];if(t.extras&&Array.isArray(t.extras.targetNames)){const e=t.extras.targetNames;if(l.morphTargetInfluences.length===e.length){l.morphTargetDictionary={};for(let s=0,i=e.length;s<i;s++)l.morphTargetDictionary[e[s]]=s}else console.warn("THREE.GLTFLoader: Invalid extras.targetNames length. Ignoring names.")}}function ai(l){let t;const e=l.extensions&&l.extensions[R.KHR_DRACO_MESH_COMPRESSION];if(e?t="draco:"+e.bufferView+":"+e.indices+":"+Xe(e.attributes):t=l.indices+":"+Xe(l.attributes)+":"+l.mode,l.targets!==void 0)for(let s=0,i=l.targets.length;s<i;s++)t+=":"+Xe(l.targets[s]);return t}function Xe(l){let t="";const e=Object.keys(l).sort();for(let s=0,i=e.length;s<i;s++)t+=e[s]+":"+l[e[s]]+";";return t}function Qe(l){switch(l){case Int8Array:return 1/127;case Uint8Array:return 1/255;case Int16Array:return 1/32767;case Uint16Array:return 1/65535;default:throw new Error("THREE.GLTFLoader: Unsupported normalized accessor component type.")}}function ci(l){return l.search(/\.jpe?g($|\?)/i)>0||l.search(/^data\:image\/jpeg/)===0?"image/jpeg":l.search(/\.webp($|\?)/i)>0||l.search(/^data\:image\/webp/)===0?"image/webp":"image/png"}const li=new Le;class hi{constructor(t={},e={}){this.json=t,this.extensions={},this.plugins={},this.options=e,this.cache=new Ps,this.associations=new Map,this.primitiveCache={},this.nodeCache={},this.meshCache={refs:{},uses:{}},this.cameraCache={refs:{},uses:{}},this.lightCache={refs:{},uses:{}},this.sourceCache={},this.textureCache={},this.nodeNamesUsed={};let s=!1,i=!1,n=-1;typeof navigator<"u"&&(s=/^((?!chrome|android).)*safari/i.test(navigator.userAgent)===!0,i=navigator.userAgent.indexOf("Firefox")>-1,n=i?navigator.userAgent.match(/Firefox\/([0-9]+)\./)[1]:-1),typeof createImageBitmap>"u"||s||i&&n<98?this.textureLoader=new ts(this.options.manager):this.textureLoader=new ss(this.options.manager),this.textureLoader.setCrossOrigin(this.options.crossOrigin),this.textureLoader.setRequestHeader(this.options.requestHeader),this.fileLoader=new Et(this.options.manager),this.fileLoader.setResponseType("arraybuffer"),this.options.crossOrigin==="use-credentials"&&this.fileLoader.setWithCredentials(!0)}setExtensions(t){this.extensions=t}setPlugins(t){this.plugins=t}parse(t,e){const s=this,i=this.json,n=this.extensions;this.cache.removeAll(),this.nodeCache={},this._invokeAll(function(o){return o._markDefs&&o._markDefs()}),Promise.all(this._invokeAll(function(o){return o.beforeRoot&&o.beforeRoot()})).then(function(){return Promise.all([s.getDependencies("scene"),s.getDependencies("animation"),s.getDependencies("camera")])}).then(function(o){const a={scene:o[0][i.scene||0],scenes:o[0],animations:o[1],cameras:o[2],asset:i.asset,parser:s,userData:{}};ee(n,a,i),q(a,i),Promise.all(s._invokeAll(function(r){return r.afterRoot&&r.afterRoot(a)})).then(function(){t(a)})}).catch(e)}_markDefs(){const t=this.json.nodes||[],e=this.json.skins||[],s=this.json.meshes||[];for(let i=0,n=e.length;i<n;i++){const o=e[i].joints;for(let a=0,r=o.length;a<r;a++)t[o[a]].isBone=!0}for(let i=0,n=t.length;i<n;i++){const o=t[i];o.mesh!==void 0&&(this._addNodeRef(this.meshCache,o.mesh),o.skin!==void 0&&(s[o.mesh].isSkinnedMesh=!0)),o.camera!==void 0&&this._addNodeRef(this.cameraCache,o.camera)}}_addNodeRef(t,e){e!==void 0&&(t.refs[e]===void 0&&(t.refs[e]=t.uses[e]=0),t.refs[e]++)}_getNodeRef(t,e,s){if(t.refs[e]<=1)return s;const i=s.clone(),n=(o,a)=>{const r=this.associations.get(o);r!=null&&this.associations.set(a,r);for(const[c,u]of o.children.entries())n(u,a.children[c])};return n(s,i),i.name+="_instance_"+t.uses[e]++,i}_invokeOne(t){const e=Object.values(this.plugins);e.push(this);for(let s=0;s<e.length;s++){const i=t(e[s]);if(i)return i}return null}_invokeAll(t){const e=Object.values(this.plugins);e.unshift(this);const s=[];for(let i=0;i<e.length;i++){const n=t(e[i]);n&&s.push(n)}return s}getDependency(t,e){const s=t+":"+e;let i=this.cache.get(s);if(!i){switch(t){case"scene":i=this.loadScene(e);break;case"node":i=this._invokeOne(function(n){return n.loadNode&&n.loadNode(e)});break;case"mesh":i=this._invokeOne(function(n){return n.loadMesh&&n.loadMesh(e)});break;case"accessor":i=this.loadAccessor(e);break;case"bufferView":i=this._invokeOne(function(n){return n.loadBufferView&&n.loadBufferView(e)});break;case"buffer":i=this.loadBuffer(e);break;case"material":i=this._invokeOne(function(n){return n.loadMaterial&&n.loadMaterial(e)});break;case"texture":i=this._invokeOne(function(n){return n.loadTexture&&n.loadTexture(e)});break;case"skin":i=this.loadSkin(e);break;case"animation":i=this._invokeOne(function(n){return n.loadAnimation&&n.loadAnimation(e)});break;case"camera":i=this.loadCamera(e);break;default:if(i=this._invokeOne(function(n){return n!=this&&n.getDependency&&n.getDependency(t,e)}),!i)throw new Error("Unknown type: "+t);break}this.cache.add(s,i)}return i}getDependencies(t){let e=this.cache.get(t);if(!e){const s=this,i=this.json[t+(t==="mesh"?"es":"s")]||[];e=Promise.all(i.map(function(n,o){return s.getDependency(t,o)})),this.cache.add(t,e)}return e}loadBuffer(t){const e=this.json.buffers[t],s=this.fileLoader;if(e.type&&e.type!=="arraybuffer")throw new Error("THREE.GLTFLoader: "+e.type+" buffer type is not supported.");if(e.uri===void 0&&t===0)return Promise.resolve(this.extensions[R.KHR_BINARY_GLTF].body);const i=this.options;return new Promise(function(n,o){s.load(qe.resolveURL(e.uri,i.path),n,void 0,function(){o(new Error('THREE.GLTFLoader: Failed to load buffer "'+e.uri+'".'))})})}loadBufferView(t){const e=this.json.bufferViews[t];return this.getDependency("buffer",e.buffer).then(function(s){const i=e.byteLength||0,n=e.byteOffset||0;return s.slice(n,n+i)})}loadAccessor(t){const e=this,s=this.json,i=this.json.accessors[t];if(i.bufferView===void 0&&i.sparse===void 0){const o=We[i.type],a=fe[i.componentType],r=i.normalized===!0,c=new a(i.count*o);return Promise.resolve(new je(c,o,r))}const n=[];return i.bufferView!==void 0?n.push(this.getDependency("bufferView",i.bufferView)):n.push(null),i.sparse!==void 0&&(n.push(this.getDependency("bufferView",i.sparse.indices.bufferView)),n.push(this.getDependency("bufferView",i.sparse.values.bufferView))),Promise.all(n).then(function(o){const a=o[0],r=We[i.type],c=fe[i.componentType],u=c.BYTES_PER_ELEMENT,h=u*r,d=i.byteOffset||0,f=i.bufferView!==void 0?s.bufferViews[i.bufferView].byteStride:void 0,m=i.normalized===!0;let y,w;if(f&&f!==h){const b=Math.floor(d/f),S="InterleavedBuffer:"+i.bufferView+":"+i.componentType+":"+b+":"+i.count;let N=e.cache.get(S);N||(y=new c(a,b*f,i.count*f/u),N=new is(y,f/u),e.cache.add(S,N)),w=new ns(N,r,d%f/u,m)}else a===null?y=new c(i.count*r):y=new c(a,d,i.count*r),w=new je(y,r,m);if(i.sparse!==void 0){const b=We.SCALAR,S=fe[i.sparse.indices.componentType],N=i.sparse.indices.byteOffset||0,E=i.sparse.values.byteOffset||0,V=new S(o[1],N,i.sparse.count*b),F=new c(o[2],E,i.sparse.count*r);a!==null&&(w=new je(w.array.slice(),w.itemSize,w.normalized));for(let O=0,K=V.length;O<K;O++){const I=V[O];if(w.setX(I,F[O*r]),r>=2&&w.setY(I,F[O*r+1]),r>=3&&w.setZ(I,F[O*r+2]),r>=4&&w.setW(I,F[O*r+3]),r>=5)throw new Error("THREE.GLTFLoader: Unsupported itemSize in sparse BufferAttribute.")}}return w})}loadTexture(t){const e=this.json,s=this.options,n=e.textures[t].source,o=e.images[n];let a=this.textureLoader;if(o.uri){const r=s.manager.getHandler(o.uri);r!==null&&(a=r)}return this.loadTextureImage(t,n,a)}loadTextureImage(t,e,s){const i=this,n=this.json,o=n.textures[t],a=n.images[e],r=(a.uri||a.bufferView)+":"+o.sampler;if(this.textureCache[r])return this.textureCache[r];const c=this.loadImageSource(e,s).then(function(u){u.flipY=!1,u.name=o.name||a.name||"",u.name===""&&typeof a.uri=="string"&&a.uri.startsWith("data:image/")===!1&&(u.name=a.uri);const d=(n.samplers||{})[o.sampler]||{};return u.magFilter=ht[d.magFilter]||_t,u.minFilter=ht[d.minFilter]||It,u.wrapS=ut[d.wrapS]||Ye,u.wrapT=ut[d.wrapT]||Ye,i.associations.set(u,{textures:t}),u}).catch(function(){return null});return this.textureCache[r]=c,c}loadImageSource(t,e){const s=this,i=this.json,n=this.options;if(this.sourceCache[t]!==void 0)return this.sourceCache[t].then(h=>h.clone());const o=i.images[t],a=self.URL||self.webkitURL;let r=o.uri||"",c=!1;if(o.bufferView!==void 0)r=s.getDependency("bufferView",o.bufferView).then(function(h){c=!0;const d=new Blob([h],{type:o.mimeType});return r=a.createObjectURL(d),r});else if(o.uri===void 0)throw new Error("THREE.GLTFLoader: Image "+t+" is missing URI and bufferView");const u=Promise.resolve(r).then(function(h){return new Promise(function(d,f){let m=d;e.isImageBitmapLoader===!0&&(m=function(y){const w=new nt(y);w.needsUpdate=!0,d(w)}),e.load(qe.resolveURL(h,n.path),m,void 0,f)})}).then(function(h){return c===!0&&a.revokeObjectURL(r),h.userData.mimeType=o.mimeType||ci(o.uri),h}).catch(function(h){throw console.error("THREE.GLTFLoader: Couldn't load texture",r),h});return this.sourceCache[t]=u,u}assignTexture(t,e,s,i){const n=this;return this.getDependency("texture",s.index).then(function(o){if(!o)return null;if(s.texCoord!==void 0&&s.texCoord>0&&(o=o.clone(),o.channel=s.texCoord),n.extensions[R.KHR_TEXTURE_TRANSFORM]){const a=s.extensions!==void 0?s.extensions[R.KHR_TEXTURE_TRANSFORM]:void 0;if(a){const r=n.associations.get(o);o=n.extensions[R.KHR_TEXTURE_TRANSFORM].extendTexture(o,a),n.associations.set(o,r)}}return i!==void 0&&(o.colorSpace=i),t[e]=o,o})}assignFinalMaterial(t){const e=t.geometry;let s=t.material;const i=e.attributes.tangent===void 0,n=e.attributes.color!==void 0,o=e.attributes.normal===void 0;if(t.isPoints){const a="PointsMaterial:"+s.uuid;let r=this.cache.get(a);r||(r=new os,Ve.prototype.copy.call(r,s),r.color.copy(s.color),r.map=s.map,r.sizeAttenuation=!1,this.cache.add(a,r)),s=r}else if(t.isLine){const a="LineBasicMaterial:"+s.uuid;let r=this.cache.get(a);r||(r=new rs,Ve.prototype.copy.call(r,s),r.color.copy(s.color),r.map=s.map,this.cache.add(a,r)),s=r}if(i||n||o){let a="ClonedMaterial:"+s.uuid+":";i&&(a+="derivative-tangents:"),n&&(a+="vertex-colors:"),o&&(a+="flat-shading:");let r=this.cache.get(a);r||(r=s.clone(),n&&(r.vertexColors=!0),o&&(r.flatShading=!0),i&&(r.normalScale&&(r.normalScale.y*=-1),r.clearcoatNormalScale&&(r.clearcoatNormalScale.y*=-1)),this.cache.add(a,r),this.associations.set(r,this.associations.get(s))),s=r}t.material=s}getMaterialType(){return Nt}loadMaterial(t){const e=this,s=this.json,i=this.extensions,n=s.materials[t];let o;const a={},r=n.extensions||{},c=[];if(r[R.KHR_MATERIALS_UNLIT]){const h=i[R.KHR_MATERIALS_UNLIT];o=h.getMaterialType(),c.push(h.extendParams(a,n,e))}else{const h=n.pbrMetallicRoughness||{};if(a.color=new ce(1,1,1),a.opacity=1,Array.isArray(h.baseColorFactor)){const d=h.baseColorFactor;a.color.fromArray(d),a.opacity=d[3]}h.baseColorTexture!==void 0&&c.push(e.assignTexture(a,"map",h.baseColorTexture,be)),a.metalness=h.metallicFactor!==void 0?h.metallicFactor:1,a.roughness=h.roughnessFactor!==void 0?h.roughnessFactor:1,h.metallicRoughnessTexture!==void 0&&(c.push(e.assignTexture(a,"metalnessMap",h.metallicRoughnessTexture)),c.push(e.assignTexture(a,"roughnessMap",h.metallicRoughnessTexture))),o=this._invokeOne(function(d){return d.getMaterialType&&d.getMaterialType(t)}),c.push(Promise.all(this._invokeAll(function(d){return d.extendMaterialParams&&d.extendMaterialParams(t,a)})))}n.doubleSided===!0&&(a.side=as);const u=n.alphaMode||Ke.OPAQUE;if(u===Ke.BLEND?(a.transparent=!0,a.depthWrite=!1):(a.transparent=!1,u===Ke.MASK&&(a.alphaTest=n.alphaCutoff!==void 0?n.alphaCutoff:.5)),n.normalTexture!==void 0&&o!==we&&(c.push(e.assignTexture(a,"normalMap",n.normalTexture)),a.normalScale=new Lt(1,1),n.normalTexture.scale!==void 0)){const h=n.normalTexture.scale;a.normalScale.set(h,h)}return n.occlusionTexture!==void 0&&o!==we&&(c.push(e.assignTexture(a,"aoMap",n.occlusionTexture)),n.occlusionTexture.strength!==void 0&&(a.aoMapIntensity=n.occlusionTexture.strength)),n.emissiveFactor!==void 0&&o!==we&&(a.emissive=new ce().fromArray(n.emissiveFactor)),n.emissiveTexture!==void 0&&o!==we&&c.push(e.assignTexture(a,"emissiveMap",n.emissiveTexture,be)),Promise.all(c).then(function(){const h=new o(a);return n.name&&(h.name=n.name),q(h,n),e.associations.set(h,{materials:t}),n.extensions&&ee(i,h,n),h})}createUniqueName(t){const e=cs.sanitizeNodeName(t||"");return e in this.nodeNamesUsed?e+"_"+ ++this.nodeNamesUsed[e]:(this.nodeNamesUsed[e]=0,e)}loadGeometries(t){const e=this,s=this.extensions,i=this.primitiveCache;function n(a){return s[R.KHR_DRACO_MESH_COMPRESSION].decodePrimitive(a,e).then(function(r){return dt(r,a,e)})}const o=[];for(let a=0,r=t.length;a<r;a++){const c=t[a],u=ai(c),h=i[u];if(h)o.push(h.promise);else{let d;c.extensions&&c.extensions[R.KHR_DRACO_MESH_COMPRESSION]?d=n(c):d=dt(new ls,c,e),i[u]={primitive:c,promise:d},o.push(d)}}return Promise.all(o)}loadMesh(t){const e=this,s=this.json,i=this.extensions,n=s.meshes[t],o=n.primitives,a=[];for(let r=0,c=o.length;r<c;r++){const u=o[r].material===void 0?ni(this.cache):this.getDependency("material",o[r].material);a.push(u)}return a.push(e.loadGeometries(o)),Promise.all(a).then(function(r){const c=r.slice(0,r.length-1),u=r[r.length-1],h=[];for(let f=0,m=u.length;f<m;f++){const y=u[f],w=o[f];let b;const S=c[f];if(w.mode===H.TRIANGLES||w.mode===H.TRIANGLE_STRIP||w.mode===H.TRIANGLE_FAN||w.mode===void 0)b=n.isSkinnedMesh===!0?new hs(y,S):new us(y,S),b.isSkinnedMesh===!0&&b.normalizeSkinWeights(),w.mode===H.TRIANGLE_STRIP?b.geometry=ct(b.geometry,Rt):w.mode===H.TRIANGLE_FAN&&(b.geometry=ct(b.geometry,$e));else if(w.mode===H.LINES)b=new ds(y,S);else if(w.mode===H.LINE_STRIP)b=new fs(y,S);else if(w.mode===H.LINE_LOOP)b=new ps(y,S);else if(w.mode===H.POINTS)b=new ms(y,S);else throw new Error("THREE.GLTFLoader: Primitive mode unsupported: "+w.mode);Object.keys(b.geometry.morphAttributes).length>0&&ri(b,n),b.name=e.createUniqueName(n.name||"mesh_"+t),q(b,n),w.extensions&&ee(i,b,w),e.assignFinalMaterial(b),h.push(b)}for(let f=0,m=h.length;f<m;f++)e.associations.set(h[f],{meshes:t,primitives:f});if(h.length===1)return n.extensions&&ee(i,h[0],n),h[0];const d=new Ue;n.extensions&&ee(i,d,n),e.associations.set(d,{meshes:t});for(let f=0,m=h.length;f<m;f++)d.add(h[f]);return d})}loadCamera(t){let e;const s=this.json.cameras[t],i=s[s.type];if(!i){console.warn("THREE.GLTFLoader: Missing camera parameters.");return}return s.type==="perspective"?e=new gs(ws.radToDeg(i.yfov),i.aspectRatio||1,i.znear||1,i.zfar||2e6):s.type==="orthographic"&&(e=new Ts(-i.xmag,i.xmag,i.ymag,-i.ymag,i.znear,i.zfar)),s.name&&(e.name=this.createUniqueName(s.name)),q(e,s),Promise.resolve(e)}loadSkin(t){const e=this.json.skins[t],s=[];for(let i=0,n=e.joints.length;i<n;i++)s.push(this._loadNodeShallow(e.joints[i]));return e.inverseBindMatrices!==void 0?s.push(this.getDependency("accessor",e.inverseBindMatrices)):s.push(null),Promise.all(s).then(function(i){const n=i.pop(),o=i,a=[],r=[];for(let c=0,u=o.length;c<u;c++){const h=o[c];if(h){a.push(h);const d=new Le;n!==null&&d.fromArray(n.array,c*16),r.push(d)}else console.warn('THREE.GLTFLoader: Joint "%s" could not be found.',e.joints[c])}return new As(a,r)})}loadAnimation(t){const e=this.json,s=this,i=e.animations[t],n=i.name?i.name:"animation_"+t,o=[],a=[],r=[],c=[],u=[];for(let h=0,d=i.channels.length;h<d;h++){const f=i.channels[h],m=i.samplers[f.sampler],y=f.target,w=y.node,b=i.parameters!==void 0?i.parameters[m.input]:m.input,S=i.parameters!==void 0?i.parameters[m.output]:m.output;y.node!==void 0&&(o.push(this.getDependency("node",w)),a.push(this.getDependency("accessor",b)),r.push(this.getDependency("accessor",S)),c.push(m),u.push(y))}return Promise.all([Promise.all(o),Promise.all(a),Promise.all(r),Promise.all(c),Promise.all(u)]).then(function(h){const d=h[0],f=h[1],m=h[2],y=h[3],w=h[4],b=[];for(let S=0,N=d.length;S<N;S++){const E=d[S],V=f[S],F=m[S],O=y[S],K=w[S];if(E===void 0)continue;E.updateMatrix&&E.updateMatrix();const I=s._createAnimationTracks(E,V,F,O,K);if(I)for(let Fe=0;Fe<I.length;Fe++)b.push(I[Fe])}return new bs(n,void 0,b)})}createNodeMesh(t){const e=this.json,s=this,i=e.nodes[t];return i.mesh===void 0?null:s.getDependency("mesh",i.mesh).then(function(n){const o=s._getNodeRef(s.meshCache,i.mesh,n);return i.weights!==void 0&&o.traverse(function(a){if(a.isMesh)for(let r=0,c=i.weights.length;r<c;r++)a.morphTargetInfluences[r]=i.weights[r]}),o})}loadNode(t){const e=this.json,s=this,i=e.nodes[t],n=s._loadNodeShallow(t),o=[],a=i.children||[];for(let c=0,u=a.length;c<u;c++)o.push(s.getDependency("node",a[c]));const r=i.skin===void 0?Promise.resolve(null):s.getDependency("skin",i.skin);return Promise.all([n,Promise.all(o),r]).then(function(c){const u=c[0],h=c[1],d=c[2];d!==null&&u.traverse(function(f){f.isSkinnedMesh&&f.bind(d,li)});for(let f=0,m=h.length;f<m;f++)u.add(h[f]);return u})}_loadNodeShallow(t){const e=this.json,s=this.extensions,i=this;if(this.nodeCache[t]!==void 0)return this.nodeCache[t];const n=e.nodes[t],o=n.name?i.createUniqueName(n.name):"",a=[],r=i._invokeOne(function(c){return c.createNodeMesh&&c.createNodeMesh(t)});return r&&a.push(r),n.camera!==void 0&&a.push(i.getDependency("camera",n.camera).then(function(c){return i._getNodeRef(i.cameraCache,n.camera,c)})),i._invokeAll(function(c){return c.createNodeAttachment&&c.createNodeAttachment(t)}).forEach(function(c){a.push(c)}),this.nodeCache[t]=Promise.all(a).then(function(c){let u;if(n.isBone===!0?u=new ys:c.length>1?u=new Ue:c.length===1?u=c[0]:u=new vt,u!==c[0])for(let h=0,d=c.length;h<d;h++)u.add(c[h]);if(n.name&&(u.userData.name=n.name,u.name=o),q(u,n),n.extensions&&ee(s,u,n),n.matrix!==void 0){const h=new Le;h.fromArray(n.matrix),u.applyMatrix4(h)}else n.translation!==void 0&&u.position.fromArray(n.translation),n.rotation!==void 0&&u.quaternion.fromArray(n.rotation),n.scale!==void 0&&u.scale.fromArray(n.scale);return i.associations.has(u)||i.associations.set(u,{}),i.associations.get(u).nodes=t,u}),this.nodeCache[t]}loadScene(t){const e=this.extensions,s=this.json.scenes[t],i=this,n=new Ue;s.name&&(n.name=i.createUniqueName(s.name)),q(n,s),s.extensions&&ee(e,n,s);const o=s.nodes||[],a=[];for(let r=0,c=o.length;r<c;r++)a.push(i.getDependency("node",o[r]));return Promise.all(a).then(function(r){for(let u=0,h=r.length;u<h;u++)n.add(r[u]);const c=u=>{const h=new Map;for(const[d,f]of i.associations)(d instanceof Ve||d instanceof nt)&&h.set(d,f);return u.traverse(d=>{const f=i.associations.get(d);f!=null&&h.set(d,f)}),h};return i.associations=c(n),n})}_createAnimationTracks(t,e,s,i,n){const o=[],a=t.name?t.name:t.uuid,r=[];X[n.path]===X.weights?t.traverse(function(d){d.morphTargetInfluences&&r.push(d.name?d.name:d.uuid)}):r.push(a);let c;switch(X[n.path]){case X.weights:c=rt;break;case X.rotation:c=at;break;case X.position:case X.scale:c=ot;break;default:switch(s.itemSize){case 1:c=rt;break;case 2:case 3:default:c=ot;break}break}const u=i.interpolation!==void 0?ii[i.interpolation]:Ct,h=this._getArrayFromAccessor(s);for(let d=0,f=r.length;d<f;d++){const m=new c(r[d]+"."+X[n.path],e.array,h,u);i.interpolation==="CUBICSPLINE"&&this._createCubicSplineTrackInterpolant(m),o.push(m)}return o}_getArrayFromAccessor(t){let e=t.array;if(t.normalized){const s=Qe(e.constructor),i=new Float32Array(e.length);for(let n=0,o=e.length;n<o;n++)i[n]=e[n]*s;e=i}return e}_createCubicSplineTrackInterpolant(t){t.createInterpolant=function(s){const i=this instanceof at?si:Pt;return new i(this.times,this.values,this.getValueSize()/3,s)},t.createInterpolant.isInterpolantFactoryMethodGLTFCubicSpline=!0}}function ui(l,t,e){const s=t.attributes,i=new Is;if(s.POSITION!==void 0){const a=e.json.accessors[s.POSITION],r=a.min,c=a.max;if(r!==void 0&&c!==void 0){if(i.set(new de(r[0],r[1],r[2]),new de(c[0],c[1],c[2])),a.normalized){const u=Qe(fe[a.componentType]);i.min.multiplyScalar(u),i.max.multiplyScalar(u)}}else{console.warn("THREE.GLTFLoader: Missing min/max properties for accessor POSITION.");return}}else return;const n=t.targets;if(n!==void 0){const a=new de,r=new de;for(let c=0,u=n.length;c<u;c++){const h=n[c];if(h.POSITION!==void 0){const d=e.json.accessors[h.POSITION],f=d.min,m=d.max;if(f!==void 0&&m!==void 0){if(r.setX(Math.max(Math.abs(f[0]),Math.abs(m[0]))),r.setY(Math.max(Math.abs(f[1]),Math.abs(m[1]))),r.setZ(Math.max(Math.abs(f[2]),Math.abs(m[2]))),d.normalized){const y=Qe(fe[d.componentType]);r.multiplyScalar(y)}a.max(r)}else console.warn("THREE.GLTFLoader: Missing min/max properties for accessor POSITION.")}}i.expandByVector(a)}l.boundingBox=i;const o=new Ns;i.getCenter(o.center),o.radius=i.min.distanceTo(i.max)/2,l.boundingSphere=o}function dt(l,t,e){const s=t.attributes,i=[];function n(o,a){return e.getDependency("accessor",o).then(function(r){l.setAttribute(a,r)})}for(const o in s){const a=Je[o]||o.toLowerCase();a in l.attributes||i.push(n(s[o],a))}if(t.indices!==void 0&&!l.index){const o=e.getDependency("accessor",t.indices).then(function(a){l.setIndex(a)});i.push(o)}return q(l,t),ui(l,t,e),Promise.all(i).then(function(){return t.targets!==void 0?oi(l,t.targets,e):l})}const di={base:"/simcity-threejs-clone/",root:"./src",publicDir:"./public",build:{outDir:"./dist"}},Ze={"under-construction":{type:"zone",filename:"construction-small.glb",scale:3},"residential-A1":{type:"zone",filename:"building-house-block-big.glb"},"residential-B1":{type:"zone",filename:"building-house-family-small.glb"},"residential-C1":{type:"zone",filename:"building-house-family-large.glb"},"residential-A2":{type:"zone",filename:"building-block-4floor-short.glb"},"residential-B2":{type:"zone",filename:"building-block-4floor-corner.glb"},"residential-C2":{type:"zone",filename:"building-block-5floor.glb"},"residential-A3":{type:"zone",filename:"building-office-balcony.glb"},"residential-B3":{type:"zone",filename:"building-office-pyramid.glb"},"residential-C3":{type:"zone",filename:"building-office-tall.glb"},"commercial-A1":{type:"zone",filename:"building-cafe.glb"},"commercial-B1":{type:"zone",filename:"building-burger-joint.glb"},"commercial-C1":{type:"zone",filename:"building-restaurant.glb"},"commercial-A2":{type:"zone",filename:"building-cinema.glb"},"commercial-B2":{type:"zone",filename:"building-casino.glb"},"commercial-C2":{type:"zone",filename:"data-center.glb"},"commercial-A3":{type:"zone",filename:"building-office.glb"},"commercial-B3":{type:"zone",filename:"building-office-big.glb"},"commercial-C3":{type:"zone",filename:"building-skyscraper.glb"},"industrial-A1":{type:"zone",filename:"industry-factory.glb"},"industrial-B1":{type:"zone",filename:"industry-refinery.glb"},"industrial-C1":{type:"zone",filename:"industry-warehouse.glb"},"industrial-A2":{type:"zone",filename:"industry-factory.glb"},"industrial-B2":{type:"zone",filename:"industry-refinery.glb"},"industrial-C2":{type:"zone",filename:"industry-warehouse.glb"},"industrial-A3":{type:"zone",filename:"industry-factory.glb"},"industrial-B3":{type:"zone",filename:"industry-refinery.glb"},"industrial-C3":{type:"zone",filename:"industry-warehouse.glb"},"power-plant":{type:"power",filename:"industry-factory-old.glb"},"power-line":{type:"power",filename:"power_line_pole_modified.glb"},"road-straight":{type:"road",filename:"tile-road-straight.glb",castShadow:!1},"road-end":{type:"road",filename:"tile-road-end.glb",castShadow:!1},"road-corner":{type:"road",filename:"tile-road-curve.glb",castShadow:!1},"road-three-way":{type:"road",filename:"tile-road-intersection-t.glb",castShadow:!1},"road-four-way":{type:"road",filename:"tile-road-intersection.glb",castShadow:!1},grass:{type:"terrain",filename:"tile-plain_grass.glb",castShadow:!1},"car-taxi":{type:"vehicle",filename:"car-taxi.glb",rotation:90},"car-police":{type:"vehicle",filename:"car-police.glb",rotation:90},"car-passenger":{type:"vehicle",filename:"car-passenger.glb",rotation:90},"car-veteran":{type:"vehicle",filename:"car-veteran.glb",rotation:90},truck:{type:"vehicle",filename:"truck.glb",rotation:90},"car-hippie-van":{type:"vehicle",filename:"car-hippie-van.glb",rotation:90},"car-tow-truck":{type:"vehicle",filename:"car-tow-truck.glb",rotation:90},"car-ambulance-pickup":{type:"vehicle",filename:"car-ambulance-pickup.glb",rotation:90},"car-passenger-race":{type:"vehicle",filename:"car-passenger-race.glb",rotation:90},"car-baywatch":{type:"vehicle",filename:"car-baywatch.glb",rotation:90},"car-truck-dump":{type:"vehicle",filename:"car-truck-dump.glb",rotation:90},"car-truck-armored-truck":{type:"vehicle",filename:"armored-truck.glb",rotation:90}},le=di.base;var Y,ue,Se,Dt;class fi{constructor(t){L(this,Y);L(this,Se);A(this,"textureLoader",new p.TextureLoader);A(this,"modelLoader",new Os);A(this,"textures",{base:M(this,Y,ue).call(this,`${le}textures/base.png`),specular:M(this,Y,ue).call(this,`${le}textures/specular.png`),grid:M(this,Y,ue).call(this,`${le}textures/grid.png`)});A(this,"statusIcons",{"no-power":M(this,Y,ue).call(this,`${le}statusIcons/no-power.png`,!0),"no-road-access":M(this,Y,ue).call(this,`${le}statusIcons/no-road-access.png`,!0)});A(this,"models",{});A(this,"sprites",{});this.modelCount=Object.keys(Ze).length,this.loadedModelCount=0;for(const[e,s]of Object.entries(Ze))M(this,Se,Dt).call(this,e,s);this.onLoad=t}getModel(t,e,s=!1){const i=this.models[t].clone();return i.traverse(n=>{n.userData=e,n.material&&(n.material=n.material.clone(),n.material.transparent=s)}),i}}Y=new WeakSet,ue=function(t,e=!1){const s=this.textureLoader.load(t);return s.colorSpace=p.SRGBColorSpace,s.flipY=e,s},Se=new WeakSet,Dt=function(t,{filename:e,scale:s=1,rotation:i=0,receiveShadow:n=!0,castShadow:o=!0}){this.modelLoader.load(`${le}models/${e}`,a=>{let r=a.scene;r.name=e,r.traverse(c=>{c.material&&(c.material=new p.MeshLambertMaterial({map:this.textures.base,specularMap:this.textures.specular}),c.receiveShadow=n,c.castShadow=o)}),r.rotation.set(0,p.MathUtils.degToRad(i),0),r.scale.set(s/30,s/30,s/30),this.models[t]=r,this.loadedModelCount++,this.loadedModelCount==this.modelCount&&this.onLoad()},a=>{},a=>{console.error(a)})};const te=Math.PI/180,ft=2,he=5,pi=.1,mi=5,gi=45,wi=45,Ti=.2,Ai=.2,bi=.002,pt=-.01,mt=new p.Vector3(0,1,0);class yi{constructor(){const t=window.ui.gameWindow.clientWidth/window.ui.gameWindow.clientHeight;this.camera=new p.OrthographicCamera(he*t/-2,he*t/2,he/2,he/-2,1,1e3),this.camera.layers.enable(1),this.cameraOrigin=new p.Vector3(8,0,8),this.cameraRadius=.5,this.cameraAzimuth=225,this.cameraElevation=45,this.updateCameraPosition(),window.ui.gameWindow.addEventListener("wheel",this.onMouseScroll.bind(this),!1),window.ui.gameWindow.addEventListener("mousedown",this.onMouseMove.bind(this),!1),window.ui.gameWindow.addEventListener("mousemove",this.onMouseMove.bind(this),!1)}updateCameraPosition(){this.camera.zoom=this.cameraRadius,this.camera.position.x=100*Math.sin(this.cameraAzimuth*te)*Math.cos(this.cameraElevation*te),this.camera.position.y=100*Math.sin(this.cameraElevation*te),this.camera.position.z=100*Math.cos(this.cameraAzimuth*te)*Math.cos(this.cameraElevation*te),this.camera.position.add(this.cameraOrigin),this.camera.lookAt(this.cameraOrigin),this.camera.updateProjectionMatrix(),this.camera.updateMatrixWorld()}onMouseMove(t){if(t.buttons&ft&&!t.ctrlKey&&(this.cameraAzimuth+=-(t.movementX*Ti),this.cameraElevation+=t.movementY*Ai,this.cameraElevation=Math.min(wi,Math.max(gi,this.cameraElevation))),t.buttons&ft&&t.ctrlKey){const e=new p.Vector3(0,0,1).applyAxisAngle(mt,this.cameraAzimuth*te),s=new p.Vector3(1,0,0).applyAxisAngle(mt,this.cameraAzimuth*te);this.cameraOrigin.add(e.multiplyScalar(pt*t.movementY)),this.cameraOrigin.add(s.multiplyScalar(pt*t.movementX))}this.updateCameraPosition()}onMouseScroll(t){this.cameraRadius*=1-t.deltaY*bi,this.cameraRadius=Math.min(mi,Math.max(pi,this.cameraRadius)),this.updateCameraPosition()}resize(){const t=window.ui.gameWindow.clientWidth/window.ui.gameWindow.clientHeight;this.camera.left=he*t/-2,this.camera.right=he*t/2,this.camera.updateProjectionMatrix()}}var ve,kt,_e,Ht,Ie,Bt;class Mi{constructor(){L(this,ve);L(this,_e);L(this,Ie);A(this,"mouse",{x:0,y:0});A(this,"isLeftMouseDown",!1);A(this,"isMiddleMouseDown",!1);A(this,"isRightMouseDown",!1);window.ui.gameWindow.addEventListener("mousedown",M(this,ve,kt).bind(this),!1),window.ui.gameWindow.addEventListener("mouseup",M(this,_e,Ht).bind(this),!1),window.ui.gameWindow.addEventListener("mousemove",M(this,Ie,Bt).bind(this),!1),window.ui.gameWindow.addEventListener("contextmenu",t=>t.preventDefault(),!1)}}ve=new WeakSet,kt=function(t){t.button===0&&(this.isLeftMouseDown=!0),t.button===1&&(this.isMiddleMouseDown=!0),t.button===2&&(this.isRightMouseDown=!0)},_e=new WeakSet,Ht=function(t){t.button===0&&(this.isLeftMouseDown=!1),t.button===1&&(this.isMiddleMouseDown=!1),t.button===2&&(this.isRightMouseDown=!1)},Ie=new WeakSet,Bt=function(t){this.isLeftMouseDown=t.buttons&1,this.isRightMouseDown=t.buttons&2,this.isMiddleMouseDown=t.buttons&4,this.mouse.x=t.clientX,this.mouse.y=t.clientY};const P={residential:"residential",commercial:"commercial",industrial:"industrial",road:"road",powerPlant:"power-plant",powerLine:"power-line"},G=Math.PI/180,xi=180/Math.PI,_={modules:{development:{abandonThreshold:10,abandonChance:.25,constructionTime:3,levelUpChance:.05,redevelopChance:.25},jobs:{maxWorkers:2},residents:{maxResidents:2,residentMoveInChance:.5},roadAccess:{searchDistance:3}},citizen:{minWorkingAge:16,retirementAge:65,maxJobSearchDistance:4},vehicle:{speed:5e-4,fadeTime:500,maxLifetime:1e4,spawnInterval:1e3}};class Ee{simulate(t){}dispose(){}toHTML(){}}const C={abandoned:"abandoned",developed:"developed",underConstruction:"under-construction",undeveloped:"undeveloped"};var ie,pe,ye,Me,J,xe,et,Ne,Ft;class Ri extends Ee{constructor(e){super();L(this,xe);L(this,Ne);L(this,ie,0);L(this,pe,0);L(this,ye,1);A(this,"maxLevel",3);L(this,Me,C.undeveloped);L(this,J,void 0);D(this,J,e)}get level(){return g(this,ye)}set level(e){D(this,ye,e),g(this,J).refreshView()}get state(){return g(this,Me)}set state(e){D(this,Me,e),g(this,J).refreshView()}simulate(e){switch(M(this,Ne,Ft).call(this),this.state){case C.undeveloped:M(this,xe,et).call(this)&&Math.random()<_.modules.development.redevelopChance&&(this.state=C.underConstruction,D(this,pe,0));break;case C.underConstruction:++ze(this,pe)._===_.modules.development.constructionTime&&(this.state=C.developed,this.level=1,D(this,pe,0));break;case C.developed:g(this,ie)>_.modules.development.abandonThreshold?Math.random()<_.modules.development.abandonChance&&(this.state=C.abandoned):this.level<this.maxLevel&&Math.random()<_.modules.development.levelUpChance&&this.level++;break;case C.abandoned:g(this,ie)==0&&Math.random()<_.modules.development.redevelopChance&&(this.state=C.developed);break}}toHTML(){return`
|
|
2
|
+
<span class="info-label">State </span>
|
|
3
|
+
<span class="info-value">${this.state}</span>
|
|
4
|
+
<br>
|
|
5
|
+
<span class="info-label">Level </span>
|
|
6
|
+
<span class="info-value">${this.level}</span>
|
|
7
|
+
<br>`}}ie=new WeakMap,pe=new WeakMap,ye=new WeakMap,Me=new WeakMap,J=new WeakMap,xe=new WeakSet,et=function(){return g(this,J).roadAccess.value&&g(this,J).power.isFullyPowered},Ne=new WeakSet,Ft=function(){M(this,xe,et).call(this)?D(this,ie,0):ze(this,ie)._++};const Ei=11184725,Li=5592405;var j,ne,oe,Te;class st extends p.Object3D{constructor(e=0,s=0){super();L(this,oe);L(this,j,null);L(this,ne,new p.Vector3);this.name="SimObject",this.position.x=e,this.position.z=s}get x(){return this.getWorldPosition(g(this,ne)),Math.floor(g(this,ne).x)}get y(){return this.getWorldPosition(g(this,ne)),Math.floor(g(this,ne).z)}get mesh(){return g(this,j)}setMesh(e){g(this,j)&&(this.dispose(),this.remove(g(this,j))),D(this,j,e),g(this,j)&&this.add(g(this,j))}simulate(e){}setSelected(e){e?M(this,oe,Te).call(this,Ei):M(this,oe,Te).call(this,0)}setFocused(e){e?M(this,oe,Te).call(this,Li):M(this,oe,Te).call(this,0)}dispose(){g(this,j).traverse(e=>{var s;e.material&&((s=e.material)==null||s.dispose())})}}j=new WeakMap,ne=new WeakMap,oe=new WeakSet,Te=function(e){this.mesh&&this.mesh.traverse(s=>{var i,n;return(n=(i=s.material)==null?void 0:i.emissive)==null?void 0:n.setHex(e)})};const se={NoPower:"no-power",NoRoadAccess:"no-road-access",Ok:"ok"};class Si extends Ee{constructor(e){super();A(this,"supplied",0);A(this,"required",0);this.required=this.supplied}get isFullyPowered(){return this.supplied>=this.required}}class vi extends Ee{constructor(e){super();A(this,"building");A(this,"enabled",!0);A(this,"value");this.building=e}simulate(e){if(!this.enabled)this.value=!0;else{const s=e.findTile(this.building,i=>{var n;return((n=i.building)==null?void 0:n.type)==="road"},_.modules.roadAccess.searchDistance);this.value=s!==null}}}var k;class Be extends st{constructor(){super();A(this,"type","building");A(this,"hideTerrain",!1);A(this,"power",new Si(this));A(this,"roadAccess",new vi(this));A(this,"status",se.Ok);L(this,k,new p.Sprite);g(this,k).visible=!1,g(this,k).material=new p.SpriteMaterial({depthTest:!1}),g(this,k).layers.set(1),g(this,k).scale.set(.5,.5,.5),this.add(g(this,k))}setStatus(e){if(e!==this.status)switch(e){case se.NoPower:g(this,k).visible=!0,g(this,k).material.map=window.assetManager.statusIcons[se.NoPower];break;case se.NoRoadAccess:g(this,k).visible=!0,g(this,k).material.map=window.assetManager.statusIcons[se.NoRoadAccess];break;default:g(this,k).visible=!1}}simulate(e){super.simulate(e),this.power.simulate(e),this.roadAccess.simulate(e),this.power.isFullyPowered?this.roadAccess.value?this.setStatus(null):this.setStatus(se.NoRoadAccess):this.setStatus(se.NoPower)}dispose(){this.power.dispose(),this.roadAccess.dispose(),super.dispose()}toHTML(){let e=`
|
|
8
|
+
<div class="info-heading">Building</div>
|
|
9
|
+
<span class="info-label">Name </span>
|
|
10
|
+
<span class="info-value">${this.name}</span>
|
|
11
|
+
<br>
|
|
12
|
+
<span class="info-label">Type </span>
|
|
13
|
+
<span class="info-value">${this.type}</span>
|
|
14
|
+
<br>
|
|
15
|
+
<span class="info-label">Road Access </span>
|
|
16
|
+
<span class="info-value">${this.roadAccess.value}</span>
|
|
17
|
+
<br>`;return this.power.required>0&&(e+=`
|
|
18
|
+
<span class="info-label">Power (kW)</span>
|
|
19
|
+
<span class="info-value">${this.power.supplied}/${this.power.required}</span>
|
|
20
|
+
<br>`),e}}k=new WeakMap;class it extends Be{constructor(e=0,s=0){super(e,s);A(this,"style",["A","B","C"][Math.floor(3*Math.random())]);A(this,"development",new Ri(this));this.name="Zone",this.power.required=10,this.rotation.y=90*Math.floor(4*Math.random())*G}refreshView(){let e;switch(this.development.state){case C.underConstruction:case C.undeveloped:e="under-construction";break;default:e=`${this.type}-${this.style}${this.development.level}`;break}let s=window.assetManager.getModel(e,this);this.development.state===C.abandoned&&s.traverse(i=>{i.material&&(i.material.color=new p.Color(7368816))}),this.setMesh(s)}simulate(e){super.simulate(e),this.development.simulate(e)}toHTML(){let e=super.toHTML();return e+=this.development.toHTML(),e}}class _i extends it{constructor(e,s){super(e,s);A(this,"jobs",new Vt(this));this.name=Ii(),this.type=P.industrial}simulate(e){super.simulate(e),this.jobs.simulate()}dispose(){this.jobs.dispose(),super.dispose()}toHTML(){let e=super.toHTML();return e+=this.jobs.toHTML(),e}}const gt=["Apex","Vortex","Elevate","Zenith","Nova","Synapse","Pulse","Enigma","Catalyst","Axiom"],wt=["Dynamics","Ventures","Solutions","Technologies","Innovations","Industries","Enterprises","Systems","Mechanics","Manufacturing"],Tt=["LLC","Inc.","Co.","Corp.","Ltd."];function Ii(){const l=gt[Math.floor(Math.random()*gt.length)],t=wt[Math.floor(Math.random()*wt.length)],e=Tt[Math.floor(Math.random()*Tt.length)];return l+" "+t+" "+e}var Q,B,Ce,Gt;class Ni extends Ee{constructor(e){super();L(this,Ce);L(this,Q,void 0);L(this,B,[]);D(this,Q,e)}get count(){return g(this,B).length}get maximum(){return Math.pow(_.modules.residents.maxResidents,g(this,Q).development.level)}simulate(e){g(this,Q).development.state===C.abandoned&&g(this,B).length>0?this.evictAll():g(this,Q).development.state===C.developed&&g(this,B).length<this.maximum&&Math.random()<_.modules.residents.residentMoveInChance&&g(this,B).push(new Pi(g(this,Q)));for(const s of g(this,B))s.simulate(e)}dispose(){M(this,Ce,Gt).call(this)}toHTML(){let e=`<div class="info-heading">Residents (${g(this,B).length}/${this.maximum})</div>`;e+='<ul class="info-citizen-list">';for(const s of g(this,B))e+=s.toHTML();return e+="</ul>",e}}Q=new WeakMap,B=new WeakMap,Ce=new WeakSet,Gt=function(){for(const e of g(this,B))e.dispose();D(this,B,[])};class Ci extends it{constructor(e,s){super(e,s);A(this,"residents",new Ni(this));this.name=Oi(),this.type=P.residential}simulate(e){super.simulate(e),this.residents.simulate(e)}dispose(){this.residents.dispose(),super.dispose()}toHTML(){let e=super.toHTML();return e+=this.residents.toHTML(),e}}const At=["Emerald","Ivory","Crimson","Opulent","Celestial","Enchanted","Serene","Whispering","Stellar","Tranquil"],bt=["Tower","Residence","Manor","Court","Plaza","House","Mansion","Place","Villa","Gardens"];function Oi(){const l=At[Math.floor(Math.random()*At.length)],t=bt[Math.floor(Math.random()*bt.length)];return l+" "+t}var Oe,zt,Pe,jt;class Pi{constructor(t){L(this,Oe);L(this,Pe);this.id=crypto.randomUUID(),this.name=Di(),this.age=1+Math.floor(100*Math.random()),this.state="idle",this.stateCounter=0,this.residence=t,this.workplace=null,M(this,Oe,zt).call(this)}simulate(t){switch(this.state){case"idle":case"school":case"retired":break;case"unemployed":this.workplace=M(this,Pe,jt).call(this,t),this.workplace&&(this.state="employed");break;case"employed":this.workplace||(this.state="unemployed");break;default:console.error(`Citizen ${this.id} is in an unknown state (${this.state})`)}}dispose(){var e;const t=(e=this.workplace)==null?void 0:e.jobs.workers.indexOf(this);t!==void 0&&t>-1&&this.workplace.jobs.workers.splice(t)}setWorkplace(t){this.workplace=t}toHTML(){return`
|
|
21
|
+
<li class="info-citizen">
|
|
22
|
+
<span class="info-citizen-name">${this.name}</span>
|
|
23
|
+
<br>
|
|
24
|
+
<span class="info-citizen-details">
|
|
25
|
+
<span>
|
|
26
|
+
<img class="info-citizen-icon" src="/icons/calendar.png">
|
|
27
|
+
${this.age}
|
|
28
|
+
</span>
|
|
29
|
+
<span>
|
|
30
|
+
<img class="info-citizen-icon" src="/icons/job.png">
|
|
31
|
+
${this.state}
|
|
32
|
+
</span>
|
|
33
|
+
</span>
|
|
34
|
+
</li>
|
|
35
|
+
`}}Oe=new WeakSet,zt=function(){this.age<_.citizen.minWorkingAge?this.state="school":this.age>=_.citizen.retirementAge?this.state="retired":this.state="unemployed"},Pe=new WeakSet,jt=function(t){const e=t.findTile(this.residence,s=>{var i,n;return(((i=s.building)==null?void 0:i.type)==="industrial"||((n=s.building)==null?void 0:n.type)==="commercial")&&s.building.jobs.availableJobs>0},_.citizen.maxJobSearchDistance);return e?(e.building.jobs.workers.push(this),e.building):null};function Di(){const l=["Emma","Olivia","Ava","Sophia","Isabella","Liam","Noah","William","James","Benjamin","Elizabeth","Margaret","Alice","Dorothy","Eleanor","John","Robert","William","Charles","Henry","Alex","Taylor","Jordan","Casey","Robin"],t=["Smith","Johnson","Williams","Jones","Brown","Davis","Miller","Wilson","Moore","Taylor","Anderson","Thomas","Jackson","White","Harris","Clark","Lewis","Walker","Hall","Young","Lee","King","Wright","Adams","Green"],e=l[Math.floor(Math.random()*l.length)],s=t[Math.floor(Math.random()*t.length)];return e+" "+s}var re,Re,tt;class Vt extends Ee{constructor(e){super();L(this,Re);L(this,re,void 0);A(this,"workers",[]);D(this,re,e)}get maxWorkers(){return g(this,re).development.state!==C.developed?0:Math.pow(_.modules.jobs.maxWorkers,g(this,re).development.level)}get availableJobs(){return this.maxWorkers-this.workers.length}get filledJobs(){return this.workers.length}simulate(e){g(this,re).development.state===C.abandoned&&M(this,Re,tt).call(this)}dispose(){M(this,Re,tt).call(this)}toHTML(){let e=`<div class="info-heading">Workers (${this.filledJobs}/${this.maxWorkers})</div>`;e+='<ul class="info-citizen-list">';for(const s of this.workers)e+=s.toHTML();return e+="</ul>",e}}re=new WeakMap,Re=new WeakSet,tt=function(){for(const e of this.workers)e.setWorkplace(null);this.workers=[]};class ki extends it{constructor(e,s){super(e,s);A(this,"jobs",new Vt(this));this.name=Hi(),this.type=P.commercial}simulate(e){super.simulate(e),this.jobs.simulate()}dispose(){this.jobs.dispose(),super.dispose()}toHTML(){let e=super.toHTML();return e+=this.jobs.toHTML(),e}}const yt=["Prime","Elite","Global","Exquisite","Vibrant","Luxury","Innovative","Sleek","Premium","Dynamic"],Mt=["Commerce","Trade","Marketplace","Ventures","Enterprises","Retail","Group","Emporium","Boutique","Mall"],xt=["LLC","Inc.","Co.","Corp.","Ltd."];function Hi(){const l=yt[Math.floor(Math.random()*yt.length)],t=Mt[Math.floor(Math.random()*Mt.length)],e=xt[Math.floor(Math.random()*xt.length)];return l+" "+t+" "+e}class Bi extends Be{constructor(t,e){super(t,e),this.type="road",this.name="Road",this.style="straight",this.hideTerrain=!0,this.roadAccess.enabled=!1}refreshView(t){var a,r,c,u,h,d,f,m;let e=((r=(a=t.getTile(this.x,this.y-1))==null?void 0:a.building)==null?void 0:r.type)===this.type,s=((u=(c=t.getTile(this.x,this.y+1))==null?void 0:c.building)==null?void 0:u.type)===this.type,i=((d=(h=t.getTile(this.x-1,this.y))==null?void 0:h.building)==null?void 0:d.type)===this.type,n=((m=(f=t.getTile(this.x+1,this.y))==null?void 0:f.building)==null?void 0:m.type)===this.type;e&&s&&i&&n?(this.style="four-way",this.rotation.y=0):!e&&s&&i&&n?(this.style="three-way",this.rotation.y=0):e&&!s&&i&&n?(this.style="three-way",this.rotation.y=180*G):e&&s&&!i&&n?(this.style="three-way",this.rotation.y=90*G):e&&s&&i&&!n?(this.style="three-way",this.rotation.y=270*G):e&&!s&&i&&!n?(this.style="corner",this.rotation.y=180*G):e&&!s&&!i&&n?(this.style="corner",this.rotation.y=90*G):!e&&s&&i&&!n?(this.style="corner",this.rotation.y=270*G):!e&&s&&!i&&n?(this.style="corner",this.rotation.y=0):e&&s&&!i&&!n?(this.style="straight",this.rotation.y=0):!e&&!s&&i&&n?(this.style="straight",this.rotation.y=90*G):e&&!s&&!i&&!n?(this.style="end",this.rotation.y=180*G):!e&&s&&!i&&!n?(this.style="end",this.rotation.y=0):!e&&!s&&i&&!n?(this.style="end",this.rotation.y=270*G):!e&&!s&&!i&&n&&(this.style="end",this.rotation.y=90*G);const o=window.assetManager.getModel(`road-${this.style}`,this);this.setMesh(o),t.vehicleGraph.updateTile(this.x,this.y,this)}toHTML(){let t=super.toHTML();return t+=`
|
|
36
|
+
<span class="info-label">Style </span>
|
|
37
|
+
<span class="info-value">${this.style}</span>
|
|
38
|
+
<br>
|
|
39
|
+
`,t}}class Fi extends Be{constructor(e,s){super(e,s);A(this,"powerCapacity",100);A(this,"powerConsumed",0);this.type=P.powerPlant}get powerAvailable(){return this.roadAccess.value?this.powerCapacity-this.powerConsumed:0}refreshView(){let e=window.assetManager.getModel(this.type,this);this.setMesh(e)}toHTML(){let e=super.toHTML();return e+=`
|
|
40
|
+
<div class="info-heading">Power</div>
|
|
41
|
+
<span class="info-label">Power Capacity (kW)</span>
|
|
42
|
+
<span class="info-value">${this.powerCapacity}</span>
|
|
43
|
+
<br>
|
|
44
|
+
<span class="info-label">Power Consumed (kW)</span>
|
|
45
|
+
<span class="info-value">${this.powerConsumed}</span>
|
|
46
|
+
<br>
|
|
47
|
+
<span class="info-label">Power Available (kW)</span>
|
|
48
|
+
<span class="info-value">${this.powerAvailable}</span>
|
|
49
|
+
<br>
|
|
50
|
+
`,e}}const $={Left:"left",Right:"right",Top:"top",Bottom:"bottom"},Gi=new p.LineBasicMaterial({color:0});var ae,Ae,z,U;class zi extends Be{constructor(e,s){super(e,s);L(this,ae);L(this,z);this.type=P.powerLine,this.roadAccess.enabled=!1}refreshView(e){var c,u,h,d,f,m,y,w;let s=new p.Group,i=window.assetManager.getModel(this.type,this);i.rotation.y=Math.PI/4;let n=((u=(c=e.getTile(this.x,this.y-1))==null?void 0:c.building)==null?void 0:u.type)===this.type,o=((d=(h=e.getTile(this.x,this.y+1))==null?void 0:h.building)==null?void 0:d.type)===this.type,a=((m=(f=e.getTile(this.x-1,this.y))==null?void 0:f.building)==null?void 0:m.type)===this.type,r=((w=(y=e.getTile(this.x+1,this.y))==null?void 0:y.building)==null?void 0:w.type)===this.type;s.add(i),n&&M(this,ae,Ae).call(this,s,$.Top),o&&M(this,ae,Ae).call(this,s,$.Bottom),a&&M(this,ae,Ae).call(this,s,$.Left),r&&M(this,ae,Ae).call(this,s,$.Right),this.setMesh(s)}}ae=new WeakSet,Ae=function(e,s){switch(s){case $.Left:e.add(M(this,z,U).call(this,-.09,.36,.09,-.5,.36,.09)),e.add(M(this,z,U).call(this,-.09,.36,-.09,-.5,.36,-.09));break;case $.Right:e.add(M(this,z,U).call(this,.09,.36,.09,.5,.36,.09)),e.add(M(this,z,U).call(this,.09,.36,-.09,.5,.36,-.09));break;case $.Top:e.add(M(this,z,U).call(this,.09,.36,-.09,.09,.36,-.5)),e.add(M(this,z,U).call(this,-.09,.36,-.09,-.09,.36,-.5));break;case $.Bottom:e.add(M(this,z,U).call(this,.09,.36,.09,.09,.36,.5)),e.add(M(this,z,U).call(this,-.09,.36,.09,-.09,.36,.5));break}},z=new WeakSet,U=function(e,s,i,n,o,a){const r=[new p.Vector3(e,s,i),new p.Vector3(n,o,a)],c=new p.BufferGeometry().setFromPoints(r),u=new p.Line(c,Gi);return u.layers.set(1),u};function ji(l,t,e){switch(e){case P.residential:return new Ci;case P.commercial:return new ki;case P.industrial:return new _i;case P.road:return new Bi;case P.powerPlant:return new Fi;case P.powerLine:return new zi;default:console.error(`${e} is not a recognized building type.`)}}var W;class Vi extends st{constructor(e,s){super(e,s);A(this,"terrain","grass");L(this,W,null);this.name=`Tile-${this.x}-${this.y}`}get building(){return g(this,W)}setBuilding(e){g(this,W)&&(g(this,W).dispose(),this.remove(g(this,W))),D(this,W,e),e&&this.add(g(this,W))}refreshView(e){var s,i;if((s=this.building)==null||s.refreshView(e),(i=this.building)!=null&&i.hideTerrain)this.setMesh(null);else{const n=window.assetManager.getModel(this.terrain,this);n.name=this.terrain,this.setMesh(n)}}simulate(e){var s;(s=this.building)==null||s.simulate(e)}distanceTo(e){return Math.abs(this.x-e.x)+Math.abs(this.y-e.y)}toHTML(){let e=`
|
|
51
|
+
<div class="info-heading">Tile</div>
|
|
52
|
+
<span class="info-label">Coordinates </span>
|
|
53
|
+
<span class="info-value">X: ${this.x}, Y: ${this.y}</span>
|
|
54
|
+
<br>
|
|
55
|
+
<span class="info-label">Terrain </span>
|
|
56
|
+
<span class="info-value">${this.terrain}</span>
|
|
57
|
+
<br>
|
|
58
|
+
`;return this.building&&(e+=this.building.toHTML()),e}}W=new WeakMap;class x extends p.Object3D{constructor(t,e){super(),this.position.set(t,0,e),this.next=[]}connect(t){t&&(this.next.includes(t)||this.next.push(t))}disconnectAll(){this.next=[]}getRandomNextNode(){if(this.next.length===0)return null;{const t=Math.floor(this.next.length*Math.random());return this.next[t]}}}const T=.05,v=.25;class me extends p.Group{constructor(t,e,s){super(),this.position.set(t,0,e),this.rotation.set(0,s,0),this.roadRotation=Math.round(s*xi),this.left={in:null,out:null},this.right={in:null,out:null},this.top={in:null,out:null},this.bottom={in:null,out:null}}static create(t,e,s,i){switch(i){case"end":return new Ui(t,e,s);case"straight":return new Wi(t,e,s);case"corner":return new Ki(t,e,s);case"three-way":return new Xi(t,e,s);case"four-way":return new $i(t,e,s);default:console.error(`Road type ${i} is not a known value`)}}disconnectAll(){for(let t of this.children)t.disconnectAll(),t.removeFromParent()}getRandomNode(){const t=[];if(this.left.in&&t.push(this.left.in),this.right.in&&t.push(this.right.in),this.top.in&&t.push(this.top.in),this.bottom.in&&t.push(this.bottom.in),t.length>0){const e=Math.floor(t.length*Math.random());return t[e]}else return null}getWorldLeftSide(){switch(this.roadRotation){case 0:return this.left;case 90:return this.top;case 180:return this.right;case 270:return this.bottom;default:return this.left}}getWorldRightSide(){switch(this.roadRotation){case 0:return this.right;case 90:return this.bottom;case 180:return this.left;case 270:return this.top;default:return this.right}}getWorldTopSide(){switch(this.roadRotation){case 0:return this.top;case 90:return this.right;case 180:return this.bottom;case 270:return this.left;default:return this.top}}getWorldBottomSide(){switch(this.roadRotation){case 0:return this.bottom;case 90:return this.left;case 180:return this.top;case 270:return this.right;default:return this.bottom}}}class Ui extends me{constructor(t,e,s){super(t,e,s),this.name=`EndRoadTile (${this.position})`,this.bottom={in:new x(T,v),out:new x(-T,v)};const i={in:new x(T,0),out:new x(-T,0)};this.add(this.bottom.in),this.add(this.bottom.out),this.add(i.in),this.add(i.out),this.bottom.in.connect(i.in),i.in.connect(i.out),i.out.connect(this.bottom.out)}}class Wi extends me{constructor(t,e,s){super(t,e,s),this.name=`StraightRoadTile (${this.position})`,this.top={in:new x(-T,-v),out:new x(T,-v)},this.bottom={in:new x(T,v),out:new x(-T,v)},this.add(this.top.in),this.add(this.top.out),this.add(this.bottom.in),this.add(this.bottom.out),this.bottom.in.connect(this.top.out),this.top.in.connect(this.bottom.out)}}class Ki extends me{constructor(t,e,s){super(t,e,s),this.name=`CornerRoadTile (${this.position})`,this.bottom={in:new x(T,v+.1),out:new x(-T,v+.1)},this.right={in:new x(v+.1,-T),out:new x(v+.1,T)};const i=new x(v-1.5*T,v-1.5*T),n=new x(v-3*T,v-3*T);this.add(i),this.add(n),this.add(this.right.in),this.add(this.right.out),this.add(this.bottom.in),this.add(this.bottom.out),this.bottom.in.connect(i),i.connect(this.right.out),this.right.in.connect(n),n.connect(this.bottom.out)}}class Xi extends me{constructor(t,e,s){super(t,e,s),this.name=`TeeRoadTile (${this.position})`,this.left={in:new x(-v,T),out:new x(-v,-T)},this.right={in:new x(v,-T),out:new x(v,T)},this.bottom={in:new x(T,v),out:new x(-T,v)};const i=new x(-T,T),n=new x(T,T),o=new x(-T,-T),a=new x(T,-T);this.add(this.left.in),this.add(this.left.out),this.add(this.right.in),this.add(this.right.out),this.add(this.bottom.in),this.add(this.bottom.out),this.add(i),this.add(n),this.add(o),this.add(a),i.connect(n),n.connect(a),a.connect(o),o.connect(i),this.left.in.connect(i),this.right.in.connect(a),this.bottom.in.connect(n),i.connect(this.bottom.out),n.connect(this.right.out),o.connect(this.left.out)}}class $i extends me{constructor(t,e,s){super(t,e,s),this.name=`IntersectionRoadTile (${this.position})`,this.left={in:new x(-v,T),out:new x(-v,-T)},this.right={in:new x(v,-T),out:new x(v,T)},this.bottom={in:new x(T,v),out:new x(-T,v)},this.top={in:new x(-T,-v),out:new x(T,-v)};const i=new x(-T,T),n=new x(T,T),o=new x(-T,-T),a=new x(T,-T);this.add(this.left.in),this.add(this.left.out),this.add(this.right.in),this.add(this.right.out),this.add(this.bottom.in),this.add(this.bottom.out),this.add(this.top.in),this.add(this.top.out),this.add(i),this.add(n),this.add(o),this.add(a),i.connect(n),n.connect(a),a.connect(o),o.connect(i),this.left.in.connect(i),this.right.in.connect(a),this.bottom.in.connect(n),this.top.in.connect(o),i.connect(this.bottom.out),n.connect(this.right.out),a.connect(this.top.out),o.connect(this.left.out)}}const qi=new p.Vector3(0,1,0),Yi=new p.SphereGeometry(.03,6,6),Ji=new p.ConeGeometry(.02,1,6),Qi=new p.MeshBasicMaterial({color:5263615}),Zi=new p.MeshBasicMaterial({color:65280}),en=new p.MeshBasicMaterial({color:16711680});class tn extends p.Group{constructor(){super(),this.visible=!1}refreshView(t){this.clear();for(let e=0;e<t.size;e++)for(let s=0;s<t.size;s++){const i=t.getTile(e,s);if(i)for(const n of i.children)this.createNodeVisualization(n)}}createNodeVisualization(t){const e=new p.Mesh(Yi,t.next.length>0?Zi:en),s=new p.Vector3;if(t.getWorldPosition(s),e.position.set(s.x,s.y,s.z),t.next.length>0)for(const i of t.next){const n=new p.Vector3;i.getWorldPosition(n);const o=new p.Vector3;o.copy(n),o.sub(s);const a=o.length(),r=new p.Mesh(Ji,Qi);r.scale.set(1,a,1),r.quaternion.setFromUnitVectors(qi,o.clone().normalize());const c=new p.Vector3(0,a/2,0).applyQuaternion(r.quaternion.clone());r.position.set(s.x+c.x,s.y+c.y,s.z+c.z),this.add(r)}this.add(e)}}const sn=new p.Vector3(1,0,0);class nn extends st{constructor(t,e){super(),this.createdTime=Date.now(),this.cycleStartTime=this.createdTime,this.origin=t,this.destination=e,this.originWorldPosition=new p.Vector3,this.destinationWorldPosition=new p.Vector3,this.originToDestination=new p.Vector3,this.orientation=new p.Vector3,this.updateWorldPositions();const s=Object.entries(Ze).filter(n=>n[1].type==="vehicle").map(n=>n[0]),i=Math.floor(s.length*Math.random());this.setMesh(window.assetManager.getModel(s[i],this,!0))}get cycleTime(){const e=this.originToDestination.length()/_.vehicle.speed,s=(Date.now()-this.cycleStartTime)/e;return Math.max(0,Math.min(s,1))}get age(){return Date.now()-this.createdTime}simulate(){if(!this.origin||!this.destination){this.dispose();return}if(!this.destination.parent){this.dispose();return}if(this.age>_.vehicle.maxLifetime){this.dispose();return}this.cycleTime===1?this.pickNewDestination():(this.position.copy(this.originWorldPosition),this.position.lerp(this.destinationWorldPosition,this.cycleTime)),this.updateOpacity()}updateOpacity(){const t=e=>{this.traverse(s=>{s.material&&(s.material.opacity=Math.max(0,Math.min(e,1)))})};this.age<_.vehicle.fadeTime?t(this.age/_.vehicle.fadeTime):_.vehicle.maxLifetime-this.age<_.vehicle.fadeTime?t((_.vehicle.maxLifetime-this.age)/_.vehicle.fadeTime):t(1)}pickNewDestination(){var t;this.origin=this.destination,this.destination=(t=this.origin)==null?void 0:t.getRandomNextNode(),this.updateWorldPositions(),this.cycleStartTime=Date.now()}updateWorldPositions(){!this.origin||!this.destination||(this.origin.getWorldPosition(this.originWorldPosition),this.destination.getWorldPosition(this.destinationWorldPosition),this.originToDestination.copy(this.destinationWorldPosition),this.originToDestination.sub(this.originWorldPosition),this.orientation.copy(this.originToDestination),this.orientation.normalize(),this.quaternion.setFromUnitVectors(sn,this.orientation))}dispose(){this.traverse(t=>{var e;return(e=t.material)==null?void 0:e.dispose()}),this.removeFromParent()}toHTML(){return"Car"}}class on extends p.Group{constructor(t){super(),this.size=t,this.tiles=[],this.vehicles=new p.Group,this.add(this.vehicles),this.helper=new tn,this.add(this.helper);for(let e=0;e<this.size;e++){const s=[];for(let i=0;i<this.size;i++)s.push(null);this.tiles.push(s)}this.helper.refreshView(this),setInterval(this.spawnVehicle.bind(this),_.vehicle.spawnInterval)}updateVehicles(){for(const t of this.vehicles.children)t.simulate()}updateTile(t,e,s){var c,u,h,d,f,m,y,w,b,S,N,E,V,F,O,K;const i=this.getTile(t,e),n=this.getTile(t-1,e),o=this.getTile(t+1,e),a=this.getTile(t,e-1),r=this.getTile(t,e+1);if(i==null||i.disconnectAll(),(u=(c=n==null?void 0:n.getWorldRightSide())==null?void 0:c.out)==null||u.disconnectAll(),(d=(h=o==null?void 0:o.getWorldLeftSide())==null?void 0:h.out)==null||d.disconnectAll(),(m=(f=a==null?void 0:a.getWorldBottomSide())==null?void 0:f.out)==null||m.disconnectAll(),(w=(y=r==null?void 0:r.getWorldTopSide())==null?void 0:y.out)==null||w.disconnectAll(),s){const I=me.create(t,e,s.rotation.y,s.style);n&&((b=I.getWorldLeftSide().out)==null||b.connect(n.getWorldRightSide().in),(S=n.getWorldRightSide().out)==null||S.connect(I.getWorldLeftSide().in)),o&&((N=I.getWorldRightSide().out)==null||N.connect(o.getWorldLeftSide().in),(E=o.getWorldLeftSide().out)==null||E.connect(I.getWorldRightSide().in)),a&&((V=I.getWorldTopSide().out)==null||V.connect(a.getWorldBottomSide().in),(F=a.getWorldBottomSide().out)==null||F.connect(I.getWorldTopSide().in)),r&&((O=I.getWorldBottomSide().out)==null||O.connect(r.getWorldTopSide().in),(K=r.getWorldTopSide().out)==null||K.connect(I.getWorldBottomSide().in)),this.tiles[t][e]=I,this.add(I)}else this.tiles[t][e]=null;this.helper.refreshView(this)}getTile(t,e){return t>=0&&t<this.size&&e>=0&&e<this.size?this.tiles[t][e]:null}spawnVehicle(){const t=this.getStartingTile();if(t!=null){const e=t.getRandomNode(),s=e==null?void 0:e.getRandomNextNode();if(e&&s){const i=new nn(e,s);this.vehicles.add(i)}}}getStartingTile(){const t=[];for(let e=0;e<this.size;e++)for(let s=0;s<this.size;s++){let i=this.getTile(e,s);i&&t.push(i)}if(t.length===0)return null;{const e=Math.floor(t.length*Math.random());return t[e]}}}class rn{simulate(t){const e=[];for(let i=0;i<t.size;i++)for(let n=0;n<t.size;n++){const o=t.getTile(i,n),a=t.getTile(i,n).building;if(a)if(a.type===P.powerPlant){const r=a;r.powerConsumed=0,e.push({powerPlant:r,frontier:[o],visited:[]})}else a.power.supplied=0}if(e.length===0)return;let s=!0;for(;s;){s=!1;for(const i of e){const{powerPlant:n,frontier:o,visited:a}=i;if(n.powerAvailable!==0&&o.length>0){s=!0;const r=o.shift(),c=r.building;if(a.push(r),c.power.supplied<c.power.required){const b=Math.min(n.powerAvailable,c.power.required);n.powerConsumed+=b,c.power.supplied=b}const{x:u,y:h}=r,d=b=>b&&!a.includes(b)&&b.building;let f=t.getTile(u-1,h),m=t.getTile(u+1,h),y=t.getTile(u,h-1),w=t.getTile(u,h+1);d(f)&&o.push(f),d(m)&&o.push(m),d(y)&&o.push(y),d(w)&&o.push(w)}}}}dispose(){}toHTML(){}}class an extends p.Group{constructor(e,s="My City"){super();A(this,"debugMeshes",new p.Group);A(this,"root",new p.Group);A(this,"services",[]);A(this,"size",16);A(this,"simTime",0);A(this,"tiles",[]);A(this,"vehicleGraph");this.name=s,this.size=e,this.add(this.debugMeshes),this.add(this.root),this.tiles=[];for(let i=0;i<this.size;i++){const n=[];for(let o=0;o<this.size;o++){const a=new Vi(i,o);a.refreshView(this),this.root.add(a),n.push(a)}this.tiles.push(n)}this.services=[],this.services.push(new rn),this.vehicleGraph=new on(this.size),this.debugMeshes.add(this.vehicleGraph)}get population(){var s,i;let e=0;for(let n=0;n<this.size;n++)for(let o=0;o<this.size;o++){const a=this.getTile(n,o);e+=((i=(s=a.building)==null?void 0:s.residents)==null?void 0:i.count)??0}return e}getTile(e,s){return e===void 0||s===void 0||e<0||s<0||e>=this.size||s>=this.size?null:this.tiles[e][s]}simulate(e=1){let s=0;for(;s++<e;){this.services.forEach(i=>i.simulate(this));for(let i=0;i<this.size;i++)for(let n=0;n<this.size;n++)this.getTile(i,n).simulate(this)}this.simTime++}placeBuilding(e,s,i){var o,a,r,c;const n=this.getTile(e,s);n&&!n.building&&(n.setBuilding(ji(e,s,i)),n.refreshView(this),(o=this.getTile(e-1,s))==null||o.refreshView(this),(a=this.getTile(e+1,s))==null||a.refreshView(this),(r=this.getTile(e,s-1))==null||r.refreshView(this),(c=this.getTile(e,s+1))==null||c.refreshView(this),n.building.type===P.road&&this.vehicleGraph.updateTile(e,s,n.building))}bulldoze(e,s){var n,o,a,r;const i=this.getTile(e,s);i.building&&(i.building.type===P.road&&this.vehicleGraph.updateTile(e,s,null),i.building.dispose(),i.setBuilding(null),i.refreshView(this),(n=this.getTile(e-1,s))==null||n.refreshView(this),(o=this.getTile(e+1,s))==null||o.refreshView(this),(a=this.getTile(e,s-1))==null||a.refreshView(this),(r=this.getTile(e,s+1))==null||r.refreshView(this))}draw(){this.vehicleGraph.updateVehicles()}findTile(e,s,i){const n=this.getTile(e.x,e.y),o=new Set,a=[];for(a.push(n);a.length>0;){const r=a.shift();if(!(o.has(r.id)||(o.add(r.id),n.distanceTo(r)>i))&&(a.push(...this.getTileNeighbors(r.x,r.y)),s(r)))return r}return null}getTileNeighbors(e,s){const i=[];return e>0&&i.push(this.getTile(e-1,s)),e<this.size-1&&i.push(this.getTile(e+1,s)),s>0&&i.push(this.getTile(e,s-1)),s<this.size-1&&i.push(this.getTile(e,s+1)),i}}var De,Ut,ke,Wt,He,Kt;class cn{constructor(t){L(this,De);L(this,ke);L(this,He);A(this,"city");A(this,"focusedObject",null);A(this,"inputManager");A(this,"selectedObject",null);this.city=t,this.renderer=new p.WebGLRenderer({antialias:!0}),this.scene=new p.Scene,this.inputManager=new Mi(window.ui.gameWindow),this.cameraManager=new yi(window.ui.gameWindow),this.renderer.setSize(window.ui.gameWindow.clientWidth,window.ui.gameWindow.clientHeight),this.renderer.setClearColor(0,0),this.renderer.shadowMap.enabled=!0,this.renderer.shadowMap.type=p.PCFShadowMap,window.ui.gameWindow.appendChild(this.renderer.domElement),this.raycaster=new p.Raycaster,window.assetManager=new fi(()=>{window.ui.hideLoadingText(),this.city=new an(16),this.initialize(this.city),this.start(),setInterval(this.simulate.bind(this),1e3)}),window.addEventListener("resize",this.onResize.bind(this),!1)}initialize(t){this.scene.clear(),this.scene.add(t),M(this,ke,Wt).call(this),M(this,De,Ut).call(this,t)}start(){this.renderer.setAnimationLoop(this.draw.bind(this))}stop(){this.renderer.setAnimationLoop(null)}draw(){this.city.draw(),this.updateFocusedObject(),this.inputManager.isLeftMouseDown&&this.useTool(),this.renderer.render(this.scene,this.cameraManager.camera)}simulate(){window.ui.isPaused||(this.city.simulate(1),window.ui.updateTitleBar(this),window.ui.updateInfoPanel(this.selectedObject))}useTool(){switch(window.ui.activeToolId){case"select":this.updateSelectedObject(),window.ui.updateInfoPanel(this.selectedObject);break;case"bulldoze":if(this.focusedObject){const{x:t,y:e}=this.focusedObject;this.city.bulldoze(t,e)}break;default:if(this.focusedObject){const{x:t,y:e}=this.focusedObject;this.city.placeBuilding(t,e,window.ui.activeToolId)}break}}updateSelectedObject(){var t,e;(t=this.selectedObject)==null||t.setSelected(!1),this.selectedObject=this.focusedObject,(e=this.selectedObject)==null||e.setSelected(!0)}updateFocusedObject(){var e,s;(e=this.focusedObject)==null||e.setFocused(!1);const t=M(this,He,Kt).call(this);t!==this.focusedObject&&(this.focusedObject=t),(s=this.focusedObject)==null||s.setFocused(!0)}onResize(){this.cameraManager.resize(window.ui.gameWindow),this.renderer.setSize(window.ui.gameWindow.clientWidth,window.ui.gameWindow.clientHeight)}}De=new WeakSet,Ut=function(t){const e=new p.MeshBasicMaterial({color:0,map:window.assetManager.textures.grid,transparent:!0,opacity:.2});e.map.repeat=new p.Vector2(t.size,t.size),e.map.wrapS=t.size,e.map.wrapT=t.size;const s=new p.Mesh(new p.BoxGeometry(t.size,.1,t.size),e);s.position.set(t.size/2-.5,-.04,t.size/2-.5),this.scene.add(s)},ke=new WeakSet,Wt=function(){const t=new p.DirectionalLight(16777215,2);t.position.set(-10,20,0),t.castShadow=!0,t.shadow.camera.left=-20,t.shadow.camera.right=20,t.shadow.camera.top=20,t.shadow.camera.bottom=-20,t.shadow.mapSize.width=2048,t.shadow.mapSize.height=2048,t.shadow.camera.near=10,t.shadow.camera.far=50,t.shadow.normalBias=.01,this.scene.add(t),this.scene.add(new p.AmbientLight(16777215,.5))},He=new WeakSet,Kt=function(){var t={x:this.inputManager.mouse.x/this.renderer.domElement.clientWidth*2-1,y:-(this.inputManager.mouse.y/this.renderer.domElement.clientHeight)*2+1};this.raycaster.setFromCamera(t,this.cameraManager.camera);let e=this.raycaster.intersectObjects(this.city.root.children,!0);return e.length>0?e[0].object.userData:null};window.onload=()=>{window.game=new cn};const ln="/ingest/simcity/icons/play-color.png",hn="/ingest/simcity/icons/pause-color.png";class un{constructor(){A(this,"activeToolId","select");A(this,"selectedControl",document.getElementById("button-select"));A(this,"isPaused",!1)}get gameWindow(){return document.getElementById("render-target")}showLoadingText(){document.getElementById("loading").style.visibility="visible"}hideLoadingText(){document.getElementById("loading").style.visibility="hidden"}onToolSelected(t){this.selectedControl&&this.selectedControl.classList.remove("selected"),this.selectedControl=t.target,this.selectedControl.classList.add("selected"),this.activeToolId=this.selectedControl.getAttribute("data-type")}togglePause(){this.isPaused=!this.isPaused,this.isPaused?(document.getElementById("pause-button-icon").src=ln,document.getElementById("paused-text").style.visibility="visible"):(document.getElementById("pause-button-icon").src=hn,document.getElementById("paused-text").style.visibility="hidden")}updateTitleBar(t){document.getElementById("city-name").innerHTML=t.city.name,document.getElementById("population-counter").innerHTML=t.city.population;const e=new Date("1/1/2023");e.setDate(e.getDate()+t.city.simTime),document.getElementById("sim-time").innerHTML=e.toLocaleDateString()}updateInfoPanel(t){const e=document.getElementById("info-panel");t?(e.style.visibility="visible",e.innerHTML=t.toHTML()):(e.style.visibility="hidden",e.innerHTML="")}}window.ui=new un;
|