@fps-games/editor 0.2.0-beta.4 → 0.2.1-beta.2

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.
Files changed (1506) hide show
  1. package/dist/agent-bridge/capabilities/editor-state.d.ts.map +1 -1
  2. package/dist/agent-bridge/capabilities/editor-state.js +12 -6
  3. package/dist/agent-bridge/capabilities/editor-state.js.map +1 -1
  4. package/dist/agent-bridge/capabilities/hierarchy.d.ts +4 -0
  5. package/dist/agent-bridge/capabilities/hierarchy.d.ts.map +1 -0
  6. package/dist/agent-bridge/capabilities/hierarchy.js +209 -0
  7. package/dist/agent-bridge/capabilities/hierarchy.js.map +1 -0
  8. package/dist/agent-bridge/capabilities/prefabs.d.ts.map +1 -1
  9. package/dist/agent-bridge/capabilities/prefabs.js +208 -73
  10. package/dist/agent-bridge/capabilities/prefabs.js.map +1 -1
  11. package/dist/agent-bridge/capabilities/scene-objects.d.ts +3 -4
  12. package/dist/agent-bridge/capabilities/scene-objects.d.ts.map +1 -1
  13. package/dist/agent-bridge/capabilities/scene-objects.js +24 -23
  14. package/dist/agent-bridge/capabilities/scene-objects.js.map +1 -1
  15. package/dist/agent-bridge/capabilities/shadows.d.ts.map +1 -1
  16. package/dist/agent-bridge/capabilities/shadows.js +829 -66
  17. package/dist/agent-bridge/capabilities/shadows.js.map +1 -1
  18. package/dist/agent-bridge/capabilities/ui-regions.d.ts.map +1 -1
  19. package/dist/agent-bridge/capabilities/ui-regions.js +19 -1
  20. package/dist/agent-bridge/capabilities/ui-regions.js.map +1 -1
  21. package/dist/agent-bridge/capabilities/viewport.d.ts.map +1 -1
  22. package/dist/agent-bridge/capabilities/viewport.js +22 -9
  23. package/dist/agent-bridge/capabilities/viewport.js.map +1 -1
  24. package/dist/agent-bridge/capability-sources.d.ts.map +1 -1
  25. package/dist/agent-bridge/capability-sources.js +2 -0
  26. package/dist/agent-bridge/capability-sources.js.map +1 -1
  27. package/dist/agent-bridge/register.d.ts.map +1 -1
  28. package/dist/agent-bridge/register.js +194 -0
  29. package/dist/agent-bridge/register.js.map +1 -1
  30. package/dist/agent-bridge/shared.d.ts +231 -11
  31. package/dist/agent-bridge/shared.d.ts.map +1 -1
  32. package/dist/agent-bridge/shared.js +162 -20
  33. package/dist/agent-bridge/shared.js.map +1 -1
  34. package/dist/agent-bridge/source-types.d.ts +17 -1
  35. package/dist/agent-bridge/source-types.d.ts.map +1 -1
  36. package/dist/agent-bridge/source-types.js.map +1 -1
  37. package/dist/build-info.json +57 -42
  38. package/dist/index.d.ts +7 -6
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +4 -3
  41. package/dist/index.js.map +1 -1
  42. package/dist/internal/babylon-preview-engine.d.ts +3 -0
  43. package/dist/internal/babylon-preview-engine.d.ts.map +1 -0
  44. package/dist/internal/babylon-preview-engine.js +11 -0
  45. package/dist/internal/babylon-preview-engine.js.map +1 -0
  46. package/dist/internal/material-preview.d.ts +22 -0
  47. package/dist/internal/material-preview.d.ts.map +1 -0
  48. package/dist/internal/material-preview.js +186 -0
  49. package/dist/internal/material-preview.js.map +1 -0
  50. package/dist/internal/product-local-editor-cleanup.d.ts +5 -0
  51. package/dist/internal/product-local-editor-cleanup.d.ts.map +1 -0
  52. package/dist/internal/product-local-editor-cleanup.js +20 -0
  53. package/dist/internal/product-local-editor-cleanup.js.map +1 -0
  54. package/dist/internal/project-model-preview.d.ts +4 -0
  55. package/dist/internal/project-model-preview.d.ts.map +1 -0
  56. package/dist/internal/project-model-preview.js +359 -0
  57. package/dist/internal/project-model-preview.js.map +1 -0
  58. package/dist/local-editor-agent-actions.d.ts +2 -4
  59. package/dist/local-editor-agent-actions.d.ts.map +1 -1
  60. package/dist/local-editor-agent-actions.js +56 -32
  61. package/dist/local-editor-agent-actions.js.map +1 -1
  62. package/dist/local-editor-agent-context.d.ts +17 -6
  63. package/dist/local-editor-agent-context.d.ts.map +1 -1
  64. package/dist/local-editor-agent-context.js +47 -0
  65. package/dist/local-editor-agent-context.js.map +1 -1
  66. package/dist/local-editor-harness.d.ts +353 -35
  67. package/dist/local-editor-harness.d.ts.map +1 -1
  68. package/dist/local-editor-harness.js +4115 -1313
  69. package/dist/local-editor-harness.js.map +1 -1
  70. package/dist/local-editor-marker-graph.d.ts +15 -15
  71. package/dist/local-editor-marker-graph.d.ts.map +1 -1
  72. package/dist/local-editor-marker-graph.js +3 -0
  73. package/dist/local-editor-marker-graph.js.map +1 -1
  74. package/dist/local-editor-performance-stats.d.ts +3 -2
  75. package/dist/local-editor-performance-stats.d.ts.map +1 -1
  76. package/dist/local-editor-performance-stats.js.map +1 -1
  77. package/dist/local-editor-prefab-stage-transaction.d.ts +19 -0
  78. package/dist/local-editor-prefab-stage-transaction.d.ts.map +1 -0
  79. package/dist/local-editor-prefab-stage-transaction.js +45 -0
  80. package/dist/local-editor-prefab-stage-transaction.js.map +1 -0
  81. package/dist/local-editor-scene-view-interaction-runtime.d.ts +3 -1
  82. package/dist/local-editor-scene-view-interaction-runtime.d.ts.map +1 -1
  83. package/dist/local-editor-scene-view-interaction-runtime.js +24 -0
  84. package/dist/local-editor-scene-view-interaction-runtime.js.map +1 -1
  85. package/dist/local-editor-tools.d.ts +19 -0
  86. package/dist/local-editor-tools.d.ts.map +1 -0
  87. package/dist/local-editor-tools.js +56 -0
  88. package/dist/local-editor-tools.js.map +1 -0
  89. package/dist/playable-babylon-rendering.d.ts +9 -0
  90. package/dist/playable-babylon-rendering.d.ts.map +1 -1
  91. package/dist/playable-babylon-rendering.js +162 -6
  92. package/dist/playable-babylon-rendering.js.map +1 -1
  93. package/dist/playable-local-editor-entry.d.ts +68 -0
  94. package/dist/playable-local-editor-entry.d.ts.map +1 -0
  95. package/dist/playable-local-editor-entry.js +424 -0
  96. package/dist/playable-local-editor-entry.js.map +1 -0
  97. package/dist/playable-local-editor-host.d.ts +55 -29
  98. package/dist/playable-local-editor-host.d.ts.map +1 -1
  99. package/dist/playable-local-editor-host.js +50 -11
  100. package/dist/playable-local-editor-host.js.map +1 -1
  101. package/dist/playable-product-local-editor.d.ts +10 -12
  102. package/dist/playable-product-local-editor.d.ts.map +1 -1
  103. package/dist/playable-product-local-editor.js +178 -85
  104. package/dist/playable-product-local-editor.js.map +1 -1
  105. package/dist/playable-product-projection-preview.d.ts +4 -1
  106. package/dist/playable-product-projection-preview.d.ts.map +1 -1
  107. package/dist/playable-product-projection-preview.js +122 -5
  108. package/dist/playable-product-projection-preview.js.map +1 -1
  109. package/dist/playable-product-rendering.d.ts +12 -0
  110. package/dist/playable-product-rendering.d.ts.map +1 -1
  111. package/dist/playable-product-rendering.js +128 -6
  112. package/dist/playable-product-rendering.js.map +1 -1
  113. package/dist/playable-product-scene-capabilities.d.ts +24 -7
  114. package/dist/playable-product-scene-capabilities.d.ts.map +1 -1
  115. package/dist/playable-product-scene-capabilities.js +180 -17
  116. package/dist/playable-product-scene-capabilities.js.map +1 -1
  117. package/dist/playable-project-mode.d.ts +17 -0
  118. package/dist/playable-project-mode.d.ts.map +1 -0
  119. package/dist/playable-project-mode.js +2 -0
  120. package/dist/playable-project-mode.js.map +1 -0
  121. package/dist/playable-runtime-babylon.d.ts +3 -6
  122. package/dist/playable-runtime-babylon.d.ts.map +1 -1
  123. package/dist/playable-runtime-babylon.js +1 -5
  124. package/dist/playable-runtime-babylon.js.map +1 -1
  125. package/dist/playable-sdk.d.ts +16 -9
  126. package/dist/playable-sdk.d.ts.map +1 -1
  127. package/dist/playable-sdk.js +6 -4
  128. package/dist/playable-sdk.js.map +1 -1
  129. package/dist/playable-standard-project.d.ts +23 -14
  130. package/dist/playable-standard-project.d.ts.map +1 -1
  131. package/dist/playable-standard-project.js +57 -20
  132. package/dist/playable-standard-project.js.map +1 -1
  133. package/dist/vite-client.d.ts +4 -0
  134. package/node_modules/@babel/helper-string-parser/lib/index.js +0 -1
  135. package/node_modules/@babel/helper-validator-identifier/lib/identifier.js +0 -1
  136. package/node_modules/@babel/helper-validator-identifier/lib/index.js +0 -1
  137. package/node_modules/@babel/helper-validator-identifier/lib/keyword.js +0 -1
  138. package/node_modules/@babel/parser/lib/index.js +0 -1
  139. package/node_modules/@babel/types/lib/asserts/assertNode.js +0 -1
  140. package/node_modules/@babel/types/lib/asserts/generated/index.js +0 -1
  141. package/node_modules/@babel/types/lib/ast-types/generated/index.js +0 -1
  142. package/node_modules/@babel/types/lib/builders/flow/createFlowUnionType.js +0 -1
  143. package/node_modules/@babel/types/lib/builders/flow/createTypeAnnotationBasedOnTypeof.js +0 -1
  144. package/node_modules/@babel/types/lib/builders/generated/index.js +0 -1
  145. package/node_modules/@babel/types/lib/builders/generated/lowercase.js +0 -1
  146. package/node_modules/@babel/types/lib/builders/generated/uppercase.js +0 -1
  147. package/node_modules/@babel/types/lib/builders/productions.js +0 -1
  148. package/node_modules/@babel/types/lib/builders/react/buildChildren.js +0 -1
  149. package/node_modules/@babel/types/lib/builders/typescript/createTSUnionType.js +0 -1
  150. package/node_modules/@babel/types/lib/builders/validateNode.js +0 -1
  151. package/node_modules/@babel/types/lib/clone/clone.js +0 -1
  152. package/node_modules/@babel/types/lib/clone/cloneDeep.js +0 -1
  153. package/node_modules/@babel/types/lib/clone/cloneDeepWithoutLoc.js +0 -1
  154. package/node_modules/@babel/types/lib/clone/cloneNode.js +0 -1
  155. package/node_modules/@babel/types/lib/clone/cloneWithoutLoc.js +0 -1
  156. package/node_modules/@babel/types/lib/comments/addComment.js +0 -1
  157. package/node_modules/@babel/types/lib/comments/addComments.js +0 -1
  158. package/node_modules/@babel/types/lib/comments/inheritInnerComments.js +0 -1
  159. package/node_modules/@babel/types/lib/comments/inheritLeadingComments.js +0 -1
  160. package/node_modules/@babel/types/lib/comments/inheritTrailingComments.js +0 -1
  161. package/node_modules/@babel/types/lib/comments/inheritsComments.js +0 -1
  162. package/node_modules/@babel/types/lib/comments/removeComments.js +0 -1
  163. package/node_modules/@babel/types/lib/constants/generated/index.js +0 -1
  164. package/node_modules/@babel/types/lib/constants/index.js +0 -1
  165. package/node_modules/@babel/types/lib/converters/ensureBlock.js +0 -1
  166. package/node_modules/@babel/types/lib/converters/gatherSequenceExpressions.js +0 -1
  167. package/node_modules/@babel/types/lib/converters/toBindingIdentifierName.js +0 -1
  168. package/node_modules/@babel/types/lib/converters/toBlock.js +0 -1
  169. package/node_modules/@babel/types/lib/converters/toComputedKey.js +0 -1
  170. package/node_modules/@babel/types/lib/converters/toExpression.js +0 -1
  171. package/node_modules/@babel/types/lib/converters/toIdentifier.js +0 -1
  172. package/node_modules/@babel/types/lib/converters/toKeyAlias.js +0 -1
  173. package/node_modules/@babel/types/lib/converters/toSequenceExpression.js +0 -1
  174. package/node_modules/@babel/types/lib/converters/toStatement.js +0 -1
  175. package/node_modules/@babel/types/lib/converters/valueToNode.js +0 -1
  176. package/node_modules/@babel/types/lib/definitions/core.js +0 -1
  177. package/node_modules/@babel/types/lib/definitions/deprecated-aliases.js +0 -1
  178. package/node_modules/@babel/types/lib/definitions/experimental.js +0 -1
  179. package/node_modules/@babel/types/lib/definitions/flow.js +0 -1
  180. package/node_modules/@babel/types/lib/definitions/index.js +0 -1
  181. package/node_modules/@babel/types/lib/definitions/jsx.js +0 -1
  182. package/node_modules/@babel/types/lib/definitions/misc.js +0 -1
  183. package/node_modules/@babel/types/lib/definitions/placeholders.js +0 -1
  184. package/node_modules/@babel/types/lib/definitions/typescript.js +0 -1
  185. package/node_modules/@babel/types/lib/definitions/utils.js +0 -1
  186. package/node_modules/@babel/types/lib/index.js +0 -1
  187. package/node_modules/@babel/types/lib/modifications/appendToMemberExpression.js +0 -1
  188. package/node_modules/@babel/types/lib/modifications/flow/removeTypeDuplicates.js +0 -1
  189. package/node_modules/@babel/types/lib/modifications/inherits.js +0 -1
  190. package/node_modules/@babel/types/lib/modifications/prependToMemberExpression.js +0 -1
  191. package/node_modules/@babel/types/lib/modifications/removeProperties.js +0 -1
  192. package/node_modules/@babel/types/lib/modifications/removePropertiesDeep.js +0 -1
  193. package/node_modules/@babel/types/lib/modifications/typescript/removeTypeDuplicates.js +0 -1
  194. package/node_modules/@babel/types/lib/retrievers/getAssignmentIdentifiers.js +0 -1
  195. package/node_modules/@babel/types/lib/retrievers/getBindingIdentifiers.js +0 -1
  196. package/node_modules/@babel/types/lib/retrievers/getFunctionName.js +0 -1
  197. package/node_modules/@babel/types/lib/retrievers/getOuterBindingIdentifiers.js +0 -1
  198. package/node_modules/@babel/types/lib/traverse/traverse.js +0 -1
  199. package/node_modules/@babel/types/lib/traverse/traverseFast.js +0 -1
  200. package/node_modules/@babel/types/lib/utils/deprecationWarning.js +0 -1
  201. package/node_modules/@babel/types/lib/utils/inherit.js +0 -1
  202. package/node_modules/@babel/types/lib/utils/react/cleanJSXElementLiteralChild.js +0 -1
  203. package/node_modules/@babel/types/lib/utils/shallowEqual.js +0 -1
  204. package/node_modules/@babel/types/lib/validators/buildMatchMemberExpression.js +0 -1
  205. package/node_modules/@babel/types/lib/validators/generated/index.js +0 -1
  206. package/node_modules/@babel/types/lib/validators/is.js +0 -1
  207. package/node_modules/@babel/types/lib/validators/isBinding.js +0 -1
  208. package/node_modules/@babel/types/lib/validators/isBlockScoped.js +0 -1
  209. package/node_modules/@babel/types/lib/validators/isImmutable.js +0 -1
  210. package/node_modules/@babel/types/lib/validators/isLet.js +0 -1
  211. package/node_modules/@babel/types/lib/validators/isNode.js +0 -1
  212. package/node_modules/@babel/types/lib/validators/isNodesEquivalent.js +0 -1
  213. package/node_modules/@babel/types/lib/validators/isPlaceholderType.js +0 -1
  214. package/node_modules/@babel/types/lib/validators/isReferenced.js +0 -1
  215. package/node_modules/@babel/types/lib/validators/isScope.js +0 -1
  216. package/node_modules/@babel/types/lib/validators/isSpecifierDefault.js +0 -1
  217. package/node_modules/@babel/types/lib/validators/isType.js +0 -1
  218. package/node_modules/@babel/types/lib/validators/isValidES3Identifier.js +0 -1
  219. package/node_modules/@babel/types/lib/validators/isValidIdentifier.js +0 -1
  220. package/node_modules/@babel/types/lib/validators/isVar.js +0 -1
  221. package/node_modules/@babel/types/lib/validators/matchesPattern.js +0 -1
  222. package/node_modules/@babel/types/lib/validators/react/isCompatTag.js +0 -1
  223. package/node_modules/@babel/types/lib/validators/react/isReactComponent.js +0 -1
  224. package/node_modules/@babel/types/lib/validators/validate.js +0 -1
  225. package/node_modules/@babylonjs/loaders/BVH/bvhFileLoader.d.ts +69 -0
  226. package/node_modules/@babylonjs/loaders/BVH/bvhFileLoader.js +132 -0
  227. package/node_modules/@babylonjs/loaders/BVH/bvhFileLoader.metadata.d.ts +8 -0
  228. package/node_modules/@babylonjs/loaders/BVH/bvhFileLoader.metadata.js +7 -0
  229. package/node_modules/@babylonjs/loaders/BVH/bvhLoader.d.ts +14 -0
  230. package/node_modules/@babylonjs/loaders/BVH/bvhLoader.js +328 -0
  231. package/node_modules/@babylonjs/loaders/BVH/bvhLoadingOptions.d.ts +9 -0
  232. package/node_modules/@babylonjs/loaders/BVH/bvhLoadingOptions.js +1 -0
  233. package/node_modules/@babylonjs/loaders/BVH/index.d.ts +2 -0
  234. package/node_modules/@babylonjs/loaders/BVH/index.js +3 -0
  235. package/node_modules/@babylonjs/loaders/OBJ/index.d.ts +4 -0
  236. package/node_modules/@babylonjs/loaders/OBJ/index.js +4 -0
  237. package/node_modules/@babylonjs/loaders/OBJ/mtlFileLoader.d.ts +41 -0
  238. package/node_modules/@babylonjs/loaders/OBJ/mtlFileLoader.js +230 -0
  239. package/node_modules/@babylonjs/loaders/OBJ/objFileLoader.d.ts +136 -0
  240. package/node_modules/@babylonjs/loaders/OBJ/objFileLoader.js +317 -0
  241. package/node_modules/@babylonjs/loaders/OBJ/objFileLoader.metadata.d.ts +4 -0
  242. package/node_modules/@babylonjs/loaders/OBJ/objFileLoader.metadata.js +4 -0
  243. package/node_modules/@babylonjs/loaders/OBJ/objLoadingOptions.d.ts +47 -0
  244. package/node_modules/@babylonjs/loaders/OBJ/objLoadingOptions.js +1 -0
  245. package/node_modules/@babylonjs/loaders/OBJ/solidParser.d.ts +175 -0
  246. package/node_modules/@babylonjs/loaders/OBJ/solidParser.js +903 -0
  247. package/node_modules/@babylonjs/loaders/SPLAT/index.d.ts +2 -0
  248. package/node_modules/@babylonjs/loaders/SPLAT/index.js +3 -0
  249. package/node_modules/@babylonjs/loaders/SPLAT/sog.d.ts +84 -0
  250. package/node_modules/@babylonjs/loaders/SPLAT/sog.js +294 -0
  251. package/node_modules/@babylonjs/loaders/SPLAT/splatDefs.d.ts +26 -0
  252. package/node_modules/@babylonjs/loaders/SPLAT/splatDefs.js +10 -0
  253. package/node_modules/@babylonjs/loaders/SPLAT/splatFileLoader.d.ts +100 -0
  254. package/node_modules/@babylonjs/loaders/SPLAT/splatFileLoader.js +536 -0
  255. package/node_modules/@babylonjs/loaders/SPLAT/splatFileLoader.metadata.d.ts +20 -0
  256. package/node_modules/@babylonjs/loaders/SPLAT/splatFileLoader.metadata.js +15 -0
  257. package/node_modules/@babylonjs/loaders/SPLAT/splatLoadingOptions.d.ts +33 -0
  258. package/node_modules/@babylonjs/loaders/SPLAT/splatLoadingOptions.js +1 -0
  259. package/node_modules/@babylonjs/loaders/SPLAT/spz.d.ts +11 -0
  260. package/node_modules/@babylonjs/loaders/SPLAT/spz.js +168 -0
  261. package/node_modules/@babylonjs/loaders/STL/index.d.ts +1 -0
  262. package/node_modules/@babylonjs/loaders/STL/index.js +1 -0
  263. package/node_modules/@babylonjs/loaders/STL/stlFileLoader.d.ts +78 -0
  264. package/node_modules/@babylonjs/loaders/STL/stlFileLoader.js +238 -0
  265. package/node_modules/@babylonjs/loaders/STL/stlFileLoader.metadata.d.ts +8 -0
  266. package/node_modules/@babylonjs/loaders/STL/stlFileLoader.metadata.js +7 -0
  267. package/node_modules/@babylonjs/loaders/bvh/license.md +21 -0
  268. package/node_modules/@babylonjs/loaders/dynamic.d.ts +5 -0
  269. package/node_modules/@babylonjs/loaders/dynamic.js +56 -0
  270. package/node_modules/@babylonjs/loaders/glTF/1.0/glTFBinaryExtension.d.ts +16 -0
  271. package/node_modules/@babylonjs/loaders/glTF/1.0/glTFBinaryExtension.js +64 -0
  272. package/node_modules/@babylonjs/loaders/glTF/1.0/glTFLoader.d.ts +144 -0
  273. package/node_modules/@babylonjs/loaders/glTF/1.0/glTFLoader.js +1841 -0
  274. package/node_modules/@babylonjs/loaders/glTF/1.0/glTFLoaderInterfaces.d.ts +412 -0
  275. package/node_modules/@babylonjs/loaders/glTF/1.0/glTFLoaderInterfaces.js +95 -0
  276. package/node_modules/@babylonjs/loaders/glTF/1.0/glTFLoaderUtils.d.ts +71 -0
  277. package/node_modules/@babylonjs/loaders/glTF/1.0/glTFLoaderUtils.js +254 -0
  278. package/node_modules/@babylonjs/loaders/glTF/1.0/glTFMaterialsCommonExtension.d.ts +13 -0
  279. package/node_modules/@babylonjs/loaders/glTF/1.0/glTFMaterialsCommonExtension.js +130 -0
  280. package/node_modules/@babylonjs/loaders/glTF/1.0/index.d.ts +5 -0
  281. package/node_modules/@babylonjs/loaders/glTF/1.0/index.js +5 -0
  282. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/EXT_lights_area.d.ts +41 -0
  283. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/EXT_lights_area.js +93 -0
  284. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/EXT_lights_ies.d.ts +41 -0
  285. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/EXT_lights_ies.js +83 -0
  286. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/EXT_lights_image_based.d.ts +48 -0
  287. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/EXT_lights_image_based.js +115 -0
  288. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.d.ts +39 -0
  289. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/EXT_mesh_gpu_instancing.js +94 -0
  290. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/EXT_meshopt_compression.d.ts +39 -0
  291. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/EXT_meshopt_compression.js +50 -0
  292. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/EXT_texture_avif.d.ts +34 -0
  293. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/EXT_texture_avif.js +38 -0
  294. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/EXT_texture_webp.d.ts +33 -0
  295. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/EXT_texture_webp.js +37 -0
  296. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/ExtrasAsMetadata.d.ts +53 -0
  297. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/ExtrasAsMetadata.js +73 -0
  298. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_animation_pointer.d.ts +47 -0
  299. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_animation_pointer.data.d.ts +1 -0
  300. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_animation_pointer.data.js +251 -0
  301. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_animation_pointer.js +77 -0
  302. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_draco_mesh_compression.d.ts +47 -0
  303. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_draco_mesh_compression.js +92 -0
  304. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_interactivity/declarationMapper.d.ts +355 -0
  305. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_interactivity/declarationMapper.js +1678 -0
  306. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_interactivity/flowGraphGLTFDataProvider.d.ts +33 -0
  307. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_interactivity/flowGraphGLTFDataProvider.js +19 -0
  308. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_interactivity/index.d.ts +3 -0
  309. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_interactivity/index.js +3 -0
  310. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphParser.d.ts +70 -0
  311. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_interactivity/interactivityGraphParser.js +438 -0
  312. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_interactivity.d.ts +38 -0
  313. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_interactivity.js +150 -0
  314. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_lights_punctual.d.ts +41 -0
  315. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_lights_punctual.js +91 -0
  316. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_anisotropy.d.ts +42 -0
  317. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_anisotropy.js +65 -0
  318. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_clearcoat.d.ts +43 -0
  319. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_clearcoat.js +79 -0
  320. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_coat.d.ts +49 -0
  321. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_coat.js +119 -0
  322. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.d.ts +43 -0
  323. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_diffuse_roughness.js +58 -0
  324. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.d.ts +43 -0
  325. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_diffuse_transmission.js +69 -0
  326. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_dispersion.d.ts +43 -0
  327. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_dispersion.js +56 -0
  328. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_emissive_strength.d.ts +42 -0
  329. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_emissive_strength.js +47 -0
  330. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_fuzz.d.ts +43 -0
  331. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_fuzz.js +77 -0
  332. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_ior.d.ts +46 -0
  333. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_ior.js +54 -0
  334. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_iridescence.d.ts +42 -0
  335. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_iridescence.js +68 -0
  336. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.d.ts +42 -0
  337. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.js +80 -0
  338. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_sheen.d.ts +43 -0
  339. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_sheen.js +73 -0
  340. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_specular.d.ts +42 -0
  341. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_specular.js +76 -0
  342. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_transmission.d.ts +42 -0
  343. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_transmission.js +303 -0
  344. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_unlit.d.ts +42 -0
  345. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_unlit.js +66 -0
  346. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_variants.d.ts +112 -0
  347. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_variants.js +262 -0
  348. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_volume.d.ts +43 -0
  349. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_volume.js +82 -0
  350. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_volume_scatter.d.ts +45 -0
  351. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_materials_volume_scatter.js +109 -0
  352. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_mesh_quantization.d.ts +29 -0
  353. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_mesh_quantization.js +22 -0
  354. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_node_hoverability.d.ts +31 -0
  355. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_node_hoverability.js +189 -0
  356. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_node_selectability.d.ts +30 -0
  357. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_node_selectability.js +123 -0
  358. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_node_visibility.d.ts +30 -0
  359. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_node_visibility.js +66 -0
  360. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_texture_basisu.d.ts +33 -0
  361. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_texture_basisu.js +37 -0
  362. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_texture_transform.d.ts +37 -0
  363. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_texture_transform.js +58 -0
  364. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_xmp_json_ld.d.ts +39 -0
  365. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/KHR_xmp_json_ld.js +47 -0
  366. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/MSFT_audio_emitter.d.ts +56 -0
  367. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/MSFT_audio_emitter.js +228 -0
  368. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/MSFT_lod.d.ts +104 -0
  369. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/MSFT_lod.js +337 -0
  370. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/MSFT_minecraftMesh.d.ts +27 -0
  371. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/MSFT_minecraftMesh.js +39 -0
  372. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/MSFT_sRGBFactors.d.ts +27 -0
  373. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/MSFT_sRGBFactors.js +38 -0
  374. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/dynamic.d.ts +4 -0
  375. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/dynamic.js +212 -0
  376. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/gltfPathToObjectConverter.d.ts +45 -0
  377. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/gltfPathToObjectConverter.js +100 -0
  378. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/index.d.ts +43 -0
  379. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/index.js +44 -0
  380. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/objectModelMapping.d.ts +306 -0
  381. package/node_modules/@babylonjs/loaders/glTF/2.0/Extensions/objectModelMapping.js +884 -0
  382. package/node_modules/@babylonjs/loaders/glTF/2.0/glTFLoader.d.ts +450 -0
  383. package/node_modules/@babylonjs/loaders/glTF/2.0/glTFLoader.js +2485 -0
  384. package/node_modules/@babylonjs/loaders/glTF/2.0/glTFLoaderAnimation.d.ts +42 -0
  385. package/node_modules/@babylonjs/loaders/glTF/2.0/glTFLoaderAnimation.js +79 -0
  386. package/node_modules/@babylonjs/loaders/glTF/2.0/glTFLoaderExtension.d.ts +165 -0
  387. package/node_modules/@babylonjs/loaders/glTF/2.0/glTFLoaderExtension.js +1 -0
  388. package/node_modules/@babylonjs/loaders/glTF/2.0/glTFLoaderExtensionRegistry.d.ts +25 -0
  389. package/node_modules/@babylonjs/loaders/glTF/2.0/glTFLoaderExtensionRegistry.js +32 -0
  390. package/node_modules/@babylonjs/loaders/glTF/2.0/glTFLoaderInterfaces.d.ts +262 -0
  391. package/node_modules/@babylonjs/loaders/glTF/2.0/glTFLoaderInterfaces.js +1 -0
  392. package/node_modules/@babylonjs/loaders/glTF/2.0/index.d.ts +8 -0
  393. package/node_modules/@babylonjs/loaders/glTF/2.0/index.js +9 -0
  394. package/node_modules/@babylonjs/loaders/glTF/2.0/materialLoadingAdapter.d.ts +364 -0
  395. package/node_modules/@babylonjs/loaders/glTF/2.0/materialLoadingAdapter.js +1 -0
  396. package/node_modules/@babylonjs/loaders/glTF/2.0/openpbrMaterialLoadingAdapter.d.ts +674 -0
  397. package/node_modules/@babylonjs/loaders/glTF/2.0/openpbrMaterialLoadingAdapter.js +1034 -0
  398. package/node_modules/@babylonjs/loaders/glTF/2.0/pbrMaterialLoadingAdapter.d.ts +705 -0
  399. package/node_modules/@babylonjs/loaders/glTF/2.0/pbrMaterialLoadingAdapter.js +1126 -0
  400. package/node_modules/@babylonjs/loaders/glTF/glTFFileLoader.d.ts +553 -0
  401. package/node_modules/@babylonjs/loaders/glTF/glTFFileLoader.js +998 -0
  402. package/node_modules/@babylonjs/loaders/glTF/glTFFileLoader.metadata.d.ts +15 -0
  403. package/node_modules/@babylonjs/loaders/glTF/glTFFileLoader.metadata.js +17 -0
  404. package/node_modules/@babylonjs/loaders/glTF/glTFValidation.d.ts +35 -0
  405. package/node_modules/@babylonjs/loaders/glTF/glTFValidation.js +131 -0
  406. package/node_modules/@babylonjs/loaders/glTF/index.d.ts +5 -0
  407. package/node_modules/@babylonjs/loaders/glTF/index.js +6 -0
  408. package/node_modules/@babylonjs/loaders/index.d.ts +6 -0
  409. package/node_modules/@babylonjs/loaders/index.js +7 -0
  410. package/node_modules/@babylonjs/loaders/legacy/legacy-bvhFileLoader.d.ts +1 -0
  411. package/node_modules/@babylonjs/loaders/legacy/legacy-bvhFileLoader.js +15 -0
  412. package/node_modules/@babylonjs/loaders/legacy/legacy-dynamic.d.ts +1 -0
  413. package/node_modules/@babylonjs/loaders/legacy/legacy-dynamic.js +13 -0
  414. package/node_modules/@babylonjs/loaders/legacy/legacy-glTF.d.ts +2 -0
  415. package/node_modules/@babylonjs/loaders/legacy/legacy-glTF.js +18 -0
  416. package/node_modules/@babylonjs/loaders/legacy/legacy-glTF1.d.ts +2 -0
  417. package/node_modules/@babylonjs/loaders/legacy/legacy-glTF1.js +15 -0
  418. package/node_modules/@babylonjs/loaders/legacy/legacy-glTF1FileLoader.d.ts +2 -0
  419. package/node_modules/@babylonjs/loaders/legacy/legacy-glTF1FileLoader.js +3 -0
  420. package/node_modules/@babylonjs/loaders/legacy/legacy-glTF2.d.ts +2 -0
  421. package/node_modules/@babylonjs/loaders/legacy/legacy-glTF2.js +34 -0
  422. package/node_modules/@babylonjs/loaders/legacy/legacy-glTF2FileLoader.d.ts +2 -0
  423. package/node_modules/@babylonjs/loaders/legacy/legacy-glTF2FileLoader.js +3 -0
  424. package/node_modules/@babylonjs/loaders/legacy/legacy-glTFFileLoader.d.ts +3 -0
  425. package/node_modules/@babylonjs/loaders/legacy/legacy-glTFFileLoader.js +4 -0
  426. package/node_modules/@babylonjs/loaders/legacy/legacy-objFileLoader.d.ts +1 -0
  427. package/node_modules/@babylonjs/loaders/legacy/legacy-objFileLoader.js +15 -0
  428. package/node_modules/@babylonjs/loaders/legacy/legacy-stlFileLoader.d.ts +1 -0
  429. package/node_modules/@babylonjs/loaders/legacy/legacy-stlFileLoader.js +15 -0
  430. package/node_modules/@babylonjs/loaders/legacy/legacy.d.ts +8 -0
  431. package/node_modules/@babylonjs/loaders/legacy/legacy.js +10 -0
  432. package/node_modules/@babylonjs/loaders/license.md +71 -0
  433. package/node_modules/@babylonjs/loaders/package.json +49 -0
  434. package/node_modules/@babylonjs/loaders/readme.md +23 -0
  435. package/node_modules/@fps-games/babylon-renderer/dist/game-world-plugin-lifecycle.d.ts +22 -0
  436. package/node_modules/@fps-games/babylon-renderer/dist/game-world-plugin-lifecycle.d.ts.map +1 -0
  437. package/node_modules/@fps-games/babylon-renderer/dist/game-world-plugin-lifecycle.js +187 -0
  438. package/node_modules/@fps-games/babylon-renderer/dist/game-world-plugin-lifecycle.js.map +1 -0
  439. package/node_modules/@fps-games/babylon-renderer/dist/index.d.ts +3 -0
  440. package/node_modules/@fps-games/babylon-renderer/dist/index.d.ts.map +1 -1
  441. package/node_modules/@fps-games/babylon-renderer/dist/index.js +3 -0
  442. package/node_modules/@fps-games/babylon-renderer/dist/index.js.map +1 -1
  443. package/node_modules/@fps-games/babylon-renderer/dist/material-owner-candidates.d.ts +19 -0
  444. package/node_modules/@fps-games/babylon-renderer/dist/material-owner-candidates.d.ts.map +1 -0
  445. package/node_modules/@fps-games/babylon-renderer/dist/material-owner-candidates.js +212 -0
  446. package/node_modules/@fps-games/babylon-renderer/dist/material-owner-candidates.js.map +1 -0
  447. package/node_modules/@fps-games/babylon-renderer/dist/plugin.d.ts +17 -2
  448. package/node_modules/@fps-games/babylon-renderer/dist/plugin.d.ts.map +1 -1
  449. package/node_modules/@fps-games/babylon-renderer/dist/plugin.js +192 -17
  450. package/node_modules/@fps-games/babylon-renderer/dist/plugin.js.map +1 -1
  451. package/node_modules/@fps-games/babylon-renderer/dist/post-process/babylon-default-pipeline.d.ts +2 -0
  452. package/node_modules/@fps-games/babylon-renderer/dist/post-process/babylon-default-pipeline.d.ts.map +1 -1
  453. package/node_modules/@fps-games/babylon-renderer/dist/post-process/babylon-default-pipeline.js +139 -3
  454. package/node_modules/@fps-games/babylon-renderer/dist/post-process/babylon-default-pipeline.js.map +1 -1
  455. package/node_modules/@fps-games/babylon-renderer/dist/post-process/types.d.ts +4 -0
  456. package/node_modules/@fps-games/babylon-renderer/dist/post-process/types.d.ts.map +1 -1
  457. package/node_modules/@fps-games/babylon-renderer/dist/post-process/types.js.map +1 -1
  458. package/node_modules/@fps-games/babylon-renderer/dist/shadows/dynamic-shadow-system.d.ts +1 -0
  459. package/node_modules/@fps-games/babylon-renderer/dist/shadows/dynamic-shadow-system.d.ts.map +1 -1
  460. package/node_modules/@fps-games/babylon-renderer/dist/shadows/dynamic-shadow-system.js +1 -0
  461. package/node_modules/@fps-games/babylon-renderer/dist/shadows/dynamic-shadow-system.js.map +1 -1
  462. package/node_modules/@fps-games/babylon-renderer/dist/shadows/shadow-generator-shaders.d.ts +14 -0
  463. package/node_modules/@fps-games/babylon-renderer/dist/shadows/shadow-generator-shaders.d.ts.map +1 -0
  464. package/node_modules/@fps-games/babylon-renderer/dist/shadows/shadow-generator-shaders.js +14 -0
  465. package/node_modules/@fps-games/babylon-renderer/dist/shadows/shadow-generator-shaders.js.map +1 -0
  466. package/node_modules/@fps-games/babylon-renderer/dist/shadows/shadow-map-experiment-depth-backend.d.ts +59 -0
  467. package/node_modules/@fps-games/babylon-renderer/dist/shadows/shadow-map-experiment-depth-backend.d.ts.map +1 -0
  468. package/node_modules/@fps-games/babylon-renderer/dist/shadows/shadow-map-experiment-depth-backend.js +725 -0
  469. package/node_modules/@fps-games/babylon-renderer/dist/shadows/shadow-map-experiment-depth-backend.js.map +1 -0
  470. package/node_modules/@fps-games/babylon-renderer/dist/shadows/shadow-map-experiment-system.d.ts +136 -0
  471. package/node_modules/@fps-games/babylon-renderer/dist/shadows/shadow-map-experiment-system.d.ts.map +1 -0
  472. package/node_modules/@fps-games/babylon-renderer/dist/shadows/shadow-map-experiment-system.js +2735 -0
  473. package/node_modules/@fps-games/babylon-renderer/dist/shadows/shadow-map-experiment-system.js.map +1 -0
  474. package/node_modules/@fps-games/babylon-renderer/package.json +7 -7
  475. package/node_modules/@fps-games/editor-babylon/dist/camera-controller.js +1 -1
  476. package/node_modules/@fps-games/editor-babylon/dist/camera-controller.js.map +1 -1
  477. package/node_modules/@fps-games/editor-babylon/dist/index.d.ts +2 -1
  478. package/node_modules/@fps-games/editor-babylon/dist/index.d.ts.map +1 -1
  479. package/node_modules/@fps-games/editor-babylon/dist/index.js +2 -1
  480. package/node_modules/@fps-games/editor-babylon/dist/index.js.map +1 -1
  481. package/node_modules/@fps-games/editor-babylon/dist/main-camera-preview.d.ts +2 -0
  482. package/node_modules/@fps-games/editor-babylon/dist/main-camera-preview.d.ts.map +1 -1
  483. package/node_modules/@fps-games/editor-babylon/dist/main-camera-preview.js +59 -6
  484. package/node_modules/@fps-games/editor-babylon/dist/main-camera-preview.js.map +1 -1
  485. package/node_modules/@fps-games/editor-babylon/dist/marker-overlay.js +24 -0
  486. package/node_modules/@fps-games/editor-babylon/dist/marker-overlay.js.map +1 -1
  487. package/node_modules/@fps-games/editor-babylon/dist/material-slot-source-resolver.d.ts.map +1 -1
  488. package/node_modules/@fps-games/editor-babylon/dist/material-slot-source-resolver.js +81 -11
  489. package/node_modules/@fps-games/editor-babylon/dist/material-slot-source-resolver.js.map +1 -1
  490. package/node_modules/@fps-games/editor-babylon/dist/projection-asset-container-importer.js +2 -8
  491. package/node_modules/@fps-games/editor-babylon/dist/projection-asset-container-importer.js.map +1 -1
  492. package/node_modules/@fps-games/editor-babylon/dist/projection.d.ts +26 -5
  493. package/node_modules/@fps-games/editor-babylon/dist/projection.d.ts.map +1 -1
  494. package/node_modules/@fps-games/editor-babylon/dist/projection.js +396 -363
  495. package/node_modules/@fps-games/editor-babylon/dist/projection.js.map +1 -1
  496. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.d.ts +4 -0
  497. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.d.ts.map +1 -1
  498. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.js +76 -10
  499. package/node_modules/@fps-games/editor-babylon/dist/scene-view-camera-controller.js.map +1 -1
  500. package/node_modules/@fps-games/editor-babylon/dist/scene-view-spatial-overlay-controller.d.ts.map +1 -1
  501. package/node_modules/@fps-games/editor-babylon/dist/scene-view-spatial-overlay-controller.js +85 -22
  502. package/node_modules/@fps-games/editor-babylon/dist/scene-view-spatial-overlay-controller.js.map +1 -1
  503. package/node_modules/@fps-games/editor-babylon/dist/selection-identity-pass.d.ts +46 -0
  504. package/node_modules/@fps-games/editor-babylon/dist/selection-identity-pass.d.ts.map +1 -0
  505. package/node_modules/@fps-games/editor-babylon/dist/selection-identity-pass.js +304 -0
  506. package/node_modules/@fps-games/editor-babylon/dist/selection-identity-pass.js.map +1 -0
  507. package/node_modules/@fps-games/editor-babylon/dist/selection-presentation-controller.d.ts +87 -0
  508. package/node_modules/@fps-games/editor-babylon/dist/selection-presentation-controller.d.ts.map +1 -0
  509. package/node_modules/@fps-games/editor-babylon/dist/selection-presentation-controller.js +1746 -0
  510. package/node_modules/@fps-games/editor-babylon/dist/selection-presentation-controller.js.map +1 -0
  511. package/node_modules/@fps-games/editor-babylon/dist/shadow-preview-controller.d.ts +11 -3
  512. package/node_modules/@fps-games/editor-babylon/dist/shadow-preview-controller.d.ts.map +1 -1
  513. package/node_modules/@fps-games/editor-babylon/dist/shadow-preview-controller.js +105 -15
  514. package/node_modules/@fps-games/editor-babylon/dist/shadow-preview-controller.js.map +1 -1
  515. package/node_modules/@fps-games/editor-babylon/dist/transform-gizmo-controller.d.ts +1 -0
  516. package/node_modules/@fps-games/editor-babylon/dist/transform-gizmo-controller.d.ts.map +1 -1
  517. package/node_modules/@fps-games/editor-babylon/dist/transform-gizmo-controller.js +249 -15
  518. package/node_modules/@fps-games/editor-babylon/dist/transform-gizmo-controller.js.map +1 -1
  519. package/node_modules/@fps-games/editor-babylon/dist/types.d.ts +1 -1
  520. package/node_modules/@fps-games/editor-babylon/dist/types.d.ts.map +1 -1
  521. package/node_modules/@fps-games/editor-babylon/dist/types.js.map +1 -1
  522. package/node_modules/@fps-games/editor-babylon/dist/viewport-ground-projection.d.ts +25 -0
  523. package/node_modules/@fps-games/editor-babylon/dist/viewport-ground-projection.d.ts.map +1 -0
  524. package/node_modules/@fps-games/editor-babylon/dist/viewport-ground-projection.js +44 -0
  525. package/node_modules/@fps-games/editor-babylon/dist/viewport-ground-projection.js.map +1 -0
  526. package/node_modules/@fps-games/editor-babylon/package.json +6 -5
  527. package/node_modules/@fps-games/editor-browser/dist/index.d.ts +13 -11
  528. package/node_modules/@fps-games/editor-browser/dist/index.d.ts.map +1 -1
  529. package/node_modules/@fps-games/editor-browser/dist/index.js +9 -9
  530. package/node_modules/@fps-games/editor-browser/dist/index.js.map +1 -1
  531. package/node_modules/@fps-games/editor-browser/dist/local-editor-asset-browser-continuity.d.ts +35 -0
  532. package/node_modules/@fps-games/editor-browser/dist/local-editor-asset-browser-continuity.d.ts.map +1 -0
  533. package/node_modules/@fps-games/editor-browser/dist/local-editor-asset-browser-continuity.js +136 -0
  534. package/node_modules/@fps-games/editor-browser/dist/local-editor-asset-browser-continuity.js.map +1 -0
  535. package/node_modules/@fps-games/editor-browser/dist/local-editor-asset-filesystem.d.ts +46 -0
  536. package/node_modules/@fps-games/editor-browser/dist/local-editor-asset-filesystem.d.ts.map +1 -0
  537. package/node_modules/@fps-games/editor-browser/dist/local-editor-asset-filesystem.js +283 -0
  538. package/node_modules/@fps-games/editor-browser/dist/local-editor-asset-filesystem.js.map +1 -0
  539. package/node_modules/@fps-games/editor-browser/dist/local-editor-clipboard.d.ts +2 -0
  540. package/node_modules/@fps-games/editor-browser/dist/local-editor-clipboard.d.ts.map +1 -0
  541. package/node_modules/@fps-games/editor-browser/dist/local-editor-clipboard.js +36 -0
  542. package/node_modules/@fps-games/editor-browser/dist/local-editor-clipboard.js.map +1 -0
  543. package/node_modules/@fps-games/editor-browser/dist/local-editor-inspector-groups.d.ts +2 -0
  544. package/node_modules/@fps-games/editor-browser/dist/local-editor-inspector-groups.d.ts.map +1 -1
  545. package/node_modules/@fps-games/editor-browser/dist/local-editor-inspector-groups.js +17 -0
  546. package/node_modules/@fps-games/editor-browser/dist/local-editor-inspector-groups.js.map +1 -1
  547. package/node_modules/@fps-games/editor-browser/dist/local-editor-preview-cleanup-registry.d.ts +12 -0
  548. package/node_modules/@fps-games/editor-browser/dist/local-editor-preview-cleanup-registry.d.ts.map +1 -0
  549. package/node_modules/@fps-games/editor-browser/dist/local-editor-preview-cleanup-registry.js +67 -0
  550. package/node_modules/@fps-games/editor-browser/dist/local-editor-preview-cleanup-registry.js.map +1 -0
  551. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-file-open.d.ts +6 -0
  552. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-file-open.d.ts.map +1 -0
  553. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-file-open.js +9 -0
  554. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-file-open.js.map +1 -0
  555. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-file-preview.d.ts +7 -0
  556. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-file-preview.d.ts.map +1 -0
  557. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-file-preview.js +20 -0
  558. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-file-preview.js.map +1 -0
  559. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-media-thumbnail-cache.d.ts +9 -0
  560. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-media-thumbnail-cache.d.ts.map +1 -0
  561. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-media-thumbnail-cache.js +219 -0
  562. package/node_modules/@fps-games/editor-browser/dist/local-editor-project-media-thumbnail-cache.js.map +1 -0
  563. package/node_modules/@fps-games/editor-browser/dist/local-editor-tool-presentation.d.ts +14 -0
  564. package/node_modules/@fps-games/editor-browser/dist/local-editor-tool-presentation.d.ts.map +1 -0
  565. package/node_modules/@fps-games/editor-browser/dist/local-editor-tool-presentation.js +42 -0
  566. package/node_modules/@fps-games/editor-browser/dist/local-editor-tool-presentation.js.map +1 -0
  567. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.d.ts +1 -1
  568. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.d.ts.map +1 -1
  569. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.js +8 -0
  570. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-asset-kind.js.map +1 -1
  571. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-console.d.ts +27 -0
  572. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-console.d.ts.map +1 -0
  573. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-console.js +288 -0
  574. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-console.js.map +1 -0
  575. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-context-menu.d.ts.map +1 -1
  576. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-context-menu.js +157 -77
  577. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-context-menu.js.map +1 -1
  578. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-dock-panel.d.ts.map +1 -1
  579. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-dock-panel.js +27 -21
  580. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-dock-panel.js.map +1 -1
  581. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-formal-surface-visibility.d.ts +19 -0
  582. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-formal-surface-visibility.d.ts.map +1 -0
  583. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-formal-surface-visibility.js +44 -0
  584. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-formal-surface-visibility.js.map +1 -0
  585. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.d.ts +36 -6
  586. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.d.ts.map +1 -1
  587. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.js +829 -866
  588. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-controller.js.map +1 -1
  589. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-drag-policy.d.ts +8 -7
  590. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-drag-policy.d.ts.map +1 -1
  591. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-drag-policy.js +1 -7
  592. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-drag-policy.js.map +1 -1
  593. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view-adapter.d.ts +7 -0
  594. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view-adapter.d.ts.map +1 -0
  595. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view-adapter.js +20 -0
  596. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view-adapter.js.map +1 -0
  597. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.d.ts +6 -7
  598. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.d.ts.map +1 -1
  599. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.js +266 -114
  600. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-view.js.map +1 -1
  601. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.d.ts +1 -1
  602. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.d.ts.map +1 -1
  603. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.js +34 -0
  604. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-icons.js.map +1 -1
  605. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-input-router.d.ts.map +1 -1
  606. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-input-router.js +3 -17
  607. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-input-router.js.map +1 -1
  608. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-modal-dialog.d.ts +14 -0
  609. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-modal-dialog.d.ts.map +1 -1
  610. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-modal-dialog.js +44 -62
  611. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-modal-dialog.js.map +1 -1
  612. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.d.ts +30 -8
  613. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.d.ts.map +1 -1
  614. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.js +911 -698
  615. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-panels.js.map +1 -1
  616. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.d.ts +10 -37
  617. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.d.ts.map +1 -1
  618. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.js +29 -105
  619. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-prefab-stage.js.map +1 -1
  620. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.d.ts.map +1 -1
  621. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.js +29 -110
  622. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-primitives.js.map +1 -1
  623. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shared.d.ts +1 -3
  624. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shared.d.ts.map +1 -1
  625. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shared.js +6 -90
  626. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shared.js.map +1 -1
  627. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shortcuts.d.ts.map +1 -1
  628. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shortcuts.js +9 -54
  629. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-shortcuts.js.map +1 -1
  630. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-status-diagnostics.d.ts +16 -1
  631. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-status-diagnostics.d.ts.map +1 -1
  632. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-status-diagnostics.js +44 -39
  633. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-status-diagnostics.js.map +1 -1
  634. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-status-format.d.ts +4 -0
  635. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-status-format.d.ts.map +1 -0
  636. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-status-format.js +44 -0
  637. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-status-format.js.map +1 -0
  638. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-structured-drag-policy.d.ts.map +1 -1
  639. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-structured-drag-policy.js +35 -44
  640. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-structured-drag-policy.js.map +1 -1
  641. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-theme.d.ts.map +1 -1
  642. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-theme.js +40 -24
  643. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-theme.js.map +1 -1
  644. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-tooltip.d.ts.map +1 -1
  645. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-tooltip.js +2 -20
  646. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-tooltip.js.map +1 -1
  647. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.d.ts +114 -343
  648. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.d.ts.map +1 -1
  649. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-types.js.map +1 -1
  650. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.d.ts +13 -14
  651. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.d.ts.map +1 -1
  652. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.js +120 -134
  653. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-workbench.js.map +1 -1
  654. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts +6 -10
  655. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.d.ts.map +1 -1
  656. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js +2019 -861
  657. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui.js.map +1 -1
  658. package/node_modules/@fps-games/editor-browser/dist/local-editor-viewport-orientation.d.ts +13 -0
  659. package/node_modules/@fps-games/editor-browser/dist/local-editor-viewport-orientation.d.ts.map +1 -0
  660. package/node_modules/@fps-games/editor-browser/dist/local-editor-viewport-orientation.js +15 -0
  661. package/node_modules/@fps-games/editor-browser/dist/local-editor-viewport-orientation.js.map +1 -0
  662. package/node_modules/@fps-games/editor-browser/dist/plugin-contributions.d.ts +2 -3
  663. package/node_modules/@fps-games/editor-browser/dist/plugin-contributions.d.ts.map +1 -1
  664. package/node_modules/@fps-games/editor-browser/dist/plugin-contributions.js +0 -180
  665. package/node_modules/@fps-games/editor-browser/dist/plugin-contributions.js.map +1 -1
  666. package/node_modules/@fps-games/editor-browser/dist/runtime-debug.d.ts +5 -0
  667. package/node_modules/@fps-games/editor-browser/dist/runtime-debug.d.ts.map +1 -0
  668. package/node_modules/@fps-games/editor-browser/dist/runtime-debug.js +5 -0
  669. package/node_modules/@fps-games/editor-browser/dist/runtime-debug.js.map +1 -0
  670. package/node_modules/@fps-games/editor-browser/package.json +15 -4
  671. package/node_modules/@fps-games/editor-core/dist/editor-diagnostic-store.d.ts +22 -0
  672. package/node_modules/@fps-games/editor-core/dist/editor-diagnostic-store.d.ts.map +1 -0
  673. package/node_modules/@fps-games/editor-core/dist/editor-diagnostic-store.js +226 -0
  674. package/node_modules/@fps-games/editor-core/dist/editor-diagnostic-store.js.map +1 -0
  675. package/node_modules/@fps-games/editor-core/dist/editor-plugin-host.d.ts +6 -1
  676. package/node_modules/@fps-games/editor-core/dist/editor-plugin-host.d.ts.map +1 -1
  677. package/node_modules/@fps-games/editor-core/dist/editor-plugin-host.js +94 -2
  678. package/node_modules/@fps-games/editor-core/dist/editor-plugin-host.js.map +1 -1
  679. package/node_modules/@fps-games/editor-core/dist/editor-session.d.ts +24 -2
  680. package/node_modules/@fps-games/editor-core/dist/editor-session.d.ts.map +1 -1
  681. package/node_modules/@fps-games/editor-core/dist/editor-session.js +70 -10
  682. package/node_modules/@fps-games/editor-core/dist/editor-session.js.map +1 -1
  683. package/node_modules/@fps-games/editor-core/dist/editor-tools.d.ts +113 -0
  684. package/node_modules/@fps-games/editor-core/dist/editor-tools.d.ts.map +1 -0
  685. package/node_modules/@fps-games/editor-core/dist/editor-tools.js +615 -0
  686. package/node_modules/@fps-games/editor-core/dist/editor-tools.js.map +1 -0
  687. package/node_modules/@fps-games/editor-core/dist/inspector.d.ts +46 -0
  688. package/node_modules/@fps-games/editor-core/dist/inspector.d.ts.map +1 -1
  689. package/node_modules/@fps-games/editor-core/dist/inspector.js +62 -0
  690. package/node_modules/@fps-games/editor-core/dist/inspector.js.map +1 -1
  691. package/node_modules/@fps-games/editor-core/dist/scene-graph.d.ts +1 -0
  692. package/node_modules/@fps-games/editor-core/dist/scene-graph.d.ts.map +1 -1
  693. package/node_modules/@fps-games/editor-core/dist/scene-graph.js.map +1 -1
  694. package/node_modules/@fps-games/editor-core/dist/viewport-tools.d.ts +11 -2
  695. package/node_modules/@fps-games/editor-core/dist/viewport-tools.d.ts.map +1 -1
  696. package/node_modules/@fps-games/editor-core/dist/viewport-tools.js +12 -1
  697. package/node_modules/@fps-games/editor-core/dist/viewport-tools.js.map +1 -1
  698. package/node_modules/@fps-games/editor-core/package.json +14 -6
  699. package/node_modules/@fps-games/editor-forge-play/package.json +2 -2
  700. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/metadata.js +14 -3
  701. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/metadata.js.map +1 -1
  702. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/node.d.ts +1 -1
  703. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/node.d.ts.map +1 -1
  704. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/node.js +1 -1
  705. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/node.js.map +1 -1
  706. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/registry.d.ts +14 -0
  707. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/registry.d.ts.map +1 -1
  708. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/registry.js +49 -1
  709. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-database/registry.js.map +1 -1
  710. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/catalog.d.ts +1 -0
  711. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/catalog.d.ts.map +1 -1
  712. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/catalog.js +63 -2
  713. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/catalog.js.map +1 -1
  714. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/document.d.ts.map +1 -1
  715. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/document.js +48 -6
  716. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/document.js.map +1 -1
  717. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/index.d.ts +1 -1
  718. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/index.d.ts.map +1 -1
  719. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/index.js +1 -1
  720. package/node_modules/@fps-games/editor-playable-sdk/dist/asset-library/index.js.map +1 -1
  721. package/node_modules/@fps-games/editor-playable-sdk/dist/authoring-server/handler.d.ts.map +1 -1
  722. package/node_modules/@fps-games/editor-playable-sdk/dist/authoring-server/handler.js +15 -1
  723. package/node_modules/@fps-games/editor-playable-sdk/dist/authoring-server/handler.js.map +1 -1
  724. package/node_modules/@fps-games/editor-playable-sdk/dist/authoring-server/routes.d.ts.map +1 -1
  725. package/node_modules/@fps-games/editor-playable-sdk/dist/authoring-server/routes.js +3 -0
  726. package/node_modules/@fps-games/editor-playable-sdk/dist/authoring-server/routes.js.map +1 -1
  727. package/node_modules/@fps-games/editor-playable-sdk/dist/authoring-server/types.d.ts +6 -1
  728. package/node_modules/@fps-games/editor-playable-sdk/dist/authoring-server/types.d.ts.map +1 -1
  729. package/node_modules/@fps-games/editor-playable-sdk/dist/authoring-server/types.js.map +1 -1
  730. package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.d.ts +28 -3
  731. package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.d.ts.map +1 -1
  732. package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.js +314 -6
  733. package/node_modules/@fps-games/editor-playable-sdk/dist/document/helpers.js.map +1 -1
  734. package/node_modules/@fps-games/editor-playable-sdk/dist/document/index.d.ts +2 -0
  735. package/node_modules/@fps-games/editor-playable-sdk/dist/document/index.d.ts.map +1 -1
  736. package/node_modules/@fps-games/editor-playable-sdk/dist/document/index.js +2 -0
  737. package/node_modules/@fps-games/editor-playable-sdk/dist/document/index.js.map +1 -1
  738. package/node_modules/@fps-games/editor-playable-sdk/dist/document/prefab-instance-identity.d.ts +11 -0
  739. package/node_modules/@fps-games/editor-playable-sdk/dist/document/prefab-instance-identity.d.ts.map +1 -0
  740. package/node_modules/@fps-games/editor-playable-sdk/dist/document/prefab-instance-identity.js +27 -0
  741. package/node_modules/@fps-games/editor-playable-sdk/dist/document/prefab-instance-identity.js.map +1 -0
  742. package/node_modules/@fps-games/editor-playable-sdk/dist/document/prefab-marker.d.ts +5 -0
  743. package/node_modules/@fps-games/editor-playable-sdk/dist/document/prefab-marker.d.ts.map +1 -0
  744. package/node_modules/@fps-games/editor-playable-sdk/dist/document/prefab-marker.js +285 -0
  745. package/node_modules/@fps-games/editor-playable-sdk/dist/document/prefab-marker.js.map +1 -0
  746. package/node_modules/@fps-games/editor-playable-sdk/dist/document/types.d.ts +7 -3
  747. package/node_modules/@fps-games/editor-playable-sdk/dist/document/types.d.ts.map +1 -1
  748. package/node_modules/@fps-games/editor-playable-sdk/dist/document/types.js.map +1 -1
  749. package/node_modules/@fps-games/editor-playable-sdk/dist/index.d.ts +4 -0
  750. package/node_modules/@fps-games/editor-playable-sdk/dist/index.d.ts.map +1 -1
  751. package/node_modules/@fps-games/editor-playable-sdk/dist/index.js +7 -0
  752. package/node_modules/@fps-games/editor-playable-sdk/dist/index.js.map +1 -1
  753. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/document-sections.d.ts.map +1 -1
  754. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/document-sections.js +23 -81
  755. package/node_modules/@fps-games/editor-playable-sdk/dist/inspector/document-sections.js.map +1 -1
  756. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/editor-entry-manifest.d.ts +41 -0
  757. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/editor-entry-manifest.d.ts.map +1 -0
  758. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/editor-entry-manifest.js +93 -0
  759. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/editor-entry-manifest.js.map +1 -0
  760. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/editor-entry-module.d.ts +29 -0
  761. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/editor-entry-module.d.ts.map +1 -0
  762. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/editor-entry-module.js +77 -0
  763. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/editor-entry-module.js.map +1 -0
  764. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/editor-entry-performance.d.ts +51 -0
  765. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/editor-entry-performance.d.ts.map +1 -0
  766. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/editor-entry-performance.js +105 -0
  767. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/editor-entry-performance.js.map +1 -0
  768. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/editor-entry.d.ts +60 -0
  769. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/editor-entry.d.ts.map +1 -0
  770. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/editor-entry.js +287 -0
  771. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/editor-entry.js.map +1 -0
  772. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/forge-play-types.d.ts +6 -1
  773. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/forge-play-types.d.ts.map +1 -1
  774. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/forge-play-types.js.map +1 -1
  775. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/forge-play.d.ts +1 -0
  776. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/forge-play.d.ts.map +1 -1
  777. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/forge-play.js +53 -17
  778. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/forge-play.js.map +1 -1
  779. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/host-controller.d.ts +16 -8
  780. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/host-controller.d.ts.map +1 -1
  781. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/host-controller.js +10 -6
  782. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/host-controller.js.map +1 -1
  783. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/index.d.ts +5 -3
  784. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/index.d.ts.map +1 -1
  785. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/index.js +2 -1
  786. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/index.js.map +1 -1
  787. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/lifecycle.d.ts.map +1 -1
  788. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/lifecycle.js +134 -66
  789. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/lifecycle.js.map +1 -1
  790. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/project-asset-commands.d.ts +11 -0
  791. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/project-asset-commands.d.ts.map +1 -1
  792. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/project-asset-commands.js +21 -14
  793. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/project-asset-commands.js.map +1 -1
  794. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/types.d.ts +17 -9
  795. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/types.d.ts.map +1 -1
  796. package/node_modules/@fps-games/editor-playable-sdk/dist/local-harness/types.js.map +1 -1
  797. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.d.ts.map +1 -1
  798. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.js +20 -0
  799. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/field-patch.js.map +1 -1
  800. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/reducer.d.ts.map +1 -1
  801. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/reducer.js +49 -10
  802. package/node_modules/@fps-games/editor-playable-sdk/dist/mutation/reducer.js.map +1 -1
  803. package/node_modules/@fps-games/editor-playable-sdk/dist/package-resolution/aliases.d.ts +2 -2
  804. package/node_modules/@fps-games/editor-playable-sdk/dist/package-resolution/aliases.d.ts.map +1 -1
  805. package/node_modules/@fps-games/editor-playable-sdk/dist/package-resolution/aliases.js +18 -0
  806. package/node_modules/@fps-games/editor-playable-sdk/dist/package-resolution/aliases.js.map +1 -1
  807. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/action-patches.d.ts +7 -0
  808. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/action-patches.d.ts.map +1 -1
  809. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/action-patches.js +130 -20
  810. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/action-patches.js.map +1 -1
  811. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/assets.d.ts +1 -1
  812. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/assets.d.ts.map +1 -1
  813. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/assets.js +12 -3
  814. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/assets.js.map +1 -1
  815. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/derived-markers.d.ts +11 -0
  816. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/derived-markers.d.ts.map +1 -0
  817. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/derived-markers.js +136 -0
  818. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/derived-markers.js.map +1 -0
  819. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/index.d.ts +1 -0
  820. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/index.d.ts.map +1 -1
  821. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/index.js +1 -0
  822. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/index.js.map +1 -1
  823. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/projection.d.ts +36 -51
  824. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/projection.d.ts.map +1 -1
  825. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/projection.js +40 -65
  826. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/projection.js.map +1 -1
  827. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/stage-inspector.d.ts +5 -2
  828. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/stage-inspector.d.ts.map +1 -1
  829. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/stage-inspector.js +207 -1
  830. package/node_modules/@fps-games/editor-playable-sdk/dist/prefab-stage/stage-inspector.js.map +1 -1
  831. package/node_modules/@fps-games/editor-playable-sdk/dist/product/index.d.ts +1 -0
  832. package/node_modules/@fps-games/editor-playable-sdk/dist/product/index.d.ts.map +1 -1
  833. package/node_modules/@fps-games/editor-playable-sdk/dist/product/index.js +3 -0
  834. package/node_modules/@fps-games/editor-playable-sdk/dist/product/index.js.map +1 -1
  835. package/node_modules/@fps-games/editor-playable-sdk/dist/product/project-host-services.d.ts +18 -7
  836. package/node_modules/@fps-games/editor-playable-sdk/dist/product/project-host-services.d.ts.map +1 -1
  837. package/node_modules/@fps-games/editor-playable-sdk/dist/product/project-host-services.js +110 -18
  838. package/node_modules/@fps-games/editor-playable-sdk/dist/product/project-host-services.js.map +1 -1
  839. package/node_modules/@fps-games/editor-playable-sdk/dist/product/scene-source.d.ts +9 -0
  840. package/node_modules/@fps-games/editor-playable-sdk/dist/product/scene-source.d.ts.map +1 -1
  841. package/node_modules/@fps-games/editor-playable-sdk/dist/product/scene-source.js +16 -1
  842. package/node_modules/@fps-games/editor-playable-sdk/dist/product/scene-source.js.map +1 -1
  843. package/node_modules/@fps-games/editor-playable-sdk/dist/product/standard-scene-assembly.d.ts +5 -2
  844. package/node_modules/@fps-games/editor-playable-sdk/dist/product/standard-scene-assembly.d.ts.map +1 -1
  845. package/node_modules/@fps-games/editor-playable-sdk/dist/product/standard-scene-assembly.js +22 -2
  846. package/node_modules/@fps-games/editor-playable-sdk/dist/product/standard-scene-assembly.js.map +1 -1
  847. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/index.d.ts +4 -0
  848. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/index.d.ts.map +1 -0
  849. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/index.js +4 -0
  850. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/index.js.map +1 -0
  851. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/protocol.d.ts +4 -0
  852. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/protocol.d.ts.map +1 -0
  853. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/protocol.js +86 -0
  854. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/protocol.js.map +1 -0
  855. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/support.d.ts +9 -0
  856. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/support.d.ts.map +1 -0
  857. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/support.js +76 -0
  858. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/support.js.map +1 -0
  859. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/types.d.ts +34 -0
  860. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/types.d.ts.map +1 -0
  861. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/types.js +2 -0
  862. package/node_modules/@fps-games/editor-playable-sdk/dist/project-files/types.js.map +1 -0
  863. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/panel.d.ts.map +1 -1
  864. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/panel.js +144 -0
  865. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/panel.js.map +1 -1
  866. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/types.d.ts +16 -0
  867. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/types.d.ts.map +1 -1
  868. package/node_modules/@fps-games/editor-playable-sdk/dist/rendering-profile/types.js.map +1 -1
  869. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.d.ts.map +1 -1
  870. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.js +1 -0
  871. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/nodes.js.map +1 -1
  872. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/types.d.ts +2 -1
  873. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/types.d.ts.map +1 -1
  874. package/node_modules/@fps-games/editor-playable-sdk/dist/runtime-preview/types.js.map +1 -1
  875. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/compiler.d.ts +2 -0
  876. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/compiler.d.ts.map +1 -1
  877. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/compiler.js +241 -13
  878. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/compiler.js.map +1 -1
  879. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/index.d.ts +1 -0
  880. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/index.d.ts.map +1 -1
  881. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/index.js +1 -0
  882. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/index.js.map +1 -1
  883. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/shadow-map-experiment-migration.d.ts +31 -0
  884. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/shadow-map-experiment-migration.d.ts.map +1 -0
  885. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/shadow-map-experiment-migration.js +170 -0
  886. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/shadow-map-experiment-migration.js.map +1 -0
  887. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/types.d.ts +153 -13
  888. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/types.d.ts.map +1 -1
  889. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/types.js.map +1 -1
  890. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/validation.d.ts +17 -0
  891. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/validation.d.ts.map +1 -1
  892. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/validation.js +1295 -3
  893. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-compiler/validation.js.map +1 -1
  894. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/client.d.ts +4 -0
  895. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/client.d.ts.map +1 -1
  896. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/client.js +54 -0
  897. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/client.js.map +1 -1
  898. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/driver.d.ts.map +1 -1
  899. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/driver.js +57 -34
  900. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/driver.js.map +1 -1
  901. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/protocol.d.ts.map +1 -1
  902. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/protocol.js +4 -1
  903. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/protocol.js.map +1 -1
  904. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/types.d.ts +4 -0
  905. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/types.d.ts.map +1 -1
  906. package/node_modules/@fps-games/editor-playable-sdk/dist/scene-source/types.js.map +1 -1
  907. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.d.ts.map +1 -1
  908. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.js +20 -198
  909. package/node_modules/@fps-games/editor-playable-sdk/dist/serialized-property/inspector.js.map +1 -1
  910. package/node_modules/@fps-games/editor-playable-sdk/dist/session/hierarchy-facade.d.ts.map +1 -1
  911. package/node_modules/@fps-games/editor-playable-sdk/dist/session/hierarchy-facade.js +5 -1
  912. package/node_modules/@fps-games/editor-playable-sdk/dist/session/hierarchy-facade.js.map +1 -1
  913. package/node_modules/@fps-games/editor-playable-sdk/dist/session/patches.d.ts +5 -0
  914. package/node_modules/@fps-games/editor-playable-sdk/dist/session/patches.d.ts.map +1 -1
  915. package/node_modules/@fps-games/editor-playable-sdk/dist/session/patches.js +144 -8
  916. package/node_modules/@fps-games/editor-playable-sdk/dist/session/patches.js.map +1 -1
  917. package/node_modules/@fps-games/editor-playable-sdk/dist/session/reducer-core.d.ts +1 -1
  918. package/node_modules/@fps-games/editor-playable-sdk/dist/session/reducer-core.d.ts.map +1 -1
  919. package/node_modules/@fps-games/editor-playable-sdk/dist/session/reducer-core.js +30 -1
  920. package/node_modules/@fps-games/editor-playable-sdk/dist/session/reducer-core.js.map +1 -1
  921. package/node_modules/@fps-games/editor-playable-sdk/dist/session/types.d.ts +6 -0
  922. package/node_modules/@fps-games/editor-playable-sdk/dist/session/types.d.ts.map +1 -1
  923. package/node_modules/@fps-games/editor-playable-sdk/dist/session/types.js.map +1 -1
  924. package/node_modules/@fps-games/editor-playable-sdk/dist/upgrade-doctor/inspectors.js +31 -3
  925. package/node_modules/@fps-games/editor-playable-sdk/dist/upgrade-doctor/inspectors.js.map +1 -1
  926. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/editor-scene-workflow.d.ts +5 -2
  927. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/editor-scene-workflow.d.ts.map +1 -1
  928. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/editor-scene-workflow.js +40 -4
  929. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/editor-scene-workflow.js.map +1 -1
  930. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/index.d.ts +1 -0
  931. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/index.d.ts.map +1 -1
  932. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/index.js +1 -0
  933. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/index.js.map +1 -1
  934. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/plugin.d.ts.map +1 -1
  935. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/plugin.js +116 -3
  936. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/plugin.js.map +1 -1
  937. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/product-adapter.d.ts +2 -1
  938. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/product-adapter.d.ts.map +1 -1
  939. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/product-adapter.js +1 -0
  940. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/product-adapter.js.map +1 -1
  941. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/product-asset-authoring.d.ts +17 -1
  942. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/product-asset-authoring.d.ts.map +1 -1
  943. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/product-asset-authoring.js +50 -2
  944. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/product-asset-authoring.js.map +1 -1
  945. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/product-authoring-api.d.ts +1 -0
  946. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/product-authoring-api.d.ts.map +1 -1
  947. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/product-authoring-api.js +101 -5
  948. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/product-authoring-api.js.map +1 -1
  949. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/product-scene-authoring.d.ts +5 -6
  950. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/product-scene-authoring.d.ts.map +1 -1
  951. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/product-scene-authoring.js +31 -17
  952. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/product-scene-authoring.js.map +1 -1
  953. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/project-file-handle.d.ts +14 -0
  954. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/project-file-handle.d.ts.map +1 -0
  955. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/project-file-handle.js +101 -0
  956. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/project-file-handle.js.map +1 -0
  957. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/project-files.d.ts +23 -0
  958. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/project-files.d.ts.map +1 -0
  959. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/project-files.js +180 -0
  960. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/project-files.js.map +1 -0
  961. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/types.d.ts +6 -0
  962. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/types.d.ts.map +1 -1
  963. package/node_modules/@fps-games/editor-playable-sdk/dist/vite/types.js.map +1 -1
  964. package/node_modules/@fps-games/editor-playable-sdk/package.json +6 -6
  965. package/node_modules/@fps-games/editor-protocol/dist/agent-bridge.d.ts +417 -2
  966. package/node_modules/@fps-games/editor-protocol/dist/agent-bridge.d.ts.map +1 -1
  967. package/node_modules/@fps-games/editor-protocol/dist/agent-bridge.js +692 -2
  968. package/node_modules/@fps-games/editor-protocol/dist/agent-bridge.js.map +1 -1
  969. package/node_modules/@fps-games/editor-protocol/dist/agent.d.ts +23 -3
  970. package/node_modules/@fps-games/editor-protocol/dist/agent.d.ts.map +1 -1
  971. package/node_modules/@fps-games/editor-protocol/dist/agent.js.map +1 -1
  972. package/node_modules/@fps-games/editor-protocol/dist/editor-diagnostics.d.ts +55 -0
  973. package/node_modules/@fps-games/editor-protocol/dist/editor-diagnostics.d.ts.map +1 -0
  974. package/node_modules/@fps-games/editor-protocol/dist/editor-diagnostics.js +2 -0
  975. package/node_modules/@fps-games/editor-protocol/dist/editor-diagnostics.js.map +1 -0
  976. package/node_modules/@fps-games/editor-protocol/dist/index.d.ts +3 -18
  977. package/node_modules/@fps-games/editor-protocol/dist/index.d.ts.map +1 -1
  978. package/node_modules/@fps-games/editor-protocol/dist/index.js +1 -0
  979. package/node_modules/@fps-games/editor-protocol/dist/index.js.map +1 -1
  980. package/node_modules/@fps-games/editor-protocol/package.json +2 -2
  981. package/node_modules/@fps-games/editor-tooling/dist/package-metadata-node.d.ts.map +1 -1
  982. package/node_modules/@fps-games/editor-tooling/dist/package-metadata-node.js +5 -0
  983. package/node_modules/@fps-games/editor-tooling/dist/package-metadata-node.js.map +1 -1
  984. package/node_modules/@fps-games/editor-tooling/dist/vite.d.ts.map +1 -1
  985. package/node_modules/@fps-games/editor-tooling/dist/vite.js +151 -5
  986. package/node_modules/@fps-games/editor-tooling/dist/vite.js.map +1 -1
  987. package/node_modules/@fps-games/editor-tooling/package.json +3 -3
  988. package/node_modules/@fps-games/editor-ui/dist/editor-ui-controls.d.ts +107 -0
  989. package/node_modules/@fps-games/editor-ui/dist/editor-ui-controls.d.ts.map +1 -0
  990. package/node_modules/@fps-games/editor-ui/dist/editor-ui-controls.js +770 -0
  991. package/node_modules/@fps-games/editor-ui/dist/editor-ui-controls.js.map +1 -0
  992. package/node_modules/@fps-games/editor-ui/dist/editor-ui-layer-host.d.ts +21 -0
  993. package/node_modules/@fps-games/editor-ui/dist/editor-ui-layer-host.d.ts.map +1 -0
  994. package/node_modules/@fps-games/editor-ui/dist/editor-ui-layer-host.js +172 -0
  995. package/node_modules/@fps-games/editor-ui/dist/editor-ui-layer-host.js.map +1 -0
  996. package/node_modules/@fps-games/editor-ui/dist/editor-ui-shell.d.ts +14 -0
  997. package/node_modules/@fps-games/editor-ui/dist/editor-ui-shell.d.ts.map +1 -0
  998. package/node_modules/@fps-games/editor-ui/dist/editor-ui-shell.js +32 -0
  999. package/node_modules/@fps-games/editor-ui/dist/editor-ui-shell.js.map +1 -0
  1000. package/node_modules/@fps-games/editor-ui/dist/editor-ui-theme.d.ts +3 -0
  1001. package/node_modules/@fps-games/editor-ui/dist/editor-ui-theme.d.ts.map +1 -0
  1002. package/node_modules/@fps-games/editor-ui/dist/editor-ui-theme.js +746 -0
  1003. package/node_modules/@fps-games/editor-ui/dist/editor-ui-theme.js.map +1 -0
  1004. package/node_modules/@fps-games/editor-ui/dist/gallery.d.ts +3 -0
  1005. package/node_modules/@fps-games/editor-ui/dist/gallery.d.ts.map +1 -0
  1006. package/node_modules/@fps-games/editor-ui/dist/gallery.js +3 -0
  1007. package/node_modules/@fps-games/editor-ui/dist/gallery.js.map +1 -0
  1008. package/node_modules/@fps-games/editor-ui/dist/index.d.ts +5 -0
  1009. package/node_modules/@fps-games/editor-ui/dist/index.d.ts.map +1 -0
  1010. package/node_modules/@fps-games/editor-ui/dist/index.js +5 -0
  1011. package/node_modules/@fps-games/editor-ui/dist/index.js.map +1 -0
  1012. package/node_modules/@fps-games/editor-ui/dist/inspector-property-gallery-model.d.ts +7 -0
  1013. package/node_modules/@fps-games/editor-ui/dist/inspector-property-gallery-model.d.ts.map +1 -0
  1014. package/node_modules/@fps-games/editor-ui/dist/inspector-property-gallery-model.js +29 -0
  1015. package/node_modules/@fps-games/editor-ui/dist/inspector-property-gallery-model.js.map +1 -0
  1016. package/node_modules/@fps-games/editor-ui/dist/inspector-property-gallery-styles.d.ts +2 -0
  1017. package/node_modules/@fps-games/editor-ui/dist/inspector-property-gallery-styles.d.ts.map +1 -0
  1018. package/node_modules/@fps-games/editor-ui/dist/inspector-property-gallery-styles.js +95 -0
  1019. package/node_modules/@fps-games/editor-ui/dist/inspector-property-gallery-styles.js.map +1 -0
  1020. package/node_modules/@fps-games/editor-ui/dist/inspector-property-gallery.d.ts +28 -0
  1021. package/node_modules/@fps-games/editor-ui/dist/inspector-property-gallery.d.ts.map +1 -0
  1022. package/node_modules/@fps-games/editor-ui/dist/inspector-property-gallery.js +387 -0
  1023. package/node_modules/@fps-games/editor-ui/dist/inspector-property-gallery.js.map +1 -0
  1024. package/node_modules/@fps-games/editor-ui/package.json +23 -0
  1025. package/node_modules/@fps-games/playable-assets/package.json +1 -1
  1026. package/node_modules/@fps-games/playable-contracts/dist/index.d.ts +1 -0
  1027. package/node_modules/@fps-games/playable-contracts/dist/index.d.ts.map +1 -1
  1028. package/node_modules/@fps-games/playable-contracts/dist/index.js +1 -0
  1029. package/node_modules/@fps-games/playable-contracts/dist/index.js.map +1 -1
  1030. package/node_modules/@fps-games/playable-contracts/dist/material-owner.d.ts +116 -0
  1031. package/node_modules/@fps-games/playable-contracts/dist/material-owner.d.ts.map +1 -0
  1032. package/node_modules/@fps-games/playable-contracts/dist/material-owner.js +403 -0
  1033. package/node_modules/@fps-games/playable-contracts/dist/material-owner.js.map +1 -0
  1034. package/node_modules/@fps-games/playable-contracts/package.json +1 -1
  1035. package/node_modules/@fps-games/playable-rendering/dist/index.d.ts +3 -0
  1036. package/node_modules/@fps-games/playable-rendering/dist/index.d.ts.map +1 -1
  1037. package/node_modules/@fps-games/playable-rendering/dist/index.js +3 -0
  1038. package/node_modules/@fps-games/playable-rendering/dist/index.js.map +1 -1
  1039. package/node_modules/@fps-games/playable-rendering/dist/rendering-profile-validation.js +5 -25
  1040. package/node_modules/@fps-games/playable-rendering/dist/rendering-profile-validation.js.map +1 -1
  1041. package/node_modules/@fps-games/playable-rendering/dist/runtime.d.ts +3 -0
  1042. package/node_modules/@fps-games/playable-rendering/dist/runtime.d.ts.map +1 -1
  1043. package/node_modules/@fps-games/playable-rendering/dist/runtime.js +3 -0
  1044. package/node_modules/@fps-games/playable-rendering/dist/runtime.js.map +1 -1
  1045. package/node_modules/@fps-games/playable-rendering/dist/shadow-map-experiment-depth.d.ts +61 -0
  1046. package/node_modules/@fps-games/playable-rendering/dist/shadow-map-experiment-depth.d.ts.map +1 -0
  1047. package/node_modules/@fps-games/playable-rendering/dist/shadow-map-experiment-depth.js +176 -0
  1048. package/node_modules/@fps-games/playable-rendering/dist/shadow-map-experiment-depth.js.map +1 -0
  1049. package/node_modules/@fps-games/playable-rendering/dist/shadow-map-experiment-lifecycle.d.ts +84 -0
  1050. package/node_modules/@fps-games/playable-rendering/dist/shadow-map-experiment-lifecycle.d.ts.map +1 -0
  1051. package/node_modules/@fps-games/playable-rendering/dist/shadow-map-experiment-lifecycle.js +362 -0
  1052. package/node_modules/@fps-games/playable-rendering/dist/shadow-map-experiment-lifecycle.js.map +1 -0
  1053. package/node_modules/@fps-games/playable-rendering/dist/shadow-map-experiment.d.ts +167 -0
  1054. package/node_modules/@fps-games/playable-rendering/dist/shadow-map-experiment.d.ts.map +1 -0
  1055. package/node_modules/@fps-games/playable-rendering/dist/shadow-map-experiment.js +484 -0
  1056. package/node_modules/@fps-games/playable-rendering/dist/shadow-map-experiment.js.map +1 -0
  1057. package/node_modules/@fps-games/playable-rendering/package.json +2 -2
  1058. package/node_modules/@fps-games/playable-runtime/dist/compiled-scene-data.d.ts +5 -0
  1059. package/node_modules/@fps-games/playable-runtime/dist/compiled-scene-data.d.ts.map +1 -1
  1060. package/node_modules/@fps-games/playable-runtime/dist/compiled-scene-data.js +1 -0
  1061. package/node_modules/@fps-games/playable-runtime/dist/compiled-scene-data.js.map +1 -1
  1062. package/node_modules/@fps-games/playable-runtime/package.json +12 -12
  1063. package/node_modules/@fps-games/playable-runtime-data/package.json +4 -4
  1064. package/node_modules/@fps-games/playable-scene/package.json +2 -2
  1065. package/node_modules/@fps-games/plugin-api/package.json +1 -1
  1066. package/node_modules/@fps-games/plugin-assets/dist/version.d.ts +1 -1
  1067. package/node_modules/@fps-games/plugin-assets/dist/version.js +1 -1
  1068. package/node_modules/@fps-games/plugin-assets/dist/version.js.map +1 -1
  1069. package/node_modules/@fps-games/plugin-assets/package.json +5 -5
  1070. package/node_modules/@fps-games/plugin-hierarchy/dist/editor.d.ts +6 -0
  1071. package/node_modules/@fps-games/plugin-hierarchy/dist/editor.d.ts.map +1 -0
  1072. package/node_modules/@fps-games/plugin-hierarchy/dist/editor.js +16 -0
  1073. package/node_modules/@fps-games/plugin-hierarchy/dist/editor.js.map +1 -0
  1074. package/node_modules/@fps-games/plugin-hierarchy/dist/integration.d.ts +7 -0
  1075. package/node_modules/@fps-games/plugin-hierarchy/dist/integration.d.ts.map +1 -0
  1076. package/node_modules/@fps-games/plugin-hierarchy/dist/integration.js +47 -0
  1077. package/node_modules/@fps-games/plugin-hierarchy/dist/integration.js.map +1 -0
  1078. package/node_modules/@fps-games/plugin-hierarchy/dist/kernel.d.ts +306 -0
  1079. package/node_modules/@fps-games/plugin-hierarchy/dist/kernel.d.ts.map +1 -0
  1080. package/node_modules/@fps-games/plugin-hierarchy/dist/kernel.js +1237 -0
  1081. package/node_modules/@fps-games/plugin-hierarchy/dist/kernel.js.map +1 -0
  1082. package/node_modules/@fps-games/plugin-hierarchy/dist/reference.d.ts +8 -0
  1083. package/node_modules/@fps-games/plugin-hierarchy/dist/reference.d.ts.map +1 -0
  1084. package/node_modules/@fps-games/plugin-hierarchy/dist/reference.js +32 -0
  1085. package/node_modules/@fps-games/plugin-hierarchy/dist/reference.js.map +1 -0
  1086. package/node_modules/@fps-games/plugin-hierarchy/dist/version.d.ts +2 -0
  1087. package/node_modules/@fps-games/plugin-hierarchy/dist/version.d.ts.map +1 -0
  1088. package/node_modules/@fps-games/plugin-hierarchy/dist/version.js +2 -0
  1089. package/node_modules/@fps-games/plugin-hierarchy/dist/version.js.map +1 -0
  1090. package/node_modules/@fps-games/plugin-hierarchy/package.json +57 -0
  1091. package/node_modules/@fps-games/plugin-host/package.json +2 -2
  1092. package/node_modules/@fps-games/plugin-markers/dist/version.d.ts +1 -1
  1093. package/node_modules/@fps-games/plugin-markers/dist/version.js +1 -1
  1094. package/node_modules/@fps-games/plugin-markers/dist/version.js.map +1 -1
  1095. package/node_modules/@fps-games/plugin-markers/package.json +5 -5
  1096. package/node_modules/@fps-games/plugin-materials/dist/version.d.ts +1 -1
  1097. package/node_modules/@fps-games/plugin-materials/dist/version.js +1 -1
  1098. package/node_modules/@fps-games/plugin-materials/dist/version.js.map +1 -1
  1099. package/node_modules/@fps-games/plugin-materials/package.json +5 -5
  1100. package/node_modules/@fps-games/plugin-rendering/dist/version.d.ts +1 -1
  1101. package/node_modules/@fps-games/plugin-rendering/dist/version.js +1 -1
  1102. package/node_modules/@fps-games/plugin-rendering/dist/version.js.map +1 -1
  1103. package/node_modules/@fps-games/plugin-rendering/package.json +5 -5
  1104. package/node_modules/@fps-games/plugin-scene/dist/version.d.ts +1 -1
  1105. package/node_modules/@fps-games/plugin-scene/dist/version.js +1 -1
  1106. package/node_modules/@fps-games/plugin-scene/dist/version.js.map +1 -1
  1107. package/node_modules/@fps-games/plugin-scene/package.json +5 -5
  1108. package/node_modules/@fps-games/plugin-shadow-map-experiment/dist/reference.d.ts +8 -0
  1109. package/node_modules/@fps-games/plugin-shadow-map-experiment/dist/reference.d.ts.map +1 -0
  1110. package/node_modules/@fps-games/plugin-shadow-map-experiment/dist/reference.js +35 -0
  1111. package/node_modules/@fps-games/plugin-shadow-map-experiment/dist/reference.js.map +1 -0
  1112. package/node_modules/@fps-games/plugin-shadow-map-experiment/dist/runtime.d.ts +11 -0
  1113. package/node_modules/@fps-games/plugin-shadow-map-experiment/dist/runtime.d.ts.map +1 -0
  1114. package/node_modules/@fps-games/plugin-shadow-map-experiment/dist/runtime.js +14 -0
  1115. package/node_modules/@fps-games/plugin-shadow-map-experiment/dist/runtime.js.map +1 -0
  1116. package/node_modules/@fps-games/plugin-shadow-map-experiment/dist/version.d.ts +2 -0
  1117. package/node_modules/@fps-games/plugin-shadow-map-experiment/dist/version.d.ts.map +1 -0
  1118. package/node_modules/@fps-games/plugin-shadow-map-experiment/dist/version.js +2 -0
  1119. package/node_modules/@fps-games/plugin-shadow-map-experiment/dist/version.js.map +1 -0
  1120. package/node_modules/@fps-games/plugin-shadow-map-experiment/package.json +53 -0
  1121. package/node_modules/@fps-games/plugin-shadows/dist/version.d.ts +1 -1
  1122. package/node_modules/@fps-games/plugin-shadows/dist/version.js +1 -1
  1123. package/node_modules/@fps-games/plugin-shadows/dist/version.js.map +1 -1
  1124. package/node_modules/@fps-games/plugin-shadows/package.json +7 -7
  1125. package/node_modules/@playcanvas/observer/LICENSE +19 -0
  1126. package/node_modules/@playcanvas/observer/README.md +72 -0
  1127. package/node_modules/@playcanvas/observer/dist/index.cjs +2033 -0
  1128. package/node_modules/@playcanvas/observer/dist/index.js +2039 -0
  1129. package/node_modules/@playcanvas/observer/dist/index.mjs +2026 -0
  1130. package/node_modules/@playcanvas/observer/package.json +78 -0
  1131. package/node_modules/@playcanvas/observer/types/event-handle.d.ts +41 -0
  1132. package/node_modules/@playcanvas/observer/types/events.d.ts +162 -0
  1133. package/node_modules/@playcanvas/observer/types/history.d.ts +123 -0
  1134. package/node_modules/@playcanvas/observer/types/index.d.ts +15 -0
  1135. package/node_modules/@playcanvas/observer/types/observer-history.d.ts +32 -0
  1136. package/node_modules/@playcanvas/observer/types/observer-list.d.ts +39 -0
  1137. package/node_modules/@playcanvas/observer/types/observer.d.ts +157 -0
  1138. package/node_modules/@playcanvas/observer/types/utils.d.ts +33 -0
  1139. package/node_modules/@playcanvas/pcui/LICENSE +19 -0
  1140. package/node_modules/@playcanvas/pcui/README.md +164 -0
  1141. package/node_modules/@playcanvas/pcui/dist/module/node_modules/playcanvas/build/playcanvas/src/core/math/constants.mjs +6 -0
  1142. package/node_modules/@playcanvas/pcui/dist/module/node_modules/playcanvas/build/playcanvas/src/core/math/curve-evaluator.mjs +119 -0
  1143. package/node_modules/@playcanvas/pcui/dist/module/node_modules/playcanvas/build/playcanvas/src/core/math/curve-set.mjs +82 -0
  1144. package/node_modules/@playcanvas/pcui/dist/module/node_modules/playcanvas/build/playcanvas/src/core/math/curve.mjs +92 -0
  1145. package/node_modules/@playcanvas/pcui/dist/module/node_modules/playcanvas/build/playcanvas/src/core/math/math.mjs +105 -0
  1146. package/node_modules/@playcanvas/pcui/dist/module/src/Math/color-value.mjs +77 -0
  1147. package/node_modules/@playcanvas/pcui/dist/module/src/binding/BindingBase/index.mjs +215 -0
  1148. package/node_modules/@playcanvas/pcui/dist/module/src/binding/BindingElementToObservers/index.mjs +297 -0
  1149. package/node_modules/@playcanvas/pcui/dist/module/src/binding/BindingObserversToElement/index.mjs +110 -0
  1150. package/node_modules/@playcanvas/pcui/dist/module/src/binding/BindingTwoWay/index.mjs +113 -0
  1151. package/node_modules/@playcanvas/pcui/dist/module/src/class.mjs +19 -0
  1152. package/node_modules/@playcanvas/pcui/dist/module/src/components/ArrayInput/index.mjs +498 -0
  1153. package/node_modules/@playcanvas/pcui/dist/module/src/components/BooleanInput/index.mjs +122 -0
  1154. package/node_modules/@playcanvas/pcui/dist/module/src/components/Button/index.mjs +119 -0
  1155. package/node_modules/@playcanvas/pcui/dist/module/src/components/Canvas/index.mjs +104 -0
  1156. package/node_modules/@playcanvas/pcui/dist/module/src/components/Code/index.mjs +43 -0
  1157. package/node_modules/@playcanvas/pcui/dist/module/src/components/ColorPicker/index.mjs +619 -0
  1158. package/node_modules/@playcanvas/pcui/dist/module/src/components/Container/index.mjs +642 -0
  1159. package/node_modules/@playcanvas/pcui/dist/module/src/components/Divider/index.mjs +20 -0
  1160. package/node_modules/@playcanvas/pcui/dist/module/src/components/Element/index.mjs +829 -0
  1161. package/node_modules/@playcanvas/pcui/dist/module/src/components/GradientPicker/index.mjs +1136 -0
  1162. package/node_modules/@playcanvas/pcui/dist/module/src/components/GridView/index.mjs +448 -0
  1163. package/node_modules/@playcanvas/pcui/dist/module/src/components/GridViewItem/index.mjs +152 -0
  1164. package/node_modules/@playcanvas/pcui/dist/module/src/components/InfoBox/index.mjs +90 -0
  1165. package/node_modules/@playcanvas/pcui/dist/module/src/components/InputElement/index.mjs +186 -0
  1166. package/node_modules/@playcanvas/pcui/dist/module/src/components/Label/index.mjs +124 -0
  1167. package/node_modules/@playcanvas/pcui/dist/module/src/components/LabelGroup/index.mjs +74 -0
  1168. package/node_modules/@playcanvas/pcui/dist/module/src/components/Menu/index.mjs +174 -0
  1169. package/node_modules/@playcanvas/pcui/dist/module/src/components/MenuItem/index.mjs +223 -0
  1170. package/node_modules/@playcanvas/pcui/dist/module/src/components/NumericInput/index.mjs +400 -0
  1171. package/node_modules/@playcanvas/pcui/dist/module/src/components/Overlay/index.mjs +108 -0
  1172. package/node_modules/@playcanvas/pcui/dist/module/src/components/Panel/index.mjs +400 -0
  1173. package/node_modules/@playcanvas/pcui/dist/module/src/components/Progress/index.mjs +45 -0
  1174. package/node_modules/@playcanvas/pcui/dist/module/src/components/RadioButton/index.mjs +113 -0
  1175. package/node_modules/@playcanvas/pcui/dist/module/src/components/SelectInput/index.mjs +1085 -0
  1176. package/node_modules/@playcanvas/pcui/dist/module/src/components/SliderInput/index.mjs +333 -0
  1177. package/node_modules/@playcanvas/pcui/dist/module/src/components/Spinner/index.mjs +34 -0
  1178. package/node_modules/@playcanvas/pcui/dist/module/src/components/TextAreaInput/index.mjs +50 -0
  1179. package/node_modules/@playcanvas/pcui/dist/module/src/components/TextInput/index.mjs +98 -0
  1180. package/node_modules/@playcanvas/pcui/dist/module/src/components/TreeView/index.mjs +1131 -0
  1181. package/node_modules/@playcanvas/pcui/dist/module/src/components/TreeViewItem/index.mjs +500 -0
  1182. package/node_modules/@playcanvas/pcui/dist/module/src/components/VectorInput/index.mjs +366 -0
  1183. package/node_modules/@playcanvas/pcui/dist/module/src/helpers/search.mjs +194 -0
  1184. package/node_modules/@playcanvas/pcui/dist/module/src/helpers/utils.mjs +43 -0
  1185. package/node_modules/@playcanvas/pcui/dist/module/src/index.mjs +56 -0
  1186. package/node_modules/@playcanvas/pcui/dist/pcui-theme-green.scss +2798 -0
  1187. package/node_modules/@playcanvas/pcui/dist/pcui-theme-grey.scss +2798 -0
  1188. package/node_modules/@playcanvas/pcui/package.json +150 -0
  1189. package/node_modules/@playcanvas/pcui/react/dist/module/node_modules/playcanvas/build/playcanvas/src/core/math/constants.mjs +6 -0
  1190. package/node_modules/@playcanvas/pcui/react/dist/module/node_modules/playcanvas/build/playcanvas/src/core/math/curve-evaluator.mjs +119 -0
  1191. package/node_modules/@playcanvas/pcui/react/dist/module/node_modules/playcanvas/build/playcanvas/src/core/math/curve-set.mjs +82 -0
  1192. package/node_modules/@playcanvas/pcui/react/dist/module/node_modules/playcanvas/build/playcanvas/src/core/math/curve.mjs +92 -0
  1193. package/node_modules/@playcanvas/pcui/react/dist/module/node_modules/playcanvas/build/playcanvas/src/core/math/math.mjs +105 -0
  1194. package/node_modules/@playcanvas/pcui/react/dist/module/src/Math/color-value.mjs +77 -0
  1195. package/node_modules/@playcanvas/pcui/react/dist/module/src/binding/BindingBase/index.mjs +215 -0
  1196. package/node_modules/@playcanvas/pcui/react/dist/module/src/binding/BindingElementToObservers/index.mjs +297 -0
  1197. package/node_modules/@playcanvas/pcui/react/dist/module/src/binding/BindingObserversToElement/index.mjs +110 -0
  1198. package/node_modules/@playcanvas/pcui/react/dist/module/src/binding/BindingTwoWay/index.mjs +113 -0
  1199. package/node_modules/@playcanvas/pcui/react/dist/module/src/class.mjs +19 -0
  1200. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/ArrayInput/component.mjs +11 -0
  1201. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/ArrayInput/index.mjs +498 -0
  1202. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/BooleanInput/component.mjs +11 -0
  1203. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/BooleanInput/index.mjs +122 -0
  1204. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Button/component.mjs +16 -0
  1205. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Button/index.mjs +119 -0
  1206. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Canvas/component.mjs +16 -0
  1207. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Canvas/index.mjs +104 -0
  1208. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Code/component.mjs +11 -0
  1209. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Code/index.mjs +43 -0
  1210. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/ColorPicker/component.mjs +16 -0
  1211. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/ColorPicker/index.mjs +619 -0
  1212. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Container/component.mjs +36 -0
  1213. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Container/index.mjs +642 -0
  1214. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Divider/component.mjs +11 -0
  1215. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Divider/index.mjs +20 -0
  1216. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Element/component.mjs +107 -0
  1217. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Element/index.mjs +829 -0
  1218. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/GradientPicker/component.mjs +16 -0
  1219. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/GradientPicker/index.mjs +1136 -0
  1220. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/GridView/component.mjs +38 -0
  1221. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/GridView/index.mjs +448 -0
  1222. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/GridViewItem/component.mjs +11 -0
  1223. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/GridViewItem/index.mjs +152 -0
  1224. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/InfoBox/component.mjs +16 -0
  1225. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/InfoBox/index.mjs +90 -0
  1226. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/InputElement/index.mjs +186 -0
  1227. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Label/component.mjs +16 -0
  1228. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Label/index.mjs +124 -0
  1229. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/LabelGroup/component.mjs +42 -0
  1230. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/LabelGroup/index.mjs +74 -0
  1231. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Menu/component.mjs +23 -0
  1232. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Menu/index.mjs +174 -0
  1233. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/MenuItem/index.mjs +223 -0
  1234. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/NumericInput/component.mjs +11 -0
  1235. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/NumericInput/index.mjs +400 -0
  1236. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Overlay/component.mjs +11 -0
  1237. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Overlay/index.mjs +108 -0
  1238. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Panel/component.mjs +32 -0
  1239. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Panel/index.mjs +400 -0
  1240. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Progress/component.mjs +11 -0
  1241. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Progress/index.mjs +45 -0
  1242. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/RadioButton/component.mjs +11 -0
  1243. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/RadioButton/index.mjs +113 -0
  1244. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/SelectInput/component.mjs +21 -0
  1245. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/SelectInput/index.mjs +1085 -0
  1246. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/SliderInput/component.mjs +12 -0
  1247. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/SliderInput/index.mjs +333 -0
  1248. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Spinner/component.mjs +16 -0
  1249. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/Spinner/index.mjs +34 -0
  1250. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/TextAreaInput/component.mjs +11 -0
  1251. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/TextAreaInput/index.mjs +50 -0
  1252. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/TextInput/component.mjs +23 -0
  1253. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/TextInput/index.mjs +98 -0
  1254. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/TreeView/component.mjs +52 -0
  1255. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/TreeView/index.mjs +1131 -0
  1256. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/TreeViewItem/component.mjs +33 -0
  1257. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/TreeViewItem/index.mjs +500 -0
  1258. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/VectorInput/component.mjs +11 -0
  1259. package/node_modules/@playcanvas/pcui/react/dist/module/src/components/VectorInput/index.mjs +366 -0
  1260. package/node_modules/@playcanvas/pcui/react/dist/module/src/helpers/search.mjs +194 -0
  1261. package/node_modules/@playcanvas/pcui/react/dist/module/src/helpers/utils.mjs +43 -0
  1262. package/node_modules/@playcanvas/pcui/react/dist/module/src/index.mjs +39 -0
  1263. package/node_modules/@playcanvas/pcui/react/package.json +18 -0
  1264. package/node_modules/@playcanvas/pcui/react/types/Math/color-value.d.ts +3 -0
  1265. package/node_modules/@playcanvas/pcui/react/types/binding/BindingBase/index.d.ts +178 -0
  1266. package/node_modules/@playcanvas/pcui/react/types/binding/BindingElementToObservers/index.d.ts +24 -0
  1267. package/node_modules/@playcanvas/pcui/react/types/binding/BindingObserversToElement/index.d.ts +40 -0
  1268. package/node_modules/@playcanvas/pcui/react/types/binding/BindingTwoWay/index.d.ts +54 -0
  1269. package/node_modules/@playcanvas/pcui/react/types/binding/index.d.ts +5 -0
  1270. package/node_modules/@playcanvas/pcui/react/types/class.d.ts +17 -0
  1271. package/node_modules/@playcanvas/pcui/react/types/components/ArrayInput/component.d.ts +9 -0
  1272. package/node_modules/@playcanvas/pcui/react/types/components/ArrayInput/index.d.ts +140 -0
  1273. package/node_modules/@playcanvas/pcui/react/types/components/BooleanInput/component.d.ts +9 -0
  1274. package/node_modules/@playcanvas/pcui/react/types/components/BooleanInput/index.d.ts +41 -0
  1275. package/node_modules/@playcanvas/pcui/react/types/components/Button/component.d.ts +11 -0
  1276. package/node_modules/@playcanvas/pcui/react/types/components/Button/index.d.ts +75 -0
  1277. package/node_modules/@playcanvas/pcui/react/types/components/Canvas/component.d.ts +11 -0
  1278. package/node_modules/@playcanvas/pcui/react/types/components/Canvas/index.d.ts +61 -0
  1279. package/node_modules/@playcanvas/pcui/react/types/components/Code/component.d.ts +9 -0
  1280. package/node_modules/@playcanvas/pcui/react/types/components/Code/index.d.ts +33 -0
  1281. package/node_modules/@playcanvas/pcui/react/types/components/ColorPicker/component.d.ts +11 -0
  1282. package/node_modules/@playcanvas/pcui/react/types/components/ColorPicker/index.d.ts +99 -0
  1283. package/node_modules/@playcanvas/pcui/react/types/components/Container/component.d.ts +15 -0
  1284. package/node_modules/@playcanvas/pcui/react/types/components/Container/index.d.ts +292 -0
  1285. package/node_modules/@playcanvas/pcui/react/types/components/Divider/component.d.ts +10 -0
  1286. package/node_modules/@playcanvas/pcui/react/types/components/Divider/index.d.ts +13 -0
  1287. package/node_modules/@playcanvas/pcui/react/types/components/Element/component.d.ts +23 -0
  1288. package/node_modules/@playcanvas/pcui/react/types/components/Element/index.d.ts +671 -0
  1289. package/node_modules/@playcanvas/pcui/react/types/components/GradientPicker/component.d.ts +11 -0
  1290. package/node_modules/@playcanvas/pcui/react/types/components/GradientPicker/index.d.ts +152 -0
  1291. package/node_modules/@playcanvas/pcui/react/types/components/GridView/component.d.ts +14 -0
  1292. package/node_modules/@playcanvas/pcui/react/types/components/GridView/index.d.ts +103 -0
  1293. package/node_modules/@playcanvas/pcui/react/types/components/GridViewItem/component.d.ts +9 -0
  1294. package/node_modules/@playcanvas/pcui/react/types/components/GridViewItem/index.d.ts +82 -0
  1295. package/node_modules/@playcanvas/pcui/react/types/components/InfoBox/component.d.ts +11 -0
  1296. package/node_modules/@playcanvas/pcui/react/types/components/InfoBox/index.d.ts +71 -0
  1297. package/node_modules/@playcanvas/pcui/react/types/components/InputElement/index.d.ts +84 -0
  1298. package/node_modules/@playcanvas/pcui/react/types/components/Label/component.d.ts +11 -0
  1299. package/node_modules/@playcanvas/pcui/react/types/components/Label/index.d.ts +85 -0
  1300. package/node_modules/@playcanvas/pcui/react/types/components/LabelGroup/component.d.ts +10 -0
  1301. package/node_modules/@playcanvas/pcui/react/types/components/LabelGroup/index.d.ts +62 -0
  1302. package/node_modules/@playcanvas/pcui/react/types/components/Menu/component.d.ts +14 -0
  1303. package/node_modules/@playcanvas/pcui/react/types/components/Menu/index.d.ts +70 -0
  1304. package/node_modules/@playcanvas/pcui/react/types/components/MenuItem/index.d.ts +139 -0
  1305. package/node_modules/@playcanvas/pcui/react/types/components/NumericInput/component.d.ts +9 -0
  1306. package/node_modules/@playcanvas/pcui/react/types/components/NumericInput/index.d.ts +173 -0
  1307. package/node_modules/@playcanvas/pcui/react/types/components/Overlay/component.d.ts +9 -0
  1308. package/node_modules/@playcanvas/pcui/react/types/components/Overlay/index.d.ts +53 -0
  1309. package/node_modules/@playcanvas/pcui/react/types/components/Panel/component.d.ts +16 -0
  1310. package/node_modules/@playcanvas/pcui/react/types/components/Panel/index.d.ts +178 -0
  1311. package/node_modules/@playcanvas/pcui/react/types/components/Progress/component.d.ts +9 -0
  1312. package/node_modules/@playcanvas/pcui/react/types/components/Progress/index.d.ts +33 -0
  1313. package/node_modules/@playcanvas/pcui/react/types/components/RadioButton/component.d.ts +9 -0
  1314. package/node_modules/@playcanvas/pcui/react/types/components/RadioButton/index.d.ts +33 -0
  1315. package/node_modules/@playcanvas/pcui/react/types/components/SelectInput/component.d.ts +12 -0
  1316. package/node_modules/@playcanvas/pcui/react/types/components/SelectInput/index.d.ts +278 -0
  1317. package/node_modules/@playcanvas/pcui/react/types/components/SliderInput/component.d.ts +10 -0
  1318. package/node_modules/@playcanvas/pcui/react/types/components/SliderInput/index.d.ts +133 -0
  1319. package/node_modules/@playcanvas/pcui/react/types/components/Spinner/component.d.ts +11 -0
  1320. package/node_modules/@playcanvas/pcui/react/types/components/Spinner/index.d.ts +27 -0
  1321. package/node_modules/@playcanvas/pcui/react/types/components/TextAreaInput/component.d.ts +9 -0
  1322. package/node_modules/@playcanvas/pcui/react/types/components/TextAreaInput/index.d.ts +24 -0
  1323. package/node_modules/@playcanvas/pcui/react/types/components/TextInput/component.d.ts +12 -0
  1324. package/node_modules/@playcanvas/pcui/react/types/components/TextInput/index.d.ts +40 -0
  1325. package/node_modules/@playcanvas/pcui/react/types/components/TreeView/component.d.ts +17 -0
  1326. package/node_modules/@playcanvas/pcui/react/types/components/TreeView/index.d.ts +359 -0
  1327. package/node_modules/@playcanvas/pcui/react/types/components/TreeViewItem/component.d.ts +13 -0
  1328. package/node_modules/@playcanvas/pcui/react/types/components/TreeViewItem/index.d.ts +224 -0
  1329. package/node_modules/@playcanvas/pcui/react/types/components/VectorInput/component.d.ts +9 -0
  1330. package/node_modules/@playcanvas/pcui/react/types/components/VectorInput/index.d.ts +176 -0
  1331. package/node_modules/@playcanvas/pcui/react/types/components/components.d.ts +30 -0
  1332. package/node_modules/@playcanvas/pcui/react/types/components/index.d.ts +32 -0
  1333. package/node_modules/@playcanvas/pcui/react/types/helpers/search.d.ts +31 -0
  1334. package/node_modules/@playcanvas/pcui/react/types/helpers/utils.d.ts +2 -0
  1335. package/node_modules/@playcanvas/pcui/react/types/index.d.ts +4 -0
  1336. package/node_modules/@playcanvas/pcui/styles/dist/index.mjs +11 -0
  1337. package/node_modules/@playcanvas/pcui/styles/package.json +17 -0
  1338. package/node_modules/@playcanvas/pcui/types/Math/color-value.d.ts +3 -0
  1339. package/node_modules/@playcanvas/pcui/types/binding/BindingBase/index.d.ts +178 -0
  1340. package/node_modules/@playcanvas/pcui/types/binding/BindingElementToObservers/index.d.ts +24 -0
  1341. package/node_modules/@playcanvas/pcui/types/binding/BindingObserversToElement/index.d.ts +40 -0
  1342. package/node_modules/@playcanvas/pcui/types/binding/BindingTwoWay/index.d.ts +54 -0
  1343. package/node_modules/@playcanvas/pcui/types/binding/index.d.ts +5 -0
  1344. package/node_modules/@playcanvas/pcui/types/class.d.ts +17 -0
  1345. package/node_modules/@playcanvas/pcui/types/components/ArrayInput/index.d.ts +140 -0
  1346. package/node_modules/@playcanvas/pcui/types/components/BooleanInput/index.d.ts +41 -0
  1347. package/node_modules/@playcanvas/pcui/types/components/Button/index.d.ts +75 -0
  1348. package/node_modules/@playcanvas/pcui/types/components/Canvas/index.d.ts +61 -0
  1349. package/node_modules/@playcanvas/pcui/types/components/Code/index.d.ts +33 -0
  1350. package/node_modules/@playcanvas/pcui/types/components/ColorPicker/index.d.ts +99 -0
  1351. package/node_modules/@playcanvas/pcui/types/components/Container/index.d.ts +292 -0
  1352. package/node_modules/@playcanvas/pcui/types/components/Divider/index.d.ts +13 -0
  1353. package/node_modules/@playcanvas/pcui/types/components/Element/index.d.ts +671 -0
  1354. package/node_modules/@playcanvas/pcui/types/components/GradientPicker/index.d.ts +152 -0
  1355. package/node_modules/@playcanvas/pcui/types/components/GridView/index.d.ts +103 -0
  1356. package/node_modules/@playcanvas/pcui/types/components/GridViewItem/index.d.ts +82 -0
  1357. package/node_modules/@playcanvas/pcui/types/components/InfoBox/index.d.ts +71 -0
  1358. package/node_modules/@playcanvas/pcui/types/components/InputElement/index.d.ts +84 -0
  1359. package/node_modules/@playcanvas/pcui/types/components/Label/index.d.ts +85 -0
  1360. package/node_modules/@playcanvas/pcui/types/components/LabelGroup/index.d.ts +62 -0
  1361. package/node_modules/@playcanvas/pcui/types/components/Menu/index.d.ts +70 -0
  1362. package/node_modules/@playcanvas/pcui/types/components/MenuItem/index.d.ts +139 -0
  1363. package/node_modules/@playcanvas/pcui/types/components/NumericInput/index.d.ts +173 -0
  1364. package/node_modules/@playcanvas/pcui/types/components/Overlay/index.d.ts +53 -0
  1365. package/node_modules/@playcanvas/pcui/types/components/Panel/index.d.ts +178 -0
  1366. package/node_modules/@playcanvas/pcui/types/components/Progress/index.d.ts +33 -0
  1367. package/node_modules/@playcanvas/pcui/types/components/RadioButton/index.d.ts +33 -0
  1368. package/node_modules/@playcanvas/pcui/types/components/SelectInput/index.d.ts +278 -0
  1369. package/node_modules/@playcanvas/pcui/types/components/SliderInput/index.d.ts +133 -0
  1370. package/node_modules/@playcanvas/pcui/types/components/Spinner/index.d.ts +27 -0
  1371. package/node_modules/@playcanvas/pcui/types/components/TextAreaInput/index.d.ts +24 -0
  1372. package/node_modules/@playcanvas/pcui/types/components/TextInput/index.d.ts +40 -0
  1373. package/node_modules/@playcanvas/pcui/types/components/TreeView/index.d.ts +359 -0
  1374. package/node_modules/@playcanvas/pcui/types/components/TreeViewItem/index.d.ts +224 -0
  1375. package/node_modules/@playcanvas/pcui/types/components/VectorInput/index.d.ts +176 -0
  1376. package/node_modules/@playcanvas/pcui/types/components/index.d.ts +32 -0
  1377. package/node_modules/@playcanvas/pcui/types/helpers/search.d.ts +31 -0
  1378. package/node_modules/@playcanvas/pcui/types/helpers/utils.d.ts +2 -0
  1379. package/node_modules/@playcanvas/pcui/types/index.d.ts +20 -0
  1380. package/node_modules/babylonjs-gltf2interface/babylon.glTF2Interface.d.ts +1655 -0
  1381. package/node_modules/babylonjs-gltf2interface/license.md +71 -0
  1382. package/node_modules/babylonjs-gltf2interface/package.json +26 -0
  1383. package/package.json +31 -19
  1384. package/dist/editor-plugin-hierarchy-command.d.ts +0 -19
  1385. package/dist/editor-plugin-hierarchy-command.d.ts.map +0 -1
  1386. package/dist/editor-plugin-hierarchy-command.js +0 -119
  1387. package/dist/editor-plugin-hierarchy-command.js.map +0 -1
  1388. package/node_modules/@babel/helper-string-parser/lib/index.js.map +0 -1
  1389. package/node_modules/@babel/helper-validator-identifier/lib/identifier.js.map +0 -1
  1390. package/node_modules/@babel/helper-validator-identifier/lib/index.js.map +0 -1
  1391. package/node_modules/@babel/helper-validator-identifier/lib/keyword.js.map +0 -1
  1392. package/node_modules/@babel/parser/lib/index.js.map +0 -1
  1393. package/node_modules/@babel/types/lib/asserts/assertNode.js.map +0 -1
  1394. package/node_modules/@babel/types/lib/asserts/generated/index.js.map +0 -1
  1395. package/node_modules/@babel/types/lib/ast-types/generated/index.js.map +0 -1
  1396. package/node_modules/@babel/types/lib/builders/flow/createFlowUnionType.js.map +0 -1
  1397. package/node_modules/@babel/types/lib/builders/flow/createTypeAnnotationBasedOnTypeof.js.map +0 -1
  1398. package/node_modules/@babel/types/lib/builders/generated/index.js.map +0 -1
  1399. package/node_modules/@babel/types/lib/builders/generated/lowercase.js.map +0 -1
  1400. package/node_modules/@babel/types/lib/builders/generated/uppercase.js.map +0 -1
  1401. package/node_modules/@babel/types/lib/builders/productions.js.map +0 -1
  1402. package/node_modules/@babel/types/lib/builders/react/buildChildren.js.map +0 -1
  1403. package/node_modules/@babel/types/lib/builders/typescript/createTSUnionType.js.map +0 -1
  1404. package/node_modules/@babel/types/lib/builders/validateNode.js.map +0 -1
  1405. package/node_modules/@babel/types/lib/clone/clone.js.map +0 -1
  1406. package/node_modules/@babel/types/lib/clone/cloneDeep.js.map +0 -1
  1407. package/node_modules/@babel/types/lib/clone/cloneDeepWithoutLoc.js.map +0 -1
  1408. package/node_modules/@babel/types/lib/clone/cloneNode.js.map +0 -1
  1409. package/node_modules/@babel/types/lib/clone/cloneWithoutLoc.js.map +0 -1
  1410. package/node_modules/@babel/types/lib/comments/addComment.js.map +0 -1
  1411. package/node_modules/@babel/types/lib/comments/addComments.js.map +0 -1
  1412. package/node_modules/@babel/types/lib/comments/inheritInnerComments.js.map +0 -1
  1413. package/node_modules/@babel/types/lib/comments/inheritLeadingComments.js.map +0 -1
  1414. package/node_modules/@babel/types/lib/comments/inheritTrailingComments.js.map +0 -1
  1415. package/node_modules/@babel/types/lib/comments/inheritsComments.js.map +0 -1
  1416. package/node_modules/@babel/types/lib/comments/removeComments.js.map +0 -1
  1417. package/node_modules/@babel/types/lib/constants/generated/index.js.map +0 -1
  1418. package/node_modules/@babel/types/lib/constants/index.js.map +0 -1
  1419. package/node_modules/@babel/types/lib/converters/ensureBlock.js.map +0 -1
  1420. package/node_modules/@babel/types/lib/converters/gatherSequenceExpressions.js.map +0 -1
  1421. package/node_modules/@babel/types/lib/converters/toBindingIdentifierName.js.map +0 -1
  1422. package/node_modules/@babel/types/lib/converters/toBlock.js.map +0 -1
  1423. package/node_modules/@babel/types/lib/converters/toComputedKey.js.map +0 -1
  1424. package/node_modules/@babel/types/lib/converters/toExpression.js.map +0 -1
  1425. package/node_modules/@babel/types/lib/converters/toIdentifier.js.map +0 -1
  1426. package/node_modules/@babel/types/lib/converters/toKeyAlias.js.map +0 -1
  1427. package/node_modules/@babel/types/lib/converters/toSequenceExpression.js.map +0 -1
  1428. package/node_modules/@babel/types/lib/converters/toStatement.js.map +0 -1
  1429. package/node_modules/@babel/types/lib/converters/valueToNode.js.map +0 -1
  1430. package/node_modules/@babel/types/lib/definitions/core.js.map +0 -1
  1431. package/node_modules/@babel/types/lib/definitions/deprecated-aliases.js.map +0 -1
  1432. package/node_modules/@babel/types/lib/definitions/experimental.js.map +0 -1
  1433. package/node_modules/@babel/types/lib/definitions/flow.js.map +0 -1
  1434. package/node_modules/@babel/types/lib/definitions/index.js.map +0 -1
  1435. package/node_modules/@babel/types/lib/definitions/jsx.js.map +0 -1
  1436. package/node_modules/@babel/types/lib/definitions/misc.js.map +0 -1
  1437. package/node_modules/@babel/types/lib/definitions/placeholders.js.map +0 -1
  1438. package/node_modules/@babel/types/lib/definitions/typescript.js.map +0 -1
  1439. package/node_modules/@babel/types/lib/definitions/utils.js.map +0 -1
  1440. package/node_modules/@babel/types/lib/index.js.map +0 -1
  1441. package/node_modules/@babel/types/lib/modifications/appendToMemberExpression.js.map +0 -1
  1442. package/node_modules/@babel/types/lib/modifications/flow/removeTypeDuplicates.js.map +0 -1
  1443. package/node_modules/@babel/types/lib/modifications/inherits.js.map +0 -1
  1444. package/node_modules/@babel/types/lib/modifications/prependToMemberExpression.js.map +0 -1
  1445. package/node_modules/@babel/types/lib/modifications/removeProperties.js.map +0 -1
  1446. package/node_modules/@babel/types/lib/modifications/removePropertiesDeep.js.map +0 -1
  1447. package/node_modules/@babel/types/lib/modifications/typescript/removeTypeDuplicates.js.map +0 -1
  1448. package/node_modules/@babel/types/lib/retrievers/getAssignmentIdentifiers.js.map +0 -1
  1449. package/node_modules/@babel/types/lib/retrievers/getBindingIdentifiers.js.map +0 -1
  1450. package/node_modules/@babel/types/lib/retrievers/getFunctionName.js.map +0 -1
  1451. package/node_modules/@babel/types/lib/retrievers/getOuterBindingIdentifiers.js.map +0 -1
  1452. package/node_modules/@babel/types/lib/traverse/traverse.js.map +0 -1
  1453. package/node_modules/@babel/types/lib/traverse/traverseFast.js.map +0 -1
  1454. package/node_modules/@babel/types/lib/utils/deprecationWarning.js.map +0 -1
  1455. package/node_modules/@babel/types/lib/utils/inherit.js.map +0 -1
  1456. package/node_modules/@babel/types/lib/utils/react/cleanJSXElementLiteralChild.js.map +0 -1
  1457. package/node_modules/@babel/types/lib/utils/shallowEqual.js.map +0 -1
  1458. package/node_modules/@babel/types/lib/validators/buildMatchMemberExpression.js.map +0 -1
  1459. package/node_modules/@babel/types/lib/validators/generated/index.js.map +0 -1
  1460. package/node_modules/@babel/types/lib/validators/is.js.map +0 -1
  1461. package/node_modules/@babel/types/lib/validators/isBinding.js.map +0 -1
  1462. package/node_modules/@babel/types/lib/validators/isBlockScoped.js.map +0 -1
  1463. package/node_modules/@babel/types/lib/validators/isImmutable.js.map +0 -1
  1464. package/node_modules/@babel/types/lib/validators/isLet.js.map +0 -1
  1465. package/node_modules/@babel/types/lib/validators/isNode.js.map +0 -1
  1466. package/node_modules/@babel/types/lib/validators/isNodesEquivalent.js.map +0 -1
  1467. package/node_modules/@babel/types/lib/validators/isPlaceholderType.js.map +0 -1
  1468. package/node_modules/@babel/types/lib/validators/isReferenced.js.map +0 -1
  1469. package/node_modules/@babel/types/lib/validators/isScope.js.map +0 -1
  1470. package/node_modules/@babel/types/lib/validators/isSpecifierDefault.js.map +0 -1
  1471. package/node_modules/@babel/types/lib/validators/isType.js.map +0 -1
  1472. package/node_modules/@babel/types/lib/validators/isValidES3Identifier.js.map +0 -1
  1473. package/node_modules/@babel/types/lib/validators/isValidIdentifier.js.map +0 -1
  1474. package/node_modules/@babel/types/lib/validators/isVar.js.map +0 -1
  1475. package/node_modules/@babel/types/lib/validators/matchesPattern.js.map +0 -1
  1476. package/node_modules/@babel/types/lib/validators/react/isCompatTag.js.map +0 -1
  1477. package/node_modules/@babel/types/lib/validators/react/isReactComponent.js.map +0 -1
  1478. package/node_modules/@babel/types/lib/validators/validate.js.map +0 -1
  1479. package/node_modules/@fps-games/editor-babylon/dist/prefab-comparison-preview-controller.d.ts +0 -37
  1480. package/node_modules/@fps-games/editor-babylon/dist/prefab-comparison-preview-controller.d.ts.map +0 -1
  1481. package/node_modules/@fps-games/editor-babylon/dist/prefab-comparison-preview-controller.js +0 -451
  1482. package/node_modules/@fps-games/editor-babylon/dist/prefab-comparison-preview-controller.js.map +0 -1
  1483. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.d.ts +0 -49
  1484. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.d.ts.map +0 -1
  1485. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.js +0 -627
  1486. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-actions.js.map +0 -1
  1487. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.d.ts +0 -52
  1488. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.d.ts.map +0 -1
  1489. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.js +0 -450
  1490. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-attach-dialog.js.map +0 -1
  1491. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-command-adapter.d.ts +0 -21
  1492. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-command-adapter.d.ts.map +0 -1
  1493. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-command-adapter.js +0 -75
  1494. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-command-adapter.js.map +0 -1
  1495. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-projection.d.ts +0 -7
  1496. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-projection.d.ts.map +0 -1
  1497. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-projection.js +0 -186
  1498. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-projection.js.map +0 -1
  1499. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-scope.d.ts +0 -5
  1500. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-scope.d.ts.map +0 -1
  1501. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-scope.js +0 -98
  1502. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-scope.js.map +0 -1
  1503. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.d.ts +0 -63
  1504. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.d.ts.map +0 -1
  1505. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.js +0 -301
  1506. package/node_modules/@fps-games/editor-browser/dist/local-editor-ui-hierarchy-tree.js.map +0 -1
@@ -7,34 +7,50 @@ import { createLocalEditorTooltipController } from './local-editor-ui-tooltip.js
7
7
  import { createLocalEditorViewportRevealController } from './local-editor-ui-dock-panel.js';
8
8
  import { createLocalEditorModalDialog } from './local-editor-ui-modal-dialog.js';
9
9
  import { parseLocalEditorBrowserInspectorGroupValueClipboardPayload, } from './local-editor-inspector-clipboard.js';
10
- import { LOCAL_EDITOR_BROWSER_INSPECTOR_VEC3_AXES, resolveLocalEditorBrowserInspectorVectorGroupPathFromPropertyPath, } from './local-editor-inspector-groups.js';
11
- import { DEFAULT_EDITOR_TRANSFORM_OPERATION_SETTINGS, DEFAULT_EDITOR_TRANSFORM_TOOL_DESCRIPTORS, } from '@fps-games/editor-core';
10
+ import { writeLocalEditorClipboardText } from './local-editor-clipboard.js';
11
+ import { captureLocalEditorAssetBrowserReturnFocus, createLocalEditorAssetBrowserContinuityController, resolveLocalEditorAssetBrowserContentKey, restoreLocalEditorAssetBrowserReturnFocus, } from './local-editor-asset-browser-continuity.js';
12
+ import { canSkipLocalEditorPreviewCleanupPass, createLocalEditorPreviewCleanupRegistry, } from './local-editor-preview-cleanup-registry.js';
13
+ import { LOCAL_EDITOR_BROWSER_INSPECTOR_VEC3_AXES, resolveLocalEditorBrowserInspectorProportionalScaleValues, resolveLocalEditorBrowserInspectorVectorGroupAxisFromPropertyPath, resolveLocalEditorBrowserInspectorVectorGroupPathFromPropertyPath, } from './local-editor-inspector-groups.js';
14
+ import { DEFAULT_EDITOR_TRANSFORM_OPERATION_SETTINGS, } from '@fps-games/editor-core';
15
+ import { createEditorUiLayerHost } from '@fps-games/editor-ui';
16
+ import { isEditorProjectFilePreviewable, isEditorProjectMediaPreviewable, } from '@fps-games/editor-playable-sdk';
17
+ import { findLocalEditorProjectFileSearchMatches, toLocalEditorProjectRelativePath, } from './local-editor-project-file-preview.js';
18
+ import { resolveLocalEditorProjectFileOpenAction } from './local-editor-project-file-open.js';
12
19
  export { createLocalEditorViewportRevealController, isLocalEditorElementVisibleInViewport, resolveLocalEditorViewportRevealScrollTop, revealLocalEditorElementInViewport, } from './local-editor-ui-dock-panel.js';
13
- export { createLocalEditorHierarchyBlankMenu, createLocalEditorHierarchyCopyShortcutAction, createLocalEditorHierarchyDeleteShortcutAction, createLocalEditorHierarchyDuplicateShortcutAction, createLocalEditorHierarchyNodeMenu, createLocalEditorHierarchyPasteShortcutAction, createLocalEditorHierarchySelectAllShortcutAction, } from './local-editor-ui-hierarchy-actions.js';
14
- export { createLocalEditorHierarchyController, resolveLocalEditorHierarchyCreateMarkerParentId, resolveLocalEditorHierarchyToolbarActiveId, } from './local-editor-ui-hierarchy-controller.js';
15
- export { resolveLocalEditorHierarchySearchRows, } from './local-editor-ui-hierarchy-view.js';
16
- export { createLocalEditorHierarchyAttachDialog, resolveLocalEditorHierarchyAttachTargets, } from './local-editor-ui-hierarchy-attach-dialog.js';
17
- export { canLocalEditorHierarchyNodeHaveChildren, canLocalEditorHierarchyNodeDelete, canLocalEditorHierarchyNodeRename, canLocalEditorHierarchyNodeToggleEnabled, createLocalEditorHierarchyTreeModel, isLocalEditorHierarchyNodeSelectable, isLocalEditorHierarchyNodeMovable, } from './local-editor-ui-hierarchy-tree.js';
20
+ export { canUseHierarchyProviderReparent, createHierarchyEnabledOperationRequest, createLocalEditorHierarchyController, createHierarchyOperationMenuItems, createHierarchyToolbarCreateMenuItems, matchesHierarchyOperationShortcut, } from './local-editor-ui-hierarchy-controller.js';
21
+ export { createLocalEditorHierarchyViewAdapter, } from './local-editor-ui-hierarchy-view-adapter.js';
18
22
  export { createLocalEditorContextMenuController, } from './local-editor-ui-context-menu.js';
19
23
  export { createLocalEditorTooltipController, } from './local-editor-ui-tooltip.js';
20
24
  import { createLocalEditorWorkbenchInputRouter } from './local-editor-ui-input-router.js';
25
+ import { createLocalEditorConsoleController } from './local-editor-ui-console.js';
26
+ import { synchronizeLocalEditorToolButtons } from './local-editor-tool-presentation.js';
21
27
  import { createLocalEditorPanelRegistry } from './local-editor-ui-panel-registry.js';
28
+ import { createLocalEditorFormalSurfaceVisibilityController, disposeLocalEditorFormalSurfaces, shouldRenderLocalEditorInspectorPreview, } from './local-editor-ui-formal-surface-visibility.js';
22
29
  import * as LocalEditorShared from './local-editor-ui-shared.js';
23
30
  import { findLocalEditorRenderingAction } from './local-editor-rendering-actions.js';
24
31
  import { createShortcutHelpPanel as createLocalEditorShortcutHelpPanel } from './local-editor-ui-shortcuts.js';
25
32
  import { applyLocalEditorTheme, ensureLocalEditorTheme, LOCAL_EDITOR_THEME_CLASS, normalizeLocalEditorThemeName, } from './local-editor-ui-theme.js';
26
33
  import { createDefaultLocalEditorWorkbenchLayout, createLocalEditorWorkbenchLayoutController, createLocalEditorWorkbench, createSceneHeaderToolbar, createWorkbenchPanelContent, } from './local-editor-ui-workbench.js';
27
34
  import { createLocalEditorIcon, isLocalEditorIconName } from './local-editor-ui-icons.js';
28
- import { createLocalEditorStatusCenterViewModel, resolveLocalEditorStatusDiagnostics, shouldCloseLocalEditorStatusCenter, } from './local-editor-ui-status-diagnostics.js';
29
- import { formatLocalEditorStatusDiagnosticDetails } from './local-editor-ui-hierarchy-projection.js';
35
+ import { createLocalEditorStatusCenterViewModel, resolveLocalEditorStatusDiagnosticLocatePlan, settleLocalEditorStatusDiagnosticRequest, resolveLocalEditorStatusDiagnostics, shouldCloseLocalEditorStatusCenter, } from './local-editor-ui-status-diagnostics.js';
36
+ import { formatLocalEditorStatusDiagnosticDetails } from './local-editor-ui-status-format.js';
30
37
  import { resolveLocalEditorBrowserAssetKind, } from './local-editor-ui-asset-kind.js';
31
- import { createLocalEditorPrefabStageTitle, findLocalEditorPrefabStageStructureItem, formatLocalEditorPrefabStageComparisonPreviewStatus, LOCAL_EDITOR_PREFAB_COMPARISON_COLUMN_WIDTH_PX, resolveLocalEditorRightDockVisibility, resolveLocalEditorPrefabStageComparisonPreviewTone, resolveLocalEditorPrefabStageWorkbenchLayout, resolveLocalEditorPreviewToolSupport, shouldLocalEditorClosePerformanceMonitor, shouldLocalEditorPrefabStageBlockHierarchyShortcut, shouldShowLocalEditorPrefabComparisonColumn, shouldToggleLocalEditorPrefabComparisonShortcut, } from './local-editor-ui-prefab-stage.js';
32
- export { applyLocalEditorBrowserInspectorControlBinding, createLocalEditorBrowserInspectorControlRegistry, formatLocalEditorBrowserInspectorNumberValue, formatLocalEditorBrowserInspectorValue, parseLocalEditorBrowserInspectorNumberValue, resolveLocalEditorBrowserInspectorSectionStatus, resolveLocalEditorBrowserInspectorControlRegistration, } from './local-editor-ui-panels.js';
38
+ import { createLocalEditorAssetFilesystemSnapshot, resolveLocalEditorAssetFilesystemFolderPath, } from './local-editor-asset-filesystem.js';
39
+ import { createLocalEditorProjectModelThumbnailCache, } from './local-editor-project-media-thumbnail-cache.js';
40
+ import { createLocalEditorPrefabStageTitle, findLocalEditorPrefabStageStructureItem, resolveLocalEditorRightDockVisibility, resolveLocalEditorPrefabStageWorkbenchLayout, resolveLocalEditorPreviewToolSupport, shouldLocalEditorClosePerformanceMonitor, } from './local-editor-ui-prefab-stage.js';
41
+ import { resolveLocalEditorCoordinateAxisActiveDirection, resolveLocalEditorCoordinateAxisDirection, } from './local-editor-viewport-orientation.js';
42
+ export { applyLocalEditorBrowserInspectorControlBinding, createLocalEditorBrowserInspectorControlRegistry, formatLocalEditorBrowserInspectorNumberValue, formatLocalEditorBrowserInspectorValue, parseLocalEditorBrowserInspectorNumberValue, resolveLocalEditorBrowserInspectorSectionStatus, resolveLocalEditorBrowserInspectorControlRegistration, shouldShowPrefabModelAddAction, } from './local-editor-ui-panels.js';
33
43
  export { createLocalEditorBrowserInspectorGroupValueClipboardPayload, createLocalEditorBrowserInspectorVectorCopyPayload, parseLocalEditorBrowserInspectorGroupValueClipboardPayload, } from './local-editor-inspector-clipboard.js';
34
44
  export { LOCAL_EDITOR_BROWSER_INSPECTOR_VEC3_AXES, isLocalEditorBrowserInspectorTransformVectorGroupPath, resolveLocalEditorBrowserInspectorVectorGroupAxisFromPropertyPath, resolveLocalEditorBrowserInspectorVectorGroupPathFromPropertyPath, resolveLocalEditorBrowserInspectorVectorGroupPathFromProperties, } from './local-editor-inspector-groups.js';
45
+ export { findLocalEditorProjectFileSearchMatches, toLocalEditorProjectRelativePath, } from './local-editor-project-file-preview.js';
35
46
  export { DEFAULT_LOCAL_EDITOR_THEME, LOCAL_EDITOR_THEME_CLASS, applyLocalEditorTheme, normalizeLocalEditorThemeName, } from './local-editor-ui-theme.js';
36
47
  export { LOCAL_EDITOR_ICON_NAMES, createLocalEditorIcon, isLocalEditorIconName, resolveLocalEditorIconName, } from './local-editor-ui-icons.js';
37
48
  const PENDING_NUMERIC_PROPERTY_INPUT = Symbol('pending-numeric-property-input');
49
+ function syncLocalEditorInspectorPendingState(panel, pending) {
50
+ panel.dataset.editorInspectorPending = String(pending);
51
+ panel.setAttribute('aria-busy', String(pending));
52
+ panel.toggleAttribute('inert', pending);
53
+ }
38
54
  function readInspectorInputValue(input, source) {
39
55
  const control = input.dataset.serializedControl;
40
56
  const valueType = input.dataset.serializedValueType;
@@ -91,12 +107,6 @@ function isInspectorSerializedInputValue(value) {
91
107
  || typeof value === 'boolean'
92
108
  || (!!value && typeof value === 'object' && !Array.isArray(value));
93
109
  }
94
- const TRANSFORM_TOOL_ICONS = {
95
- select: 'select',
96
- move: 'move',
97
- rotate: 'rotate',
98
- scale: 'scale',
99
- };
100
110
  const TRANSFORM_SPACE_ICONS = {
101
111
  world: 'world',
102
112
  local: 'local',
@@ -111,28 +121,6 @@ const PLACEMENT_MODE_DESCRIPTIONS = {
111
121
  ground: '放置到 XZ 地面',
112
122
  surface: '放置到场景表面',
113
123
  };
114
- const VIEW_PRESET_ICONS = {
115
- perspective: 'view-perspective',
116
- top: 'view-top',
117
- bottom: 'view-top',
118
- front: 'view-front',
119
- back: 'view-front',
120
- left: 'view-right',
121
- right: 'view-right',
122
- iso: 'view-perspective',
123
- threeQuarterTop: 'view-perspective',
124
- };
125
- const VIEW_PRESET_TOOLTIPS = {
126
- perspective: '透视视图',
127
- top: '顶视图 · 自动切换正交',
128
- bottom: '底视图 · 自动切换正交',
129
- front: '前视图 · 自动切换正交',
130
- back: '后视图 · 自动切换正交',
131
- left: '左视图 · 自动切换正交',
132
- right: '右视图 · 自动切换正交',
133
- iso: '等距视图 · 自动切换正交',
134
- threeQuarterTop: '斜 45° 俯视图',
135
- };
136
124
  const VIEWPORT_OVERLAY_TOGGLE_LABELS = {
137
125
  bounds: '包围盒',
138
126
  dimensions: '尺寸摘要',
@@ -143,6 +131,17 @@ const VIEWPORT_PROJECTION_LABELS = {
143
131
  perspective: '透视',
144
132
  orthographic: '正交',
145
133
  };
134
+ const VIEWPORT_VIEW_LABELS = {
135
+ perspective: '透视',
136
+ top: '顶视图',
137
+ bottom: '底视图',
138
+ front: '前视图',
139
+ back: '后视图',
140
+ left: '左视图',
141
+ right: '右视图',
142
+ iso: '等距正交',
143
+ threeQuarterTop: '斜 45° 俯视',
144
+ };
146
145
  const STATIC_SHADOW_BAKE_ACTION_ID = 'bake-static-shadows';
147
146
  const TRANSFORM_ACTION_GROUPS = [
148
147
  {
@@ -165,12 +164,6 @@ const TRANSFORM_ACTION_LABELS = {
165
164
  'distribute-y': '分布 Y',
166
165
  'distribute-z': '分布 Z',
167
166
  };
168
- function createTransformToolTooltip(descriptor) {
169
- const toolLabel = descriptor.shortcut
170
- ? `${descriptor.label}工具 (${descriptor.shortcut})`
171
- : `${descriptor.label}工具`;
172
- return `${toolLabel} · ${LocalEditorShared.toTransformMouseHint(descriptor.tool)}`;
173
- }
174
167
  function createToolbarIconButton(doc, label, icon, tooltip = label, toolbarRole = 'command') {
175
168
  return LocalEditorShared.createButton(doc, label, {
176
169
  icon,
@@ -185,6 +178,42 @@ function setToolbarButtonTooltip(button, tooltip) {
185
178
  button.dataset.editorTooltip = tooltip;
186
179
  button.setAttribute('aria-label', tooltip);
187
180
  }
181
+ export function matchesContextActionShortcut(shortcut, event) {
182
+ if (!shortcut)
183
+ return false;
184
+ const parts = shortcut.toLowerCase().split('+').map(part => part.trim()).filter(Boolean);
185
+ const key = parts[parts.length - 1];
186
+ if (!key || event.key.toLowerCase() !== key)
187
+ return false;
188
+ const needsPrimary = parts.includes('mod');
189
+ if (needsPrimary !== (event.metaKey || event.ctrlKey))
190
+ return false;
191
+ if (parts.includes('shift') !== event.shiftKey)
192
+ return false;
193
+ if (parts.includes('alt') !== event.altKey)
194
+ return false;
195
+ return true;
196
+ }
197
+ function renderContextActionButtons(group, actions, busy) {
198
+ group.replaceChildren();
199
+ const visible = actions
200
+ .filter(action => action.availability.state !== 'hidden')
201
+ .sort((left, right) => left.order - right.order || left.id.localeCompare(right.id));
202
+ group.style.display = visible.length > 0 ? 'flex' : 'none';
203
+ for (const action of visible) {
204
+ const icon = isLocalEditorIconName(action.icon) ? action.icon : 'execute';
205
+ const tooltip = action.shortcut ? `${action.label} (${action.shortcut})` : action.label;
206
+ const button = createToolbarIconButton(group.ownerDocument, action.label, icon, tooltip);
207
+ button.dataset.editorContextAction = action.id;
208
+ button.disabled = busy || action.availability.state !== 'enabled';
209
+ if (action.availability.state === 'disabled' && action.availability.reason) {
210
+ setToolbarButtonTooltip(button, action.availability.reason);
211
+ }
212
+ if (action.danger)
213
+ button.style.color = 'var(--fps-editor-danger-strong)';
214
+ group.appendChild(button);
215
+ }
216
+ }
188
217
  function createAgentBridgeStatusTooltip(status) {
189
218
  const label = formatAgentBridgeStatusLabel(status?.status);
190
219
  const details = [
@@ -282,7 +311,8 @@ function createInspectorPropertyInputs(input, source, lockedVectorGroups) {
282
311
  const propertyInput = createInspectorPropertyInput(input, source);
283
312
  if (!propertyInput)
284
313
  return null;
285
- const groupPath = resolveLocalEditorBrowserInspectorVectorGroupPathFromPropertyPath(propertyInput.path);
314
+ const vectorAxis = resolveLocalEditorBrowserInspectorVectorGroupAxisFromPropertyPath(propertyInput.path);
315
+ const groupPath = vectorAxis?.groupPath ?? null;
286
316
  const forceVectorLock = input.dataset.serializedForceVectorLock === 'true';
287
317
  if (!groupPath || (!forceVectorLock && !lockedVectorGroups.has(groupPath)))
288
318
  return [propertyInput];
@@ -290,9 +320,30 @@ function createInspectorPropertyInputs(input, source, lockedVectorGroups) {
290
320
  return [propertyInput];
291
321
  if (typeof propertyInput.value !== 'number' || !Number.isFinite(propertyInput.value))
292
322
  return [propertyInput];
323
+ if (groupPath !== 'transform.scale' || !vectorAxis)
324
+ return [propertyInput];
325
+ const group = input.closest('[data-editor-inspector-vector-group-path="transform.scale"]');
326
+ const baseValue = {};
327
+ for (const field of group?.querySelectorAll('input[data-serialized-path]') ?? []) {
328
+ const fieldAxis = resolveLocalEditorBrowserInspectorVectorGroupAxisFromPropertyPath(field.dataset.serializedPath);
329
+ const serializedBaseValue = field.dataset.serializedVectorBaseValue;
330
+ if (fieldAxis?.groupPath !== groupPath || serializedBaseValue == null)
331
+ continue;
332
+ const numericBaseValue = Number(serializedBaseValue);
333
+ if (Number.isFinite(numericBaseValue))
334
+ baseValue[fieldAxis.axis] = numericBaseValue;
335
+ }
336
+ if (!LOCAL_EDITOR_BROWSER_INSPECTOR_VEC3_AXES.every(axis => typeof baseValue[axis] === 'number')) {
337
+ return [propertyInput];
338
+ }
339
+ const serializedPrecision = Number(input.dataset.serializedNumberPrecision);
340
+ const scaleValues = resolveLocalEditorBrowserInspectorProportionalScaleValues(baseValue, vectorAxis.axis, propertyInput.value, Number.isInteger(serializedPrecision) ? serializedPrecision : 4);
341
+ if (!scaleValues)
342
+ return [propertyInput];
293
343
  return LOCAL_EDITOR_BROWSER_INSPECTOR_VEC3_AXES.map(axis => ({
294
344
  ...propertyInput,
295
345
  path: `${groupPath}.${axis}`,
346
+ value: scaleValues[axis],
296
347
  }));
297
348
  }
298
349
  function createInspectorVectorPastePropertyInputs(input, payload) {
@@ -334,23 +385,22 @@ function applyInspectorVectorPasteToDom(input, payload) {
334
385
  function applyInspectorLockedVectorInputToDom(input, propertyInputs) {
335
386
  if (!(input instanceof HTMLInputElement))
336
387
  return;
337
- const first = propertyInputs[0];
338
- if (!first || propertyInputs.length !== LOCAL_EDITOR_BROWSER_INSPECTOR_VEC3_AXES.length)
388
+ if (propertyInputs.length !== LOCAL_EDITOR_BROWSER_INSPECTOR_VEC3_AXES.length)
339
389
  return;
340
- if (typeof first.value !== 'number' || !Number.isFinite(first.value))
341
- return;
342
- const groupPath = resolveLocalEditorBrowserInspectorVectorGroupPathFromPropertyPath(first.path);
390
+ const groupPath = resolveLocalEditorBrowserInspectorVectorGroupPathFromPropertyPath(propertyInputs[0]?.path);
343
391
  if (!groupPath)
344
392
  return;
393
+ const values = new Map(propertyInputs.map(propertyInput => [propertyInput.path, propertyInput.value]));
345
394
  const group = input.closest('[data-editor-inspector-vector-group-path]');
346
395
  const fields = group
347
396
  ? Array.from(group.querySelectorAll('input[data-serialized-path]'))
348
397
  : [input];
349
- const formatted = LocalEditorPanels.formatLocalEditorBrowserInspectorNumberValue(first.value);
350
398
  for (const field of fields) {
351
- if (resolveLocalEditorBrowserInspectorVectorGroupPathFromPropertyPath(field.dataset.serializedPath) === groupPath) {
352
- field.value = formatted;
353
- }
399
+ const path = field.dataset.serializedPath;
400
+ const value = path ? values.get(path) : undefined;
401
+ if (typeof value !== 'number' || !Number.isFinite(value))
402
+ continue;
403
+ field.value = String(Object.is(value, -0) ? 0 : value);
354
404
  }
355
405
  }
356
406
  function readRenderingInputValue(input, source) {
@@ -765,6 +815,9 @@ function consumeLocalEditorKeyboardCommittedValue(input) {
765
815
  delete input.dataset.editorKeyboardCommittedValue;
766
816
  return true;
767
817
  }
818
+ function hasLocalEditorUiKeyboardCommitPending(input) {
819
+ return input.dataset.editorUiKeyboardCommitPending === 'true';
820
+ }
768
821
  function isLocalEditorKeyboardCommitEvent(event, input) {
769
822
  if (event.key !== 'Enter' || event.isComposing)
770
823
  return false;
@@ -780,6 +833,7 @@ function commitLocalEditorInspectorInput(input, callbacks, lockedInspectorVector
780
833
  const propertyInputs = createInspectorPropertyInputs(input, 'input', lockedInspectorVectorGroups);
781
834
  if (!propertyInputs)
782
835
  return false;
836
+ delete input.dataset.editorUiKeyboardCommitPending;
783
837
  applyInspectorLockedVectorInputToDom(input, propertyInputs);
784
838
  markLocalEditorKeyboardCommittedValue(input);
785
839
  for (const propertyInput of propertyInputs)
@@ -1174,99 +1228,9 @@ const PREFAB_IMPORT_STATS_METRICS = [
1174
1228
  format: stats => formatPerformanceInteger(stats?.animationCount ?? null),
1175
1229
  },
1176
1230
  ];
1177
- function createSceneFrameRateOverlay(doc) {
1178
- const root = doc.createElement('div');
1179
- root.classList.add(LOCAL_EDITOR_THEME_CLASS);
1180
- root.dataset.editorSceneFrameRateOverlay = 'true';
1181
- root.style.cssText = [
1182
- 'position:absolute',
1183
- 'right:14px',
1184
- 'bottom:134px',
1185
- 'z-index:3',
1186
- 'display:none',
1187
- 'align-items:center',
1188
- 'gap:6px',
1189
- 'width:112px',
1190
- 'height:30px',
1191
- 'padding:0 8px',
1192
- 'box-sizing:border-box',
1193
- 'border:1px solid color-mix(in srgb, var(--fps-editor-border) 78%, transparent)',
1194
- 'border-radius:6px',
1195
- 'background:color-mix(in srgb, var(--fps-editor-chrome) 76%, transparent)',
1196
- 'box-shadow:var(--fps-editor-shadow-panel)',
1197
- 'font-family:var(--fps-editor-font)',
1198
- 'font-size:11px',
1199
- 'font-weight:900',
1200
- 'letter-spacing:0',
1201
- 'color:var(--fps-editor-text-strong)',
1202
- 'pointer-events:none',
1203
- 'backdrop-filter:blur(5px)',
1204
- 'overflow:hidden',
1205
- ].join(';');
1206
- const label = doc.createElement('span');
1207
- label.textContent = 'FPS';
1208
- label.style.cssText = [
1209
- 'color:var(--fps-editor-muted-strong)',
1210
- 'font-size:10px',
1211
- 'line-height:1',
1212
- ].join(';');
1213
- const fpsValue = doc.createElement('span');
1214
- fpsValue.textContent = '--';
1215
- fpsValue.style.cssText = [
1216
- 'width:26px',
1217
- 'flex:0 0 26px',
1218
- 'font-variant-numeric:tabular-nums',
1219
- 'font-size:13px',
1220
- 'line-height:1',
1221
- ].join(';');
1222
- const modeLabel = doc.createElement('span');
1223
- modeLabel.textContent = 'IDLE';
1224
- modeLabel.style.cssText = [
1225
- 'margin-left:auto',
1226
- 'padding:2px 4px',
1227
- 'flex:0 0 auto',
1228
- 'border:1px solid var(--fps-editor-border-soft)',
1229
- 'border-radius:4px',
1230
- 'background:color-mix(in srgb, var(--fps-editor-field) 72%, transparent)',
1231
- 'color:var(--fps-editor-muted)',
1232
- 'font-size:9px',
1233
- 'line-height:1',
1234
- ].join(';');
1235
- root.appendChild(label);
1236
- root.appendChild(fpsValue);
1237
- root.appendChild(modeLabel);
1238
- return { root, fpsValue, modeLabel };
1239
- }
1240
- function renderSceneFrameRateOverlay(overlay, stats) {
1241
- if (!stats) {
1242
- overlay.root.style.display = 'none';
1243
- return;
1244
- }
1245
- overlay.root.style.display = 'flex';
1246
- const fps = Number.isFinite(stats.fps) ? Math.round(stats.fps) : null;
1247
- const displayFps = stats.mode === 'idle' ? 0 : fps;
1248
- overlay.fpsValue.textContent = displayFps == null ? '--' : String(displayFps);
1249
- overlay.modeLabel.textContent = stats.mode === 'continuous' ? 'LIVE' : 'IDLE';
1250
- overlay.modeLabel.style.color = stats.mode === 'continuous'
1251
- ? 'var(--fps-editor-success)'
1252
- : 'var(--fps-editor-muted)';
1253
- overlay.fpsValue.style.color = displayFps == null || stats.mode === 'idle'
1254
- ? 'var(--fps-editor-muted)'
1255
- : displayFps >= 50
1256
- ? 'var(--fps-editor-success)'
1257
- : displayFps >= 30
1258
- ? 'var(--fps-editor-warn)'
1259
- : 'var(--fps-editor-danger-strong)';
1260
- overlay.root.title = [
1261
- `Scene FPS: ${displayFps == null ? '--' : displayFps}`,
1262
- `mode: ${stats.mode}`,
1263
- stats.lastFrameMs == null ? '' : `frame: ${stats.lastFrameMs.toFixed(1)}ms`,
1264
- stats.activeReasons.length ? `active: ${stats.activeReasons.join(', ')}` : '',
1265
- ].filter(Boolean).join(' | ');
1266
- }
1267
1231
  function createPerformanceMonitorOverlay(doc) {
1268
1232
  const root = doc.createElement('section');
1269
- root.classList.add(LOCAL_EDITOR_THEME_CLASS);
1233
+ root.classList.add(LOCAL_EDITOR_THEME_CLASS, 'fps-editor-ui-overlay-card');
1270
1234
  root.dataset.editorPerformanceMonitorOverlay = 'true';
1271
1235
  root.setAttribute('aria-label', '编辑器性能监控');
1272
1236
  root.style.cssText = [
@@ -1394,7 +1358,7 @@ function renderPerformanceMonitorOverlay(overlay, stats, open) {
1394
1358
  }
1395
1359
  function createPrefabImportStatsOverlay(doc) {
1396
1360
  const root = doc.createElement('section');
1397
- root.classList.add(LOCAL_EDITOR_THEME_CLASS);
1361
+ root.classList.add(LOCAL_EDITOR_THEME_CLASS, 'fps-editor-ui-overlay-card');
1398
1362
  root.dataset.editorPrefabImportStatsOverlay = 'true';
1399
1363
  root.setAttribute('aria-label', 'Prefab import diagnostics');
1400
1364
  root.style.cssText = [
@@ -1505,7 +1469,7 @@ function renderPrefabImportStatsOverlay(overlay, stage) {
1505
1469
  }
1506
1470
  function createPrefabStagePreviewLayout(doc) {
1507
1471
  const root = doc.createElement('section');
1508
- root.classList.add(LOCAL_EDITOR_THEME_CLASS);
1472
+ root.classList.add(LOCAL_EDITOR_THEME_CLASS, 'fps-editor-ui-prefab-stage-layout');
1509
1473
  root.dataset.editorPrefabStagePreviewLayout = 'true';
1510
1474
  root.setAttribute('aria-label', 'Prefab stage preview layout');
1511
1475
  root.style.cssText = [
@@ -1532,215 +1496,8 @@ function createPrefabStagePreviewLayout(doc) {
1532
1496
  'overflow:hidden',
1533
1497
  'pointer-events:none',
1534
1498
  ].join(';');
1535
- const comparisonColumn = doc.createElement('aside');
1536
- comparisonColumn.dataset.editorPrefabStageComparisonColumn = 'true';
1537
- comparisonColumn.setAttribute('aria-label', 'Prefab comparison previews');
1538
- comparisonColumn.style.cssText = [
1539
- 'position:absolute',
1540
- 'top:0',
1541
- 'right:0',
1542
- 'bottom:0',
1543
- `width:${LOCAL_EDITOR_PREFAB_COMPARISON_COLUMN_WIDTH_PX}px`,
1544
- 'display:none',
1545
- 'flex-direction:column',
1546
- 'box-sizing:border-box',
1547
- 'gap:10px',
1548
- 'padding:10px',
1549
- 'border-left:1px solid color-mix(in srgb, var(--fps-editor-divider) 82%, transparent)',
1550
- 'background:transparent',
1551
- 'box-shadow:none',
1552
- 'pointer-events:auto',
1553
- 'overflow:hidden',
1554
- ].join(';');
1555
- root.append(mainRegion, comparisonColumn);
1556
- return { root, mainRegion, comparisonColumn };
1557
- }
1558
- function createPrefabComparisonPreviewOverlay(doc) {
1559
- const root = doc.createElement('section');
1560
- root.classList.add(LOCAL_EDITOR_THEME_CLASS);
1561
- root.dataset.editorPrefabComparisonPreviewOverlay = 'true';
1562
- root.setAttribute('aria-label', 'Prefab clone and InstanceMesh comparison previews');
1563
- root.style.cssText = [
1564
- 'display:none',
1565
- 'flex:1 1 auto',
1566
- 'min-height:0',
1567
- 'width:100%',
1568
- 'box-sizing:border-box',
1569
- 'grid-template-rows:minmax(0,1fr) minmax(0,1fr)',
1570
- 'gap:10px',
1571
- 'overflow:hidden',
1572
- 'font-family:var(--fps-editor-font)',
1573
- 'pointer-events:auto',
1574
- ].join(';');
1575
- return { root, cards: new Map() };
1576
- }
1577
- function renderPrefabComparisonPreviewOverlay(overlay, stage) {
1578
- const previews = stage?.comparisonPreviews ?? [];
1579
- if (!stage || previews.length === 0) {
1580
- overlay.root.style.display = 'none';
1581
- return;
1582
- }
1583
- overlay.root.style.display = 'grid';
1584
- const visibleIds = new Set();
1585
- for (const preview of previews) {
1586
- const card = getOrCreatePrefabComparisonPreviewCard(overlay, preview);
1587
- visibleIds.add(preview.id);
1588
- card.root.style.display = 'flex';
1589
- card.title.textContent = preview.label;
1590
- card.statusLabel.textContent = formatLocalEditorPrefabStageComparisonPreviewStatus(preview.status);
1591
- card.statusLabel.style.color = getPrefabComparisonPreviewStatusColor(preview.status);
1592
- card.surface.dataset.editorPrefabComparisonPreviewId = preview.id;
1593
- card.surface.dataset.editorPrefabComparisonPreviewSurface = preview.projectionNodeId;
1594
- card.surface.dataset.editorPrefabComparisonPreviewStatus = preview.status;
1595
- card.surface.style.background = preview.status === 'ready'
1596
- ? 'transparent'
1597
- : 'color-mix(in srgb, var(--fps-editor-field) 74%, transparent)';
1598
- card.surface.textContent = preview.status === 'ready'
1599
- ? ''
1600
- : preview.status === 'loading'
1601
- ? 'Preview loading'
1602
- : 'Preview unavailable';
1603
- card.root.title = [
1604
- `${preview.label}: ${preview.status}`,
1605
- `mode: ${preview.mode}`,
1606
- `projection: ${preview.projectionNodeId}`,
1607
- ].join(' | ');
1608
- }
1609
- for (const [id, card] of overlay.cards) {
1610
- if (!visibleIds.has(id))
1611
- card.root.style.display = 'none';
1612
- }
1613
- }
1614
- function readPrefabComparisonPreviewSurfaces(overlay) {
1615
- if (overlay.root.style.display === 'none')
1616
- return [];
1617
- const surfaces = [];
1618
- for (const [previewId, card] of overlay.cards) {
1619
- if (card.root.style.display === 'none')
1620
- continue;
1621
- const projectionNodeId = card.surface.dataset.editorPrefabComparisonPreviewSurface;
1622
- if (!projectionNodeId)
1623
- continue;
1624
- const rect = card.surface.getBoundingClientRect();
1625
- if (rect.width < 1 || rect.height < 1)
1626
- continue;
1627
- surfaces.push({
1628
- previewId,
1629
- projectionNodeId,
1630
- element: card.surface,
1631
- rect,
1632
- });
1633
- }
1634
- return surfaces;
1635
- }
1636
- function findPrefabComparisonPreviewSurface(target) {
1637
- return target instanceof HTMLElement
1638
- ? target.closest('[data-editor-prefab-comparison-preview-surface]')
1639
- : null;
1640
- }
1641
- function readPrefabComparisonPreviewSurfaceId(surface) {
1642
- return surface.dataset.editorPrefabComparisonPreviewId
1643
- ?? surface.closest('[data-editor-prefab-comparison-preview]')?.dataset.editorPrefabComparisonPreview
1644
- ?? null;
1645
- }
1646
- function isPrefabComparisonPreviewSurfaceReady(surface) {
1647
- return surface.dataset.editorPrefabComparisonPreviewStatus === 'ready';
1648
- }
1649
- function getOrCreatePrefabComparisonPreviewCard(overlay, preview) {
1650
- const existing = overlay.cards.get(preview.id);
1651
- if (existing)
1652
- return existing;
1653
- const doc = overlay.root.ownerDocument;
1654
- const root = doc.createElement('article');
1655
- root.dataset.editorPrefabComparisonPreview = preview.id;
1656
- root.style.cssText = [
1657
- 'display:flex',
1658
- 'flex-direction:column',
1659
- 'min-width:0',
1660
- 'min-height:0',
1661
- 'flex:1 1 0',
1662
- 'box-sizing:border-box',
1663
- 'padding:8px',
1664
- 'border:1px solid color-mix(in srgb, var(--fps-editor-border) 78%, transparent)',
1665
- 'border-radius:6px',
1666
- 'background:transparent',
1667
- 'box-shadow:none',
1668
- 'color:var(--fps-editor-text)',
1669
- 'pointer-events:auto',
1670
- 'overflow:hidden',
1671
- ].join(';');
1672
- const header = doc.createElement('div');
1673
- header.style.cssText = [
1674
- 'display:flex',
1675
- 'align-items:center',
1676
- 'justify-content:space-between',
1677
- 'gap:8px',
1678
- 'margin-bottom:7px',
1679
- 'padding:6px 8px',
1680
- 'border:1px solid color-mix(in srgb, var(--fps-editor-border) 74%, transparent)',
1681
- 'border-radius:5px',
1682
- 'background:color-mix(in srgb, var(--fps-editor-chrome) 86%, transparent)',
1683
- 'box-shadow:0 6px 14px color-mix(in srgb, #000 18%, transparent)',
1684
- ].join(';');
1685
- const title = doc.createElement('div');
1686
- title.textContent = preview.label;
1687
- title.style.cssText = [
1688
- 'min-width:0',
1689
- 'overflow:hidden',
1690
- 'text-overflow:ellipsis',
1691
- 'white-space:nowrap',
1692
- 'color:var(--fps-editor-text-strong)',
1693
- 'font-size:12px',
1694
- 'line-height:1.2',
1695
- 'font-weight:900',
1696
- ].join(';');
1697
- const statusLabel = doc.createElement('span');
1698
- statusLabel.textContent = 'UNAVAILABLE';
1699
- statusLabel.style.cssText = [
1700
- 'flex:0 0 auto',
1701
- 'padding:2px 5px',
1702
- 'border:1px solid var(--fps-editor-border-soft)',
1703
- 'border-radius:4px',
1704
- 'background:color-mix(in srgb, var(--fps-editor-field) 72%, transparent)',
1705
- 'font-size:9px',
1706
- 'line-height:1',
1707
- 'font-weight:900',
1708
- ].join(';');
1709
- header.append(title, statusLabel);
1710
- const surface = doc.createElement('div');
1711
- surface.style.cssText = [
1712
- 'display:flex',
1713
- 'flex:1 1 auto',
1714
- 'align-items:center',
1715
- 'justify-content:center',
1716
- 'width:100%',
1717
- 'min-height:0',
1718
- 'box-sizing:border-box',
1719
- 'border:1px solid color-mix(in srgb, var(--fps-editor-border-soft) 84%, transparent)',
1720
- 'border-radius:4px',
1721
- 'background:transparent',
1722
- 'overflow:hidden',
1723
- 'color:var(--fps-editor-muted)',
1724
- 'font-size:10px',
1725
- 'font-weight:800',
1726
- 'text-align:center',
1727
- 'touch-action:none',
1728
- 'user-select:none',
1729
- 'cursor:grab',
1730
- ].join(';');
1731
- root.append(header, surface);
1732
- overlay.root.appendChild(root);
1733
- const card = { root, title, statusLabel, surface };
1734
- overlay.cards.set(preview.id, card);
1735
- return card;
1736
- }
1737
- function getPrefabComparisonPreviewStatusColor(status) {
1738
- const tone = resolveLocalEditorPrefabStageComparisonPreviewTone(status);
1739
- return tone === 'success'
1740
- ? 'var(--fps-editor-success)'
1741
- : tone === 'warning'
1742
- ? 'var(--fps-editor-warn)'
1743
- : 'var(--fps-editor-danger-strong)';
1499
+ root.append(mainRegion);
1500
+ return { root, mainRegion };
1744
1501
  }
1745
1502
  function formatPrefabImportStatsStatusLabel(status) {
1746
1503
  return status === 'ready' ? 'READY' : status === 'loading' ? 'LOADING' : 'MISSING';
@@ -1770,154 +1527,211 @@ function isFinitePerformanceNumber(value) {
1770
1527
  }
1771
1528
  function createCoordinateAxesOverlay(doc) {
1772
1529
  const root = doc.createElement('div');
1530
+ root.classList.add(LOCAL_EDITOR_THEME_CLASS);
1773
1531
  root.dataset.editorCoordinateAxesOverlay = 'true';
1774
1532
  root.style.cssText = [
1775
1533
  'position:absolute',
1776
1534
  'right:14px',
1777
1535
  'bottom:14px',
1778
- 'width:112px',
1779
- 'height:112px',
1536
+ 'width:124px',
1537
+ 'height:124px',
1780
1538
  'display:none',
1781
1539
  'z-index:2',
1782
1540
  'box-sizing:border-box',
1783
- 'border:1px solid color-mix(in srgb, var(--fps-editor-border) 78%, transparent)',
1784
- 'border-radius:8px',
1785
- 'background:color-mix(in srgb, var(--fps-editor-chrome) 58%, transparent)',
1786
- 'box-shadow:var(--fps-editor-shadow-panel)',
1541
+ 'background:transparent',
1787
1542
  'pointer-events:none',
1788
- 'overflow:hidden',
1543
+ 'overflow:visible',
1789
1544
  ].join(';');
1790
1545
  const svg = doc.createElementNS('http://www.w3.org/2000/svg', 'svg');
1791
- svg.setAttribute('viewBox', '0 0 112 112');
1792
- svg.setAttribute('aria-hidden', 'true');
1546
+ svg.setAttribute('viewBox', '0 0 124 124');
1547
+ svg.setAttribute('role', 'group');
1548
+ svg.setAttribute('aria-label', '视口方向控制');
1793
1549
  svg.style.cssText = 'display:block;width:100%;height:100%';
1794
1550
  root.appendChild(svg);
1795
1551
  const lineLayer = doc.createElementNS('http://www.w3.org/2000/svg', 'g');
1796
1552
  const labelLayer = doc.createElementNS('http://www.w3.org/2000/svg', 'g');
1797
1553
  svg.appendChild(lineLayer);
1798
1554
  svg.appendChild(labelLayer);
1799
- const axisGroups = new Map();
1555
+ const axisDirectionGroups = new Map();
1556
+ const axisDirectionVisuals = new Map();
1800
1557
  const axisLines = new Map();
1801
- const axisLabels = new Map();
1802
- const axisDiscs = new Map();
1803
1558
  for (const axis of ['x', 'y', 'z']) {
1804
- const group = doc.createElementNS('http://www.w3.org/2000/svg', 'g');
1805
1559
  const line = doc.createElementNS('http://www.w3.org/2000/svg', 'line');
1806
1560
  line.setAttribute('stroke-width', '3.2');
1807
1561
  line.setAttribute('stroke-linecap', 'round');
1808
- line.setAttribute('x1', '56');
1809
- line.setAttribute('y1', '56');
1810
- const disc = doc.createElementNS('http://www.w3.org/2000/svg', 'circle');
1811
- disc.setAttribute('r', '7');
1812
- const label = doc.createElementNS('http://www.w3.org/2000/svg', 'text');
1813
- label.setAttribute('text-anchor', 'middle');
1814
- label.setAttribute('dominant-baseline', 'middle');
1815
- label.setAttribute('dy', '0.04em');
1816
- label.style.cssText = [
1817
- 'fill:#172033',
1818
- 'font-size:10px',
1819
- 'font-weight:900',
1820
- 'font-family:Arial, Helvetica, sans-serif',
1821
- 'letter-spacing:0',
1822
- ].join(';');
1823
- group.appendChild(disc);
1824
- group.appendChild(label);
1562
+ line.setAttribute('x1', '62');
1563
+ line.setAttribute('y1', '62');
1564
+ line.style.filter = 'drop-shadow(0 1px 1.5px rgba(0,0,0,0.88))';
1825
1565
  lineLayer.appendChild(line);
1826
- labelLayer.appendChild(group);
1827
- axisGroups.set(axis, group);
1828
1566
  axisLines.set(axis, line);
1829
- axisLabels.set(axis, label);
1830
- axisDiscs.set(axis, disc);
1567
+ for (const sign of ['positive', 'negative']) {
1568
+ const directionId = `${axis}-${sign}`;
1569
+ const direction = resolveLocalEditorCoordinateAxisDirection(directionId);
1570
+ const group = doc.createElementNS('http://www.w3.org/2000/svg', 'g');
1571
+ group.setAttribute('role', 'button');
1572
+ group.setAttribute('tabindex', '0');
1573
+ group.dataset.coordinateAxisDirection = directionId;
1574
+ group.dataset.viewportViewPreset = direction.preset;
1575
+ group.style.cssText = 'pointer-events:auto;cursor:pointer;outline:none';
1576
+ const title = doc.createElementNS('http://www.w3.org/2000/svg', 'title');
1577
+ title.textContent = `${direction.label} · 点击切换正交视图`;
1578
+ const hit = doc.createElementNS('http://www.w3.org/2000/svg', 'circle');
1579
+ hit.setAttribute('r', '14');
1580
+ hit.setAttribute('fill', 'transparent');
1581
+ const visual = doc.createElementNS('http://www.w3.org/2000/svg', 'circle');
1582
+ visual.setAttribute('r', sign === 'positive' ? '9' : '8.5');
1583
+ visual.style.cssText = 'transition:filter 120ms ease,opacity 120ms ease;filter:drop-shadow(0 1px 2.5px rgba(0,0,0,0.78))';
1584
+ group.append(title, hit, visual);
1585
+ if (sign === 'positive') {
1586
+ const label = doc.createElementNS('http://www.w3.org/2000/svg', 'text');
1587
+ label.setAttribute('text-anchor', 'middle');
1588
+ label.setAttribute('dominant-baseline', 'middle');
1589
+ label.setAttribute('dy', '0.04em');
1590
+ label.style.cssText = [
1591
+ 'fill:#172033',
1592
+ 'font-size:11px',
1593
+ 'font-weight:900',
1594
+ 'font-family:Arial, Helvetica, sans-serif',
1595
+ 'letter-spacing:0',
1596
+ 'pointer-events:none',
1597
+ ].join(';');
1598
+ label.textContent = axis.toUpperCase();
1599
+ group.appendChild(label);
1600
+ }
1601
+ const emphasize = () => {
1602
+ visual.style.filter = 'drop-shadow(0 0 4px rgba(255,255,255,0.78))';
1603
+ };
1604
+ const restore = () => {
1605
+ visual.style.filter = 'drop-shadow(0 1px 2.5px rgba(0,0,0,0.78))';
1606
+ };
1607
+ group.addEventListener('pointerenter', emphasize);
1608
+ group.addEventListener('pointerleave', restore);
1609
+ group.addEventListener('focus', emphasize);
1610
+ group.addEventListener('blur', restore);
1611
+ labelLayer.appendChild(group);
1612
+ axisDirectionGroups.set(directionId, group);
1613
+ axisDirectionVisuals.set(directionId, visual);
1614
+ }
1831
1615
  }
1832
1616
  const centerDot = doc.createElementNS('http://www.w3.org/2000/svg', 'circle');
1833
- centerDot.setAttribute('cx', '56');
1834
- centerDot.setAttribute('cy', '56');
1617
+ centerDot.setAttribute('cx', '62');
1618
+ centerDot.setAttribute('cy', '62');
1835
1619
  centerDot.setAttribute('r', '3.2');
1836
- centerDot.setAttribute('fill', 'color-mix(in srgb, var(--fps-editor-text) 82%, transparent)');
1620
+ centerDot.setAttribute('fill', '#f4f7fb');
1621
+ centerDot.setAttribute('stroke', 'rgba(16,20,26,0.82)');
1622
+ centerDot.setAttribute('stroke-width', '1.5');
1837
1623
  labelLayer.appendChild(centerDot);
1838
- const projectionIcon = doc.createElementNS('http://www.w3.org/2000/svg', 'g');
1839
- projectionIcon.setAttribute('transform', 'translate(8 8)');
1840
- projectionIcon.setAttribute('role', 'button');
1841
- projectionIcon.setAttribute('tabindex', '0');
1842
- projectionIcon.dataset.coordinateAxesProjectionToggle = 'true';
1843
- projectionIcon.style.cssText = 'opacity:0.92;pointer-events:auto;cursor:pointer;outline:none';
1844
- const projectionIconFrame = doc.createElementNS('http://www.w3.org/2000/svg', 'rect');
1845
- projectionIconFrame.setAttribute('x', '0');
1846
- projectionIconFrame.setAttribute('y', '0');
1847
- projectionIconFrame.setAttribute('width', '18');
1848
- projectionIconFrame.setAttribute('height', '18');
1849
- projectionIconFrame.setAttribute('rx', '4');
1850
- projectionIconFrame.setAttribute('fill', 'color-mix(in srgb, var(--fps-editor-chrome) 78%, transparent)');
1851
- projectionIconFrame.setAttribute('stroke', 'color-mix(in srgb, var(--fps-editor-border) 82%, transparent)');
1852
- projectionIconFrame.setAttribute('stroke-width', '1');
1853
- const projectionIconShape = doc.createElementNS('http://www.w3.org/2000/svg', 'path');
1854
- projectionIconShape.setAttribute('fill', 'none');
1855
- projectionIconShape.setAttribute('stroke', 'color-mix(in srgb, var(--fps-editor-accent) 82%, #ffffff)');
1856
- projectionIconShape.setAttribute('stroke-width', '1.6');
1857
- projectionIconShape.setAttribute('stroke-linejoin', 'round');
1858
- projectionIconShape.setAttribute('stroke-linecap', 'round');
1859
- projectionIcon.appendChild(projectionIconFrame);
1860
- projectionIcon.appendChild(projectionIconShape);
1861
- svg.appendChild(projectionIcon);
1624
+ const floatingButtonStyle = [
1625
+ 'position:absolute',
1626
+ 'top:4px',
1627
+ 'width:26px',
1628
+ 'height:26px',
1629
+ 'min-width:26px',
1630
+ 'padding:0',
1631
+ 'border-color:color-mix(in srgb, var(--fps-editor-border) 72%, transparent)',
1632
+ 'background:color-mix(in srgb, var(--fps-editor-chrome) 72%, transparent)',
1633
+ 'box-shadow:0 2px 6px rgba(0,0,0,0.34)',
1634
+ 'backdrop-filter:blur(5px)',
1635
+ 'pointer-events:auto',
1636
+ ].join(';');
1637
+ const projectionButton = createToolbarIconButton(doc, '投影模式', 'projection-perspective', '投影模式:透视', 'toggle');
1638
+ projectionButton.dataset.coordinateAxesProjectionToggle = 'true';
1639
+ projectionButton.style.cssText = `${floatingButtonStyle};left:4px`;
1640
+ root.appendChild(projectionButton);
1641
+ const viewMenuButton = createToolbarIconButton(doc, '更多视角', 'chevron-down', '更多视角');
1642
+ viewMenuButton.dataset.coordinateAxesViewMenu = 'true';
1643
+ viewMenuButton.setAttribute('aria-haspopup', 'menu');
1644
+ viewMenuButton.style.cssText = `${floatingButtonStyle};right:4px`;
1645
+ root.appendChild(viewMenuButton);
1862
1646
  return {
1863
1647
  root,
1864
1648
  lineLayer,
1865
1649
  labelLayer,
1866
- axisGroups,
1650
+ axisDirectionGroups,
1651
+ axisDirectionVisuals,
1867
1652
  axisLines,
1868
- axisLabels,
1869
- axisDiscs,
1870
1653
  centerDot,
1871
- projectionIcon,
1872
- projectionIconShape,
1654
+ projectionButton,
1655
+ viewMenuButton,
1873
1656
  };
1874
1657
  }
1875
- function renderCoordinateAxesOverlay(overlay, state) {
1658
+ function renderCoordinateAxesOverlay(overlay, state, viewPreset, busy) {
1876
1659
  if (!state?.axes?.length) {
1877
1660
  overlay.root.style.display = 'none';
1878
1661
  return;
1879
1662
  }
1880
1663
  overlay.root.style.display = '';
1881
- renderCoordinateAxesProjectionIcon(overlay, state.projectionMode, state.projectionToggleDisabled === true);
1882
- const center = 56;
1883
- const lineLength = 38;
1664
+ const controlsDisabled = state.projectionToggleDisabled === true || busy;
1665
+ renderCoordinateAxesProjectionButton(overlay, state.projectionMode, controlsDisabled);
1666
+ overlay.viewMenuButton.disabled = controlsDisabled;
1667
+ overlay.viewMenuButton.setAttribute('aria-disabled', controlsDisabled ? 'true' : 'false');
1668
+ setToolbarButtonTooltip(overlay.viewMenuButton, controlsDisabled
1669
+ ? `视角预设:${VIEWPORT_VIEW_LABELS[viewPreset]} · 当前不可切换`
1670
+ : `视角预设:${VIEWPORT_VIEW_LABELS[viewPreset]}`);
1671
+ const center = 62;
1672
+ const lineLength = 40;
1673
+ const activeDirectionId = resolveLocalEditorCoordinateAxisActiveDirection(viewPreset);
1884
1674
  const sortedAxes = [...state.axes].sort((left, right) => right.depth - left.depth);
1885
1675
  for (const axis of sortedAxes) {
1886
- const group = overlay.axisGroups.get(axis.id);
1887
1676
  const line = overlay.axisLines.get(axis.id);
1888
- const disc = overlay.axisDiscs.get(axis.id);
1889
- const label = overlay.axisLabels.get(axis.id);
1890
- if (!group || !line || !disc || !label)
1677
+ if (!line)
1891
1678
  continue;
1892
1679
  const length = lineLength * axis.scale;
1893
1680
  const endX = center + axis.x * length;
1894
1681
  const endY = center + axis.y * length;
1682
+ const oppositeX = center - axis.x * length;
1683
+ const oppositeY = center - axis.y * length;
1895
1684
  line.setAttribute('x2', formatSvgNumber(endX));
1896
1685
  line.setAttribute('y2', formatSvgNumber(endY));
1897
1686
  line.setAttribute('stroke', axis.color);
1898
- disc.setAttribute('cx', formatSvgNumber(endX));
1899
- disc.setAttribute('cy', formatSvgNumber(endY));
1900
- disc.setAttribute('fill', axis.color);
1901
- label.setAttribute('x', formatSvgNumber(endX));
1902
- label.setAttribute('y', formatSvgNumber(endY));
1903
- label.textContent = axis.label;
1904
- group.style.opacity = String(0.72 + axis.scale * 0.28);
1687
+ const positiveId = `${axis.id}-positive`;
1688
+ const negativeId = `${axis.id}-negative`;
1689
+ const positiveDirection = resolveLocalEditorCoordinateAxisDirection(positiveId);
1690
+ const negativeDirection = resolveLocalEditorCoordinateAxisDirection(negativeId);
1691
+ const positiveGroup = overlay.axisDirectionGroups.get(positiveId);
1692
+ const negativeGroup = overlay.axisDirectionGroups.get(negativeId);
1693
+ const positiveVisual = overlay.axisDirectionVisuals.get(positiveId);
1694
+ const negativeVisual = overlay.axisDirectionVisuals.get(negativeId);
1695
+ if (!positiveGroup || !negativeGroup || !positiveVisual || !negativeVisual)
1696
+ continue;
1697
+ positiveGroup.setAttribute('transform', `translate(${formatSvgNumber(endX)} ${formatSvgNumber(endY)})`);
1698
+ negativeGroup.setAttribute('transform', `translate(${formatSvgNumber(oppositeX)} ${formatSvgNumber(oppositeY)})`);
1699
+ positiveGroup.setAttribute('aria-label', `${positiveDirection.label} · 点击切换正交视图`);
1700
+ negativeGroup.setAttribute('aria-label', `${negativeDirection.label} · 点击切换正交视图`);
1701
+ positiveGroup.setAttribute('aria-disabled', controlsDisabled ? 'true' : 'false');
1702
+ negativeGroup.setAttribute('aria-disabled', controlsDisabled ? 'true' : 'false');
1703
+ positiveGroup.style.cursor = controlsDisabled ? 'not-allowed' : 'pointer';
1704
+ negativeGroup.style.cursor = controlsDisabled ? 'not-allowed' : 'pointer';
1705
+ positiveGroup.style.opacity = String((controlsDisabled ? 0.42 : 0.72) + axis.scale * (controlsDisabled ? 0.12 : 0.28));
1706
+ negativeGroup.style.opacity = controlsDisabled ? '0.3' : String(0.5 + axis.scale * 0.18);
1707
+ const positiveActive = positiveId === activeDirectionId;
1708
+ const negativeActive = negativeId === activeDirectionId;
1709
+ positiveGroup.setAttribute('aria-pressed', String(positiveActive));
1710
+ negativeGroup.setAttribute('aria-pressed', String(negativeActive));
1711
+ positiveVisual.setAttribute('fill', axis.color);
1712
+ positiveVisual.setAttribute('stroke', positiveActive ? '#ffffff' : 'color-mix(in srgb, var(--fps-editor-chrome) 72%, transparent)');
1713
+ positiveVisual.setAttribute('stroke-width', positiveActive ? '2.4' : '1.2');
1714
+ negativeVisual.setAttribute('fill', negativeActive ? `color-mix(in srgb, ${axis.color} 26%, transparent)` : 'color-mix(in srgb, var(--fps-editor-chrome) 62%, transparent)');
1715
+ negativeVisual.setAttribute('stroke', axis.color);
1716
+ negativeVisual.setAttribute('stroke-width', negativeActive ? '3.8' : '3');
1905
1717
  overlay.lineLayer.appendChild(line);
1906
- overlay.labelLayer.appendChild(group);
1718
+ const farGroup = axis.depth >= 0 ? negativeGroup : positiveGroup;
1719
+ const nearGroup = axis.depth >= 0 ? positiveGroup : negativeGroup;
1720
+ overlay.labelLayer.appendChild(farGroup);
1721
+ overlay.labelLayer.appendChild(nearGroup);
1907
1722
  }
1908
1723
  overlay.labelLayer.appendChild(overlay.centerDot);
1909
1724
  }
1910
- function renderCoordinateAxesProjectionIcon(overlay, mode, disabled) {
1911
- overlay.projectionIcon.dataset.viewportProjectionMode = mode;
1912
- overlay.projectionIcon.setAttribute('aria-label', disabled
1913
- ? `编辑视口投影:${VIEWPORT_PROJECTION_LABELS[mode]},Main Camera 预览中不可切换`
1914
- : `编辑视口投影:${VIEWPORT_PROJECTION_LABELS[mode]},点击切换`);
1915
- overlay.projectionIcon.setAttribute('aria-disabled', disabled ? 'true' : 'false');
1916
- overlay.projectionIcon.style.opacity = disabled ? '0.46' : '0.92';
1917
- overlay.projectionIcon.style.cursor = disabled ? 'not-allowed' : 'pointer';
1918
- overlay.projectionIconShape.setAttribute('d', mode === 'orthographic'
1919
- ? 'M5 6.5H12.5V14H5ZM7.5 4H15V11.5'
1920
- : 'M4.5 14H13.5L10.5 4H7.5ZM7 10.5H11');
1725
+ function renderCoordinateAxesProjectionButton(overlay, mode, disabled) {
1726
+ const nextMode = mode === 'orthographic' ? 'perspective' : 'orthographic';
1727
+ overlay.projectionButton.dataset.viewportProjectionMode = mode;
1728
+ overlay.projectionButton.disabled = disabled;
1729
+ overlay.projectionButton.setAttribute('aria-pressed', mode === 'orthographic' ? 'true' : 'false');
1730
+ setToolbarButtonIcon(overlay.projectionButton.ownerDocument, overlay.projectionButton, mode === 'orthographic' ? 'projection-ortho' : 'projection-perspective');
1731
+ setToolbarButtonTooltip(overlay.projectionButton, disabled
1732
+ ? `投影模式:${VIEWPORT_PROJECTION_LABELS[mode]} · 当前不可切换`
1733
+ : `投影模式:${VIEWPORT_PROJECTION_LABELS[mode]} · 点击切换为${VIEWPORT_PROJECTION_LABELS[nextMode]}`);
1734
+ LocalEditorShared.applyButtonActiveState(overlay.projectionButton, mode === 'orthographic');
1921
1735
  }
1922
1736
  function createSpatialOverlay(doc) {
1923
1737
  const root = doc.createElement('div');
@@ -2034,8 +1848,8 @@ function ensureSpatialOverlayLine(overlay, id) {
2034
1848
  if (existing)
2035
1849
  return existing;
2036
1850
  const line = overlay.root.ownerDocument.createElementNS('http://www.w3.org/2000/svg', 'line');
2037
- line.setAttribute('stroke', 'color-mix(in srgb, var(--fps-editor-drop-target) 82%, white)');
2038
- line.setAttribute('stroke-width', '1.4');
1851
+ line.setAttribute('stroke', 'color-mix(in srgb, var(--fps-editor-text) 82%, white)');
1852
+ line.setAttribute('stroke-width', '1.15');
2039
1853
  line.setAttribute('stroke-linecap', 'round');
2040
1854
  line.setAttribute('vector-effect', 'non-scaling-stroke');
2041
1855
  line.style.filter = 'drop-shadow(0 1px 2px rgba(0,0,0,0.45))';
@@ -2179,7 +1993,7 @@ function formatSvgNumber(value) {
2179
1993
  return Number.isFinite(value) ? value.toFixed(2) : '0';
2180
1994
  }
2181
1995
  function isLocalEditorAssetBrowserTab(value) {
2182
- return value === 'all' || value === 'models' || value === 'prefabs' || value === 'materials' || value === 'textures';
1996
+ return value === 'all' || value === 'models' || value === 'prefabs' || value === 'materials' || value === 'textures' || value === 'audio';
2183
1997
  }
2184
1998
  export function createAssetBrowserMenuItems(state, asset) {
2185
1999
  const assetKind = resolveLocalEditorBrowserAssetKind(asset);
@@ -2189,6 +2003,12 @@ export function createAssetBrowserMenuItems(state, asset) {
2189
2003
  const items = [];
2190
2004
  if (assetKind === 'material') {
2191
2005
  const deleteDisabledReason = getMaterialAssetDeleteDisabledReason(asset);
2006
+ if (asset.preview) {
2007
+ items.push({
2008
+ id: 'asset.preview',
2009
+ label: '预览材质',
2010
+ });
2011
+ }
2192
2012
  items.push({
2193
2013
  id: 'asset.edit-material',
2194
2014
  label: '编辑材质球',
@@ -2381,8 +2201,29 @@ export function resolveAssetBrowserDoubleClickAction(state, asset) {
2381
2201
  return 'asset.edit-prefab';
2382
2202
  return null;
2383
2203
  }
2384
- function copyTextToClipboard(win, text) {
2385
- void win?.navigator?.clipboard?.writeText?.(text);
2204
+ function copyTextToClipboard(win, text, onResult) {
2205
+ void writeLocalEditorClipboardText(win, text).then(onResult ?? (() => undefined));
2206
+ }
2207
+ function formatProjectFileByteSize(size) {
2208
+ if (size < 1024)
2209
+ return `${size} B`;
2210
+ if (size < 1024 * 1024)
2211
+ return `${(size / 1024).toFixed(size < 10 * 1024 ? 1 : 0)} KiB`;
2212
+ return `${(size / (1024 * 1024)).toFixed(1)} MiB`;
2213
+ }
2214
+ function copyEditorStatusText(button, win, text) {
2215
+ const idleLabel = button.getAttribute('aria-label') ?? '复制诊断';
2216
+ copyTextToClipboard(win, text, copied => {
2217
+ const resultLabel = copied ? '已复制' : '复制失败,请检查浏览器剪贴板权限';
2218
+ button.dataset.editorStatusCopyResult = copied ? 'success' : 'error';
2219
+ button.title = resultLabel;
2220
+ button.setAttribute('aria-label', resultLabel);
2221
+ win?.setTimeout(() => {
2222
+ delete button.dataset.editorStatusCopyResult;
2223
+ button.title = idleLabel;
2224
+ button.setAttribute('aria-label', idleLabel);
2225
+ }, 1600);
2226
+ });
2386
2227
  }
2387
2228
  function readInspectorAssetPickerOptions(property) {
2388
2229
  const title = readControlOptionString(property, 'pickerTitle') || property.label;
@@ -2538,6 +2379,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
2538
2379
  const root = options.root ?? doc.body;
2539
2380
  const callbacks = options.callbacks ?? {};
2540
2381
  const localTestActionsEnabled = options.localTestActions === true;
2382
+ const gameModeEntryVisible = options.gameModeEntryVisible !== false;
2541
2383
  ensureLocalEditorTheme(doc);
2542
2384
  let activeTheme = normalizeLocalEditorThemeName(options.theme);
2543
2385
  const inputRouter = createLocalEditorWorkbenchInputRouter(doc, {
@@ -2561,34 +2403,32 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
2561
2403
  });
2562
2404
  construction.addCleanup('tooltip-controller', () => tooltipController.dispose());
2563
2405
  let currentState = null;
2406
+ let pendingStatusDiagnosticRequest = null;
2564
2407
  let inspectorFilter = '';
2408
+ let lastRenderedInspectorContentKey = null;
2565
2409
  const lockedInspectorVectorGroups = new Set();
2566
2410
  let assetBrowserTab = 'all';
2567
- const workbenchLayout = createDefaultLocalEditorWorkbenchLayout();
2411
+ let assetBrowserFolderPath = '/';
2412
+ const assetBrowserExpandedFolderPaths = new Set(['/']);
2413
+ let assetBrowserViewMode = 'grid';
2414
+ let selectedProjectEntryPath = null;
2415
+ const expandAssetBrowserFolderPath = (folderPath) => {
2416
+ assetBrowserExpandedFolderPaths.add('/');
2417
+ let currentPath = '';
2418
+ for (const segment of folderPath.split('/').filter(Boolean)) {
2419
+ currentPath = `${currentPath}/${segment}`;
2420
+ assetBrowserExpandedFolderPaths.add(currentPath);
2421
+ }
2422
+ };
2423
+ const hierarchySurface = options.hierarchy?.surface;
2424
+ if (!hierarchySurface)
2425
+ throw new Error('Hierarchy surface is required by the Local Editor workbench.');
2426
+ const hierarchyKernel = options.hierarchy?.kernel ?? hierarchySurface.createKernel();
2427
+ const workbenchLayout = createDefaultLocalEditorWorkbenchLayout(hierarchySurface);
2568
2428
  const panelRegistry = createLocalEditorPanelRegistry(workbenchLayout);
2569
2429
  const hostChrome = doc.createElement('div');
2570
2430
  hostChrome.dataset.editorWorkbenchRegion = 'top-bar';
2571
- hostChrome.className = LOCAL_EDITOR_THEME_CLASS;
2572
- hostChrome.style.cssText = [
2573
- 'position:fixed',
2574
- 'top:12px',
2575
- 'left:50%',
2576
- 'transform:translateX(-50%)',
2577
- 'z-index:2147483640',
2578
- 'display:none',
2579
- 'align-items:center',
2580
- 'gap:8px',
2581
- 'height:34px',
2582
- 'padding:0 8px',
2583
- 'border:1px solid var(--fps-editor-border)',
2584
- 'border-radius:3px',
2585
- 'background:var(--fps-editor-chrome)',
2586
- 'box-shadow:var(--fps-editor-shadow-panel)',
2587
- 'font-family:var(--fps-editor-font)',
2588
- 'color:var(--fps-editor-text)',
2589
- 'font-size:12px',
2590
- 'pointer-events:auto',
2591
- ].join(';');
2431
+ hostChrome.className = `${LOCAL_EDITOR_THEME_CLASS} fps-editor-ui-host-chrome`;
2592
2432
  const hostModeLabel = doc.createElement('span');
2593
2433
  hostModeLabel.textContent = '本地宿主 · 游戏模式';
2594
2434
  hostModeLabel.style.cssText = [
@@ -2624,7 +2464,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
2624
2464
  const localTestButton = createToolbarIconButton(doc, '本地测试', 'execute', '打开本地测试操作');
2625
2465
  localTestButton.dataset.editorLocalTestToggle = 'true';
2626
2466
  const localTestMenu = doc.createElement('div');
2627
- localTestMenu.classList.add(LOCAL_EDITOR_THEME_CLASS);
2467
+ localTestMenu.classList.add(LOCAL_EDITOR_THEME_CLASS, 'fps-editor-ui-popover');
2628
2468
  localTestMenu.dataset.editorLocalTestMenu = 'true';
2629
2469
  localTestMenu.style.cssText = [
2630
2470
  'position:fixed',
@@ -2646,6 +2486,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
2646
2486
  localTestMenu.appendChild(button);
2647
2487
  }
2648
2488
  const localTestGroup = doc.createElement('div');
2489
+ localTestGroup.className = 'fps-editor-ui-toolbar-group';
2649
2490
  localTestGroup.style.cssText = [
2650
2491
  `display:${localTestActionsEnabled ? 'flex' : 'none'}`,
2651
2492
  'align-items:center',
@@ -2657,22 +2498,55 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
2657
2498
  let helpOpen = false;
2658
2499
  let editorStatusCenterOpen = false;
2659
2500
  let performanceMonitorOpen = false;
2660
- let prefabComparisonPreviewOpen = true;
2661
2501
  let assetPreviewOpen = false;
2502
+ let assetPreviewReturnFocus = null;
2662
2503
  let previewedAsset = null;
2663
2504
  let assetPreviewMode = 'preview';
2505
+ let projectMediaPreviewSource = null;
2506
+ let projectMediaPreviewRequestedPath = '';
2507
+ let projectMediaPreviewError = '';
2508
+ let projectMediaPreviewRequestId = 0;
2509
+ let uiDisposed = false;
2510
+ let projectModelPreviewCleanup = null;
2511
+ let projectModelPreviewAbortController = null;
2512
+ const projectModelPreviewCleanupRegistry = createLocalEditorPreviewCleanupRegistry({
2513
+ onTerminalFailure(error) {
2514
+ console.error('[fps-editor:model-preview] cleanup failed after bounded retries', error);
2515
+ },
2516
+ });
2517
+ const projectMediaThumbnailCache = new Map();
2518
+ const projectMediaThumbnailAbortControllers = new Set();
2519
+ const projectModelThumbnailCache = createLocalEditorProjectModelThumbnailCache(doc.defaultView);
2520
+ let projectMediaThumbnailGeneration = 0;
2521
+ let projectMediaThumbnailObserver = null;
2522
+ let materialPreviewRequestId = 0;
2523
+ let materialPreviewCleanup = null;
2524
+ const materialPreviewCleanupRegistry = createLocalEditorPreviewCleanupRegistry({
2525
+ onTerminalFailure(error) {
2526
+ console.error('[fps-editor:material-preview] cleanup failed after bounded retries', error);
2527
+ },
2528
+ });
2529
+ let projectFilePreviewOpen = false;
2530
+ let projectFilePreviewReturnFocus = null;
2531
+ let projectFilePreviewRequestId = 0;
2532
+ let projectFilePreviewContent = null;
2533
+ let projectFilePreviewRequestedPath = '';
2534
+ let projectFilePreviewError = '';
2535
+ let projectFilePreviewMatches = [];
2536
+ let projectFilePreviewActiveMatch = -1;
2537
+ let projectFilePreviewSearchRaf = null;
2664
2538
  let assetPickerOpen = false;
2665
2539
  let assetPickerFilter = '';
2666
2540
  let assetPickerInput = null;
2667
2541
  let assetPickerProperty = null;
2668
- let prefabComparisonPreviewDrag = null;
2542
+ let hierarchyOperationInputRequest = null;
2669
2543
  let prefabStageMainWorkbenchLayoutSnapshot = null;
2670
- const editorStatusButton = createToolbarIconButton(doc, '编辑器状态', 'status', '编辑器状态');
2544
+ const editorStatusButton = createToolbarIconButton(doc, '验证中心', 'status', '编辑器状态与验证中心');
2671
2545
  editorStatusButton.dataset.editorStatusButton = 'true';
2672
2546
  editorStatusButton.dataset.editorStatusToggle = 'true';
2673
2547
  editorStatusButton.setAttribute('aria-expanded', 'false');
2674
2548
  const editorStatusCenter = doc.createElement('div');
2675
- editorStatusCenter.classList.add(LOCAL_EDITOR_THEME_CLASS);
2549
+ editorStatusCenter.classList.add(LOCAL_EDITOR_THEME_CLASS, 'fps-editor-ui-popover', 'fps-editor-ui-status-center');
2676
2550
  editorStatusCenter.dataset.editorStatusCenter = 'true';
2677
2551
  editorStatusCenter.style.cssText = [
2678
2552
  'position:fixed',
@@ -2691,19 +2565,29 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
2691
2565
  'pointer-events:auto',
2692
2566
  ].join(';');
2693
2567
  const editorStatusCenterHeader = doc.createElement('div');
2694
- editorStatusCenterHeader.style.cssText = 'display:flex;align-items:center;justify-content:space-between;gap:12px';
2568
+ editorStatusCenterHeader.className = 'fps-editor-ui-surface-header';
2695
2569
  const editorStatusCenterTitle = doc.createElement('div');
2696
- editorStatusCenterTitle.textContent = '编辑器状态';
2570
+ editorStatusCenterTitle.className = 'fps-editor-ui-surface-title';
2571
+ editorStatusCenterTitle.textContent = '验证中心';
2697
2572
  editorStatusCenterTitle.style.cssText = 'font-size:13px;font-weight:900;color:var(--fps-editor-text-strong)';
2573
+ const editorStatusCenterActions = doc.createElement('div');
2574
+ editorStatusCenterActions.className = 'fps-editor-ui-surface-actions';
2698
2575
  const editorStatusCopyAllButton = LocalEditorShared.createButton(doc, '复制全部', { icon: 'copy' });
2699
2576
  editorStatusCopyAllButton.dataset.editorStatusCopyAll = 'true';
2700
2577
  editorStatusCopyAllButton.style.cssText += ';min-height:26px;padding:3px 8px;font-size:11px';
2578
+ const editorStatusCloseButton = createToolbarIconButton(doc, '关闭', 'discard', '关闭验证中心');
2579
+ editorStatusCloseButton.dataset.editorStatusClose = 'true';
2580
+ editorStatusCloseButton.style.minWidth = '28px';
2581
+ editorStatusCenterActions.appendChild(editorStatusCopyAllButton);
2582
+ editorStatusCenterActions.appendChild(editorStatusCloseButton);
2701
2583
  editorStatusCenterHeader.appendChild(editorStatusCenterTitle);
2702
- editorStatusCenterHeader.appendChild(editorStatusCopyAllButton);
2584
+ editorStatusCenterHeader.appendChild(editorStatusCenterActions);
2703
2585
  const editorStatusCenterSummary = doc.createElement('div');
2586
+ editorStatusCenterSummary.className = 'fps-editor-ui-status-summary';
2704
2587
  editorStatusCenterSummary.dataset.editorStatusSummary = 'true';
2705
2588
  editorStatusCenterSummary.style.cssText = 'font-size:11px;line-height:1.45;color:var(--fps-editor-muted-strong)';
2706
2589
  const editorStatusCenterList = doc.createElement('div');
2590
+ editorStatusCenterList.className = 'fps-editor-ui-status-list';
2707
2591
  editorStatusCenterList.dataset.editorStatusList = 'true';
2708
2592
  editorStatusCenterList.style.cssText = 'display:flex;flex-direction:column;gap:7px;overflow:auto;min-height:0';
2709
2593
  editorStatusCenter.appendChild(editorStatusCenterHeader);
@@ -2713,6 +2597,8 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
2713
2597
  agentBridgeStatusButton.dataset.editorAgentBridgeStatusButton = 'true';
2714
2598
  agentBridgeStatusButton.style.cursor = 'help';
2715
2599
  const workbench = createLocalEditorWorkbench(doc);
2600
+ const editorUiLayerHost = createEditorUiLayerHost(doc, workbench.root);
2601
+ construction.addCleanup('editor-ui-layer-host', () => editorUiLayerHost.dispose());
2716
2602
  const leftDockTabs = doc.createElement('div');
2717
2603
  const hierarchyPanel = createWorkbenchPanelContent(doc);
2718
2604
  const assetPanel = workbench.bottomDock;
@@ -2730,24 +2616,70 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
2730
2616
  workbench.rightDock.appendChild(pluginsPanel);
2731
2617
  construction.appendRootChild(workbench.root);
2732
2618
  tooltipSurfaces.add(workbench.root);
2619
+ const disposeRightDockFormalSurfaces = () => {
2620
+ disposeLocalEditorFormalSurfaces([
2621
+ () => LocalEditorPanels.disposeInspectorPanelUi(inspectorPanel),
2622
+ () => LocalEditorPanels.disposeInspectorPanelUi(renderingPanel),
2623
+ ]);
2624
+ };
2625
+ const rightDockFormalSurfaceVisibility = createLocalEditorFormalSurfaceVisibilityController({
2626
+ disposeHidden() {
2627
+ disposeRightDockFormalSurfaces();
2628
+ lastRenderedInspectorContentKey = null;
2629
+ },
2630
+ rehydrateVisible() {
2631
+ disposeRightDockFormalSurfaces();
2632
+ if (currentState?.mode !== 'editor' || currentState.prefabStage)
2633
+ return;
2634
+ const activeRightTab = panelRegistry.getRightDockTab();
2635
+ if (activeRightTab === 'inspector') {
2636
+ LocalEditorPanels.renderInspectorPanel(doc, inspectorPanel, currentState, inspectorFilter, {
2637
+ ...options.inspector,
2638
+ layerHost: editorUiLayerHost,
2639
+ lockedVectorGroups: lockedInspectorVectorGroups,
2640
+ });
2641
+ lastRenderedInspectorContentKey = resolveLocalEditorRightDockContentKey(currentState, 'inspector', inspectorFilter);
2642
+ }
2643
+ else if (activeRightTab === 'rendering') {
2644
+ LocalEditorPanels.renderRenderingPanel(doc, renderingPanel, currentState, { layerHost: editorUiLayerHost });
2645
+ }
2646
+ },
2647
+ });
2733
2648
  const workbenchLayoutController = createLocalEditorWorkbenchLayoutController(doc, workbench, {
2734
- onAfterApply(layout) {
2649
+ onBeforeApply(_layout, dockDisplay) {
2650
+ if (currentState?.mode === 'editor' && currentState.prefabStage)
2651
+ return;
2652
+ if (dockDisplay.rightDockVisible) {
2653
+ rightDockFormalSurfaceVisibility.apply(true);
2654
+ }
2655
+ },
2656
+ onAfterApply(layout, dockDisplay) {
2735
2657
  if (currentState?.mode === 'editor' && currentState.prefabStage) {
2736
2658
  applyPrefabStageWorkbenchLayoutOverride(layout);
2659
+ return;
2660
+ }
2661
+ if (!dockDisplay.rightDockVisible) {
2662
+ rightDockFormalSurfaceVisibility.apply(false);
2737
2663
  }
2738
2664
  },
2739
2665
  });
2740
2666
  construction.addCleanup('workbench-layout-controller', () => workbenchLayoutController.dispose());
2667
+ const editorConsole = createLocalEditorConsoleController(doc, workbench.consoleDock, {
2668
+ isCollapsed: () => workbenchLayoutController.getLayout().consoleCollapsed,
2669
+ onCollapsedChange: collapsed => workbenchLayoutController.setConsoleCollapsed(collapsed, true),
2670
+ });
2671
+ construction.addCleanup('editor-console', () => editorConsole.dispose());
2741
2672
  const findAssetBrowserScrollViewport = () => (assetPanel.querySelector('[data-editor-asset-browser-scroll-viewport]'));
2742
2673
  const assetBrowserViewportReveal = createLocalEditorViewportRevealController({
2743
2674
  getViewport: findAssetBrowserScrollViewport,
2744
2675
  margin: 4,
2745
2676
  });
2746
- let lastRenderedAssetBrowserTab;
2747
- let lastRenderedBottomDockTab;
2677
+ const assetBrowserContinuity = createLocalEditorAssetBrowserContinuityController(() => assetPanel);
2678
+ let lastRenderedAssetBrowserContentKey = null;
2748
2679
  let lastRenderedSelectedAssetId;
2749
2680
  const sceneToolOverlay = createSceneHeaderToolbar(doc);
2750
2681
  const sceneTitle = doc.createElement('div');
2682
+ sceneTitle.className = 'fps-editor-ui-surface-title';
2751
2683
  sceneTitle.textContent = 'Preview';
2752
2684
  sceneTitle.style.cssText = [
2753
2685
  'height:100%',
@@ -2762,8 +2694,11 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
2762
2694
  'white-space:nowrap',
2763
2695
  ].join(';');
2764
2696
  const sceneQuickActions = doc.createElement('div');
2697
+ sceneQuickActions.className = 'fps-editor-ui-toolbar-group';
2698
+ sceneQuickActions.dataset.editorUiFirst = 'true';
2765
2699
  sceneQuickActions.style.cssText = 'display:flex;align-items:center;gap:4px';
2766
2700
  const sceneUtilityActions = doc.createElement('div');
2701
+ sceneUtilityActions.className = 'fps-editor-ui-toolbar-group';
2767
2702
  sceneUtilityActions.style.cssText = [
2768
2703
  'display:flex',
2769
2704
  'align-items:center',
@@ -2772,6 +2707,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
2772
2707
  'border-left:1px solid var(--fps-editor-divider)',
2773
2708
  ].join(';');
2774
2709
  const toolGroup = doc.createElement('div');
2710
+ toolGroup.className = 'fps-editor-ui-toolbar-group';
2775
2711
  toolGroup.style.cssText = [
2776
2712
  'display:flex',
2777
2713
  'align-items:center',
@@ -2780,21 +2716,20 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
2780
2716
  'border-left:1px solid var(--fps-editor-divider)',
2781
2717
  ].join(';');
2782
2718
  const toolButtons = new Map();
2783
- const transformToolDescriptors = Object.values(DEFAULT_EDITOR_TRANSFORM_TOOL_DESCRIPTORS);
2784
- for (const descriptor of transformToolDescriptors) {
2785
- const tooltip = createTransformToolTooltip(descriptor);
2786
- const button = LocalEditorShared.createButton(doc, descriptor.label, {
2787
- icon: TRANSFORM_TOOL_ICONS[descriptor.tool],
2788
- labelMode: 'icon-only',
2789
- variant: 'toolbar-icon',
2790
- tooltip,
2791
- ariaLabel: tooltip,
2719
+ const renderToolPresentationState = (state) => {
2720
+ synchronizeLocalEditorToolButtons({
2721
+ document: doc,
2722
+ group: toolGroup,
2723
+ buttons: toolButtons,
2724
+ presentations: state.tools ?? [],
2792
2725
  });
2793
- button.dataset.transformTool = descriptor.tool;
2794
- toolButtons.set(descriptor.tool, button);
2795
- toolGroup.appendChild(button);
2796
- }
2726
+ toolGroup.style.display = state.mode === 'editor'
2727
+ && (state.tools ?? []).some(tool => tool.kind === 'primary' && tool.availability.state !== 'hidden')
2728
+ ? 'flex'
2729
+ : 'none';
2730
+ };
2797
2731
  const spaceGroup = doc.createElement('div');
2732
+ spaceGroup.className = 'fps-editor-ui-toolbar-group';
2798
2733
  spaceGroup.style.cssText = [
2799
2734
  'display:flex',
2800
2735
  'align-items:center',
@@ -2811,6 +2746,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
2811
2746
  spaceGroup.appendChild(button);
2812
2747
  }
2813
2748
  const snapGroup = doc.createElement('div');
2749
+ snapGroup.className = 'fps-editor-ui-toolbar-group';
2814
2750
  snapGroup.style.cssText = [
2815
2751
  'display:flex',
2816
2752
  'align-items:center',
@@ -2821,7 +2757,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
2821
2757
  const snapButton = createToolbarIconButton(doc, '吸附设置', 'snap', '吸附设置', 'settings');
2822
2758
  snapButton.dataset.transformSnapToggle = 'true';
2823
2759
  const snapSettingsPopover = doc.createElement('div');
2824
- snapSettingsPopover.classList.add(LOCAL_EDITOR_THEME_CLASS);
2760
+ snapSettingsPopover.classList.add(LOCAL_EDITOR_THEME_CLASS, 'fps-editor-ui-popover');
2825
2761
  snapSettingsPopover.dataset.transformSnapSettingsPopover = 'true';
2826
2762
  snapSettingsPopover.setAttribute('role', 'dialog');
2827
2763
  snapSettingsPopover.setAttribute('aria-label', '吸附设置');
@@ -2903,6 +2839,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
2903
2839
  }
2904
2840
  snapGroup.appendChild(snapButton);
2905
2841
  const placementGroup = doc.createElement('div');
2842
+ placementGroup.className = 'fps-editor-ui-toolbar-group';
2906
2843
  placementGroup.style.cssText = [
2907
2844
  'display:flex',
2908
2845
  'align-items:center',
@@ -2913,7 +2850,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
2913
2850
  const placementButton = createToolbarIconButton(doc, '放置模式', PLACEMENT_MODE_ICONS.off, '放置模式', 'settings');
2914
2851
  placementButton.dataset.placementModeToggle = 'true';
2915
2852
  const placementSettingsPopover = doc.createElement('div');
2916
- placementSettingsPopover.classList.add(LOCAL_EDITOR_THEME_CLASS);
2853
+ placementSettingsPopover.classList.add(LOCAL_EDITOR_THEME_CLASS, 'fps-editor-ui-popover');
2917
2854
  placementSettingsPopover.dataset.placementSettingsPopover = 'true';
2918
2855
  placementSettingsPopover.setAttribute('role', 'dialog');
2919
2856
  placementSettingsPopover.setAttribute('aria-label', '放置模式');
@@ -2945,6 +2882,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
2945
2882
  }));
2946
2883
  placementGroup.appendChild(placementButton);
2947
2884
  const actionGroup = doc.createElement('div');
2885
+ actionGroup.className = 'fps-editor-ui-toolbar-group';
2948
2886
  actionGroup.style.cssText = [
2949
2887
  'display:flex',
2950
2888
  'align-items:center',
@@ -2955,7 +2893,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
2955
2893
  const transformActionButton = createToolbarIconButton(doc, '对齐与分布', 'arrange', '对齐与分布', 'settings');
2956
2894
  transformActionButton.dataset.transformActionToggle = 'true';
2957
2895
  const transformActionPopover = doc.createElement('div');
2958
- transformActionPopover.classList.add(LOCAL_EDITOR_THEME_CLASS);
2896
+ transformActionPopover.classList.add(LOCAL_EDITOR_THEME_CLASS, 'fps-editor-ui-popover');
2959
2897
  transformActionPopover.dataset.transformActionPopover = 'true';
2960
2898
  transformActionPopover.setAttribute('role', 'dialog');
2961
2899
  transformActionPopover.setAttribute('aria-label', '对齐与分布');
@@ -3010,6 +2948,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
3010
2948
  }
3011
2949
  actionGroup.appendChild(transformActionButton);
3012
2950
  const staticShadowBakeGroup = doc.createElement('div');
2951
+ staticShadowBakeGroup.className = 'fps-editor-ui-toolbar-group';
3013
2952
  staticShadowBakeGroup.style.cssText = [
3014
2953
  'display:none',
3015
2954
  'align-items:center',
@@ -3022,7 +2961,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
3022
2961
  staticShadowBakeButton.dataset.editorRenderingAction = STATIC_SHADOW_BAKE_ACTION_ID;
3023
2962
  staticShadowBakeGroup.appendChild(staticShadowBakeButton);
3024
2963
  const staticShadowBakePopover = doc.createElement('div');
3025
- staticShadowBakePopover.classList.add(LOCAL_EDITOR_THEME_CLASS);
2964
+ staticShadowBakePopover.classList.add(LOCAL_EDITOR_THEME_CLASS, 'fps-editor-ui-popover');
3026
2965
  staticShadowBakePopover.dataset.editorToolbarStaticShadowBakePopover = 'true';
3027
2966
  staticShadowBakePopover.setAttribute('role', 'dialog');
3028
2967
  staticShadowBakePopover.setAttribute('aria-label', '静态阴影烘焙进度');
@@ -3110,23 +3049,22 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
3110
3049
  performanceMonitorButton.dataset.performanceMonitorToggle = 'true';
3111
3050
  const gridToggleButton = createToolbarIconButton(doc, '网格', 'grid', '显示 / 隐藏 Scene View 网格');
3112
3051
  gridToggleButton.dataset.editorGridToggle = 'true';
3113
- const prefabComparisonPreviewButton = createToolbarIconButton(doc, '对比预览', 'eye', 'Compare Previews (Shift+P)', 'toggle');
3114
- prefabComparisonPreviewButton.dataset.prefabComparisonPreviewToggle = 'true';
3115
3052
  const sceneHelpButton = createToolbarIconButton(doc, '快捷键', 'help', '快捷键与操作说明');
3116
3053
  sceneQuickActions.appendChild(localTestGroup);
3117
- const prefabStageBackButton = createToolbarIconButton(doc, '返回场景', 'chevron-right', '返回主场景');
3118
- prefabStageBackButton.dataset.editorPrefabStageBack = 'true';
3119
- prefabStageBackButton.style.display = 'none';
3120
- sceneQuickActions.appendChild(prefabStageBackButton);
3054
+ const contextActionGroup = doc.createElement('div');
3055
+ contextActionGroup.className = 'fps-editor-ui-toolbar-group';
3056
+ contextActionGroup.dataset.editorContextActions = 'true';
3057
+ contextActionGroup.style.cssText = 'display:none;align-items:center;gap:4px';
3058
+ sceneQuickActions.appendChild(contextActionGroup);
3121
3059
  sceneQuickActions.appendChild(undoButton);
3122
3060
  sceneQuickActions.appendChild(redoButton);
3123
3061
  sceneQuickActions.appendChild(dirtyBadge);
3124
3062
  sceneUtilityActions.appendChild(performanceMonitorButton);
3125
3063
  sceneUtilityActions.appendChild(gridToggleButton);
3126
- sceneUtilityActions.appendChild(prefabComparisonPreviewButton);
3127
3064
  sceneUtilityActions.appendChild(themeToggleButton);
3128
3065
  sceneUtilityActions.appendChild(sceneHelpButton);
3129
3066
  const cameraPreviewGroup = doc.createElement('div');
3067
+ cameraPreviewGroup.className = 'fps-editor-ui-toolbar-group';
3130
3068
  cameraPreviewGroup.style.cssText = [
3131
3069
  'display:flex',
3132
3070
  'align-items:center',
@@ -3138,6 +3076,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
3138
3076
  sceneCameraButton.dataset.sceneCameraPreviewToggle = 'true';
3139
3077
  cameraPreviewGroup.appendChild(sceneCameraButton);
3140
3078
  const viewportToolsGroup = doc.createElement('div');
3079
+ viewportToolsGroup.className = 'fps-editor-ui-toolbar-group';
3141
3080
  viewportToolsGroup.style.cssText = [
3142
3081
  'display:flex',
3143
3082
  'align-items:center',
@@ -3145,19 +3084,12 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
3145
3084
  'padding-left:8px',
3146
3085
  'border-left:1px solid var(--fps-editor-divider)',
3147
3086
  ].join(';');
3148
- const viewportPresetButtons = new Map();
3149
- for (const preset of ['perspective', 'top', 'front', 'right']) {
3150
- const button = createToolbarIconButton(doc, VIEW_PRESET_TOOLTIPS[preset], VIEW_PRESET_ICONS[preset], VIEW_PRESET_TOOLTIPS[preset]);
3151
- button.dataset.viewportViewPreset = preset;
3152
- viewportPresetButtons.set(preset, button);
3153
- viewportToolsGroup.appendChild(button);
3154
- }
3155
- const projectionToggleButton = createToolbarIconButton(doc, '投影模式', 'projection-perspective', '切换投影模式');
3156
- projectionToggleButton.dataset.viewportProjectionToggle = 'true';
3157
- viewportToolsGroup.appendChild(projectionToggleButton);
3158
3087
  const markerVisibilityButton = createToolbarIconButton(doc, '标记视图', 'view-overlay', '隐藏标记与关系线', 'toggle');
3159
3088
  markerVisibilityButton.dataset.viewportMarkerVisibilityToggle = 'true';
3160
3089
  viewportToolsGroup.appendChild(markerVisibilityButton);
3090
+ const showAllPrefabMarkersButton = createToolbarIconButton(doc, '全部 Prefab 标记', 'view-overlay', '显示所有 Prefab 实例的标记', 'toggle');
3091
+ showAllPrefabMarkersButton.dataset.viewportShowAllPrefabMarkersToggle = 'true';
3092
+ viewportToolsGroup.appendChild(showAllPrefabMarkersButton);
3161
3093
  const overlaySettingsButton = createToolbarIconButton(doc, '视口信息层设置', 'view-overlay', '视口信息层设置', 'settings');
3162
3094
  overlaySettingsButton.dataset.viewportOverlaySettingsToggle = 'true';
3163
3095
  viewportToolsGroup.appendChild(overlaySettingsButton);
@@ -3168,7 +3100,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
3168
3100
  clearMeasurementButton.dataset.viewportMeasurementClear = 'true';
3169
3101
  viewportToolsGroup.appendChild(clearMeasurementButton);
3170
3102
  const overlaySettingsPopover = doc.createElement('div');
3171
- overlaySettingsPopover.classList.add(LOCAL_EDITOR_THEME_CLASS);
3103
+ overlaySettingsPopover.classList.add(LOCAL_EDITOR_THEME_CLASS, 'fps-editor-ui-popover');
3172
3104
  overlaySettingsPopover.dataset.viewportOverlaySettingsPopover = 'true';
3173
3105
  overlaySettingsPopover.setAttribute('role', 'dialog');
3174
3106
  overlaySettingsPopover.setAttribute('aria-label', '视口信息层设置');
@@ -3212,7 +3144,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
3212
3144
  toolbarOverflowButton.dataset.editorToolbarOverflowToggle = 'true';
3213
3145
  toolbarOverflowButton.style.display = 'none';
3214
3146
  const toolbarOverflowMenu = doc.createElement('div');
3215
- toolbarOverflowMenu.classList.add(LOCAL_EDITOR_THEME_CLASS);
3147
+ toolbarOverflowMenu.classList.add(LOCAL_EDITOR_THEME_CLASS, 'fps-editor-ui-popover');
3216
3148
  toolbarOverflowMenu.dataset.editorToolbarOverflowMenu = 'true';
3217
3149
  toolbarOverflowMenu.style.cssText = [
3218
3150
  'position:fixed',
@@ -3232,114 +3164,13 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
3232
3164
  'pointer-events:auto',
3233
3165
  ].join(';');
3234
3166
  const coordinateAxesOverlay = createCoordinateAxesOverlay(doc);
3235
- const sceneFrameRateOverlay = createSceneFrameRateOverlay(doc);
3236
3167
  const performanceMonitorOverlay = createPerformanceMonitorOverlay(doc);
3237
3168
  const prefabImportStatsOverlay = createPrefabImportStatsOverlay(doc);
3238
- const prefabComparisonPreviewOverlay = createPrefabComparisonPreviewOverlay(doc);
3239
3169
  const prefabStagePreviewLayout = createPrefabStagePreviewLayout(doc);
3240
3170
  prefabImportStatsOverlay.root.style.position = 'absolute';
3241
3171
  prefabImportStatsOverlay.root.style.top = '10px';
3242
3172
  prefabImportStatsOverlay.root.style.right = '14px';
3243
- prefabComparisonPreviewOverlay.root.style.height = '100%';
3244
3173
  prefabStagePreviewLayout.mainRegion.appendChild(prefabImportStatsOverlay.root);
3245
- prefabStagePreviewLayout.comparisonColumn.appendChild(prefabComparisonPreviewOverlay.root);
3246
- const emitPrefabComparisonPreviewInteraction = (input) => {
3247
- if (currentState?.mode !== 'editor' || !currentState.prefabStage)
3248
- return;
3249
- callbacks.onPrefabComparisonPreviewInteraction?.(input);
3250
- };
3251
- const endPrefabComparisonPreviewDrag = (pointerId) => {
3252
- const drag = prefabComparisonPreviewDrag;
3253
- if (!drag || (pointerId != null && drag.pointerId !== pointerId))
3254
- return;
3255
- try {
3256
- if (!drag.surface.hasPointerCapture || drag.surface.hasPointerCapture(drag.pointerId)) {
3257
- drag.surface.releasePointerCapture?.(drag.pointerId);
3258
- }
3259
- }
3260
- catch {
3261
- // Pointer capture may already be released by the browser when this cleanup runs.
3262
- }
3263
- drag.surface.style.cursor = 'grab';
3264
- prefabComparisonPreviewDrag = null;
3265
- };
3266
- const onPrefabComparisonPreviewPointerDown = (event) => {
3267
- if (event.button !== 0 || currentState?.mode !== 'editor' || !currentState.prefabStage)
3268
- return;
3269
- const surface = findPrefabComparisonPreviewSurface(event.target);
3270
- if (!surface || !isPrefabComparisonPreviewSurfaceReady(surface))
3271
- return;
3272
- const previewId = readPrefabComparisonPreviewSurfaceId(surface);
3273
- if (!previewId)
3274
- return;
3275
- event.preventDefault();
3276
- event.stopPropagation();
3277
- endPrefabComparisonPreviewDrag();
3278
- try {
3279
- surface.setPointerCapture?.(event.pointerId);
3280
- }
3281
- catch {
3282
- // Pointer capture is an input nicety; drag state still works through the overlay listener.
3283
- }
3284
- surface.style.cursor = 'grabbing';
3285
- prefabComparisonPreviewDrag = {
3286
- pointerId: event.pointerId,
3287
- previewId,
3288
- surface,
3289
- lastClientX: event.clientX,
3290
- lastClientY: event.clientY,
3291
- };
3292
- };
3293
- const onPrefabComparisonPreviewPointerMove = (event) => {
3294
- const drag = prefabComparisonPreviewDrag;
3295
- if (!drag || drag.pointerId !== event.pointerId)
3296
- return;
3297
- event.preventDefault();
3298
- event.stopPropagation();
3299
- const deltaX = event.clientX - drag.lastClientX;
3300
- const deltaY = event.clientY - drag.lastClientY;
3301
- drag.lastClientX = event.clientX;
3302
- drag.lastClientY = event.clientY;
3303
- if (Math.abs(deltaX) < 0.001 && Math.abs(deltaY) < 0.001)
3304
- return;
3305
- emitPrefabComparisonPreviewInteraction({
3306
- kind: 'orbit',
3307
- previewId: drag.previewId,
3308
- deltaX,
3309
- deltaY,
3310
- });
3311
- };
3312
- const onPrefabComparisonPreviewPointerEnd = (event) => {
3313
- const drag = prefabComparisonPreviewDrag;
3314
- if (!drag || drag.pointerId !== event.pointerId)
3315
- return;
3316
- event.preventDefault();
3317
- event.stopPropagation();
3318
- endPrefabComparisonPreviewDrag(event.pointerId);
3319
- };
3320
- const onPrefabComparisonPreviewWheel = (event) => {
3321
- if (currentState?.mode !== 'editor' || !currentState.prefabStage)
3322
- return;
3323
- const surface = findPrefabComparisonPreviewSurface(event.target);
3324
- if (!surface || !isPrefabComparisonPreviewSurfaceReady(surface))
3325
- return;
3326
- const previewId = readPrefabComparisonPreviewSurfaceId(surface);
3327
- if (!previewId)
3328
- return;
3329
- event.preventDefault();
3330
- event.stopPropagation();
3331
- emitPrefabComparisonPreviewInteraction({
3332
- kind: 'zoom',
3333
- previewId,
3334
- deltaY: event.deltaY,
3335
- });
3336
- };
3337
- prefabComparisonPreviewOverlay.root.addEventListener('pointerdown', onPrefabComparisonPreviewPointerDown);
3338
- prefabComparisonPreviewOverlay.root.addEventListener('pointermove', onPrefabComparisonPreviewPointerMove);
3339
- prefabComparisonPreviewOverlay.root.addEventListener('pointerup', onPrefabComparisonPreviewPointerEnd);
3340
- prefabComparisonPreviewOverlay.root.addEventListener('pointercancel', onPrefabComparisonPreviewPointerEnd);
3341
- prefabComparisonPreviewOverlay.root.addEventListener('lostpointercapture', onPrefabComparisonPreviewPointerEnd);
3342
- prefabComparisonPreviewOverlay.root.addEventListener('wheel', onPrefabComparisonPreviewWheel, { passive: false });
3343
3174
  const spatialOverlay = createSpatialOverlay(doc);
3344
3175
  const measurementOverlay = createMeasurementOverlay(doc);
3345
3176
  sceneToolOverlay.appendChild(sceneTitle);
@@ -3359,7 +3190,6 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
3359
3190
  workbench.sceneHeader.appendChild(sceneToolOverlay);
3360
3191
  workbench.sceneFrame.appendChild(spatialOverlay.root);
3361
3192
  workbench.sceneFrame.appendChild(measurementOverlay.root);
3362
- workbench.sceneFrame.appendChild(sceneFrameRateOverlay.root);
3363
3193
  workbench.sceneFrame.appendChild(performanceMonitorOverlay.root);
3364
3194
  workbench.sceneFrame.appendChild(prefabStagePreviewLayout.root);
3365
3195
  workbench.sceneFrame.appendChild(coordinateAxesOverlay.root);
@@ -3397,7 +3227,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
3397
3227
  construction.appendRootChild(shortcutHelpPanel);
3398
3228
  tooltipSurfaces.add(shortcutHelpPanel);
3399
3229
  const assetPreviewModal = doc.createElement('div');
3400
- assetPreviewModal.classList.add(LOCAL_EDITOR_THEME_CLASS);
3230
+ assetPreviewModal.classList.add(LOCAL_EDITOR_THEME_CLASS, 'fps-editor-ui-modal-root', 'fps-editor-ui-asset-preview-modal');
3401
3231
  assetPreviewModal.dataset.editorAssetPreviewModal = 'true';
3402
3232
  assetPreviewModal.dataset.editorWorkbenchRegion = 'modal';
3403
3233
  assetPreviewModal.style.cssText = [
@@ -3414,6 +3244,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
3414
3244
  'pointer-events:auto',
3415
3245
  ].join(';');
3416
3246
  const assetPreviewDialog = doc.createElement('div');
3247
+ assetPreviewDialog.className = 'fps-editor-ui-modal';
3417
3248
  assetPreviewDialog.setAttribute('role', 'dialog');
3418
3249
  assetPreviewDialog.setAttribute('aria-modal', 'true');
3419
3250
  assetPreviewDialog.setAttribute('aria-label', '资产预览');
@@ -3431,8 +3262,10 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
3431
3262
  'overflow:auto',
3432
3263
  ].join(';');
3433
3264
  const assetPreviewHeader = doc.createElement('div');
3265
+ assetPreviewHeader.className = 'fps-editor-ui-modal-header';
3434
3266
  assetPreviewHeader.style.cssText = 'display:flex;align-items:center;justify-content:space-between;gap:12px';
3435
3267
  const assetPreviewTitle = doc.createElement('h2');
3268
+ assetPreviewTitle.className = 'fps-editor-ui-modal-title';
3436
3269
  assetPreviewTitle.style.cssText = [
3437
3270
  'min-width:0',
3438
3271
  'margin:0',
@@ -3473,8 +3306,114 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
3473
3306
  assetPreviewModal.appendChild(assetPreviewDialog);
3474
3307
  construction.appendRootChild(assetPreviewModal);
3475
3308
  tooltipSurfaces.add(assetPreviewModal);
3309
+ const projectFilePreviewModal = doc.createElement('div');
3310
+ projectFilePreviewModal.classList.add(LOCAL_EDITOR_THEME_CLASS, 'fps-editor-ui-modal-root');
3311
+ projectFilePreviewModal.dataset.editorProjectFilePreviewModal = 'true';
3312
+ projectFilePreviewModal.dataset.editorWorkbenchRegion = 'modal';
3313
+ projectFilePreviewModal.style.cssText = [
3314
+ 'position:fixed',
3315
+ 'inset:0',
3316
+ 'z-index:2147483642',
3317
+ 'display:none',
3318
+ 'align-items:center',
3319
+ 'justify-content:center',
3320
+ 'padding:24px',
3321
+ 'background:rgba(0,0,0,0.5)',
3322
+ 'font-family:var(--fps-editor-font)',
3323
+ 'color:var(--fps-editor-text)',
3324
+ 'pointer-events:auto',
3325
+ ].join(';');
3326
+ const projectFilePreviewDialog = doc.createElement('div');
3327
+ projectFilePreviewDialog.className = 'fps-editor-ui-modal';
3328
+ projectFilePreviewDialog.setAttribute('role', 'dialog');
3329
+ projectFilePreviewDialog.setAttribute('aria-modal', 'true');
3330
+ projectFilePreviewDialog.setAttribute('aria-label', '只读文件预览');
3331
+ projectFilePreviewDialog.style.cssText = [
3332
+ 'width:min(980px,calc(100vw - 48px))',
3333
+ 'height:min(720px,calc(100vh - 48px))',
3334
+ 'min-height:320px',
3335
+ 'display:grid',
3336
+ 'grid-template-rows:auto auto minmax(0,1fr) auto',
3337
+ 'gap:8px',
3338
+ 'padding:12px',
3339
+ 'border:1px solid var(--fps-editor-border)',
3340
+ 'border-radius:4px',
3341
+ 'background:var(--fps-editor-panel)',
3342
+ 'box-shadow:var(--fps-editor-shadow-modal)',
3343
+ 'overflow:hidden',
3344
+ ].join(';');
3345
+ const projectFilePreviewHeader = doc.createElement('div');
3346
+ projectFilePreviewHeader.className = 'fps-editor-ui-modal-header';
3347
+ projectFilePreviewHeader.style.cssText = 'display:flex;align-items:center;justify-content:space-between;gap:12px;min-width:0';
3348
+ const projectFilePreviewHeading = doc.createElement('div');
3349
+ projectFilePreviewHeading.style.cssText = 'display:flex;flex-direction:column;gap:2px;min-width:0';
3350
+ const projectFilePreviewTitle = doc.createElement('h2');
3351
+ projectFilePreviewTitle.className = 'fps-editor-ui-modal-title fps-editor-ui-ellipsis';
3352
+ projectFilePreviewTitle.style.cssText = 'margin:0;font-size:13px;font-weight:800;color:var(--fps-editor-text-strong)';
3353
+ const projectFilePreviewPath = doc.createElement('div');
3354
+ projectFilePreviewPath.className = 'fps-editor-ui-ellipsis';
3355
+ projectFilePreviewPath.style.cssText = 'font-size:11px;color:var(--fps-editor-muted)';
3356
+ projectFilePreviewHeading.append(projectFilePreviewTitle, projectFilePreviewPath);
3357
+ const projectFilePreviewCloseButton = createToolbarIconButton(doc, '关闭', 'close', '关闭文件预览');
3358
+ projectFilePreviewCloseButton.dataset.editorProjectFilePreviewClose = 'true';
3359
+ projectFilePreviewHeader.append(projectFilePreviewHeading, projectFilePreviewCloseButton);
3360
+ const projectFilePreviewSearchBar = doc.createElement('div');
3361
+ projectFilePreviewSearchBar.style.cssText = 'display:grid;grid-template-columns:minmax(160px,1fr) auto auto auto;align-items:center;gap:5px';
3362
+ const projectFilePreviewSearchShell = doc.createElement('div');
3363
+ projectFilePreviewSearchShell.className = 'fps-editor-ui-asset-search';
3364
+ const projectFilePreviewSearchIcon = createLocalEditorIcon(doc, 'search', { size: 15 });
3365
+ projectFilePreviewSearchIcon.classList.add('fps-editor-ui-asset-search-icon');
3366
+ const projectFilePreviewSearch = doc.createElement('input');
3367
+ projectFilePreviewSearch.className = 'fps-editor-ui-search';
3368
+ projectFilePreviewSearch.type = 'search';
3369
+ projectFilePreviewSearch.placeholder = '在文件中搜索';
3370
+ projectFilePreviewSearch.dataset.editorProjectFileSearch = 'true';
3371
+ projectFilePreviewSearch.style.paddingLeft = '28px';
3372
+ projectFilePreviewSearchShell.append(projectFilePreviewSearchIcon, projectFilePreviewSearch);
3373
+ const projectFilePreviewMatchCount = doc.createElement('span');
3374
+ projectFilePreviewMatchCount.dataset.editorProjectFileMatchCount = 'true';
3375
+ projectFilePreviewMatchCount.style.cssText = 'min-width:58px;text-align:center;font-size:11px;color:var(--fps-editor-muted-strong);font-variant-numeric:tabular-nums';
3376
+ const projectFilePreviewPrevious = createToolbarIconButton(doc, '上一个匹配项', 'arrow-up', '上一个匹配项');
3377
+ projectFilePreviewPrevious.dataset.editorProjectFileSearchPrevious = 'true';
3378
+ const projectFilePreviewNext = createToolbarIconButton(doc, '下一个匹配项', 'chevron-down', '下一个匹配项');
3379
+ projectFilePreviewNext.dataset.editorProjectFileSearchNext = 'true';
3380
+ projectFilePreviewSearchBar.append(projectFilePreviewSearchShell, projectFilePreviewMatchCount, projectFilePreviewPrevious, projectFilePreviewNext);
3381
+ const projectFilePreviewViewport = doc.createElement('div');
3382
+ projectFilePreviewViewport.dataset.editorProjectFilePreviewViewport = 'true';
3383
+ projectFilePreviewViewport.style.cssText = [
3384
+ 'min-width:0',
3385
+ 'min-height:0',
3386
+ 'overflow:auto',
3387
+ 'border:1px solid var(--fps-editor-divider)',
3388
+ 'border-radius:3px',
3389
+ 'background:var(--fps-editor-field)',
3390
+ ].join(';');
3391
+ const projectFilePreviewCode = doc.createElement('pre');
3392
+ projectFilePreviewCode.dataset.editorProjectFilePreviewCode = 'true';
3393
+ projectFilePreviewCode.setAttribute('aria-label', '只读文件内容');
3394
+ projectFilePreviewCode.style.cssText = [
3395
+ 'min-width:max-content',
3396
+ 'min-height:100%',
3397
+ 'margin:0',
3398
+ 'padding:12px 14px',
3399
+ 'box-sizing:border-box',
3400
+ 'white-space:pre',
3401
+ 'font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace',
3402
+ 'font-size:12px',
3403
+ 'line-height:1.55',
3404
+ 'tab-size:2',
3405
+ 'color:var(--fps-editor-text)',
3406
+ ].join(';');
3407
+ projectFilePreviewViewport.appendChild(projectFilePreviewCode);
3408
+ const projectFilePreviewMeta = doc.createElement('div');
3409
+ projectFilePreviewMeta.dataset.editorProjectFilePreviewMeta = 'true';
3410
+ projectFilePreviewMeta.style.cssText = 'min-height:16px;font-size:10px;color:var(--fps-editor-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap';
3411
+ projectFilePreviewDialog.append(projectFilePreviewHeader, projectFilePreviewSearchBar, projectFilePreviewViewport, projectFilePreviewMeta);
3412
+ projectFilePreviewModal.appendChild(projectFilePreviewDialog);
3413
+ construction.appendRootChild(projectFilePreviewModal);
3414
+ tooltipSurfaces.add(projectFilePreviewModal);
3476
3415
  const assetPickerModal = doc.createElement('div');
3477
- assetPickerModal.classList.add(LOCAL_EDITOR_THEME_CLASS);
3416
+ assetPickerModal.classList.add(LOCAL_EDITOR_THEME_CLASS, 'fps-editor-ui-modal-root', 'fps-editor-ui-asset-modal');
3478
3417
  assetPickerModal.dataset.editorAssetPickerModal = 'true';
3479
3418
  assetPickerModal.dataset.editorWorkbenchRegion = 'modal';
3480
3419
  assetPickerModal.style.cssText = [
@@ -3491,6 +3430,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
3491
3430
  'pointer-events:auto',
3492
3431
  ].join(';');
3493
3432
  const assetPickerDialog = doc.createElement('div');
3433
+ assetPickerDialog.className = 'fps-editor-ui-modal';
3494
3434
  assetPickerDialog.setAttribute('role', 'dialog');
3495
3435
  assetPickerDialog.setAttribute('aria-modal', 'true');
3496
3436
  assetPickerDialog.setAttribute('aria-label', '资产选择');
@@ -3508,8 +3448,10 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
3508
3448
  'overflow:hidden',
3509
3449
  ].join(';');
3510
3450
  const assetPickerHeader = doc.createElement('div');
3451
+ assetPickerHeader.className = 'fps-editor-ui-modal-header';
3511
3452
  assetPickerHeader.style.cssText = 'display:flex;align-items:center;justify-content:space-between;gap:12px';
3512
3453
  const assetPickerTitle = doc.createElement('h2');
3454
+ assetPickerTitle.className = 'fps-editor-ui-modal-title';
3513
3455
  assetPickerTitle.style.cssText = [
3514
3456
  'min-width:0',
3515
3457
  'margin:0',
@@ -3525,6 +3467,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
3525
3467
  assetPickerHeader.appendChild(assetPickerTitle);
3526
3468
  assetPickerHeader.appendChild(assetPickerCloseButton);
3527
3469
  const assetPickerSearch = doc.createElement('input');
3470
+ assetPickerSearch.className = 'fps-editor-ui-modal-search';
3528
3471
  assetPickerSearch.type = 'search';
3529
3472
  assetPickerSearch.dataset.editorAssetPickerSearch = 'true';
3530
3473
  assetPickerSearch.placeholder = '搜索资产';
@@ -3539,6 +3482,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
3539
3482
  'padding:0 8px',
3540
3483
  ].join(';');
3541
3484
  const assetPickerList = doc.createElement('div');
3485
+ assetPickerList.className = 'fps-editor-ui-modal-grid';
3542
3486
  assetPickerList.style.cssText = [
3543
3487
  'min-height:180px',
3544
3488
  'max-height:min(430px,calc(100vh - 196px))',
@@ -3559,13 +3503,12 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
3559
3503
  applyLocalEditorTheme(workbench.root, activeTheme);
3560
3504
  applyLocalEditorTheme(spatialOverlay.root, activeTheme);
3561
3505
  applyLocalEditorTheme(measurementOverlay.root, activeTheme);
3562
- applyLocalEditorTheme(sceneFrameRateOverlay.root, activeTheme);
3563
3506
  applyLocalEditorTheme(performanceMonitorOverlay.root, activeTheme);
3564
3507
  applyLocalEditorTheme(prefabStagePreviewLayout.root, activeTheme);
3565
3508
  applyLocalEditorTheme(prefabImportStatsOverlay.root, activeTheme);
3566
- applyLocalEditorTheme(prefabComparisonPreviewOverlay.root, activeTheme);
3567
3509
  applyLocalEditorTheme(shortcutHelpPanel, activeTheme);
3568
3510
  applyLocalEditorTheme(assetPreviewModal, activeTheme);
3511
+ applyLocalEditorTheme(projectFilePreviewModal, activeTheme);
3569
3512
  applyLocalEditorTheme(assetPickerModal, activeTheme);
3570
3513
  applyLocalEditorTheme(boxSelectionOverlay, activeTheme);
3571
3514
  applyLocalEditorTheme(localTestMenu, activeTheme);
@@ -3612,37 +3555,150 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
3612
3555
  if (viewModel.diagnostics.length === 0) {
3613
3556
  const empty = doc.createElement('div');
3614
3557
  empty.dataset.editorStatusEmpty = 'true';
3615
- empty.textContent = '没有需要处理的错误或警告。';
3558
+ empty.textContent = '当前没有诊断信息。';
3616
3559
  empty.style.cssText = 'padding:14px 8px;text-align:center;color:var(--fps-editor-muted);font-size:12px';
3617
3560
  editorStatusCenterList.appendChild(empty);
3618
3561
  return;
3619
3562
  }
3563
+ const currentScopeId = state?.prefabStage
3564
+ ? `prefab-stage:${state.prefabStage.assetId}`
3565
+ : 'scene';
3566
+ let previousGroup = '';
3620
3567
  viewModel.entries.forEach(({ diagnostic, copyText }, index) => {
3568
+ const group = `${diagnostic.severity}\u0000${diagnostic.phase ?? 'edit'}\u0000${diagnostic.source}`;
3569
+ if (group !== previousGroup) {
3570
+ const groupHeader = doc.createElement('div');
3571
+ groupHeader.dataset.editorStatusGroup = group;
3572
+ groupHeader.textContent = `${diagnostic.severity === 'error' ? '错误' : diagnostic.severity === 'warning' ? '警告' : '信息'} · ${diagnostic.phase ?? 'edit'} · ${diagnostic.source}`;
3573
+ groupHeader.style.cssText = 'padding:5px 2px 1px;font-size:10px;font-weight:900;color:var(--fps-editor-muted-strong);text-transform:uppercase';
3574
+ editorStatusCenterList.appendChild(groupHeader);
3575
+ previousGroup = group;
3576
+ }
3621
3577
  const item = doc.createElement('div');
3622
3578
  item.dataset.editorStatusDiagnostic = diagnostic.code;
3579
+ const diagnosticBorder = diagnostic.severity === 'error'
3580
+ ? 'var(--fps-editor-danger-border)'
3581
+ : diagnostic.severity === 'warning'
3582
+ ? 'var(--fps-editor-warn-border)'
3583
+ : 'var(--fps-editor-border)';
3584
+ const diagnosticBackground = diagnostic.severity === 'error'
3585
+ ? 'var(--fps-editor-danger-soft)'
3586
+ : diagnostic.severity === 'warning'
3587
+ ? 'var(--fps-editor-warn-soft)'
3588
+ : 'var(--fps-editor-surface-soft)';
3623
3589
  item.style.cssText = [
3624
3590
  'display:grid',
3625
3591
  'grid-template-columns:minmax(0,1fr) auto',
3626
3592
  'gap:8px',
3627
3593
  'padding:8px',
3628
- `border:1px solid ${diagnostic.severity === 'error' ? 'var(--fps-editor-danger-border)' : 'var(--fps-editor-warn-border)'}`,
3594
+ `border:1px solid ${diagnosticBorder}`,
3629
3595
  'border-radius:3px',
3630
- `background:${diagnostic.severity === 'error' ? 'var(--fps-editor-danger-soft)' : 'var(--fps-editor-warn-soft)'}`,
3596
+ `background:${diagnosticBackground}`,
3631
3597
  ].join(';');
3632
3598
  const content = doc.createElement('div');
3633
3599
  content.style.cssText = 'min-width:0;display:flex;flex-direction:column;gap:4px';
3600
+ const locateAction = diagnostic.actions?.find(action => action.kind === 'locate');
3601
+ const locatePlan = resolveLocalEditorStatusDiagnosticLocatePlan(diagnostic, currentScopeId);
3602
+ const locator = locatePlan.locator;
3603
+ const canLocate = locatePlan.canLocate && !!callbacks.onStatusDiagnosticLocate;
3604
+ const locate = () => {
3605
+ const navigationRequest = {
3606
+ settled: false,
3607
+ ...(locator.assetId ? { assetId: locator.assetId } : {}),
3608
+ ...(locator.path ? {
3609
+ path: {
3610
+ value: locator.path,
3611
+ ...(locator.scopeId ? { scopeId: locator.scopeId } : {}),
3612
+ ...(diagnostic.documentRevision != null ? { documentRevision: diagnostic.documentRevision } : {}),
3613
+ ...(diagnostic.projectionRevision != null ? { projectionRevision: diagnostic.projectionRevision } : {}),
3614
+ },
3615
+ } : {}),
3616
+ };
3617
+ pendingStatusDiagnosticRequest = navigationRequest;
3618
+ if (locator.assetId) {
3619
+ assetBrowserTab = 'all';
3620
+ const asset = currentState?.assets.find(candidate => (candidate.id === locator.assetId || candidate.assetId === locator.assetId));
3621
+ if (asset && currentState) {
3622
+ assetBrowserFolderPath = resolveLocalEditorAssetFilesystemFolderPath(createLocalEditorAssetFilesystemSnapshot(currentState.assets, currentState.projectFiles), asset.id);
3623
+ expandAssetBrowserFolderPath(assetBrowserFolderPath);
3624
+ }
3625
+ panelRegistry.setBottomDockTab('assets');
3626
+ workbenchLayoutController.setBottomCollapsed(false);
3627
+ callbacks.onAssetFilterChange?.('');
3628
+ }
3629
+ if (locator.path) {
3630
+ inspectorFilter = '';
3631
+ panelRegistry.setRightDockTab('inspector');
3632
+ const layout = workbenchLayoutController.getLayout();
3633
+ if (layout.rightCollapsed) {
3634
+ workbenchLayoutController.setLayout({ ...layout, rightCollapsed: false });
3635
+ }
3636
+ }
3637
+ const result = callbacks.onStatusDiagnosticLocate?.({
3638
+ ...diagnostic,
3639
+ locator,
3640
+ });
3641
+ const settle = (accepted) => {
3642
+ pendingStatusDiagnosticRequest = settleLocalEditorStatusDiagnosticRequest(pendingStatusDiagnosticRequest, navigationRequest, accepted);
3643
+ if (accepted !== false && pendingStatusDiagnosticRequest === navigationRequest && currentState) {
3644
+ revealPendingStatusDiagnosticPath(currentState);
3645
+ revealPendingStatusDiagnosticAsset(currentState);
3646
+ clearCompletedStatusDiagnosticRequest(navigationRequest);
3647
+ }
3648
+ };
3649
+ if (result && typeof result.then === 'function') {
3650
+ void result.then(settle, () => settle(false));
3651
+ }
3652
+ else {
3653
+ settle(result);
3654
+ }
3655
+ };
3656
+ if (canLocate) {
3657
+ content.dataset.editorStatusLocate = locator.objectId
3658
+ ?? locator.rowId
3659
+ ?? locator.prefabNodeId
3660
+ ?? locator.assetId
3661
+ ?? locator.path
3662
+ ?? '';
3663
+ content.setAttribute('role', 'button');
3664
+ content.tabIndex = 0;
3665
+ content.style.cursor = 'pointer';
3666
+ content.addEventListener('click', locate);
3667
+ content.addEventListener('keydown', event => {
3668
+ if (event.key !== 'Enter' && event.key !== ' ')
3669
+ return;
3670
+ event.preventDefault();
3671
+ locate();
3672
+ });
3673
+ }
3634
3674
  const code = doc.createElement('div');
3635
- code.textContent = `${diagnostic.severity === 'error' ? '错误' : '警告'} · ${diagnostic.code}`;
3636
- code.style.cssText = `font-size:11px;font-weight:900;color:${diagnostic.severity === 'error' ? 'var(--fps-editor-danger-strong)' : 'var(--fps-editor-warn)'}`;
3675
+ code.textContent = `${diagnostic.severity === 'error' ? '错误' : diagnostic.severity === 'warning' ? '警告' : '信息'} · ${diagnostic.code}`;
3676
+ code.style.cssText = `font-size:11px;font-weight:900;color:${diagnostic.severity === 'error' ? 'var(--fps-editor-danger-strong)' : diagnostic.severity === 'warning' ? 'var(--fps-editor-warn)' : 'var(--fps-editor-text-strong)'}`;
3637
3677
  const message = doc.createElement('div');
3638
3678
  message.textContent = diagnostic.message;
3639
3679
  message.style.cssText = 'font-size:12px;line-height:1.45;color:var(--fps-editor-text-strong);overflow-wrap:anywhere';
3680
+ const suggestion = doc.createElement('div');
3681
+ suggestion.dataset.editorStatusSuggestion = diagnostic.code;
3682
+ suggestion.textContent = diagnostic.suggestion ? `建议:${diagnostic.suggestion}` : '';
3683
+ suggestion.style.cssText = 'font-size:11px;line-height:1.4;color:var(--fps-editor-muted-strong);overflow-wrap:anywhere';
3684
+ suggestion.style.display = diagnostic.suggestion ? 'block' : 'none';
3640
3685
  const meta = doc.createElement('div');
3641
- const diagnosticLocation = [diagnostic.scopeId, diagnostic.rowId, diagnostic.targetId]
3686
+ const diagnosticLocation = [
3687
+ locator.scopeId,
3688
+ locator.rowId,
3689
+ locator.objectId,
3690
+ locator.prefabAssetId,
3691
+ locator.prefabNodeId,
3692
+ locator.assetId,
3693
+ locator.materialSlotId,
3694
+ locator.path,
3695
+ ]
3642
3696
  .filter(value => value !== undefined && value !== null && value !== '')
3643
3697
  .join(' / ');
3644
3698
  meta.textContent = [
3645
3699
  `来源: ${diagnostic.source}`,
3700
+ diagnostic.producer ? `producer: ${diagnostic.producer}` : '',
3701
+ diagnostic.phase ? `phase: ${diagnostic.phase}` : '',
3646
3702
  diagnosticLocation ? `位置: ${diagnosticLocation}` : '',
3647
3703
  diagnostic.documentRevision != null ? `document revision: ${diagnostic.documentRevision}` : '',
3648
3704
  diagnostic.projectionRevision != null ? `projection revision: ${diagnostic.projectionRevision}` : '',
@@ -3652,15 +3708,33 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
3652
3708
  meta.style.display = meta.textContent ? 'block' : 'none';
3653
3709
  content.appendChild(code);
3654
3710
  content.appendChild(message);
3711
+ content.appendChild(suggestion);
3655
3712
  content.appendChild(meta);
3713
+ const actions = doc.createElement('div');
3714
+ actions.style.cssText = 'display:flex;align-items:flex-start;gap:4px';
3715
+ if (locateAction) {
3716
+ const locateButton = doc.createElement('button');
3717
+ locateButton.type = 'button';
3718
+ locateButton.dataset.editorStatusAction = locateAction.id;
3719
+ locateButton.textContent = locateAction.label;
3720
+ locateButton.disabled = !canLocate;
3721
+ locateButton.style.cssText = 'font:inherit;font-size:10px;padding:3px 6px;border:1px solid var(--fps-editor-border);border-radius:3px;background:var(--fps-editor-surface);color:var(--fps-editor-text-strong);cursor:pointer;white-space:nowrap';
3722
+ locateButton.addEventListener('click', event => {
3723
+ event.stopPropagation();
3724
+ if (canLocate)
3725
+ locate();
3726
+ });
3727
+ actions.appendChild(locateButton);
3728
+ }
3656
3729
  const copy = createToolbarIconButton(doc, `复制诊断 ${index + 1}`, 'copy', '复制该诊断');
3657
3730
  copy.dataset.editorStatusCopy = String(index);
3658
3731
  copy.addEventListener('click', event => {
3659
3732
  event.stopPropagation();
3660
- copyTextToClipboard(doc.defaultView, copyText);
3733
+ copyEditorStatusText(copy, doc.defaultView, copyText);
3661
3734
  });
3662
3735
  item.appendChild(content);
3663
- item.appendChild(copy);
3736
+ actions.appendChild(copy);
3737
+ item.appendChild(actions);
3664
3738
  editorStatusCenterList.appendChild(item);
3665
3739
  });
3666
3740
  }
@@ -4137,7 +4211,11 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
4137
4211
  };
4138
4212
  const onEditorStatusCopyAllClick = (event) => {
4139
4213
  event.stopPropagation();
4140
- copyTextToClipboard(doc.defaultView, createLocalEditorStatusCenterViewModel(currentState).copyAllText);
4214
+ copyEditorStatusText(editorStatusCopyAllButton, doc.defaultView, createLocalEditorStatusCenterViewModel(currentState).copyAllText);
4215
+ };
4216
+ const onEditorStatusCloseClick = (event) => {
4217
+ event.stopPropagation();
4218
+ closeEditorStatusCenter();
4141
4219
  };
4142
4220
  const onToolbarOverflowPointerDown = (event) => {
4143
4221
  const target = event.target instanceof HTMLElement ? event.target : null;
@@ -4176,6 +4254,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
4176
4254
  localTestButton.addEventListener('click', onLocalTestButtonClick);
4177
4255
  editorStatusButton.addEventListener('click', onEditorStatusButtonClick);
4178
4256
  editorStatusCopyAllButton.addEventListener('click', onEditorStatusCopyAllClick);
4257
+ editorStatusCloseButton.addEventListener('click', onEditorStatusCloseClick);
4179
4258
  doc.addEventListener('pointerdown', onToolbarOverflowPointerDown);
4180
4259
  construction.addCleanup('toolbar-overflow-pointerdown', () => {
4181
4260
  doc.removeEventListener('pointerdown', onToolbarOverflowPointerDown);
@@ -4190,27 +4269,30 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
4190
4269
  enterEditorButton.addEventListener('click', () => callbacks.onEnterEditor?.());
4191
4270
  saveButton.addEventListener('click', () => {
4192
4271
  closeLocalTestMenu();
4193
- if (localTestActionsEnabled)
4272
+ if (localTestActionsEnabled) {
4273
+ editorConsole.append({ severity: 'info', source: 'save', message: '请求保存场景' });
4194
4274
  callbacks.onSaveScene?.();
4275
+ }
4195
4276
  });
4196
4277
  saveAndRunButton.addEventListener('click', () => {
4197
4278
  closeLocalTestMenu();
4198
- if (localTestActionsEnabled)
4279
+ if (localTestActionsEnabled) {
4280
+ editorConsole.append({ severity: 'info', source: 'run', message: '请求保存并运行' });
4199
4281
  callbacks.onSaveAndRunGame?.();
4282
+ }
4200
4283
  });
4201
4284
  discardRunButton.addEventListener('click', () => {
4202
4285
  closeLocalTestMenu();
4203
- if (localTestActionsEnabled)
4286
+ if (localTestActionsEnabled) {
4287
+ editorConsole.append({ severity: 'warning', source: 'run', message: '请求放弃更改并运行' });
4204
4288
  callbacks.onDiscardAndRunGame?.();
4289
+ }
4205
4290
  });
4206
4291
  undoButton.addEventListener('click', () => callbacks.onUndo?.());
4207
4292
  redoButton.addEventListener('click', () => callbacks.onRedo?.());
4208
4293
  performanceMonitorButton.addEventListener('click', () => {
4209
4294
  setPerformanceMonitorOpen(!performanceMonitorOpen);
4210
4295
  });
4211
- prefabComparisonPreviewButton.addEventListener('click', () => {
4212
- setPrefabComparisonPreviewOpen(!prefabComparisonPreviewOpen);
4213
- });
4214
4296
  gridToggleButton.addEventListener('click', () => {
4215
4297
  const visible = currentState?.grid?.visible ?? true;
4216
4298
  callbacks.onGridVisibleChange?.(!visible);
@@ -4239,37 +4321,111 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
4239
4321
  const nextMode = currentMode === 'orthographic' ? 'perspective' : 'orthographic';
4240
4322
  callbacks.onViewportProjectionModeChange?.(nextMode);
4241
4323
  if (event.type === 'click')
4242
- coordinateAxesOverlay.projectionIcon.blur();
4324
+ coordinateAxesOverlay.projectionButton.blur();
4243
4325
  };
4244
- coordinateAxesOverlay.projectionIcon.addEventListener('pointerdown', (event) => {
4326
+ coordinateAxesOverlay.projectionButton.addEventListener('pointerdown', (event) => {
4245
4327
  event.preventDefault();
4246
4328
  });
4247
- coordinateAxesOverlay.projectionIcon.addEventListener('click', toggleCoordinateAxesProjection);
4248
- coordinateAxesOverlay.projectionIcon.addEventListener('keydown', (event) => {
4329
+ coordinateAxesOverlay.projectionButton.addEventListener('click', toggleCoordinateAxesProjection);
4330
+ coordinateAxesOverlay.projectionButton.addEventListener('keydown', (event) => {
4249
4331
  if (event.key !== 'Enter' && event.key !== ' ')
4250
4332
  return;
4251
4333
  toggleCoordinateAxesProjection(event);
4252
4334
  });
4253
- viewportToolsGroup.addEventListener('click', (event) => {
4254
- const target = event.target instanceof HTMLElement ? event.target : null;
4255
- const preset = target?.closest('[data-viewport-view-preset]')?.dataset.viewportViewPreset;
4256
- if (preset) {
4257
- callbacks.onViewportViewPresetChange?.(preset);
4335
+ const activateCoordinateAxesViewPreset = (preset) => {
4336
+ const axesState = currentState?.coordinateAxes ?? null;
4337
+ if (!axesState || axesState.projectionToggleDisabled || currentState?.busy)
4258
4338
  return;
4259
- }
4260
- const projectionToggle = target?.closest('[data-viewport-projection-toggle]');
4261
- if (projectionToggle) {
4262
- const currentMode = currentState?.viewportTools?.projectionMode ?? 'perspective';
4263
- const nextMode = currentMode === 'orthographic' ? 'perspective' : 'orthographic';
4264
- callbacks.onViewportProjectionModeChange?.(nextMode);
4339
+ callbacks.onViewportViewPresetChange?.(preset);
4340
+ };
4341
+ coordinateAxesOverlay.root.addEventListener('pointerdown', (event) => {
4342
+ if (!(event.target instanceof Element))
4265
4343
  return;
4266
- }
4344
+ if (!event.target.closest('[data-coordinate-axis-direction],[data-coordinate-axes-projection-toggle],[data-coordinate-axes-view-menu]'))
4345
+ return;
4346
+ event.preventDefault();
4347
+ event.stopPropagation();
4348
+ });
4349
+ coordinateAxesOverlay.root.addEventListener('click', (event) => {
4350
+ const target = event.target instanceof Element ? event.target : null;
4351
+ const direction = target?.closest('[data-coordinate-axis-direction]');
4352
+ const preset = direction?.dataset.viewportViewPreset;
4353
+ if (!preset)
4354
+ return;
4355
+ event.preventDefault();
4356
+ event.stopPropagation();
4357
+ activateCoordinateAxesViewPreset(preset);
4358
+ });
4359
+ coordinateAxesOverlay.root.addEventListener('keydown', (event) => {
4360
+ if (event.key !== 'Enter' && event.key !== ' ')
4361
+ return;
4362
+ const target = event.target instanceof Element ? event.target : null;
4363
+ const direction = target?.closest('[data-coordinate-axis-direction]');
4364
+ const preset = direction?.dataset.viewportViewPreset;
4365
+ if (!preset)
4366
+ return;
4367
+ event.preventDefault();
4368
+ event.stopPropagation();
4369
+ activateCoordinateAxesViewPreset(preset);
4370
+ });
4371
+ coordinateAxesOverlay.viewMenuButton.addEventListener('click', (event) => {
4372
+ event.preventDefault();
4373
+ event.stopPropagation();
4374
+ const axesState = currentState?.coordinateAxes ?? null;
4375
+ if (!axesState || axesState.projectionToggleDisabled || currentState?.busy)
4376
+ return;
4377
+ const rect = coordinateAxesOverlay.viewMenuButton.getBoundingClientRect();
4378
+ const activePreset = currentState?.viewportTools?.viewPreset ?? 'perspective';
4379
+ const viewItem = (preset, label) => ({
4380
+ id: `viewport-view:${preset}`,
4381
+ label,
4382
+ ...(preset === activePreset ? { shortcut: '当前' } : {}),
4383
+ });
4384
+ contextMenu.open({
4385
+ x: rect.right,
4386
+ y: rect.bottom + 4,
4387
+ items: [
4388
+ viewItem('perspective', '透视视图'),
4389
+ viewItem('threeQuarterTop', '斜 45° 俯视'),
4390
+ viewItem('iso', '等距正交'),
4391
+ {
4392
+ id: 'viewport-view:fixed',
4393
+ label: '固定正交视图',
4394
+ separatorBefore: true,
4395
+ children: [
4396
+ viewItem('top', '顶视图 (+Y)'),
4397
+ viewItem('bottom', '底视图 (-Y)'),
4398
+ viewItem('front', '前视图 (-Z)'),
4399
+ viewItem('back', '后视图 (+Z)'),
4400
+ viewItem('left', '左视图 (-X)'),
4401
+ viewItem('right', '右视图 (+X)'),
4402
+ ],
4403
+ },
4404
+ ],
4405
+ onAction(item) {
4406
+ const presetId = item.id.startsWith('viewport-view:')
4407
+ ? item.id.slice('viewport-view:'.length)
4408
+ : null;
4409
+ if (presetId && presetId !== 'fixed') {
4410
+ activateCoordinateAxesViewPreset(presetId);
4411
+ }
4412
+ },
4413
+ });
4414
+ });
4415
+ viewportToolsGroup.addEventListener('click', (event) => {
4416
+ const target = event.target instanceof HTMLElement ? event.target : null;
4267
4417
  const markerVisibilityToggle = target?.closest('[data-viewport-marker-visibility-toggle]');
4268
4418
  if (markerVisibilityToggle) {
4269
4419
  const markersVisible = currentState?.viewportTools?.markersVisible ?? true;
4270
4420
  callbacks.onMarkerViewportVisibilityChange?.(!markersVisible);
4271
4421
  return;
4272
4422
  }
4423
+ const showAllPrefabMarkersToggle = target?.closest('[data-viewport-show-all-prefab-markers-toggle]');
4424
+ if (showAllPrefabMarkersToggle) {
4425
+ const showAllPrefabMarkers = currentState?.viewportTools?.showAllPrefabMarkers ?? false;
4426
+ callbacks.onShowAllPrefabMarkersChange?.(!showAllPrefabMarkers);
4427
+ return;
4428
+ }
4273
4429
  const overlayToggle = target?.closest('[data-viewport-overlay-settings-toggle]');
4274
4430
  if (overlayToggle) {
4275
4431
  event.stopPropagation();
@@ -4307,21 +4463,15 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
4307
4463
  if (notify)
4308
4464
  callbacks.onPerformanceMonitorOpenChange?.(performanceMonitorOpen);
4309
4465
  };
4310
- const setPrefabComparisonPreviewOpen = (open) => {
4311
- if (prefabComparisonPreviewOpen === open)
4312
- return;
4313
- if (!open)
4314
- endPrefabComparisonPreviewDrag();
4315
- prefabComparisonPreviewOpen = open;
4316
- if (currentState)
4317
- renderPreviewState(currentState);
4318
- LocalEditorShared.applyButtonActiveState(prefabComparisonPreviewButton, prefabComparisonPreviewOpen);
4319
- callbacks.onPrefabComparisonPreviewLayoutChange?.();
4466
+ const captureAssetBrowserReturnFocus = (trigger) => {
4467
+ const active = doc.activeElement instanceof HTMLElement ? doc.activeElement : null;
4468
+ return captureLocalEditorAssetBrowserReturnFocus(assetPanel, trigger ?? active);
4320
4469
  };
4321
- const openAssetPreviewModal = (asset) => {
4470
+ const openAssetPreviewModal = (asset, trigger) => {
4322
4471
  if (!asset.preview)
4323
4472
  return;
4324
4473
  contextMenu.close();
4474
+ assetPreviewReturnFocus = captureAssetBrowserReturnFocus(trigger);
4325
4475
  previewedAsset = asset;
4326
4476
  assetPreviewMode = 'preview';
4327
4477
  assetPreviewDialog.setAttribute('aria-label', '资产预览');
@@ -4330,10 +4480,11 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
4330
4480
  syncInputModalOpen();
4331
4481
  assetPreviewCloseButton.focus({ preventScroll: true });
4332
4482
  };
4333
- const openAssetMaterialEditorModal = (asset) => {
4483
+ const openAssetMaterialEditorModal = (asset, trigger) => {
4334
4484
  if (!asset.material)
4335
4485
  return;
4336
4486
  contextMenu.close();
4487
+ assetPreviewReturnFocus = captureAssetBrowserReturnFocus(trigger);
4337
4488
  previewedAsset = asset;
4338
4489
  assetPreviewMode = 'material-editor';
4339
4490
  assetPreviewDialog.setAttribute('aria-label', '编辑材质球');
@@ -4342,8 +4493,9 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
4342
4493
  syncInputModalOpen();
4343
4494
  assetPreviewCloseButton.focus({ preventScroll: true });
4344
4495
  };
4345
- const openAssetRenameModal = (asset) => {
4496
+ const openAssetRenameModal = (asset, trigger) => {
4346
4497
  contextMenu.close();
4498
+ assetPreviewReturnFocus = captureAssetBrowserReturnFocus(trigger);
4347
4499
  previewedAsset = asset;
4348
4500
  assetPreviewMode = 'rename';
4349
4501
  assetPreviewDialog.setAttribute('aria-label', '重命名资产');
@@ -4356,41 +4508,508 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
4356
4508
  input?.select();
4357
4509
  }, 0);
4358
4510
  };
4511
+ const disposeProjectModelPreview = () => {
4512
+ projectModelPreviewAbortController?.abort();
4513
+ projectModelPreviewAbortController = null;
4514
+ const cleanup = projectModelPreviewCleanup;
4515
+ projectModelPreviewCleanup = null;
4516
+ projectModelPreviewCleanupRegistry.disposeOwned(cleanup);
4517
+ const failures = projectModelPreviewCleanupRegistry.takeFailures();
4518
+ if (failures.length > 0) {
4519
+ const error = new Error('Project model preview cleanup failed after bounded retries.');
4520
+ error.errors = failures;
4521
+ throw error;
4522
+ }
4523
+ };
4524
+ const resetProjectMediaThumbnailCache = () => {
4525
+ projectMediaThumbnailGeneration += 1;
4526
+ for (const controller of projectMediaThumbnailAbortControllers)
4527
+ controller.abort();
4528
+ projectMediaThumbnailAbortControllers.clear();
4529
+ projectMediaThumbnailCache.clear();
4530
+ projectMediaThumbnailObserver?.disconnect();
4531
+ projectMediaThumbnailObserver = null;
4532
+ };
4533
+ const resolveProjectMediaThumbnail = (browserPath, cacheKey) => {
4534
+ const requestGeneration = projectMediaThumbnailGeneration;
4535
+ const relativePath = toLocalEditorProjectRelativePath(browserPath);
4536
+ const memoryKey = cacheKey || relativePath;
4537
+ const cached = projectMediaThumbnailCache.get(memoryKey);
4538
+ if (cached)
4539
+ return cached;
4540
+ const pending = Promise.resolve(callbacks.onProjectMediaResolve?.(relativePath) ?? null)
4541
+ .then(async (source) => {
4542
+ if (!source)
4543
+ return null;
4544
+ if (source.kind === 'image') {
4545
+ return { alt: source.name, kind: 'image', url: source.url };
4546
+ }
4547
+ if (source.kind !== 'model' || !callbacks.onProjectModelThumbnailResolve)
4548
+ return null;
4549
+ if (requestGeneration !== projectMediaThumbnailGeneration)
4550
+ return null;
4551
+ if (cacheKey) {
4552
+ const cachedUrl = await projectModelThumbnailCache.get(cacheKey);
4553
+ if (cachedUrl) {
4554
+ return { alt: `${source.name} 模型缩略图`, kind: 'model', url: cachedUrl };
4555
+ }
4556
+ }
4557
+ const controller = new AbortController();
4558
+ projectMediaThumbnailAbortControllers.add(controller);
4559
+ let url;
4560
+ try {
4561
+ url = await callbacks.onProjectModelThumbnailResolve(source, controller.signal);
4562
+ }
4563
+ finally {
4564
+ projectMediaThumbnailAbortControllers.delete(controller);
4565
+ }
4566
+ if (controller.signal.aborted || requestGeneration !== projectMediaThumbnailGeneration)
4567
+ return null;
4568
+ if (url && cacheKey)
4569
+ void projectModelThumbnailCache.put(cacheKey, url);
4570
+ return url ? { alt: `${source.name} 模型缩略图`, kind: 'model', url } : null;
4571
+ })
4572
+ .catch(() => null);
4573
+ projectMediaThumbnailCache.set(memoryKey, pending);
4574
+ return pending;
4575
+ };
4576
+ const hydrateProjectMediaThumbnails = () => {
4577
+ if (!callbacks.onProjectMediaResolve)
4578
+ return;
4579
+ const generation = projectMediaThumbnailGeneration;
4580
+ projectMediaThumbnailObserver?.disconnect();
4581
+ projectMediaThumbnailObserver = null;
4582
+ const hydrate = (frame) => {
4583
+ const path = frame.dataset.editorProjectMediaThumbnailPath;
4584
+ if (!path || frame.dataset.thumbnailRequested === 'true')
4585
+ return;
4586
+ const cacheKey = frame.dataset.editorProjectMediaThumbnailCacheKey;
4587
+ frame.dataset.thumbnailRequested = 'true';
4588
+ void resolveProjectMediaThumbnail(path, cacheKey).then((result) => {
4589
+ if (!frame.isConnected || generation !== projectMediaThumbnailGeneration)
4590
+ return;
4591
+ if (!result) {
4592
+ frame.dataset.thumbnailState = 'failed';
4593
+ return;
4594
+ }
4595
+ const image = doc.createElement('img');
4596
+ image.alt = result.alt;
4597
+ image.decoding = 'async';
4598
+ image.draggable = false;
4599
+ if (result.kind === 'image')
4600
+ image.loading = 'lazy';
4601
+ image.addEventListener('load', () => {
4602
+ if (frame.isConnected)
4603
+ frame.dataset.thumbnailState = 'ready';
4604
+ }, { once: true });
4605
+ image.addEventListener('error', () => {
4606
+ image.remove();
4607
+ if (frame.isConnected)
4608
+ frame.dataset.thumbnailState = 'failed';
4609
+ }, { once: true });
4610
+ image.src = result.url;
4611
+ frame.appendChild(image);
4612
+ });
4613
+ };
4614
+ const frames = assetPanel.querySelectorAll('[data-editor-project-media-thumbnail-path]');
4615
+ const Observer = doc.defaultView?.IntersectionObserver;
4616
+ if (!Observer) {
4617
+ for (const frame of frames)
4618
+ hydrate(frame);
4619
+ return;
4620
+ }
4621
+ const viewport = assetPanel.querySelector('[data-editor-asset-browser-scroll-viewport]');
4622
+ projectMediaThumbnailObserver = new Observer((entries, observer) => {
4623
+ for (const entry of entries) {
4624
+ if (!entry.isIntersecting || !(entry.target instanceof HTMLElement))
4625
+ continue;
4626
+ observer.unobserve(entry.target);
4627
+ hydrate(entry.target);
4628
+ }
4629
+ }, { root: viewport, rootMargin: '120px 0px' });
4630
+ for (const frame of frames)
4631
+ projectMediaThumbnailObserver.observe(frame);
4632
+ };
4633
+ const disposeMaterialPreview = () => {
4634
+ materialPreviewRequestId += 1;
4635
+ const cleanup = materialPreviewCleanup;
4636
+ materialPreviewCleanup = null;
4637
+ materialPreviewCleanupRegistry.disposeOwned(cleanup);
4638
+ const failures = materialPreviewCleanupRegistry.takeFailures();
4639
+ if (failures.length > 0) {
4640
+ const error = new Error('Material preview cleanup failed after bounded retries.');
4641
+ error.errors = failures;
4642
+ throw error;
4643
+ }
4644
+ };
4645
+ const createMaterialPreviewStage = (asset) => {
4646
+ const preview = asset.preview;
4647
+ if (preview?.kind !== 'material-sphere' || !callbacks.onMaterialPreviewMount) {
4648
+ return LocalEditorPanels.createAssetPreviewElement(doc, asset, 'modal');
4649
+ }
4650
+ disposeMaterialPreview();
4651
+ const requestId = materialPreviewRequestId;
4652
+ const stage = doc.createElement('div');
4653
+ stage.dataset.editorMaterialPreviewStage = 'true';
4654
+ stage.dataset.previewState = 'loading';
4655
+ stage.style.cssText = [
4656
+ 'position:relative',
4657
+ 'width:100%',
4658
+ 'aspect-ratio:16 / 10',
4659
+ 'min-height:180px',
4660
+ 'overflow:hidden',
4661
+ 'border:1px solid var(--fps-editor-border)',
4662
+ 'border-radius:4px',
4663
+ 'background:var(--fps-editor-field)',
4664
+ 'box-sizing:border-box',
4665
+ ].join(';');
4666
+ const fallback = LocalEditorPanels.createAssetPreviewElement(doc, asset, 'modal');
4667
+ fallback.dataset.editorMaterialPreviewFallback = 'true';
4668
+ fallback.style.position = 'absolute';
4669
+ fallback.style.left = '50%';
4670
+ fallback.style.top = '50%';
4671
+ fallback.style.transform = 'translate(-50%,-50%)';
4672
+ fallback.style.border = '0';
4673
+ fallback.style.background = 'transparent';
4674
+ const canvas = doc.createElement('canvas');
4675
+ canvas.dataset.editorMaterialPreviewCanvas = 'true';
4676
+ canvas.setAttribute('aria-label', `${asset.label} 材质球三维预览`);
4677
+ canvas.title = '材质球预览';
4678
+ canvas.style.cssText = [
4679
+ 'position:absolute',
4680
+ 'inset:0',
4681
+ 'display:block',
4682
+ 'width:100%',
4683
+ 'height:100%',
4684
+ 'opacity:0',
4685
+ 'cursor:grab',
4686
+ 'touch-action:none',
4687
+ 'outline:none',
4688
+ ].join(';');
4689
+ stage.append(fallback, canvas);
4690
+ const source = {
4691
+ id: asset.material?.id ?? asset.assetId ?? asset.id,
4692
+ name: asset.material?.name || asset.label,
4693
+ materialKind: asset.material?.materialKind,
4694
+ preview,
4695
+ };
4696
+ void Promise.resolve().then(() => callbacks.onMaterialPreviewMount(source, canvas)).then((cleanup) => {
4697
+ if (!assetPreviewOpen || requestId !== materialPreviewRequestId || !stage.isConnected) {
4698
+ materialPreviewCleanupRegistry.disposeOwned(cleanup);
4699
+ return undefined;
4700
+ }
4701
+ materialPreviewCleanupRegistry.own(cleanup);
4702
+ materialPreviewCleanup = cleanup;
4703
+ stage.dataset.previewState = 'ready';
4704
+ fallback.style.display = 'none';
4705
+ canvas.style.opacity = '1';
4706
+ return undefined;
4707
+ }).catch(() => {
4708
+ if (requestId !== materialPreviewRequestId || !stage.isConnected)
4709
+ return;
4710
+ stage.dataset.previewState = 'fallback';
4711
+ canvas.style.display = 'none';
4712
+ fallback.style.display = 'flex';
4713
+ });
4714
+ return stage;
4715
+ };
4716
+ const openProjectMediaPreview = async (browserPath, trigger) => {
4717
+ const relativePath = toLocalEditorProjectRelativePath(browserPath);
4718
+ if (!callbacks.onProjectMediaResolve || !isEditorProjectMediaPreviewable(relativePath))
4719
+ return;
4720
+ contextMenu.close();
4721
+ closeProjectFilePreview();
4722
+ disposeProjectModelPreview();
4723
+ assetPreviewReturnFocus = captureAssetBrowserReturnFocus(trigger);
4724
+ const requestId = ++projectMediaPreviewRequestId;
4725
+ projectMediaPreviewSource = null;
4726
+ projectMediaPreviewRequestedPath = relativePath;
4727
+ projectMediaPreviewError = '';
4728
+ previewedAsset = null;
4729
+ assetPreviewMode = 'project-media';
4730
+ assetPreviewDialog.setAttribute('aria-label', '媒体文件预览');
4731
+ assetPreviewOpen = true;
4732
+ renderAssetPreviewModal();
4733
+ syncInputModalOpen();
4734
+ try {
4735
+ const source = await callbacks.onProjectMediaResolve(relativePath);
4736
+ if (!assetPreviewOpen || assetPreviewMode !== 'project-media' || requestId !== projectMediaPreviewRequestId)
4737
+ return;
4738
+ if (!source)
4739
+ throw new Error('project_file_media_unsupported');
4740
+ projectMediaPreviewSource = source;
4741
+ renderAssetPreviewModal();
4742
+ if (source.kind === 'model') {
4743
+ const canvas = assetPreviewBody.querySelector('[data-editor-project-model-preview]');
4744
+ if (!canvas || !callbacks.onProjectModelPreviewMount)
4745
+ throw new Error('project_model_preview_unavailable');
4746
+ const controller = new AbortController();
4747
+ projectModelPreviewAbortController = controller;
4748
+ const cleanup = await callbacks.onProjectModelPreviewMount(source, canvas, controller.signal);
4749
+ if (uiDisposed
4750
+ || !assetPreviewDialog.isConnected
4751
+ || !assetPreviewOpen
4752
+ || assetPreviewMode !== 'project-media'
4753
+ || requestId !== projectMediaPreviewRequestId) {
4754
+ controller.abort();
4755
+ if (projectModelPreviewAbortController === controller)
4756
+ projectModelPreviewAbortController = null;
4757
+ projectModelPreviewCleanupRegistry.disposeOwned(cleanup);
4758
+ return;
4759
+ }
4760
+ projectModelPreviewCleanupRegistry.own(cleanup);
4761
+ projectModelPreviewCleanup = cleanup;
4762
+ }
4763
+ assetPreviewCloseButton.focus({ preventScroll: true });
4764
+ }
4765
+ catch (error) {
4766
+ if (uiDisposed
4767
+ || !assetPreviewDialog.isConnected
4768
+ || !assetPreviewOpen
4769
+ || assetPreviewMode !== 'project-media'
4770
+ || requestId !== projectMediaPreviewRequestId)
4771
+ return;
4772
+ disposeProjectModelPreview();
4773
+ projectMediaPreviewError = error instanceof Error ? error.message : String(error);
4774
+ renderAssetPreviewModal();
4775
+ assetPreviewCloseButton.focus({ preventScroll: true });
4776
+ }
4777
+ };
4359
4778
  const closeAssetPreviewModal = () => {
4360
4779
  if (!assetPreviewOpen)
4361
4780
  return;
4781
+ const returnFocus = assetPreviewReturnFocus;
4782
+ assetPreviewReturnFocus = null;
4783
+ projectMediaPreviewRequestId += 1;
4784
+ disposeProjectModelPreview();
4785
+ disposeMaterialPreview();
4362
4786
  assetPreviewOpen = false;
4363
4787
  previewedAsset = null;
4788
+ projectMediaPreviewSource = null;
4789
+ projectMediaPreviewRequestedPath = '';
4790
+ projectMediaPreviewError = '';
4364
4791
  assetPreviewMode = 'preview';
4365
4792
  renderAssetPreviewModal();
4366
4793
  syncInputModalOpen();
4794
+ restoreLocalEditorAssetBrowserReturnFocus(assetPanel, returnFocus);
4795
+ };
4796
+ const renderProjectFilePreview = () => {
4797
+ if (projectFilePreviewSearchRaf != null) {
4798
+ doc.defaultView?.cancelAnimationFrame(projectFilePreviewSearchRaf);
4799
+ projectFilePreviewSearchRaf = null;
4800
+ }
4801
+ projectFilePreviewModal.style.display = projectFilePreviewOpen ? 'flex' : 'none';
4802
+ if (!projectFilePreviewOpen)
4803
+ return;
4804
+ const content = projectFilePreviewContent;
4805
+ const displayPath = content?.path ?? projectFilePreviewRequestedPath;
4806
+ const displayPathSegments = displayPath.split('/');
4807
+ projectFilePreviewTitle.textContent = content?.name
4808
+ ?? displayPathSegments[displayPathSegments.length - 1]
4809
+ ?? '文件预览';
4810
+ projectFilePreviewPath.textContent = displayPath;
4811
+ projectFilePreviewPath.title = displayPath;
4812
+ projectFilePreviewSearch.disabled = !content;
4813
+ projectFilePreviewPrevious.disabled = projectFilePreviewMatches.length === 0;
4814
+ projectFilePreviewNext.disabled = projectFilePreviewMatches.length === 0;
4815
+ projectFilePreviewMatchCount.textContent = projectFilePreviewMatches.length > 0
4816
+ ? `${projectFilePreviewActiveMatch + 1} / ${projectFilePreviewMatches.length}`
4817
+ : projectFilePreviewSearch.value.trim() ? '0 / 0' : '0';
4818
+ projectFilePreviewMeta.textContent = projectFilePreviewError
4819
+ ? projectFilePreviewError
4820
+ : content
4821
+ ? [
4822
+ content.language,
4823
+ formatProjectFileByteSize(content.size),
4824
+ content.truncated ? '文件内容已截断' : '',
4825
+ '只读',
4826
+ ].filter(Boolean).join(' · ')
4827
+ : '正在读取文件...';
4828
+ while (projectFilePreviewCode.firstChild)
4829
+ projectFilePreviewCode.removeChild(projectFilePreviewCode.firstChild);
4830
+ if (projectFilePreviewError) {
4831
+ projectFilePreviewCode.textContent = `无法查看文件:${projectFilePreviewError}`;
4832
+ return;
4833
+ }
4834
+ if (!content) {
4835
+ projectFilePreviewCode.textContent = '正在读取文件...';
4836
+ return;
4837
+ }
4838
+ if (projectFilePreviewMatches.length === 0) {
4839
+ projectFilePreviewCode.textContent = content.text;
4840
+ return;
4841
+ }
4842
+ let cursor = 0;
4843
+ for (const [index, match] of projectFilePreviewMatches.entries()) {
4844
+ if (match.start > cursor) {
4845
+ projectFilePreviewCode.appendChild(doc.createTextNode(content.text.slice(cursor, match.start)));
4846
+ }
4847
+ const mark = doc.createElement('mark');
4848
+ mark.dataset.editorProjectFileSearchMatch = String(index);
4849
+ mark.dataset.active = index === projectFilePreviewActiveMatch ? 'true' : 'false';
4850
+ mark.textContent = content.text.slice(match.start, match.end);
4851
+ mark.style.cssText = index === projectFilePreviewActiveMatch
4852
+ ? 'background:var(--fps-editor-accent);color:var(--fps-editor-panel);outline:1px solid var(--fps-editor-accent-strong)'
4853
+ : 'background:var(--fps-editor-warn-soft);color:var(--fps-editor-text-strong);outline:1px solid var(--fps-editor-warn-border)';
4854
+ projectFilePreviewCode.appendChild(mark);
4855
+ cursor = match.end;
4856
+ }
4857
+ if (cursor < content.text.length) {
4858
+ projectFilePreviewCode.appendChild(doc.createTextNode(content.text.slice(cursor)));
4859
+ }
4860
+ const active = projectFilePreviewCode.querySelector('[data-editor-project-file-search-match][data-active="true"]');
4861
+ projectFilePreviewSearchRaf = doc.defaultView?.requestAnimationFrame(() => {
4862
+ projectFilePreviewSearchRaf = null;
4863
+ if (projectFilePreviewOpen && active?.isConnected) {
4864
+ active.scrollIntoView({ block: 'center', inline: 'nearest' });
4865
+ }
4866
+ }) ?? null;
4867
+ };
4868
+ const updateProjectFilePreviewSearch = (resetActive) => {
4869
+ projectFilePreviewMatches = projectFilePreviewContent
4870
+ ? findLocalEditorProjectFileSearchMatches(projectFilePreviewContent.text, projectFilePreviewSearch.value)
4871
+ : [];
4872
+ if (resetActive)
4873
+ projectFilePreviewActiveMatch = projectFilePreviewMatches.length > 0 ? 0 : -1;
4874
+ else if (projectFilePreviewMatches.length === 0)
4875
+ projectFilePreviewActiveMatch = -1;
4876
+ else
4877
+ projectFilePreviewActiveMatch = Math.min(Math.max(0, projectFilePreviewActiveMatch), projectFilePreviewMatches.length - 1);
4878
+ renderProjectFilePreview();
4879
+ };
4880
+ const moveProjectFilePreviewMatch = (delta) => {
4881
+ if (projectFilePreviewMatches.length === 0)
4882
+ return;
4883
+ projectFilePreviewActiveMatch = (projectFilePreviewActiveMatch + delta + projectFilePreviewMatches.length) % projectFilePreviewMatches.length;
4884
+ renderProjectFilePreview();
4885
+ };
4886
+ const closeProjectFilePreview = () => {
4887
+ if (!projectFilePreviewOpen)
4888
+ return;
4889
+ if (projectFilePreviewSearchRaf != null) {
4890
+ doc.defaultView?.cancelAnimationFrame(projectFilePreviewSearchRaf);
4891
+ projectFilePreviewSearchRaf = null;
4892
+ }
4893
+ const returnFocus = projectFilePreviewReturnFocus;
4894
+ projectFilePreviewReturnFocus = null;
4895
+ projectFilePreviewRequestId += 1;
4896
+ projectFilePreviewOpen = false;
4897
+ projectFilePreviewContent = null;
4898
+ projectFilePreviewRequestedPath = '';
4899
+ projectFilePreviewError = '';
4900
+ projectFilePreviewMatches = [];
4901
+ projectFilePreviewActiveMatch = -1;
4902
+ projectFilePreviewSearch.value = '';
4903
+ renderProjectFilePreview();
4904
+ syncInputModalOpen();
4905
+ restoreLocalEditorAssetBrowserReturnFocus(assetPanel, returnFocus);
4906
+ };
4907
+ const openProjectFilePreview = async (browserPath, trigger) => {
4908
+ const relativePath = toLocalEditorProjectRelativePath(browserPath);
4909
+ if (!callbacks.onProjectFileRead || !isEditorProjectFilePreviewable(relativePath))
4910
+ return;
4911
+ contextMenu.close();
4912
+ if (assetPreviewOpen)
4913
+ closeAssetPreviewModal();
4914
+ projectFilePreviewReturnFocus = captureAssetBrowserReturnFocus(trigger);
4915
+ const requestId = ++projectFilePreviewRequestId;
4916
+ projectFilePreviewOpen = true;
4917
+ projectFilePreviewContent = null;
4918
+ projectFilePreviewRequestedPath = relativePath;
4919
+ projectFilePreviewError = '';
4920
+ projectFilePreviewMatches = [];
4921
+ projectFilePreviewActiveMatch = -1;
4922
+ projectFilePreviewSearch.value = '';
4923
+ renderProjectFilePreview();
4924
+ syncInputModalOpen();
4925
+ try {
4926
+ const content = await callbacks.onProjectFileRead(relativePath);
4927
+ if (!projectFilePreviewOpen || requestId !== projectFilePreviewRequestId)
4928
+ return;
4929
+ projectFilePreviewContent = content;
4930
+ updateProjectFilePreviewSearch(true);
4931
+ projectFilePreviewSearch.focus({ preventScroll: true });
4932
+ }
4933
+ catch (error) {
4934
+ if (!projectFilePreviewOpen || requestId !== projectFilePreviewRequestId)
4935
+ return;
4936
+ projectFilePreviewError = error instanceof Error ? error.message : String(error);
4937
+ renderProjectFilePreview();
4938
+ projectFilePreviewCloseButton.focus({ preventScroll: true });
4939
+ }
4940
+ };
4941
+ const openProjectBrowserFile = (browserPath, trigger) => {
4942
+ const relativePath = toLocalEditorProjectRelativePath(browserPath);
4943
+ const action = resolveLocalEditorProjectFileOpenAction(relativePath, {
4944
+ mediaPreview: !!callbacks.onProjectMediaResolve,
4945
+ textPreview: !!callbacks.onProjectFileRead,
4946
+ });
4947
+ if (action === 'media-preview') {
4948
+ void openProjectMediaPreview(browserPath, trigger);
4949
+ return true;
4950
+ }
4951
+ if (action === 'text-preview') {
4952
+ void openProjectFilePreview(browserPath, trigger);
4953
+ return true;
4954
+ }
4955
+ return false;
4367
4956
  };
4368
4957
  const openInspectorAssetPicker = (input, property) => {
4369
4958
  contextMenu.close();
4370
4959
  if (helpOpen)
4371
4960
  setShortcutHelpOpen(false);
4961
+ settleHierarchyOperationInputRequest(null);
4372
4962
  assetPickerInput = input;
4373
4963
  assetPickerProperty = property;
4374
4964
  assetPickerFilter = '';
4375
4965
  assetPickerOpen = true;
4376
4966
  closeAssetPreviewModal();
4967
+ closeProjectFilePreview();
4968
+ renderAssetPickerModal();
4969
+ syncInputModalOpen();
4970
+ assetPickerSearch.focus({ preventScroll: true });
4971
+ assetPickerSearch.select();
4972
+ };
4973
+ const requestHierarchyOperationInput = (operation, context) => {
4974
+ if (!operation.inputPresentation || currentState?.mode !== 'editor' || currentState.busy) {
4975
+ return Promise.resolve(null);
4976
+ }
4977
+ contextMenu.close();
4978
+ if (helpOpen)
4979
+ setShortcutHelpOpen(false);
4980
+ assetPickerInput = null;
4981
+ assetPickerProperty = null;
4982
+ settleHierarchyOperationInputRequest(null);
4983
+ assetPickerFilter = '';
4984
+ assetPickerOpen = true;
4985
+ closeAssetPreviewModal();
4377
4986
  renderAssetPickerModal();
4378
4987
  syncInputModalOpen();
4379
4988
  assetPickerSearch.focus({ preventScroll: true });
4380
4989
  assetPickerSearch.select();
4990
+ return new Promise(resolve => {
4991
+ hierarchyOperationInputRequest = { operation, context, resolve };
4992
+ renderAssetPickerModal();
4993
+ });
4381
4994
  };
4995
+ function settleHierarchyOperationInputRequest(value) {
4996
+ const request = hierarchyOperationInputRequest;
4997
+ hierarchyOperationInputRequest = null;
4998
+ request?.resolve(value);
4999
+ }
4382
5000
  const closeInspectorAssetPicker = () => {
4383
5001
  if (!assetPickerOpen)
4384
5002
  return;
4385
5003
  assetPickerOpen = false;
4386
5004
  assetPickerInput = null;
4387
5005
  assetPickerProperty = null;
5006
+ settleHierarchyOperationInputRequest(null);
4388
5007
  assetPickerFilter = '';
4389
5008
  renderAssetPickerModal();
4390
5009
  syncInputModalOpen();
4391
5010
  };
4392
5011
  function syncInputModalOpen() {
4393
- inputRouter.setModalOpen(currentState?.mode === 'editor' && (helpOpen || assetPreviewOpen || assetPickerOpen));
5012
+ inputRouter.setModalOpen(currentState?.mode === 'editor' && (helpOpen || assetPreviewOpen || projectFilePreviewOpen || assetPickerOpen));
4394
5013
  }
4395
5014
  function resolvePreviewedAssetFromState() {
4396
5015
  if (!previewedAsset)
@@ -4403,11 +5022,17 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
4403
5022
  return previewedAsset;
4404
5023
  }
4405
5024
  function renderAssetPreviewModal() {
5025
+ if (assetPreviewMode === 'project-media') {
5026
+ disposeMaterialPreview();
5027
+ renderProjectMediaPreviewModal();
5028
+ return;
5029
+ }
4406
5030
  const asset = resolvePreviewedAssetFromState();
4407
5031
  if (!assetPreviewOpen
4408
5032
  || !asset
4409
5033
  || (assetPreviewMode === 'preview' && !asset.preview)
4410
5034
  || (assetPreviewMode === 'material-editor' && !asset.material)) {
5035
+ disposeMaterialPreview();
4411
5036
  assetPreviewModal.style.display = 'none';
4412
5037
  assetPreviewTitle.textContent = '';
4413
5038
  assetPreviewMeta.textContent = '';
@@ -4421,6 +5046,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
4421
5046
  return;
4422
5047
  }
4423
5048
  if (assetPreviewMode === 'rename') {
5049
+ disposeMaterialPreview();
4424
5050
  renderAssetRenameModal(asset);
4425
5051
  assetPreviewModal.style.display = 'flex';
4426
5052
  return;
@@ -4442,8 +5068,81 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
4442
5068
  ].filter(Boolean).join(' · ');
4443
5069
  while (assetPreviewBody.firstChild)
4444
5070
  assetPreviewBody.removeChild(assetPreviewBody.firstChild);
4445
- assetPreviewBody.appendChild(LocalEditorPanels.createAssetPreviewElement(doc, asset, 'modal'));
5071
+ assetPreviewBody.appendChild(createMaterialPreviewStage(asset));
5072
+ assetPreviewModal.style.display = 'flex';
5073
+ }
5074
+ function renderProjectMediaPreviewModal() {
5075
+ if (!assetPreviewOpen) {
5076
+ assetPreviewModal.style.display = 'none';
5077
+ while (assetPreviewBody.firstChild)
5078
+ assetPreviewBody.removeChild(assetPreviewBody.firstChild);
5079
+ delete assetPreviewBody.dataset.editorProjectMediaPath;
5080
+ return;
5081
+ }
5082
+ const source = projectMediaPreviewSource;
5083
+ const path = source?.path ?? projectMediaPreviewRequestedPath;
5084
+ assetPreviewDialog.style.width = 'min(760px,calc(100vw - 64px))';
5085
+ const pathSegments = path.split('/');
5086
+ assetPreviewTitle.textContent = source?.name ?? pathSegments[pathSegments.length - 1] ?? '媒体预览';
5087
+ assetPreviewMeta.textContent = projectMediaPreviewError
5088
+ ? `无法预览:${projectMediaPreviewError}`
5089
+ : source
5090
+ ? [source.kind, source.extension.toUpperCase(), source.path, '只读'].join(' · ')
5091
+ : '正在准备预览...';
5092
+ assetPreviewBody.style.cssText = [
5093
+ 'display:flex',
5094
+ 'align-items:center',
5095
+ 'justify-content:center',
5096
+ 'min-height:360px',
5097
+ 'max-height:min(620px,calc(100vh - 170px))',
5098
+ 'overflow:hidden',
5099
+ 'border:1px solid var(--fps-editor-divider)',
5100
+ 'border-radius:4px',
5101
+ 'background:var(--fps-editor-field)',
5102
+ ].join(';');
4446
5103
  assetPreviewModal.style.display = 'flex';
5104
+ const previewKey = projectMediaPreviewError ? `error:${path}:${projectMediaPreviewError}` : source?.url ?? `loading:${path}`;
5105
+ if (assetPreviewBody.dataset.editorProjectMediaPath === previewKey && assetPreviewBody.firstChild)
5106
+ return;
5107
+ while (assetPreviewBody.firstChild)
5108
+ assetPreviewBody.removeChild(assetPreviewBody.firstChild);
5109
+ assetPreviewBody.dataset.editorProjectMediaPath = previewKey;
5110
+ if (projectMediaPreviewError) {
5111
+ const error = doc.createElement('div');
5112
+ error.style.cssText = 'padding:24px;color:var(--fps-editor-danger);font-size:12px;text-align:center';
5113
+ error.textContent = projectMediaPreviewError;
5114
+ assetPreviewBody.appendChild(error);
5115
+ return;
5116
+ }
5117
+ if (!source) {
5118
+ const loading = doc.createElement('div');
5119
+ loading.style.cssText = 'color:var(--fps-editor-muted);font-size:12px';
5120
+ loading.textContent = '正在准备预览...';
5121
+ assetPreviewBody.appendChild(loading);
5122
+ return;
5123
+ }
5124
+ if (source.kind === 'image') {
5125
+ const image = doc.createElement('img');
5126
+ image.src = source.url;
5127
+ image.alt = source.name;
5128
+ image.style.cssText = 'display:block;width:100%;height:100%;max-height:min(620px,calc(100vh - 170px));object-fit:contain';
5129
+ assetPreviewBody.appendChild(image);
5130
+ return;
5131
+ }
5132
+ if (source.kind === 'audio') {
5133
+ const audio = doc.createElement('audio');
5134
+ audio.controls = true;
5135
+ audio.preload = 'metadata';
5136
+ audio.src = source.url;
5137
+ audio.style.cssText = 'width:min(560px,calc(100% - 32px))';
5138
+ assetPreviewBody.appendChild(audio);
5139
+ return;
5140
+ }
5141
+ const canvas = doc.createElement('canvas');
5142
+ canvas.dataset.editorProjectModelPreview = 'true';
5143
+ canvas.setAttribute('aria-label', `${source.name} 三维模型预览`);
5144
+ canvas.style.cssText = 'display:block;width:100%;height:min(560px,calc(100vh - 190px));min-height:360px;touch-action:none;outline:none';
5145
+ assetPreviewBody.appendChild(canvas);
4447
5146
  }
4448
5147
  function renderAssetRenameModal(asset) {
4449
5148
  assetPreviewDialog.style.width = 'min(420px,calc(100vw - 64px))';
@@ -4495,7 +5194,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
4495
5194
  const emission = profile.emission ?? {};
4496
5195
  const readonly = material.readonly === true;
4497
5196
  const materialKind = material.materialKind === 'standard' ? 'standard' : 'pbr';
4498
- assetPreviewDialog.style.width = 'min(780px,calc(100vw - 64px))';
5197
+ assetPreviewDialog.style.width = 'min(840px,calc(100vw - 64px))';
4499
5198
  assetPreviewTitle.textContent = '编辑材质球';
4500
5199
  assetPreviewMeta.textContent = [
4501
5200
  material.name || asset.label,
@@ -4508,7 +5207,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
4508
5207
  assetPreviewBody.removeChild(assetPreviewBody.firstChild);
4509
5208
  assetPreviewBody.style.cssText = [
4510
5209
  'display:grid',
4511
- 'grid-template-columns:minmax(180px,250px) minmax(0,1fr)',
5210
+ 'grid-template-columns:repeat(auto-fit,minmax(min(280px,100%),1fr))',
4512
5211
  'gap:14px',
4513
5212
  'align-items:start',
4514
5213
  'min-height:360px',
@@ -4520,7 +5219,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
4520
5219
  ].join(';');
4521
5220
  const previewColumn = doc.createElement('div');
4522
5221
  previewColumn.style.cssText = 'display:flex;flex-direction:column;gap:10px;min-width:0';
4523
- previewColumn.appendChild(LocalEditorPanels.createAssetPreviewElement(doc, asset, 'modal'));
5222
+ previewColumn.appendChild(createMaterialPreviewStage(asset));
4524
5223
  const previewMeta = doc.createElement('div');
4525
5224
  previewMeta.textContent = readonly
4526
5225
  ? '系统默认材质不可编辑。'
@@ -4784,15 +5483,33 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
4784
5483
  });
4785
5484
  }
4786
5485
  function renderAssetPickerModal() {
4787
- if (!assetPickerOpen || !assetPickerProperty || !assetPickerInput) {
5486
+ if (!assetPickerOpen || (!hierarchyOperationInputRequest && (!assetPickerProperty || !assetPickerInput))) {
4788
5487
  assetPickerModal.style.display = 'none';
5488
+ delete assetPickerModal.dataset.editorAssetPickerMode;
4789
5489
  assetPickerTitle.textContent = '';
4790
5490
  assetPickerSearch.value = '';
4791
5491
  while (assetPickerList.firstChild)
4792
5492
  assetPickerList.removeChild(assetPickerList.firstChild);
4793
5493
  return;
4794
5494
  }
4795
- const options = readInspectorAssetPickerOptions(assetPickerProperty);
5495
+ const operationInput = hierarchyOperationInputRequest?.operation.inputPresentation;
5496
+ const options = operationInput
5497
+ ? {
5498
+ title: operationInput.title,
5499
+ candidates: (currentState?.assets ?? [])
5500
+ .filter(asset => (operationInput.assetKinds.includes(resolveLocalEditorBrowserAssetKind(asset))
5501
+ && asset.placeable !== false
5502
+ && asset.disabled !== true))
5503
+ .map(asset => ({
5504
+ label: asset.label,
5505
+ value: asset.assetId ?? asset.id,
5506
+ meta: asset.meta ?? asset.assetId ?? asset.id,
5507
+ kind: asset.kind ?? resolveLocalEditorBrowserAssetKind(asset),
5508
+ preview: asset.preview,
5509
+ })),
5510
+ }
5511
+ : readInspectorAssetPickerOptions(assetPickerProperty);
5512
+ assetPickerModal.dataset.editorAssetPickerMode = operationInput ? 'hierarchy-operation' : 'inspector';
4796
5513
  assetPickerTitle.textContent = options.title;
4797
5514
  assetPickerSearch.value = assetPickerFilter;
4798
5515
  while (assetPickerList.firstChild)
@@ -4811,7 +5528,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
4811
5528
  assetPickerList.appendChild(empty);
4812
5529
  }
4813
5530
  for (const candidate of candidates) {
4814
- assetPickerList.appendChild(createInspectorAssetPickerCandidateButton(candidate, assetPickerInput.value));
5531
+ assetPickerList.appendChild(createInspectorAssetPickerCandidateButton(candidate, assetPickerInput?.value ?? ''));
4815
5532
  }
4816
5533
  assetPickerModal.style.display = 'flex';
4817
5534
  }
@@ -4855,8 +5572,13 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
4855
5572
  sceneHelpButton.addEventListener('click', () => {
4856
5573
  setShortcutHelpOpen(!helpOpen);
4857
5574
  });
4858
- prefabStageBackButton.addEventListener('click', () => {
4859
- callbacks.onExitPrefabStage?.();
5575
+ contextActionGroup.addEventListener('click', (event) => {
5576
+ const button = event.target instanceof Element
5577
+ ? event.target.closest('[data-editor-context-action]')
5578
+ : null;
5579
+ if (!button || button.disabled)
5580
+ return;
5581
+ callbacks.onContextAction?.(button.dataset.editorContextAction ?? '');
4860
5582
  });
4861
5583
  themeToggleButton.addEventListener('click', () => {
4862
5584
  setActiveTheme(activeTheme === 'dark' ? 'light' : 'dark');
@@ -4876,6 +5598,32 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
4876
5598
  if (target === assetPreviewModal)
4877
5599
  closeAssetPreviewModal();
4878
5600
  });
5601
+ projectFilePreviewModal.addEventListener('click', (event) => {
5602
+ const target = event.target instanceof HTMLElement ? event.target : null;
5603
+ if (target?.closest('[data-editor-project-file-preview-close]')) {
5604
+ closeProjectFilePreview();
5605
+ return;
5606
+ }
5607
+ if (target?.closest('[data-editor-project-file-search-previous]')) {
5608
+ moveProjectFilePreviewMatch(-1);
5609
+ return;
5610
+ }
5611
+ if (target?.closest('[data-editor-project-file-search-next]')) {
5612
+ moveProjectFilePreviewMatch(1);
5613
+ return;
5614
+ }
5615
+ if (target === projectFilePreviewModal)
5616
+ closeProjectFilePreview();
5617
+ });
5618
+ projectFilePreviewSearch.addEventListener('input', () => {
5619
+ updateProjectFilePreviewSearch(true);
5620
+ });
5621
+ projectFilePreviewSearch.addEventListener('keydown', (event) => {
5622
+ if (event.key !== 'Enter')
5623
+ return;
5624
+ event.preventDefault();
5625
+ moveProjectFilePreviewMatch(event.shiftKey ? -1 : 1);
5626
+ });
4879
5627
  assetPreviewBody.addEventListener('change', (event) => {
4880
5628
  const target = event.target instanceof HTMLElement ? event.target : null;
4881
5629
  if (assetPreviewMode !== 'material-editor')
@@ -4910,6 +5658,18 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
4910
5658
  return;
4911
5659
  }
4912
5660
  const candidateButton = target?.closest('[data-editor-asset-picker-candidate]');
5661
+ if (candidateButton && hierarchyOperationInputRequest?.operation.inputPresentation) {
5662
+ const value = candidateButton.dataset.editorAssetPickerCandidate ?? '';
5663
+ const presentation = hierarchyOperationInputRequest.operation.inputPresentation;
5664
+ const asset = currentState?.assets.find(candidate => (candidate.assetId ?? candidate.id) === value);
5665
+ if (asset)
5666
+ callbacks.onSelectAsset?.(asset.id);
5667
+ settleHierarchyOperationInputRequest(Object.freeze({
5668
+ [presentation.field]: presentation.multiple ? Object.freeze([value]) : value,
5669
+ }));
5670
+ closeInspectorAssetPicker();
5671
+ return;
5672
+ }
4913
5673
  if (candidateButton && assetPickerInput) {
4914
5674
  assetPickerInput.value = candidateButton.dataset.editorAssetPickerCandidate ?? '';
4915
5675
  assetPickerInput.dispatchEvent(new Event('change', { bubbles: true }));
@@ -4925,9 +5685,9 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
4925
5685
  });
4926
5686
  toolGroup.addEventListener('click', (event) => {
4927
5687
  const target = event.target instanceof HTMLElement ? event.target : null;
4928
- const tool = target?.closest('[data-transform-tool]')?.dataset.transformTool;
4929
- if (tool)
4930
- callbacks.onTransformToolChange?.(tool);
5688
+ const toolId = target?.closest('[data-editor-tool-id]')?.dataset.editorToolId;
5689
+ if (toolId)
5690
+ callbacks.onToolActivate?.(toolId);
4931
5691
  });
4932
5692
  spaceGroup.addEventListener('click', (event) => {
4933
5693
  const target = event.target instanceof HTMLElement ? event.target : null;
@@ -5014,8 +5774,47 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5014
5774
  if (button.dataset.editorAssetId !== assetId)
5015
5775
  continue;
5016
5776
  assetBrowserViewportReveal.revealElement(button);
5777
+ return true;
5778
+ }
5779
+ return false;
5780
+ }
5781
+ function revealPendingStatusDiagnosticPath(state) {
5782
+ const request = pendingStatusDiagnosticRequest;
5783
+ const path = request?.path;
5784
+ if (!request?.settled || !path || panelRegistry.getRightDockTab() !== 'inspector')
5785
+ return;
5786
+ const hierarchySnapshot = hierarchyKernel.getViewModel()?.snapshot;
5787
+ const current = (!path.scopeId || path.scopeId === hierarchySnapshot?.scopeKey)
5788
+ && (path.documentRevision == null || path.documentRevision === state.documentRevision)
5789
+ && (path.projectionRevision == null || path.projectionRevision === hierarchySnapshot?.revision);
5790
+ const target = [...inspectorPanel.querySelectorAll('[data-serialized-path]')]
5791
+ .find(element => current && element.dataset.serializedPath === path.value);
5792
+ delete request.path;
5793
+ if (!target) {
5794
+ clearCompletedStatusDiagnosticRequest(request);
5017
5795
  return;
5018
5796
  }
5797
+ target.closest('details')?.setAttribute('open', '');
5798
+ target.scrollIntoView({ block: 'center', inline: 'nearest' });
5799
+ const focusTarget = target.matches('input,select,textarea,button,[tabindex]')
5800
+ ? target
5801
+ : target.querySelector('input,select,textarea,button,[tabindex]');
5802
+ focusTarget?.focus({ preventScroll: true });
5803
+ clearCompletedStatusDiagnosticRequest(request);
5804
+ }
5805
+ function revealPendingStatusDiagnosticAsset(state) {
5806
+ const request = pendingStatusDiagnosticRequest;
5807
+ if (!request?.settled || !request.assetId || panelRegistry.getBottomDockTab() !== 'assets')
5808
+ return;
5809
+ const revealId = state.selectedAssetId ?? request.assetId;
5810
+ revealSelectedAssetBrowserItem(revealId);
5811
+ delete request.assetId;
5812
+ clearCompletedStatusDiagnosticRequest(request);
5813
+ }
5814
+ function clearCompletedStatusDiagnosticRequest(request) {
5815
+ if (pendingStatusDiagnosticRequest === request && !request.path && !request.assetId) {
5816
+ pendingStatusDiagnosticRequest = null;
5817
+ }
5019
5818
  }
5020
5819
  function createCurrentAssetBrowserActionContext() {
5021
5820
  const stage = currentState?.prefabStage;
@@ -5029,8 +5828,21 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5029
5828
  : {}),
5030
5829
  };
5031
5830
  }
5831
+ function navigateAssetBrowserFolder(folderPath) {
5832
+ assetBrowserFolderPath = folderPath;
5833
+ expandAssetBrowserFolderPath(folderPath);
5834
+ selectedProjectEntryPath = null;
5835
+ if (currentState)
5836
+ render(currentState);
5837
+ }
5838
+ function selectProjectBrowserEntry(path, button) {
5839
+ selectedProjectEntryPath = path;
5840
+ for (const candidate of assetPanel.querySelectorAll('[data-editor-project-directory-path],[data-editor-project-file-path]')) {
5841
+ candidate.setAttribute('aria-selected', candidate === button ? 'true' : 'false');
5842
+ }
5843
+ }
5032
5844
  assetPanel.addEventListener('click', (event) => {
5033
- const target = event.target instanceof HTMLElement ? event.target : null;
5845
+ const target = event.target instanceof Element ? event.target : null;
5034
5846
  const tabButton = target?.closest('[data-editor-dock-tab]');
5035
5847
  const tab = tabButton?.dataset.editorDockTab;
5036
5848
  if (tab === 'assets' || tab === 'history') {
@@ -5039,6 +5851,61 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5039
5851
  render(currentState);
5040
5852
  return;
5041
5853
  }
5854
+ const clearAssetFilterButton = target?.closest('[data-editor-asset-filter-clear]');
5855
+ if (clearAssetFilterButton) {
5856
+ callbacks.onAssetFilterChange?.('');
5857
+ return;
5858
+ }
5859
+ const refreshAssetBrowserButton = target?.closest('[data-editor-asset-browser-refresh]');
5860
+ if (refreshAssetBrowserButton) {
5861
+ resetProjectMediaThumbnailCache();
5862
+ void projectModelThumbnailCache.clearPathEntries()
5863
+ .catch((error) => {
5864
+ console.error('[fps-editor:asset-browser] thumbnail cache refresh cleanup failed', error);
5865
+ })
5866
+ .finally(() => callbacks.onAssetBrowserRefresh?.());
5867
+ return;
5868
+ }
5869
+ const assetFolderToggle = target?.closest('[data-editor-asset-folder-toggle]');
5870
+ const toggledFolderPath = assetFolderToggle?.dataset.editorAssetFolderToggle;
5871
+ if (toggledFolderPath) {
5872
+ if (assetBrowserExpandedFolderPaths.has(toggledFolderPath)) {
5873
+ assetBrowserExpandedFolderPaths.delete(toggledFolderPath);
5874
+ }
5875
+ else {
5876
+ assetBrowserExpandedFolderPaths.add(toggledFolderPath);
5877
+ }
5878
+ if (currentState)
5879
+ render(currentState);
5880
+ return;
5881
+ }
5882
+ const assetFolderButton = target?.closest('[data-editor-asset-folder-path]');
5883
+ if (assetFolderButton?.dataset.editorAssetFolderPath) {
5884
+ const treeFolderPath = assetFolderButton.dataset.editorAssetFolderTreePath;
5885
+ if (treeFolderPath) {
5886
+ assetBrowserFolderPath = treeFolderPath;
5887
+ selectedProjectEntryPath = null;
5888
+ if (assetBrowserExpandedFolderPaths.has(treeFolderPath)) {
5889
+ assetBrowserExpandedFolderPaths.delete(treeFolderPath);
5890
+ }
5891
+ else {
5892
+ assetBrowserExpandedFolderPaths.add(treeFolderPath);
5893
+ }
5894
+ if (currentState)
5895
+ render(currentState);
5896
+ return;
5897
+ }
5898
+ navigateAssetBrowserFolder(assetFolderButton.dataset.editorAssetFolderPath);
5899
+ return;
5900
+ }
5901
+ const assetViewButton = target?.closest('[data-editor-asset-view-mode]');
5902
+ const nextAssetViewMode = assetViewButton?.dataset.editorAssetViewMode;
5903
+ if (nextAssetViewMode === 'grid' || nextAssetViewMode === 'list') {
5904
+ assetBrowserViewMode = nextAssetViewMode;
5905
+ if (currentState)
5906
+ render(currentState);
5907
+ return;
5908
+ }
5042
5909
  const assetBrowserTabButton = target?.closest('[data-editor-asset-browser-tab]');
5043
5910
  const nextAssetBrowserTab = assetBrowserTabButton?.dataset.editorAssetBrowserTab;
5044
5911
  if (isLocalEditorAssetBrowserTab(nextAssetBrowserTab)) {
@@ -5055,28 +5922,107 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5055
5922
  });
5056
5923
  return;
5057
5924
  }
5925
+ const addToPrefabButton = target?.closest('[data-editor-asset-add-to-prefab]');
5926
+ const addToPrefabAssetId = addToPrefabButton?.dataset.editorAssetAddToPrefab;
5927
+ if (addToPrefabAssetId && currentState) {
5928
+ const asset = currentState.assets.find(candidate => candidate.id === addToPrefabAssetId);
5929
+ if (asset && LocalEditorPanels.shouldShowPrefabModelAddAction(currentState, asset)) {
5930
+ event.preventDefault();
5931
+ event.stopPropagation();
5932
+ callbacks.onSelectAsset?.(asset.id);
5933
+ callbacks.onAssetAction?.(createAssetBrowserActionInput('asset.add-to-current-prefab', asset, createCurrentAssetBrowserActionContext()));
5934
+ }
5935
+ return;
5936
+ }
5058
5937
  const assetButton = target?.closest('[data-editor-asset-id]');
5059
5938
  if (assetButton?.dataset.editorAssetId) {
5939
+ selectedProjectEntryPath = null;
5060
5940
  suppressAssetBrowserRevealIfVisible(assetButton);
5061
5941
  callbacks.onSelectAsset?.(assetButton.dataset.editorAssetId);
5062
5942
  return;
5063
5943
  }
5944
+ const projectDirectoryButton = target?.closest('[data-editor-project-directory-path]');
5945
+ if (projectDirectoryButton?.dataset.editorProjectDirectoryPath) {
5946
+ selectProjectBrowserEntry(projectDirectoryButton.dataset.editorProjectDirectoryPath, projectDirectoryButton);
5947
+ return;
5948
+ }
5949
+ const projectFileButton = target?.closest('[data-editor-project-file-path]');
5950
+ if (projectFileButton?.dataset.editorProjectFilePath) {
5951
+ selectProjectBrowserEntry(projectFileButton.dataset.editorProjectFilePath, projectFileButton);
5952
+ return;
5953
+ }
5064
5954
  });
5065
5955
  assetPanel.addEventListener('dblclick', (event) => {
5066
- const target = event.target instanceof HTMLElement ? event.target : null;
5956
+ const target = event.target instanceof Element ? event.target : null;
5957
+ const projectDirectoryButton = target?.closest('[data-editor-project-directory-path]');
5958
+ const projectDirectoryPath = projectDirectoryButton?.dataset.editorProjectDirectoryPath;
5959
+ if (projectDirectoryPath) {
5960
+ event.preventDefault();
5961
+ event.stopPropagation();
5962
+ navigateAssetBrowserFolder(projectDirectoryPath);
5963
+ return;
5964
+ }
5067
5965
  const assetButton = target?.closest('[data-editor-asset-id]');
5068
5966
  const browserAssetId = assetButton?.dataset.editorAssetId;
5069
- if (!browserAssetId || !currentState)
5967
+ const projectFileButton = target?.closest('[data-editor-project-file-path]');
5968
+ const browserProjectFilePath = projectFileButton?.dataset.editorProjectFilePath;
5969
+ if (!currentState)
5070
5970
  return;
5071
- const asset = currentState.assets.find(candidate => candidate.id === browserAssetId);
5971
+ const asset = browserAssetId
5972
+ ? currentState.assets.find(candidate => candidate.id === browserAssetId)
5973
+ : undefined;
5072
5974
  const actionId = asset ? resolveAssetBrowserDoubleClickAction(currentState, asset) : null;
5073
- if (!asset || !actionId)
5975
+ if (asset && actionId && browserAssetId) {
5976
+ event.preventDefault();
5977
+ event.stopPropagation();
5978
+ suppressAssetBrowserRevealIfVisible(assetButton);
5979
+ callbacks.onSelectAsset?.(browserAssetId);
5980
+ callbacks.onAssetAction?.(createAssetBrowserActionInput(actionId, asset, createCurrentAssetBrowserActionContext()));
5981
+ return;
5982
+ }
5983
+ if (browserProjectFilePath && openProjectBrowserFile(browserProjectFilePath, projectFileButton)) {
5984
+ event.preventDefault();
5985
+ event.stopPropagation();
5986
+ }
5987
+ });
5988
+ assetPanel.addEventListener('keydown', (event) => {
5989
+ if (event.key !== 'Enter')
5990
+ return;
5991
+ const target = event.target instanceof Element ? event.target : null;
5992
+ const projectDirectoryButton = target?.closest('[data-editor-project-directory-path]');
5993
+ const projectDirectoryPath = projectDirectoryButton?.dataset.editorProjectDirectoryPath;
5994
+ if (projectDirectoryPath) {
5995
+ event.preventDefault();
5996
+ navigateAssetBrowserFolder(projectDirectoryPath);
5997
+ return;
5998
+ }
5999
+ const assetButton = target?.closest('[data-editor-asset-id]');
6000
+ const browserAssetId = assetButton?.dataset.editorAssetId;
6001
+ const asset = browserAssetId
6002
+ ? currentState?.assets.find(candidate => candidate.id === browserAssetId)
6003
+ : undefined;
6004
+ const assetActionId = asset && currentState
6005
+ ? resolveAssetBrowserDoubleClickAction(currentState, asset)
6006
+ : null;
6007
+ if (asset && browserAssetId && assetActionId) {
6008
+ event.preventDefault();
6009
+ suppressAssetBrowserRevealIfVisible(assetButton);
6010
+ callbacks.onSelectAsset?.(browserAssetId);
6011
+ callbacks.onAssetAction?.(createAssetBrowserActionInput(assetActionId, asset, createCurrentAssetBrowserActionContext()));
6012
+ return;
6013
+ }
6014
+ const projectFileButton = target?.closest('[data-editor-project-file-path]');
6015
+ const projectFilePath = projectFileButton?.dataset.editorProjectFilePath;
6016
+ if (projectFilePath && openProjectBrowserFile(projectFilePath, projectFileButton)) {
6017
+ event.preventDefault();
6018
+ return;
6019
+ }
6020
+ const treeFolderButton = target?.closest('[data-editor-asset-folder-tree-path]');
6021
+ const treeFolderPath = treeFolderButton?.dataset.editorAssetFolderTreePath;
6022
+ if (!treeFolderPath)
5074
6023
  return;
5075
6024
  event.preventDefault();
5076
- event.stopPropagation();
5077
- suppressAssetBrowserRevealIfVisible(assetButton);
5078
- callbacks.onSelectAsset?.(browserAssetId);
5079
- callbacks.onAssetAction?.(createAssetBrowserActionInput(actionId, asset, createCurrentAssetBrowserActionContext()));
6025
+ treeFolderButton.click();
5080
6026
  });
5081
6027
  assetPanel.addEventListener('contextmenu', (event) => {
5082
6028
  if (!inputRouter.shouldPreventBrowserContextMenu(event))
@@ -5084,31 +6030,119 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5084
6030
  const target = inputRouter.getEventTarget(event);
5085
6031
  if (!target)
5086
6032
  return;
5087
- const assetButton = target?.closest('[data-editor-asset-id]');
6033
+ const projectFileButton = target.closest('[data-editor-project-file-path]');
6034
+ const browserProjectFilePath = projectFileButton?.dataset.editorProjectFilePath;
6035
+ const projectDirectoryButton = target.closest('[data-editor-project-directory-path],[data-editor-asset-folder-tree-path]');
6036
+ const browserProjectDirectoryPath = projectDirectoryButton?.dataset.editorProjectDirectoryPath
6037
+ ?? projectDirectoryButton?.dataset.editorAssetFolderTreePath;
6038
+ const assetButton = target.closest('[data-editor-asset-id]');
5088
6039
  const browserAssetId = assetButton?.dataset.editorAssetId;
5089
- if (!browserAssetId || !currentState)
6040
+ if ((!browserProjectFilePath && browserProjectDirectoryPath == null && !browserAssetId) || !currentState)
5090
6041
  return;
5091
- const asset = currentState.assets.find(candidate => candidate.id === browserAssetId);
5092
- if (!asset)
6042
+ const asset = browserAssetId
6043
+ ? currentState.assets.find(candidate => candidate.id === browserAssetId) ?? null
6044
+ : null;
6045
+ if (browserAssetId && !asset)
5093
6046
  return;
5094
6047
  inputRouter.claimContextMenu(event);
5095
- suppressAssetBrowserRevealIfVisible(assetButton);
5096
- callbacks.onSelectAsset?.(browserAssetId);
5097
- contextMenu.open({
6048
+ if (asset && assetButton) {
6049
+ suppressAssetBrowserRevealIfVisible(assetButton);
6050
+ callbacks.onSelectAsset?.(asset.id);
6051
+ }
6052
+ else if (browserProjectFilePath && projectFileButton) {
6053
+ selectProjectBrowserEntry(browserProjectFilePath, projectFileButton);
6054
+ }
6055
+ else if (browserProjectDirectoryPath != null && projectDirectoryButton) {
6056
+ selectProjectBrowserEntry(browserProjectDirectoryPath, projectDirectoryButton);
6057
+ }
6058
+ const relativeProjectFilePath = browserProjectFilePath
6059
+ ? toLocalEditorProjectRelativePath(browserProjectFilePath)
6060
+ : null;
6061
+ const relativeProjectDirectoryPath = browserProjectDirectoryPath != null
6062
+ ? toLocalEditorProjectRelativePath(browserProjectDirectoryPath) || '.'
6063
+ : null;
6064
+ const snapshot = createLocalEditorAssetFilesystemSnapshot(currentState.assets, currentState.projectFiles);
6065
+ const fileEntry = browserProjectFilePath
6066
+ ? snapshot.entries.find(entry => entry.path === browserProjectFilePath) ?? null
6067
+ : null;
6068
+ const directoryEntry = browserProjectDirectoryPath != null
6069
+ ? snapshot.entries.find(entry => entry.path === browserProjectDirectoryPath) ?? null
6070
+ : null;
6071
+ const directoryFolder = browserProjectDirectoryPath != null
6072
+ ? snapshot.folders.find(folder => folder.path === browserProjectDirectoryPath) ?? null
6073
+ : null;
6074
+ const projectItems = relativeProjectFilePath
6075
+ ? [
6076
+ ...(callbacks.onProjectFileRead && isEditorProjectFilePreviewable(relativeProjectFilePath)
6077
+ ? [{ id: 'project-file.preview', label: '查看文件' }]
6078
+ : []),
6079
+ ...(callbacks.onProjectMediaResolve && isEditorProjectMediaPreviewable(relativeProjectFilePath)
6080
+ ? [{ id: 'project-file.preview-media', label: '预览媒体' }]
6081
+ : []),
6082
+ ...(callbacks.onProjectEntrySendToAgent
6083
+ ? [{ id: 'project-entry.send-to-agent', label: '发送给 Agent' }]
6084
+ : []),
6085
+ { id: 'project-file.copy-path', label: '复制路径' },
6086
+ ]
6087
+ : relativeProjectDirectoryPath
6088
+ ? [
6089
+ ...(callbacks.onProjectEntrySendToAgent
6090
+ ? [{ id: 'project-entry.send-to-agent', label: '发送给 Agent' }]
6091
+ : []),
6092
+ { id: 'project-file.copy-path', label: '复制路径' },
6093
+ ]
6094
+ : [];
6095
+ const assetItems = asset ? createAssetBrowserMenuItems(currentState, asset) : [];
6096
+ if (projectItems.length > 0 && assetItems.length > 0)
6097
+ assetItems[0] = { ...assetItems[0], separatorBefore: true };
6098
+ const openContextMenu = () => contextMenu.open({
5098
6099
  x: event.clientX,
5099
6100
  y: event.clientY,
5100
- items: createAssetBrowserMenuItems(currentState, asset),
6101
+ items: [...projectItems, ...assetItems],
5101
6102
  onAction(item) {
6103
+ if (item.id === 'project-file.preview' && browserProjectFilePath) {
6104
+ void openProjectFilePreview(browserProjectFilePath, projectFileButton);
6105
+ return;
6106
+ }
6107
+ if (item.id === 'project-file.preview-media' && browserProjectFilePath) {
6108
+ void openProjectMediaPreview(browserProjectFilePath, projectFileButton);
6109
+ return;
6110
+ }
6111
+ if (item.id === 'project-entry.send-to-agent' && callbacks.onProjectEntrySendToAgent) {
6112
+ const path = relativeProjectFilePath ?? relativeProjectDirectoryPath;
6113
+ if (!path)
6114
+ return;
6115
+ const entryKind = relativeProjectFilePath ? 'file' : 'directory';
6116
+ const name = entryKind === 'file'
6117
+ ? fileEntry?.label ?? path.split('/').slice(-1)[0] ?? path
6118
+ : directoryEntry?.label ?? directoryFolder?.label ?? currentState?.projectFiles?.rootName ?? path;
6119
+ void Promise.resolve(callbacks.onProjectEntrySendToAgent({
6120
+ path,
6121
+ name,
6122
+ entryKind,
6123
+ ...(entryKind === 'file' && fileEntry?.extension ? { extension: fileEntry.extension } : {}),
6124
+ ...(asset ? { assetId: asset.assetId ?? asset.id, assetKind: asset.kind } : {}),
6125
+ })).catch(() => undefined);
6126
+ return;
6127
+ }
6128
+ if (item.id === 'project-file.copy-path') {
6129
+ const path = relativeProjectFilePath ?? relativeProjectDirectoryPath;
6130
+ if (path)
6131
+ copyTextToClipboard(doc.defaultView, path);
6132
+ return;
6133
+ }
6134
+ if (!asset)
6135
+ return;
5102
6136
  if (item.id === 'asset.preview') {
5103
- openAssetPreviewModal(asset);
6137
+ openAssetPreviewModal(asset, assetButton);
5104
6138
  return;
5105
6139
  }
5106
6140
  if (item.id === 'asset.edit-material') {
5107
- openAssetMaterialEditorModal(asset);
6141
+ openAssetMaterialEditorModal(asset, assetButton);
5108
6142
  return;
5109
6143
  }
5110
6144
  if (item.id === 'asset.rename') {
5111
- openAssetRenameModal(asset);
6145
+ openAssetRenameModal(asset, assetButton);
5112
6146
  return;
5113
6147
  }
5114
6148
  if (item.id === 'asset.edit-prefab' || item.id === 'asset.add-to-current-prefab') {
@@ -5122,6 +6156,15 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5122
6156
  callbacks.onAssetAction?.(createAssetBrowserActionInput(item.id, asset, createCurrentAssetBrowserActionContext()));
5123
6157
  },
5124
6158
  });
6159
+ // Selecting a catalog asset rerenders the asset browser synchronously. Open
6160
+ // its menu on the next frame so the first right-click is not cleared by that
6161
+ // selection refresh.
6162
+ if (asset && assetButton && doc.defaultView?.requestAnimationFrame) {
6163
+ doc.defaultView.requestAnimationFrame(openContextMenu);
6164
+ }
6165
+ else {
6166
+ openContextMenu();
6167
+ }
5125
6168
  });
5126
6169
  workbench.rightDock.addEventListener('click', (event) => {
5127
6170
  const target = event.target instanceof HTMLElement ? event.target : null;
@@ -5154,11 +6197,11 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5154
6197
  const hierarchyController = createLocalEditorHierarchyController({
5155
6198
  doc,
5156
6199
  panel: hierarchyPanel,
5157
- callbacks,
5158
6200
  inputRouter,
5159
6201
  contextMenu,
6202
+ kernel: hierarchyKernel,
6203
+ onOperationResult: options.hierarchy?.onOperationResult,
5160
6204
  getState: () => currentState,
5161
- contextActions: options.hierarchy?.contextActions,
5162
6205
  requestRender: () => {
5163
6206
  if (currentState)
5164
6207
  render(currentState);
@@ -5168,7 +6211,10 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5168
6211
  setShortcutHelpOpen(false);
5169
6212
  if (assetPreviewOpen)
5170
6213
  closeAssetPreviewModal();
6214
+ if (projectFilePreviewOpen)
6215
+ closeProjectFilePreview();
5171
6216
  },
6217
+ requestOperationInput: requestHierarchyOperationInput,
5172
6218
  });
5173
6219
  construction.addCleanup('hierarchy-controller', () => hierarchyController.dispose());
5174
6220
  assetPanel.addEventListener('input', (event) => {
@@ -5177,6 +6223,15 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5177
6223
  return;
5178
6224
  callbacks.onAssetFilterChange?.(input.value);
5179
6225
  });
6226
+ assetPanel.addEventListener('change', (event) => {
6227
+ const select = event.target instanceof HTMLSelectElement ? event.target : null;
6228
+ const nextAssetBrowserTab = select?.dataset.editorAssetBrowserTypeFilter ? select.value : null;
6229
+ if (!isLocalEditorAssetBrowserTab(nextAssetBrowserTab))
6230
+ return;
6231
+ assetBrowserTab = nextAssetBrowserTab;
6232
+ if (currentState)
6233
+ render(currentState);
6234
+ });
5180
6235
  inspectorPanel.addEventListener('input', (event) => {
5181
6236
  const input = event.target instanceof HTMLInputElement ? event.target : null;
5182
6237
  if (input?.dataset.editorInspectorSearch != null) {
@@ -5185,6 +6240,8 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5185
6240
  render(currentState);
5186
6241
  return;
5187
6242
  }
6243
+ if (currentState?.inspectorPending === true)
6244
+ return;
5188
6245
  if (input?.type === 'checkbox' || input?.type === 'color')
5189
6246
  return;
5190
6247
  if (!input?.dataset.serializedPath || !input.dataset.serializedTargetId)
@@ -5199,6 +6256,11 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5199
6256
  callbacks.onPropertyInput?.(propertyInput);
5200
6257
  });
5201
6258
  inspectorPanel.addEventListener('paste', (event) => {
6259
+ if (currentState?.inspectorPending === true) {
6260
+ event.preventDefault();
6261
+ event.stopPropagation();
6262
+ return;
6263
+ }
5202
6264
  const input = event.target instanceof HTMLInputElement ? event.target : null;
5203
6265
  const text = event.clipboardData?.getData('text/plain') ?? event.clipboardData?.getData('text') ?? '';
5204
6266
  if (!input || !text)
@@ -5216,6 +6278,11 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5216
6278
  callbacks.onPropertyInput?.(propertyInput);
5217
6279
  });
5218
6280
  inspectorPanel.addEventListener('click', (event) => {
6281
+ if (currentState?.inspectorPending === true) {
6282
+ event.preventDefault();
6283
+ event.stopPropagation();
6284
+ return;
6285
+ }
5219
6286
  const target = event.target instanceof HTMLElement ? event.target : null;
5220
6287
  const renderingActionButton = target?.closest('[data-editor-rendering-action]');
5221
6288
  if (renderingActionButton) {
@@ -5294,14 +6361,11 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5294
6361
  const materialSlotSelectTarget = target?.closest('[data-editor-inspector-material-slot-select]');
5295
6362
  const materialSlotSelectionId = materialSlotSelectTarget?.dataset.editorInspectorMaterialSlotSelect;
5296
6363
  if (materialSlotSelectionId) {
5297
- const precondition = createCurrentHierarchyCommandPrecondition();
5298
- if (!precondition)
5299
- return;
5300
- callbacks.onSelectHierarchyItem?.({
5301
- id: materialSlotSelectionId,
5302
- additive: event.shiftKey && !event.metaKey && !event.ctrlKey,
5303
- toggle: event.metaKey || event.ctrlKey,
5304
- }, precondition);
6364
+ void hierarchyKernel.dispatch({
6365
+ type: 'selection',
6366
+ targetId: materialSlotSelectionId,
6367
+ modifier: event.metaKey || event.ctrlKey ? 'toggle' : event.shiftKey ? 'range' : 'replace',
6368
+ });
5305
6369
  return;
5306
6370
  }
5307
6371
  const copyButton = target?.closest('[data-editor-inspector-asset-copy]');
@@ -5331,11 +6395,15 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5331
6395
  openInspectorAssetPicker(input, property);
5332
6396
  });
5333
6397
  inspectorPanel.addEventListener('change', (event) => {
6398
+ if (currentState?.inspectorPending === true)
6399
+ return;
5334
6400
  const input = event.target instanceof HTMLInputElement || event.target instanceof HTMLSelectElement
5335
6401
  ? event.target
5336
6402
  : null;
5337
6403
  if (!input?.dataset.serializedPath || !input.dataset.serializedTargetId)
5338
6404
  return;
6405
+ if (hasLocalEditorUiKeyboardCommitPending(input))
6406
+ return;
5339
6407
  if (input instanceof HTMLInputElement && (input.type === 'text' || input.type === 'number')) {
5340
6408
  if (readInspectorCommitMode(input) !== 'change')
5341
6409
  return;
@@ -5350,6 +6418,11 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5350
6418
  callbacks.onPropertyInput?.(propertyInput);
5351
6419
  });
5352
6420
  inspectorPanel.addEventListener('keydown', (event) => {
6421
+ if (currentState?.inspectorPending === true) {
6422
+ event.preventDefault();
6423
+ event.stopPropagation();
6424
+ return;
6425
+ }
5353
6426
  const input = event.target instanceof HTMLInputElement ? event.target : null;
5354
6427
  if (!input || !isLocalEditorKeyboardCommitEvent(event, input))
5355
6428
  return;
@@ -5359,9 +6432,13 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5359
6432
  event.stopPropagation();
5360
6433
  });
5361
6434
  inspectorPanel.addEventListener('focusout', (event) => {
6435
+ if (currentState?.inspectorPending === true)
6436
+ return;
5362
6437
  const input = event.target instanceof HTMLInputElement ? event.target : null;
5363
6438
  if (!input?.dataset.serializedPath || !input.dataset.serializedTargetId)
5364
6439
  return;
6440
+ if (hasLocalEditorUiKeyboardCommitPending(input))
6441
+ return;
5365
6442
  if (readInspectorCommitMode(input) !== 'blur')
5366
6443
  return;
5367
6444
  if (consumeLocalEditorKeyboardCommittedValue(input))
@@ -5395,6 +6472,8 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5395
6472
  : null;
5396
6473
  if (!input?.dataset.editorRenderingProperty)
5397
6474
  return;
6475
+ if (hasLocalEditorUiKeyboardCommitPending(input))
6476
+ return;
5398
6477
  if ((input instanceof HTMLInputElement && (input.type === 'text' || input.type === 'number')) || input instanceof HTMLTextAreaElement) {
5399
6478
  if (readRenderingCommitMode(input) !== 'change')
5400
6479
  return;
@@ -5422,6 +6501,8 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5422
6501
  : null;
5423
6502
  if (!input?.dataset.editorRenderingProperty)
5424
6503
  return;
6504
+ if (hasLocalEditorUiKeyboardCommitPending(input))
6505
+ return;
5425
6506
  if (input instanceof HTMLSelectElement)
5426
6507
  return;
5427
6508
  if (readRenderingCommitMode(input) !== 'blur')
@@ -5494,11 +6575,21 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5494
6575
  closeAssetPreviewModal();
5495
6576
  return;
5496
6577
  }
6578
+ if (key === 'escape' && projectFilePreviewOpen) {
6579
+ event.preventDefault();
6580
+ closeProjectFilePreview();
6581
+ return;
6582
+ }
5497
6583
  if (key === 'escape' && assetPickerOpen) {
5498
6584
  event.preventDefault();
5499
6585
  closeInspectorAssetPicker();
5500
6586
  return;
5501
6587
  }
6588
+ if (key === 'escape' && editorStatusCenterOpen) {
6589
+ event.preventDefault();
6590
+ closeEditorStatusCenter();
6591
+ return;
6592
+ }
5502
6593
  if (key === 'escape' && snapSettingsOpen) {
5503
6594
  event.preventDefault();
5504
6595
  closeSnapSettingsPopover();
@@ -5527,17 +6618,13 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5527
6618
  const primaryModifier = event.metaKey || event.ctrlKey;
5528
6619
  const handleDocumentShortcut = inputRouter.shouldHandleDocumentShortcut(event);
5529
6620
  const handleGlobalShortcut = inputRouter.shouldHandleGlobalShortcut(event);
5530
- if (shouldToggleLocalEditorPrefabComparisonShortcut({
5531
- inPrefabStage: currentState.prefabStage != null,
5532
- handleGlobalShortcut,
5533
- key,
5534
- shiftKey: event.shiftKey,
5535
- metaKey: event.metaKey,
5536
- ctrlKey: event.ctrlKey,
5537
- altKey: event.altKey,
5538
- })) {
6621
+ const contextAction = currentState.contextActions?.find(action => (action.availability.state !== 'hidden'
6622
+ && matchesContextActionShortcut(action.shortcut, event)));
6623
+ if (handleDocumentShortcut && contextAction) {
5539
6624
  event.preventDefault();
5540
- setPrefabComparisonPreviewOpen(!prefabComparisonPreviewOpen);
6625
+ if (contextAction.availability.state === 'enabled') {
6626
+ callbacks.onContextAction?.(contextAction.id);
6627
+ }
5541
6628
  return;
5542
6629
  }
5543
6630
  if (handleDocumentShortcut
@@ -5546,6 +6633,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5546
6633
  && primaryModifier
5547
6634
  && key === 's') {
5548
6635
  event.preventDefault();
6636
+ editorConsole.append({ severity: 'info', source: 'save', message: '请求保存场景' });
5549
6637
  callbacks.onSaveScene?.();
5550
6638
  return;
5551
6639
  }
@@ -5562,33 +6650,28 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5562
6650
  callbacks.onRedo?.();
5563
6651
  return;
5564
6652
  }
5565
- if (shouldLocalEditorPrefabStageBlockHierarchyShortcut({
5566
- inPrefabStage: currentState.prefabStage != null,
5567
- handleGlobalShortcut,
5568
- key,
5569
- metaKey: event.metaKey,
5570
- ctrlKey: event.ctrlKey,
5571
- altKey: event.altKey,
5572
- })) {
5573
- event.preventDefault();
5574
- return;
5575
- }
5576
- if (!currentState.prefabStage && handleGlobalShortcut && hierarchyController.handleEditShortcut(event)) {
6653
+ if (handleGlobalShortcut && hierarchyController.handleEditShortcut(event)) {
5577
6654
  return;
5578
6655
  }
5579
6656
  if (!handleGlobalShortcut || event.metaKey || event.ctrlKey || event.altKey)
5580
6657
  return;
5581
- const toolByKey = {
5582
- q: 'select',
5583
- w: 'move',
5584
- e: 'rotate',
5585
- r: 'scale',
5586
- };
5587
- const tool = toolByKey[key];
6658
+ const tool = currentState.tools?.find(candidate => (candidate.kind === 'primary'
6659
+ && candidate.shortcut?.toLowerCase() === key));
5588
6660
  if (tool) {
5589
6661
  event.preventDefault();
5590
- if (isPreviewToolEnabled(tool))
5591
- callbacks.onTransformToolChange?.(tool);
6662
+ if (/(?:^|[?&])debugGizmo=(?:1|true)(?:&|$)/.test(doc.defaultView?.location?.search ?? '')) {
6663
+ console.info('[fps-editor:gizmo]', 'shortcut.dispatched', {
6664
+ timestamp: typeof performance !== 'undefined' ? Number(performance.now().toFixed(2)) : Date.now(),
6665
+ key,
6666
+ toolId: tool.id,
6667
+ availability: tool.availability.state,
6668
+ active: tool.active,
6669
+ eventTarget: event.target instanceof Element ? event.target.tagName : null,
6670
+ defaultPrevented: event.defaultPrevented,
6671
+ });
6672
+ }
6673
+ if (tool.availability.state === 'enabled')
6674
+ callbacks.onToolActivate?.(tool.id);
5592
6675
  return;
5593
6676
  }
5594
6677
  if (key === 'f') {
@@ -5617,24 +6700,13 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5617
6700
  : snap.scaleStep;
5618
6701
  return Number.isFinite(value) ? String(value) : '';
5619
6702
  }
5620
- function createCurrentHierarchyCommandPrecondition() {
5621
- if (!currentState)
5622
- return null;
5623
- const documentRevision = currentState.documentRevision ?? 0;
5624
- return {
5625
- scopeId: currentState.prefabStage ? `prefab-stage:${currentState.prefabStage.assetId}` : 'scene',
5626
- documentRevision,
5627
- projectionRevision: currentState.hierarchyProjectionRevision ?? documentRevision,
5628
- };
5629
- }
5630
6703
  function isTransformActionEnabled(action, operationState) {
5631
6704
  return action.startsWith('align-')
5632
6705
  ? operationState.canAlign
5633
6706
  : operationState.canDistribute;
5634
6707
  }
5635
6708
  function getPreviewToolSupport(tool) {
5636
- const inPrefabStage = currentState?.mode === 'editor' && !!currentState.prefabStage;
5637
- return resolveLocalEditorPreviewToolSupport({ inPrefabStage, tool });
6709
+ return resolveLocalEditorPreviewToolSupport({ capabilities: currentState?.capabilities, tool });
5638
6710
  }
5639
6711
  function isPreviewToolVisible(tool) {
5640
6712
  return currentState?.mode === 'editor' && getPreviewToolSupport(tool).support !== 'hidden';
@@ -5645,27 +6717,31 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5645
6717
  && getPreviewToolSupport(tool).support === 'enabled';
5646
6718
  }
5647
6719
  function applyPrefabStageWorkbenchLayoutOverride(layout = workbenchLayoutController.getLayout()) {
5648
- const { leftWidth, rightWidth, bottomEdge, bottomVisible } = resolveLocalEditorPrefabStageWorkbenchLayout(layout, readLocalEditorWorkbenchViewport(doc));
6720
+ const { leftWidth, rightWidth, consoleEdge, sceneBottomEdge, bottomVisible } = resolveLocalEditorPrefabStageWorkbenchLayout(layout, readLocalEditorWorkbenchViewport(doc));
5649
6721
  workbench.leftDock.style.display = 'flex';
5650
6722
  workbench.leftDock.style.width = `${leftWidth}px`;
5651
- workbench.leftDock.style.bottom = `${bottomEdge}px`;
6723
+ workbench.leftDock.style.bottom = `${consoleEdge}px`;
5652
6724
  workbench.leftDock.style.zIndex = '';
5653
6725
  workbench.leftDock.style.boxShadow = '';
5654
6726
  workbench.rightDock.style.display = 'flex';
5655
6727
  workbench.rightDock.style.width = `${rightWidth}px`;
6728
+ workbench.rightDock.style.bottom = `${consoleEdge}px`;
5656
6729
  workbench.rightDock.style.zIndex = '';
5657
6730
  workbench.rightDock.style.boxShadow = '';
5658
6731
  workbench.sceneFrame.style.left = `${leftWidth}px`;
5659
6732
  workbench.sceneFrame.style.right = `${rightWidth}px`;
5660
- workbench.sceneFrame.style.bottom = `${bottomEdge}px`;
6733
+ workbench.sceneFrame.style.bottom = `${sceneBottomEdge}px`;
5661
6734
  if (bottomVisible) {
6735
+ workbench.bottomDock.style.left = `${leftWidth}px`;
5662
6736
  workbench.bottomDock.style.right = `${rightWidth}px`;
6737
+ workbench.bottomDock.style.bottom = `${consoleEdge}px`;
6738
+ workbench.bottomResizer.style.left = `${leftWidth}px`;
5663
6739
  workbench.bottomResizer.style.right = `${rightWidth}px`;
5664
6740
  }
5665
6741
  workbench.leftToggle.style.display = 'none';
5666
6742
  workbench.rightToggle.style.display = 'none';
5667
- workbench.leftResizer.style.bottom = `${bottomEdge}px`;
5668
- workbench.rightResizer.style.bottom = '0';
6743
+ workbench.leftResizer.style.bottom = `${consoleEdge}px`;
6744
+ workbench.rightResizer.style.bottom = `${consoleEdge}px`;
5669
6745
  }
5670
6746
  function readLocalEditorWorkbenchViewport(docRef) {
5671
6747
  const win = docRef.defaultView;
@@ -5675,29 +6751,21 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5675
6751
  };
5676
6752
  }
5677
6753
  function renderPrefabStagePropertiesPanel(stage) {
5678
- inspectorPanel.dataset.editorPanelId = 'prefab-properties';
6754
+ inspectorPanel.dataset.editorPanelId = 'inspector';
5679
6755
  inspectorPanel.style.display = '';
5680
6756
  renderingPanel.style.display = 'none';
5681
- if (stage.inspectorObject) {
5682
- LocalEditorPanels.renderInspectorPanel(doc, inspectorPanel, {
5683
- ...currentState,
5684
- selectedIds: stage.inspectorObject.targetIds,
5685
- activeId: stage.inspectorObject.activeId,
5686
- selectionSummary: {
5687
- count: stage.inspectorObject.targetIds.length,
5688
- activeId: stage.inspectorObject.activeId,
5689
- },
5690
- inspectorObject: stage.inspectorObject,
5691
- inspectorMultiObject: null,
5692
- }, inspectorFilter, {
6757
+ if (currentState?.inspectorObject) {
6758
+ LocalEditorPanels.renderInspectorPanel(doc, inspectorPanel, currentState, inspectorFilter, {
5693
6759
  ...options.inspector,
6760
+ layerHost: editorUiLayerHost,
5694
6761
  title: 'Prefab Properties',
5695
6762
  emptyText: 'Select an item in Prefab Explorer.',
5696
- summaryTitle: 'Prefab',
5697
6763
  lockedVectorGroups: lockedInspectorVectorGroups,
5698
6764
  });
6765
+ lastRenderedInspectorContentKey = resolveLocalEditorRightDockContentKey(currentState, 'inspector', inspectorFilter);
5699
6766
  return;
5700
6767
  }
6768
+ LocalEditorPanels.disposeInspectorPanelUi(inspectorPanel);
5701
6769
  LocalEditorShared.clearElement(inspectorPanel);
5702
6770
  inspectorPanel.appendChild(createPrefabStagePanelHeader('Prefab Properties', 'inspector'));
5703
6771
  const selectedItem = findLocalEditorPrefabStageStructureItem(stage, stage.selectedItemId);
@@ -5711,6 +6779,9 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5711
6779
  appendPrefabStageReadonlyRow(grid, 'Mode', stage.readonly ? '只读' : '可编辑');
5712
6780
  appendPrefabStageSelectedItemDetails(grid, selectedItem);
5713
6781
  inspectorPanel.appendChild(grid);
6782
+ lastRenderedInspectorContentKey = currentState
6783
+ ? resolveLocalEditorRightDockContentKey(currentState, 'inspector', inspectorFilter)
6784
+ : null;
5714
6785
  }
5715
6786
  function appendPrefabStageSelectedItemDetails(container, item) {
5716
6787
  if (!item)
@@ -5855,7 +6926,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5855
6926
  : 'var(--fps-editor-muted)';
5856
6927
  setToolbarButtonIcon(doc, editorStatusButton, statusViewModel.icon);
5857
6928
  setToolbarButtonTooltip(editorStatusButton, [
5858
- `编辑器状态:${editorStatusText}`,
6929
+ `验证中心:${editorStatusText}`,
5859
6930
  state.statusDetails && state.statusDetails !== state.status ? state.statusDetails : '',
5860
6931
  transformStatusText,
5861
6932
  LocalEditorShared.toTransformOperationStatusLabel(transformOperations.settings),
@@ -5875,23 +6946,10 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5875
6946
  ? 'var(--fps-editor-border)'
5876
6947
  : agentBridgeStatusColor;
5877
6948
  setToolbarButtonTooltip(agentBridgeStatusButton, createAgentBridgeStatusTooltip(state.agentBridge));
5878
- renderCoordinateAxesOverlay(coordinateAxesOverlay, inEditor ? state.coordinateAxes ?? null : null);
5879
- renderSceneFrameRateOverlay(sceneFrameRateOverlay, inEditor && !inPrefabStage ? state.sceneFrameStats ?? null : null);
6949
+ renderCoordinateAxesOverlay(coordinateAxesOverlay, inEditor ? state.coordinateAxes ?? null : null, state.viewportTools?.viewPreset ?? 'perspective', state.busy);
5880
6950
  renderPerformanceMonitorOverlay(performanceMonitorOverlay, inEditor && !inPrefabStage ? state.performanceStats ?? null : null, inEditor && !inPrefabStage && performanceMonitorOpen);
5881
- const comparisonColumnVisible = shouldShowLocalEditorPrefabComparisonColumn({
5882
- inPrefabStage: inEditor && inPrefabStage,
5883
- userOpen: prefabComparisonPreviewOpen,
5884
- sceneWidth: workbench.sceneFrame.clientWidth,
5885
- });
5886
- if (!comparisonColumnVisible)
5887
- endPrefabComparisonPreviewDrag();
5888
6951
  prefabStagePreviewLayout.root.style.display = inEditor && inPrefabStage ? 'block' : 'none';
5889
- prefabStagePreviewLayout.mainRegion.style.right = comparisonColumnVisible
5890
- ? `${LOCAL_EDITOR_PREFAB_COMPARISON_COLUMN_WIDTH_PX}px`
5891
- : '0';
5892
- prefabStagePreviewLayout.comparisonColumn.style.display = comparisonColumnVisible ? 'flex' : 'none';
5893
6952
  renderPrefabImportStatsOverlay(prefabImportStatsOverlay, inEditor && inPrefabStage ? state.prefabStage ?? null : null);
5894
- renderPrefabComparisonPreviewOverlay(prefabComparisonPreviewOverlay, inEditor && inPrefabStage && comparisonColumnVisible ? state.prefabStage ?? null : null);
5895
6953
  renderSpatialOverlay(spatialOverlay, inEditor ? state.viewportSpatialOverlay ?? null : null);
5896
6954
  renderMeasurementOverlay(measurementOverlay, inEditor ? state.viewportMeasurement ?? null : null);
5897
6955
  const boxSelection = state.boxSelection;
@@ -5911,26 +6969,82 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5911
6969
  const updatePreview = (preview) => {
5912
6970
  if (!currentState)
5913
6971
  return;
6972
+ const toolPresentationStartedAt = typeof performance !== 'undefined' ? performance.now() : Date.now();
6973
+ const shouldRenderToolPresentation = 'tools' in preview || 'activeToolId' in preview;
6974
+ const previousActiveToolId = currentState.activeToolId ?? null;
5914
6975
  const shouldRenderInspectorPreview = 'inspectorObject' in preview || 'inspectorMultiObject' in preview;
5915
- currentState = {
6976
+ const shouldRenderSelectionPresentation = 'selectedIds' in preview
6977
+ || 'activeId' in preview
6978
+ || 'selectionSummary' in preview;
6979
+ const nextState = {
5916
6980
  ...currentState,
5917
6981
  ...preview,
5918
6982
  };
6983
+ const nextInspectorContentKey = resolveLocalEditorRightDockContentKey(nextState, 'inspector', inspectorFilter);
6984
+ const inspectorPreviewScrollSnapshot = shouldRenderInspectorPreview
6985
+ && lastRenderedInspectorContentKey === nextInspectorContentKey
6986
+ ? captureLocalEditorRightDockScrollSnapshot(currentState, 'inspector', inspectorFilter, inspectorPanel, renderingPanel, markersPanel, pluginsPanel)
6987
+ : null;
6988
+ currentState = nextState;
6989
+ if ('inspectorPending' in preview) {
6990
+ syncLocalEditorInspectorPendingState(inspectorPanel, currentState.inspectorPending === true);
6991
+ }
6992
+ if (shouldRenderToolPresentation) {
6993
+ renderToolPresentationState(currentState);
6994
+ scheduleToolbarOverflowLayout();
6995
+ if (/(?:^|[?&])debugGizmo=(?:1|true)(?:&|$)/.test(doc.defaultView?.location?.search ?? '')) {
6996
+ console.info('[fps-editor:gizmo]', 'ui.tool-presentation.updated', {
6997
+ timestamp: typeof performance !== 'undefined' ? Number(performance.now().toFixed(2)) : Date.now(),
6998
+ durationMs: Number(((typeof performance !== 'undefined' ? performance.now() : Date.now()) - toolPresentationStartedAt).toFixed(2)),
6999
+ previousActiveToolId,
7000
+ activeToolId: currentState.activeToolId ?? null,
7001
+ toolCount: currentState.tools?.length ?? 0,
7002
+ });
7003
+ }
7004
+ }
7005
+ if (shouldRenderSelectionPresentation)
7006
+ hierarchyController.render(currentState);
5919
7007
  renderPreviewState(currentState);
5920
- if (shouldRenderInspectorPreview && panelRegistry.getRightDockTab() === 'inspector') {
5921
- const rightDockScrollSnapshot = captureLocalEditorRightDockScrollSnapshot(currentState, 'inspector', inspectorFilter, inspectorPanel, renderingPanel, markersPanel, pluginsPanel);
7008
+ if (shouldRenderInspectorPreview
7009
+ && currentState.mode === 'editor'
7010
+ && !!currentState.prefabStage
7011
+ && rightDockFormalSurfaceVisibility.isVisible()) {
7012
+ renderPrefabStagePropertiesPanel(currentState.prefabStage);
7013
+ }
7014
+ if (shouldRenderLocalEditorInspectorPreview({
7015
+ hasInspectorPreview: shouldRenderInspectorPreview,
7016
+ mode: currentState.mode,
7017
+ inPrefabStage: !!currentState.prefabStage,
7018
+ rightDockVisible: rightDockFormalSurfaceVisibility.isVisible(),
7019
+ activeRightTab: panelRegistry.getRightDockTab(),
7020
+ })) {
5922
7021
  LocalEditorPanels.renderInspectorPanel(doc, inspectorPanel, currentState, inspectorFilter, {
5923
7022
  ...options.inspector,
7023
+ layerHost: editorUiLayerHost,
5924
7024
  lockedVectorGroups: lockedInspectorVectorGroups,
5925
7025
  });
5926
- restoreLocalEditorRightDockScrollSnapshot(rightDockScrollSnapshot, currentState, 'inspector', inspectorFilter, inspectorPanel, renderingPanel, markersPanel, pluginsPanel);
7026
+ lastRenderedInspectorContentKey = nextInspectorContentKey;
7027
+ restoreLocalEditorRightDockScrollSnapshot(inspectorPreviewScrollSnapshot, currentState, 'inspector', inspectorFilter, inspectorPanel, renderingPanel, markersPanel, pluginsPanel);
7028
+ }
7029
+ if ((shouldRenderSelectionPresentation || shouldRenderInspectorPreview)
7030
+ && /(?:^|[?&])debug(?:Gizmo|Selection)=(?:1|true)(?:&|$)/.test(doc.defaultView?.location?.search ?? '')) {
7031
+ console.info('[fps-editor:selection]', 'ui.selection-preview.updated', {
7032
+ timestamp: typeof performance !== 'undefined' ? Number(performance.now().toFixed(2)) : Date.now(),
7033
+ durationMs: Number(((typeof performance !== 'undefined' ? performance.now() : Date.now()) - toolPresentationStartedAt).toFixed(2)),
7034
+ phase: shouldRenderSelectionPresentation ? 'presentation' : 'inspector',
7035
+ activeId: currentState.activeId,
7036
+ selectedCount: currentState.selectedIds.length,
7037
+ });
5927
7038
  }
5928
7039
  };
5929
7040
  const render = (state) => {
5930
7041
  const previousState = currentState;
7042
+ const assetBrowserContinuitySnapshot = assetBrowserContinuity.capture(lastRenderedAssetBrowserContentKey);
5931
7043
  const previousRightTab = panelRegistry.getRightDockTab();
5932
7044
  const rightDockScrollSnapshot = captureLocalEditorRightDockScrollSnapshot(previousState, previousRightTab, inspectorFilter, inspectorPanel, renderingPanel, markersPanel, pluginsPanel);
5933
7045
  currentState = state;
7046
+ syncLocalEditorInspectorPendingState(inspectorPanel, state.inspectorPending === true);
7047
+ editorConsole.syncState(state, previousState);
5934
7048
  const focusSnapshot = captureLocalEditorEditableFocus(doc);
5935
7049
  const inEditor = state.mode === 'editor';
5936
7050
  const disabled = state.busy;
@@ -5939,9 +7053,9 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5939
7053
  const previousInPrefabStage = previousState?.mode === 'editor' && !!previousState.prefabStage;
5940
7054
  if (!inEditor || disabled)
5941
7055
  contextMenu.close();
5942
- hostChrome.style.display = !inEditor && localTestActionsEnabled ? 'flex' : 'none';
7056
+ hostChrome.style.display = !inEditor && localTestActionsEnabled && gameModeEntryVisible ? 'flex' : 'none';
5943
7057
  enterEditorButton.disabled = disabled;
5944
- for (const button of [saveButton, saveAndRunButton, discardRunButton, undoButton, redoButton, sceneHelpButton, sceneCameraButton, performanceMonitorButton, gridToggleButton, prefabComparisonPreviewButton]) {
7058
+ for (const button of [saveButton, saveAndRunButton, discardRunButton, undoButton, redoButton, sceneHelpButton, sceneCameraButton, performanceMonitorButton, gridToggleButton]) {
5945
7059
  button.style.display = 'inline-flex';
5946
7060
  button.disabled = disabled;
5947
7061
  }
@@ -5959,20 +7073,36 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5959
7073
  setPerformanceMonitorOpen(false);
5960
7074
  }
5961
7075
  if (!inEditor || disabled) {
7076
+ projectMediaPreviewRequestId += 1;
7077
+ disposeProjectModelPreview();
5962
7078
  assetPreviewOpen = false;
7079
+ assetPreviewReturnFocus = null;
5963
7080
  previewedAsset = null;
5964
7081
  assetPreviewMode = 'preview';
7082
+ projectMediaPreviewSource = null;
7083
+ projectMediaPreviewRequestedPath = '';
7084
+ projectMediaPreviewError = '';
7085
+ projectFilePreviewOpen = false;
7086
+ projectFilePreviewReturnFocus = null;
7087
+ projectFilePreviewRequestId += 1;
7088
+ projectFilePreviewContent = null;
7089
+ projectFilePreviewRequestedPath = '';
7090
+ projectFilePreviewError = '';
7091
+ projectFilePreviewMatches = [];
7092
+ projectFilePreviewActiveMatch = -1;
5965
7093
  assetPickerOpen = false;
5966
7094
  assetPickerInput = null;
5967
7095
  assetPickerProperty = null;
7096
+ settleHierarchyOperationInputRequest(null);
5968
7097
  }
7098
+ renderProjectFilePreview();
5969
7099
  syncInputModalOpen();
5970
7100
  const transformTool = state.transformTool ?? null;
5971
7101
  workbench.root.style.display = inEditor ? '' : 'none';
5972
7102
  workbench.root.dataset.editorPrefabStage = String(inPrefabStage);
5973
7103
  sceneTitle.textContent = createLocalEditorPrefabStageTitle(prefabStage);
5974
7104
  sceneToolOverlay.style.display = inEditor ? 'flex' : 'none';
5975
- prefabStageBackButton.style.display = inPrefabStage ? 'inline-flex' : 'none';
7105
+ renderContextActionButtons(contextActionGroup, state.contextActions ?? [], disabled);
5976
7106
  if (inPrefabStage && !previousInPrefabStage) {
5977
7107
  prefabStageMainWorkbenchLayoutSnapshot = workbenchLayoutController.getLayout();
5978
7108
  workbenchLayoutController.setBottomCollapsed(false);
@@ -5981,6 +7111,9 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
5981
7111
  workbenchLayoutController.setLayout(prefabStageMainWorkbenchLayoutSnapshot, true);
5982
7112
  prefabStageMainWorkbenchLayoutSnapshot = null;
5983
7113
  }
7114
+ if (!inPrefabStage) {
7115
+ LocalEditorPanels.disposeInspectorPanelUi(inspectorPanel);
7116
+ }
5984
7117
  workbench.leftToggle.style.display = '';
5985
7118
  workbench.rightToggle.style.display = '';
5986
7119
  workbench.bottomToggle.style.display = '';
@@ -6028,25 +7161,15 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
6028
7161
  const viewportControlsTooltip = sceneCameraPreview.enabled
6029
7162
  ? '当前为 Main Camera 预览,请关闭后再使用视口工具'
6030
7163
  : '';
6031
- const viewportProjectionTooltip = sceneCameraPreview.enabled
6032
- ? '当前为 Main Camera 预览,投影由 Main Camera 决定;关闭预览后可切换编辑视口投影'
6033
- : '';
6034
7164
  viewportToolsGroup.style.display = isPreviewToolVisible('viewport-camera') ? 'flex' : 'none';
6035
- for (const [preset, button] of viewportPresetButtons) {
6036
- button.disabled = viewportControlsDisabled;
6037
- setToolbarButtonTooltip(button, viewportControlsTooltip || VIEW_PRESET_TOOLTIPS[preset]);
6038
- LocalEditorShared.applyButtonActiveState(button, viewportTools?.viewPreset === preset);
6039
- }
6040
- projectionToggleButton.disabled = viewportControlsDisabled;
6041
- const projectionMode = viewportTools?.projectionMode ?? 'perspective';
6042
- const nextProjectionMode = projectionMode === 'orthographic' ? 'perspective' : 'orthographic';
6043
- setToolbarButtonIcon(doc, projectionToggleButton, projectionMode === 'orthographic' ? 'projection-ortho' : 'projection-perspective');
6044
- setToolbarButtonTooltip(projectionToggleButton, viewportProjectionTooltip || `投影模式:${VIEWPORT_PROJECTION_LABELS[projectionMode]}。切换为${VIEWPORT_PROJECTION_LABELS[nextProjectionMode]}`);
6045
- LocalEditorShared.applyButtonActiveState(projectionToggleButton, projectionMode === 'orthographic');
6046
7165
  const markersVisible = viewportTools?.markersVisible ?? true;
6047
7166
  markerVisibilityButton.disabled = disabled;
6048
7167
  setToolbarButtonTooltip(markerVisibilityButton, markersVisible ? '隐藏标记与关系线' : '显示标记与关系线');
6049
7168
  LocalEditorShared.applyButtonActiveState(markerVisibilityButton, markersVisible);
7169
+ const showAllPrefabMarkers = viewportTools?.showAllPrefabMarkers ?? false;
7170
+ showAllPrefabMarkersButton.disabled = disabled || !!state.prefabStage;
7171
+ setToolbarButtonTooltip(showAllPrefabMarkersButton, showAllPrefabMarkers ? '仅显示选中 Prefab 实例的标记' : '显示所有 Prefab 实例的标记');
7172
+ LocalEditorShared.applyButtonActiveState(showAllPrefabMarkersButton, showAllPrefabMarkers);
6050
7173
  overlaySettingsButton.disabled = !isPreviewToolEnabled('spatial-overlay');
6051
7174
  setToolbarButtonTooltip(overlaySettingsButton, '视口信息层设置');
6052
7175
  LocalEditorShared.applyButtonActiveState(overlaySettingsButton, overlaySettingsOpen);
@@ -6075,24 +7198,11 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
6075
7198
  ? performanceMonitorOpen ? '隐藏性能监控' : '显示性能监控'
6076
7199
  : performanceMonitorSupport.reason);
6077
7200
  LocalEditorShared.applyButtonActiveState(performanceMonitorButton, performanceMonitorOpen);
6078
- prefabComparisonPreviewButton.style.display = isPreviewToolVisible('prefab-comparison') ? 'inline-flex' : 'none';
6079
- prefabComparisonPreviewButton.disabled = !isPreviewToolEnabled('prefab-comparison');
6080
- const prefabComparisonSupport = getPreviewToolSupport('prefab-comparison');
6081
- setToolbarButtonTooltip(prefabComparisonPreviewButton, prefabComparisonSupport.support === 'enabled'
6082
- ? prefabComparisonPreviewOpen
6083
- ? '隐藏对比预览 (Shift+P)'
6084
- : '显示对比预览 (Shift+P)'
6085
- : prefabComparisonSupport.reason);
6086
- LocalEditorShared.applyButtonActiveState(prefabComparisonPreviewButton, inPrefabStage && prefabComparisonPreviewOpen);
6087
7201
  gridToggleButton.disabled = disabled || !gridState.available;
6088
7202
  setToolbarButtonTooltip(gridToggleButton, gridState.visible ? '隐藏 Scene View 网格' : '显示 Scene View 网格');
6089
7203
  LocalEditorShared.applyButtonActiveState(gridToggleButton, gridState.visible);
6090
- toolGroup.style.display = isPreviewToolVisible('select') ? 'flex' : 'none';
7204
+ renderToolPresentationState(state);
6091
7205
  spaceGroup.style.display = isPreviewToolVisible('transform-space') ? 'flex' : 'none';
6092
- for (const [tool, button] of toolButtons) {
6093
- button.disabled = !isPreviewToolEnabled(tool);
6094
- LocalEditorShared.applyButtonActiveState(button, transformTool?.activeTool === tool);
6095
- }
6096
7206
  for (const [space, button] of Object.entries(spaceButtons)) {
6097
7207
  button.disabled = !isPreviewToolEnabled('transform-space');
6098
7208
  LocalEditorShared.applyButtonActiveState(button, transformTool?.activeSpace === space);
@@ -6152,21 +7262,21 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
6152
7262
  dirtyBadge.style.display = inEditor && state.session?.dirty ? 'inline-flex' : 'none';
6153
7263
  renderPreviewState(state);
6154
7264
  scheduleToolbarOverflowLayout();
6155
- if (!inEditor)
7265
+ if (!inEditor) {
7266
+ LocalEditorPanels.disposeInspectorPanelUi(renderingPanel);
6156
7267
  return;
7268
+ }
6157
7269
  const activeRightTab = panelRegistry.getRightDockTab();
7270
+ if (inPrefabStage || activeRightTab !== 'rendering') {
7271
+ LocalEditorPanels.disposeInspectorPanelUi(renderingPanel);
7272
+ }
6158
7273
  if (inPrefabStage && prefabStage) {
6159
7274
  const rightDockVisibility = resolveLocalEditorRightDockVisibility({
6160
7275
  inPrefabStage: true,
6161
7276
  activeRightTab,
6162
7277
  });
6163
7278
  const activeBottomTab = panelRegistry.getBottomDockTab();
6164
- const assetBrowserTabChanged = assetBrowserTab !== lastRenderedAssetBrowserTab;
6165
- const bottomDockTabChanged = activeBottomTab !== lastRenderedBottomDockTab;
6166
7279
  const selectedAssetChanged = state.selectedAssetId !== lastRenderedSelectedAssetId;
6167
- const assetBrowserScrollSnapshot = activeBottomTab === 'assets'
6168
- ? assetBrowserViewportReveal.captureScrollSnapshot()
6169
- : { scrollTop: null };
6170
7280
  leftDockTabs.style.display = 'none';
6171
7281
  rightDockTabs.style.display = rightDockVisibility.tabsDisplay;
6172
7282
  inspectorPanel.style.display = rightDockVisibility.inspectorDisplay;
@@ -6175,20 +7285,29 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
6175
7285
  pluginsPanel.style.display = rightDockVisibility.pluginsDisplay;
6176
7286
  hierarchyController.render(state);
6177
7287
  renderPrefabStagePropertiesPanel(prefabStage);
6178
- LocalEditorPanels.renderWorkbenchBottomDockPanel(doc, assetPanel, state, activeBottomTab, panelRegistry.getPanels('bottom'), assetBrowserTab);
6179
- if (activeBottomTab === 'assets' && !assetBrowserTabChanged && !bottomDockTabChanged) {
6180
- assetBrowserViewportReveal.restoreScrollSnapshot(assetBrowserScrollSnapshot);
7288
+ LocalEditorPanels.renderWorkbenchBottomDockPanel(doc, assetPanel, state, activeBottomTab, panelRegistry.getPanels('bottom'), assetBrowserTab, { expandedFolderPaths: assetBrowserExpandedFolderPaths, folderPath: assetBrowserFolderPath, viewMode: assetBrowserViewMode, selectedEntryPath: selectedProjectEntryPath });
7289
+ if (activeBottomTab === 'assets') {
7290
+ assetBrowserFolderPath = assetPanel.dataset.editorAssetBrowserFolderPath ?? assetBrowserFolderPath;
6181
7291
  }
7292
+ const assetBrowserContentKey = resolveLocalEditorAssetBrowserContentKey({
7293
+ assetFilter: state.assetFilter,
7294
+ folderPath: assetBrowserFolderPath,
7295
+ tab: assetBrowserTab,
7296
+ viewMode: assetBrowserViewMode,
7297
+ });
7298
+ hydrateProjectMediaThumbnails();
7299
+ assetBrowserContinuity.restore(assetBrowserContinuitySnapshot, assetBrowserContentKey, activeBottomTab === 'assets');
6182
7300
  const suppressAssetScroll = state.selectedAssetId
6183
7301
  ? assetBrowserViewportReveal.consumeRevealSuppression(state.selectedAssetId, { clearWhenDifferent: selectedAssetChanged })
6184
7302
  : false;
6185
7303
  if (activeBottomTab === 'assets' && selectedAssetChanged && state.selectedAssetId && !suppressAssetScroll) {
6186
7304
  revealSelectedAssetBrowserItem(state.selectedAssetId);
6187
7305
  }
6188
- lastRenderedAssetBrowserTab = assetBrowserTab;
6189
- lastRenderedBottomDockTab = activeBottomTab;
7306
+ revealPendingStatusDiagnosticAsset(state);
7307
+ lastRenderedAssetBrowserContentKey = activeBottomTab === 'assets' ? assetBrowserContentKey : null;
6190
7308
  lastRenderedSelectedAssetId = state.selectedAssetId ?? null;
6191
7309
  restoreLocalEditorEditableFocus(doc, focusSnapshot);
7310
+ revealPendingStatusDiagnosticPath(state);
6192
7311
  return;
6193
7312
  }
6194
7313
  leftDockTabs.style.display = '';
@@ -6200,12 +7319,7 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
6200
7319
  });
6201
7320
  rightDockTabs.style.display = rightDockVisibility.tabsDisplay;
6202
7321
  const activeBottomTab = panelRegistry.getBottomDockTab();
6203
- const assetBrowserTabChanged = assetBrowserTab !== lastRenderedAssetBrowserTab;
6204
- const bottomDockTabChanged = activeBottomTab !== lastRenderedBottomDockTab;
6205
7322
  const selectedAssetChanged = state.selectedAssetId !== lastRenderedSelectedAssetId;
6206
- const assetBrowserScrollSnapshot = activeBottomTab === 'assets'
6207
- ? assetBrowserViewportReveal.captureScrollSnapshot()
6208
- : { scrollTop: null };
6209
7323
  hierarchyPanel.dataset.editorPanelId = hierarchyDescriptor?.id ?? 'hierarchy';
6210
7324
  inspectorPanel.dataset.editorPanelId = activeRightTab === 'inspector' ? rightDescriptor?.id ?? 'inspector' : 'inspector';
6211
7325
  renderingPanel.dataset.editorPanelId = activeRightTab === 'rendering' ? rightDescriptor?.id ?? 'rendering' : 'rendering';
@@ -6217,28 +7331,44 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
6217
7331
  pluginsPanel.style.display = rightDockVisibility.pluginsDisplay;
6218
7332
  LocalEditorPanels.renderWorkbenchLeftDockTabs(doc, leftDockTabs, 'hierarchy', panelRegistry.getPanels('left'));
6219
7333
  hierarchyController.render(state);
6220
- LocalEditorPanels.renderWorkbenchBottomDockPanel(doc, assetPanel, state, activeBottomTab, panelRegistry.getPanels('bottom'), assetBrowserTab);
6221
- if (activeBottomTab === 'assets' && !assetBrowserTabChanged && !bottomDockTabChanged) {
6222
- assetBrowserViewportReveal.restoreScrollSnapshot(assetBrowserScrollSnapshot);
6223
- }
7334
+ LocalEditorPanels.renderWorkbenchBottomDockPanel(doc, assetPanel, state, activeBottomTab, panelRegistry.getPanels('bottom'), assetBrowserTab, { expandedFolderPaths: assetBrowserExpandedFolderPaths, folderPath: assetBrowserFolderPath, viewMode: assetBrowserViewMode, selectedEntryPath: selectedProjectEntryPath });
7335
+ if (activeBottomTab === 'assets') {
7336
+ assetBrowserFolderPath = assetPanel.dataset.editorAssetBrowserFolderPath ?? assetBrowserFolderPath;
7337
+ }
7338
+ const assetBrowserContentKey = resolveLocalEditorAssetBrowserContentKey({
7339
+ assetFilter: state.assetFilter,
7340
+ folderPath: assetBrowserFolderPath,
7341
+ tab: assetBrowserTab,
7342
+ viewMode: assetBrowserViewMode,
7343
+ });
7344
+ hydrateProjectMediaThumbnails();
7345
+ assetBrowserContinuity.restore(assetBrowserContinuitySnapshot, assetBrowserContentKey, activeBottomTab === 'assets');
6224
7346
  const suppressAssetScroll = state.selectedAssetId
6225
7347
  ? assetBrowserViewportReveal.consumeRevealSuppression(state.selectedAssetId, { clearWhenDifferent: selectedAssetChanged })
6226
7348
  : false;
6227
7349
  if (activeBottomTab === 'assets' && selectedAssetChanged && state.selectedAssetId && !suppressAssetScroll) {
6228
7350
  revealSelectedAssetBrowserItem(state.selectedAssetId);
6229
7351
  }
6230
- lastRenderedAssetBrowserTab = assetBrowserTab;
6231
- lastRenderedBottomDockTab = activeBottomTab;
7352
+ revealPendingStatusDiagnosticAsset(state);
7353
+ lastRenderedAssetBrowserContentKey = activeBottomTab === 'assets' ? assetBrowserContentKey : null;
6232
7354
  lastRenderedSelectedAssetId = state.selectedAssetId;
6233
7355
  LocalEditorPanels.renderWorkbenchRightDockTabs(doc, rightDockTabs, activeRightTab, panelRegistry.getPanels('right'));
6234
- if (activeRightTab === 'inspector') {
7356
+ const rightDockVisible = rightDockFormalSurfaceVisibility.isVisible();
7357
+ if (!rightDockVisible) {
7358
+ LocalEditorPanels.disposeInspectorPanelUi(inspectorPanel);
7359
+ LocalEditorPanels.disposeInspectorPanelUi(renderingPanel);
7360
+ lastRenderedInspectorContentKey = null;
7361
+ }
7362
+ else if (activeRightTab === 'inspector') {
6235
7363
  LocalEditorPanels.renderInspectorPanel(doc, inspectorPanel, state, inspectorFilter, {
6236
7364
  ...options.inspector,
7365
+ layerHost: editorUiLayerHost,
6237
7366
  lockedVectorGroups: lockedInspectorVectorGroups,
6238
7367
  });
7368
+ lastRenderedInspectorContentKey = resolveLocalEditorRightDockContentKey(state, 'inspector', inspectorFilter);
6239
7369
  }
6240
7370
  else if (activeRightTab === 'rendering') {
6241
- LocalEditorPanels.renderRenderingPanel(doc, renderingPanel, state);
7371
+ LocalEditorPanels.renderRenderingPanel(doc, renderingPanel, state, { layerHost: editorUiLayerHost });
6242
7372
  }
6243
7373
  else if (activeRightTab === 'markers') {
6244
7374
  LocalEditorPanels.renderMarkerPanel(doc, markersPanel, state);
@@ -6248,9 +7378,9 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
6248
7378
  }
6249
7379
  restoreLocalEditorEditableFocus(doc, focusSnapshot);
6250
7380
  restoreLocalEditorRightDockScrollSnapshot(rightDockScrollSnapshot, state, activeRightTab, inspectorFilter, inspectorPanel, renderingPanel, markersPanel, pluginsPanel);
7381
+ revealPendingStatusDiagnosticPath(state);
6251
7382
  };
6252
7383
  const completedCleanup = new Set();
6253
- let uiDisposed = false;
6254
7384
  return {
6255
7385
  update(state) {
6256
7386
  render(state);
@@ -6259,22 +7389,21 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
6259
7389
  updateSceneFrameStats(stats) {
6260
7390
  if (currentState)
6261
7391
  currentState = { ...currentState, sceneFrameStats: stats };
6262
- renderSceneFrameRateOverlay(sceneFrameRateOverlay, currentState?.mode === 'editor' && !currentState.prefabStage ? stats : null);
6263
7392
  },
6264
7393
  updatePerformanceStats(stats) {
6265
7394
  if (currentState)
6266
7395
  currentState = { ...currentState, performanceStats: stats };
6267
7396
  renderPerformanceMonitorOverlay(performanceMonitorOverlay, currentState?.mode === 'editor' && !currentState.prefabStage ? stats : null, currentState?.mode === 'editor' && !currentState.prefabStage && performanceMonitorOpen);
6268
7397
  },
6269
- getPrefabComparisonPreviewSurfaces() {
6270
- return readPrefabComparisonPreviewSurfaces(prefabComparisonPreviewOverlay);
6271
- },
6272
7398
  alert(input) {
6273
7399
  return modalDialog.alert(input);
6274
7400
  },
6275
7401
  confirm(input) {
6276
7402
  return modalDialog.confirm(input);
6277
7403
  },
7404
+ choose(input) {
7405
+ return modalDialog.choose(input);
7406
+ },
6278
7407
  setTheme(theme) {
6279
7408
  setActiveTheme(theme);
6280
7409
  },
@@ -6282,7 +7411,10 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
6282
7411
  return activeTheme;
6283
7412
  },
6284
7413
  dispose() {
6285
- if (uiDisposed)
7414
+ if (canSkipLocalEditorPreviewCleanupPass(uiDisposed, [
7415
+ projectModelPreviewCleanupRegistry,
7416
+ materialPreviewCleanupRegistry,
7417
+ ]))
6286
7418
  return;
6287
7419
  const errors = [];
6288
7420
  const run = (key, operation) => {
@@ -6315,7 +7447,14 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
6315
7447
  run('toolbar-overflow-resize', () => {
6316
7448
  doc.defaultView?.removeEventListener('resize', scheduleToolbarOverflowLayout);
6317
7449
  });
7450
+ run('project-media-preview-request', () => {
7451
+ projectMediaPreviewRequestId += 1;
7452
+ assetPreviewOpen = false;
7453
+ });
6318
7454
  run('host-chrome', () => hostChrome.remove());
7455
+ run('inspector-ui', () => LocalEditorPanels.disposeInspectorPanelUi(inspectorPanel));
7456
+ run('rendering-ui', () => LocalEditorPanels.disposeInspectorPanelUi(renderingPanel));
7457
+ run('editor-ui-layer-host', () => editorUiLayerHost.dispose());
6319
7458
  run('workbench-root', () => workbench.root.remove());
6320
7459
  run('local-test-menu', () => localTestMenu.remove());
6321
7460
  run('editor-status-center', () => editorStatusCenter.remove());
@@ -6327,14 +7466,25 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
6327
7466
  run('overlay-settings-popover', () => overlaySettingsPopover.remove());
6328
7467
  run('spatial-overlay', () => spatialOverlay.root.remove());
6329
7468
  run('measurement-overlay', () => measurementOverlay.root.remove());
6330
- run('scene-frame-rate-overlay', () => sceneFrameRateOverlay.root.remove());
6331
7469
  run('performance-monitor-overlay', () => performanceMonitorOverlay.root.remove());
6332
7470
  run('prefab-stage-preview-layout', () => prefabStagePreviewLayout.root.remove());
6333
7471
  run('box-selection-overlay', () => boxSelectionOverlay.remove());
6334
7472
  run('shortcut-help-panel', () => shortcutHelpPanel.remove());
7473
+ run('project-model-preview', () => disposeProjectModelPreview());
7474
+ run('project-media-thumbnails', () => resetProjectMediaThumbnailCache());
7475
+ run('project-model-thumbnail-cache', () => projectModelThumbnailCache.dispose());
7476
+ run('material-preview', () => disposeMaterialPreview());
6335
7477
  run('asset-preview-modal', () => assetPreviewModal.remove());
7478
+ run('project-file-preview-modal', () => projectFilePreviewModal.remove());
7479
+ run('project-file-preview-search-frame', () => {
7480
+ if (projectFilePreviewSearchRaf != null) {
7481
+ doc.defaultView?.cancelAnimationFrame(projectFilePreviewSearchRaf);
7482
+ projectFilePreviewSearchRaf = null;
7483
+ }
7484
+ });
6336
7485
  run('asset-picker-modal', () => assetPickerModal.remove());
6337
7486
  run('hierarchy-controller', () => hierarchyController.dispose());
7487
+ run('editor-console', () => editorConsole.dispose());
6338
7488
  run('workbench-layout-controller', () => workbenchLayoutController.dispose());
6339
7489
  run('tooltip-controller', () => tooltipController.dispose());
6340
7490
  run('context-menu', () => contextMenu.dispose());
@@ -6342,12 +7492,20 @@ function createLocalEditorBrowserUiImplementation(options, construction) {
6342
7492
  run('input-router', () => inputRouter.dispose());
6343
7493
  run('document-keydown', () => doc.removeEventListener('keydown', onKeyDown));
6344
7494
  run('owned-root-children', () => construction.removeMountedRootChildren());
7495
+ projectModelPreviewCleanupRegistry.disposeOwned();
7496
+ materialPreviewCleanupRegistry.disposeOwned();
7497
+ const retainedPreviewCleanups = [
7498
+ ...projectModelPreviewCleanupRegistry.takeFailures(),
7499
+ ...materialPreviewCleanupRegistry.takeFailures(),
7500
+ ];
7501
+ errors.push(...retainedPreviewCleanups);
6345
7502
  if (errors.length > 0) {
6346
7503
  const error = new Error('Local Editor browser UI cleanup failed.');
6347
7504
  error.errors = errors;
6348
7505
  throw error;
6349
7506
  }
6350
- uiDisposed = true;
7507
+ uiDisposed = !projectModelPreviewCleanupRegistry.hasOwned()
7508
+ && !materialPreviewCleanupRegistry.hasOwned();
6351
7509
  },
6352
7510
  };
6353
7511
  }