@roomle/web-sdk 3.7.0-alpha.3 → 3.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/{BufferGeometry-C696z6r3.mjs → BufferGeometry-BzmfTBQt.mjs} +1 -1
- package/lib/{BufferGeometry-C696z6r3.mjs.map → BufferGeometry-BzmfTBQt.mjs.map} +1 -1
- package/lib/ConfiguratorKernel.wasm +0 -0
- package/lib/{GLTFExporter-AfQIvZAD.mjs → GLTFExporter-CyhgWPq0.mjs} +2 -2
- package/lib/{GLTFExporter-AfQIvZAD.mjs.map → GLTFExporter-CyhgWPq0.mjs.map} +1 -1
- package/lib/{PointLightHelper-wVSmrAnD.mjs → PointLightHelper-DwIXACyT.mjs} +2 -2
- package/lib/{PointLightHelper-wVSmrAnD.mjs.map → PointLightHelper-DwIXACyT.mjs.map} +1 -1
- package/lib/RoomleCore.js +2 -2
- package/lib/RoomleCore.wasm +0 -0
- package/lib/RoomleToolsCore.wasm +0 -0
- package/lib/{SpotLightHelper-C7J95t4f.mjs → SpotLightHelper-CfLHM7LU.mjs} +2 -2
- package/lib/{SpotLightHelper-C7J95t4f.mjs.map → SpotLightHelper-CfLHM7LU.mjs.map} +1 -1
- package/lib/{USDZExporter-BBk0APeK.mjs → USDZExporter-kmxcTvnQ.mjs} +2 -2
- package/lib/{USDZExporter-BBk0APeK.mjs.map → USDZExporter-kmxcTvnQ.mjs.map} +1 -1
- package/lib/{api-DgXsyN04.mjs → api-X1dDTDvL.mjs} +2 -2
- package/lib/{api-DgXsyN04.mjs.map → api-X1dDTDvL.mjs.map} +1 -1
- package/lib/asset-loader.worker-A7nEeQB4.mjs.map +1 -1
- package/lib/{banana-for-scale-D8t2dmc7.mjs → banana-for-scale-Bpf8RfLi.mjs} +4 -4
- package/lib/{banana-for-scale-D8t2dmc7.mjs.map → banana-for-scale-Bpf8RfLi.mjs.map} +1 -1
- package/lib/budgeteer.sw-CQWYbQSc.mjs.map +1 -1
- package/lib/budgeteer.sw.js +1 -1
- package/lib/{common-utils-qErzZAiR.mjs → common-utils-DMI8Yuhe.mjs} +5 -3
- package/lib/common-utils-DMI8Yuhe.mjs.map +1 -0
- package/lib/{component-dimensioning-DlB7-9Om.mjs → component-dimensioning-MtS9xiY-.mjs} +15 -15
- package/lib/{component-dimensioning-DlB7-9Om.mjs.map → component-dimensioning-MtS9xiY-.mjs.map} +1 -1
- package/lib/{component-raycast-helper-C6ptEb0K.mjs → component-raycast-helper-C1qWqpRH.mjs} +13 -9
- package/lib/component-raycast-helper-C1qWqpRH.mjs.map +1 -0
- package/lib/configurator-C5t3clCx.mjs +2 -0
- package/lib/{configurator-CmMBHkyd.mjs → configurator-Cg1a9XSL.mjs} +4 -4
- package/lib/{configurator-CmMBHkyd.mjs.map → configurator-Cg1a9XSL.mjs.map} +1 -1
- package/lib/{continuous-drawing-helper-BwulJHKj.mjs → continuous-drawing-helper-CQx5Sbns.mjs} +3 -3
- package/lib/{continuous-drawing-helper-BwulJHKj.mjs.map → continuous-drawing-helper-CQx5Sbns.mjs.map} +1 -1
- package/lib/{dat.gui.module-CZHqOVGq.mjs → dat.gui.module-CZ-DIWHM.mjs} +1 -1
- package/lib/{dat.gui.module-CZHqOVGq.mjs.map → dat.gui.module-CZ-DIWHM.mjs.map} +1 -1
- package/lib/{decorate-BAtqSPNS.mjs → decorate-Bck1_lG8.mjs} +1 -1
- package/lib/{decorate-BAtqSPNS.mjs.map → decorate-Bck1_lG8.mjs.map} +1 -1
- package/lib/dimensioning-helper-Bfe0fImX.mjs +2 -0
- package/lib/{dimensioning-helper--Y0Y-Wr1.mjs → dimensioning-helper-GPn7Z8GE.mjs} +7 -7
- package/lib/{dimensioning-helper--Y0Y-Wr1.mjs.map → dimensioning-helper-GPn7Z8GE.mjs.map} +1 -1
- package/lib/glb-viewer-DIEpkrvY.mjs +2 -0
- package/lib/{glb-viewer-Cs3i0yb8.mjs → glb-viewer-tgKOPCaI.mjs} +44 -45
- package/lib/glb-viewer-tgKOPCaI.mjs.map +1 -0
- package/lib/highlight-coordinator-DRHeEU-E.mjs +116 -0
- package/lib/highlight-coordinator-DRHeEU-E.mjs.map +1 -0
- package/lib/{homag-intelligence-CBZujG1I.mjs → homag-intelligence-D5mCTWgG.mjs} +19 -11
- package/lib/homag-intelligence-D5mCTWgG.mjs.map +1 -0
- package/lib/{imos-ix-poc-export-helper-CW7QZhhn.mjs → imos-ix-poc-export-helper-BKFs_Yhm.mjs} +5 -5
- package/lib/{imos-ix-poc-export-helper-CW7QZhhn.mjs.map → imos-ix-poc-export-helper-BKFs_Yhm.mjs.map} +1 -1
- package/lib/kernel-C7YDLxq8.mjs.map +1 -1
- package/lib/{kernel-utils-DCnHzW4n.mjs → kernel-utils-B80amC-l.mjs} +2 -2
- package/lib/{kernel-utils-DCnHzW4n.mjs.map → kernel-utils-B80amC-l.mjs.map} +1 -1
- package/lib/{layer-CFAr2mK_.mjs → layer-BfckfWZz.mjs} +1 -1
- package/lib/{layer-CFAr2mK_.mjs.map → layer-BfckfWZz.mjs.map} +1 -1
- package/lib/{main-_HtiLIhS.mjs → main-CJ5TNhBt.mjs} +2484 -2533
- package/lib/main-CJ5TNhBt.mjs.map +1 -0
- package/lib/{material-viewer-BCjg687R.mjs → material-viewer-DCqZzMZN.mjs} +40 -35
- package/lib/material-viewer-DCqZzMZN.mjs.map +1 -0
- package/lib/packages-DuOz6rk6.mjs +4 -0
- package/lib/{planner-OYwMFSWo.mjs → planner-CSboZram.mjs} +3 -3
- package/lib/{planner-OYwMFSWo.mjs.map → planner-CSboZram.mjs.map} +1 -1
- package/lib/planner-CWPqJktz.mjs +2 -0
- package/lib/{plugin-system-DInww4H_.mjs → plugin-system-DD0Z9Jvt.mjs} +3 -3
- package/lib/{plugin-system-DInww4H_.mjs.map → plugin-system-DD0Z9Jvt.mjs.map} +1 -1
- package/lib/{roomle-headless-setup-LoBO7UJe.mjs → roomle-headless-setup-nsoGENQV.mjs} +1 -1
- package/lib/{roomle-headless-setup-LoBO7UJe.mjs.map → roomle-headless-setup-nsoGENQV.mjs.map} +1 -1
- package/lib/roomle-headless.d.ts +185 -63
- package/lib/roomle-headless.js +9 -9
- package/lib/{roomle-renderer-DVlJsHYn.mjs → roomle-renderer-BEJNPCKx.mjs} +2 -2
- package/lib/roomle-renderer-BEJNPCKx.mjs.map +1 -0
- package/lib/roomle-sdk.d.ts +185 -63
- package/lib/roomle-sdk.js +6 -6
- package/lib/roomle-webgpu-renderer-D5flithq.mjs +1502 -0
- package/lib/roomle-webgpu-renderer-D5flithq.mjs.map +1 -0
- package/lib/{scene-renderer-BHZrQYAH.mjs → scene-renderer-Dm1kij1z.mjs} +26 -26
- package/lib/scene-renderer-Dm1kij1z.mjs.map +1 -0
- package/lib/{script-loader-X4I-gQl2.mjs → script-loader-DqaDm1FG.mjs} +3 -3
- package/lib/{script-loader-X4I-gQl2.mjs.map → script-loader-DqaDm1FG.mjs.map} +1 -1
- package/lib/static/packages/workers/generated/budgeteer.sw.js +1 -1
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/package.json +1 -1
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/configuratorCallback.d.ts +2 -2
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/configuratorCallback.js +1 -1
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/configuratorCallback.js.map +1 -1
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/configuratorCoreInterface.d.ts +18 -6
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/configuratorUtils.js +15 -11
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/configuratorUtils.js.map +1 -1
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/plannerCoreCallback.d.ts +1 -1
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/plannerCoreCallback.js +1 -1
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/plannerCoreCallback.js.map +1 -1
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/embind/plannerCoreInterface.d.ts +21 -12
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/loader/planElementManager.js +1 -1
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/src/loader/planElementManager.js.map +1 -1
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/wasm_modern/ConfiguratorKernel.wasm +0 -0
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/wasm_modern/RoomleCore.js +2 -2
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/wasm_modern/RoomleCore.wasm +0 -0
- package/lib/static/roomle-core-hsc/node_modules/roomle-core-hsc/wasm_modern/RoomleToolsCore.wasm +0 -0
- package/lib/{stats-helper-Cv5SoEWT.mjs → stats-helper-D7a7oxnj.mjs} +3 -3
- package/lib/{stats-helper-Cv5SoEWT.mjs.map → stats-helper-D7a7oxnj.mjs.map} +1 -1
- package/lib/{three.core-mM-jZdgg.mjs → three.core-BmQnspOL.mjs} +819 -816
- package/lib/{three.core-mM-jZdgg.mjs.map → three.core-BmQnspOL.mjs.map} +1 -1
- package/lib/{three.module-Bmy3sVQ-.mjs → three.module-DkrZwaid.mjs} +455 -455
- package/lib/{three.module-Bmy3sVQ-.mjs.map → three.module-DkrZwaid.mjs.map} +1 -1
- package/lib/{three.webgpu-BbVYfCDp.mjs → three.webgpu-DLZjhIYv.mjs} +1517 -1517
- package/lib/{three.webgpu-BbVYfCDp.mjs.map → three.webgpu-DLZjhIYv.mjs.map} +1 -1
- package/lib/three.webgpu-RkQxSIwG.mjs +3 -0
- package/lib/{threejs-utils-Bq4pVWBA.mjs → threejs-utils-CrK_gp1x.mjs} +67 -63
- package/lib/{threejs-utils-Bq4pVWBA.mjs.map → threejs-utils-CrK_gp1x.mjs.map} +1 -1
- package/lib/{tools-core-BRzDdhLJ.mjs → tools-core-CZWgXTFV.mjs} +3 -3
- package/lib/{tools-core-BRzDdhLJ.mjs.map → tools-core-CZWgXTFV.mjs.map} +1 -1
- package/package.json +1 -1
- package/lib/common-utils-qErzZAiR.mjs.map +0 -1
- package/lib/component-raycast-helper-C6ptEb0K.mjs.map +0 -1
- package/lib/component-raycast-helper-LrhRpeDD.mjs +0 -2
- package/lib/configurator-DtvX4JqP.mjs +0 -2
- package/lib/dimensioning-helper-BpUreWo2.mjs +0 -2
- package/lib/glb-viewer-Cs3i0yb8.mjs.map +0 -1
- package/lib/glb-viewer-Dcllu_oG.mjs +0 -2
- package/lib/homag-intelligence-CBZujG1I.mjs.map +0 -1
- package/lib/main-_HtiLIhS.mjs.map +0 -1
- package/lib/material-viewer-BCjg687R.mjs.map +0 -1
- package/lib/packages-BhrPUb9k.mjs +0 -4
- package/lib/planner-CDJtTG3g.mjs +0 -2
- package/lib/roomle-renderer-DVlJsHYn.mjs.map +0 -1
- package/lib/roomle-webgpu-renderer-CVxBRv6o.mjs +0 -217
- package/lib/roomle-webgpu-renderer-CVxBRv6o.mjs.map +0 -1
- package/lib/scene-renderer-BHZrQYAH.mjs.map +0 -1
- package/lib/three.webgpu-Bnp8Whu8.mjs +0 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roomle-webgpu-renderer-D5flithq.mjs","names":["NodeUpdateType"],"sources":["../../../../node_modules/three/build/three.tsl.js","../../../../node_modules/three/examples/jsm/tsl/display/OutlineNode.js","../../packages/common-core/src/webgpu/passes/roomle-webgpu-render-pass.ts","../../packages/common-core/src/webgpu/passes/outline-render-pass.ts","../../../../node_modules/three/examples/jsm/inspector/RendererInspector.js","../../../../node_modules/three/examples/jsm/inspector/ui/Style.js","../../../../node_modules/three/examples/jsm/inspector/ui/Profiler.js","../../../../node_modules/three/examples/jsm/inspector/ui/Tab.js","../../../../node_modules/three/examples/jsm/inspector/ui/List.js","../../../../node_modules/three/examples/jsm/inspector/ui/Graph.js","../../../../node_modules/three/examples/jsm/inspector/ui/Item.js","../../../../node_modules/three/examples/jsm/inspector/ui/utils.js","../../../../node_modules/three/examples/jsm/inspector/tabs/Performance.js","../../../../node_modules/three/examples/jsm/inspector/tabs/Console.js","../../../../node_modules/three/examples/jsm/inspector/ui/Values.js","../../../../node_modules/three/examples/jsm/inspector/tabs/Parameters.js","../../../../node_modules/three/examples/jsm/inspector/tabs/Viewer.js","../../../../node_modules/three/examples/jsm/inspector/Inspector.js","../../packages/common-core/src/webgpu/roomle-webgpu-renderer.ts"],"sourcesContent":["/**\n * @license\n * Copyright 2010-2026 Three.js Authors\n * SPDX-License-Identifier: MIT\n */\nimport { TSL } from 'three/webgpu';\n\nconst BRDF_GGX = TSL.BRDF_GGX;\nconst BRDF_Lambert = TSL.BRDF_Lambert;\nconst BasicPointShadowFilter = TSL.BasicPointShadowFilter;\nconst BasicShadowFilter = TSL.BasicShadowFilter;\nconst Break = TSL.Break;\nconst Const = TSL.Const;\nconst Continue = TSL.Continue;\nconst DFGLUT = TSL.DFGLUT;\nconst D_GGX = TSL.D_GGX;\nconst Discard = TSL.Discard;\nconst EPSILON = TSL.EPSILON;\nconst F_Schlick = TSL.F_Schlick;\nconst Fn = TSL.Fn;\nconst INFINITY = TSL.INFINITY;\nconst If = TSL.If;\nconst Loop = TSL.Loop;\nconst NodeAccess = TSL.NodeAccess;\nconst NodeShaderStage = TSL.NodeShaderStage;\nconst NodeType = TSL.NodeType;\nconst NodeUpdateType = TSL.NodeUpdateType;\nconst PCFShadowFilter = TSL.PCFShadowFilter;\nconst PCFSoftShadowFilter = TSL.PCFSoftShadowFilter;\nconst PI = TSL.PI;\nconst PI2 = TSL.PI2;\nconst TWO_PI = TSL.TWO_PI;\nconst HALF_PI = TSL.HALF_PI;\nconst PointShadowFilter = TSL.PointShadowFilter;\nconst Return = TSL.Return;\nconst Schlick_to_F0 = TSL.Schlick_to_F0;\nconst ShaderNode = TSL.ShaderNode;\nconst Stack = TSL.Stack;\nconst Switch = TSL.Switch;\nconst TBNViewMatrix = TSL.TBNViewMatrix;\nconst VSMShadowFilter = TSL.VSMShadowFilter;\nconst V_GGX_SmithCorrelated = TSL.V_GGX_SmithCorrelated;\nconst Var = TSL.Var;\nconst VarIntent = TSL.VarIntent;\nconst abs = TSL.abs;\nconst acesFilmicToneMapping = TSL.acesFilmicToneMapping;\nconst acos = TSL.acos;\nconst add = TSL.add;\nconst addMethodChaining = TSL.addMethodChaining;\nconst addNodeElement = TSL.addNodeElement;\nconst agxToneMapping = TSL.agxToneMapping;\nconst all = TSL.all;\nconst alphaT = TSL.alphaT;\nconst and = TSL.and;\nconst anisotropy = TSL.anisotropy;\nconst anisotropyB = TSL.anisotropyB;\nconst anisotropyT = TSL.anisotropyT;\nconst any = TSL.any;\nconst append = TSL.append;\nconst array = TSL.array;\nconst arrayBuffer = TSL.arrayBuffer;\nconst asin = TSL.asin;\nconst assign = TSL.assign;\nconst atan = TSL.atan;\nconst atomicAdd = TSL.atomicAdd;\nconst atomicAnd = TSL.atomicAnd;\nconst atomicFunc = TSL.atomicFunc;\nconst atomicLoad = TSL.atomicLoad;\nconst atomicMax = TSL.atomicMax;\nconst atomicMin = TSL.atomicMin;\nconst atomicOr = TSL.atomicOr;\nconst atomicStore = TSL.atomicStore;\nconst atomicSub = TSL.atomicSub;\nconst atomicXor = TSL.atomicXor;\nconst attenuationColor = TSL.attenuationColor;\nconst attenuationDistance = TSL.attenuationDistance;\nconst attribute = TSL.attribute;\nconst attributeArray = TSL.attributeArray;\nconst backgroundBlurriness = TSL.backgroundBlurriness;\nconst backgroundIntensity = TSL.backgroundIntensity;\nconst backgroundRotation = TSL.backgroundRotation;\nconst batch = TSL.batch;\nconst bentNormalView = TSL.bentNormalView;\nconst billboarding = TSL.billboarding;\nconst bitAnd = TSL.bitAnd;\nconst bitNot = TSL.bitNot;\nconst bitOr = TSL.bitOr;\nconst bitXor = TSL.bitXor;\nconst bitangentGeometry = TSL.bitangentGeometry;\nconst bitangentLocal = TSL.bitangentLocal;\nconst bitangentView = TSL.bitangentView;\nconst bitangentWorld = TSL.bitangentWorld;\nconst bitcast = TSL.bitcast;\nconst blendBurn = TSL.blendBurn;\nconst blendColor = TSL.blendColor;\nconst blendDodge = TSL.blendDodge;\nconst blendOverlay = TSL.blendOverlay;\nconst blendScreen = TSL.blendScreen;\nconst blur = TSL.blur;\nconst bool = TSL.bool;\nconst buffer = TSL.buffer;\nconst bufferAttribute = TSL.bufferAttribute;\nconst bumpMap = TSL.bumpMap;\nconst builtin = TSL.builtin;\nconst builtinAOContext = TSL.builtinAOContext;\nconst builtinShadowContext = TSL.builtinShadowContext;\nconst bvec2 = TSL.bvec2;\nconst bvec3 = TSL.bvec3;\nconst bvec4 = TSL.bvec4;\nconst bypass = TSL.bypass;\nconst cache = TSL.cache;\nconst call = TSL.call;\nconst cameraFar = TSL.cameraFar;\nconst cameraIndex = TSL.cameraIndex;\nconst cameraNear = TSL.cameraNear;\nconst cameraNormalMatrix = TSL.cameraNormalMatrix;\nconst cameraPosition = TSL.cameraPosition;\nconst cameraProjectionMatrix = TSL.cameraProjectionMatrix;\nconst cameraProjectionMatrixInverse = TSL.cameraProjectionMatrixInverse;\nconst cameraViewMatrix = TSL.cameraViewMatrix;\nconst cameraViewport = TSL.cameraViewport;\nconst cameraWorldMatrix = TSL.cameraWorldMatrix;\nconst cbrt = TSL.cbrt;\nconst cdl = TSL.cdl;\nconst ceil = TSL.ceil;\nconst checker = TSL.checker;\nconst cineonToneMapping = TSL.cineonToneMapping;\nconst clamp = TSL.clamp;\nconst clearcoat = TSL.clearcoat;\nconst clearcoatNormalView = TSL.clearcoatNormalView;\nconst clearcoatRoughness = TSL.clearcoatRoughness;\nconst clipSpace = TSL.clipSpace;\nconst code = TSL.code;\nconst color = TSL.color;\nconst colorSpaceToWorking = TSL.colorSpaceToWorking;\nconst colorToDirection = TSL.colorToDirection;\nconst compute = TSL.compute;\nconst computeKernel = TSL.computeKernel;\nconst computeSkinning = TSL.computeSkinning;\nconst context = TSL.context;\nconst convert = TSL.convert;\nconst convertColorSpace = TSL.convertColorSpace;\nconst convertToTexture = TSL.convertToTexture;\nconst countLeadingZeros = TSL.countLeadingZeros;\nconst countOneBits = TSL.countOneBits;\nconst countTrailingZeros = TSL.countTrailingZeros;\nconst cos = TSL.cos;\nconst cross = TSL.cross;\nconst cubeTexture = TSL.cubeTexture;\nconst cubeTextureBase = TSL.cubeTextureBase;\nconst dFdx = TSL.dFdx;\nconst dFdy = TSL.dFdy;\nconst dashSize = TSL.dashSize;\nconst debug = TSL.debug;\nconst decrement = TSL.decrement;\nconst decrementBefore = TSL.decrementBefore;\nconst defaultBuildStages = TSL.defaultBuildStages;\nconst defaultShaderStages = TSL.defaultShaderStages;\nconst defined = TSL.defined;\nconst degrees = TSL.degrees;\nconst deltaTime = TSL.deltaTime;\nconst densityFog = TSL.densityFog;\nconst densityFogFactor = TSL.densityFogFactor;\nconst depth = TSL.depth;\nconst depthPass = TSL.depthPass;\nconst determinant = TSL.determinant;\nconst difference = TSL.difference;\nconst diffuseColor = TSL.diffuseColor;\nconst directPointLight = TSL.directPointLight;\nconst directionToColor = TSL.directionToColor;\nconst directionToFaceDirection = TSL.directionToFaceDirection;\nconst dispersion = TSL.dispersion;\nconst distance = TSL.distance;\nconst div = TSL.div;\nconst dot = TSL.dot;\nconst drawIndex = TSL.drawIndex;\nconst dynamicBufferAttribute = TSL.dynamicBufferAttribute;\nconst element = TSL.element;\nconst emissive = TSL.emissive;\nconst equal = TSL.equal;\nconst equirectUV = TSL.equirectUV;\nconst exp = TSL.exp;\nconst exp2 = TSL.exp2;\nconst exponentialHeightFogFactor = TSL.exponentialHeightFogFactor;\nconst expression = TSL.expression;\nconst faceDirection = TSL.faceDirection;\nconst faceForward = TSL.faceForward;\nconst faceforward = TSL.faceforward;\nconst float = TSL.float;\nconst floatBitsToInt = TSL.floatBitsToInt;\nconst floatBitsToUint = TSL.floatBitsToUint;\nconst floor = TSL.floor;\nconst fog = TSL.fog;\nconst fract = TSL.fract;\nconst frameGroup = TSL.frameGroup;\nconst frameId = TSL.frameId;\nconst frontFacing = TSL.frontFacing;\nconst fwidth = TSL.fwidth;\nconst gain = TSL.gain;\nconst gapSize = TSL.gapSize;\nconst getConstNodeType = TSL.getConstNodeType;\nconst getCurrentStack = TSL.getCurrentStack;\nconst getDirection = TSL.getDirection;\nconst getDistanceAttenuation = TSL.getDistanceAttenuation;\nconst getGeometryRoughness = TSL.getGeometryRoughness;\nconst getNormalFromDepth = TSL.getNormalFromDepth;\nconst interleavedGradientNoise = TSL.interleavedGradientNoise;\nconst vogelDiskSample = TSL.vogelDiskSample;\nconst getParallaxCorrectNormal = TSL.getParallaxCorrectNormal;\nconst getRoughness = TSL.getRoughness;\nconst getScreenPosition = TSL.getScreenPosition;\nconst getShIrradianceAt = TSL.getShIrradianceAt;\nconst getShadowMaterial = TSL.getShadowMaterial;\nconst getShadowRenderObjectFunction = TSL.getShadowRenderObjectFunction;\nconst getTextureIndex = TSL.getTextureIndex;\nconst getViewPosition = TSL.getViewPosition;\nconst globalId = TSL.globalId;\nconst glsl = TSL.glsl;\nconst glslFn = TSL.glslFn;\nconst grayscale = TSL.grayscale;\nconst greaterThan = TSL.greaterThan;\nconst greaterThanEqual = TSL.greaterThanEqual;\nconst hash = TSL.hash;\nconst highpModelNormalViewMatrix = TSL.highpModelNormalViewMatrix;\nconst highpModelViewMatrix = TSL.highpModelViewMatrix;\nconst hue = TSL.hue;\nconst increment = TSL.increment;\nconst incrementBefore = TSL.incrementBefore;\nconst instance = TSL.instance;\nconst instanceIndex = TSL.instanceIndex;\nconst instancedArray = TSL.instancedArray;\nconst instancedBufferAttribute = TSL.instancedBufferAttribute;\nconst instancedDynamicBufferAttribute = TSL.instancedDynamicBufferAttribute;\nconst instancedMesh = TSL.instancedMesh;\nconst int = TSL.int;\nconst intBitsToFloat = TSL.intBitsToFloat;\nconst inverse = TSL.inverse;\nconst inverseSqrt = TSL.inverseSqrt;\nconst inversesqrt = TSL.inversesqrt;\nconst invocationLocalIndex = TSL.invocationLocalIndex;\nconst invocationSubgroupIndex = TSL.invocationSubgroupIndex;\nconst ior = TSL.ior;\nconst iridescence = TSL.iridescence;\nconst iridescenceIOR = TSL.iridescenceIOR;\nconst iridescenceThickness = TSL.iridescenceThickness;\nconst ivec2 = TSL.ivec2;\nconst ivec3 = TSL.ivec3;\nconst ivec4 = TSL.ivec4;\nconst js = TSL.js;\nconst label = TSL.label;\nconst length = TSL.length;\nconst lengthSq = TSL.lengthSq;\nconst lessThan = TSL.lessThan;\nconst lessThanEqual = TSL.lessThanEqual;\nconst lightPosition = TSL.lightPosition;\nconst lightProjectionUV = TSL.lightProjectionUV;\nconst lightShadowMatrix = TSL.lightShadowMatrix;\nconst lightTargetDirection = TSL.lightTargetDirection;\nconst lightTargetPosition = TSL.lightTargetPosition;\nconst lightViewPosition = TSL.lightViewPosition;\nconst lightingContext = TSL.lightingContext;\nconst lights = TSL.lights;\nconst linearDepth = TSL.linearDepth;\nconst linearToneMapping = TSL.linearToneMapping;\nconst localId = TSL.localId;\nconst log = TSL.log;\nconst log2 = TSL.log2;\nconst logarithmicDepthToViewZ = TSL.logarithmicDepthToViewZ;\nconst luminance = TSL.luminance;\nconst mat2 = TSL.mat2;\nconst mat3 = TSL.mat3;\nconst mat4 = TSL.mat4;\nconst matcapUV = TSL.matcapUV;\nconst materialAO = TSL.materialAO;\nconst materialAlphaTest = TSL.materialAlphaTest;\nconst materialAnisotropy = TSL.materialAnisotropy;\nconst materialAnisotropyVector = TSL.materialAnisotropyVector;\nconst materialAttenuationColor = TSL.materialAttenuationColor;\nconst materialAttenuationDistance = TSL.materialAttenuationDistance;\nconst materialClearcoat = TSL.materialClearcoat;\nconst materialClearcoatNormal = TSL.materialClearcoatNormal;\nconst materialClearcoatRoughness = TSL.materialClearcoatRoughness;\nconst materialColor = TSL.materialColor;\nconst materialDispersion = TSL.materialDispersion;\nconst materialEmissive = TSL.materialEmissive;\nconst materialEnvIntensity = TSL.materialEnvIntensity;\nconst materialEnvRotation = TSL.materialEnvRotation;\nconst materialIOR = TSL.materialIOR;\nconst materialIridescence = TSL.materialIridescence;\nconst materialIridescenceIOR = TSL.materialIridescenceIOR;\nconst materialIridescenceThickness = TSL.materialIridescenceThickness;\nconst materialLightMap = TSL.materialLightMap;\nconst materialLineDashOffset = TSL.materialLineDashOffset;\nconst materialLineDashSize = TSL.materialLineDashSize;\nconst materialLineGapSize = TSL.materialLineGapSize;\nconst materialLineScale = TSL.materialLineScale;\nconst materialLineWidth = TSL.materialLineWidth;\nconst materialMetalness = TSL.materialMetalness;\nconst materialNormal = TSL.materialNormal;\nconst materialOpacity = TSL.materialOpacity;\nconst materialPointSize = TSL.materialPointSize;\nconst materialReference = TSL.materialReference;\nconst materialReflectivity = TSL.materialReflectivity;\nconst materialRefractionRatio = TSL.materialRefractionRatio;\nconst materialRotation = TSL.materialRotation;\nconst materialRoughness = TSL.materialRoughness;\nconst materialSheen = TSL.materialSheen;\nconst materialSheenRoughness = TSL.materialSheenRoughness;\nconst materialShininess = TSL.materialShininess;\nconst materialSpecular = TSL.materialSpecular;\nconst materialSpecularColor = TSL.materialSpecularColor;\nconst materialSpecularIntensity = TSL.materialSpecularIntensity;\nconst materialSpecularStrength = TSL.materialSpecularStrength;\nconst materialThickness = TSL.materialThickness;\nconst materialTransmission = TSL.materialTransmission;\nconst max = TSL.max;\nconst maxMipLevel = TSL.maxMipLevel;\nconst mediumpModelViewMatrix = TSL.mediumpModelViewMatrix;\nconst metalness = TSL.metalness;\nconst min = TSL.min;\nconst mix = TSL.mix;\nconst mixElement = TSL.mixElement;\nconst mod = TSL.mod;\nconst modInt = TSL.modInt;\nconst modelDirection = TSL.modelDirection;\nconst modelNormalMatrix = TSL.modelNormalMatrix;\nconst modelPosition = TSL.modelPosition;\nconst modelRadius = TSL.modelRadius;\nconst modelScale = TSL.modelScale;\nconst modelViewMatrix = TSL.modelViewMatrix;\nconst modelViewPosition = TSL.modelViewPosition;\nconst modelViewProjection = TSL.modelViewProjection;\nconst modelWorldMatrix = TSL.modelWorldMatrix;\nconst modelWorldMatrixInverse = TSL.modelWorldMatrixInverse;\nconst morphReference = TSL.morphReference;\nconst mrt = TSL.mrt;\nconst mul = TSL.mul;\nconst mx_aastep = TSL.mx_aastep;\nconst mx_add = TSL.mx_add;\nconst mx_atan2 = TSL.mx_atan2;\nconst mx_cell_noise_float = TSL.mx_cell_noise_float;\nconst mx_contrast = TSL.mx_contrast;\nconst mx_divide = TSL.mx_divide;\nconst mx_fractal_noise_float = TSL.mx_fractal_noise_float;\nconst mx_fractal_noise_vec2 = TSL.mx_fractal_noise_vec2;\nconst mx_fractal_noise_vec3 = TSL.mx_fractal_noise_vec3;\nconst mx_fractal_noise_vec4 = TSL.mx_fractal_noise_vec4;\nconst mx_frame = TSL.mx_frame;\nconst mx_heighttonormal = TSL.mx_heighttonormal;\nconst mx_hsvtorgb = TSL.mx_hsvtorgb;\nconst mx_ifequal = TSL.mx_ifequal;\nconst mx_ifgreater = TSL.mx_ifgreater;\nconst mx_ifgreatereq = TSL.mx_ifgreatereq;\nconst mx_invert = TSL.mx_invert;\nconst mx_modulo = TSL.mx_modulo;\nconst mx_multiply = TSL.mx_multiply;\nconst mx_noise_float = TSL.mx_noise_float;\nconst mx_noise_vec3 = TSL.mx_noise_vec3;\nconst mx_noise_vec4 = TSL.mx_noise_vec4;\nconst mx_place2d = TSL.mx_place2d;\nconst mx_power = TSL.mx_power;\nconst mx_ramp4 = TSL.mx_ramp4;\nconst mx_ramplr = TSL.mx_ramplr;\nconst mx_ramptb = TSL.mx_ramptb;\nconst mx_rgbtohsv = TSL.mx_rgbtohsv;\nconst mx_rotate2d = TSL.mx_rotate2d;\nconst mx_rotate3d = TSL.mx_rotate3d;\nconst mx_safepower = TSL.mx_safepower;\nconst mx_separate = TSL.mx_separate;\nconst mx_splitlr = TSL.mx_splitlr;\nconst mx_splittb = TSL.mx_splittb;\nconst mx_srgb_texture_to_lin_rec709 = TSL.mx_srgb_texture_to_lin_rec709;\nconst mx_subtract = TSL.mx_subtract;\nconst mx_timer = TSL.mx_timer;\nconst mx_transform_uv = TSL.mx_transform_uv;\nconst mx_unifiednoise2d = TSL.mx_unifiednoise2d;\nconst mx_unifiednoise3d = TSL.mx_unifiednoise3d;\nconst mx_worley_noise_float = TSL.mx_worley_noise_float;\nconst mx_worley_noise_vec2 = TSL.mx_worley_noise_vec2;\nconst mx_worley_noise_vec3 = TSL.mx_worley_noise_vec3;\nconst negate = TSL.negate;\nconst neutralToneMapping = TSL.neutralToneMapping;\nconst nodeArray = TSL.nodeArray;\nconst nodeImmutable = TSL.nodeImmutable;\nconst nodeObject = TSL.nodeObject;\nconst nodeObjectIntent = TSL.nodeObjectIntent;\nconst nodeObjects = TSL.nodeObjects;\nconst nodeProxy = TSL.nodeProxy;\nconst nodeProxyIntent = TSL.nodeProxyIntent;\nconst normalFlat = TSL.normalFlat;\nconst normalGeometry = TSL.normalGeometry;\nconst normalLocal = TSL.normalLocal;\nconst normalMap = TSL.normalMap;\nconst normalView = TSL.normalView;\nconst normalViewGeometry = TSL.normalViewGeometry;\nconst normalWorld = TSL.normalWorld;\nconst normalWorldGeometry = TSL.normalWorldGeometry;\nconst normalize = TSL.normalize;\nconst not = TSL.not;\nconst notEqual = TSL.notEqual;\nconst numWorkgroups = TSL.numWorkgroups;\nconst objectDirection = TSL.objectDirection;\nconst objectGroup = TSL.objectGroup;\nconst objectPosition = TSL.objectPosition;\nconst objectRadius = TSL.objectRadius;\nconst objectScale = TSL.objectScale;\nconst objectViewPosition = TSL.objectViewPosition;\nconst objectWorldMatrix = TSL.objectWorldMatrix;\nconst OnBeforeObjectUpdate = TSL.OnBeforeObjectUpdate;\nconst OnBeforeMaterialUpdate = TSL.OnBeforeMaterialUpdate;\nconst OnObjectUpdate = TSL.OnObjectUpdate;\nconst OnMaterialUpdate = TSL.OnMaterialUpdate;\nconst oneMinus = TSL.oneMinus;\nconst or = TSL.or;\nconst orthographicDepthToViewZ = TSL.orthographicDepthToViewZ;\nconst oscSawtooth = TSL.oscSawtooth;\nconst oscSine = TSL.oscSine;\nconst oscSquare = TSL.oscSquare;\nconst oscTriangle = TSL.oscTriangle;\nconst output = TSL.output;\nconst outputStruct = TSL.outputStruct;\nconst overloadingFn = TSL.overloadingFn;\nconst packHalf2x16 = TSL.packHalf2x16;\nconst packSnorm2x16 = TSL.packSnorm2x16;\nconst packUnorm2x16 = TSL.packUnorm2x16;\nconst parabola = TSL.parabola;\nconst parallaxDirection = TSL.parallaxDirection;\nconst parallaxUV = TSL.parallaxUV;\nconst parameter = TSL.parameter;\nconst pass = TSL.pass;\nconst passTexture = TSL.passTexture;\nconst pcurve = TSL.pcurve;\nconst perspectiveDepthToViewZ = TSL.perspectiveDepthToViewZ;\nconst pmremTexture = TSL.pmremTexture;\nconst pointShadow = TSL.pointShadow;\nconst pointUV = TSL.pointUV;\nconst pointWidth = TSL.pointWidth;\nconst positionGeometry = TSL.positionGeometry;\nconst positionLocal = TSL.positionLocal;\nconst positionPrevious = TSL.positionPrevious;\nconst positionView = TSL.positionView;\nconst positionViewDirection = TSL.positionViewDirection;\nconst positionWorld = TSL.positionWorld;\nconst positionWorldDirection = TSL.positionWorldDirection;\nconst posterize = TSL.posterize;\nconst pow = TSL.pow;\nconst pow2 = TSL.pow2;\nconst pow3 = TSL.pow3;\nconst pow4 = TSL.pow4;\nconst premultiplyAlpha = TSL.premultiplyAlpha;\nconst property = TSL.property;\nconst radians = TSL.radians;\nconst rand = TSL.rand;\nconst range = TSL.range;\nconst rangeFog = TSL.rangeFog;\nconst rangeFogFactor = TSL.rangeFogFactor;\nconst reciprocal = TSL.reciprocal;\nconst reference = TSL.reference;\nconst referenceBuffer = TSL.referenceBuffer;\nconst reflect = TSL.reflect;\nconst reflectVector = TSL.reflectVector;\nconst reflectView = TSL.reflectView;\nconst reflector = TSL.reflector;\nconst refract = TSL.refract;\nconst refractVector = TSL.refractVector;\nconst refractView = TSL.refractView;\nconst reinhardToneMapping = TSL.reinhardToneMapping;\nconst remap = TSL.remap;\nconst remapClamp = TSL.remapClamp;\nconst renderGroup = TSL.renderGroup;\nconst renderOutput = TSL.renderOutput;\nconst rendererReference = TSL.rendererReference;\nconst replaceDefaultUV = TSL.replaceDefaultUV;\nconst rotate = TSL.rotate;\nconst rotateUV = TSL.rotateUV;\nconst roughness = TSL.roughness;\nconst round = TSL.round;\nconst rtt = TSL.rtt;\nconst sRGBTransferEOTF = TSL.sRGBTransferEOTF;\nconst sRGBTransferOETF = TSL.sRGBTransferOETF;\nconst sample = TSL.sample;\nconst sampler = TSL.sampler;\nconst samplerComparison = TSL.samplerComparison;\nconst saturate = TSL.saturate;\nconst saturation = TSL.saturation;\nconst screen = TSL.screen;\nconst screenCoordinate = TSL.screenCoordinate;\nconst screenDPR = TSL.screenDPR;\nconst screenSize = TSL.screenSize;\nconst screenUV = TSL.screenUV;\nconst select = TSL.select;\nconst setCurrentStack = TSL.setCurrentStack;\nconst setName = TSL.setName;\nconst shaderStages = TSL.shaderStages;\nconst shadow = TSL.shadow;\nconst shadowPositionWorld = TSL.shadowPositionWorld;\nconst shapeCircle = TSL.shapeCircle;\nconst sharedUniformGroup = TSL.sharedUniformGroup;\nconst sheen = TSL.sheen;\nconst sheenRoughness = TSL.sheenRoughness;\nconst shiftLeft = TSL.shiftLeft;\nconst shiftRight = TSL.shiftRight;\nconst shininess = TSL.shininess;\nconst sign = TSL.sign;\nconst sin = TSL.sin;\nconst sinc = TSL.sinc;\nconst skinning = TSL.skinning;\nconst smoothstep = TSL.smoothstep;\nconst smoothstepElement = TSL.smoothstepElement;\nconst specularColor = TSL.specularColor;\nconst specularF90 = TSL.specularF90;\nconst spherizeUV = TSL.spherizeUV;\nconst split = TSL.split;\nconst spritesheetUV = TSL.spritesheetUV;\nconst sqrt = TSL.sqrt;\nconst stack = TSL.stack;\nconst step = TSL.step;\nconst stepElement = TSL.stepElement;\nconst storage = TSL.storage;\nconst storageBarrier = TSL.storageBarrier;\nconst storageTexture = TSL.storageTexture;\nconst string = TSL.string;\nconst struct = TSL.struct;\nconst sub = TSL.sub;\nconst subgroupAdd = TSL.subgroupAdd;\nconst subgroupAll = TSL.subgroupAll;\nconst subgroupAnd = TSL.subgroupAnd;\nconst subgroupAny = TSL.subgroupAny;\nconst subgroupBallot = TSL.subgroupBallot;\nconst subgroupBroadcast = TSL.subgroupBroadcast;\nconst subgroupBroadcastFirst = TSL.subgroupBroadcastFirst;\nconst subBuild = TSL.subBuild;\nconst subgroupElect = TSL.subgroupElect;\nconst subgroupExclusiveAdd = TSL.subgroupExclusiveAdd;\nconst subgroupExclusiveMul = TSL.subgroupExclusiveMul;\nconst subgroupInclusiveAdd = TSL.subgroupInclusiveAdd;\nconst subgroupInclusiveMul = TSL.subgroupInclusiveMul;\nconst subgroupIndex = TSL.subgroupIndex;\nconst subgroupMax = TSL.subgroupMax;\nconst subgroupMin = TSL.subgroupMin;\nconst subgroupMul = TSL.subgroupMul;\nconst subgroupOr = TSL.subgroupOr;\nconst subgroupShuffle = TSL.subgroupShuffle;\nconst subgroupShuffleDown = TSL.subgroupShuffleDown;\nconst subgroupShuffleUp = TSL.subgroupShuffleUp;\nconst subgroupShuffleXor = TSL.subgroupShuffleXor;\nconst subgroupSize = TSL.subgroupSize;\nconst subgroupXor = TSL.subgroupXor;\nconst tan = TSL.tan;\nconst tangentGeometry = TSL.tangentGeometry;\nconst tangentLocal = TSL.tangentLocal;\nconst tangentView = TSL.tangentView;\nconst tangentWorld = TSL.tangentWorld;\nconst texture = TSL.texture;\nconst texture3D = TSL.texture3D;\nconst textureBarrier = TSL.textureBarrier;\nconst textureBicubic = TSL.textureBicubic;\nconst textureBicubicLevel = TSL.textureBicubicLevel;\nconst textureCubeUV = TSL.textureCubeUV;\nconst textureLoad = TSL.textureLoad;\nconst textureSize = TSL.textureSize;\nconst textureLevel = TSL.textureLevel;\nconst textureStore = TSL.textureStore;\nconst thickness = TSL.thickness;\nconst time = TSL.time;\nconst toneMapping = TSL.toneMapping;\nconst toneMappingExposure = TSL.toneMappingExposure;\nconst toonOutlinePass = TSL.toonOutlinePass;\nconst transformDirection = TSL.transformDirection;\nconst transformNormal = TSL.transformNormal;\nconst transformNormalToView = TSL.transformNormalToView;\nconst transformedClearcoatNormalView = TSL.transformedClearcoatNormalView;\nconst transformedNormalView = TSL.transformedNormalView;\nconst transformedNormalWorld = TSL.transformedNormalWorld;\nconst transmission = TSL.transmission;\nconst transpose = TSL.transpose;\nconst triNoise3D = TSL.triNoise3D;\nconst triplanarTexture = TSL.triplanarTexture;\nconst triplanarTextures = TSL.triplanarTextures;\nconst trunc = TSL.trunc;\nconst uint = TSL.uint;\nconst uintBitsToFloat = TSL.uintBitsToFloat;\nconst uniform = TSL.uniform;\nconst uniformArray = TSL.uniformArray;\nconst uniformCubeTexture = TSL.uniformCubeTexture;\nconst uniformGroup = TSL.uniformGroup;\nconst uniformFlow = TSL.uniformFlow;\nconst uniformTexture = TSL.uniformTexture;\nconst unpackHalf2x16 = TSL.unpackHalf2x16;\nconst unpackSnorm2x16 = TSL.unpackSnorm2x16;\nconst unpackUnorm2x16 = TSL.unpackUnorm2x16;\nconst unpremultiplyAlpha = TSL.unpremultiplyAlpha;\nconst userData = TSL.userData;\nconst uv = TSL.uv;\nconst uvec2 = TSL.uvec2;\nconst uvec3 = TSL.uvec3;\nconst uvec4 = TSL.uvec4;\nconst varying = TSL.varying;\nconst varyingProperty = TSL.varyingProperty;\nconst vec2 = TSL.vec2;\nconst vec3 = TSL.vec3;\nconst vec4 = TSL.vec4;\nconst vectorComponents = TSL.vectorComponents;\nconst velocity = TSL.velocity;\nconst vertexColor = TSL.vertexColor;\nconst vertexIndex = TSL.vertexIndex;\nconst vertexStage = TSL.vertexStage;\nconst vibrance = TSL.vibrance;\nconst viewZToLogarithmicDepth = TSL.viewZToLogarithmicDepth;\nconst viewZToOrthographicDepth = TSL.viewZToOrthographicDepth;\nconst viewZToPerspectiveDepth = TSL.viewZToPerspectiveDepth;\nconst viewZToReversedOrthographicDepth = TSL.viewZToReversedOrthographicDepth;\nconst viewZToReversedPerspectiveDepth = TSL.viewZToReversedPerspectiveDepth;\nconst viewport = TSL.viewport;\nconst viewportCoordinate = TSL.viewportCoordinate;\nconst viewportDepthTexture = TSL.viewportDepthTexture;\nconst viewportLinearDepth = TSL.viewportLinearDepth;\nconst viewportMipTexture = TSL.viewportMipTexture;\nconst viewportOpaqueMipTexture = TSL.viewportOpaqueMipTexture;\nconst viewportResolution = TSL.viewportResolution;\nconst viewportSafeUV = TSL.viewportSafeUV;\nconst viewportSharedTexture = TSL.viewportSharedTexture;\nconst viewportSize = TSL.viewportSize;\nconst viewportTexture = TSL.viewportTexture;\nconst viewportUV = TSL.viewportUV;\nconst wgsl = TSL.wgsl;\nconst wgslFn = TSL.wgslFn;\nconst workgroupArray = TSL.workgroupArray;\nconst workgroupBarrier = TSL.workgroupBarrier;\nconst workgroupId = TSL.workgroupId;\nconst workingToColorSpace = TSL.workingToColorSpace;\nconst xor = TSL.xor;\n\n/*\n// Use this code to generate the export statements dynamically\n\nlet code = '';\n\nfor ( const key of Object.keys( THREE.TSL ) ) {\n\n\tcode += `export const ${ key } = TSL.${ key };\\n`;\n\n}\n\nlog( code );\n//*/\n\nexport { BRDF_GGX, BRDF_Lambert, BasicPointShadowFilter, BasicShadowFilter, Break, Const, Continue, DFGLUT, D_GGX, Discard, EPSILON, F_Schlick, Fn, HALF_PI, INFINITY, If, Loop, NodeAccess, NodeShaderStage, NodeType, NodeUpdateType, OnBeforeMaterialUpdate, OnBeforeObjectUpdate, OnMaterialUpdate, OnObjectUpdate, PCFShadowFilter, PCFSoftShadowFilter, PI, PI2, PointShadowFilter, Return, Schlick_to_F0, ShaderNode, Stack, Switch, TBNViewMatrix, TWO_PI, VSMShadowFilter, V_GGX_SmithCorrelated, Var, VarIntent, abs, acesFilmicToneMapping, acos, add, addMethodChaining, addNodeElement, agxToneMapping, all, alphaT, and, anisotropy, anisotropyB, anisotropyT, any, append, array, arrayBuffer, asin, assign, atan, atomicAdd, atomicAnd, atomicFunc, atomicLoad, atomicMax, atomicMin, atomicOr, atomicStore, atomicSub, atomicXor, attenuationColor, attenuationDistance, attribute, attributeArray, backgroundBlurriness, backgroundIntensity, backgroundRotation, batch, bentNormalView, billboarding, bitAnd, bitNot, bitOr, bitXor, bitangentGeometry, bitangentLocal, bitangentView, bitangentWorld, bitcast, blendBurn, blendColor, blendDodge, blendOverlay, blendScreen, blur, bool, buffer, bufferAttribute, builtin, builtinAOContext, builtinShadowContext, bumpMap, bvec2, bvec3, bvec4, bypass, cache, call, cameraFar, cameraIndex, cameraNear, cameraNormalMatrix, cameraPosition, cameraProjectionMatrix, cameraProjectionMatrixInverse, cameraViewMatrix, cameraViewport, cameraWorldMatrix, cbrt, cdl, ceil, checker, cineonToneMapping, clamp, clearcoat, clearcoatNormalView, clearcoatRoughness, clipSpace, code, color, colorSpaceToWorking, colorToDirection, compute, computeKernel, computeSkinning, context, convert, convertColorSpace, convertToTexture, cos, countLeadingZeros, countOneBits, countTrailingZeros, cross, cubeTexture, cubeTextureBase, dFdx, dFdy, dashSize, debug, decrement, decrementBefore, defaultBuildStages, defaultShaderStages, defined, degrees, deltaTime, densityFog, densityFogFactor, depth, depthPass, determinant, difference, diffuseColor, directPointLight, directionToColor, directionToFaceDirection, dispersion, distance, div, dot, drawIndex, dynamicBufferAttribute, element, emissive, equal, equirectUV, exp, exp2, exponentialHeightFogFactor, expression, faceDirection, faceForward, faceforward, float, floatBitsToInt, floatBitsToUint, floor, fog, fract, frameGroup, frameId, frontFacing, fwidth, gain, gapSize, getConstNodeType, getCurrentStack, getDirection, getDistanceAttenuation, getGeometryRoughness, getNormalFromDepth, getParallaxCorrectNormal, getRoughness, getScreenPosition, getShIrradianceAt, getShadowMaterial, getShadowRenderObjectFunction, getTextureIndex, getViewPosition, globalId, glsl, glslFn, grayscale, greaterThan, greaterThanEqual, hash, highpModelNormalViewMatrix, highpModelViewMatrix, hue, increment, incrementBefore, instance, instanceIndex, instancedArray, instancedBufferAttribute, instancedDynamicBufferAttribute, instancedMesh, int, intBitsToFloat, interleavedGradientNoise, inverse, inverseSqrt, inversesqrt, invocationLocalIndex, invocationSubgroupIndex, ior, iridescence, iridescenceIOR, iridescenceThickness, ivec2, ivec3, ivec4, js, label, length, lengthSq, lessThan, lessThanEqual, lightPosition, lightProjectionUV, lightShadowMatrix, lightTargetDirection, lightTargetPosition, lightViewPosition, lightingContext, lights, linearDepth, linearToneMapping, localId, log, log2, logarithmicDepthToViewZ, luminance, mat2, mat3, mat4, matcapUV, materialAO, materialAlphaTest, materialAnisotropy, materialAnisotropyVector, materialAttenuationColor, materialAttenuationDistance, materialClearcoat, materialClearcoatNormal, materialClearcoatRoughness, materialColor, materialDispersion, materialEmissive, materialEnvIntensity, materialEnvRotation, materialIOR, materialIridescence, materialIridescenceIOR, materialIridescenceThickness, materialLightMap, materialLineDashOffset, materialLineDashSize, materialLineGapSize, materialLineScale, materialLineWidth, materialMetalness, materialNormal, materialOpacity, materialPointSize, materialReference, materialReflectivity, materialRefractionRatio, materialRotation, materialRoughness, materialSheen, materialSheenRoughness, materialShininess, materialSpecular, materialSpecularColor, materialSpecularIntensity, materialSpecularStrength, materialThickness, materialTransmission, max, maxMipLevel, mediumpModelViewMatrix, metalness, min, mix, mixElement, mod, modInt, modelDirection, modelNormalMatrix, modelPosition, modelRadius, modelScale, modelViewMatrix, modelViewPosition, modelViewProjection, modelWorldMatrix, modelWorldMatrixInverse, morphReference, mrt, mul, mx_aastep, mx_add, mx_atan2, mx_cell_noise_float, mx_contrast, mx_divide, mx_fractal_noise_float, mx_fractal_noise_vec2, mx_fractal_noise_vec3, mx_fractal_noise_vec4, mx_frame, mx_heighttonormal, mx_hsvtorgb, mx_ifequal, mx_ifgreater, mx_ifgreatereq, mx_invert, mx_modulo, mx_multiply, mx_noise_float, mx_noise_vec3, mx_noise_vec4, mx_place2d, mx_power, mx_ramp4, mx_ramplr, mx_ramptb, mx_rgbtohsv, mx_rotate2d, mx_rotate3d, mx_safepower, mx_separate, mx_splitlr, mx_splittb, mx_srgb_texture_to_lin_rec709, mx_subtract, mx_timer, mx_transform_uv, mx_unifiednoise2d, mx_unifiednoise3d, mx_worley_noise_float, mx_worley_noise_vec2, mx_worley_noise_vec3, negate, neutralToneMapping, nodeArray, nodeImmutable, nodeObject, nodeObjectIntent, nodeObjects, nodeProxy, nodeProxyIntent, normalFlat, normalGeometry, normalLocal, normalMap, normalView, normalViewGeometry, normalWorld, normalWorldGeometry, normalize, not, notEqual, numWorkgroups, objectDirection, objectGroup, objectPosition, objectRadius, objectScale, objectViewPosition, objectWorldMatrix, oneMinus, or, orthographicDepthToViewZ, oscSawtooth, oscSine, oscSquare, oscTriangle, output, outputStruct, overloadingFn, packHalf2x16, packSnorm2x16, packUnorm2x16, parabola, parallaxDirection, parallaxUV, parameter, pass, passTexture, pcurve, perspectiveDepthToViewZ, pmremTexture, pointShadow, pointUV, pointWidth, positionGeometry, positionLocal, positionPrevious, positionView, positionViewDirection, positionWorld, positionWorldDirection, posterize, pow, pow2, pow3, pow4, premultiplyAlpha, property, radians, rand, range, rangeFog, rangeFogFactor, reciprocal, reference, referenceBuffer, reflect, reflectVector, reflectView, reflector, refract, refractVector, refractView, reinhardToneMapping, remap, remapClamp, renderGroup, renderOutput, rendererReference, replaceDefaultUV, rotate, rotateUV, roughness, round, rtt, sRGBTransferEOTF, sRGBTransferOETF, sample, sampler, samplerComparison, saturate, saturation, screen, screenCoordinate, screenDPR, screenSize, screenUV, select, setCurrentStack, setName, shaderStages, shadow, shadowPositionWorld, shapeCircle, sharedUniformGroup, sheen, sheenRoughness, shiftLeft, shiftRight, shininess, sign, sin, sinc, skinning, smoothstep, smoothstepElement, specularColor, specularF90, spherizeUV, split, spritesheetUV, sqrt, stack, step, stepElement, storage, storageBarrier, storageTexture, string, struct, sub, subBuild, subgroupAdd, subgroupAll, subgroupAnd, subgroupAny, subgroupBallot, subgroupBroadcast, subgroupBroadcastFirst, subgroupElect, subgroupExclusiveAdd, subgroupExclusiveMul, subgroupInclusiveAdd, subgroupInclusiveMul, subgroupIndex, subgroupMax, subgroupMin, subgroupMul, subgroupOr, subgroupShuffle, subgroupShuffleDown, subgroupShuffleUp, subgroupShuffleXor, subgroupSize, subgroupXor, tan, tangentGeometry, tangentLocal, tangentView, tangentWorld, texture, texture3D, textureBarrier, textureBicubic, textureBicubicLevel, textureCubeUV, textureLevel, textureLoad, textureSize, textureStore, thickness, time, toneMapping, toneMappingExposure, toonOutlinePass, transformDirection, transformNormal, transformNormalToView, transformedClearcoatNormalView, transformedNormalView, transformedNormalWorld, transmission, transpose, triNoise3D, triplanarTexture, triplanarTextures, trunc, uint, uintBitsToFloat, uniform, uniformArray, uniformCubeTexture, uniformFlow, uniformGroup, uniformTexture, unpackHalf2x16, unpackSnorm2x16, unpackUnorm2x16, unpremultiplyAlpha, userData, uv, uvec2, uvec3, uvec4, varying, varyingProperty, vec2, vec3, vec4, vectorComponents, velocity, vertexColor, vertexIndex, vertexStage, vibrance, viewZToLogarithmicDepth, viewZToOrthographicDepth, viewZToPerspectiveDepth, viewZToReversedOrthographicDepth, viewZToReversedPerspectiveDepth, viewport, viewportCoordinate, viewportDepthTexture, viewportLinearDepth, viewportMipTexture, viewportOpaqueMipTexture, viewportResolution, viewportSafeUV, viewportSharedTexture, viewportSize, viewportTexture, viewportUV, vogelDiskSample, wgsl, wgslFn, workgroupArray, workgroupBarrier, workgroupId, workingToColorSpace, xor };\n","import { DepthTexture, FloatType, RenderTarget, Vector2, TempNode, QuadMesh, NodeMaterial, RendererUtils, NodeUpdateType } from 'three/webgpu';\nimport { Loop, int, exp, min, float, mul, uv, vec2, vec3, Fn, textureSize, orthographicDepthToViewZ, screenUV, nodeObject, uniform, vec4, passTexture, texture, perspectiveDepthToViewZ, positionView, reference } from 'three/tsl';\n\nconst _quadMesh = /*@__PURE__*/ new QuadMesh();\nconst _size = /*@__PURE__*/ new Vector2();\nconst _BLUR_DIRECTION_X = /*@__PURE__*/ new Vector2( 1.0, 0.0 );\nconst _BLUR_DIRECTION_Y = /*@__PURE__*/ new Vector2( 0.0, 1.0 );\n\nlet _rendererState;\n\n/**\n * Post processing node for rendering outlines around selected objects. The node\n * gives you great flexibility in composing the final outline look depending on\n * your requirements.\n * ```js\n * const renderPipeline = new THREE.RenderPipeline( renderer );\n *\n * const scenePass = pass( scene, camera );\n *\n * // outline parameter\n *\n * const edgeStrength = uniform( 3.0 );\n * const edgeGlow = uniform( 0.0 );\n * const edgeThickness = uniform( 1.0 );\n * const visibleEdgeColor = uniform( new THREE.Color( 0xffffff ) );\n * const hiddenEdgeColor = uniform( new THREE.Color( 0x4e3636 ) );\n *\n * outlinePass = outline( scene, camera, {\n * \tselectedObjects,\n * \tedgeGlow,\n * \tedgeThickness\n * } );\n *\n * // compose custom outline\n *\n * const { visibleEdge, hiddenEdge } = outlinePass;\n * const outlineColor = visibleEdge.mul( visibleEdgeColor ).add( hiddenEdge.mul( hiddenEdgeColor ) ).mul( edgeStrength );\n *\n * renderPipeline.outputNode = outlineColor.add( scenePass );\n * ```\n *\n * @augments TempNode\n * @three_import import { outline } from 'three/addons/tsl/display/OutlineNode.js';\n */\nclass OutlineNode extends TempNode {\n\n\tstatic get type() {\n\n\t\treturn 'OutlineNode';\n\n\t}\n\n\t/**\n\t * Constructs a new outline node.\n\t *\n\t * @param {Scene} scene - A reference to the scene.\n\t * @param {Camera} camera - The camera the scene is rendered with.\n\t * @param {Object} params - The configuration parameters.\n\t * @param {Array<Object3D>} [params.selectedObjects] - An array of selected objects.\n\t * @param {Node<float>} [params.edgeThickness=float(1)] - The thickness of the edges.\n\t * @param {Node<float>} [params.edgeGlow=float(0)] - Can be used for an animated glow/pulse effects.\n\t * @param {number} [params.downSampleRatio=2] - The downsample ratio.\n\t */\n\tconstructor( scene, camera, params = {} ) {\n\n\t\tsuper( 'vec4' );\n\n\t\tconst {\n\t\t\tselectedObjects = [],\n\t\t\tedgeThickness = float( 1 ),\n\t\t\tedgeGlow = float( 0 ),\n\t\t\tdownSampleRatio = 2\n\t\t} = params;\n\n\t\t/**\n\t\t * A reference to the scene.\n\t\t *\n\t\t * @type {Scene}\n\t\t */\n\t\tthis.scene = scene;\n\n\t\t/**\n\t\t * The camera the scene is rendered with.\n\t\t *\n\t\t * @type {Camera}\n\t\t */\n\t\tthis.camera = camera;\n\n\t\t/**\n\t\t * An array of selected objects.\n\t\t *\n\t\t * @type {Array<Object3D>}\n\t\t */\n\t\tthis.selectedObjects = selectedObjects;\n\n\t\t/**\n\t\t * The thickness of the edges.\n\t\t *\n\t\t * @type {Node<float>}\n\t\t */\n\t\tthis.edgeThicknessNode = nodeObject( edgeThickness );\n\n\t\t/**\n\t\t * Can be used for an animated glow/pulse effect.\n\t\t *\n\t\t * @type {Node<float>}\n\t\t */\n\t\tthis.edgeGlowNode = nodeObject( edgeGlow );\n\n\t\t/**\n\t\t * The downsample ratio.\n\t\t *\n\t\t * @type {number}\n\t\t * @default 2\n\t\t */\n\t\tthis.downSampleRatio = downSampleRatio;\n\n\t\t/**\n\t\t * The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node renders\n\t\t * its effect once per frame in `updateBefore()`.\n\t\t *\n\t\t * @type {string}\n\t\t * @default 'frame'\n\t\t */\n\t\tthis.updateBeforeType = NodeUpdateType.FRAME;\n\n\t\t// render targets\n\n\t\t/**\n\t\t * The render target for the depth pre-pass.\n\t\t *\n\t\t * @private\n\t\t * @type {RenderTarget}\n\t\t */\n\t\tthis._renderTargetDepthBuffer = new RenderTarget();\n\t\tthis._renderTargetDepthBuffer.depthTexture = new DepthTexture();\n\t\tthis._renderTargetDepthBuffer.depthTexture.type = FloatType;\n\n\t\t/**\n\t\t * The render target for the mask pass.\n\t\t *\n\t\t * @private\n\t\t * @type {RenderTarget}\n\t\t */\n\t\tthis._renderTargetMaskBuffer = new RenderTarget();\n\n\t\t/**\n\t\t * The render target for the mask downsample.\n\t\t *\n\t\t * @private\n\t\t * @type {RenderTarget}\n\t\t */\n\t\tthis._renderTargetMaskDownSampleBuffer = new RenderTarget( 1, 1, { depthBuffer: false } );\n\n\t\t/**\n\t\t * The first render target for the edge detection.\n\t\t *\n\t\t * @private\n\t\t * @type {RenderTarget}\n\t\t */\n\t\tthis._renderTargetEdgeBuffer1 = new RenderTarget( 1, 1, { depthBuffer: false } );\n\n\t\t/**\n\t\t * The second render target for the edge detection.\n\t\t *\n\t\t * @private\n\t\t * @type {RenderTarget}\n\t\t */\n\t\tthis._renderTargetEdgeBuffer2 = new RenderTarget( 1, 1, { depthBuffer: false } );\n\n\t\t/**\n\t\t * The first render target for the blur pass.\n\t\t *\n\t\t * @private\n\t\t * @type {RenderTarget}\n\t\t */\n\t\tthis._renderTargetBlurBuffer1 = new RenderTarget( 1, 1, { depthBuffer: false } );\n\n\t\t/**\n\t\t * The second render target for the blur pass.\n\t\t *\n\t\t * @private\n\t\t * @type {RenderTarget}\n\t\t */\n\t\tthis._renderTargetBlurBuffer2 = new RenderTarget( 1, 1, { depthBuffer: false } );\n\n\t\t/**\n\t\t * The render target for the final composite.\n\t\t *\n\t\t * @private\n\t\t * @type {RenderTarget}\n\t\t */\n\t\tthis._renderTargetComposite = new RenderTarget( 1, 1, { depthBuffer: false } );\n\n\t\t// uniforms\n\n\t\t/**\n\t\t * Represents the near value of the scene's camera.\n\t\t *\n\t\t * @private\n\t\t * @type {ReferenceNode<float>}\n\t\t */\n\t\tthis._cameraNear = reference( 'near', 'float', camera );\n\n\t\t/**\n\t\t * Represents the far value of the scene's camera.\n\t\t *\n\t\t * @private\n\t\t * @type {ReferenceNode<float>}\n\t\t */\n\t\tthis._cameraFar = reference( 'far', 'float', camera );\n\n\t\t/**\n\t\t * Uniform that represents the blur direction of the pass.\n\t\t *\n\t\t * @private\n\t\t * @type {UniformNode<vec2>}\n\t\t */\n\t\tthis._blurDirection = uniform( new Vector2() );\n\n\t\t/**\n\t\t * Texture node that holds the data from the depth pre-pass.\n\t\t *\n\t\t * @private\n\t\t * @type {TextureNode}\n\t\t */\n\t\tthis._depthTextureUniform = texture( this._renderTargetDepthBuffer.depthTexture );\n\n\t\t/**\n\t\t * Texture node that holds the data from the mask pass.\n\t\t *\n\t\t * @private\n\t\t * @type {TextureNode}\n\t\t */\n\t\tthis._maskTextureUniform = texture( this._renderTargetMaskBuffer.texture );\n\n\t\t/**\n\t\t * Texture node that holds the data from the mask downsample pass.\n\t\t *\n\t\t * @private\n\t\t * @type {TextureNode}\n\t\t */\n\t\tthis._maskTextureDownsSampleUniform = texture( this._renderTargetMaskDownSampleBuffer.texture );\n\n\t\t/**\n\t\t * Texture node that holds the data from the first edge detection pass.\n\t\t *\n\t\t * @private\n\t\t * @type {TextureNode}\n\t\t */\n\t\tthis._edge1TextureUniform = texture( this._renderTargetEdgeBuffer1.texture );\n\n\t\t/**\n\t\t * Texture node that holds the data from the second edge detection pass.\n\t\t *\n\t\t * @private\n\t\t * @type {TextureNode}\n\t\t */\n\t\tthis._edge2TextureUniform = texture( this._renderTargetEdgeBuffer2.texture );\n\n\t\t/**\n\t\t * Texture node that holds the current blurred color data.\n\t\t *\n\t\t * @private\n\t\t * @type {TextureNode}\n\t\t */\n\t\tthis._blurColorTextureUniform = texture( this._renderTargetEdgeBuffer1.texture );\n\n\t\t// constants\n\n\t\t/**\n\t\t * Visible edge color.\n\t\t *\n\t\t * @private\n\t\t * @type {Node<vec3>}\n\t\t */\n\t\tthis._visibleEdgeColor = vec3( 1, 0, 0 );\n\n\t\t/**\n\t\t * Hidden edge color.\n\t\t *\n\t\t * @private\n\t\t * @type {Node<vec3>}\n\t\t */\n\t\tthis._hiddenEdgeColor = vec3( 0, 1, 0 );\n\n\t\t// materials\n\n\t\t/**\n\t\t * The material for the depth pre-pass.\n\t\t *\n\t\t * @private\n\t\t * @type {NodeMaterial}\n\t\t */\n\t\tthis._depthMaterial = new NodeMaterial();\n\t\tthis._depthMaterial.fragmentNode = vec4( 0, 0, 0, 1 );\n\t\tthis._depthMaterial.name = 'OutlineNode.depth';\n\n\t\t/**\n\t\t * The material for preparing the mask.\n\t\t *\n\t\t * @private\n\t\t * @type {NodeMaterial}\n\t\t */\n\t\tthis._prepareMaskMaterial = new NodeMaterial();\n\t\tthis._prepareMaskMaterial.name = 'OutlineNode.prepareMask';\n\n\t\t/**\n\t\t * The copy material\n\t\t *\n\t\t * @private\n\t\t * @type {NodeMaterial}\n\t\t */\n\t\tthis._materialCopy = new NodeMaterial();\n\t\tthis._materialCopy.name = 'OutlineNode.copy';\n\n\t\t/**\n\t\t * The edge detection material.\n\t\t *\n\t\t * @private\n\t\t * @type {NodeMaterial}\n\t\t */\n\t\tthis._edgeDetectionMaterial = new NodeMaterial();\n\t\tthis._edgeDetectionMaterial.name = 'OutlineNode.edgeDetection';\n\n\t\t/**\n\t\t * The material that is used to render in the blur pass.\n\t\t *\n\t\t * @private\n\t\t * @type {NodeMaterial}\n\t\t */\n\t\tthis._separableBlurMaterial = new NodeMaterial();\n\t\tthis._separableBlurMaterial.name = 'OutlineNode.separableBlur';\n\n\t\t/**\n\t\t * The material that is used to render in the blur pass.\n\t\t *\n\t\t * @private\n\t\t * @type {NodeMaterial}\n\t\t */\n\t\tthis._separableBlurMaterial2 = new NodeMaterial();\n\t\tthis._separableBlurMaterial2.name = 'OutlineNode.separableBlur2';\n\n\t\t/**\n\t\t * The final composite material.\n\t\t *\n\t\t * @private\n\t\t * @type {NodeMaterial}\n\t\t */\n\t\tthis._compositeMaterial = new NodeMaterial();\n\t\tthis._compositeMaterial.name = 'OutlineNode.composite';\n\n\t\t/**\n\t\t * A set to cache selected objects in the scene.\n\t\t *\n\t\t * @private\n\t\t * @type {Set<Object3D>}\n\t\t */\n\t\tthis._selectionCache = new Set();\n\n\t\t/**\n\t\t * The result of the effect is represented as a separate texture node.\n\t\t *\n\t\t * @private\n\t\t * @type {PassTextureNode}\n\t\t */\n\t\tthis._textureNode = passTexture( this, this._renderTargetComposite.texture );\n\n\t}\n\n\t/**\n\t * A mask value that represents the visible edge.\n\t *\n\t * @return {Node<float>} The visible edge.\n\t */\n\tget visibleEdge() {\n\n\t\treturn this.r;\n\n\t}\n\n\t/**\n\t * A mask value that represents the hidden edge.\n\t *\n\t * @return {Node<float>} The hidden edge.\n\t */\n\tget hiddenEdge() {\n\n\t\treturn this.g;\n\n\t}\n\n\t/**\n\t * Returns the result of the effect as a texture node.\n\t *\n\t * @return {PassTextureNode} A texture node that represents the result of the effect.\n\t */\n\tgetTextureNode() {\n\n\t\treturn this._textureNode;\n\n\t}\n\n\t/**\n\t * Sets the size of the effect.\n\t *\n\t * @param {number} width - The width of the effect.\n\t * @param {number} height - The height of the effect.\n\t */\n\tsetSize( width, height ) {\n\n\t\tthis._renderTargetDepthBuffer.setSize( width, height );\n\t\tthis._renderTargetMaskBuffer.setSize( width, height );\n\t\tthis._renderTargetComposite.setSize( width, height );\n\n\t\t// downsample 1\n\n\t\tlet resx = Math.round( width / this.downSampleRatio );\n\t\tlet resy = Math.round( height / this.downSampleRatio );\n\n\t\tthis._renderTargetMaskDownSampleBuffer.setSize( resx, resy );\n\t\tthis._renderTargetEdgeBuffer1.setSize( resx, resy );\n\t\tthis._renderTargetBlurBuffer1.setSize( resx, resy );\n\n\t\t// downsample 2\n\n\t\tresx = Math.round( resx / 2 );\n\t\tresy = Math.round( resy / 2 );\n\n\t\tthis._renderTargetEdgeBuffer2.setSize( resx, resy );\n\t\tthis._renderTargetBlurBuffer2.setSize( resx, resy );\n\n\t}\n\n\t/**\n\t * This method is used to render the effect once per frame.\n\t *\n\t * @param {NodeFrame} frame - The current node frame.\n\t */\n\tupdateBefore( frame ) {\n\n\t\tconst { renderer } = frame;\n\t\tconst { camera, scene } = this;\n\n\t\t_rendererState = RendererUtils.resetRendererAndSceneState( renderer, scene, _rendererState );\n\n\t\t//\n\n\t\tconst size = renderer.getDrawingBufferSize( _size );\n\t\tthis.setSize( size.width, size.height );\n\n\t\t//\n\n\t\trenderer.setClearColor( 0xffffff, 1 );\n\n\t\tthis._updateSelectionCache();\n\n\t\tconst currentSceneName = scene.name;\n\n\t\t// 1. Draw non-selected objects in the depth buffer\n\n\t\tscene.overrideMaterial = this._depthMaterial;\n\n\t\trenderer.setRenderTarget( this._renderTargetDepthBuffer );\n\t\trenderer.setRenderObjectFunction( ( object, ...params ) => {\n\n\t\t\tif ( this._selectionCache.has( object ) === false ) {\n\n\t\t\t\trenderer.renderObject( object, ...params );\n\n\t\t\t}\n\n\t\t} );\n\n\t\tscene.name = 'Outline [ Non-Selected Objects Pass ]';\n\t\trenderer.render( scene, camera );\n\n\t\t// 2. Draw only the selected objects by comparing the depth buffer of non-selected objects\n\n\t\tscene.overrideMaterial = this._prepareMaskMaterial;\n\n\t\trenderer.setRenderTarget( this._renderTargetMaskBuffer );\n\t\trenderer.setRenderObjectFunction( ( object, ...params ) => {\n\n\t\t\tif ( this._selectionCache.has( object ) === true ) {\n\n\t\t\t\trenderer.renderObject( object, ...params );\n\n\t\t\t}\n\n\t\t} );\n\n\t\tscene.name = 'Outline [ Selected Objects Pass ]';\n\t\trenderer.render( scene, camera );\n\n\t\t//\n\n\t\trenderer.setRenderObjectFunction( _rendererState.renderObjectFunction );\n\n\t\tthis._selectionCache.clear();\n\n\t\tscene.name = currentSceneName;\n\n\t\t// 3. Downsample to (at least) half resolution\n\n\t\t_quadMesh.material = this._materialCopy;\n\t\t_quadMesh.name = 'Outline [ Downsample ]';\n\t\trenderer.setRenderTarget( this._renderTargetMaskDownSampleBuffer );\n\t\t_quadMesh.render( renderer );\n\n\t\t// 4. Perform edge detection (half resolution)\n\n\t\t_quadMesh.material = this._edgeDetectionMaterial;\n\t\t_quadMesh.name = 'Outline [ Edge Detection ]';\n\t\trenderer.setRenderTarget( this._renderTargetEdgeBuffer1 );\n\t\t_quadMesh.render( renderer );\n\n\t\t// 5. Apply blur (half resolution)\n\n\t\tthis._blurColorTextureUniform.value = this._renderTargetEdgeBuffer1.texture;\n\t\tthis._blurDirection.value.copy( _BLUR_DIRECTION_X );\n\n\t\t_quadMesh.material = this._separableBlurMaterial;\n\t\t_quadMesh.name = 'Outline [ Blur Half Resolution ]';\n\t\trenderer.setRenderTarget( this._renderTargetBlurBuffer1 );\n\t\t_quadMesh.render( renderer );\n\n\t\tthis._blurColorTextureUniform.value = this._renderTargetBlurBuffer1.texture;\n\t\tthis._blurDirection.value.copy( _BLUR_DIRECTION_Y );\n\n\t\trenderer.setRenderTarget( this._renderTargetEdgeBuffer1 );\n\t\t_quadMesh.render( renderer );\n\n\t\t// 6. Apply blur (quarter resolution)\n\n\t\tthis._blurColorTextureUniform.value = this._renderTargetEdgeBuffer1.texture;\n\t\tthis._blurDirection.value.copy( _BLUR_DIRECTION_X );\n\n\t\t_quadMesh.material = this._separableBlurMaterial2;\n\t\t_quadMesh.name = 'Outline [ Blur Quarter Resolution ]';\n\t\trenderer.setRenderTarget( this._renderTargetBlurBuffer2 );\n\t\t_quadMesh.render( renderer );\n\n\t\tthis._blurColorTextureUniform.value = this._renderTargetBlurBuffer2.texture;\n\t\tthis._blurDirection.value.copy( _BLUR_DIRECTION_Y );\n\n\t\trenderer.setRenderTarget( this._renderTargetEdgeBuffer2 );\n\t\t_quadMesh.render( renderer );\n\n\t\t// 7. Composite\n\n\t\t_quadMesh.material = this._compositeMaterial;\n\t\t_quadMesh.name = 'Outline [ Blur Quarter Resolution ]';\n\t\trenderer.setRenderTarget( this._renderTargetComposite );\n\t\t_quadMesh.render( renderer );\n\n\t\t// restore\n\n\t\tRendererUtils.restoreRendererAndSceneState( renderer, scene, _rendererState );\n\n\t}\n\n\t/**\n\t * This method is used to setup the effect's TSL code.\n\t *\n\t * @param {NodeBuilder} builder - The current node builder.\n\t * @return {PassTextureNode}\n\t */\n\tsetup() {\n\n\t\t// prepare mask material\n\n\t\tconst prepareMask = () => {\n\n\t\t\tconst depth = this._depthTextureUniform.sample( screenUV );\n\n\t\t\tlet viewZNode;\n\n\t\t\tif ( this.camera.isPerspectiveCamera ) {\n\n\t\t\t\tviewZNode = perspectiveDepthToViewZ( depth, this._cameraNear, this._cameraFar );\n\n\t\t\t} else {\n\n\t\t\t\tviewZNode = orthographicDepthToViewZ( depth, this._cameraNear, this._cameraFar );\n\n\t\t\t}\n\n\t\t\tconst depthTest = positionView.z.lessThanEqual( viewZNode ).select( 1, 0 );\n\t\t\treturn vec4( 0.0, depthTest, 1.0, 1.0 );\n\n\t\t};\n\n\t\tthis._prepareMaskMaterial.fragmentNode = prepareMask();\n\t\tthis._prepareMaskMaterial.needsUpdate = true;\n\n\t\t// copy material\n\n\t\tthis._materialCopy.fragmentNode = this._maskTextureUniform;\n\t\tthis._materialCopy.needsUpdate = true;\n\n\t\t// edge detection material\n\n\t\tconst edgeDetection = Fn( () => {\n\n\t\t\tconst resolution = textureSize( this._maskTextureDownsSampleUniform );\n\t\t\tconst invSize = vec2( 1 ).div( resolution ).toVar();\n\t\t\tconst uvOffset = vec4( 1.0, 0.0, 0.0, 1.0 ).mul( vec4( invSize, invSize ) );\n\n\t\t\tconst uvNode = uv();\n\t\t\tconst c1 = this._maskTextureDownsSampleUniform.sample( uvNode.add( uvOffset.xy ) ).toVar();\n\t\t\tconst c2 = this._maskTextureDownsSampleUniform.sample( uvNode.sub( uvOffset.xy ) ).toVar();\n\t\t\tconst c3 = this._maskTextureDownsSampleUniform.sample( uvNode.add( uvOffset.yw ) ).toVar();\n\t\t\tconst c4 = this._maskTextureDownsSampleUniform.sample( uvNode.sub( uvOffset.yw ) ).toVar();\n\n\t\t\tconst diff1 = mul( c1.r.sub( c2.r ), 0.5 );\n\t\t\tconst diff2 = mul( c3.r.sub( c4.r ), 0.5 );\n\t\t\tconst d = vec2( diff1, diff2 ).length();\n\t\t\tconst a1 = min( c1.g, c2.g );\n\t\t\tconst a2 = min( c3.g, c4.g );\n\t\t\tconst visibilityFactor = min( a1, a2 );\n\t\t\tconst edgeColor = visibilityFactor.oneMinus().greaterThan( 0.001 ).select( this._visibleEdgeColor, this._hiddenEdgeColor );\n\t\t\treturn vec4( edgeColor, 1 ).mul( d );\n\n\t\t} );\n\n\t\tthis._edgeDetectionMaterial.fragmentNode = edgeDetection();\n\t\tthis._edgeDetectionMaterial.needsUpdate = true;\n\n\t\t// separable blur material\n\n\t\tconst MAX_RADIUS = 4;\n\n\t\tconst gaussianPdf = Fn( ( [ x, sigma ] ) => {\n\n\t\t\treturn float( 0.39894 ).mul( exp( float( - 0.5 ).mul( x ).mul( x ).div( sigma.mul( sigma ) ) ).div( sigma ) );\n\n\t\t} );\n\n\t\tconst separableBlur = Fn( ( [ kernelRadius ] ) => {\n\n\t\t\tconst resolution = textureSize( this._maskTextureDownsSampleUniform );\n\t\t\tconst invSize = vec2( 1 ).div( resolution ).toVar();\n\t\t\tconst uvNode = uv();\n\n\t\t\tconst sigma = kernelRadius.div( 2 ).toVar();\n\t\t\tconst weightSum = gaussianPdf( 0, sigma ).toVar();\n\t\t\tconst diffuseSum = this._blurColorTextureUniform.sample( uvNode ).mul( weightSum ).toVar();\n\t\t\tconst delta = this._blurDirection.mul( invSize ).mul( kernelRadius ).div( MAX_RADIUS ).toVar();\n\n\t\t\tconst uvOffset = delta.toVar();\n\n\t\t\tLoop( { start: int( 1 ), end: int( MAX_RADIUS ), type: 'int', condition: '<=' }, ( { i } ) => {\n\n\t\t\t\tconst x = kernelRadius.mul( float( i ) ).div( MAX_RADIUS );\n\t\t\t\tconst w = gaussianPdf( x, sigma );\n\t\t\t\tconst sample1 = this._blurColorTextureUniform.sample( uvNode.add( uvOffset ) );\n\t\t\t\tconst sample2 = this._blurColorTextureUniform.sample( uvNode.sub( uvOffset ) );\n\n\t\t\t\tdiffuseSum.addAssign( sample1.add( sample2 ).mul( w ) );\n\t\t\t\tweightSum.addAssign( w.mul( 2 ) );\n\t\t\t\tuvOffset.addAssign( delta );\n\n\t\t\t} );\n\n\t\t\treturn diffuseSum.div( weightSum );\n\n\t\t} );\n\n\t\tthis._separableBlurMaterial.fragmentNode = separableBlur( this.edgeThicknessNode );\n\t\tthis._separableBlurMaterial.needsUpdate = true;\n\n\t\tthis._separableBlurMaterial2.fragmentNode = separableBlur( MAX_RADIUS );\n\t\tthis._separableBlurMaterial2.needsUpdate = true;\n\n\t\t// composite material\n\n\t\tconst composite = Fn( () => {\n\n\t\t\tconst edgeValue1 = this._edge1TextureUniform;\n\t\t\tconst edgeValue2 = this._edge2TextureUniform;\n\t\t\tconst maskColor = this._maskTextureUniform;\n\n\t\t\tconst edgeValue = edgeValue1.add( edgeValue2.mul( this.edgeGlowNode ) );\n\n\t\t\treturn maskColor.r.mul( edgeValue );\n\n\t\t} );\n\n\t\tthis._compositeMaterial.fragmentNode = composite();\n\t\tthis._compositeMaterial.needsUpdate = true;\n\n\t\treturn this._textureNode;\n\n\t}\n\n\t/**\n\t * Frees internal resources. This method should be called\n\t * when the effect is no longer required.\n\t */\n\tdispose() {\n\n\t\tthis.selectedObjects.length = 0;\n\n\t\tthis._renderTargetDepthBuffer.dispose();\n\t\tthis._renderTargetMaskBuffer.dispose();\n\t\tthis._renderTargetMaskDownSampleBuffer.dispose();\n\t\tthis._renderTargetEdgeBuffer1.dispose();\n\t\tthis._renderTargetEdgeBuffer2.dispose();\n\t\tthis._renderTargetBlurBuffer1.dispose();\n\t\tthis._renderTargetBlurBuffer2.dispose();\n\t\tthis._renderTargetComposite.dispose();\n\n\t\tthis._depthMaterial.dispose();\n\t\tthis._prepareMaskMaterial.dispose();\n\t\tthis._materialCopy.dispose();\n\t\tthis._edgeDetectionMaterial.dispose();\n\t\tthis._separableBlurMaterial.dispose();\n\t\tthis._separableBlurMaterial2.dispose();\n\t\tthis._compositeMaterial.dispose();\n\n\t}\n\n\t/**\n\t * Updates the selection cache based on the selected objects.\n\t *\n\t * @private\n\t */\n\t_updateSelectionCache() {\n\n\t\tfor ( let i = 0; i < this.selectedObjects.length; i ++ ) {\n\n\t\t\tconst selectedObject = this.selectedObjects[ i ];\n\t\t\tselectedObject.traverse( ( object ) => {\n\n\t\t\t\tif ( object.isMesh ) this._selectionCache.add( object );\n\n\t\t\t} );\n\n\t\t}\n\n\t}\n\n}\n\nexport default OutlineNode;\n\n/**\n * TSL function for creating an outline effect around selected objects.\n *\n * @tsl\n * @function\n * @param {Scene} scene - A reference to the scene.\n * @param {Camera} camera - The camera the scene is rendered with.\n * @param {Object} params - The configuration parameters.\n * @param {Array<Object3D>} [params.selectedObjects] - An array of selected objects.\n * @param {Node<float>} [params.edgeThickness=float(1)] - The thickness of the edges.\n * @param {Node<float>} [params.edgeGlow=float(0)] - Can be used for animated glow/pulse effects.\n * @param {number} [params.downSampleRatio=2] - The downsample ratio.\n * @returns {OutlineNode}\n */\nexport const outline = ( scene, camera, params ) => new OutlineNode( scene, camera, params );\n","import type { Node } from 'three/webgpu';\nimport type { Camera, Scene } from 'three';\nimport type { ParametersGroup } from 'three/examples/jsm/inspector/tabs/Parameters.js';\nimport type { WebGPUDebugMode } from '../roomle-webgpu-renderer';\n\nexport abstract class RoomleWebGPURenderPass {\n abstract readonly passId: string;\n\n /**\n * Combines this effect with the passed basePassNode\n */\n abstract assemble(\n basePassNode: Node<'vec4'>,\n scene: Scene,\n camera: Camera,\n debugMode: WebGPUDebugMode,\n ): Node<'vec4'>;\n\n /**\n * mutates the gui by adding the relevant pass settings to it\n */\n abstract addParametersToGUI(\n renderPassSettings: ParametersGroup,\n updateCallback: () => void,\n ): void;\n}\n","import type { Camera, ColorRepresentation, Object3D, Scene } from 'three';\nimport { SRGBColorSpace } from 'three';\nimport type { Node, UniformNode } from 'three/webgpu';\nimport { Color } from 'three';\nimport { uniform, vec4 } from 'three/tsl';\nimport { outline } from 'three/addons/tsl/display/OutlineNode.js';\nimport { RoomleWebGPURenderPass } from './roomle-webgpu-render-pass';\nimport type { ParametersGroup } from 'three/examples/jsm/inspector/tabs/Parameters.js';\nimport type { WebGPUDebugMode } from '../roomle-webgpu-renderer';\n\nexport interface OutlinePassParameters {\n selectedObjects: Object3D[];\n visibleEdgeColor: ColorRepresentation;\n hiddenEdgeColor: ColorRepresentation;\n edgeStrength: number;\n edgeGlow: number;\n edgeThickness: number;\n}\n\nexport class OutlineRenderPass extends RoomleWebGPURenderPass {\n static readonly passId = 'OutlineRenderPass';\n override readonly passId = OutlineRenderPass.passId;\n private readonly selectedObjects: Object3D[];\n private readonly edgeStrength: UniformNode<'float', number>;\n private readonly edgeGlow: UniformNode<'float', number>;\n private readonly edgeThickness: UniformNode<'float', number>;\n private readonly visibleEdgeColor: UniformNode<'color', Color>;\n private readonly hiddenEdgeColor: UniformNode<'color', Color>;\n\n constructor(params: OutlinePassParameters) {\n super();\n this.selectedObjects = params.selectedObjects;\n this.edgeStrength = uniform(params.edgeStrength);\n this.edgeGlow = uniform(params.edgeGlow);\n this.edgeThickness = uniform(params.edgeThickness);\n this.visibleEdgeColor = uniform(new Color(params.visibleEdgeColor));\n this.hiddenEdgeColor = uniform(new Color(params.hiddenEdgeColor));\n }\n\n public highlightObjects(selectedMeshes: Object3D[]): void {\n this.selectedObjects.splice(\n 0,\n this.selectedObjects.length,\n ...selectedMeshes,\n );\n }\n\n public setOutlineColors(\n visibleEdgeColor: ColorRepresentation,\n hiddenEdgeColor: ColorRepresentation,\n ): void {\n this.visibleEdgeColor.value = new Color(visibleEdgeColor);\n this.hiddenEdgeColor.value = new Color(hiddenEdgeColor);\n }\n\n public areObjectsSelected(): boolean {\n return this.selectedObjects.length !== 0;\n }\n\n override assemble(\n basePassNode: Node<'vec4'>,\n scene: Scene,\n camera: Camera,\n debugMode: WebGPUDebugMode,\n ): Node<'vec4'> {\n // dont render outline pass if no objects are selected\n // this should be fixed by threejs themselves at some point, see https://github.com/mrdoob/three.js/issues/33355\n if (!this.areObjectsSelected()) {\n return basePassNode;\n }\n\n const outlinePass = outline(scene, camera, {\n selectedObjects: this.selectedObjects,\n edgeThickness: this.edgeThickness,\n edgeGlow: this.edgeGlow,\n });\n\n const { visibleEdge, hiddenEdge } = outlinePass;\n\n const finalOutline = visibleEdge\n .mul(this.visibleEdgeColor)\n .add(hiddenEdge.mul(this.hiddenEdgeColor))\n .mul(this.edgeStrength);\n\n if (debugMode === 'outline') {\n return vec4(0, 0, 0, 0).add(finalOutline);\n }\n\n return basePassNode.add(finalOutline);\n }\n\n override addParametersToGUI(\n renderPassSettings: ParametersGroup,\n updateCallback: () => void,\n ): void {\n const gui = renderPassSettings.addFolder('Outline Settings');\n gui\n .add(this.edgeStrength, 'value', 0.01, 10)\n .name('edgeStrength')\n .onChange(() => updateCallback());\n gui\n .add(this.edgeGlow, 'value', 0.0, 1)\n .name('edgeGlow')\n .onChange(() => updateCallback());\n gui\n .add(this.edgeThickness, 'value', 1, 4)\n .name('edgeThickness')\n .onChange(() => updateCallback());\n gui\n .addColor(\n { color: this.visibleEdgeColor.value.getHex(SRGBColorSpace) },\n 'color',\n )\n .name('visibleEdgeColor')\n .onChange((value) => {\n this.visibleEdgeColor.value.set(value);\n updateCallback();\n });\n gui\n .addColor(\n { color: this.hiddenEdgeColor.value.getHex(SRGBColorSpace) },\n 'color',\n )\n .name('hiddenEdgeColor')\n .onChange((value) => {\n this.hiddenEdgeColor.value.set(value);\n updateCallback();\n });\n }\n}\n","\nimport { InspectorBase, TimestampQuery, warnOnce } from 'three/webgpu';\n\nclass ObjectStats {\n\n\tconstructor( uid, name ) {\n\n\t\tthis.uid = uid;\n\t\tthis.cid = uid.match( /^(.*):f(\\d+)$/ )[ 1 ]; // call id\n\t\tthis.name = name;\n\t\tthis.timestamp = 0;\n\t\tthis.cpu = 0;\n\t\tthis.gpu = 0;\n\t\tthis.fps = 0;\n\n\t\tthis.children = [];\n\t\tthis.parent = null;\n\n\t}\n\n}\n\nclass RenderStats extends ObjectStats {\n\n\tconstructor( uid, scene, camera, renderTarget ) {\n\n\t\tlet name = scene.name;\n\n\t\tif ( name === '' ) {\n\n\t\t\tif ( scene.isScene ) {\n\n\t\t\t\tname = 'Scene';\n\n\t\t\t} else if ( scene.isQuadMesh ) {\n\n\t\t\t\tname = 'QuadMesh';\n\n\t\t\t}\n\n\t\t}\n\n\t\tsuper( uid, name );\n\n\t\tthis.scene = scene;\n\t\tthis.camera = camera;\n\t\tthis.renderTarget = renderTarget;\n\n\t\tthis.isRenderStats = true;\n\n\t}\n\n}\n\nclass ComputeStats extends ObjectStats {\n\n\tconstructor( uid, computeNode ) {\n\n\t\tsuper( uid, computeNode.name );\n\n\t\tthis.computeNode = computeNode;\n\n\t\tthis.isComputeStats = true;\n\n\t}\n\n}\n\nexport class RendererInspector extends InspectorBase {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.currentFrame = null;\n\t\tthis.currentRender = null;\n\t\tthis.currentNodes = null;\n\t\tthis.lastFrame = null;\n\n\t\tthis.frames = [];\n\t\tthis.framesLib = {};\n\t\tthis.maxFrames = 512;\n\n\t\tthis._lastFinishTime = 0;\n\t\tthis._resolveTimestampPromise = null;\n\n\t\tthis.isRendererInspector = true;\n\n\t}\n\n\tgetParent() {\n\n\t\treturn this.currentRender || this.getFrame();\n\n\t}\n\n\tbegin() {\n\n\t\tthis.currentFrame = this._createFrame();\n\t\tthis.currentRender = this.currentFrame;\n\t\tthis.currentNodes = [];\n\n\t}\n\n\tfinish() {\n\n\t\tconst now = performance.now();\n\n\t\tconst frame = this.currentFrame;\n\t\tframe.finishTime = now;\n\t\tframe.deltaTime = now - ( this._lastFinishTime > 0 ? this._lastFinishTime : now );\n\n\t\tthis.addFrame( frame );\n\n\t\tthis.fps = this._getFPS();\n\n\t\tthis.lastFrame = frame;\n\n\t\tthis.currentFrame = null;\n\t\tthis.currentRender = null;\n\t\tthis.currentNodes = null;\n\n\t\tthis._lastFinishTime = now;\n\n\t}\n\n\t_getFPS() {\n\n\t\tlet frameSum = 0;\n\t\tlet timeSum = 0;\n\n\t\tfor ( let i = this.frames.length - 1; i >= 0; i -- ) {\n\n\t\t\tconst frame = this.frames[ i ];\n\n\t\t\tframeSum ++;\n\t\t\ttimeSum += frame.deltaTime;\n\n\t\t\tif ( timeSum >= 1000 ) break;\n\n\t\t}\n\n\t\treturn ( frameSum * 1000 ) / timeSum;\n\n\t}\n\n\t_createFrame() {\n\n\t\treturn {\n\t\t\tframeId: this.nodeFrame.frameId,\n\t\t\tresolvedCompute: false,\n\t\t\tresolvedRender: false,\n\t\t\tdeltaTime: 0,\n\t\t\tstartTime: performance.now(),\n\t\t\tfinishTime: 0,\n\t\t\tmiscellaneous: 0,\n\t\t\tchildren: [],\n\t\t\trenders: [],\n\t\t\tcomputes: []\n\t\t};\n\n\t}\n\n\tgetFrame() {\n\n\t\treturn this.currentFrame || this.lastFrame;\n\n\t}\n\n\tgetFrameById( frameId ) {\n\n\t\treturn this.framesLib[ frameId ] || null;\n\n\t}\n\n\tresolveViewer() { }\n\n\tresolveFrame( /*frame*/ ) { }\n\n\tasync resolveTimestamp() {\n\n\t\tif ( this._resolveTimestampPromise !== null ) {\n\n\t\t\treturn this._resolveTimestampPromise;\n\n\t\t}\n\n\t\tthis._resolveTimestampPromise = new Promise( ( resolve ) => {\n\n\t\t\trequestAnimationFrame( async () => {\n\n\t\t\t\tconst renderer = this.getRenderer();\n\n\t\t\t\tawait renderer.resolveTimestampsAsync( TimestampQuery.COMPUTE );\n\t\t\t\tawait renderer.resolveTimestampsAsync( TimestampQuery.RENDER );\n\n\t\t\t\tconst computeFrames = renderer.backend.getTimestampFrames( TimestampQuery.COMPUTE );\n\t\t\t\tconst renderFrames = renderer.backend.getTimestampFrames( TimestampQuery.RENDER );\n\n\t\t\t\tconst frameIds = [ ...new Set( [ ...computeFrames, ...renderFrames ] ) ];\n\n\t\t\t\tfor ( const frameId of frameIds ) {\n\n\t\t\t\t\tconst frame = this.getFrameById( frameId );\n\n\t\t\t\t\tif ( frame !== null ) {\n\n\t\t\t\t\t\t// resolve compute timestamps\n\n\t\t\t\t\t\tif ( frame.resolvedCompute === false ) {\n\n\t\t\t\t\t\t\tif ( frame.computes.length > 0 ) {\n\n\t\t\t\t\t\t\t\tif ( computeFrames.includes( frameId ) ) {\n\n\t\t\t\t\t\t\t\t\tfor ( const stats of frame.computes ) {\n\n\t\t\t\t\t\t\t\t\t\tif ( renderer.backend.hasTimestamp( stats.uid ) ) {\n\n\t\t\t\t\t\t\t\t\t\t\tstats.gpu = renderer.backend.getTimestamp( stats.uid );\n\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\tstats.gpu = 0;\n\t\t\t\t\t\t\t\t\t\t\tstats.gpuNotAvailable = true;\n\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tframe.resolvedCompute = true;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tframe.resolvedCompute = true;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// resolve render timestamps\n\n\t\t\t\t\t\tif ( frame.resolvedRender === false ) {\n\n\t\t\t\t\t\t\tif ( frame.renders.length > 0 ) {\n\n\t\t\t\t\t\t\t\tif ( renderFrames.includes( frameId ) ) {\n\n\t\t\t\t\t\t\t\t\tfor ( const stats of frame.renders ) {\n\n\t\t\t\t\t\t\t\t\t\tif ( renderer.backend.hasTimestamp( stats.uid ) ) {\n\n\t\t\t\t\t\t\t\t\t\t\tstats.gpu = renderer.backend.getTimestamp( stats.uid );\n\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\tstats.gpu = 0;\n\t\t\t\t\t\t\t\t\t\t\tstats.gpuNotAvailable = true;\n\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tframe.resolvedRender = true;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tframe.resolvedRender = true;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( frame.resolvedCompute === true && frame.resolvedRender === true ) {\n\n\t\t\t\t\t\t\tthis.resolveFrame( frame );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tthis._resolveTimestampPromise = null;\n\n\t\t\t\tresolve();\n\n\t\t\t} );\n\n\t\t} );\n\n\t\treturn this._resolveTimestampPromise;\n\n\t}\n\n\tget isAvailable() {\n\n\t\tconst renderer = this.getRenderer();\n\n\t\treturn renderer !== null;\n\n\t}\n\n\taddFrame( frame ) {\n\n\t\t// Limit to max frames.\n\n\t\tif ( this.frames.length >= this.maxFrames ) {\n\n\t\t\tconst removedFrame = this.frames.shift();\n\t\t\tdelete this.framesLib[ removedFrame.frameId ];\n\n\t\t}\n\n\t\tthis.frames.push( frame );\n\t\tthis.framesLib[ frame.frameId ] = frame;\n\n\t\tif ( this.isAvailable ) {\n\n\t\t\tthis.resolveViewer();\n\t\t\tthis.resolveTimestamp();\n\n\t\t}\n\n\t}\n\n\tinspect( node ) {\n\n\t\tconst currentNodes = this.currentNodes;\n\n\t\tif ( currentNodes !== null ) {\n\n\t\t\tcurrentNodes.push( node );\n\n\t\t} else {\n\n\t\t\twarnOnce( 'RendererInspector: Unable to inspect node outside of frame scope. Use \"renderer.setAnimationLoop()\".' );\n\n\t\t}\n\n\t}\n\n\tbeginCompute( uid, computeNode ) {\n\n\t\tconst frame = this.getFrame();\n\n\t\tif ( ! frame ) return;\n\n\t\tconst currentCompute = new ComputeStats( uid, computeNode );\n\t\tcurrentCompute.timestamp = performance.now();\n\t\tcurrentCompute.parent = this.currentCompute || this.getParent();\n\n\t\tframe.computes.push( currentCompute );\n\n\t\tif ( this.currentRender !== null ) {\n\n\t\t\tthis.currentRender.children.push( currentCompute );\n\n\t\t} else {\n\n\t\t\tframe.children.push( currentCompute );\n\n\t\t}\n\n\t\tthis.currentCompute = currentCompute;\n\n\t}\n\n\tfinishCompute() {\n\n\t\tconst frame = this.getFrame();\n\n\t\tif ( ! frame ) return;\n\n\t\tconst currentCompute = this.currentCompute;\n\t\tcurrentCompute.cpu = performance.now() - currentCompute.timestamp;\n\n\t\tthis.currentCompute = currentCompute.parent.isComputeStats ? currentCompute.parent : null;\n\n\t}\n\n\tbeginRender( uid, scene, camera, renderTarget ) {\n\n\t\tconst frame = this.getFrame();\n\n\t\tif ( ! frame ) return;\n\n\t\tconst currentRender = new RenderStats( uid, scene, camera, renderTarget );\n\t\tcurrentRender.timestamp = performance.now();\n\t\tcurrentRender.parent = this.getParent();\n\n\t\tframe.renders.push( currentRender );\n\n\t\tif ( this.currentRender !== null ) {\n\n\t\t\tthis.currentRender.children.push( currentRender );\n\n\t\t} else {\n\n\t\t\tframe.children.push( currentRender );\n\n\t\t}\n\n\t\tthis.currentRender = currentRender;\n\n\t}\n\n\tfinishRender() {\n\n\t\tconst frame = this.getFrame();\n\n\t\tif ( ! frame ) return;\n\n\t\tconst currentRender = this.currentRender;\n\t\tcurrentRender.cpu = performance.now() - currentRender.timestamp;\n\n\t\tthis.currentRender = currentRender.parent;\n\n\t}\n\n}\n","export class Style {\n\n\tstatic init() {\n\n\t\tif ( document.getElementById( 'profiler-styles' ) ) return;\n\n\t\tconst css = `\n:root {\n\t--profiler-bg: #1e1e24f5;\n\t--profiler-header-bg: #2a2a33aa;\n\t--profiler-header: #2a2a33;\n\t--profiler-border: #4a4a5a;\n\t--text-primary: #e0e0e0;\n\t--text-secondary: #9a9aab;\n\t--accent-color: #00aaff;\n\t--color-green: #4caf50;\n\t--color-yellow: #ffc107;\n\t--color-red: #f44336;\n\t--font-family: 'Inter', 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n\t--font-mono: 'Fira Code', 'Courier New', Courier, monospace;\n}\n\n@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;600&family=Fira+Code&display=swap');\n\n#profiler-panel *, #profiler-toggle * {\n\ttext-transform: initial;\n\tline-height: normal;\n\tbox-sizing: border-box;\n\t-webkit-font-smoothing: antialiased;\n\t-moz-osx-font-smoothing: grayscale;\n}\n\n#profiler-toggle {\n\tposition: fixed;\n\ttop: 15px;\n\tright: 15px;\n\tbackground-color: rgba(30, 30, 36, 0.85);\n\tborder: 1px solid #4a4a5a54;\n\tborder-radius: 12px 6px 6px 12px;\n\tcolor: var(--text-primary);\n\tcursor: pointer;\n\tz-index: 1001;\n\ttransition: all 0.2s ease-in-out;\n\t/*font-size: 14px;*/\n\tfont-size: 15px;\n\tbackdrop-filter: blur(8px);\n\tbox-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);\n\tdisplay: flex;\n\talign-items: stretch;\n\tpadding: 0;\n\toverflow: hidden;\n\tfont-family: var(--font-family);\n}\n\n#profiler-toggle:hover {\n\tborder-color: var(--accent-color);\n}\n\n#profiler-toggle.hidden {\n\topacity: 0;\n\tpointer-events: none;\n}\n\n#toggle-icon {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 40px;\n\tfont-size: 20px;\n\ttransition: background-color 0.2s;\n}\n\n#profiler-toggle:hover #toggle-icon {\n\tbackground-color: rgba(255, 255, 255, 0.05);\n}\n\n.toggle-separator {\n\twidth: 1px;\n\tbackground-color: var(--profiler-border);\n}\n\n#toggle-text {\n\tdisplay: flex;\n\talign-items: baseline;\n\tpadding: 8px 14px;\n\tmin-width: 80px;\n\tjustify-content: right;\n}\n\n#toggle-text .fps-label {\n\tfont-size: 0.7em;\n\tmargin-left: 10px;\n color: #999;\n}\n\n#builtin-tabs-container {\n\tdisplay: flex;\n\talign-items: stretch;\n\tgap: 0;\n\tborder-right: 1px solid #262636;\n\torder: -1;\n}\n\n.builtin-tab-btn {\n\tbackground: transparent;\n\tborder: none;\n\tcolor: var(--text-secondary);\n\tcursor: pointer;\n\tpadding: 8px 14px;\n\tfont-family: var(--font-family);\n\tfont-size: 13px;\n\tfont-weight: 600;\n\ttransition: all 0.2s;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tmin-width: 32px;\n\tposition: relative;\n}\n\n.builtin-tab-btn svg {\n\twidth: 20px;\n\theight: 20px;\n\tstroke: currentColor;\n}\n\n.builtin-tab-btn:hover {\n\tbackground-color: rgba(255, 255, 255, 0.08);\n\tcolor: var(--accent-color);\n}\n\n.builtin-tab-btn:active {\n\tbackground-color: rgba(255, 255, 255, 0.12);\n}\n\n.builtin-tab-btn.active {\n\tbackground-color: rgba(0, 170, 255, 0.2);\n\tcolor: var(--accent-color);\n}\n\n.builtin-tab-btn.active:hover {\n\tbackground-color: rgba(0, 170, 255, 0.3);\n}\n\n#profiler-mini-panel {\n\tposition: fixed;\n\ttop: 60px;\n\tright: 15px;\n\tbackground-color: rgba(30, 30, 36, 0.85);\n\tborder: 1px solid #4a4a5a54;\n\tborder-radius: 8px;\n\tcolor: var(--text-primary);\n\tz-index: 9999;\n\tbackdrop-filter: blur(8px);\n\tbox-shadow: 0 6px 24px rgba(0, 0, 0, 0.5);\n\tfont-family: var(--font-family);\n\tfont-size: 11px;\n\twidth: 350px;\n\tmax-height: calc(100vh - 100px);\n\toverflow-y: auto;\n\toverflow-x: hidden;\n\tdisplay: none;\n\topacity: 0;\n\ttransform: translateY(-10px) scale(0.98);\n\ttransition: opacity 0.25s cubic-bezier(0.4, 0, 0.2, 1), \n\t transform 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n#profiler-mini-panel.visible {\n\tdisplay: block;\n\topacity: 1;\n\ttransform: translateY(0) scale(1);\n}\n\n#profiler-mini-panel::-webkit-scrollbar {\n\twidth: 6px;\n}\n\n#profiler-mini-panel::-webkit-scrollbar-track {\n\tbackground: transparent;\n}\n\n#profiler-mini-panel::-webkit-scrollbar-thumb {\n\tbackground: rgba(255, 255, 255, 0.15);\n\tborder-radius: 3px;\n\ttransition: background 0.2s;\n}\n\n#profiler-mini-panel::-webkit-scrollbar-thumb:hover {\n\tbackground: rgba(255, 255, 255, 0.25);\n}\n\n.mini-panel-content {\n\tpadding: 0;\n\tfont-size: 11px;\n\tline-height: 1.5;\n\tfont-family: var(--font-mono);\n\tletter-spacing: 0.3px;\n\tuser-select: none;\n\t-webkit-user-select: none;\n}\n\n.mini-panel-content .profiler-content {\n\tdisplay: block !important;\n\tbackground: transparent;\n}\n\n.mini-panel-content .list-scroll-wrapper {\n\tmax-height: calc(100vh - 120px);\n\toverflow-y: auto;\n\toverflow-x: hidden;\n}\n\n.mini-panel-content .list-scroll-wrapper::-webkit-scrollbar {\n\twidth: 4px;\n}\n\n.mini-panel-content .list-scroll-wrapper::-webkit-scrollbar-track {\n\tbackground: transparent;\n}\n\n.mini-panel-content .list-scroll-wrapper::-webkit-scrollbar-thumb {\n\tbackground: rgba(255, 255, 255, 0.1);\n\tborder-radius: 2px;\n}\n\n.mini-panel-content .list-scroll-wrapper::-webkit-scrollbar-thumb:hover {\n\tbackground: rgba(255, 255, 255, 0.2);\n}\n\n.mini-panel-content .parameters {\n\tbackground: transparent;\n\tborder: none;\n\tbox-shadow: none;\n\tpadding: 4px;\n}\n\n.mini-panel-content .list-container.parameters {\n\tpadding: 2px 6px 0px 6px !important;\n}\n\n.mini-panel-content .list-header {\n\tdisplay: none;\n\tpadding: 2px 4px;\n\tfont-size: 11px;\n\tfont-weight: 600;\n\ttext-transform: uppercase;\n\tletter-spacing: 0.5px;\n}\n\n.mini-panel-content .list-item {\n\tborder-bottom: 1px solid rgba(74, 74, 90, 0.2);\n\ttransition: background-color 0.15s;\n}\n\n.mini-panel-content .list-item:last-child {\n\tborder-bottom: none;\n}\n\n.mini-panel-content .list-item:hover {\n\tbackground-color: rgba(255, 255, 255, 0.04);\n}\n\n.mini-panel-content .list-item.actionable:hover {\n\tbackground-color: rgba(255, 255, 255, 0.06);\n\tcursor: pointer;\n}\n\n/* Style adjustments for lil-gui look */\n.mini-panel-content .item-row {\n\tpadding: 3px 8px;\n\tmin-height: 24px;\n}\n\n.mini-panel-content .list-item-row {\n\tpadding: 1px 4px;\n\tgap: 8px;\n\tmin-height: 21px;\n\talign-items: center;\n}\n\n.mini-panel-content input[type=\"checkbox\"] {\n\twidth: 12px;\n\theight: 12px;\n}\n\n.mini-panel-content input[type=\"range\"] {\n\theight: 18px;\n}\n\n.mini-panel-content .value-number input,\n.mini-panel-content .value-slider input {\n\tbackground-color: rgba(0, 0, 0, 0.3);\n\tborder: 1px solid rgba(74, 74, 90, 0.5);\n\tfont-size: 10px;\n}\n\n.mini-panel-content .value-number input:focus,\n.mini-panel-content .value-slider input:focus {\n\tborder-color: var(--accent-color);\n}\n\n.mini-panel-content .value-slider {\n\tgap: 6px;\n}\n\n/* Compact nested items */\n.mini-panel-content .list-item .list-item {\n\tmargin-left: 8px;\n}\n\n.mini-panel-content .list-item .list-item .item-row,\n.mini-panel-content .list-item .list-item .list-item-row {\n\tpadding: 2px 6px;\n\tmin-height: 22px;\n}\n\n/* Compact collapsible headers */\n.mini-panel-content .collapsible .item-row,\n.mini-panel-content .list-item-row.collapsible {\n\tpadding: 2px 8px;\n\tfont-weight: 600;\n\tmin-height: 16px;\n\tdisplay: flex;\n\talign-items: center;\n}\n\n.mini-panel-content .collapsible-icon {\n\tfont-size: 10px;\n\twidth: 14px;\n\theight: 14px;\n}\n\n.mini-panel-content .param-control input[type=\"range\"] {\n\theight: 12px;\n\tmargin-top: 1px;\n\tpadding-top: 5px;\n\tuser-select: none;\n\t-webkit-user-select: none;\n\toutline: none;\n}\n\n.mini-panel-content .param-control input[type=\"range\"]::-webkit-slider-thumb {\n\twidth: 14px;\n\theight: 14px;\n\tmargin-top: -5px;\n\tuser-select: none;\n\t-webkit-user-select: none;\n}\n\n.mini-panel-content .param-control input[type=\"range\"]::-moz-range-thumb {\n\twidth: 14px;\n\theight: 14px;\n\tuser-select: none;\n\t-moz-user-select: none;\n}\n\n.mini-panel-content .list-children-container {\n\tpadding-left: 0;\n}\n\n.mini-panel-content .param-control input[type=\"number\"] {\n\tflex-basis: 60px !important;\n}\n\n.mini-panel-content .param-control {\n\talign-items: center;\n}\n\n.mini-panel-content .param-control select {\n\tfont-size: 11px;\n}\n\n.mini-panel-content .list-item-wrapper {\n\tmargin-top: 0;\n\tmargin-bottom: 0;\n}\n\n#profiler-panel {\n\tposition: fixed;\n\tz-index: 1001 !important;\n\tbottom: 0;\n\tleft: 0;\n\tright: 0;\n\theight: 350px;\n\tbackground-color: var(--profiler-bg);\n\tbackdrop-filter: blur(8px);\n\tborder-top: 2px solid var(--profiler-border);\n\tcolor: var(--text-primary);\n\tdisplay: flex;\n\tflex-direction: column;\n\tz-index: 1000;\n\t/*box-shadow: 0 -5px 25px rgba(0, 0, 0, 0.5);*/\n\ttransform: translateY(100%);\n\ttransition: transform 0.35s cubic-bezier(0.25, 0.46, 0.45, 0.94), height 0.3s ease-out, width 0.3s ease-out;\n\tfont-family: var(--font-mono);\n}\n\n#profiler-panel.resizing,\n#profiler-panel.dragging {\n\ttransition: none;\n}\n\n#profiler-panel.visible {\n\ttransform: translateY(0);\n}\n\n#profiler-panel.maximized {\n\theight: 100vh;\n}\n\n/* Position-specific styles */\n#profiler-panel.position-top {\n\tbottom: auto;\n\ttop: 0;\n\tborder-top: none;\n\tborder-bottom: 2px solid var(--profiler-border);\n\ttransform: translateY(-100%);\n}\n\n#profiler-panel.position-top.visible {\n\ttransform: translateY(0);\n}\n\n#profiler-panel.position-bottom {\n\t/* Default position - already defined above */\n}\n\n#profiler-panel.position-left {\n\ttop: 0;\n\tbottom: 0;\n\tleft: 0;\n\tright: auto;\n\twidth: 350px;\n\theight: 100%;\n\tborder-top: none;\n\tborder-right: 2px solid var(--profiler-border);\n\ttransform: translateX(-100%);\n}\n\n#profiler-panel.position-left.visible {\n\ttransform: translateX(0);\n}\n\n#profiler-panel.position-right {\n\ttop: 0;\n\tbottom: 0;\n\tleft: auto;\n\tright: 0;\n\twidth: 350px;\n\theight: 100%;\n\tborder-top: none;\n\tborder-left: 2px solid var(--profiler-border);\n\ttransform: translateX(100%);\n}\n\n#profiler-panel.position-right.visible {\n\ttransform: translateX(0);\n}\n\n#profiler-panel.position-floating {\n\tborder: 2px solid var(--profiler-border);\n\tborder-radius: 8px;\n\tbox-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);\n\ttransform: none !important;\n\toverflow: hidden;\n}\n\n#profiler-panel.position-floating.visible {\n\ttransform: none !important;\n}\n\n#profiler-panel.position-floating .profiler-header {\n\tborder-radius: 6px 6px 0 0;\n}\n\n#profiler-panel.position-floating .panel-resizer {\n\tbottom: 0;\n\tright: 0;\n\ttop: auto;\n\tleft: auto;\n\twidth: 16px;\n\theight: 16px;\n\tcursor: nwse-resize;\n\tborder-radius: 0 0 6px 0;\n}\n\n#profiler-panel.position-floating .panel-resizer::after {\n\tcontent: '';\n\tposition: absolute;\n\tright: 2px;\n\tbottom: 2px;\n\twidth: 10px;\n\theight: 10px;\n\tbackground: linear-gradient(135deg, transparent 0%, transparent 45%, var(--profiler-border) 45%, var(--profiler-border) 55%, transparent 55%);\n}\n\n\n.panel-resizer {\n\tposition: absolute;\n\ttop: -2px;\n\tleft: 0;\n\twidth: 100%;\n\theight: 5px;\n\tcursor: ns-resize;\n\tz-index: 1001;\n\ttouch-action: none;\n}\n\n#profiler-panel.position-top .panel-resizer {\n\ttop: auto;\n\tbottom: -2px;\n}\n\n#profiler-panel.position-left .panel-resizer {\n\ttop: 0;\n\tleft: auto;\n\tright: -2px;\n\twidth: 5px;\n\theight: 100%;\n\tcursor: ew-resize;\n}\n\n#profiler-panel.position-right .panel-resizer {\n\ttop: 0;\n\tleft: -2px;\n\tright: auto;\n\twidth: 5px;\n\theight: 100%;\n\tcursor: ew-resize;\n}\n\n.profiler-header {\n\tdisplay: flex;\n\tbackground-color: var(--profiler-header-bg);\n\tborder-bottom: 1px solid var(--profiler-border);\n\tflex-shrink: 0;\n\tjustify-content: space-between;\n\talign-items: stretch;\n\n\toverflow-x: auto;\n\toverflow-y: hidden;\n\twidth: calc(100% - 134px);\n\theight: 38px;\n\tuser-select: none;\n\t-webkit-user-select: none;\n}\n\n/* Adjust header width based on panel position */\n#profiler-panel.position-right .profiler-header,\n#profiler-panel.position-left .profiler-header {\n\twidth: calc(100% - 134px);\n}\n\n#profiler-panel.position-bottom .profiler-header,\n#profiler-panel.position-top .profiler-header {\n\twidth: calc(100% - 134px);\n}\n\n/* Adjust header width when position toggle button is hidden (mobile) */\n#profiler-panel.hide-position-toggle .profiler-header {\n\twidth: calc(100% - 90px);\n}\n\n/* ===== RULES FOR WHEN THERE ARE NO TABS ===== */\n\n/* Horizontal mode (bottom/top) without tabs */\n#profiler-panel.position-bottom.no-tabs:not(.maximized),\n#profiler-panel.position-top.no-tabs:not(.maximized) {\n\theight: 38px !important;\n\tmin-height: 38px !important;\n}\n\n#profiler-panel.position-bottom.no-tabs .profiler-header,\n#profiler-panel.position-top.no-tabs .profiler-header {\n\twidth: 100%;\n\theight: 38px;\n\tborder-bottom: none;\n}\n\n#profiler-panel.position-bottom.no-tabs .profiler-content-wrapper,\n#profiler-panel.position-top.no-tabs .profiler-content-wrapper {\n\tdisplay: none;\n}\n\n#profiler-panel.position-bottom.no-tabs .panel-resizer,\n#profiler-panel.position-top.no-tabs .panel-resizer {\n\tdisplay: none;\n}\n\n/* Vertical mode (right/left) without tabs */\n#profiler-panel.position-right.no-tabs:not(.maximized),\n#profiler-panel.position-left.no-tabs:not(.maximized) {\n\twidth: 45px !important;\n\tmin-width: 45px !important;\n}\n\n/* Vertical layout for header when no tabs */\n#profiler-panel.position-right.no-tabs .profiler-header,\n#profiler-panel.position-left.no-tabs .profiler-header {\n\twidth: 100%;\n\tflex-direction: column;\n\theight: 100%;\n\tborder-bottom: none;\n}\n\n/* Vertical layout for controls when no tabs */\n#profiler-panel.position-right.no-tabs .profiler-controls,\n#profiler-panel.position-left.no-tabs .profiler-controls {\n\tposition: static;\n\tflex-direction: column-reverse;\n\tjustify-content: flex-end;\n\twidth: 100%;\n\theight: 100%;\n\tborder-bottom: none;\n\tborder-left: none;\n\tbackground: transparent;\n}\n\n#profiler-panel.position-right.no-tabs .profiler-controls button,\n#profiler-panel.position-left.no-tabs .profiler-controls button {\n\twidth: 100%;\n\theight: 45px;\n\tborder-left: none;\n\tborder-top: none;\n\tborder-bottom: 1px solid var(--profiler-border);\n}\n\n#profiler-panel.position-right.no-tabs .profiler-content-wrapper,\n#profiler-panel.position-left.no-tabs .profiler-content-wrapper {\n\tdisplay: none;\n}\n\n#profiler-panel.position-right.no-tabs .profiler-tabs,\n#profiler-panel.position-left.no-tabs .profiler-tabs {\n\tdisplay: none;\n}\n\n#profiler-panel.position-right.no-tabs .panel-resizer,\n#profiler-panel.position-left.no-tabs .panel-resizer {\n\tdisplay: none;\n}\n\n/* Hide position toggle on mobile without tabs */\n#profiler-panel.hide-position-toggle.position-right.no-tabs:not(.maximized),\n#profiler-panel.hide-position-toggle.position-left.no-tabs:not(.maximized) {\n\twidth: 45px !important;\n\tmin-width: 45px !important;\n}\n\n/* Hide drag indicator on mobile devices */\n#profiler-panel.hide-position-toggle .tab-btn.active::before {\n\tdisplay: none;\n}\n\n.profiler-header::-webkit-scrollbar {\n\twidth: 8px;\n\theight: 8px;\n}\n\n.profiler-header::-webkit-scrollbar-track {\n\tbackground: transparent;\n}\n\n.profiler-header::-webkit-scrollbar-thumb {\n\tbackground-color: rgba(0, 0, 0, 0.25);\n\tborder-radius: 10px;\n\ttransition: background 0.3s ease;\n}\n\n.profiler-header::-webkit-scrollbar-thumb:hover {\n\tbackground-color: rgba(0, 0, 0, 0.4);\n}\n\n.profiler-header::-webkit-scrollbar-corner {\n\tbackground: transparent;\n}\n\n#profiler-panel.dragging .profiler-header {\n\tcursor: grabbing !important;\n}\n\n#profiler-panel.dragging {\n\topacity: 0.8;\n}\n\n.profiler-tabs {\n\tdisplay: flex;\n\tcursor: grab;\n\tposition: relative;\n}\n\n.profiler-tabs:active {\n\tcursor: grabbing;\n}\n\n.profiler-tabs::-webkit-scrollbar {\n\twidth: 8px;\n\theight: 8px;\n}\n\n.profiler-tabs::-webkit-scrollbar-track {\n\tbackground: transparent;\n}\n\n.profiler-tabs::-webkit-scrollbar-thumb {\n\tbackground-color: rgba(0, 0, 0, 0.25);\n\tborder-radius: 10px;\n\ttransition: background 0.3s ease;\n}\n\n.profiler-tabs::-webkit-scrollbar-thumb:hover {\n\tbackground-color: rgba(0, 0, 0, 0.4);\n}\n\n.profiler-tabs::-webkit-scrollbar-corner {\n\tbackground: transparent;\n}\n\n.profiler-controls {\n\tdisplay: flex;\n\tposition: absolute;\n\tright: 0;\n\ttop: 0;\n\theight: 38px;\n\tbackground: var(--profiler-header-bg);\n\tborder-bottom: 1px solid var(--profiler-border);\n}\n\n.tab-btn {\n\tposition: relative;\n\tbackground: transparent;\n\tborder: none;\n\t/*border-right: 1px solid var(--profiler-border);*/\n\tcolor: var(--text-secondary);\n\tpadding: 8px 18px;\n\tcursor: default;\n\tdisplay: flex;\n\talign-items: center;\n\tfont-family: var(--font-family);\n\tfont-weight: 600;\n\tfont-size: 14px;\n\tuser-select: none;\n\ttransition: opacity 0.2s, transform 0.2s;\n\ttouch-action: none;\n}\n\n.tab-btn.active {\n\tborder-bottom: 2px solid var(--accent-color);\n\tcolor: white;\n}\n\n.tab-btn.active::before {\n\tcontent: '⋮⋮';\n\tposition: absolute;\n\tleft: 3px;\n\ttop: calc(50% - 2px);\n\ttransform: translateY(-50%);\n\tcolor: var(--profiler-border);\n\tfont-size: 18px;\n\tletter-spacing: -2px;\n\topacity: 0.6;\n}\n\n.tab-btn.no-detach.active::before {\n\tdisplay: none;\n}\n\n#floating-btn,\n#maximize-btn,\n#hide-panel-btn {\n\tbackground: transparent;\n\tborder: none;\n\tborder-left: 1px solid var(--profiler-border);\n\tcolor: var(--text-secondary);\n\twidth: 45px;\n\theight: 100%;\n\tcursor: pointer;\n\ttransition: all 0.2s;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tflex-shrink: 0;\n}\n\n/* Disable transitions in vertical mode to avoid broken animations */\n#profiler-panel.position-right #floating-btn,\n#profiler-panel.position-right #maximize-btn,\n#profiler-panel.position-right #hide-panel-btn,\n#profiler-panel.position-left #floating-btn,\n#profiler-panel.position-left #maximize-btn,\n#profiler-panel.position-left #hide-panel-btn {\n\ttransition: background-color 0.2s, color 0.2s;\n}\n\n#floating-btn:hover,\n#maximize-btn:hover,\n#hide-panel-btn:hover {\n\tbackground-color: rgba(255, 255, 255, 0.1);\n\tcolor: var(--text-primary);\n}\n\n/* Hide maximize button when there are no tabs */\n#profiler-panel.position-right.no-tabs #maximize-btn,\n#profiler-panel.position-left.no-tabs #maximize-btn,\n#profiler-panel.position-bottom.no-tabs #maximize-btn,\n#profiler-panel.position-top.no-tabs #maximize-btn {\n\tdisplay: none !important;\n}\n\n.profiler-content-wrapper {\n\tflex-grow: 1;\n\toverflow: hidden;\n\tposition: relative;\n}\n\n.profiler-content {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\twidth: 100%;\n\theight: 100%;\n\toverflow-y: auto;\n\tfont-size: 13px;\n\tvisibility: hidden;\n\topacity: 0;\n\ttransition: opacity 0.2s, visibility 0.2s;\n\tbox-sizing: border-box;\n\tdisplay: flex;\n\tflex-direction: column;\n\tuser-select: none;\n\t-webkit-user-select: none;\n}\n\n.profiler-content.active {\n\tvisibility: visible;\n\topacity: 1;\n}\n\n.profiler-content {\n\toverflow: auto; /* make sure scrollbars can appear */\n}\n\n.profiler-content::-webkit-scrollbar {\n\twidth: 8px;\n\theight: 8px;\n}\n\n.profiler-content::-webkit-scrollbar-track {\n\tbackground: transparent;\n}\n\n.profiler-content::-webkit-scrollbar-thumb {\n\tbackground-color: rgba(0, 0, 0, 0.25);\n\tborder-radius: 10px;\n\ttransition: background 0.3s ease;\n}\n\n.profiler-content::-webkit-scrollbar-thumb:hover {\n\tbackground-color: rgba(0, 0, 0, 0.4);\n}\n\n.profiler-content::-webkit-scrollbar-corner {\n\tbackground: transparent;\n}\n\n.profiler-content {\n\tscrollbar-width: thin; /* \"auto\" | \"thin\" */\n\tscrollbar-color: rgba(0, 0, 0, 0.25) transparent;\n}\n\n.list-item-row {\n\tdisplay: grid;\n\talign-items: center;\n\tpadding: 4px 8px;\n\tborder-radius: 3px;\n\ttransition: background-color 0.2s;\n\tgap: 10px;\n\tborder-bottom: none;\n\tuser-select: none;\n\t-webkit-user-select: none;\n}\n\n.parameters .list-item-row {\n\tmin-height: 31px;\n}\n\n.mini-panel-content .parameters .list-item-row {\n\tmin-height: 21px;\n}\n\n.list-item-wrapper {\n\tmargin-top: 2px;\n\tmargin-bottom: 2px;\n\tuser-select: none;\n\t-webkit-user-select: none;\n}\n\n.list-item-wrapper:first-child {\n\t/*margin-top: 0;*/\n}\n\n.list-item-wrapper:not(.header-wrapper):nth-child(odd) > .list-item-row {\n\tbackground-color: rgba(0,0,0,0.1);\n}\n\n.list-item-wrapper.header-wrapper>.list-item-row {\n\tcolor: var(--accent-color);\n\tbackground-color: rgba(0, 170, 255, 0.1);\n}\n\n.list-item-wrapper.header-wrapper>.list-item-row>.list-item-cell:first-child {\n\tfont-weight: 600;\n\tline-height: 1;\n}\n\n.list-item-row.collapsible,\n.list-item-row.actionable {\n\tcursor: pointer;\n}\n\n.list-item-row.collapsible {\n\tbackground-color: rgba(0, 170, 255, 0.15) !important;\n\tmin-height: 23px;\n}\n\n.list-item-row.collapsible.alert,\n.list-item-row.alert {\n\tbackground-color: rgba(244, 67, 54, 0.1) !important;\n}\n\n@media (hover: hover) {\n\n\t.list-item-row:hover:not(.collapsible):not(.no-hover),\n\t.list-item-row:hover:not(.no-hover),\n\t.list-item-row.actionable:hover,\n\t.list-item-row.collapsible.actionable:hover {\n\t\tbackground-color: rgba(255, 255, 255, 0.05) !important;\n\t}\n\n\t.list-item-row.collapsible:hover {\n\t\tbackground-color: rgba(0, 170, 255, 0.25) !important;\n\t}\n\n}\n\n.list-item-cell {\n\twhite-space: pre;\n\tdisplay: flex;\n\talign-items: center;\n\tuser-select: none;\n\t-webkit-user-select: none;\n}\n\n.list-item-cell:not(:first-child) {\n\tjustify-content: flex-end;\n\tfont-weight: 600;\n}\n\n.list-header {\n\tdisplay: grid;\n\talign-items: center;\n\tpadding: 4px 8px;\n\tfont-weight: 600;\n\tcolor: var(--text-secondary);\n\tpadding-bottom: 6px;\n\tborder-bottom: 1px solid var(--profiler-border);\n\tmargin-bottom: 5px;\n\tgap: 10px;\n\tuser-select: none;\n\t-webkit-user-select: none;\n}\n\n.list-item-wrapper.section-start {\n\tmargin-top: 5px;\n\tmargin-bottom: 5px;\n}\n\n.list-header .list-header-cell:not(:first-child) {\n\ttext-align: right;\n}\n\n.list-children-container {\n\tpadding-left: 1.5em;\n\toverflow: hidden;\n\ttransition: max-height 0.1s ease-out;\n\tmargin-top: 2px;\n}\n\n.list-children-container.closed {\n\tmax-height: 0;\n}\n\n.item-toggler {\n\tdisplay: inline-block;\n\tmargin-right: 0.8em;\n\ttext-align: left;\n}\n\n.list-item-row.open .item-toggler::before {\n\tcontent: '-';\n}\n\n.list-item-row:not(.open) .item-toggler::before {\n\tcontent: '+';\n}\n\n.list-item-cell .value.good {\n\tcolor: var(--color-green);\n}\n\n.list-item-cell .value.warn {\n\tcolor: var(--color-yellow);\n}\n\n.list-item-cell .value.bad {\n\tcolor: var(--color-red);\n}\n\n.list-scroll-wrapper {\n\toverflow-x: auto;\n\twidth: 100%;\n\tuser-select: none;\n\t-webkit-user-select: none;\n}\n\n.list-container.parameters .list-item-row:not(.collapsible) {\n}\n\n.graph-container {\n\twidth: 100%;\n\tbox-sizing: border-box;\n\tpadding: 8px 0;\n\tposition: relative;\n}\n\n.graph-svg {\n\twidth: 100%;\n\theight: 80px;\n\tbackground-color: var(--profiler-header);\n\tborder: 1px solid var(--profiler-border);\n\tborder-radius: 4px;\n}\n\n.graph-path {\n\tstroke-width: 2;\n\tfill-opacity: 0.4;\n}\n\n.console-header {\n\tpadding: 10px;\n\tborder-bottom: 1px solid var(--profiler-border);\n\tdisplay: flex;\n\tgap: 20px;\n\tflex-shrink: 0;\n\talign-items: center;\n\tjustify-content: space-between;\n}\n\n.console-buttons-group {\n\tdisplay: flex;\n\tgap: 20px;\n}\n\n.console-filter-input {\n\tbackground-color: var(--profiler-bg);\n\tborder: 1px solid var(--profiler-border);\n\tcolor: var(--text-primary);\n\tborder-radius: 4px;\n\tpadding: 4px 8px;\n\tfont-family: var(--font-mono);\n\tflex-grow: 1;\n\tmax-width: 300px;\n\tborder-radius: 15px;\n}\n\n.console-copy-button {\n\tbackground: transparent;\n\tborder: none;\n\tcolor: var(--text-secondary);\n\tcursor: pointer;\n\tpadding: 4px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tborder-radius: 4px;\n\ttransition: color 0.2s, background-color 0.2s;\n}\n\n.console-copy-button:hover {\n\tcolor: var(--text-primary);\n\tbackground-color: var(--profiler-hover);\n}\n\n.console-copy-button.copied {\n\tcolor: var(--color-green);\n}\n\n#console-log {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n\tpadding: 10px;\n\toverflow-y: auto;\n\tflex-grow: 1;\n\tuser-select: text;\n\t-webkit-user-select: text;\n}\n\n.log-message {\n\tpadding: 2px 5px;\n\twhite-space: pre-wrap;\n\tword-break: break-all;\n\tborder-radius: 3px;\n\tline-height: 1.5 !important;\n}\n\n.log-message.hidden {\n\tdisplay: none;\n}\n\n.log-message.info {\n\tcolor: var(--text-primary);\n}\n\n.log-message.warn {\n\tcolor: var(--color-yellow);\n}\n\n.log-message.error {\n\tcolor: #f9dedc;\n\tbackground-color: rgba(244, 67, 54, 0.1);\n}\n\n.log-prefix {\n\tcolor: var(--text-secondary);\n\tmargin-right: 8px;\n}\n\n.log-code {\n\tbackground-color: rgba(255, 255, 255, 0.1);\n\tborder-radius: 3px;\n\tpadding: 1px 4px;\n}\n\n.thumbnail-container {\n\tdisplay: flex;\n\talign-items: center;\n}\n\n.thumbnail-svg {\n\twidth: 40px;\n\theight: 22.5px;\n\tflex-shrink: 0;\n\tmargin-right: 8px;\n}\n\n.param-control {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: flex-end;\n\tgap: 10px;\n\twidth: 100%;\n}\n\n.param-control input,\n.param-control select,\n.param-control button {\n\tbackground-color: var(--profiler-bg);\n\tborder: 1px solid var(--profiler-border);\n\tcolor: var(--text-primary);\n\tborder-radius: 4px;\n\tpadding: 4px 6px;\n\tpadding-bottom: 2px;\n\tfont-family: var(--font-mono);\n\twidth: 100%;\n\tbox-sizing: border-box;\n}\n\n.param-control select {\n\tpadding-top: 3px;\n\tpadding-bottom: 1px;\n}\n\n.param-control input[type=\"number\"] {\n\tcursor: ns-resize;\n}\n\n.param-control input[type=\"color\"] {\n\tpadding: 2px;\n}\n\n.param-control button {\n\tcursor: pointer;\n\ttransition: background-color 0.2s;\n}\n\n.param-control button:hover {\n\tbackground-color: var(--profiler-header);\n}\n\n.param-control-vector {\n\tdisplay: flex;\n\tgap: 5px;\n}\n\n.custom-checkbox {\n\tdisplay: inline-flex;\n\talign-items: center;\n\tcursor: pointer;\n\tgap: 8px;\n\twill-change: transform;\n}\n\n.custom-checkbox input {\n\tdisplay: none;\n}\n\n.custom-checkbox .checkmark {\n\twidth: 14px;\n\theight: 14px;\n\tborder: 1px solid var(--accent-color);\n\tborder-radius: 3px;\n\tdisplay: inline-flex;\n\tjustify-content: center;\n\talign-items: center;\n\ttransition: background-color 0.2s, border-color 0.2s;\n}\n\n.custom-checkbox .checkmark::after {\n\tcontent: '';\n\twidth: 6px;\n\theight: 6px;\n\tbackground-color: var(--accent-color);\n\tborder-radius: 1px;\n\tdisplay: block;\n\ttransform: scale(0);\n\ttransition: transform 0.2s;\n}\n\n.custom-checkbox input:checked+.checkmark {\n\tborder-color: var(--accent-color);\n}\n\n.custom-checkbox input:checked+.checkmark::after {\n\ttransform: scale(1);\n}\n\n.param-control input[type=\"range\"] {\n\t-webkit-appearance: none;\n\tappearance: none;\n\twidth: 100%;\n\theight: 16px;\n\tbackground: var(--profiler-header);\n\tborder-radius: 5px;\n\tborder: 1px solid var(--profiler-border);\n\toutline: none;\n\tpadding: 0px;\n\tpadding-top: 8px;\n}\n\n.param-control input[type=\"range\"]::-webkit-slider-thumb {\n\t-webkit-appearance: none;\n\tappearance: none;\n\twidth: 18px;\n\theight: 18px;\n\tbackground: var(--profiler-bg);\n\tborder: 1px solid var(--accent-color);\n\tborder-radius: 3px;\n\tcursor: pointer;\n\tmargin-top: -8px;\n}\n\n.param-control input[type=\"range\"]::-moz-range-thumb {\n\twidth: 18px;\n\theight: 18px;\n\tbackground: var(--profiler-bg);\n\tborder: 2px solid var(--accent-color);\n\tborder-radius: 3px;\n\tcursor: pointer;\n}\n\n.param-control input[type=\"range\"]::-moz-range-track {\n\twidth: 100%;\n\theight: 16px;\n\tbackground: var(--profiler-header);\n\tborder-radius: 5px;\n\tborder: 1px solid var(--profiler-border);\n}\n\n/* Override .param-control styles for mini-panel-content */\n.mini-panel-content input,\n.mini-panel-content select,\n.mini-panel-content button {\n\tpadding: 2px 4px;\n\theight: 21px;\n\tline-height: 1.4;\n\tpadding-top: 4px;\n}\n\n.mini-panel-content .param-control input,\n.mini-panel-content .param-control select,\n.mini-panel-content .param-control button {\n\tbackground-color: #1e1e24c2;\n\tline-height: 1.0;\n}\n\n.mini-panel-content .param-control select {\n\tpadding: 2px 2px;\n\tpadding-top: 3px;\n}\n\n.mini-panel-content .param-control input[type=\"number\"]::-webkit-outer-spin-button,\n.mini-panel-content .param-control input[type=\"number\"]::-webkit-inner-spin-button {\n\t-webkit-appearance: none;\n\tmargin: 0;\n}\n\n.mini-panel-content .param-control input[type=\"number\"] {\n\t-moz-appearance: textfield;\n}\n\n.mini-panel-content .list-item-cell span {\n\tposition: relative;\n\ttop: 1px;\n\tmargin-left: 2px;\n}\n\n.mini-panel-content .custom-checkbox .checkmark {\n\twidth: 12px;\n\theight: 12px;\n\tmargin-bottom: 2px;\n\twill-change: transform;\n}\n\n.mini-panel-content .list-container.parameters .list-item-row:not(.collapsible) {\n\tmargin-bottom: 2px;\n}\n\n@media screen and (max-width: 450px) and (orientation: portrait) {\n\n\t.console-filter-input {\n\t\tmax-width: 100px;\n\t}\n\n}\n\n/* Touch device optimizations */\n@media (hover: none) and (pointer: coarse) {\n\n\t.panel-resizer {\n\t\ttop: -10px !important;\n\t\theight: 20px !important;\n\t}\n\n\t#profiler-panel.position-top .panel-resizer {\n\t\ttop: auto !important;\n\t\tbottom: -10px !important;\n\t\theight: 20px !important;\n\t}\n\n\t#profiler-panel.position-left .panel-resizer {\n\t\tright: -10px !important;\n\t\twidth: 20px !important;\n\t\theight: 100% !important;\n\t}\n\n\t#profiler-panel.position-right .panel-resizer {\n\t\tleft: -10px !important;\n\t\twidth: 20px !important;\n\t\theight: 100% !important;\n\t}\n\n\t.detached-tab-resizer-top,\n\t.detached-tab-resizer-bottom {\n\t\theight: 10px !important;\n\t}\n\n\t.detached-tab-resizer-left,\n\t.detached-tab-resizer-right {\n\t\twidth: 10px !important;\n\t}\n\n}\n\n.drag-preview-indicator {\n\tposition: fixed;\n\tbackground-color: rgba(0, 170, 255, 0.2);\n\tborder: 2px dashed var(--accent-color);\n\tz-index: 999;\n\tpointer-events: none;\n\ttransition: all 0.2s ease-out;\n}\n\n/* Detached Tab Windows */\n.detached-tab-panel {\n\tposition: fixed;\n\twidth: 500px;\n\theight: 400px;\n\tbackground: var(--profiler-bg);\n\tborder: 1px solid var(--profiler-border);\n\tborder-radius: 8px;\n\tbox-shadow: 0 10px 40px rgba(0, 0, 0, 0.5);\n\tz-index: 1002;\n\tdisplay: flex;\n\tflex-direction: column;\n\tbackdrop-filter: blur(10px);\n\toverflow: hidden;\n\topacity: 1;\n\tvisibility: visible;\n\ttransition: opacity 0.2s, visibility 0.2s;\n}\n\n#profiler-panel:not(.visible) ~ * .detached-tab-panel,\nbody:has(#profiler-panel:not(.visible)) .detached-tab-panel {\n\topacity: 0;\n\tvisibility: hidden;\n\tpointer-events: none;\n}\n\n.detached-tab-header {\n\tbackground: var(--profiler-header-bg);\n\tpadding: 0 7px 0 15px;\n\tfont-family: var(--font-family);\n\tfont-size: 14px;\n\tcolor: var(--text-primary);\n\tfont-weight: 600;\n\tdisplay: flex;\n\tjustify-content: space-between;\n\talign-items: center;\n\tborder-bottom: 1px solid var(--profiler-border);\n\tcursor: grab;\n\tuser-select: none;\n\theight: 38px;\n\tflex-shrink: 0;\n\t-webkit-font-smoothing: antialiased;\n\t-moz-osx-font-smoothing: grayscale;\n\ttouch-action: none;\n}\n\n.detached-tab-header:active {\n\tcursor: grabbing;\n}\n\n.detached-header-controls {\n\tdisplay: flex;\n\tgap: 5px;\n}\n\n.detached-reattach-btn {\n\tbackground: transparent;\n\tborder: none;\n\tcolor: var(--text-secondary);\n\tfont-family: var(--font-family);\n\tfont-size: 18px;\n\tline-height: 1;\n\tcursor: pointer;\n\tpadding: 4px 8px;\n\tborder-radius: 4px;\n\ttransition: all 0.2s;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\t-webkit-font-smoothing: antialiased;\n\t-moz-osx-font-smoothing: grayscale;\n}\n\n.detached-reattach-btn:hover {\n\tbackground: rgba(0, 170, 255, 0.2);\n\tcolor: var(--accent-color);\n}\n\n.detached-tab-content {\n\tflex: 1;\n\toverflow: auto;\n\tposition: relative;\n\tbackground: var(--profiler-bg);\n}\n\n.detached-tab-content::-webkit-scrollbar {\n\twidth: 8px;\n\theight: 8px;\n}\n\n.detached-tab-content::-webkit-scrollbar-track {\n\tbackground: transparent;\n}\n\n.detached-tab-content::-webkit-scrollbar-thumb {\n\tbackground-color: rgba(0, 0, 0, 0.25);\n\tborder-radius: 10px;\n\ttransition: background 0.3s ease;\n}\n\n.detached-tab-content::-webkit-scrollbar-thumb:hover {\n\tbackground-color: rgba(0, 0, 0, 0.4);\n}\n\n.detached-tab-content::-webkit-scrollbar-corner {\n\tbackground: transparent;\n}\n\n.detached-tab-content .profiler-content {\n\tdisplay: block !important;\n\theight: 100%;\n\tvisibility: visible !important;\n\topacity: 1 !important;\n\tposition: relative !important;\n}\n\n.detached-tab-content .profiler-content > * {\n\tfont-family: var(--font-mono);\n\tcolor: var(--text-primary);\n}\n\n.detached-tab-resizer {\n\tposition: absolute;\n\tbottom: 0;\n\tright: 0;\n\twidth: 20px;\n\theight: 20px;\n\tcursor: nwse-resize;\n\tz-index: 10;\n\ttouch-action: none;\n}\n\n.detached-tab-resizer::after {\n\tcontent: '';\n\tposition: absolute;\n\tbottom: 2px;\n\tright: 2px;\n\twidth: 12px;\n\theight: 12px;\n\tborder-right: 2px solid var(--profiler-border);\n\tborder-bottom: 2px solid var(--profiler-border);\n\tborder-bottom-right-radius: 6px;\n\topacity: 0.5;\n}\n\n.detached-tab-resizer:hover::after {\n\topacity: 1;\n\tborder-color: var(--accent-color);\n}\n\n/* Edge resizers */\n.detached-tab-resizer-top {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n\theight: 5px;\n\tcursor: ns-resize;\n\tz-index: 10;\n\ttouch-action: none;\n}\n\n.detached-tab-resizer-right {\n\tposition: absolute;\n\ttop: 0;\n\tright: 0;\n\tbottom: 0;\n\twidth: 5px;\n\tcursor: ew-resize;\n\tz-index: 10;\n\ttouch-action: none;\n}\n\n.detached-tab-resizer-bottom {\n\tposition: absolute;\n\tbottom: 0;\n\tleft: 0;\n\tright: 0;\n\theight: 5px;\n\tcursor: ns-resize;\n\tz-index: 10;\n\ttouch-action: none;\n}\n\n.detached-tab-resizer-left {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tbottom: 0;\n\twidth: 5px;\n\tcursor: ew-resize;\n\tz-index: 10;\n\ttouch-action: none;\n}\n\n/* Input number spin buttons - hide arrows */\n/* Chrome, Safari, Edge, Opera */\n#profiler-panel input[type=\"number\"]::-webkit-outer-spin-button,\n#profiler-panel input[type=\"number\"]::-webkit-inner-spin-button,\n.detached-tab-content input[type=\"number\"]::-webkit-outer-spin-button,\n.detached-tab-content input[type=\"number\"]::-webkit-inner-spin-button {\n\t-webkit-appearance: none;\n\tmargin: 0;\n}\n\n/* Firefox */\n#profiler-panel input[type=\"number\"],\n.detached-tab-content input[type=\"number\"] {\n\t-moz-appearance: textfield;\n}\n`;\n\t\tconst styleElement = document.createElement( 'style' );\n\t\tstyleElement.id = 'profiler-styles';\n\t\tstyleElement.textContent = css;\n\t\tdocument.head.appendChild( styleElement );\n\n\t}\n\n}\n","import { Style } from './Style.js';\n\nexport class Profiler {\n\n\tconstructor() {\n\n\t\tthis.tabs = {};\n\t\tthis.activeTabId = null;\n\t\tthis.isResizing = false;\n\t\tthis.lastHeightBottom = 350; // Height for bottom position\n\t\tthis.lastWidthRight = 450; // Width for right position\n\t\tthis.position = 'bottom'; // 'bottom' or 'right'\n\t\tthis.detachedWindows = []; // Array to store detached tab windows\n\t\tthis.isMobile = this.detectMobile();\n\t\tthis.maxZIndex = 1002; // Track the highest z-index for detached windows (starts at base z-index from CSS)\n\t\tthis.nextTabOriginalIndex = 0; // Track the original order of tabs as they are added\n\n\t\tStyle.init();\n\n\t\tthis.setupShell();\n\t\tthis.setupResizing();\n\n\t\t// Setup orientation change listener for mobile devices\n\t\tif ( this.isMobile ) {\n\n\t\t\tthis.setupOrientationListener();\n\n\t\t}\n\n\t\t// Setup window resize listener to constrain detached windows\n\t\tthis.setupWindowResizeListener();\n\n\t}\n\n\tdetectMobile() {\n\n\t\t// Check for mobile devices\n\t\tconst userAgent = navigator.userAgent || navigator.vendor || window.opera;\n\t\tconst isMobileUA = /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini/i.test( userAgent );\n\t\tconst isTouchDevice = ( 'ontouchstart' in window ) || ( navigator.maxTouchPoints > 0 );\n\t\tconst isSmallScreen = window.innerWidth <= 768;\n\n\t\treturn isMobileUA || ( isTouchDevice && isSmallScreen );\n\n\t}\n\n\tsetupOrientationListener() {\n\n\t\tconst handleOrientationChange = () => {\n\n\t\t\t// Check if device is in landscape or portrait mode\n\t\t\tconst isLandscape = window.innerWidth > window.innerHeight;\n\n\t\t\t// In landscape mode, use right position (vertical panel)\n\t\t\t// In portrait mode, use bottom position (horizontal panel)\n\t\t\tconst targetPosition = isLandscape ? 'right' : 'bottom';\n\n\t\t\tif ( this.position !== targetPosition ) {\n\n\t\t\t\tthis.setPosition( targetPosition );\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Initial check\n\t\thandleOrientationChange();\n\n\t\t// Listen for orientation changes\n\t\twindow.addEventListener( 'orientationchange', handleOrientationChange );\n\t\twindow.addEventListener( 'resize', handleOrientationChange );\n\n\t}\n\n\tsetupWindowResizeListener() {\n\n\t\tconst constrainDetachedWindows = () => {\n\n\t\t\tthis.detachedWindows.forEach( detachedWindow => {\n\n\t\t\t\tthis.constrainWindowToBounds( detachedWindow.panel );\n\n\t\t\t} );\n\n\t\t};\n\n\t\tconst constrainMainPanel = () => {\n\n\t\t\t// Skip if panel is maximized (it should always fill the screen)\n\t\t\tif ( this.panel.classList.contains( 'maximized' ) ) return;\n\n\t\t\tconst windowWidth = window.innerWidth;\n\t\t\tconst windowHeight = window.innerHeight;\n\n\t\t\tif ( this.position === 'bottom' ) {\n\n\t\t\t\tconst currentHeight = this.panel.offsetHeight;\n\t\t\t\tconst maxHeight = windowHeight - 50; // Leave 50px margin\n\n\t\t\t\tif ( currentHeight > maxHeight ) {\n\n\t\t\t\t\tthis.panel.style.height = `${ maxHeight }px`;\n\t\t\t\t\tthis.lastHeightBottom = maxHeight;\n\n\t\t\t\t}\n\n\t\t\t} else if ( this.position === 'right' ) {\n\n\t\t\t\tconst currentWidth = this.panel.offsetWidth;\n\t\t\t\tconst maxWidth = windowWidth - 50; // Leave 50px margin\n\n\t\t\t\tif ( currentWidth > maxWidth ) {\n\n\t\t\t\t\tthis.panel.style.width = `${ maxWidth }px`;\n\t\t\t\t\tthis.lastWidthRight = maxWidth;\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\t// Listen for window resize events\n\t\twindow.addEventListener( 'resize', () => {\n\n\t\t\tconstrainDetachedWindows();\n\t\t\tconstrainMainPanel();\n\n\t\t} );\n\n\t}\n\n\tconstrainWindowToBounds( windowPanel ) {\n\n\t\tconst windowWidth = window.innerWidth;\n\t\tconst windowHeight = window.innerHeight;\n\n\t\tconst panelWidth = windowPanel.offsetWidth;\n\t\tconst panelHeight = windowPanel.offsetHeight;\n\n\t\tlet left = parseFloat( windowPanel.style.left ) || windowPanel.offsetLeft || 0;\n\t\tlet top = parseFloat( windowPanel.style.top ) || windowPanel.offsetTop || 0;\n\n\t\t// Allow window to extend half its width/height outside the screen\n\t\tconst halfWidth = panelWidth / 2;\n\t\tconst halfHeight = panelHeight / 2;\n\n\t\t// Constrain horizontal position (allow half width to extend beyond right edge)\n\t\tif ( left + panelWidth > windowWidth + halfWidth ) {\n\n\t\t\tleft = windowWidth + halfWidth - panelWidth;\n\n\t\t}\n\n\t\t// Constrain horizontal position (allow half width to extend beyond left edge)\n\t\tif ( left < - halfWidth ) {\n\n\t\t\tleft = - halfWidth;\n\n\t\t}\n\n\t\t// Constrain vertical position (allow half height to extend beyond bottom edge)\n\t\tif ( top + panelHeight > windowHeight + halfHeight ) {\n\n\t\t\ttop = windowHeight + halfHeight - panelHeight;\n\n\t\t}\n\n\t\t// Constrain vertical position (allow half height to extend beyond top edge)\n\t\tif ( top < - halfHeight ) {\n\n\t\t\ttop = - halfHeight;\n\n\t\t}\n\n\t\t// Apply constrained position\n\t\twindowPanel.style.left = `${ left }px`;\n\t\twindowPanel.style.top = `${ top }px`;\n\n\t}\n\n\tsetupShell() {\n\n\t\tthis.domElement = document.createElement( 'div' );\n\t\tthis.domElement.id = 'profiler-shell';\n\n\t\tthis.toggleButton = document.createElement( 'button' );\n\t\tthis.toggleButton.id = 'profiler-toggle';\n\t\tthis.toggleButton.innerHTML = `\n<span id=\"builtin-tabs-container\"></span>\n<span id=\"toggle-text\">\n\t<span id=\"fps-counter\">-</span>\n\t<span class=\"fps-label\">FPS</span>\n</span>\n<span id=\"toggle-icon\">\n\t<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"icon icon-tabler icons-tabler-outline icon-tabler-device-ipad-horizontal-search\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M11.5 20h-6.5a2 2 0 0 1 -2 -2v-12a2 2 0 0 1 2 -2h14a2 2 0 0 1 2 2v5.5\" /><path d=\"M9 17h2\" /><path d=\"M18 18m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0\" /><path d=\"M20.2 20.2l1.8 1.8\" /></svg>\n</span>\n`;\n\t\tthis.toggleButton.onclick = () => this.togglePanel();\n\n\t\tthis.builtinTabsContainer = this.toggleButton.querySelector( '#builtin-tabs-container' );\n\n\t\t// Create mini-panel for builtin tabs (shown when panel is hidden)\n\t\tthis.miniPanel = document.createElement( 'div' );\n\t\tthis.miniPanel.id = 'profiler-mini-panel';\n\t\tthis.miniPanel.className = 'profiler-mini-panel';\n\n\t\tthis.panel = document.createElement( 'div' );\n\t\tthis.panel.id = 'profiler-panel';\n\n\t\tconst header = document.createElement( 'div' );\n\t\theader.className = 'profiler-header';\n\t\tthis.tabsContainer = document.createElement( 'div' );\n\t\tthis.tabsContainer.className = 'profiler-tabs';\n\n\t\tconst controls = document.createElement( 'div' );\n\t\tcontrols.className = 'profiler-controls';\n\n\t\tthis.floatingBtn = document.createElement( 'button' );\n\t\tthis.floatingBtn.id = 'floating-btn';\n\t\tthis.floatingBtn.title = 'Switch to Right Side';\n\t\tthis.floatingBtn.innerHTML = '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><line x1=\"15\" y1=\"3\" x2=\"15\" y2=\"21\"></line></svg>';\n\t\tthis.floatingBtn.onclick = () => this.togglePosition();\n\n\t\t// Hide position toggle button on mobile devices\n\t\tif ( this.isMobile ) {\n\n\t\t\tthis.floatingBtn.style.display = 'none';\n\t\t\tthis.panel.classList.add( 'hide-position-toggle' );\n\n\t\t}\n\n\t\tthis.maximizeBtn = document.createElement( 'button' );\n\t\tthis.maximizeBtn.id = 'maximize-btn';\n\t\tthis.maximizeBtn.innerHTML = '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3\"/></svg>';\n\t\tthis.maximizeBtn.onclick = () => this.toggleMaximize();\n\n\t\tconst hideBtn = document.createElement( 'button' );\n\t\thideBtn.id = 'hide-panel-btn';\n\t\thideBtn.textContent = '-';\n\t\thideBtn.onclick = () => this.togglePanel();\n\n\t\tcontrols.append( this.floatingBtn, this.maximizeBtn, hideBtn );\n\t\theader.append( this.tabsContainer, controls );\n\n\t\tthis.contentWrapper = document.createElement( 'div' );\n\t\tthis.contentWrapper.className = 'profiler-content-wrapper';\n\n\t\tconst resizer = document.createElement( 'div' );\n\t\tresizer.className = 'panel-resizer';\n\n\t\tthis.panel.append( resizer, header, this.contentWrapper );\n\n\t\tthis.domElement.append( this.toggleButton, this.miniPanel, this.panel );\n\n\t\t// Set initial position class\n\t\tthis.panel.classList.add( `position-${this.position}` );\n\n\t}\n\n\tsetupResizing() {\n\n\t\tconst resizer = this.panel.querySelector( '.panel-resizer' );\n\n\t\tconst onStart = ( e ) => {\n\n\t\t\tthis.isResizing = true;\n\t\t\tthis.panel.classList.add( 'resizing' );\n\t\t\tresizer.setPointerCapture( e.pointerId );\n\t\t\tconst startX = e.clientX;\n\t\t\tconst startY = e.clientY;\n\t\t\tconst startHeight = this.panel.offsetHeight;\n\t\t\tconst startWidth = this.panel.offsetWidth;\n\n\t\t\tconst onMove = ( moveEvent ) => {\n\n\t\t\t\tif ( ! this.isResizing ) return;\n\t\t\t\tmoveEvent.preventDefault();\n\t\t\t\tconst currentX = moveEvent.clientX;\n\t\t\t\tconst currentY = moveEvent.clientY;\n\n\t\t\t\tif ( this.position === 'bottom' ) {\n\n\t\t\t\t\t// Vertical resize for bottom position\n\t\t\t\t\tconst newHeight = startHeight - ( currentY - startY );\n\n\t\t\t\t\tif ( newHeight > 100 && newHeight < window.innerHeight - 50 ) {\n\n\t\t\t\t\t\tthis.panel.style.height = `${ newHeight }px`;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( this.position === 'right' ) {\n\n\t\t\t\t\t// Horizontal resize for right position\n\t\t\t\t\tconst newWidth = startWidth - ( currentX - startX );\n\n\t\t\t\t\tif ( newWidth > 200 && newWidth < window.innerWidth - 50 ) {\n\n\t\t\t\t\t\tthis.panel.style.width = `${ newWidth }px`;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tconst onEnd = () => {\n\n\t\t\t\tthis.isResizing = false;\n\t\t\t\tthis.panel.classList.remove( 'resizing' );\n\t\t\t\tresizer.removeEventListener( 'pointermove', onMove );\n\t\t\t\tresizer.removeEventListener( 'pointerup', onEnd );\n\t\t\t\tresizer.removeEventListener( 'pointercancel', onEnd );\n\t\t\t\tif ( ! this.panel.classList.contains( 'maximized' ) ) {\n\n\t\t\t\t\t// Save dimensions based on current position\n\t\t\t\t\tif ( this.position === 'bottom' ) {\n\n\t\t\t\t\t\tthis.lastHeightBottom = this.panel.offsetHeight;\n\n\t\t\t\t\t} else if ( this.position === 'right' ) {\n\n\t\t\t\t\t\tthis.lastWidthRight = this.panel.offsetWidth;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Save layout after resize\n\t\t\t\t\tthis.saveLayout();\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tresizer.addEventListener( 'pointermove', onMove );\n\t\t\tresizer.addEventListener( 'pointerup', onEnd );\n\t\t\tresizer.addEventListener( 'pointercancel', onEnd );\n\n\t\t};\n\n\t\tresizer.addEventListener( 'pointerdown', onStart );\n\n\t}\n\n\ttoggleMaximize() {\n\n\t\tif ( this.panel.classList.contains( 'maximized' ) ) {\n\n\t\t\tthis.panel.classList.remove( 'maximized' );\n\n\t\t\t// Restore size based on current position\n\t\t\tif ( this.position === 'bottom' ) {\n\n\t\t\t\tthis.panel.style.height = `${ this.lastHeightBottom }px`;\n\t\t\t\tthis.panel.style.width = '100%';\n\n\t\t\t} else if ( this.position === 'right' ) {\n\n\t\t\t\tthis.panel.style.height = '100%';\n\t\t\t\tthis.panel.style.width = `${ this.lastWidthRight }px`;\n\n\t\t\t}\n\n\t\t\tthis.maximizeBtn.innerHTML = '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3\"/></svg>';\n\n\t\t} else {\n\n\t\t\t// Save current size before maximizing\n\t\t\tif ( this.position === 'bottom' ) {\n\n\t\t\t\tthis.lastHeightBottom = this.panel.offsetHeight;\n\n\t\t\t} else if ( this.position === 'right' ) {\n\n\t\t\t\tthis.lastWidthRight = this.panel.offsetWidth;\n\n\t\t\t}\n\n\t\t\tthis.panel.classList.add( 'maximized' );\n\n\t\t\t// Maximize based on current position\n\t\t\tif ( this.position === 'bottom' ) {\n\n\t\t\t\tthis.panel.style.height = '100vh';\n\t\t\t\tthis.panel.style.width = '100%';\n\n\t\t\t} else if ( this.position === 'right' ) {\n\n\t\t\t\tthis.panel.style.height = '100%';\n\t\t\t\tthis.panel.style.width = '100vw';\n\n\t\t\t}\n\n\t\t\tthis.maximizeBtn.innerHTML = '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"8\" y=\"8\" width=\"12\" height=\"12\" rx=\"2\" ry=\"2\"></rect><path d=\"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2\"></path></svg>';\n\n\t\t}\n\n\t}\n\n\taddTab( tab ) {\n\n\t\tthis.tabs[ tab.id ] = tab;\n\n\t\t// Assign a permanent original index to this tab\n\t\ttab.originalIndex = this.nextTabOriginalIndex ++;\n\n\t\t// Add visual indicator for tabs that cannot be detached\n\t\tif ( tab.allowDetach === false ) {\n\n\t\t\ttab.button.classList.add( 'no-detach' );\n\n\t\t}\n\n\t\t// Set visibility change callback\n\t\ttab.onVisibilityChange = () => this.updatePanelSize();\n\n\t\tthis.setupTabDragAndDrop( tab );\n\n\t\tthis.tabsContainer.appendChild( tab.button );\n\t\tthis.contentWrapper.appendChild( tab.content );\n\n\t\t// Apply the current visibility state to the DOM elements\n\t\tif ( ! tab.isVisible ) {\n\n\t\t\ttab.button.style.display = 'none';\n\t\t\ttab.content.style.display = 'none';\n\n\t\t}\n\n\t\t// If tab is builtin, add it to the profiler-toggle button\n\t\tif ( tab.builtin ) {\n\n\t\t\tthis.addBuiltinTab( tab );\n\n\t\t}\n\n\t\t// Update panel size when tabs change\n\t\tthis.updatePanelSize();\n\n\t}\n\n\taddBuiltinTab( tab ) {\n\n\t\t// Create a button for the builtin tab in the profiler-toggle\n\t\tconst builtinButton = document.createElement( 'button' );\n\t\tbuiltinButton.className = 'builtin-tab-btn';\n\n\t\t// Use icon if provided, otherwise use first letter\n\t\tif ( tab.icon ) {\n\n\t\t\tbuiltinButton.innerHTML = tab.icon;\n\n\t\t} else {\n\n\t\t\tbuiltinButton.textContent = tab.button.textContent.charAt( 0 ).toUpperCase();\n\n\t\t}\n\n\t\tbuiltinButton.title = tab.button.textContent;\n\n\t\t// Create mini-panel content container for this tab\n\t\tconst miniContent = document.createElement( 'div' );\n\t\tminiContent.className = 'mini-panel-content';\n\t\tminiContent.style.display = 'none';\n\n\t\t// Store references in the tab object\n\t\ttab.builtinButton = builtinButton;\n\t\ttab.miniContent = miniContent;\n\n\t\tthis.miniPanel.appendChild( miniContent );\n\n\t\tbuiltinButton.onclick = ( e ) => {\n\n\t\t\te.stopPropagation(); // Prevent toggle panel from triggering\n\n\t\t\tconst isPanelVisible = this.panel.classList.contains( 'visible' );\n\n\t\t\tif ( isPanelVisible ) {\n\n\t\t\t\t// Panel is visible - navigate to tab\n\t\t\t\tif ( ! tab.isVisible ) {\n\n\t\t\t\t\ttab.show();\n\n\t\t\t\t}\n\n\t\t\t\tif ( tab.isDetached ) {\n\n\t\t\t\t\t// If tab is detached, just bring its window to front\n\t\t\t\t\tif ( tab.detachedWindow ) {\n\n\t\t\t\t\t\tthis.bringWindowToFront( tab.detachedWindow.panel );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Activate the tab\n\t\t\t\t\tthis.setActiveTab( tab.id );\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\t// Panel is hidden - toggle mini-panel for this tab\n\t\t\t\tconst isCurrentlyActive = miniContent.style.display !== 'none' && miniContent.children.length > 0;\n\n\t\t\t\t// Hide all other mini-panel contents\n\t\t\t\tthis.miniPanel.querySelectorAll( '.mini-panel-content' ).forEach( content => {\n\n\t\t\t\t\tcontent.style.display = 'none';\n\n\t\t\t\t} );\n\n\t\t\t\t// Remove active state from all builtin buttons\n\t\t\t\tthis.builtinTabsContainer.querySelectorAll( '.builtin-tab-btn' ).forEach( btn => {\n\n\t\t\t\t\tbtn.classList.remove( 'active' );\n\n\t\t\t\t} );\n\n\t\t\t\tif ( isCurrentlyActive ) {\n\n\t\t\t\t\t// Toggle off - hide mini-panel and move content back\n\t\t\t\t\tthis.miniPanel.classList.remove( 'visible' );\n\t\t\t\t\tminiContent.style.display = 'none';\n\n\t\t\t\t\t// Move content back to main panel\n\t\t\t\t\tif ( miniContent.firstChild ) {\n\n\t\t\t\t\t\ttab.content.appendChild( miniContent.firstChild );\n\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Toggle on - show mini-panel with this tab's content\n\t\t\t\t\tbuiltinButton.classList.add( 'active' );\n\n\t\t\t\t\t// Move actual content to mini-panel (not clone) if not already there\n\t\t\t\t\tif ( ! miniContent.firstChild ) {\n\n\t\t\t\t\t\tconst actualContent = tab.content.querySelector( '.list-scroll-wrapper' ) || tab.content.firstElementChild;\n\n\t\t\t\t\t\tif ( actualContent ) {\n\n\t\t\t\t\t\t\tminiContent.appendChild( actualContent );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Show after content is moved\n\t\t\t\t\tminiContent.style.display = 'block';\n\t\t\t\t\tthis.miniPanel.classList.add( 'visible' );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tthis.builtinTabsContainer.appendChild( builtinButton );\n\n\t\t// Store references\n\t\ttab.builtinButton = builtinButton;\n\t\ttab.miniContent = miniContent;\n\t\ttab.profiler = this;\n\n\t\t// If the tab was hidden before being added, hide the builtin button\n\t\tif ( ! tab.isVisible ) {\n\n\t\t\tbuiltinButton.style.display = 'none';\n\t\t\tminiContent.style.display = 'none';\n\n\t\t\t// Hide the builtin-tabs-container if all builtin buttons are hidden\n\t\t\tconst hasVisibleBuiltinButtons = Array.from( this.builtinTabsContainer.querySelectorAll( '.builtin-tab-btn' ) )\n\t\t\t\t.some( btn => btn.style.display !== 'none' );\n\n\t\t\tif ( ! hasVisibleBuiltinButtons ) {\n\n\t\t\t\tthis.builtinTabsContainer.style.display = 'none';\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tupdatePanelSize() {\n\n\t\t// Check if there are any visible tabs in the panel\n\t\tconst hasVisibleTabs = Object.values( this.tabs ).some( tab => ! tab.isDetached && tab.isVisible );\n\n\t\t// Add or remove CSS class to indicate no tabs state\n\t\tif ( ! hasVisibleTabs ) {\n\n\t\t\tthis.panel.classList.add( 'no-tabs' );\n\n\t\t\t// If maximized and no tabs, restore to normal size\n\t\t\tif ( this.panel.classList.contains( 'maximized' ) ) {\n\n\t\t\t\tthis.panel.classList.remove( 'maximized' );\n\t\t\t\tthis.maximizeBtn.innerHTML = '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path d=\"M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3\"/></svg>';\n\n\t\t\t}\n\n\t\t\t// No tabs visible - set to minimum size\n\t\t\tif ( this.position === 'bottom' ) {\n\n\t\t\t\tthis.panel.style.height = '38px';\n\n\t\t\t} else if ( this.position === 'right' ) {\n\n\t\t\t\t// 45px = width of one button column\n\t\t\t\tthis.panel.style.width = '45px';\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tthis.panel.classList.remove( 'no-tabs' );\n\n\t\t\tif ( Object.keys( this.tabs ).length > 0 ) {\n\n\t\t\t\t// Has tabs - restore to saved size only if we had set it to minimum before\n\t\t\t\tif ( this.position === 'bottom' ) {\n\n\t\t\t\t\tconst currentHeight = parseInt( this.panel.style.height );\n\t\t\t\t\tif ( currentHeight === 38 ) {\n\n\t\t\t\t\t\tthis.panel.style.height = `${ this.lastHeightBottom }px`;\n\n\t\t\t\t\t}\n\n\t\t\t\t} else if ( this.position === 'right' ) {\n\n\t\t\t\t\tconst currentWidth = parseInt( this.panel.style.width );\n\t\t\t\t\tif ( currentWidth === 45 ) {\n\n\t\t\t\t\t\tthis.panel.style.width = `${ this.lastWidthRight }px`;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n\tsetupTabDragAndDrop( tab ) {\n\n\t\t// Disable drag and drop on mobile devices\n\t\tif ( this.isMobile ) {\n\n\t\t\ttab.button.addEventListener( 'click', () => {\n\n\t\t\t\tthis.setActiveTab( tab.id );\n\n\t\t\t} );\n\n\t\t\treturn;\n\n\t\t}\n\n\t\t// Disable drag and drop if tab doesn't allow detach\n\t\tif ( tab.allowDetach === false ) {\n\n\t\t\ttab.button.addEventListener( 'click', () => {\n\n\t\t\t\tthis.setActiveTab( tab.id );\n\n\t\t\t} );\n\n\t\t\ttab.button.style.cursor = 'default';\n\n\t\t\treturn;\n\n\t\t}\n\n\t\tlet isDragging = false;\n\t\tlet startX, startY;\n\t\tlet hasMoved = false;\n\t\tlet previewWindow = null;\n\t\tconst dragThreshold = 10; // pixels to move before starting drag\n\n\t\tconst onDragStart = ( e ) => {\n\n\t\t\tstartX = e.clientX;\n\t\t\tstartY = e.clientY;\n\t\t\tisDragging = false;\n\t\t\thasMoved = false;\n\t\t\ttab.button.setPointerCapture( e.pointerId );\n\n\t\t};\n\n\t\tconst onDragMove = ( e ) => {\n\n\t\t\tconst currentX = e.clientX;\n\t\t\tconst currentY = e.clientY;\n\n\t\t\tconst deltaX = Math.abs( currentX - startX );\n\t\t\tconst deltaY = Math.abs( currentY - startY );\n\n\t\t\tif ( ! isDragging && ( deltaX > dragThreshold || deltaY > dragThreshold ) ) {\n\n\t\t\t\tisDragging = true;\n\t\t\t\ttab.button.style.cursor = 'grabbing';\n\t\t\t\ttab.button.style.opacity = '0.5';\n\t\t\t\ttab.button.style.transform = 'scale(1.05)';\n\n\t\t\t\tpreviewWindow = this.createPreviewWindow( tab, currentX, currentY );\n\t\t\t\tpreviewWindow.style.opacity = '0.8';\n\n\t\t\t}\n\n\t\t\tif ( isDragging && previewWindow ) {\n\n\t\t\t\thasMoved = true;\n\t\t\t\te.preventDefault();\n\n\t\t\t\tpreviewWindow.style.left = `${ currentX - 200 }px`;\n\t\t\t\tpreviewWindow.style.top = `${ currentY - 20 }px`;\n\n\t\t\t}\n\n\t\t};\n\n\t\tconst onDragEnd = () => {\n\n\t\t\tif ( isDragging && hasMoved && previewWindow ) {\n\n\t\t\t\tif ( previewWindow.parentNode ) {\n\n\t\t\t\t\tpreviewWindow.parentNode.removeChild( previewWindow );\n\n\t\t\t\t}\n\n\t\t\t\tconst finalX = parseInt( previewWindow.style.left ) + 200;\n\t\t\t\tconst finalY = parseInt( previewWindow.style.top ) + 20;\n\n\t\t\t\tthis.detachTab( tab, finalX, finalY );\n\n\t\t\t} else if ( ! hasMoved ) {\n\n\t\t\t\tthis.setActiveTab( tab.id );\n\n\t\t\t\tif ( previewWindow && previewWindow.parentNode ) {\n\n\t\t\t\t\tpreviewWindow.parentNode.removeChild( previewWindow );\n\n\t\t\t\t}\n\n\t\t\t} else if ( previewWindow ) {\n\n\t\t\t\tif ( previewWindow.parentNode ) {\n\n\t\t\t\t\tpreviewWindow.parentNode.removeChild( previewWindow );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\ttab.button.style.opacity = '';\n\t\t\ttab.button.style.transform = '';\n\t\t\ttab.button.style.cursor = '';\n\t\t\tisDragging = false;\n\t\t\thasMoved = false;\n\t\t\tpreviewWindow = null;\n\n\t\t\ttab.button.removeEventListener( 'pointermove', onDragMove );\n\t\t\ttab.button.removeEventListener( 'pointerup', onDragEnd );\n\t\t\ttab.button.removeEventListener( 'pointercancel', onDragEnd );\n\n\t\t};\n\n\t\ttab.button.addEventListener( 'pointerdown', ( e ) => {\n\n\t\t\tonDragStart( e );\n\t\t\ttab.button.addEventListener( 'pointermove', onDragMove );\n\t\t\ttab.button.addEventListener( 'pointerup', onDragEnd );\n\t\t\ttab.button.addEventListener( 'pointercancel', onDragEnd );\n\n\t\t} );\n\n\t\t// Set cursor to grab for tabs that can be detached\n\t\ttab.button.style.cursor = 'grab';\n\n\t}\n\n\tcreatePreviewWindow( tab, x, y ) {\n\n\t\tconst windowPanel = document.createElement( 'div' );\n\t\twindowPanel.className = 'detached-tab-panel';\n\t\twindowPanel.style.left = `${ x - 200 }px`;\n\t\twindowPanel.style.top = `${ y - 20 }px`;\n\t\twindowPanel.style.pointerEvents = 'none'; // Preview only\n\n\t\t// Set z-index for preview window to be on top\n\t\tthis.maxZIndex ++;\n\t\twindowPanel.style.setProperty( 'z-index', this.maxZIndex, 'important' );\n\n\t\tconst windowHeader = document.createElement( 'div' );\n\t\twindowHeader.className = 'detached-tab-header';\n\n\t\tconst title = document.createElement( 'span' );\n\t\ttitle.textContent = tab.button.textContent.replace( '⇱', '' ).trim();\n\t\twindowHeader.appendChild( title );\n\n\t\tconst headerControls = document.createElement( 'div' );\n\t\theaderControls.className = 'detached-header-controls';\n\n\t\tconst reattachBtn = document.createElement( 'button' );\n\t\treattachBtn.className = 'detached-reattach-btn';\n\t\treattachBtn.innerHTML = '↩';\n\t\theaderControls.appendChild( reattachBtn );\n\t\twindowHeader.appendChild( headerControls );\n\n\t\tconst windowContent = document.createElement( 'div' );\n\t\twindowContent.className = 'detached-tab-content';\n\n\t\tconst resizer = document.createElement( 'div' );\n\t\tresizer.className = 'detached-tab-resizer';\n\n\t\twindowPanel.appendChild( resizer );\n\t\twindowPanel.appendChild( windowHeader );\n\t\twindowPanel.appendChild( windowContent );\n\n\t\tdocument.body.appendChild( windowPanel );\n\n\t\treturn windowPanel;\n\n\t}\n\n\tdetachTab( tab, x, y ) {\n\n\t\tif ( tab.isDetached ) return;\n\n\t\t// Check if tab allows detachment\n\t\tif ( tab.allowDetach === false ) return;\n\n\t\tconst allButtons = Array.from( this.tabsContainer.children );\n\n\t\tconst tabIdsInOrder = allButtons.map( btn => {\n\n\t\t\treturn Object.keys( this.tabs ).find( id => this.tabs[ id ].button === btn );\n\n\t\t} ).filter( id => id !== undefined );\n\n\t\tconst currentIndex = tabIdsInOrder.indexOf( tab.id );\n\n\t\tlet newActiveTab = null;\n\n\t\tif ( this.activeTabId === tab.id ) {\n\n\t\t\ttab.setActive( false );\n\n\t\t\tconst remainingTabs = tabIdsInOrder.filter( id =>\n\t\t\t\tid !== tab.id &&\n\t\t\t\t! this.tabs[ id ].isDetached &&\n\t\t\t\tthis.tabs[ id ].isVisible\n\t\t\t);\n\n\t\t\tif ( remainingTabs.length > 0 ) {\n\n\t\t\t\tfor ( let i = currentIndex - 1; i >= 0; i -- ) {\n\n\t\t\t\t\tif ( remainingTabs.includes( tabIdsInOrder[ i ] ) ) {\n\n\t\t\t\t\t\tnewActiveTab = tabIdsInOrder[ i ];\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! newActiveTab ) {\n\n\t\t\t\t\tfor ( let i = currentIndex + 1; i < tabIdsInOrder.length; i ++ ) {\n\n\t\t\t\t\t\tif ( remainingTabs.includes( tabIdsInOrder[ i ] ) ) {\n\n\t\t\t\t\t\t\tnewActiveTab = tabIdsInOrder[ i ];\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( ! newActiveTab ) {\n\n\t\t\t\t\tnewActiveTab = remainingTabs[ 0 ];\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( tab.button.parentNode ) {\n\n\t\t\ttab.button.parentNode.removeChild( tab.button );\n\n\t\t}\n\n\t\tif ( tab.content.parentNode ) {\n\n\t\t\ttab.content.parentNode.removeChild( tab.content );\n\n\t\t}\n\n\t\tconst detachedWindow = this.createDetachedWindow( tab, x, y );\n\t\tthis.detachedWindows.push( detachedWindow );\n\n\t\ttab.isDetached = true;\n\t\ttab.detachedWindow = detachedWindow;\n\n\t\tif ( newActiveTab ) {\n\n\t\t\tthis.setActiveTab( newActiveTab );\n\n\t\t} else if ( this.activeTabId === tab.id ) {\n\n\t\t\tthis.activeTabId = null;\n\n\t\t}\n\n\t\t// Update panel size after detaching\n\t\tthis.updatePanelSize();\n\n\t\tthis.saveLayout();\n\n\t}\n\n\tcreateDetachedWindow( tab, x, y ) {\n\n\t\t// Constrain initial position to window bounds\n\t\tconst windowWidth = window.innerWidth;\n\t\tconst windowHeight = window.innerHeight;\n\t\tconst estimatedWidth = 400; // Default detached window width\n\t\tconst estimatedHeight = 300; // Default detached window height\n\n\t\tlet constrainedX = x - 200;\n\t\tlet constrainedY = y - 20;\n\n\t\tif ( constrainedX + estimatedWidth > windowWidth ) {\n\n\t\t\tconstrainedX = windowWidth - estimatedWidth;\n\n\t\t}\n\n\t\tif ( constrainedX < 0 ) {\n\n\t\t\tconstrainedX = 0;\n\n\t\t}\n\n\t\tif ( constrainedY + estimatedHeight > windowHeight ) {\n\n\t\t\tconstrainedY = windowHeight - estimatedHeight;\n\n\t\t}\n\n\t\tif ( constrainedY < 0 ) {\n\n\t\t\tconstrainedY = 0;\n\n\t\t}\n\n\t\tconst windowPanel = document.createElement( 'div' );\n\t\twindowPanel.className = 'detached-tab-panel';\n\t\twindowPanel.style.left = `${ constrainedX }px`;\n\t\twindowPanel.style.top = `${ constrainedY }px`;\n\n\t\tif ( ! this.panel.classList.contains( 'visible' ) ) {\n\n\t\t\twindowPanel.style.opacity = '0';\n\t\t\twindowPanel.style.visibility = 'hidden';\n\t\t\twindowPanel.style.pointerEvents = 'none';\n\n\t\t}\n\n\t\t// Hide detached window if tab is not visible\n\t\tif ( ! tab.isVisible ) {\n\n\t\t\twindowPanel.style.display = 'none';\n\n\t\t}\n\n\t\tconst windowHeader = document.createElement( 'div' );\n\t\twindowHeader.className = 'detached-tab-header';\n\n\t\tconst title = document.createElement( 'span' );\n\t\ttitle.textContent = tab.button.textContent.replace( '⇱', '' ).trim();\n\t\twindowHeader.appendChild( title );\n\n\t\tconst headerControls = document.createElement( 'div' );\n\t\theaderControls.className = 'detached-header-controls';\n\n\t\tconst reattachBtn = document.createElement( 'button' );\n\t\treattachBtn.className = 'detached-reattach-btn';\n\t\treattachBtn.innerHTML = '↩';\n\t\treattachBtn.title = 'Reattach to main panel';\n\t\treattachBtn.onclick = () => this.reattachTab( tab );\n\n\t\theaderControls.appendChild( reattachBtn );\n\t\twindowHeader.appendChild( headerControls );\n\n\t\tconst windowContent = document.createElement( 'div' );\n\t\twindowContent.className = 'detached-tab-content';\n\t\twindowContent.appendChild( tab.content );\n\n\t\t// Make sure content is visible\n\t\ttab.content.style.display = 'block';\n\t\ttab.content.classList.add( 'active' );\n\n\t\t// Create resize handles for all edges\n\t\tconst resizerTop = document.createElement( 'div' );\n\t\tresizerTop.className = 'detached-tab-resizer-top';\n\n\t\tconst resizerRight = document.createElement( 'div' );\n\t\tresizerRight.className = 'detached-tab-resizer-right';\n\n\t\tconst resizerBottom = document.createElement( 'div' );\n\t\tresizerBottom.className = 'detached-tab-resizer-bottom';\n\n\t\tconst resizerLeft = document.createElement( 'div' );\n\t\tresizerLeft.className = 'detached-tab-resizer-left';\n\n\t\tconst resizerCorner = document.createElement( 'div' );\n\t\tresizerCorner.className = 'detached-tab-resizer';\n\n\t\twindowPanel.appendChild( resizerTop );\n\t\twindowPanel.appendChild( resizerRight );\n\t\twindowPanel.appendChild( resizerBottom );\n\t\twindowPanel.appendChild( resizerLeft );\n\t\twindowPanel.appendChild( resizerCorner );\n\t\twindowPanel.appendChild( windowHeader );\n\t\twindowPanel.appendChild( windowContent );\n\n\t\tdocument.body.appendChild( windowPanel );\n\n\t\t// Setup window dragging\n\t\tthis.setupDetachedWindowDrag( windowPanel, windowHeader, tab );\n\n\t\t// Setup window resizing\n\t\tthis.setupDetachedWindowResize( windowPanel, resizerTop, resizerRight, resizerBottom, resizerLeft, resizerCorner );\n\n\t\t// Use the same z-index that was set on the preview window\n\t\twindowPanel.style.setProperty( 'z-index', this.maxZIndex, 'important' );\n\n\t\treturn { panel: windowPanel, tab: tab };\n\n\t}\n\n\tbringWindowToFront( windowPanel ) {\n\n\t\t// Increment the max z-index and apply it to the clicked window\n\t\tthis.maxZIndex ++;\n\t\twindowPanel.style.setProperty( 'z-index', this.maxZIndex, 'important' );\n\n\t}\n\n\tsetupDetachedWindowDrag( windowPanel, header, tab ) {\n\n\t\tlet isDragging = false;\n\t\tlet startX, startY, startLeft, startTop;\n\n\t\t// Bring window to front when clicking anywhere on it\n\t\twindowPanel.addEventListener( 'pointerdown', () => {\n\n\t\t\tthis.bringWindowToFront( windowPanel );\n\n\t\t} );\n\n\t\tconst onDragStart = ( e ) => {\n\n\t\t\tif ( e.target.classList.contains( 'detached-reattach-btn' ) ) {\n\n\t\t\t\treturn;\n\n\t\t\t}\n\n\t\t\t// Bring window to front when starting to drag\n\t\t\tthis.bringWindowToFront( windowPanel );\n\n\t\t\tisDragging = true;\n\t\t\theader.style.cursor = 'grabbing';\n\t\t\theader.setPointerCapture( e.pointerId );\n\n\t\t\tstartX = e.clientX;\n\t\t\tstartY = e.clientY;\n\n\t\t\tconst rect = windowPanel.getBoundingClientRect();\n\t\t\tstartLeft = rect.left;\n\t\t\tstartTop = rect.top;\n\n\t\t};\n\n\t\tconst onDragMove = ( e ) => {\n\n\t\t\tif ( ! isDragging ) return;\n\n\t\t\te.preventDefault();\n\n\t\t\tconst currentX = e.clientX;\n\t\t\tconst currentY = e.clientY;\n\n\t\t\tconst deltaX = currentX - startX;\n\t\t\tconst deltaY = currentY - startY;\n\n\t\t\tlet newLeft = startLeft + deltaX;\n\t\t\tlet newTop = startTop + deltaY;\n\n\t\t\t// Constrain to window bounds (allow half width/height to extend outside)\n\t\t\tconst windowWidth = window.innerWidth;\n\t\t\tconst windowHeight = window.innerHeight;\n\t\t\tconst panelWidth = windowPanel.offsetWidth;\n\t\t\tconst panelHeight = windowPanel.offsetHeight;\n\t\t\tconst halfWidth = panelWidth / 2;\n\t\t\tconst halfHeight = panelHeight / 2;\n\n\t\t\t// Allow window to extend half its width beyond right edge\n\t\t\tif ( newLeft + panelWidth > windowWidth + halfWidth ) {\n\n\t\t\t\tnewLeft = windowWidth + halfWidth - panelWidth;\n\n\t\t\t}\n\n\t\t\t// Allow window to extend half its width beyond left edge\n\t\t\tif ( newLeft < - halfWidth ) {\n\n\t\t\t\tnewLeft = - halfWidth;\n\n\t\t\t}\n\n\t\t\t// Allow window to extend half its height beyond bottom edge\n\t\t\tif ( newTop + panelHeight > windowHeight + halfHeight ) {\n\n\t\t\t\tnewTop = windowHeight + halfHeight - panelHeight;\n\n\t\t\t}\n\n\t\t\t// Allow window to extend half its height beyond top edge\n\t\t\tif ( newTop < - halfHeight ) {\n\n\t\t\t\tnewTop = - halfHeight;\n\n\t\t\t}\n\n\t\t\twindowPanel.style.left = `${ newLeft }px`;\n\t\t\twindowPanel.style.top = `${ newTop }px`;\n\n\t\t\t// Check if cursor is over the inspector panel\n\t\t\tconst panelRect = this.panel.getBoundingClientRect();\n\t\t\tconst isOverPanel = currentX >= panelRect.left && currentX <= panelRect.right &&\n\t\t\t\t\t\t\t\tcurrentY >= panelRect.top && currentY <= panelRect.bottom;\n\n\t\t\tif ( isOverPanel ) {\n\n\t\t\t\twindowPanel.style.opacity = '0.5';\n\t\t\t\tthis.panel.style.outline = '2px solid var(--accent-color)';\n\n\t\t\t} else {\n\n\t\t\t\twindowPanel.style.opacity = '';\n\t\t\t\tthis.panel.style.outline = '';\n\n\t\t\t}\n\n\t\t};\n\n\t\tconst onDragEnd = ( e ) => {\n\n\t\t\tif ( ! isDragging ) return;\n\n\t\t\tisDragging = false;\n\t\t\theader.style.cursor = '';\n\t\t\twindowPanel.style.opacity = '';\n\t\t\tthis.panel.style.outline = '';\n\n\t\t\t// Check if dropped over the inspector panel\n\t\t\tconst currentX = e.clientX;\n\t\t\tconst currentY = e.clientY;\n\n\t\t\tif ( currentX !== undefined && currentY !== undefined ) {\n\n\t\t\t\tconst panelRect = this.panel.getBoundingClientRect();\n\t\t\t\tconst isOverPanel = currentX >= panelRect.left && currentX <= panelRect.right &&\n\t\t\t\t\t\t\t\t\tcurrentY >= panelRect.top && currentY <= panelRect.bottom;\n\n\t\t\t\tif ( isOverPanel && tab ) {\n\n\t\t\t\t\t// Reattach the tab\n\t\t\t\t\tthis.reattachTab( tab );\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// Save layout after moving detached window\n\t\t\t\t\tthis.saveLayout();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\theader.removeEventListener( 'pointermove', onDragMove );\n\t\t\theader.removeEventListener( 'pointerup', onDragEnd );\n\t\t\theader.removeEventListener( 'pointercancel', onDragEnd );\n\n\t\t};\n\n\t\theader.addEventListener( 'pointerdown', ( e ) => {\n\n\t\t\tonDragStart( e );\n\t\t\theader.addEventListener( 'pointermove', onDragMove );\n\t\t\theader.addEventListener( 'pointerup', onDragEnd );\n\t\t\theader.addEventListener( 'pointercancel', onDragEnd );\n\n\t\t} );\n\n\t\theader.style.cursor = 'grab';\n\n\t}\n\n\tsetupDetachedWindowResize( windowPanel, resizerTop, resizerRight, resizerBottom, resizerLeft, resizerCorner ) {\n\n\t\tconst minWidth = 250;\n\t\tconst minHeight = 150;\n\n\t\tconst setupResizer = ( resizer, direction ) => {\n\n\t\t\tlet isResizing = false;\n\t\t\tlet startX, startY, startWidth, startHeight, startLeft, startTop;\n\n\t\t\tconst onResizeStart = ( e ) => {\n\n\t\t\t\te.preventDefault();\n\t\t\t\te.stopPropagation();\n\t\t\t\tisResizing = true;\n\n\t\t\t\t// Bring window to front when resizing\n\t\t\t\tthis.bringWindowToFront( windowPanel );\n\n\t\t\t\tresizer.setPointerCapture( e.pointerId );\n\n\t\t\t\tstartX = e.clientX;\n\t\t\t\tstartY = e.clientY;\n\t\t\t\tstartWidth = windowPanel.offsetWidth;\n\t\t\t\tstartHeight = windowPanel.offsetHeight;\n\t\t\t\tstartLeft = windowPanel.offsetLeft;\n\t\t\t\tstartTop = windowPanel.offsetTop;\n\n\t\t\t};\n\n\t\t\tconst onResizeMove = ( e ) => {\n\n\t\t\t\tif ( ! isResizing ) return;\n\n\t\t\t\te.preventDefault();\n\n\t\t\t\tconst currentX = e.clientX;\n\t\t\t\tconst currentY = e.clientY;\n\n\t\t\t\tconst deltaX = currentX - startX;\n\t\t\t\tconst deltaY = currentY - startY;\n\n\t\t\t\tconst windowWidth = window.innerWidth;\n\t\t\t\tconst windowHeight = window.innerHeight;\n\n\t\t\t\tif ( direction === 'right' || direction === 'corner' ) {\n\n\t\t\t\t\tconst newWidth = startWidth + deltaX;\n\t\t\t\t\tconst maxWidth = windowWidth - startLeft;\n\n\t\t\t\t\tif ( newWidth >= minWidth && newWidth <= maxWidth ) {\n\n\t\t\t\t\t\twindowPanel.style.width = `${ newWidth }px`;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( direction === 'bottom' || direction === 'corner' ) {\n\n\t\t\t\t\tconst newHeight = startHeight + deltaY;\n\t\t\t\t\tconst maxHeight = windowHeight - startTop;\n\n\t\t\t\t\tif ( newHeight >= minHeight && newHeight <= maxHeight ) {\n\n\t\t\t\t\t\twindowPanel.style.height = `${ newHeight }px`;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( direction === 'left' ) {\n\n\t\t\t\t\tconst newWidth = startWidth - deltaX;\n\t\t\t\t\tconst maxLeft = startLeft + startWidth - minWidth;\n\n\t\t\t\t\tif ( newWidth >= minWidth ) {\n\n\t\t\t\t\t\tconst newLeft = startLeft + deltaX;\n\n\t\t\t\t\t\tif ( newLeft >= 0 && newLeft <= maxLeft ) {\n\n\t\t\t\t\t\t\twindowPanel.style.width = `${ newWidth }px`;\n\t\t\t\t\t\t\twindowPanel.style.left = `${ newLeft }px`;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\tif ( direction === 'top' ) {\n\n\t\t\t\t\tconst newHeight = startHeight - deltaY;\n\t\t\t\t\tconst maxTop = startTop + startHeight - minHeight;\n\n\t\t\t\t\tif ( newHeight >= minHeight ) {\n\n\t\t\t\t\t\tconst newTop = startTop + deltaY;\n\n\t\t\t\t\t\tif ( newTop >= 0 && newTop <= maxTop ) {\n\n\t\t\t\t\t\t\twindowPanel.style.height = `${ newHeight }px`;\n\t\t\t\t\t\t\twindowPanel.style.top = `${ newTop }px`;\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t};\n\n\t\t\tconst onResizeEnd = () => {\n\n\t\t\t\tisResizing = false;\n\n\t\t\t\tresizer.removeEventListener( 'pointermove', onResizeMove );\n\t\t\t\tresizer.removeEventListener( 'pointerup', onResizeEnd );\n\t\t\t\tresizer.removeEventListener( 'pointercancel', onResizeEnd );\n\n\t\t\t\t// Save layout after resizing detached window\n\t\t\t\tthis.saveLayout();\n\n\t\t\t};\n\n\t\t\tresizer.addEventListener( 'pointerdown', ( e ) => {\n\n\t\t\t\tonResizeStart( e );\n\t\t\t\tresizer.addEventListener( 'pointermove', onResizeMove );\n\t\t\t\tresizer.addEventListener( 'pointerup', onResizeEnd );\n\t\t\t\tresizer.addEventListener( 'pointercancel', onResizeEnd );\n\n\t\t\t} );\n\n\t\t};\n\n\t\t// Setup all resizers\n\t\tsetupResizer( resizerTop, 'top' );\n\t\tsetupResizer( resizerRight, 'right' );\n\t\tsetupResizer( resizerBottom, 'bottom' );\n\t\tsetupResizer( resizerLeft, 'left' );\n\t\tsetupResizer( resizerCorner, 'corner' );\n\n\t}\n\n\treattachTab( tab ) {\n\n\t\tif ( ! tab.isDetached ) return;\n\n\t\tif ( tab.detachedWindow ) {\n\n\t\t\tconst index = this.detachedWindows.indexOf( tab.detachedWindow );\n\n\t\t\tif ( index > - 1 ) {\n\n\t\t\t\tthis.detachedWindows.splice( index, 1 );\n\n\t\t\t}\n\n\t\t\tif ( tab.detachedWindow.panel.parentNode ) {\n\n\t\t\t\ttab.detachedWindow.panel.parentNode.removeChild( tab.detachedWindow.panel );\n\n\t\t\t}\n\n\t\t\ttab.detachedWindow = null;\n\n\t\t}\n\n\t\ttab.isDetached = false;\n\n\t\t// Get all tabs and sort by their original index to determine the correct order\n\t\tconst allTabs = Object.values( this.tabs );\n\t\tconst allTabsSorted = allTabs\n\t\t\t.filter( t => t.originalIndex !== undefined && t.isVisible )\n\t\t\t.sort( ( a, b ) => a.originalIndex - b.originalIndex );\n\n\t\t// Get currently attached tab buttons\n\t\tconst currentButtons = Array.from( this.tabsContainer.children );\n\n\t\t// Find the correct position for this tab\n\t\tlet insertIndex = 0;\n\t\tfor ( const t of allTabsSorted ) {\n\n\t\t\tif ( t.id === tab.id ) {\n\n\t\t\t\tbreak;\n\n\t\t\t}\n\n\t\t\t// Count only non-detached tabs that come before this one\n\t\t\tif ( ! t.isDetached ) {\n\n\t\t\t\tinsertIndex ++;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Insert the button at the correct position\n\t\tif ( insertIndex >= currentButtons.length || currentButtons.length === 0 ) {\n\n\t\t\t// If insert index is beyond current buttons, or no buttons exist, append at the end\n\t\t\tthis.tabsContainer.appendChild( tab.button );\n\n\t\t} else {\n\n\t\t\t// Insert before the button at the insert index\n\t\t\tthis.tabsContainer.insertBefore( tab.button, currentButtons[ insertIndex ] );\n\n\t\t}\n\n\t\tthis.contentWrapper.appendChild( tab.content );\n\n\t\tthis.setActiveTab( tab.id );\n\n\t\t// Update panel size after reattaching\n\t\tthis.updatePanelSize();\n\n\t\tthis.saveLayout();\n\n\t}\n\n\tsetActiveTab( id ) {\n\n\t\tif ( this.activeTabId && this.tabs[ this.activeTabId ] && ! this.tabs[ this.activeTabId ].isDetached ) {\n\n\t\t\tthis.tabs[ this.activeTabId ].setActive( false );\n\n\t\t}\n\n\t\tthis.activeTabId = id;\n\n\t\tif ( this.tabs[ id ] ) {\n\n\t\t\tthis.tabs[ id ].setActive( true );\n\n\t\t}\n\n\t}\n\n\ttogglePanel() {\n\n\t\tthis.panel.classList.toggle( 'visible' );\n\t\tthis.toggleButton.classList.toggle( 'hidden' );\n\n\t\tconst isVisible = this.panel.classList.contains( 'visible' );\n\n\t\tif ( isVisible ) {\n\n\t\t\t// Save mini-panel state before hiding\n\t\t\tthis.savedMiniPanelState = {\n\t\t\t\tisVisible: this.miniPanel.classList.contains( 'visible' ),\n\t\t\t\tactiveTabId: null,\n\t\t\t\tcontentMap: {}\n\t\t\t};\n\n\t\t\t// Find which tab was active in mini-panel\n\t\t\tthis.miniPanel.querySelectorAll( '.mini-panel-content' ).forEach( content => {\n\n\t\t\t\tif ( content.style.display !== 'none' && content.firstChild ) {\n\n\t\t\t\t\t// Find the tab that owns this content\n\t\t\t\t\tObject.values( this.tabs ).forEach( tab => {\n\n\t\t\t\t\t\tif ( tab.miniContent === content ) {\n\n\t\t\t\t\t\t\tthis.savedMiniPanelState.activeTabId = tab.id;\n\t\t\t\t\t\t\t// Move content back to main panel\n\t\t\t\t\t\t\ttab.content.appendChild( content.firstChild );\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} );\n\n\t\t\t\t}\n\n\t\t\t} );\n\n\t\t\t// Hide mini-panel temporarily\n\t\t\tthis.miniPanel.classList.remove( 'visible' );\n\n\t\t\t// Hide all mini-panel contents\n\t\t\tthis.miniPanel.querySelectorAll( '.mini-panel-content' ).forEach( content => {\n\n\t\t\t\tcontent.style.display = 'none';\n\n\t\t\t} );\n\n\t\t\t// Remove active state from builtin buttons\n\t\t\tthis.builtinTabsContainer.querySelectorAll( '.builtin-tab-btn' ).forEach( btn => {\n\n\t\t\t\tbtn.classList.remove( 'active' );\n\n\t\t\t} );\n\n\t\t} else {\n\n\t\t\t// Restore mini-panel state when minimizing\n\t\t\tif ( this.savedMiniPanelState && this.savedMiniPanelState.isVisible && this.savedMiniPanelState.activeTabId ) {\n\n\t\t\t\tconst tab = this.tabs[ this.savedMiniPanelState.activeTabId ];\n\n\t\t\t\tif ( tab && tab.miniContent && tab.builtinButton ) {\n\n\t\t\t\t\t// Restore mini-panel visibility\n\t\t\t\t\tthis.miniPanel.classList.add( 'visible' );\n\t\t\t\t\ttab.miniContent.style.display = 'block';\n\t\t\t\t\ttab.builtinButton.classList.add( 'active' );\n\n\t\t\t\t\t// Move content back to mini-panel\n\t\t\t\t\tconst actualContent = tab.content.querySelector( '.list-scroll-wrapper, .profiler-content > *' );\n\n\t\t\t\t\tif ( actualContent ) {\n\n\t\t\t\t\t\ttab.miniContent.appendChild( actualContent );\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t}\n\n\t\tthis.detachedWindows.forEach( detachedWindow => {\n\n\t\t\tif ( isVisible ) {\n\n\t\t\t\tdetachedWindow.panel.style.opacity = '';\n\t\t\t\tdetachedWindow.panel.style.visibility = '';\n\t\t\t\tdetachedWindow.panel.style.pointerEvents = '';\n\n\t\t\t} else {\n\n\t\t\t\tdetachedWindow.panel.style.opacity = '0';\n\t\t\t\tdetachedWindow.panel.style.visibility = 'hidden';\n\t\t\t\tdetachedWindow.panel.style.pointerEvents = 'none';\n\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\ttogglePosition() {\n\n\t\tconst newPosition = this.position === 'bottom' ? 'right' : 'bottom';\n\t\tthis.setPosition( newPosition );\n\n\t}\n\n\tsetPosition( targetPosition ) {\n\n\t\tif ( this.position === targetPosition ) return;\n\n\t\tthis.panel.style.transition = 'none';\n\n\t\t// Check if panel is currently maximized\n\t\tconst isMaximized = this.panel.classList.contains( 'maximized' );\n\n\t\tif ( targetPosition === 'right' ) {\n\n\t\t\tthis.position = 'right';\n\t\t\tthis.floatingBtn.classList.add( 'active' );\n\t\t\tthis.floatingBtn.innerHTML = '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><path d=\"M3 15h18\"></path></svg>';\n\t\t\tthis.floatingBtn.title = 'Switch to Bottom';\n\n\t\t\t// Apply right position styles\n\t\t\tthis.panel.classList.remove( 'position-bottom' );\n\t\t\tthis.panel.classList.add( 'position-right' );\n\t\t\tthis.panel.style.bottom = '';\n\t\t\tthis.panel.style.top = '0';\n\t\t\tthis.panel.style.right = '0';\n\t\t\tthis.panel.style.left = '';\n\n\t\t\t// Apply size based on maximized state\n\t\t\tif ( isMaximized ) {\n\n\t\t\t\tthis.panel.style.width = '100vw';\n\t\t\t\tthis.panel.style.height = '100%';\n\n\t\t\t} else {\n\n\t\t\t\tthis.panel.style.width = `${ this.lastWidthRight }px`;\n\t\t\t\tthis.panel.style.height = '100%';\n\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tthis.position = 'bottom';\n\t\t\tthis.floatingBtn.classList.remove( 'active' );\n\t\t\tthis.floatingBtn.innerHTML = '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><line x1=\"15\" y1=\"3\" x2=\"15\" y2=\"21\"></line></svg>';\n\t\t\tthis.floatingBtn.title = 'Switch to Right Side';\n\n\t\t\t// Apply bottom position styles\n\t\t\tthis.panel.classList.remove( 'position-right' );\n\t\t\tthis.panel.classList.add( 'position-bottom' );\n\t\t\tthis.panel.style.top = '';\n\t\t\tthis.panel.style.right = '';\n\t\t\tthis.panel.style.bottom = '0';\n\t\t\tthis.panel.style.left = '0';\n\n\t\t\t// Apply size based on maximized state\n\t\t\tif ( isMaximized ) {\n\n\t\t\t\tthis.panel.style.width = '100%';\n\t\t\t\tthis.panel.style.height = '100vh';\n\n\t\t\t} else {\n\n\t\t\t\tthis.panel.style.width = '100%';\n\t\t\t\tthis.panel.style.height = `${ this.lastHeightBottom }px`;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Re-enable transition after a brief delay\n\t\tsetTimeout( () => {\n\n\t\t\tthis.panel.style.transition = '';\n\n\t\t}, 50 );\n\n\t\t// Update panel size based on visible tabs\n\t\tthis.updatePanelSize();\n\n\t\t// Save layout after position change\n\t\tthis.saveLayout();\n\n\t}\n\n\tsaveLayout() {\n\n\t\tconst layout = {\n\t\t\tposition: this.position,\n\t\t\tlastHeightBottom: this.lastHeightBottom,\n\t\t\tlastWidthRight: this.lastWidthRight,\n\t\t\tactiveTabId: this.activeTabId,\n\t\t\tdetachedTabs: []\n\t\t};\n\n\t\t// Save detached windows state\n\t\tthis.detachedWindows.forEach( detachedWindow => {\n\n\t\t\tconst tab = detachedWindow.tab;\n\t\t\tconst panel = detachedWindow.panel;\n\n\t\t\t// Get position values, ensuring they're valid numbers\n\t\t\tconst left = parseFloat( panel.style.left ) || panel.offsetLeft || 0;\n\t\t\tconst top = parseFloat( panel.style.top ) || panel.offsetTop || 0;\n\t\t\tconst width = panel.offsetWidth;\n\t\t\tconst height = panel.offsetHeight;\n\n\t\t\tlayout.detachedTabs.push( {\n\t\t\t\ttabId: tab.id,\n\t\t\t\toriginalIndex: tab.originalIndex !== undefined ? tab.originalIndex : 0,\n\t\t\t\tleft: left,\n\t\t\t\ttop: top,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t} );\n\n\t\t} );\n\n\t\ttry {\n\n\t\t\tlocalStorage.setItem( 'profiler-layout', JSON.stringify( layout ) );\n\n\t\t} catch ( e ) {\n\n\t\t\tconsole.warn( 'Failed to save profiler layout:', e );\n\n\t\t}\n\n\t}\n\n\tloadLayout() {\n\n\t\ttry {\n\n\t\t\tconst savedLayout = localStorage.getItem( 'profiler-layout' );\n\n\t\t\tif ( ! savedLayout ) return;\n\n\t\t\tconst layout = JSON.parse( savedLayout );\n\n\t\t\t// Constrain detached tabs positions to current screen bounds\n\t\t\tif ( layout.detachedTabs && layout.detachedTabs.length > 0 ) {\n\n\t\t\t\tconst windowWidth = window.innerWidth;\n\t\t\t\tconst windowHeight = window.innerHeight;\n\n\t\t\t\tlayout.detachedTabs = layout.detachedTabs.map( detachedTabData => {\n\n\t\t\t\t\tlet { left, top, width, height } = detachedTabData;\n\n\t\t\t\t\t// Ensure width and height are within bounds\n\t\t\t\t\tif ( width > windowWidth ) {\n\n\t\t\t\t\t\twidth = windowWidth - 100; // Leave some margin\n\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( height > windowHeight ) {\n\n\t\t\t\t\t\theight = windowHeight - 100; // Leave some margin\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Allow window to extend half its width/height outside the screen\n\t\t\t\t\tconst halfWidth = width / 2;\n\t\t\t\t\tconst halfHeight = height / 2;\n\n\t\t\t\t\t// Constrain horizontal position (allow half width to extend beyond right edge)\n\t\t\t\t\tif ( left + width > windowWidth + halfWidth ) {\n\n\t\t\t\t\t\tleft = windowWidth + halfWidth - width;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Constrain horizontal position (allow half width to extend beyond left edge)\n\t\t\t\t\tif ( left < - halfWidth ) {\n\n\t\t\t\t\t\tleft = - halfWidth;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Constrain vertical position (allow half height to extend beyond bottom edge)\n\t\t\t\t\tif ( top + height > windowHeight + halfHeight ) {\n\n\t\t\t\t\t\ttop = windowHeight + halfHeight - height;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t// Constrain vertical position (allow half height to extend beyond top edge)\n\t\t\t\t\tif ( top < - halfHeight ) {\n\n\t\t\t\t\t\ttop = - halfHeight;\n\n\t\t\t\t\t}\n\n\t\t\t\t\treturn {\n\t\t\t\t\t\t...detachedTabData,\n\t\t\t\t\t\tleft,\n\t\t\t\t\t\ttop,\n\t\t\t\t\t\twidth,\n\t\t\t\t\t\theight\n\t\t\t\t\t};\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t\t// Restore position and dimensions\n\t\t\tif ( layout.position ) {\n\n\t\t\t\tthis.position = layout.position;\n\n\t\t\t}\n\n\t\t\tif ( layout.lastHeightBottom ) {\n\n\t\t\t\tthis.lastHeightBottom = layout.lastHeightBottom;\n\n\t\t\t}\n\n\t\t\tif ( layout.lastWidthRight ) {\n\n\t\t\t\tthis.lastWidthRight = layout.lastWidthRight;\n\n\t\t\t}\n\n\t\t\t// Constrain saved dimensions to current screen bounds\n\t\t\tconst windowWidth = window.innerWidth;\n\t\t\tconst windowHeight = window.innerHeight;\n\n\t\t\tif ( this.lastHeightBottom > windowHeight - 50 ) {\n\n\t\t\t\tthis.lastHeightBottom = windowHeight - 50;\n\n\t\t\t}\n\n\t\t\tif ( this.lastWidthRight > windowWidth - 50 ) {\n\n\t\t\t\tthis.lastWidthRight = windowWidth - 50;\n\n\t\t\t}\n\n\t\t\t// Apply the saved position after shell is set up\n\t\t\tif ( this.position === 'right' ) {\n\n\t\t\t\tthis.floatingBtn.classList.add( 'active' );\n\t\t\t\tthis.floatingBtn.innerHTML = '<svg width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"3\" y=\"3\" width=\"18\" height=\"18\" rx=\"2\" ry=\"2\"></rect><path d=\"M3 15h18\"></path></svg>';\n\t\t\t\tthis.floatingBtn.title = 'Switch to Bottom';\n\n\t\t\t\tthis.panel.classList.remove( 'position-bottom' );\n\t\t\t\tthis.panel.classList.add( 'position-right' );\n\t\t\t\tthis.panel.style.bottom = '';\n\t\t\t\tthis.panel.style.top = '0';\n\t\t\t\tthis.panel.style.right = '0';\n\t\t\t\tthis.panel.style.left = '';\n\t\t\t\tthis.panel.style.width = `${ this.lastWidthRight }px`;\n\t\t\t\tthis.panel.style.height = '100%';\n\n\t\t\t} else {\n\n\t\t\t\tthis.panel.style.height = `${ this.lastHeightBottom }px`;\n\n\t\t\t}\n\n\t\t\tif ( layout.activeTabId ) {\n\n\t\t\t\tconst willBeDetached = layout.detachedTabs &&\n\t\t\t\t\tlayout.detachedTabs.some( dt => dt.tabId === layout.activeTabId );\n\n\t\t\t\tif ( willBeDetached ) {\n\n\t\t\t\t\tthis.setActiveTab( layout.activeTabId );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif ( layout.detachedTabs && layout.detachedTabs.length > 0 ) {\n\n\t\t\t\tthis.pendingDetachedTabs = layout.detachedTabs;\n\t\t\t\tthis.restoreDetachedTabs();\n\n\t\t\t}\n\n\t\t\t// Update panel size after loading layout\n\t\t\tthis.updatePanelSize();\n\n\t\t} catch ( e ) {\n\n\t\t\tconsole.warn( 'Failed to load profiler layout:', e );\n\n\t\t}\n\n\t}\n\n\trestoreDetachedTabs() {\n\n\t\tif ( ! this.pendingDetachedTabs || this.pendingDetachedTabs.length === 0 ) return;\n\n\t\tthis.pendingDetachedTabs.forEach( detachedTabData => {\n\n\t\t\tconst tab = this.tabs[ detachedTabData.tabId ];\n\n\t\t\tif ( ! tab || tab.isDetached ) return;\n\n\t\t\t// Restore originalIndex if saved\n\t\t\tif ( detachedTabData.originalIndex !== undefined ) {\n\n\t\t\t\ttab.originalIndex = detachedTabData.originalIndex;\n\n\t\t\t}\n\n\t\t\tif ( tab.button.parentNode ) {\n\n\t\t\t\ttab.button.parentNode.removeChild( tab.button );\n\n\t\t\t}\n\n\t\t\tif ( tab.content.parentNode ) {\n\n\t\t\t\ttab.content.parentNode.removeChild( tab.content );\n\n\t\t\t}\n\n\t\t\tconst detachedWindow = this.createDetachedWindow( tab, 0, 0 );\n\n\t\t\tdetachedWindow.panel.style.left = `${ detachedTabData.left }px`;\n\t\t\tdetachedWindow.panel.style.top = `${ detachedTabData.top }px`;\n\t\t\tdetachedWindow.panel.style.width = `${ detachedTabData.width }px`;\n\t\t\tdetachedWindow.panel.style.height = `${ detachedTabData.height }px`;\n\n\t\t\t// Constrain window to bounds after restoring position and size\n\t\t\tthis.constrainWindowToBounds( detachedWindow.panel );\n\n\t\t\tthis.detachedWindows.push( detachedWindow );\n\n\t\t\ttab.isDetached = true;\n\t\t\ttab.detachedWindow = detachedWindow;\n\n\t\t} );\n\n\t\tthis.pendingDetachedTabs = null;\n\n\t\t// Update maxZIndex to be higher than all existing windows\n\t\tthis.detachedWindows.forEach( detachedWindow => {\n\n\t\t\tconst currentZIndex = parseInt( getComputedStyle( detachedWindow.panel ).zIndex ) || 0;\n\t\t\tif ( currentZIndex > this.maxZIndex ) {\n\n\t\t\t\tthis.maxZIndex = currentZIndex;\n\n\t\t\t}\n\n\t\t} );\n\n\t\tconst needsNewActiveTab = ! this.activeTabId ||\n\t\t\t! this.tabs[ this.activeTabId ] ||\n\t\t\tthis.tabs[ this.activeTabId ].isDetached ||\n\t\t\t! this.tabs[ this.activeTabId ].isVisible;\n\n\t\tif ( needsNewActiveTab ) {\n\n\t\t\tconst tabIds = Object.keys( this.tabs );\n\t\t\tconst availableTabs = tabIds.filter( id =>\n\t\t\t\t! this.tabs[ id ].isDetached &&\n\t\t\t\tthis.tabs[ id ].isVisible\n\t\t\t);\n\n\t\t\tif ( availableTabs.length > 0 ) {\n\n\t\t\t\tconst buttons = Array.from( this.tabsContainer.children );\n\t\t\t\tconst orderedTabIds = buttons.map( btn => {\n\n\t\t\t\t\treturn Object.keys( this.tabs ).find( id => this.tabs[ id ].button === btn );\n\n\t\t\t\t} ).filter( id =>\n\t\t\t\t\tid !== undefined &&\n\t\t\t\t\t! this.tabs[ id ].isDetached &&\n\t\t\t\t\tthis.tabs[ id ].isVisible\n\t\t\t\t);\n\n\t\t\t\tthis.setActiveTab( orderedTabIds[ 0 ] || availableTabs[ 0 ] );\n\n\t\t\t} else {\n\n\t\t\t\tthis.activeTabId = null;\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Update panel size after restoring detached tabs\n\t\tthis.updatePanelSize();\n\n\t}\n\n}\n","/**\n * Tab class\n * @param {string} title - The title of the tab\n * @param {Object} options - Options for the tab\n * @param {boolean} [options.allowDetach=true] - Whether the tab can be detached into a separate window\n * @param {boolean} [options.builtin=false] - Whether the tab should appear in the profiler-toggle button\n * @param {string} [options.icon] - SVG icon HTML for the builtin button\n *\n * @example\n * // Create a tab that can be detached (default behavior)\n * const tab1 = new Tab('My Tab');\n *\n * // Create a tab that cannot be detached\n * const tab2 = new Tab('Fixed Tab', { allowDetach: false });\n *\n * // Create a builtin tab that appears in the profiler-toggle\n * const tab3 = new Tab('Builtin Tab', { builtin: true });\n *\n * // Create a builtin tab with custom icon\n * const tab4 = new Tab('Settings', { builtin: true, icon: '<svg>...</svg>' });\n *\n * // Control builtin tab visibility\n * tab3.showBuiltin(); // Show the builtin button and mini-content\n * tab3.hideBuiltin(); // Hide the builtin button and mini-content\n */\nexport class Tab {\n\n\tconstructor( title, options = {} ) {\n\n\t\tthis.id = title.toLowerCase();\n\t\tthis.button = document.createElement( 'button' );\n\t\tthis.button.className = 'tab-btn';\n\t\tthis.button.textContent = title;\n\n\t\tthis.content = document.createElement( 'div' );\n\t\tthis.content.id = `${this.id}-content`;\n\t\tthis.content.className = 'profiler-content';\n\n\t\tthis.isActive = false;\n\t\tthis.isVisible = true;\n\t\tthis.isDetached = false;\n\t\tthis.detachedWindow = null;\n\t\tthis.allowDetach = options.allowDetach !== undefined ? options.allowDetach : true;\n\t\tthis.builtin = options.builtin !== undefined ? options.builtin : false;\n\t\tthis.icon = options.icon || null;\n\t\tthis.builtinButton = null; // Reference to the builtin button in profiler-toggle\n\t\tthis.miniContent = null; // Reference to the mini-panel content container\n\t\tthis.profiler = null; // Reference to the profiler instance\n\t\tthis.onVisibilityChange = null; // Callback for visibility changes\n\n\t}\n\n\tsetActive( isActive ) {\n\n\t\tthis.button.classList.toggle( 'active', isActive );\n\t\tthis.content.classList.toggle( 'active', isActive );\n\n\t\tthis.isActive = isActive;\n\n\t}\n\n\tshow() {\n\n\t\tthis.content.style.display = '';\n\t\tthis.button.style.display = '';\n\n\t\tthis.isVisible = true;\n\n\t\t// Show detached window if tab is detached\n\t\tif ( this.isDetached && this.detachedWindow ) {\n\n\t\t\tthis.detachedWindow.panel.style.display = '';\n\n\t\t}\n\n\t\t// Notify profiler of visibility change\n\t\tif ( this.onVisibilityChange ) {\n\n\t\t\tthis.onVisibilityChange();\n\n\t\t}\n\n\t\tthis.showBuiltin();\n\n\t}\n\n\thide() {\n\n\t\tthis.content.style.display = 'none';\n\t\tthis.button.style.display = 'none';\n\n\t\tthis.isVisible = false;\n\n\t\t// Hide detached window if tab is detached\n\t\tif ( this.isDetached && this.detachedWindow ) {\n\n\t\t\tthis.detachedWindow.panel.style.display = 'none';\n\n\t\t}\n\n\t\t// Notify profiler of visibility change\n\t\tif ( this.onVisibilityChange ) {\n\n\t\t\tthis.onVisibilityChange();\n\n\t\t}\n\n\t\tthis.hideBuiltin();\n\n\t}\n\n\tshowBuiltin() {\n\n\t\tif ( ! this.builtin ) return;\n\n\t\t// Show the builtin-tabs-container\n\t\tif ( this.profiler && this.profiler.builtinTabsContainer ) {\n\n\t\t\tthis.profiler.builtinTabsContainer.style.display = '';\n\n\t\t}\n\n\t\t// Show the button\n\t\tif ( this.builtinButton ) {\n\n\t\t\tthis.builtinButton.style.display = '';\n\n\t\t}\n\n\t\t// Show and activate the mini-panel with content\n\t\tif ( this.miniContent && this.profiler ) {\n\n\t\t\t// Hide all other mini-panel contents\n\t\t\tthis.profiler.miniPanel.querySelectorAll( '.mini-panel-content' ).forEach( content => {\n\n\t\t\t\tcontent.style.display = 'none';\n\n\t\t\t} );\n\n\t\t\t// Remove active state from all builtin buttons\n\t\t\tthis.profiler.builtinTabsContainer.querySelectorAll( '.builtin-tab-btn' ).forEach( btn => {\n\n\t\t\t\tbtn.classList.remove( 'active' );\n\n\t\t\t} );\n\n\t\t\t// Activate this tab's button\n\t\t\tif ( this.builtinButton ) {\n\n\t\t\t\tthis.builtinButton.classList.add( 'active' );\n\n\t\t\t}\n\n\t\t\t// Move content to mini-panel if not already there\n\t\t\tif ( ! this.miniContent.firstChild ) {\n\n\t\t\t\tconst actualContent = this.content.querySelector( '.list-scroll-wrapper' ) || this.content.firstElementChild;\n\n\t\t\t\tif ( actualContent ) {\n\n\t\t\t\t\tthis.miniContent.appendChild( actualContent );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Show the mini-panel and content\n\t\t\tthis.miniContent.style.display = 'block';\n\t\t\tthis.profiler.miniPanel.classList.add( 'visible' );\n\n\t\t}\n\n\t}\n\n\thideBuiltin() {\n\n\t\tif ( ! this.builtin ) return;\n\n\t\t// Hide the button\n\t\tif ( this.builtinButton ) {\n\n\t\t\tthis.builtinButton.style.display = 'none';\n\n\t\t}\n\n\t\t// Hide the mini-panel content\n\t\tif ( this.miniContent ) {\n\n\t\t\tthis.miniContent.style.display = 'none';\n\n\t\t\t// Move content back to main panel\n\t\t\tif ( this.miniContent.firstChild ) {\n\n\t\t\t\tthis.content.appendChild( this.miniContent.firstChild );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// Deactivate button\n\t\tif ( this.builtinButton ) {\n\n\t\t\tthis.builtinButton.classList.remove( 'active' );\n\n\t\t}\n\n\t\t// Hide mini-panel if no content is visible\n\t\tif ( this.profiler ) {\n\n\t\t\tconst hasVisibleContent = Array.from( this.profiler.miniPanel.querySelectorAll( '.mini-panel-content' ) )\n\t\t\t\t.some( content => content.style.display !== 'none' );\n\n\t\t\tif ( ! hasVisibleContent ) {\n\n\t\t\t\tthis.profiler.miniPanel.classList.remove( 'visible' );\n\n\t\t\t}\n\n\t\t\t// Hide the builtin-tabs-container if all builtin buttons are hidden\n\t\t\tconst hasVisibleBuiltinButtons = Array.from( this.profiler.builtinTabsContainer.querySelectorAll( '.builtin-tab-btn' ) )\n\t\t\t\t.some( btn => btn.style.display !== 'none' );\n\n\t\t\tif ( ! hasVisibleBuiltinButtons ) {\n\n\t\t\t\tthis.profiler.builtinTabsContainer.style.display = 'none';\n\n\t\t\t}\n\n\t\t}\n\n\t}\n\n}\n","\nexport class List {\n\n\tconstructor( ...headers ) {\n\n\t\tthis.headers = headers;\n\t\tthis.children = [];\n\t\tthis.domElement = document.createElement( 'div' );\n\t\tthis.domElement.className = 'list-container';\n\t\tthis.domElement.style.padding = '10px';\n\t\tthis.id = `list-${Math.random().toString( 36 ).substr( 2, 9 )}`;\n\t\tthis.domElement.dataset.listId = this.id;\n\n\t\tthis.gridStyleElement = document.createElement( 'style' );\n\t\tthis.domElement.appendChild( this.gridStyleElement );\n\n\t\tconst headerRow = document.createElement( 'div' );\n\t\theaderRow.className = 'list-header';\n\t\tthis.headers.forEach( headerText => {\n\n\t\t\tconst headerCell = document.createElement( 'div' );\n\t\t\theaderCell.className = 'list-header-cell';\n\t\t\theaderCell.textContent = headerText;\n\t\t\theaderRow.appendChild( headerCell );\n\n\t\t} );\n\t\tthis.domElement.appendChild( headerRow );\n\n\t}\n\n\tsetGridStyle( gridTemplate ) {\n\n\t\tthis.gridStyleElement.textContent = `\n[data-list-id=\"${this.id}\"] > .list-header,\n[data-list-id=\"${this.id}\"] .list-item-row {\n\tgrid-template-columns: ${gridTemplate};\n}\n`;\n\n\t}\n\n\tadd( item ) {\n\n\t\tif ( item.parent !== null ) {\n\n\t\t\titem.parent.remove( item );\n\n\t\t}\n\n\t\titem.domElement.classList.add( 'header-wrapper', 'section-start' );\n\t\titem.parent = this;\n\n\t\tthis.children.push( item );\n\t\tthis.domElement.appendChild( item.domElement );\n\n\t}\n\n\tremove( item ) {\n\n\t\tconst index = this.children.indexOf( item );\n\n\t\tif ( index !== - 1 ) {\n\n\t\t\tthis.children.splice( index, 1 );\n\t\t\tthis.domElement.removeChild( item.domElement );\n\n\t\t\titem.parent = null;\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n}\n","\nexport class Graph {\n\n\tconstructor( maxPoints = 512 ) {\n\n\t\tthis.maxPoints = maxPoints;\n\t\tthis.lines = {};\n\t\tthis.limit = 0;\n\t\tthis.limitIndex = 0;\n\n\t\tthis.domElement = document.createElementNS( 'http://www.w3.org/2000/svg', 'svg' );\n\t\tthis.domElement.setAttribute( 'class', 'graph-svg' );\n\n\t}\n\n\taddLine( id, color ) {\n\n\t\tconst path = document.createElementNS( 'http://www.w3.org/2000/svg', 'path' );\n\t\tpath.setAttribute( 'class', 'graph-path' );\n\t\tpath.style.stroke = `var(${color})`;\n\t\tpath.style.fill = `var(${color})`;\n\t\tthis.domElement.appendChild( path );\n\n\t\tthis.lines[ id ] = { path, color, points: [] };\n\n\t}\n\n\taddPoint( lineId, value ) {\n\n\t\tconst line = this.lines[ lineId ];\n\t\tif ( ! line ) return;\n\n\t\tline.points.push( value );\n\t\tif ( line.points.length > this.maxPoints ) {\n\n\t\t\tline.points.shift();\n\n\t\t}\n\n\t\tif ( value > this.limit ) {\n\n\t\t\tthis.limit = value;\n\t\t\tthis.limitIndex = 0;\n\n\t\t}\n\n\t}\n\n\tresetLimit() {\n\n\t\tthis.limit = 0;\n\t\tthis.limitIndex = 0;\n\n\t}\n\n\tupdate() {\n\n\t\tconst svgWidth = this.domElement.clientWidth;\n\t\tconst svgHeight = this.domElement.clientHeight;\n\t\tif ( svgWidth === 0 ) return;\n\n\t\tconst pointStep = svgWidth / ( this.maxPoints - 1 );\n\n\t\tfor ( const id in this.lines ) {\n\n\t\t\tconst line = this.lines[ id ];\n\n\t\t\tlet pathString = `M 0,${ svgHeight }`;\n\t\t\tfor ( let i = 0; i < line.points.length; i ++ ) {\n\n\t\t\t\tconst x = i * pointStep;\n\t\t\t\tconst y = svgHeight - ( line.points[ i ] / this.limit ) * svgHeight;\n\t\t\t\tpathString += ` L ${ x },${ y }`;\n\n\t\t\t}\n\n\t\t\tpathString += ` L ${( line.points.length - 1 ) * pointStep},${ svgHeight } Z`;\n\n\t\t\tconst offset = svgWidth - ( ( line.points.length - 1 ) * pointStep );\n\t\t\tline.path.setAttribute( 'transform', `translate(${ offset }, 0)` );\n\t\t\tline.path.setAttribute( 'd', pathString );\n\n\t\t}\n\n\t\t//\n\n\t\tif ( this.limitIndex ++ > this.maxPoints ) {\n\n\t\t\tthis.resetLimit();\n\n\t\t}\n\n\t}\n\n}\n","export class Item {\n\n\tconstructor( ...data ) {\n\n\t\tthis.children = [];\n\t\tthis.isOpen = true;\n\t\tthis.childrenContainer = null;\n\t\tthis.parent = null;\n\t\tthis.domElement = document.createElement( 'div' );\n\t\tthis.domElement.className = 'list-item-wrapper';\n\t\tthis.itemRow = document.createElement( 'div' );\n\t\tthis.itemRow.className = 'list-item-row';\n\n\t\tthis.userData = {};\n\n\t\tthis.data = data;\n\t\tthis.data.forEach( ( cellData ) => {\n\n\t\t\tconst cell = document.createElement( 'div' );\n\t\t\tcell.className = 'list-item-cell';\n\t\t\tif ( cellData instanceof HTMLElement ) {\n\n\t\t\t\tcell.appendChild( cellData );\n\n\t\t\t} else {\n\n\t\t\t\tcell.append( String( cellData ) );\n\n\t\t\t}\n\n\t\t\tthis.itemRow.appendChild( cell );\n\n\t\t} );\n\n\t\tthis.domElement.appendChild( this.itemRow );\n\n\t\t// Bindings\n\n\t\tthis.onItemClick = this.onItemClick.bind( this );\n\n\t}\n\n\tonItemClick( e ) {\n\n\t\tif ( e.target.closest( 'button, a, input, label' ) ) return;\n\n\t\tthis.toggle();\n\n\t}\n\n\tadd( item, index = this.children.length ) {\n\n\t\tif ( item.parent !== null ) {\n\n\t\t\titem.parent.remove( item );\n\n\t\t}\n\n\t\titem.parent = this;\n\n\t\tthis.children.splice( index, 0, item );\n\n\t\tthis.itemRow.classList.add( 'collapsible' );\n\n\t\tif ( ! this.childrenContainer ) {\n\n\t\t\tthis.childrenContainer = document.createElement( 'div' );\n\t\t\tthis.childrenContainer.className = 'list-children-container';\n\t\t\tthis.childrenContainer.classList.toggle( 'closed', ! this.isOpen );\n\t\t\tthis.domElement.appendChild( this.childrenContainer );\n\t\t\tthis.itemRow.addEventListener( 'click', this.onItemClick );\n\n\t\t}\n\n\t\tthis.childrenContainer.insertBefore(\n\t\t\titem.domElement,\n\t\t\tthis.childrenContainer.children[ index ] || null\n\t\t);\n\n\t\tthis.updateToggler();\n\t\treturn this;\n\n\t}\n\n\tremove( item ) {\n\n\t\tconst index = this.children.indexOf( item );\n\n\t\tif ( index !== - 1 ) {\n\n\t\t\tthis.children.splice( index, 1 );\n\t\t\tthis.childrenContainer.removeChild( item.domElement );\n\n\t\t\titem.parent = null;\n\n\t\t\tif ( this.children.length === 0 ) {\n\n\t\t\t\tthis.itemRow.classList.remove( 'collapsible' );\n\t\t\t\tthis.itemRow.removeEventListener( 'click', this.onItemClick );\n\n\t\t\t\tthis.childrenContainer.remove();\n\t\t\t\tthis.childrenContainer = null;\n\n\t\t\t}\n\n\t\t\tthis.updateToggler();\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tupdateToggler() {\n\n\t\tconst firstCell = this.itemRow.querySelector( '.list-item-cell:first-child' );\n\t\tlet toggler = this.itemRow.querySelector( '.item-toggler' );\n\n\t\tif ( this.children.length > 0 ) {\n\n\t\t\tif ( ! toggler ) {\n\n\t\t\t\ttoggler = document.createElement( 'span' );\n\t\t\t\ttoggler.className = 'item-toggler';\n\t\t\t\tfirstCell.prepend( toggler );\n\n\t\t\t}\n\n\t\t\tif ( this.isOpen ) {\n\n\t\t\t\tthis.itemRow.classList.add( 'open' );\n\n\t\t\t}\n\n\t\t} else if ( toggler ) {\n\n\t\t\ttoggler.remove();\n\n\t\t}\n\n\t}\n\n\ttoggle() {\n\n\t\tthis.isOpen = ! this.isOpen;\n\t\tthis.itemRow.classList.toggle( 'open', this.isOpen );\n\n\t\tif ( this.childrenContainer ) {\n\n\t\t\tthis.childrenContainer.classList.toggle( 'closed', ! this.isOpen );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tclose() {\n\n\t\tif ( this.isOpen ) {\n\n\t\t\tthis.toggle();\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n}\n","export function createValueSpan( id = null ) {\n\n\tconst span = document.createElement( 'span' );\n\tspan.className = 'value';\n\n\tif ( id !== null ) span.id = id;\n\n\treturn span;\n\n}\n\nexport function setText( element, text ) {\n\n\tconst el = element instanceof HTMLElement ? element : document.getElementById( element );\n\n\tif ( el && el.textContent !== text ) {\n\n\t\tel.textContent = text;\n\n\t}\n\n}\n\nexport function getText( element ) {\n\n\tconst el = element instanceof HTMLElement ? element : document.getElementById( element );\n\n\treturn el ? el.textContent : null;\n\n}\n\nexport function splitPath( fullPath ) {\n\n\tconst lastSlash = fullPath.lastIndexOf( '/' );\n\n\tif ( lastSlash === - 1 ) {\n\n\t\treturn {\n\t\t\tpath: '',\n\t\t\tname: fullPath.trim()\n\t\t};\n\n\t}\n\n\tconst path = fullPath.substring( 0, lastSlash ).trim();\n\tconst name = fullPath.substring( lastSlash + 1 ).trim();\n\n\treturn { path, name };\n\n}\n\nexport function splitCamelCase( str ) {\n\n\treturn str.replace( /([a-z0-9])([A-Z])/g, '$1 $2' ).trim();\n\n}\n","import { Tab } from '../ui/Tab.js';\nimport { List } from '../ui/List.js';\nimport { Graph } from '../ui/Graph.js';\nimport { Item } from '../ui/Item.js';\nimport { createValueSpan, setText } from '../ui/utils.js';\n\nclass Performance extends Tab {\n\n\tconstructor( options = {} ) {\n\n\t\tsuper( 'Performance', options );\n\n\t\tconst perfList = new List( 'Name', 'CPU', 'GPU', 'Total' );\n\t\tperfList.setGridStyle( 'minmax(200px, 2fr) 80px 80px 80px' );\n\t\tperfList.domElement.style.minWidth = '600px';\n\n\t\tconst scrollWrapper = document.createElement( 'div' );\n\t\tscrollWrapper.className = 'list-scroll-wrapper';\n\t\tscrollWrapper.appendChild( perfList.domElement );\n\t\tthis.content.appendChild( scrollWrapper );\n\n\t\t//\n\n\t\tconst graphContainer = document.createElement( 'div' );\n\t\tgraphContainer.className = 'graph-container';\n\n\t\tconst graph = new Graph();\n\t\tgraph.addLine( 'fps', '--accent-color' );\n\t\t//graph.addLine( 'gpu', '--color-yellow' );\n\t\tgraphContainer.append( graph.domElement );\n\n\t\t//\n\n\t\t/*\n\t\tconst label = document.createElement( 'label' );\n\t\tlabel.className = 'custom-checkbox';\n\n\t\tconst checkbox = document.createElement( 'input' );\n\t\tcheckbox.type = 'checkbox';\n\n\t\tconst checkmark = document.createElement( 'span' );\n\t\tcheckmark.className = 'checkmark';\n\n\t\tlabel.appendChild( checkbox );\n\t\tlabel.appendChild( checkmark );\n\t\t*/\n\n\t\tconst graphStats = new Item( 'Graph Stats', createValueSpan(), createValueSpan(), createValueSpan( 'graph-fps-counter' ) );\n\t\tperfList.add( graphStats );\n\n\t\tconst graphItem = new Item( graphContainer );\n\t\tgraphItem.itemRow.childNodes[ 0 ].style.gridColumn = '1 / -1';\n\t\tgraphStats.add( graphItem );\n\n\t\t//\n\n\t\tconst frameStats = new Item( 'Frame Stats', createValueSpan(), createValueSpan(), createValueSpan() );\n\t\tperfList.add( frameStats );\n\n\t\tconst miscellaneous = new Item( 'Miscellaneous & Idle', createValueSpan(), createValueSpan(), createValueSpan() );\n\t\tmiscellaneous.domElement.firstChild.style.backgroundColor = '#00ff0b1a';\n\t\tmiscellaneous.domElement.firstChild.classList.add( 'no-hover' );\n\t\tframeStats.add( miscellaneous );\n\n\t\t//\n\n\t\tthis.notInUse = new Map();\n\t\tthis.frameStats = frameStats;\n\t\tthis.graphStats = graphStats;\n\t\tthis.graph = graph;\n\t\tthis.miscellaneous = miscellaneous;\n\n\t\t//\n\n\t\tthis.currentRender = null;\n\t\tthis.currentItem = null;\n\t\tthis.frameItems = new Map();\n\n\t}\n\n\tresolveStats( inspector, stats ) {\n\n\t\tconst data = inspector.getStatsData( stats.cid );\n\n\t\tlet item = data.item;\n\n\t\tif ( item === undefined ) {\n\n\t\t\titem = new Item( createValueSpan(), createValueSpan(), createValueSpan(), createValueSpan() );\n\n\t\t\tif ( stats.name ) {\n\n\t\t\t\tif ( stats.isComputeStats === true ) {\n\n\t\t\t\t\tstats.name = `${ stats.name } [ Compute ]`;\n\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tstats.name = `Unnamed ${ stats.cid }`;\n\n\t\t\t}\n\n\t\t\titem.userData.name = stats.name;\n\n\t\t\tthis.currentItem.add( item );\n\t\t\tdata.item = item;\n\n\t\t} else {\n\n\t\t\titem.userData.name = stats.name;\n\n\t\t\tif ( this.notInUse.has( stats.cid ) ) {\n\n\t\t\t\titem.domElement.firstElementChild.classList.remove( 'alert' );\n\n\t\t\t\tthis.notInUse.delete( stats.cid );\n\n\t\t\t}\n\n\t\t\tconst statsIndex = stats.parent.children.indexOf( stats );\n\n\t\t\tif ( item.parent === null || item.parent.children.indexOf( item ) !== statsIndex ) {\n\n\t\t\t\tthis.currentItem.add( item, statsIndex );\n\n\t\t\t}\n\n\t\t}\n\n\t\tlet name = item.userData.name;\n\n\t\tif ( stats.isComputeStats ) {\n\n\t\t\tname += ' [ Compute ]';\n\n\t\t}\n\n\t\tsetText( item.data[ 0 ], name );\n\t\tsetText( item.data[ 1 ], data.cpu.toFixed( 2 ) );\n\t\tsetText( item.data[ 2 ], stats.gpuNotAvailable === true ? '-' : data.gpu.toFixed( 2 ) );\n\t\tsetText( item.data[ 3 ], data.total.toFixed( 2 ) );\n\n\t\t//\n\n\t\tconst previousItem = this.currentItem;\n\n\t\tthis.currentItem = item;\n\n\t\tfor ( const child of stats.children ) {\n\n\t\t\tthis.resolveStats( inspector, child );\n\n\t\t}\n\n\t\tthis.currentItem = previousItem;\n\n\t\tthis.frameItems.set( stats.cid, item );\n\n\t}\n\n\tupdateGraph( inspector/*, frame*/ ) {\n\n\t\tthis.graph.addPoint( 'fps', inspector.fps );\n\t\tthis.graph.update();\n\n\t}\n\n\taddNotInUse( cid, item ) {\n\n\t\titem.domElement.firstElementChild.classList.add( 'alert' );\n\n\t\tthis.notInUse.set( cid, {\n\t\t\titem,\n\t\t\ttime: performance.now()\n\t\t} );\n\n\t\tthis.updateNotInUse( cid );\n\n\t}\n\n\tupdateNotInUse( cid ) {\n\n\t\tconst { item, time } = this.notInUse.get( cid );\n\n\t\tconst current = performance.now();\n\t\tconst duration = 5;\n\t\tconst remaining = duration - Math.floor( ( current - time ) / 1000 );\n\n\t\tif ( remaining >= 0 ) {\n\n\t\t\tconst counter = '*'.repeat( Math.max( 0, remaining ) );\n\t\t\tconst element = item.domElement.querySelector( '.list-item-cell .value' );\n\n\t\t\tsetText( element, item.userData.name + ' (not in use) ' + counter );\n\n\t\t} else {\n\n\t\t\titem.domElement.firstElementChild.classList.remove( 'alert' );\n\t\t\titem.parent.remove( item );\n\n\t\t\tthis.notInUse.delete( cid );\n\n\t\t}\n\n\t}\n\n\tupdateText( inspector, frame ) {\n\n\t\tconst oldFrameItems = new Map( this.frameItems );\n\n\t\tthis.frameItems.clear();\n\t\tthis.currentItem = this.frameStats;\n\n\t\tfor ( const child of frame.children ) {\n\n\t\t\tthis.resolveStats( inspector, child );\n\n\t\t}\n\n\t\t// remove unused frame items\n\n\t\tfor ( const [ cid, item ] of oldFrameItems ) {\n\n\t\t\tif ( ! this.frameItems.has( cid ) ) {\n\n\t\t\t\tthis.addNotInUse( cid, item );\n\n\t\t\t\toldFrameItems.delete( cid );\n\n\t\t\t}\n\n\t\t}\n\n\t\t// update not in use items\n\n\t\tfor ( const cid of this.notInUse.keys() ) {\n\n\t\t\tthis.updateNotInUse( cid );\n\n\t\t}\n\n\t\t//\n\n\t\tsetText( 'graph-fps-counter', inspector.fps.toFixed() + ' FPS' );\n\n\t\t//\n\n\t\tsetText( this.frameStats.data[ 1 ], frame.cpu.toFixed( 2 ) );\n\t\tsetText( this.frameStats.data[ 2 ], frame.gpu.toFixed( 2 ) );\n\t\tsetText( this.frameStats.data[ 3 ], frame.total.toFixed( 2 ) );\n\n\t\t//\n\n\t\tsetText( this.miscellaneous.data[ 1 ], frame.miscellaneous.toFixed( 2 ) );\n\t\tsetText( this.miscellaneous.data[ 2 ], '-' );\n\t\tsetText( this.miscellaneous.data[ 3 ], frame.miscellaneous.toFixed( 2 ) );\n\n\t\t//\n\n\t\tthis.currentItem = null;\n\n\t}\n\n}\n\nexport { Performance };\n","import { Tab } from '../ui/Tab.js';\n\nclass Console extends Tab {\n\n\tconstructor( options = {} ) {\n\n\t\tsuper( 'Console', options );\n\n\t\tthis.filters = { info: true, warn: true, error: true };\n\t\tthis.filterText = '';\n\n\t\tthis.buildHeader();\n\n\t\tthis.logContainer = document.createElement( 'div' );\n\t\tthis.logContainer.id = 'console-log';\n\t\tthis.content.appendChild( this.logContainer );\n\n\t}\n\n\tbuildHeader() {\n\n\t\tconst header = document.createElement( 'div' );\n\t\theader.className = 'console-header';\n\n\t\tconst filterInput = document.createElement( 'input' );\n\t\tfilterInput.type = 'text';\n\t\tfilterInput.className = 'console-filter-input';\n\t\tfilterInput.placeholder = 'Filter...';\n\t\tfilterInput.addEventListener( 'input', ( e ) => {\n\n\t\t\tthis.filterText = e.target.value.toLowerCase();\n\t\t\tthis.applyFilters();\n\n\t\t} );\n\n\t\tconst copyButton = document.createElement( 'button' );\n\t\tcopyButton.className = 'console-copy-button';\n\t\tcopyButton.title = 'Copy all';\n\t\tcopyButton.innerHTML = '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"14\" height=\"14\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><rect x=\"9\" y=\"9\" width=\"13\" height=\"13\" rx=\"2\" ry=\"2\"></rect><path d=\"M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1\"></path></svg>';\n\t\tcopyButton.addEventListener( 'click', () => this.copyAll( copyButton ) );\n\n\t\tconst buttonsGroup = document.createElement( 'div' );\n\t\tbuttonsGroup.className = 'console-buttons-group';\n\n\t\tObject.keys( this.filters ).forEach( type => {\n\n\t\t\tconst label = document.createElement( 'label' );\n\t\t\tlabel.className = 'custom-checkbox';\n\t\t\tlabel.style.color = `var(--${type === 'info' ? 'text-primary' : 'color-' + ( type === 'warn' ? 'yellow' : 'red' )})`;\n\n\t\t\tconst checkbox = document.createElement( 'input' );\n\t\t\tcheckbox.type = 'checkbox';\n\t\t\tcheckbox.checked = this.filters[ type ];\n\t\t\tcheckbox.dataset.type = type;\n\n\t\t\tconst checkmark = document.createElement( 'span' );\n\t\t\tcheckmark.className = 'checkmark';\n\n\t\t\tlabel.appendChild( checkbox );\n\t\t\tlabel.appendChild( checkmark );\n\t\t\tlabel.append( type.charAt( 0 ).toUpperCase() + type.slice( 1 ) );\n\t\t\tbuttonsGroup.appendChild( label );\n\n\t\t} );\n\n\t\tbuttonsGroup.addEventListener( 'change', ( e ) => {\n\n\t\t\tconst type = e.target.dataset.type;\n\t\t\tif ( type in this.filters ) {\n\n\t\t\t\tthis.filters[ type ] = e.target.checked;\n\t\t\t\tthis.applyFilters();\n\n\t\t\t}\n\n\t\t} );\n\n\t\tbuttonsGroup.appendChild( copyButton );\n\n\t\theader.appendChild( filterInput );\n\t\theader.appendChild( buttonsGroup );\n\t\tthis.content.appendChild( header );\n\n\t}\n\n\tapplyFilters() {\n\n\t\tconst messages = this.logContainer.querySelectorAll( '.log-message' );\n\t\tmessages.forEach( msg => {\n\n\t\t\tconst type = msg.dataset.type;\n\t\t\tconst text = msg.dataset.rawText.toLowerCase();\n\n\t\t\tconst showByType = this.filters[ type ];\n\t\t\tconst showByText = text.includes( this.filterText );\n\n\t\t\tmsg.classList.toggle( 'hidden', ! ( showByType && showByText ) );\n\n\t\t} );\n\n\t}\n\n\tcopyAll( button ) {\n\n\t\tconst win = this.logContainer.ownerDocument.defaultView;\n\t\tconst selection = win.getSelection();\n\t\tconst selectedText = selection.toString();\n\t\tconst textInConsole = selectedText && this.logContainer.contains( selection.anchorNode );\n\n\t\tlet text;\n\t\tif ( textInConsole ) {\n\n\t\t\ttext = selectedText;\n\n\t\t} else {\n\n\t\t\tconst messages = this.logContainer.querySelectorAll( '.log-message:not(.hidden)' );\n\t\t\ttext = Array.from( messages ).map( msg => msg.dataset.rawText ).join( '\\n' );\n\n\t\t}\n\n\t\tnavigator.clipboard.writeText( text );\n\n\t\tbutton.classList.add( 'copied' );\n\t\tsetTimeout( () => button.classList.remove( 'copied' ), 350 );\n\n\t}\n\n\t_getIcon( type, subType ) {\n\n\t\tlet icon;\n\n\t\tif ( subType === 'tip' ) {\n\n\t\t\ticon = '💭';\n\n\t\t} else if ( subType === 'tsl' ) {\n\n\t\t\ticon = '✨';\n\n\t\t} else if ( subType === 'webgpurenderer' ) {\n\n\t\t\ticon = '🎨';\n\n\t\t} else if ( type === 'warn' ) {\n\n\t\t\ticon = '⚠️';\n\n\t\t} else if ( type === 'error' ) {\n\n\t\t\ticon = '🔴';\n\n\t\t} else if ( type === 'info' ) {\n\n\t\t\ticon = 'ℹ️';\n\n\t\t}\n\n\t\treturn icon;\n\n\t}\n\n\t_formatMessage( type, text ) {\n\n\t\tconst fragment = document.createDocumentFragment();\n\t\tconst prefixMatch = text.match( /^([\\w\\.]+:\\s)/ );\n\t\tlet content = text;\n\n\t\tif ( prefixMatch ) {\n\n\t\t\tconst fullPrefix = prefixMatch[ 0 ];\n\t\t\tconst parts = fullPrefix.slice( 0, - 2 ).split( '.' );\n\t\t\tconst shortPrefix = ( parts.length > 1 ? parts[ parts.length - 1 ] : parts[ 0 ] ) + ':';\n\n\t\t\tconst icon = this._getIcon( type, shortPrefix.split( ':' )[ 0 ].toLowerCase() );\n\n\t\t\tfragment.appendChild( document.createTextNode( icon + ' ' ) );\n\n\t\t\tconst prefixSpan = document.createElement( 'span' );\n\t\t\tprefixSpan.className = 'log-prefix';\n\t\t\tprefixSpan.textContent = shortPrefix;\n\t\t\tfragment.appendChild( prefixSpan );\n\t\t\tcontent = text.substring( fullPrefix.length );\n\n\t\t}\n\n\t\tconst parts = content.split( /(\".*?\"|'.*?'|`.*?`)/g ).map( p => p.trim() ).filter( Boolean );\n\n\t\tparts.forEach( ( part, index ) => {\n\n\t\t\tif ( /^(\"|'|`)/.test( part ) ) {\n\n\t\t\t\tconst codeSpan = document.createElement( 'span' );\n\t\t\t\tcodeSpan.className = 'log-code';\n\t\t\t\tcodeSpan.textContent = part.slice( 1, - 1 );\n\t\t\t\tfragment.appendChild( codeSpan );\n\n\t\t\t} else {\n\n\t\t\t\tif ( index > 0 ) part = ' ' + part; // add space before parts except the first\n\t\t\t\tif ( index < parts.length - 1 ) part += ' '; // add space between parts\n\n\t\t\t\tfragment.appendChild( document.createTextNode( part ) );\n\n\t\t\t}\n\n\t\t} );\n\n\t\treturn fragment;\n\n\t}\n\n\taddMessage( type, text ) {\n\n\t\tconst msg = document.createElement( 'div' );\n\t\tmsg.className = `log-message ${type}`;\n\t\tmsg.dataset.type = type;\n\t\tmsg.dataset.rawText = text;\n\n\t\tmsg.appendChild( this._formatMessage( type, text ) );\n\n\t\tconst showByType = this.filters[ type ];\n\t\tconst showByText = text.toLowerCase().includes( this.filterText );\n\t\tmsg.classList.toggle( 'hidden', ! ( showByType && showByText ) );\n\n\t\tthis.logContainer.appendChild( msg );\n\t\tthis.logContainer.scrollTop = this.logContainer.scrollHeight;\n\t\tif ( this.logContainer.children.length > 200 ) {\n\n\t\t\tthis.logContainer.removeChild( this.logContainer.firstChild );\n\n\t\t}\n\n\t}\n\n}\n\nexport { Console };\n","import { EventDispatcher } from 'three';\n\nclass Value extends EventDispatcher {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.domElement = document.createElement( 'div' );\n\t\tthis.domElement.className = 'param-control';\n\n\t\tthis._onChangeFunction = null;\n\n\t\tthis.addEventListener( 'change', ( e ) => {\n\n\t\t\t// defer to avoid issues when changing multiple values in the same call stack\n\n\t\t\trequestAnimationFrame( () => {\n\n\t\t\t\tif ( this._onChangeFunction ) this._onChangeFunction( e.value );\n\n\t\t\t} );\n\n\t\t} );\n\n\t}\n\n\tsetValue( /*val*/ ) {\n\n\t\tthis.dispatchChange();\n\n\t\treturn this;\n\n\t}\n\n\tgetValue() {\n\n\t\treturn null;\n\n\t}\n\n\tdispatchChange() {\n\n\t\tthis.dispatchEvent( { type: 'change', value: this.getValue() } );\n\n\t}\n\n\tonChange( callback ) {\n\n\t\tthis._onChangeFunction = callback;\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass ValueNumber extends Value {\n\n\tconstructor( { value = 0, step = 0.1, min = - Infinity, max = Infinity } ) {\n\n\t\tsuper();\n\n\t\tthis.input = document.createElement( 'input' );\n\t\tthis.input.type = 'number';\n\t\tthis.input.value = value;\n\t\tthis.input.step = step;\n\t\tthis.input.min = min;\n\t\tthis.input.max = max;\n\t\tthis.input.addEventListener( 'change', this._onChangeValue.bind( this ) );\n\t\tthis.domElement.appendChild( this.input );\n\t\tthis.addDragHandler();\n\n\t}\n\n\t_onChangeValue() {\n\n\t\tconst value = parseFloat( this.input.value );\n\t\tconst min = parseFloat( this.input.min );\n\t\tconst max = parseFloat( this.input.max );\n\n\t\tif ( value > max ) {\n\n\t\t\tthis.input.value = max;\n\n\t\t} else if ( value < min ) {\n\n\t\t\tthis.input.value = min;\n\n\t\t} else if ( isNaN( value ) ) {\n\n\t\t\tthis.input.value = min;\n\n\t\t}\n\n\t\tthis.dispatchChange();\n\n\t}\n\n\taddDragHandler() {\n\n\t\tlet isDragging = false;\n\t\tlet startY, startValue;\n\n\t\tthis.input.addEventListener( 'mousedown', ( e ) => {\n\n\t\t\tisDragging = true;\n\t\t\tstartY = e.clientY;\n\t\t\tstartValue = parseFloat( this.input.value );\n\t\t\tdocument.body.style.cursor = 'ns-resize';\n\n\t\t} );\n\n\t\tdocument.addEventListener( 'mousemove', ( e ) => {\n\n\t\t\tif ( isDragging ) {\n\n\t\t\t\tconst deltaY = startY - e.clientY;\n\t\t\t\tconst step = parseFloat( this.input.step ) || 1;\n\t\t\t\tconst min = parseFloat( this.input.min );\n\t\t\t\tconst max = parseFloat( this.input.max );\n\n\t\t\t\tlet stepSize = step;\n\n\t\t\t\tif ( ! isNaN( max ) && isFinite( min ) ) {\n\n\t\t\t\t\tstepSize = ( max - min ) / 100;\n\n\t\t\t\t}\n\n\t\t\t\tconst change = deltaY * stepSize;\n\n\t\t\t\tlet newValue = startValue + change;\n\t\t\t\tnewValue = Math.max( min, Math.min( newValue, max ) );\n\n\t\t\t\tconst precision = ( String( step ).split( '.' )[ 1 ] || [] ).length;\n\t\t\t\tthis.input.value = newValue.toFixed( precision );\n\n\t\t\t\tthis.input.dispatchEvent( new Event( 'input' ) );\n\n\t\t\t\tthis.dispatchChange();\n\n\t\t\t}\n\n\t\t} );\n\n\t\tdocument.addEventListener( 'mouseup', () => {\n\n\t\t\tif ( isDragging ) {\n\n\t\t\t\tisDragging = false;\n\t\t\t\tdocument.body.style.cursor = 'default';\n\n\t\t\t}\n\n\t\t} );\n\n\t}\n\n\tsetValue( val ) {\n\n\t\tthis.input.value = val;\n\n\t\treturn super.setValue( val );\n\n\t}\n\n\tgetValue() {\n\n\t\treturn parseFloat( this.input.value );\n\n\t}\n\n}\n\nclass ValueCheckbox extends Value {\n\n\tconstructor( { value = false } ) {\n\n\t\tsuper();\n\n\t\tconst label = document.createElement( 'label' );\n\t\tlabel.className = 'custom-checkbox';\n\n\t\tconst checkbox = document.createElement( 'input' );\n\t\tcheckbox.type = 'checkbox';\n\t\tcheckbox.checked = value;\n\t\tthis.checkbox = checkbox;\n\n\t\tconst checkmark = document.createElement( 'span' );\n\t\tcheckmark.className = 'checkmark';\n\n\t\tlabel.appendChild( checkbox );\n\t\tlabel.appendChild( checkmark );\n\t\tthis.domElement.appendChild( label );\n\n\t\tcheckbox.addEventListener( 'change', () => {\n\n\t\t\tthis.dispatchChange();\n\n\t\t} );\n\n\t}\n\n\tsetValue( val ) {\n\n\t\tthis.checkbox.value = val;\n\n\t\treturn super.setValue( val );\n\n\t}\n\n\tgetValue() {\n\n\t\treturn this.checkbox.checked;\n\n\t}\n\n}\n\nclass ValueSlider extends Value {\n\n\tconstructor( { value = 0, min = 0, max = 1, step = 0.01 } ) {\n\n\t\tsuper();\n\n\t\tthis.slider = document.createElement( 'input' );\n\t\tthis.slider.type = 'range';\n\t\tthis.slider.min = min;\n\t\tthis.slider.max = max;\n\t\tthis.slider.step = step;\n\n\t\tconst numberValue = new ValueNumber( { value, min, max, step } );\n\t\tthis.numberInput = numberValue.input;\n\t\tthis.numberInput.style.flexBasis = '80px';\n\t\tthis.numberInput.style.flexShrink = '0';\n\n\t\tthis.slider.value = value;\n\n\t\tthis.domElement.append( this.slider, this.numberInput );\n\n\t\tthis.slider.addEventListener( 'input', () => {\n\n\t\t\tthis.numberInput.value = this.slider.value;\n\n\t\t\tthis.dispatchChange();\n\n\t\t} );\n\n\t\tnumberValue.addEventListener( 'change', () => {\n\n\t\t\tthis.slider.value = parseFloat( this.numberInput.value );\n\n\t\t\tthis.dispatchChange();\n\n\t\t} );\n\n\t}\n\n\tsetValue( val ) {\n\n\t\tthis.slider.value = val;\n\t\tthis.numberInput.value = val;\n\n\t\treturn super.setValue( val );\n\n\t}\n\n\tgetValue() {\n\n\t\treturn parseFloat( this.slider.value );\n\n\t}\n\n\tstep( value ) {\n\n\t\tthis.slider.step = value;\n\t\tthis.numberInput.step = value;\n\n\t\treturn this;\n\n\t}\n\n}\n\nclass ValueSelect extends Value {\n\n\tconstructor( { options = [], value = '' } ) {\n\n\t\tsuper();\n\n\t\tconst select = document.createElement( 'select' );\n\n\t\tconst createOption = ( name, optionValue ) => {\n\n\t\t\tconst optionEl = document.createElement( 'option' );\n\t\t\toptionEl.value = name;\n\t\t\toptionEl.textContent = name;\n\n\t\t\tif ( optionValue == value ) optionEl.selected = true;\n\n\t\t\tselect.appendChild( optionEl );\n\n\t\t\treturn optionEl;\n\n\t\t};\n\n\t\tif ( Array.isArray( options ) ) {\n\n\t\t\toptions.forEach( opt => createOption( opt, opt ) );\n\n\t\t} else {\n\n\t\t\tObject.entries( options ).forEach( ( [ key, value ] ) => createOption( key, value ) );\n\n\t\t}\n\n\t\tthis.domElement.appendChild( select );\n\n\t\t//\n\n\t\tselect.addEventListener( 'change', () => {\n\n\t\t\tthis.dispatchChange();\n\n\t\t} );\n\n\t\tthis.options = options;\n\t\tthis.select = select;\n\n\t}\n\n\tgetValue() {\n\n\t\tconst options = this.options;\n\n\t\tif ( Array.isArray( options ) ) {\n\n\t\t\treturn options[ this.select.selectedIndex ];\n\n\t\t} else {\n\n\t\t\treturn options[ this.select.value ];\n\n\t\t}\n\n\t}\n\n}\n\nclass ValueColor extends Value {\n\n\tconstructor( { value = '#ffffff' } ) {\n\n\t\tsuper();\n\n\t\tconst colorInput = document.createElement( 'input' );\n\t\tcolorInput.type = 'color';\n\t\tcolorInput.value = this._getColorHex( value );\n\t\tthis.colorInput = colorInput;\n\n\t\tthis._value = value;\n\n\t\tcolorInput.addEventListener( 'input', () => {\n\n\t\t\tconst colorValue = colorInput.value;\n\n\t\t\tif ( this._value.isColor ) {\n\n\t\t\t\tthis._value.setHex( parseInt( colorValue.slice( 1 ), 16 ) );\n\n\t\t\t} else {\n\n\t\t\t\tthis._value = colorValue;\n\n\t\t\t}\n\n\t\t\tthis.dispatchChange();\n\n\t\t} );\n\n\t\tthis.domElement.appendChild( colorInput );\n\n\t}\n\n\t_getColorHex( color ) {\n\n\t\tif ( color.isColor ) {\n\n\t\t\tcolor = color.getHex();\n\n\t\t}\n\n\t\tif ( typeof color === 'number' ) {\n\n\t\t\tcolor = `#${ color.toString( 16 ) }`;\n\n\t\t} else if ( color[ 0 ] !== '#' ) {\n\n\t\t\tcolor = '#' + color;\n\n\t\t}\n\n\t\treturn color;\n\n\t}\n\n\tgetValue() {\n\n\t\tlet value = this._value;\n\n\t\tif ( typeof value === 'string' ) {\n\n\t\t\tvalue = parseInt( value.slice( 1 ), 16 );\n\n\t\t}\n\n\t\treturn value;\n\n\t}\n\n}\n\nclass ValueButton extends Value {\n\n\tconstructor( { text = 'Button', value = () => {} } ) {\n\n\t\tsuper();\n\n\t\tconst button = document.createElement( 'button' );\n\t\tbutton.textContent = text;\n\t\tbutton.onclick = value;\n\t\tthis.domElement.appendChild( button );\n\n\t}\n\n}\n\nexport { Value, ValueNumber, ValueCheckbox, ValueSlider, ValueSelect, ValueColor, ValueButton };\n","import { Tab } from '../ui/Tab.js';\nimport { List } from '../ui/List.js';\nimport { Item } from '../ui/Item.js';\nimport { createValueSpan } from '../ui/utils.js';\nimport { ValueNumber, ValueSlider, ValueSelect, ValueCheckbox, ValueColor, ValueButton } from '../ui/Values.js';\n\nclass ParametersGroup {\n\n\tconstructor( parameters, name ) {\n\n\t\tthis.parameters = parameters;\n\t\tthis.name = name;\n\n\t\tthis.paramList = new Item( name );\n\n\t\tthis.objects = [];\n\n\t}\n\n\tclose() {\n\n\t\tthis.paramList.close();\n\n\t\treturn this;\n\n\t}\n\n\tadd( object, property, ...params ) {\n\n\t\tconst value = object[ property ];\n\t\tconst type = typeof value;\n\n\t\tlet item = null;\n\n\t\tif ( typeof params[ 0 ] === 'object' ) {\n\n\t\t\titem = this.addSelect( object, property, params[ 0 ] );\n\n\t\t} else if ( type === 'number' ) {\n\n\t\t\tif ( params.length >= 2 ) {\n\n\t\t\t\titem = this.addSlider( object, property, ...params );\n\n\t\t\t} else {\n\n\t\t\t\titem = this.addNumber( object, property, ...params );\n\n\t\t\t}\n\n\t\t} else if ( type === 'boolean' ) {\n\n\t\t\titem = this.addBoolean( object, property );\n\n\t\t} else if ( type === 'function' ) {\n\n\t\t\titem = this.addButton( object, property, ...params );\n\n\t\t}\n\n\t\treturn item;\n\n\t}\n\n\t_addParameter( object, property, editor, subItem ) {\n\n\t\teditor.name = ( name ) => {\n\n\t\t\tsubItem.data[ 0 ].textContent = name;\n\n\t\t\treturn editor;\n\n\t\t};\n\n\t\teditor.listen = () => {\n\n\t\t\tconst update = () => {\n\n\t\t\t\tconst value = editor.getValue();\n\t\t\t\tconst propertyValue = object[ property ];\n\n\t\t\t\tif ( value !== propertyValue ) {\n\n\t\t\t\t\teditor.setValue( propertyValue );\n\n\t\t\t\t}\n\n\t\t\t\trequestAnimationFrame( update );\n\n\t\t\t};\n\n\t\t\trequestAnimationFrame( update );\n\n\t\t\treturn editor;\n\n\t\t};\n\n\n\t\tthis._registerParameter( object, property, editor, subItem );\n\n\t}\n\n\t_registerParameter( object, property, editor, subItem ) {\n\n\t\tthis.objects.push( { object: object, key: property, editor: editor, subItem: subItem } );\n\n\t}\n\n\taddFolder( name ) {\n\n\t\tconst group = new ParametersGroup( this.parameters, name );\n\n\t\tthis.paramList.add( group.paramList );\n\n\t\treturn group;\n\n\t}\n\n\taddBoolean( object, property ) {\n\n\t\tconst value = object[ property ];\n\n\t\tconst editor = new ValueCheckbox( { value } );\n\t\teditor.addEventListener( 'change', ( { value } ) => {\n\n\t\t\tobject[ property ] = value;\n\n\t\t} );\n\n\t\tconst description = createValueSpan();\n\t\tdescription.textContent = property;\n\n\t\tconst subItem = new Item( description, editor.domElement );\n\t\tthis.paramList.add( subItem );\n\n\t\t// extends logic to toggle checkbox when clicking on the row\n\n\t\tconst itemRow = subItem.domElement.firstChild;\n\n\t\titemRow.classList.add( 'actionable' );\n\t\titemRow.addEventListener( 'click', ( e ) => {\n\n\t\t\tif ( e.target.closest( 'label' ) ) return;\n\n\t\t\tconst checkbox = itemRow.querySelector( 'input[type=\"checkbox\"]' );\n\n\t\t\tif ( checkbox ) {\n\n\t\t\t\tcheckbox.checked = ! checkbox.checked;\n\t\t\t\tcheckbox.dispatchEvent( new Event( 'change' ) );\n\n\t\t\t}\n\n\t\t} );\n\n\t\t// extend object property\n\n\t\tthis._addParameter( object, property, editor, subItem );\n\n\t\treturn editor;\n\n\t}\n\n\taddSelect( object, property, options ) {\n\n\t\tconst value = object[ property ];\n\n\t\tconst editor = new ValueSelect( { options, value } );\n\t\teditor.addEventListener( 'change', ( { value } ) => {\n\n\t\t\tobject[ property ] = value;\n\n\t\t} );\n\n\t\tconst description = createValueSpan();\n\t\tdescription.textContent = property;\n\n\t\tconst subItem = new Item( description, editor.domElement );\n\t\tthis.paramList.add( subItem );\n\n\t\tconst itemRow = subItem.domElement.firstChild;\n\t\titemRow.classList.add( 'actionable' );\n\n\t\t// extend object property\n\n\t\tthis._addParameter( object, property, editor, subItem );\n\n\t\treturn editor;\n\n\t}\n\n\taddColor( object, property ) {\n\n\t\tconst value = object[ property ];\n\n\t\tconst editor = new ValueColor( { value } );\n\t\teditor.addEventListener( 'change', ( { value } ) => {\n\n\t\t\tobject[ property ] = value;\n\n\t\t} );\n\n\t\tconst description = createValueSpan();\n\t\tdescription.textContent = property;\n\n\t\tconst subItem = new Item( description, editor.domElement );\n\t\tthis.paramList.add( subItem );\n\n\t\tconst itemRow = subItem.domElement.firstChild;\n\t\titemRow.classList.add( 'actionable' );\n\n\t\t// extend object property\n\n\t\tthis._addParameter( object, property, editor, subItem );\n\n\t\treturn editor;\n\n\t}\n\n\taddSlider( object, property, min = 0, max = 1, step = 0.01 ) {\n\n\t\tconst value = object[ property ];\n\n\t\tconst editor = new ValueSlider( { value, min, max, step } );\n\t\teditor.addEventListener( 'change', ( { value } ) => {\n\n\t\t\tobject[ property ] = value;\n\n\t\t} );\n\n\t\tconst description = createValueSpan();\n\t\tdescription.textContent = property;\n\n\t\tconst subItem = new Item( description, editor.domElement );\n\t\tthis.paramList.add( subItem );\n\n\t\tconst itemRow = subItem.domElement.firstChild;\n\t\titemRow.classList.add( 'actionable' );\n\n\t\t// extend object property\n\n\t\tthis._addParameter( object, property, editor, subItem );\n\n\t\treturn editor;\n\n\t}\n\n\taddNumber( object, property, ...params ) {\n\n\t\tconst value = object[ property ];\n\t\tconst [ min, max ] = params;\n\n\t\tconst editor = new ValueNumber( { value, min, max } );\n\t\teditor.addEventListener( 'change', ( { value } ) => {\n\n\t\t\tobject[ property ] = value;\n\n\t\t} );\n\n\t\tconst description = createValueSpan();\n\t\tdescription.textContent = property;\n\n\t\tconst subItem = new Item( description, editor.domElement );\n\t\tthis.paramList.add( subItem );\n\n\t\tconst itemRow = subItem.domElement.firstChild;\n\t\titemRow.classList.add( 'actionable' );\n\n\t\t// extend object property\n\n\t\tthis._addParameter( object, property, editor, subItem );\n\n\t\treturn editor;\n\n\t}\n\n\taddButton( object, property ) {\n\n\t\tconst value = object[ property ];\n\n\t\tconst editor = new ValueButton( { text: property, value } );\n\t\teditor.addEventListener( 'change', ( { value } ) => {\n\n\t\t\tobject[ property ] = value;\n\n\t\t} );\n\n\t\tconst subItem = new Item( editor.domElement );\n\t\tsubItem.itemRow.childNodes[ 0 ].style.gridColumn = '1 / -1';\n\t\tthis.paramList.add( subItem );\n\n\t\tconst itemRow = subItem.domElement.firstChild;\n\t\titemRow.classList.add( 'actionable' );\n\n\t\t// extend object property\n\n\t\teditor.name = ( name ) => {\n\n\t\t\teditor.domElement.childNodes[ 0 ].textContent = name;\n\n\t\t\treturn editor;\n\n\t\t};\n\n\t\tthis._registerParameter( object, property, editor, subItem );\n\n\t\treturn editor;\n\n\t}\n\n}\n\nclass Parameters extends Tab {\n\n\tconstructor( options = {} ) {\n\n\t\tsuper( 'Parameters', options );\n\n\t\tconst paramList = new List( 'Property', 'Value' );\n\t\tparamList.domElement.classList.add( 'parameters' );\n\t\tparamList.setGridStyle( '.5fr 1fr' );\n\t\tparamList.domElement.style.minWidth = '300px';\n\n\t\tconst scrollWrapper = document.createElement( 'div' );\n\t\tscrollWrapper.className = 'list-scroll-wrapper';\n\t\tscrollWrapper.appendChild( paramList.domElement );\n\t\tthis.content.appendChild( scrollWrapper );\n\n\t\tthis.paramList = paramList;\n\n\t\tthis.groups = [];\n\n\t}\n\n\tcreateGroup( name ) {\n\n\t\tconst group = new ParametersGroup( this, name );\n\n\t\tthis.paramList.add( group.paramList );\n\t\tthis.groups.push( group );\n\n\t\treturn group;\n\n\t}\n\n}\n\nexport { Parameters };\n","import { Tab } from '../ui/Tab.js';\nimport { List } from '../ui/List.js';\nimport { Item } from '../ui/Item.js';\n\nimport { RendererUtils, NoToneMapping, LinearSRGBColorSpace } from 'three/webgpu';\n\nclass Viewer extends Tab {\n\n\tconstructor( options = {} ) {\n\n\t\tsuper( 'Viewer', options );\n\n\t\tconst nodeList = new List( 'Viewer', 'Name' );\n\t\tnodeList.setGridStyle( '150px minmax(200px, 2fr)' );\n\t\tnodeList.domElement.style.minWidth = '400px';\n\n\t\tconst scrollWrapper = document.createElement( 'div' );\n\t\tscrollWrapper.className = 'list-scroll-wrapper';\n\t\tscrollWrapper.appendChild( nodeList.domElement );\n\t\tthis.content.appendChild( scrollWrapper );\n\n\t\tconst nodes = new Item( 'Nodes' );\n\t\tnodeList.add( nodes );\n\n\t\t//\n\n\t\tthis.itemLibrary = new Map();\n\t\tthis.folderLibrary = new Map();\n\t\tthis.currentDataList = [];\n\t\tthis.nodeList = nodeList;\n\t\tthis.nodes = nodes;\n\n\t}\n\n\tgetFolder( name ) {\n\n\t\tlet folder = this.folderLibrary.get( name );\n\n\t\tif ( folder === undefined ) {\n\n\t\t\tfolder = new Item( name );\n\n\t\t\tthis.folderLibrary.set( name, folder );\n\t\t\tthis.nodeList.add( folder );\n\n\t\t}\n\n\t\treturn folder;\n\n\t}\n\n\taddNodeItem( canvasData ) {\n\n\t\tlet item = this.itemLibrary.get( canvasData.id );\n\n\t\tif ( item === undefined ) {\n\n\t\t\tconst name = canvasData.name;\n\t\t\tconst domElement = canvasData.canvasTarget.domElement;\n\n\t\t\titem = new Item( domElement, name );\n\t\t\titem.itemRow.children[ 1 ].style[ 'justify-content' ] = 'flex-start';\n\t\t\tthis.itemLibrary.set( canvasData.id, item );\n\n\t\t}\n\n\t\treturn item;\n\n\t}\n\n\tupdate( renderer, canvasDataList ) {\n\n\t\tif ( ! this.isActive && ! this.isDetached ) return;\n\n\t\t//\n\n\t\tconst previousDataList = [ ...this.currentDataList ];\n\n\t\t// remove old\n\n\t\tfor ( const canvasData of previousDataList ) {\n\n\t\t\tif ( this.itemLibrary.has( canvasData.id ) && canvasDataList.indexOf( canvasData ) === - 1 ) {\n\n\t\t\t\tconst item = this.itemLibrary.get( canvasData.id );\n\t\t\t\tconst parent = item.parent;\n\n\t\t\t\tparent.remove( item );\n\n\t\t\t\tif ( this.folderLibrary.has( parent.data[ 0 ] ) && parent.children.length === 0 ) {\n\n\t\t\t\t\tparent.parent.remove( parent );\n\n\t\t\t\t\tthis.folderLibrary.delete( parent.data[ 0 ] );\n\n\t\t\t\t}\n\n\t\t\t\tthis.itemLibrary.delete( canvasData.id );\n\n\t\t\t}\n\n\t\t}\n\n\t\t//\n\n\t\tconst indexes = {};\n\n\t\tfor ( const canvasData of canvasDataList ) {\n\n\t\t\tconst item = this.addNodeItem( canvasData );\n\t\t\tconst previousCanvasTarget = renderer.getCanvasTarget();\n\n\t\t\tconst path = canvasData.path;\n\n\t\t\tif ( path ) {\n\n\t\t\t\tconst folder = this.getFolder( path );\n\n\t\t\t\tif ( indexes[ path ] === undefined ) {\n\n\t\t\t\t\tindexes[ path ] = 0;\n\n\t\t\t\t}\n\n\t\t\t\tif ( folder.parent === null || item.parent !== folder || folder.children.indexOf( item ) !== indexes[ path ] ) {\n\n\t\t\t\t\tfolder.add( item );\n\n\t\t\t\t}\n\n\t\t\t\tindexes[ path ] ++;\n\n\t\t\t} else {\n\n\t\t\t\tif ( ! item.parent ) {\n\n\t\t\t\t\tthis.nodes.add( item );\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.currentDataList = canvasDataList;\n\n\t\t\t//\n\n\t\t\tconst state = RendererUtils.resetRendererState( renderer );\n\n\t\t\trenderer.toneMapping = NoToneMapping;\n\t\t\trenderer.outputColorSpace = LinearSRGBColorSpace;\n\n\t\t\trenderer.setCanvasTarget( canvasData.canvasTarget );\n\n\t\t\tcanvasData.quad.render( renderer );\n\n\t\t\trenderer.setCanvasTarget( previousCanvasTarget );\n\n\t\t\tRendererUtils.restoreRendererState( renderer, state );\n\n\t\t}\n\n\t}\n\n}\n\nexport { Viewer };\n","\nimport { RendererInspector } from './RendererInspector.js';\nimport { Profiler } from './ui/Profiler.js';\nimport { Performance } from './tabs/Performance.js';\nimport { Console } from './tabs/Console.js';\nimport { Parameters } from './tabs/Parameters.js';\nimport { Viewer } from './tabs/Viewer.js';\nimport { setText, splitPath, splitCamelCase } from './ui/utils.js';\n\nimport { QuadMesh, NodeMaterial, CanvasTarget, setConsoleFunction, REVISION, NoToneMapping } from 'three/webgpu';\nimport { renderOutput, vec2, vec3, vec4, Fn, screenUV, step, OnMaterialUpdate, uniform } from 'three/tsl';\n\nconst aspectRatioUV = /*@__PURE__*/ Fn( ( [ uv, textureNode ] ) => {\n\n\tconst aspect = uniform( 0 );\n\n\tOnMaterialUpdate( () => {\n\n\t\tconst { width, height } = textureNode.value;\n\n\t\taspect.value = width / height;\n\n\t} );\n\n\tconst centered = uv.sub( 0.5 );\n\tconst corrected = vec2( centered.x.div( aspect ), centered.y );\n\tconst finalUV = corrected.add( 0.5 );\n\n\tconst inBounds = step( 0.0, finalUV.x ).mul( step( finalUV.x, 1.0 ) ).mul( step( 0.0, finalUV.y ) ).mul( step( finalUV.y, 1.0 ) );\n\n\treturn vec3( finalUV, inBounds );\n\n} );\n\nclass Inspector extends RendererInspector {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\t// init profiler\n\n\t\tconst profiler = new Profiler();\n\n\t\tconst parameters = new Parameters( {\n\t\t\tbuiltin: true,\n\t\t\ticon: '<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><path stroke=\"none\" d=\"M0 0h24v24H0z\" fill=\"none\"/><path d=\"M14 6m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0\" /><path d=\"M4 6l8 0\" /><path d=\"M16 6l4 0\" /><path d=\"M8 12m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0\" /><path d=\"M4 12l2 0\" /><path d=\"M10 12l10 0\" /><path d=\"M17 18m-2 0a2 2 0 1 0 4 0a2 2 0 1 0 -4 0\" /><path d=\"M4 18l11 0\" /><path d=\"M19 18l1 0\" /></svg>'\n\t\t} );\n\t\tparameters.hide();\n\t\tprofiler.addTab( parameters );\n\n\t\tconst viewer = new Viewer();\n\t\tviewer.hide();\n\t\tprofiler.addTab( viewer );\n\n\t\tconst performance = new Performance();\n\t\tprofiler.addTab( performance );\n\n\t\tconst consoleTab = new Console();\n\t\tprofiler.addTab( consoleTab );\n\n\t\tprofiler.loadLayout();\n\n\t\tif ( ! profiler.activeTabId ) {\n\n\t\t\tprofiler.setActiveTab( performance.id );\n\n\t\t}\n\n\t\tthis.statsData = new Map();\n\t\tthis.canvasNodes = new Map();\n\t\tthis.profiler = profiler;\n\t\tthis.performance = performance;\n\t\tthis.console = consoleTab;\n\t\tthis.parameters = parameters;\n\t\tthis.viewer = viewer;\n\t\tthis.once = {};\n\n\t\tthis.displayCycle = {\n\t\t\ttext: {\n\t\t\t\tneedsUpdate: false,\n\t\t\t\tduration: .25,\n\t\t\t\ttime: 0\n\t\t\t},\n\t\t\tgraph: {\n\t\t\t\tneedsUpdate: false,\n\t\t\t\tduration: .02,\n\t\t\t\ttime: 0\n\t\t\t}\n\t\t};\n\n\t}\n\n\tget domElement() {\n\n\t\treturn this.profiler.domElement;\n\n\t}\n\n\tresolveConsoleOnce( type, message ) {\n\n\t\tconst key = type + message;\n\n\t\tif ( this.once[ key ] !== true ) {\n\n\t\t\tthis.resolveConsole( type, message );\n\t\t\tthis.once[ key ] = true;\n\n\t\t}\n\n\t}\n\n\tresolveConsole( type, message, stackTrace = null ) {\n\n\t\tswitch ( type ) {\n\n\t\t\tcase 'log':\n\n\t\t\t\tthis.console.addMessage( 'info', message );\n\n\t\t\t\tconsole.log( message );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'warn':\n\n\t\t\t\tthis.console.addMessage( 'warn', message );\n\n\t\t\t\tif ( stackTrace && stackTrace.isStackTrace ) {\n\n\t\t\t\t\tconsole.warn( stackTrace.getError( message ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.warn( message );\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t\tcase 'error':\n\n\t\t\t\tthis.console.addMessage( 'error', message );\n\n\t\t\t\tif ( stackTrace && stackTrace.isStackTrace ) {\n\n\t\t\t\t\tconsole.error( stackTrace.getError( message ) );\n\n\t\t\t\t} else {\n\n\t\t\t\t\tconsole.error( message );\n\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\n\t\t}\n\n\t}\n\n\tinit() {\n\n\t\tconst renderer = this.getRenderer();\n\n\t\tlet sign = `THREE.WebGPURenderer: ${ REVISION } [ \"`;\n\n\t\tif ( renderer.backend.isWebGPUBackend ) {\n\n\t\t\tsign += 'WebGPU';\n\n\t\t} else if ( renderer.backend.isWebGLBackend ) {\n\n\t\t\tsign += 'WebGL2';\n\n\t\t}\n\n\t\tsign += '\" ]';\n\n\t\tthis.console.addMessage( 'info', sign );\n\n\t\t//\n\n\t\tif ( renderer.inspector.domElement.parentElement === null && renderer.domElement.parentElement !== null ) {\n\n\t\t\trenderer.domElement.parentElement.appendChild( renderer.inspector.domElement );\n\n\t\t}\n\n\t}\n\n\tsetRenderer( renderer ) {\n\n\t\tsuper.setRenderer( renderer );\n\n\t\tif ( renderer !== null ) {\n\n\t\t\tsetConsoleFunction( this.resolveConsole.bind( this ) );\n\n\t\t\tif ( this.isAvailable ) {\n\n\t\t\t\trenderer.backend.trackTimestamp = true;\n\n\t\t\t\trenderer.init().then( () => {\n\n\t\t\t\t\tif ( renderer.hasFeature( 'timestamp-query' ) !== true ) {\n\n\t\t\t\t\t\tthis.console.addMessage( 'error', 'THREE.Inspector: GPU Timestamp Queries not available.' );\n\n\t\t\t\t\t}\n\n\t\t\t\t} );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n\tcreateParameters( name ) {\n\n\t\tif ( this.parameters.isVisible === false ) {\n\n\t\t\tthis.parameters.show();\n\n\t\t\tif ( this.parameters.isDetached === false ) {\n\n\t\t\t\tthis.profiler.setActiveTab( this.parameters.id );\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn this.parameters.createGroup( name );\n\n\t}\n\n\tgetStatsData( cid ) {\n\n\t\tlet data = this.statsData.get( cid );\n\n\t\tif ( data === undefined ) {\n\n\t\t\tdata = {};\n\n\t\t\tthis.statsData.set( cid, data );\n\n\t\t}\n\n\t\treturn data;\n\n\t}\n\n\tresolveStats( stats ) {\n\n\t\tconst data = this.getStatsData( stats.cid );\n\n\t\tif ( data.initialized !== true ) {\n\n\t\t\tdata.cpu = stats.cpu;\n\t\t\tdata.gpu = stats.gpu;\n\t\t\tdata.stats = [];\n\n\t\t\tdata.initialized = true;\n\n\t\t}\n\n\t\t// store stats\n\n\t\tif ( data.stats.length > this.maxFrames ) {\n\n\t\t\tdata.stats.shift();\n\n\t\t}\n\n\t\tdata.stats.push( stats );\n\n\t\t// compute averages\n\n\t\tdata.cpu = this.getAverageDeltaTime( data, 'cpu' );\n\t\tdata.gpu = this.getAverageDeltaTime( data, 'gpu' );\n\t\tdata.total = data.cpu + data.gpu;\n\n\t\t// children\n\n\t\tfor ( const child of stats.children ) {\n\n\t\t\tthis.resolveStats( child );\n\n\t\t\tconst childData = this.getStatsData( child.cid );\n\n\t\t\tdata.cpu += childData.cpu;\n\t\t\tdata.gpu += childData.gpu;\n\t\t\tdata.total += childData.total;\n\n\t\t}\n\n\t}\n\n\tgetCanvasDataByNode( node ) {\n\n\t\tlet canvasData = this.canvasNodes.get( node );\n\n\t\tif ( canvasData === undefined ) {\n\n\t\t\tconst renderer = this.getRenderer();\n\n\t\t\tconst canvas = document.createElement( 'canvas' );\n\n\t\t\tconst canvasTarget = new CanvasTarget( canvas );\n\t\t\tcanvasTarget.setPixelRatio( window.devicePixelRatio );\n\t\t\tcanvasTarget.setSize( 140, 140 );\n\n\t\t\tconst id = node.id;\n\n\t\t\tconst { path, name } = splitPath( splitCamelCase( node.getName() || '(unnamed)' ) );\n\n\t\t\tconst target = node.context( { getUV: ( textureNode ) => {\n\n\t\t\t\tconst uvData = aspectRatioUV( screenUV, textureNode );\n\t\t\t\tconst correctedUV = uvData.xy;\n\t\t\t\tconst mask = uvData.z;\n\n\t\t\t\treturn correctedUV.mul( mask );\n\n\t\t\t} } );\n\n\t\t\tlet output = vec4( vec3( target ), 1 );\n\t\t\toutput = renderOutput( output, NoToneMapping, renderer.outputColorSpace );\n\t\t\toutput = output.context( { inspector: true } );\n\n\t\t\tconst material = new NodeMaterial();\n\t\t\tmaterial.outputNode = output;\n\n\t\t\tconst quad = new QuadMesh( material );\n\t\t\tquad.name = 'Viewer - ' + name;\n\n\t\t\tcanvasData = {\n\t\t\t\tid,\n\t\t\t\tname,\n\t\t\t\tpath,\n\t\t\t\tnode,\n\t\t\t\tquad,\n\t\t\t\tcanvasTarget,\n\t\t\t\tmaterial\n\t\t\t};\n\n\t\t\tthis.canvasNodes.set( node, canvasData );\n\n\t\t}\n\n\t\treturn canvasData;\n\n\t}\n\n\tresolveViewer() {\n\n\t\tconst nodes = this.currentNodes;\n\t\tconst renderer = this.getRenderer();\n\n\t\tif ( nodes.length === 0 ) return;\n\n\t\tif ( ! renderer.backend.isWebGPUBackend ) {\n\n\t\t\tthis.resolveConsoleOnce( 'warn', 'Inspector: Viewer is only available with WebGPU.' );\n\n\t\t\treturn;\n\n\t\t}\n\n\t\t//\n\n\t\tif ( ! this.viewer.isVisible ) {\n\n\t\t\tthis.viewer.show();\n\n\t\t}\n\n\t\tconst canvasDataList = nodes.map( node => this.getCanvasDataByNode( node ) );\n\n\t\tthis.viewer.update( renderer, canvasDataList );\n\n\t}\n\n\tgetAverageDeltaTime( statsData, property, frames = this.fps ) {\n\n\t\tconst statsArray = statsData.stats;\n\n\t\tlet sum = 0;\n\t\tlet count = 0;\n\n\t\tfor ( let i = statsArray.length - 1; i >= 0 && count < frames; i -- ) {\n\n\t\t\tconst stats = statsArray[ i ];\n\t\t\tconst value = stats[ property ];\n\n\t\t\tif ( value > 0 ) {\n\n\t\t\t\t// ignore invalid values\n\n\t\t\t\tsum += value;\n\t\t\t\tcount ++;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn count > 0 ? sum / count : 0;\n\n\t}\n\n\tresolveFrame( frame ) {\n\n\t\tconst nextFrame = this.getFrameById( frame.frameId + 1 );\n\n\t\tif ( ! nextFrame ) return;\n\n\t\tframe.cpu = 0;\n\t\tframe.gpu = 0;\n\t\tframe.total = 0;\n\n\t\tfor ( const stats of frame.children ) {\n\n\t\t\tthis.resolveStats( stats );\n\n\t\t\tconst data = this.getStatsData( stats.cid );\n\n\t\t\tframe.cpu += data.cpu;\n\t\t\tframe.gpu += data.gpu;\n\t\t\tframe.total += data.total;\n\n\t\t}\n\n\t\t// improve stats using next frame\n\n\t\tframe.deltaTime = nextFrame.startTime - frame.startTime;\n\t\tframe.miscellaneous = frame.deltaTime - frame.total;\n\n\t\tif ( frame.miscellaneous < 0 ) {\n\n\t\t\t// Frame desync, probably due to async GPU timing.\n\n\t\t\tframe.miscellaneous = 0;\n\n\t\t}\n\n\t\t//\n\n\t\tthis.updateCycle( this.displayCycle.text );\n\t\tthis.updateCycle( this.displayCycle.graph );\n\n\t\tif ( this.displayCycle.text.needsUpdate ) {\n\n\t\t\tsetText( 'fps-counter', this.fps.toFixed() );\n\n\t\t\tthis.performance.updateText( this, frame );\n\n\t\t}\n\n\t\tif ( this.displayCycle.graph.needsUpdate ) {\n\n\t\t\tthis.performance.updateGraph( this, frame );\n\n\t\t}\n\n\t\tthis.displayCycle.text.needsUpdate = false;\n\t\tthis.displayCycle.graph.needsUpdate = false;\n\n\t}\n\n\tupdateCycle( cycle ) {\n\n\t\tcycle.time += this.nodeFrame.deltaTime;\n\n\t\tif ( cycle.time >= cycle.duration ) {\n\n\t\t\tcycle.needsUpdate = true;\n\t\t\tcycle.time = 0;\n\n\t\t}\n\n\t}\n\n}\n\nexport { Inspector };\n","import type { Node } from 'three/webgpu';\nimport { type WebGPURenderer, RenderPipeline } from 'three/webgpu';\nimport { RoomleRenderer } from '../roomle-renderer';\nimport type {\n LutImageDefinition,\n OutlineCustomParameters,\n QualityLevel,\n QualityMap,\n} from '../webgl/renderer/scene-renderer';\nimport { QUALITY_LEVELS } from '../webgl/renderer/scene-renderer';\nimport type { Camera, ColorRepresentation, Object3D, Scene } from 'three';\nimport type {\n CustomShadingParameters,\n SceneShadingType,\n} from '../webgl/renderer/shading-settings';\nimport { pass } from 'three/tsl';\nimport type { RoomleWebGPURenderPass } from './passes/roomle-webgpu-render-pass';\nimport { OutlineRenderPass } from './passes/outline-render-pass';\nimport { Inspector } from 'three/examples/jsm/inspector/Inspector.js';\nimport type DomHelper from '../utils/dom-helper';\nimport inject from '../di/inject';\nimport type { ParametersGroup } from 'three/examples/jsm/inspector/tabs/Parameters.js';\n\nexport type WebGPUDebugMode = 'off' | 'outline';\n\nexport class RoomleWebGPURenderer extends RoomleRenderer<WebGPURenderer> {\n private readonly renderPipeline: RenderPipeline;\n private passNeedsReassembly = true;\n private debugMode: WebGPUDebugMode = 'off';\n private readonly renderPasses = new Map<string, RoomleWebGPURenderPass>();\n private readonly guiParameterGroups = new Map<string, ParametersGroup>();\n\n @inject\n private declare _domHelper: DomHelper;\n\n constructor(\n creator: string,\n renderer: WebGPURenderer,\n outlineColors?: {\n outlineVisibleEdgeColor: ColorRepresentation;\n outlineHiddenEdgeColor: ColorRepresentation;\n },\n ) {\n super(creator, renderer);\n\n this.renderPipeline = new RenderPipeline(renderer);\n if (outlineColors) {\n this.enableOutline(\n outlineColors.outlineVisibleEdgeColor,\n outlineColors.outlineHiddenEdgeColor,\n );\n }\n }\n\n private addRenderPass(renderPass: RoomleWebGPURenderPass): void {\n this.renderPasses.set(renderPass.passId, renderPass);\n this.passNeedsReassembly = true;\n }\n\n public override clearCache(): void {\n console.error('RoomleWebGPURenderer.clearCache is not implemented yet');\n }\n\n public override disableUiInteractionMode(): void {\n console.error(\n 'RoomleWebGPURenderer.disableUiInteractionMode is not implemented yet',\n );\n }\n\n public override enableUiInteractionMode(): void {\n console.error(\n 'RoomleWebGPURenderer.enableUiInteractionMode is not implemented yet',\n );\n }\n\n public override getQualityLevel(): QualityLevel {\n console.error(\n 'RoomleWebGPURenderer.getQualityLevel is not implemented yet',\n );\n return QUALITY_LEVELS.HIGHEST;\n }\n\n public override highlightObjects(selectedMeshes: Object3D[]): void {\n const outlinePass = this.getOutlinePassOrUndefined();\n if (outlinePass) {\n this.passNeedsReassembly =\n this.passNeedsReassembly ||\n (outlinePass.areObjectsSelected() && selectedMeshes.length === 0) ||\n (!outlinePass.areObjectsSelected() && selectedMeshes.length > 0);\n }\n outlinePass?.highlightObjects(selectedMeshes);\n }\n\n public override loadLutImages(_luts: LutImageDefinition[]): void {\n console.error('RoomleWebGPURenderer.loadLutImages is not implemented yet');\n }\n\n public override render(scene: Scene, camera: Camera): void {\n if (this.passNeedsReassembly) {\n this.renderPipeline.outputNode = this.assembleRenderPasses(scene, camera);\n this.renderPipeline.needsUpdate = true;\n this.passNeedsReassembly = false;\n }\n this.renderPipeline.render(scene, camera);\n }\n\n private assembleRenderPasses(scene: Scene, camera: Camera): Node<'vec4'> {\n let result: Node<'vec4'> = pass(scene, camera); // always include the scene pass\n\n for (const renderPass of this.renderPasses.values()) {\n result = renderPass.assemble(result, scene, camera, this.debugMode);\n }\n\n return result;\n }\n\n public override setAutoQuality(_autoQuality: boolean): void {\n console.error('RoomleWebGPURenderer.setAutoQuality is not implemented yet');\n }\n\n public override setCustomShadingParameters(\n _customShadingParameters: CustomShadingParameters | undefined,\n _customShadingParametersMoc: CustomShadingParameters | undefined,\n ): void {\n console.error(\n 'RoomleWebGPURenderer.setCustomShadingParameters is not implemented yet',\n );\n }\n\n public override setCustomOutlineParameters(\n customOutlineParameters: OutlineCustomParameters,\n ): void {\n const outlinePass = this.getOutlinePassOrUndefined();\n if (outlinePass) {\n outlinePass.setOutlineColors(\n customOutlineParameters.outlineVisibleEdgeColor,\n customOutlineParameters.outlineHiddenEdgeColor,\n );\n this.passNeedsReassembly = true;\n }\n }\n\n public override setGroundShadow(_enabled: boolean): void {\n console.error(\n 'RoomleWebGPURenderer.setGroundShadow is not implemented yet',\n );\n }\n\n public override setOnQualityLevelChangeCallback(\n _callback: (qualityLevel: QualityLevel) => void,\n ): void {\n console.error(\n 'RoomleWebGPURenderer.setOnQualityLevelChangeCallback is not implemented yet',\n );\n }\n\n private enableOutline(\n visibleEdgeColor: ColorRepresentation,\n hiddenEdgeColor: ColorRepresentation,\n ): void {\n if (this.renderPasses.get(OutlineRenderPass.passId)) {\n return;\n }\n\n this.addRenderPass(\n new OutlineRenderPass({\n selectedObjects: [],\n visibleEdgeColor: visibleEdgeColor,\n hiddenEdgeColor: hiddenEdgeColor,\n edgeStrength: 3.0,\n edgeGlow: 0.0,\n edgeThickness: 1.0,\n }),\n );\n }\n\n private getOutlinePassOrUndefined(): OutlineRenderPass | undefined {\n const pass = this.renderPasses.get(OutlineRenderPass.passId);\n if (pass && pass instanceof OutlineRenderPass) {\n return pass;\n }\n return undefined;\n }\n\n public setQualityLevel(_qualityLevel: QualityLevel): void {\n console.error(\n 'RoomleWebGPURenderer.setQualityLevel is not implemented yet',\n );\n }\n\n public override setQualityMap(_qualityMap: QualityMap): void {\n console.error('RoomleWebGPURenderer.setQualityMap is not implemented yet');\n }\n\n public override setShadingType(_shadingType: SceneShadingType): void {\n console.error('RoomleWebGPURenderer.setShadingType is not implemented yet');\n }\n\n public override showGUI(updateCallback: () => void): void {\n if (this.renderer.inspector instanceof Inspector) {\n return;\n }\n const guiStyle = document.createElement('style');\n guiStyle.innerText =\n '#profiler-toggle,\\n' +\n ' #profiler-mini-panel {\\n' +\n ' left: 15px;\\n' + // webgpu gui should be top left not top right\n ' right: auto !important;\\n' +\n ' }';\n document.head.appendChild(guiStyle);\n\n const inspector = new Inspector();\n this.renderer.inspector = inspector;\n this._domHelper.element?.appendChild(inspector.domElement);\n\n this.addDebugGUI(inspector, updateCallback);\n\n const renderPassSettings = inspector.createParameters(\n 'Render Pass Settings',\n );\n for (const renderPass of this.renderPasses.values()) {\n renderPass.addParametersToGUI(renderPassSettings, updateCallback);\n }\n }\n\n private addDebugGUI(inspector: Inspector, updateCallback: () => void): void {\n const debugSettings = inspector.createParameters('Debug Settings');\n const params = { debugMode: this.debugMode };\n debugSettings\n .add(params, 'debugMode', {\n Off: 'off',\n Outline: 'outline',\n } satisfies Record<string, WebGPUDebugMode>)\n .onChange((mode: WebGPUDebugMode) => {\n this.debugMode = mode;\n this.passNeedsReassembly = true;\n updateCallback();\n });\n }\n\n public getOrCreateGUIParameters(name: string): ParametersGroup {\n const inspector = this.renderer.inspector;\n if (inspector instanceof Inspector) {\n return (\n this.guiParameterGroups.get(name) ??\n this.createAndCacheGUIParameters(inspector, name)\n );\n }\n throw new Error(\n 'Inspector GUI is not initialized. Call showGUI() before creating parameter groups.',\n );\n }\n\n private createAndCacheGUIParameters(\n inspector: Inspector,\n name: string,\n ): ParametersGroup {\n const parameters = inspector.createParameters(name);\n this.guiParameterGroups.set(name, parameters);\n return parameters;\n }\n}\n"],"x_google_ignoreList":[0,1,4,5,6,7,8,9,10,11,12,13,14,15,16,17],"mappings":"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"}
|