@mml-io/3d-web-client-core 0.21.5 → 0.21.6

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/camera/CameraManager.ts", "../src/helpers/math-helpers.ts", "../src/input/EventHandlerCollection.ts", "../src/tweakpane/blades/cameraFolder.ts", "../src/tweakpane/tweakPaneActivity.ts", "../src/character/Character.ts", "../src/character/CharacterModel.ts", "../src/character/CharacterMaterial.ts", "../src/rendering/shaders/bayer-dither.ts", "../src/rendering/shaders/shader-helpers.ts", "../src/tweakpane/blades/characterFolder.ts", "../src/character/CharacterState.ts", "../src/character/CharacterSpeakingIndicator.ts", "../src/character/CharacterTooltip.ts", "../src/character/CanvasText.ts", "../src/character/CharacterManager.ts", "../src/character/LocalController.ts", "../src/tweakpane/blades/characterControlsFolder.ts", "../src/character/RemoteController.ts", "../src/character/url-position.ts", "../src/character/CharacterModelLoader.ts", "../src/input/KeyInputManager.ts", "../src/input/VirtualJoystick.ts", "../src/mml/MMLCompositionScene.ts", "../src/tweakpane/TweakPane.ts", "../src/tweakpane/blades/bcsFolder.ts", "../src/tweakpane/blades/environmentFolder.ts", "../src/tweakpane/blades/postExtrasFolder.ts", "../src/tweakpane/blades/rendererFolder.ts", "../src/tweakpane/blades/rendererStatsFolder.ts", "../src/tweakpane/blades/ssaoFolder.ts", "../src/tweakpane/blades/toneMappingFolder.ts", "../src/tweakpane/tweakPaneStyle.ts", "../src/rendering/composer.ts", "../src/sun/Sun.ts", "../src/rendering/post-effects/bright-contrast-sat.ts", "../src/rendering/shaders/vertex-shader.ts", "../src/rendering/post-effects/gauss-grain.ts", "../src/rendering/post-effects/n8-ssao/N8SSAOPass.ts", "../src/rendering/post-effects/n8-ssao/BlueNoise.ts", "../src/rendering/post-effects/n8-ssao/DepthDownSample.ts", "../src/rendering/post-effects/n8-ssao/EffectCompositer.ts", "../src/rendering/post-effects/n8-ssao/EffectShader.ts", "../src/rendering/post-effects/n8-ssao/FullScreenTriangle.ts", "../src/rendering/post-effects/n8-ssao/PoissionBlur.ts", "../src/time/TimeManager.ts", "../src/collisions/CollisionsManager.ts", "../src/collisions/getRelativePositionAndRotationRelativeToObject.ts", "../src/ground-plane/GroundPlane.ts", "../src/loading-screen/LoadingScreen.ts", "../src/error-screen/ErrorScreen.ts"],
4
- "sourcesContent": ["import { PerspectiveCamera, Raycaster, Vector3 } from \"three\";\nimport { OrbitControls } from \"three/examples/jsm/controls/OrbitControls.js\";\n\nimport { CollisionsManager } from \"../collisions/CollisionsManager\";\nimport { remap } from \"../helpers/math-helpers\";\nimport { EventHandlerCollection } from \"../input/EventHandlerCollection\";\nimport { camValues } from \"../tweakpane/blades/cameraFolder\";\nimport { TweakPane } from \"../tweakpane/TweakPane\";\nimport { getTweakpaneActive } from \"../tweakpane/tweakPaneActivity\";\n\nconst cameraPanSensitivity = 20;\nconst scrollZoomSensitivity = 0.1;\nconst pinchZoomSensitivity = 0.025;\n\nexport class CameraManager {\n public readonly camera: PerspectiveCamera;\n private flyCamera: PerspectiveCamera;\n private orbitControls: OrbitControls;\n private isMainCameraActive: boolean = true;\n\n public initialDistance: number = camValues.initialDistance;\n public minDistance: number = camValues.minDistance;\n public maxDistance: number = camValues.maxDistance;\n public damping: number = camValues.damping;\n public zoomScale: number = camValues.zoomScale;\n public zoomDamping: number = camValues.zoomDamping;\n\n public initialFOV: number = camValues.initialFOV;\n public maxFOV: number = camValues.maxFOV;\n public minFOV: number = camValues.minFOV;\n public invertFOVMapping: boolean = camValues.invertFOVMapping;\n public fov: number = this.initialFOV;\n private targetFOV: number = this.initialFOV;\n\n public minPolarAngle: number = Math.PI * 0.25;\n private maxPolarAngle: number = Math.PI * 0.95;\n\n public distance: number = this.initialDistance;\n public targetDistance: number = this.initialDistance;\n public desiredDistance: number = this.initialDistance;\n\n private phi: number;\n private targetPhi: number;\n private theta: number;\n private targetTheta: number;\n\n private target: Vector3 = new Vector3(0, 1.55, 0);\n private hadTarget: boolean = false;\n\n private rayCaster: Raycaster;\n\n private eventHandlerCollection: EventHandlerCollection;\n\n private finalTarget: Vector3 = new Vector3();\n private isLerping: boolean = false;\n private lerpTarget: Vector3 = new Vector3();\n private lerpFactor: number = 0;\n private lerpDuration: number = 2.1;\n\n private activePointers = new Map<number, { x: number; y: number }>();\n\n constructor(\n private targetElement: HTMLElement,\n private collisionsManager: CollisionsManager,\n initialPhi = Math.PI / 2,\n initialTheta = -Math.PI / 2,\n ) {\n this.targetElement.style.touchAction = \"pinch-zoom\";\n this.phi = initialPhi;\n this.targetPhi = this.phi;\n this.theta = initialTheta;\n this.targetTheta = this.theta;\n\n const aspect = window.innerWidth / window.innerHeight;\n\n this.camera = new PerspectiveCamera(this.fov, aspect, 0.1, 400);\n this.camera.position.set(0, 1.4, -this.initialDistance);\n this.camera.name = \"MainCamera\";\n this.flyCamera = new PerspectiveCamera(this.initialFOV, aspect, 0.1, 400);\n this.flyCamera.name = \"FlyCamera\";\n this.flyCamera.position.copy(this.camera.position);\n this.flyCamera.name = \"FlyCamera\";\n\n this.orbitControls = new OrbitControls(this.flyCamera, this.targetElement);\n this.orbitControls.enableDamping = true;\n this.orbitControls.dampingFactor = 0.05;\n this.orbitControls.enablePan = true;\n this.orbitControls.enabled = false;\n\n this.rayCaster = new Raycaster();\n\n this.createEventHandlers();\n }\n\n private createEventHandlers(): void {\n this.eventHandlerCollection = EventHandlerCollection.create([\n [this.targetElement, \"pointerdown\", this.onPointerDown.bind(this)],\n [this.targetElement, \"gesturestart\", this.preventDefaultAndStopPropagation.bind(this)],\n [this.targetElement, \"wheel\", this.onMouseWheel.bind(this)],\n [this.targetElement, \"contextmenu\", this.onContextMenu.bind(this)],\n [document, \"pointerup\", this.onPointerUp.bind(this)],\n [document, \"pointercancel\", this.onPointerUp.bind(this)],\n [document, \"pointermove\", this.onPointerMove.bind(this)],\n ]);\n }\n\n private disposeEventHandlers(): void {\n this.eventHandlerCollection.clear();\n }\n\n private preventDefaultAndStopPropagation(evt: PointerEvent): void {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n public setupTweakPane(tweakPane: TweakPane) {\n tweakPane.setupCamPane(this);\n }\n\n private onPointerDown(event: PointerEvent): void {\n if (event.button === 0 || event.button === 2) {\n // Left or right mouse button\n\n const pointerInfo = { x: event.clientX, y: event.clientY };\n this.activePointers.set(event.pointerId, pointerInfo);\n document.body.style.cursor = \"none\";\n }\n }\n\n private onPointerUp(event: PointerEvent): void {\n const existingPointer = this.activePointers.get(event.pointerId);\n if (existingPointer) {\n this.activePointers.delete(event.pointerId);\n if (this.activePointers.size === 0) {\n document.body.style.cursor = \"default\";\n }\n }\n }\n\n private getAveragePointerPositionAndSpread(): { pos: { x: number; y: number }; spread: number } {\n const existingSum = { x: 0, y: 0 };\n this.activePointers.forEach((p) => {\n existingSum.x += p.x;\n existingSum.y += p.y;\n });\n const aX = existingSum.x / this.activePointers.size;\n const aY = existingSum.y / this.activePointers.size;\n\n let sumOfDistances = 0;\n this.activePointers.forEach((p) => {\n const distance = Math.sqrt((p.x - aX) ** 2 + (p.y - aY) ** 2);\n sumOfDistances += distance;\n });\n return { pos: { x: aX, y: aY }, spread: sumOfDistances / this.activePointers.size };\n }\n\n private onPointerMove(event: PointerEvent): void {\n if (getTweakpaneActive()) {\n return;\n }\n\n const existingPointer = this.activePointers.get(event.pointerId);\n if (existingPointer) {\n const previous = this.getAveragePointerPositionAndSpread();\n\n // Replace the pointer info and recalculate to determine the delta\n existingPointer.x = event.clientX;\n existingPointer.y = event.clientY;\n\n const latest = this.getAveragePointerPositionAndSpread();\n\n const sX = latest.pos.x - previous.pos.x;\n const sY = latest.pos.y - previous.pos.y;\n\n const dx = (sX / this.targetElement.clientWidth) * cameraPanSensitivity;\n const dy = (sY / this.targetElement.clientHeight) * cameraPanSensitivity;\n\n if (this.activePointers.size > 1) {\n const zoomDelta = latest.spread - previous.spread;\n this.zoom(-zoomDelta * pinchZoomSensitivity);\n }\n\n this.targetTheta += dx;\n this.targetPhi -= dy;\n this.targetPhi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, this.targetPhi));\n event.preventDefault();\n }\n }\n\n private onMouseWheel(event: WheelEvent): void {\n if (getTweakpaneActive()) {\n return;\n }\n event.preventDefault();\n const scrollAmount = event.deltaY * this.zoomScale * scrollZoomSensitivity;\n this.zoom(scrollAmount);\n }\n\n private zoom(delta: number) {\n this.targetDistance += delta;\n this.targetDistance = Math.max(\n this.minDistance,\n Math.min(this.maxDistance, this.targetDistance),\n );\n this.desiredDistance = this.targetDistance;\n }\n\n private onContextMenu(event: PointerEvent): void {\n event.preventDefault();\n }\n\n public setTarget(target: Vector3): void {\n if (!this.isLerping) {\n this.target.copy(target);\n } else {\n this.finalTarget.copy(target);\n this.lerpTarget.copy(this.target);\n this.lerpFactor = 0;\n }\n\n if (!this.hadTarget) {\n this.hadTarget = true;\n this.reverseUpdateFromPositions();\n }\n }\n\n public setLerpedTarget(target: Vector3, targetDistance: number): void {\n this.isLerping = true;\n this.targetDistance = targetDistance;\n this.desiredDistance = targetDistance;\n this.setTarget(target);\n }\n\n public reverseUpdateFromPositions(): void {\n const dx = this.camera.position.x - this.target.x;\n const dy = this.camera.position.y - this.target.y;\n const dz = this.camera.position.z - this.target.z;\n this.targetDistance = Math.sqrt(dx * dx + dy * dy + dz * dz);\n this.distance = this.targetDistance;\n this.desiredDistance = this.targetDistance;\n this.theta = Math.atan2(dz, dx);\n this.targetTheta = this.theta;\n this.phi = Math.acos(dy / this.targetDistance);\n this.targetPhi = this.phi;\n this.recomputeFoV(true);\n }\n\n public adjustCameraPosition(): void {\n const offsetDistance = 0.5;\n const offset = new Vector3(0, 0, offsetDistance);\n offset.applyEuler(this.camera.rotation);\n const rayOrigin = this.camera.position.clone().add(offset);\n const rayDirection = rayOrigin.sub(this.target.clone()).normalize();\n\n this.rayCaster.set(this.target.clone(), rayDirection);\n const firstRaycastHit = this.collisionsManager.raycastFirst(this.rayCaster.ray);\n\n if (firstRaycastHit !== null && firstRaycastHit[0] <= this.desiredDistance) {\n const distanceToCollision = firstRaycastHit[0] - 0.1;\n this.targetDistance = distanceToCollision;\n this.distance = distanceToCollision;\n } else {\n this.targetDistance = this.desiredDistance;\n }\n }\n\n public dispose() {\n this.disposeEventHandlers();\n this.orbitControls.dispose();\n document.body.style.cursor = \"\";\n }\n\n private easeOutExpo(x: number): number {\n return x === 1 ? 1 : 1 - Math.pow(2, -10 * x);\n }\n\n public updateAspect(aspect: number): void {\n this.camera.aspect = aspect;\n this.flyCamera.aspect = aspect;\n }\n\n public recomputeFoV(immediately: boolean = false): void {\n this.targetFOV = remap(\n this.targetDistance,\n this.minDistance,\n this.maxDistance,\n this.invertFOVMapping ? this.minFOV : this.maxFOV,\n this.invertFOVMapping ? this.maxFOV : this.minFOV,\n );\n if (immediately) {\n this.fov = this.targetFOV;\n }\n }\n\n public toggleFlyCamera(): void {\n this.isMainCameraActive = !this.isMainCameraActive;\n this.orbitControls.enabled = !this.isMainCameraActive;\n\n if (!this.isMainCameraActive) {\n this.updateAspect(window.innerWidth / window.innerHeight);\n this.flyCamera.position.copy(this.camera.position);\n this.flyCamera.rotation.copy(this.camera.rotation);\n const target = new Vector3();\n this.camera.getWorldDirection(target);\n target.multiplyScalar(this.targetDistance).add(this.camera.position);\n this.orbitControls.target.copy(target);\n this.orbitControls.update();\n this.disposeEventHandlers();\n } else {\n this.createEventHandlers();\n }\n }\n\n get activeCamera(): PerspectiveCamera {\n return this.isMainCameraActive ? this.camera : this.flyCamera;\n }\n\n public update(): void {\n if (!this.isMainCameraActive) {\n this.orbitControls.update();\n return;\n }\n if (this.isLerping && this.lerpFactor < 1) {\n this.lerpFactor += 0.01 / this.lerpDuration;\n this.lerpFactor = Math.min(1, this.lerpFactor);\n this.target.lerpVectors(this.lerpTarget, this.finalTarget, this.easeOutExpo(this.lerpFactor));\n } else {\n this.adjustCameraPosition();\n }\n\n this.distance += (this.targetDistance - this.distance) * this.zoomDamping;\n\n this.theta += (this.targetTheta - this.theta) * this.damping;\n this.phi += (this.targetPhi - this.phi) * this.damping;\n\n const x = this.target.x + this.distance * Math.sin(this.phi) * Math.cos(this.theta);\n const y = this.target.y + this.distance * Math.cos(this.phi);\n const z = this.target.z + this.distance * Math.sin(this.phi) * Math.sin(this.theta);\n\n this.recomputeFoV();\n this.fov += (this.targetFOV - this.fov) * this.zoomDamping;\n this.camera.fov = this.fov;\n this.camera.updateProjectionMatrix();\n\n this.camera.position.set(x, y, z);\n this.camera.lookAt(this.target);\n\n if (this.isLerping && this.lerpFactor >= 1) {\n this.isLerping = false;\n }\n }\n\n public hasActiveInput(): boolean {\n return this.activePointers.size > 0;\n }\n}\n", "import { Quaternion, Vector3, Vector4 } from \"three\";\n\nexport const roundToDecimalPlaces = (value: number, decimalPlaces: number): number => {\n const mult = 10 ** decimalPlaces;\n return Math.round(value * mult) / mult;\n};\n\nexport const toArray = (\n origin: Vector3 | Vector4 | Quaternion,\n precision: number = 3,\n): number[] => {\n const array = [];\n array[0] = roundToDecimalPlaces(origin.x, precision);\n array[1] = roundToDecimalPlaces(origin.y, precision);\n array[2] = roundToDecimalPlaces(origin.z, precision);\n if (origin instanceof Vector4 || origin instanceof Quaternion) {\n array[3] = roundToDecimalPlaces(origin.w, precision);\n }\n return array;\n};\n\nexport const getSpawnPositionInsideCircle = (\n radius: number,\n positions: number,\n id: number,\n yPos: number = 0,\n): Vector3 => {\n if (id > 0) id += 3;\n const goldenAngle = Math.PI * (3 - Math.sqrt(5));\n const theta = id * goldenAngle;\n const scale = id / positions;\n const scaledRadius = scale * radius;\n const x = Math.cos(theta) * scaledRadius;\n const z = Math.sin(theta) * scaledRadius;\n return new Vector3(x, yPos, z);\n};\n\nexport const round = (n: number, digits: number): number => {\n return Number(n.toFixed(digits));\n};\n\nexport const ease = (target: number, n: number, factor: number): number => {\n return round((target - n) * factor, 5);\n};\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nexport const remap = (\n value: number,\n minValue: number,\n maxValue: number,\n minScaledValue: number,\n maxScaledValue: number,\n): number => {\n return (\n minScaledValue +\n ((maxScaledValue - minScaledValue) * (value - minValue)) / (maxValue - minValue)\n );\n};\n", "type ListenerFunc = (...args: any[]) => void;\n\ntype EventSpecificationTuple = [EventTarget, string, ListenerFunc, AddEventListenerOptions?];\n\nexport class EventHandlerCollection {\n private eventsByTarget: Map<EventTarget, Map<string, Set<ListenerFunc>>> = new Map();\n\n public add(\n target: EventTarget,\n key: string,\n listener: ListenerFunc,\n options?: AddEventListenerOptions,\n ): this {\n target.addEventListener(key, listener, options);\n\n let existingTarget = this.eventsByTarget.get(target);\n if (existingTarget === undefined) {\n existingTarget = new Map();\n this.eventsByTarget.set(target, existingTarget);\n }\n let existingKey = existingTarget.get(key);\n if (existingKey === undefined) {\n existingKey = new Set();\n existingTarget.set(key, existingKey);\n }\n existingKey.add(listener);\n\n return this;\n }\n\n public clear() {\n this.eventsByTarget.forEach((keyMap, target) => {\n keyMap.forEach((listenerSet, key) => {\n listenerSet.forEach((listenerFunc) => {\n target.removeEventListener(key, listenerFunc);\n });\n });\n });\n this.eventsByTarget.clear();\n }\n\n static create(initial?: Array<EventSpecificationTuple>): EventHandlerCollection {\n const instance = new EventHandlerCollection();\n if (initial !== undefined) {\n initial.forEach(([target, key, listenerFunc, options]) => {\n instance.add(target, key, listenerFunc, options);\n });\n }\n return instance;\n }\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { BladeApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nimport { CameraManager } from \"../../camera/CameraManager\";\n\nexport const camValues = {\n initialDistance: 3.3,\n minDistance: 0.1,\n maxDistance: 5,\n initialFOV: 60,\n maxFOV: 70,\n minFOV: 60,\n invertFOVMapping: false,\n damping: 0.25,\n zoomScale: 0.088,\n zoomDamping: 0.4,\n};\n\nexport const camOptions = {\n initialDistance: { min: 1, max: 5, step: 0.1 },\n minDistance: { min: 0.1, max: 2, step: 0.1 },\n maxDistance: { min: 5, max: 20, step: 0.5 },\n initialFOV: { min: 60, max: 85, step: 1 },\n maxFOV: { min: 50, max: 100, step: 1 },\n minFOV: { min: 50, max: 100, step: 1 },\n damping: { min: 0.01, max: 1, step: 0.001 },\n zoomScale: { min: 0.005, max: 0.3, step: 0.001 },\n zoomDamping: { min: 0.0, max: 2.0, step: 0.01 },\n};\n\ntype CamData = {\n distance: string;\n FoV: string;\n};\n\nexport class CameraFolder {\n public folder: FolderApi;\n\n private camData: CamData = {\n distance: \"0\",\n FoV: \"0\",\n };\n\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({ title: \"camera\", expanded: expand });\n this.folder.addBinding(this.camData, \"distance\", { readonly: true });\n this.folder.addBinding(this.camData, \"FoV\", { readonly: true });\n this.folder.addBinding(camValues, \"initialDistance\", camOptions.initialDistance);\n this.folder.addBinding(camValues, \"minDistance\", camOptions.minDistance);\n this.folder.addBinding(camValues, \"maxDistance\", camOptions.maxDistance);\n this.folder.addBinding(camValues, \"minFOV\", camOptions.minFOV);\n this.folder.addBinding(camValues, \"maxFOV\", camOptions.maxFOV);\n this.folder.addBinding({ invertFOVMapping: camValues.invertFOVMapping }, \"invertFOVMapping\");\n this.folder.addBinding(camValues, \"damping\", camOptions.damping);\n this.folder.addBinding(camValues, \"zoomScale\", camOptions.zoomScale);\n this.folder.addBinding(camValues, \"zoomDamping\", camOptions.zoomDamping);\n }\n\n public setupChangeEvent(cameraManager: CameraManager): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"initialDistance\": {\n const value = e.value as number;\n cameraManager.initialDistance = value;\n cameraManager.distance = value;\n cameraManager.targetDistance = value;\n cameraManager.desiredDistance = value;\n cameraManager.recomputeFoV();\n break;\n }\n case \"minDistance\": {\n const value = e.value as number;\n cameraManager.minDistance = value;\n cameraManager.distance = value;\n cameraManager.targetDistance = value;\n cameraManager.desiredDistance = value;\n cameraManager.recomputeFoV();\n break;\n }\n case \"maxDistance\": {\n const value = e.value as number;\n cameraManager.maxDistance = value;\n cameraManager.distance = value;\n cameraManager.targetDistance = value;\n cameraManager.desiredDistance = value;\n cameraManager.recomputeFoV();\n break;\n }\n case \"minFOV\": {\n const value = e.value as number;\n cameraManager.minFOV = value;\n cameraManager.recomputeFoV();\n break;\n }\n case \"maxFOV\": {\n const value = e.value as number;\n cameraManager.maxFOV = value;\n cameraManager.recomputeFoV();\n break;\n }\n case \"invertFOVMapping\": {\n const boolValue = e.value as boolean;\n cameraManager.invertFOVMapping = boolValue;\n break;\n }\n case \"damping\": {\n const value = e.value as number;\n cameraManager.damping = value;\n break;\n }\n case \"zoomScale\": {\n const value = e.value as number;\n cameraManager.zoomScale = value;\n break;\n }\n case \"zoomDamping\": {\n const value = e.value as number;\n cameraManager.zoomDamping = value;\n break;\n }\n default:\n break;\n }\n });\n }\n\n public update(cameraManager: CameraManager): void {\n this.camData.distance = cameraManager.distance.toFixed(2);\n this.camData.FoV = cameraManager.fov.toFixed(2);\n }\n}\n", "let isTweakpaneActive = false;\n\nexport function setTweakpaneActive(status: boolean) {\n isTweakpaneActive = status;\n}\n\nexport function getTweakpaneActive() {\n return isTweakpaneActive;\n}\n", "import { Color, Group, Vector3 } from \"three\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\nimport { Composer } from \"../rendering/composer\";\n\nimport { CharacterModel } from \"./CharacterModel\";\nimport { CharacterModelLoader } from \"./CharacterModelLoader\";\nimport { CharacterSpeakingIndicator } from \"./CharacterSpeakingIndicator\";\nimport { AnimationState } from \"./CharacterState\";\nimport { CharacterTooltip } from \"./CharacterTooltip\";\n\nexport type AnimationConfig = {\n idleAnimationFileUrl: string;\n jogAnimationFileUrl: string;\n sprintAnimationFileUrl: string;\n airAnimationFileUrl: string;\n doubleJumpAnimationFileUrl: string;\n};\n\nexport type CharacterDescription =\n | {\n meshFileUrl: string;\n mmlCharacterString?: null;\n mmlCharacterUrl?: null;\n }\n | {\n meshFileUrl?: null;\n mmlCharacterString: string;\n mmlCharacterUrl?: null;\n }\n | {\n meshFileUrl?: null;\n mmlCharacterString?: null;\n mmlCharacterUrl: string;\n };\n\nexport type CharacterConfig = {\n username: string;\n characterDescription: CharacterDescription;\n animationConfig: AnimationConfig;\n characterModelLoader: CharacterModelLoader;\n characterId: number;\n modelLoadedCallback: () => void;\n cameraManager: CameraManager;\n composer: Composer;\n isLocal: boolean;\n};\n\nfunction characterHeightToTooltipHeightOffset(characterHeight: number): number {\n return characterHeight - 0.4 + 0.1;\n}\n\nfunction characterDescriptionMatches(a: CharacterDescription, b: CharacterDescription): boolean {\n return (\n a.meshFileUrl === b.meshFileUrl &&\n a.mmlCharacterString === b.mmlCharacterString &&\n a.mmlCharacterUrl === b.mmlCharacterUrl\n );\n}\n\nexport class Character extends Group {\n private model: CharacterModel | null = null;\n public color: Color = new Color();\n public tooltip: CharacterTooltip;\n public speakingIndicator: CharacterSpeakingIndicator | null = null;\n\n public chatTooltips: CharacterTooltip[] = [];\n\n constructor(private config: CharacterConfig) {\n super();\n this.tooltip = new CharacterTooltip(\n this.config.isLocal\n ? {\n secondsToFadeOut: 10,\n }\n : {},\n );\n this.tooltip.setText(this.config.username);\n this.add(this.tooltip);\n this.load().then(() => {\n this.config.modelLoadedCallback();\n this.setTooltipHeights();\n });\n }\n\n updateCharacter(username: string, characterDescription: CharacterDescription) {\n if (!characterDescriptionMatches(this.config.characterDescription, characterDescription)) {\n this.config.characterDescription = characterDescription;\n this.load().then(() => {\n this.setTooltipHeights();\n });\n }\n if (this.config.username !== username) {\n this.config.username = username;\n this.tooltip.setText(username);\n // Force the tooltip to show if the character's name changes\n this.tooltip.show();\n }\n }\n\n private setTooltipHeights() {\n if (this.model && this.model.characterHeight) {\n let height = characterHeightToTooltipHeightOffset(this.model.characterHeight);\n this.tooltip.setHeightOffset(height);\n height += this.tooltip.scale.y;\n\n for (const chatTooltip of this.chatTooltips) {\n chatTooltip.setHeightOffset(height);\n height += chatTooltip.scale.y;\n }\n }\n }\n\n private async load(): Promise<void> {\n const previousModel = this.model;\n if (previousModel && previousModel.mesh) {\n this.remove(previousModel.mesh);\n }\n this.model = new CharacterModel({\n characterDescription: this.config.characterDescription,\n animationConfig: this.config.animationConfig,\n characterModelLoader: this.config.characterModelLoader,\n cameraManager: this.config.cameraManager,\n characterId: this.config.characterId,\n isLocal: this.config.isLocal,\n });\n await this.model.init();\n if (this.model.mesh) {\n this.add(this.model.mesh);\n }\n if (this.speakingIndicator === null) {\n this.speakingIndicator = new CharacterSpeakingIndicator(this.config.composer.postPostScene);\n }\n }\n\n public updateAnimation(targetAnimation: AnimationState) {\n this.model?.updateAnimation(targetAnimation);\n }\n\n public update(time: number, deltaTime: number) {\n if (!this.model) return;\n if (this.tooltip) {\n this.tooltip.update();\n }\n if (this.speakingIndicator) {\n this.speakingIndicator.setTime(time);\n if (this.model.mesh && this.model.headBone) {\n this.speakingIndicator.setBillboarding(\n this.model.headBone?.getWorldPosition(new Vector3()),\n this.config.cameraManager.camera,\n );\n }\n }\n this.model.update(deltaTime);\n }\n\n getCurrentAnimation(): AnimationState {\n return this.model?.currentAnimation || AnimationState.idle;\n }\n\n addChatBubble(message: string) {\n const tooltip = new CharacterTooltip({\n maxWidth: 1000,\n secondsToFadeOut: 10,\n color: new Color(0.125, 0.125, 0.125),\n });\n this.add(tooltip);\n this.chatTooltips.unshift(tooltip);\n tooltip.setText(message, () => {\n this.chatTooltips = this.chatTooltips.filter((t) => t !== tooltip);\n this.remove(tooltip);\n this.setTooltipHeights();\n });\n if (this.config.isLocal) {\n // Show the character's name if they're local and they emit a chat bubble\n this.tooltip.show();\n }\n this.setTooltipHeights();\n }\n}\n", "import {\n MMLCharacter,\n type MMLCharacterDescription,\n parseMMLDescription,\n} from \"@mml-io/3d-web-avatar\";\nimport { ModelLoader } from \"@mml-io/model-loader\";\nimport {\n AnimationAction,\n AnimationClip,\n AnimationMixer,\n Bone,\n Box3,\n LoopRepeat,\n Mesh,\n MeshStandardMaterial,\n Object3D,\n SkinnedMesh,\n Vector3,\n} from \"three\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\n\nimport { AnimationConfig, CharacterDescription } from \"./Character\";\nimport { CharacterMaterial } from \"./CharacterMaterial\";\nimport { CharacterModelLoader } from \"./CharacterModelLoader\";\nimport { AnimationState } from \"./CharacterState\";\n\nexport type CharacterModelConfig = {\n characterDescription: CharacterDescription;\n animationConfig: AnimationConfig;\n characterModelLoader: CharacterModelLoader;\n cameraManager: CameraManager;\n characterId: number;\n isLocal: boolean;\n};\n\nexport class CharacterModel {\n public static ModelLoader: ModelLoader = new ModelLoader();\n\n public mesh: Object3D | null = null;\n public headBone: Bone | null = null;\n public characterHeight: number | null = null;\n\n private materials: Map<string, CharacterMaterial> = new Map();\n\n public animations: Record<string, AnimationAction> = {};\n public animationMixer: AnimationMixer | null = null;\n public currentAnimation: AnimationState = AnimationState.idle;\n\n public mmlCharacterDescription: MMLCharacterDescription;\n\n private isPostDoubleJump = false;\n\n constructor(private config: CharacterModelConfig) {}\n\n public async init(): Promise<void> {\n await this.loadMainMesh();\n if (this.mesh) {\n await this.setAnimationFromFile(\n this.config.animationConfig.idleAnimationFileUrl,\n AnimationState.idle,\n true,\n );\n await this.setAnimationFromFile(\n this.config.animationConfig.jogAnimationFileUrl,\n AnimationState.walking,\n true,\n );\n await this.setAnimationFromFile(\n this.config.animationConfig.sprintAnimationFileUrl,\n AnimationState.running,\n true,\n );\n await this.setAnimationFromFile(\n this.config.animationConfig.airAnimationFileUrl,\n AnimationState.air,\n true,\n );\n await this.setAnimationFromFile(\n this.config.animationConfig.doubleJumpAnimationFileUrl,\n AnimationState.doubleJump,\n false,\n 1.45,\n );\n this.applyCustomMaterials();\n }\n }\n\n private applyCustomMaterials(): void {\n if (!this.mesh) return;\n const boundingBox = new Box3();\n this.mesh.updateWorldMatrix(true, true);\n boundingBox.expandByObject(this.mesh);\n this.characterHeight = boundingBox.max.y - boundingBox.min.y;\n\n this.mesh.traverse((child: Object3D) => {\n if ((child as Bone).isBone) {\n if (child.name === \"head\") {\n const worldPosition = new Vector3();\n this.headBone = child as Bone;\n this.headBone.getWorldPosition(worldPosition);\n }\n }\n if ((child as Mesh).isMesh || (child as SkinnedMesh).isSkinnedMesh) {\n const asMesh = child as Mesh;\n const originalMaterial = asMesh.material as MeshStandardMaterial;\n if (this.materials.has(originalMaterial.name)) {\n asMesh.material = this.materials.get(originalMaterial.name)!;\n } else {\n const material =\n originalMaterial.name === \"body_replaceable_color\"\n ? new CharacterMaterial({\n isLocal: this.config.isLocal,\n cameraManager: this.config.cameraManager,\n characterId: this.config.characterId,\n originalMaterial,\n })\n : new CharacterMaterial({\n isLocal: this.config.isLocal,\n cameraManager: this.config.cameraManager,\n characterId: this.config.characterId,\n originalMaterial,\n colorOverride: originalMaterial.color,\n });\n this.materials.set(originalMaterial.name, material);\n asMesh.material = material;\n }\n }\n });\n }\n\n public updateAnimation(targetAnimation: AnimationState) {\n if (this.isPostDoubleJump) {\n if (targetAnimation === AnimationState.doubleJump) {\n // Double jump is requested, but we're in the post double jump state so we play air instead\n targetAnimation = AnimationState.air;\n } else {\n // Reset the post double jump flag if something other than double jump is requested\n this.isPostDoubleJump = false;\n }\n }\n if (this.currentAnimation !== targetAnimation) {\n this.transitionToAnimation(targetAnimation);\n }\n }\n\n private setMainMesh(mainMesh: Object3D): void {\n this.mesh = mainMesh;\n this.mesh.position.set(0, -0.44, 0);\n this.mesh.traverse((child: Object3D) => {\n if (child.type === \"SkinnedMesh\") {\n child.castShadow = true;\n child.receiveShadow = true;\n }\n });\n this.animationMixer = new AnimationMixer(this.mesh);\n }\n\n private async composeMMLCharacter(\n mmlCharacterDescription: MMLCharacterDescription,\n ): Promise<Object3D | undefined> {\n if (mmlCharacterDescription.base?.url.length === 0) {\n throw new Error(\n \"ERROR: An MML Character Description was provided, but it's not a valid <m-character> string, or a valid URL\",\n );\n }\n\n let mergedCharacter: Object3D | null = null;\n if (mmlCharacterDescription) {\n const characterBase = mmlCharacterDescription.base?.url || null;\n if (characterBase) {\n this.mmlCharacterDescription = mmlCharacterDescription;\n const mmlCharacter = new MMLCharacter(CharacterModel.ModelLoader);\n mergedCharacter = await mmlCharacter.mergeBodyParts(\n characterBase,\n mmlCharacterDescription.parts,\n );\n if (mergedCharacter) {\n return mergedCharacter;\n }\n }\n }\n }\n\n private async loadCharacterFromDescription(): Promise<Object3D | null> {\n if (this.config.characterDescription.meshFileUrl) {\n return (\n (await this.config.characterModelLoader.load(\n this.config.characterDescription.meshFileUrl,\n \"model\",\n )) || null\n );\n }\n\n let mmlCharacterSource: string;\n if (this.config.characterDescription.mmlCharacterUrl) {\n const res = await fetch(this.config.characterDescription.mmlCharacterUrl);\n mmlCharacterSource = await res.text();\n } else if (this.config.characterDescription.mmlCharacterString) {\n mmlCharacterSource = this.config.characterDescription.mmlCharacterString;\n } else {\n throw new Error(\n \"ERROR: No Character Description was provided. Specify one of meshFileUrl, mmlCharacterUrl or mmlCharacterString\",\n );\n }\n\n const parsedMMLDescription = parseMMLDescription(mmlCharacterSource);\n const mmlCharacterDescription = parsedMMLDescription[0];\n if (parsedMMLDescription[1].length > 0) {\n console.warn(\"Errors parsing MML Character Description: \", parsedMMLDescription[1]);\n }\n const mmlCharacterBody = await this.composeMMLCharacter(mmlCharacterDescription);\n if (mmlCharacterBody) {\n return mmlCharacterBody;\n }\n return null;\n }\n\n private async loadMainMesh(): Promise<void> {\n let mainMesh: Object3D | null = null;\n try {\n mainMesh = await this.loadCharacterFromDescription();\n } catch (error) {\n console.error(\"Failed to load character from description\", error);\n }\n if (mainMesh) {\n this.setMainMesh(mainMesh as Object3D);\n }\n }\n\n private cleanAnimationClips(\n skeletalMesh: Object3D | null,\n animationClip: AnimationClip,\n keepRootBonePositionAnimation: boolean,\n ): AnimationClip {\n const availableBones = new Set<string>();\n if (skeletalMesh) {\n skeletalMesh.traverse((child) => {\n const asBone = child as Bone;\n if (asBone.isBone) {\n availableBones.add(child.name);\n }\n });\n }\n animationClip.tracks = animationClip.tracks.filter((track) => {\n const [trackName, trackProperty] = track.name.split(\".\");\n if (keepRootBonePositionAnimation && trackName === \"root\" && trackProperty === \"position\") {\n return true;\n }\n const shouldAnimate =\n availableBones.has(trackName) && trackProperty !== \"position\" && trackProperty !== \"scale\";\n return shouldAnimate;\n });\n return animationClip;\n }\n\n private async setAnimationFromFile(\n animationFileUrl: string,\n animationType: AnimationState,\n loop: boolean = true,\n playbackSpeed: number = 1.0,\n ): Promise<void> {\n return new Promise(async (resolve, reject) => {\n const animation = await this.config.characterModelLoader.load(animationFileUrl, \"animation\");\n const cleanAnimation = this.cleanAnimationClips(this.mesh, animation as AnimationClip, true);\n if (typeof animation !== \"undefined\" && cleanAnimation instanceof AnimationClip) {\n this.animations[animationType] = this.animationMixer!.clipAction(cleanAnimation);\n this.animations[animationType].stop();\n this.animations[animationType].timeScale = playbackSpeed;\n if (animationType === AnimationState.idle) {\n this.animations[animationType].play();\n }\n if (!loop) {\n this.animations[animationType].setLoop(LoopRepeat, 1); // Ensure non-looping\n this.animations[animationType].clampWhenFinished = true;\n }\n resolve();\n } else {\n reject(`failed to load ${animationType} from ${animationFileUrl}`);\n }\n });\n }\n\n private transitionToAnimation(\n targetAnimation: AnimationState,\n transitionDuration: number = 0.15,\n ): void {\n if (!this.mesh) {\n return;\n }\n\n const currentAction = this.animations[this.currentAnimation];\n this.currentAnimation = targetAnimation;\n const targetAction = this.animations[targetAnimation];\n\n if (!targetAction) {\n return;\n }\n\n if (currentAction) {\n currentAction.fadeOut(transitionDuration);\n }\n\n targetAction.reset();\n if (!targetAction.isRunning()) {\n targetAction.play();\n }\n\n if (targetAnimation === AnimationState.doubleJump) {\n targetAction.getMixer().addEventListener(\"finished\", (_event) => {\n if (this.currentAnimation === AnimationState.doubleJump) {\n this.isPostDoubleJump = true;\n // This triggers the transition to the air animation because the double jump animation is done\n this.updateAnimation(AnimationState.doubleJump);\n }\n });\n }\n\n targetAction.enabled = true;\n targetAction.fadeIn(transitionDuration);\n }\n\n update(time: number) {\n if (this.animationMixer) {\n this.animationMixer.update(time);\n this.materials.forEach((material) => material.update());\n }\n }\n}\n", "import { Color, MeshStandardMaterial, UniformsUtils } from \"three\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\nimport { ease } from \"../helpers/math-helpers\";\nimport { bayerDither } from \"../rendering/shaders/bayer-dither\";\nimport {\n injectBefore,\n injectBeforeMain,\n injectInsideMain,\n} from \"../rendering/shaders/shader-helpers\";\nimport { characterValues } from \"../tweakpane/blades/characterFolder\";\n\ntype TUniform<TValue = any> = { value: TValue };\n\nexport type CharacterMaterialConfig = {\n isLocal: boolean;\n cameraManager: CameraManager;\n characterId: number;\n originalMaterial: MeshStandardMaterial;\n colorOverride?: Color;\n};\n\nexport class CharacterMaterial extends MeshStandardMaterial {\n private uniforms: Record<string, TUniform> = {\n discardAll: { value: 1 },\n diffuseColor: { value: new Color() },\n map: { value: null },\n };\n private colorsCube216: Color[] = [];\n private targetAlpha: number = 1;\n private currentAlpha: number = 1;\n\n constructor(private config: CharacterMaterialConfig) {\n super();\n this.copy(this.config.originalMaterial);\n this.generateColorCube();\n\n this.color = this.config.colorOverride || this.colorsCube216[this.config.characterId];\n this.envMapIntensity = characterValues.envMapIntensity;\n this.transparent = true;\n this.side = this.config.originalMaterial.side;\n\n this.onBeforeCompile = (shader) => {\n this.uniforms = UniformsUtils.clone(shader.uniforms);\n this.uniforms.nearClip = { value: 0.01 };\n this.uniforms.farClip = { value: 1000.0 };\n this.uniforms.ditheringNear = { value: 0.3 };\n this.uniforms.ditheringRange = { value: 0.5 };\n this.uniforms.time = { value: 0.0 };\n this.uniforms.diffuseRandomColor = { value: new Color() };\n this.uniforms.discardAll = { value: 0 };\n shader.uniforms = this.uniforms;\n\n shader.vertexShader = \"varying vec3 vWorldPosition;\\n\" + shader.vertexShader;\n shader.vertexShader = shader.vertexShader.replace(\n \"#include <worldpos_vertex>\",\n \"vec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\\nvWorldPosition = worldPosition.xyz;\",\n );\n shader.vertexShader = injectBeforeMain(shader.vertexShader, \"varying vec2 vUv;\");\n shader.vertexShader = injectInsideMain(shader.vertexShader, \"vUv = uv;\");\n\n shader.fragmentShader = injectBeforeMain(\n shader.fragmentShader,\n /* glsl */ `\n varying vec2 vUv;\n varying vec3 vWorldPosition;\n uniform float nearClip;\n uniform float farClip;\n uniform float ditheringNear;\n uniform float ditheringRange;\n uniform float time;\n uniform vec3 diffuseRandomColor;\n uniform int discardAll;\n ${bayerDither}\n `,\n );\n\n shader.fragmentShader = injectBefore(\n shader.fragmentShader,\n \"#include <dithering_fragment>\",\n /* glsl */ `\n if (discardAll == 1) {\n discard;\n } else {\n float distance = length(vWorldPosition - cameraPosition);\n float normalizedDistance = (distance - nearClip) / (farClip - nearClip);\n ivec2 p = ivec2(mod(gl_FragCoord.xy, 8.0));\n float d = 0.0;\n if (p.x <= 3 && p.y <= 3) {\n d = bayerDither(bayertl, p);\n } else if (p.x > 3 && p.y <= 3) {\n d = bayerDither(bayertr, p - ivec2(4, 0));\n } else if (p.x <= 3 && p.y > 3) {\n d = bayerDither(bayerbl, p - ivec2(0, 4));\n } else if (p.x > 3 && p.y > 3) {\n d = bayerDither(bayerbr, p - ivec2(4, 4));\n }\n if (distance <= ditheringNear + d * ditheringRange) discard; \n outgoingLight *= diffuseRandomColor; \n }\n `,\n );\n };\n this.needsUpdate = true;\n }\n\n private generateColorCube() {\n const saturation = 1.0;\n const lightness = 0.9;\n const goldenRatioConjugate = 0.618033988749895;\n let hue = 0;\n\n for (let i = 0; i < 216; i++) {\n const color = new Color();\n color.setHSL(hue, saturation, lightness);\n this.colorsCube216.push(color);\n hue = (hue + goldenRatioConjugate) % 1;\n }\n }\n\n public update() {\n if (this.config.isLocal) {\n this.targetAlpha = this.config.cameraManager.distance < 0.4 ? 0.0 : 1.0;\n this.currentAlpha += ease(this.targetAlpha, this.currentAlpha, 0.07);\n if (this.currentAlpha > 0.999) {\n this.currentAlpha = 1;\n this.config.cameraManager.minPolarAngle = Math.PI * 0.25;\n }\n if (this.currentAlpha < 0.001) {\n this.currentAlpha = 0;\n this.config.cameraManager.minPolarAngle = Math.PI * 0.35;\n }\n this.uniforms.discardAll.value = this.currentAlpha === 0 ? 1 : 0;\n if (this.currentAlpha !== this.opacity) {\n this.opacity = this.currentAlpha;\n }\n }\n this.metalness = characterValues.metalness;\n this.roughness = characterValues.roughness;\n this.emissive = new Color().setRGB(\n characterValues.emissive.r,\n characterValues.emissive.g,\n characterValues.emissive.b,\n );\n this.emissiveIntensity = characterValues.emissiveIntensity;\n this.envMapIntensity = characterValues.envMapIntensity;\n }\n}\n", "export const bayerDither: string = /* glsl */ `\nconst mat4 bayertl = mat4( \n 0.0 / 64.0, 32.0 / 64.0, 8.0 / 64.0, 40.0 / 64.0,\n 48.0 / 64.0, 16.0 / 64.0, 56.0 / 64.0, 24.0 / 64.0,\n 12.0 / 64.0, 44.0 / 64.0, 4.0 / 64.0, 36.0 / 64.0,\n 60.0 / 64.0, 28.0 / 64.0, 52.0 / 64.0, 20.0 / 64.0\n);\n\nconst mat4 bayertr = mat4( \n 2.0 / 64.0, 34.0 / 64.0, 10.0 / 64.0, 42.0 / 64.0,\n 50.0 / 64.0, 18.0 / 64.0, 58.0 / 64.0, 26.0 / 64.0,\n 14.0 / 64.0, 46.0 / 64.0, 6.0 / 64.0, 38.0 / 64.0,\n 62.0 / 64.0, 30.0 / 64.0, 54.0 / 64.0, 22.0 / 64.0\n);\n\nconst mat4 bayerbl = mat4( \n 3.0 / 64.0, 35.0 / 64.0, 11.0 / 64.0, 43.0 / 64.0,\n 51.0 / 64.0, 19.0 / 64.0, 59.0 / 64.0, 27.0 / 64.0,\n 15.0 / 64.0, 47.0 / 64.0, 7.0 / 64.0, 39.0 / 64.0,\n 63.0 / 64.0, 31.0 / 64.0, 55.0 / 64.0, 23.0 / 64.0\n);\n\nconst mat4 bayerbr = mat4( \n 1.0 / 64.0, 33.0 / 64.0, 9.0 / 64.0, 41.0 / 64.0,\n 49.0 / 64.0, 17.0 / 64.0, 57.0 / 64.0, 25.0 / 64.0,\n 13.0 / 64.0, 45.0 / 64.0, 5.0 / 64.0, 37.0 / 64.0,\n 61.0 / 64.0, 29.0 / 64.0, 53.0 / 64.0, 21.0 / 64.0\n);\n\nfloat bayerDither(mat4 m, ivec2 p) {\n if (p.y == 0) {\n if (p.x == 0) { return m[0][0]; }\n else if (p.x == 1) { return m[1][0]; }\n else if (p.x == 2) { return m[2][0]; }\n else { return m[3][0]; }\n } else if (p.y == 1) {\n if (p.x == 0) { return m[0][1]; }\n else if (p.x == 1) { return m[1][1]; }\n else if (p.x == 2) { return m[2][1]; }\n else { return m[3][1]; }\n } else if (p.y == 2) {\n if (p.x == 0) { return m[0][1]; }\n else if (p.x == 1) { return m[1][2]; }\n else if (p.x == 2) { return m[2][2]; }\n else { return m[3][2]; }\n } else {\n if (p.x == 0) { return m[0][3]; }\n else if (p.x == 1) { return m[1][3]; }\n else if (p.x == 2) { return m[2][3]; }\n else { return m[3][3]; }\n }\n}\n`;\n", "export function injectBeforeMain(shaderSource: string, codeToInject: string): string {\n return shaderSource.replace(\n \"void main() {\",\n `\n\n${codeToInject}\n\nvoid main() {`,\n );\n}\n\nexport function injectInsideMain(shaderSource: string, codeToInject: string): string {\n return shaderSource.replace(\n \"void main() {\",\n `void main() {\n\n${codeToInject}\n\n `,\n );\n}\n\nexport function injectBefore(shaderSource: string, before: string, codeToInject: string): string {\n return shaderSource.replace(\n before,\n `\n${codeToInject}\n\n${before}\n `,\n );\n}\n\nexport function injectAfter(shaderSource: string, after: string, codeToInject: string): string {\n return shaderSource.replace(\n after,\n `\n${after}\n\n${codeToInject}\n\n `,\n );\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { BladeApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nexport const characterValues = {\n metalness: 0.2,\n roughness: 0.8,\n emissive: { r: 1.0, g: 1.0, b: 1.0 },\n emissiveIntensity: 0.01,\n envMapIntensity: 0.12,\n};\n\nconst characterOptions = {\n metalness: { min: 0, max: 1, step: 0.01 },\n roughness: { min: 0, max: 1, step: 0.01 },\n emissiveIntensity: { min: 0, max: 1, step: 0.01 },\n envMapIntensity: { min: 0, max: 1, step: 0.01 },\n};\n\nexport class CharacterFolder {\n private folder: FolderApi;\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({ title: \"characterMaterial\", expanded: expand });\n this.folder.addBinding(characterValues, \"metalness\", characterOptions.metalness);\n this.folder.addBinding(characterValues, \"roughness\", characterOptions.roughness);\n this.folder.addBinding(characterValues, \"emissive\", {\n color: { type: \"float\" },\n });\n this.folder.addBinding(\n characterValues,\n \"emissiveIntensity\",\n characterOptions.emissiveIntensity,\n );\n this.folder.addBinding(characterValues, \"envMapIntensity\", characterOptions.envMapIntensity);\n }\n\n public setupChangeEvent(): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"emissive\": {\n const value = e.value as { r: number; g: number; b: number };\n characterValues.emissive = {\n r: value.r,\n g: value.g,\n b: value.b,\n };\n break;\n }\n default: {\n break;\n }\n }\n });\n }\n}\n", "export enum AnimationState {\n \"idle\" = 0,\n \"walking\" = 1,\n \"running\" = 2,\n \"jumpToAir\" = 3,\n \"air\" = 4,\n \"airToGround\" = 5,\n \"doubleJump\" = 6,\n}\n\nexport type CharacterState = {\n id: number;\n position: {\n x: number;\n y: number;\n z: number;\n };\n rotation: {\n quaternionY: number;\n quaternionW: number;\n };\n camPosition?: {\n x: number;\n y: number;\n z: number;\n };\n camQuaternion?: {\n y: number;\n w: number;\n };\n state: AnimationState;\n};\n", "import {\n Camera,\n CircleGeometry,\n GLSL3,\n Mesh,\n Object3D,\n RawShaderMaterial,\n Scene,\n Vector3,\n} from \"three\";\n\nimport { ease } from \"../helpers/math-helpers\";\n\nexport class CharacterSpeakingIndicator {\n private vertexShader = /* glsl */ `\n in vec3 position;\n in vec2 uv;\n uniform mat4 modelViewMatrix;\n uniform mat4 projectionMatrix;\n out vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }`;\n\n private fragmentShader = /* glsl */ `\n precision highp float;\n\n uniform float time;\n uniform float alpha;\n in vec2 vUv;\n out vec4 fragColor;\n\n const float size = 1.7;\n const float distribution = 0.03;\n const float speed = 0.2;\n const float overdraw = 3.5;\n const float shapeK = 0.25;\n\n float sdHyperbola(vec2 p, float k, float wi) {\n p = abs(p);\n float k2 = k * k;\n float a = p.x + p.y;\n float i = 0.5 * (a - k2 / a) > wi ? -1.0 : 1.0;\n float x = clamp(0.5 * (a - k2 / a), 0.0, wi);\n vec2 q = vec2(x, sqrt(x * x + k2));\n float s = sign(p.x * p.x - p.y * p.y + k2);\n return s * length(p - q);\n }\n\n void main(void) {\n vec2 uv = (vUv * 2.0 - 1.0);\n float r = -(uv.x * uv.x + uv.y * uv.y);\n float z = 0.5 + 0.5 * sin((r + time * speed) / distribution);\n float a = clamp(smoothstep(-0.1, 0.2, size - length(uv * 2.0)), 0.0, 0.5);\n float h = clamp(sdHyperbola(uv, shapeK, 1.0), 0.0, 1.0) * overdraw;\n float fragAlpha = clamp(a * h, 0.0, 0.7);\n fragColor = vec4(z * fragAlpha) * alpha;\n }`;\n\n private uniforms = {\n time: { value: 0.0 },\n alpha: { value: 0.0 },\n };\n\n private geometry: CircleGeometry = new CircleGeometry(0.35, 21);\n private material: RawShaderMaterial = new RawShaderMaterial({\n vertexShader: this.vertexShader,\n fragmentShader: this.fragmentShader,\n uniforms: this.uniforms,\n transparent: true,\n glslVersion: GLSL3,\n });\n private mesh = new Mesh(this.geometry, this.material);\n\n private currentAlpha = 0.0;\n private targetAlpha = 0.0;\n\n constructor(private scene: Scene | Object3D) {\n this.scene.add(this.mesh);\n }\n\n public setBillboarding(position: Vector3, camera: Camera) {\n this.mesh.position.set(position.x, position.y, position.z);\n this.mesh.lookAt(camera.position);\n }\n\n public setTime(value: number) {\n this.currentAlpha += ease(this.targetAlpha, this.currentAlpha, 0.06);\n this.uniforms.time.value = value;\n this.uniforms.alpha.value = this.currentAlpha;\n }\n\n public setSpeaking(value: boolean) {\n this.targetAlpha = value === true ? 1.0 : 0.0;\n }\n\n public dispose() {\n this.scene.remove(this.mesh);\n this.mesh.material.dispose();\n this.mesh.geometry.dispose();\n }\n}\n", "import { Color, FrontSide, LinearFilter, Sprite, SpriteMaterial } from \"three\";\n\nimport { THREECanvasTextTexture } from \"./CanvasText\";\n\nenum LabelAlignment {\n left = \"left\",\n center = \"center\",\n right = \"right\",\n}\n\nconst fontScale = 5;\nconst defaultLabelColor = new Color(0x000000);\nconst defaultFontColor = new Color(0xffffff);\nconst defaultLabelAlignment = LabelAlignment.center;\nconst defaultLabelFontSize = 10;\nconst defaultLabelPadding = 10;\nconst defaultVisibleOpacity = 0.85;\nconst defaultHeightOffset = 1.4;\nconst defaultSecondsToFadeOut = null;\n\nexport type CharacterTooltipConfig = {\n alignment: LabelAlignment;\n fontSize: number;\n padding: number;\n color: Color;\n fontColor: Color;\n visibleOpacity: number;\n maxWidth?: number;\n secondsToFadeOut: number | null;\n};\n\nexport class CharacterTooltip extends Sprite {\n private targetOpacity: number = 0;\n private fadingSpeed: number = 0.02;\n private config: CharacterTooltipConfig;\n private content: string | null = null;\n private hideTimeout: NodeJS.Timeout | null = null;\n\n constructor(configArg?: Partial<CharacterTooltipConfig>) {\n super();\n this.config = {\n alignment: defaultLabelAlignment,\n fontSize: defaultLabelFontSize,\n padding: defaultLabelPadding,\n color: defaultLabelColor,\n fontColor: defaultFontColor,\n visibleOpacity: defaultVisibleOpacity,\n secondsToFadeOut: defaultSecondsToFadeOut,\n ...configArg,\n };\n\n this.material = new SpriteMaterial({\n map: null,\n transparent: true,\n opacity: this.config.visibleOpacity,\n side: FrontSide,\n });\n\n this.position.set(0, 1.6, 0);\n this.visible = false;\n }\n\n public setHeightOffset(height: number) {\n this.position.y = height + this.scale.y / 2;\n }\n\n private redrawText(content: string) {\n if (content === this.content) {\n // No need to redraw if the content is the same\n return;\n }\n this.content = content;\n if (this.material.map) {\n this.material.map.dispose();\n }\n const { texture, width, height } = THREECanvasTextTexture(content, {\n bold: true,\n fontSize: this.config.fontSize * fontScale,\n paddingPx: this.config.padding,\n textColorRGB255A1: {\n r: this.config.fontColor.r * 255,\n g: this.config.fontColor.g * 255,\n b: this.config.fontColor.b * 255,\n a: 1.0,\n },\n backgroundColorRGB255A1: {\n r: this.config.color.r * 255,\n g: this.config.color.g * 255,\n b: this.config.color.b * 255,\n a: 1.0,\n },\n alignment: this.config.alignment,\n dimensions:\n this.config.maxWidth !== undefined\n ? {\n maxWidth: this.config.maxWidth,\n }\n : undefined,\n });\n\n this.material.map = texture;\n this.material.map.magFilter = LinearFilter;\n this.material.map.minFilter = LinearFilter;\n this.material.needsUpdate = true;\n\n this.scale.x = width / (100 * fontScale);\n this.scale.y = height / (100 * fontScale);\n }\n\n setText(text: string, onRemove?: () => void) {\n const sanitizedText = text.replace(/(\\r\\n|\\n|\\r)/gm, \"\");\n this.visible = true;\n this.targetOpacity = this.config.visibleOpacity;\n if (this.hideTimeout) {\n clearTimeout(this.hideTimeout);\n this.hideTimeout = null;\n }\n if (this.config.secondsToFadeOut !== null) {\n this.hideTimeout = setTimeout(() => {\n this.hideTimeout = null;\n this.hide();\n if (onRemove) {\n onRemove();\n }\n }, this.config.secondsToFadeOut * 1000);\n }\n this.redrawText(sanitizedText);\n }\n\n hide() {\n this.targetOpacity = 0;\n }\n\n show() {\n this.setText(this.content || \"\");\n }\n\n update() {\n const opacity = this.material.opacity;\n if (opacity < this.targetOpacity) {\n this.material.opacity = Math.min(\n this.material.opacity + this.fadingSpeed,\n this.targetOpacity,\n );\n } else if (opacity > this.targetOpacity) {\n this.material.opacity = Math.max(\n this.material.opacity - this.fadingSpeed,\n this.targetOpacity,\n );\n if (opacity >= 1 && this.material.transparent) {\n this.material.transparent = false;\n this.material.needsUpdate = true;\n } else if (opacity > 0 && opacity < 1 && !this.material.transparent) {\n this.material.transparent = true;\n this.material.needsUpdate = true;\n }\n if (this.material.opacity <= 0) {\n this.visible = false;\n }\n }\n }\n}\n", "import { Texture, LinearFilter, RGBAFormat } from \"three\";\n\nexport type RGBA = {\n r: number;\n g: number;\n b: number;\n a: number;\n};\n\nexport type CanvasTextOptions = {\n fontSize: number;\n textColorRGB255A1: RGBA;\n backgroundColorRGB255A1?: RGBA;\n font?: string;\n bold?: boolean;\n paddingPx?: number;\n alignment?: string;\n dimensions?:\n | {\n maxWidth?: undefined;\n width: number;\n height: number;\n }\n | {\n maxWidth: number;\n };\n};\n\nfunction getTextAlignOffset(textAlign: CanvasTextAlign, width: number) {\n switch (textAlign) {\n case \"center\":\n return width / 2;\n case \"right\":\n return width;\n default:\n return 0;\n }\n}\n\nfunction printAtWordWrap(\n context: CanvasRenderingContext2D,\n fullText: string,\n textAlign: CanvasTextAlign,\n y: number,\n lineHeight: number,\n fitWidth: number,\n padding: number,\n) {\n const x = getTextAlignOffset(textAlign, fitWidth - padding * 2);\n const lines = fullText.split(\"\\n\");\n let currentLine = 0;\n for (const text of lines) {\n fitWidth = fitWidth || 0;\n\n if (fitWidth <= 0) {\n context.fillText(text, x, y + lineHeight * currentLine);\n currentLine++;\n continue;\n }\n let words = text.split(\" \");\n let lastWordIndex = 1;\n while (words.length > 0 && lastWordIndex <= words.length) {\n const str = words.slice(0, lastWordIndex).join(\" \");\n const textWidth = context.measureText(str).width;\n if (textWidth + padding * 2 > fitWidth) {\n if (lastWordIndex === 1) {\n // Handle case where single word is too long\n const word = words[0];\n let charIndex = 1;\n while (charIndex < word.length) {\n const substring = word.substring(0, charIndex);\n const subWidth = context.measureText(substring).width;\n if (subWidth + padding * 2 > fitWidth) {\n if (charIndex === 1) charIndex = 2;\n context.fillText(\n word.substring(0, charIndex - 1),\n x + padding,\n y + lineHeight * currentLine + padding,\n );\n currentLine++;\n words[0] = word.substring(charIndex - 1);\n break;\n }\n charIndex++;\n }\n if (charIndex >= word.length) {\n lastWordIndex = 2;\n } else {\n continue;\n }\n }\n context.fillText(\n words.slice(0, lastWordIndex - 1).join(\" \"),\n x + padding,\n y + lineHeight * currentLine + padding,\n );\n currentLine++;\n words = words.splice(lastWordIndex - 1);\n lastWordIndex = 1;\n } else {\n lastWordIndex++;\n }\n }\n if (lastWordIndex > 0 && words.length > 0) {\n context.fillText(words.join(\" \"), x + padding, y + lineHeight * currentLine + padding);\n currentLine++;\n }\n }\n}\n\nexport class CanvasText {\n private canvas: HTMLCanvasElement;\n private context: CanvasRenderingContext2D;\n\n constructor() {\n this.canvas = document.createElement(\"canvas\");\n this.context = this.canvas.getContext(\"2d\") as CanvasRenderingContext2D;\n }\n\n public renderText(message: string, options: CanvasTextOptions): HTMLCanvasElement {\n const fontsize = options.fontSize;\n const textColor = options.textColorRGB255A1;\n const backgroundColor = options.backgroundColorRGB255A1 || { r: 255, g: 255, b: 255, a: 1 };\n const padding = options.paddingPx || 0;\n const font = options.font || \"Arial\";\n const fontString = (options.bold ? \"bold \" : \"\") + fontsize + \"px \" + font;\n\n // calculate text alignment offset\n const textAlign = (options.alignment as CanvasTextAlign) ?? \"left\";\n\n if (options.dimensions && options.dimensions.maxWidth === undefined) {\n // NOTE: setting the canvas dimensions resets the context properties, so\n // we always do it first\n this.canvas.width = options.dimensions.width;\n this.canvas.height = options.dimensions.height;\n this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n this.context.font = fontString;\n this.context.textAlign = textAlign;\n this.context.fillStyle = `rgba(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b}, ${backgroundColor.a})`;\n this.context.lineWidth = 0;\n this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);\n this.context.fillStyle = `rgba(${textColor.r}, ${textColor.g}, ${textColor.b}, ${textColor.a})`;\n printAtWordWrap(\n this.context,\n message,\n textAlign,\n fontsize,\n fontsize,\n this.canvas.width,\n padding,\n );\n return this.canvas;\n } else {\n this.context.font = fontString;\n this.context.textAlign = textAlign;\n const metrics = this.context.measureText(message);\n const textWidth = metrics.width;\n const textHeight = metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent;\n\n if (options.dimensions && options.dimensions.maxWidth !== undefined) {\n const maxWidthWithoutPadding = options.dimensions.maxWidth - padding * 2;\n if (textWidth > maxWidthWithoutPadding) {\n // This is multiple lines - estimate the lines\n const lineCount = Math.ceil(textWidth / maxWidthWithoutPadding);\n this.canvas.width = options.dimensions.maxWidth;\n this.canvas.height = textHeight * lineCount + padding * 2;\n this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n this.context.font = fontString;\n this.context.textAlign = textAlign;\n this.context.fillStyle = `rgba(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b}, ${backgroundColor.a})`;\n this.context.lineWidth = 0;\n this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);\n this.context.fillStyle = `rgba(${textColor.r}, ${textColor.g}, ${textColor.b}, ${textColor.a})`;\n printAtWordWrap(\n this.context,\n message,\n textAlign,\n fontsize,\n fontsize,\n this.canvas.width,\n padding,\n );\n return this.canvas;\n } else {\n // Allow the text to be rendered as a single line (below)\n }\n }\n\n // NOTE: setting the this.canvas dimensions resets the context properties, so\n // we always do it first. However, we also need to take into account the\n // font size to measure the text in the first place.\n this.canvas.width = textWidth + padding * 2;\n this.canvas.height = textHeight + padding * 2;\n this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n this.context.font = fontString;\n this.context.textAlign = textAlign;\n this.context.fillStyle = `rgba(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b}, ${backgroundColor.a})`;\n this.context.lineWidth = 0;\n this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);\n this.context.fillStyle = `rgba(${textColor.r}, ${textColor.g}, ${textColor.b}, ${textColor.a})`;\n this.context.fillText(\n message,\n padding + getTextAlignOffset(textAlign, textWidth),\n textHeight,\n );\n }\n\n return this.canvas;\n }\n}\n\nexport function THREECanvasTextTexture(\n text: string,\n options: CanvasTextOptions,\n): { texture: Texture; width: number; height: number } {\n const canvas = new CanvasText().renderText(text, options);\n const texture = new Texture(canvas);\n texture.minFilter = LinearFilter;\n texture.magFilter = LinearFilter;\n texture.format = RGBAFormat;\n texture.needsUpdate = true;\n\n return { texture, width: canvas.width, height: canvas.height };\n}\n", "import { PositionAndRotation } from \"@mml-io/mml-web\";\nimport { Euler, Group, Quaternion, Vector3 } from \"three\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\nimport { CollisionsManager } from \"../collisions/CollisionsManager\";\nimport { KeyInputManager } from \"../input/KeyInputManager\";\nimport { VirtualJoystick } from \"../input/VirtualJoystick\";\nimport { Composer } from \"../rendering/composer\";\nimport { TimeManager } from \"../time/TimeManager\";\nimport { TweakPane } from \"../tweakpane/TweakPane\";\n\nimport { AnimationConfig, Character, CharacterDescription } from \"./Character\";\nimport { CharacterModelLoader } from \"./CharacterModelLoader\";\nimport { AnimationState, CharacterState } from \"./CharacterState\";\nimport { LocalController } from \"./LocalController\";\nimport { RemoteController } from \"./RemoteController\";\nimport { encodeCharacterAndCamera } from \"./url-position\";\n\nexport type CharacterManagerConfig = {\n composer: Composer;\n characterModelLoader: CharacterModelLoader;\n collisionsManager: CollisionsManager;\n cameraManager: CameraManager;\n timeManager: TimeManager;\n keyInputManager: KeyInputManager;\n virtualJoystick?: VirtualJoystick;\n remoteUserStates: Map<number, CharacterState>;\n sendUpdate: (update: CharacterState) => void;\n animationConfig: AnimationConfig;\n characterResolve: (clientId: number) => {\n username: string;\n characterDescription: CharacterDescription;\n };\n updateURLLocation?: boolean;\n};\n\nexport class CharacterManager {\n public readonly headTargetOffset = new Vector3(0, 1.3, 0);\n\n private localClientId: number = 0;\n\n public remoteCharacters: Map<number, Character> = new Map();\n public remoteCharacterControllers: Map<number, RemoteController> = new Map();\n\n private localCharacterSpawned: boolean = false;\n public localController: LocalController;\n public localCharacter: Character | null = null;\n\n private speakingCharacters: Map<number, boolean> = new Map();\n\n public readonly group: Group;\n private lastUpdateSentTime: number = 0;\n\n constructor(private config: CharacterManagerConfig) {\n this.group = new Group();\n }\n\n public spawnLocalCharacter(\n id: number,\n username: string,\n characterDescription: CharacterDescription,\n spawnPosition: Vector3 = new Vector3(),\n spawnRotation: Euler = new Euler(),\n ) {\n const character = new Character({\n username,\n characterDescription,\n animationConfig: this.config.animationConfig,\n characterModelLoader: this.config.characterModelLoader,\n characterId: id,\n modelLoadedCallback: () => {\n // character loaded callback\n },\n cameraManager: this.config.cameraManager,\n composer: this.config.composer,\n isLocal: true,\n });\n const quaternion = new Quaternion().setFromEuler(character.rotation);\n this.config.sendUpdate({\n id: id,\n position: {\n x: spawnPosition.x,\n y: spawnPosition.y,\n z: spawnPosition.z,\n },\n rotation: { quaternionY: quaternion.y, quaternionW: quaternion.w },\n state: AnimationState.idle,\n });\n this.localClientId = id;\n this.localCharacter = character;\n this.localController = new LocalController({\n character: this.localCharacter,\n id: this.localClientId,\n collisionsManager: this.config.collisionsManager,\n keyInputManager: this.config.keyInputManager,\n virtualJoystick: this.config.virtualJoystick,\n cameraManager: this.config.cameraManager,\n timeManager: this.config.timeManager,\n });\n this.localCharacter.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);\n this.localCharacter.rotation.set(spawnRotation.x, spawnRotation.y, spawnRotation.z);\n this.group.add(character);\n this.localCharacterSpawned = true;\n }\n\n public setupTweakPane(tweakPane: TweakPane) {\n tweakPane.setupCharacterController(this.localController);\n }\n\n public spawnRemoteCharacter(\n id: number,\n username: string,\n characterDescription: CharacterDescription,\n spawnPosition: Vector3 = new Vector3(),\n spawnRotation: Euler = new Euler(),\n ) {\n const character = new Character({\n username,\n characterDescription,\n animationConfig: this.config.animationConfig,\n characterModelLoader: this.config.characterModelLoader,\n characterId: id,\n modelLoadedCallback: () => {\n // character loaded callback\n },\n cameraManager: this.config.cameraManager,\n composer: this.config.composer,\n isLocal: false,\n });\n\n this.remoteCharacters.set(id, character);\n character.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);\n character.rotation.set(spawnRotation.x, spawnRotation.y, spawnRotation.z);\n const remoteController = new RemoteController({ character, id });\n this.remoteCharacterControllers.set(id, remoteController);\n this.group.add(character);\n }\n\n public getLocalCharacterPositionAndRotation(): PositionAndRotation {\n if (this.localCharacter && this.localCharacter && this.localCharacter) {\n return {\n position: this.localCharacter.position,\n rotation: this.localCharacter.rotation,\n };\n }\n return {\n position: { x: 0, y: 0, z: 0 },\n rotation: { x: 0, y: 0, z: 0 },\n };\n }\n\n public clear() {\n for (const [id, character] of this.remoteCharacters) {\n this.group.remove(character);\n this.remoteCharacters.delete(id);\n this.remoteCharacterControllers.delete(id);\n }\n if (this.localCharacter) {\n this.group.remove(this.localCharacter);\n this.localCharacter = null;\n }\n }\n\n public setSpeakingCharacter(id: number, value: boolean) {\n this.speakingCharacters.set(id, value);\n }\n\n public addSelfChatBubble(message: string) {\n if (this.localCharacter) {\n this.localCharacter.addChatBubble(message);\n }\n }\n\n public addChatBubble(id: number, message: string) {\n this.remoteCharacters.get(id)?.addChatBubble(message);\n }\n\n public respawnIfPresent(id: number) {\n const characterInfo = this.config.characterResolve(id);\n\n if (this.localCharacter && this.localClientId == id) {\n this.localCharacter.updateCharacter(\n characterInfo.username,\n characterInfo.characterDescription,\n );\n }\n\n const remoteCharacter = this.remoteCharacters.get(id);\n if (remoteCharacter) {\n remoteCharacter.updateCharacter(characterInfo.username, characterInfo.characterDescription);\n }\n }\n\n public update() {\n if (this.localCharacter) {\n this.localCharacter.update(this.config.timeManager.time, this.config.timeManager.deltaTime);\n if (this.speakingCharacters.has(this.localClientId)) {\n this.localCharacter.speakingIndicator?.setSpeaking(\n this.speakingCharacters.get(this.localClientId)!,\n );\n }\n\n this.localController.update();\n const currentTime = new Date().getTime();\n const timeSinceLastUpdate = currentTime - this.lastUpdateSentTime;\n if (timeSinceLastUpdate > 30) {\n // Limit updates to per 30ms\n this.lastUpdateSentTime = currentTime;\n this.config.sendUpdate(this.localController.networkState);\n }\n\n const targetOffset = new Vector3();\n targetOffset\n .add(this.headTargetOffset)\n .applyQuaternion(this.localCharacter.quaternion)\n .add(this.localCharacter.position);\n this.config.cameraManager.setTarget(targetOffset);\n\n for (const [id, update] of this.config.remoteUserStates) {\n if (this.remoteCharacters.has(id) && this.speakingCharacters.has(id)) {\n const character = this.remoteCharacters.get(id);\n character?.speakingIndicator?.setSpeaking(this.speakingCharacters.get(id)!);\n }\n const { position } = update;\n\n if (!this.remoteCharacters.has(id) && this.localCharacterSpawned === true) {\n const characterInfo = this.config.characterResolve(id);\n this.spawnRemoteCharacter(\n id,\n characterInfo.username,\n characterInfo.characterDescription,\n new Vector3(position.x, position.y, position.z),\n );\n }\n\n const characterController = this.remoteCharacterControllers.get(id);\n if (characterController) {\n characterController.update(\n update,\n this.config.timeManager.time,\n this.config.timeManager.deltaTime,\n );\n }\n }\n\n for (const [id, character] of this.remoteCharacters) {\n if (!this.config.remoteUserStates.has(id)) {\n character.speakingIndicator?.dispose();\n this.group.remove(character);\n this.remoteCharacters.delete(id);\n this.remoteCharacterControllers.delete(id);\n }\n }\n\n if (\n this.config.updateURLLocation &&\n this.config.timeManager.frame % 60 === 0 &&\n document.hasFocus() &&\n /*\n Don't update the URL if the camera is being controlled as some browsers (e.g. Chrome) cause a hitch to Pointer\n events when the url is updated\n */\n !this.config.cameraManager.hasActiveInput()\n ) {\n const hash = encodeCharacterAndCamera(\n this.localCharacter,\n this.config.cameraManager.camera,\n );\n const url = new URL(window.location.href);\n url.hash = hash;\n window.history.replaceState({}, \"\", url);\n }\n }\n }\n}\n", "import { Euler, Line3, Matrix4, Quaternion, Ray, Raycaster, Vector3 } from \"three\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\nimport { CollisionMeshState, CollisionsManager } from \"../collisions/CollisionsManager\";\nimport { KeyInputManager } from \"../input/KeyInputManager\";\nimport { VirtualJoystick } from \"../input/VirtualJoystick\";\nimport { TimeManager } from \"../time/TimeManager\";\nimport { characterControllerValues } from \"../tweakpane/blades/characterControlsFolder\";\n\nimport { Character } from \"./Character\";\nimport { AnimationState, CharacterState } from \"./CharacterState\";\n\nconst downVector = new Vector3(0, -1, 0);\n\nexport type LocalControllerConfig = {\n id: number;\n character: Character;\n collisionsManager: CollisionsManager;\n keyInputManager: KeyInputManager;\n virtualJoystick?: VirtualJoystick;\n cameraManager: CameraManager;\n timeManager: TimeManager;\n};\n\nexport class LocalController {\n public capsuleInfo = {\n radius: 0.4,\n segment: new Line3(new Vector3(), new Vector3(0, 1.05, 0)),\n };\n\n public gravity: number = -characterControllerValues.gravity;\n public jumpForce: number = characterControllerValues.jumpForce;\n public doubleJumpForce: number = characterControllerValues.doubleJumpForce;\n public coyoteTimeThreshold: number = characterControllerValues.coyoteJump;\n public canJump: boolean = true;\n public canDoubleJump: boolean = true;\n public coyoteJumped = false;\n public doubleJumpUsed: boolean = false;\n public jumpCounter: number = 0;\n\n public airResistance = characterControllerValues.airResistance;\n public groundResistance = 0.99999999 + characterControllerValues.groundResistance * 1e-7;\n public airControlModifier = characterControllerValues.airControlModifier;\n public groundWalkControl = characterControllerValues.groundWalkControl;\n public groundRunControl = characterControllerValues.groundRunControl;\n public baseControl = characterControllerValues.baseControlMultiplier;\n public minimumSurfaceAngle = characterControllerValues.minimumSurfaceAngle;\n\n public latestPosition: Vector3 = new Vector3();\n public characterOnGround: boolean = false;\n public coyoteTime: boolean = false;\n\n private collisionDetectionSteps = 15;\n\n private characterWasOnGround: boolean = false;\n private characterAirborneSince: number = 0;\n private currentHeight: number = 0;\n private currentSurfaceAngle = new Vector3();\n\n private characterVelocity: Vector3 = new Vector3();\n private vectorUp: Vector3 = new Vector3(0, 1, 0);\n private vectorDown: Vector3 = new Vector3(0, -1, 0);\n\n private rotationOffset: number = 0;\n private azimuthalAngle: number = 0;\n\n private tempMatrix: Matrix4 = new Matrix4();\n private tempSegment: Line3 = new Line3();\n private tempQuaternion: Quaternion = new Quaternion();\n private tempEuler: Euler = new Euler();\n private tempVector: Vector3 = new Vector3();\n private tempVector2: Vector3 = new Vector3();\n private tempVector3: Vector3 = new Vector3();\n private rayCaster: Raycaster = new Raycaster();\n\n private surfaceTempQuaternion = new Quaternion();\n private surfaceTempQuaternion2 = new Quaternion();\n private surfaceTempVector1 = new Vector3();\n private surfaceTempVector2 = new Vector3();\n private surfaceTempVector3 = new Vector3();\n private surfaceTempVector4 = new Vector3();\n private surfaceTempVector5 = new Vector3();\n private surfaceTempRay = new Ray();\n private lastFrameSurfaceState:\n | [\n CollisionMeshState,\n {\n lastMatrix: Matrix4;\n },\n ]\n | null = null;\n\n public jumpPressed: boolean = false; // Tracks if the jump button is pressed\n public jumpReleased: boolean = true; // Indicates if the jump button has been released\n\n public networkState: CharacterState;\n private controlState: { direction: number | null; isSprinting: boolean; jump: boolean } | null =\n null;\n\n constructor(private config: LocalControllerConfig) {\n this.networkState = {\n id: this.config.id,\n position: { x: 0, y: 0, z: 0 },\n rotation: { quaternionY: 0, quaternionW: 1 },\n state: AnimationState.idle,\n };\n }\n\n public update(): void {\n this.controlState =\n this.config.keyInputManager.getOutput() || this.config.virtualJoystick?.getOutput() || null;\n\n this.rayCaster.set(this.config.character.position, this.vectorDown);\n const firstRaycastHit = this.config.collisionsManager.raycastFirst(this.rayCaster.ray);\n if (firstRaycastHit !== null) {\n this.currentHeight = firstRaycastHit[0];\n this.currentSurfaceAngle.copy(firstRaycastHit[1]);\n }\n\n if (this.controlState?.direction !== null || !this.characterOnGround) {\n const targetAnimation = this.getTargetAnimation();\n this.config.character.updateAnimation(targetAnimation);\n } else {\n this.config.character.updateAnimation(AnimationState.idle);\n }\n\n if (this.controlState) {\n this.updateRotation();\n }\n\n for (let i = 0; i < this.collisionDetectionSteps; i++) {\n this.updatePosition(\n this.config.timeManager.deltaTime,\n this.config.timeManager.deltaTime / this.collisionDetectionSteps,\n i,\n );\n }\n\n // Allow the user to fall far below zero before resetting\n // TODO - Might want to make this a configurable value\n if (this.config.character.position.y < -100) {\n this.resetPosition();\n }\n this.updateNetworkState();\n }\n\n private getTargetAnimation(): AnimationState {\n if (!this.config.character) return AnimationState.idle;\n\n const jumpHeight = this.characterVelocity.y > 0 ? 0.2 : 1.8;\n if (this.currentHeight > jumpHeight && !this.characterOnGround) {\n if (this.doubleJumpUsed) {\n return AnimationState.doubleJump;\n }\n return AnimationState.air;\n }\n if (!this.controlState) {\n return AnimationState.idle;\n }\n\n if (this.controlState.isSprinting) {\n return AnimationState.running;\n }\n\n return AnimationState.walking;\n }\n\n private updateRotationOffset(): void {\n if (this.controlState && this.controlState.direction !== null) {\n this.rotationOffset = this.controlState.direction;\n }\n }\n\n private updateAzimuthalAngle(): void {\n const camToModelDistance = this.config.cameraManager.activeCamera.position.distanceTo(\n this.config.character.position,\n );\n const isCameraFirstPerson = camToModelDistance < 2;\n if (isCameraFirstPerson) {\n const cameraForward = this.tempVector\n .set(0, 0, 1)\n .applyQuaternion(this.config.cameraManager.activeCamera.quaternion);\n this.azimuthalAngle = Math.atan2(cameraForward.x, cameraForward.z);\n } else {\n this.azimuthalAngle = Math.atan2(\n this.config.cameraManager.activeCamera.position.x - this.config.character.position.x,\n this.config.cameraManager.activeCamera.position.z - this.config.character.position.z,\n );\n }\n }\n\n private computeAngularDifference(rotationQuaternion: Quaternion): number {\n return 2 * Math.acos(Math.abs(this.config.character.quaternion.dot(rotationQuaternion)));\n }\n\n private updateRotation(): void {\n this.updateRotationOffset();\n this.updateAzimuthalAngle();\n const rotationQuaternion = this.tempQuaternion.setFromAxisAngle(\n this.vectorUp,\n this.azimuthalAngle + this.rotationOffset,\n );\n const angularDifference = this.computeAngularDifference(rotationQuaternion);\n const desiredTime = 0.07;\n const angularSpeed = angularDifference / desiredTime;\n const frameRotation = angularSpeed * this.config.timeManager.deltaTime;\n this.config.character.quaternion.rotateTowards(rotationQuaternion, frameRotation);\n }\n\n private processJump(currentAcceleration: Vector3, deltaTime: number) {\n const jump = this.controlState?.jump;\n\n if (this.characterOnGround) {\n this.coyoteJumped = false;\n this.canDoubleJump = false;\n this.doubleJumpUsed = false;\n this.jumpCounter = 0;\n\n if (!jump) {\n this.canDoubleJump = !this.doubleJumpUsed && this.jumpReleased && this.jumpCounter === 1;\n this.canJump = true;\n this.jumpReleased = true;\n }\n\n if (jump && this.canJump && this.jumpReleased) {\n currentAcceleration.y += this.jumpForce / deltaTime;\n this.canJump = false;\n this.jumpReleased = false;\n this.jumpCounter++;\n } else {\n if (this.currentSurfaceAngle.y < this.minimumSurfaceAngle) {\n currentAcceleration.y += this.gravity;\n }\n }\n } else {\n if (jump && !this.coyoteJumped && this.coyoteTime) {\n this.coyoteJumped = true;\n currentAcceleration.y += this.jumpForce / deltaTime;\n this.canJump = false;\n this.jumpReleased = false;\n this.jumpCounter++;\n } else if (jump && this.canDoubleJump) {\n currentAcceleration.y += this.doubleJumpForce / deltaTime;\n this.doubleJumpUsed = true;\n this.jumpReleased = false;\n this.jumpCounter++;\n } else {\n currentAcceleration.y += this.gravity;\n this.canJump = false;\n }\n }\n\n if (!jump) {\n this.jumpReleased = true;\n if (!this.characterOnGround) {\n currentAcceleration.y += this.gravity;\n }\n }\n }\n\n private applyControls(deltaTime: number) {\n const resistance = this.characterOnGround ? this.groundResistance : this.airResistance;\n\n // Dampen the velocity based on the resistance\n const speedFactor = Math.pow(1 - resistance, deltaTime);\n this.characterVelocity.multiplyScalar(speedFactor);\n\n const acceleration = this.tempVector.set(0, 0, 0);\n this.canDoubleJump = !this.doubleJumpUsed && this.jumpReleased && this.jumpCounter === 1;\n this.processJump(acceleration, deltaTime);\n\n const control =\n (this.characterOnGround\n ? this.controlState?.isSprinting\n ? this.groundRunControl\n : this.groundWalkControl\n : this.airControlModifier) * this.baseControl;\n\n const controlAcceleration = this.tempVector2.set(0, 0, 0);\n\n if (this.controlState && this.controlState.direction !== null) {\n // convert heading to direction vector\n const heading = this.controlState.direction;\n const headingVector = this.tempVector3\n .set(0, 0, 1)\n .applyAxisAngle(this.vectorUp, this.azimuthalAngle + heading);\n controlAcceleration.add(headingVector);\n }\n if (controlAcceleration.length() > 0) {\n controlAcceleration.normalize();\n controlAcceleration.multiplyScalar(control);\n }\n acceleration.add(controlAcceleration);\n this.characterVelocity.addScaledVector(acceleration, deltaTime);\n\n this.config.character.position.addScaledVector(this.characterVelocity, deltaTime);\n }\n\n private updatePosition(deltaTime: number, stepDeltaTime: number, iter: number): void {\n this.applyControls(stepDeltaTime);\n\n if (iter === 0) {\n const lastMovement = this.getMovementFromSurfaces(this.config.character.position, deltaTime);\n if (lastMovement) {\n this.config.character.position.add(lastMovement.position);\n const asQuaternion = this.tempQuaternion.setFromEuler(this.config.character.rotation);\n const lastMovementEuler = this.tempEuler.setFromQuaternion(lastMovement.rotation);\n lastMovementEuler.x = 0;\n lastMovementEuler.z = 0;\n lastMovement.rotation.setFromEuler(lastMovementEuler);\n asQuaternion.multiply(lastMovement.rotation);\n this.config.character.rotation.setFromQuaternion(asQuaternion);\n }\n }\n this.config.character.updateMatrixWorld();\n\n const avatarSegment = this.tempSegment;\n avatarSegment.copy(this.capsuleInfo.segment!);\n avatarSegment.start\n .applyMatrix4(this.config.character.matrixWorld)\n .applyMatrix4(this.tempMatrix);\n avatarSegment.end.applyMatrix4(this.config.character.matrixWorld).applyMatrix4(this.tempMatrix);\n\n const positionBeforeCollisions = this.tempVector.copy(avatarSegment.start);\n this.config.collisionsManager.applyColliders(avatarSegment, this.capsuleInfo.radius!);\n this.config.character.position.copy(avatarSegment.start);\n const deltaCollisionPosition = avatarSegment.start.sub(positionBeforeCollisions);\n\n this.characterOnGround = deltaCollisionPosition.y > 0;\n\n if (this.characterOnGround) {\n this.doubleJumpUsed = false;\n this.jumpCounter = 0;\n }\n\n if (this.characterWasOnGround && !this.characterOnGround) {\n this.characterAirborneSince = Date.now();\n }\n\n if (!this.controlState?.jump) {\n this.jumpReleased = true;\n }\n\n this.coyoteTime =\n this.characterVelocity.y < 0 &&\n !this.characterOnGround &&\n Date.now() - this.characterAirborneSince < this.coyoteTimeThreshold;\n\n this.latestPosition = this.config.character.position.clone();\n this.characterWasOnGround = this.characterOnGround;\n }\n\n public getMovementFromSurfaces(userPosition: Vector3, deltaTime: number) {\n let lastMovement: { rotation: Quaternion; position: Vector3 } | null = null;\n\n // If we have a last frame state, we can calculate the movement of the mesh to apply it to the user\n if (this.lastFrameSurfaceState !== null) {\n const meshState = this.lastFrameSurfaceState[0];\n\n // Extract the matrix from the current frame and the last frame\n const currentFrameMatrix = meshState.matrix;\n const lastFrameMatrix = this.lastFrameSurfaceState[1].lastMatrix;\n\n if (lastFrameMatrix.equals(currentFrameMatrix)) {\n // No movement from this mesh - do nothing\n } else {\n // The mesh has moved since the last frame - calculate the movement\n\n // Get the position of the mesh in the last frame\n const lastMeshPosition = this.surfaceTempVector1;\n const lastMeshRotation = this.surfaceTempQuaternion;\n lastFrameMatrix.decompose(lastMeshPosition, lastMeshRotation, this.surfaceTempVector3);\n\n // Get the position of the mesh in the current frame\n const currentMeshPosition = this.surfaceTempVector2;\n const currentMeshRotation = this.surfaceTempQuaternion2;\n currentFrameMatrix.decompose(\n currentMeshPosition,\n currentMeshRotation,\n this.surfaceTempVector3,\n );\n\n // Calculate the difference between the new position and the old position to determine the movement due to translation of position\n const meshTranslationDelta = this.surfaceTempVector5\n .copy(currentMeshPosition)\n .sub(lastMeshPosition);\n\n // Calculate the relative position of the user to the mesh in the last frame\n const lastFrameRelativeUserPosition = this.surfaceTempVector3\n .copy(userPosition)\n .sub(lastMeshPosition);\n\n // Calculate the relative quaternion of the mesh in the last frame to the mesh in the current frame\n const meshRotationDelta = lastMeshRotation.invert().multiply(currentMeshRotation);\n\n // Apply the relative quaternion to the relative user position to determine the new position of the user given just the rotation\n const translationDueToRotation = this.surfaceTempVector4\n .copy(lastFrameRelativeUserPosition)\n .applyQuaternion(meshRotationDelta)\n .sub(lastFrameRelativeUserPosition);\n\n // Combine the mesh translation delta and the rotation translation delta to determine the total movement of the user\n const translationAndRotationPositionDelta = this.surfaceTempVector1\n .copy(meshTranslationDelta)\n .add(translationDueToRotation);\n\n lastMovement = {\n position: translationAndRotationPositionDelta,\n rotation: meshRotationDelta,\n };\n lastFrameMatrix.copy(currentFrameMatrix);\n }\n }\n\n const newPosition = this.surfaceTempVector3.copy(userPosition);\n if (lastMovement) {\n newPosition.add(lastMovement.position);\n }\n newPosition.setY(newPosition.y + 0.05);\n\n // Raycast down from the new position to see if there is a surface below the user which will be tracked in the next frame\n const ray = this.surfaceTempRay.set(newPosition, downVector);\n const hit = this.config.collisionsManager.raycastFirst(ray);\n if (hit && hit[0] < 0.8) {\n // There is a surface below the user\n const currentCollisionMeshState = hit[2];\n this.lastFrameSurfaceState = [\n currentCollisionMeshState,\n { lastMatrix: currentCollisionMeshState.matrix.clone() },\n ];\n } else {\n if (this.lastFrameSurfaceState !== null && lastMovement) {\n // Apply the last movement to the user's velocity\n this.characterVelocity.add(\n lastMovement.position.clone().divideScalar(deltaTime), // The position delta is the result of one tick which is deltaTime seconds, so we need to divide by deltaTime to get the velocity per second\n );\n }\n this.lastFrameSurfaceState = null;\n }\n return lastMovement;\n }\n\n private updateNetworkState(): void {\n const characterQuaternion = this.config.character.getWorldQuaternion(this.tempQuaternion);\n const cameraQuaternion = new Quaternion();\n this.config.cameraManager.camera.getWorldQuaternion(cameraQuaternion);\n this.networkState = {\n id: this.config.id,\n position: {\n x: this.config.character.position.x,\n y: this.config.character.position.y,\n z: this.config.character.position.z,\n },\n rotation: { quaternionY: characterQuaternion.y, quaternionW: characterQuaternion.w },\n camPosition: {\n x: this.config.cameraManager.camera.position.x,\n y: this.config.cameraManager.camera.position.y,\n z: this.config.cameraManager.camera.position.z,\n },\n camQuaternion: {\n y: cameraQuaternion.y,\n w: cameraQuaternion.w,\n },\n state: this.config.character.getCurrentAnimation(),\n };\n }\n\n private resetPosition(): void {\n this.characterVelocity.y = 0;\n this.config.character.position.y = 3;\n this.characterOnGround = false;\n this.doubleJumpUsed = false;\n this.jumpReleased = true;\n this.jumpCounter = 0;\n }\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { BladeApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nimport { LocalController } from \"../../character/LocalController\";\n\nexport const characterControllerValues = {\n gravity: 35.5,\n jumpForce: 18,\n doubleJumpForce: 17.7,\n coyoteJump: 120,\n airResistance: 0.5,\n groundResistance: 0,\n airControlModifier: 0.05,\n groundWalkControl: 0.75,\n groundRunControl: 1.0,\n baseControlMultiplier: 200,\n minimumSurfaceAngle: 0.905,\n};\n\nexport const characterControllerOptions = {\n gravity: { min: 1, max: 100, step: 0.05 },\n jumpForce: { min: 1, max: 50, step: 0.05 },\n doubleJumpForce: { min: 1, max: 50, step: 0.05 },\n coyoteJump: { min: 60, max: 200, step: 1 },\n airResistance: { min: 0.01, max: 0.9, step: 0.01 },\n groundResistance: { min: -100, max: 0, step: 1 },\n airControlModifier: { min: 0.001, max: 0.15, step: 0.01 },\n groundWalkControl: { min: 0.1, max: 1.5, step: 0.01 },\n groundRunControl: { min: 0.5, max: 2.0, step: 0.01 },\n baseControlMultiplier: { min: 150, max: 300, step: 1 },\n minimumSurfaceAngle: { min: 0.254, max: 1, step: 0.001 },\n};\n\ntype CharacterData = {\n position: string;\n onGround: string;\n canJump: string;\n canDoubleJump: string;\n jumpCount: string;\n coyoteTime: string;\n coyoteJumped: string;\n};\n\nexport class CharacterControlsFolder {\n public folder: FolderApi;\n\n private characterData: CharacterData = {\n position: \"(0, 0, 0)\",\n onGround: \"false\",\n canJump: \"false\",\n canDoubleJump: \"false\",\n jumpCount: \"0\",\n coyoteTime: \"false\",\n coyoteJumped: \"false\",\n };\n\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({ title: \"character\", expanded: expand });\n this.folder.addBinding(this.characterData, \"position\", { readonly: true });\n this.folder.addBinding(this.characterData, \"onGround\", { readonly: true });\n this.folder.addBinding(this.characterData, \"canJump\", { readonly: true });\n this.folder.addBinding(this.characterData, \"canDoubleJump\", { readonly: true });\n this.folder.addBinding(this.characterData, \"jumpCount\", { readonly: true });\n this.folder.addBinding(this.characterData, \"coyoteTime\", { readonly: true });\n this.folder.addBinding(this.characterData, \"coyoteJumped\", { readonly: true });\n this.folder.addBinding(\n characterControllerValues,\n \"gravity\",\n characterControllerOptions.gravity,\n );\n this.folder.addBinding(\n characterControllerValues,\n \"jumpForce\",\n characterControllerOptions.jumpForce,\n );\n this.folder.addBinding(\n characterControllerValues,\n \"doubleJumpForce\",\n characterControllerOptions.doubleJumpForce,\n );\n this.folder.addBinding(\n characterControllerValues,\n \"coyoteJump\",\n characterControllerOptions.coyoteJump,\n );\n this.folder.addBinding(\n characterControllerValues,\n \"airResistance\",\n characterControllerOptions.airResistance,\n );\n this.folder.addBinding(\n characterControllerValues,\n \"groundResistance\",\n characterControllerOptions.groundResistance,\n );\n this.folder.addBinding(\n characterControllerValues,\n \"airControlModifier\",\n characterControllerOptions.airControlModifier,\n );\n this.folder.addBinding(\n characterControllerValues,\n \"groundWalkControl\",\n characterControllerOptions.groundWalkControl,\n );\n this.folder.addBinding(\n characterControllerValues,\n \"groundRunControl\",\n characterControllerOptions.groundRunControl,\n );\n this.folder.addBinding(\n characterControllerValues,\n \"baseControlMultiplier\",\n characterControllerOptions.baseControlMultiplier,\n );\n this.folder.addBinding(\n characterControllerValues,\n \"minimumSurfaceAngle\",\n characterControllerOptions.minimumSurfaceAngle,\n );\n }\n\n public setupChangeEvent(localController: LocalController): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"gravity\": {\n const value = e.value as number;\n localController.gravity = value * -1;\n break;\n }\n case \"jumpForce\": {\n const value = e.value as number;\n localController.jumpForce = value;\n break;\n }\n case \"doubleJumpForce\": {\n const value = e.value as number;\n localController.doubleJumpForce = value;\n break;\n }\n case \"coyoteJump\": {\n const value = e.value as number;\n localController.coyoteTimeThreshold = value;\n break;\n }\n case \"airResistance\": {\n const value = e.value as number;\n localController.airResistance = value;\n break;\n }\n case \"groundResistance\": {\n const value = e.value as number;\n localController.groundResistance = 0.99999999 + value * 1e-6;\n break;\n }\n case \"airControlModifier\": {\n const value = e.value as number;\n localController.airControlModifier = value;\n break;\n }\n case \"groundWalkControl\": {\n const value = e.value as number;\n localController.groundWalkControl = value;\n break;\n }\n case \"groundRunControl\": {\n const value = e.value as number;\n localController.groundRunControl = value;\n break;\n }\n case \"baseControlMultiplier\": {\n const value = e.value as number;\n localController.baseControl = value;\n break;\n }\n case \"minimumSurfaceAngle\": {\n const value = e.value as number;\n localController.minimumSurfaceAngle = value;\n break;\n }\n default:\n break;\n }\n });\n }\n\n public update(localController: LocalController): void {\n const { x, y, z } = localController.latestPosition;\n this.characterData.position = `(${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)})`;\n this.characterData.onGround = `${localController.characterOnGround}`;\n this.characterData.canJump = `${localController.canJump || localController.coyoteTime ? \"true\" : \"false\"}`;\n this.characterData.canDoubleJump = `${localController.canDoubleJump}`;\n this.characterData.jumpCount = `${localController.jumpCounter}`;\n this.characterData.coyoteTime = `${localController.coyoteTime}`;\n this.characterData.coyoteJumped = `${localController.coyoteJumped}`;\n }\n}\n", "import { Quaternion, Vector3 } from \"three\";\n\nimport { Character } from \"./Character\";\nimport { AnimationState, CharacterState } from \"./CharacterState\";\n\nexport type RemoteControllerConfig = {\n id: number;\n character: Character;\n};\n\nconst tempQuaternion = new Quaternion();\n\nexport class RemoteController {\n public currentAnimation: AnimationState = AnimationState.idle;\n\n public networkState: CharacterState;\n\n constructor(private config: RemoteControllerConfig) {\n this.networkState = {\n id: this.config.id,\n position: {\n x: this.config.character.position.x,\n y: this.config.character.position.y,\n z: this.config.character.position.z,\n },\n rotation: {\n quaternionY: tempQuaternion.setFromEuler(this.config.character.rotation).y,\n quaternionW: 1,\n },\n state: this.currentAnimation as AnimationState,\n };\n }\n\n public update(clientUpdate: CharacterState, time: number, deltaTime: number): void {\n if (!this.config.character) {\n return;\n }\n this.updateFromNetwork(clientUpdate);\n this.config.character.update(time, deltaTime);\n }\n\n private updateFromNetwork(clientUpdate: CharacterState): void {\n const { position, rotation, state } = clientUpdate;\n this.config.character.position.lerp(new Vector3(position.x, position.y, position.z), 0.15);\n const rotationQuaternion = new Quaternion(0, rotation.quaternionY, 0, rotation.quaternionW);\n this.config.character.quaternion.slerp(rotationQuaternion, 0.6);\n if (state !== this.currentAnimation) {\n this.currentAnimation = state;\n this.config.character.updateAnimation(state);\n }\n }\n}\n", "import { Object3D, Quaternion, Vector3 } from \"three\";\n\nimport { toArray } from \"../helpers/math-helpers\";\n\nexport function encodeCharacterAndCamera(character: Object3D, camera: Object3D): string {\n return [\n ...toArray(character.position),\n ...toArray(character.quaternion),\n ...toArray(camera.position),\n ...toArray(camera.quaternion),\n ].join(\",\");\n}\n\nexport function decodeCharacterAndCamera(hash: string): {\n character: { position: Vector3; quaternion: Quaternion };\n camera: { position: Vector3; quaternion: Quaternion };\n} {\n const values = hash.split(\",\").map(Number);\n return {\n character: {\n position: new Vector3(values[0], values[1], values[2]),\n quaternion: new Quaternion(values[3], values[4], values[5], values[6]),\n },\n camera: {\n position: new Vector3(values[7], values[8], values[9]),\n quaternion: new Quaternion(values[10], values[11], values[12], values[13]),\n },\n };\n}\n", "import { ModelLoader, ModelLoadResult } from \"@mml-io/model-loader\";\nimport { AnimationClip, Object3D } from \"three\";\nimport { GLTF } from \"three/examples/jsm/loaders/GLTFLoader.js\";\n\nclass LRUCache<K, V> {\n private maxSize: number;\n private cache: Map<K, V>;\n\n constructor(maxSize: number = 100) {\n this.maxSize = maxSize;\n this.cache = new Map();\n }\n\n get(key: K): V | undefined {\n const item = this.cache.get(key);\n if (item) {\n this.cache.delete(key);\n this.cache.set(key, item);\n }\n return item;\n }\n\n set(key: K, value: V): void {\n if (this.cache.size >= this.maxSize) {\n const oldestKey = this.cache.keys().next().value;\n this.cache.delete(oldestKey);\n }\n this.cache.set(key, value);\n }\n}\n\ninterface CachedModel {\n blob: Blob;\n originalExtension: string;\n}\n\nexport class CharacterModelLoader {\n private readonly modelLoader: ModelLoader = new ModelLoader();\n private modelCache: LRUCache<string, CachedModel>;\n private ongoingLoads: Map<string, Promise<CachedModel>> = new Map();\n\n constructor(\n maxCacheSize: number = 100,\n private debug: boolean = false,\n ) {\n this.modelCache = new LRUCache(maxCacheSize);\n }\n\n async load(fileUrl: string, fileType: \"model\"): Promise<Object3D | undefined>;\n async load(fileUrl: string, fileType: \"animation\"): Promise<AnimationClip | undefined>;\n async load(\n fileUrl: string,\n fileType: \"model\" | \"animation\",\n ): Promise<Object3D | AnimationClip | undefined> {\n const cachedModel = this.modelCache.get(fileUrl);\n\n if (cachedModel) {\n return this.loadFromUrl(fileUrl, fileType, cachedModel.originalExtension);\n } else {\n if (this.debug === true) {\n console.log(`Loading ${fileUrl} from server`);\n }\n const ongoingLoad = this.ongoingLoads.get(fileUrl);\n if (ongoingLoad)\n return ongoingLoad.then((loadedModel) => {\n const blobURL = URL.createObjectURL(loadedModel.blob);\n return this.loadFromUrl(blobURL, fileType, loadedModel.originalExtension);\n });\n\n const loadPromise: Promise<CachedModel> = fetch(fileUrl)\n .then((response) => response.blob())\n .then((blob) => {\n const originalExtension = fileUrl.split(\".\").pop() || \"\";\n const cached = { blob, originalExtension };\n this.modelCache.set(fileUrl, cached);\n this.ongoingLoads.delete(fileUrl);\n return cached;\n });\n\n this.ongoingLoads.set(fileUrl, loadPromise);\n return loadPromise.then((loadedModel) => {\n const blobURL = URL.createObjectURL(loadedModel.blob);\n return this.loadFromUrl(blobURL, fileType, loadedModel.originalExtension);\n });\n }\n }\n\n private async loadFromUrl(\n url: string,\n fileType: \"model\" | \"animation\",\n extension: string,\n ): Promise<Object3D | AnimationClip | undefined> {\n return new Promise(async (resolve, reject) => {\n const modelLoadResult: ModelLoadResult = await this.modelLoader.load(\n url,\n (loaded: number, total: number) => {\n // no-op\n },\n );\n if (fileType === \"model\") {\n resolve(modelLoadResult.group as Object3D);\n } else if (fileType === \"animation\") {\n resolve(modelLoadResult.animations[0] as AnimationClip);\n } else {\n const error = `Trying to load unknown ${fileType} type of element from file ${url}`;\n console.error(error);\n reject(error);\n }\n });\n }\n}\n", "import { EventHandlerCollection } from \"./EventHandlerCollection\";\nimport { VirtualJoystick } from \"./VirtualJoystick\";\n\nexport enum Key {\n W = \"w\",\n A = \"a\",\n S = \"s\",\n D = \"d\",\n SHIFT = \"shift\",\n SPACE = \" \",\n C = \"c\",\n}\n\ntype KeyCallback = () => void;\ntype BindingsType = Map<Key, KeyCallback>;\n\nexport class KeyInputManager {\n private keys = new Map<string, boolean>();\n private eventHandlerCollection = new EventHandlerCollection();\n private bindings: BindingsType = new Map();\n\n constructor(private shouldCaptureKeyPress: () => boolean = () => true) {\n this.eventHandlerCollection.add(document, \"keydown\", this.onKeyDown.bind(this));\n this.eventHandlerCollection.add(document, \"keyup\", this.onKeyUp.bind(this));\n this.eventHandlerCollection.add(window, \"blur\", this.handleUnfocus.bind(this));\n }\n\n private handleUnfocus(_event: FocusEvent): void {\n this.keys.clear();\n }\n\n private onKeyDown(event: KeyboardEvent): void {\n if (this.shouldCaptureKeyPress()) {\n if (event.key.length === 2 && event.key[0] === \"F\") {\n // Ignore all Function keys\n return;\n }\n if (event.metaKey) {\n // Ignore all meta keys (e.g. Alt, Cmd)\n return;\n }\n this.keys.set(event.key.toLowerCase(), true);\n event.preventDefault();\n }\n }\n\n private onKeyUp(event: KeyboardEvent): void {\n this.keys.set(event.key.toLowerCase(), false);\n if (this.bindings.has(event.key.toLowerCase() as Key)) {\n this.bindings.get(event.key.toLowerCase() as Key)!();\n }\n }\n\n public isKeyPressed(key: string): boolean {\n return this.keys.get(key) || false;\n }\n\n public createKeyBinding(key: Key, callback: () => void): void {\n this.bindings.set(key, callback);\n }\n\n public isMovementKeyPressed(): boolean {\n return [Key.W, Key.A, Key.S, Key.D].some((key) => this.isKeyPressed(key));\n }\n\n private getForward(): boolean {\n return this.isKeyPressed(Key.W);\n }\n\n private getBackward(): boolean {\n return this.isKeyPressed(Key.S);\n }\n\n private getLeft(): boolean {\n return this.isKeyPressed(Key.A);\n }\n\n private getRight(): boolean {\n return this.isKeyPressed(Key.D);\n }\n\n private getRun(): boolean {\n return this.isKeyPressed(Key.SHIFT);\n }\n\n private getJump(): boolean {\n return this.isKeyPressed(Key.SPACE);\n }\n\n public getOutput(): { direction: number | null; isSprinting: boolean; jump: boolean } | null {\n const dx = (this.getRight() ? 1 : 0) - (this.getLeft() ? 1 : 0);\n const dy = (this.getBackward() ? 1 : 0) - (this.getForward() ? 1 : 0);\n const jump = this.getJump();\n if (dx === 0 && dy === 0) {\n if (this.getJump()) {\n return { direction: null, isSprinting: false, jump };\n }\n return null;\n }\n const direction = Math.atan2(dx, dy);\n return { direction, isSprinting: this.getRun(), jump };\n }\n\n public dispose() {\n this.eventHandlerCollection.clear();\n this.bindings.clear();\n }\n}\n", "interface VirtualJoyStickConfig {\n radius?: number;\n innerRadius?: number;\n mouseSupport?: boolean;\n}\n\nconst sprintingThreshold = 0.6;\n\nexport class VirtualJoystick {\n private radius: number;\n private innerRadius: number;\n private mouseSupport: boolean;\n\n private element: HTMLDivElement;\n\n private joystickBaseElement: HTMLSpanElement;\n private joystickCenterElement: HTMLSpanElement;\n private joystickPointerId: number | null = null;\n private joystickOutput: { direction: number; isSprinting: boolean } | null = null;\n\n private jumpButton: HTMLButtonElement;\n private jumpPointerId: number | null = null;\n\n constructor(\n private holderElement: HTMLElement,\n private config: VirtualJoyStickConfig,\n ) {\n this.radius = config.radius || 50;\n this.innerRadius = config.innerRadius || this.radius / 2;\n this.mouseSupport = this.checkTouch() || config.mouseSupport === true;\n\n this.element = document.createElement(\"div\");\n const style = this.element.style;\n style.display = this.mouseSupport ? \"flex\" : \"none\";\n style.position = \"absolute\";\n style.width = `100%`;\n style.height = `200px`;\n style.bottom = \"50px\";\n style.zIndex = \"10000\";\n style.alignItems = \"center\";\n style.justifyContent = \"space-between\";\n style.pointerEvents = \"none\";\n style.padding = \"20px\";\n style.boxSizing = \"border-box\";\n style.userSelect = \"none\";\n this.holderElement.appendChild(this.element);\n\n this.joystickBaseElement = this.createBase();\n this.element.appendChild(this.joystickBaseElement);\n\n this.joystickCenterElement = this.createCenter();\n this.joystickBaseElement.appendChild(this.joystickCenterElement);\n\n this.jumpButton = this.createJumpButton();\n this.element.appendChild(this.jumpButton);\n\n this.bindEvents();\n\n this.clearJoystickState();\n }\n\n public static checkForTouch(): boolean {\n try {\n document.createEvent(\"TouchEvent\");\n return true;\n } catch (e) {\n return false;\n }\n }\n\n private checkTouch() {\n return VirtualJoystick.checkForTouch();\n }\n\n private createBase() {\n const base = document.createElement(\"span\");\n const style = base.style;\n style.touchAction = \"pinch-zoom\";\n style.width = `${this.radius * 2}px`;\n style.height = `${this.radius * 2}px`;\n style.position = \"relative\";\n style.display = \"block\";\n style.borderRadius = \"50%\";\n style.borderColor = \"rgba(200,200,200,0.5)\";\n style.borderWidth = \"2px\";\n style.borderStyle = \"solid\";\n style.pointerEvents = \"auto\";\n style.userSelect = \"none\";\n return base;\n }\n\n private createCenter() {\n const center = document.createElement(\"div\");\n const style = center.style;\n style.width = `${this.innerRadius * 2}px`;\n style.height = `${this.innerRadius * 2}px`;\n style.position = \"absolute\";\n style.borderRadius = \"50%\";\n style.backgroundColor = \"rgba(200,200,200,0.3)\";\n style.borderWidth = \"1px\";\n style.borderColor = \"rgba(200,200,200,0.8)\";\n style.borderStyle = \"solid\";\n style.userSelect = \"none\";\n return center;\n }\n\n private createJumpButton() {\n const button = document.createElement(\"button\");\n button.textContent = \"JUMP\";\n const style = button.style;\n style.touchAction = \"pinch-zoom\";\n style.width = `100px`;\n style.height = `100px`;\n style.borderRadius = \"20px\";\n style.color = \"white\";\n style.font = \"Helvetica, sans-serif\";\n style.fontSize = \"16px\";\n style.backgroundColor = \"rgba(200,200,200,0.3)\";\n style.color = \"rgba(220,220,220,1)\";\n style.borderWidth = \"1px\";\n style.borderColor = \"rgba(200,200,200,0.8)\";\n style.borderStyle = \"solid\";\n style.pointerEvents = \"auto\";\n style.userSelect = \"none\";\n return button;\n }\n\n private bindEvents(): void {\n this.joystickBaseElement.addEventListener(\"pointerdown\", this.onJoystickPointerDown.bind(this));\n this.joystickBaseElement.addEventListener(\n \"contextmenu\",\n this.preventDefaultAndStopPropagation.bind(this),\n );\n this.joystickBaseElement.addEventListener(\n \"touchstart\",\n this.preventDefaultAndStopPropagation.bind(this),\n );\n\n this.jumpButton.addEventListener(\"pointerdown\", this.onJumpPointerDown.bind(this));\n this.jumpButton.addEventListener(\n \"contextmenu\",\n this.preventDefaultAndStopPropagation.bind(this),\n );\n this.jumpButton.addEventListener(\n \"touchstart\",\n this.preventDefaultAndStopPropagation.bind(this),\n );\n document.addEventListener(\"pointermove\", this.onPointerMove.bind(this));\n document.addEventListener(\"pointerup\", this.onPointerUp.bind(this));\n document.addEventListener(\"pointercancel\", this.onPointerUp.bind(this));\n }\n\n private preventDefaultAndStopPropagation(evt: PointerEvent): void {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n private onJumpPointerDown(evt: PointerEvent): void {\n if (this.jumpPointerId === null) {\n this.jumpPointerId = evt.pointerId;\n }\n }\n\n private onJoystickPointerDown(evt: PointerEvent): void {\n evt.preventDefault();\n evt.stopPropagation();\n if (evt.buttons !== 1) {\n return;\n }\n if (this.joystickPointerId === null) {\n this.joystickPointerId = evt.pointerId;\n this.updateControlAndDirection(evt);\n }\n }\n\n private onPointerMove(evt: PointerEvent): void {\n evt.preventDefault();\n evt.stopPropagation();\n if (evt.pointerId !== this.joystickPointerId) {\n return;\n }\n this.updateControlAndDirection(evt);\n }\n\n private onPointerUp(evt: PointerEvent): void {\n evt.preventDefault();\n evt.stopPropagation();\n\n if (evt.pointerId === this.jumpPointerId) {\n this.jumpPointerId = null;\n }\n if (evt.pointerId === this.joystickPointerId) {\n this.joystickPointerId = null;\n this.clearJoystickState();\n }\n }\n\n private clearJoystickState = (): void => {\n this.joystickOutput = null;\n this.joystickCenterElement.style.left = `${this.radius - this.innerRadius}px`;\n this.joystickCenterElement.style.top = `${this.radius - this.innerRadius}px`;\n };\n\n private updateControlAndDirection(input: PointerEvent): void {\n const rect = this.joystickBaseElement.getBoundingClientRect();\n const dx = input.clientX - (rect.left + this.radius);\n const dy = input.clientY - (rect.top + this.radius);\n\n const distance = Math.min(Math.sqrt(dx * dx + dy * dy), this.radius);\n const angle = Math.atan2(dy, dx);\n const constrainedX = distance * Math.cos(angle);\n const constrainedY = distance * Math.sin(angle);\n\n this.joystickCenterElement.style.left = `${constrainedX + this.radius - this.innerRadius}px`;\n this.joystickCenterElement.style.top = `${constrainedY + this.radius - this.innerRadius}px`;\n\n const direction = Math.atan2(dx, dy);\n const speed = distance / this.radius;\n const isSprinting = speed > sprintingThreshold;\n this.joystickOutput = { direction, isSprinting };\n }\n\n public getOutput(): { direction: number | null; isSprinting: boolean; jump: boolean } | null {\n const jump = this.jumpPointerId !== null;\n if (!this.joystickOutput) {\n if (jump) {\n return { direction: null, isSprinting: false, jump: jump };\n }\n return null;\n }\n return {\n ...this.joystickOutput,\n jump: jump,\n };\n }\n}\n", "import {\n ChatProbe,\n IMMLScene,\n Interaction,\n InteractionListener,\n InteractionManager,\n LinkProps,\n LoadingProgressManager,\n MElement,\n MMLDocumentTimeManager,\n PositionAndRotation,\n PromptManager,\n PromptProps,\n} from \"@mml-io/mml-web\";\nimport {\n ThreeJSClickTrigger,\n ThreeJSGraphicsAdapter,\n ThreeJSGraphicsInterface,\n ThreeJSInteractionAdapter,\n} from \"@mml-io/mml-web-threejs\";\nimport { AudioListener, Group, Object3D, PerspectiveCamera, Scene, WebGLRenderer } from \"three\";\n\nimport { CollisionsManager } from \"../collisions/CollisionsManager\";\n\ntype MMLCompositionSceneConfig = {\n targetElement: HTMLElement;\n renderer: WebGLRenderer;\n scene: Scene;\n camera: PerspectiveCamera;\n audioListener: AudioListener;\n collisionsManager: CollisionsManager;\n getUserPositionAndRotation: () => PositionAndRotation;\n};\n\nexport class MMLCompositionScene {\n public group: Group;\n\n public readonly mmlScene: IMMLScene<ThreeJSGraphicsAdapter>;\n public readonly documentTimeManager: MMLDocumentTimeManager;\n private readonly promptManager: PromptManager;\n private readonly interactionManager: InteractionManager;\n private readonly interactionListener: InteractionListener<ThreeJSGraphicsAdapter>;\n private readonly chatProbes = new Set<ChatProbe<ThreeJSGraphicsAdapter>>();\n private readonly clickTrigger: ThreeJSClickTrigger;\n private readonly loadingProgressManager: LoadingProgressManager;\n\n constructor(private config: MMLCompositionSceneConfig) {\n this.group = new Group();\n this.promptManager = PromptManager.init(this.config.targetElement);\n\n const graphicsAdapter: ThreeJSGraphicsAdapter = {\n collisionType: null as unknown as Object3D,\n containerType: null as unknown as Object3D,\n getGraphicsAdapterFactory: () => {\n return ThreeJSGraphicsInterface;\n },\n getRootContainer: () => {\n return this.group;\n },\n interactionShouldShowDistance(\n interaction: Interaction<ThreeJSGraphicsAdapter>,\n ): number | null {\n return ThreeJSInteractionAdapter.interactionShouldShowDistance(\n interaction,\n this.config.camera,\n this.config.scene,\n );\n },\n dispose(): void {},\n getAudioListener: () => {\n return config.audioListener;\n },\n getCamera: () => {\n return config.camera;\n },\n getThreeScene: () => {\n return config.scene;\n },\n getUserPositionAndRotation: () => {\n return this.config.getUserPositionAndRotation();\n },\n };\n\n const { interactionListener, interactionManager } = InteractionManager.init(\n this.config.targetElement,\n (interaction: Interaction<ThreeJSGraphicsAdapter>) => {\n return graphicsAdapter.interactionShouldShowDistance(interaction);\n },\n );\n this.interactionManager = interactionManager;\n this.interactionListener = interactionListener;\n this.loadingProgressManager = new LoadingProgressManager();\n this.documentTimeManager = new MMLDocumentTimeManager();\n\n this.mmlScene = {\n getGraphicsAdapter(): ThreeJSGraphicsAdapter {\n return graphicsAdapter;\n },\n hasGraphicsAdapter(): boolean {\n return true;\n },\n addCollider: (object: Object3D, mElement: MElement<ThreeJSGraphicsAdapter>) => {\n this.config.collisionsManager.addMeshesGroup(object as Group, mElement);\n },\n updateCollider: (object: Object3D) => {\n this.config.collisionsManager.updateMeshesGroup(object as Group);\n },\n removeCollider: (object: Object3D) => {\n this.config.collisionsManager.removeMeshesGroup(object as Group);\n },\n getUserPositionAndRotation: this.config.getUserPositionAndRotation,\n addInteraction: (interaction: Interaction<ThreeJSGraphicsAdapter>) => {\n this.interactionListener.addInteraction(interaction);\n },\n updateInteraction: (interaction: Interaction<ThreeJSGraphicsAdapter>) => {\n this.interactionListener.updateInteraction(interaction);\n },\n removeInteraction: (interaction: Interaction<ThreeJSGraphicsAdapter>) => {\n this.interactionListener.removeInteraction(interaction);\n },\n addChatProbe: (chatProbe: ChatProbe<ThreeJSGraphicsAdapter>) => {\n this.chatProbes.add(chatProbe);\n },\n updateChatProbe: () => {\n // no-op\n },\n removeChatProbe: (chatProbe: ChatProbe<ThreeJSGraphicsAdapter>) => {\n this.chatProbes.delete(chatProbe);\n },\n prompt: (\n promptProps: PromptProps,\n abortSignal: AbortSignal,\n callback: (message: string | null) => void,\n ) => {\n this.promptManager.prompt(promptProps, abortSignal, callback);\n },\n link: (\n linkProps: LinkProps,\n abortSignal: AbortSignal,\n windowCallback: (openedWindow: Window | null) => void,\n ) => {\n this.promptManager.link(linkProps, abortSignal, windowCallback);\n },\n getLoadingProgressManager: () => {\n return this.loadingProgressManager;\n },\n };\n\n this.clickTrigger = ThreeJSClickTrigger.init(\n this.config.targetElement,\n this.group,\n this.config.camera,\n );\n }\n\n onChatMessage(message: string) {\n for (const chatProbe of this.chatProbes) {\n chatProbe.trigger(message);\n }\n }\n\n dispose() {\n this.promptManager.dispose();\n this.clickTrigger.dispose();\n this.interactionManager.dispose();\n }\n}\n", "import * as EssentialsPlugin from \"@tweakpane/plugin-essentials\";\nimport {\n BloomEffect,\n EffectComposer,\n EffectPass,\n NormalPass,\n SSAOEffect,\n ToneMappingEffect,\n} from \"postprocessing\";\nimport { Scene, WebGLRenderer } from \"three\";\nimport { FolderApi, Pane } from \"tweakpane\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\nimport { LocalController } from \"../character/LocalController\";\nimport { EventHandlerCollection } from \"../input/EventHandlerCollection\";\nimport { BrightnessContrastSaturation } from \"../rendering/post-effects/bright-contrast-sat\";\nimport { GaussGrainEffect } from \"../rendering/post-effects/gauss-grain\";\nimport { Sun } from \"../sun/Sun\";\nimport { TimeManager } from \"../time/TimeManager\";\n\nimport { BrightnessContrastSaturationFolder } from \"./blades/bcsFolder\";\nimport { CameraFolder } from \"./blades/cameraFolder\";\nimport { CharacterControlsFolder } from \"./blades/characterControlsFolder\";\nimport { CharacterFolder } from \"./blades/characterFolder\";\nimport { EnvironmentFolder } from \"./blades/environmentFolder\";\nimport { PostExtrasFolder } from \"./blades/postExtrasFolder\";\nimport { RendererFolder, rendererValues } from \"./blades/rendererFolder\";\nimport { RendererStatsFolder } from \"./blades/rendererStatsFolder\";\nimport { SSAOFolder } from \"./blades/ssaoFolder\";\nimport { ToneMappingFolder } from \"./blades/toneMappingFolder\";\nimport { setTweakpaneActive } from \"./tweakPaneActivity\";\nimport { tweakPaneStyle } from \"./tweakPaneStyle\";\n\nexport class TweakPane {\n private gui: Pane;\n\n private renderStatsFolder: RendererStatsFolder;\n private rendererFolder: RendererFolder;\n private toneMappingFolder: ToneMappingFolder;\n private ssaoFolder: SSAOFolder;\n private bcsFolder: BrightnessContrastSaturationFolder;\n private postExtrasFolder: PostExtrasFolder;\n // @ts-ignore\n private character: CharacterFolder;\n private environment: EnvironmentFolder;\n private camera: CameraFolder;\n private characterControls: CharacterControlsFolder;\n\n private export: FolderApi;\n\n private saveVisibilityInLocalStorage: boolean = true;\n public guiVisible: boolean = false;\n private tweakPaneWrapper: HTMLDivElement;\n private eventHandlerCollection: EventHandlerCollection;\n\n constructor(\n private holderElement: HTMLElement,\n private renderer: WebGLRenderer,\n private scene: Scene,\n private composer: EffectComposer,\n ) {\n this.tweakPaneWrapper = document.createElement(\"div\");\n this.tweakPaneWrapper.style.position = \"fixed\";\n this.tweakPaneWrapper.style.width = \"400px\";\n this.tweakPaneWrapper.style.height = \"100%\";\n this.tweakPaneWrapper.style.top = \"0px\";\n this.tweakPaneWrapper.style.right = \"calc(-50vw)\";\n this.tweakPaneWrapper.style.zIndex = \"99\";\n this.tweakPaneWrapper.style.overflow = \"auto\";\n this.tweakPaneWrapper.style.backgroundColor = \"rgba(0, 0, 0, 0.66)\";\n this.tweakPaneWrapper.style.paddingLeft = \"5px\";\n this.tweakPaneWrapper.style.boxShadow = \"-7px 0px 12px rgba(0, 0, 0, 0.5)\";\n this.tweakPaneWrapper.style.transition = \"right cubic-bezier(0.83, 0, 0.17, 1) 0.7s\";\n holderElement.appendChild(this.tweakPaneWrapper);\n\n this.gui = new Pane({ container: this.tweakPaneWrapper! });\n this.gui.registerPlugin(EssentialsPlugin);\n\n if (this.saveVisibilityInLocalStorage) {\n const localStorageGuiVisible = localStorage.getItem(\"guiVisible\");\n if (localStorageGuiVisible !== null) {\n if (localStorageGuiVisible === \"true\") {\n this.guiVisible = true;\n } else if (localStorageGuiVisible === \"false\") {\n this.guiVisible = false;\n }\n }\n }\n\n const styleElement = document.createElement(\"style\");\n styleElement.type = \"text/css\";\n styleElement.appendChild(document.createTextNode(tweakPaneStyle));\n document.head.appendChild(styleElement);\n\n this.renderStatsFolder = new RendererStatsFolder(this.gui, true);\n this.rendererFolder = new RendererFolder(this.gui, false);\n this.toneMappingFolder = new ToneMappingFolder(this.gui, false);\n this.ssaoFolder = new SSAOFolder(this.gui, false);\n this.bcsFolder = new BrightnessContrastSaturationFolder(this.gui, false);\n this.postExtrasFolder = new PostExtrasFolder(this.gui, false);\n this.character = new CharacterFolder(this.gui, false);\n this.environment = new EnvironmentFolder(this.gui, false);\n this.camera = new CameraFolder(this.gui, false);\n this.characterControls = new CharacterControlsFolder(this.gui, false);\n\n this.toneMappingFolder.folder.hidden = rendererValues.toneMapping === 5 ? false : true;\n\n this.export = this.gui.addFolder({ title: \"import / export\", expanded: false });\n\n this.eventHandlerCollection = new EventHandlerCollection();\n\n const gui = this.gui as any;\n const paneElement: HTMLElement = gui.containerElem_;\n paneElement.style.right = this.guiVisible ? \"0px\" : \"-450px\";\n this.eventHandlerCollection.add(this.gui.element, \"mouseenter\", () => setTweakpaneActive(true));\n this.eventHandlerCollection.add(this.gui.element, \"mousemove\", () => setTweakpaneActive(true));\n this.eventHandlerCollection.add(this.gui.element, \"mousedown\", () => setTweakpaneActive(true));\n this.eventHandlerCollection.add(this.gui.element, \"mouseleave\", () =>\n setTweakpaneActive(false),\n );\n this.eventHandlerCollection.add(this.gui.element, \"mouseup\", () => setTweakpaneActive(false));\n this.eventHandlerCollection.add(window, \"keydown\", (e) => {\n this.processKey(e);\n });\n }\n\n private processKey(e: KeyboardEvent): void {\n if (e.key === \"p\") {\n this.toggleGUI();\n }\n }\n\n public setupRenderPane(\n composer: EffectComposer,\n normalPass: NormalPass,\n ppssaoEffect: SSAOEffect,\n ppssaoPass: EffectPass,\n n8aopass: any,\n toneMappingEffect: ToneMappingEffect,\n toneMappingPass: EffectPass,\n brightnessContrastSaturation: typeof BrightnessContrastSaturation,\n bloomEffect: BloomEffect,\n gaussGrainEffect: typeof GaussGrainEffect,\n hasLighting: boolean,\n sun: Sun | null,\n setHDR: () => void,\n setSkyboxAzimuthalAngle: (azimuthalAngle: number) => void,\n setSkyboxPolarAngle: (azimuthalAngle: number) => void,\n setAmbientLight: () => void,\n setFog: () => void,\n ): void {\n // RenderOptions\n this.rendererFolder.setupChangeEvent(\n this.renderer,\n this.toneMappingFolder.folder,\n toneMappingPass,\n );\n\n this.toneMappingFolder.setupChangeEvent(toneMappingEffect);\n this.ssaoFolder.setupChangeEvent(composer, normalPass, ppssaoEffect, ppssaoPass, n8aopass);\n this.bcsFolder.setupChangeEvent(brightnessContrastSaturation);\n this.postExtrasFolder.setupChangeEvent(bloomEffect, gaussGrainEffect);\n this.environment.setupChangeEvent(\n this.scene,\n setHDR,\n setSkyboxAzimuthalAngle,\n setSkyboxPolarAngle,\n setAmbientLight,\n setFog,\n sun,\n );\n this.environment.folder.hidden = hasLighting === false || sun === null;\n\n const exportButton = this.export.addButton({ title: \"export\" });\n exportButton.on(\"click\", () => {\n this.downloadSettingsAsJSON(this.gui.exportState());\n });\n const importButton = this.export.addButton({ title: \"import\" });\n importButton.on(\"click\", () => {\n this.importSettingsFromJSON((settings) => {\n this.gui.importState(settings);\n });\n });\n }\n\n public dispose() {\n this.eventHandlerCollection.clear();\n this.gui.dispose();\n this.tweakPaneWrapper.remove();\n }\n\n public setupCamPane(cameraManager: CameraManager) {\n this.camera.setupChangeEvent(cameraManager);\n }\n\n public setupCharacterController(localController: LocalController) {\n this.characterControls.setupChangeEvent(localController);\n }\n\n public updateStats(timeManager: TimeManager): void {\n this.renderStatsFolder.update(this.renderer, this.composer, timeManager);\n }\n\n public updateCameraData(cameraManager: CameraManager) {\n this.camera.update(cameraManager);\n }\n\n public updateCharacterData(localController: LocalController) {\n this.characterControls.update(localController);\n }\n\n private formatDateForFilename(): string {\n const date = new Date();\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\"); // Months are 0-11\n const day = String(date.getDate()).padStart(2, \"0\");\n const hours = String(date.getHours()).padStart(2, \"0\");\n const minutes = String(date.getMinutes()).padStart(2, \"0\");\n const seconds = String(date.getSeconds()).padStart(2, \"0\");\n return `${year}-${month}-${day} ${hours}-${minutes}-${seconds}`;\n }\n\n private downloadSettingsAsJSON(settings: any): void {\n const jsonString = JSON.stringify(settings, null, 2);\n const blob = new Blob([jsonString], { type: \"application/json\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.download = `settings ${this.formatDateForFilename()}.json`;\n a.href = url;\n a.click();\n URL.revokeObjectURL(url);\n }\n\n private importSettingsFromJSON(callback: (settings: any) => void): void {\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = \".json\";\n input.addEventListener(\"change\", (event) => {\n const file = (event.target as HTMLInputElement).files?.[0];\n if (file) {\n const reader = new FileReader();\n reader.onload = (loadEvent) => {\n try {\n const settings = JSON.parse(loadEvent.target?.result as string);\n callback(settings);\n } catch (err) {\n console.error(\"Error parsing JSON:\", err);\n }\n };\n reader.readAsText(file);\n }\n });\n input.click();\n }\n\n private toggleGUI(): void {\n this.guiVisible = !this.guiVisible;\n const gui = this.gui as any;\n const paneElement: HTMLElement = gui.containerElem_;\n paneElement.style.right = this.guiVisible ? \"0px\" : \"-450px\";\n if (this.saveVisibilityInLocalStorage) {\n localStorage.setItem(\"guiVisible\", this.guiVisible === true ? \"true\" : \"false\");\n }\n }\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { BladeApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nimport { BrightnessContrastSaturation } from \"../../rendering/post-effects/bright-contrast-sat\";\n\nexport const bcsValues = {\n brightness: 0.06,\n contrast: 1.2,\n saturation: 1,\n};\n\nconst bcsOptions = {\n brightness: {\n amount: { min: -1.0, max: 1.0, step: 0.01 },\n },\n contrast: {\n amount: { min: 0.0, max: 2.0, step: 0.01 },\n },\n saturation: {\n amount: { min: 0.0, max: 2.0, step: 0.01 },\n },\n};\n\nexport class BrightnessContrastSaturationFolder {\n private folder: FolderApi;\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({\n title: \"brightness / contrast / sat\",\n expanded: expand,\n });\n this.folder.addBinding(bcsValues, \"brightness\", bcsOptions.brightness.amount);\n this.folder.addBinding(bcsValues, \"contrast\", bcsOptions.contrast.amount);\n this.folder.addBinding(bcsValues, \"saturation\", bcsOptions.saturation.amount);\n }\n\n public setupChangeEvent(brightnessContrastSaturation: typeof BrightnessContrastSaturation): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"brightness\":\n brightnessContrastSaturation.uniforms.brightness.value = e.value;\n break;\n case \"contrast\":\n brightnessContrastSaturation.uniforms.contrast.value = e.value;\n break;\n case \"saturation\":\n brightnessContrastSaturation.uniforms.saturation.value = e.value;\n break;\n }\n });\n }\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { Scene } from \"three\";\nimport { BladeApi, ButtonApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nimport { Sun } from \"../../sun/Sun\";\n\nexport const sunValues = {\n sunPosition: {\n sunAzimuthalAngle: 219,\n sunPolarAngle: -37,\n },\n sunIntensity: 3.7,\n sunColor: { r: 1.0, g: 1.0, b: 1.0 },\n};\n\nconst sunOptions = {\n sunPosition: {\n sunAzimuthalAngle: { min: 0, max: 360, step: 1 },\n sunPolarAngle: { min: -90, max: 90, step: 1 },\n },\n sunIntensity: { min: 0, max: 10, step: 0.1 },\n};\n\nexport const envValues = {\n skyboxAzimuthalAngle: 0,\n skyboxPolarAngle: 0,\n envMapIntensity: 0.07,\n skyboxIntensity: 0.8,\n skyboxBlurriness: 0.0,\n ambientLight: {\n ambientLightIntensity: 0.27,\n ambientLightColor: { r: 1, g: 1, b: 1 },\n },\n fog: {\n fogNear: 21,\n fogFar: 180,\n fogColor: { r: 0.7, g: 0.7, b: 0.7 },\n },\n};\n\nconst envOptions = {\n skyboxAzimuthalAngle: { min: 0, max: 360, step: 1 },\n skyboxPolarAngle: { min: 0, max: 360, step: 1 },\n skyboxIntensity: { min: 0, max: 1.3, step: 0.01 },\n skyboxBlurriness: { min: 0, max: 0.1, step: 0.001 },\n ambientLight: {\n ambientLightIntensity: { min: 0, max: 1, step: 0.01 },\n },\n fog: {\n fogNear: { min: 0, max: 80, step: 1 },\n fogFar: { min: 0, max: 300, step: 1 },\n },\n};\n\nexport class EnvironmentFolder {\n public folder: FolderApi;\n private sun: FolderApi;\n private envMap: FolderApi;\n private hdrButton: ButtonApi;\n private skybox: FolderApi;\n private ambient: FolderApi;\n private fog: FolderApi;\n\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({ title: \"environment\", expanded: expand });\n this.sun = this.folder.addFolder({ title: \"sun\", expanded: true });\n this.envMap = this.folder.addFolder({ title: \"envMap\", expanded: true });\n this.fog = this.folder.addFolder({ title: \"fog\", expanded: true });\n this.skybox = this.folder.addFolder({ title: \"skybox\", expanded: true });\n this.ambient = this.folder.addFolder({ title: \"ambient\", expanded: true });\n\n this.sun.addBinding(\n sunValues.sunPosition,\n \"sunAzimuthalAngle\",\n sunOptions.sunPosition.sunAzimuthalAngle,\n );\n this.sun.addBinding(\n sunValues.sunPosition,\n \"sunPolarAngle\",\n sunOptions.sunPosition.sunPolarAngle,\n );\n this.sun.addBinding(sunValues, \"sunIntensity\", sunOptions.sunIntensity);\n this.sun.addBinding(sunValues, \"sunColor\", {\n color: { type: \"float\" },\n });\n\n this.hdrButton = this.skybox.addButton({ title: \"Set HDRI\" });\n this.skybox.addBinding(envValues, \"skyboxIntensity\", envOptions.skyboxIntensity);\n this.skybox.addBinding(envValues, \"skyboxBlurriness\", envOptions.skyboxBlurriness);\n this.skybox.addBinding(envValues, \"skyboxAzimuthalAngle\", envOptions.skyboxAzimuthalAngle);\n this.skybox.addBinding(envValues, \"skyboxPolarAngle\", envOptions.skyboxPolarAngle);\n\n this.envMap.addBinding(envValues, \"envMapIntensity\", envOptions.skyboxIntensity);\n\n this.ambient.addBinding(\n envValues.ambientLight,\n \"ambientLightIntensity\",\n envOptions.ambientLight.ambientLightIntensity,\n );\n this.ambient.addBinding(envValues.ambientLight, \"ambientLightColor\", {\n color: { type: \"float\" },\n });\n\n this.fog.addBinding(envValues.fog, \"fogNear\", envOptions.fog.fogNear);\n this.fog.addBinding(envValues.fog, \"fogFar\", envOptions.fog.fogFar);\n this.fog.addBinding(envValues.fog, \"fogColor\", {\n color: { type: \"float\" },\n });\n }\n\n public setupChangeEvent(\n scene: Scene,\n setHDR: () => void,\n setSkyboxAzimuthalAngle: (azimuthalAngle: number) => void,\n setSkyboxPolarAngle: (polarAngle: number) => void,\n setAmbientLight: () => void,\n setFog: () => void,\n sun: Sun | null,\n ): void {\n this.sun.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"sunAzimuthalAngle\": {\n const value = e.value as number;\n sun?.setAzimuthalAngle(value * (Math.PI / 180));\n break;\n }\n case \"sunPolarAngle\": {\n const value = e.value as number;\n sun?.setPolarAngle(value * (Math.PI / 180));\n break;\n }\n case \"sunIntensity\": {\n const value = e.value as number;\n sun?.setIntensity(value);\n break;\n }\n case \"sunColor\": {\n const value = e.value as { r: number; g: number; b: number };\n sunValues.sunColor = {\n r: value.r,\n g: value.g,\n b: value.b,\n };\n sun?.setColor();\n break;\n }\n default:\n break;\n }\n });\n\n this.hdrButton.on(\"click\", () => {\n setHDR();\n });\n\n this.envMap.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"envMapIntensity\":\n scene.environmentIntensity = e.value as number;\n break;\n }\n });\n\n this.skybox.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"skyboxAzimuthalAngle\": {\n const value = e.value as number;\n setSkyboxAzimuthalAngle(value);\n break;\n }\n case \"skyboxPolarAngle\": {\n const value = e.value as number;\n envValues.skyboxPolarAngle = value;\n setSkyboxPolarAngle(value);\n break;\n }\n case \"skyboxIntensity\":\n scene.backgroundIntensity = e.value as number;\n break;\n case \"skyboxBlurriness\":\n scene.backgroundBlurriness = e.value as number;\n break;\n }\n });\n\n this.ambient.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"ambientLightIntensity\": {\n envValues.ambientLight.ambientLightIntensity = e.value as number;\n setAmbientLight();\n break;\n }\n case \"ambientLightColor\": {\n const value = e.value as { r: number; g: number; b: number };\n envValues.ambientLight.ambientLightColor = {\n r: value.r,\n g: value.g,\n b: value.b,\n };\n setAmbientLight();\n break;\n }\n }\n });\n\n this.fog.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"fogNear\": {\n envValues.fog.fogNear = e.value as number;\n setFog();\n break;\n }\n case \"fogFar\": {\n envValues.fog.fogFar = e.value as number;\n setFog();\n break;\n }\n case \"fogColor\": {\n const value = e.value as { r: number; g: number; b: number };\n envValues.fog.fogColor = {\n r: value.r,\n g: value.g,\n b: value.b,\n };\n setFog();\n break;\n }\n }\n });\n }\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { BloomEffect } from \"postprocessing\";\nimport { BladeApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nimport { GaussGrainEffect } from \"../../rendering/post-effects/gauss-grain\";\n\nexport const extrasValues = {\n grain: 0.045,\n bloom: 0.15,\n};\n\nconst extrasOptions = {\n grain: {\n amount: { min: 0, max: 0.2, step: 0.002 },\n },\n bloom: {\n amount: { min: 0, max: 50, step: 0.05 },\n },\n};\n\nexport class PostExtrasFolder {\n private folder: FolderApi;\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({ title: \"bloom / grain\", expanded: expand });\n this.folder.addBinding(extrasValues, \"bloom\", extrasOptions.bloom.amount);\n this.folder.addBinding(extrasValues, \"grain\", extrasOptions.grain.amount);\n }\n\n public setupChangeEvent(\n bloomEffect: BloomEffect,\n gaussGrainEffect: typeof GaussGrainEffect,\n ): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"bloom\":\n bloomEffect.intensity = e.value as number;\n break;\n case \"grain\":\n gaussGrainEffect.uniforms.amount.value = e.value as number;\n break;\n default:\n break;\n }\n });\n }\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { EffectPass } from \"postprocessing\";\nimport { Scene, ShadowMapType, ToneMapping, WebGLRenderer } from \"three\";\nimport { BladeApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nexport const rendererValues = {\n shadowMap: 2,\n toneMapping: 5,\n exposure: 1.7,\n};\n\nconst rendererOptions = {\n shadowMap: { min: 0, max: 2, step: 1 },\n toneMapping: { min: 0, max: 5, step: 1 },\n exposure: { min: 0, max: 3, step: 0.01 },\n};\n\nconst shadowMapTypes: Record<number, string> = {\n 0: \"BasicShadowMap\",\n 1: \"PCFShadowMap\",\n 2: \"PCFSoftShadowMap\",\n};\n\nconst toneMappingTypes: Record<number, string> = {\n 0: \"NoToneMapping\",\n 1: \"LinearToneMapping\",\n 2: \"ReinhardToneMapping\",\n 3: \"CineonToneMapping\",\n 4: \"ACESFilmicToneMapping\",\n 5: \"CustomToneMapping\",\n};\n\nconst monitoredValues = {\n shadowMapType: shadowMapTypes[rendererValues.shadowMap],\n toneMappingType: toneMappingTypes[rendererValues.toneMapping],\n};\n\nconst setShadowMapType = (value: number): void => {\n monitoredValues.shadowMapType = shadowMapTypes[value];\n};\n\nconst setToneMappingType = (value: number): void => {\n monitoredValues.toneMappingType = toneMappingTypes[value];\n rendererValues.toneMapping = value;\n console.log(rendererValues.toneMapping);\n};\n\nexport class RendererFolder {\n private folder: FolderApi;\n\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({\n title: \"rendererOptions\",\n expanded: expand,\n });\n\n this.folder.addBinding(rendererValues, \"shadowMap\", rendererOptions.shadowMap);\n this.folder.addBinding(monitoredValues, \"shadowMapType\", { readonly: true });\n this.folder.addBinding(rendererValues, \"toneMapping\", rendererOptions.toneMapping);\n this.folder.addBinding(monitoredValues, \"toneMappingType\", { readonly: true });\n this.folder.addBinding(rendererValues, \"exposure\", rendererOptions.exposure);\n }\n\n public setupChangeEvent(\n renderer: WebGLRenderer,\n toneMappingFolder: FolderApi,\n toneMappingPass: EffectPass,\n ): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"shadowMap\": {\n const value = e.value as ShadowMapType;\n renderer.shadowMap.type = value;\n setShadowMapType(value);\n break;\n }\n case \"toneMapping\":\n const value = e.value as ToneMapping;\n toneMappingFolder.hidden = e.value !== 5;\n toneMappingPass.enabled = e.value === 5 ? true : false;\n setToneMappingType(e.value as ToneMapping);\n break;\n case \"exposure\":\n renderer.toneMappingExposure = e.value as number;\n break;\n default:\n break;\n }\n });\n }\n}\n", "import { EffectComposer } from \"postprocessing\";\nimport { WebGLRenderer } from \"three\";\nimport { FolderApi } from \"tweakpane\";\n\nimport { TimeManager } from \"../../time/TimeManager\";\n\ntype StatsData = {\n triangles: string;\n geometries: string;\n textures: string;\n shaders: string;\n postPasses: string;\n drawCalls: string;\n rawDeltaTime: string;\n deltaTime: string;\n FPS: string;\n};\n\nexport class RendererStatsFolder {\n private folder: FolderApi;\n private performance: FolderApi;\n private defails: FolderApi;\n\n private statsData: StatsData = {\n triangles: \"0\",\n geometries: \"0\",\n textures: \"0\",\n shaders: \"0\",\n postPasses: \"0\",\n drawCalls: \"0\",\n rawDeltaTime: \"0\",\n deltaTime: \"0\",\n FPS: \"0\",\n };\n\n constructor(parentFolder: FolderApi, expanded: boolean = true) {\n this.folder = parentFolder.addFolder({ title: \"renderStats\", expanded: expanded });\n this.folder.addBinding(this.statsData, \"FPS\", { readonly: true });\n this.folder.addBinding(this.statsData, \"deltaTime\", { readonly: true });\n this.folder.addBinding(this.statsData, \"rawDeltaTime\", { readonly: true });\n this.folder.addBinding(this.statsData, \"triangles\", { readonly: true });\n this.folder.addBinding(this.statsData, \"geometries\", { readonly: true });\n this.folder.addBinding(this.statsData, \"textures\", { readonly: true });\n this.folder.addBinding(this.statsData, \"shaders\", { readonly: true });\n this.folder.addBinding(this.statsData, \"postPasses\", { readonly: true });\n this.folder.addBinding(this.statsData, \"drawCalls\", { readonly: true });\n }\n\n public update(renderer: WebGLRenderer, composer: EffectComposer, timeManager: TimeManager): void {\n const { geometries, textures } = renderer.info.memory;\n const { triangles, calls } = renderer.info.render;\n this.statsData.triangles = triangles.toString();\n this.statsData.geometries = geometries.toString();\n this.statsData.textures = textures.toString();\n this.statsData.shaders = renderer.info.programs!.length.toString();\n this.statsData.postPasses = composer.passes.length.toString();\n this.statsData.drawCalls = calls.toString();\n this.statsData.rawDeltaTime = (\n Math.round(timeManager.rawDeltaTime * 100000) / 100000\n ).toString();\n this.statsData.deltaTime = (Math.round(timeManager.deltaTime * 100000) / 100000).toString();\n this.statsData.FPS = timeManager.fps.toString();\n }\n}\n", "import { BindingApi, BladeApi, BladeController, TpChangeEvent, View } from \"@tweakpane/core\";\nimport { BlendFunction, EffectComposer, EffectPass, NormalPass, SSAOEffect } from \"postprocessing\";\nimport { Color } from \"three\";\nimport { FolderApi } from \"tweakpane\";\n\nexport const ppssaoValues = {\n enabled: false,\n blendFunction: BlendFunction.MULTIPLY,\n distanceScaling: true,\n depthAwareUpsampling: true,\n samples: 30,\n rings: 11,\n luminanceInfluence: 0.7,\n radius: 0.045,\n intensity: 3.14,\n bias: 0.01,\n fade: 0.06,\n resolutionScale: 0.5,\n color: { r: 0, g: 0, b: 0 },\n worldDistanceThreshold: 30,\n worldDistanceFalloff: 7,\n worldProximityThreshold: 0.5,\n worldProximityFalloff: 0.3,\n};\n\nconst ppssaoOptions = {\n samples: { min: 1, max: 50, step: 1 },\n rings: { min: 1, max: 50, step: 1 },\n luminanceInfluence: { min: 0, max: 1, step: 0.01 },\n radius: { min: 0, max: 0.1, step: 0.001 },\n intensity: { min: 0, max: 5, step: 0.1 },\n bias: { min: 0, max: 0.1, step: 0.001 },\n fade: { min: 0, max: 0.1, step: 0.001 },\n resolutionScale: { min: 0.25, max: 2, step: 0.25 },\n worldDistanceThreshold: { min: 0, max: 200, step: 1 },\n worldDistanceFalloff: { min: 0, max: 200, step: 1 },\n worldProximityThreshold: { min: 0, max: 2, step: 0.01 },\n worldProximityFalloff: { min: 0, max: 2, step: 0.01 },\n};\n\nexport const n8ssaoValues = {\n enabled: true,\n halfRes: true,\n aoRadius: 5,\n distanceFalloff: 3.0,\n intensity: 1.5,\n color: { r: 0, g: 0, b: 0 },\n aoSamples: 16,\n denoiseSamples: 4,\n denoiseRadius: 12,\n viewMode: \"Combined\",\n};\n\nexport const n8ssaoOptions = {\n radius: { min: 0.1, max: 6, step: 0.1 },\n distanceFalloff: { min: 1, max: 6, step: 0.1 },\n intensity: { min: 0.1, max: 5, step: 0.1 },\n aoSamples: [2, 4, 8, 16, 32, 64],\n denoiseSamples: [2, 4, 8, 16, 32, 64],\n denoiseRadius: [3, 6, 12],\n viewMode: [\"Combined\", \"AO\", \"No AO\", \"Split\", \"Split AO\", \"No AO\"],\n};\n\nconst ssaoMaterialParams = [\n \"fade\",\n \"bias\",\n \"minRadiusScale\",\n \"worldDistanceThreshold\",\n \"worldDistanceFalloff\",\n \"worldProximityThreshold\",\n \"worldProximityFalloff\",\n];\n\nexport class SSAOFolder {\n private folder: FolderApi;\n\n private ppssao: FolderApi;\n private n8ssao: FolderApi;\n\n private aoSamples: BindingApi;\n private denoiseSamples: BindingApi;\n private denoiseRadius: BindingApi;\n private aoDisplay: BindingApi;\n\n private postProcessingSSAOIndex: number = 1;\n\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({ title: \"ambientOcclusion\", expanded: expand });\n this.n8ssao = this.folder.addFolder({\n title: \"N8 ambientOcclusion\",\n expanded: n8ssaoValues.enabled,\n });\n this.ppssao = this.folder.addFolder({\n title: \"PP ambientOcclusion\",\n expanded: ppssaoValues.enabled,\n });\n\n // Post-processing SSAO\n {\n this.ppssao.addBinding({ enabled: ppssaoValues.enabled }, \"enabled\");\n this.ppssao.addBinding({ showEffectOnly: false }, \"showEffectOnly\");\n this.ppssao.addBinding(ppssaoValues, \"samples\", ppssaoOptions.samples);\n this.ppssao.addBinding(ppssaoValues, \"rings\", ppssaoOptions.rings);\n this.ppssao.addBinding(ppssaoValues, \"luminanceInfluence\", ppssaoOptions.luminanceInfluence);\n this.ppssao.addBinding(ppssaoValues, \"radius\", ppssaoOptions.radius);\n this.ppssao.addBinding(ppssaoValues, \"intensity\", ppssaoOptions.intensity);\n this.ppssao.addBinding(ppssaoValues, \"bias\", ppssaoOptions.bias);\n this.ppssao.addBinding(ppssaoValues, \"fade\", ppssaoOptions.fade);\n this.ppssao.addBinding(ppssaoValues, \"resolutionScale\", ppssaoOptions.resolutionScale);\n this.ppssao.addBinding(\n ppssaoValues,\n \"worldDistanceThreshold\",\n ppssaoOptions.worldDistanceThreshold,\n );\n this.ppssao.addBinding(\n ppssaoValues,\n \"worldDistanceFalloff\",\n ppssaoOptions.worldDistanceFalloff,\n );\n this.ppssao.addBinding(\n ppssaoValues,\n \"worldProximityThreshold\",\n ppssaoOptions.worldProximityThreshold,\n );\n this.ppssao.addBinding(\n ppssaoValues,\n \"worldProximityFalloff\",\n ppssaoOptions.worldProximityFalloff,\n );\n this.ppssao.addBinding(ppssaoValues, \"color\", { color: { alpha: false, type: \"float\" } });\n }\n\n // N8 SSAO\n {\n this.n8ssao.addBinding({ enabled: n8ssaoValues.enabled }, \"enabled\");\n this.n8ssao.addBinding({ halfRes: n8ssaoValues.halfRes }, \"halfRes\");\n this.n8ssao.addBinding(n8ssaoValues, \"aoRadius\", n8ssaoOptions.radius);\n this.n8ssao.addBinding(n8ssaoValues, \"distanceFalloff\", n8ssaoOptions.distanceFalloff);\n this.n8ssao.addBinding(n8ssaoValues, \"intensity\", n8ssaoOptions.intensity);\n this.n8ssao.addBinding(n8ssaoValues, \"color\", { color: { alpha: false, type: \"float\" } });\n\n this.aoSamples = this.n8ssao.addBinding(n8ssaoValues, \"aoSamples\", {\n view: \"radiogrid\",\n groupName: \"aoSamples\",\n size: [3, 2],\n cells: (x: number, y: number) => ({\n title: `${n8ssaoOptions.aoSamples[y * 3 + x]}`,\n value: n8ssaoOptions.aoSamples[y * 3 + x],\n }),\n label: \"aoSamples\",\n });\n\n this.denoiseSamples = this.n8ssao.addBinding(n8ssaoValues, \"denoiseSamples\", {\n view: \"radiogrid\",\n groupName: \"denoiseSamples\",\n size: [3, 2],\n cells: (x: number, y: number) => ({\n title: `${n8ssaoOptions.denoiseSamples[y * 3 + x]}`,\n value: n8ssaoOptions.denoiseSamples[y * 3 + x],\n }),\n label: \"denoiseSamples\",\n });\n\n this.denoiseRadius = this.n8ssao.addBinding(n8ssaoValues, \"denoiseRadius\", {\n view: \"radiogrid\",\n groupName: \"denoiseRadius\",\n size: [3, 1],\n cells: (x: number, y: number) => ({\n title: `${n8ssaoOptions.denoiseRadius[y * 3 + x]}`,\n value: n8ssaoOptions.denoiseRadius[y * 3 + x],\n }),\n label: \"denoiseRadius\",\n });\n\n this.aoDisplay = this.n8ssao.addBinding(n8ssaoValues, \"viewMode\", {\n view: \"radiogrid\",\n groupName: \"viewMode\",\n size: [3, 2],\n cells: (x: number, y: number) => ({\n title: `${n8ssaoOptions.viewMode[y * 3 + x]}`,\n value: `${n8ssaoOptions.viewMode[y * 3 + x]}`,\n }),\n label: \"viewMode\",\n });\n }\n\n this.folder.addBlade({ view: \"separator\" });\n }\n\n public setupChangeEvent(\n composer: EffectComposer,\n normalPass: NormalPass,\n ppssaoEffect: SSAOEffect,\n ppssaoPass: EffectPass,\n n8aopass: any,\n ): void {\n this.ppssao.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"enabled\": {\n const value = e.value as boolean;\n if (e.value === true) {\n composer.addPass(normalPass, this.postProcessingSSAOIndex);\n composer.addPass(ppssaoPass, this.postProcessingSSAOIndex + 1);\n } else {\n composer.removePass(ppssaoPass);\n composer.removePass(normalPass);\n }\n ppssaoValues.enabled = value;\n normalPass.enabled = value;\n ppssaoPass.enabled = value;\n break;\n }\n case \"showEffectOnly\": {\n const value = e.value as boolean;\n const blend = value === true ? BlendFunction.NORMAL : BlendFunction.MULTIPLY;\n ppssaoEffect.blendMode.blendFunction = blend;\n break;\n }\n case \"resolutionScale\": {\n const value = e.value as number;\n ppssaoEffect.resolution.scale = value;\n break;\n }\n case \"color\": {\n const value = e.value as { r: number; g: number; b: number };\n ppssaoEffect.color = new Color().setRGB(value.r, value.g, value.b);\n break;\n }\n default: {\n break;\n }\n }\n\n if (ssaoMaterialParams.includes(target)) {\n (ppssaoEffect.ssaoMaterial as any)[target] = e.value;\n return;\n }\n (ppssaoEffect as any)[target] = e.value;\n });\n\n this.n8ssao.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"enabled\":\n if (e.value === true) {\n composer.addPass(n8aopass, this.postProcessingSSAOIndex + 2);\n composer.passes[this.postProcessingSSAOIndex + 2].setSize(\n window.innerWidth,\n window.innerHeight,\n );\n } else {\n composer.removePass(n8aopass);\n }\n n8aopass.enabled = e.value;\n break;\n case \"halfRes\":\n n8aopass.configuration.halfRes = e.value;\n break;\n case \"aoRadius\":\n n8aopass.configuration.aoRadius = e.value;\n break;\n case \"distanceFalloff\":\n n8aopass.configuration.distanceFalloff = e.value;\n break;\n case \"intensity\":\n n8aopass.configuration.intensity = e.value;\n break;\n case \"color\":\n const value = (e as any).value;\n n8aopass.configuration.color = new Color().setRGB(value.r, value.g, value.b);\n break;\n default:\n break;\n }\n });\n\n this.aoSamples.on(\"change\", (e: any) => {\n n8aopass.configuration.aoSamples = e.value;\n });\n\n this.denoiseSamples.on(\"change\", (e: any) => {\n n8aopass.configuration.denoiseSamples = e.value;\n });\n\n this.denoiseRadius.on(\"change\", (e: any) => {\n n8aopass.configuration.denoiseRadius = e.value;\n });\n\n this.aoDisplay.on(\"change\", (e: any) => {\n n8aopass.setDisplayMode(e.value);\n });\n }\n}\n", "import { BindingApi, BladeApi, BladeController, TpChangeEvent, View } from \"@tweakpane/core\";\nimport { ToneMappingEffect, ToneMappingMode } from \"postprocessing\";\nimport { FolderApi } from \"tweakpane\";\n\nexport const toneMappingValues = {\n mode: 7 as ToneMappingMode,\n resolution: 512,\n whitePoint: 32.0,\n middleGrey: 21.0,\n minLuminance: 0.01,\n averageLuminance: 0.01,\n adaptationRate: 2.0,\n};\n\nconst toneMappingOptions = {\n mode: { min: 0, max: 8, step: 1 },\n resolution: { min: 64, max: 512, step: 64 },\n whitePoint: { min: 0, max: 32, step: 0.01 },\n middleGrey: { min: 0, max: 32, step: 0.01 },\n minLuminance: { min: 0, max: 32, step: 0.001 },\n averageLuminance: { min: 0.001, max: 2, step: 0.001 },\n adaptationRate: { min: 0.1, max: 2.0, step: 0.1 },\n};\n\nconst customToneMappingTypes: Record<number, string> = {\n 0: \"LINEAR\",\n 1: \"REINHARD\",\n 2: \"REINHARD2\",\n 3: \"REINHARD2_ADAPTIVE\",\n 4: \"UNCHARTED2\",\n 5: \"OPTIMIZED_CINEON\",\n 6: \"ACES_FILMIC\",\n 7: \"AGX\",\n 8: \"NEUTRAL\",\n};\n\nconst customToneMappingBlade = {\n customToneMappingType: customToneMappingTypes[toneMappingValues.mode],\n};\n\nconst setCustomToneMappingType = (value: number): void => {\n customToneMappingBlade.customToneMappingType = customToneMappingTypes[value];\n};\n\nexport class ToneMappingFolder {\n public folder: FolderApi;\n private minLuminance: BindingApi;\n private avgLuminance: BindingApi;\n\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({\n title: \"customToneMapping\",\n expanded: expand,\n });\n this.folder.addBinding(toneMappingValues, \"mode\", toneMappingOptions.mode);\n this.folder.addBinding(customToneMappingBlade, \"customToneMappingType\", { readonly: true });\n this.folder.addBinding(toneMappingValues, \"whitePoint\", toneMappingOptions.whitePoint);\n this.folder.addBinding(toneMappingValues, \"middleGrey\", toneMappingOptions.middleGrey);\n this.minLuminance = this.folder.addBinding(\n toneMappingValues,\n \"minLuminance\",\n toneMappingOptions.minLuminance,\n );\n this.minLuminance.hidden = false;\n this.avgLuminance = this.folder.addBinding(\n toneMappingValues,\n \"averageLuminance\",\n toneMappingOptions.averageLuminance,\n );\n this.avgLuminance.hidden = false;\n this.folder.addBinding(toneMappingValues, \"adaptationRate\", toneMappingOptions.adaptationRate);\n }\n\n public setupChangeEvent(toneMappingEffect: ToneMappingEffect): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n if (target === \"mode\") {\n setCustomToneMappingType(e.value as number);\n }\n (toneMappingEffect as any)[target] = e.value;\n return;\n });\n }\n}\n", "export const tweakPaneStyle = `\n:root {\n --tp-base-background-color: rgba(12, 12, 12, 0.6);\n --tp-base-shadow-color: hsla(0, 0%, 0%, 0.2);\n --tp-button-background-color: hsla(0, 0%, 80%, 1);\n --tp-button-background-color-active: hsla(0, 0%, 100%, 1);\n --tp-button-background-color-focus: hsla(0, 0%, 95%, 1);\n --tp-button-background-color-hover: hsla(0, 0%, 85%, 1);\n --tp-button-foreground-color: hsla(0, 0%, 0%, 0.7);\n --tp-container-background-color: hsla(0, 0%, 0%, 0.3);\n --tp-container-background-color-active: hsla(0, 0%, 0%, 0.6);\n --tp-container-background-color-focus: hsla(0, 0%, 0%, 0.5);\n --tp-container-background-color-hover: hsla(0, 0%, 0%, 0.4);\n --tp-container-foreground-color: hsla(0, 0%, 90%, 0.6);\n --tp-groove-foreground-color: hsla(0, 0%, 0%, 0.2);\n --tp-input-background-color: hsla(0, 0%, 30%, 0.3);\n --tp-input-background-color-active: hsla(0, 0%, 0%, 0.6);\n --tp-input-background-color-focus: hsla(0, 0%, 0%, 0.5);\n --tp-input-background-color-hover: hsla(0, 0%, 0%, 0.4);\n --tp-input-foreground-color: hsla(0, 0%, 100%, 0.6);\n --tp-label-foreground-color: hsla(0, 0%, 100%, 0.6);\n --tp-monitor-background-color: hsla(0, 0%, 0%, 0.3);\n --tp-monitor-foreground-color: hsla(0, 0%, 100%, 0.3);\n}\n\n.tp-brkv {\n -webkit-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.tp-dfwv {\n z-index: 100;\n color: white;\n width: 600px !important;\n display: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.tp-fldv {\n margin: 1px 0px 0px 0px !important;\n}\n\n.tp-fldv_b {\n overflow: visible !important;\n}\n\n.tp-fldv_t {\n font-size: 13px;\n font-weight: 900;\n color: #ffffff;\n background-color: rgba(70, 70, 70, 0.3);\n border-top: 1px solid rgba(210, 210, 210, 0.1);\n border-radius: 3px;\n}\n\n.tp-lblv_l {\n font-size: 12px;\n padding-left: 0px !important;\n padding-right: 0px !important;\n}\n\n.tp-lblv_v {\n width: 150px;\n}\n\n.tp-sldtxtv_t {\n max-width: 50px;\n}\n\n.tp-sglv_i {\n font-size: 12px;\n color: rgba(255, 255, 255, 0.7);\n}\n\n.tp-ckbv_w {\n border: 1px solid rgba(200, 200, 250, 0.2);\n}\n`;\n", "import { HDRJPGLoader } from \"@monogrid/gainmap-js\";\nimport {\n BlendFunction,\n BloomEffect,\n EdgeDetectionMode,\n EffectComposer,\n EffectPass,\n FXAAEffect,\n NormalPass,\n PredicationMode,\n RenderPass,\n ShaderPass,\n SMAAEffect,\n SMAAPreset,\n SSAOEffect,\n TextureEffect,\n ToneMappingEffect,\n} from \"postprocessing\";\nimport {\n AmbientLight,\n Color,\n EquirectangularReflectionMapping,\n Euler,\n Fog,\n HalfFloatType,\n LinearSRGBColorSpace,\n LoadingManager,\n MathUtils,\n PerspectiveCamera,\n PMREMGenerator,\n Scene,\n ShadowMapType,\n SRGBColorSpace,\n Texture,\n ToneMapping,\n Vector2,\n WebGLRenderer,\n} from \"three\";\nimport { RGBELoader } from \"three/examples/jsm/loaders/RGBELoader.js\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\nimport { Sun } from \"../sun/Sun\";\nimport { TimeManager } from \"../time/TimeManager\";\nimport { bcsValues } from \"../tweakpane/blades/bcsFolder\";\nimport { envValues, sunValues } from \"../tweakpane/blades/environmentFolder\";\nimport { extrasValues } from \"../tweakpane/blades/postExtrasFolder\";\nimport { rendererValues } from \"../tweakpane/blades/rendererFolder\";\nimport { n8ssaoValues, ppssaoValues } from \"../tweakpane/blades/ssaoFolder\";\nimport { toneMappingValues } from \"../tweakpane/blades/toneMappingFolder\";\nimport { TweakPane } from \"../tweakpane/TweakPane\";\n\nimport { BrightnessContrastSaturation } from \"./post-effects/bright-contrast-sat\";\nimport { GaussGrainEffect } from \"./post-effects/gauss-grain\";\nimport { N8SSAOPass } from \"./post-effects/n8-ssao/N8SSAOPass\";\n\ntype ComposerContructorArgs = {\n scene: Scene;\n cameraManager: CameraManager;\n spawnSun: boolean;\n environmentConfiguration?: EnvironmentConfiguration;\n};\n\nexport type EnvironmentConfiguration = {\n groundPlane?: boolean;\n skybox?: {\n intensity?: number;\n blurriness?: number;\n azimuthalAngle?: number;\n polarAngle?: number;\n } & (\n | {\n hdrJpgUrl: string;\n }\n | {\n hdrUrl: string;\n }\n );\n envMap?: {\n intensity?: number;\n };\n sun?: {\n intensity?: number;\n polarAngle?: number;\n azimuthalAngle?: number;\n };\n postProcessing?: {\n bloomIntensity?: number;\n };\n ambientLight?: {\n intensity?: number;\n };\n};\n\nexport class Composer {\n private width: number = 1;\n private height: number = 1;\n private resizeListener: () => void;\n public resolution: Vector2 = new Vector2(this.width, this.height);\n\n private readonly scene: Scene;\n public postPostScene: Scene;\n private readonly cameraManager: CameraManager;\n public readonly renderer: WebGLRenderer;\n\n public readonly effectComposer: EffectComposer;\n private readonly renderPass: RenderPass;\n\n private readonly normalPass: NormalPass;\n private readonly normalTextureEffect: TextureEffect;\n private readonly ppssaoEffect: SSAOEffect;\n private readonly ppssaoPass: EffectPass;\n private readonly n8aopass: N8SSAOPass;\n\n private readonly fxaaEffect: FXAAEffect;\n private readonly fxaaPass: EffectPass;\n private readonly bloomEffect: BloomEffect;\n private readonly bloomPass: EffectPass;\n private readonly toneMappingEffect: ToneMappingEffect;\n private readonly smaaEffect: SMAAEffect;\n\n private readonly toneMappingPass: EffectPass;\n private readonly smaaPass: EffectPass;\n\n private readonly bcs = BrightnessContrastSaturation;\n private readonly bcsPass: ShaderPass;\n\n private readonly gaussGrainEffect = GaussGrainEffect;\n private readonly gaussGrainPass: ShaderPass;\n\n private ambientLight: AmbientLight | null = null;\n private environmentConfiguration?: EnvironmentConfiguration;\n\n private skyboxState: {\n src: {\n hdrJpgUrl?: string;\n hdrUrl?: string;\n };\n latestPromise: Promise<unknown> | null;\n } = { src: {}, latestPromise: null };\n\n public sun: Sun | null = null;\n public spawnSun: boolean;\n\n constructor({\n scene,\n cameraManager,\n spawnSun = false,\n environmentConfiguration,\n }: ComposerContructorArgs) {\n this.scene = scene;\n this.cameraManager = cameraManager;\n this.postPostScene = new Scene();\n this.spawnSun = spawnSun;\n this.renderer = new WebGLRenderer({\n powerPreference: \"high-performance\",\n antialias: false,\n });\n this.renderer.outputColorSpace = SRGBColorSpace;\n this.renderer.info.autoReset = false;\n this.renderer.setSize(this.width, this.height);\n this.renderer.shadowMap.enabled = true;\n this.renderer.shadowMap.type = rendererValues.shadowMap as ShadowMapType;\n this.renderer.toneMapping = rendererValues.toneMapping as ToneMapping;\n this.renderer.toneMappingExposure = rendererValues.exposure;\n\n this.environmentConfiguration = environmentConfiguration;\n\n this.updateSkyboxAndEnvValues();\n this.updateAmbientLightValues();\n this.setFog();\n\n this.effectComposer = new EffectComposer(this.renderer, {\n frameBufferType: HalfFloatType,\n });\n\n this.renderPass = new RenderPass(this.scene, this.cameraManager.activeCamera);\n\n this.normalPass = new NormalPass(this.scene, this.cameraManager.activeCamera);\n this.normalPass.enabled = ppssaoValues.enabled;\n this.normalTextureEffect = new TextureEffect({\n blendFunction: BlendFunction.SKIP,\n texture: this.normalPass.texture,\n });\n\n this.ppssaoEffect = new SSAOEffect(this.cameraManager.activeCamera, this.normalPass.texture, {\n blendFunction: ppssaoValues.blendFunction,\n distanceScaling: ppssaoValues.distanceScaling,\n depthAwareUpsampling: ppssaoValues.depthAwareUpsampling,\n samples: ppssaoValues.samples,\n rings: ppssaoValues.rings,\n luminanceInfluence: ppssaoValues.luminanceInfluence,\n radius: ppssaoValues.radius,\n intensity: ppssaoValues.intensity,\n bias: ppssaoValues.bias,\n fade: ppssaoValues.fade,\n resolutionScale: ppssaoValues.resolutionScale,\n color: new Color().setRGB(ppssaoValues.color.r, ppssaoValues.color.g, ppssaoValues.color.b),\n worldDistanceThreshold: ppssaoValues.worldDistanceThreshold,\n worldDistanceFalloff: ppssaoValues.worldDistanceFalloff,\n worldProximityThreshold: ppssaoValues.worldProximityThreshold,\n worldProximityFalloff: ppssaoValues.worldProximityFalloff,\n });\n this.ppssaoPass = new EffectPass(\n this.cameraManager.activeCamera,\n this.ppssaoEffect,\n this.normalTextureEffect,\n );\n this.ppssaoPass.enabled = ppssaoValues.enabled;\n\n this.fxaaEffect = new FXAAEffect();\n\n if (environmentConfiguration?.postProcessing?.bloomIntensity) {\n extrasValues.bloom = environmentConfiguration.postProcessing.bloomIntensity;\n }\n\n this.bloomEffect = new BloomEffect({\n intensity: extrasValues.bloom,\n });\n\n this.n8aopass = new N8SSAOPass(\n this.scene,\n this.cameraManager.activeCamera,\n this.width,\n this.height,\n );\n this.n8aopass.configuration.aoRadius = n8ssaoValues.aoRadius;\n this.n8aopass.configuration.distanceFalloff = n8ssaoValues.distanceFalloff;\n this.n8aopass.configuration.intensity = n8ssaoValues.intensity;\n this.n8aopass.configuration.color = new Color().setRGB(\n n8ssaoValues.color.r,\n n8ssaoValues.color.g,\n n8ssaoValues.color.b,\n );\n this.n8aopass.configuration.aoSamples = n8ssaoValues.aoSamples;\n this.n8aopass.configuration.denoiseSamples = n8ssaoValues.denoiseSamples;\n this.n8aopass.configuration.denoiseRadius = n8ssaoValues.denoiseRadius;\n this.n8aopass.enabled = n8ssaoValues.enabled;\n\n this.fxaaPass = new EffectPass(this.cameraManager.activeCamera, this.fxaaEffect);\n this.bloomPass = new EffectPass(this.cameraManager.activeCamera, this.bloomEffect);\n\n this.toneMappingEffect = new ToneMappingEffect({\n mode: toneMappingValues.mode,\n resolution: toneMappingValues.resolution,\n whitePoint: toneMappingValues.whitePoint,\n middleGrey: toneMappingValues.middleGrey,\n minLuminance: toneMappingValues.minLuminance,\n averageLuminance: toneMappingValues.averageLuminance,\n adaptationRate: toneMappingValues.adaptationRate,\n });\n this.smaaEffect = new SMAAEffect({\n preset: SMAAPreset.ULTRA,\n edgeDetectionMode: EdgeDetectionMode.COLOR,\n predicationMode: PredicationMode.DEPTH,\n });\n\n this.toneMappingPass = new EffectPass(this.cameraManager.activeCamera, this.toneMappingEffect);\n this.toneMappingPass.enabled =\n rendererValues.toneMapping === 5 || rendererValues.toneMapping === 0 ? true : false;\n\n this.bcsPass = new ShaderPass(this.bcs, \"tDiffuse\");\n this.bcs.uniforms.brightness.value = bcsValues.brightness;\n this.bcs.uniforms.contrast.value = bcsValues.contrast;\n this.bcs.uniforms.saturation.value = bcsValues.saturation;\n\n this.gaussGrainPass = new ShaderPass(this.gaussGrainEffect, \"tDiffuse\");\n this.gaussGrainEffect.uniforms.amount.value = extrasValues.grain;\n this.gaussGrainEffect.uniforms.alpha.value = 1.0;\n\n this.smaaPass = new EffectPass(this.cameraManager.activeCamera, this.smaaEffect);\n\n this.effectComposer.addPass(this.renderPass);\n if (ppssaoValues.enabled) {\n this.effectComposer.addPass(this.normalPass);\n this.effectComposer.addPass(this.ppssaoPass);\n }\n if (n8ssaoValues.enabled) {\n this.effectComposer.addPass(this.n8aopass);\n }\n this.effectComposer.addPass(this.fxaaPass);\n this.effectComposer.addPass(this.bloomPass);\n this.effectComposer.addPass(this.toneMappingPass);\n this.effectComposer.addPass(this.bcsPass);\n this.effectComposer.addPass(this.gaussGrainPass);\n\n if (this.spawnSun === true) {\n this.sun = new Sun();\n this.scene.add(this.sun);\n }\n\n if (this.environmentConfiguration?.skybox) {\n if (\"hdrJpgUrl\" in this.environmentConfiguration.skybox) {\n this.useHDRJPG(this.environmentConfiguration.skybox.hdrJpgUrl);\n } else if (\"hdrUrl\" in this.environmentConfiguration.skybox) {\n this.useHDRI(this.environmentConfiguration.skybox.hdrUrl);\n }\n }\n\n this.updateSunValues();\n\n this.resizeListener = () => {\n this.fitContainer();\n };\n window.addEventListener(\"resize\", this.resizeListener, false);\n this.fitContainer();\n }\n\n public updateEnvironmentConfiguration(environmentConfiguration: EnvironmentConfiguration) {\n this.environmentConfiguration = environmentConfiguration;\n\n if (environmentConfiguration.skybox) {\n if (\"hdrJpgUrl\" in environmentConfiguration.skybox) {\n this.useHDRJPG(environmentConfiguration.skybox.hdrJpgUrl);\n } else if (\"hdrUrl\" in environmentConfiguration.skybox) {\n this.useHDRI(environmentConfiguration.skybox.hdrUrl);\n }\n }\n\n this.updateSkyboxAndEnvValues();\n this.updateAmbientLightValues();\n this.updateSunValues();\n }\n\n public setupTweakPane(tweakPane: TweakPane) {\n tweakPane.setupRenderPane(\n this.effectComposer,\n this.normalPass,\n this.ppssaoEffect,\n this.ppssaoPass,\n this.n8aopass,\n this.toneMappingEffect,\n this.toneMappingPass,\n this.bcs,\n this.bloomEffect,\n this.gaussGrainEffect,\n this.spawnSun,\n this.sun,\n this.setHDRIFromFile.bind(this),\n (azimuthalAngle: number) => {\n envValues.skyboxAzimuthalAngle = azimuthalAngle;\n this.updateSkyboxRotation();\n },\n (polarAngle: number) => {\n envValues.skyboxPolarAngle = polarAngle;\n this.updateSkyboxRotation();\n },\n this.setAmbientLight.bind(this),\n this.setFog.bind(this),\n );\n }\n\n public dispose() {\n window.removeEventListener(\"resize\", this.resizeListener);\n this.renderer.dispose();\n }\n\n public fitContainer() {\n if (!this) {\n console.error(\"Composer not initialized\");\n return;\n }\n const parentElement = this.renderer.domElement.parentNode as HTMLElement;\n if (!parentElement) {\n return;\n }\n this.width = parentElement.clientWidth;\n this.height = parentElement.clientHeight;\n this.cameraManager.activeCamera.aspect = this.width / this.height;\n this.cameraManager.activeCamera.updateProjectionMatrix();\n this.renderer.setPixelRatio(window.devicePixelRatio);\n this.resolution.set(\n this.width * window.devicePixelRatio,\n this.height * window.devicePixelRatio,\n );\n this.effectComposer.setSize(\n this.width / window.devicePixelRatio,\n this.height / window.devicePixelRatio,\n );\n this.renderPass.setSize(this.width, this.height);\n if (ppssaoValues.enabled) {\n this.normalPass.setSize(this.width, this.height);\n this.normalTextureEffect.setSize(this.width, this.height);\n this.ppssaoPass.setSize(this.width, this.height);\n }\n if (n8ssaoValues.enabled) {\n this.n8aopass.setSize(this.width, this.height);\n }\n this.fxaaPass.setSize(this.width, this.height);\n this.smaaPass.setSize(this.width, this.height);\n this.bloomPass.setSize(this.width, this.height);\n this.toneMappingPass.setSize(this.width, this.height);\n this.gaussGrainPass.setSize(this.width, this.height);\n this.gaussGrainEffect.uniforms.resolution.value = new Vector2(this.width, this.height);\n this.renderer.setSize(this.width, this.height);\n }\n\n public render(timeManager: TimeManager): void {\n this.renderer.info.reset();\n this.renderPass.mainCamera = this.cameraManager.activeCamera;\n this.normalPass.texture.needsUpdate = true;\n this.gaussGrainEffect.uniforms.time.value = timeManager.time;\n this.effectComposer.render();\n this.renderer.clearDepth();\n this.renderer.render(this.postPostScene, this.cameraManager.activeCamera);\n }\n\n public updateSkyboxRotation() {\n this.scene.backgroundRotation = new Euler(\n MathUtils.degToRad(envValues.skyboxPolarAngle),\n MathUtils.degToRad(envValues.skyboxAzimuthalAngle),\n 0,\n );\n this.scene.environmentRotation = new Euler(\n MathUtils.degToRad(envValues.skyboxPolarAngle),\n MathUtils.degToRad(envValues.skyboxAzimuthalAngle),\n 0,\n );\n }\n\n private async loadHDRJPG(url: string): Promise<Texture> {\n return new Promise((resolve, reject) => {\n const pmremGenerator = new PMREMGenerator(this.renderer);\n const hdrJpg = new HDRJPGLoader(this.renderer).load(url, () => {\n const hdrJpgEquirectangularMap = hdrJpg.renderTarget.texture;\n hdrJpgEquirectangularMap.mapping = EquirectangularReflectionMapping;\n hdrJpgEquirectangularMap.needsUpdate = true;\n\n const envMap = pmremGenerator!.fromEquirectangular(hdrJpgEquirectangularMap).texture;\n hdrJpgEquirectangularMap.dispose();\n pmremGenerator!.dispose();\n hdrJpg.dispose();\n if (envMap) {\n envMap.colorSpace = LinearSRGBColorSpace;\n envMap.needsUpdate = true;\n resolve(envMap);\n } else {\n reject(\"Failed to generate environment map\");\n }\n });\n });\n }\n\n private async loadHDRi(url: string): Promise<Texture> {\n return new Promise((resolve, reject) => {\n const pmremGenerator = new PMREMGenerator(this.renderer);\n new RGBELoader(new LoadingManager()).load(url, (texture) => {\n const envMap = pmremGenerator!.fromEquirectangular(texture).texture;\n texture.dispose();\n pmremGenerator!.dispose();\n if (envMap) {\n envMap.colorSpace = LinearSRGBColorSpace;\n envMap.needsUpdate = true;\n resolve(envMap);\n } else {\n reject(\"Failed to generate environment map\");\n }\n });\n });\n }\n\n public useHDRJPG(url: string, fromFile: boolean = false): void {\n if (this.skyboxState.src.hdrJpgUrl === url) {\n return;\n }\n\n const hdrJPGPromise = this.loadHDRJPG(url);\n this.skyboxState.src = { hdrJpgUrl: url };\n this.skyboxState.latestPromise = hdrJPGPromise;\n hdrJPGPromise.then((envMap) => {\n if (this.skyboxState.latestPromise !== hdrJPGPromise) {\n return;\n }\n this.applyEnvMap(envMap);\n });\n }\n\n public useHDRI(url: string): void {\n if (this.skyboxState.src.hdrUrl === url) {\n return;\n }\n const hdrPromise = this.loadHDRi(url);\n this.skyboxState.src = { hdrUrl: url };\n this.skyboxState.latestPromise = hdrPromise;\n hdrPromise.then((envMap) => {\n if (this.skyboxState.latestPromise !== hdrPromise) {\n return;\n }\n this.applyEnvMap(envMap);\n });\n }\n\n public setHDRIFromFile(): void {\n if (!this.renderer) return;\n const fileInput = document.createElement(\"input\");\n fileInput.type = \"file\";\n fileInput.accept = \".hdr,.jpg\";\n fileInput.addEventListener(\"change\", () => {\n const file = fileInput.files?.[0];\n if (!file) {\n console.log(\"no file\");\n return;\n }\n const extension = file.name.split(\".\").pop();\n const fileURL = URL.createObjectURL(file);\n if (fileURL) {\n if (extension === \"hdr\") {\n this.useHDRI(fileURL);\n } else if (extension === \"jpg\") {\n this.useHDRJPG(fileURL);\n } else {\n console.error(`Unrecognized extension for HDR file ${file.name}`);\n }\n URL.revokeObjectURL(fileURL);\n document.body.removeChild(fileInput);\n }\n });\n document.body.appendChild(fileInput);\n fileInput.click();\n }\n\n public setFog(): void {\n if (envValues.fog.fogFar === 0) {\n this.scene.fog = null;\n return;\n }\n const fogColor = new Color().setRGB(\n envValues.fog.fogColor.r,\n envValues.fog.fogColor.g,\n envValues.fog.fogColor.b,\n );\n this.scene.fog = new Fog(fogColor, envValues.fog.fogNear, envValues.fog.fogFar);\n }\n\n public setAmbientLight(): void {\n if (this.ambientLight) {\n this.scene.remove(this.ambientLight);\n this.ambientLight.dispose();\n }\n const ambientLightColor = new Color().setRGB(\n envValues.ambientLight.ambientLightColor.r,\n envValues.ambientLight.ambientLightColor.g,\n envValues.ambientLight.ambientLightColor.b,\n );\n this.ambientLight = new AmbientLight(\n ambientLightColor,\n envValues.ambientLight.ambientLightIntensity,\n );\n this.scene.add(this.ambientLight);\n }\n\n private updateSunValues() {\n if (typeof this.environmentConfiguration?.sun?.intensity === \"number\") {\n sunValues.sunIntensity = this.environmentConfiguration.sun.intensity;\n this.sun?.setIntensity(this.environmentConfiguration.sun.intensity);\n }\n if (typeof this.environmentConfiguration?.sun?.azimuthalAngle === \"number\") {\n sunValues.sunPosition.sunAzimuthalAngle = this.environmentConfiguration.sun.azimuthalAngle;\n this.sun?.setAzimuthalAngle(\n this.environmentConfiguration.sun.azimuthalAngle * (Math.PI / 180),\n );\n }\n if (typeof this.environmentConfiguration?.sun?.polarAngle === \"number\") {\n sunValues.sunPosition.sunPolarAngle = this.environmentConfiguration.sun.polarAngle;\n this.sun?.setPolarAngle(this.environmentConfiguration.sun.polarAngle * (Math.PI / 180));\n }\n }\n\n private updateSkyboxAndEnvValues() {\n if (typeof this.environmentConfiguration?.envMap?.intensity === \"number\") {\n envValues.envMapIntensity = this.environmentConfiguration?.envMap.intensity;\n }\n this.scene.environmentIntensity = envValues.envMapIntensity;\n\n if (typeof this.environmentConfiguration?.skybox?.intensity === \"number\") {\n envValues.skyboxIntensity = this.environmentConfiguration?.skybox.intensity;\n }\n this.scene.backgroundIntensity = envValues.skyboxIntensity;\n\n if (typeof this.environmentConfiguration?.skybox?.blurriness === \"number\") {\n envValues.skyboxBlurriness = this.environmentConfiguration?.skybox.blurriness;\n }\n this.scene.backgroundBlurriness = envValues.skyboxBlurriness;\n\n if (typeof this.environmentConfiguration?.skybox?.azimuthalAngle === \"number\") {\n envValues.skyboxAzimuthalAngle = this.environmentConfiguration?.skybox.azimuthalAngle;\n this.updateSkyboxRotation();\n }\n\n if (typeof this.environmentConfiguration?.skybox?.polarAngle === \"number\") {\n envValues.skyboxPolarAngle = this.environmentConfiguration?.skybox.polarAngle;\n this.updateSkyboxRotation();\n }\n }\n\n private updateAmbientLightValues() {\n if (typeof this.environmentConfiguration?.ambientLight?.intensity === \"number\") {\n envValues.ambientLight.ambientLightIntensity =\n this.environmentConfiguration.ambientLight.intensity;\n }\n this.setAmbientLight();\n }\n\n private applyEnvMap(envMap: Texture) {\n this.scene.environment = envMap;\n this.scene.environmentIntensity = envValues.envMapIntensity;\n this.scene.environmentRotation = new Euler(\n MathUtils.degToRad(envValues.skyboxPolarAngle),\n MathUtils.degToRad(envValues.skyboxAzimuthalAngle),\n 0,\n );\n this.scene.background = envMap;\n this.scene.backgroundIntensity = envValues.skyboxIntensity;\n this.scene.backgroundBlurriness = envValues.skyboxBlurriness;\n this.scene.backgroundRotation = new Euler(\n MathUtils.degToRad(envValues.skyboxPolarAngle),\n MathUtils.degToRad(envValues.skyboxAzimuthalAngle),\n 0,\n );\n }\n}\n", "import { CameraHelper, Color, DirectionalLight, Group, OrthographicCamera, Vector3 } from \"three\";\n\nimport { sunValues } from \"../tweakpane/blades/environmentFolder\";\n\nexport class Sun extends Group {\n private readonly debug: boolean = false;\n private readonly sunOffset: Vector3 = new Vector3(\n sunValues.sunPosition.sunAzimuthalAngle * (Math.PI / 180),\n sunValues.sunPosition.sunPolarAngle * (Math.PI / 180),\n 100,\n );\n private readonly shadowResolution: number = 8192;\n private readonly shadowCamFrustum: number = 50;\n private readonly camHelper: CameraHelper | null = null;\n\n private readonly shadowCamera: OrthographicCamera;\n private readonly directionalLight: DirectionalLight;\n\n public target: Vector3 | null = null;\n\n constructor() {\n super();\n this.shadowCamera = new OrthographicCamera(\n -this.shadowCamFrustum,\n this.shadowCamFrustum,\n this.shadowCamFrustum,\n -this.shadowCamFrustum,\n 0.1,\n 200,\n );\n if (this.debug === true) {\n this.camHelper = new CameraHelper(this.shadowCamera);\n }\n this.directionalLight = new DirectionalLight(0xffffff);\n this.directionalLight.intensity = sunValues.sunIntensity;\n this.directionalLight.shadow.normalBias = 0.1;\n this.directionalLight.shadow.radius = 0.02;\n this.directionalLight.shadow.camera = this.shadowCamera;\n this.directionalLight.shadow.mapSize.set(this.shadowResolution, this.shadowResolution);\n this.directionalLight.castShadow = true;\n this.setColor();\n\n this.updateCharacterPosition(new Vector3(0, 0, 0));\n\n this.add(this.directionalLight);\n if (this.debug === true && this.camHelper instanceof CameraHelper) {\n this.add(this.camHelper);\n }\n }\n\n public updateCharacterPosition(position: Vector3 | undefined) {\n if (!position) return;\n this.target = position;\n this.setSunPosition(this.sunOffset.x, this.sunOffset.y);\n }\n\n public setAzimuthalAngle(angle: number) {\n if (this.sunOffset) this.sunOffset.x = angle;\n if (this.target) this.updateCharacterPosition(this.target);\n }\n\n public setPolarAngle(angle: number) {\n if (this.sunOffset) this.sunOffset.y = angle;\n if (this.target) this.updateCharacterPosition(this.target);\n }\n\n public setIntensity(intensity: number) {\n this.directionalLight.intensity = intensity;\n }\n\n public setColor() {\n this.directionalLight.color = new Color().setRGB(\n sunValues.sunColor.r,\n sunValues.sunColor.g,\n sunValues.sunColor.b,\n );\n }\n\n private setSunPosition(azimuthalAngle: number, polarAngle: number) {\n if (!this.target) return;\n const distance = this.sunOffset.z;\n const sphericalPosition = new Vector3(\n distance * Math.sin(polarAngle) * Math.cos(azimuthalAngle),\n distance * Math.cos(polarAngle),\n distance * Math.sin(polarAngle) * Math.sin(azimuthalAngle),\n );\n const newSunPosition = this.target.clone().add(sphericalPosition);\n this.directionalLight.position.set(newSunPosition.x, newSunPosition.y, newSunPosition.z);\n this.directionalLight.target.position.copy(this.target.clone());\n this.directionalLight.target.updateMatrixWorld();\n }\n}\n", "import { ShaderMaterial, Uniform } from \"three\";\n\nimport { vertexShader } from \"../shaders/vertex-shader\";\n\nexport const BrightnessContrastSaturation = new ShaderMaterial({\n uniforms: {\n tDiffuse: new Uniform(null),\n brightness: new Uniform(0.0),\n contrast: new Uniform(1.0),\n saturation: new Uniform(1.0),\n },\n vertexShader: vertexShader,\n fragmentShader: /* glsl */ `\n precision highp float;\n in vec2 vUv;\n\n uniform sampler2D tDiffuse;\n uniform float brightness;\n uniform float contrast;\n uniform float saturation;\n\n mat4 brightnessMatrix(float brightness) {\n return mat4(\n 1, 0, 0, 0,\n 0, 1, 0, 0,\n 0, 0, 1, 0,\n brightness, brightness, brightness, 1\n );\n }\n\n mat4 contrastMatrix(float contrast) {\n float t = (1.0 - contrast) / 2.0;\n\n return mat4(\n contrast, 0, 0, 0,\n 0, contrast, 0, 0,\n 0, 0, contrast, 0,\n t, t, t, 1\n );\n }\n\n mat4 saturationMatrix(float saturation) {\n vec3 luminance = vec3(0.3086, 0.6094, 0.0820);\n float oneMinusSat = 1.0 - saturation;\n vec3 red = vec3(luminance.x * oneMinusSat);\n red += vec3(saturation, 0, 0);\n vec3 green = vec3(luminance.y * oneMinusSat);\n green += vec3(0, saturation, 0);\n vec3 blue = vec3(luminance.z * oneMinusSat);\n blue += vec3(0, 0, saturation);\n return mat4(\n red, 0,\n green, 0,\n blue, 0,\n 0, 0, 0, 1\n );\n }\n\n void main(void) {\n vec4 color = texture(tDiffuse, vUv);\n gl_FragColor = (\n brightnessMatrix(brightness) *\n contrastMatrix(contrast) *\n saturationMatrix(saturation) *\n color\n );\n }\n `,\n dithering: true,\n});\n", "export const vertexShader = /* glsl */ `\n precision highp float;\n\n out vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n `;\n", "import { ShaderMaterial, Uniform, Vector2 } from \"three\";\n\nimport { vertexShader } from \"../shaders/vertex-shader\";\n\nexport const GaussGrainEffect = new ShaderMaterial({\n uniforms: {\n tDiffuse: new Uniform(null),\n resolution: new Uniform(new Vector2()),\n time: new Uniform(0.0),\n amount: new Uniform(0.0),\n alpha: new Uniform(0.0),\n },\n vertexShader: vertexShader,\n fragmentShader: /* glsl */ `\n precision highp float;\n in vec2 vUv;\n\n uniform sampler2D tDiffuse;\n uniform vec2 resolution;\n uniform float time;\n uniform float amount;\n uniform float alpha;\n\n const float PI = acos(-1.0);\n const float TAU = PI * 2.0;\n const float SQRTAU = sqrt(TAU);\n\n float gaussian(float z, float u, float o) {\n return (\n (1.0 / (o * SQRTAU)) *\n (exp(-(((z - u) * (z - u)) / (2.0 * (o * o)))))\n );\n }\n\n vec3 gaussgrain() {\n vec2 ps = vec2(1.0) / resolution.xy;\n vec2 uv = gl_FragCoord.xy * ps;\n float t = time;\n float seed = dot(uv, vec2(12.9898, 78.233));\n float noise = fract(sin(seed) * 43758.5453123 + t);\n noise = gaussian(noise, 0.0, 0.5);\n return vec3(noise);\n }\n\n void main(void) {\n vec2 uv = vUv;\n vec4 originalColor = texture(tDiffuse, uv);\n vec3 grain = gaussgrain();\n vec3 col = originalColor.rgb + (grain * amount);\n gl_FragColor = vec4(clamp(col, 0.0, 1.0), alpha);\n }\n `,\n dithering: true,\n});\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport { Pass } from \"postprocessing\";\nimport {\n Color,\n DataTexture,\n FloatType,\n Fog,\n FogExp2,\n HalfFloatType,\n LinearFilter,\n NearestFilter,\n NoColorSpace,\n OrthographicCamera,\n PerspectiveCamera,\n RGBAFormat,\n RedFormat,\n RepeatWrapping,\n Scene,\n ShaderMaterial,\n Texture,\n Uniform,\n Vector2,\n Vector3,\n WebGLRenderTarget,\n WebGLRenderer,\n} from \"three\";\n\nimport { BlueNoise } from \"./BlueNoise\";\nimport { DepthDownSample } from \"./DepthDownSample\";\nimport { EffectCompositer } from \"./EffectCompositer\";\nimport { EffectShader } from \"./EffectShader\";\nimport { FullScreenTriangle } from \"./FullScreenTriangle\";\nimport { PoissionBlur } from \"./PoissionBlur\";\n\nconst bluenoiseBits: Uint8Array = Uint8Array.from(atob(BlueNoise), (c) => c.charCodeAt(0));\n\nexport type RenderModeType = \"Combined\" | \"AO\" | \"No AO\" | \"Split\" | \"Split AO\";\n\ntype PresetsType = \"Performance\" | \"Low\" | \"Medium\" | \"High\" | \"Ultra\";\n\ninterface IConfiguration {\n aoSamples: number;\n aoRadius: number;\n denoiseSamples: number;\n denoiseRadius: number;\n distanceFalloff: number;\n intensity: number;\n denoiseIterations: number;\n renderMode: number;\n color: Color;\n gammaCorrection: boolean;\n logarithmicDepthBuffer: boolean;\n screenSpaceRadius: boolean;\n halfRes: boolean;\n depthAwareUpsampling: boolean;\n colorMultiply: boolean;\n}\n\nfunction checkTimerQuery(\n timerQuery: WebGLQuery,\n gl: WebGL2RenderingContext,\n pass: N8SSAOPass,\n): void {\n const available = gl.getQueryParameter(timerQuery, gl.QUERY_RESULT_AVAILABLE);\n if (available) {\n const elapsedTimeInNs = gl.getQueryParameter(timerQuery, gl.QUERY_RESULT);\n const elapsedTimeInMs = elapsedTimeInNs / 1000000;\n pass.lastTime = elapsedTimeInMs;\n } else {\n setTimeout(() => checkTimerQuery(timerQuery, gl, pass), 1);\n }\n}\n\nclass N8SSAOPass extends Pass {\n private debugMode: boolean;\n\n public scene: Scene;\n public camera: PerspectiveCamera | OrthographicCamera;\n public lastTime: number = 0;\n\n private width: number;\n private height: number;\n\n public configuration: IConfiguration & ProxyHandler<IConfiguration>;\n\n private autosetGamma: boolean = true;\n private samples: Vector3[] = [];\n private samplesR: number[] = [];\n private samplesDenoise: Vector2[] = [];\n\n private copyQuadMaterial: ShaderMaterial = new ShaderMaterial({\n uniforms: { tDiffuse: new Uniform(null) },\n\n depthWrite: false,\n\n vertexShader: /* glsl */ `\n varying vec2 vUv;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(position, 1);\n }\n `,\n\n fragmentShader: /* glsl */ `\n uniform sampler2D tDiffuse;\n varying vec2 vUv;\n void main(void) {\n gl_FragColor = texture2D(tDiffuse, vUv);\n }\n `,\n });\n\n private copyQuad: FullScreenTriangle = new FullScreenTriangle(this.copyQuadMaterial);\n\n private writeTargetInternal: WebGLRenderTarget;\n private readTargetInternal: WebGLRenderTarget;\n private outputTargetInternal: WebGLRenderTarget;\n private depthDownsampleTarget: WebGLRenderTarget | null;\n\n private depthDownsampleQuad: FullScreenTriangle | null;\n private effectShaderQuad: FullScreenTriangle | null;\n private effectCompositerQuad: FullScreenTriangle | null;\n private poissonBlurQuad: FullScreenTriangle | null;\n\n private depthTexture: Texture;\n private bluenoise: DataTexture;\n\n private r: Vector2;\n private c: Color;\n\n constructor(\n scene: Scene,\n camera: PerspectiveCamera | OrthographicCamera,\n width = 512,\n height = 512,\n ) {\n super();\n this.width = width;\n this.height = height;\n\n this.camera = camera;\n this.scene = scene;\n\n this.configuration = new Proxy(\n {\n aoSamples: 16,\n aoRadius: 5.0,\n denoiseSamples: 8,\n denoiseRadius: 12,\n distanceFalloff: 1.0,\n intensity: 5,\n denoiseIterations: 2.0,\n renderMode: 0,\n color: new Color(0, 0, 0),\n gammaCorrection: true,\n logarithmicDepthBuffer: false,\n screenSpaceRadius: false,\n halfRes: false,\n depthAwareUpsampling: true,\n colorMultiply: true,\n },\n {\n set: (target: any, propName: string, value: any) => {\n const oldProp = target[propName];\n target[propName] = value;\n if (propName === \"aoSamples\" && oldProp !== value) {\n this.configureAOPass(this.configuration.logarithmicDepthBuffer);\n }\n if (propName === \"denoiseSamples\" && oldProp !== value) {\n this.configureDenoisePass(this.configuration.logarithmicDepthBuffer);\n }\n if (propName === \"halfRes\" && oldProp !== value) {\n this.configureAOPass(this.configuration.logarithmicDepthBuffer);\n this.configureHalfResTargets();\n this.configureEffectCompositer(this.configuration.logarithmicDepthBuffer);\n this.setSize(this.width, this.height);\n }\n if (propName === \"depthAwareUpsampling\" && oldProp !== value) {\n this.configureEffectCompositer(this.configuration.logarithmicDepthBuffer);\n }\n if (propName === \"gammaCorrection\") {\n this.autosetGamma = false;\n }\n return true;\n },\n },\n );\n\n this.configureEffectCompositer(this.configuration.logarithmicDepthBuffer);\n this.configureSampleDependentPasses();\n this.configureHalfResTargets();\n\n this.writeTargetInternal = new WebGLRenderTarget(this.width, this.height, {\n minFilter: LinearFilter,\n magFilter: LinearFilter,\n depthBuffer: false,\n });\n\n this.readTargetInternal = new WebGLRenderTarget(this.width, this.height, {\n minFilter: LinearFilter,\n magFilter: LinearFilter,\n depthBuffer: false,\n });\n\n this.outputTargetInternal = new WebGLRenderTarget(this.width, this.height, {\n minFilter: LinearFilter,\n magFilter: LinearFilter,\n depthBuffer: false,\n });\n\n this.bluenoise = new DataTexture(bluenoiseBits, 128, 128);\n this.bluenoise.colorSpace = NoColorSpace;\n this.bluenoise.wrapS = RepeatWrapping;\n this.bluenoise.wrapT = RepeatWrapping;\n this.bluenoise.minFilter = NearestFilter;\n this.bluenoise.magFilter = NearestFilter;\n this.bluenoise.needsUpdate = true;\n this.lastTime = 0;\n this.needsDepthTexture = true;\n this.needsSwap = true;\n this.r = new Vector2();\n this.c = new Color();\n }\n\n private configureHalfResTargets(): void {\n if (this.configuration.halfRes) {\n this.depthDownsampleTarget = new WebGLRenderTarget(this.width / 2, this.height / 2, {\n count: 2,\n depthBuffer: false,\n });\n this.depthDownsampleTarget.textures[0].format = RedFormat;\n this.depthDownsampleTarget.textures[0].type = FloatType;\n this.depthDownsampleTarget.textures[0].minFilter = NearestFilter;\n this.depthDownsampleTarget.textures[0].magFilter = NearestFilter;\n this.depthDownsampleTarget.textures[1].format = RGBAFormat;\n this.depthDownsampleTarget.textures[1].type = HalfFloatType;\n this.depthDownsampleTarget.textures[1].minFilter = NearestFilter;\n this.depthDownsampleTarget.textures[1].magFilter = NearestFilter;\n this.depthDownsampleQuad = new FullScreenTriangle(new ShaderMaterial(DepthDownSample));\n } else {\n if (this.depthDownsampleTarget) {\n this.depthDownsampleTarget.dispose();\n this.depthDownsampleTarget = null;\n }\n if (this.depthDownsampleQuad) {\n this.depthDownsampleQuad.dispose();\n this.depthDownsampleQuad = null;\n }\n }\n }\n\n private configureSampleDependentPasses(): void {\n this.configureAOPass(this.configuration.logarithmicDepthBuffer);\n this.configureDenoisePass(this.configuration.logarithmicDepthBuffer);\n }\n\n private configureAOPass(logarithmicDepthBuffer = false): void {\n this.samples = this.generateHemisphereSamples(this.configuration.aoSamples);\n this.samplesR = this.generateHemisphereSamplesR(this.configuration.aoSamples);\n const e = { ...EffectShader };\n e.fragmentShader = e.fragmentShader\n .replace(\"16\", this.configuration.aoSamples.toString())\n .replace(\"16.0\", this.configuration.aoSamples.toString() + \".0\");\n if (logarithmicDepthBuffer) {\n e.fragmentShader = \"#define LOGDEPTH\\n\" + e.fragmentShader;\n }\n if (this.configuration.halfRes) {\n e.fragmentShader = \"#define HALFRES\\n\" + e.fragmentShader;\n }\n if (this.effectShaderQuad) {\n this.effectShaderQuad.material.dispose();\n this.effectShaderQuad.material = new ShaderMaterial(e);\n } else {\n this.effectShaderQuad = new FullScreenTriangle(new ShaderMaterial(e));\n }\n }\n\n private configureDenoisePass(logarithmicDepthBuffer: boolean = false): void {\n this.samplesDenoise = this.generateDenoiseSamples(this.configuration.denoiseSamples, 11);\n const p = { ...PoissionBlur };\n p.fragmentShader = p.fragmentShader.replace(\"16\", this.configuration.denoiseSamples.toString());\n if (logarithmicDepthBuffer) {\n p.fragmentShader = \"#define LOGDEPTH\\n\" + p.fragmentShader;\n }\n if (this.poissonBlurQuad) {\n this.poissonBlurQuad.material.dispose();\n this.poissonBlurQuad.material = new ShaderMaterial(p);\n } else {\n this.poissonBlurQuad = new FullScreenTriangle(new ShaderMaterial(p));\n }\n }\n\n private configureEffectCompositer(logarithmicDepthBuffer: boolean = false): void {\n const e = { ...EffectCompositer };\n\n if (logarithmicDepthBuffer) {\n e.fragmentShader = \"#define LOGDEPTH\\n\" + e.fragmentShader;\n }\n\n if (this.configuration.halfRes && this.configuration.depthAwareUpsampling) {\n e.fragmentShader = \"#define HALFRES\\n\" + e.fragmentShader;\n }\n\n if (this.effectCompositerQuad) {\n this.effectCompositerQuad.material.dispose();\n this.effectCompositerQuad.material = new ShaderMaterial(e);\n } else {\n this.effectCompositerQuad = new FullScreenTriangle(new ShaderMaterial(e));\n }\n }\n\n private generateHemisphereSamples(n: number): Vector3[] {\n const points = [];\n for (let k = 0; k < n; k++) {\n const theta = 2.399963 * k;\n const r = Math.sqrt(k + 0.5) / Math.sqrt(n);\n const x = r * Math.cos(theta);\n const y = r * Math.sin(theta);\n\n const z = Math.sqrt(1 - (x * x + y * y));\n points.push(new Vector3(x, y, z));\n }\n return points;\n }\n\n private generateHemisphereSamplesR(n: number): number[] {\n const samplesR = [];\n for (let i = 0; i < n; i++) {\n samplesR.push((i + 1) / n);\n }\n return samplesR;\n }\n\n private generateDenoiseSamples(numSamples: number, numRings: number): Vector2[] {\n const angleStep = (2 * Math.PI * numRings) / numSamples;\n const invNumSamples = 1.0 / numSamples;\n const radiusStep = invNumSamples;\n const samples = [];\n let radius = invNumSamples;\n let angle = 0;\n for (let i = 0; i < numSamples; i++) {\n samples.push(\n new Vector2(Math.cos(angle), Math.sin(angle)).multiplyScalar(Math.pow(radius, 0.75)),\n );\n radius += radiusStep;\n angle += angleStep;\n }\n return samples;\n }\n\n public setSize(width: number, height: number): void {\n this.width = width;\n this.height = height;\n const c = this.configuration.halfRes ? 0.5 : 1;\n this.writeTargetInternal.setSize(width * c, height * c);\n this.readTargetInternal.setSize(width * c, height * c);\n if (this.configuration.halfRes && this.depthDownsampleTarget) {\n this.depthDownsampleTarget.setSize(width * c, height * c);\n }\n this.outputTargetInternal.setSize(width, height);\n }\n\n public setDepthTexture(depthTexture: DataTexture): void {\n this.depthTexture = depthTexture;\n }\n\n public render(\n renderer: WebGLRenderer,\n inputBuffer: WebGLRenderTarget,\n outputBuffer: WebGLRenderTarget,\n ): void {\n const xrEnabled = renderer.xr.enabled;\n renderer.xr.enabled = false;\n\n let ext: any;\n let timerQuery: WebGLQuery | null = null;\n let gl: WebGL2RenderingContext | WebGLRenderingContext | null = null;\n gl = renderer.getContext();\n\n if (this.debugMode) {\n ext = gl.getExtension(\"EXT_disjoint_timer_query_webgl2\");\n if (ext === null) {\n console.error(\"EXT_disjoint_timer_query_webgl2 not available, disabling debug mode.\");\n this.debugMode = false;\n gl = null;\n }\n }\n\n if (this.debugMode && gl) {\n timerQuery = (gl as WebGL2RenderingContext).createQuery()!;\n (gl as WebGL2RenderingContext).beginQuery(ext.TIME_ELAPSED_EXT, timerQuery);\n }\n\n if (\n renderer.capabilities.logarithmicDepthBuffer !== this.configuration.logarithmicDepthBuffer\n ) {\n this.configuration.logarithmicDepthBuffer = renderer.capabilities.logarithmicDepthBuffer;\n this.configureAOPass(this.configuration.logarithmicDepthBuffer);\n this.configureDenoisePass(this.configuration.logarithmicDepthBuffer);\n this.configureEffectCompositer(this.configuration.logarithmicDepthBuffer);\n }\n\n if (inputBuffer.texture.type !== this.outputTargetInternal.texture.type) {\n this.outputTargetInternal.texture.type = inputBuffer.texture.type;\n this.outputTargetInternal.texture.needsUpdate = true;\n }\n\n this.camera.updateMatrixWorld();\n this.r.set(this.width, this.height);\n let trueRadius = this.configuration.aoRadius;\n\n if (this.configuration.halfRes && this.configuration.screenSpaceRadius) {\n trueRadius *= 0.5;\n }\n\n if (this.configuration.halfRes && this.depthDownsampleQuad) {\n const depthDownsampleUniforms = this.depthDownsampleQuad.material.uniforms;\n renderer.setRenderTarget(this.depthDownsampleTarget);\n depthDownsampleUniforms.sceneDepth.value = this.depthTexture;\n depthDownsampleUniforms.resolution.value = this.r;\n depthDownsampleUniforms.near.value = this.camera.near;\n depthDownsampleUniforms.far.value = this.camera.far;\n depthDownsampleUniforms.projectionMatrixInv.value = this.camera.projectionMatrixInverse;\n depthDownsampleUniforms.viewMatrixInv.value = this.camera.matrixWorld;\n depthDownsampleUniforms.logDepth.value = this.configuration.logarithmicDepthBuffer;\n this.depthDownsampleQuad.render(renderer);\n }\n\n if (!this.effectShaderQuad) return;\n\n const effectShaderUniforms = this.effectShaderQuad.material.uniforms;\n\n effectShaderUniforms.sceneDiffuse.value = inputBuffer.texture;\n effectShaderUniforms.sceneDepth.value = this.configuration.halfRes\n ? this.depthDownsampleTarget!.textures[0]\n : this.depthTexture;\n effectShaderUniforms.sceneNormal.value = this.configuration.halfRes\n ? this.depthDownsampleTarget!.textures[1]\n : null;\n effectShaderUniforms.projMat.value = this.camera.projectionMatrix;\n effectShaderUniforms.viewMat.value = this.camera.matrixWorldInverse;\n effectShaderUniforms.projViewMat.value = this.camera.projectionMatrix\n .clone()\n .multiply(this.camera.matrixWorldInverse.clone());\n effectShaderUniforms.projectionMatrixInv.value = this.camera.projectionMatrixInverse;\n effectShaderUniforms.viewMatrixInv.value = this.camera.matrixWorld;\n effectShaderUniforms.cameraPos.value = this.camera.getWorldPosition(new Vector3());\n effectShaderUniforms.resolution.value = this.configuration.halfRes\n ? this.r\n .clone()\n .multiplyScalar(1 / 2)\n .floor()\n : this.r;\n effectShaderUniforms.time.value = performance.now() / 1000;\n effectShaderUniforms.samples.value = this.samples;\n effectShaderUniforms.samplesR.value = this.samplesR;\n effectShaderUniforms.bluenoise.value = this.bluenoise;\n effectShaderUniforms.radius.value = trueRadius;\n effectShaderUniforms.distanceFalloff.value = this.configuration.distanceFalloff;\n effectShaderUniforms.near.value = this.camera.near;\n effectShaderUniforms.far.value = this.camera.far;\n effectShaderUniforms.logDepth.value = renderer.capabilities.logarithmicDepthBuffer;\n effectShaderUniforms.ortho.value = this.camera instanceof OrthographicCamera;\n effectShaderUniforms.screenSpaceRadius.value = this.configuration.screenSpaceRadius;\n\n // Start the AO\n renderer.setRenderTarget(this.writeTargetInternal);\n this.effectShaderQuad.render(renderer);\n // End the AO\n\n const poissonBlurUniforms = this.poissonBlurQuad!.material.uniforms;\n\n // Start the blur\n for (let i = 0; i < this.configuration.denoiseIterations; i++) {\n if (!poissonBlurUniforms || !this.poissonBlurQuad) return;\n [this.writeTargetInternal, this.readTargetInternal] = [\n this.readTargetInternal,\n this.writeTargetInternal,\n ];\n poissonBlurUniforms.tDiffuse.value = this.readTargetInternal.texture;\n poissonBlurUniforms.sceneDepth.value = this.configuration.halfRes\n ? this.depthDownsampleTarget!.textures[0]\n : this.depthTexture;\n poissonBlurUniforms.projMat.value = this.camera.projectionMatrix;\n poissonBlurUniforms.viewMat.value = this.camera.matrixWorldInverse;\n poissonBlurUniforms.projectionMatrixInv.value = this.camera.projectionMatrixInverse;\n poissonBlurUniforms.viewMatrixInv.value = this.camera.matrixWorld;\n poissonBlurUniforms.cameraPos.value = this.camera.getWorldPosition(new Vector3());\n poissonBlurUniforms.resolution.value = this.configuration.halfRes\n ? this.r\n .clone()\n .multiplyScalar(1 / 2)\n .floor()\n : this.r;\n poissonBlurUniforms.time.value = performance.now() / 1000;\n poissonBlurUniforms.blueNoise.value = this.bluenoise;\n poissonBlurUniforms.radius.value =\n this.configuration.denoiseRadius * (this.configuration.halfRes ? 1 / 2 : 1);\n poissonBlurUniforms.worldRadius.value = trueRadius;\n poissonBlurUniforms.distanceFalloff.value = this.configuration.distanceFalloff;\n poissonBlurUniforms.index.value = i;\n poissonBlurUniforms.poissonDisk.value = this.samplesDenoise;\n poissonBlurUniforms.near.value = this.camera.near;\n poissonBlurUniforms.far.value = this.camera.far;\n poissonBlurUniforms.logDepth.value = renderer.capabilities.logarithmicDepthBuffer;\n poissonBlurUniforms.screenSpaceRadius.value = this.configuration.screenSpaceRadius;\n renderer.setRenderTarget(this.writeTargetInternal);\n this.poissonBlurQuad.render(renderer);\n }\n // End the blur\n\n const effectCompositerUniforms = this.effectCompositerQuad!.material.uniforms;\n\n // Start the composition\n if (!effectCompositerUniforms || !this.effectCompositerQuad) return;\n effectCompositerUniforms.sceneDiffuse.value = inputBuffer.texture;\n effectCompositerUniforms.sceneDepth.value = this.depthTexture;\n effectCompositerUniforms.near.value = this.camera.near;\n effectCompositerUniforms.far.value = this.camera.far;\n effectCompositerUniforms.projectionMatrixInv.value = this.camera.projectionMatrixInverse;\n effectCompositerUniforms.viewMatrixInv.value = this.camera.matrixWorld;\n effectCompositerUniforms.logDepth.value = renderer.capabilities.logarithmicDepthBuffer;\n effectCompositerUniforms.ortho.value = this.camera instanceof OrthographicCamera;\n effectCompositerUniforms.downsampledDepth.value = this.configuration.halfRes\n ? this.depthDownsampleTarget!.textures[0]\n : this.depthTexture;\n effectCompositerUniforms.resolution.value = this.r;\n effectCompositerUniforms.blueNoise.value = this.bluenoise;\n effectCompositerUniforms.intensity.value = this.configuration.intensity;\n effectCompositerUniforms.renderMode.value = this.configuration.renderMode;\n effectCompositerUniforms.screenSpaceRadius.value = this.configuration.screenSpaceRadius;\n effectCompositerUniforms.radius.value = trueRadius;\n effectCompositerUniforms.distanceFalloff.value = this.configuration.distanceFalloff;\n effectCompositerUniforms.gammaCorrection.value = this.autosetGamma\n ? this.renderToScreen\n : this.configuration.gammaCorrection;\n effectCompositerUniforms.tDiffuse.value = this.writeTargetInternal.texture;\n effectCompositerUniforms.color.value = this.c\n .copy(this.configuration.color)\n .convertSRGBToLinear();\n effectCompositerUniforms.colorMultiply.value = this.configuration.colorMultiply;\n effectCompositerUniforms.cameraPos.value = this.camera.getWorldPosition(new Vector3());\n effectCompositerUniforms.fog.value = !!this.scene.fog;\n\n if (this.scene.fog) {\n if (this.scene.fog instanceof Fog && this.scene.fog.isFog === true) {\n effectCompositerUniforms.fogExp.value = false;\n effectCompositerUniforms.fogNear.value = this.scene.fog.near;\n effectCompositerUniforms.fogFar.value = this.scene.fog.far;\n } else if (this.scene.fog instanceof FogExp2) {\n effectCompositerUniforms.fogExp.value = true;\n effectCompositerUniforms.fogDensity.value = this.scene.fog.density;\n } else {\n console.error(`Unsupported fog type ${this.scene.fog.constructor.name} in SSAOPass.`);\n }\n }\n\n renderer.setRenderTarget(this.outputTargetInternal);\n this.effectCompositerQuad.render(renderer);\n renderer.setRenderTarget(this.renderToScreen ? null : outputBuffer);\n this.copyQuad.material.uniforms.tDiffuse.value = this.outputTargetInternal.texture;\n this.copyQuad.render(renderer);\n\n if (this.debugMode && gl && timerQuery) {\n (gl as WebGL2RenderingContext).endQuery(ext.TIME_ELAPSED_EXT);\n checkTimerQuery(timerQuery as WebGLQuery, gl as WebGL2RenderingContext, this);\n }\n\n renderer.xr.enabled = xrEnabled;\n }\n\n public enableDebugMode(): void {\n this.debugMode = true;\n }\n\n public disableDebugMode(): void {\n this.debugMode = false;\n }\n\n public setDisplayMode(mode: \"Combined\" | \"AO\" | \"No AO\" | \"Split\" | \"Split AO\"): void {\n this.configuration.renderMode = [\"Combined\", \"AO\", \"No AO\", \"Split\", \"Split AO\"].indexOf(\n mode,\n ) as number;\n }\n\n public setQualityMode(mode: PresetsType): void {\n if (mode === \"Performance\") {\n this.configuration.aoSamples = 8;\n this.configuration.denoiseSamples = 4;\n this.configuration.denoiseRadius = 12;\n } else if (mode === \"Low\") {\n this.configuration.aoSamples = 16;\n this.configuration.denoiseSamples = 4;\n this.configuration.denoiseRadius = 12;\n } else if (mode === \"Medium\") {\n this.configuration.aoSamples = 16;\n this.configuration.denoiseSamples = 8;\n this.configuration.denoiseRadius = 12;\n } else if (mode === \"High\") {\n this.configuration.aoSamples = 64;\n this.configuration.denoiseSamples = 8;\n this.configuration.denoiseRadius = 6;\n } else if (mode === \"Ultra\") {\n this.configuration.aoSamples = 64;\n this.configuration.denoiseSamples = 16;\n this.configuration.denoiseRadius = 6;\n }\n }\n}\n\nexport { N8SSAOPass };\n", "// Original code from: https://github.com/N8python/n8ao\n\n/* eslint-disable max-len */\nexport const BlueNoise: string =\n \"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\";\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport { Matrix4, Uniform, Vector2 } from \"three\";\n\nconst DepthDownSample = {\n uniforms: {\n sceneDepth: new Uniform(null),\n resolution: new Uniform(new Vector2()),\n near: new Uniform(0.1),\n far: new Uniform(1000.0),\n viewMatrixInv: new Uniform(new Matrix4()),\n projectionMatrixInv: new Uniform(new Matrix4()),\n logDepth: new Uniform(false),\n },\n\n depthWrite: false,\n\n depthTest: false,\n\n vertexShader: /* glsl */ `\n varying vec2 vUv;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(position, 1);\n }`,\n\n fragmentShader: /* glsl */ `\n uniform highp sampler2D sceneDepth;\n uniform vec2 resolution;\n uniform float near;\n uniform float far;\n uniform bool logDepth;\n uniform mat4 viewMatrixInv;\n uniform mat4 projectionMatrixInv;\n varying vec2 vUv;\n\n layout(location = 1) out vec4 gNormal;\n\n vec3 getWorldPosLog(vec3 posS) {\n vec2 uv = posS.xy;\n float z = posS.z;\n float nearZ = near;\n float farZ = far;\n float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;\n vec4 wpos = projectionMatrixInv * clipVec;\n return wpos.xyz / wpos.w;\n }\n\n vec3 getWorldPos(float depth, vec2 coord) {\n if (logDepth) {\n return getWorldPosLog(vec3(coord, depth));\n }\n float z = depth * 2.0 - 1.0;\n vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);\n vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;\n\n vec4 worldSpacePosition = viewSpacePosition;\n worldSpacePosition.xyz /= worldSpacePosition.w;\n\n return worldSpacePosition.xyz;\n }\n\n vec3 computeNormal(vec3 worldPos, vec2 vUv) {\n ivec2 p = ivec2(vUv * resolution);\n float c0 = texelFetch(sceneDepth, p, 0).x;\n float l2 = texelFetch(sceneDepth, p - ivec2(2, 0), 0).x;\n float l1 = texelFetch(sceneDepth, p - ivec2(1, 0), 0).x;\n float r1 = texelFetch(sceneDepth, p + ivec2(1, 0), 0).x;\n float r2 = texelFetch(sceneDepth, p + ivec2(2, 0), 0).x;\n float b2 = texelFetch(sceneDepth, p - ivec2(0, 2), 0).x;\n float b1 = texelFetch(sceneDepth, p - ivec2(0, 1), 0).x;\n float t1 = texelFetch(sceneDepth, p + ivec2(0, 1), 0).x;\n float t2 = texelFetch(sceneDepth, p + ivec2(0, 2), 0).x;\n float dl = abs((2.0 * l1 - l2) - c0);\n float dr = abs((2.0 * r1 - r2) - c0);\n float db = abs((2.0 * b1 - b2) - c0);\n float dt = abs((2.0 * t1 - t2) - c0);\n vec3 ce = getWorldPos(c0, vUv).xyz;\n vec3 dpdx = (\n (dl < dr)\n ? ce - getWorldPos(l1, (vUv - vec2(1.0 / resolution.x, 0.0))).xyz\n : -ce + getWorldPos(r1, (vUv + vec2(1.0 / resolution.x, 0.0))).xyz\n );\n vec3 dpdy = (\n (db < dt)\n ? ce - getWorldPos(b1, (vUv - vec2(0.0, 1.0 / resolution.y))).xyz\n : -ce + getWorldPos(t1, (vUv + vec2(0.0, 1.0 / resolution.y))).xyz\n );\n return normalize(cross(dpdx, dpdy));\n }\n\n void main(void) {\n vec2 uv = vUv - vec2(0.5) / resolution;\n vec2 pixelSize = vec2(1.0) / resolution;\n vec2[] uvSamples = vec2[4](\n uv,\n uv + vec2(pixelSize.x, 0.0),\n uv + vec2(0.0, pixelSize.y),\n uv + pixelSize\n );\n float depth00 = texture2D(sceneDepth, uvSamples[0]).r;\n float depth10 = texture2D(sceneDepth, uvSamples[1]).r;\n float depth01 = texture2D(sceneDepth, uvSamples[2]).r;\n float depth11 = texture2D(sceneDepth, uvSamples[3]).r;\n float minDepth = min(min(depth00, depth10), min(depth01, depth11));\n float maxDepth = max(max(depth00, depth10), max(depth01, depth11));\n float targetDepth = minDepth;\n\n if (mod(gl_FragCoord.x + gl_FragCoord.y, 2.0) > 0.5) { \n targetDepth = maxDepth;\n }\n\n int chosenIndex = 0;\n float[] samples = float[4](depth00, depth10, depth01, depth11);\n\n for(int i = 0; i < 4; ++i) {\n if (samples[i] == targetDepth) {\n chosenIndex = i;\n break;\n }\n }\n\n gl_FragColor = vec4(samples[chosenIndex], 0.0, 0.0, 1.0);\n gNormal = vec4(\n computeNormal(\n getWorldPos(samples[chosenIndex], uvSamples[chosenIndex]), uvSamples[chosenIndex]\n ),\n 0.0\n );\n }`,\n};\n\nexport { DepthDownSample };\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport { Matrix4, Uniform, Vector2, Vector3 } from \"three\";\n\nconst EffectCompositer = {\n uniforms: {\n sceneDiffuse: new Uniform(null),\n sceneDepth: new Uniform(null),\n tDiffuse: new Uniform(null),\n projMat: new Uniform(new Matrix4()),\n viewMat: new Uniform(new Matrix4()),\n projectionMatrixInv: new Uniform(new Matrix4()),\n viewMatrixInv: new Uniform(new Matrix4()),\n cameraPos: new Uniform(new Vector3()),\n resolution: new Uniform(new Vector2()),\n color: new Uniform(new Vector3()),\n blueNoise: new Uniform(null),\n downsampledDepth: new Uniform(null),\n time: new Uniform(0.0),\n intensity: new Uniform(10.0),\n renderMode: new Uniform(0.0),\n gammaCorrection: new Uniform(false),\n logDepth: new Uniform(false),\n ortho: new Uniform(false),\n near: new Uniform(0.1),\n far: new Uniform(1000.0),\n screenSpaceRadius: new Uniform(false),\n radius: new Uniform(0.0),\n distanceFalloff: new Uniform(1.0),\n fog: new Uniform(false),\n fogExp: new Uniform(false),\n fogDensity: new Uniform(0.0),\n fogNear: new Uniform(Infinity),\n fogFar: new Uniform(Infinity),\n colorMultiply: new Uniform(true),\n },\n\n depthWrite: false,\n\n depthTest: false,\n\n vertexShader: /* glsl */ `\n varying vec2 vUv;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(position, 1);\n }`,\n\n fragmentShader: /* glsl */ `\n uniform sampler2D sceneDiffuse;\n uniform highp sampler2D sceneDepth;\n uniform highp sampler2D downsampledDepth;\n uniform sampler2D tDiffuse;\n uniform sampler2D blueNoise;\n uniform vec2 resolution;\n uniform vec3 color;\n uniform mat4 projectionMatrixInv;\n uniform mat4 viewMatrixInv;\n uniform float intensity;\n uniform float renderMode;\n uniform float near;\n uniform float far;\n uniform bool gammaCorrection;\n uniform bool logDepth;\n uniform bool ortho;\n uniform bool screenSpaceRadius;\n uniform bool fog;\n uniform bool fogExp;\n uniform bool colorMultiply;\n uniform float fogDensity;\n uniform float fogNear;\n uniform float fogFar;\n uniform float radius;\n uniform float distanceFalloff;\n uniform vec3 cameraPos;\n varying vec2 vUv;\n\n highp float linearize_depth(highp float d, highp float zNear,highp float zFar) {\n return (zFar * zNear) / (zFar - d * (zFar - zNear));\n }\n \n highp float linearize_depth_ortho(highp float d, highp float nearZ, highp float farZ) {\n return nearZ + (farZ - nearZ) * d;\n }\n\n highp float linearize_depth_log(highp float d, highp float nearZ,highp float farZ) {\n float depth = pow(2.0, d * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n return (\n ortho\n ? linearize_depth_ortho(linDepth, nearZ, farZ)\n : linearize_depth(linDepth, nearZ, farZ)\n );\n }\n\n vec3 getWorldPosLog(vec3 posS) {\n vec2 uv = posS.xy;\n float z = posS.z;\n float nearZ =near;\n float farZ = far;\n float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;\n vec4 wpos = projectionMatrixInv * clipVec;\n return wpos.xyz / wpos.w;\n }\n\n vec3 getWorldPos(float depth, vec2 coord) {\n #ifdef LOGDEPTH\n return getWorldPosLog(vec3(coord, depth));\n #endif\n\n float z = depth * 2.0 - 1.0;\n vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);\n vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;\n\n if (abs(viewSpacePosition.w) < 1e-6) {\n discard;\n }\n\n viewSpacePosition /= viewSpacePosition.w;\n return (viewMatrixInv * viewSpacePosition).xyz;\n }\n\n\n vec3 computeNormal(vec3 worldPos, vec2 vUv) {\n ivec2 p = ivec2(vUv * resolution);\n float c0 = texelFetch(sceneDepth, p, 0).x;\n float l2 = texelFetch(sceneDepth, p - ivec2(2, 0), 0).x;\n float l1 = texelFetch(sceneDepth, p - ivec2(1, 0), 0).x;\n float r1 = texelFetch(sceneDepth, p + ivec2(1, 0), 0).x;\n float r2 = texelFetch(sceneDepth, p + ivec2(2, 0), 0).x;\n float b2 = texelFetch(sceneDepth, p - ivec2(0, 2), 0).x;\n float b1 = texelFetch(sceneDepth, p - ivec2(0, 1), 0).x;\n float t1 = texelFetch(sceneDepth, p + ivec2(0, 1), 0).x;\n float t2 = texelFetch(sceneDepth, p + ivec2(0, 2), 0).x;\n float dl = abs((2.0 * l1 - l2) - c0);\n float dr = abs((2.0 * r1 - r2) - c0);\n float db = abs((2.0 * b1 - b2) - c0);\n float dt = abs((2.0 * t1 - t2) - c0);\n vec3 ce = getWorldPos(c0, vUv).xyz;\n vec3 dpdx = (\n (dl < dr)\n ? ce - getWorldPos(l1, (vUv - vec2(1.0 / resolution.x, 0.0))).xyz\n : -ce + getWorldPos(r1, (vUv + vec2(1.0 / resolution.x, 0.0))).xyz\n );\n vec3 dpdy = (\n (db < dt)\n ? ce - getWorldPos(b1, (vUv - vec2(0.0, 1.0 / resolution.y))).xyz\n : -ce + getWorldPos(t1, (vUv + vec2(0.0, 1.0 / resolution.y))).xyz\n );\n return normalize(cross(dpdx, dpdy));\n }\n\n #include <common>\n #include <dithering_pars_fragment>\n\n void main(void) {\n vec4 sceneTexel = texture2D(sceneDiffuse, vUv);\n float depth = texture2D(sceneDepth, vUv).x;\n \n #ifdef HALFRES \n vec4 texel;\n if (depth == 1.0) {\n texel = vec4(0.0, 0.0, 0.0, 1.0);\n } else {\n vec3 worldPos = getWorldPos(depth, vUv);\n vec3 normal = computeNormal(getWorldPos(depth, vUv), vUv);\n\n float totalWeight = 0.0;\n float radiusToUse = (\n screenSpaceRadius\n ? distance(worldPos, getWorldPos(depth, vUv + vec2(radius, 0.0) / resolution))\n : radius\n );\n float distanceFalloffToUse = (\n screenSpaceRadius\n ? radiusToUse * distanceFalloff\n : distanceFalloff\n );\n for(float x = -1.0; x <= 1.0; x++) {\n for(float y = -1.0; y <= 1.0; y++) {\n vec2 offset = vec2(x, y);\n ivec2 p = ivec2((vUv * resolution * 0.5) + offset);\n vec2 pUv = vec2(p) / (resolution * 0.5);\n float sampleDepth = texelFetch(downsampledDepth,p, 0).x;\n vec4 sampleInfo = texelFetch(tDiffuse, p, 0);\n vec3 normalSample = sampleInfo.xyz * 2.0 - 1.0;\n vec3 worldPosSample = getWorldPos(sampleDepth, pUv);\n float tangentPlaneDist = abs(dot(worldPos - worldPosSample, normal));\n float rangeCheck = exp(\n -1.0 * tangentPlaneDist * (1.0 / distanceFalloffToUse)) * max(dot(normal, normalSample),\n 0.0\n );\n float weight = rangeCheck;\n totalWeight += weight;\n texel += sampleInfo * weight;\n }\n }\n if (totalWeight == 0.0) {\n texel = texture2D(tDiffuse, vUv);\n } else {\n texel /= totalWeight;\n }\n }\n #else\n vec4 texel = texture2D(tDiffuse, vUv);\n #endif\n\n #ifdef LOGDEPTH\n texel.a = clamp(texel.a, 0.0, 1.0);\n if (texel.a == 0.0) {\n texel.a = 1.0;\n }\n #endif\n\n float finalAo = pow(texel.a, intensity);\n float fogFactor;\n float fogDepth = distance(cameraPos, getWorldPos(depth, vUv));\n\n if (fog) {\n if (fogExp) {\n fogFactor = 1.0 - exp(-fogDensity * fogDensity * fogDepth * fogDepth);\n } else {\n fogFactor = smoothstep(fogNear, fogFar, fogDepth);\n }\n }\n\n finalAo = mix(finalAo, 1.0, fogFactor);\n vec3 aoApplied = color * mix(vec3(1.0), sceneTexel.rgb, float(colorMultiply));\n if (renderMode == 0.0) {\n gl_FragColor = vec4( mix(sceneTexel.rgb, aoApplied, 1.0 - finalAo), sceneTexel.a);\n } else if (renderMode == 1.0) {\n gl_FragColor = vec4( mix(vec3(1.0), aoApplied, 1.0 - finalAo), sceneTexel.a);\n } else if (renderMode == 2.0) {\n gl_FragColor = vec4( sceneTexel.rgb, sceneTexel.a);\n } else if (renderMode == 3.0) {\n if (vUv.x < 0.5) {\n gl_FragColor = vec4( sceneTexel.rgb, sceneTexel.a);\n } else if (abs(vUv.x - 0.5) < 1.0 / resolution.x) {\n gl_FragColor = vec4(1.0);\n } else {\n gl_FragColor = vec4(mix(sceneTexel.rgb, aoApplied, 1.0 - finalAo), sceneTexel.a);\n }\n } else if (renderMode == 4.0) {\n if (vUv.x < 0.5) {\n gl_FragColor = vec4( sceneTexel.rgb, sceneTexel.a);\n } else if (abs(vUv.x - 0.5) < 1.0 / resolution.x) {\n gl_FragColor = vec4(1.0);\n } else {\n gl_FragColor = vec4(mix(vec3(1.0), aoApplied, 1.0 - finalAo), sceneTexel.a);\n }\n }\n\n #include <dithering_fragment>\n\n if (gammaCorrection) {\n gl_FragColor = LinearTosRGB(gl_FragColor);\n }\n }\n `,\n};\nexport { EffectCompositer };\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport { Matrix4, Uniform, Vector2, Vector3 } from \"three\";\n\nconst EffectShader = {\n uniforms: {\n sceneDiffuse: new Uniform(null),\n sceneDepth: new Uniform(null),\n sceneNormal: new Uniform(null),\n projMat: new Uniform(new Matrix4()),\n viewMat: new Uniform(new Matrix4()),\n projViewMat: new Uniform(new Matrix4()),\n projectionMatrixInv: new Uniform(new Matrix4()),\n viewMatrixInv: new Uniform(new Matrix4()),\n cameraPos: new Uniform(new Vector3()),\n resolution: new Uniform(new Vector2()),\n time: new Uniform(0.0),\n samples: new Uniform([]),\n samplesR: new Uniform([]),\n bluenoise: new Uniform(null),\n distanceFalloff: new Uniform(1.0),\n radius: new Uniform(5.0),\n near: new Uniform(0.1),\n far: new Uniform(1000.0),\n logDepth: new Uniform(false),\n ortho: new Uniform(false),\n screenSpaceRadius: new Uniform(false),\n },\n\n depthWrite: false,\n\n depthTest: false,\n\n vertexShader: /* glsl */ `\n varying vec2 vUv;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(position, 1);\n }\n `,\n\n fragmentShader: /* glsl */ `\n #define SAMPLES 16\n #define FSAMPLES 16.0\n uniform sampler2D sceneDiffuse;\n uniform highp sampler2D sceneNormal;\n uniform highp sampler2D sceneDepth;\n uniform mat4 projectionMatrixInv;\n uniform mat4 viewMatrixInv;\n uniform mat4 projMat;\n uniform mat4 viewMat;\n uniform mat4 projViewMat;\n uniform vec3 cameraPos;\n uniform vec2 resolution;\n uniform float time;\n uniform vec3[SAMPLES] samples;\n uniform float[SAMPLES] samplesR;\n uniform float radius;\n uniform float distanceFalloff;\n uniform float near;\n uniform float far;\n uniform bool logDepth;\n uniform bool ortho;\n uniform bool screenSpaceRadius;\n uniform sampler2D bluenoise;\n varying vec2 vUv;\n\n highp float linearize_depth(highp float d, highp float zNear,highp float zFar) {\n return (zFar * zNear) / (zFar - d * (zFar - zNear));\n }\n\n highp float linearize_depth_ortho(highp float d, highp float nearZ, highp float farZ) {\n return nearZ + (farZ - nearZ) * d;\n }\n\n highp float linearize_depth_log(highp float d, highp float nearZ,highp float farZ) {\n float depth = pow(2.0, d * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n return (\n ortho\n ? linearize_depth_ortho(linDepth, nearZ, farZ)\n : linearize_depth(linDepth, nearZ, farZ)\n );\n }\n\n vec3 getWorldPosLog(vec3 posS) {\n vec2 uv = posS.xy;\n float z = posS.z;\n float nearZ =near;\n float farZ = far;\n float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;\n vec4 wpos = projectionMatrixInv * clipVec;\n return wpos.xyz / wpos.w;\n }\n\n vec3 getWorldPos(float depth, vec2 coord) {\n #ifdef LOGDEPTH\n return getWorldPosLog(vec3(coord, depth));\n #endif\n float z = depth * 2.0 - 1.0;\n vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);\n vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;\n\n vec4 worldSpacePosition = viewSpacePosition;\n worldSpacePosition.xyz /= worldSpacePosition.w;\n return worldSpacePosition.xyz;\n }\n\n vec3 computeNormal(vec3 worldPos, vec2 vUv) {\n ivec2 p = ivec2(vUv * resolution);\n float c0 = texelFetch(sceneDepth, p, 0).x;\n float l2 = texelFetch(sceneDepth, p - ivec2(2, 0), 0).x;\n float l1 = texelFetch(sceneDepth, p - ivec2(1, 0), 0).x;\n float r1 = texelFetch(sceneDepth, p + ivec2(1, 0), 0).x;\n float r2 = texelFetch(sceneDepth, p + ivec2(2, 0), 0).x;\n float b2 = texelFetch(sceneDepth, p - ivec2(0, 2), 0).x;\n float b1 = texelFetch(sceneDepth, p - ivec2(0, 1), 0).x;\n float t1 = texelFetch(sceneDepth, p + ivec2(0, 1), 0).x;\n float t2 = texelFetch(sceneDepth, p + ivec2(0, 2), 0).x;\n float dl = abs((2.0 * l1 - l2) - c0);\n float dr = abs((2.0 * r1 - r2) - c0);\n float db = abs((2.0 * b1 - b2) - c0);\n float dt = abs((2.0 * t1 - t2) - c0);\n vec3 ce = getWorldPos(c0, vUv).xyz;\n vec3 dpdx = (\n (dl < dr)\n ? ce - getWorldPos(l1, (vUv - vec2(1.0 / resolution.x, 0.0))).xyz\n : -ce + getWorldPos(r1, (vUv + vec2(1.0 / resolution.x, 0.0))).xyz\n );\n vec3 dpdy = (\n (db < dt)\n ? ce - getWorldPos(b1, (vUv - vec2(0.0, 1.0 / resolution.y))).xyz\n : -ce + getWorldPos(t1, (vUv + vec2(0.0, 1.0 / resolution.y))).xyz\n );\n return normalize(cross(dpdx, dpdy));\n }\n\n void main(void) {\n vec4 diffuse = texture2D(sceneDiffuse, vUv);\n float depth = texture2D(sceneDepth, vUv).x;\n\n if (depth == 1.0) {\n gl_FragColor = vec4(vec3(1.0), 1.0);\n return;\n }\n\n vec3 worldPos = getWorldPos(depth, vUv);\n\n #ifdef HALFRES\n vec3 normal = texture2D(sceneNormal, vUv).rgb;\n #else\n vec3 normal = computeNormal(worldPos, vUv);\n #endif\n\n vec4 noise = texture2D(bluenoise, gl_FragCoord.xy / 128.0);\n vec3 randomVec = normalize(noise.rgb * 2.0 - 1.0);\n vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));\n vec3 bitangent = cross(normal, tangent);\n mat3 tbn = mat3(tangent, bitangent, normal);\n float occluded = 0.0;\n float totalWeight = 0.0;\n\n float radiusToUse = (\n screenSpaceRadius\n ? distance(worldPos, getWorldPos(depth, vUv + vec2(radius, 0.0) / resolution))\n : radius\n );\n float distanceFalloffToUse = (\n screenSpaceRadius\n ? radiusToUse * distanceFalloff\n : distanceFalloff\n );\n float bias = (0.1 / near) * fwidth(distance(worldPos, cameraPos)) / radiusToUse;\n for(float i = 0.0; i < FSAMPLES; i++) {\n vec3 sampleDirection = tbn * samples[int(i)];\n float moveAmt = samplesR[int(mod(i + noise.a * FSAMPLES, FSAMPLES))];\n vec3 samplePos = worldPos + radiusToUse * moveAmt * sampleDirection;\n vec4 offset = projMat * vec4(samplePos, 1.0);\n offset.xyz /= offset.w;\n offset.xyz = offset.xyz * 0.5 + 0.5;\n float sampleDepth = textureLod(sceneDepth, offset.xy, 0.0).x;\n #ifdef LOGDEPTH\n float distSample = linearize_depth_log(sampleDepth, near, far);\n #else\n float distSample = (\n ortho\n ? linearize_depth_ortho(sampleDepth, near, far)\n : linearize_depth(sampleDepth, near, far)\n );\n #endif\n float distWorld = (\n ortho\n ? linearize_depth_ortho(offset.z, near, far)\n : linearize_depth(offset.z, near, far)\n );\n float rangeCheck = smoothstep(0.0, 1.0, distanceFalloffToUse / (abs(distSample - distWorld)));\n vec2 diff = gl_FragCoord.xy - ( offset.xy * resolution);\n float weight = dot(sampleDirection, normal);\n occluded += rangeCheck * weight *\n (distSample + bias < distWorld ? 1.0 : 0.0) *\n (\n (\n dot(diff, diff) < 1.0 ||\n (sampleDepth == depth) ||\n (offset.x < 0.0 || offset.x > 1.0 || offset.y < 0.0 || offset.y > 1.0) ? 0.0 : 1.0\n )\n );\n totalWeight += weight;\n }\n float occ = clamp(1.0 - occluded / totalWeight, 0.0, 1.0);\n gl_FragColor = vec4(0.5 + 0.5 * normal, occ);\n }`,\n};\n\nexport { EffectShader };\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport {\n BufferAttribute,\n BufferGeometry,\n Mesh,\n OrthographicCamera,\n ShaderMaterial,\n Sphere,\n WebGLRenderer,\n} from \"three\";\n\nexport class FullScreenTriangle {\n private camera: OrthographicCamera = new OrthographicCamera();\n private geometry: BufferGeometry = new BufferGeometry();\n private mesh: Mesh<BufferGeometry, ShaderMaterial>;\n\n constructor(material: ShaderMaterial) {\n this.geometry.setAttribute(\n \"position\",\n new BufferAttribute(new Float32Array([-1, -1, 3, -1, -1, 3]), 2),\n );\n this.geometry.setAttribute(\"uv\", new BufferAttribute(new Float32Array([0, 0, 2, 0, 0, 2]), 2));\n\n this.geometry.boundingSphere = new Sphere();\n this.geometry.computeBoundingSphere = function () {};\n\n this.mesh = new Mesh(this.geometry, material);\n this.mesh.frustumCulled = false;\n }\n\n get material(): ShaderMaterial {\n return this.mesh.material as ShaderMaterial;\n }\n\n set material(value: ShaderMaterial) {\n this.mesh.material = value;\n }\n\n public render(renderer: WebGLRenderer): void {\n renderer.render(this.mesh, this.camera);\n }\n\n public dispose(): void {\n this.mesh.material.dispose();\n this.mesh.geometry.dispose();\n }\n}\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport { Matrix4, Uniform, Vector2, Vector3 } from \"three\";\n\nexport const PoissionBlur = {\n uniforms: {\n sceneDiffuse: new Uniform(null),\n sceneDepth: new Uniform(null),\n tDiffuse: new Uniform(null),\n projMat: new Uniform(new Matrix4()),\n viewMat: new Uniform(new Matrix4()),\n projectionMatrixInv: new Uniform(new Matrix4()),\n viewMatrixInv: new Uniform(new Matrix4()),\n cameraPos: new Uniform(new Vector3()),\n resolution: new Uniform(new Vector2()),\n time: new Uniform(0.0),\n r: new Uniform(5.0),\n blueNoise: new Uniform(null),\n radius: new Uniform(12.0),\n worldRadius: new Uniform(5.0),\n index: new Uniform(0.0),\n poissonDisk: new Uniform([]),\n distanceFalloff: new Uniform(1.0),\n near: new Uniform(0.1),\n far: new Uniform(1000.0),\n logDepth: new Uniform(false),\n screenSpaceRadius: new Uniform(false),\n },\n\n depthWrite: false,\n\n depthTest: false,\n\n vertexShader: /* glsl */ `\n varying vec2 vUv;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(position, 1.0);\n }`,\n\n fragmentShader: /* glsl */ `\n uniform sampler2D sceneDiffuse;\n uniform highp sampler2D sceneDepth;\n uniform sampler2D tDiffuse;\n uniform sampler2D blueNoise;\n uniform mat4 projectionMatrixInv;\n uniform mat4 viewMatrixInv;\n uniform vec2 resolution;\n uniform float r;\n uniform float radius;\n uniform float worldRadius;\n uniform float index;\n uniform float near;\n uniform float far;\n uniform float distanceFalloff;\n uniform bool logDepth;\n uniform bool screenSpaceRadius;\n varying vec2 vUv;\n\n highp float linearize_depth(highp float d, highp float zNear,highp float zFar) {\n highp float z_n = 2.0 * d - 1.0;\n return 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear));\n }\n\n highp float linearize_depth_log(highp float d, highp float nearZ,highp float farZ) {\n float depth = pow(2.0, d * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n return linearize_depth(linDepth, nearZ, farZ);\n }\n\n highp float linearize_depth_ortho(highp float d, highp float nearZ, highp float farZ) {\n return nearZ + (farZ - nearZ) * d;\n }\n\n vec3 getWorldPosLog(vec3 posS) {\n vec2 uv = posS.xy;\n float z = posS.z;\n float nearZ =near;\n float farZ = far;\n float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;\n vec4 wpos = projectionMatrixInv * clipVec;\n return wpos.xyz / wpos.w;\n }\n\n vec3 getWorldPos(float depth, vec2 coord) {\n #ifdef LOGDEPTH\n return getWorldPosLog(vec3(coord, depth));\n #endif\n\n float z = depth * 2.0 - 1.0;\n vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);\n vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;\n\n vec4 worldSpacePosition = viewSpacePosition;\n worldSpacePosition.xyz /= worldSpacePosition.w;\n return worldSpacePosition.xyz;\n }\n\n #include <common>\n\n #define NUM_SAMPLES 16\n\n uniform vec2 poissonDisk[NUM_SAMPLES];\n\n void main(void) {\n const float pi = acos(-1.0);\n vec2 texelSize = vec2(1.0 / resolution.x, 1.0 / resolution.y);\n vec2 uv = vUv;\n vec4 data = texture2D(tDiffuse, vUv);\n float occlusion = data.a;\n float baseOcc = data.a;\n vec3 normal = data.rgb * 2.0 - 1.0;\n float count = 1.0;\n float d = texture2D(sceneDepth, vUv).x;\n if (d == 1.0) {\n gl_FragColor = data;\n return;\n }\n vec3 worldPos = getWorldPos(d, vUv);\n float size = radius;\n float angle;\n\n if (index == 0.0) {\n angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).x * PI2;\n } else if (index == 1.0) {\n angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).y * PI2;\n } else if (index == 2.0) {\n angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).z * PI2;\n } else {\n angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).w * PI2;\n }\n\n mat2 rotationMatrix = mat2(cos(angle), -sin(angle), sin(angle), cos(angle));\n float radiusToUse = (\n screenSpaceRadius\n ? distance(worldPos, getWorldPos(d, vUv + vec2(worldRadius, 0.0) / resolution))\n : worldRadius\n );\n float distanceFalloffToUse = (\n screenSpaceRadius\n ? radiusToUse * distanceFalloff\n : distanceFalloff\n );\n\n for(int i = 0; i < NUM_SAMPLES; i++) {\n vec2 offset = (rotationMatrix * poissonDisk[i]) * texelSize * size;\n vec4 dataSample = texture2D(tDiffuse, uv + offset);\n float occSample = dataSample.a;\n vec3 normalSample = dataSample.rgb * 2.0 - 1.0;\n float dSample = texture2D(sceneDepth, uv + offset).x;\n vec3 worldPosSample = getWorldPos(dSample, uv + offset);\n float tangentPlaneDist = abs(dot(worldPos - worldPosSample, normal));\n float rangeCheck = (\n (dSample == 1.0)\n ? 0.0\n : exp(\n -1.0 * tangentPlaneDist * (1.0 / distanceFalloffToUse)\n ) * max(dot(normal, normalSample), 0.0) * (1.0 - abs(occSample - baseOcc))\n );\n occlusion += occSample * rangeCheck;\n count += rangeCheck;\n }\n\n if (count > 0.0) {\n occlusion /= count;\n }\n\n #ifdef LOGDEPTH\n occlusion = clamp(occlusion, 0.0, 1.0);\n if (occlusion == 0.0) {\n occlusion = 1.0;\n }\n #endif\n gl_FragColor = vec4(0.5 + 0.5 * normal, occlusion);\n }\n `,\n};\n", "import { Clock } from \"three\";\n\nimport { ease } from \"../helpers/math-helpers\";\n\nexport class TimeManager {\n private clock: Clock = new Clock();\n private roundMagnitude: number = 200000;\n private maxAverageFrames: number = 150;\n private deltaTimes: number[] = [];\n\n private targetAverageDeltaTime: number = 0;\n private lerpedAverageMagDelta: number = 0;\n private fpsUpdateTime: number = 0;\n private framesSinceLastFPSUpdate: number = 0;\n\n public time: number = 0;\n public deltaTime: number = 0;\n public rawDeltaTime: number = 0;\n public smoothDeltaTime: number = 0;\n public frame: number = 0;\n public fps: number = 0;\n public averageFPS: number = 0;\n\n update() {\n this.rawDeltaTime = this.clock.getDelta();\n this.frame++;\n this.time += this.rawDeltaTime;\n this.deltaTimes.push(this.rawDeltaTime);\n\n if (this.deltaTimes.length > this.maxAverageFrames) this.deltaTimes.shift();\n\n this.targetAverageDeltaTime =\n this.deltaTimes.reduce((prev, curr) => prev + curr, 0) / this.deltaTimes.length;\n\n this.lerpedAverageMagDelta += ease(\n this.targetAverageDeltaTime * this.roundMagnitude,\n this.lerpedAverageMagDelta,\n 0.12,\n );\n\n const revertMagnitude = this.lerpedAverageMagDelta / this.roundMagnitude;\n const smoothDT = Math.round(revertMagnitude * this.roundMagnitude) / this.roundMagnitude;\n\n this.smoothDeltaTime = smoothDT > this.rawDeltaTime * 1.75 ? this.rawDeltaTime : smoothDT;\n this.deltaTime = this.smoothDeltaTime;\n\n this.framesSinceLastFPSUpdate++;\n if (this.framesSinceLastFPSUpdate >= 60) {\n this.fps =\n Math.round((this.framesSinceLastFPSUpdate / (this.time - this.fpsUpdateTime)) * 100) / 100;\n\n this.fpsUpdateTime = this.time;\n this.framesSinceLastFPSUpdate = 0;\n }\n }\n}\n", "import { MElement, MMLCollisionTrigger } from \"@mml-io/mml-web\";\nimport {\n Box3,\n BufferGeometry,\n Color,\n DoubleSide,\n Euler,\n Group,\n InstancedMesh,\n Line3,\n LineBasicMaterial,\n Matrix4,\n Mesh,\n MeshBasicMaterial,\n Object3D,\n Quaternion,\n Ray,\n Scene,\n Vector3,\n} from \"three\";\nimport { VertexNormalsHelper } from \"three/examples/jsm/helpers/VertexNormalsHelper.js\";\nimport * as BufferGeometryUtils from \"three/examples/jsm/utils/BufferGeometryUtils.js\";\nimport { MeshBVH, MeshBVHHelper } from \"three-mesh-bvh\";\n\nimport { getRelativePositionAndRotationRelativeToObject } from \"./getRelativePositionAndRotationRelativeToObject\";\n\nexport type CollisionMeshState = {\n matrix: Matrix4;\n source: Group;\n meshBVH: MeshBVH;\n debugGroup?: Group;\n trackCollisions: boolean;\n};\n\nexport class CollisionsManager {\n private debug: boolean = false;\n private scene: Scene;\n private tempVector: Vector3 = new Vector3();\n private tempVector2: Vector3 = new Vector3();\n private tempVector3: Vector3 = new Vector3();\n private tempQuaternion: Quaternion = new Quaternion();\n private tempRay: Ray = new Ray();\n private tempMatrix = new Matrix4();\n private tempMatrix2 = new Matrix4();\n private tempBox = new Box3();\n private tempEuler = new Euler();\n private tempSegment = new Line3();\n private tempSegment2 = new Line3();\n\n public collisionMeshState: Map<Group, CollisionMeshState> = new Map();\n private collisionTrigger: MMLCollisionTrigger<Group>;\n private previouslyCollidingElements: null | Map<\n Group,\n { position: { x: number; y: number; z: number } }\n >;\n\n constructor(scene: Scene) {\n this.scene = scene;\n this.collisionTrigger = MMLCollisionTrigger.init();\n }\n\n public raycastFirst(ray: Ray): [number, Vector3, CollisionMeshState] | null {\n let minimumDistance: number | null = null;\n let minimumHit: CollisionMeshState | null = null;\n let minimumNormal: Vector3 | null = new Vector3();\n for (const [, collisionMeshState] of this.collisionMeshState) {\n this.tempRay.copy(ray).applyMatrix4(this.tempMatrix.copy(collisionMeshState.matrix).invert());\n const hit = collisionMeshState.meshBVH.raycastFirst(this.tempRay, DoubleSide);\n if (hit) {\n this.tempSegment.start.copy(this.tempRay.origin);\n this.tempSegment.end.copy(hit.point);\n this.tempSegment.applyMatrix4(collisionMeshState.matrix);\n const dist = this.tempSegment.distance();\n if (minimumDistance === null || dist < minimumDistance) {\n minimumDistance = dist;\n minimumHit = collisionMeshState;\n minimumNormal = (hit.normal ? minimumNormal.copy(hit.normal) : minimumNormal)\n // Apply the rotation of the mesh to the normal\n .applyQuaternion(this.tempQuaternion.setFromRotationMatrix(collisionMeshState.matrix))\n .normalize();\n }\n }\n }\n if (minimumDistance === null || minimumNormal === null || minimumHit === null) {\n return null;\n }\n return [minimumDistance, minimumNormal, minimumHit];\n }\n\n private createCollisionMeshState(group: Group, trackCollisions: boolean): CollisionMeshState {\n const geometries: Array<BufferGeometry> = [];\n group.updateWorldMatrix(true, false);\n const invertedRootMatrix = this.tempMatrix.copy(group.matrixWorld).invert();\n group.traverse((child: Object3D) => {\n const asMesh = child as Mesh;\n if (asMesh.isMesh) {\n const asInstancedMesh = asMesh as InstancedMesh;\n if (asInstancedMesh.isInstancedMesh) {\n for (let i = 0; i < asInstancedMesh.count; i++) {\n const clonedGeometry = asInstancedMesh.geometry.clone();\n for (const key in clonedGeometry.attributes) {\n if (key !== \"position\") {\n clonedGeometry.deleteAttribute(key);\n }\n }\n clonedGeometry.applyMatrix4(\n this.tempMatrix2.fromArray(asInstancedMesh.instanceMatrix.array, i * 16),\n );\n if (clonedGeometry.index) {\n geometries.push(clonedGeometry.toNonIndexed());\n } else {\n geometries.push(clonedGeometry);\n }\n }\n } else {\n const clonedGeometry = asMesh.geometry.clone();\n asMesh.updateWorldMatrix(true, false);\n for (const key in clonedGeometry.attributes) {\n if (key !== \"position\") {\n clonedGeometry.deleteAttribute(key);\n }\n }\n clonedGeometry.applyMatrix4(\n this.tempMatrix2.multiplyMatrices(invertedRootMatrix, asMesh.matrixWorld),\n );\n if (clonedGeometry.index) {\n geometries.push(clonedGeometry.toNonIndexed());\n } else {\n geometries.push(clonedGeometry);\n }\n }\n }\n });\n\n const newBufferGeometry = BufferGeometryUtils.mergeGeometries(geometries, false);\n newBufferGeometry.computeVertexNormals();\n const meshBVH = new MeshBVH(newBufferGeometry);\n\n const meshState: CollisionMeshState = {\n source: group,\n meshBVH,\n matrix: group.matrixWorld.clone(),\n trackCollisions,\n };\n if (this.debug) {\n // Have to cast to add the boundsTree property to the geometry so that the MeshBVHHelper can find it\n (newBufferGeometry as any).boundsTree = meshBVH;\n\n const wireframeMesh = new Mesh(newBufferGeometry, new MeshBasicMaterial({ wireframe: true }));\n\n const normalsHelper = new VertexNormalsHelper(wireframeMesh, 0.25, 0x00ff00);\n\n const visualizer = new MeshBVHHelper(wireframeMesh, 4);\n (visualizer.edgeMaterial as LineBasicMaterial).color = new Color(\"blue\");\n\n const debugGroup = new Group();\n debugGroup.add(wireframeMesh, normalsHelper, visualizer as unknown as Object3D);\n\n group.matrixWorld.decompose(debugGroup.position, debugGroup.quaternion, debugGroup.scale);\n visualizer.update();\n\n meshState.debugGroup = debugGroup;\n }\n return meshState;\n }\n\n public addMeshesGroup(group: Group, mElement?: MElement): void {\n if (mElement) {\n this.collisionTrigger.addCollider(group, mElement);\n }\n const meshState = this.createCollisionMeshState(group, mElement !== undefined);\n if (meshState.debugGroup) {\n this.scene.add(meshState.debugGroup);\n }\n this.collisionMeshState.set(group, meshState);\n }\n\n public updateMeshesGroup(group: Group): void {\n const meshState = this.collisionMeshState.get(group);\n if (meshState) {\n group.updateWorldMatrix(true, false);\n meshState.matrix.copy(group.matrixWorld);\n if (meshState.debugGroup) {\n group.matrixWorld.decompose(\n meshState.debugGroup.position,\n meshState.debugGroup.quaternion,\n meshState.debugGroup.scale,\n );\n }\n }\n }\n\n public removeMeshesGroup(group: Group): void {\n this.collisionTrigger.removeCollider(group);\n const meshState = this.collisionMeshState.get(group);\n if (meshState) {\n if (meshState.debugGroup) {\n this.scene.remove(meshState.debugGroup);\n }\n this.collisionMeshState.delete(group);\n }\n }\n\n private applyCollider(\n worldBasedCapsuleSegment: Line3,\n capsuleRadius: number,\n meshState: CollisionMeshState,\n ): Vector3 | null {\n // Create a matrix to convert from world-space to mesh-space\n const meshMatrix = this.tempMatrix.copy(meshState.matrix).invert();\n\n // Create the bounding box for the capsule if it were in mesh-space\n const meshRelativeCapsuleBoundingBox = this.tempBox;\n meshRelativeCapsuleBoundingBox.makeEmpty();\n meshRelativeCapsuleBoundingBox.expandByPoint(worldBasedCapsuleSegment.start);\n meshRelativeCapsuleBoundingBox.expandByPoint(worldBasedCapsuleSegment.end);\n meshRelativeCapsuleBoundingBox.min.subScalar(capsuleRadius);\n meshRelativeCapsuleBoundingBox.max.addScalar(capsuleRadius);\n meshRelativeCapsuleBoundingBox.applyMatrix4(meshMatrix);\n // Create a segment/line for the capsule in mesh-space\n const meshRelativeCapsuleSegment = this.tempSegment;\n meshRelativeCapsuleSegment.start.copy(worldBasedCapsuleSegment.start);\n meshRelativeCapsuleSegment.end.copy(worldBasedCapsuleSegment.end);\n meshRelativeCapsuleSegment.applyMatrix4(meshMatrix);\n\n // Keep track of where the segment started in mesh-space so that we can calculate the delta later\n const initialMeshRelativeCapsuleSegmentStart = this.tempVector3.copy(\n meshRelativeCapsuleSegment.start,\n );\n\n let collisionPosition: Vector3 | null = null;\n let currentCollisionDistance: number = -1;\n meshState.meshBVH.shapecast({\n intersectsBounds: (meshBox) => {\n // Determine if this portion of the mesh overlaps with the capsule bounding box and is therefore worth checking\n // all of the triangles within\n return meshBox.intersectsBox(meshRelativeCapsuleBoundingBox);\n },\n intersectsTriangle: (meshTriangle) => {\n const closestPointOnTriangle = this.tempVector;\n const closestPointOnSegment = this.tempVector2;\n // Find the closest point between this triangle and the capsule segment in mesh-space\n meshTriangle.closestPointToSegment(\n meshRelativeCapsuleSegment,\n closestPointOnTriangle,\n closestPointOnSegment,\n );\n // Create a line segment between the closest points\n const intersectionSegment = this.tempSegment2;\n intersectionSegment.start.copy(closestPointOnTriangle);\n intersectionSegment.end.copy(closestPointOnSegment);\n // Calculate the distance between the closest points in mesh-space\n const modelReferenceDistance = intersectionSegment.distance();\n\n // Calculate the distance between the points in world-space\n intersectionSegment.applyMatrix4(meshState.matrix);\n const realDistance = intersectionSegment.distance();\n\n // If the real distance is less than the capsule radius then there is actually a collision between the capsule\n // and the triangle\n if (realDistance < capsuleRadius) {\n if (!collisionPosition) {\n collisionPosition = new Vector3()\n .copy(closestPointOnTriangle)\n .applyMatrix4(meshState.matrix);\n currentCollisionDistance = realDistance;\n } else if (realDistance < currentCollisionDistance) {\n collisionPosition.copy(closestPointOnTriangle).applyMatrix4(meshState.matrix);\n currentCollisionDistance = realDistance;\n }\n // Calculate the ratio between the real distance and the mesh-space distance\n const ratio = realDistance / modelReferenceDistance;\n // Calculate the depth of the collision in world-space\n const realDepth = capsuleRadius - realDistance;\n // Convert that depth back into mesh-space as all calculations during collision are to a mesh-space segment\n const modelDepth = realDepth / ratio;\n\n // Apply a corrective movement to the segment in mesh-space\n const direction = closestPointOnSegment.sub(closestPointOnTriangle).normalize();\n meshRelativeCapsuleSegment.start.addScaledVector(direction, modelDepth);\n meshRelativeCapsuleSegment.end.addScaledVector(direction, modelDepth);\n }\n },\n });\n\n if (collisionPosition) {\n // If there was a collision, calculate the delta between the original mesh-space segment and the now-moved one\n const delta = this.tempVector\n .copy(meshRelativeCapsuleSegment.start)\n .sub(initialMeshRelativeCapsuleSegmentStart);\n\n // Use the matrix for the mesh to convert the delta vector back to world-space (remove the position component of the matrix first to avoid translation)\n this.tempMatrix.copy(meshState.matrix).setPosition(0, 0, 0);\n delta.applyMatrix4(this.tempMatrix);\n\n // There's a possibility that the matrix is invalid (or scale zero) and the delta is NaN - if so, don't apply the delta\n if (!(isNaN(delta.x) && isNaN(delta.y) && isNaN(delta.z))) {\n // Convert the potentially-modified mesh-space segment back to world-space\n worldBasedCapsuleSegment.start.add(delta);\n worldBasedCapsuleSegment.end.add(delta);\n }\n }\n\n return collisionPosition;\n }\n\n public applyColliders(tempSegment: Line3, radius: number) {\n const collidedElements = new Map<\n Group,\n {\n position: { x: number; y: number; z: number };\n }\n >();\n for (const meshState of this.collisionMeshState.values()) {\n const collisionPosition = this.applyCollider(tempSegment, radius, meshState);\n if (collisionPosition && meshState.trackCollisions) {\n const relativePosition = getRelativePositionAndRotationRelativeToObject(\n {\n position: collisionPosition,\n rotation: this.tempEuler.set(0, 0, 0),\n },\n meshState.source,\n );\n collidedElements.set(meshState.source, {\n position: relativePosition.position,\n });\n }\n }\n\n /*\n The reported collisions include elements that were reported in the previous tick to ensure that the case of an\n avatar rising to a negligible distance above the surface and immediately back down onto it does not result in a\n discontinuity in the collision lifecycle. If the element is not colliding in the next frame then it will be\n dropped.\n\n This results in a single tick delay of reporting leave events, but this is a reasonable trade-off to avoid\n flickering collisions.\n */\n const reportedCollidingElements = new Map(collidedElements);\n if (this.previouslyCollidingElements) {\n for (const [element, position] of this.previouslyCollidingElements) {\n if (!reportedCollidingElements.has(element)) {\n reportedCollidingElements.set(element, position);\n }\n }\n }\n\n // Store the elements that were genuinely collided with this tick for the next tick to preserve if they are missed\n this.previouslyCollidingElements = collidedElements;\n this.collisionTrigger.setCurrentCollisions(reportedCollidingElements);\n }\n}\n", "import { PositionAndRotation } from \"@mml-io/mml-web\";\nimport { Euler, Matrix4, Object3D, Quaternion, Vector3 } from \"three\";\n\nconst tempContainerMatrix = new Matrix4();\nconst tempTargetMatrix = new Matrix4();\nconst tempPositionVector = new Vector3();\nconst tempRotationEuler = new Euler();\nconst tempRotationQuaternion = new Quaternion();\nconst tempScaleVector = new Vector3();\n\nexport function getRelativePositionAndRotationRelativeToObject(\n positionAndRotation: PositionAndRotation,\n container: Object3D,\n): PositionAndRotation {\n const { x, y, z } = positionAndRotation.position;\n const { x: rx, y: ry, z: rz } = positionAndRotation.rotation;\n\n container.updateWorldMatrix(true, false);\n tempContainerMatrix.copy(container.matrixWorld).invert();\n\n tempPositionVector.set(x, y, z);\n tempRotationEuler.set(rx, ry, rz);\n tempRotationQuaternion.setFromEuler(tempRotationEuler);\n tempScaleVector.set(1, 1, 1);\n\n tempTargetMatrix.compose(tempPositionVector, tempRotationQuaternion, tempScaleVector);\n tempTargetMatrix.premultiply(tempContainerMatrix);\n tempTargetMatrix.decompose(tempPositionVector, tempRotationQuaternion, tempScaleVector);\n\n tempRotationEuler.setFromQuaternion(tempRotationQuaternion);\n\n // Correct for the container's local scale\n tempPositionVector.multiply(container.scale);\n\n return {\n position: {\n x: tempPositionVector.x,\n y: tempPositionVector.y,\n z: tempPositionVector.z,\n },\n rotation: {\n x: tempRotationEuler.x,\n y: tempRotationEuler.y,\n z: tempRotationEuler.z,\n },\n };\n}\n", "import {\n CanvasTexture,\n FrontSide,\n Group,\n LinearMipMapLinearFilter,\n Mesh,\n MeshStandardMaterial,\n NearestFilter,\n PlaneGeometry,\n RepeatWrapping,\n Texture,\n} from \"three\";\n\n// Create a simple 2x2 checkerboard image\nconst canvas = document.createElement(\"canvas\");\ncanvas.width = 2;\ncanvas.height = 2;\nconst ctx = canvas.getContext(\"2d\")!;\nctx.fillStyle = \"#e0e0e0\";\nctx.fillRect(0, 0, 2, 2);\nctx.fillStyle = \"#606060\";\nctx.fillRect(0, 0, 1, 1);\nctx.fillRect(1, 1, 1, 1);\n\nexport class GroundPlane extends Group {\n private readonly floorSize = 210;\n private readonly floorTexture: Texture | null = null;\n private readonly floorGeometry = new PlaneGeometry(this.floorSize, this.floorSize, 1, 1);\n private readonly floorMaterial: MeshStandardMaterial;\n private readonly floorMesh: Mesh | null = null;\n\n constructor() {\n super();\n\n this.floorMaterial = new MeshStandardMaterial({\n color: 0xffffff,\n side: FrontSide,\n metalness: 0.05,\n roughness: 0.95,\n });\n this.floorMesh = new Mesh(this.floorGeometry, this.floorMaterial);\n this.floorMesh.receiveShadow = true;\n this.floorMesh.rotation.x = Math.PI * -0.5;\n this.add(this.floorMesh);\n\n this.floorTexture = new CanvasTexture(canvas);\n this.floorTexture!.wrapS = RepeatWrapping;\n this.floorTexture!.wrapT = RepeatWrapping;\n this.floorTexture!.magFilter = NearestFilter;\n this.floorTexture!.minFilter = LinearMipMapLinearFilter;\n this.floorTexture!.repeat.set(this.floorSize / 1.5, this.floorSize / 1.5);\n this.floorMaterial.map = this.floorTexture;\n this.floorMaterial.needsUpdate = true;\n }\n}\n", "import { LoadingProgressManager } from \"@mml-io/mml-web\";\n\nexport type LoadingScreenConfig = {\n background?: string;\n backgroundImageUrl?: string;\n backgroundBlurAmount?: number;\n overlayLayers?: Array<{\n overlayImageUrl: string;\n overlayAnchor: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\";\n overlayOffset?: { x: number; y: number };\n }>;\n title?: string;\n subtitle?: string;\n color?: string;\n};\n\nexport class LoadingScreen {\n public readonly element: HTMLDivElement;\n\n private readonly backgroundBlur: HTMLDivElement;\n\n private overlayLayers: HTMLDivElement[] = [];\n\n private loadingBanner: HTMLDivElement;\n private loadingBannerTitle: HTMLDivElement;\n private loadingBannerSubtitle: HTMLDivElement;\n\n private progressBarBackground: HTMLDivElement;\n private progressBarHolder: HTMLDivElement;\n private progressBar: HTMLDivElement;\n private loadingStatusText: HTMLDivElement;\n\n private progressDebugViewHolder: HTMLDivElement;\n private progressDebugView: HTMLDivElement;\n private progressDebugElement: HTMLPreElement;\n\n private debugLabel: HTMLLabelElement;\n private debugCheckbox: HTMLInputElement;\n\n private hasCompleted = false;\n private loadingCallback: () => void;\n private disposed: boolean = false;\n\n constructor(\n private loadingProgressManager: LoadingProgressManager,\n private config?: LoadingScreenConfig,\n ) {\n const defaultBackground = \"linear-gradient(45deg, #28284B 0%, #303056 100%)\";\n this.element = document.createElement(\"div\");\n this.element.id = \"loading-screen\";\n\n this.element.style.position = \"absolute\";\n this.element.style.top = \"0\";\n this.element.style.left = \"0\";\n this.element.style.width = \"100%\";\n this.element.style.height = \"100%\";\n this.element.style.backgroundColor = this.config?.background || defaultBackground;\n this.element.style.background = this.config?.background || defaultBackground;\n this.element.style.zIndex = \"10001\";\n\n this.backgroundBlur = document.createElement(\"div\");\n this.backgroundBlur.id = \"loading-screen-blur\";\n this.backgroundBlur.style.position = \"absolute\";\n this.backgroundBlur.style.top = \"0\";\n this.backgroundBlur.style.left = \"0\";\n this.backgroundBlur.style.width = \"100%\";\n this.backgroundBlur.style.height = \"100%\";\n this.backgroundBlur.style.display = \"flex\";\n if (this.config?.backgroundBlurAmount) {\n this.backgroundBlur.style.backdropFilter = `blur(${this.config.backgroundBlurAmount}px)`;\n }\n this.element.append(this.backgroundBlur);\n\n if (this.config?.backgroundImageUrl) {\n this.element.style.backgroundImage = `url(${this.config.backgroundImageUrl})`;\n this.element.style.backgroundPosition = \"center\";\n this.element.style.backgroundSize = \"cover\";\n }\n\n if (this.config?.overlayLayers) {\n const logLoadError = (imageUrl: string) => {\n console.error(`Failed to load overlay image: ${imageUrl}`);\n };\n\n for (const layer of this.config.overlayLayers) {\n const overlayLayer = document.createElement(\"div\");\n overlayLayer.style.position = \"absolute\";\n overlayLayer.style.background = `url(${layer.overlayImageUrl}) no-repeat`;\n overlayLayer.style.backgroundSize = \"contain\";\n\n const anchor = layer.overlayAnchor;\n const offsetX = layer.overlayOffset?.x || 0;\n const offsetY = layer.overlayOffset?.y || 0;\n\n if (anchor.includes(\"top\")) {\n overlayLayer.style.top = `${offsetY}px`;\n } else if (anchor.includes(\"bottom\")) {\n overlayLayer.style.bottom = `${offsetY}px`;\n }\n\n if (anchor.includes(\"left\")) {\n overlayLayer.style.left = `${offsetX}px`;\n } else if (anchor.includes(\"right\")) {\n overlayLayer.style.right = `${offsetX}px`;\n }\n\n const image = new Image();\n image.src = layer.overlayImageUrl;\n image.onload = () => {\n const naturalWidth = image.naturalWidth;\n const naturalHeight = image.naturalHeight;\n\n overlayLayer.style.width = `${naturalWidth}px`;\n overlayLayer.style.height = `${naturalHeight}px`;\n };\n\n image.onerror = () => logLoadError(layer.overlayImageUrl);\n\n this.overlayLayers.push(overlayLayer);\n this.backgroundBlur.append(overlayLayer);\n }\n }\n\n this.element.style.color = this.config?.color || \"white\";\n\n this.loadingBanner = document.createElement(\"div\");\n this.loadingBanner.style.position = \"absolute\";\n this.loadingBanner.style.display = \"flex\";\n this.loadingBanner.style.flexDirection = \"column\";\n this.loadingBanner.style.left = \"0\";\n this.loadingBanner.style.bottom = \"0\";\n this.loadingBanner.style.padding = \"0\";\n this.loadingBanner.style.width = \"100%\";\n this.loadingBanner.style.justifyContent = \"flex-end\";\n this.backgroundBlur.append(this.loadingBanner);\n\n if (this.config?.title) {\n this.loadingBannerTitle = document.createElement(\"div\");\n this.loadingBannerTitle.textContent = this.config.title;\n this.loadingBannerTitle.style.color = this.config?.color || \"white\";\n this.loadingBannerTitle.style.paddingLeft = \"40px\";\n this.loadingBannerTitle.style.paddingRight = \"40px\";\n this.loadingBannerTitle.style.fontSize = \"42px\";\n this.loadingBannerTitle.style.fontWeight = \"bold\";\n this.loadingBannerTitle.style.fontFamily = \"sans-serif\";\n if (this.config?.background) {\n this.loadingBannerTitle.style.textShadow = `0px 0px 80px ${this.config.background}`;\n }\n this.loadingBanner.append(this.loadingBannerTitle);\n }\n\n if (this.config?.subtitle) {\n this.loadingBannerSubtitle = document.createElement(\"div\");\n this.loadingBannerSubtitle.style.color = this.config?.color || \"white\";\n this.loadingBannerSubtitle.style.paddingLeft = \"40px\";\n this.loadingBannerSubtitle.style.paddingRight = \"40px\";\n this.loadingBannerSubtitle.style.fontSize = \"16px\";\n this.loadingBannerSubtitle.style.fontWeight = \"400\";\n this.loadingBannerSubtitle.style.fontFamily = \"sans-serif\";\n this.loadingBannerSubtitle.style.marginTop = \"12px\";\n if (this.config?.background) {\n this.loadingBannerSubtitle.style.textShadow = `0px 0px 40px ${this.config.background}`;\n }\n\n this.loadingBannerSubtitle.textContent = this.config.subtitle;\n this.loadingBanner.append(this.loadingBannerSubtitle);\n }\n\n this.progressDebugViewHolder = document.createElement(\"div\");\n this.progressDebugViewHolder.style.display = \"none\";\n this.progressDebugViewHolder.style.position = \"absolute\";\n this.progressDebugViewHolder.style.width = \"calc(100% - 80px)\";\n this.progressDebugViewHolder.style.maxHeight = \"calc(100% - 120px)\";\n this.progressDebugViewHolder.style.left = \"40px\";\n this.progressDebugViewHolder.style.bottom = \"60px\";\n this.progressDebugViewHolder.style.alignItems = \"center\";\n this.progressDebugViewHolder.style.justifyContent = \"center\";\n this.progressDebugViewHolder.style.zIndex = \"10003\";\n this.element.append(this.progressDebugViewHolder);\n\n this.progressDebugView = document.createElement(\"div\");\n this.progressDebugView.style.backgroundColor = \"rgba(128, 128, 128, 0.5)\";\n this.progressDebugView.style.border = \"1px solid black\";\n this.progressDebugView.style.borderRadius = \"7px\";\n this.progressDebugView.style.width = \"100%\";\n this.progressDebugView.style.maxWidth = \"100%\";\n this.progressDebugView.style.overflow = \"auto\";\n this.progressDebugViewHolder.append(this.progressDebugView);\n\n this.debugCheckbox = document.createElement(\"input\");\n this.debugCheckbox.type = \"checkbox\";\n this.debugCheckbox.checked = false;\n this.debugCheckbox.addEventListener(\"change\", () => {\n this.progressDebugElement.style.display = this.debugCheckbox.checked ? \"block\" : \"none\";\n this.loadingBannerTitle.style.display = this.debugCheckbox.checked ? \"none\" : \"flex\";\n this.loadingBannerSubtitle.style.display = this.debugCheckbox.checked ? \"none\" : \"flex\";\n if (this.hasCompleted) {\n this.dispose();\n }\n });\n\n this.debugLabel = document.createElement(\"label\");\n this.debugLabel.textContent = \"Debug loading\";\n this.debugLabel.style.fontFamily = \"sans-serif\";\n this.debugLabel.style.padding = \"5px\";\n this.debugLabel.style.display = \"inline-block\";\n this.debugLabel.style.userSelect = \"none\";\n this.debugLabel.append(this.debugCheckbox);\n this.progressDebugView.append(this.debugLabel);\n\n this.progressDebugElement = document.createElement(\"pre\");\n this.progressDebugElement.style.margin = \"0\";\n this.progressDebugElement.style.display = this.debugCheckbox.checked ? \"block\" : \"none\";\n this.progressDebugView.append(this.progressDebugElement);\n\n this.progressBarHolder = document.createElement(\"div\");\n this.progressBarHolder.style.display = \"flex\";\n this.progressBarHolder.style.alignItems = \"start\";\n this.progressBarHolder.style.justifyContent = \"flex-start\";\n this.progressBarHolder.style.width = \"100%\";\n this.progressBarHolder.style.marginLeft = \"40px\";\n this.progressBarHolder.style.marginBottom = \"40px\";\n this.progressBarHolder.style.cursor = \"pointer\";\n this.progressBarHolder.style.marginTop = \"24px\";\n this.loadingBanner.append(this.progressBarHolder);\n\n this.progressBarBackground = document.createElement(\"div\");\n this.progressBarBackground.style.position = \"relative\";\n this.progressBarBackground.style.width = \"80%\";\n this.progressBarBackground.style.maxWidth = \"400px\";\n this.progressBarBackground.style.minWidth = \"240px\";\n this.progressBarBackground.style.backgroundColor = \"rgba(32,32,32, 0.25)\";\n this.progressBarBackground.style.backdropFilter = \"blur(4px)\";\n this.progressBarBackground.style.height = \"16px\";\n this.progressBarBackground.style.lineHeight = \"16px\";\n this.progressBarBackground.style.borderRadius = \"16px\";\n this.progressBarBackground.style.overflow = \"hidden\";\n this.progressBarBackground.addEventListener(\"click\", () => {\n const display = this.progressDebugViewHolder.style.display;\n if (display === \"none\") {\n this.progressDebugViewHolder.style.display = \"flex\";\n } else {\n this.progressDebugViewHolder.style.display = \"none\";\n this.debugCheckbox.checked = false;\n this.progressDebugElement.style.display = this.debugCheckbox.checked ? \"block\" : \"none\";\n this.loadingBannerTitle.style.display = this.debugCheckbox.checked ? \"none\" : \"flex\";\n }\n });\n this.progressBarHolder.append(this.progressBarBackground);\n\n this.progressBar = document.createElement(\"div\");\n this.progressBar.style.position = \"absolute\";\n this.progressBar.style.top = \"0\";\n this.progressBar.style.left = \"0\";\n this.progressBar.style.width = \"0\";\n this.progressBar.style.height = \"100%\";\n this.progressBar.style.pointerEvents = \"none\";\n this.progressBar.style.backgroundColor = this.config?.color || \"#0050a4\";\n this.progressBarBackground.append(this.progressBar);\n\n this.loadingStatusText = document.createElement(\"div\");\n this.loadingStatusText.style.position = \"absolute\";\n this.loadingStatusText.style.top = \"0\";\n this.loadingStatusText.style.left = \"0\";\n this.loadingStatusText.style.width = \"100%\";\n this.loadingStatusText.style.height = \"100%\";\n this.loadingStatusText.style.color = \"rgba(200,200,200,0.9)\";\n this.loadingStatusText.style.fontSize = \"10px\";\n this.loadingStatusText.style.textAlign = \"center\";\n this.loadingStatusText.style.verticalAlign = \"middle\";\n this.loadingStatusText.style.mixBlendMode = \"difference\";\n this.loadingStatusText.style.fontFamily = \"sans-serif\";\n this.loadingStatusText.style.fontWeight = \"bold\";\n this.loadingStatusText.style.userSelect = \"none\";\n this.loadingStatusText.textContent = \"Loading...\";\n this.progressBarBackground.append(this.loadingStatusText);\n\n this.loadingCallback = () => {\n const [loadingRatio, completedLoading] = this.loadingProgressManager.toRatio();\n if (completedLoading) {\n if (!this.hasCompleted) {\n this.hasCompleted = true;\n if (!this.debugCheckbox.checked) {\n this.dispose();\n }\n }\n this.loadingStatusText.textContent = \"Completed\";\n this.progressBar.style.width = \"100%\";\n } else {\n this.loadingStatusText.textContent = `${(loadingRatio * 100).toFixed(2)}%`;\n this.progressBar.style.width = `${loadingRatio * 100}%`;\n }\n this.progressDebugElement.textContent = LoadingProgressManager.LoadingProgressSummaryToString(\n this.loadingProgressManager.toSummary(),\n );\n };\n\n this.loadingProgressManager.addProgressCallback(this.loadingCallback);\n }\n\n public dispose() {\n if (this.disposed) {\n return;\n }\n this.disposed = true;\n this.loadingProgressManager.removeProgressCallback(this.loadingCallback);\n this.element.remove();\n }\n}\n", "export class ErrorScreen {\n public readonly element: HTMLDivElement;\n\n private titleBannerText: HTMLDivElement;\n private messageText: HTMLDivElement;\n\n constructor(title: string, message: string) {\n this.element = document.createElement(\"div\");\n this.element.style.position = \"absolute\";\n this.element.style.top = \"0\";\n this.element.style.left = \"0\";\n this.element.style.display = \"flex\";\n this.element.style.alignItems = \"center\";\n this.element.style.justifyContent = \"center\";\n this.element.style.flexDirection = \"column\";\n this.element.style.width = \"100%\";\n this.element.style.height = \"100%\";\n this.element.style.background = \"linear-gradient(45deg, #111111 0%, #444444 100%)\";\n this.element.style.color = \"white\";\n\n this.titleBannerText = document.createElement(\"div\");\n this.titleBannerText.textContent = title;\n this.titleBannerText.style.fontSize = \"40px\";\n this.titleBannerText.style.fontWeight = \"bold\";\n this.titleBannerText.style.fontFamily = \"sans-serif\";\n this.element.append(this.titleBannerText);\n\n this.messageText = document.createElement(\"div\");\n this.messageText.style.textAlign = \"center\";\n this.messageText.style.fontFamily = \"sans-serif\";\n this.messageText.style.fontWeight = \"bold\";\n this.messageText.textContent = message;\n this.element.append(this.messageText);\n }\n\n public dispose() {\n this.element.remove();\n }\n}\n"],
5
- "mappings": ";AAAA,SAAS,mBAAmB,WAAW,WAAAA,gBAAe;AACtD,SAAS,qBAAqB;;;ACD9B,SAAS,YAAY,SAAS,eAAe;AAEtC,IAAM,uBAAuB,CAAC,OAAe,kBAAkC;AACpF,QAAM,OAAO,MAAM;AACnB,SAAO,KAAK,MAAM,QAAQ,IAAI,IAAI;AACpC;AAEO,IAAM,UAAU,CACrB,QACA,YAAoB,MACP;AACb,QAAM,QAAQ,CAAC;AACf,QAAM,CAAC,IAAI,qBAAqB,OAAO,GAAG,SAAS;AACnD,QAAM,CAAC,IAAI,qBAAqB,OAAO,GAAG,SAAS;AACnD,QAAM,CAAC,IAAI,qBAAqB,OAAO,GAAG,SAAS;AACnD,MAAI,kBAAkB,WAAW,kBAAkB,YAAY;AAC7D,UAAM,CAAC,IAAI,qBAAqB,OAAO,GAAG,SAAS;AAAA,EACrD;AACA,SAAO;AACT;AAEO,IAAM,+BAA+B,CAC1C,QACA,WACA,IACA,OAAe,MACH;AACZ,MAAI,KAAK,EAAG,OAAM;AAClB,QAAM,cAAc,KAAK,MAAM,IAAI,KAAK,KAAK,CAAC;AAC9C,QAAM,QAAQ,KAAK;AACnB,QAAM,QAAQ,KAAK;AACnB,QAAM,eAAe,QAAQ;AAC7B,QAAM,IAAI,KAAK,IAAI,KAAK,IAAI;AAC5B,QAAM,IAAI,KAAK,IAAI,KAAK,IAAI;AAC5B,SAAO,IAAI,QAAQ,GAAG,MAAM,CAAC;AAC/B;AAEO,IAAM,QAAQ,CAAC,GAAW,WAA2B;AAC1D,SAAO,OAAO,EAAE,QAAQ,MAAM,CAAC;AACjC;AAEO,IAAM,OAAO,CAAC,QAAgB,GAAW,WAA2B;AACzE,SAAO,OAAO,SAAS,KAAK,QAAQ,CAAC;AACvC;AAEO,SAAS,MAAM,OAAe,KAAa,KAAqB;AACrE,SAAO,KAAK,IAAI,KAAK,IAAI,OAAO,GAAG,GAAG,GAAG;AAC3C;AAEO,IAAM,QAAQ,CACnB,OACA,UACA,UACA,gBACA,mBACW;AACX,SACE,kBACE,iBAAiB,mBAAmB,QAAQ,aAAc,WAAW;AAE3E;;;ACxDO,IAAM,yBAAN,MAAM,wBAAuB;AAAA,EAA7B;AACL,SAAQ,iBAAmE,oBAAI,IAAI;AAAA;AAAA,EAE5E,IACL,QACA,KACA,UACA,SACM;AACN,WAAO,iBAAiB,KAAK,UAAU,OAAO;AAE9C,QAAI,iBAAiB,KAAK,eAAe,IAAI,MAAM;AACnD,QAAI,mBAAmB,QAAW;AAChC,uBAAiB,oBAAI,IAAI;AACzB,WAAK,eAAe,IAAI,QAAQ,cAAc;AAAA,IAChD;AACA,QAAI,cAAc,eAAe,IAAI,GAAG;AACxC,QAAI,gBAAgB,QAAW;AAC7B,oBAAc,oBAAI,IAAI;AACtB,qBAAe,IAAI,KAAK,WAAW;AAAA,IACrC;AACA,gBAAY,IAAI,QAAQ;AAExB,WAAO;AAAA,EACT;AAAA,EAEO,QAAQ;AACb,SAAK,eAAe,QAAQ,CAAC,QAAQ,WAAW;AAC9C,aAAO,QAAQ,CAAC,aAAa,QAAQ;AACnC,oBAAY,QAAQ,CAAC,iBAAiB;AACpC,iBAAO,oBAAoB,KAAK,YAAY;AAAA,QAC9C,CAAC;AAAA,MACH,CAAC;AAAA,IACH,CAAC;AACD,SAAK,eAAe,MAAM;AAAA,EAC5B;AAAA,EAEA,OAAO,OAAO,SAAkE;AAC9E,UAAM,WAAW,IAAI,wBAAuB;AAC5C,QAAI,YAAY,QAAW;AACzB,cAAQ,QAAQ,CAAC,CAAC,QAAQ,KAAK,cAAc,OAAO,MAAM;AACxD,iBAAS,IAAI,QAAQ,KAAK,cAAc,OAAO;AAAA,MACjD,CAAC;AAAA,IACH;AACA,WAAO;AAAA,EACT;AACF;;;AC7CO,IAAM,YAAY;AAAA,EACvB,iBAAiB;AAAA,EACjB,aAAa;AAAA,EACb,aAAa;AAAA,EACb,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,kBAAkB;AAAA,EAClB,SAAS;AAAA,EACT,WAAW;AAAA,EACX,aAAa;AACf;AAEO,IAAM,aAAa;AAAA,EACxB,iBAAiB,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,IAAI;AAAA,EAC7C,aAAa,EAAE,KAAK,KAAK,KAAK,GAAG,MAAM,IAAI;AAAA,EAC3C,aAAa,EAAE,KAAK,GAAG,KAAK,IAAI,MAAM,IAAI;AAAA,EAC1C,YAAY,EAAE,KAAK,IAAI,KAAK,IAAI,MAAM,EAAE;AAAA,EACxC,QAAQ,EAAE,KAAK,IAAI,KAAK,KAAK,MAAM,EAAE;AAAA,EACrC,QAAQ,EAAE,KAAK,IAAI,KAAK,KAAK,MAAM,EAAE;AAAA,EACrC,SAAS,EAAE,KAAK,MAAM,KAAK,GAAG,MAAM,KAAM;AAAA,EAC1C,WAAW,EAAE,KAAK,MAAO,KAAK,KAAK,MAAM,KAAM;AAAA,EAC/C,aAAa,EAAE,KAAK,GAAK,KAAK,GAAK,MAAM,KAAK;AAChD;AAOO,IAAM,eAAN,MAAmB;AAAA,EAQxB,YAAY,cAAyB,SAAkB,OAAO;AAL9D,SAAQ,UAAmB;AAAA,MACzB,UAAU;AAAA,MACV,KAAK;AAAA,IACP;AAGE,SAAK,SAAS,aAAa,UAAU,EAAE,OAAO,UAAU,UAAU,OAAO,CAAC;AAC1E,SAAK,OAAO,WAAW,KAAK,SAAS,YAAY,EAAE,UAAU,KAAK,CAAC;AACnE,SAAK,OAAO,WAAW,KAAK,SAAS,OAAO,EAAE,UAAU,KAAK,CAAC;AAC9D,SAAK,OAAO,WAAW,WAAW,mBAAmB,WAAW,eAAe;AAC/E,SAAK,OAAO,WAAW,WAAW,eAAe,WAAW,WAAW;AACvE,SAAK,OAAO,WAAW,WAAW,eAAe,WAAW,WAAW;AACvE,SAAK,OAAO,WAAW,WAAW,UAAU,WAAW,MAAM;AAC7D,SAAK,OAAO,WAAW,WAAW,UAAU,WAAW,MAAM;AAC7D,SAAK,OAAO,WAAW,EAAE,kBAAkB,UAAU,iBAAiB,GAAG,kBAAkB;AAC3F,SAAK,OAAO,WAAW,WAAW,WAAW,WAAW,OAAO;AAC/D,SAAK,OAAO,WAAW,WAAW,aAAa,WAAW,SAAS;AACnE,SAAK,OAAO,WAAW,WAAW,eAAe,WAAW,WAAW;AAAA,EACzE;AAAA,EAEO,iBAAiB,eAAoC;AAC1D,SAAK,OAAO,GAAG,UAAU,CAAC,MAA+D;AACvF,YAAM,SAAU,EAAE,OAAe;AACjC,UAAI,CAAC,OAAQ;AACb,cAAQ,QAAQ;AAAA,QACd,KAAK,mBAAmB;AACtB,gBAAM,QAAQ,EAAE;AAChB,wBAAc,kBAAkB;AAChC,wBAAc,WAAW;AACzB,wBAAc,iBAAiB;AAC/B,wBAAc,kBAAkB;AAChC,wBAAc,aAAa;AAC3B;AAAA,QACF;AAAA,QACA,KAAK,eAAe;AAClB,gBAAM,QAAQ,EAAE;AAChB,wBAAc,cAAc;AAC5B,wBAAc,WAAW;AACzB,wBAAc,iBAAiB;AAC/B,wBAAc,kBAAkB;AAChC,wBAAc,aAAa;AAC3B;AAAA,QACF;AAAA,QACA,KAAK,eAAe;AAClB,gBAAM,QAAQ,EAAE;AAChB,wBAAc,cAAc;AAC5B,wBAAc,WAAW;AACzB,wBAAc,iBAAiB;AAC/B,wBAAc,kBAAkB;AAChC,wBAAc,aAAa;AAC3B;AAAA,QACF;AAAA,QACA,KAAK,UAAU;AACb,gBAAM,QAAQ,EAAE;AAChB,wBAAc,SAAS;AACvB,wBAAc,aAAa;AAC3B;AAAA,QACF;AAAA,QACA,KAAK,UAAU;AACb,gBAAM,QAAQ,EAAE;AAChB,wBAAc,SAAS;AACvB,wBAAc,aAAa;AAC3B;AAAA,QACF;AAAA,QACA,KAAK,oBAAoB;AACvB,gBAAM,YAAY,EAAE;AACpB,wBAAc,mBAAmB;AACjC;AAAA,QACF;AAAA,QACA,KAAK,WAAW;AACd,gBAAM,QAAQ,EAAE;AAChB,wBAAc,UAAU;AACxB;AAAA,QACF;AAAA,QACA,KAAK,aAAa;AAChB,gBAAM,QAAQ,EAAE;AAChB,wBAAc,YAAY;AAC1B;AAAA,QACF;AAAA,QACA,KAAK,eAAe;AAClB,gBAAM,QAAQ,EAAE;AAChB,wBAAc,cAAc;AAC5B;AAAA,QACF;AAAA,QACA;AACE;AAAA,MACJ;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEO,OAAO,eAAoC;AAChD,SAAK,QAAQ,WAAW,cAAc,SAAS,QAAQ,CAAC;AACxD,SAAK,QAAQ,MAAM,cAAc,IAAI,QAAQ,CAAC;AAAA,EAChD;AACF;;;ACpIA,IAAI,oBAAoB;AAEjB,SAAS,mBAAmB,QAAiB;AAClD,sBAAoB;AACtB;AAEO,SAAS,qBAAqB;AACnC,SAAO;AACT;;;AJEA,IAAM,uBAAuB;AAC7B,IAAM,wBAAwB;AAC9B,IAAM,uBAAuB;AAEtB,IAAM,gBAAN,MAAoB;AAAA,EA+CzB,YACU,eACA,mBACR,aAAa,KAAK,KAAK,GACvB,eAAe,CAAC,KAAK,KAAK,GAC1B;AAJQ;AACA;AA7CV,SAAQ,qBAA8B;AAEtC,SAAO,kBAA0B,UAAU;AAC3C,SAAO,cAAsB,UAAU;AACvC,SAAO,cAAsB,UAAU;AACvC,SAAO,UAAkB,UAAU;AACnC,SAAO,YAAoB,UAAU;AACrC,SAAO,cAAsB,UAAU;AAEvC,SAAO,aAAqB,UAAU;AACtC,SAAO,SAAiB,UAAU;AAClC,SAAO,SAAiB,UAAU;AAClC,SAAO,mBAA4B,UAAU;AAC7C,SAAO,MAAc,KAAK;AAC1B,SAAQ,YAAoB,KAAK;AAEjC,SAAO,gBAAwB,KAAK,KAAK;AACzC,SAAQ,gBAAwB,KAAK,KAAK;AAE1C,SAAO,WAAmB,KAAK;AAC/B,SAAO,iBAAyB,KAAK;AACrC,SAAO,kBAA0B,KAAK;AAOtC,SAAQ,SAAkB,IAAIC,SAAQ,GAAG,MAAM,CAAC;AAChD,SAAQ,YAAqB;AAM7B,SAAQ,cAAuB,IAAIA,SAAQ;AAC3C,SAAQ,YAAqB;AAC7B,SAAQ,aAAsB,IAAIA,SAAQ;AAC1C,SAAQ,aAAqB;AAC7B,SAAQ,eAAuB;AAE/B,SAAQ,iBAAiB,oBAAI,IAAsC;AAQjE,SAAK,cAAc,MAAM,cAAc;AACvC,SAAK,MAAM;AACX,SAAK,YAAY,KAAK;AACtB,SAAK,QAAQ;AACb,SAAK,cAAc,KAAK;AAExB,UAAM,SAAS,OAAO,aAAa,OAAO;AAE1C,SAAK,SAAS,IAAI,kBAAkB,KAAK,KAAK,QAAQ,KAAK,GAAG;AAC9D,SAAK,OAAO,SAAS,IAAI,GAAG,KAAK,CAAC,KAAK,eAAe;AACtD,SAAK,OAAO,OAAO;AACnB,SAAK,YAAY,IAAI,kBAAkB,KAAK,YAAY,QAAQ,KAAK,GAAG;AACxE,SAAK,UAAU,OAAO;AACtB,SAAK,UAAU,SAAS,KAAK,KAAK,OAAO,QAAQ;AACjD,SAAK,UAAU,OAAO;AAEtB,SAAK,gBAAgB,IAAI,cAAc,KAAK,WAAW,KAAK,aAAa;AACzE,SAAK,cAAc,gBAAgB;AACnC,SAAK,cAAc,gBAAgB;AACnC,SAAK,cAAc,YAAY;AAC/B,SAAK,cAAc,UAAU;AAE7B,SAAK,YAAY,IAAI,UAAU;AAE/B,SAAK,oBAAoB;AAAA,EAC3B;AAAA,EAEQ,sBAA4B;AAClC,SAAK,yBAAyB,uBAAuB,OAAO;AAAA,MAC1D,CAAC,KAAK,eAAe,eAAe,KAAK,cAAc,KAAK,IAAI,CAAC;AAAA,MACjE,CAAC,KAAK,eAAe,gBAAgB,KAAK,iCAAiC,KAAK,IAAI,CAAC;AAAA,MACrF,CAAC,KAAK,eAAe,SAAS,KAAK,aAAa,KAAK,IAAI,CAAC;AAAA,MAC1D,CAAC,KAAK,eAAe,eAAe,KAAK,cAAc,KAAK,IAAI,CAAC;AAAA,MACjE,CAAC,UAAU,aAAa,KAAK,YAAY,KAAK,IAAI,CAAC;AAAA,MACnD,CAAC,UAAU,iBAAiB,KAAK,YAAY,KAAK,IAAI,CAAC;AAAA,MACvD,CAAC,UAAU,eAAe,KAAK,cAAc,KAAK,IAAI,CAAC;AAAA,IACzD,CAAC;AAAA,EACH;AAAA,EAEQ,uBAA6B;AACnC,SAAK,uBAAuB,MAAM;AAAA,EACpC;AAAA,EAEQ,iCAAiC,KAAyB;AAChE,QAAI,eAAe;AACnB,QAAI,gBAAgB;AAAA,EACtB;AAAA,EAEO,eAAe,WAAsB;AAC1C,cAAU,aAAa,IAAI;AAAA,EAC7B;AAAA,EAEQ,cAAc,OAA2B;AAC/C,QAAI,MAAM,WAAW,KAAK,MAAM,WAAW,GAAG;AAG5C,YAAM,cAAc,EAAE,GAAG,MAAM,SAAS,GAAG,MAAM,QAAQ;AACzD,WAAK,eAAe,IAAI,MAAM,WAAW,WAAW;AACpD,eAAS,KAAK,MAAM,SAAS;AAAA,IAC/B;AAAA,EACF;AAAA,EAEQ,YAAY,OAA2B;AAC7C,UAAM,kBAAkB,KAAK,eAAe,IAAI,MAAM,SAAS;AAC/D,QAAI,iBAAiB;AACnB,WAAK,eAAe,OAAO,MAAM,SAAS;AAC1C,UAAI,KAAK,eAAe,SAAS,GAAG;AAClC,iBAAS,KAAK,MAAM,SAAS;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,qCAAwF;AAC9F,UAAM,cAAc,EAAE,GAAG,GAAG,GAAG,EAAE;AACjC,SAAK,eAAe,QAAQ,CAAC,MAAM;AACjC,kBAAY,KAAK,EAAE;AACnB,kBAAY,KAAK,EAAE;AAAA,IACrB,CAAC;AACD,UAAM,KAAK,YAAY,IAAI,KAAK,eAAe;AAC/C,UAAM,KAAK,YAAY,IAAI,KAAK,eAAe;AAE/C,QAAI,iBAAiB;AACrB,SAAK,eAAe,QAAQ,CAAC,MAAM;AACjC,YAAM,WAAW,KAAK,MAAM,EAAE,IAAI,OAAO,KAAK,EAAE,IAAI,OAAO,CAAC;AAC5D,wBAAkB;AAAA,IACpB,CAAC;AACD,WAAO,EAAE,KAAK,EAAE,GAAG,IAAI,GAAG,GAAG,GAAG,QAAQ,iBAAiB,KAAK,eAAe,KAAK;AAAA,EACpF;AAAA,EAEQ,cAAc,OAA2B;AAC/C,QAAI,mBAAmB,GAAG;AACxB;AAAA,IACF;AAEA,UAAM,kBAAkB,KAAK,eAAe,IAAI,MAAM,SAAS;AAC/D,QAAI,iBAAiB;AACnB,YAAM,WAAW,KAAK,mCAAmC;AAGzD,sBAAgB,IAAI,MAAM;AAC1B,sBAAgB,IAAI,MAAM;AAE1B,YAAM,SAAS,KAAK,mCAAmC;AAEvD,YAAM,KAAK,OAAO,IAAI,IAAI,SAAS,IAAI;AACvC,YAAM,KAAK,OAAO,IAAI,IAAI,SAAS,IAAI;AAEvC,YAAM,KAAM,KAAK,KAAK,cAAc,cAAe;AACnD,YAAM,KAAM,KAAK,KAAK,cAAc,eAAgB;AAEpD,UAAI,KAAK,eAAe,OAAO,GAAG;AAChC,cAAM,YAAY,OAAO,SAAS,SAAS;AAC3C,aAAK,KAAK,CAAC,YAAY,oBAAoB;AAAA,MAC7C;AAEA,WAAK,eAAe;AACpB,WAAK,aAAa;AAClB,WAAK,YAAY,KAAK,IAAI,KAAK,eAAe,KAAK,IAAI,KAAK,eAAe,KAAK,SAAS,CAAC;AAC1F,YAAM,eAAe;AAAA,IACvB;AAAA,EACF;AAAA,EAEQ,aAAa,OAAyB;AAC5C,QAAI,mBAAmB,GAAG;AACxB;AAAA,IACF;AACA,UAAM,eAAe;AACrB,UAAM,eAAe,MAAM,SAAS,KAAK,YAAY;AACrD,SAAK,KAAK,YAAY;AAAA,EACxB;AAAA,EAEQ,KAAK,OAAe;AAC1B,SAAK,kBAAkB;AACvB,SAAK,iBAAiB,KAAK;AAAA,MACzB,KAAK;AAAA,MACL,KAAK,IAAI,KAAK,aAAa,KAAK,cAAc;AAAA,IAChD;AACA,SAAK,kBAAkB,KAAK;AAAA,EAC9B;AAAA,EAEQ,cAAc,OAA2B;AAC/C,UAAM,eAAe;AAAA,EACvB;AAAA,EAEO,UAAU,QAAuB;AACtC,QAAI,CAAC,KAAK,WAAW;AACnB,WAAK,OAAO,KAAK,MAAM;AAAA,IACzB,OAAO;AACL,WAAK,YAAY,KAAK,MAAM;AAC5B,WAAK,WAAW,KAAK,KAAK,MAAM;AAChC,WAAK,aAAa;AAAA,IACpB;AAEA,QAAI,CAAC,KAAK,WAAW;AACnB,WAAK,YAAY;AACjB,WAAK,2BAA2B;AAAA,IAClC;AAAA,EACF;AAAA,EAEO,gBAAgB,QAAiB,gBAA8B;AACpE,SAAK,YAAY;AACjB,SAAK,iBAAiB;AACtB,SAAK,kBAAkB;AACvB,SAAK,UAAU,MAAM;AAAA,EACvB;AAAA,EAEO,6BAAmC;AACxC,UAAM,KAAK,KAAK,OAAO,SAAS,IAAI,KAAK,OAAO;AAChD,UAAM,KAAK,KAAK,OAAO,SAAS,IAAI,KAAK,OAAO;AAChD,UAAM,KAAK,KAAK,OAAO,SAAS,IAAI,KAAK,OAAO;AAChD,SAAK,iBAAiB,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE;AAC3D,SAAK,WAAW,KAAK;AACrB,SAAK,kBAAkB,KAAK;AAC5B,SAAK,QAAQ,KAAK,MAAM,IAAI,EAAE;AAC9B,SAAK,cAAc,KAAK;AACxB,SAAK,MAAM,KAAK,KAAK,KAAK,KAAK,cAAc;AAC7C,SAAK,YAAY,KAAK;AACtB,SAAK,aAAa,IAAI;AAAA,EACxB;AAAA,EAEO,uBAA6B;AAClC,UAAM,iBAAiB;AACvB,UAAM,SAAS,IAAIA,SAAQ,GAAG,GAAG,cAAc;AAC/C,WAAO,WAAW,KAAK,OAAO,QAAQ;AACtC,UAAM,YAAY,KAAK,OAAO,SAAS,MAAM,EAAE,IAAI,MAAM;AACzD,UAAM,eAAe,UAAU,IAAI,KAAK,OAAO,MAAM,CAAC,EAAE,UAAU;AAElE,SAAK,UAAU,IAAI,KAAK,OAAO,MAAM,GAAG,YAAY;AACpD,UAAM,kBAAkB,KAAK,kBAAkB,aAAa,KAAK,UAAU,GAAG;AAE9E,QAAI,oBAAoB,QAAQ,gBAAgB,CAAC,KAAK,KAAK,iBAAiB;AAC1E,YAAM,sBAAsB,gBAAgB,CAAC,IAAI;AACjD,WAAK,iBAAiB;AACtB,WAAK,WAAW;AAAA,IAClB,OAAO;AACL,WAAK,iBAAiB,KAAK;AAAA,IAC7B;AAAA,EACF;AAAA,EAEO,UAAU;AACf,SAAK,qBAAqB;AAC1B,SAAK,cAAc,QAAQ;AAC3B,aAAS,KAAK,MAAM,SAAS;AAAA,EAC/B;AAAA,EAEQ,YAAY,GAAmB;AACrC,WAAO,MAAM,IAAI,IAAI,IAAI,KAAK,IAAI,GAAG,MAAM,CAAC;AAAA,EAC9C;AAAA,EAEO,aAAa,QAAsB;AACxC,SAAK,OAAO,SAAS;AACrB,SAAK,UAAU,SAAS;AAAA,EAC1B;AAAA,EAEO,aAAa,cAAuB,OAAa;AACtD,SAAK,YAAY;AAAA,MACf,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,mBAAmB,KAAK,SAAS,KAAK;AAAA,MAC3C,KAAK,mBAAmB,KAAK,SAAS,KAAK;AAAA,IAC7C;AACA,QAAI,aAAa;AACf,WAAK,MAAM,KAAK;AAAA,IAClB;AAAA,EACF;AAAA,EAEO,kBAAwB;AAC7B,SAAK,qBAAqB,CAAC,KAAK;AAChC,SAAK,cAAc,UAAU,CAAC,KAAK;AAEnC,QAAI,CAAC,KAAK,oBAAoB;AAC5B,WAAK,aAAa,OAAO,aAAa,OAAO,WAAW;AACxD,WAAK,UAAU,SAAS,KAAK,KAAK,OAAO,QAAQ;AACjD,WAAK,UAAU,SAAS,KAAK,KAAK,OAAO,QAAQ;AACjD,YAAM,SAAS,IAAIA,SAAQ;AAC3B,WAAK,OAAO,kBAAkB,MAAM;AACpC,aAAO,eAAe,KAAK,cAAc,EAAE,IAAI,KAAK,OAAO,QAAQ;AACnE,WAAK,cAAc,OAAO,KAAK,MAAM;AACrC,WAAK,cAAc,OAAO;AAC1B,WAAK,qBAAqB;AAAA,IAC5B,OAAO;AACL,WAAK,oBAAoB;AAAA,IAC3B;AAAA,EACF;AAAA,EAEA,IAAI,eAAkC;AACpC,WAAO,KAAK,qBAAqB,KAAK,SAAS,KAAK;AAAA,EACtD;AAAA,EAEO,SAAe;AACpB,QAAI,CAAC,KAAK,oBAAoB;AAC5B,WAAK,cAAc,OAAO;AAC1B;AAAA,IACF;AACA,QAAI,KAAK,aAAa,KAAK,aAAa,GAAG;AACzC,WAAK,cAAc,OAAO,KAAK;AAC/B,WAAK,aAAa,KAAK,IAAI,GAAG,KAAK,UAAU;AAC7C,WAAK,OAAO,YAAY,KAAK,YAAY,KAAK,aAAa,KAAK,YAAY,KAAK,UAAU,CAAC;AAAA,IAC9F,OAAO;AACL,WAAK,qBAAqB;AAAA,IAC5B;AAEA,SAAK,aAAa,KAAK,iBAAiB,KAAK,YAAY,KAAK;AAE9D,SAAK,UAAU,KAAK,cAAc,KAAK,SAAS,KAAK;AACrD,SAAK,QAAQ,KAAK,YAAY,KAAK,OAAO,KAAK;AAE/C,UAAM,IAAI,KAAK,OAAO,IAAI,KAAK,WAAW,KAAK,IAAI,KAAK,GAAG,IAAI,KAAK,IAAI,KAAK,KAAK;AAClF,UAAM,IAAI,KAAK,OAAO,IAAI,KAAK,WAAW,KAAK,IAAI,KAAK,GAAG;AAC3D,UAAM,IAAI,KAAK,OAAO,IAAI,KAAK,WAAW,KAAK,IAAI,KAAK,GAAG,IAAI,KAAK,IAAI,KAAK,KAAK;AAElF,SAAK,aAAa;AAClB,SAAK,QAAQ,KAAK,YAAY,KAAK,OAAO,KAAK;AAC/C,SAAK,OAAO,MAAM,KAAK;AACvB,SAAK,OAAO,uBAAuB;AAEnC,SAAK,OAAO,SAAS,IAAI,GAAG,GAAG,CAAC;AAChC,SAAK,OAAO,OAAO,KAAK,MAAM;AAE9B,QAAI,KAAK,aAAa,KAAK,cAAc,GAAG;AAC1C,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AAAA,EAEO,iBAA0B;AAC/B,WAAO,KAAK,eAAe,OAAO;AAAA,EACpC;AACF;;;AKnWA,SAAS,SAAAC,QAAO,OAAO,WAAAC,gBAAe;;;ACAtC;AAAA,EACE;AAAA,EAEA;AAAA,OACK;AACP,SAAS,mBAAmB;AAC5B;AAAA,EAEE;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EAKA,WAAAC;AAAA,OACK;;;AClBP,SAAS,OAAO,sBAAsB,qBAAqB;;;ACApD,IAAM;AAAA;AAAA,EAAiC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAvC,SAAS,iBAAiB,cAAsB,cAA8B;AACnF,SAAO,aAAa;AAAA,IAClB;AAAA,IACA;AAAA;AAAA,EAEF,YAAY;AAAA;AAAA;AAAA,EAGZ;AACF;AAEO,SAAS,iBAAiB,cAAsB,cAA8B;AACnF,SAAO,aAAa;AAAA,IAClB;AAAA,IACA;AAAA;AAAA,EAEF,YAAY;AAAA;AAAA;AAAA,EAGZ;AACF;AAEO,SAAS,aAAa,cAAsB,QAAgB,cAA8B;AAC/F,SAAO,aAAa;AAAA,IAClB;AAAA,IACA;AAAA,EACF,YAAY;AAAA;AAAA,EAEZ,MAAM;AAAA;AAAA,EAEN;AACF;;;AC5BO,IAAM,kBAAkB;AAAA,EAC7B,WAAW;AAAA,EACX,WAAW;AAAA,EACX,UAAU,EAAE,GAAG,GAAK,GAAG,GAAK,GAAG,EAAI;AAAA,EACnC,mBAAmB;AAAA,EACnB,iBAAiB;AACnB;AAEA,IAAM,mBAAmB;AAAA,EACvB,WAAW,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AAAA,EACxC,WAAW,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AAAA,EACxC,mBAAmB,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AAAA,EAChD,iBAAiB,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AAChD;AAEO,IAAM,kBAAN,MAAsB;AAAA,EAE3B,YAAY,cAAyB,SAAkB,OAAO;AAC5D,SAAK,SAAS,aAAa,UAAU,EAAE,OAAO,qBAAqB,UAAU,OAAO,CAAC;AACrF,SAAK,OAAO,WAAW,iBAAiB,aAAa,iBAAiB,SAAS;AAC/E,SAAK,OAAO,WAAW,iBAAiB,aAAa,iBAAiB,SAAS;AAC/E,SAAK,OAAO,WAAW,iBAAiB,YAAY;AAAA,MAClD,OAAO,EAAE,MAAM,QAAQ;AAAA,IACzB,CAAC;AACD,SAAK,OAAO;AAAA,MACV;AAAA,MACA;AAAA,MACA,iBAAiB;AAAA,IACnB;AACA,SAAK,OAAO,WAAW,iBAAiB,mBAAmB,iBAAiB,eAAe;AAAA,EAC7F;AAAA,EAEO,mBAAyB;AAC9B,SAAK,OAAO,GAAG,UAAU,CAAC,MAA+D;AACvF,YAAM,SAAU,EAAE,OAAe;AACjC,UAAI,CAAC,OAAQ;AACb,cAAQ,QAAQ;AAAA,QACd,KAAK,YAAY;AACf,gBAAM,QAAQ,EAAE;AAChB,0BAAgB,WAAW;AAAA,YACzB,GAAG,MAAM;AAAA,YACT,GAAG,MAAM;AAAA,YACT,GAAG,MAAM;AAAA,UACX;AACA;AAAA,QACF;AAAA,QACA,SAAS;AACP;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AHjCO,IAAM,oBAAN,cAAgC,qBAAqB;AAAA,EAU1D,YAAoB,QAAiC;AACnD,UAAM;AADY;AATpB,SAAQ,WAAqC;AAAA,MAC3C,YAAY,EAAE,OAAO,EAAE;AAAA,MACvB,cAAc,EAAE,OAAO,IAAI,MAAM,EAAE;AAAA,MACnC,KAAK,EAAE,OAAO,KAAK;AAAA,IACrB;AACA,SAAQ,gBAAyB,CAAC;AAClC,SAAQ,cAAsB;AAC9B,SAAQ,eAAuB;AAI7B,SAAK,KAAK,KAAK,OAAO,gBAAgB;AACtC,SAAK,kBAAkB;AAEvB,SAAK,QAAQ,KAAK,OAAO,iBAAiB,KAAK,cAAc,KAAK,OAAO,WAAW;AACpF,SAAK,kBAAkB,gBAAgB;AACvC,SAAK,cAAc;AACnB,SAAK,OAAO,KAAK,OAAO,iBAAiB;AAEzC,SAAK,kBAAkB,CAAC,WAAW;AACjC,WAAK,WAAW,cAAc,MAAM,OAAO,QAAQ;AACnD,WAAK,SAAS,WAAW,EAAE,OAAO,KAAK;AACvC,WAAK,SAAS,UAAU,EAAE,OAAO,IAAO;AACxC,WAAK,SAAS,gBAAgB,EAAE,OAAO,IAAI;AAC3C,WAAK,SAAS,iBAAiB,EAAE,OAAO,IAAI;AAC5C,WAAK,SAAS,OAAO,EAAE,OAAO,EAAI;AAClC,WAAK,SAAS,qBAAqB,EAAE,OAAO,IAAI,MAAM,EAAE;AACxD,WAAK,SAAS,aAAa,EAAE,OAAO,EAAE;AACtC,aAAO,WAAW,KAAK;AAEvB,aAAO,eAAe,mCAAmC,OAAO;AAChE,aAAO,eAAe,OAAO,aAAa;AAAA,QACxC;AAAA,QACA;AAAA,MACF;AACA,aAAO,eAAe,iBAAiB,OAAO,cAAc,mBAAmB;AAC/E,aAAO,eAAe,iBAAiB,OAAO,cAAc,WAAW;AAEvE,aAAO,iBAAiB;AAAA,QACtB,OAAO;AAAA;AAAA,QACI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,YAUP,WAAW;AAAA;AAAA,MAEjB;AAEA,aAAO,iBAAiB;AAAA,QACtB,OAAO;AAAA,QACP;AAAA;AAAA,QACW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAqBb;AAAA,IACF;AACA,SAAK,cAAc;AAAA,EACrB;AAAA,EAEQ,oBAAoB;AAC1B,UAAM,aAAa;AACnB,UAAM,YAAY;AAClB,UAAM,uBAAuB;AAC7B,QAAI,MAAM;AAEV,aAAS,IAAI,GAAG,IAAI,KAAK,KAAK;AAC5B,YAAM,QAAQ,IAAI,MAAM;AACxB,YAAM,OAAO,KAAK,YAAY,SAAS;AACvC,WAAK,cAAc,KAAK,KAAK;AAC7B,aAAO,MAAM,wBAAwB;AAAA,IACvC;AAAA,EACF;AAAA,EAEO,SAAS;AACd,QAAI,KAAK,OAAO,SAAS;AACvB,WAAK,cAAc,KAAK,OAAO,cAAc,WAAW,MAAM,IAAM;AACpE,WAAK,gBAAgB,KAAK,KAAK,aAAa,KAAK,cAAc,IAAI;AACnE,UAAI,KAAK,eAAe,OAAO;AAC7B,aAAK,eAAe;AACpB,aAAK,OAAO,cAAc,gBAAgB,KAAK,KAAK;AAAA,MACtD;AACA,UAAI,KAAK,eAAe,MAAO;AAC7B,aAAK,eAAe;AACpB,aAAK,OAAO,cAAc,gBAAgB,KAAK,KAAK;AAAA,MACtD;AACA,WAAK,SAAS,WAAW,QAAQ,KAAK,iBAAiB,IAAI,IAAI;AAC/D,UAAI,KAAK,iBAAiB,KAAK,SAAS;AACtC,aAAK,UAAU,KAAK;AAAA,MACtB;AAAA,IACF;AACA,SAAK,YAAY,gBAAgB;AACjC,SAAK,YAAY,gBAAgB;AACjC,SAAK,WAAW,IAAI,MAAM,EAAE;AAAA,MAC1B,gBAAgB,SAAS;AAAA,MACzB,gBAAgB,SAAS;AAAA,MACzB,gBAAgB,SAAS;AAAA,IAC3B;AACA,SAAK,oBAAoB,gBAAgB;AACzC,SAAK,kBAAkB,gBAAgB;AAAA,EACzC;AACF;;;AInJO,IAAK,iBAAL,kBAAKC,oBAAL;AACL,EAAAA,gCAAA,UAAS,KAAT;AACA,EAAAA,gCAAA,aAAY,KAAZ;AACA,EAAAA,gCAAA,aAAY,KAAZ;AACA,EAAAA,gCAAA,eAAc,KAAd;AACA,EAAAA,gCAAA,SAAQ,KAAR;AACA,EAAAA,gCAAA,iBAAgB,KAAhB;AACA,EAAAA,gCAAA,gBAAe,KAAf;AAPU,SAAAA;AAAA,GAAA;;;ALoCL,IAAM,kBAAN,MAAM,gBAAe;AAAA,EAiB1B,YAAoB,QAA8B;AAA9B;AAdpB,SAAO,OAAwB;AAC/B,SAAO,WAAwB;AAC/B,SAAO,kBAAiC;AAExC,SAAQ,YAA4C,oBAAI,IAAI;AAE5D,SAAO,aAA8C,CAAC;AACtD,SAAO,iBAAwC;AAC/C,SAAO;AAIP,SAAQ,mBAAmB;AAAA,EAEwB;AAAA,EAEnD,MAAa,OAAsB;AACjC,UAAM,KAAK,aAAa;AACxB,QAAI,KAAK,MAAM;AACb,YAAM,KAAK;AAAA,QACT,KAAK,OAAO,gBAAgB;AAAA;AAAA,QAE5B;AAAA,MACF;AACA,YAAM,KAAK;AAAA,QACT,KAAK,OAAO,gBAAgB;AAAA;AAAA,QAE5B;AAAA,MACF;AACA,YAAM,KAAK;AAAA,QACT,KAAK,OAAO,gBAAgB;AAAA;AAAA,QAE5B;AAAA,MACF;AACA,YAAM,KAAK;AAAA,QACT,KAAK,OAAO,gBAAgB;AAAA;AAAA,QAE5B;AAAA,MACF;AACA,YAAM,KAAK;AAAA,QACT,KAAK,OAAO,gBAAgB;AAAA;AAAA,QAE5B;AAAA,QACA;AAAA,MACF;AACA,WAAK,qBAAqB;AAAA,IAC5B;AAAA,EACF;AAAA,EAEQ,uBAA6B;AACnC,QAAI,CAAC,KAAK,KAAM;AAChB,UAAM,cAAc,IAAI,KAAK;AAC7B,SAAK,KAAK,kBAAkB,MAAM,IAAI;AACtC,gBAAY,eAAe,KAAK,IAAI;AACpC,SAAK,kBAAkB,YAAY,IAAI,IAAI,YAAY,IAAI;AAE3D,SAAK,KAAK,SAAS,CAAC,UAAoB;AACtC,UAAK,MAAe,QAAQ;AAC1B,YAAI,MAAM,SAAS,QAAQ;AACzB,gBAAM,gBAAgB,IAAIC,SAAQ;AAClC,eAAK,WAAW;AAChB,eAAK,SAAS,iBAAiB,aAAa;AAAA,QAC9C;AAAA,MACF;AACA,UAAK,MAAe,UAAW,MAAsB,eAAe;AAClE,cAAM,SAAS;AACf,cAAM,mBAAmB,OAAO;AAChC,YAAI,KAAK,UAAU,IAAI,iBAAiB,IAAI,GAAG;AAC7C,iBAAO,WAAW,KAAK,UAAU,IAAI,iBAAiB,IAAI;AAAA,QAC5D,OAAO;AACL,gBAAM,WACJ,iBAAiB,SAAS,2BACtB,IAAI,kBAAkB;AAAA,YACpB,SAAS,KAAK,OAAO;AAAA,YACrB,eAAe,KAAK,OAAO;AAAA,YAC3B,aAAa,KAAK,OAAO;AAAA,YACzB;AAAA,UACF,CAAC,IACD,IAAI,kBAAkB;AAAA,YACpB,SAAS,KAAK,OAAO;AAAA,YACrB,eAAe,KAAK,OAAO;AAAA,YAC3B,aAAa,KAAK,OAAO;AAAA,YACzB;AAAA,YACA,eAAe,iBAAiB;AAAA,UAClC,CAAC;AACP,eAAK,UAAU,IAAI,iBAAiB,MAAM,QAAQ;AAClD,iBAAO,WAAW;AAAA,QACpB;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEO,gBAAgB,iBAAiC;AACtD,QAAI,KAAK,kBAAkB;AACzB,UAAI,wCAA+C;AAEjD;AAAA,MACF,OAAO;AAEL,aAAK,mBAAmB;AAAA,MAC1B;AAAA,IACF;AACA,QAAI,KAAK,qBAAqB,iBAAiB;AAC7C,WAAK,sBAAsB,eAAe;AAAA,IAC5C;AAAA,EACF;AAAA,EAEQ,YAAY,UAA0B;AAC5C,SAAK,OAAO;AACZ,SAAK,KAAK,SAAS,IAAI,GAAG,OAAO,CAAC;AAClC,SAAK,KAAK,SAAS,CAAC,UAAoB;AACtC,UAAI,MAAM,SAAS,eAAe;AAChC,cAAM,aAAa;AACnB,cAAM,gBAAgB;AAAA,MACxB;AAAA,IACF,CAAC;AACD,SAAK,iBAAiB,IAAI,eAAe,KAAK,IAAI;AAAA,EACpD;AAAA,EAEA,MAAc,oBACZ,yBAC+B;AAhKnC;AAiKI,UAAI,6BAAwB,SAAxB,mBAA8B,IAAI,YAAW,GAAG;AAClD,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,QAAI,kBAAmC;AACvC,QAAI,yBAAyB;AAC3B,YAAM,kBAAgB,6BAAwB,SAAxB,mBAA8B,QAAO;AAC3D,UAAI,eAAe;AACjB,aAAK,0BAA0B;AAC/B,cAAM,eAAe,IAAI,aAAa,gBAAe,WAAW;AAChE,0BAAkB,MAAM,aAAa;AAAA,UACnC;AAAA,UACA,wBAAwB;AAAA,QAC1B;AACA,YAAI,iBAAiB;AACnB,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,+BAAyD;AACrE,QAAI,KAAK,OAAO,qBAAqB,aAAa;AAChD,aACG,MAAM,KAAK,OAAO,qBAAqB;AAAA,QACtC,KAAK,OAAO,qBAAqB;AAAA,QACjC;AAAA,MACF,KAAM;AAAA,IAEV;AAEA,QAAI;AACJ,QAAI,KAAK,OAAO,qBAAqB,iBAAiB;AACpD,YAAM,MAAM,MAAM,MAAM,KAAK,OAAO,qBAAqB,eAAe;AACxE,2BAAqB,MAAM,IAAI,KAAK;AAAA,IACtC,WAAW,KAAK,OAAO,qBAAqB,oBAAoB;AAC9D,2BAAqB,KAAK,OAAO,qBAAqB;AAAA,IACxD,OAAO;AACL,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,uBAAuB,oBAAoB,kBAAkB;AACnE,UAAM,0BAA0B,qBAAqB,CAAC;AACtD,QAAI,qBAAqB,CAAC,EAAE,SAAS,GAAG;AACtC,cAAQ,KAAK,8CAA8C,qBAAqB,CAAC,CAAC;AAAA,IACpF;AACA,UAAM,mBAAmB,MAAM,KAAK,oBAAoB,uBAAuB;AAC/E,QAAI,kBAAkB;AACpB,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,eAA8B;AAC1C,QAAI,WAA4B;AAChC,QAAI;AACF,iBAAW,MAAM,KAAK,6BAA6B;AAAA,IACrD,SAAS,OAAO;AACd,cAAQ,MAAM,6CAA6C,KAAK;AAAA,IAClE;AACA,QAAI,UAAU;AACZ,WAAK,YAAY,QAAoB;AAAA,IACvC;AAAA,EACF;AAAA,EAEQ,oBACN,cACA,eACA,+BACe;AACf,UAAM,iBAAiB,oBAAI,IAAY;AACvC,QAAI,cAAc;AAChB,mBAAa,SAAS,CAAC,UAAU;AAC/B,cAAM,SAAS;AACf,YAAI,OAAO,QAAQ;AACjB,yBAAe,IAAI,MAAM,IAAI;AAAA,QAC/B;AAAA,MACF,CAAC;AAAA,IACH;AACA,kBAAc,SAAS,cAAc,OAAO,OAAO,CAAC,UAAU;AAC5D,YAAM,CAAC,WAAW,aAAa,IAAI,MAAM,KAAK,MAAM,GAAG;AACvD,UAAI,iCAAiC,cAAc,UAAU,kBAAkB,YAAY;AACzF,eAAO;AAAA,MACT;AACA,YAAM,gBACJ,eAAe,IAAI,SAAS,KAAK,kBAAkB,cAAc,kBAAkB;AACrF,aAAO;AAAA,IACT,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,MAAc,qBACZ,kBACA,eACA,OAAgB,MAChB,gBAAwB,GACT;AACf,WAAO,IAAI,QAAQ,OAAO,SAAS,WAAW;AAC5C,YAAM,YAAY,MAAM,KAAK,OAAO,qBAAqB,KAAK,kBAAkB,WAAW;AAC3F,YAAM,iBAAiB,KAAK,oBAAoB,KAAK,MAAM,WAA4B,IAAI;AAC3F,UAAI,OAAO,cAAc,eAAe,0BAA0B,eAAe;AAC/E,aAAK,WAAW,aAAa,IAAI,KAAK,eAAgB,WAAW,cAAc;AAC/E,aAAK,WAAW,aAAa,EAAE,KAAK;AACpC,aAAK,WAAW,aAAa,EAAE,YAAY;AAC3C,YAAI,gCAAuC;AACzC,eAAK,WAAW,aAAa,EAAE,KAAK;AAAA,QACtC;AACA,YAAI,CAAC,MAAM;AACT,eAAK,WAAW,aAAa,EAAE,QAAQ,YAAY,CAAC;AACpD,eAAK,WAAW,aAAa,EAAE,oBAAoB;AAAA,QACrD;AACA,gBAAQ;AAAA,MACV,OAAO;AACL,eAAO,kBAAkB,aAAa,SAAS,gBAAgB,EAAE;AAAA,MACnE;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEQ,sBACN,iBACA,qBAA6B,MACvB;AACN,QAAI,CAAC,KAAK,MAAM;AACd;AAAA,IACF;AAEA,UAAM,gBAAgB,KAAK,WAAW,KAAK,gBAAgB;AAC3D,SAAK,mBAAmB;AACxB,UAAM,eAAe,KAAK,WAAW,eAAe;AAEpD,QAAI,CAAC,cAAc;AACjB;AAAA,IACF;AAEA,QAAI,eAAe;AACjB,oBAAc,QAAQ,kBAAkB;AAAA,IAC1C;AAEA,iBAAa,MAAM;AACnB,QAAI,CAAC,aAAa,UAAU,GAAG;AAC7B,mBAAa,KAAK;AAAA,IACpB;AAEA,QAAI,wCAA+C;AACjD,mBAAa,SAAS,EAAE,iBAAiB,YAAY,CAAC,WAAW;AAC/D,YAAI,KAAK,yCAAgD;AACvD,eAAK,mBAAmB;AAExB,eAAK,kCAAyC;AAAA,QAChD;AAAA,MACF,CAAC;AAAA,IACH;AAEA,iBAAa,UAAU;AACvB,iBAAa,OAAO,kBAAkB;AAAA,EACxC;AAAA,EAEA,OAAO,MAAc;AACnB,QAAI,KAAK,gBAAgB;AACvB,WAAK,eAAe,OAAO,IAAI;AAC/B,WAAK,UAAU,QAAQ,CAAC,aAAa,SAAS,OAAO,CAAC;AAAA,IACxD;AAAA,EACF;AACF;AApSa,gBACG,cAA2B,IAAI,YAAY;AADpD,IAAM,iBAAN;;;AMpCP;AAAA,EAEE;AAAA,EACA;AAAA,EACA,QAAAC;AAAA,EAEA;AAAA,OAGK;AAIA,IAAM,6BAAN,MAAiC;AAAA,EAiEtC,YAAoB,OAAyB;AAAzB;AAhEpB,SAAQ;AAAA,IAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWlC,SAAQ;AAAA,IAA4B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmCpC,SAAQ,WAAW;AAAA,MACjB,MAAM,EAAE,OAAO,EAAI;AAAA,MACnB,OAAO,EAAE,OAAO,EAAI;AAAA,IACtB;AAEA,SAAQ,WAA2B,IAAI,eAAe,MAAM,EAAE;AAC9D,SAAQ,WAA8B,IAAI,kBAAkB;AAAA,MAC1D,cAAc,KAAK;AAAA,MACnB,gBAAgB,KAAK;AAAA,MACrB,UAAU,KAAK;AAAA,MACf,aAAa;AAAA,MACb,aAAa;AAAA,IACf,CAAC;AACD,SAAQ,OAAO,IAAIC,MAAK,KAAK,UAAU,KAAK,QAAQ;AAEpD,SAAQ,eAAe;AACvB,SAAQ,cAAc;AAGpB,SAAK,MAAM,IAAI,KAAK,IAAI;AAAA,EAC1B;AAAA,EAEO,gBAAgB,UAAmB,QAAgB;AACxD,SAAK,KAAK,SAAS,IAAI,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AACzD,SAAK,KAAK,OAAO,OAAO,QAAQ;AAAA,EAClC;AAAA,EAEO,QAAQ,OAAe;AAC5B,SAAK,gBAAgB,KAAK,KAAK,aAAa,KAAK,cAAc,IAAI;AACnE,SAAK,SAAS,KAAK,QAAQ;AAC3B,SAAK,SAAS,MAAM,QAAQ,KAAK;AAAA,EACnC;AAAA,EAEO,YAAY,OAAgB;AACjC,SAAK,cAAc,UAAU,OAAO,IAAM;AAAA,EAC5C;AAAA,EAEO,UAAU;AACf,SAAK,MAAM,OAAO,KAAK,IAAI;AAC3B,SAAK,KAAK,SAAS,QAAQ;AAC3B,SAAK,KAAK,SAAS,QAAQ;AAAA,EAC7B;AACF;;;ACtGA,SAAS,SAAAC,QAAO,WAAW,gBAAAC,eAAc,QAAQ,sBAAsB;;;ACAvE,SAAS,SAAS,cAAc,kBAAkB;AA4BlD,SAAS,mBAAmB,WAA4B,OAAe;AACrE,UAAQ,WAAW;AAAA,IACjB,KAAK;AACH,aAAO,QAAQ;AAAA,IACjB,KAAK;AACH,aAAO;AAAA,IACT;AACE,aAAO;AAAA,EACX;AACF;AAEA,SAAS,gBACP,SACA,UACA,WACA,GACA,YACA,UACA,SACA;AACA,QAAM,IAAI,mBAAmB,WAAW,WAAW,UAAU,CAAC;AAC9D,QAAM,QAAQ,SAAS,MAAM,IAAI;AACjC,MAAI,cAAc;AAClB,aAAW,QAAQ,OAAO;AACxB,eAAW,YAAY;AAEvB,QAAI,YAAY,GAAG;AACjB,cAAQ,SAAS,MAAM,GAAG,IAAI,aAAa,WAAW;AACtD;AACA;AAAA,IACF;AACA,QAAI,QAAQ,KAAK,MAAM,GAAG;AAC1B,QAAI,gBAAgB;AACpB,WAAO,MAAM,SAAS,KAAK,iBAAiB,MAAM,QAAQ;AACxD,YAAM,MAAM,MAAM,MAAM,GAAG,aAAa,EAAE,KAAK,GAAG;AAClD,YAAM,YAAY,QAAQ,YAAY,GAAG,EAAE;AAC3C,UAAI,YAAY,UAAU,IAAI,UAAU;AACtC,YAAI,kBAAkB,GAAG;AAEvB,gBAAM,OAAO,MAAM,CAAC;AACpB,cAAI,YAAY;AAChB,iBAAO,YAAY,KAAK,QAAQ;AAC9B,kBAAM,YAAY,KAAK,UAAU,GAAG,SAAS;AAC7C,kBAAM,WAAW,QAAQ,YAAY,SAAS,EAAE;AAChD,gBAAI,WAAW,UAAU,IAAI,UAAU;AACrC,kBAAI,cAAc,EAAG,aAAY;AACjC,sBAAQ;AAAA,gBACN,KAAK,UAAU,GAAG,YAAY,CAAC;AAAA,gBAC/B,IAAI;AAAA,gBACJ,IAAI,aAAa,cAAc;AAAA,cACjC;AACA;AACA,oBAAM,CAAC,IAAI,KAAK,UAAU,YAAY,CAAC;AACvC;AAAA,YACF;AACA;AAAA,UACF;AACA,cAAI,aAAa,KAAK,QAAQ;AAC5B,4BAAgB;AAAA,UAClB,OAAO;AACL;AAAA,UACF;AAAA,QACF;AACA,gBAAQ;AAAA,UACN,MAAM,MAAM,GAAG,gBAAgB,CAAC,EAAE,KAAK,GAAG;AAAA,UAC1C,IAAI;AAAA,UACJ,IAAI,aAAa,cAAc;AAAA,QACjC;AACA;AACA,gBAAQ,MAAM,OAAO,gBAAgB,CAAC;AACtC,wBAAgB;AAAA,MAClB,OAAO;AACL;AAAA,MACF;AAAA,IACF;AACA,QAAI,gBAAgB,KAAK,MAAM,SAAS,GAAG;AACzC,cAAQ,SAAS,MAAM,KAAK,GAAG,GAAG,IAAI,SAAS,IAAI,aAAa,cAAc,OAAO;AACrF;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,aAAN,MAAiB;AAAA,EAItB,cAAc;AACZ,SAAK,SAAS,SAAS,cAAc,QAAQ;AAC7C,SAAK,UAAU,KAAK,OAAO,WAAW,IAAI;AAAA,EAC5C;AAAA,EAEO,WAAW,SAAiB,SAA+C;AAChF,UAAM,WAAW,QAAQ;AACzB,UAAM,YAAY,QAAQ;AAC1B,UAAM,kBAAkB,QAAQ,2BAA2B,EAAE,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,EAAE;AAC1F,UAAM,UAAU,QAAQ,aAAa;AACrC,UAAM,OAAO,QAAQ,QAAQ;AAC7B,UAAM,cAAc,QAAQ,OAAO,UAAU,MAAM,WAAW,QAAQ;AAGtE,UAAM,YAAa,QAAQ,aAAiC;AAE5D,QAAI,QAAQ,cAAc,QAAQ,WAAW,aAAa,QAAW;AAGnE,WAAK,OAAO,QAAQ,QAAQ,WAAW;AACvC,WAAK,OAAO,SAAS,QAAQ,WAAW;AACxC,WAAK,QAAQ,UAAU,GAAG,GAAG,KAAK,OAAO,OAAO,KAAK,OAAO,MAAM;AAClE,WAAK,QAAQ,OAAO;AACpB,WAAK,QAAQ,YAAY;AACzB,WAAK,QAAQ,YAAY,QAAQ,gBAAgB,CAAC,KAAK,gBAAgB,CAAC,KAAK,gBAAgB,CAAC,KAAK,gBAAgB,CAAC;AACpH,WAAK,QAAQ,YAAY;AACzB,WAAK,QAAQ,SAAS,GAAG,GAAG,KAAK,OAAO,OAAO,KAAK,OAAO,MAAM;AACjE,WAAK,QAAQ,YAAY,QAAQ,UAAU,CAAC,KAAK,UAAU,CAAC,KAAK,UAAU,CAAC,KAAK,UAAU,CAAC;AAC5F;AAAA,QACE,KAAK;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,KAAK,OAAO;AAAA,QACZ;AAAA,MACF;AACA,aAAO,KAAK;AAAA,IACd,OAAO;AACL,WAAK,QAAQ,OAAO;AACpB,WAAK,QAAQ,YAAY;AACzB,YAAM,UAAU,KAAK,QAAQ,YAAY,OAAO;AAChD,YAAM,YAAY,QAAQ;AAC1B,YAAM,aAAa,QAAQ,wBAAwB,QAAQ;AAE3D,UAAI,QAAQ,cAAc,QAAQ,WAAW,aAAa,QAAW;AACnE,cAAM,yBAAyB,QAAQ,WAAW,WAAW,UAAU;AACvE,YAAI,YAAY,wBAAwB;AAEtC,gBAAM,YAAY,KAAK,KAAK,YAAY,sBAAsB;AAC9D,eAAK,OAAO,QAAQ,QAAQ,WAAW;AACvC,eAAK,OAAO,SAAS,aAAa,YAAY,UAAU;AACxD,eAAK,QAAQ,UAAU,GAAG,GAAG,KAAK,OAAO,OAAO,KAAK,OAAO,MAAM;AAClE,eAAK,QAAQ,OAAO;AACpB,eAAK,QAAQ,YAAY;AACzB,eAAK,QAAQ,YAAY,QAAQ,gBAAgB,CAAC,KAAK,gBAAgB,CAAC,KAAK,gBAAgB,CAAC,KAAK,gBAAgB,CAAC;AACpH,eAAK,QAAQ,YAAY;AACzB,eAAK,QAAQ,SAAS,GAAG,GAAG,KAAK,OAAO,OAAO,KAAK,OAAO,MAAM;AACjE,eAAK,QAAQ,YAAY,QAAQ,UAAU,CAAC,KAAK,UAAU,CAAC,KAAK,UAAU,CAAC,KAAK,UAAU,CAAC;AAC5F;AAAA,YACE,KAAK;AAAA,YACL;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,KAAK,OAAO;AAAA,YACZ;AAAA,UACF;AACA,iBAAO,KAAK;AAAA,QACd,OAAO;AAAA,QAEP;AAAA,MACF;AAKA,WAAK,OAAO,QAAQ,YAAY,UAAU;AAC1C,WAAK,OAAO,SAAS,aAAa,UAAU;AAC5C,WAAK,QAAQ,UAAU,GAAG,GAAG,KAAK,OAAO,OAAO,KAAK,OAAO,MAAM;AAClE,WAAK,QAAQ,OAAO;AACpB,WAAK,QAAQ,YAAY;AACzB,WAAK,QAAQ,YAAY,QAAQ,gBAAgB,CAAC,KAAK,gBAAgB,CAAC,KAAK,gBAAgB,CAAC,KAAK,gBAAgB,CAAC;AACpH,WAAK,QAAQ,YAAY;AACzB,WAAK,QAAQ,SAAS,GAAG,GAAG,KAAK,OAAO,OAAO,KAAK,OAAO,MAAM;AACjE,WAAK,QAAQ,YAAY,QAAQ,UAAU,CAAC,KAAK,UAAU,CAAC,KAAK,UAAU,CAAC,KAAK,UAAU,CAAC;AAC5F,WAAK,QAAQ;AAAA,QACX;AAAA,QACA,UAAU,mBAAmB,WAAW,SAAS;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,EACd;AACF;AAEO,SAAS,uBACd,MACA,SACqD;AACrD,QAAMC,UAAS,IAAI,WAAW,EAAE,WAAW,MAAM,OAAO;AACxD,QAAM,UAAU,IAAI,QAAQA,OAAM;AAClC,UAAQ,YAAY;AACpB,UAAQ,YAAY;AACpB,UAAQ,SAAS;AACjB,UAAQ,cAAc;AAEtB,SAAO,EAAE,SAAS,OAAOA,QAAO,OAAO,QAAQA,QAAO,OAAO;AAC/D;;;ADrNA,IAAM,YAAY;AAClB,IAAM,oBAAoB,IAAIC,OAAM,CAAQ;AAC5C,IAAM,mBAAmB,IAAIA,OAAM,QAAQ;AAC3C,IAAM,wBAAwB;AAC9B,IAAM,uBAAuB;AAC7B,IAAM,sBAAsB;AAC5B,IAAM,wBAAwB;AAE9B,IAAM,0BAA0B;AAazB,IAAM,mBAAN,cAA+B,OAAO;AAAA,EAO3C,YAAY,WAA6C;AACvD,UAAM;AAPR,SAAQ,gBAAwB;AAChC,SAAQ,cAAsB;AAE9B,SAAQ,UAAyB;AACjC,SAAQ,cAAqC;AAI3C,SAAK,SAAS;AAAA,MACZ,WAAW;AAAA,MACX,UAAU;AAAA,MACV,SAAS;AAAA,MACT,OAAO;AAAA,MACP,WAAW;AAAA,MACX,gBAAgB;AAAA,MAChB,kBAAkB;AAAA,MAClB,GAAG;AAAA,IACL;AAEA,SAAK,WAAW,IAAI,eAAe;AAAA,MACjC,KAAK;AAAA,MACL,aAAa;AAAA,MACb,SAAS,KAAK,OAAO;AAAA,MACrB,MAAM;AAAA,IACR,CAAC;AAED,SAAK,SAAS,IAAI,GAAG,KAAK,CAAC;AAC3B,SAAK,UAAU;AAAA,EACjB;AAAA,EAEO,gBAAgB,QAAgB;AACrC,SAAK,SAAS,IAAI,SAAS,KAAK,MAAM,IAAI;AAAA,EAC5C;AAAA,EAEQ,WAAW,SAAiB;AAClC,QAAI,YAAY,KAAK,SAAS;AAE5B;AAAA,IACF;AACA,SAAK,UAAU;AACf,QAAI,KAAK,SAAS,KAAK;AACrB,WAAK,SAAS,IAAI,QAAQ;AAAA,IAC5B;AACA,UAAM,EAAE,SAAS,OAAO,OAAO,IAAI,uBAAuB,SAAS;AAAA,MACjE,MAAM;AAAA,MACN,UAAU,KAAK,OAAO,WAAW;AAAA,MACjC,WAAW,KAAK,OAAO;AAAA,MACvB,mBAAmB;AAAA,QACjB,GAAG,KAAK,OAAO,UAAU,IAAI;AAAA,QAC7B,GAAG,KAAK,OAAO,UAAU,IAAI;AAAA,QAC7B,GAAG,KAAK,OAAO,UAAU,IAAI;AAAA,QAC7B,GAAG;AAAA,MACL;AAAA,MACA,yBAAyB;AAAA,QACvB,GAAG,KAAK,OAAO,MAAM,IAAI;AAAA,QACzB,GAAG,KAAK,OAAO,MAAM,IAAI;AAAA,QACzB,GAAG,KAAK,OAAO,MAAM,IAAI;AAAA,QACzB,GAAG;AAAA,MACL;AAAA,MACA,WAAW,KAAK,OAAO;AAAA,MACvB,YACE,KAAK,OAAO,aAAa,SACrB;AAAA,QACE,UAAU,KAAK,OAAO;AAAA,MACxB,IACA;AAAA,IACR,CAAC;AAED,SAAK,SAAS,MAAM;AACpB,SAAK,SAAS,IAAI,YAAYC;AAC9B,SAAK,SAAS,IAAI,YAAYA;AAC9B,SAAK,SAAS,cAAc;AAE5B,SAAK,MAAM,IAAI,SAAS,MAAM;AAC9B,SAAK,MAAM,IAAI,UAAU,MAAM;AAAA,EACjC;AAAA,EAEA,QAAQ,MAAc,UAAuB;AAC3C,UAAM,gBAAgB,KAAK,QAAQ,kBAAkB,EAAE;AACvD,SAAK,UAAU;AACf,SAAK,gBAAgB,KAAK,OAAO;AACjC,QAAI,KAAK,aAAa;AACpB,mBAAa,KAAK,WAAW;AAC7B,WAAK,cAAc;AAAA,IACrB;AACA,QAAI,KAAK,OAAO,qBAAqB,MAAM;AACzC,WAAK,cAAc,WAAW,MAAM;AAClC,aAAK,cAAc;AACnB,aAAK,KAAK;AACV,YAAI,UAAU;AACZ,mBAAS;AAAA,QACX;AAAA,MACF,GAAG,KAAK,OAAO,mBAAmB,GAAI;AAAA,IACxC;AACA,SAAK,WAAW,aAAa;AAAA,EAC/B;AAAA,EAEA,OAAO;AACL,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEA,OAAO;AACL,SAAK,QAAQ,KAAK,WAAW,EAAE;AAAA,EACjC;AAAA,EAEA,SAAS;AACP,UAAM,UAAU,KAAK,SAAS;AAC9B,QAAI,UAAU,KAAK,eAAe;AAChC,WAAK,SAAS,UAAU,KAAK;AAAA,QAC3B,KAAK,SAAS,UAAU,KAAK;AAAA,QAC7B,KAAK;AAAA,MACP;AAAA,IACF,WAAW,UAAU,KAAK,eAAe;AACvC,WAAK,SAAS,UAAU,KAAK;AAAA,QAC3B,KAAK,SAAS,UAAU,KAAK;AAAA,QAC7B,KAAK;AAAA,MACP;AACA,UAAI,WAAW,KAAK,KAAK,SAAS,aAAa;AAC7C,aAAK,SAAS,cAAc;AAC5B,aAAK,SAAS,cAAc;AAAA,MAC9B,WAAW,UAAU,KAAK,UAAU,KAAK,CAAC,KAAK,SAAS,aAAa;AACnE,aAAK,SAAS,cAAc;AAC5B,aAAK,SAAS,cAAc;AAAA,MAC9B;AACA,UAAI,KAAK,SAAS,WAAW,GAAG;AAC9B,aAAK,UAAU;AAAA,MACjB;AAAA,IACF;AAAA,EACF;AACF;;;ARjHA,SAAS,qCAAqC,iBAAiC;AAC7E,SAAO,kBAAkB,MAAM;AACjC;AAEA,SAAS,4BAA4B,GAAyB,GAAkC;AAC9F,SACE,EAAE,gBAAgB,EAAE,eACpB,EAAE,uBAAuB,EAAE,sBAC3B,EAAE,oBAAoB,EAAE;AAE5B;AAEO,IAAM,YAAN,cAAwB,MAAM;AAAA,EAQnC,YAAoB,QAAyB;AAC3C,UAAM;AADY;AAPpB,SAAQ,QAA+B;AACvC,SAAO,QAAe,IAAIC,OAAM;AAEhC,SAAO,oBAAuD;AAE9D,SAAO,eAAmC,CAAC;AAIzC,SAAK,UAAU,IAAI;AAAA,MACjB,KAAK,OAAO,UACR;AAAA,QACE,kBAAkB;AAAA,MACpB,IACA,CAAC;AAAA,IACP;AACA,SAAK,QAAQ,QAAQ,KAAK,OAAO,QAAQ;AACzC,SAAK,IAAI,KAAK,OAAO;AACrB,SAAK,KAAK,EAAE,KAAK,MAAM;AACrB,WAAK,OAAO,oBAAoB;AAChC,WAAK,kBAAkB;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EAEA,gBAAgB,UAAkB,sBAA4C;AAC5E,QAAI,CAAC,4BAA4B,KAAK,OAAO,sBAAsB,oBAAoB,GAAG;AACxF,WAAK,OAAO,uBAAuB;AACnC,WAAK,KAAK,EAAE,KAAK,MAAM;AACrB,aAAK,kBAAkB;AAAA,MACzB,CAAC;AAAA,IACH;AACA,QAAI,KAAK,OAAO,aAAa,UAAU;AACrC,WAAK,OAAO,WAAW;AACvB,WAAK,QAAQ,QAAQ,QAAQ;AAE7B,WAAK,QAAQ,KAAK;AAAA,IACpB;AAAA,EACF;AAAA,EAEQ,oBAAoB;AAC1B,QAAI,KAAK,SAAS,KAAK,MAAM,iBAAiB;AAC5C,UAAI,SAAS,qCAAqC,KAAK,MAAM,eAAe;AAC5E,WAAK,QAAQ,gBAAgB,MAAM;AACnC,gBAAU,KAAK,QAAQ,MAAM;AAE7B,iBAAW,eAAe,KAAK,cAAc;AAC3C,oBAAY,gBAAgB,MAAM;AAClC,kBAAU,YAAY,MAAM;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,OAAsB;AAClC,UAAM,gBAAgB,KAAK;AAC3B,QAAI,iBAAiB,cAAc,MAAM;AACvC,WAAK,OAAO,cAAc,IAAI;AAAA,IAChC;AACA,SAAK,QAAQ,IAAI,eAAe;AAAA,MAC9B,sBAAsB,KAAK,OAAO;AAAA,MAClC,iBAAiB,KAAK,OAAO;AAAA,MAC7B,sBAAsB,KAAK,OAAO;AAAA,MAClC,eAAe,KAAK,OAAO;AAAA,MAC3B,aAAa,KAAK,OAAO;AAAA,MACzB,SAAS,KAAK,OAAO;AAAA,IACvB,CAAC;AACD,UAAM,KAAK,MAAM,KAAK;AACtB,QAAI,KAAK,MAAM,MAAM;AACnB,WAAK,IAAI,KAAK,MAAM,IAAI;AAAA,IAC1B;AACA,QAAI,KAAK,sBAAsB,MAAM;AACnC,WAAK,oBAAoB,IAAI,2BAA2B,KAAK,OAAO,SAAS,aAAa;AAAA,IAC5F;AAAA,EACF;AAAA,EAEO,gBAAgB,iBAAiC;AAvI1D;AAwII,eAAK,UAAL,mBAAY,gBAAgB;AAAA,EAC9B;AAAA,EAEO,OAAO,MAAc,WAAmB;AA3IjD;AA4II,QAAI,CAAC,KAAK,MAAO;AACjB,QAAI,KAAK,SAAS;AAChB,WAAK,QAAQ,OAAO;AAAA,IACtB;AACA,QAAI,KAAK,mBAAmB;AAC1B,WAAK,kBAAkB,QAAQ,IAAI;AACnC,UAAI,KAAK,MAAM,QAAQ,KAAK,MAAM,UAAU;AAC1C,aAAK,kBAAkB;AAAA,WACrB,UAAK,MAAM,aAAX,mBAAqB,iBAAiB,IAAIC,SAAQ;AAAA,UAClD,KAAK,OAAO,cAAc;AAAA,QAC5B;AAAA,MACF;AAAA,IACF;AACA,SAAK,MAAM,OAAO,SAAS;AAAA,EAC7B;AAAA,EAEA,sBAAsC;AA5JxC;AA6JI,aAAO,UAAK,UAAL,mBAAY;AAAA,EACrB;AAAA,EAEA,cAAc,SAAiB;AAC7B,UAAM,UAAU,IAAI,iBAAiB;AAAA,MACnC,UAAU;AAAA,MACV,kBAAkB;AAAA,MAClB,OAAO,IAAID,OAAM,OAAO,OAAO,KAAK;AAAA,IACtC,CAAC;AACD,SAAK,IAAI,OAAO;AAChB,SAAK,aAAa,QAAQ,OAAO;AACjC,YAAQ,QAAQ,SAAS,MAAM;AAC7B,WAAK,eAAe,KAAK,aAAa,OAAO,CAAC,MAAM,MAAM,OAAO;AACjE,WAAK,OAAO,OAAO;AACnB,WAAK,kBAAkB;AAAA,IACzB,CAAC;AACD,QAAI,KAAK,OAAO,SAAS;AAEvB,WAAK,QAAQ,KAAK;AAAA,IACpB;AACA,SAAK,kBAAkB;AAAA,EACzB;AACF;;;AUlLA,SAAS,SAAAE,QAAO,SAAAC,QAAO,cAAAC,aAAY,WAAAC,gBAAe;;;ACDlD,SAAS,OAAO,OAAO,SAAS,cAAAC,aAAY,KAAK,aAAAC,YAAW,WAAAC,gBAAe;;;ACKpE,IAAM,4BAA4B;AAAA,EACvC,SAAS;AAAA,EACT,WAAW;AAAA,EACX,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,oBAAoB;AAAA,EACpB,mBAAmB;AAAA,EACnB,kBAAkB;AAAA,EAClB,uBAAuB;AAAA,EACvB,qBAAqB;AACvB;AAEO,IAAM,6BAA6B;AAAA,EACxC,SAAS,EAAE,KAAK,GAAG,KAAK,KAAK,MAAM,KAAK;AAAA,EACxC,WAAW,EAAE,KAAK,GAAG,KAAK,IAAI,MAAM,KAAK;AAAA,EACzC,iBAAiB,EAAE,KAAK,GAAG,KAAK,IAAI,MAAM,KAAK;AAAA,EAC/C,YAAY,EAAE,KAAK,IAAI,KAAK,KAAK,MAAM,EAAE;AAAA,EACzC,eAAe,EAAE,KAAK,MAAM,KAAK,KAAK,MAAM,KAAK;AAAA,EACjD,kBAAkB,EAAE,KAAK,MAAM,KAAK,GAAG,MAAM,EAAE;AAAA,EAC/C,oBAAoB,EAAE,KAAK,MAAO,KAAK,MAAM,MAAM,KAAK;AAAA,EACxD,mBAAmB,EAAE,KAAK,KAAK,KAAK,KAAK,MAAM,KAAK;AAAA,EACpD,kBAAkB,EAAE,KAAK,KAAK,KAAK,GAAK,MAAM,KAAK;AAAA,EACnD,uBAAuB,EAAE,KAAK,KAAK,KAAK,KAAK,MAAM,EAAE;AAAA,EACrD,qBAAqB,EAAE,KAAK,OAAO,KAAK,GAAG,MAAM,KAAM;AACzD;AAYO,IAAM,0BAAN,MAA8B;AAAA,EAanC,YAAY,cAAyB,SAAkB,OAAO;AAV9D,SAAQ,gBAA+B;AAAA,MACrC,UAAU;AAAA,MACV,UAAU;AAAA,MACV,SAAS;AAAA,MACT,eAAe;AAAA,MACf,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,cAAc;AAAA,IAChB;AAGE,SAAK,SAAS,aAAa,UAAU,EAAE,OAAO,aAAa,UAAU,OAAO,CAAC;AAC7E,SAAK,OAAO,WAAW,KAAK,eAAe,YAAY,EAAE,UAAU,KAAK,CAAC;AACzE,SAAK,OAAO,WAAW,KAAK,eAAe,YAAY,EAAE,UAAU,KAAK,CAAC;AACzE,SAAK,OAAO,WAAW,KAAK,eAAe,WAAW,EAAE,UAAU,KAAK,CAAC;AACxE,SAAK,OAAO,WAAW,KAAK,eAAe,iBAAiB,EAAE,UAAU,KAAK,CAAC;AAC9E,SAAK,OAAO,WAAW,KAAK,eAAe,aAAa,EAAE,UAAU,KAAK,CAAC;AAC1E,SAAK,OAAO,WAAW,KAAK,eAAe,cAAc,EAAE,UAAU,KAAK,CAAC;AAC3E,SAAK,OAAO,WAAW,KAAK,eAAe,gBAAgB,EAAE,UAAU,KAAK,CAAC;AAC7E,SAAK,OAAO;AAAA,MACV;AAAA,MACA;AAAA,MACA,2BAA2B;AAAA,IAC7B;AACA,SAAK,OAAO;AAAA,MACV;AAAA,MACA;AAAA,MACA,2BAA2B;AAAA,IAC7B;AACA,SAAK,OAAO;AAAA,MACV;AAAA,MACA;AAAA,MACA,2BAA2B;AAAA,IAC7B;AACA,SAAK,OAAO;AAAA,MACV;AAAA,MACA;AAAA,MACA,2BAA2B;AAAA,IAC7B;AACA,SAAK,OAAO;AAAA,MACV;AAAA,MACA;AAAA,MACA,2BAA2B;AAAA,IAC7B;AACA,SAAK,OAAO;AAAA,MACV;AAAA,MACA;AAAA,MACA,2BAA2B;AAAA,IAC7B;AACA,SAAK,OAAO;AAAA,MACV;AAAA,MACA;AAAA,MACA,2BAA2B;AAAA,IAC7B;AACA,SAAK,OAAO;AAAA,MACV;AAAA,MACA;AAAA,MACA,2BAA2B;AAAA,IAC7B;AACA,SAAK,OAAO;AAAA,MACV;AAAA,MACA;AAAA,MACA,2BAA2B;AAAA,IAC7B;AACA,SAAK,OAAO;AAAA,MACV;AAAA,MACA;AAAA,MACA,2BAA2B;AAAA,IAC7B;AACA,SAAK,OAAO;AAAA,MACV;AAAA,MACA;AAAA,MACA,2BAA2B;AAAA,IAC7B;AAAA,EACF;AAAA,EAEO,iBAAiB,iBAAwC;AAC9D,SAAK,OAAO,GAAG,UAAU,CAAC,MAA+D;AACvF,YAAM,SAAU,EAAE,OAAe;AACjC,UAAI,CAAC,OAAQ;AACb,cAAQ,QAAQ;AAAA,QACd,KAAK,WAAW;AACd,gBAAM,QAAQ,EAAE;AAChB,0BAAgB,UAAU,QAAQ;AAClC;AAAA,QACF;AAAA,QACA,KAAK,aAAa;AAChB,gBAAM,QAAQ,EAAE;AAChB,0BAAgB,YAAY;AAC5B;AAAA,QACF;AAAA,QACA,KAAK,mBAAmB;AACtB,gBAAM,QAAQ,EAAE;AAChB,0BAAgB,kBAAkB;AAClC;AAAA,QACF;AAAA,QACA,KAAK,cAAc;AACjB,gBAAM,QAAQ,EAAE;AAChB,0BAAgB,sBAAsB;AACtC;AAAA,QACF;AAAA,QACA,KAAK,iBAAiB;AACpB,gBAAM,QAAQ,EAAE;AAChB,0BAAgB,gBAAgB;AAChC;AAAA,QACF;AAAA,QACA,KAAK,oBAAoB;AACvB,gBAAM,QAAQ,EAAE;AAChB,0BAAgB,mBAAmB,aAAa,QAAQ;AACxD;AAAA,QACF;AAAA,QACA,KAAK,sBAAsB;AACzB,gBAAM,QAAQ,EAAE;AAChB,0BAAgB,qBAAqB;AACrC;AAAA,QACF;AAAA,QACA,KAAK,qBAAqB;AACxB,gBAAM,QAAQ,EAAE;AAChB,0BAAgB,oBAAoB;AACpC;AAAA,QACF;AAAA,QACA,KAAK,oBAAoB;AACvB,gBAAM,QAAQ,EAAE;AAChB,0BAAgB,mBAAmB;AACnC;AAAA,QACF;AAAA,QACA,KAAK,yBAAyB;AAC5B,gBAAM,QAAQ,EAAE;AAChB,0BAAgB,cAAc;AAC9B;AAAA,QACF;AAAA,QACA,KAAK,uBAAuB;AAC1B,gBAAM,QAAQ,EAAE;AAChB,0BAAgB,sBAAsB;AACtC;AAAA,QACF;AAAA,QACA;AACE;AAAA,MACJ;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEO,OAAO,iBAAwC;AACpD,UAAM,EAAE,GAAG,GAAG,EAAE,IAAI,gBAAgB;AACpC,SAAK,cAAc,WAAW,IAAI,EAAE,QAAQ,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;AAChF,SAAK,cAAc,WAAW,GAAG,gBAAgB,iBAAiB;AAClE,SAAK,cAAc,UAAU,GAAG,gBAAgB,WAAW,gBAAgB,aAAa,SAAS,OAAO;AACxG,SAAK,cAAc,gBAAgB,GAAG,gBAAgB,aAAa;AACnE,SAAK,cAAc,YAAY,GAAG,gBAAgB,WAAW;AAC7D,SAAK,cAAc,aAAa,GAAG,gBAAgB,UAAU;AAC7D,SAAK,cAAc,eAAe,GAAG,gBAAgB,YAAY;AAAA,EACnE;AACF;;;AD1LA,IAAM,aAAa,IAAIC,SAAQ,GAAG,IAAI,CAAC;AAYhC,IAAM,kBAAN,MAAsB;AAAA,EA2E3B,YAAoB,QAA+B;AAA/B;AA1EpB,SAAO,cAAc;AAAA,MACnB,QAAQ;AAAA,MACR,SAAS,IAAI,MAAM,IAAIA,SAAQ,GAAG,IAAIA,SAAQ,GAAG,MAAM,CAAC,CAAC;AAAA,IAC3D;AAEA,SAAO,UAAkB,CAAC,0BAA0B;AACpD,SAAO,YAAoB,0BAA0B;AACrD,SAAO,kBAA0B,0BAA0B;AAC3D,SAAO,sBAA8B,0BAA0B;AAC/D,SAAO,UAAmB;AAC1B,SAAO,gBAAyB;AAChC,SAAO,eAAe;AACtB,SAAO,iBAA0B;AACjC,SAAO,cAAsB;AAE7B,SAAO,gBAAgB,0BAA0B;AACjD,SAAO,mBAAmB,aAAa,0BAA0B,mBAAmB;AACpF,SAAO,qBAAqB,0BAA0B;AACtD,SAAO,oBAAoB,0BAA0B;AACrD,SAAO,mBAAmB,0BAA0B;AACpD,SAAO,cAAc,0BAA0B;AAC/C,SAAO,sBAAsB,0BAA0B;AAEvD,SAAO,iBAA0B,IAAIA,SAAQ;AAC7C,SAAO,oBAA6B;AACpC,SAAO,aAAsB;AAE7B,SAAQ,0BAA0B;AAElC,SAAQ,uBAAgC;AACxC,SAAQ,yBAAiC;AACzC,SAAQ,gBAAwB;AAChC,SAAQ,sBAAsB,IAAIA,SAAQ;AAE1C,SAAQ,oBAA6B,IAAIA,SAAQ;AACjD,SAAQ,WAAoB,IAAIA,SAAQ,GAAG,GAAG,CAAC;AAC/C,SAAQ,aAAsB,IAAIA,SAAQ,GAAG,IAAI,CAAC;AAElD,SAAQ,iBAAyB;AACjC,SAAQ,iBAAyB;AAEjC,SAAQ,aAAsB,IAAI,QAAQ;AAC1C,SAAQ,cAAqB,IAAI,MAAM;AACvC,SAAQ,iBAA6B,IAAIC,YAAW;AACpD,SAAQ,YAAmB,IAAI,MAAM;AACrC,SAAQ,aAAsB,IAAID,SAAQ;AAC1C,SAAQ,cAAuB,IAAIA,SAAQ;AAC3C,SAAQ,cAAuB,IAAIA,SAAQ;AAC3C,SAAQ,YAAuB,IAAIE,WAAU;AAE7C,SAAQ,wBAAwB,IAAID,YAAW;AAC/C,SAAQ,yBAAyB,IAAIA,YAAW;AAChD,SAAQ,qBAAqB,IAAID,SAAQ;AACzC,SAAQ,qBAAqB,IAAIA,SAAQ;AACzC,SAAQ,qBAAqB,IAAIA,SAAQ;AACzC,SAAQ,qBAAqB,IAAIA,SAAQ;AACzC,SAAQ,qBAAqB,IAAIA,SAAQ;AACzC,SAAQ,iBAAiB,IAAI,IAAI;AACjC,SAAQ,wBAOG;AAEX,SAAO,cAAuB;AAC9B;AAAA,SAAO,eAAwB;AAG/B,SAAQ,eACN;AAGA,SAAK,eAAe;AAAA,MAClB,IAAI,KAAK,OAAO;AAAA,MAChB,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,MAC7B,UAAU,EAAE,aAAa,GAAG,aAAa,EAAE;AAAA,MAC3C;AAAA,IACF;AAAA,EACF;AAAA,EAEO,SAAe;AA5GxB;AA6GI,SAAK,eACH,KAAK,OAAO,gBAAgB,UAAU,OAAK,UAAK,OAAO,oBAAZ,mBAA6B,gBAAe;AAEzF,SAAK,UAAU,IAAI,KAAK,OAAO,UAAU,UAAU,KAAK,UAAU;AAClE,UAAM,kBAAkB,KAAK,OAAO,kBAAkB,aAAa,KAAK,UAAU,GAAG;AACrF,QAAI,oBAAoB,MAAM;AAC5B,WAAK,gBAAgB,gBAAgB,CAAC;AACtC,WAAK,oBAAoB,KAAK,gBAAgB,CAAC,CAAC;AAAA,IAClD;AAEA,UAAI,UAAK,iBAAL,mBAAmB,eAAc,QAAQ,CAAC,KAAK,mBAAmB;AACpE,YAAM,kBAAkB,KAAK,mBAAmB;AAChD,WAAK,OAAO,UAAU,gBAAgB,eAAe;AAAA,IACvD,OAAO;AACL,WAAK,OAAO,UAAU,4BAAmC;AAAA,IAC3D;AAEA,QAAI,KAAK,cAAc;AACrB,WAAK,eAAe;AAAA,IACtB;AAEA,aAAS,IAAI,GAAG,IAAI,KAAK,yBAAyB,KAAK;AACrD,WAAK;AAAA,QACH,KAAK,OAAO,YAAY;AAAA,QACxB,KAAK,OAAO,YAAY,YAAY,KAAK;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAIA,QAAI,KAAK,OAAO,UAAU,SAAS,IAAI,MAAM;AAC3C,WAAK,cAAc;AAAA,IACrB;AACA,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EAEQ,qBAAqC;AAC3C,QAAI,CAAC,KAAK,OAAO,UAAW;AAE5B,UAAM,aAAa,KAAK,kBAAkB,IAAI,IAAI,MAAM;AACxD,QAAI,KAAK,gBAAgB,cAAc,CAAC,KAAK,mBAAmB;AAC9D,UAAI,KAAK,gBAAgB;AACvB;AAAA,MACF;AACA;AAAA,IACF;AACA,QAAI,CAAC,KAAK,cAAc;AACtB;AAAA,IACF;AAEA,QAAI,KAAK,aAAa,aAAa;AACjC;AAAA,IACF;AAEA;AAAA,EACF;AAAA,EAEQ,uBAA6B;AACnC,QAAI,KAAK,gBAAgB,KAAK,aAAa,cAAc,MAAM;AAC7D,WAAK,iBAAiB,KAAK,aAAa;AAAA,IAC1C;AAAA,EACF;AAAA,EAEQ,uBAA6B;AACnC,UAAM,qBAAqB,KAAK,OAAO,cAAc,aAAa,SAAS;AAAA,MACzE,KAAK,OAAO,UAAU;AAAA,IACxB;AACA,UAAM,sBAAsB,qBAAqB;AACjD,QAAI,qBAAqB;AACvB,YAAM,gBAAgB,KAAK,WACxB,IAAI,GAAG,GAAG,CAAC,EACX,gBAAgB,KAAK,OAAO,cAAc,aAAa,UAAU;AACpE,WAAK,iBAAiB,KAAK,MAAM,cAAc,GAAG,cAAc,CAAC;AAAA,IACnE,OAAO;AACL,WAAK,iBAAiB,KAAK;AAAA,QACzB,KAAK,OAAO,cAAc,aAAa,SAAS,IAAI,KAAK,OAAO,UAAU,SAAS;AAAA,QACnF,KAAK,OAAO,cAAc,aAAa,SAAS,IAAI,KAAK,OAAO,UAAU,SAAS;AAAA,MACrF;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,yBAAyB,oBAAwC;AACvE,WAAO,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,OAAO,UAAU,WAAW,IAAI,kBAAkB,CAAC,CAAC;AAAA,EACzF;AAAA,EAEQ,iBAAuB;AAC7B,SAAK,qBAAqB;AAC1B,SAAK,qBAAqB;AAC1B,UAAM,qBAAqB,KAAK,eAAe;AAAA,MAC7C,KAAK;AAAA,MACL,KAAK,iBAAiB,KAAK;AAAA,IAC7B;AACA,UAAM,oBAAoB,KAAK,yBAAyB,kBAAkB;AAC1E,UAAM,cAAc;AACpB,UAAM,eAAe,oBAAoB;AACzC,UAAM,gBAAgB,eAAe,KAAK,OAAO,YAAY;AAC7D,SAAK,OAAO,UAAU,WAAW,cAAc,oBAAoB,aAAa;AAAA,EAClF;AAAA,EAEQ,YAAY,qBAA8B,WAAmB;AAjNvE;AAkNI,UAAM,QAAO,UAAK,iBAAL,mBAAmB;AAEhC,QAAI,KAAK,mBAAmB;AAC1B,WAAK,eAAe;AACpB,WAAK,gBAAgB;AACrB,WAAK,iBAAiB;AACtB,WAAK,cAAc;AAEnB,UAAI,CAAC,MAAM;AACT,aAAK,gBAAgB,CAAC,KAAK,kBAAkB,KAAK,gBAAgB,KAAK,gBAAgB;AACvF,aAAK,UAAU;AACf,aAAK,eAAe;AAAA,MACtB;AAEA,UAAI,QAAQ,KAAK,WAAW,KAAK,cAAc;AAC7C,4BAAoB,KAAK,KAAK,YAAY;AAC1C,aAAK,UAAU;AACf,aAAK,eAAe;AACpB,aAAK;AAAA,MACP,OAAO;AACL,YAAI,KAAK,oBAAoB,IAAI,KAAK,qBAAqB;AACzD,8BAAoB,KAAK,KAAK;AAAA,QAChC;AAAA,MACF;AAAA,IACF,OAAO;AACL,UAAI,QAAQ,CAAC,KAAK,gBAAgB,KAAK,YAAY;AACjD,aAAK,eAAe;AACpB,4BAAoB,KAAK,KAAK,YAAY;AAC1C,aAAK,UAAU;AACf,aAAK,eAAe;AACpB,aAAK;AAAA,MACP,WAAW,QAAQ,KAAK,eAAe;AACrC,4BAAoB,KAAK,KAAK,kBAAkB;AAChD,aAAK,iBAAiB;AACtB,aAAK,eAAe;AACpB,aAAK;AAAA,MACP,OAAO;AACL,4BAAoB,KAAK,KAAK;AAC9B,aAAK,UAAU;AAAA,MACjB;AAAA,IACF;AAEA,QAAI,CAAC,MAAM;AACT,WAAK,eAAe;AACpB,UAAI,CAAC,KAAK,mBAAmB;AAC3B,4BAAoB,KAAK,KAAK;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,cAAc,WAAmB;AApQ3C;AAqQI,UAAM,aAAa,KAAK,oBAAoB,KAAK,mBAAmB,KAAK;AAGzE,UAAM,cAAc,KAAK,IAAI,IAAI,YAAY,SAAS;AACtD,SAAK,kBAAkB,eAAe,WAAW;AAEjD,UAAM,eAAe,KAAK,WAAW,IAAI,GAAG,GAAG,CAAC;AAChD,SAAK,gBAAgB,CAAC,KAAK,kBAAkB,KAAK,gBAAgB,KAAK,gBAAgB;AACvF,SAAK,YAAY,cAAc,SAAS;AAExC,UAAM,WACH,KAAK,sBACF,UAAK,iBAAL,mBAAmB,eACjB,KAAK,mBACL,KAAK,oBACP,KAAK,sBAAsB,KAAK;AAEtC,UAAM,sBAAsB,KAAK,YAAY,IAAI,GAAG,GAAG,CAAC;AAExD,QAAI,KAAK,gBAAgB,KAAK,aAAa,cAAc,MAAM;AAE7D,YAAM,UAAU,KAAK,aAAa;AAClC,YAAM,gBAAgB,KAAK,YACxB,IAAI,GAAG,GAAG,CAAC,EACX,eAAe,KAAK,UAAU,KAAK,iBAAiB,OAAO;AAC9D,0BAAoB,IAAI,aAAa;AAAA,IACvC;AACA,QAAI,oBAAoB,OAAO,IAAI,GAAG;AACpC,0BAAoB,UAAU;AAC9B,0BAAoB,eAAe,OAAO;AAAA,IAC5C;AACA,iBAAa,IAAI,mBAAmB;AACpC,SAAK,kBAAkB,gBAAgB,cAAc,SAAS;AAE9D,SAAK,OAAO,UAAU,SAAS,gBAAgB,KAAK,mBAAmB,SAAS;AAAA,EAClF;AAAA,EAEQ,eAAe,WAAmB,eAAuB,MAAoB;AA1SvF;AA2SI,SAAK,cAAc,aAAa;AAEhC,QAAI,SAAS,GAAG;AACd,YAAM,eAAe,KAAK,wBAAwB,KAAK,OAAO,UAAU,UAAU,SAAS;AAC3F,UAAI,cAAc;AAChB,aAAK,OAAO,UAAU,SAAS,IAAI,aAAa,QAAQ;AACxD,cAAM,eAAe,KAAK,eAAe,aAAa,KAAK,OAAO,UAAU,QAAQ;AACpF,cAAM,oBAAoB,KAAK,UAAU,kBAAkB,aAAa,QAAQ;AAChF,0BAAkB,IAAI;AACtB,0BAAkB,IAAI;AACtB,qBAAa,SAAS,aAAa,iBAAiB;AACpD,qBAAa,SAAS,aAAa,QAAQ;AAC3C,aAAK,OAAO,UAAU,SAAS,kBAAkB,YAAY;AAAA,MAC/D;AAAA,IACF;AACA,SAAK,OAAO,UAAU,kBAAkB;AAExC,UAAM,gBAAgB,KAAK;AAC3B,kBAAc,KAAK,KAAK,YAAY,OAAQ;AAC5C,kBAAc,MACX,aAAa,KAAK,OAAO,UAAU,WAAW,EAC9C,aAAa,KAAK,UAAU;AAC/B,kBAAc,IAAI,aAAa,KAAK,OAAO,UAAU,WAAW,EAAE,aAAa,KAAK,UAAU;AAE9F,UAAM,2BAA2B,KAAK,WAAW,KAAK,cAAc,KAAK;AACzE,SAAK,OAAO,kBAAkB,eAAe,eAAe,KAAK,YAAY,MAAO;AACpF,SAAK,OAAO,UAAU,SAAS,KAAK,cAAc,KAAK;AACvD,UAAM,yBAAyB,cAAc,MAAM,IAAI,wBAAwB;AAE/E,SAAK,oBAAoB,uBAAuB,IAAI;AAEpD,QAAI,KAAK,mBAAmB;AAC1B,WAAK,iBAAiB;AACtB,WAAK,cAAc;AAAA,IACrB;AAEA,QAAI,KAAK,wBAAwB,CAAC,KAAK,mBAAmB;AACxD,WAAK,yBAAyB,KAAK,IAAI;AAAA,IACzC;AAEA,QAAI,GAAC,UAAK,iBAAL,mBAAmB,OAAM;AAC5B,WAAK,eAAe;AAAA,IACtB;AAEA,SAAK,aACH,KAAK,kBAAkB,IAAI,KAC3B,CAAC,KAAK,qBACN,KAAK,IAAI,IAAI,KAAK,yBAAyB,KAAK;AAElD,SAAK,iBAAiB,KAAK,OAAO,UAAU,SAAS,MAAM;AAC3D,SAAK,uBAAuB,KAAK;AAAA,EACnC;AAAA,EAEO,wBAAwB,cAAuB,WAAmB;AACvE,QAAI,eAAmE;AAGvE,QAAI,KAAK,0BAA0B,MAAM;AACvC,YAAM,YAAY,KAAK,sBAAsB,CAAC;AAG9C,YAAM,qBAAqB,UAAU;AACrC,YAAM,kBAAkB,KAAK,sBAAsB,CAAC,EAAE;AAEtD,UAAI,gBAAgB,OAAO,kBAAkB,GAAG;AAAA,MAEhD,OAAO;AAIL,cAAM,mBAAmB,KAAK;AAC9B,cAAM,mBAAmB,KAAK;AAC9B,wBAAgB,UAAU,kBAAkB,kBAAkB,KAAK,kBAAkB;AAGrF,cAAM,sBAAsB,KAAK;AACjC,cAAM,sBAAsB,KAAK;AACjC,2BAAmB;AAAA,UACjB;AAAA,UACA;AAAA,UACA,KAAK;AAAA,QACP;AAGA,cAAM,uBAAuB,KAAK,mBAC/B,KAAK,mBAAmB,EACxB,IAAI,gBAAgB;AAGvB,cAAM,gCAAgC,KAAK,mBACxC,KAAK,YAAY,EACjB,IAAI,gBAAgB;AAGvB,cAAM,oBAAoB,iBAAiB,OAAO,EAAE,SAAS,mBAAmB;AAGhF,cAAM,2BAA2B,KAAK,mBACnC,KAAK,6BAA6B,EAClC,gBAAgB,iBAAiB,EACjC,IAAI,6BAA6B;AAGpC,cAAM,sCAAsC,KAAK,mBAC9C,KAAK,oBAAoB,EACzB,IAAI,wBAAwB;AAE/B,uBAAe;AAAA,UACb,UAAU;AAAA,UACV,UAAU;AAAA,QACZ;AACA,wBAAgB,KAAK,kBAAkB;AAAA,MACzC;AAAA,IACF;AAEA,UAAM,cAAc,KAAK,mBAAmB,KAAK,YAAY;AAC7D,QAAI,cAAc;AAChB,kBAAY,IAAI,aAAa,QAAQ;AAAA,IACvC;AACA,gBAAY,KAAK,YAAY,IAAI,IAAI;AAGrC,UAAM,MAAM,KAAK,eAAe,IAAI,aAAa,UAAU;AAC3D,UAAM,MAAM,KAAK,OAAO,kBAAkB,aAAa,GAAG;AAC1D,QAAI,OAAO,IAAI,CAAC,IAAI,KAAK;AAEvB,YAAM,4BAA4B,IAAI,CAAC;AACvC,WAAK,wBAAwB;AAAA,QAC3B;AAAA,QACA,EAAE,YAAY,0BAA0B,OAAO,MAAM,EAAE;AAAA,MACzD;AAAA,IACF,OAAO;AACL,UAAI,KAAK,0BAA0B,QAAQ,cAAc;AAEvD,aAAK,kBAAkB;AAAA,UACrB,aAAa,SAAS,MAAM,EAAE,aAAa,SAAS;AAAA;AAAA,QACtD;AAAA,MACF;AACA,WAAK,wBAAwB;AAAA,IAC/B;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,qBAA2B;AACjC,UAAM,sBAAsB,KAAK,OAAO,UAAU,mBAAmB,KAAK,cAAc;AACxF,UAAM,mBAAmB,IAAIC,YAAW;AACxC,SAAK,OAAO,cAAc,OAAO,mBAAmB,gBAAgB;AACpE,SAAK,eAAe;AAAA,MAClB,IAAI,KAAK,OAAO;AAAA,MAChB,UAAU;AAAA,QACR,GAAG,KAAK,OAAO,UAAU,SAAS;AAAA,QAClC,GAAG,KAAK,OAAO,UAAU,SAAS;AAAA,QAClC,GAAG,KAAK,OAAO,UAAU,SAAS;AAAA,MACpC;AAAA,MACA,UAAU,EAAE,aAAa,oBAAoB,GAAG,aAAa,oBAAoB,EAAE;AAAA,MACnF,aAAa;AAAA,QACX,GAAG,KAAK,OAAO,cAAc,OAAO,SAAS;AAAA,QAC7C,GAAG,KAAK,OAAO,cAAc,OAAO,SAAS;AAAA,QAC7C,GAAG,KAAK,OAAO,cAAc,OAAO,SAAS;AAAA,MAC/C;AAAA,MACA,eAAe;AAAA,QACb,GAAG,iBAAiB;AAAA,QACpB,GAAG,iBAAiB;AAAA,MACtB;AAAA,MACA,OAAO,KAAK,OAAO,UAAU,oBAAoB;AAAA,IACnD;AAAA,EACF;AAAA,EAEQ,gBAAsB;AAC5B,SAAK,kBAAkB,IAAI;AAC3B,SAAK,OAAO,UAAU,SAAS,IAAI;AACnC,SAAK,oBAAoB;AACzB,SAAK,iBAAiB;AACtB,SAAK,eAAe;AACpB,SAAK,cAAc;AAAA,EACrB;AACF;;;AE3dA,SAAS,cAAAE,aAAY,WAAAC,gBAAe;AAUpC,IAAM,iBAAiB,IAAIC,YAAW;AAE/B,IAAM,mBAAN,MAAuB;AAAA,EAK5B,YAAoB,QAAgC;AAAhC;AAJpB,SAAO;AAKL,SAAK,eAAe;AAAA,MAClB,IAAI,KAAK,OAAO;AAAA,MAChB,UAAU;AAAA,QACR,GAAG,KAAK,OAAO,UAAU,SAAS;AAAA,QAClC,GAAG,KAAK,OAAO,UAAU,SAAS;AAAA,QAClC,GAAG,KAAK,OAAO,UAAU,SAAS;AAAA,MACpC;AAAA,MACA,UAAU;AAAA,QACR,aAAa,eAAe,aAAa,KAAK,OAAO,UAAU,QAAQ,EAAE;AAAA,QACzE,aAAa;AAAA,MACf;AAAA,MACA,OAAO,KAAK;AAAA,IACd;AAAA,EACF;AAAA,EAEO,OAAO,cAA8B,MAAc,WAAyB;AACjF,QAAI,CAAC,KAAK,OAAO,WAAW;AAC1B;AAAA,IACF;AACA,SAAK,kBAAkB,YAAY;AACnC,SAAK,OAAO,UAAU,OAAO,MAAM,SAAS;AAAA,EAC9C;AAAA,EAEQ,kBAAkB,cAAoC;AAC5D,UAAM,EAAE,UAAU,UAAU,MAAM,IAAI;AACtC,SAAK,OAAO,UAAU,SAAS,KAAK,IAAIC,SAAQ,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC,GAAG,IAAI;AACzF,UAAM,qBAAqB,IAAID,YAAW,GAAG,SAAS,aAAa,GAAG,SAAS,WAAW;AAC1F,SAAK,OAAO,UAAU,WAAW,MAAM,oBAAoB,GAAG;AAC9D,QAAI,UAAU,KAAK,kBAAkB;AACnC,WAAK,mBAAmB;AACxB,WAAK,OAAO,UAAU,gBAAgB,KAAK;AAAA,IAC7C;AAAA,EACF;AACF;;;ACnDA,SAAmB,cAAAE,aAAY,WAAAC,gBAAe;AAIvC,SAAS,yBAAyB,WAAqB,QAA0B;AACtF,SAAO;AAAA,IACL,GAAG,QAAQ,UAAU,QAAQ;AAAA,IAC7B,GAAG,QAAQ,UAAU,UAAU;AAAA,IAC/B,GAAG,QAAQ,OAAO,QAAQ;AAAA,IAC1B,GAAG,QAAQ,OAAO,UAAU;AAAA,EAC9B,EAAE,KAAK,GAAG;AACZ;AAEO,SAAS,yBAAyB,MAGvC;AACA,QAAM,SAAS,KAAK,MAAM,GAAG,EAAE,IAAI,MAAM;AACzC,SAAO;AAAA,IACL,WAAW;AAAA,MACT,UAAU,IAAIC,SAAQ,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAAA,MACrD,YAAY,IAAIC,YAAW,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAAA,IACvE;AAAA,IACA,QAAQ;AAAA,MACN,UAAU,IAAID,SAAQ,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC;AAAA,MACrD,YAAY,IAAIC,YAAW,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;AAAA,IAC3E;AAAA,EACF;AACF;;;AJQO,IAAM,mBAAN,MAAuB;AAAA,EAiB5B,YAAoB,QAAgC;AAAhC;AAhBpB,SAAgB,mBAAmB,IAAIC,SAAQ,GAAG,KAAK,CAAC;AAExD,SAAQ,gBAAwB;AAEhC,SAAO,mBAA2C,oBAAI,IAAI;AAC1D,SAAO,6BAA4D,oBAAI,IAAI;AAE3E,SAAQ,wBAAiC;AAEzC,SAAO,iBAAmC;AAE1C,SAAQ,qBAA2C,oBAAI,IAAI;AAG3D,SAAQ,qBAA6B;AAGnC,SAAK,QAAQ,IAAIC,OAAM;AAAA,EACzB;AAAA,EAEO,oBACL,IACA,UACA,sBACA,gBAAyB,IAAID,SAAQ,GACrC,gBAAuB,IAAIE,OAAM,GACjC;AACA,UAAM,YAAY,IAAI,UAAU;AAAA,MAC9B;AAAA,MACA;AAAA,MACA,iBAAiB,KAAK,OAAO;AAAA,MAC7B,sBAAsB,KAAK,OAAO;AAAA,MAClC,aAAa;AAAA,MACb,qBAAqB,MAAM;AAAA,MAE3B;AAAA,MACA,eAAe,KAAK,OAAO;AAAA,MAC3B,UAAU,KAAK,OAAO;AAAA,MACtB,SAAS;AAAA,IACX,CAAC;AACD,UAAM,aAAa,IAAIC,YAAW,EAAE,aAAa,UAAU,QAAQ;AACnE,SAAK,OAAO,WAAW;AAAA,MACrB;AAAA,MACA,UAAU;AAAA,QACR,GAAG,cAAc;AAAA,QACjB,GAAG,cAAc;AAAA,QACjB,GAAG,cAAc;AAAA,MACnB;AAAA,MACA,UAAU,EAAE,aAAa,WAAW,GAAG,aAAa,WAAW,EAAE;AAAA,MACjE;AAAA,IACF,CAAC;AACD,SAAK,gBAAgB;AACrB,SAAK,iBAAiB;AACtB,SAAK,kBAAkB,IAAI,gBAAgB;AAAA,MACzC,WAAW,KAAK;AAAA,MAChB,IAAI,KAAK;AAAA,MACT,mBAAmB,KAAK,OAAO;AAAA,MAC/B,iBAAiB,KAAK,OAAO;AAAA,MAC7B,iBAAiB,KAAK,OAAO;AAAA,MAC7B,eAAe,KAAK,OAAO;AAAA,MAC3B,aAAa,KAAK,OAAO;AAAA,IAC3B,CAAC;AACD,SAAK,eAAe,SAAS,IAAI,cAAc,GAAG,cAAc,GAAG,cAAc,CAAC;AAClF,SAAK,eAAe,SAAS,IAAI,cAAc,GAAG,cAAc,GAAG,cAAc,CAAC;AAClF,SAAK,MAAM,IAAI,SAAS;AACxB,SAAK,wBAAwB;AAAA,EAC/B;AAAA,EAEO,eAAe,WAAsB;AAC1C,cAAU,yBAAyB,KAAK,eAAe;AAAA,EACzD;AAAA,EAEO,qBACL,IACA,UACA,sBACA,gBAAyB,IAAIH,SAAQ,GACrC,gBAAuB,IAAIE,OAAM,GACjC;AACA,UAAM,YAAY,IAAI,UAAU;AAAA,MAC9B;AAAA,MACA;AAAA,MACA,iBAAiB,KAAK,OAAO;AAAA,MAC7B,sBAAsB,KAAK,OAAO;AAAA,MAClC,aAAa;AAAA,MACb,qBAAqB,MAAM;AAAA,MAE3B;AAAA,MACA,eAAe,KAAK,OAAO;AAAA,MAC3B,UAAU,KAAK,OAAO;AAAA,MACtB,SAAS;AAAA,IACX,CAAC;AAED,SAAK,iBAAiB,IAAI,IAAI,SAAS;AACvC,cAAU,SAAS,IAAI,cAAc,GAAG,cAAc,GAAG,cAAc,CAAC;AACxE,cAAU,SAAS,IAAI,cAAc,GAAG,cAAc,GAAG,cAAc,CAAC;AACxE,UAAM,mBAAmB,IAAI,iBAAiB,EAAE,WAAW,GAAG,CAAC;AAC/D,SAAK,2BAA2B,IAAI,IAAI,gBAAgB;AACxD,SAAK,MAAM,IAAI,SAAS;AAAA,EAC1B;AAAA,EAEO,uCAA4D;AACjE,QAAI,KAAK,kBAAkB,KAAK,kBAAkB,KAAK,gBAAgB;AACrE,aAAO;AAAA,QACL,UAAU,KAAK,eAAe;AAAA,QAC9B,UAAU,KAAK,eAAe;AAAA,MAChC;AAAA,IACF;AACA,WAAO;AAAA,MACL,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,MAC7B,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,IAC/B;AAAA,EACF;AAAA,EAEO,QAAQ;AACb,eAAW,CAAC,IAAI,SAAS,KAAK,KAAK,kBAAkB;AACnD,WAAK,MAAM,OAAO,SAAS;AAC3B,WAAK,iBAAiB,OAAO,EAAE;AAC/B,WAAK,2BAA2B,OAAO,EAAE;AAAA,IAC3C;AACA,QAAI,KAAK,gBAAgB;AACvB,WAAK,MAAM,OAAO,KAAK,cAAc;AACrC,WAAK,iBAAiB;AAAA,IACxB;AAAA,EACF;AAAA,EAEO,qBAAqB,IAAY,OAAgB;AACtD,SAAK,mBAAmB,IAAI,IAAI,KAAK;AAAA,EACvC;AAAA,EAEO,kBAAkB,SAAiB;AACxC,QAAI,KAAK,gBAAgB;AACvB,WAAK,eAAe,cAAc,OAAO;AAAA,IAC3C;AAAA,EACF;AAAA,EAEO,cAAc,IAAY,SAAiB;AA7KpD;AA8KI,eAAK,iBAAiB,IAAI,EAAE,MAA5B,mBAA+B,cAAc;AAAA,EAC/C;AAAA,EAEO,iBAAiB,IAAY;AAClC,UAAM,gBAAgB,KAAK,OAAO,iBAAiB,EAAE;AAErD,QAAI,KAAK,kBAAkB,KAAK,iBAAiB,IAAI;AACnD,WAAK,eAAe;AAAA,QAClB,cAAc;AAAA,QACd,cAAc;AAAA,MAChB;AAAA,IACF;AAEA,UAAM,kBAAkB,KAAK,iBAAiB,IAAI,EAAE;AACpD,QAAI,iBAAiB;AACnB,sBAAgB,gBAAgB,cAAc,UAAU,cAAc,oBAAoB;AAAA,IAC5F;AAAA,EACF;AAAA,EAEO,SAAS;AAjMlB;AAkMI,QAAI,KAAK,gBAAgB;AACvB,WAAK,eAAe,OAAO,KAAK,OAAO,YAAY,MAAM,KAAK,OAAO,YAAY,SAAS;AAC1F,UAAI,KAAK,mBAAmB,IAAI,KAAK,aAAa,GAAG;AACnD,mBAAK,eAAe,sBAApB,mBAAuC;AAAA,UACrC,KAAK,mBAAmB,IAAI,KAAK,aAAa;AAAA;AAAA,MAElD;AAEA,WAAK,gBAAgB,OAAO;AAC5B,YAAM,eAAc,oBAAI,KAAK,GAAE,QAAQ;AACvC,YAAM,sBAAsB,cAAc,KAAK;AAC/C,UAAI,sBAAsB,IAAI;AAE5B,aAAK,qBAAqB;AAC1B,aAAK,OAAO,WAAW,KAAK,gBAAgB,YAAY;AAAA,MAC1D;AAEA,YAAM,eAAe,IAAIF,SAAQ;AACjC,mBACG,IAAI,KAAK,gBAAgB,EACzB,gBAAgB,KAAK,eAAe,UAAU,EAC9C,IAAI,KAAK,eAAe,QAAQ;AACnC,WAAK,OAAO,cAAc,UAAU,YAAY;AAEhD,iBAAW,CAAC,IAAI,MAAM,KAAK,KAAK,OAAO,kBAAkB;AACvD,YAAI,KAAK,iBAAiB,IAAI,EAAE,KAAK,KAAK,mBAAmB,IAAI,EAAE,GAAG;AACpE,gBAAM,YAAY,KAAK,iBAAiB,IAAI,EAAE;AAC9C,uDAAW,sBAAX,mBAA8B,YAAY,KAAK,mBAAmB,IAAI,EAAE;AAAA,QAC1E;AACA,cAAM,EAAE,SAAS,IAAI;AAErB,YAAI,CAAC,KAAK,iBAAiB,IAAI,EAAE,KAAK,KAAK,0BAA0B,MAAM;AACzE,gBAAM,gBAAgB,KAAK,OAAO,iBAAiB,EAAE;AACrD,eAAK;AAAA,YACH;AAAA,YACA,cAAc;AAAA,YACd,cAAc;AAAA,YACd,IAAIA,SAAQ,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAAA,UAChD;AAAA,QACF;AAEA,cAAM,sBAAsB,KAAK,2BAA2B,IAAI,EAAE;AAClE,YAAI,qBAAqB;AACvB,8BAAoB;AAAA,YAClB;AAAA,YACA,KAAK,OAAO,YAAY;AAAA,YACxB,KAAK,OAAO,YAAY;AAAA,UAC1B;AAAA,QACF;AAAA,MACF;AAEA,iBAAW,CAAC,IAAI,SAAS,KAAK,KAAK,kBAAkB;AACnD,YAAI,CAAC,KAAK,OAAO,iBAAiB,IAAI,EAAE,GAAG;AACzC,0BAAU,sBAAV,mBAA6B;AAC7B,eAAK,MAAM,OAAO,SAAS;AAC3B,eAAK,iBAAiB,OAAO,EAAE;AAC/B,eAAK,2BAA2B,OAAO,EAAE;AAAA,QAC3C;AAAA,MACF;AAEA,UACE,KAAK,OAAO,qBACZ,KAAK,OAAO,YAAY,QAAQ,OAAO,KACvC,SAAS,SAAS;AAAA;AAAA;AAAA;AAAA,MAKlB,CAAC,KAAK,OAAO,cAAc,eAAe,GAC1C;AACA,cAAM,OAAO;AAAA,UACX,KAAK;AAAA,UACL,KAAK,OAAO,cAAc;AAAA,QAC5B;AACA,cAAM,MAAM,IAAI,IAAI,OAAO,SAAS,IAAI;AACxC,YAAI,OAAO;AACX,eAAO,QAAQ,aAAa,CAAC,GAAG,IAAI,GAAG;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AACF;;;AKlRA,SAAS,eAAAI,oBAAoC;AAI7C,IAAM,WAAN,MAAqB;AAAA,EAInB,YAAY,UAAkB,KAAK;AACjC,SAAK,UAAU;AACf,SAAK,QAAQ,oBAAI,IAAI;AAAA,EACvB;AAAA,EAEA,IAAI,KAAuB;AACzB,UAAM,OAAO,KAAK,MAAM,IAAI,GAAG;AAC/B,QAAI,MAAM;AACR,WAAK,MAAM,OAAO,GAAG;AACrB,WAAK,MAAM,IAAI,KAAK,IAAI;AAAA,IAC1B;AACA,WAAO;AAAA,EACT;AAAA,EAEA,IAAI,KAAQ,OAAgB;AAC1B,QAAI,KAAK,MAAM,QAAQ,KAAK,SAAS;AACnC,YAAM,YAAY,KAAK,MAAM,KAAK,EAAE,KAAK,EAAE;AAC3C,WAAK,MAAM,OAAO,SAAS;AAAA,IAC7B;AACA,SAAK,MAAM,IAAI,KAAK,KAAK;AAAA,EAC3B;AACF;AAOO,IAAM,uBAAN,MAA2B;AAAA,EAKhC,YACE,eAAuB,KACf,QAAiB,OACzB;AADQ;AANV,SAAiB,cAA2B,IAAIA,aAAY;AAE5D,SAAQ,eAAkD,oBAAI,IAAI;AAMhE,SAAK,aAAa,IAAI,SAAS,YAAY;AAAA,EAC7C;AAAA,EAIA,MAAM,KACJ,SACA,UAC+C;AAC/C,UAAM,cAAc,KAAK,WAAW,IAAI,OAAO;AAE/C,QAAI,aAAa;AACf,aAAO,KAAK,YAAY,SAAS,UAAU,YAAY,iBAAiB;AAAA,IAC1E,OAAO;AACL,UAAI,KAAK,UAAU,MAAM;AACvB,gBAAQ,IAAI,WAAW,OAAO,cAAc;AAAA,MAC9C;AACA,YAAM,cAAc,KAAK,aAAa,IAAI,OAAO;AACjD,UAAI;AACF,eAAO,YAAY,KAAK,CAAC,gBAAgB;AACvC,gBAAM,UAAU,IAAI,gBAAgB,YAAY,IAAI;AACpD,iBAAO,KAAK,YAAY,SAAS,UAAU,YAAY,iBAAiB;AAAA,QAC1E,CAAC;AAEH,YAAM,cAAoC,MAAM,OAAO,EACpD,KAAK,CAAC,aAAa,SAAS,KAAK,CAAC,EAClC,KAAK,CAAC,SAAS;AACd,cAAM,oBAAoB,QAAQ,MAAM,GAAG,EAAE,IAAI,KAAK;AACtD,cAAM,SAAS,EAAE,MAAM,kBAAkB;AACzC,aAAK,WAAW,IAAI,SAAS,MAAM;AACnC,aAAK,aAAa,OAAO,OAAO;AAChC,eAAO;AAAA,MACT,CAAC;AAEH,WAAK,aAAa,IAAI,SAAS,WAAW;AAC1C,aAAO,YAAY,KAAK,CAAC,gBAAgB;AACvC,cAAM,UAAU,IAAI,gBAAgB,YAAY,IAAI;AACpD,eAAO,KAAK,YAAY,SAAS,UAAU,YAAY,iBAAiB;AAAA,MAC1E,CAAC;AAAA,IACH;AAAA,EACF;AAAA,EAEA,MAAc,YACZ,KACA,UACA,WAC+C;AAC/C,WAAO,IAAI,QAAQ,OAAO,SAAS,WAAW;AAC5C,YAAM,kBAAmC,MAAM,KAAK,YAAY;AAAA,QAC9D;AAAA,QACA,CAAC,QAAgB,UAAkB;AAAA,QAEnC;AAAA,MACF;AACA,UAAI,aAAa,SAAS;AACxB,gBAAQ,gBAAgB,KAAiB;AAAA,MAC3C,WAAW,aAAa,aAAa;AACnC,gBAAQ,gBAAgB,WAAW,CAAC,CAAkB;AAAA,MACxD,OAAO;AACL,cAAM,QAAQ,0BAA0B,QAAQ,8BAA8B,GAAG;AACjF,gBAAQ,MAAM,KAAK;AACnB,eAAO,KAAK;AAAA,MACd;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AC3GO,IAAK,MAAL,kBAAKC,SAAL;AACL,EAAAA,KAAA,OAAI;AACJ,EAAAA,KAAA,OAAI;AACJ,EAAAA,KAAA,OAAI;AACJ,EAAAA,KAAA,OAAI;AACJ,EAAAA,KAAA,WAAQ;AACR,EAAAA,KAAA,WAAQ;AACR,EAAAA,KAAA,OAAI;AAPM,SAAAA;AAAA,GAAA;AAaL,IAAM,kBAAN,MAAsB;AAAA,EAK3B,YAAoB,wBAAuC,MAAM,MAAM;AAAnD;AAJpB,SAAQ,OAAO,oBAAI,IAAqB;AACxC,SAAQ,yBAAyB,IAAI,uBAAuB;AAC5D,SAAQ,WAAyB,oBAAI,IAAI;AAGvC,SAAK,uBAAuB,IAAI,UAAU,WAAW,KAAK,UAAU,KAAK,IAAI,CAAC;AAC9E,SAAK,uBAAuB,IAAI,UAAU,SAAS,KAAK,QAAQ,KAAK,IAAI,CAAC;AAC1E,SAAK,uBAAuB,IAAI,QAAQ,QAAQ,KAAK,cAAc,KAAK,IAAI,CAAC;AAAA,EAC/E;AAAA,EAEQ,cAAc,QAA0B;AAC9C,SAAK,KAAK,MAAM;AAAA,EAClB;AAAA,EAEQ,UAAU,OAA4B;AAC5C,QAAI,KAAK,sBAAsB,GAAG;AAChC,UAAI,MAAM,IAAI,WAAW,KAAK,MAAM,IAAI,CAAC,MAAM,KAAK;AAElD;AAAA,MACF;AACA,UAAI,MAAM,SAAS;AAEjB;AAAA,MACF;AACA,WAAK,KAAK,IAAI,MAAM,IAAI,YAAY,GAAG,IAAI;AAC3C,YAAM,eAAe;AAAA,IACvB;AAAA,EACF;AAAA,EAEQ,QAAQ,OAA4B;AAC1C,SAAK,KAAK,IAAI,MAAM,IAAI,YAAY,GAAG,KAAK;AAC5C,QAAI,KAAK,SAAS,IAAI,MAAM,IAAI,YAAY,CAAQ,GAAG;AACrD,WAAK,SAAS,IAAI,MAAM,IAAI,YAAY,CAAQ,EAAG;AAAA,IACrD;AAAA,EACF;AAAA,EAEO,aAAa,KAAsB;AACxC,WAAO,KAAK,KAAK,IAAI,GAAG,KAAK;AAAA,EAC/B;AAAA,EAEO,iBAAiB,KAAU,UAA4B;AAC5D,SAAK,SAAS,IAAI,KAAK,QAAQ;AAAA,EACjC;AAAA,EAEO,uBAAgC;AACrC,WAAO,CAAC,aAAO,aAAO,aAAO,WAAK,EAAE,KAAK,CAAC,QAAQ,KAAK,aAAa,GAAG,CAAC;AAAA,EAC1E;AAAA,EAEQ,aAAsB;AAC5B,WAAO,KAAK,aAAa,WAAK;AAAA,EAChC;AAAA,EAEQ,cAAuB;AAC7B,WAAO,KAAK,aAAa,WAAK;AAAA,EAChC;AAAA,EAEQ,UAAmB;AACzB,WAAO,KAAK,aAAa,WAAK;AAAA,EAChC;AAAA,EAEQ,WAAoB;AAC1B,WAAO,KAAK,aAAa,WAAK;AAAA,EAChC;AAAA,EAEQ,SAAkB;AACxB,WAAO,KAAK,aAAa,mBAAS;AAAA,EACpC;AAAA,EAEQ,UAAmB;AACzB,WAAO,KAAK,aAAa,eAAS;AAAA,EACpC;AAAA,EAEO,YAAsF;AAC3F,UAAM,MAAM,KAAK,SAAS,IAAI,IAAI,MAAM,KAAK,QAAQ,IAAI,IAAI;AAC7D,UAAM,MAAM,KAAK,YAAY,IAAI,IAAI,MAAM,KAAK,WAAW,IAAI,IAAI;AACnE,UAAM,OAAO,KAAK,QAAQ;AAC1B,QAAI,OAAO,KAAK,OAAO,GAAG;AACxB,UAAI,KAAK,QAAQ,GAAG;AAClB,eAAO,EAAE,WAAW,MAAM,aAAa,OAAO,KAAK;AAAA,MACrD;AACA,aAAO;AAAA,IACT;AACA,UAAM,YAAY,KAAK,MAAM,IAAI,EAAE;AACnC,WAAO,EAAE,WAAW,aAAa,KAAK,OAAO,GAAG,KAAK;AAAA,EACvD;AAAA,EAEO,UAAU;AACf,SAAK,uBAAuB,MAAM;AAClC,SAAK,SAAS,MAAM;AAAA,EACtB;AACF;;;ACrGA,IAAM,qBAAqB;AAEpB,IAAM,kBAAN,MAAM,iBAAgB;AAAA,EAe3B,YACU,eACA,QACR;AAFQ;AACA;AARV,SAAQ,oBAAmC;AAC3C,SAAQ,iBAAqE;AAG7E,SAAQ,gBAA+B;AAgLvC,SAAQ,qBAAqB,MAAY;AACvC,WAAK,iBAAiB;AACtB,WAAK,sBAAsB,MAAM,OAAO,GAAG,KAAK,SAAS,KAAK,WAAW;AACzE,WAAK,sBAAsB,MAAM,MAAM,GAAG,KAAK,SAAS,KAAK,WAAW;AAAA,IAC1E;AA9KE,SAAK,SAAS,OAAO,UAAU;AAC/B,SAAK,cAAc,OAAO,eAAe,KAAK,SAAS;AACvD,SAAK,eAAe,KAAK,WAAW,KAAK,OAAO,iBAAiB;AAEjE,SAAK,UAAU,SAAS,cAAc,KAAK;AAC3C,UAAM,QAAQ,KAAK,QAAQ;AAC3B,UAAM,UAAU,KAAK,eAAe,SAAS;AAC7C,UAAM,WAAW;AACjB,UAAM,QAAQ;AACd,UAAM,SAAS;AACf,UAAM,SAAS;AACf,UAAM,SAAS;AACf,UAAM,aAAa;AACnB,UAAM,iBAAiB;AACvB,UAAM,gBAAgB;AACtB,UAAM,UAAU;AAChB,UAAM,YAAY;AAClB,UAAM,aAAa;AACnB,SAAK,cAAc,YAAY,KAAK,OAAO;AAE3C,SAAK,sBAAsB,KAAK,WAAW;AAC3C,SAAK,QAAQ,YAAY,KAAK,mBAAmB;AAEjD,SAAK,wBAAwB,KAAK,aAAa;AAC/C,SAAK,oBAAoB,YAAY,KAAK,qBAAqB;AAE/D,SAAK,aAAa,KAAK,iBAAiB;AACxC,SAAK,QAAQ,YAAY,KAAK,UAAU;AAExC,SAAK,WAAW;AAEhB,SAAK,mBAAmB;AAAA,EAC1B;AAAA,EAEA,OAAc,gBAAyB;AACrC,QAAI;AACF,eAAS,YAAY,YAAY;AACjC,aAAO;AAAA,IACT,SAAS,GAAG;AACV,aAAO;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,aAAa;AACnB,WAAO,iBAAgB,cAAc;AAAA,EACvC;AAAA,EAEQ,aAAa;AACnB,UAAM,OAAO,SAAS,cAAc,MAAM;AAC1C,UAAM,QAAQ,KAAK;AACnB,UAAM,cAAc;AACpB,UAAM,QAAQ,GAAG,KAAK,SAAS,CAAC;AAChC,UAAM,SAAS,GAAG,KAAK,SAAS,CAAC;AACjC,UAAM,WAAW;AACjB,UAAM,UAAU;AAChB,UAAM,eAAe;AACrB,UAAM,cAAc;AACpB,UAAM,cAAc;AACpB,UAAM,cAAc;AACpB,UAAM,gBAAgB;AACtB,UAAM,aAAa;AACnB,WAAO;AAAA,EACT;AAAA,EAEQ,eAAe;AACrB,UAAM,SAAS,SAAS,cAAc,KAAK;AAC3C,UAAM,QAAQ,OAAO;AACrB,UAAM,QAAQ,GAAG,KAAK,cAAc,CAAC;AACrC,UAAM,SAAS,GAAG,KAAK,cAAc,CAAC;AACtC,UAAM,WAAW;AACjB,UAAM,eAAe;AACrB,UAAM,kBAAkB;AACxB,UAAM,cAAc;AACpB,UAAM,cAAc;AACpB,UAAM,cAAc;AACpB,UAAM,aAAa;AACnB,WAAO;AAAA,EACT;AAAA,EAEQ,mBAAmB;AACzB,UAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,WAAO,cAAc;AACrB,UAAM,QAAQ,OAAO;AACrB,UAAM,cAAc;AACpB,UAAM,QAAQ;AACd,UAAM,SAAS;AACf,UAAM,eAAe;AACrB,UAAM,QAAQ;AACd,UAAM,OAAO;AACb,UAAM,WAAW;AACjB,UAAM,kBAAkB;AACxB,UAAM,QAAQ;AACd,UAAM,cAAc;AACpB,UAAM,cAAc;AACpB,UAAM,cAAc;AACpB,UAAM,gBAAgB;AACtB,UAAM,aAAa;AACnB,WAAO;AAAA,EACT;AAAA,EAEQ,aAAmB;AACzB,SAAK,oBAAoB,iBAAiB,eAAe,KAAK,sBAAsB,KAAK,IAAI,CAAC;AAC9F,SAAK,oBAAoB;AAAA,MACvB;AAAA,MACA,KAAK,iCAAiC,KAAK,IAAI;AAAA,IACjD;AACA,SAAK,oBAAoB;AAAA,MACvB;AAAA,MACA,KAAK,iCAAiC,KAAK,IAAI;AAAA,IACjD;AAEA,SAAK,WAAW,iBAAiB,eAAe,KAAK,kBAAkB,KAAK,IAAI,CAAC;AACjF,SAAK,WAAW;AAAA,MACd;AAAA,MACA,KAAK,iCAAiC,KAAK,IAAI;AAAA,IACjD;AACA,SAAK,WAAW;AAAA,MACd;AAAA,MACA,KAAK,iCAAiC,KAAK,IAAI;AAAA,IACjD;AACA,aAAS,iBAAiB,eAAe,KAAK,cAAc,KAAK,IAAI,CAAC;AACtE,aAAS,iBAAiB,aAAa,KAAK,YAAY,KAAK,IAAI,CAAC;AAClE,aAAS,iBAAiB,iBAAiB,KAAK,YAAY,KAAK,IAAI,CAAC;AAAA,EACxE;AAAA,EAEQ,iCAAiC,KAAyB;AAChE,QAAI,eAAe;AACnB,QAAI,gBAAgB;AAAA,EACtB;AAAA,EAEQ,kBAAkB,KAAyB;AACjD,QAAI,KAAK,kBAAkB,MAAM;AAC/B,WAAK,gBAAgB,IAAI;AAAA,IAC3B;AAAA,EACF;AAAA,EAEQ,sBAAsB,KAAyB;AACrD,QAAI,eAAe;AACnB,QAAI,gBAAgB;AACpB,QAAI,IAAI,YAAY,GAAG;AACrB;AAAA,IACF;AACA,QAAI,KAAK,sBAAsB,MAAM;AACnC,WAAK,oBAAoB,IAAI;AAC7B,WAAK,0BAA0B,GAAG;AAAA,IACpC;AAAA,EACF;AAAA,EAEQ,cAAc,KAAyB;AAC7C,QAAI,eAAe;AACnB,QAAI,gBAAgB;AACpB,QAAI,IAAI,cAAc,KAAK,mBAAmB;AAC5C;AAAA,IACF;AACA,SAAK,0BAA0B,GAAG;AAAA,EACpC;AAAA,EAEQ,YAAY,KAAyB;AAC3C,QAAI,eAAe;AACnB,QAAI,gBAAgB;AAEpB,QAAI,IAAI,cAAc,KAAK,eAAe;AACxC,WAAK,gBAAgB;AAAA,IACvB;AACA,QAAI,IAAI,cAAc,KAAK,mBAAmB;AAC5C,WAAK,oBAAoB;AACzB,WAAK,mBAAmB;AAAA,IAC1B;AAAA,EACF;AAAA,EAQQ,0BAA0B,OAA2B;AAC3D,UAAM,OAAO,KAAK,oBAAoB,sBAAsB;AAC5D,UAAM,KAAK,MAAM,WAAW,KAAK,OAAO,KAAK;AAC7C,UAAM,KAAK,MAAM,WAAW,KAAK,MAAM,KAAK;AAE5C,UAAM,WAAW,KAAK,IAAI,KAAK,KAAK,KAAK,KAAK,KAAK,EAAE,GAAG,KAAK,MAAM;AACnE,UAAM,QAAQ,KAAK,MAAM,IAAI,EAAE;AAC/B,UAAM,eAAe,WAAW,KAAK,IAAI,KAAK;AAC9C,UAAM,eAAe,WAAW,KAAK,IAAI,KAAK;AAE9C,SAAK,sBAAsB,MAAM,OAAO,GAAG,eAAe,KAAK,SAAS,KAAK,WAAW;AACxF,SAAK,sBAAsB,MAAM,MAAM,GAAG,eAAe,KAAK,SAAS,KAAK,WAAW;AAEvF,UAAM,YAAY,KAAK,MAAM,IAAI,EAAE;AACnC,UAAM,QAAQ,WAAW,KAAK;AAC9B,UAAM,cAAc,QAAQ;AAC5B,SAAK,iBAAiB,EAAE,WAAW,YAAY;AAAA,EACjD;AAAA,EAEO,YAAsF;AAC3F,UAAM,OAAO,KAAK,kBAAkB;AACpC,QAAI,CAAC,KAAK,gBAAgB;AACxB,UAAI,MAAM;AACR,eAAO,EAAE,WAAW,MAAM,aAAa,OAAO,KAAW;AAAA,MAC3D;AACA,aAAO;AAAA,IACT;AACA,WAAO;AAAA,MACL,GAAG,KAAK;AAAA,MACR;AAAA,IACF;AAAA,EACF;AACF;;;AC3OA;AAAA,EAKE;AAAA,EAEA;AAAA,EAEA;AAAA,EAEA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EAEA;AAAA,EACA;AAAA,OACK;AACP,SAAwB,SAAAC,cAAgE;AAcjF,IAAM,sBAAN,MAA0B;AAAA,EAY/B,YAAoB,QAAmC;AAAnC;AAJpB,SAAiB,aAAa,oBAAI,IAAuC;AAKvE,SAAK,QAAQ,IAAIA,OAAM;AACvB,SAAK,gBAAgB,cAAc,KAAK,KAAK,OAAO,aAAa;AAEjE,UAAM,kBAA0C;AAAA,MAC9C,eAAe;AAAA,MACf,eAAe;AAAA,MACf,2BAA2B,MAAM;AAC/B,eAAO;AAAA,MACT;AAAA,MACA,kBAAkB,MAAM;AACtB,eAAO,KAAK;AAAA,MACd;AAAA,MACA,8BACE,aACe;AACf,eAAO,0BAA0B;AAAA,UAC/B;AAAA,UACA,KAAK,OAAO;AAAA,UACZ,KAAK,OAAO;AAAA,QACd;AAAA,MACF;AAAA,MACA,UAAgB;AAAA,MAAC;AAAA,MACjB,kBAAkB,MAAM;AACtB,eAAO,OAAO;AAAA,MAChB;AAAA,MACA,WAAW,MAAM;AACf,eAAO,OAAO;AAAA,MAChB;AAAA,MACA,eAAe,MAAM;AACnB,eAAO,OAAO;AAAA,MAChB;AAAA,MACA,4BAA4B,MAAM;AAChC,eAAO,KAAK,OAAO,2BAA2B;AAAA,MAChD;AAAA,IACF;AAEA,UAAM,EAAE,qBAAqB,mBAAmB,IAAI,mBAAmB;AAAA,MACrE,KAAK,OAAO;AAAA,MACZ,CAAC,gBAAqD;AACpD,eAAO,gBAAgB,8BAA8B,WAAW;AAAA,MAClE;AAAA,IACF;AACA,SAAK,qBAAqB;AAC1B,SAAK,sBAAsB;AAC3B,SAAK,yBAAyB,IAAI,uBAAuB;AACzD,SAAK,sBAAsB,IAAI,uBAAuB;AAEtD,SAAK,WAAW;AAAA,MACd,qBAA6C;AAC3C,eAAO;AAAA,MACT;AAAA,MACA,qBAA8B;AAC5B,eAAO;AAAA,MACT;AAAA,MACA,aAAa,CAAC,QAAkB,aAA+C;AAC7E,aAAK,OAAO,kBAAkB,eAAe,QAAiB,QAAQ;AAAA,MACxE;AAAA,MACA,gBAAgB,CAAC,WAAqB;AACpC,aAAK,OAAO,kBAAkB,kBAAkB,MAAe;AAAA,MACjE;AAAA,MACA,gBAAgB,CAAC,WAAqB;AACpC,aAAK,OAAO,kBAAkB,kBAAkB,MAAe;AAAA,MACjE;AAAA,MACA,4BAA4B,KAAK,OAAO;AAAA,MACxC,gBAAgB,CAAC,gBAAqD;AACpE,aAAK,oBAAoB,eAAe,WAAW;AAAA,MACrD;AAAA,MACA,mBAAmB,CAAC,gBAAqD;AACvE,aAAK,oBAAoB,kBAAkB,WAAW;AAAA,MACxD;AAAA,MACA,mBAAmB,CAAC,gBAAqD;AACvE,aAAK,oBAAoB,kBAAkB,WAAW;AAAA,MACxD;AAAA,MACA,cAAc,CAAC,cAAiD;AAC9D,aAAK,WAAW,IAAI,SAAS;AAAA,MAC/B;AAAA,MACA,iBAAiB,MAAM;AAAA,MAEvB;AAAA,MACA,iBAAiB,CAAC,cAAiD;AACjE,aAAK,WAAW,OAAO,SAAS;AAAA,MAClC;AAAA,MACA,QAAQ,CACN,aACA,aACA,aACG;AACH,aAAK,cAAc,OAAO,aAAa,aAAa,QAAQ;AAAA,MAC9D;AAAA,MACA,MAAM,CACJ,WACA,aACA,mBACG;AACH,aAAK,cAAc,KAAK,WAAW,aAAa,cAAc;AAAA,MAChE;AAAA,MACA,2BAA2B,MAAM;AAC/B,eAAO,KAAK;AAAA,MACd;AAAA,IACF;AAEA,SAAK,eAAe,oBAAoB;AAAA,MACtC,KAAK,OAAO;AAAA,MACZ,KAAK;AAAA,MACL,KAAK,OAAO;AAAA,IACd;AAAA,EACF;AAAA,EAEA,cAAc,SAAiB;AAC7B,eAAW,aAAa,KAAK,YAAY;AACvC,gBAAU,QAAQ,OAAO;AAAA,IAC3B;AAAA,EACF;AAAA,EAEA,UAAU;AACR,SAAK,cAAc,QAAQ;AAC3B,SAAK,aAAa,QAAQ;AAC1B,SAAK,mBAAmB,QAAQ;AAAA,EAClC;AACF;;;ACtKA,YAAY,sBAAsB;AAUlC,SAAoB,YAAY;;;ACLzB,IAAM,YAAY;AAAA,EACvB,YAAY;AAAA,EACZ,UAAU;AAAA,EACV,YAAY;AACd;AAEA,IAAM,aAAa;AAAA,EACjB,YAAY;AAAA,IACV,QAAQ,EAAE,KAAK,IAAM,KAAK,GAAK,MAAM,KAAK;AAAA,EAC5C;AAAA,EACA,UAAU;AAAA,IACR,QAAQ,EAAE,KAAK,GAAK,KAAK,GAAK,MAAM,KAAK;AAAA,EAC3C;AAAA,EACA,YAAY;AAAA,IACV,QAAQ,EAAE,KAAK,GAAK,KAAK,GAAK,MAAM,KAAK;AAAA,EAC3C;AACF;AAEO,IAAM,qCAAN,MAAyC;AAAA,EAE9C,YAAY,cAAyB,SAAkB,OAAO;AAC5D,SAAK,SAAS,aAAa,UAAU;AAAA,MACnC,OAAO;AAAA,MACP,UAAU;AAAA,IACZ,CAAC;AACD,SAAK,OAAO,WAAW,WAAW,cAAc,WAAW,WAAW,MAAM;AAC5E,SAAK,OAAO,WAAW,WAAW,YAAY,WAAW,SAAS,MAAM;AACxE,SAAK,OAAO,WAAW,WAAW,cAAc,WAAW,WAAW,MAAM;AAAA,EAC9E;AAAA,EAEO,iBAAiB,8BAAyE;AAC/F,SAAK,OAAO,GAAG,UAAU,CAAC,MAA+D;AACvF,YAAM,SAAU,EAAE,OAAe;AACjC,UAAI,CAAC,OAAQ;AACb,cAAQ,QAAQ;AAAA,QACd,KAAK;AACH,uCAA6B,SAAS,WAAW,QAAQ,EAAE;AAC3D;AAAA,QACF,KAAK;AACH,uCAA6B,SAAS,SAAS,QAAQ,EAAE;AACzD;AAAA,QACF,KAAK;AACH,uCAA6B,SAAS,WAAW,QAAQ,EAAE;AAC3D;AAAA,MACJ;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AC9CO,IAAM,YAAY;AAAA,EACvB,aAAa;AAAA,IACX,mBAAmB;AAAA,IACnB,eAAe;AAAA,EACjB;AAAA,EACA,cAAc;AAAA,EACd,UAAU,EAAE,GAAG,GAAK,GAAG,GAAK,GAAG,EAAI;AACrC;AAEA,IAAM,aAAa;AAAA,EACjB,aAAa;AAAA,IACX,mBAAmB,EAAE,KAAK,GAAG,KAAK,KAAK,MAAM,EAAE;AAAA,IAC/C,eAAe,EAAE,KAAK,KAAK,KAAK,IAAI,MAAM,EAAE;AAAA,EAC9C;AAAA,EACA,cAAc,EAAE,KAAK,GAAG,KAAK,IAAI,MAAM,IAAI;AAC7C;AAEO,IAAM,YAAY;AAAA,EACvB,sBAAsB;AAAA,EACtB,kBAAkB;AAAA,EAClB,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,kBAAkB;AAAA,EAClB,cAAc;AAAA,IACZ,uBAAuB;AAAA,IACvB,mBAAmB,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EACxC;AAAA,EACA,KAAK;AAAA,IACH,SAAS;AAAA,IACT,QAAQ;AAAA,IACR,UAAU,EAAE,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI;AAAA,EACrC;AACF;AAEA,IAAM,aAAa;AAAA,EACjB,sBAAsB,EAAE,KAAK,GAAG,KAAK,KAAK,MAAM,EAAE;AAAA,EAClD,kBAAkB,EAAE,KAAK,GAAG,KAAK,KAAK,MAAM,EAAE;AAAA,EAC9C,iBAAiB,EAAE,KAAK,GAAG,KAAK,KAAK,MAAM,KAAK;AAAA,EAChD,kBAAkB,EAAE,KAAK,GAAG,KAAK,KAAK,MAAM,KAAM;AAAA,EAClD,cAAc;AAAA,IACZ,uBAAuB,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AAAA,EACtD;AAAA,EACA,KAAK;AAAA,IACH,SAAS,EAAE,KAAK,GAAG,KAAK,IAAI,MAAM,EAAE;AAAA,IACpC,QAAQ,EAAE,KAAK,GAAG,KAAK,KAAK,MAAM,EAAE;AAAA,EACtC;AACF;AAEO,IAAM,oBAAN,MAAwB;AAAA,EAS7B,YAAY,cAAyB,SAAkB,OAAO;AAC5D,SAAK,SAAS,aAAa,UAAU,EAAE,OAAO,eAAe,UAAU,OAAO,CAAC;AAC/E,SAAK,MAAM,KAAK,OAAO,UAAU,EAAE,OAAO,OAAO,UAAU,KAAK,CAAC;AACjE,SAAK,SAAS,KAAK,OAAO,UAAU,EAAE,OAAO,UAAU,UAAU,KAAK,CAAC;AACvE,SAAK,MAAM,KAAK,OAAO,UAAU,EAAE,OAAO,OAAO,UAAU,KAAK,CAAC;AACjE,SAAK,SAAS,KAAK,OAAO,UAAU,EAAE,OAAO,UAAU,UAAU,KAAK,CAAC;AACvE,SAAK,UAAU,KAAK,OAAO,UAAU,EAAE,OAAO,WAAW,UAAU,KAAK,CAAC;AAEzE,SAAK,IAAI;AAAA,MACP,UAAU;AAAA,MACV;AAAA,MACA,WAAW,YAAY;AAAA,IACzB;AACA,SAAK,IAAI;AAAA,MACP,UAAU;AAAA,MACV;AAAA,MACA,WAAW,YAAY;AAAA,IACzB;AACA,SAAK,IAAI,WAAW,WAAW,gBAAgB,WAAW,YAAY;AACtE,SAAK,IAAI,WAAW,WAAW,YAAY;AAAA,MACzC,OAAO,EAAE,MAAM,QAAQ;AAAA,IACzB,CAAC;AAED,SAAK,YAAY,KAAK,OAAO,UAAU,EAAE,OAAO,WAAW,CAAC;AAC5D,SAAK,OAAO,WAAW,WAAW,mBAAmB,WAAW,eAAe;AAC/E,SAAK,OAAO,WAAW,WAAW,oBAAoB,WAAW,gBAAgB;AACjF,SAAK,OAAO,WAAW,WAAW,wBAAwB,WAAW,oBAAoB;AACzF,SAAK,OAAO,WAAW,WAAW,oBAAoB,WAAW,gBAAgB;AAEjF,SAAK,OAAO,WAAW,WAAW,mBAAmB,WAAW,eAAe;AAE/E,SAAK,QAAQ;AAAA,MACX,UAAU;AAAA,MACV;AAAA,MACA,WAAW,aAAa;AAAA,IAC1B;AACA,SAAK,QAAQ,WAAW,UAAU,cAAc,qBAAqB;AAAA,MACnE,OAAO,EAAE,MAAM,QAAQ;AAAA,IACzB,CAAC;AAED,SAAK,IAAI,WAAW,UAAU,KAAK,WAAW,WAAW,IAAI,OAAO;AACpE,SAAK,IAAI,WAAW,UAAU,KAAK,UAAU,WAAW,IAAI,MAAM;AAClE,SAAK,IAAI,WAAW,UAAU,KAAK,YAAY;AAAA,MAC7C,OAAO,EAAE,MAAM,QAAQ;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EAEO,iBACL,OACA,QACA,yBACA,qBACA,iBACA,QACA,KACM;AACN,SAAK,IAAI,GAAG,UAAU,CAAC,MAA+D;AACpF,YAAM,SAAU,EAAE,OAAe;AACjC,UAAI,CAAC,OAAQ;AACb,cAAQ,QAAQ;AAAA,QACd,KAAK,qBAAqB;AACxB,gBAAM,QAAQ,EAAE;AAChB,qCAAK,kBAAkB,SAAS,KAAK,KAAK;AAC1C;AAAA,QACF;AAAA,QACA,KAAK,iBAAiB;AACpB,gBAAM,QAAQ,EAAE;AAChB,qCAAK,cAAc,SAAS,KAAK,KAAK;AACtC;AAAA,QACF;AAAA,QACA,KAAK,gBAAgB;AACnB,gBAAM,QAAQ,EAAE;AAChB,qCAAK,aAAa;AAClB;AAAA,QACF;AAAA,QACA,KAAK,YAAY;AACf,gBAAM,QAAQ,EAAE;AAChB,oBAAU,WAAW;AAAA,YACnB,GAAG,MAAM;AAAA,YACT,GAAG,MAAM;AAAA,YACT,GAAG,MAAM;AAAA,UACX;AACA,qCAAK;AACL;AAAA,QACF;AAAA,QACA;AACE;AAAA,MACJ;AAAA,IACF,CAAC;AAED,SAAK,UAAU,GAAG,SAAS,MAAM;AAC/B,aAAO;AAAA,IACT,CAAC;AAED,SAAK,OAAO,GAAG,UAAU,CAAC,MAA+D;AACvF,YAAM,SAAU,EAAE,OAAe;AACjC,UAAI,CAAC,OAAQ;AACb,cAAQ,QAAQ;AAAA,QACd,KAAK;AACH,gBAAM,uBAAuB,EAAE;AAC/B;AAAA,MACJ;AAAA,IACF,CAAC;AAED,SAAK,OAAO,GAAG,UAAU,CAAC,MAA+D;AACvF,YAAM,SAAU,EAAE,OAAe;AACjC,UAAI,CAAC,OAAQ;AACb,cAAQ,QAAQ;AAAA,QACd,KAAK,wBAAwB;AAC3B,gBAAM,QAAQ,EAAE;AAChB,kCAAwB,KAAK;AAC7B;AAAA,QACF;AAAA,QACA,KAAK,oBAAoB;AACvB,gBAAM,QAAQ,EAAE;AAChB,oBAAU,mBAAmB;AAC7B,8BAAoB,KAAK;AACzB;AAAA,QACF;AAAA,QACA,KAAK;AACH,gBAAM,sBAAsB,EAAE;AAC9B;AAAA,QACF,KAAK;AACH,gBAAM,uBAAuB,EAAE;AAC/B;AAAA,MACJ;AAAA,IACF,CAAC;AAED,SAAK,QAAQ,GAAG,UAAU,CAAC,MAA+D;AACxF,YAAM,SAAU,EAAE,OAAe;AACjC,UAAI,CAAC,OAAQ;AACb,cAAQ,QAAQ;AAAA,QACd,KAAK,yBAAyB;AAC5B,oBAAU,aAAa,wBAAwB,EAAE;AACjD,0BAAgB;AAChB;AAAA,QACF;AAAA,QACA,KAAK,qBAAqB;AACxB,gBAAM,QAAQ,EAAE;AAChB,oBAAU,aAAa,oBAAoB;AAAA,YACzC,GAAG,MAAM;AAAA,YACT,GAAG,MAAM;AAAA,YACT,GAAG,MAAM;AAAA,UACX;AACA,0BAAgB;AAChB;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAED,SAAK,IAAI,GAAG,UAAU,CAAC,MAA+D;AACpF,YAAM,SAAU,EAAE,OAAe;AACjC,UAAI,CAAC,OAAQ;AACb,cAAQ,QAAQ;AAAA,QACd,KAAK,WAAW;AACd,oBAAU,IAAI,UAAU,EAAE;AAC1B,iBAAO;AACP;AAAA,QACF;AAAA,QACA,KAAK,UAAU;AACb,oBAAU,IAAI,SAAS,EAAE;AACzB,iBAAO;AACP;AAAA,QACF;AAAA,QACA,KAAK,YAAY;AACf,gBAAM,QAAQ,EAAE;AAChB,oBAAU,IAAI,WAAW;AAAA,YACvB,GAAG,MAAM;AAAA,YACT,GAAG,MAAM;AAAA,YACT,GAAG,MAAM;AAAA,UACX;AACA,iBAAO;AACP;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AC1OO,IAAM,eAAe;AAAA,EAC1B,OAAO;AAAA,EACP,OAAO;AACT;AAEA,IAAM,gBAAgB;AAAA,EACpB,OAAO;AAAA,IACL,QAAQ,EAAE,KAAK,GAAG,KAAK,KAAK,MAAM,KAAM;AAAA,EAC1C;AAAA,EACA,OAAO;AAAA,IACL,QAAQ,EAAE,KAAK,GAAG,KAAK,IAAI,MAAM,KAAK;AAAA,EACxC;AACF;AAEO,IAAM,mBAAN,MAAuB;AAAA,EAE5B,YAAY,cAAyB,SAAkB,OAAO;AAC5D,SAAK,SAAS,aAAa,UAAU,EAAE,OAAO,iBAAiB,UAAU,OAAO,CAAC;AACjF,SAAK,OAAO,WAAW,cAAc,SAAS,cAAc,MAAM,MAAM;AACxE,SAAK,OAAO,WAAW,cAAc,SAAS,cAAc,MAAM,MAAM;AAAA,EAC1E;AAAA,EAEO,iBACL,aACA,kBACM;AACN,SAAK,OAAO,GAAG,UAAU,CAAC,MAA+D;AACvF,YAAM,SAAU,EAAE,OAAe;AACjC,UAAI,CAAC,OAAQ;AACb,cAAQ,QAAQ;AAAA,QACd,KAAK;AACH,sBAAY,YAAY,EAAE;AAC1B;AAAA,QACF,KAAK;AACH,2BAAiB,SAAS,OAAO,QAAQ,EAAE;AAC3C;AAAA,QACF;AACE;AAAA,MACJ;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AC1CO,IAAM,iBAAiB;AAAA,EAC5B,WAAW;AAAA,EACX,aAAa;AAAA,EACb,UAAU;AACZ;AAEA,IAAM,kBAAkB;AAAA,EACtB,WAAW,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,EAAE;AAAA,EACrC,aAAa,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,EAAE;AAAA,EACvC,UAAU,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AACzC;AAEA,IAAM,iBAAyC;AAAA,EAC7C,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAEA,IAAM,mBAA2C;AAAA,EAC/C,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAEA,IAAM,kBAAkB;AAAA,EACtB,eAAe,eAAe,eAAe,SAAS;AAAA,EACtD,iBAAiB,iBAAiB,eAAe,WAAW;AAC9D;AAEA,IAAM,mBAAmB,CAAC,UAAwB;AAChD,kBAAgB,gBAAgB,eAAe,KAAK;AACtD;AAEA,IAAM,qBAAqB,CAAC,UAAwB;AAClD,kBAAgB,kBAAkB,iBAAiB,KAAK;AACxD,iBAAe,cAAc;AAC7B,UAAQ,IAAI,eAAe,WAAW;AACxC;AAEO,IAAM,iBAAN,MAAqB;AAAA,EAG1B,YAAY,cAAyB,SAAkB,OAAO;AAC5D,SAAK,SAAS,aAAa,UAAU;AAAA,MACnC,OAAO;AAAA,MACP,UAAU;AAAA,IACZ,CAAC;AAED,SAAK,OAAO,WAAW,gBAAgB,aAAa,gBAAgB,SAAS;AAC7E,SAAK,OAAO,WAAW,iBAAiB,iBAAiB,EAAE,UAAU,KAAK,CAAC;AAC3E,SAAK,OAAO,WAAW,gBAAgB,eAAe,gBAAgB,WAAW;AACjF,SAAK,OAAO,WAAW,iBAAiB,mBAAmB,EAAE,UAAU,KAAK,CAAC;AAC7E,SAAK,OAAO,WAAW,gBAAgB,YAAY,gBAAgB,QAAQ;AAAA,EAC7E;AAAA,EAEO,iBACL,UACA,mBACA,iBACM;AACN,SAAK,OAAO,GAAG,UAAU,CAAC,MAA+D;AACvF,YAAM,SAAU,EAAE,OAAe;AACjC,UAAI,CAAC,OAAQ;AACb,cAAQ,QAAQ;AAAA,QACd,KAAK,aAAa;AAChB,gBAAMC,SAAQ,EAAE;AAChB,mBAAS,UAAU,OAAOA;AAC1B,2BAAiBA,MAAK;AACtB;AAAA,QACF;AAAA,QACA,KAAK;AACH,gBAAM,QAAQ,EAAE;AAChB,4BAAkB,SAAS,EAAE,UAAU;AACvC,0BAAgB,UAAU,EAAE,UAAU,IAAI,OAAO;AACjD,6BAAmB,EAAE,KAAoB;AACzC;AAAA,QACF,KAAK;AACH,mBAAS,sBAAsB,EAAE;AACjC;AAAA,QACF;AACE;AAAA,MACJ;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;AC1EO,IAAM,sBAAN,MAA0B;AAAA,EAiB/B,YAAY,cAAyB,WAAoB,MAAM;AAZ/D,SAAQ,YAAuB;AAAA,MAC7B,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,UAAU;AAAA,MACV,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,WAAW;AAAA,MACX,cAAc;AAAA,MACd,WAAW;AAAA,MACX,KAAK;AAAA,IACP;AAGE,SAAK,SAAS,aAAa,UAAU,EAAE,OAAO,eAAe,SAAmB,CAAC;AACjF,SAAK,OAAO,WAAW,KAAK,WAAW,OAAO,EAAE,UAAU,KAAK,CAAC;AAChE,SAAK,OAAO,WAAW,KAAK,WAAW,aAAa,EAAE,UAAU,KAAK,CAAC;AACtE,SAAK,OAAO,WAAW,KAAK,WAAW,gBAAgB,EAAE,UAAU,KAAK,CAAC;AACzE,SAAK,OAAO,WAAW,KAAK,WAAW,aAAa,EAAE,UAAU,KAAK,CAAC;AACtE,SAAK,OAAO,WAAW,KAAK,WAAW,cAAc,EAAE,UAAU,KAAK,CAAC;AACvE,SAAK,OAAO,WAAW,KAAK,WAAW,YAAY,EAAE,UAAU,KAAK,CAAC;AACrE,SAAK,OAAO,WAAW,KAAK,WAAW,WAAW,EAAE,UAAU,KAAK,CAAC;AACpE,SAAK,OAAO,WAAW,KAAK,WAAW,cAAc,EAAE,UAAU,KAAK,CAAC;AACvE,SAAK,OAAO,WAAW,KAAK,WAAW,aAAa,EAAE,UAAU,KAAK,CAAC;AAAA,EACxE;AAAA,EAEO,OAAO,UAAyB,UAA0B,aAAgC;AAC/F,UAAM,EAAE,YAAY,SAAS,IAAI,SAAS,KAAK;AAC/C,UAAM,EAAE,WAAW,MAAM,IAAI,SAAS,KAAK;AAC3C,SAAK,UAAU,YAAY,UAAU,SAAS;AAC9C,SAAK,UAAU,aAAa,WAAW,SAAS;AAChD,SAAK,UAAU,WAAW,SAAS,SAAS;AAC5C,SAAK,UAAU,UAAU,SAAS,KAAK,SAAU,OAAO,SAAS;AACjE,SAAK,UAAU,aAAa,SAAS,OAAO,OAAO,SAAS;AAC5D,SAAK,UAAU,YAAY,MAAM,SAAS;AAC1C,SAAK,UAAU,gBACb,KAAK,MAAM,YAAY,eAAe,GAAM,IAAI,KAChD,SAAS;AACX,SAAK,UAAU,aAAa,KAAK,MAAM,YAAY,YAAY,GAAM,IAAI,KAAQ,SAAS;AAC1F,SAAK,UAAU,MAAM,YAAY,IAAI,SAAS;AAAA,EAChD;AACF;;;AC9DA,SAAS,qBAAyE;AAClF,SAAS,SAAAC,cAAa;AAGf,IAAM,eAAe;AAAA,EAC1B,SAAS;AAAA,EACT,eAAe,cAAc;AAAA,EAC7B,iBAAiB;AAAA,EACjB,sBAAsB;AAAA,EACtB,SAAS;AAAA,EACT,OAAO;AAAA,EACP,oBAAoB;AAAA,EACpB,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,MAAM;AAAA,EACN,MAAM;AAAA,EACN,iBAAiB;AAAA,EACjB,OAAO,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAC1B,wBAAwB;AAAA,EACxB,sBAAsB;AAAA,EACtB,yBAAyB;AAAA,EACzB,uBAAuB;AACzB;AAEA,IAAM,gBAAgB;AAAA,EACpB,SAAS,EAAE,KAAK,GAAG,KAAK,IAAI,MAAM,EAAE;AAAA,EACpC,OAAO,EAAE,KAAK,GAAG,KAAK,IAAI,MAAM,EAAE;AAAA,EAClC,oBAAoB,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AAAA,EACjD,QAAQ,EAAE,KAAK,GAAG,KAAK,KAAK,MAAM,KAAM;AAAA,EACxC,WAAW,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,IAAI;AAAA,EACvC,MAAM,EAAE,KAAK,GAAG,KAAK,KAAK,MAAM,KAAM;AAAA,EACtC,MAAM,EAAE,KAAK,GAAG,KAAK,KAAK,MAAM,KAAM;AAAA,EACtC,iBAAiB,EAAE,KAAK,MAAM,KAAK,GAAG,MAAM,KAAK;AAAA,EACjD,wBAAwB,EAAE,KAAK,GAAG,KAAK,KAAK,MAAM,EAAE;AAAA,EACpD,sBAAsB,EAAE,KAAK,GAAG,KAAK,KAAK,MAAM,EAAE;AAAA,EAClD,yBAAyB,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AAAA,EACtD,uBAAuB,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,KAAK;AACtD;AAEO,IAAM,eAAe;AAAA,EAC1B,SAAS;AAAA,EACT,SAAS;AAAA,EACT,UAAU;AAAA,EACV,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,OAAO,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,EAC1B,WAAW;AAAA,EACX,gBAAgB;AAAA,EAChB,eAAe;AAAA,EACf,UAAU;AACZ;AAEO,IAAM,gBAAgB;AAAA,EAC3B,QAAQ,EAAE,KAAK,KAAK,KAAK,GAAG,MAAM,IAAI;AAAA,EACtC,iBAAiB,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,IAAI;AAAA,EAC7C,WAAW,EAAE,KAAK,KAAK,KAAK,GAAG,MAAM,IAAI;AAAA,EACzC,WAAW,CAAC,GAAG,GAAG,GAAG,IAAI,IAAI,EAAE;AAAA,EAC/B,gBAAgB,CAAC,GAAG,GAAG,GAAG,IAAI,IAAI,EAAE;AAAA,EACpC,eAAe,CAAC,GAAG,GAAG,EAAE;AAAA,EACxB,UAAU,CAAC,YAAY,MAAM,SAAS,SAAS,YAAY,OAAO;AACpE;AAEA,IAAM,qBAAqB;AAAA,EACzB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEO,IAAM,aAAN,MAAiB;AAAA,EAatB,YAAY,cAAyB,SAAkB,OAAO;AAF9D,SAAQ,0BAAkC;AAGxC,SAAK,SAAS,aAAa,UAAU,EAAE,OAAO,oBAAoB,UAAU,OAAO,CAAC;AACpF,SAAK,SAAS,KAAK,OAAO,UAAU;AAAA,MAClC,OAAO;AAAA,MACP,UAAU,aAAa;AAAA,IACzB,CAAC;AACD,SAAK,SAAS,KAAK,OAAO,UAAU;AAAA,MAClC,OAAO;AAAA,MACP,UAAU,aAAa;AAAA,IACzB,CAAC;AAGD;AACE,WAAK,OAAO,WAAW,EAAE,SAAS,aAAa,QAAQ,GAAG,SAAS;AACnE,WAAK,OAAO,WAAW,EAAE,gBAAgB,MAAM,GAAG,gBAAgB;AAClE,WAAK,OAAO,WAAW,cAAc,WAAW,cAAc,OAAO;AACrE,WAAK,OAAO,WAAW,cAAc,SAAS,cAAc,KAAK;AACjE,WAAK,OAAO,WAAW,cAAc,sBAAsB,cAAc,kBAAkB;AAC3F,WAAK,OAAO,WAAW,cAAc,UAAU,cAAc,MAAM;AACnE,WAAK,OAAO,WAAW,cAAc,aAAa,cAAc,SAAS;AACzE,WAAK,OAAO,WAAW,cAAc,QAAQ,cAAc,IAAI;AAC/D,WAAK,OAAO,WAAW,cAAc,QAAQ,cAAc,IAAI;AAC/D,WAAK,OAAO,WAAW,cAAc,mBAAmB,cAAc,eAAe;AACrF,WAAK,OAAO;AAAA,QACV;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB;AACA,WAAK,OAAO;AAAA,QACV;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB;AACA,WAAK,OAAO;AAAA,QACV;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB;AACA,WAAK,OAAO;AAAA,QACV;AAAA,QACA;AAAA,QACA,cAAc;AAAA,MAChB;AACA,WAAK,OAAO,WAAW,cAAc,SAAS,EAAE,OAAO,EAAE,OAAO,OAAO,MAAM,QAAQ,EAAE,CAAC;AAAA,IAC1F;AAGA;AACE,WAAK,OAAO,WAAW,EAAE,SAAS,aAAa,QAAQ,GAAG,SAAS;AACnE,WAAK,OAAO,WAAW,EAAE,SAAS,aAAa,QAAQ,GAAG,SAAS;AACnE,WAAK,OAAO,WAAW,cAAc,YAAY,cAAc,MAAM;AACrE,WAAK,OAAO,WAAW,cAAc,mBAAmB,cAAc,eAAe;AACrF,WAAK,OAAO,WAAW,cAAc,aAAa,cAAc,SAAS;AACzE,WAAK,OAAO,WAAW,cAAc,SAAS,EAAE,OAAO,EAAE,OAAO,OAAO,MAAM,QAAQ,EAAE,CAAC;AAExF,WAAK,YAAY,KAAK,OAAO,WAAW,cAAc,aAAa;AAAA,QACjE,MAAM;AAAA,QACN,WAAW;AAAA,QACX,MAAM,CAAC,GAAG,CAAC;AAAA,QACX,OAAO,CAAC,GAAW,OAAe;AAAA,UAChC,OAAO,GAAG,cAAc,UAAU,IAAI,IAAI,CAAC,CAAC;AAAA,UAC5C,OAAO,cAAc,UAAU,IAAI,IAAI,CAAC;AAAA,QAC1C;AAAA,QACA,OAAO;AAAA,MACT,CAAC;AAED,WAAK,iBAAiB,KAAK,OAAO,WAAW,cAAc,kBAAkB;AAAA,QAC3E,MAAM;AAAA,QACN,WAAW;AAAA,QACX,MAAM,CAAC,GAAG,CAAC;AAAA,QACX,OAAO,CAAC,GAAW,OAAe;AAAA,UAChC,OAAO,GAAG,cAAc,eAAe,IAAI,IAAI,CAAC,CAAC;AAAA,UACjD,OAAO,cAAc,eAAe,IAAI,IAAI,CAAC;AAAA,QAC/C;AAAA,QACA,OAAO;AAAA,MACT,CAAC;AAED,WAAK,gBAAgB,KAAK,OAAO,WAAW,cAAc,iBAAiB;AAAA,QACzE,MAAM;AAAA,QACN,WAAW;AAAA,QACX,MAAM,CAAC,GAAG,CAAC;AAAA,QACX,OAAO,CAAC,GAAW,OAAe;AAAA,UAChC,OAAO,GAAG,cAAc,cAAc,IAAI,IAAI,CAAC,CAAC;AAAA,UAChD,OAAO,cAAc,cAAc,IAAI,IAAI,CAAC;AAAA,QAC9C;AAAA,QACA,OAAO;AAAA,MACT,CAAC;AAED,WAAK,YAAY,KAAK,OAAO,WAAW,cAAc,YAAY;AAAA,QAChE,MAAM;AAAA,QACN,WAAW;AAAA,QACX,MAAM,CAAC,GAAG,CAAC;AAAA,QACX,OAAO,CAAC,GAAW,OAAe;AAAA,UAChC,OAAO,GAAG,cAAc,SAAS,IAAI,IAAI,CAAC,CAAC;AAAA,UAC3C,OAAO,GAAG,cAAc,SAAS,IAAI,IAAI,CAAC,CAAC;AAAA,QAC7C;AAAA,QACA,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AAEA,SAAK,OAAO,SAAS,EAAE,MAAM,YAAY,CAAC;AAAA,EAC5C;AAAA,EAEO,iBACL,UACA,YACA,cACA,YACA,UACM;AACN,SAAK,OAAO,GAAG,UAAU,CAAC,MAA+D;AACvF,YAAM,SAAU,EAAE,OAAe;AACjC,UAAI,CAAC,OAAQ;AACb,cAAQ,QAAQ;AAAA,QACd,KAAK,WAAW;AACd,gBAAM,QAAQ,EAAE;AAChB,cAAI,EAAE,UAAU,MAAM;AACpB,qBAAS,QAAQ,YAAY,KAAK,uBAAuB;AACzD,qBAAS,QAAQ,YAAY,KAAK,0BAA0B,CAAC;AAAA,UAC/D,OAAO;AACL,qBAAS,WAAW,UAAU;AAC9B,qBAAS,WAAW,UAAU;AAAA,UAChC;AACA,uBAAa,UAAU;AACvB,qBAAW,UAAU;AACrB,qBAAW,UAAU;AACrB;AAAA,QACF;AAAA,QACA,KAAK,kBAAkB;AACrB,gBAAM,QAAQ,EAAE;AAChB,gBAAM,QAAQ,UAAU,OAAO,cAAc,SAAS,cAAc;AACpE,uBAAa,UAAU,gBAAgB;AACvC;AAAA,QACF;AAAA,QACA,KAAK,mBAAmB;AACtB,gBAAM,QAAQ,EAAE;AAChB,uBAAa,WAAW,QAAQ;AAChC;AAAA,QACF;AAAA,QACA,KAAK,SAAS;AACZ,gBAAM,QAAQ,EAAE;AAChB,uBAAa,QAAQ,IAAIA,OAAM,EAAE,OAAO,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AACjE;AAAA,QACF;AAAA,QACA,SAAS;AACP;AAAA,QACF;AAAA,MACF;AAEA,UAAI,mBAAmB,SAAS,MAAM,GAAG;AACvC,QAAC,aAAa,aAAqB,MAAM,IAAI,EAAE;AAC/C;AAAA,MACF;AACA,MAAC,aAAqB,MAAM,IAAI,EAAE;AAAA,IACpC,CAAC;AAED,SAAK,OAAO,GAAG,UAAU,CAAC,MAA+D;AACvF,YAAM,SAAU,EAAE,OAAe;AACjC,UAAI,CAAC,OAAQ;AACb,cAAQ,QAAQ;AAAA,QACd,KAAK;AACH,cAAI,EAAE,UAAU,MAAM;AACpB,qBAAS,QAAQ,UAAU,KAAK,0BAA0B,CAAC;AAC3D,qBAAS,OAAO,KAAK,0BAA0B,CAAC,EAAE;AAAA,cAChD,OAAO;AAAA,cACP,OAAO;AAAA,YACT;AAAA,UACF,OAAO;AACL,qBAAS,WAAW,QAAQ;AAAA,UAC9B;AACA,mBAAS,UAAU,EAAE;AACrB;AAAA,QACF,KAAK;AACH,mBAAS,cAAc,UAAU,EAAE;AACnC;AAAA,QACF,KAAK;AACH,mBAAS,cAAc,WAAW,EAAE;AACpC;AAAA,QACF,KAAK;AACH,mBAAS,cAAc,kBAAkB,EAAE;AAC3C;AAAA,QACF,KAAK;AACH,mBAAS,cAAc,YAAY,EAAE;AACrC;AAAA,QACF,KAAK;AACH,gBAAM,QAAS,EAAU;AACzB,mBAAS,cAAc,QAAQ,IAAIA,OAAM,EAAE,OAAO,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAC3E;AAAA,QACF;AACE;AAAA,MACJ;AAAA,IACF,CAAC;AAED,SAAK,UAAU,GAAG,UAAU,CAAC,MAAW;AACtC,eAAS,cAAc,YAAY,EAAE;AAAA,IACvC,CAAC;AAED,SAAK,eAAe,GAAG,UAAU,CAAC,MAAW;AAC3C,eAAS,cAAc,iBAAiB,EAAE;AAAA,IAC5C,CAAC;AAED,SAAK,cAAc,GAAG,UAAU,CAAC,MAAW;AAC1C,eAAS,cAAc,gBAAgB,EAAE;AAAA,IAC3C,CAAC;AAED,SAAK,UAAU,GAAG,UAAU,CAAC,MAAW;AACtC,eAAS,eAAe,EAAE,KAAK;AAAA,IACjC,CAAC;AAAA,EACH;AACF;;;ACnSO,IAAM,oBAAoB;AAAA,EAC/B,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,YAAY;AAAA,EACZ,cAAc;AAAA,EACd,kBAAkB;AAAA,EAClB,gBAAgB;AAClB;AAEA,IAAM,qBAAqB;AAAA,EACzB,MAAM,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,EAAE;AAAA,EAChC,YAAY,EAAE,KAAK,IAAI,KAAK,KAAK,MAAM,GAAG;AAAA,EAC1C,YAAY,EAAE,KAAK,GAAG,KAAK,IAAI,MAAM,KAAK;AAAA,EAC1C,YAAY,EAAE,KAAK,GAAG,KAAK,IAAI,MAAM,KAAK;AAAA,EAC1C,cAAc,EAAE,KAAK,GAAG,KAAK,IAAI,MAAM,KAAM;AAAA,EAC7C,kBAAkB,EAAE,KAAK,MAAO,KAAK,GAAG,MAAM,KAAM;AAAA,EACpD,gBAAgB,EAAE,KAAK,KAAK,KAAK,GAAK,MAAM,IAAI;AAClD;AAEA,IAAM,yBAAiD;AAAA,EACrD,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAEA,IAAM,yBAAyB;AAAA,EAC7B,uBAAuB,uBAAuB,kBAAkB,IAAI;AACtE;AAEA,IAAM,2BAA2B,CAAC,UAAwB;AACxD,yBAAuB,wBAAwB,uBAAuB,KAAK;AAC7E;AAEO,IAAM,oBAAN,MAAwB;AAAA,EAK7B,YAAY,cAAyB,SAAkB,OAAO;AAC5D,SAAK,SAAS,aAAa,UAAU;AAAA,MACnC,OAAO;AAAA,MACP,UAAU;AAAA,IACZ,CAAC;AACD,SAAK,OAAO,WAAW,mBAAmB,QAAQ,mBAAmB,IAAI;AACzE,SAAK,OAAO,WAAW,wBAAwB,yBAAyB,EAAE,UAAU,KAAK,CAAC;AAC1F,SAAK,OAAO,WAAW,mBAAmB,cAAc,mBAAmB,UAAU;AACrF,SAAK,OAAO,WAAW,mBAAmB,cAAc,mBAAmB,UAAU;AACrF,SAAK,eAAe,KAAK,OAAO;AAAA,MAC9B;AAAA,MACA;AAAA,MACA,mBAAmB;AAAA,IACrB;AACA,SAAK,aAAa,SAAS;AAC3B,SAAK,eAAe,KAAK,OAAO;AAAA,MAC9B;AAAA,MACA;AAAA,MACA,mBAAmB;AAAA,IACrB;AACA,SAAK,aAAa,SAAS;AAC3B,SAAK,OAAO,WAAW,mBAAmB,kBAAkB,mBAAmB,cAAc;AAAA,EAC/F;AAAA,EAEO,iBAAiB,mBAA4C;AAClE,SAAK,OAAO,GAAG,UAAU,CAAC,MAA+D;AACvF,YAAM,SAAU,EAAE,OAAe;AACjC,UAAI,CAAC,OAAQ;AACb,UAAI,WAAW,QAAQ;AACrB,iCAAyB,EAAE,KAAe;AAAA,MAC5C;AACA,MAAC,kBAA0B,MAAM,IAAI,EAAE;AACvC;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;ACpFO,IAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ARiCvB,IAAM,YAAN,MAAgB;AAAA,EAsBrB,YACU,eACA,UACA,OACA,UACR;AAJQ;AACA;AACA;AACA;AATV,SAAQ,+BAAwC;AAChD,SAAO,aAAsB;AAU3B,SAAK,mBAAmB,SAAS,cAAc,KAAK;AACpD,SAAK,iBAAiB,MAAM,WAAW;AACvC,SAAK,iBAAiB,MAAM,QAAQ;AACpC,SAAK,iBAAiB,MAAM,SAAS;AACrC,SAAK,iBAAiB,MAAM,MAAM;AAClC,SAAK,iBAAiB,MAAM,QAAQ;AACpC,SAAK,iBAAiB,MAAM,SAAS;AACrC,SAAK,iBAAiB,MAAM,WAAW;AACvC,SAAK,iBAAiB,MAAM,kBAAkB;AAC9C,SAAK,iBAAiB,MAAM,cAAc;AAC1C,SAAK,iBAAiB,MAAM,YAAY;AACxC,SAAK,iBAAiB,MAAM,aAAa;AACzC,kBAAc,YAAY,KAAK,gBAAgB;AAE/C,SAAK,MAAM,IAAI,KAAK,EAAE,WAAW,KAAK,iBAAkB,CAAC;AACzD,SAAK,IAAI,eAAe,gBAAgB;AAExC,QAAI,KAAK,8BAA8B;AACrC,YAAM,yBAAyB,aAAa,QAAQ,YAAY;AAChE,UAAI,2BAA2B,MAAM;AACnC,YAAI,2BAA2B,QAAQ;AACrC,eAAK,aAAa;AAAA,QACpB,WAAW,2BAA2B,SAAS;AAC7C,eAAK,aAAa;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AAEA,UAAM,eAAe,SAAS,cAAc,OAAO;AACnD,iBAAa,OAAO;AACpB,iBAAa,YAAY,SAAS,eAAe,cAAc,CAAC;AAChE,aAAS,KAAK,YAAY,YAAY;AAEtC,SAAK,oBAAoB,IAAI,oBAAoB,KAAK,KAAK,IAAI;AAC/D,SAAK,iBAAiB,IAAI,eAAe,KAAK,KAAK,KAAK;AACxD,SAAK,oBAAoB,IAAI,kBAAkB,KAAK,KAAK,KAAK;AAC9D,SAAK,aAAa,IAAI,WAAW,KAAK,KAAK,KAAK;AAChD,SAAK,YAAY,IAAI,mCAAmC,KAAK,KAAK,KAAK;AACvE,SAAK,mBAAmB,IAAI,iBAAiB,KAAK,KAAK,KAAK;AAC5D,SAAK,YAAY,IAAI,gBAAgB,KAAK,KAAK,KAAK;AACpD,SAAK,cAAc,IAAI,kBAAkB,KAAK,KAAK,KAAK;AACxD,SAAK,SAAS,IAAI,aAAa,KAAK,KAAK,KAAK;AAC9C,SAAK,oBAAoB,IAAI,wBAAwB,KAAK,KAAK,KAAK;AAEpE,SAAK,kBAAkB,OAAO,SAAS,eAAe,gBAAgB,IAAI,QAAQ;AAElF,SAAK,SAAS,KAAK,IAAI,UAAU,EAAE,OAAO,mBAAmB,UAAU,MAAM,CAAC;AAE9E,SAAK,yBAAyB,IAAI,uBAAuB;AAEzD,UAAM,MAAM,KAAK;AACjB,UAAM,cAA2B,IAAI;AACrC,gBAAY,MAAM,QAAQ,KAAK,aAAa,QAAQ;AACpD,SAAK,uBAAuB,IAAI,KAAK,IAAI,SAAS,cAAc,MAAM,mBAAmB,IAAI,CAAC;AAC9F,SAAK,uBAAuB,IAAI,KAAK,IAAI,SAAS,aAAa,MAAM,mBAAmB,IAAI,CAAC;AAC7F,SAAK,uBAAuB,IAAI,KAAK,IAAI,SAAS,aAAa,MAAM,mBAAmB,IAAI,CAAC;AAC7F,SAAK,uBAAuB;AAAA,MAAI,KAAK,IAAI;AAAA,MAAS;AAAA,MAAc,MAC9D,mBAAmB,KAAK;AAAA,IAC1B;AACA,SAAK,uBAAuB,IAAI,KAAK,IAAI,SAAS,WAAW,MAAM,mBAAmB,KAAK,CAAC;AAC5F,SAAK,uBAAuB,IAAI,QAAQ,WAAW,CAAC,MAAM;AACxD,WAAK,WAAW,CAAC;AAAA,IACnB,CAAC;AAAA,EACH;AAAA,EAEQ,WAAW,GAAwB;AACzC,QAAI,EAAE,QAAQ,KAAK;AACjB,WAAK,UAAU;AAAA,IACjB;AAAA,EACF;AAAA,EAEO,gBACL,UACA,YACA,cACA,YACA,UACA,mBACA,iBACA,8BACA,aACA,kBACA,aACA,KACA,QACA,yBACA,qBACA,iBACA,QACM;AAEN,SAAK,eAAe;AAAA,MAClB,KAAK;AAAA,MACL,KAAK,kBAAkB;AAAA,MACvB;AAAA,IACF;AAEA,SAAK,kBAAkB,iBAAiB,iBAAiB;AACzD,SAAK,WAAW,iBAAiB,UAAU,YAAY,cAAc,YAAY,QAAQ;AACzF,SAAK,UAAU,iBAAiB,4BAA4B;AAC5D,SAAK,iBAAiB,iBAAiB,aAAa,gBAAgB;AACpE,SAAK,YAAY;AAAA,MACf,KAAK;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,SAAK,YAAY,OAAO,SAAS,gBAAgB,SAAS,QAAQ;AAElE,UAAM,eAAe,KAAK,OAAO,UAAU,EAAE,OAAO,SAAS,CAAC;AAC9D,iBAAa,GAAG,SAAS,MAAM;AAC7B,WAAK,uBAAuB,KAAK,IAAI,YAAY,CAAC;AAAA,IACpD,CAAC;AACD,UAAM,eAAe,KAAK,OAAO,UAAU,EAAE,OAAO,SAAS,CAAC;AAC9D,iBAAa,GAAG,SAAS,MAAM;AAC7B,WAAK,uBAAuB,CAAC,aAAa;AACxC,aAAK,IAAI,YAAY,QAAQ;AAAA,MAC/B,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEO,UAAU;AACf,SAAK,uBAAuB,MAAM;AAClC,SAAK,IAAI,QAAQ;AACjB,SAAK,iBAAiB,OAAO;AAAA,EAC/B;AAAA,EAEO,aAAa,eAA8B;AAChD,SAAK,OAAO,iBAAiB,aAAa;AAAA,EAC5C;AAAA,EAEO,yBAAyB,iBAAkC;AAChE,SAAK,kBAAkB,iBAAiB,eAAe;AAAA,EACzD;AAAA,EAEO,YAAY,aAAgC;AACjD,SAAK,kBAAkB,OAAO,KAAK,UAAU,KAAK,UAAU,WAAW;AAAA,EACzE;AAAA,EAEO,iBAAiB,eAA8B;AACpD,SAAK,OAAO,OAAO,aAAa;AAAA,EAClC;AAAA,EAEO,oBAAoB,iBAAkC;AAC3D,SAAK,kBAAkB,OAAO,eAAe;AAAA,EAC/C;AAAA,EAEQ,wBAAgC;AACtC,UAAM,OAAO,oBAAI,KAAK;AACtB,UAAM,OAAO,KAAK,YAAY;AAC9B,UAAM,QAAQ,OAAO,KAAK,SAAS,IAAI,CAAC,EAAE,SAAS,GAAG,GAAG;AACzD,UAAM,MAAM,OAAO,KAAK,QAAQ,CAAC,EAAE,SAAS,GAAG,GAAG;AAClD,UAAM,QAAQ,OAAO,KAAK,SAAS,CAAC,EAAE,SAAS,GAAG,GAAG;AACrD,UAAM,UAAU,OAAO,KAAK,WAAW,CAAC,EAAE,SAAS,GAAG,GAAG;AACzD,UAAM,UAAU,OAAO,KAAK,WAAW,CAAC,EAAE,SAAS,GAAG,GAAG;AACzD,WAAO,GAAG,IAAI,IAAI,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,OAAO,IAAI,OAAO;AAAA,EAC/D;AAAA,EAEQ,uBAAuB,UAAqB;AAClD,UAAM,aAAa,KAAK,UAAU,UAAU,MAAM,CAAC;AACnD,UAAM,OAAO,IAAI,KAAK,CAAC,UAAU,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAChE,UAAM,MAAM,IAAI,gBAAgB,IAAI;AACpC,UAAM,IAAI,SAAS,cAAc,GAAG;AACpC,MAAE,WAAW,YAAY,KAAK,sBAAsB,CAAC;AACrD,MAAE,OAAO;AACT,MAAE,MAAM;AACR,QAAI,gBAAgB,GAAG;AAAA,EACzB;AAAA,EAEQ,uBAAuB,UAAyC;AACtE,UAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,UAAM,OAAO;AACb,UAAM,SAAS;AACf,UAAM,iBAAiB,UAAU,CAAC,UAAU;AA7OhD;AA8OM,YAAM,QAAQ,WAAM,OAA4B,UAAlC,mBAA0C;AACxD,UAAI,MAAM;AACR,cAAM,SAAS,IAAI,WAAW;AAC9B,eAAO,SAAS,CAAC,cAAc;AAjPvC,cAAAC;AAkPU,cAAI;AACF,kBAAM,WAAW,KAAK,OAAMA,MAAA,UAAU,WAAV,gBAAAA,IAAkB,MAAgB;AAC9D,qBAAS,QAAQ;AAAA,UACnB,SAAS,KAAK;AACZ,oBAAQ,MAAM,uBAAuB,GAAG;AAAA,UAC1C;AAAA,QACF;AACA,eAAO,WAAW,IAAI;AAAA,MACxB;AAAA,IACF,CAAC;AACD,UAAM,MAAM;AAAA,EACd;AAAA,EAEQ,YAAkB;AACxB,SAAK,aAAa,CAAC,KAAK;AACxB,UAAM,MAAM,KAAK;AACjB,UAAM,cAA2B,IAAI;AACrC,gBAAY,MAAM,QAAQ,KAAK,aAAa,QAAQ;AACpD,QAAI,KAAK,8BAA8B;AACrC,mBAAa,QAAQ,cAAc,KAAK,eAAe,OAAO,SAAS,OAAO;AAAA,IAChF;AAAA,EACF;AACF;;;ASxQA,SAAS,oBAAoB;AAC7B;AAAA,EACE,iBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA,kBAAAC;AAAA,EACA,cAAAC;AAAA,EACA;AAAA,EACA,cAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAAC;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA,SAAAC;AAAA,EACA;AAAA,EACA,SAAAC;AAAA,EACA,OAAAC;AAAA,EACA,iBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA,SAAAC;AAAA,EAEA;AAAA,EAGA,WAAAC;AAAA,EACA,iBAAAC;AAAA,OACK;AACP,SAAS,kBAAkB;;;ACtC3B,SAAS,cAAc,SAAAC,QAAO,kBAAkB,SAAAC,QAAO,oBAAoB,WAAAC,iBAAe;AAInF,IAAM,MAAN,cAAkBC,OAAM;AAAA,EAgB7B,cAAc;AACZ,UAAM;AAhBR,SAAiB,QAAiB;AAClC,SAAiB,YAAqB,IAAIC;AAAA,MACxC,UAAU,YAAY,qBAAqB,KAAK,KAAK;AAAA,MACrD,UAAU,YAAY,iBAAiB,KAAK,KAAK;AAAA,MACjD;AAAA,IACF;AACA,SAAiB,mBAA2B;AAC5C,SAAiB,mBAA2B;AAC5C,SAAiB,YAAiC;AAKlD,SAAO,SAAyB;AAI9B,SAAK,eAAe,IAAI;AAAA,MACtB,CAAC,KAAK;AAAA,MACN,KAAK;AAAA,MACL,KAAK;AAAA,MACL,CAAC,KAAK;AAAA,MACN;AAAA,MACA;AAAA,IACF;AACA,QAAI,KAAK,UAAU,MAAM;AACvB,WAAK,YAAY,IAAI,aAAa,KAAK,YAAY;AAAA,IACrD;AACA,SAAK,mBAAmB,IAAI,iBAAiB,QAAQ;AACrD,SAAK,iBAAiB,YAAY,UAAU;AAC5C,SAAK,iBAAiB,OAAO,aAAa;AAC1C,SAAK,iBAAiB,OAAO,SAAS;AACtC,SAAK,iBAAiB,OAAO,SAAS,KAAK;AAC3C,SAAK,iBAAiB,OAAO,QAAQ,IAAI,KAAK,kBAAkB,KAAK,gBAAgB;AACrF,SAAK,iBAAiB,aAAa;AACnC,SAAK,SAAS;AAEd,SAAK,wBAAwB,IAAIA,UAAQ,GAAG,GAAG,CAAC,CAAC;AAEjD,SAAK,IAAI,KAAK,gBAAgB;AAC9B,QAAI,KAAK,UAAU,QAAQ,KAAK,qBAAqB,cAAc;AACjE,WAAK,IAAI,KAAK,SAAS;AAAA,IACzB;AAAA,EACF;AAAA,EAEO,wBAAwB,UAA+B;AAC5D,QAAI,CAAC,SAAU;AACf,SAAK,SAAS;AACd,SAAK,eAAe,KAAK,UAAU,GAAG,KAAK,UAAU,CAAC;AAAA,EACxD;AAAA,EAEO,kBAAkB,OAAe;AACtC,QAAI,KAAK,UAAW,MAAK,UAAU,IAAI;AACvC,QAAI,KAAK,OAAQ,MAAK,wBAAwB,KAAK,MAAM;AAAA,EAC3D;AAAA,EAEO,cAAc,OAAe;AAClC,QAAI,KAAK,UAAW,MAAK,UAAU,IAAI;AACvC,QAAI,KAAK,OAAQ,MAAK,wBAAwB,KAAK,MAAM;AAAA,EAC3D;AAAA,EAEO,aAAa,WAAmB;AACrC,SAAK,iBAAiB,YAAY;AAAA,EACpC;AAAA,EAEO,WAAW;AAChB,SAAK,iBAAiB,QAAQ,IAAIC,OAAM,EAAE;AAAA,MACxC,UAAU,SAAS;AAAA,MACnB,UAAU,SAAS;AAAA,MACnB,UAAU,SAAS;AAAA,IACrB;AAAA,EACF;AAAA,EAEQ,eAAe,gBAAwB,YAAoB;AACjE,QAAI,CAAC,KAAK,OAAQ;AAClB,UAAM,WAAW,KAAK,UAAU;AAChC,UAAM,oBAAoB,IAAID;AAAA,MAC5B,WAAW,KAAK,IAAI,UAAU,IAAI,KAAK,IAAI,cAAc;AAAA,MACzD,WAAW,KAAK,IAAI,UAAU;AAAA,MAC9B,WAAW,KAAK,IAAI,UAAU,IAAI,KAAK,IAAI,cAAc;AAAA,IAC3D;AACA,UAAM,iBAAiB,KAAK,OAAO,MAAM,EAAE,IAAI,iBAAiB;AAChE,SAAK,iBAAiB,SAAS,IAAI,eAAe,GAAG,eAAe,GAAG,eAAe,CAAC;AACvF,SAAK,iBAAiB,OAAO,SAAS,KAAK,KAAK,OAAO,MAAM,CAAC;AAC9D,SAAK,iBAAiB,OAAO,kBAAkB;AAAA,EACjD;AACF;;;AC3FA,SAAS,gBAAgB,eAAe;;;ACAjC,IAAM;AAAA;AAAA,EAA0B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ADIhC,IAAM,+BAA+B,IAAI,eAAe;AAAA,EAC7D,UAAU;AAAA,IACR,UAAU,IAAI,QAAQ,IAAI;AAAA,IAC1B,YAAY,IAAI,QAAQ,CAAG;AAAA,IAC3B,UAAU,IAAI,QAAQ,CAAG;AAAA,IACzB,YAAY,IAAI,QAAQ,CAAG;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA;AAAA,IAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAwD3B,WAAW;AACb,CAAC;;;AErED,SAAS,kBAAAE,iBAAgB,WAAAC,UAAS,eAAe;AAI1C,IAAM,mBAAmB,IAAIC,gBAAe;AAAA,EACjD,UAAU;AAAA,IACR,UAAU,IAAIC,SAAQ,IAAI;AAAA,IAC1B,YAAY,IAAIA,SAAQ,IAAI,QAAQ,CAAC;AAAA,IACrC,MAAM,IAAIA,SAAQ,CAAG;AAAA,IACrB,QAAQ,IAAIA,SAAQ,CAAG;AAAA,IACvB,OAAO,IAAIA,SAAQ,CAAG;AAAA,EACxB;AAAA,EACA;AAAA,EACA;AAAA;AAAA,IAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuC3B,WAAW;AACb,CAAC;;;AClDD,SAAS,YAAY;AACrB;AAAA,EACE,SAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,gBAAAC;AAAA,EACA;AAAA,EACA;AAAA,EACA,sBAAAC;AAAA,EAEA,cAAAC;AAAA,EACA;AAAA,EACA;AAAA,EAEA,kBAAAC;AAAA,EAEA,WAAAC;AAAA,EACA,WAAAC;AAAA,EACA,WAAAC;AAAA,EACA;AAAA,OAEK;;;ACxBA,IAAM,YACX;;;ACDF,SAAS,WAAAC,UAAS,WAAAC,UAAS,WAAAC,gBAAe;AAE1C,IAAM,kBAAkB;AAAA,EACtB,UAAU;AAAA,IACR,YAAY,IAAID,SAAQ,IAAI;AAAA,IAC5B,YAAY,IAAIA,SAAQ,IAAIC,SAAQ,CAAC;AAAA,IACrC,MAAM,IAAID,SAAQ,GAAG;AAAA,IACrB,KAAK,IAAIA,SAAQ,GAAM;AAAA,IACvB,eAAe,IAAIA,SAAQ,IAAID,SAAQ,CAAC;AAAA,IACxC,qBAAqB,IAAIC,SAAQ,IAAID,SAAQ,CAAC;AAAA,IAC9C,UAAU,IAAIC,SAAQ,KAAK;AAAA,EAC7B;AAAA,EAEA,YAAY;AAAA,EAEZ,WAAW;AAAA,EAEX;AAAA;AAAA,IAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOzB;AAAA;AAAA,IAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA4G7B;;;ACpIA,SAAS,WAAAE,UAAS,WAAAC,UAAS,WAAAC,UAAS,WAAAC,iBAAe;AAEnD,IAAM,mBAAmB;AAAA,EACvB,UAAU;AAAA,IACR,cAAc,IAAIF,SAAQ,IAAI;AAAA,IAC9B,YAAY,IAAIA,SAAQ,IAAI;AAAA,IAC5B,UAAU,IAAIA,SAAQ,IAAI;AAAA,IAC1B,SAAS,IAAIA,SAAQ,IAAID,SAAQ,CAAC;AAAA,IAClC,SAAS,IAAIC,SAAQ,IAAID,SAAQ,CAAC;AAAA,IAClC,qBAAqB,IAAIC,SAAQ,IAAID,SAAQ,CAAC;AAAA,IAC9C,eAAe,IAAIC,SAAQ,IAAID,SAAQ,CAAC;AAAA,IACxC,WAAW,IAAIC,SAAQ,IAAIE,UAAQ,CAAC;AAAA,IACpC,YAAY,IAAIF,SAAQ,IAAIC,SAAQ,CAAC;AAAA,IACrC,OAAO,IAAID,SAAQ,IAAIE,UAAQ,CAAC;AAAA,IAChC,WAAW,IAAIF,SAAQ,IAAI;AAAA,IAC3B,kBAAkB,IAAIA,SAAQ,IAAI;AAAA,IAClC,MAAM,IAAIA,SAAQ,CAAG;AAAA,IACrB,WAAW,IAAIA,SAAQ,EAAI;AAAA,IAC3B,YAAY,IAAIA,SAAQ,CAAG;AAAA,IAC3B,iBAAiB,IAAIA,SAAQ,KAAK;AAAA,IAClC,UAAU,IAAIA,SAAQ,KAAK;AAAA,IAC3B,OAAO,IAAIA,SAAQ,KAAK;AAAA,IACxB,MAAM,IAAIA,SAAQ,GAAG;AAAA,IACrB,KAAK,IAAIA,SAAQ,GAAM;AAAA,IACvB,mBAAmB,IAAIA,SAAQ,KAAK;AAAA,IACpC,QAAQ,IAAIA,SAAQ,CAAG;AAAA,IACvB,iBAAiB,IAAIA,SAAQ,CAAG;AAAA,IAChC,KAAK,IAAIA,SAAQ,KAAK;AAAA,IACtB,QAAQ,IAAIA,SAAQ,KAAK;AAAA,IACzB,YAAY,IAAIA,SAAQ,CAAG;AAAA,IAC3B,SAAS,IAAIA,SAAQ,QAAQ;AAAA,IAC7B,QAAQ,IAAIA,SAAQ,QAAQ;AAAA,IAC5B,eAAe,IAAIA,SAAQ,IAAI;AAAA,EACjC;AAAA,EAEA,YAAY;AAAA,EAEZ,WAAW;AAAA,EAEX;AAAA;AAAA,IAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOzB;AAAA;AAAA,IAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAyN7B;;;ACvQA,SAAS,WAAAG,UAAS,WAAAC,UAAS,WAAAC,UAAS,WAAAC,iBAAe;AAEnD,IAAM,eAAe;AAAA,EACnB,UAAU;AAAA,IACR,cAAc,IAAIF,SAAQ,IAAI;AAAA,IAC9B,YAAY,IAAIA,SAAQ,IAAI;AAAA,IAC5B,aAAa,IAAIA,SAAQ,IAAI;AAAA,IAC7B,SAAS,IAAIA,SAAQ,IAAID,SAAQ,CAAC;AAAA,IAClC,SAAS,IAAIC,SAAQ,IAAID,SAAQ,CAAC;AAAA,IAClC,aAAa,IAAIC,SAAQ,IAAID,SAAQ,CAAC;AAAA,IACtC,qBAAqB,IAAIC,SAAQ,IAAID,SAAQ,CAAC;AAAA,IAC9C,eAAe,IAAIC,SAAQ,IAAID,SAAQ,CAAC;AAAA,IACxC,WAAW,IAAIC,SAAQ,IAAIE,UAAQ,CAAC;AAAA,IACpC,YAAY,IAAIF,SAAQ,IAAIC,SAAQ,CAAC;AAAA,IACrC,MAAM,IAAID,SAAQ,CAAG;AAAA,IACrB,SAAS,IAAIA,SAAQ,CAAC,CAAC;AAAA,IACvB,UAAU,IAAIA,SAAQ,CAAC,CAAC;AAAA,IACxB,WAAW,IAAIA,SAAQ,IAAI;AAAA,IAC3B,iBAAiB,IAAIA,SAAQ,CAAG;AAAA,IAChC,QAAQ,IAAIA,SAAQ,CAAG;AAAA,IACvB,MAAM,IAAIA,SAAQ,GAAG;AAAA,IACrB,KAAK,IAAIA,SAAQ,GAAM;AAAA,IACvB,UAAU,IAAIA,SAAQ,KAAK;AAAA,IAC3B,OAAO,IAAIA,SAAQ,KAAK;AAAA,IACxB,mBAAmB,IAAIA,SAAQ,KAAK;AAAA,EACtC;AAAA,EAEA,YAAY;AAAA,EAEZ,WAAW;AAAA,EAEX;AAAA;AAAA,IAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQzB;AAAA;AAAA,IAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiL7B;;;ACxNA;AAAA,EACE;AAAA,EACA;AAAA,EACA,QAAAG;AAAA,EACA,sBAAAC;AAAA,EAEA;AAAA,OAEK;AAEA,IAAM,qBAAN,MAAyB;AAAA,EAK9B,YAAY,UAA0B;AAJtC,SAAQ,SAA6B,IAAIA,oBAAmB;AAC5D,SAAQ,WAA2B,IAAI,eAAe;AAIpD,SAAK,SAAS;AAAA,MACZ;AAAA,MACA,IAAI,gBAAgB,IAAI,aAAa,CAAC,IAAI,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC;AAAA,IACjE;AACA,SAAK,SAAS,aAAa,MAAM,IAAI,gBAAgB,IAAI,aAAa,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;AAE7F,SAAK,SAAS,iBAAiB,IAAI,OAAO;AAC1C,SAAK,SAAS,wBAAwB,WAAY;AAAA,IAAC;AAEnD,SAAK,OAAO,IAAID,MAAK,KAAK,UAAU,QAAQ;AAC5C,SAAK,KAAK,gBAAgB;AAAA,EAC5B;AAAA,EAEA,IAAI,WAA2B;AAC7B,WAAO,KAAK,KAAK;AAAA,EACnB;AAAA,EAEA,IAAI,SAAS,OAAuB;AAClC,SAAK,KAAK,WAAW;AAAA,EACvB;AAAA,EAEO,OAAO,UAA+B;AAC3C,aAAS,OAAO,KAAK,MAAM,KAAK,MAAM;AAAA,EACxC;AAAA,EAEO,UAAgB;AACrB,SAAK,KAAK,SAAS,QAAQ;AAC3B,SAAK,KAAK,SAAS,QAAQ;AAAA,EAC7B;AACF;;;AC7CA,SAAS,WAAAE,UAAS,WAAAC,UAAS,WAAAC,UAAS,WAAAC,iBAAe;AAE5C,IAAM,eAAe;AAAA,EAC1B,UAAU;AAAA,IACR,cAAc,IAAIF,SAAQ,IAAI;AAAA,IAC9B,YAAY,IAAIA,SAAQ,IAAI;AAAA,IAC5B,UAAU,IAAIA,SAAQ,IAAI;AAAA,IAC1B,SAAS,IAAIA,SAAQ,IAAID,SAAQ,CAAC;AAAA,IAClC,SAAS,IAAIC,SAAQ,IAAID,SAAQ,CAAC;AAAA,IAClC,qBAAqB,IAAIC,SAAQ,IAAID,SAAQ,CAAC;AAAA,IAC9C,eAAe,IAAIC,SAAQ,IAAID,SAAQ,CAAC;AAAA,IACxC,WAAW,IAAIC,SAAQ,IAAIE,UAAQ,CAAC;AAAA,IACpC,YAAY,IAAIF,SAAQ,IAAIC,SAAQ,CAAC;AAAA,IACrC,MAAM,IAAID,SAAQ,CAAG;AAAA,IACrB,GAAG,IAAIA,SAAQ,CAAG;AAAA,IAClB,WAAW,IAAIA,SAAQ,IAAI;AAAA,IAC3B,QAAQ,IAAIA,SAAQ,EAAI;AAAA,IACxB,aAAa,IAAIA,SAAQ,CAAG;AAAA,IAC5B,OAAO,IAAIA,SAAQ,CAAG;AAAA,IACtB,aAAa,IAAIA,SAAQ,CAAC,CAAC;AAAA,IAC3B,iBAAiB,IAAIA,SAAQ,CAAG;AAAA,IAChC,MAAM,IAAIA,SAAQ,GAAG;AAAA,IACrB,KAAK,IAAIA,SAAQ,GAAM;AAAA,IACvB,UAAU,IAAIA,SAAQ,KAAK;AAAA,IAC3B,mBAAmB,IAAIA,SAAQ,KAAK;AAAA,EACtC;AAAA,EAEA,YAAY;AAAA,EAEZ,WAAW;AAAA,EAEX;AAAA;AAAA,IAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOzB;AAAA;AAAA,IAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA8I7B;;;ANnJA,IAAM,gBAA4B,WAAW,KAAK,KAAK,SAAS,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAwBzF,SAAS,gBACP,YACA,IACA,MACM;AACN,QAAM,YAAY,GAAG,kBAAkB,YAAY,GAAG,sBAAsB;AAC5E,MAAI,WAAW;AACb,UAAM,kBAAkB,GAAG,kBAAkB,YAAY,GAAG,YAAY;AACxE,UAAM,kBAAkB,kBAAkB;AAC1C,SAAK,WAAW;AAAA,EAClB,OAAO;AACL,eAAW,MAAM,gBAAgB,YAAY,IAAI,IAAI,GAAG,CAAC;AAAA,EAC3D;AACF;AAEA,IAAM,aAAN,cAAyB,KAAK;AAAA,EAyD5B,YACE,OACA,QACA,QAAQ,KACR,SAAS,KACT;AACA,UAAM;AA1DR,SAAO,WAAmB;AAO1B,SAAQ,eAAwB;AAChC,SAAQ,UAAqB,CAAC;AAC9B,SAAQ,WAAqB,CAAC;AAC9B,SAAQ,iBAA4B,CAAC;AAErC,SAAQ,mBAAmC,IAAIG,gBAAe;AAAA,MAC5D,UAAU,EAAE,UAAU,IAAIC,SAAQ,IAAI,EAAE;AAAA,MAExC,YAAY;AAAA,MAEZ;AAAA;AAAA,QAAyB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQzB;AAAA;AAAA,QAA2B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAO7B,CAAC;AAED,SAAQ,WAA+B,IAAI,mBAAmB,KAAK,gBAAgB;AAyBjF,SAAK,QAAQ;AACb,SAAK,SAAS;AAEd,SAAK,SAAS;AACd,SAAK,QAAQ;AAEb,SAAK,gBAAgB,IAAI;AAAA,MACvB;AAAA,QACE,WAAW;AAAA,QACX,UAAU;AAAA,QACV,gBAAgB;AAAA,QAChB,eAAe;AAAA,QACf,iBAAiB;AAAA,QACjB,WAAW;AAAA,QACX,mBAAmB;AAAA,QACnB,YAAY;AAAA,QACZ,OAAO,IAAIC,OAAM,GAAG,GAAG,CAAC;AAAA,QACxB,iBAAiB;AAAA,QACjB,wBAAwB;AAAA,QACxB,mBAAmB;AAAA,QACnB,SAAS;AAAA,QACT,sBAAsB;AAAA,QACtB,eAAe;AAAA,MACjB;AAAA,MACA;AAAA,QACE,KAAK,CAAC,QAAa,UAAkB,UAAe;AAClD,gBAAM,UAAU,OAAO,QAAQ;AAC/B,iBAAO,QAAQ,IAAI;AACnB,cAAI,aAAa,eAAe,YAAY,OAAO;AACjD,iBAAK,gBAAgB,KAAK,cAAc,sBAAsB;AAAA,UAChE;AACA,cAAI,aAAa,oBAAoB,YAAY,OAAO;AACtD,iBAAK,qBAAqB,KAAK,cAAc,sBAAsB;AAAA,UACrE;AACA,cAAI,aAAa,aAAa,YAAY,OAAO;AAC/C,iBAAK,gBAAgB,KAAK,cAAc,sBAAsB;AAC9D,iBAAK,wBAAwB;AAC7B,iBAAK,0BAA0B,KAAK,cAAc,sBAAsB;AACxE,iBAAK,QAAQ,KAAK,OAAO,KAAK,MAAM;AAAA,UACtC;AACA,cAAI,aAAa,0BAA0B,YAAY,OAAO;AAC5D,iBAAK,0BAA0B,KAAK,cAAc,sBAAsB;AAAA,UAC1E;AACA,cAAI,aAAa,mBAAmB;AAClC,iBAAK,eAAe;AAAA,UACtB;AACA,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAEA,SAAK,0BAA0B,KAAK,cAAc,sBAAsB;AACxE,SAAK,+BAA+B;AACpC,SAAK,wBAAwB;AAE7B,SAAK,sBAAsB,IAAI,kBAAkB,KAAK,OAAO,KAAK,QAAQ;AAAA,MACxE,WAAWC;AAAA,MACX,WAAWA;AAAA,MACX,aAAa;AAAA,IACf,CAAC;AAED,SAAK,qBAAqB,IAAI,kBAAkB,KAAK,OAAO,KAAK,QAAQ;AAAA,MACvE,WAAWA;AAAA,MACX,WAAWA;AAAA,MACX,aAAa;AAAA,IACf,CAAC;AAED,SAAK,uBAAuB,IAAI,kBAAkB,KAAK,OAAO,KAAK,QAAQ;AAAA,MACzE,WAAWA;AAAA,MACX,WAAWA;AAAA,MACX,aAAa;AAAA,IACf,CAAC;AAED,SAAK,YAAY,IAAI,YAAY,eAAe,KAAK,GAAG;AACxD,SAAK,UAAU,aAAa;AAC5B,SAAK,UAAU,QAAQ;AACvB,SAAK,UAAU,QAAQ;AACvB,SAAK,UAAU,YAAY;AAC3B,SAAK,UAAU,YAAY;AAC3B,SAAK,UAAU,cAAc;AAC7B,SAAK,WAAW;AAChB,SAAK,oBAAoB;AACzB,SAAK,YAAY;AACjB,SAAK,IAAI,IAAIC,SAAQ;AACrB,SAAK,IAAI,IAAIF,OAAM;AAAA,EACrB;AAAA,EAEQ,0BAAgC;AACtC,QAAI,KAAK,cAAc,SAAS;AAC9B,WAAK,wBAAwB,IAAI,kBAAkB,KAAK,QAAQ,GAAG,KAAK,SAAS,GAAG;AAAA,QAClF,OAAO;AAAA,QACP,aAAa;AAAA,MACf,CAAC;AACD,WAAK,sBAAsB,SAAS,CAAC,EAAE,SAAS;AAChD,WAAK,sBAAsB,SAAS,CAAC,EAAE,OAAO;AAC9C,WAAK,sBAAsB,SAAS,CAAC,EAAE,YAAY;AACnD,WAAK,sBAAsB,SAAS,CAAC,EAAE,YAAY;AACnD,WAAK,sBAAsB,SAAS,CAAC,EAAE,SAASG;AAChD,WAAK,sBAAsB,SAAS,CAAC,EAAE,OAAO;AAC9C,WAAK,sBAAsB,SAAS,CAAC,EAAE,YAAY;AACnD,WAAK,sBAAsB,SAAS,CAAC,EAAE,YAAY;AACnD,WAAK,sBAAsB,IAAI,mBAAmB,IAAIL,gBAAe,eAAe,CAAC;AAAA,IACvF,OAAO;AACL,UAAI,KAAK,uBAAuB;AAC9B,aAAK,sBAAsB,QAAQ;AACnC,aAAK,wBAAwB;AAAA,MAC/B;AACA,UAAI,KAAK,qBAAqB;AAC5B,aAAK,oBAAoB,QAAQ;AACjC,aAAK,sBAAsB;AAAA,MAC7B;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,iCAAuC;AAC7C,SAAK,gBAAgB,KAAK,cAAc,sBAAsB;AAC9D,SAAK,qBAAqB,KAAK,cAAc,sBAAsB;AAAA,EACrE;AAAA,EAEQ,gBAAgB,yBAAyB,OAAa;AAC5D,SAAK,UAAU,KAAK,0BAA0B,KAAK,cAAc,SAAS;AAC1E,SAAK,WAAW,KAAK,2BAA2B,KAAK,cAAc,SAAS;AAC5E,UAAM,IAAI,EAAE,GAAG,aAAa;AAC5B,MAAE,iBAAiB,EAAE,eAClB,QAAQ,MAAM,KAAK,cAAc,UAAU,SAAS,CAAC,EACrD,QAAQ,QAAQ,KAAK,cAAc,UAAU,SAAS,IAAI,IAAI;AACjE,QAAI,wBAAwB;AAC1B,QAAE,iBAAiB,uBAAuB,EAAE;AAAA,IAC9C;AACA,QAAI,KAAK,cAAc,SAAS;AAC9B,QAAE,iBAAiB,sBAAsB,EAAE;AAAA,IAC7C;AACA,QAAI,KAAK,kBAAkB;AACzB,WAAK,iBAAiB,SAAS,QAAQ;AACvC,WAAK,iBAAiB,WAAW,IAAIA,gBAAe,CAAC;AAAA,IACvD,OAAO;AACL,WAAK,mBAAmB,IAAI,mBAAmB,IAAIA,gBAAe,CAAC,CAAC;AAAA,IACtE;AAAA,EACF;AAAA,EAEQ,qBAAqB,yBAAkC,OAAa;AAC1E,SAAK,iBAAiB,KAAK,uBAAuB,KAAK,cAAc,gBAAgB,EAAE;AACvF,UAAM,IAAI,EAAE,GAAG,aAAa;AAC5B,MAAE,iBAAiB,EAAE,eAAe,QAAQ,MAAM,KAAK,cAAc,eAAe,SAAS,CAAC;AAC9F,QAAI,wBAAwB;AAC1B,QAAE,iBAAiB,uBAAuB,EAAE;AAAA,IAC9C;AACA,QAAI,KAAK,iBAAiB;AACxB,WAAK,gBAAgB,SAAS,QAAQ;AACtC,WAAK,gBAAgB,WAAW,IAAIA,gBAAe,CAAC;AAAA,IACtD,OAAO;AACL,WAAK,kBAAkB,IAAI,mBAAmB,IAAIA,gBAAe,CAAC,CAAC;AAAA,IACrE;AAAA,EACF;AAAA,EAEQ,0BAA0B,yBAAkC,OAAa;AAC/E,UAAM,IAAI,EAAE,GAAG,iBAAiB;AAEhC,QAAI,wBAAwB;AAC1B,QAAE,iBAAiB,uBAAuB,EAAE;AAAA,IAC9C;AAEA,QAAI,KAAK,cAAc,WAAW,KAAK,cAAc,sBAAsB;AACzE,QAAE,iBAAiB,sBAAsB,EAAE;AAAA,IAC7C;AAEA,QAAI,KAAK,sBAAsB;AAC7B,WAAK,qBAAqB,SAAS,QAAQ;AAC3C,WAAK,qBAAqB,WAAW,IAAIA,gBAAe,CAAC;AAAA,IAC3D,OAAO;AACL,WAAK,uBAAuB,IAAI,mBAAmB,IAAIA,gBAAe,CAAC,CAAC;AAAA,IAC1E;AAAA,EACF;AAAA,EAEQ,0BAA0B,GAAsB;AACtD,UAAM,SAAS,CAAC;AAChB,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,YAAM,QAAQ,WAAW;AACzB,YAAM,IAAI,KAAK,KAAK,IAAI,GAAG,IAAI,KAAK,KAAK,CAAC;AAC1C,YAAM,IAAI,IAAI,KAAK,IAAI,KAAK;AAC5B,YAAM,IAAI,IAAI,KAAK,IAAI,KAAK;AAE5B,YAAM,IAAI,KAAK,KAAK,KAAK,IAAI,IAAI,IAAI,EAAE;AACvC,aAAO,KAAK,IAAIM,UAAQ,GAAG,GAAG,CAAC,CAAC;AAAA,IAClC;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,2BAA2B,GAAqB;AACtD,UAAM,WAAW,CAAC;AAClB,aAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,eAAS,MAAM,IAAI,KAAK,CAAC;AAAA,IAC3B;AACA,WAAO;AAAA,EACT;AAAA,EAEQ,uBAAuB,YAAoB,UAA6B;AAC9E,UAAM,YAAa,IAAI,KAAK,KAAK,WAAY;AAC7C,UAAM,gBAAgB,IAAM;AAC5B,UAAM,aAAa;AACnB,UAAM,UAAU,CAAC;AACjB,QAAI,SAAS;AACb,QAAI,QAAQ;AACZ,aAAS,IAAI,GAAG,IAAI,YAAY,KAAK;AACnC,cAAQ;AAAA,QACN,IAAIF,SAAQ,KAAK,IAAI,KAAK,GAAG,KAAK,IAAI,KAAK,CAAC,EAAE,eAAe,KAAK,IAAI,QAAQ,IAAI,CAAC;AAAA,MACrF;AACA,gBAAU;AACV,eAAS;AAAA,IACX;AACA,WAAO;AAAA,EACT;AAAA,EAEO,QAAQ,OAAe,QAAsB;AAClD,SAAK,QAAQ;AACb,SAAK,SAAS;AACd,UAAM,IAAI,KAAK,cAAc,UAAU,MAAM;AAC7C,SAAK,oBAAoB,QAAQ,QAAQ,GAAG,SAAS,CAAC;AACtD,SAAK,mBAAmB,QAAQ,QAAQ,GAAG,SAAS,CAAC;AACrD,QAAI,KAAK,cAAc,WAAW,KAAK,uBAAuB;AAC5D,WAAK,sBAAsB,QAAQ,QAAQ,GAAG,SAAS,CAAC;AAAA,IAC1D;AACA,SAAK,qBAAqB,QAAQ,OAAO,MAAM;AAAA,EACjD;AAAA,EAEO,gBAAgB,cAAiC;AACtD,SAAK,eAAe;AAAA,EACtB;AAAA,EAEO,OACL,UACA,aACA,cACM;AACN,UAAM,YAAY,SAAS,GAAG;AAC9B,aAAS,GAAG,UAAU;AAEtB,QAAI;AACJ,QAAI,aAAgC;AACpC,QAAI,KAA4D;AAChE,SAAK,SAAS,WAAW;AAEzB,QAAI,KAAK,WAAW;AAClB,YAAM,GAAG,aAAa,iCAAiC;AACvD,UAAI,QAAQ,MAAM;AAChB,gBAAQ,MAAM,sEAAsE;AACpF,aAAK,YAAY;AACjB,aAAK;AAAA,MACP;AAAA,IACF;AAEA,QAAI,KAAK,aAAa,IAAI;AACxB,mBAAc,GAA8B,YAAY;AACxD,MAAC,GAA8B,WAAW,IAAI,kBAAkB,UAAU;AAAA,IAC5E;AAEA,QACE,SAAS,aAAa,2BAA2B,KAAK,cAAc,wBACpE;AACA,WAAK,cAAc,yBAAyB,SAAS,aAAa;AAClE,WAAK,gBAAgB,KAAK,cAAc,sBAAsB;AAC9D,WAAK,qBAAqB,KAAK,cAAc,sBAAsB;AACnE,WAAK,0BAA0B,KAAK,cAAc,sBAAsB;AAAA,IAC1E;AAEA,QAAI,YAAY,QAAQ,SAAS,KAAK,qBAAqB,QAAQ,MAAM;AACvE,WAAK,qBAAqB,QAAQ,OAAO,YAAY,QAAQ;AAC7D,WAAK,qBAAqB,QAAQ,cAAc;AAAA,IAClD;AAEA,SAAK,OAAO,kBAAkB;AAC9B,SAAK,EAAE,IAAI,KAAK,OAAO,KAAK,MAAM;AAClC,QAAI,aAAa,KAAK,cAAc;AAEpC,QAAI,KAAK,cAAc,WAAW,KAAK,cAAc,mBAAmB;AACtE,oBAAc;AAAA,IAChB;AAEA,QAAI,KAAK,cAAc,WAAW,KAAK,qBAAqB;AAC1D,YAAM,0BAA0B,KAAK,oBAAoB,SAAS;AAClE,eAAS,gBAAgB,KAAK,qBAAqB;AACnD,8BAAwB,WAAW,QAAQ,KAAK;AAChD,8BAAwB,WAAW,QAAQ,KAAK;AAChD,8BAAwB,KAAK,QAAQ,KAAK,OAAO;AACjD,8BAAwB,IAAI,QAAQ,KAAK,OAAO;AAChD,8BAAwB,oBAAoB,QAAQ,KAAK,OAAO;AAChE,8BAAwB,cAAc,QAAQ,KAAK,OAAO;AAC1D,8BAAwB,SAAS,QAAQ,KAAK,cAAc;AAC5D,WAAK,oBAAoB,OAAO,QAAQ;AAAA,IAC1C;AAEA,QAAI,CAAC,KAAK,iBAAkB;AAE5B,UAAM,uBAAuB,KAAK,iBAAiB,SAAS;AAE5D,yBAAqB,aAAa,QAAQ,YAAY;AACtD,yBAAqB,WAAW,QAAQ,KAAK,cAAc,UACvD,KAAK,sBAAuB,SAAS,CAAC,IACtC,KAAK;AACT,yBAAqB,YAAY,QAAQ,KAAK,cAAc,UACxD,KAAK,sBAAuB,SAAS,CAAC,IACtC;AACJ,yBAAqB,QAAQ,QAAQ,KAAK,OAAO;AACjD,yBAAqB,QAAQ,QAAQ,KAAK,OAAO;AACjD,yBAAqB,YAAY,QAAQ,KAAK,OAAO,iBAClD,MAAM,EACN,SAAS,KAAK,OAAO,mBAAmB,MAAM,CAAC;AAClD,yBAAqB,oBAAoB,QAAQ,KAAK,OAAO;AAC7D,yBAAqB,cAAc,QAAQ,KAAK,OAAO;AACvD,yBAAqB,UAAU,QAAQ,KAAK,OAAO,iBAAiB,IAAIE,UAAQ,CAAC;AACjF,yBAAqB,WAAW,QAAQ,KAAK,cAAc,UACvD,KAAK,EACF,MAAM,EACN,eAAe,IAAI,CAAC,EACpB,MAAM,IACT,KAAK;AACT,yBAAqB,KAAK,QAAQ,YAAY,IAAI,IAAI;AACtD,yBAAqB,QAAQ,QAAQ,KAAK;AAC1C,yBAAqB,SAAS,QAAQ,KAAK;AAC3C,yBAAqB,UAAU,QAAQ,KAAK;AAC5C,yBAAqB,OAAO,QAAQ;AACpC,yBAAqB,gBAAgB,QAAQ,KAAK,cAAc;AAChE,yBAAqB,KAAK,QAAQ,KAAK,OAAO;AAC9C,yBAAqB,IAAI,QAAQ,KAAK,OAAO;AAC7C,yBAAqB,SAAS,QAAQ,SAAS,aAAa;AAC5D,yBAAqB,MAAM,QAAQ,KAAK,kBAAkBC;AAC1D,yBAAqB,kBAAkB,QAAQ,KAAK,cAAc;AAGlE,aAAS,gBAAgB,KAAK,mBAAmB;AACjD,SAAK,iBAAiB,OAAO,QAAQ;AAGrC,UAAM,sBAAsB,KAAK,gBAAiB,SAAS;AAG3D,aAAS,IAAI,GAAG,IAAI,KAAK,cAAc,mBAAmB,KAAK;AAC7D,UAAI,CAAC,uBAAuB,CAAC,KAAK,gBAAiB;AACnD,OAAC,KAAK,qBAAqB,KAAK,kBAAkB,IAAI;AAAA,QACpD,KAAK;AAAA,QACL,KAAK;AAAA,MACP;AACA,0BAAoB,SAAS,QAAQ,KAAK,mBAAmB;AAC7D,0BAAoB,WAAW,QAAQ,KAAK,cAAc,UACtD,KAAK,sBAAuB,SAAS,CAAC,IACtC,KAAK;AACT,0BAAoB,QAAQ,QAAQ,KAAK,OAAO;AAChD,0BAAoB,QAAQ,QAAQ,KAAK,OAAO;AAChD,0BAAoB,oBAAoB,QAAQ,KAAK,OAAO;AAC5D,0BAAoB,cAAc,QAAQ,KAAK,OAAO;AACtD,0BAAoB,UAAU,QAAQ,KAAK,OAAO,iBAAiB,IAAID,UAAQ,CAAC;AAChF,0BAAoB,WAAW,QAAQ,KAAK,cAAc,UACtD,KAAK,EACF,MAAM,EACN,eAAe,IAAI,CAAC,EACpB,MAAM,IACT,KAAK;AACT,0BAAoB,KAAK,QAAQ,YAAY,IAAI,IAAI;AACrD,0BAAoB,UAAU,QAAQ,KAAK;AAC3C,0BAAoB,OAAO,QACzB,KAAK,cAAc,iBAAiB,KAAK,cAAc,UAAU,IAAI,IAAI;AAC3E,0BAAoB,YAAY,QAAQ;AACxC,0BAAoB,gBAAgB,QAAQ,KAAK,cAAc;AAC/D,0BAAoB,MAAM,QAAQ;AAClC,0BAAoB,YAAY,QAAQ,KAAK;AAC7C,0BAAoB,KAAK,QAAQ,KAAK,OAAO;AAC7C,0BAAoB,IAAI,QAAQ,KAAK,OAAO;AAC5C,0BAAoB,SAAS,QAAQ,SAAS,aAAa;AAC3D,0BAAoB,kBAAkB,QAAQ,KAAK,cAAc;AACjE,eAAS,gBAAgB,KAAK,mBAAmB;AACjD,WAAK,gBAAgB,OAAO,QAAQ;AAAA,IACtC;AAGA,UAAM,2BAA2B,KAAK,qBAAsB,SAAS;AAGrE,QAAI,CAAC,4BAA4B,CAAC,KAAK,qBAAsB;AAC7D,6BAAyB,aAAa,QAAQ,YAAY;AAC1D,6BAAyB,WAAW,QAAQ,KAAK;AACjD,6BAAyB,KAAK,QAAQ,KAAK,OAAO;AAClD,6BAAyB,IAAI,QAAQ,KAAK,OAAO;AACjD,6BAAyB,oBAAoB,QAAQ,KAAK,OAAO;AACjE,6BAAyB,cAAc,QAAQ,KAAK,OAAO;AAC3D,6BAAyB,SAAS,QAAQ,SAAS,aAAa;AAChE,6BAAyB,MAAM,QAAQ,KAAK,kBAAkBC;AAC9D,6BAAyB,iBAAiB,QAAQ,KAAK,cAAc,UACjE,KAAK,sBAAuB,SAAS,CAAC,IACtC,KAAK;AACT,6BAAyB,WAAW,QAAQ,KAAK;AACjD,6BAAyB,UAAU,QAAQ,KAAK;AAChD,6BAAyB,UAAU,QAAQ,KAAK,cAAc;AAC9D,6BAAyB,WAAW,QAAQ,KAAK,cAAc;AAC/D,6BAAyB,kBAAkB,QAAQ,KAAK,cAAc;AACtE,6BAAyB,OAAO,QAAQ;AACxC,6BAAyB,gBAAgB,QAAQ,KAAK,cAAc;AACpE,6BAAyB,gBAAgB,QAAQ,KAAK,eAClD,KAAK,iBACL,KAAK,cAAc;AACvB,6BAAyB,SAAS,QAAQ,KAAK,oBAAoB;AACnE,6BAAyB,MAAM,QAAQ,KAAK,EACzC,KAAK,KAAK,cAAc,KAAK,EAC7B,oBAAoB;AACvB,6BAAyB,cAAc,QAAQ,KAAK,cAAc;AAClE,6BAAyB,UAAU,QAAQ,KAAK,OAAO,iBAAiB,IAAID,UAAQ,CAAC;AACrF,6BAAyB,IAAI,QAAQ,CAAC,CAAC,KAAK,MAAM;AAElD,QAAI,KAAK,MAAM,KAAK;AAClB,UAAI,KAAK,MAAM,eAAe,OAAO,KAAK,MAAM,IAAI,UAAU,MAAM;AAClE,iCAAyB,OAAO,QAAQ;AACxC,iCAAyB,QAAQ,QAAQ,KAAK,MAAM,IAAI;AACxD,iCAAyB,OAAO,QAAQ,KAAK,MAAM,IAAI;AAAA,MACzD,WAAW,KAAK,MAAM,eAAe,SAAS;AAC5C,iCAAyB,OAAO,QAAQ;AACxC,iCAAyB,WAAW,QAAQ,KAAK,MAAM,IAAI;AAAA,MAC7D,OAAO;AACL,gBAAQ,MAAM,wBAAwB,KAAK,MAAM,IAAI,YAAY,IAAI,eAAe;AAAA,MACtF;AAAA,IACF;AAEA,aAAS,gBAAgB,KAAK,oBAAoB;AAClD,SAAK,qBAAqB,OAAO,QAAQ;AACzC,aAAS,gBAAgB,KAAK,iBAAiB,OAAO,YAAY;AAClE,SAAK,SAAS,SAAS,SAAS,SAAS,QAAQ,KAAK,qBAAqB;AAC3E,SAAK,SAAS,OAAO,QAAQ;AAE7B,QAAI,KAAK,aAAa,MAAM,YAAY;AACtC,MAAC,GAA8B,SAAS,IAAI,gBAAgB;AAC5D,sBAAgB,YAA0B,IAA8B,IAAI;AAAA,IAC9E;AAEA,aAAS,GAAG,UAAU;AAAA,EACxB;AAAA,EAEO,kBAAwB;AAC7B,SAAK,YAAY;AAAA,EACnB;AAAA,EAEO,mBAAyB;AAC9B,SAAK,YAAY;AAAA,EACnB;AAAA,EAEO,eAAe,MAAgE;AACpF,SAAK,cAAc,aAAa,CAAC,YAAY,MAAM,SAAS,SAAS,UAAU,EAAE;AAAA,MAC/E;AAAA,IACF;AAAA,EACF;AAAA,EAEO,eAAe,MAAyB;AAC7C,QAAI,SAAS,eAAe;AAC1B,WAAK,cAAc,YAAY;AAC/B,WAAK,cAAc,iBAAiB;AACpC,WAAK,cAAc,gBAAgB;AAAA,IACrC,WAAW,SAAS,OAAO;AACzB,WAAK,cAAc,YAAY;AAC/B,WAAK,cAAc,iBAAiB;AACpC,WAAK,cAAc,gBAAgB;AAAA,IACrC,WAAW,SAAS,UAAU;AAC5B,WAAK,cAAc,YAAY;AAC/B,WAAK,cAAc,iBAAiB;AACpC,WAAK,cAAc,gBAAgB;AAAA,IACrC,WAAW,SAAS,QAAQ;AAC1B,WAAK,cAAc,YAAY;AAC/B,WAAK,cAAc,iBAAiB;AACpC,WAAK,cAAc,gBAAgB;AAAA,IACrC,WAAW,SAAS,SAAS;AAC3B,WAAK,cAAc,YAAY;AAC/B,WAAK,cAAc,iBAAiB;AACpC,WAAK,cAAc,gBAAgB;AAAA,IACrC;AAAA,EACF;AACF;;;ALrgBO,IAAM,WAAN,MAAe;AAAA,EAkDpB,YAAY;AAAA,IACV;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX;AAAA,EACF,GAA2B;AAtD3B,SAAQ,QAAgB;AACxB,SAAQ,SAAiB;AAEzB,SAAO,aAAsB,IAAIE,SAAQ,KAAK,OAAO,KAAK,MAAM;AA0BhE,SAAiB,MAAM;AAGvB,SAAiB,mBAAmB;AAGpC,SAAQ,eAAoC;AAG5C,SAAQ,cAMJ,EAAE,KAAK,CAAC,GAAG,eAAe,KAAK;AAEnC,SAAO,MAAkB;AA5I3B;AAqJI,SAAK,QAAQ;AACb,SAAK,gBAAgB;AACrB,SAAK,gBAAgB,IAAIC,OAAM;AAC/B,SAAK,WAAW;AAChB,SAAK,WAAW,IAAIC,eAAc;AAAA,MAChC,iBAAiB;AAAA,MACjB,WAAW;AAAA,IACb,CAAC;AACD,SAAK,SAAS,mBAAmB;AACjC,SAAK,SAAS,KAAK,YAAY;AAC/B,SAAK,SAAS,QAAQ,KAAK,OAAO,KAAK,MAAM;AAC7C,SAAK,SAAS,UAAU,UAAU;AAClC,SAAK,SAAS,UAAU,OAAO,eAAe;AAC9C,SAAK,SAAS,cAAc,eAAe;AAC3C,SAAK,SAAS,sBAAsB,eAAe;AAEnD,SAAK,2BAA2B;AAEhC,SAAK,yBAAyB;AAC9B,SAAK,yBAAyB;AAC9B,SAAK,OAAO;AAEZ,SAAK,iBAAiB,IAAIC,gBAAe,KAAK,UAAU;AAAA,MACtD,iBAAiBC;AAAA,IACnB,CAAC;AAED,SAAK,aAAa,IAAI,WAAW,KAAK,OAAO,KAAK,cAAc,YAAY;AAE5E,SAAK,aAAa,IAAIC,YAAW,KAAK,OAAO,KAAK,cAAc,YAAY;AAC5E,SAAK,WAAW,UAAU,aAAa;AACvC,SAAK,sBAAsB,IAAI,cAAc;AAAA,MAC3C,eAAeC,eAAc;AAAA,MAC7B,SAAS,KAAK,WAAW;AAAA,IAC3B,CAAC;AAED,SAAK,eAAe,IAAIC,YAAW,KAAK,cAAc,cAAc,KAAK,WAAW,SAAS;AAAA,MAC3F,eAAe,aAAa;AAAA,MAC5B,iBAAiB,aAAa;AAAA,MAC9B,sBAAsB,aAAa;AAAA,MACnC,SAAS,aAAa;AAAA,MACtB,OAAO,aAAa;AAAA,MACpB,oBAAoB,aAAa;AAAA,MACjC,QAAQ,aAAa;AAAA,MACrB,WAAW,aAAa;AAAA,MACxB,MAAM,aAAa;AAAA,MACnB,MAAM,aAAa;AAAA,MACnB,iBAAiB,aAAa;AAAA,MAC9B,OAAO,IAAIC,OAAM,EAAE,OAAO,aAAa,MAAM,GAAG,aAAa,MAAM,GAAG,aAAa,MAAM,CAAC;AAAA,MAC1F,wBAAwB,aAAa;AAAA,MACrC,sBAAsB,aAAa;AAAA,MACnC,yBAAyB,aAAa;AAAA,MACtC,uBAAuB,aAAa;AAAA,IACtC,CAAC;AACD,SAAK,aAAa,IAAIC;AAAA,MACpB,KAAK,cAAc;AAAA,MACnB,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AACA,SAAK,WAAW,UAAU,aAAa;AAEvC,SAAK,aAAa,IAAI,WAAW;AAEjC,SAAI,0EAA0B,mBAA1B,mBAA0C,gBAAgB;AAC5D,mBAAa,QAAQ,yBAAyB,eAAe;AAAA,IAC/D;AAEA,SAAK,cAAc,IAAI,YAAY;AAAA,MACjC,WAAW,aAAa;AAAA,IAC1B,CAAC;AAED,SAAK,WAAW,IAAI;AAAA,MAClB,KAAK;AAAA,MACL,KAAK,cAAc;AAAA,MACnB,KAAK;AAAA,MACL,KAAK;AAAA,IACP;AACA,SAAK,SAAS,cAAc,WAAW,aAAa;AACpD,SAAK,SAAS,cAAc,kBAAkB,aAAa;AAC3D,SAAK,SAAS,cAAc,YAAY,aAAa;AACrD,SAAK,SAAS,cAAc,QAAQ,IAAID,OAAM,EAAE;AAAA,MAC9C,aAAa,MAAM;AAAA,MACnB,aAAa,MAAM;AAAA,MACnB,aAAa,MAAM;AAAA,IACrB;AACA,SAAK,SAAS,cAAc,YAAY,aAAa;AACrD,SAAK,SAAS,cAAc,iBAAiB,aAAa;AAC1D,SAAK,SAAS,cAAc,gBAAgB,aAAa;AACzD,SAAK,SAAS,UAAU,aAAa;AAErC,SAAK,WAAW,IAAIC,YAAW,KAAK,cAAc,cAAc,KAAK,UAAU;AAC/E,SAAK,YAAY,IAAIA,YAAW,KAAK,cAAc,cAAc,KAAK,WAAW;AAEjF,SAAK,oBAAoB,IAAI,kBAAkB;AAAA,MAC7C,MAAM,kBAAkB;AAAA,MACxB,YAAY,kBAAkB;AAAA,MAC9B,YAAY,kBAAkB;AAAA,MAC9B,YAAY,kBAAkB;AAAA,MAC9B,cAAc,kBAAkB;AAAA,MAChC,kBAAkB,kBAAkB;AAAA,MACpC,gBAAgB,kBAAkB;AAAA,IACpC,CAAC;AACD,SAAK,aAAa,IAAI,WAAW;AAAA,MAC/B,QAAQ,WAAW;AAAA,MACnB,mBAAmB,kBAAkB;AAAA,MACrC,iBAAiB,gBAAgB;AAAA,IACnC,CAAC;AAED,SAAK,kBAAkB,IAAIA,YAAW,KAAK,cAAc,cAAc,KAAK,iBAAiB;AAC7F,SAAK,gBAAgB,UACnB,eAAe,gBAAgB,KAAK,eAAe,gBAAgB,IAAI,OAAO;AAEhF,SAAK,UAAU,IAAI,WAAW,KAAK,KAAK,UAAU;AAClD,SAAK,IAAI,SAAS,WAAW,QAAQ,UAAU;AAC/C,SAAK,IAAI,SAAS,SAAS,QAAQ,UAAU;AAC7C,SAAK,IAAI,SAAS,WAAW,QAAQ,UAAU;AAE/C,SAAK,iBAAiB,IAAI,WAAW,KAAK,kBAAkB,UAAU;AACtE,SAAK,iBAAiB,SAAS,OAAO,QAAQ,aAAa;AAC3D,SAAK,iBAAiB,SAAS,MAAM,QAAQ;AAE7C,SAAK,WAAW,IAAIA,YAAW,KAAK,cAAc,cAAc,KAAK,UAAU;AAE/E,SAAK,eAAe,QAAQ,KAAK,UAAU;AAC3C,QAAI,aAAa,SAAS;AACxB,WAAK,eAAe,QAAQ,KAAK,UAAU;AAC3C,WAAK,eAAe,QAAQ,KAAK,UAAU;AAAA,IAC7C;AACA,QAAI,aAAa,SAAS;AACxB,WAAK,eAAe,QAAQ,KAAK,QAAQ;AAAA,IAC3C;AACA,SAAK,eAAe,QAAQ,KAAK,QAAQ;AACzC,SAAK,eAAe,QAAQ,KAAK,SAAS;AAC1C,SAAK,eAAe,QAAQ,KAAK,eAAe;AAChD,SAAK,eAAe,QAAQ,KAAK,OAAO;AACxC,SAAK,eAAe,QAAQ,KAAK,cAAc;AAE/C,QAAI,KAAK,aAAa,MAAM;AAC1B,WAAK,MAAM,IAAI,IAAI;AACnB,WAAK,MAAM,IAAI,KAAK,GAAG;AAAA,IACzB;AAEA,SAAI,UAAK,6BAAL,mBAA+B,QAAQ;AACzC,UAAI,eAAe,KAAK,yBAAyB,QAAQ;AACvD,aAAK,UAAU,KAAK,yBAAyB,OAAO,SAAS;AAAA,MAC/D,WAAW,YAAY,KAAK,yBAAyB,QAAQ;AAC3D,aAAK,QAAQ,KAAK,yBAAyB,OAAO,MAAM;AAAA,MAC1D;AAAA,IACF;AAEA,SAAK,gBAAgB;AAErB,SAAK,iBAAiB,MAAM;AAC1B,WAAK,aAAa;AAAA,IACpB;AACA,WAAO,iBAAiB,UAAU,KAAK,gBAAgB,KAAK;AAC5D,SAAK,aAAa;AAAA,EACpB;AAAA,EAEO,+BAA+B,0BAAoD;AACxF,SAAK,2BAA2B;AAEhC,QAAI,yBAAyB,QAAQ;AACnC,UAAI,eAAe,yBAAyB,QAAQ;AAClD,aAAK,UAAU,yBAAyB,OAAO,SAAS;AAAA,MAC1D,WAAW,YAAY,yBAAyB,QAAQ;AACtD,aAAK,QAAQ,yBAAyB,OAAO,MAAM;AAAA,MACrD;AAAA,IACF;AAEA,SAAK,yBAAyB;AAC9B,SAAK,yBAAyB;AAC9B,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEO,eAAe,WAAsB;AAC1C,cAAU;AAAA,MACR,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK;AAAA,MACL,KAAK,gBAAgB,KAAK,IAAI;AAAA,MAC9B,CAAC,mBAA2B;AAC1B,kBAAU,uBAAuB;AACjC,aAAK,qBAAqB;AAAA,MAC5B;AAAA,MACA,CAAC,eAAuB;AACtB,kBAAU,mBAAmB;AAC7B,aAAK,qBAAqB;AAAA,MAC5B;AAAA,MACA,KAAK,gBAAgB,KAAK,IAAI;AAAA,MAC9B,KAAK,OAAO,KAAK,IAAI;AAAA,IACvB;AAAA,EACF;AAAA,EAEO,UAAU;AACf,WAAO,oBAAoB,UAAU,KAAK,cAAc;AACxD,SAAK,SAAS,QAAQ;AAAA,EACxB;AAAA,EAEO,eAAe;AACpB,QAAI,CAAC,MAAM;AACT,cAAQ,MAAM,0BAA0B;AACxC;AAAA,IACF;AACA,UAAM,gBAAgB,KAAK,SAAS,WAAW;AAC/C,QAAI,CAAC,eAAe;AAClB;AAAA,IACF;AACA,SAAK,QAAQ,cAAc;AAC3B,SAAK,SAAS,cAAc;AAC5B,SAAK,cAAc,aAAa,SAAS,KAAK,QAAQ,KAAK;AAC3D,SAAK,cAAc,aAAa,uBAAuB;AACvD,SAAK,SAAS,cAAc,OAAO,gBAAgB;AACnD,SAAK,WAAW;AAAA,MACd,KAAK,QAAQ,OAAO;AAAA,MACpB,KAAK,SAAS,OAAO;AAAA,IACvB;AACA,SAAK,eAAe;AAAA,MAClB,KAAK,QAAQ,OAAO;AAAA,MACpB,KAAK,SAAS,OAAO;AAAA,IACvB;AACA,SAAK,WAAW,QAAQ,KAAK,OAAO,KAAK,MAAM;AAC/C,QAAI,aAAa,SAAS;AACxB,WAAK,WAAW,QAAQ,KAAK,OAAO,KAAK,MAAM;AAC/C,WAAK,oBAAoB,QAAQ,KAAK,OAAO,KAAK,MAAM;AACxD,WAAK,WAAW,QAAQ,KAAK,OAAO,KAAK,MAAM;AAAA,IACjD;AACA,QAAI,aAAa,SAAS;AACxB,WAAK,SAAS,QAAQ,KAAK,OAAO,KAAK,MAAM;AAAA,IAC/C;AACA,SAAK,SAAS,QAAQ,KAAK,OAAO,KAAK,MAAM;AAC7C,SAAK,SAAS,QAAQ,KAAK,OAAO,KAAK,MAAM;AAC7C,SAAK,UAAU,QAAQ,KAAK,OAAO,KAAK,MAAM;AAC9C,SAAK,gBAAgB,QAAQ,KAAK,OAAO,KAAK,MAAM;AACpD,SAAK,eAAe,QAAQ,KAAK,OAAO,KAAK,MAAM;AACnD,SAAK,iBAAiB,SAAS,WAAW,QAAQ,IAAIT,SAAQ,KAAK,OAAO,KAAK,MAAM;AACrF,SAAK,SAAS,QAAQ,KAAK,OAAO,KAAK,MAAM;AAAA,EAC/C;AAAA,EAEO,OAAO,aAAgC;AAC5C,SAAK,SAAS,KAAK,MAAM;AACzB,SAAK,WAAW,aAAa,KAAK,cAAc;AAChD,SAAK,WAAW,QAAQ,cAAc;AACtC,SAAK,iBAAiB,SAAS,KAAK,QAAQ,YAAY;AACxD,SAAK,eAAe,OAAO;AAC3B,SAAK,SAAS,WAAW;AACzB,SAAK,SAAS,OAAO,KAAK,eAAe,KAAK,cAAc,YAAY;AAAA,EAC1E;AAAA,EAEO,uBAAuB;AAC5B,SAAK,MAAM,qBAAqB,IAAIU;AAAA,MAClC,UAAU,SAAS,UAAU,gBAAgB;AAAA,MAC7C,UAAU,SAAS,UAAU,oBAAoB;AAAA,MACjD;AAAA,IACF;AACA,SAAK,MAAM,sBAAsB,IAAIA;AAAA,MACnC,UAAU,SAAS,UAAU,gBAAgB;AAAA,MAC7C,UAAU,SAAS,UAAU,oBAAoB;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,WAAW,KAA+B;AACtD,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,iBAAiB,IAAI,eAAe,KAAK,QAAQ;AACvD,YAAM,SAAS,IAAI,aAAa,KAAK,QAAQ,EAAE,KAAK,KAAK,MAAM;AAC7D,cAAM,2BAA2B,OAAO,aAAa;AACrD,iCAAyB,UAAU;AACnC,iCAAyB,cAAc;AAEvC,cAAM,SAAS,eAAgB,oBAAoB,wBAAwB,EAAE;AAC7E,iCAAyB,QAAQ;AACjC,uBAAgB,QAAQ;AACxB,eAAO,QAAQ;AACf,YAAI,QAAQ;AACV,iBAAO,aAAa;AACpB,iBAAO,cAAc;AACrB,kBAAQ,MAAM;AAAA,QAChB,OAAO;AACL,iBAAO,oCAAoC;AAAA,QAC7C;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,SAAS,KAA+B;AACpD,WAAO,IAAI,QAAQ,CAAC,SAAS,WAAW;AACtC,YAAM,iBAAiB,IAAI,eAAe,KAAK,QAAQ;AACvD,UAAI,WAAW,IAAI,eAAe,CAAC,EAAE,KAAK,KAAK,CAAC,YAAY;AAC1D,cAAM,SAAS,eAAgB,oBAAoB,OAAO,EAAE;AAC5D,gBAAQ,QAAQ;AAChB,uBAAgB,QAAQ;AACxB,YAAI,QAAQ;AACV,iBAAO,aAAa;AACpB,iBAAO,cAAc;AACrB,kBAAQ,MAAM;AAAA,QAChB,OAAO;AACL,iBAAO,oCAAoC;AAAA,QAC7C;AAAA,MACF,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AAAA,EAEO,UAAU,KAAa,WAAoB,OAAa;AAC7D,QAAI,KAAK,YAAY,IAAI,cAAc,KAAK;AAC1C;AAAA,IACF;AAEA,UAAM,gBAAgB,KAAK,WAAW,GAAG;AACzC,SAAK,YAAY,MAAM,EAAE,WAAW,IAAI;AACxC,SAAK,YAAY,gBAAgB;AACjC,kBAAc,KAAK,CAAC,WAAW;AAC7B,UAAI,KAAK,YAAY,kBAAkB,eAAe;AACpD;AAAA,MACF;AACA,WAAK,YAAY,MAAM;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EAEO,QAAQ,KAAmB;AAChC,QAAI,KAAK,YAAY,IAAI,WAAW,KAAK;AACvC;AAAA,IACF;AACA,UAAM,aAAa,KAAK,SAAS,GAAG;AACpC,SAAK,YAAY,MAAM,EAAE,QAAQ,IAAI;AACrC,SAAK,YAAY,gBAAgB;AACjC,eAAW,KAAK,CAAC,WAAW;AAC1B,UAAI,KAAK,YAAY,kBAAkB,YAAY;AACjD;AAAA,MACF;AACA,WAAK,YAAY,MAAM;AAAA,IACzB,CAAC;AAAA,EACH;AAAA,EAEO,kBAAwB;AAC7B,QAAI,CAAC,KAAK,SAAU;AACpB,UAAM,YAAY,SAAS,cAAc,OAAO;AAChD,cAAU,OAAO;AACjB,cAAU,SAAS;AACnB,cAAU,iBAAiB,UAAU,MAAM;AAhf/C;AAifM,YAAM,QAAO,eAAU,UAAV,mBAAkB;AAC/B,UAAI,CAAC,MAAM;AACT,gBAAQ,IAAI,SAAS;AACrB;AAAA,MACF;AACA,YAAM,YAAY,KAAK,KAAK,MAAM,GAAG,EAAE,IAAI;AAC3C,YAAM,UAAU,IAAI,gBAAgB,IAAI;AACxC,UAAI,SAAS;AACX,YAAI,cAAc,OAAO;AACvB,eAAK,QAAQ,OAAO;AAAA,QACtB,WAAW,cAAc,OAAO;AAC9B,eAAK,UAAU,OAAO;AAAA,QACxB,OAAO;AACL,kBAAQ,MAAM,uCAAuC,KAAK,IAAI,EAAE;AAAA,QAClE;AACA,YAAI,gBAAgB,OAAO;AAC3B,iBAAS,KAAK,YAAY,SAAS;AAAA,MACrC;AAAA,IACF,CAAC;AACD,aAAS,KAAK,YAAY,SAAS;AACnC,cAAU,MAAM;AAAA,EAClB;AAAA,EAEO,SAAe;AACpB,QAAI,UAAU,IAAI,WAAW,GAAG;AAC9B,WAAK,MAAM,MAAM;AACjB;AAAA,IACF;AACA,UAAM,WAAW,IAAIF,OAAM,EAAE;AAAA,MAC3B,UAAU,IAAI,SAAS;AAAA,MACvB,UAAU,IAAI,SAAS;AAAA,MACvB,UAAU,IAAI,SAAS;AAAA,IACzB;AACA,SAAK,MAAM,MAAM,IAAIG,KAAI,UAAU,UAAU,IAAI,SAAS,UAAU,IAAI,MAAM;AAAA,EAChF;AAAA,EAEO,kBAAwB;AAC7B,QAAI,KAAK,cAAc;AACrB,WAAK,MAAM,OAAO,KAAK,YAAY;AACnC,WAAK,aAAa,QAAQ;AAAA,IAC5B;AACA,UAAM,oBAAoB,IAAIH,OAAM,EAAE;AAAA,MACpC,UAAU,aAAa,kBAAkB;AAAA,MACzC,UAAU,aAAa,kBAAkB;AAAA,MACzC,UAAU,aAAa,kBAAkB;AAAA,IAC3C;AACA,SAAK,eAAe,IAAI;AAAA,MACtB;AAAA,MACA,UAAU,aAAa;AAAA,IACzB;AACA,SAAK,MAAM,IAAI,KAAK,YAAY;AAAA,EAClC;AAAA,EAEQ,kBAAkB;AAtiB5B;AAuiBI,QAAI,SAAO,gBAAK,6BAAL,mBAA+B,QAA/B,mBAAoC,eAAc,UAAU;AACrE,gBAAU,eAAe,KAAK,yBAAyB,IAAI;AAC3D,iBAAK,QAAL,mBAAU,aAAa,KAAK,yBAAyB,IAAI;AAAA,IAC3D;AACA,QAAI,SAAO,gBAAK,6BAAL,mBAA+B,QAA/B,mBAAoC,oBAAmB,UAAU;AAC1E,gBAAU,YAAY,oBAAoB,KAAK,yBAAyB,IAAI;AAC5E,iBAAK,QAAL,mBAAU;AAAA,QACR,KAAK,yBAAyB,IAAI,kBAAkB,KAAK,KAAK;AAAA;AAAA,IAElE;AACA,QAAI,SAAO,gBAAK,6BAAL,mBAA+B,QAA/B,mBAAoC,gBAAe,UAAU;AACtE,gBAAU,YAAY,gBAAgB,KAAK,yBAAyB,IAAI;AACxE,iBAAK,QAAL,mBAAU,cAAc,KAAK,yBAAyB,IAAI,cAAc,KAAK,KAAK;AAAA,IACpF;AAAA,EACF;AAAA,EAEQ,2BAA2B;AAvjBrC;AAwjBI,QAAI,SAAO,gBAAK,6BAAL,mBAA+B,WAA/B,mBAAuC,eAAc,UAAU;AACxE,gBAAU,mBAAkB,UAAK,6BAAL,mBAA+B,OAAO;AAAA,IACpE;AACA,SAAK,MAAM,uBAAuB,UAAU;AAE5C,QAAI,SAAO,gBAAK,6BAAL,mBAA+B,WAA/B,mBAAuC,eAAc,UAAU;AACxE,gBAAU,mBAAkB,UAAK,6BAAL,mBAA+B,OAAO;AAAA,IACpE;AACA,SAAK,MAAM,sBAAsB,UAAU;AAE3C,QAAI,SAAO,gBAAK,6BAAL,mBAA+B,WAA/B,mBAAuC,gBAAe,UAAU;AACzE,gBAAU,oBAAmB,UAAK,6BAAL,mBAA+B,OAAO;AAAA,IACrE;AACA,SAAK,MAAM,uBAAuB,UAAU;AAE5C,QAAI,SAAO,gBAAK,6BAAL,mBAA+B,WAA/B,mBAAuC,oBAAmB,UAAU;AAC7E,gBAAU,wBAAuB,UAAK,6BAAL,mBAA+B,OAAO;AACvE,WAAK,qBAAqB;AAAA,IAC5B;AAEA,QAAI,SAAO,gBAAK,6BAAL,mBAA+B,WAA/B,mBAAuC,gBAAe,UAAU;AACzE,gBAAU,oBAAmB,UAAK,6BAAL,mBAA+B,OAAO;AACnE,WAAK,qBAAqB;AAAA,IAC5B;AAAA,EACF;AAAA,EAEQ,2BAA2B;AAllBrC;AAmlBI,QAAI,SAAO,gBAAK,6BAAL,mBAA+B,iBAA/B,mBAA6C,eAAc,UAAU;AAC9E,gBAAU,aAAa,wBACrB,KAAK,yBAAyB,aAAa;AAAA,IAC/C;AACA,SAAK,gBAAgB;AAAA,EACvB;AAAA,EAEQ,YAAY,QAAiB;AACnC,SAAK,MAAM,cAAc;AACzB,SAAK,MAAM,uBAAuB,UAAU;AAC5C,SAAK,MAAM,sBAAsB,IAAIE;AAAA,MACnC,UAAU,SAAS,UAAU,gBAAgB;AAAA,MAC7C,UAAU,SAAS,UAAU,oBAAoB;AAAA,MACjD;AAAA,IACF;AACA,SAAK,MAAM,aAAa;AACxB,SAAK,MAAM,sBAAsB,UAAU;AAC3C,SAAK,MAAM,uBAAuB,UAAU;AAC5C,SAAK,MAAM,qBAAqB,IAAIA;AAAA,MAClC,UAAU,SAAS,UAAU,gBAAgB;AAAA,MAC7C,UAAU,SAAS,UAAU,oBAAoB;AAAA,MACjD;AAAA,IACF;AAAA,EACF;AACF;;;AY3mBA,SAAS,aAAa;AAIf,IAAM,cAAN,MAAkB;AAAA,EAAlB;AACL,SAAQ,QAAe,IAAI,MAAM;AACjC,SAAQ,iBAAyB;AACjC,SAAQ,mBAA2B;AACnC,SAAQ,aAAuB,CAAC;AAEhC,SAAQ,yBAAiC;AACzC,SAAQ,wBAAgC;AACxC,SAAQ,gBAAwB;AAChC,SAAQ,2BAAmC;AAE3C,SAAO,OAAe;AACtB,SAAO,YAAoB;AAC3B,SAAO,eAAuB;AAC9B,SAAO,kBAA0B;AACjC,SAAO,QAAgB;AACvB,SAAO,MAAc;AACrB,SAAO,aAAqB;AAAA;AAAA,EAE5B,SAAS;AACP,SAAK,eAAe,KAAK,MAAM,SAAS;AACxC,SAAK;AACL,SAAK,QAAQ,KAAK;AAClB,SAAK,WAAW,KAAK,KAAK,YAAY;AAEtC,QAAI,KAAK,WAAW,SAAS,KAAK,iBAAkB,MAAK,WAAW,MAAM;AAE1E,SAAK,yBACH,KAAK,WAAW,OAAO,CAAC,MAAM,SAAS,OAAO,MAAM,CAAC,IAAI,KAAK,WAAW;AAE3E,SAAK,yBAAyB;AAAA,MAC5B,KAAK,yBAAyB,KAAK;AAAA,MACnC,KAAK;AAAA,MACL;AAAA,IACF;AAEA,UAAM,kBAAkB,KAAK,wBAAwB,KAAK;AAC1D,UAAM,WAAW,KAAK,MAAM,kBAAkB,KAAK,cAAc,IAAI,KAAK;AAE1E,SAAK,kBAAkB,WAAW,KAAK,eAAe,OAAO,KAAK,eAAe;AACjF,SAAK,YAAY,KAAK;AAEtB,SAAK;AACL,QAAI,KAAK,4BAA4B,IAAI;AACvC,WAAK,MACH,KAAK,MAAO,KAAK,4BAA4B,KAAK,OAAO,KAAK,iBAAkB,GAAG,IAAI;AAEzF,WAAK,gBAAgB,KAAK;AAC1B,WAAK,2BAA2B;AAAA,IAClC;AAAA,EACF;AACF;;;ACvDA,SAAmB,2BAA2B;AAC9C;AAAA,EACE,QAAAE;AAAA,EAEA,SAAAC;AAAA,EACA;AAAA,EACA,SAAAC;AAAA,EACA,SAAAC;AAAA,EAEA,SAAAC;AAAA,EAEA,WAAAC;AAAA,EACA,QAAAC;AAAA,EACA;AAAA,EAEA,cAAAC;AAAA,EACA,OAAAC;AAAA,EAEA,WAAAC;AAAA,OACK;AACP,SAAS,2BAA2B;AACpC,YAAY,yBAAyB;AACrC,SAAS,SAAS,qBAAqB;;;ACrBvC,SAAS,SAAAC,QAAO,WAAAC,UAAmB,cAAAC,aAAY,WAAAC,iBAAe;AAE9D,IAAM,sBAAsB,IAAIF,SAAQ;AACxC,IAAM,mBAAmB,IAAIA,SAAQ;AACrC,IAAM,qBAAqB,IAAIE,UAAQ;AACvC,IAAM,oBAAoB,IAAIH,OAAM;AACpC,IAAM,yBAAyB,IAAIE,YAAW;AAC9C,IAAM,kBAAkB,IAAIC,UAAQ;AAE7B,SAAS,+CACd,qBACA,WACqB;AACrB,QAAM,EAAE,GAAG,GAAG,EAAE,IAAI,oBAAoB;AACxC,QAAM,EAAE,GAAG,IAAI,GAAG,IAAI,GAAG,GAAG,IAAI,oBAAoB;AAEpD,YAAU,kBAAkB,MAAM,KAAK;AACvC,sBAAoB,KAAK,UAAU,WAAW,EAAE,OAAO;AAEvD,qBAAmB,IAAI,GAAG,GAAG,CAAC;AAC9B,oBAAkB,IAAI,IAAI,IAAI,EAAE;AAChC,yBAAuB,aAAa,iBAAiB;AACrD,kBAAgB,IAAI,GAAG,GAAG,CAAC;AAE3B,mBAAiB,QAAQ,oBAAoB,wBAAwB,eAAe;AACpF,mBAAiB,YAAY,mBAAmB;AAChD,mBAAiB,UAAU,oBAAoB,wBAAwB,eAAe;AAEtF,oBAAkB,kBAAkB,sBAAsB;AAG1D,qBAAmB,SAAS,UAAU,KAAK;AAE3C,SAAO;AAAA,IACL,UAAU;AAAA,MACR,GAAG,mBAAmB;AAAA,MACtB,GAAG,mBAAmB;AAAA,MACtB,GAAG,mBAAmB;AAAA,IACxB;AAAA,IACA,UAAU;AAAA,MACR,GAAG,kBAAkB;AAAA,MACrB,GAAG,kBAAkB;AAAA,MACrB,GAAG,kBAAkB;AAAA,IACvB;AAAA,EACF;AACF;;;ADZO,IAAM,oBAAN,MAAwB;AAAA,EAsB7B,YAAY,OAAc;AArB1B,SAAQ,QAAiB;AAEzB,SAAQ,aAAsB,IAAIC,UAAQ;AAC1C,SAAQ,cAAuB,IAAIA,UAAQ;AAC3C,SAAQ,cAAuB,IAAIA,UAAQ;AAC3C,SAAQ,iBAA6B,IAAIC,YAAW;AACpD,SAAQ,UAAe,IAAIC,KAAI;AAC/B,SAAQ,aAAa,IAAIC,SAAQ;AACjC,SAAQ,cAAc,IAAIA,SAAQ;AAClC,SAAQ,UAAU,IAAIC,MAAK;AAC3B,SAAQ,YAAY,IAAIC,OAAM;AAC9B,SAAQ,cAAc,IAAIC,OAAM;AAChC,SAAQ,eAAe,IAAIA,OAAM;AAEjC,SAAO,qBAAqD,oBAAI,IAAI;AAQlE,SAAK,QAAQ;AACb,SAAK,mBAAmB,oBAAoB,KAAK;AAAA,EACnD;AAAA,EAEO,aAAa,KAAwD;AAC1E,QAAI,kBAAiC;AACrC,QAAI,aAAwC;AAC5C,QAAI,gBAAgC,IAAIN,UAAQ;AAChD,eAAW,CAAC,EAAE,kBAAkB,KAAK,KAAK,oBAAoB;AAC5D,WAAK,QAAQ,KAAK,GAAG,EAAE,aAAa,KAAK,WAAW,KAAK,mBAAmB,MAAM,EAAE,OAAO,CAAC;AAC5F,YAAM,MAAM,mBAAmB,QAAQ,aAAa,KAAK,SAAS,UAAU;AAC5E,UAAI,KAAK;AACP,aAAK,YAAY,MAAM,KAAK,KAAK,QAAQ,MAAM;AAC/C,aAAK,YAAY,IAAI,KAAK,IAAI,KAAK;AACnC,aAAK,YAAY,aAAa,mBAAmB,MAAM;AACvD,cAAM,OAAO,KAAK,YAAY,SAAS;AACvC,YAAI,oBAAoB,QAAQ,OAAO,iBAAiB;AACtD,4BAAkB;AAClB,uBAAa;AACb,2BAAiB,IAAI,SAAS,cAAc,KAAK,IAAI,MAAM,IAAI,eAE5D,gBAAgB,KAAK,eAAe,sBAAsB,mBAAmB,MAAM,CAAC,EACpF,UAAU;AAAA,QACf;AAAA,MACF;AAAA,IACF;AACA,QAAI,oBAAoB,QAAQ,kBAAkB,QAAQ,eAAe,MAAM;AAC7E,aAAO;AAAA,IACT;AACA,WAAO,CAAC,iBAAiB,eAAe,UAAU;AAAA,EACpD;AAAA,EAEQ,yBAAyB,OAAc,iBAA8C;AAC3F,UAAM,aAAoC,CAAC;AAC3C,UAAM,kBAAkB,MAAM,KAAK;AACnC,UAAM,qBAAqB,KAAK,WAAW,KAAK,MAAM,WAAW,EAAE,OAAO;AAC1E,UAAM,SAAS,CAAC,UAAoB;AAClC,YAAM,SAAS;AACf,UAAI,OAAO,QAAQ;AACjB,cAAM,kBAAkB;AACxB,YAAI,gBAAgB,iBAAiB;AACnC,mBAAS,IAAI,GAAG,IAAI,gBAAgB,OAAO,KAAK;AAC9C,kBAAM,iBAAiB,gBAAgB,SAAS,MAAM;AACtD,uBAAW,OAAO,eAAe,YAAY;AAC3C,kBAAI,QAAQ,YAAY;AACtB,+BAAe,gBAAgB,GAAG;AAAA,cACpC;AAAA,YACF;AACA,2BAAe;AAAA,cACb,KAAK,YAAY,UAAU,gBAAgB,eAAe,OAAO,IAAI,EAAE;AAAA,YACzE;AACA,gBAAI,eAAe,OAAO;AACxB,yBAAW,KAAK,eAAe,aAAa,CAAC;AAAA,YAC/C,OAAO;AACL,yBAAW,KAAK,cAAc;AAAA,YAChC;AAAA,UACF;AAAA,QACF,OAAO;AACL,gBAAM,iBAAiB,OAAO,SAAS,MAAM;AAC7C,iBAAO,kBAAkB,MAAM,KAAK;AACpC,qBAAW,OAAO,eAAe,YAAY;AAC3C,gBAAI,QAAQ,YAAY;AACtB,6BAAe,gBAAgB,GAAG;AAAA,YACpC;AAAA,UACF;AACA,yBAAe;AAAA,YACb,KAAK,YAAY,iBAAiB,oBAAoB,OAAO,WAAW;AAAA,UAC1E;AACA,cAAI,eAAe,OAAO;AACxB,uBAAW,KAAK,eAAe,aAAa,CAAC;AAAA,UAC/C,OAAO;AACL,uBAAW,KAAK,cAAc;AAAA,UAChC;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAED,UAAM,oBAAwC,oCAAgB,YAAY,KAAK;AAC/E,sBAAkB,qBAAqB;AACvC,UAAM,UAAU,IAAI,QAAQ,iBAAiB;AAE7C,UAAM,YAAgC;AAAA,MACpC,QAAQ;AAAA,MACR;AAAA,MACA,QAAQ,MAAM,YAAY,MAAM;AAAA,MAChC;AAAA,IACF;AACA,QAAI,KAAK,OAAO;AAEd,MAAC,kBAA0B,aAAa;AAExC,YAAM,gBAAgB,IAAIO,MAAK,mBAAmB,IAAI,kBAAkB,EAAE,WAAW,KAAK,CAAC,CAAC;AAE5F,YAAM,gBAAgB,IAAI,oBAAoB,eAAe,MAAM,KAAQ;AAE3E,YAAM,aAAa,IAAI,cAAc,eAAe,CAAC;AACrD,MAAC,WAAW,aAAmC,QAAQ,IAAIC,OAAM,MAAM;AAEvE,YAAM,aAAa,IAAIC,OAAM;AAC7B,iBAAW,IAAI,eAAe,eAAe,UAAiC;AAE9E,YAAM,YAAY,UAAU,WAAW,UAAU,WAAW,YAAY,WAAW,KAAK;AACxF,iBAAW,OAAO;AAElB,gBAAU,aAAa;AAAA,IACzB;AACA,WAAO;AAAA,EACT;AAAA,EAEO,eAAe,OAAc,UAA2B;AAC7D,QAAI,UAAU;AACZ,WAAK,iBAAiB,YAAY,OAAO,QAAQ;AAAA,IACnD;AACA,UAAM,YAAY,KAAK,yBAAyB,OAAO,aAAa,MAAS;AAC7E,QAAI,UAAU,YAAY;AACxB,WAAK,MAAM,IAAI,UAAU,UAAU;AAAA,IACrC;AACA,SAAK,mBAAmB,IAAI,OAAO,SAAS;AAAA,EAC9C;AAAA,EAEO,kBAAkB,OAAoB;AAC3C,UAAM,YAAY,KAAK,mBAAmB,IAAI,KAAK;AACnD,QAAI,WAAW;AACb,YAAM,kBAAkB,MAAM,KAAK;AACnC,gBAAU,OAAO,KAAK,MAAM,WAAW;AACvC,UAAI,UAAU,YAAY;AACxB,cAAM,YAAY;AAAA,UAChB,UAAU,WAAW;AAAA,UACrB,UAAU,WAAW;AAAA,UACrB,UAAU,WAAW;AAAA,QACvB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EAEO,kBAAkB,OAAoB;AAC3C,SAAK,iBAAiB,eAAe,KAAK;AAC1C,UAAM,YAAY,KAAK,mBAAmB,IAAI,KAAK;AACnD,QAAI,WAAW;AACb,UAAI,UAAU,YAAY;AACxB,aAAK,MAAM,OAAO,UAAU,UAAU;AAAA,MACxC;AACA,WAAK,mBAAmB,OAAO,KAAK;AAAA,IACtC;AAAA,EACF;AAAA,EAEQ,cACN,0BACA,eACA,WACgB;AAEhB,UAAM,aAAa,KAAK,WAAW,KAAK,UAAU,MAAM,EAAE,OAAO;AAGjE,UAAM,iCAAiC,KAAK;AAC5C,mCAA+B,UAAU;AACzC,mCAA+B,cAAc,yBAAyB,KAAK;AAC3E,mCAA+B,cAAc,yBAAyB,GAAG;AACzE,mCAA+B,IAAI,UAAU,aAAa;AAC1D,mCAA+B,IAAI,UAAU,aAAa;AAC1D,mCAA+B,aAAa,UAAU;AAEtD,UAAM,6BAA6B,KAAK;AACxC,+BAA2B,MAAM,KAAK,yBAAyB,KAAK;AACpE,+BAA2B,IAAI,KAAK,yBAAyB,GAAG;AAChE,+BAA2B,aAAa,UAAU;AAGlD,UAAM,yCAAyC,KAAK,YAAY;AAAA,MAC9D,2BAA2B;AAAA,IAC7B;AAEA,QAAI,oBAAoC;AACxC,QAAI,2BAAmC;AACvC,cAAU,QAAQ,UAAU;AAAA,MAC1B,kBAAkB,CAAC,YAAY;AAG7B,eAAO,QAAQ,cAAc,8BAA8B;AAAA,MAC7D;AAAA,MACA,oBAAoB,CAAC,iBAAiB;AACpC,cAAM,yBAAyB,KAAK;AACpC,cAAM,wBAAwB,KAAK;AAEnC,qBAAa;AAAA,UACX;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAEA,cAAM,sBAAsB,KAAK;AACjC,4BAAoB,MAAM,KAAK,sBAAsB;AACrD,4BAAoB,IAAI,KAAK,qBAAqB;AAElD,cAAM,yBAAyB,oBAAoB,SAAS;AAG5D,4BAAoB,aAAa,UAAU,MAAM;AACjD,cAAM,eAAe,oBAAoB,SAAS;AAIlD,YAAI,eAAe,eAAe;AAChC,cAAI,CAAC,mBAAmB;AACtB,gCAAoB,IAAIT,UAAQ,EAC7B,KAAK,sBAAsB,EAC3B,aAAa,UAAU,MAAM;AAChC,uCAA2B;AAAA,UAC7B,WAAW,eAAe,0BAA0B;AAClD,8BAAkB,KAAK,sBAAsB,EAAE,aAAa,UAAU,MAAM;AAC5E,uCAA2B;AAAA,UAC7B;AAEA,gBAAM,QAAQ,eAAe;AAE7B,gBAAM,YAAY,gBAAgB;AAElC,gBAAM,aAAa,YAAY;AAG/B,gBAAM,YAAY,sBAAsB,IAAI,sBAAsB,EAAE,UAAU;AAC9E,qCAA2B,MAAM,gBAAgB,WAAW,UAAU;AACtE,qCAA2B,IAAI,gBAAgB,WAAW,UAAU;AAAA,QACtE;AAAA,MACF;AAAA,IACF,CAAC;AAED,QAAI,mBAAmB;AAErB,YAAM,QAAQ,KAAK,WAChB,KAAK,2BAA2B,KAAK,EACrC,IAAI,sCAAsC;AAG7C,WAAK,WAAW,KAAK,UAAU,MAAM,EAAE,YAAY,GAAG,GAAG,CAAC;AAC1D,YAAM,aAAa,KAAK,UAAU;AAGlC,UAAI,EAAE,MAAM,MAAM,CAAC,KAAK,MAAM,MAAM,CAAC,KAAK,MAAM,MAAM,CAAC,IAAI;AAEzD,iCAAyB,MAAM,IAAI,KAAK;AACxC,iCAAyB,IAAI,IAAI,KAAK;AAAA,MACxC;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA,EAEO,eAAe,aAAoB,QAAgB;AACxD,UAAM,mBAAmB,oBAAI,IAK3B;AACF,eAAW,aAAa,KAAK,mBAAmB,OAAO,GAAG;AACxD,YAAM,oBAAoB,KAAK,cAAc,aAAa,QAAQ,SAAS;AAC3E,UAAI,qBAAqB,UAAU,iBAAiB;AAClD,cAAM,mBAAmB;AAAA,UACvB;AAAA,YACE,UAAU;AAAA,YACV,UAAU,KAAK,UAAU,IAAI,GAAG,GAAG,CAAC;AAAA,UACtC;AAAA,UACA,UAAU;AAAA,QACZ;AACA,yBAAiB,IAAI,UAAU,QAAQ;AAAA,UACrC,UAAU,iBAAiB;AAAA,QAC7B,CAAC;AAAA,MACH;AAAA,IACF;AAWA,UAAM,4BAA4B,IAAI,IAAI,gBAAgB;AAC1D,QAAI,KAAK,6BAA6B;AACpC,iBAAW,CAAC,SAAS,QAAQ,KAAK,KAAK,6BAA6B;AAClE,YAAI,CAAC,0BAA0B,IAAI,OAAO,GAAG;AAC3C,oCAA0B,IAAI,SAAS,QAAQ;AAAA,QACjD;AAAA,MACF;AAAA,IACF;AAGA,SAAK,8BAA8B;AACnC,SAAK,iBAAiB,qBAAqB,yBAAyB;AAAA,EACtE;AACF;;;AE/VA;AAAA,EACE;AAAA,EACA,aAAAU;AAAA,EACA,SAAAC;AAAA,EACA;AAAA,EACA,QAAAC;AAAA,EACA,wBAAAC;AAAA,EACA,iBAAAC;AAAA,EACA;AAAA,EACA,kBAAAC;AAAA,OAEK;AAGP,IAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,OAAO,QAAQ;AACf,OAAO,SAAS;AAChB,IAAM,MAAM,OAAO,WAAW,IAAI;AAClC,IAAI,YAAY;AAChB,IAAI,SAAS,GAAG,GAAG,GAAG,CAAC;AACvB,IAAI,YAAY;AAChB,IAAI,SAAS,GAAG,GAAG,GAAG,CAAC;AACvB,IAAI,SAAS,GAAG,GAAG,GAAG,CAAC;AAEhB,IAAM,cAAN,cAA0BJ,OAAM;AAAA,EAOrC,cAAc;AACZ,UAAM;AAPR,SAAiB,YAAY;AAC7B,SAAiB,eAA+B;AAChD,SAAiB,gBAAgB,IAAI,cAAc,KAAK,WAAW,KAAK,WAAW,GAAG,CAAC;AAEvF,SAAiB,YAAyB;AAKxC,SAAK,gBAAgB,IAAIE,sBAAqB;AAAA,MAC5C,OAAO;AAAA,MACP,MAAMH;AAAA,MACN,WAAW;AAAA,MACX,WAAW;AAAA,IACb,CAAC;AACD,SAAK,YAAY,IAAIE,MAAK,KAAK,eAAe,KAAK,aAAa;AAChE,SAAK,UAAU,gBAAgB;AAC/B,SAAK,UAAU,SAAS,IAAI,KAAK,KAAK;AACtC,SAAK,IAAI,KAAK,SAAS;AAEvB,SAAK,eAAe,IAAI,cAAc,MAAM;AAC5C,SAAK,aAAc,QAAQG;AAC3B,SAAK,aAAc,QAAQA;AAC3B,SAAK,aAAc,YAAYD;AAC/B,SAAK,aAAc,YAAY;AAC/B,SAAK,aAAc,OAAO,IAAI,KAAK,YAAY,KAAK,KAAK,YAAY,GAAG;AACxE,SAAK,cAAc,MAAM,KAAK;AAC9B,SAAK,cAAc,cAAc;AAAA,EACnC;AACF;;;ACtDA,SAAS,0BAAAE,+BAA8B;AAgBhC,IAAM,gBAAN,MAAoB;AAAA,EA2BzB,YACU,wBACA,QACR;AAFQ;AACA;AAxBV,SAAQ,gBAAkC,CAAC;AAkB3C,SAAQ,eAAe;AAEvB,SAAQ,WAAoB;AAzC9B;AA+CI,UAAM,oBAAoB;AAC1B,SAAK,UAAU,SAAS,cAAc,KAAK;AAC3C,SAAK,QAAQ,KAAK;AAElB,SAAK,QAAQ,MAAM,WAAW;AAC9B,SAAK,QAAQ,MAAM,MAAM;AACzB,SAAK,QAAQ,MAAM,OAAO;AAC1B,SAAK,QAAQ,MAAM,QAAQ;AAC3B,SAAK,QAAQ,MAAM,SAAS;AAC5B,SAAK,QAAQ,MAAM,oBAAkB,UAAK,WAAL,mBAAa,eAAc;AAChE,SAAK,QAAQ,MAAM,eAAa,UAAK,WAAL,mBAAa,eAAc;AAC3D,SAAK,QAAQ,MAAM,SAAS;AAE5B,SAAK,iBAAiB,SAAS,cAAc,KAAK;AAClD,SAAK,eAAe,KAAK;AACzB,SAAK,eAAe,MAAM,WAAW;AACrC,SAAK,eAAe,MAAM,MAAM;AAChC,SAAK,eAAe,MAAM,OAAO;AACjC,SAAK,eAAe,MAAM,QAAQ;AAClC,SAAK,eAAe,MAAM,SAAS;AACnC,SAAK,eAAe,MAAM,UAAU;AACpC,SAAI,UAAK,WAAL,mBAAa,sBAAsB;AACrC,WAAK,eAAe,MAAM,iBAAiB,QAAQ,KAAK,OAAO,oBAAoB;AAAA,IACrF;AACA,SAAK,QAAQ,OAAO,KAAK,cAAc;AAEvC,SAAI,UAAK,WAAL,mBAAa,oBAAoB;AACnC,WAAK,QAAQ,MAAM,kBAAkB,OAAO,KAAK,OAAO,kBAAkB;AAC1E,WAAK,QAAQ,MAAM,qBAAqB;AACxC,WAAK,QAAQ,MAAM,iBAAiB;AAAA,IACtC;AAEA,SAAI,UAAK,WAAL,mBAAa,eAAe;AAC9B,YAAM,eAAe,CAAC,aAAqB;AACzC,gBAAQ,MAAM,iCAAiC,QAAQ,EAAE;AAAA,MAC3D;AAEA,iBAAW,SAAS,KAAK,OAAO,eAAe;AAC7C,cAAM,eAAe,SAAS,cAAc,KAAK;AACjD,qBAAa,MAAM,WAAW;AAC9B,qBAAa,MAAM,aAAa,OAAO,MAAM,eAAe;AAC5D,qBAAa,MAAM,iBAAiB;AAEpC,cAAM,SAAS,MAAM;AACrB,cAAM,YAAU,WAAM,kBAAN,mBAAqB,MAAK;AAC1C,cAAM,YAAU,WAAM,kBAAN,mBAAqB,MAAK;AAE1C,YAAI,OAAO,SAAS,KAAK,GAAG;AAC1B,uBAAa,MAAM,MAAM,GAAG,OAAO;AAAA,QACrC,WAAW,OAAO,SAAS,QAAQ,GAAG;AACpC,uBAAa,MAAM,SAAS,GAAG,OAAO;AAAA,QACxC;AAEA,YAAI,OAAO,SAAS,MAAM,GAAG;AAC3B,uBAAa,MAAM,OAAO,GAAG,OAAO;AAAA,QACtC,WAAW,OAAO,SAAS,OAAO,GAAG;AACnC,uBAAa,MAAM,QAAQ,GAAG,OAAO;AAAA,QACvC;AAEA,cAAM,QAAQ,IAAI,MAAM;AACxB,cAAM,MAAM,MAAM;AAClB,cAAM,SAAS,MAAM;AACnB,gBAAM,eAAe,MAAM;AAC3B,gBAAM,gBAAgB,MAAM;AAE5B,uBAAa,MAAM,QAAQ,GAAG,YAAY;AAC1C,uBAAa,MAAM,SAAS,GAAG,aAAa;AAAA,QAC9C;AAEA,cAAM,UAAU,MAAM,aAAa,MAAM,eAAe;AAExD,aAAK,cAAc,KAAK,YAAY;AACpC,aAAK,eAAe,OAAO,YAAY;AAAA,MACzC;AAAA,IACF;AAEA,SAAK,QAAQ,MAAM,UAAQ,UAAK,WAAL,mBAAa,UAAS;AAEjD,SAAK,gBAAgB,SAAS,cAAc,KAAK;AACjD,SAAK,cAAc,MAAM,WAAW;AACpC,SAAK,cAAc,MAAM,UAAU;AACnC,SAAK,cAAc,MAAM,gBAAgB;AACzC,SAAK,cAAc,MAAM,OAAO;AAChC,SAAK,cAAc,MAAM,SAAS;AAClC,SAAK,cAAc,MAAM,UAAU;AACnC,SAAK,cAAc,MAAM,QAAQ;AACjC,SAAK,cAAc,MAAM,iBAAiB;AAC1C,SAAK,eAAe,OAAO,KAAK,aAAa;AAE7C,SAAI,UAAK,WAAL,mBAAa,OAAO;AACtB,WAAK,qBAAqB,SAAS,cAAc,KAAK;AACtD,WAAK,mBAAmB,cAAc,KAAK,OAAO;AAClD,WAAK,mBAAmB,MAAM,UAAQ,UAAK,WAAL,mBAAa,UAAS;AAC5D,WAAK,mBAAmB,MAAM,cAAc;AAC5C,WAAK,mBAAmB,MAAM,eAAe;AAC7C,WAAK,mBAAmB,MAAM,WAAW;AACzC,WAAK,mBAAmB,MAAM,aAAa;AAC3C,WAAK,mBAAmB,MAAM,aAAa;AAC3C,WAAI,UAAK,WAAL,mBAAa,YAAY;AAC3B,aAAK,mBAAmB,MAAM,aAAa,gBAAgB,KAAK,OAAO,UAAU;AAAA,MACnF;AACA,WAAK,cAAc,OAAO,KAAK,kBAAkB;AAAA,IACnD;AAEA,SAAI,UAAK,WAAL,mBAAa,UAAU;AACzB,WAAK,wBAAwB,SAAS,cAAc,KAAK;AACzD,WAAK,sBAAsB,MAAM,UAAQ,UAAK,WAAL,mBAAa,UAAS;AAC/D,WAAK,sBAAsB,MAAM,cAAc;AAC/C,WAAK,sBAAsB,MAAM,eAAe;AAChD,WAAK,sBAAsB,MAAM,WAAW;AAC5C,WAAK,sBAAsB,MAAM,aAAa;AAC9C,WAAK,sBAAsB,MAAM,aAAa;AAC9C,WAAK,sBAAsB,MAAM,YAAY;AAC7C,WAAI,UAAK,WAAL,mBAAa,YAAY;AAC3B,aAAK,sBAAsB,MAAM,aAAa,gBAAgB,KAAK,OAAO,UAAU;AAAA,MACtF;AAEA,WAAK,sBAAsB,cAAc,KAAK,OAAO;AACrD,WAAK,cAAc,OAAO,KAAK,qBAAqB;AAAA,IACtD;AAEA,SAAK,0BAA0B,SAAS,cAAc,KAAK;AAC3D,SAAK,wBAAwB,MAAM,UAAU;AAC7C,SAAK,wBAAwB,MAAM,WAAW;AAC9C,SAAK,wBAAwB,MAAM,QAAQ;AAC3C,SAAK,wBAAwB,MAAM,YAAY;AAC/C,SAAK,wBAAwB,MAAM,OAAO;AAC1C,SAAK,wBAAwB,MAAM,SAAS;AAC5C,SAAK,wBAAwB,MAAM,aAAa;AAChD,SAAK,wBAAwB,MAAM,iBAAiB;AACpD,SAAK,wBAAwB,MAAM,SAAS;AAC5C,SAAK,QAAQ,OAAO,KAAK,uBAAuB;AAEhD,SAAK,oBAAoB,SAAS,cAAc,KAAK;AACrD,SAAK,kBAAkB,MAAM,kBAAkB;AAC/C,SAAK,kBAAkB,MAAM,SAAS;AACtC,SAAK,kBAAkB,MAAM,eAAe;AAC5C,SAAK,kBAAkB,MAAM,QAAQ;AACrC,SAAK,kBAAkB,MAAM,WAAW;AACxC,SAAK,kBAAkB,MAAM,WAAW;AACxC,SAAK,wBAAwB,OAAO,KAAK,iBAAiB;AAE1D,SAAK,gBAAgB,SAAS,cAAc,OAAO;AACnD,SAAK,cAAc,OAAO;AAC1B,SAAK,cAAc,UAAU;AAC7B,SAAK,cAAc,iBAAiB,UAAU,MAAM;AAClD,WAAK,qBAAqB,MAAM,UAAU,KAAK,cAAc,UAAU,UAAU;AACjF,WAAK,mBAAmB,MAAM,UAAU,KAAK,cAAc,UAAU,SAAS;AAC9E,WAAK,sBAAsB,MAAM,UAAU,KAAK,cAAc,UAAU,SAAS;AACjF,UAAI,KAAK,cAAc;AACrB,aAAK,QAAQ;AAAA,MACf;AAAA,IACF,CAAC;AAED,SAAK,aAAa,SAAS,cAAc,OAAO;AAChD,SAAK,WAAW,cAAc;AAC9B,SAAK,WAAW,MAAM,aAAa;AACnC,SAAK,WAAW,MAAM,UAAU;AAChC,SAAK,WAAW,MAAM,UAAU;AAChC,SAAK,WAAW,MAAM,aAAa;AACnC,SAAK,WAAW,OAAO,KAAK,aAAa;AACzC,SAAK,kBAAkB,OAAO,KAAK,UAAU;AAE7C,SAAK,uBAAuB,SAAS,cAAc,KAAK;AACxD,SAAK,qBAAqB,MAAM,SAAS;AACzC,SAAK,qBAAqB,MAAM,UAAU,KAAK,cAAc,UAAU,UAAU;AACjF,SAAK,kBAAkB,OAAO,KAAK,oBAAoB;AAEvD,SAAK,oBAAoB,SAAS,cAAc,KAAK;AACrD,SAAK,kBAAkB,MAAM,UAAU;AACvC,SAAK,kBAAkB,MAAM,aAAa;AAC1C,SAAK,kBAAkB,MAAM,iBAAiB;AAC9C,SAAK,kBAAkB,MAAM,QAAQ;AACrC,SAAK,kBAAkB,MAAM,aAAa;AAC1C,SAAK,kBAAkB,MAAM,eAAe;AAC5C,SAAK,kBAAkB,MAAM,SAAS;AACtC,SAAK,kBAAkB,MAAM,YAAY;AACzC,SAAK,cAAc,OAAO,KAAK,iBAAiB;AAEhD,SAAK,wBAAwB,SAAS,cAAc,KAAK;AACzD,SAAK,sBAAsB,MAAM,WAAW;AAC5C,SAAK,sBAAsB,MAAM,QAAQ;AACzC,SAAK,sBAAsB,MAAM,WAAW;AAC5C,SAAK,sBAAsB,MAAM,WAAW;AAC5C,SAAK,sBAAsB,MAAM,kBAAkB;AACnD,SAAK,sBAAsB,MAAM,iBAAiB;AAClD,SAAK,sBAAsB,MAAM,SAAS;AAC1C,SAAK,sBAAsB,MAAM,aAAa;AAC9C,SAAK,sBAAsB,MAAM,eAAe;AAChD,SAAK,sBAAsB,MAAM,WAAW;AAC5C,SAAK,sBAAsB,iBAAiB,SAAS,MAAM;AACzD,YAAM,UAAU,KAAK,wBAAwB,MAAM;AACnD,UAAI,YAAY,QAAQ;AACtB,aAAK,wBAAwB,MAAM,UAAU;AAAA,MAC/C,OAAO;AACL,aAAK,wBAAwB,MAAM,UAAU;AAC7C,aAAK,cAAc,UAAU;AAC7B,aAAK,qBAAqB,MAAM,UAAU,KAAK,cAAc,UAAU,UAAU;AACjF,aAAK,mBAAmB,MAAM,UAAU,KAAK,cAAc,UAAU,SAAS;AAAA,MAChF;AAAA,IACF,CAAC;AACD,SAAK,kBAAkB,OAAO,KAAK,qBAAqB;AAExD,SAAK,cAAc,SAAS,cAAc,KAAK;AAC/C,SAAK,YAAY,MAAM,WAAW;AAClC,SAAK,YAAY,MAAM,MAAM;AAC7B,SAAK,YAAY,MAAM,OAAO;AAC9B,SAAK,YAAY,MAAM,QAAQ;AAC/B,SAAK,YAAY,MAAM,SAAS;AAChC,SAAK,YAAY,MAAM,gBAAgB;AACvC,SAAK,YAAY,MAAM,oBAAkB,UAAK,WAAL,mBAAa,UAAS;AAC/D,SAAK,sBAAsB,OAAO,KAAK,WAAW;AAElD,SAAK,oBAAoB,SAAS,cAAc,KAAK;AACrD,SAAK,kBAAkB,MAAM,WAAW;AACxC,SAAK,kBAAkB,MAAM,MAAM;AACnC,SAAK,kBAAkB,MAAM,OAAO;AACpC,SAAK,kBAAkB,MAAM,QAAQ;AACrC,SAAK,kBAAkB,MAAM,SAAS;AACtC,SAAK,kBAAkB,MAAM,QAAQ;AACrC,SAAK,kBAAkB,MAAM,WAAW;AACxC,SAAK,kBAAkB,MAAM,YAAY;AACzC,SAAK,kBAAkB,MAAM,gBAAgB;AAC7C,SAAK,kBAAkB,MAAM,eAAe;AAC5C,SAAK,kBAAkB,MAAM,aAAa;AAC1C,SAAK,kBAAkB,MAAM,aAAa;AAC1C,SAAK,kBAAkB,MAAM,aAAa;AAC1C,SAAK,kBAAkB,cAAc;AACrC,SAAK,sBAAsB,OAAO,KAAK,iBAAiB;AAExD,SAAK,kBAAkB,MAAM;AAC3B,YAAM,CAAC,cAAc,gBAAgB,IAAI,KAAK,uBAAuB,QAAQ;AAC7E,UAAI,kBAAkB;AACpB,YAAI,CAAC,KAAK,cAAc;AACtB,eAAK,eAAe;AACpB,cAAI,CAAC,KAAK,cAAc,SAAS;AAC/B,iBAAK,QAAQ;AAAA,UACf;AAAA,QACF;AACA,aAAK,kBAAkB,cAAc;AACrC,aAAK,YAAY,MAAM,QAAQ;AAAA,MACjC,OAAO;AACL,aAAK,kBAAkB,cAAc,IAAI,eAAe,KAAK,QAAQ,CAAC,CAAC;AACvE,aAAK,YAAY,MAAM,QAAQ,GAAG,eAAe,GAAG;AAAA,MACtD;AACA,WAAK,qBAAqB,cAAcA,wBAAuB;AAAA,QAC7D,KAAK,uBAAuB,UAAU;AAAA,MACxC;AAAA,IACF;AAEA,SAAK,uBAAuB,oBAAoB,KAAK,eAAe;AAAA,EACtE;AAAA,EAEO,UAAU;AACf,QAAI,KAAK,UAAU;AACjB;AAAA,IACF;AACA,SAAK,WAAW;AAChB,SAAK,uBAAuB,uBAAuB,KAAK,eAAe;AACvE,SAAK,QAAQ,OAAO;AAAA,EACtB;AACF;;;ACpTO,IAAM,cAAN,MAAkB;AAAA,EAMvB,YAAY,OAAe,SAAiB;AAC1C,SAAK,UAAU,SAAS,cAAc,KAAK;AAC3C,SAAK,QAAQ,MAAM,WAAW;AAC9B,SAAK,QAAQ,MAAM,MAAM;AACzB,SAAK,QAAQ,MAAM,OAAO;AAC1B,SAAK,QAAQ,MAAM,UAAU;AAC7B,SAAK,QAAQ,MAAM,aAAa;AAChC,SAAK,QAAQ,MAAM,iBAAiB;AACpC,SAAK,QAAQ,MAAM,gBAAgB;AACnC,SAAK,QAAQ,MAAM,QAAQ;AAC3B,SAAK,QAAQ,MAAM,SAAS;AAC5B,SAAK,QAAQ,MAAM,aAAa;AAChC,SAAK,QAAQ,MAAM,QAAQ;AAE3B,SAAK,kBAAkB,SAAS,cAAc,KAAK;AACnD,SAAK,gBAAgB,cAAc;AACnC,SAAK,gBAAgB,MAAM,WAAW;AACtC,SAAK,gBAAgB,MAAM,aAAa;AACxC,SAAK,gBAAgB,MAAM,aAAa;AACxC,SAAK,QAAQ,OAAO,KAAK,eAAe;AAExC,SAAK,cAAc,SAAS,cAAc,KAAK;AAC/C,SAAK,YAAY,MAAM,YAAY;AACnC,SAAK,YAAY,MAAM,aAAa;AACpC,SAAK,YAAY,MAAM,aAAa;AACpC,SAAK,YAAY,cAAc;AAC/B,SAAK,QAAQ,OAAO,KAAK,WAAW;AAAA,EACtC;AAAA,EAEO,UAAU;AACf,SAAK,QAAQ,OAAO;AAAA,EACtB;AACF;",
4
+ "sourcesContent": ["import { PerspectiveCamera, Raycaster, Vector3 } from \"three\";\nimport { OrbitControls } from \"three/examples/jsm/controls/OrbitControls.js\";\n\nimport { CollisionsManager } from \"../collisions/CollisionsManager\";\nimport { remap } from \"../helpers/math-helpers\";\nimport { EventHandlerCollection } from \"../input/EventHandlerCollection\";\nimport { camValues } from \"../tweakpane/blades/cameraFolder\";\nimport { TweakPane } from \"../tweakpane/TweakPane\";\nimport { getTweakpaneActive } from \"../tweakpane/tweakPaneActivity\";\n\nconst cameraPanSensitivity = 20;\nconst scrollZoomSensitivity = 0.1;\nconst pinchZoomSensitivity = 0.025;\n\nexport class CameraManager {\n public readonly camera: PerspectiveCamera;\n private flyCamera: PerspectiveCamera;\n private orbitControls: OrbitControls;\n private isMainCameraActive: boolean = true;\n\n public initialDistance: number = camValues.initialDistance;\n public minDistance: number = camValues.minDistance;\n public maxDistance: number = camValues.maxDistance;\n public damping: number = camValues.damping;\n public zoomScale: number = camValues.zoomScale;\n public zoomDamping: number = camValues.zoomDamping;\n\n public initialFOV: number = camValues.initialFOV;\n public maxFOV: number = camValues.maxFOV;\n public minFOV: number = camValues.minFOV;\n public invertFOVMapping: boolean = camValues.invertFOVMapping;\n public fov: number = this.initialFOV;\n private targetFOV: number = this.initialFOV;\n\n public minPolarAngle: number = Math.PI * 0.25;\n private maxPolarAngle: number = Math.PI * 0.95;\n\n public distance: number = this.initialDistance;\n public targetDistance: number = this.initialDistance;\n public desiredDistance: number = this.initialDistance;\n\n private phi: number;\n private targetPhi: number;\n private theta: number;\n private targetTheta: number;\n\n private target: Vector3 = new Vector3(0, 1.55, 0);\n private hadTarget: boolean = false;\n\n private rayCaster: Raycaster;\n\n private eventHandlerCollection: EventHandlerCollection;\n\n private finalTarget: Vector3 = new Vector3();\n private isLerping: boolean = false;\n private lerpTarget: Vector3 = new Vector3();\n private lerpFactor: number = 0;\n private lerpDuration: number = 2.1;\n\n private activePointers = new Map<number, { x: number; y: number }>();\n\n constructor(\n private targetElement: HTMLElement,\n private collisionsManager: CollisionsManager,\n initialPhi = Math.PI / 2,\n initialTheta = -Math.PI / 2,\n ) {\n this.targetElement.style.touchAction = \"pinch-zoom\";\n this.phi = initialPhi;\n this.targetPhi = this.phi;\n this.theta = initialTheta;\n this.targetTheta = this.theta;\n\n const aspect = window.innerWidth / window.innerHeight;\n\n this.camera = new PerspectiveCamera(this.fov, aspect, 0.1, 400);\n this.camera.position.set(0, 1.4, -this.initialDistance);\n this.camera.name = \"MainCamera\";\n this.flyCamera = new PerspectiveCamera(this.initialFOV, aspect, 0.1, 400);\n this.flyCamera.name = \"FlyCamera\";\n this.flyCamera.position.copy(this.camera.position);\n this.flyCamera.name = \"FlyCamera\";\n\n this.orbitControls = new OrbitControls(this.flyCamera, this.targetElement);\n this.orbitControls.enableDamping = true;\n this.orbitControls.dampingFactor = 0.05;\n this.orbitControls.enablePan = true;\n this.orbitControls.enabled = false;\n\n this.rayCaster = new Raycaster();\n\n this.createEventHandlers();\n }\n\n private createEventHandlers(): void {\n this.eventHandlerCollection = EventHandlerCollection.create([\n [this.targetElement, \"pointerdown\", this.onPointerDown.bind(this)],\n [this.targetElement, \"gesturestart\", this.preventDefaultAndStopPropagation.bind(this)],\n [this.targetElement, \"wheel\", this.onMouseWheel.bind(this)],\n [this.targetElement, \"contextmenu\", this.onContextMenu.bind(this)],\n [document, \"pointerup\", this.onPointerUp.bind(this)],\n [document, \"pointercancel\", this.onPointerUp.bind(this)],\n [document, \"pointermove\", this.onPointerMove.bind(this)],\n ]);\n }\n\n private disposeEventHandlers(): void {\n this.eventHandlerCollection.clear();\n }\n\n private preventDefaultAndStopPropagation(evt: PointerEvent): void {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n public setupTweakPane(tweakPane: TweakPane) {\n tweakPane.setupCamPane(this);\n }\n\n private onPointerDown(event: PointerEvent): void {\n if (event.button === 0 || event.button === 2) {\n // Left or right mouse button\n\n const pointerInfo = { x: event.clientX, y: event.clientY };\n this.activePointers.set(event.pointerId, pointerInfo);\n document.body.style.cursor = \"none\";\n }\n }\n\n private onPointerUp(event: PointerEvent): void {\n const existingPointer = this.activePointers.get(event.pointerId);\n if (existingPointer) {\n this.activePointers.delete(event.pointerId);\n if (this.activePointers.size === 0) {\n document.body.style.cursor = \"default\";\n }\n }\n }\n\n private getAveragePointerPositionAndSpread(): { pos: { x: number; y: number }; spread: number } {\n const existingSum = { x: 0, y: 0 };\n this.activePointers.forEach((p) => {\n existingSum.x += p.x;\n existingSum.y += p.y;\n });\n const aX = existingSum.x / this.activePointers.size;\n const aY = existingSum.y / this.activePointers.size;\n\n let sumOfDistances = 0;\n this.activePointers.forEach((p) => {\n const distance = Math.sqrt((p.x - aX) ** 2 + (p.y - aY) ** 2);\n sumOfDistances += distance;\n });\n return { pos: { x: aX, y: aY }, spread: sumOfDistances / this.activePointers.size };\n }\n\n private onPointerMove(event: PointerEvent): void {\n if (getTweakpaneActive()) {\n return;\n }\n\n const existingPointer = this.activePointers.get(event.pointerId);\n if (existingPointer) {\n const previous = this.getAveragePointerPositionAndSpread();\n\n // Replace the pointer info and recalculate to determine the delta\n existingPointer.x = event.clientX;\n existingPointer.y = event.clientY;\n\n const latest = this.getAveragePointerPositionAndSpread();\n\n const sX = latest.pos.x - previous.pos.x;\n const sY = latest.pos.y - previous.pos.y;\n\n const dx = (sX / this.targetElement.clientWidth) * cameraPanSensitivity;\n const dy = (sY / this.targetElement.clientHeight) * cameraPanSensitivity;\n\n if (this.activePointers.size > 1) {\n const zoomDelta = latest.spread - previous.spread;\n this.zoom(-zoomDelta * pinchZoomSensitivity);\n }\n\n this.targetTheta += dx;\n this.targetPhi -= dy;\n this.targetPhi = Math.max(this.minPolarAngle, Math.min(this.maxPolarAngle, this.targetPhi));\n event.preventDefault();\n }\n }\n\n private onMouseWheel(event: WheelEvent): void {\n if (getTweakpaneActive()) {\n return;\n }\n event.preventDefault();\n const scrollAmount = event.deltaY * this.zoomScale * scrollZoomSensitivity;\n this.zoom(scrollAmount);\n }\n\n private zoom(delta: number) {\n this.targetDistance += delta;\n this.targetDistance = Math.max(\n this.minDistance,\n Math.min(this.maxDistance, this.targetDistance),\n );\n this.desiredDistance = this.targetDistance;\n }\n\n private onContextMenu(event: PointerEvent): void {\n event.preventDefault();\n }\n\n public setTarget(target: Vector3): void {\n if (!this.isLerping) {\n this.target.copy(target);\n } else {\n this.finalTarget.copy(target);\n this.lerpTarget.copy(this.target);\n this.lerpFactor = 0;\n }\n\n if (!this.hadTarget) {\n this.hadTarget = true;\n this.reverseUpdateFromPositions();\n }\n }\n\n public setLerpedTarget(target: Vector3, targetDistance: number): void {\n this.isLerping = true;\n this.targetDistance = targetDistance;\n this.desiredDistance = targetDistance;\n this.setTarget(target);\n }\n\n public reverseUpdateFromPositions(): void {\n const dx = this.camera.position.x - this.target.x;\n const dy = this.camera.position.y - this.target.y;\n const dz = this.camera.position.z - this.target.z;\n this.targetDistance = Math.sqrt(dx * dx + dy * dy + dz * dz);\n this.distance = this.targetDistance;\n this.desiredDistance = this.targetDistance;\n this.theta = Math.atan2(dz, dx);\n this.targetTheta = this.theta;\n this.phi = Math.acos(dy / this.targetDistance);\n this.targetPhi = this.phi;\n this.recomputeFoV(true);\n }\n\n public adjustCameraPosition(): void {\n const offsetDistance = 0.5;\n const offset = new Vector3(0, 0, offsetDistance);\n offset.applyEuler(this.camera.rotation);\n const rayOrigin = this.camera.position.clone().add(offset);\n const rayDirection = rayOrigin.sub(this.target.clone()).normalize();\n\n this.rayCaster.set(this.target.clone(), rayDirection);\n const firstRaycastHit = this.collisionsManager.raycastFirst(this.rayCaster.ray);\n\n if (firstRaycastHit !== null && firstRaycastHit[0] <= this.desiredDistance) {\n const distanceToCollision = firstRaycastHit[0] - 0.1;\n this.targetDistance = distanceToCollision;\n this.distance = distanceToCollision;\n } else {\n this.targetDistance = this.desiredDistance;\n }\n }\n\n public dispose() {\n this.disposeEventHandlers();\n this.orbitControls.dispose();\n document.body.style.cursor = \"\";\n }\n\n private easeOutExpo(x: number): number {\n return x === 1 ? 1 : 1 - Math.pow(2, -10 * x);\n }\n\n public updateAspect(aspect: number): void {\n this.camera.aspect = aspect;\n this.flyCamera.aspect = aspect;\n }\n\n public recomputeFoV(immediately: boolean = false): void {\n this.targetFOV = remap(\n this.targetDistance,\n this.minDistance,\n this.maxDistance,\n this.invertFOVMapping ? this.minFOV : this.maxFOV,\n this.invertFOVMapping ? this.maxFOV : this.minFOV,\n );\n if (immediately) {\n this.fov = this.targetFOV;\n }\n }\n\n public toggleFlyCamera(): void {\n this.isMainCameraActive = !this.isMainCameraActive;\n this.orbitControls.enabled = !this.isMainCameraActive;\n\n if (!this.isMainCameraActive) {\n this.updateAspect(window.innerWidth / window.innerHeight);\n this.flyCamera.position.copy(this.camera.position);\n this.flyCamera.rotation.copy(this.camera.rotation);\n const target = new Vector3();\n this.camera.getWorldDirection(target);\n target.multiplyScalar(this.targetDistance).add(this.camera.position);\n this.orbitControls.target.copy(target);\n this.orbitControls.update();\n this.disposeEventHandlers();\n } else {\n this.createEventHandlers();\n }\n }\n\n get activeCamera(): PerspectiveCamera {\n return this.isMainCameraActive ? this.camera : this.flyCamera;\n }\n\n public update(): void {\n if (!this.isMainCameraActive) {\n this.orbitControls.update();\n return;\n }\n if (this.isLerping && this.lerpFactor < 1) {\n this.lerpFactor += 0.01 / this.lerpDuration;\n this.lerpFactor = Math.min(1, this.lerpFactor);\n this.target.lerpVectors(this.lerpTarget, this.finalTarget, this.easeOutExpo(this.lerpFactor));\n } else {\n this.adjustCameraPosition();\n }\n\n this.distance += (this.targetDistance - this.distance) * this.zoomDamping;\n\n this.theta += (this.targetTheta - this.theta) * this.damping;\n this.phi += (this.targetPhi - this.phi) * this.damping;\n\n const x = this.target.x + this.distance * Math.sin(this.phi) * Math.cos(this.theta);\n const y = this.target.y + this.distance * Math.cos(this.phi);\n const z = this.target.z + this.distance * Math.sin(this.phi) * Math.sin(this.theta);\n\n this.recomputeFoV();\n this.fov += (this.targetFOV - this.fov) * this.zoomDamping;\n this.camera.fov = this.fov;\n this.camera.updateProjectionMatrix();\n\n this.camera.position.set(x, y, z);\n this.camera.lookAt(this.target);\n\n if (this.isLerping && this.lerpFactor >= 1) {\n this.isLerping = false;\n }\n }\n\n public hasActiveInput(): boolean {\n return this.activePointers.size > 0;\n }\n}\n", "import { Quaternion, Vector3, Vector4 } from \"three\";\n\nexport const roundToDecimalPlaces = (value: number, decimalPlaces: number): number => {\n const mult = 10 ** decimalPlaces;\n return Math.round(value * mult) / mult;\n};\n\nexport const toArray = (\n origin: Vector3 | Vector4 | Quaternion,\n precision: number = 3,\n): number[] => {\n const array = [];\n array[0] = roundToDecimalPlaces(origin.x, precision);\n array[1] = roundToDecimalPlaces(origin.y, precision);\n array[2] = roundToDecimalPlaces(origin.z, precision);\n if (origin instanceof Vector4 || origin instanceof Quaternion) {\n array[3] = roundToDecimalPlaces(origin.w, precision);\n }\n return array;\n};\n\nexport const getSpawnPositionInsideCircle = (\n radius: number,\n positions: number,\n id: number,\n yPos: number = 0,\n): Vector3 => {\n if (id > 0) id += 3;\n const goldenAngle = Math.PI * (3 - Math.sqrt(5));\n const theta = id * goldenAngle;\n const scale = id / positions;\n const scaledRadius = scale * radius;\n const x = Math.cos(theta) * scaledRadius;\n const z = Math.sin(theta) * scaledRadius;\n return new Vector3(x, yPos, z);\n};\n\nexport const round = (n: number, digits: number): number => {\n return Number(n.toFixed(digits));\n};\n\nexport const ease = (target: number, n: number, factor: number): number => {\n return round((target - n) * factor, 5);\n};\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(Math.max(value, min), max);\n}\n\nexport const remap = (\n value: number,\n minValue: number,\n maxValue: number,\n minScaledValue: number,\n maxScaledValue: number,\n): number => {\n return (\n minScaledValue +\n ((maxScaledValue - minScaledValue) * (value - minValue)) / (maxValue - minValue)\n );\n};\n", "type ListenerFunc = (...args: any[]) => void;\n\ntype EventSpecificationTuple = [EventTarget, string, ListenerFunc, AddEventListenerOptions?];\n\nexport class EventHandlerCollection {\n private eventsByTarget: Map<EventTarget, Map<string, Set<ListenerFunc>>> = new Map();\n\n public add(\n target: EventTarget,\n key: string,\n listener: ListenerFunc,\n options?: AddEventListenerOptions,\n ): this {\n target.addEventListener(key, listener, options);\n\n let existingTarget = this.eventsByTarget.get(target);\n if (existingTarget === undefined) {\n existingTarget = new Map();\n this.eventsByTarget.set(target, existingTarget);\n }\n let existingKey = existingTarget.get(key);\n if (existingKey === undefined) {\n existingKey = new Set();\n existingTarget.set(key, existingKey);\n }\n existingKey.add(listener);\n\n return this;\n }\n\n public clear() {\n this.eventsByTarget.forEach((keyMap, target) => {\n keyMap.forEach((listenerSet, key) => {\n listenerSet.forEach((listenerFunc) => {\n target.removeEventListener(key, listenerFunc);\n });\n });\n });\n this.eventsByTarget.clear();\n }\n\n static create(initial?: Array<EventSpecificationTuple>): EventHandlerCollection {\n const instance = new EventHandlerCollection();\n if (initial !== undefined) {\n initial.forEach(([target, key, listenerFunc, options]) => {\n instance.add(target, key, listenerFunc, options);\n });\n }\n return instance;\n }\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { BladeApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nimport { CameraManager } from \"../../camera/CameraManager\";\n\nexport const camValues = {\n initialDistance: 3.3,\n minDistance: 0.1,\n maxDistance: 5,\n initialFOV: 60,\n maxFOV: 70,\n minFOV: 60,\n invertFOVMapping: false,\n damping: 0.25,\n zoomScale: 0.088,\n zoomDamping: 0.4,\n};\n\nexport const camOptions = {\n initialDistance: { min: 1, max: 5, step: 0.1 },\n minDistance: { min: 0.1, max: 2, step: 0.1 },\n maxDistance: { min: 5, max: 20, step: 0.5 },\n initialFOV: { min: 60, max: 85, step: 1 },\n maxFOV: { min: 50, max: 100, step: 1 },\n minFOV: { min: 50, max: 100, step: 1 },\n damping: { min: 0.01, max: 1, step: 0.001 },\n zoomScale: { min: 0.005, max: 0.3, step: 0.001 },\n zoomDamping: { min: 0.0, max: 2.0, step: 0.01 },\n};\n\ntype CamData = {\n distance: string;\n FoV: string;\n};\n\nexport class CameraFolder {\n public folder: FolderApi;\n\n private camData: CamData = {\n distance: \"0\",\n FoV: \"0\",\n };\n\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({ title: \"camera\", expanded: expand });\n this.folder.addBinding(this.camData, \"distance\", { readonly: true });\n this.folder.addBinding(this.camData, \"FoV\", { readonly: true });\n this.folder.addBinding(camValues, \"initialDistance\", camOptions.initialDistance);\n this.folder.addBinding(camValues, \"minDistance\", camOptions.minDistance);\n this.folder.addBinding(camValues, \"maxDistance\", camOptions.maxDistance);\n this.folder.addBinding(camValues, \"minFOV\", camOptions.minFOV);\n this.folder.addBinding(camValues, \"maxFOV\", camOptions.maxFOV);\n this.folder.addBinding({ invertFOVMapping: camValues.invertFOVMapping }, \"invertFOVMapping\");\n this.folder.addBinding(camValues, \"damping\", camOptions.damping);\n this.folder.addBinding(camValues, \"zoomScale\", camOptions.zoomScale);\n this.folder.addBinding(camValues, \"zoomDamping\", camOptions.zoomDamping);\n }\n\n public setupChangeEvent(cameraManager: CameraManager): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"initialDistance\": {\n const value = e.value as number;\n cameraManager.initialDistance = value;\n cameraManager.distance = value;\n cameraManager.targetDistance = value;\n cameraManager.desiredDistance = value;\n cameraManager.recomputeFoV();\n break;\n }\n case \"minDistance\": {\n const value = e.value as number;\n cameraManager.minDistance = value;\n cameraManager.distance = value;\n cameraManager.targetDistance = value;\n cameraManager.desiredDistance = value;\n cameraManager.recomputeFoV();\n break;\n }\n case \"maxDistance\": {\n const value = e.value as number;\n cameraManager.maxDistance = value;\n cameraManager.distance = value;\n cameraManager.targetDistance = value;\n cameraManager.desiredDistance = value;\n cameraManager.recomputeFoV();\n break;\n }\n case \"minFOV\": {\n const value = e.value as number;\n cameraManager.minFOV = value;\n cameraManager.recomputeFoV();\n break;\n }\n case \"maxFOV\": {\n const value = e.value as number;\n cameraManager.maxFOV = value;\n cameraManager.recomputeFoV();\n break;\n }\n case \"invertFOVMapping\": {\n const boolValue = e.value as boolean;\n cameraManager.invertFOVMapping = boolValue;\n break;\n }\n case \"damping\": {\n const value = e.value as number;\n cameraManager.damping = value;\n break;\n }\n case \"zoomScale\": {\n const value = e.value as number;\n cameraManager.zoomScale = value;\n break;\n }\n case \"zoomDamping\": {\n const value = e.value as number;\n cameraManager.zoomDamping = value;\n break;\n }\n default:\n break;\n }\n });\n }\n\n public update(cameraManager: CameraManager): void {\n this.camData.distance = cameraManager.distance.toFixed(2);\n this.camData.FoV = cameraManager.fov.toFixed(2);\n }\n}\n", "let isTweakpaneActive = false;\n\nexport function setTweakpaneActive(status: boolean) {\n isTweakpaneActive = status;\n}\n\nexport function getTweakpaneActive() {\n return isTweakpaneActive;\n}\n", "import { Color, Group, Vector3 } from \"three\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\nimport { Composer } from \"../rendering/composer\";\n\nimport { CharacterModel } from \"./CharacterModel\";\nimport { CharacterModelLoader } from \"./CharacterModelLoader\";\nimport { CharacterSpeakingIndicator } from \"./CharacterSpeakingIndicator\";\nimport { AnimationState } from \"./CharacterState\";\nimport { CharacterTooltip } from \"./CharacterTooltip\";\n\nexport type AnimationConfig = {\n idleAnimationFileUrl: string;\n jogAnimationFileUrl: string;\n sprintAnimationFileUrl: string;\n airAnimationFileUrl: string;\n doubleJumpAnimationFileUrl: string;\n};\n\nexport type CharacterDescription =\n | {\n meshFileUrl: string;\n mmlCharacterString?: null;\n mmlCharacterUrl?: null;\n }\n | {\n meshFileUrl?: null;\n mmlCharacterString: string;\n mmlCharacterUrl?: null;\n }\n | {\n meshFileUrl?: null;\n mmlCharacterString?: null;\n mmlCharacterUrl: string;\n };\n\nexport type CharacterConfig = {\n username: string;\n characterDescription: CharacterDescription;\n animationConfig: AnimationConfig;\n characterModelLoader: CharacterModelLoader;\n characterId: number;\n modelLoadedCallback: () => void;\n cameraManager: CameraManager;\n composer: Composer;\n isLocal: boolean;\n};\n\nfunction characterHeightToTooltipHeightOffset(characterHeight: number): number {\n return characterHeight - 0.4 + 0.1;\n}\n\nfunction characterDescriptionMatches(a: CharacterDescription, b: CharacterDescription): boolean {\n return (\n a.meshFileUrl === b.meshFileUrl &&\n a.mmlCharacterString === b.mmlCharacterString &&\n a.mmlCharacterUrl === b.mmlCharacterUrl\n );\n}\n\nexport class Character extends Group {\n private model: CharacterModel | null = null;\n public color: Color = new Color();\n public tooltip: CharacterTooltip;\n public speakingIndicator: CharacterSpeakingIndicator | null = null;\n\n public chatTooltips: CharacterTooltip[] = [];\n\n constructor(private config: CharacterConfig) {\n super();\n this.tooltip = new CharacterTooltip(\n this.config.isLocal\n ? {\n secondsToFadeOut: 10,\n }\n : {},\n );\n this.tooltip.setText(this.config.username);\n this.add(this.tooltip);\n this.load().then(() => {\n this.config.modelLoadedCallback();\n this.setTooltipHeights();\n });\n }\n\n updateCharacter(username: string, characterDescription: CharacterDescription) {\n if (!characterDescriptionMatches(this.config.characterDescription, characterDescription)) {\n this.config.characterDescription = characterDescription;\n this.load().then(() => {\n this.setTooltipHeights();\n });\n }\n if (this.config.username !== username) {\n this.config.username = username;\n this.tooltip.setText(username);\n // Force the tooltip to show if the character's name changes\n this.tooltip.show();\n }\n }\n\n private setTooltipHeights() {\n if (this.model && this.model.characterHeight) {\n let height = characterHeightToTooltipHeightOffset(this.model.characterHeight);\n this.tooltip.setHeightOffset(height);\n height += this.tooltip.scale.y;\n\n for (const chatTooltip of this.chatTooltips) {\n chatTooltip.setHeightOffset(height);\n height += chatTooltip.scale.y;\n }\n }\n }\n\n private async load(): Promise<void> {\n const previousModel = this.model;\n if (previousModel && previousModel.mesh) {\n this.remove(previousModel.mesh);\n }\n this.model = new CharacterModel({\n characterDescription: this.config.characterDescription,\n animationConfig: this.config.animationConfig,\n characterModelLoader: this.config.characterModelLoader,\n cameraManager: this.config.cameraManager,\n characterId: this.config.characterId,\n isLocal: this.config.isLocal,\n });\n await this.model.init();\n if (this.model.mesh) {\n this.add(this.model.mesh);\n }\n if (this.speakingIndicator === null) {\n this.speakingIndicator = new CharacterSpeakingIndicator(this.config.composer.postPostScene);\n }\n }\n\n public updateAnimation(targetAnimation: AnimationState) {\n this.model?.updateAnimation(targetAnimation);\n }\n\n public update(time: number, deltaTime: number) {\n if (!this.model) return;\n if (this.tooltip) {\n this.tooltip.update();\n }\n if (this.speakingIndicator) {\n this.speakingIndicator.setTime(time);\n if (this.model.mesh && this.model.headBone) {\n this.speakingIndicator.setBillboarding(\n this.model.headBone?.getWorldPosition(new Vector3()),\n this.config.cameraManager.camera,\n );\n }\n }\n this.model.update(deltaTime);\n }\n\n getCurrentAnimation(): AnimationState {\n return this.model?.currentAnimation || AnimationState.idle;\n }\n\n addChatBubble(message: string) {\n const tooltip = new CharacterTooltip({\n maxWidth: 1000,\n secondsToFadeOut: 10,\n color: new Color(0.125, 0.125, 0.125),\n });\n this.add(tooltip);\n this.chatTooltips.unshift(tooltip);\n tooltip.setText(message, () => {\n this.chatTooltips = this.chatTooltips.filter((t) => t !== tooltip);\n this.remove(tooltip);\n this.setTooltipHeights();\n });\n if (this.config.isLocal) {\n // Show the character's name if they're local and they emit a chat bubble\n this.tooltip.show();\n }\n this.setTooltipHeights();\n }\n}\n", "import {\n MMLCharacter,\n type MMLCharacterDescription,\n parseMMLDescription,\n} from \"@mml-io/3d-web-avatar\";\nimport { ModelLoader } from \"@mml-io/model-loader\";\nimport {\n AnimationAction,\n AnimationClip,\n AnimationMixer,\n Bone,\n Box3,\n LoopRepeat,\n Mesh,\n MeshStandardMaterial,\n Object3D,\n SkinnedMesh,\n Vector3,\n} from \"three\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\n\nimport { AnimationConfig, CharacterDescription } from \"./Character\";\nimport { CharacterMaterial } from \"./CharacterMaterial\";\nimport { CharacterModelLoader } from \"./CharacterModelLoader\";\nimport { AnimationState } from \"./CharacterState\";\n\nexport type CharacterModelConfig = {\n characterDescription: CharacterDescription;\n animationConfig: AnimationConfig;\n characterModelLoader: CharacterModelLoader;\n cameraManager: CameraManager;\n characterId: number;\n isLocal: boolean;\n};\n\nexport class CharacterModel {\n public static ModelLoader: ModelLoader = new ModelLoader();\n\n public mesh: Object3D | null = null;\n public headBone: Bone | null = null;\n public characterHeight: number | null = null;\n\n private materials: Map<string, CharacterMaterial> = new Map();\n\n public animations: Record<string, AnimationAction> = {};\n public animationMixer: AnimationMixer | null = null;\n public currentAnimation: AnimationState = AnimationState.idle;\n\n public mmlCharacterDescription: MMLCharacterDescription;\n\n private isPostDoubleJump = false;\n\n constructor(private config: CharacterModelConfig) {}\n\n public async init(): Promise<void> {\n await this.loadMainMesh();\n if (this.mesh) {\n await this.setAnimationFromFile(\n this.config.animationConfig.idleAnimationFileUrl,\n AnimationState.idle,\n true,\n );\n await this.setAnimationFromFile(\n this.config.animationConfig.jogAnimationFileUrl,\n AnimationState.walking,\n true,\n );\n await this.setAnimationFromFile(\n this.config.animationConfig.sprintAnimationFileUrl,\n AnimationState.running,\n true,\n );\n await this.setAnimationFromFile(\n this.config.animationConfig.airAnimationFileUrl,\n AnimationState.air,\n true,\n );\n await this.setAnimationFromFile(\n this.config.animationConfig.doubleJumpAnimationFileUrl,\n AnimationState.doubleJump,\n false,\n 1.45,\n );\n this.applyCustomMaterials();\n }\n }\n\n private applyCustomMaterials(): void {\n if (!this.mesh) return;\n const boundingBox = new Box3();\n this.mesh.updateWorldMatrix(true, true);\n boundingBox.expandByObject(this.mesh);\n this.characterHeight = boundingBox.max.y - boundingBox.min.y;\n\n this.mesh.traverse((child: Object3D) => {\n if ((child as Bone).isBone) {\n if (child.name === \"head\") {\n const worldPosition = new Vector3();\n this.headBone = child as Bone;\n this.headBone.getWorldPosition(worldPosition);\n }\n }\n if ((child as Mesh).isMesh || (child as SkinnedMesh).isSkinnedMesh) {\n const asMesh = child as Mesh;\n const originalMaterial = asMesh.material as MeshStandardMaterial;\n if (this.materials.has(originalMaterial.name)) {\n asMesh.material = this.materials.get(originalMaterial.name)!;\n } else {\n const material =\n originalMaterial.name === \"body_replaceable_color\"\n ? new CharacterMaterial({\n isLocal: this.config.isLocal,\n cameraManager: this.config.cameraManager,\n characterId: this.config.characterId,\n originalMaterial,\n })\n : new CharacterMaterial({\n isLocal: this.config.isLocal,\n cameraManager: this.config.cameraManager,\n characterId: this.config.characterId,\n originalMaterial,\n colorOverride: originalMaterial.color,\n });\n this.materials.set(originalMaterial.name, material);\n asMesh.material = material;\n }\n }\n });\n }\n\n public updateAnimation(targetAnimation: AnimationState) {\n if (this.isPostDoubleJump) {\n if (targetAnimation === AnimationState.doubleJump) {\n // Double jump is requested, but we're in the post double jump state so we play air instead\n targetAnimation = AnimationState.air;\n } else {\n // Reset the post double jump flag if something other than double jump is requested\n this.isPostDoubleJump = false;\n }\n }\n if (this.currentAnimation !== targetAnimation) {\n this.transitionToAnimation(targetAnimation);\n }\n }\n\n private setMainMesh(mainMesh: Object3D): void {\n this.mesh = mainMesh;\n this.mesh.position.set(0, -0.44, 0);\n this.mesh.traverse((child: Object3D) => {\n if (child.type === \"SkinnedMesh\") {\n child.castShadow = true;\n child.receiveShadow = true;\n }\n });\n this.animationMixer = new AnimationMixer(this.mesh);\n }\n\n private async composeMMLCharacter(\n mmlCharacterDescription: MMLCharacterDescription,\n ): Promise<Object3D | undefined> {\n if (mmlCharacterDescription.base?.url.length === 0) {\n throw new Error(\n \"ERROR: An MML Character Description was provided, but it's not a valid <m-character> string, or a valid URL\",\n );\n }\n\n let mergedCharacter: Object3D | null = null;\n if (mmlCharacterDescription) {\n const characterBase = mmlCharacterDescription.base?.url || null;\n if (characterBase) {\n this.mmlCharacterDescription = mmlCharacterDescription;\n const mmlCharacter = new MMLCharacter(CharacterModel.ModelLoader);\n mergedCharacter = await mmlCharacter.mergeBodyParts(\n characterBase,\n mmlCharacterDescription.parts,\n );\n if (mergedCharacter) {\n return mergedCharacter;\n }\n }\n }\n }\n\n private async loadCharacterFromDescription(): Promise<Object3D | null> {\n if (this.config.characterDescription.meshFileUrl) {\n return (\n (await this.config.characterModelLoader.load(\n this.config.characterDescription.meshFileUrl,\n \"model\",\n )) || null\n );\n }\n\n let mmlCharacterSource: string;\n if (this.config.characterDescription.mmlCharacterUrl) {\n const res = await fetch(this.config.characterDescription.mmlCharacterUrl);\n mmlCharacterSource = await res.text();\n } else if (this.config.characterDescription.mmlCharacterString) {\n mmlCharacterSource = this.config.characterDescription.mmlCharacterString;\n } else {\n throw new Error(\n \"ERROR: No Character Description was provided. Specify one of meshFileUrl, mmlCharacterUrl or mmlCharacterString\",\n );\n }\n\n const parsedMMLDescription = parseMMLDescription(mmlCharacterSource);\n const mmlCharacterDescription = parsedMMLDescription[0];\n if (parsedMMLDescription[1].length > 0) {\n console.warn(\"Errors parsing MML Character Description: \", parsedMMLDescription[1]);\n }\n const mmlCharacterBody = await this.composeMMLCharacter(mmlCharacterDescription);\n if (mmlCharacterBody) {\n return mmlCharacterBody;\n }\n return null;\n }\n\n private async loadMainMesh(): Promise<void> {\n let mainMesh: Object3D | null = null;\n try {\n mainMesh = await this.loadCharacterFromDescription();\n } catch (error) {\n console.error(\"Failed to load character from description\", error);\n }\n if (mainMesh) {\n this.setMainMesh(mainMesh as Object3D);\n }\n }\n\n private cleanAnimationClips(\n skeletalMesh: Object3D | null,\n animationClip: AnimationClip,\n keepRootBonePositionAnimation: boolean,\n ): AnimationClip {\n const availableBones = new Set<string>();\n if (skeletalMesh) {\n skeletalMesh.traverse((child) => {\n const asBone = child as Bone;\n if (asBone.isBone) {\n availableBones.add(child.name);\n }\n });\n }\n animationClip.tracks = animationClip.tracks.filter((track) => {\n const [trackName, trackProperty] = track.name.split(\".\");\n if (keepRootBonePositionAnimation && trackName === \"root\" && trackProperty === \"position\") {\n return true;\n }\n const shouldAnimate =\n availableBones.has(trackName) && trackProperty !== \"position\" && trackProperty !== \"scale\";\n return shouldAnimate;\n });\n return animationClip;\n }\n\n private async setAnimationFromFile(\n animationFileUrl: string,\n animationType: AnimationState,\n loop: boolean = true,\n playbackSpeed: number = 1.0,\n ): Promise<void> {\n return new Promise(async (resolve, reject) => {\n const animation = await this.config.characterModelLoader.load(animationFileUrl, \"animation\");\n const cleanAnimation = this.cleanAnimationClips(this.mesh, animation as AnimationClip, true);\n if (typeof animation !== \"undefined\" && cleanAnimation instanceof AnimationClip) {\n this.animations[animationType] = this.animationMixer!.clipAction(cleanAnimation);\n this.animations[animationType].stop();\n this.animations[animationType].timeScale = playbackSpeed;\n if (animationType === AnimationState.idle) {\n this.animations[animationType].play();\n }\n if (!loop) {\n this.animations[animationType].setLoop(LoopRepeat, 1); // Ensure non-looping\n this.animations[animationType].clampWhenFinished = true;\n }\n resolve();\n } else {\n reject(`failed to load ${animationType} from ${animationFileUrl}`);\n }\n });\n }\n\n private transitionToAnimation(\n targetAnimation: AnimationState,\n transitionDuration: number = 0.15,\n ): void {\n if (!this.mesh) {\n return;\n }\n\n const currentAction = this.animations[this.currentAnimation];\n this.currentAnimation = targetAnimation;\n const targetAction = this.animations[targetAnimation];\n\n if (!targetAction) {\n return;\n }\n\n if (currentAction) {\n currentAction.fadeOut(transitionDuration);\n }\n\n targetAction.reset();\n if (!targetAction.isRunning()) {\n targetAction.play();\n }\n\n if (targetAnimation === AnimationState.doubleJump) {\n targetAction.getMixer().addEventListener(\"finished\", (_event) => {\n if (this.currentAnimation === AnimationState.doubleJump) {\n this.isPostDoubleJump = true;\n // This triggers the transition to the air animation because the double jump animation is done\n this.updateAnimation(AnimationState.doubleJump);\n }\n });\n }\n\n targetAction.enabled = true;\n targetAction.fadeIn(transitionDuration);\n }\n\n update(time: number) {\n if (this.animationMixer) {\n this.animationMixer.update(time);\n this.materials.forEach((material) => material.update());\n }\n }\n}\n", "import { Color, MeshStandardMaterial, UniformsUtils } from \"three\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\nimport { ease } from \"../helpers/math-helpers\";\nimport { bayerDither } from \"../rendering/shaders/bayer-dither\";\nimport {\n injectBefore,\n injectBeforeMain,\n injectInsideMain,\n} from \"../rendering/shaders/shader-helpers\";\nimport { characterValues } from \"../tweakpane/blades/characterFolder\";\n\ntype TUniform<TValue = any> = { value: TValue };\n\nexport type CharacterMaterialConfig = {\n isLocal: boolean;\n cameraManager: CameraManager;\n characterId: number;\n originalMaterial: MeshStandardMaterial;\n colorOverride?: Color;\n};\n\nexport class CharacterMaterial extends MeshStandardMaterial {\n private uniforms: Record<string, TUniform> = {\n discardAll: { value: 1 },\n diffuseColor: { value: new Color() },\n map: { value: null },\n };\n private colorsCube216: Color[] = [];\n private targetAlpha: number = 1;\n private currentAlpha: number = 1;\n\n constructor(private config: CharacterMaterialConfig) {\n super();\n this.copy(this.config.originalMaterial);\n this.generateColorCube();\n\n this.color = this.config.colorOverride || this.colorsCube216[this.config.characterId];\n this.envMapIntensity = characterValues.envMapIntensity;\n this.transparent = true;\n this.side = this.config.originalMaterial.side;\n\n this.onBeforeCompile = (shader) => {\n this.uniforms = UniformsUtils.clone(shader.uniforms);\n this.uniforms.nearClip = { value: 0.01 };\n this.uniforms.farClip = { value: 1000.0 };\n this.uniforms.ditheringNear = { value: 0.3 };\n this.uniforms.ditheringRange = { value: 0.5 };\n this.uniforms.time = { value: 0.0 };\n this.uniforms.diffuseRandomColor = { value: new Color() };\n this.uniforms.discardAll = { value: 0 };\n shader.uniforms = this.uniforms;\n\n shader.vertexShader = \"varying vec3 vWorldPosition;\\n\" + shader.vertexShader;\n shader.vertexShader = shader.vertexShader.replace(\n \"#include <worldpos_vertex>\",\n \"vec4 worldPosition = modelMatrix * vec4( transformed, 1.0 );\\nvWorldPosition = worldPosition.xyz;\",\n );\n shader.vertexShader = injectBeforeMain(shader.vertexShader, \"varying vec2 vUv;\");\n shader.vertexShader = injectInsideMain(shader.vertexShader, \"vUv = uv;\");\n\n shader.fragmentShader = injectBeforeMain(\n shader.fragmentShader,\n /* glsl */ `\n varying vec2 vUv;\n varying vec3 vWorldPosition;\n uniform float nearClip;\n uniform float farClip;\n uniform float ditheringNear;\n uniform float ditheringRange;\n uniform float time;\n uniform vec3 diffuseRandomColor;\n uniform int discardAll;\n ${bayerDither}\n `,\n );\n\n shader.fragmentShader = injectBefore(\n shader.fragmentShader,\n \"#include <dithering_fragment>\",\n /* glsl */ `\n if (discardAll == 1) {\n discard;\n } else {\n float distance = length(vWorldPosition - cameraPosition);\n float normalizedDistance = (distance - nearClip) / (farClip - nearClip);\n ivec2 p = ivec2(mod(gl_FragCoord.xy, 8.0));\n float d = 0.0;\n if (p.x <= 3 && p.y <= 3) {\n d = bayerDither(bayertl, p);\n } else if (p.x > 3 && p.y <= 3) {\n d = bayerDither(bayertr, p - ivec2(4, 0));\n } else if (p.x <= 3 && p.y > 3) {\n d = bayerDither(bayerbl, p - ivec2(0, 4));\n } else if (p.x > 3 && p.y > 3) {\n d = bayerDither(bayerbr, p - ivec2(4, 4));\n }\n if (distance <= ditheringNear + d * ditheringRange) discard; \n outgoingLight *= diffuseRandomColor; \n }\n `,\n );\n };\n this.needsUpdate = true;\n }\n\n private generateColorCube() {\n const saturation = 1.0;\n const lightness = 0.9;\n const goldenRatioConjugate = 0.618033988749895;\n let hue = 0;\n\n for (let i = 0; i < 216; i++) {\n const color = new Color();\n color.setHSL(hue, saturation, lightness);\n this.colorsCube216.push(color);\n hue = (hue + goldenRatioConjugate) % 1;\n }\n }\n\n public update() {\n if (this.config.isLocal) {\n this.targetAlpha = this.config.cameraManager.distance < 0.4 ? 0.0 : 1.0;\n this.currentAlpha += ease(this.targetAlpha, this.currentAlpha, 0.07);\n if (this.currentAlpha > 0.999) {\n this.currentAlpha = 1;\n this.config.cameraManager.minPolarAngle = Math.PI * 0.25;\n }\n if (this.currentAlpha < 0.001) {\n this.currentAlpha = 0;\n this.config.cameraManager.minPolarAngle = Math.PI * 0.35;\n }\n this.uniforms.discardAll.value = this.currentAlpha === 0 ? 1 : 0;\n if (this.currentAlpha !== this.opacity) {\n this.opacity = this.currentAlpha;\n }\n }\n this.metalness = characterValues.metalness;\n this.roughness = characterValues.roughness;\n this.emissive = new Color().setRGB(\n characterValues.emissive.r,\n characterValues.emissive.g,\n characterValues.emissive.b,\n );\n this.emissiveIntensity = characterValues.emissiveIntensity;\n this.envMapIntensity = characterValues.envMapIntensity;\n }\n}\n", "export const bayerDither: string = /* glsl */ `\nconst mat4 bayertl = mat4( \n 0.0 / 64.0, 32.0 / 64.0, 8.0 / 64.0, 40.0 / 64.0,\n 48.0 / 64.0, 16.0 / 64.0, 56.0 / 64.0, 24.0 / 64.0,\n 12.0 / 64.0, 44.0 / 64.0, 4.0 / 64.0, 36.0 / 64.0,\n 60.0 / 64.0, 28.0 / 64.0, 52.0 / 64.0, 20.0 / 64.0\n);\n\nconst mat4 bayertr = mat4( \n 2.0 / 64.0, 34.0 / 64.0, 10.0 / 64.0, 42.0 / 64.0,\n 50.0 / 64.0, 18.0 / 64.0, 58.0 / 64.0, 26.0 / 64.0,\n 14.0 / 64.0, 46.0 / 64.0, 6.0 / 64.0, 38.0 / 64.0,\n 62.0 / 64.0, 30.0 / 64.0, 54.0 / 64.0, 22.0 / 64.0\n);\n\nconst mat4 bayerbl = mat4( \n 3.0 / 64.0, 35.0 / 64.0, 11.0 / 64.0, 43.0 / 64.0,\n 51.0 / 64.0, 19.0 / 64.0, 59.0 / 64.0, 27.0 / 64.0,\n 15.0 / 64.0, 47.0 / 64.0, 7.0 / 64.0, 39.0 / 64.0,\n 63.0 / 64.0, 31.0 / 64.0, 55.0 / 64.0, 23.0 / 64.0\n);\n\nconst mat4 bayerbr = mat4( \n 1.0 / 64.0, 33.0 / 64.0, 9.0 / 64.0, 41.0 / 64.0,\n 49.0 / 64.0, 17.0 / 64.0, 57.0 / 64.0, 25.0 / 64.0,\n 13.0 / 64.0, 45.0 / 64.0, 5.0 / 64.0, 37.0 / 64.0,\n 61.0 / 64.0, 29.0 / 64.0, 53.0 / 64.0, 21.0 / 64.0\n);\n\nfloat bayerDither(mat4 m, ivec2 p) {\n if (p.y == 0) {\n if (p.x == 0) { return m[0][0]; }\n else if (p.x == 1) { return m[1][0]; }\n else if (p.x == 2) { return m[2][0]; }\n else { return m[3][0]; }\n } else if (p.y == 1) {\n if (p.x == 0) { return m[0][1]; }\n else if (p.x == 1) { return m[1][1]; }\n else if (p.x == 2) { return m[2][1]; }\n else { return m[3][1]; }\n } else if (p.y == 2) {\n if (p.x == 0) { return m[0][1]; }\n else if (p.x == 1) { return m[1][2]; }\n else if (p.x == 2) { return m[2][2]; }\n else { return m[3][2]; }\n } else {\n if (p.x == 0) { return m[0][3]; }\n else if (p.x == 1) { return m[1][3]; }\n else if (p.x == 2) { return m[2][3]; }\n else { return m[3][3]; }\n }\n}\n`;\n", "export function injectBeforeMain(shaderSource: string, codeToInject: string): string {\n return shaderSource.replace(\n \"void main() {\",\n `\n\n${codeToInject}\n\nvoid main() {`,\n );\n}\n\nexport function injectInsideMain(shaderSource: string, codeToInject: string): string {\n return shaderSource.replace(\n \"void main() {\",\n `void main() {\n\n${codeToInject}\n\n `,\n );\n}\n\nexport function injectBefore(shaderSource: string, before: string, codeToInject: string): string {\n return shaderSource.replace(\n before,\n `\n${codeToInject}\n\n${before}\n `,\n );\n}\n\nexport function injectAfter(shaderSource: string, after: string, codeToInject: string): string {\n return shaderSource.replace(\n after,\n `\n${after}\n\n${codeToInject}\n\n `,\n );\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { BladeApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nexport const characterValues = {\n metalness: 0.2,\n roughness: 0.8,\n emissive: { r: 1.0, g: 1.0, b: 1.0 },\n emissiveIntensity: 0.01,\n envMapIntensity: 0.12,\n};\n\nconst characterOptions = {\n metalness: { min: 0, max: 1, step: 0.01 },\n roughness: { min: 0, max: 1, step: 0.01 },\n emissiveIntensity: { min: 0, max: 1, step: 0.01 },\n envMapIntensity: { min: 0, max: 1, step: 0.01 },\n};\n\nexport class CharacterFolder {\n private folder: FolderApi;\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({ title: \"characterMaterial\", expanded: expand });\n this.folder.addBinding(characterValues, \"metalness\", characterOptions.metalness);\n this.folder.addBinding(characterValues, \"roughness\", characterOptions.roughness);\n this.folder.addBinding(characterValues, \"emissive\", {\n color: { type: \"float\" },\n });\n this.folder.addBinding(\n characterValues,\n \"emissiveIntensity\",\n characterOptions.emissiveIntensity,\n );\n this.folder.addBinding(characterValues, \"envMapIntensity\", characterOptions.envMapIntensity);\n }\n\n public setupChangeEvent(): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"emissive\": {\n const value = e.value as { r: number; g: number; b: number };\n characterValues.emissive = {\n r: value.r,\n g: value.g,\n b: value.b,\n };\n break;\n }\n default: {\n break;\n }\n }\n });\n }\n}\n", "export enum AnimationState {\n \"idle\" = 0,\n \"walking\" = 1,\n \"running\" = 2,\n \"jumpToAir\" = 3,\n \"air\" = 4,\n \"airToGround\" = 5,\n \"doubleJump\" = 6,\n}\n\nexport type CharacterState = {\n id: number;\n position: {\n x: number;\n y: number;\n z: number;\n };\n rotation: {\n quaternionY: number;\n quaternionW: number;\n };\n camPosition?: {\n x: number;\n y: number;\n z: number;\n };\n camQuaternion?: {\n y: number;\n w: number;\n };\n state: AnimationState;\n};\n", "import {\n Camera,\n CircleGeometry,\n GLSL3,\n Mesh,\n Object3D,\n RawShaderMaterial,\n Scene,\n Vector3,\n} from \"three\";\n\nimport { ease } from \"../helpers/math-helpers\";\n\nexport class CharacterSpeakingIndicator {\n private vertexShader = /* glsl */ `\n in vec3 position;\n in vec2 uv;\n uniform mat4 modelViewMatrix;\n uniform mat4 projectionMatrix;\n out vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }`;\n\n private fragmentShader = /* glsl */ `\n precision highp float;\n\n uniform float time;\n uniform float alpha;\n in vec2 vUv;\n out vec4 fragColor;\n\n const float size = 1.7;\n const float distribution = 0.03;\n const float speed = 0.2;\n const float overdraw = 3.5;\n const float shapeK = 0.25;\n\n float sdHyperbola(vec2 p, float k, float wi) {\n p = abs(p);\n float k2 = k * k;\n float a = p.x + p.y;\n float i = 0.5 * (a - k2 / a) > wi ? -1.0 : 1.0;\n float x = clamp(0.5 * (a - k2 / a), 0.0, wi);\n vec2 q = vec2(x, sqrt(x * x + k2));\n float s = sign(p.x * p.x - p.y * p.y + k2);\n return s * length(p - q);\n }\n\n void main(void) {\n vec2 uv = (vUv * 2.0 - 1.0);\n float r = -(uv.x * uv.x + uv.y * uv.y);\n float z = 0.5 + 0.5 * sin((r + time * speed) / distribution);\n float a = clamp(smoothstep(-0.1, 0.2, size - length(uv * 2.0)), 0.0, 0.5);\n float h = clamp(sdHyperbola(uv, shapeK, 1.0), 0.0, 1.0) * overdraw;\n float fragAlpha = clamp(a * h, 0.0, 0.7);\n fragColor = vec4(z * fragAlpha) * alpha;\n }`;\n\n private uniforms = {\n time: { value: 0.0 },\n alpha: { value: 0.0 },\n };\n\n private geometry: CircleGeometry = new CircleGeometry(0.35, 21);\n private material: RawShaderMaterial = new RawShaderMaterial({\n vertexShader: this.vertexShader,\n fragmentShader: this.fragmentShader,\n uniforms: this.uniforms,\n transparent: true,\n glslVersion: GLSL3,\n });\n private mesh = new Mesh(this.geometry, this.material);\n\n private currentAlpha = 0.0;\n private targetAlpha = 0.0;\n\n constructor(private scene: Scene | Object3D) {\n this.scene.add(this.mesh);\n }\n\n public setBillboarding(position: Vector3, camera: Camera) {\n this.mesh.position.set(position.x, position.y, position.z);\n this.mesh.lookAt(camera.position);\n }\n\n public setTime(value: number) {\n this.currentAlpha += ease(this.targetAlpha, this.currentAlpha, 0.06);\n this.uniforms.time.value = value;\n this.uniforms.alpha.value = this.currentAlpha;\n }\n\n public setSpeaking(value: boolean) {\n this.targetAlpha = value === true ? 1.0 : 0.0;\n }\n\n public dispose() {\n this.scene.remove(this.mesh);\n this.mesh.material.dispose();\n this.mesh.geometry.dispose();\n }\n}\n", "import { Color, FrontSide, LinearFilter, Sprite, SpriteMaterial } from \"three\";\n\nimport { THREECanvasTextTexture } from \"./CanvasText\";\n\nenum LabelAlignment {\n left = \"left\",\n center = \"center\",\n right = \"right\",\n}\n\nconst fontScale = 5;\nconst defaultLabelColor = new Color(0x000000);\nconst defaultFontColor = new Color(0xffffff);\nconst defaultLabelAlignment = LabelAlignment.center;\nconst defaultLabelFontSize = 10;\nconst defaultLabelPadding = 10;\nconst defaultVisibleOpacity = 0.85;\nconst defaultHeightOffset = 1.4;\nconst defaultSecondsToFadeOut = null;\n\nexport type CharacterTooltipConfig = {\n alignment: LabelAlignment;\n fontSize: number;\n padding: number;\n color: Color;\n fontColor: Color;\n visibleOpacity: number;\n maxWidth?: number;\n secondsToFadeOut: number | null;\n};\n\nexport class CharacterTooltip extends Sprite {\n private targetOpacity: number = 0;\n private fadingSpeed: number = 0.02;\n private config: CharacterTooltipConfig;\n private content: string | null = null;\n private hideTimeout: NodeJS.Timeout | null = null;\n\n constructor(configArg?: Partial<CharacterTooltipConfig>) {\n super();\n this.config = {\n alignment: defaultLabelAlignment,\n fontSize: defaultLabelFontSize,\n padding: defaultLabelPadding,\n color: defaultLabelColor,\n fontColor: defaultFontColor,\n visibleOpacity: defaultVisibleOpacity,\n secondsToFadeOut: defaultSecondsToFadeOut,\n ...configArg,\n };\n\n this.material = new SpriteMaterial({\n map: null,\n transparent: true,\n opacity: this.config.visibleOpacity,\n side: FrontSide,\n });\n\n this.position.set(0, 1.6, 0);\n this.visible = false;\n }\n\n public setHeightOffset(height: number) {\n this.position.y = height + this.scale.y / 2;\n }\n\n private redrawText(content: string) {\n if (content === this.content) {\n // No need to redraw if the content is the same\n return;\n }\n this.content = content;\n if (this.material.map) {\n this.material.map.dispose();\n }\n const { texture, width, height } = THREECanvasTextTexture(content, {\n bold: true,\n fontSize: this.config.fontSize * fontScale,\n paddingPx: this.config.padding,\n textColorRGB255A1: {\n r: this.config.fontColor.r * 255,\n g: this.config.fontColor.g * 255,\n b: this.config.fontColor.b * 255,\n a: 1.0,\n },\n backgroundColorRGB255A1: {\n r: this.config.color.r * 255,\n g: this.config.color.g * 255,\n b: this.config.color.b * 255,\n a: 1.0,\n },\n alignment: this.config.alignment,\n dimensions:\n this.config.maxWidth !== undefined\n ? {\n maxWidth: this.config.maxWidth,\n }\n : undefined,\n });\n\n this.material.map = texture;\n this.material.map.magFilter = LinearFilter;\n this.material.map.minFilter = LinearFilter;\n this.material.needsUpdate = true;\n\n this.scale.x = width / (100 * fontScale);\n this.scale.y = height / (100 * fontScale);\n }\n\n setText(text: string, onRemove?: () => void) {\n const sanitizedText = text.replace(/(\\r\\n|\\n|\\r)/gm, \"\");\n this.visible = true;\n this.targetOpacity = this.config.visibleOpacity;\n if (this.hideTimeout) {\n clearTimeout(this.hideTimeout);\n this.hideTimeout = null;\n }\n if (this.config.secondsToFadeOut !== null) {\n this.hideTimeout = setTimeout(() => {\n this.hideTimeout = null;\n this.hide();\n if (onRemove) {\n onRemove();\n }\n }, this.config.secondsToFadeOut * 1000);\n }\n this.redrawText(sanitizedText);\n }\n\n hide() {\n this.targetOpacity = 0;\n }\n\n show() {\n this.setText(this.content || \"\");\n }\n\n update() {\n const opacity = this.material.opacity;\n if (opacity < this.targetOpacity) {\n this.material.opacity = Math.min(\n this.material.opacity + this.fadingSpeed,\n this.targetOpacity,\n );\n } else if (opacity > this.targetOpacity) {\n this.material.opacity = Math.max(\n this.material.opacity - this.fadingSpeed,\n this.targetOpacity,\n );\n if (opacity >= 1 && this.material.transparent) {\n this.material.transparent = false;\n this.material.needsUpdate = true;\n } else if (opacity > 0 && opacity < 1 && !this.material.transparent) {\n this.material.transparent = true;\n this.material.needsUpdate = true;\n }\n if (this.material.opacity <= 0) {\n this.visible = false;\n }\n }\n }\n}\n", "import { Texture, LinearFilter, RGBAFormat } from \"three\";\n\nexport type RGBA = {\n r: number;\n g: number;\n b: number;\n a: number;\n};\n\nexport type CanvasTextOptions = {\n fontSize: number;\n textColorRGB255A1: RGBA;\n backgroundColorRGB255A1?: RGBA;\n font?: string;\n bold?: boolean;\n paddingPx?: number;\n alignment?: string;\n dimensions?:\n | {\n maxWidth?: undefined;\n width: number;\n height: number;\n }\n | {\n maxWidth: number;\n };\n};\n\nfunction getTextAlignOffset(textAlign: CanvasTextAlign, width: number) {\n switch (textAlign) {\n case \"center\":\n return width / 2;\n case \"right\":\n return width;\n default:\n return 0;\n }\n}\n\nfunction printAtWordWrap(\n context: CanvasRenderingContext2D,\n fullText: string,\n textAlign: CanvasTextAlign,\n y: number,\n lineHeight: number,\n fitWidth: number,\n padding: number,\n) {\n const x = getTextAlignOffset(textAlign, fitWidth - padding * 2);\n const lines = fullText.split(\"\\n\");\n let currentLine = 0;\n for (const text of lines) {\n fitWidth = fitWidth || 0;\n\n if (fitWidth <= 0) {\n context.fillText(text, x, y + lineHeight * currentLine);\n currentLine++;\n continue;\n }\n let words = text.split(\" \");\n let lastWordIndex = 1;\n while (words.length > 0 && lastWordIndex <= words.length) {\n const str = words.slice(0, lastWordIndex).join(\" \");\n const textWidth = context.measureText(str).width;\n if (textWidth + padding * 2 > fitWidth) {\n if (lastWordIndex === 1) {\n // Handle case where single word is too long\n const word = words[0];\n let charIndex = 1;\n while (charIndex < word.length) {\n const substring = word.substring(0, charIndex);\n const subWidth = context.measureText(substring).width;\n if (subWidth + padding * 2 > fitWidth) {\n if (charIndex === 1) charIndex = 2;\n context.fillText(\n word.substring(0, charIndex - 1),\n x + padding,\n y + lineHeight * currentLine + padding,\n );\n currentLine++;\n words[0] = word.substring(charIndex - 1);\n break;\n }\n charIndex++;\n }\n if (charIndex >= word.length) {\n lastWordIndex = 2;\n } else {\n continue;\n }\n }\n context.fillText(\n words.slice(0, lastWordIndex - 1).join(\" \"),\n x + padding,\n y + lineHeight * currentLine + padding,\n );\n currentLine++;\n words = words.splice(lastWordIndex - 1);\n lastWordIndex = 1;\n } else {\n lastWordIndex++;\n }\n }\n if (lastWordIndex > 0 && words.length > 0) {\n context.fillText(words.join(\" \"), x + padding, y + lineHeight * currentLine + padding);\n currentLine++;\n }\n }\n}\n\nexport class CanvasText {\n private canvas: HTMLCanvasElement;\n private context: CanvasRenderingContext2D;\n\n constructor() {\n this.canvas = document.createElement(\"canvas\");\n this.context = this.canvas.getContext(\"2d\") as CanvasRenderingContext2D;\n }\n\n public renderText(message: string, options: CanvasTextOptions): HTMLCanvasElement {\n const fontsize = options.fontSize;\n const textColor = options.textColorRGB255A1;\n const backgroundColor = options.backgroundColorRGB255A1 || { r: 255, g: 255, b: 255, a: 1 };\n const padding = options.paddingPx || 0;\n const font = options.font || \"Arial\";\n const fontString = (options.bold ? \"bold \" : \"\") + fontsize + \"px \" + font;\n\n // calculate text alignment offset\n const textAlign = (options.alignment as CanvasTextAlign) ?? \"left\";\n\n if (options.dimensions && options.dimensions.maxWidth === undefined) {\n // NOTE: setting the canvas dimensions resets the context properties, so\n // we always do it first\n this.canvas.width = options.dimensions.width;\n this.canvas.height = options.dimensions.height;\n this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n this.context.font = fontString;\n this.context.textAlign = textAlign;\n this.context.fillStyle = `rgba(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b}, ${backgroundColor.a})`;\n this.context.lineWidth = 0;\n this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);\n this.context.fillStyle = `rgba(${textColor.r}, ${textColor.g}, ${textColor.b}, ${textColor.a})`;\n printAtWordWrap(\n this.context,\n message,\n textAlign,\n fontsize,\n fontsize,\n this.canvas.width,\n padding,\n );\n return this.canvas;\n } else {\n this.context.font = fontString;\n this.context.textAlign = textAlign;\n const metrics = this.context.measureText(message);\n const textWidth = metrics.width;\n const textHeight = metrics.fontBoundingBoxAscent + metrics.fontBoundingBoxDescent;\n\n if (options.dimensions && options.dimensions.maxWidth !== undefined) {\n const maxWidthWithoutPadding = options.dimensions.maxWidth - padding * 2;\n if (textWidth > maxWidthWithoutPadding) {\n // This is multiple lines - estimate the lines\n const lineCount = Math.ceil(textWidth / maxWidthWithoutPadding);\n this.canvas.width = options.dimensions.maxWidth;\n this.canvas.height = textHeight * lineCount + padding * 2;\n this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n this.context.font = fontString;\n this.context.textAlign = textAlign;\n this.context.fillStyle = `rgba(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b}, ${backgroundColor.a})`;\n this.context.lineWidth = 0;\n this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);\n this.context.fillStyle = `rgba(${textColor.r}, ${textColor.g}, ${textColor.b}, ${textColor.a})`;\n printAtWordWrap(\n this.context,\n message,\n textAlign,\n fontsize,\n fontsize,\n this.canvas.width,\n padding,\n );\n return this.canvas;\n } else {\n // Allow the text to be rendered as a single line (below)\n }\n }\n\n // NOTE: setting the this.canvas dimensions resets the context properties, so\n // we always do it first. However, we also need to take into account the\n // font size to measure the text in the first place.\n this.canvas.width = textWidth + padding * 2;\n this.canvas.height = textHeight + padding * 2;\n this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);\n this.context.font = fontString;\n this.context.textAlign = textAlign;\n this.context.fillStyle = `rgba(${backgroundColor.r}, ${backgroundColor.g}, ${backgroundColor.b}, ${backgroundColor.a})`;\n this.context.lineWidth = 0;\n this.context.fillRect(0, 0, this.canvas.width, this.canvas.height);\n this.context.fillStyle = `rgba(${textColor.r}, ${textColor.g}, ${textColor.b}, ${textColor.a})`;\n this.context.fillText(\n message,\n padding + getTextAlignOffset(textAlign, textWidth),\n textHeight,\n );\n }\n\n return this.canvas;\n }\n}\n\nexport function THREECanvasTextTexture(\n text: string,\n options: CanvasTextOptions,\n): { texture: Texture; width: number; height: number } {\n const canvas = new CanvasText().renderText(text, options);\n const texture = new Texture(canvas);\n texture.minFilter = LinearFilter;\n texture.magFilter = LinearFilter;\n texture.format = RGBAFormat;\n texture.needsUpdate = true;\n\n return { texture, width: canvas.width, height: canvas.height };\n}\n", "import { PositionAndRotation } from \"@mml-io/mml-web\";\nimport { Euler, Group, Quaternion, Vector3 } from \"three\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\nimport { CollisionsManager } from \"../collisions/CollisionsManager\";\nimport { KeyInputManager } from \"../input/KeyInputManager\";\nimport { VirtualJoystick } from \"../input/VirtualJoystick\";\nimport { Composer } from \"../rendering/composer\";\nimport { TimeManager } from \"../time/TimeManager\";\nimport { TweakPane } from \"../tweakpane/TweakPane\";\n\nimport { AnimationConfig, Character, CharacterDescription } from \"./Character\";\nimport { CharacterModelLoader } from \"./CharacterModelLoader\";\nimport { AnimationState, CharacterState } from \"./CharacterState\";\nimport { LocalController } from \"./LocalController\";\nimport { RemoteController } from \"./RemoteController\";\nimport { encodeCharacterAndCamera } from \"./url-position\";\n\nexport type CharacterManagerConfig = {\n composer: Composer;\n characterModelLoader: CharacterModelLoader;\n collisionsManager: CollisionsManager;\n cameraManager: CameraManager;\n timeManager: TimeManager;\n keyInputManager: KeyInputManager;\n virtualJoystick?: VirtualJoystick;\n remoteUserStates: Map<number, CharacterState>;\n sendUpdate: (update: CharacterState) => void;\n animationConfig: AnimationConfig;\n characterResolve: (clientId: number) => {\n username: string;\n characterDescription: CharacterDescription;\n };\n updateURLLocation?: boolean;\n};\n\nexport class CharacterManager {\n public readonly headTargetOffset = new Vector3(0, 1.3, 0);\n\n private localClientId: number = 0;\n\n public remoteCharacters: Map<number, Character> = new Map();\n public remoteCharacterControllers: Map<number, RemoteController> = new Map();\n\n private localCharacterSpawned: boolean = false;\n public localController: LocalController;\n public localCharacter: Character | null = null;\n\n private speakingCharacters: Map<number, boolean> = new Map();\n\n public readonly group: Group;\n private lastUpdateSentTime: number = 0;\n\n constructor(private config: CharacterManagerConfig) {\n this.group = new Group();\n }\n\n public spawnLocalCharacter(\n id: number,\n username: string,\n characterDescription: CharacterDescription,\n spawnPosition: Vector3 = new Vector3(),\n spawnRotation: Euler = new Euler(),\n ) {\n const character = new Character({\n username,\n characterDescription,\n animationConfig: this.config.animationConfig,\n characterModelLoader: this.config.characterModelLoader,\n characterId: id,\n modelLoadedCallback: () => {\n // character loaded callback\n },\n cameraManager: this.config.cameraManager,\n composer: this.config.composer,\n isLocal: true,\n });\n const quaternion = new Quaternion().setFromEuler(character.rotation);\n this.config.sendUpdate({\n id: id,\n position: {\n x: spawnPosition.x,\n y: spawnPosition.y,\n z: spawnPosition.z,\n },\n rotation: { quaternionY: quaternion.y, quaternionW: quaternion.w },\n state: AnimationState.idle,\n });\n this.localClientId = id;\n this.localCharacter = character;\n this.localController = new LocalController({\n character: this.localCharacter,\n id: this.localClientId,\n collisionsManager: this.config.collisionsManager,\n keyInputManager: this.config.keyInputManager,\n virtualJoystick: this.config.virtualJoystick,\n cameraManager: this.config.cameraManager,\n timeManager: this.config.timeManager,\n });\n this.localCharacter.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);\n this.localCharacter.rotation.set(spawnRotation.x, spawnRotation.y, spawnRotation.z);\n this.group.add(character);\n this.localCharacterSpawned = true;\n }\n\n public setupTweakPane(tweakPane: TweakPane) {\n tweakPane.setupCharacterController(this.localController);\n }\n\n public spawnRemoteCharacter(\n id: number,\n username: string,\n characterDescription: CharacterDescription,\n spawnPosition: Vector3 = new Vector3(),\n spawnRotation: Euler = new Euler(),\n ) {\n const character = new Character({\n username,\n characterDescription,\n animationConfig: this.config.animationConfig,\n characterModelLoader: this.config.characterModelLoader,\n characterId: id,\n modelLoadedCallback: () => {\n // character loaded callback\n },\n cameraManager: this.config.cameraManager,\n composer: this.config.composer,\n isLocal: false,\n });\n\n this.remoteCharacters.set(id, character);\n character.position.set(spawnPosition.x, spawnPosition.y, spawnPosition.z);\n character.rotation.set(spawnRotation.x, spawnRotation.y, spawnRotation.z);\n const remoteController = new RemoteController({ character, id });\n this.remoteCharacterControllers.set(id, remoteController);\n this.group.add(character);\n }\n\n public getLocalCharacterPositionAndRotation(): PositionAndRotation {\n if (this.localCharacter && this.localCharacter && this.localCharacter) {\n return {\n position: this.localCharacter.position,\n rotation: this.localCharacter.rotation,\n };\n }\n return {\n position: { x: 0, y: 0, z: 0 },\n rotation: { x: 0, y: 0, z: 0 },\n };\n }\n\n public clear() {\n for (const [id, character] of this.remoteCharacters) {\n this.group.remove(character);\n this.remoteCharacters.delete(id);\n this.remoteCharacterControllers.delete(id);\n }\n if (this.localCharacter) {\n this.group.remove(this.localCharacter);\n this.localCharacter = null;\n }\n }\n\n public setSpeakingCharacter(id: number, value: boolean) {\n this.speakingCharacters.set(id, value);\n }\n\n public addSelfChatBubble(message: string) {\n if (this.localCharacter) {\n this.localCharacter.addChatBubble(message);\n }\n }\n\n public addChatBubble(id: number, message: string) {\n this.remoteCharacters.get(id)?.addChatBubble(message);\n }\n\n public respawnIfPresent(id: number) {\n const characterInfo = this.config.characterResolve(id);\n\n if (this.localCharacter && this.localClientId == id) {\n this.localCharacter.updateCharacter(\n characterInfo.username,\n characterInfo.characterDescription,\n );\n }\n\n const remoteCharacter = this.remoteCharacters.get(id);\n if (remoteCharacter) {\n remoteCharacter.updateCharacter(characterInfo.username, characterInfo.characterDescription);\n }\n }\n\n public update() {\n if (this.localCharacter) {\n this.localCharacter.update(this.config.timeManager.time, this.config.timeManager.deltaTime);\n if (this.speakingCharacters.has(this.localClientId)) {\n this.localCharacter.speakingIndicator?.setSpeaking(\n this.speakingCharacters.get(this.localClientId)!,\n );\n }\n\n this.localController.update();\n const currentTime = new Date().getTime();\n const timeSinceLastUpdate = currentTime - this.lastUpdateSentTime;\n if (timeSinceLastUpdate > 30) {\n // Limit updates to per 30ms\n this.lastUpdateSentTime = currentTime;\n this.config.sendUpdate(this.localController.networkState);\n }\n\n const targetOffset = new Vector3();\n targetOffset\n .add(this.headTargetOffset)\n .applyQuaternion(this.localCharacter.quaternion)\n .add(this.localCharacter.position);\n this.config.cameraManager.setTarget(targetOffset);\n\n for (const [id, update] of this.config.remoteUserStates) {\n if (this.remoteCharacters.has(id) && this.speakingCharacters.has(id)) {\n const character = this.remoteCharacters.get(id);\n character?.speakingIndicator?.setSpeaking(this.speakingCharacters.get(id)!);\n }\n const { position } = update;\n\n if (!this.remoteCharacters.has(id) && this.localCharacterSpawned === true) {\n const characterInfo = this.config.characterResolve(id);\n this.spawnRemoteCharacter(\n id,\n characterInfo.username,\n characterInfo.characterDescription,\n new Vector3(position.x, position.y, position.z),\n );\n }\n\n const characterController = this.remoteCharacterControllers.get(id);\n if (characterController) {\n characterController.update(\n update,\n this.config.timeManager.time,\n this.config.timeManager.deltaTime,\n );\n }\n }\n\n for (const [id, character] of this.remoteCharacters) {\n if (!this.config.remoteUserStates.has(id)) {\n character.speakingIndicator?.dispose();\n this.group.remove(character);\n this.remoteCharacters.delete(id);\n this.remoteCharacterControllers.delete(id);\n }\n }\n\n if (\n this.config.updateURLLocation &&\n this.config.timeManager.frame % 60 === 0 &&\n document.hasFocus() &&\n /*\n Don't update the URL if the camera is being controlled as some browsers (e.g. Chrome) cause a hitch to Pointer\n events when the url is updated\n */\n !this.config.cameraManager.hasActiveInput()\n ) {\n const hash = encodeCharacterAndCamera(\n this.localCharacter,\n this.config.cameraManager.camera,\n );\n const url = new URL(window.location.href);\n url.hash = hash;\n window.history.replaceState({}, \"\", url);\n }\n }\n }\n}\n", "import { Euler, Line3, Matrix4, Quaternion, Ray, Raycaster, Vector3 } from \"three\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\nimport { CollisionMeshState, CollisionsManager } from \"../collisions/CollisionsManager\";\nimport { KeyInputManager } from \"../input/KeyInputManager\";\nimport { VirtualJoystick } from \"../input/VirtualJoystick\";\nimport { TimeManager } from \"../time/TimeManager\";\nimport { characterControllerValues } from \"../tweakpane/blades/characterControlsFolder\";\n\nimport { Character } from \"./Character\";\nimport { AnimationState, CharacterState } from \"./CharacterState\";\n\nconst downVector = new Vector3(0, -1, 0);\n\nexport type LocalControllerConfig = {\n id: number;\n character: Character;\n collisionsManager: CollisionsManager;\n keyInputManager: KeyInputManager;\n virtualJoystick?: VirtualJoystick;\n cameraManager: CameraManager;\n timeManager: TimeManager;\n};\n\nexport class LocalController {\n public capsuleInfo = {\n radius: 0.4,\n segment: new Line3(new Vector3(), new Vector3(0, 1.05, 0)),\n };\n\n public gravity: number = -characterControllerValues.gravity;\n public jumpForce: number = characterControllerValues.jumpForce;\n public doubleJumpForce: number = characterControllerValues.doubleJumpForce;\n public coyoteTimeThreshold: number = characterControllerValues.coyoteJump;\n public canJump: boolean = true;\n public canDoubleJump: boolean = true;\n public coyoteJumped = false;\n public doubleJumpUsed: boolean = false;\n public jumpCounter: number = 0;\n\n public airResistance = characterControllerValues.airResistance;\n public groundResistance = 0.99999999 + characterControllerValues.groundResistance * 1e-7;\n public airControlModifier = characterControllerValues.airControlModifier;\n public groundWalkControl = characterControllerValues.groundWalkControl;\n public groundRunControl = characterControllerValues.groundRunControl;\n public baseControl = characterControllerValues.baseControlMultiplier;\n public minimumSurfaceAngle = characterControllerValues.minimumSurfaceAngle;\n\n public latestPosition: Vector3 = new Vector3();\n public characterOnGround: boolean = false;\n public coyoteTime: boolean = false;\n\n private collisionDetectionSteps = 15;\n\n private characterWasOnGround: boolean = false;\n private characterAirborneSince: number = 0;\n private currentHeight: number = 0;\n private currentSurfaceAngle = new Vector3();\n\n private characterVelocity: Vector3 = new Vector3();\n private vectorUp: Vector3 = new Vector3(0, 1, 0);\n private vectorDown: Vector3 = new Vector3(0, -1, 0);\n\n private rotationOffset: number = 0;\n private azimuthalAngle: number = 0;\n\n private tempSegment: Line3 = new Line3();\n private tempQuaternion: Quaternion = new Quaternion();\n private tempEuler: Euler = new Euler();\n private tempVector: Vector3 = new Vector3();\n private tempVector2: Vector3 = new Vector3();\n private tempVector3: Vector3 = new Vector3();\n private rayCaster: Raycaster = new Raycaster();\n\n private surfaceTempQuaternion = new Quaternion();\n private surfaceTempQuaternion2 = new Quaternion();\n private surfaceTempVector1 = new Vector3();\n private surfaceTempVector2 = new Vector3();\n private surfaceTempVector3 = new Vector3();\n private surfaceTempVector4 = new Vector3();\n private surfaceTempVector5 = new Vector3();\n private surfaceTempRay = new Ray();\n private lastFrameSurfaceState:\n | [\n CollisionMeshState,\n {\n lastMatrix: Matrix4;\n },\n ]\n | null = null;\n\n public jumpPressed: boolean = false; // Tracks if the jump button is pressed\n public jumpReleased: boolean = true; // Indicates if the jump button has been released\n\n public networkState: CharacterState;\n private controlState: { direction: number | null; isSprinting: boolean; jump: boolean } | null =\n null;\n\n constructor(private config: LocalControllerConfig) {\n this.networkState = {\n id: this.config.id,\n position: { x: 0, y: 0, z: 0 },\n rotation: { quaternionY: 0, quaternionW: 1 },\n state: AnimationState.idle,\n };\n }\n\n public update(): void {\n this.controlState =\n this.config.keyInputManager.getOutput() || this.config.virtualJoystick?.getOutput() || null;\n\n this.rayCaster.set(this.config.character.position, this.vectorDown);\n const firstRaycastHit = this.config.collisionsManager.raycastFirst(this.rayCaster.ray);\n if (firstRaycastHit !== null) {\n this.currentHeight = firstRaycastHit[0];\n this.currentSurfaceAngle.copy(firstRaycastHit[1]);\n }\n\n if (this.controlState?.direction !== null || !this.characterOnGround) {\n const targetAnimation = this.getTargetAnimation();\n this.config.character.updateAnimation(targetAnimation);\n } else {\n this.config.character.updateAnimation(AnimationState.idle);\n }\n\n if (this.controlState) {\n this.updateRotation();\n }\n\n for (let i = 0; i < this.collisionDetectionSteps; i++) {\n this.updatePosition(\n this.config.timeManager.deltaTime,\n this.config.timeManager.deltaTime / this.collisionDetectionSteps,\n i,\n );\n }\n\n // Allow the user to fall far below zero before resetting\n // TODO - Might want to make this a configurable value\n if (this.config.character.position.y < -100) {\n this.resetPosition();\n }\n this.updateNetworkState();\n }\n\n private getTargetAnimation(): AnimationState {\n if (!this.config.character) return AnimationState.idle;\n\n const jumpHeight = this.characterVelocity.y > 0 ? 0.2 : 1.8;\n if (this.currentHeight > jumpHeight && !this.characterOnGround) {\n if (this.doubleJumpUsed) {\n return AnimationState.doubleJump;\n }\n return AnimationState.air;\n }\n if (!this.controlState) {\n return AnimationState.idle;\n }\n\n if (this.controlState.isSprinting) {\n return AnimationState.running;\n }\n\n return AnimationState.walking;\n }\n\n private updateRotationOffset(): void {\n if (this.controlState && this.controlState.direction !== null) {\n this.rotationOffset = this.controlState.direction;\n }\n }\n\n private updateAzimuthalAngle(): void {\n const camToModelDistance = this.config.cameraManager.activeCamera.position.distanceTo(\n this.config.character.position,\n );\n const isCameraFirstPerson = camToModelDistance < 2;\n if (isCameraFirstPerson) {\n const cameraForward = this.tempVector\n .set(0, 0, 1)\n .applyQuaternion(this.config.cameraManager.activeCamera.quaternion);\n this.azimuthalAngle = Math.atan2(cameraForward.x, cameraForward.z);\n } else {\n this.azimuthalAngle = Math.atan2(\n this.config.cameraManager.activeCamera.position.x - this.config.character.position.x,\n this.config.cameraManager.activeCamera.position.z - this.config.character.position.z,\n );\n }\n }\n\n private computeAngularDifference(rotationQuaternion: Quaternion): number {\n return 2 * Math.acos(Math.abs(this.config.character.quaternion.dot(rotationQuaternion)));\n }\n\n private updateRotation(): void {\n this.updateRotationOffset();\n this.updateAzimuthalAngle();\n const rotationQuaternion = this.tempQuaternion.setFromAxisAngle(\n this.vectorUp,\n this.azimuthalAngle + this.rotationOffset,\n );\n const angularDifference = this.computeAngularDifference(rotationQuaternion);\n const desiredTime = 0.07;\n const angularSpeed = angularDifference / desiredTime;\n const frameRotation = angularSpeed * this.config.timeManager.deltaTime;\n this.config.character.quaternion.rotateTowards(rotationQuaternion, frameRotation);\n }\n\n private processJump(currentAcceleration: Vector3, deltaTime: number) {\n const jump = this.controlState?.jump;\n\n if (this.characterOnGround) {\n this.coyoteJumped = false;\n this.canDoubleJump = false;\n this.doubleJumpUsed = false;\n this.jumpCounter = 0;\n\n if (!jump) {\n this.canDoubleJump = !this.doubleJumpUsed && this.jumpReleased && this.jumpCounter === 1;\n this.canJump = true;\n this.jumpReleased = true;\n }\n\n if (jump && this.canJump && this.jumpReleased) {\n currentAcceleration.y += this.jumpForce / deltaTime;\n this.canJump = false;\n this.jumpReleased = false;\n this.jumpCounter++;\n } else {\n if (this.currentSurfaceAngle.y < this.minimumSurfaceAngle) {\n currentAcceleration.y += this.gravity;\n }\n }\n } else {\n if (jump && !this.coyoteJumped && this.coyoteTime) {\n this.coyoteJumped = true;\n currentAcceleration.y += this.jumpForce / deltaTime;\n this.canJump = false;\n this.jumpReleased = false;\n this.jumpCounter++;\n } else if (jump && this.canDoubleJump) {\n currentAcceleration.y += this.doubleJumpForce / deltaTime;\n this.doubleJumpUsed = true;\n this.jumpReleased = false;\n this.jumpCounter++;\n } else {\n currentAcceleration.y += this.gravity;\n this.canJump = false;\n }\n }\n\n if (!jump) {\n this.jumpReleased = true;\n if (!this.characterOnGround) {\n currentAcceleration.y += this.gravity;\n }\n }\n }\n\n private applyControls(deltaTime: number) {\n const resistance = this.characterOnGround ? this.groundResistance : this.airResistance;\n\n // Dampen the velocity based on the resistance\n const speedFactor = Math.pow(1 - resistance, deltaTime);\n this.characterVelocity.multiplyScalar(speedFactor);\n\n const acceleration = this.tempVector.set(0, 0, 0);\n this.canDoubleJump = !this.doubleJumpUsed && this.jumpReleased && this.jumpCounter === 1;\n this.processJump(acceleration, deltaTime);\n\n const control =\n (this.characterOnGround\n ? this.controlState?.isSprinting\n ? this.groundRunControl\n : this.groundWalkControl\n : this.airControlModifier) * this.baseControl;\n\n const controlAcceleration = this.tempVector2.set(0, 0, 0);\n\n if (this.controlState && this.controlState.direction !== null) {\n // convert heading to direction vector\n const heading = this.controlState.direction;\n const headingVector = this.tempVector3\n .set(0, 0, 1)\n .applyAxisAngle(this.vectorUp, this.azimuthalAngle + heading);\n controlAcceleration.add(headingVector);\n }\n if (controlAcceleration.length() > 0) {\n controlAcceleration.normalize();\n controlAcceleration.multiplyScalar(control);\n }\n acceleration.add(controlAcceleration);\n this.characterVelocity.addScaledVector(acceleration, deltaTime);\n\n this.config.character.position.addScaledVector(this.characterVelocity, deltaTime);\n }\n\n private updatePosition(deltaTime: number, stepDeltaTime: number, iter: number): void {\n this.applyControls(stepDeltaTime);\n\n if (iter === 0) {\n const lastMovement = this.getMovementFromSurfaces(this.config.character.position, deltaTime);\n if (lastMovement) {\n this.config.character.position.add(lastMovement.position);\n const asQuaternion = this.tempQuaternion.setFromEuler(this.config.character.rotation);\n const lastMovementEuler = this.tempEuler.setFromQuaternion(lastMovement.rotation);\n lastMovementEuler.x = 0;\n lastMovementEuler.z = 0;\n lastMovement.rotation.setFromEuler(lastMovementEuler);\n asQuaternion.multiply(lastMovement.rotation);\n this.config.character.rotation.setFromQuaternion(asQuaternion);\n }\n }\n\n const avatarSegment = this.tempSegment;\n avatarSegment.copy(this.capsuleInfo.segment!);\n avatarSegment.start.add(this.config.character.position);\n avatarSegment.end.add(this.config.character.position);\n\n const positionBeforeCollisions = this.tempVector.copy(avatarSegment.start);\n this.config.collisionsManager.applyColliders(avatarSegment, this.capsuleInfo.radius!);\n\n // Raycast from the top of the capsule to the bottom of the capsule to see if there is a surface intersecting the capsule\n const capsuleLength =\n this.capsuleInfo.segment.end.y -\n this.capsuleInfo.segment.start.y +\n this.capsuleInfo.radius * 2;\n // Set the origin of the ray to the bottom of the segment (1 radius length from the bottom point of the capsule)\n this.rayCaster.set(avatarSegment.start, this.vectorDown);\n\n // Amount to ignore from the start and end of the ray (to avoid unwanted collisions)\n const endIgnoreLength = 0.1;\n\n // Move the ray origin to the bottom of the capsule and then add the total length to move the ray origin to the top point of the capsule\n this.rayCaster.ray.origin.y += -this.capsuleInfo.radius + capsuleLength - endIgnoreLength;\n // Find the first mesh that intersects the ray\n const withinCapsuleRayHit = this.config.collisionsManager.raycastFirst(\n this.rayCaster.ray,\n capsuleLength - endIgnoreLength * 2,\n );\n if (withinCapsuleRayHit !== null) {\n // There is a mesh ray collision within the capsule. Move the character up to the point of the collision\n const rayHitPosition = withinCapsuleRayHit[3];\n avatarSegment.start.copy(rayHitPosition);\n // Account for the radius of the capsule\n avatarSegment.start.y += this.capsuleInfo.radius;\n }\n\n this.config.character.position.copy(avatarSegment.start);\n const deltaCollisionPosition = avatarSegment.start.sub(positionBeforeCollisions);\n\n this.characterOnGround = deltaCollisionPosition.y > 0;\n\n if (this.characterOnGround) {\n this.doubleJumpUsed = false;\n this.jumpCounter = 0;\n }\n\n if (this.characterWasOnGround && !this.characterOnGround) {\n this.characterAirborneSince = Date.now();\n }\n\n if (!this.controlState?.jump) {\n this.jumpReleased = true;\n }\n\n this.coyoteTime =\n this.characterVelocity.y < 0 &&\n !this.characterOnGround &&\n Date.now() - this.characterAirborneSince < this.coyoteTimeThreshold;\n\n this.latestPosition = this.config.character.position.clone();\n this.characterWasOnGround = this.characterOnGround;\n }\n\n public getMovementFromSurfaces(userPosition: Vector3, deltaTime: number) {\n let lastMovement: { rotation: Quaternion; position: Vector3 } | null = null;\n\n // If we have a last frame state, we can calculate the movement of the mesh to apply it to the user\n if (this.lastFrameSurfaceState !== null) {\n const meshState = this.lastFrameSurfaceState[0];\n\n // Extract the matrix from the current frame and the last frame\n const currentFrameMatrix = meshState.matrix;\n const lastFrameMatrix = this.lastFrameSurfaceState[1].lastMatrix;\n\n if (lastFrameMatrix.equals(currentFrameMatrix)) {\n // No movement from this mesh - do nothing\n } else {\n // The mesh has moved since the last frame - calculate the movement\n\n // Get the position of the mesh in the last frame\n const lastMeshPosition = this.surfaceTempVector1;\n const lastMeshRotation = this.surfaceTempQuaternion;\n lastFrameMatrix.decompose(lastMeshPosition, lastMeshRotation, this.surfaceTempVector3);\n\n // Get the position of the mesh in the current frame\n const currentMeshPosition = this.surfaceTempVector2;\n const currentMeshRotation = this.surfaceTempQuaternion2;\n currentFrameMatrix.decompose(\n currentMeshPosition,\n currentMeshRotation,\n this.surfaceTempVector3,\n );\n\n // Calculate the difference between the new position and the old position to determine the movement due to translation of position\n const meshTranslationDelta = this.surfaceTempVector5\n .copy(currentMeshPosition)\n .sub(lastMeshPosition);\n\n // Calculate the relative position of the user to the mesh in the last frame\n const lastFrameRelativeUserPosition = this.surfaceTempVector3\n .copy(userPosition)\n .sub(lastMeshPosition);\n\n // Calculate the relative quaternion of the mesh in the last frame to the mesh in the current frame\n const meshRotationDelta = lastMeshRotation.invert().multiply(currentMeshRotation);\n\n // Apply the relative quaternion to the relative user position to determine the new position of the user given just the rotation\n const translationDueToRotation = this.surfaceTempVector4\n .copy(lastFrameRelativeUserPosition)\n .applyQuaternion(meshRotationDelta)\n .sub(lastFrameRelativeUserPosition);\n\n // Combine the mesh translation delta and the rotation translation delta to determine the total movement of the user\n const translationAndRotationPositionDelta = this.surfaceTempVector1\n .copy(meshTranslationDelta)\n .add(translationDueToRotation);\n\n lastMovement = {\n position: translationAndRotationPositionDelta,\n rotation: meshRotationDelta,\n };\n lastFrameMatrix.copy(currentFrameMatrix);\n }\n }\n\n const newPosition = this.surfaceTempVector3.copy(userPosition);\n if (lastMovement) {\n newPosition.add(lastMovement.position);\n }\n newPosition.setY(newPosition.y + 0.05);\n\n // Raycast down from the new position to see if there is a surface below the user which will be tracked in the next frame\n const ray = this.surfaceTempRay.set(newPosition, downVector);\n const hit = this.config.collisionsManager.raycastFirst(ray);\n if (hit && hit[0] < 0.8) {\n // There is a surface below the user\n const currentCollisionMeshState = hit[2];\n this.lastFrameSurfaceState = [\n currentCollisionMeshState,\n { lastMatrix: currentCollisionMeshState.matrix.clone() },\n ];\n } else {\n if (this.lastFrameSurfaceState !== null && lastMovement) {\n // Apply the last movement to the user's velocity\n this.characterVelocity.add(\n lastMovement.position.clone().divideScalar(deltaTime), // The position delta is the result of one tick which is deltaTime seconds, so we need to divide by deltaTime to get the velocity per second\n );\n }\n this.lastFrameSurfaceState = null;\n }\n return lastMovement;\n }\n\n private updateNetworkState(): void {\n const characterQuaternion = this.config.character.getWorldQuaternion(this.tempQuaternion);\n const cameraQuaternion = new Quaternion();\n this.config.cameraManager.camera.getWorldQuaternion(cameraQuaternion);\n this.networkState = {\n id: this.config.id,\n position: {\n x: this.config.character.position.x,\n y: this.config.character.position.y,\n z: this.config.character.position.z,\n },\n rotation: { quaternionY: characterQuaternion.y, quaternionW: characterQuaternion.w },\n camPosition: {\n x: this.config.cameraManager.camera.position.x,\n y: this.config.cameraManager.camera.position.y,\n z: this.config.cameraManager.camera.position.z,\n },\n camQuaternion: {\n y: cameraQuaternion.y,\n w: cameraQuaternion.w,\n },\n state: this.config.character.getCurrentAnimation(),\n };\n }\n\n private resetPosition(): void {\n this.characterVelocity.y = 0;\n this.config.character.position.y = 3;\n this.characterOnGround = false;\n this.doubleJumpUsed = false;\n this.jumpReleased = true;\n this.jumpCounter = 0;\n }\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { BladeApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nimport { LocalController } from \"../../character/LocalController\";\n\nexport const characterControllerValues = {\n gravity: 35.5,\n jumpForce: 18,\n doubleJumpForce: 17.7,\n coyoteJump: 120,\n airResistance: 0.5,\n groundResistance: 0,\n airControlModifier: 0.05,\n groundWalkControl: 0.75,\n groundRunControl: 1.0,\n baseControlMultiplier: 200,\n minimumSurfaceAngle: 0.905,\n};\n\nexport const characterControllerOptions = {\n gravity: { min: 1, max: 100, step: 0.05 },\n jumpForce: { min: 1, max: 50, step: 0.05 },\n doubleJumpForce: { min: 1, max: 50, step: 0.05 },\n coyoteJump: { min: 60, max: 200, step: 1 },\n airResistance: { min: 0.01, max: 0.9, step: 0.01 },\n groundResistance: { min: -100, max: 0, step: 1 },\n airControlModifier: { min: 0.001, max: 0.15, step: 0.01 },\n groundWalkControl: { min: 0.1, max: 1.5, step: 0.01 },\n groundRunControl: { min: 0.5, max: 2.0, step: 0.01 },\n baseControlMultiplier: { min: 150, max: 300, step: 1 },\n minimumSurfaceAngle: { min: 0.254, max: 1, step: 0.001 },\n};\n\ntype CharacterData = {\n position: string;\n onGround: string;\n canJump: string;\n canDoubleJump: string;\n jumpCount: string;\n coyoteTime: string;\n coyoteJumped: string;\n};\n\nexport class CharacterControlsFolder {\n public folder: FolderApi;\n\n private characterData: CharacterData = {\n position: \"(0, 0, 0)\",\n onGround: \"false\",\n canJump: \"false\",\n canDoubleJump: \"false\",\n jumpCount: \"0\",\n coyoteTime: \"false\",\n coyoteJumped: \"false\",\n };\n\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({ title: \"character\", expanded: expand });\n this.folder.addBinding(this.characterData, \"position\", { readonly: true });\n this.folder.addBinding(this.characterData, \"onGround\", { readonly: true });\n this.folder.addBinding(this.characterData, \"canJump\", { readonly: true });\n this.folder.addBinding(this.characterData, \"canDoubleJump\", { readonly: true });\n this.folder.addBinding(this.characterData, \"jumpCount\", { readonly: true });\n this.folder.addBinding(this.characterData, \"coyoteTime\", { readonly: true });\n this.folder.addBinding(this.characterData, \"coyoteJumped\", { readonly: true });\n this.folder.addBinding(\n characterControllerValues,\n \"gravity\",\n characterControllerOptions.gravity,\n );\n this.folder.addBinding(\n characterControllerValues,\n \"jumpForce\",\n characterControllerOptions.jumpForce,\n );\n this.folder.addBinding(\n characterControllerValues,\n \"doubleJumpForce\",\n characterControllerOptions.doubleJumpForce,\n );\n this.folder.addBinding(\n characterControllerValues,\n \"coyoteJump\",\n characterControllerOptions.coyoteJump,\n );\n this.folder.addBinding(\n characterControllerValues,\n \"airResistance\",\n characterControllerOptions.airResistance,\n );\n this.folder.addBinding(\n characterControllerValues,\n \"groundResistance\",\n characterControllerOptions.groundResistance,\n );\n this.folder.addBinding(\n characterControllerValues,\n \"airControlModifier\",\n characterControllerOptions.airControlModifier,\n );\n this.folder.addBinding(\n characterControllerValues,\n \"groundWalkControl\",\n characterControllerOptions.groundWalkControl,\n );\n this.folder.addBinding(\n characterControllerValues,\n \"groundRunControl\",\n characterControllerOptions.groundRunControl,\n );\n this.folder.addBinding(\n characterControllerValues,\n \"baseControlMultiplier\",\n characterControllerOptions.baseControlMultiplier,\n );\n this.folder.addBinding(\n characterControllerValues,\n \"minimumSurfaceAngle\",\n characterControllerOptions.minimumSurfaceAngle,\n );\n }\n\n public setupChangeEvent(localController: LocalController): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"gravity\": {\n const value = e.value as number;\n localController.gravity = value * -1;\n break;\n }\n case \"jumpForce\": {\n const value = e.value as number;\n localController.jumpForce = value;\n break;\n }\n case \"doubleJumpForce\": {\n const value = e.value as number;\n localController.doubleJumpForce = value;\n break;\n }\n case \"coyoteJump\": {\n const value = e.value as number;\n localController.coyoteTimeThreshold = value;\n break;\n }\n case \"airResistance\": {\n const value = e.value as number;\n localController.airResistance = value;\n break;\n }\n case \"groundResistance\": {\n const value = e.value as number;\n localController.groundResistance = 0.99999999 + value * 1e-6;\n break;\n }\n case \"airControlModifier\": {\n const value = e.value as number;\n localController.airControlModifier = value;\n break;\n }\n case \"groundWalkControl\": {\n const value = e.value as number;\n localController.groundWalkControl = value;\n break;\n }\n case \"groundRunControl\": {\n const value = e.value as number;\n localController.groundRunControl = value;\n break;\n }\n case \"baseControlMultiplier\": {\n const value = e.value as number;\n localController.baseControl = value;\n break;\n }\n case \"minimumSurfaceAngle\": {\n const value = e.value as number;\n localController.minimumSurfaceAngle = value;\n break;\n }\n default:\n break;\n }\n });\n }\n\n public update(localController: LocalController): void {\n const { x, y, z } = localController.latestPosition;\n this.characterData.position = `(${x.toFixed(2)}, ${y.toFixed(2)}, ${z.toFixed(2)})`;\n this.characterData.onGround = `${localController.characterOnGround}`;\n this.characterData.canJump = `${localController.canJump || localController.coyoteTime ? \"true\" : \"false\"}`;\n this.characterData.canDoubleJump = `${localController.canDoubleJump}`;\n this.characterData.jumpCount = `${localController.jumpCounter}`;\n this.characterData.coyoteTime = `${localController.coyoteTime}`;\n this.characterData.coyoteJumped = `${localController.coyoteJumped}`;\n }\n}\n", "import { Quaternion, Vector3 } from \"three\";\n\nimport { Character } from \"./Character\";\nimport { AnimationState, CharacterState } from \"./CharacterState\";\n\nexport type RemoteControllerConfig = {\n id: number;\n character: Character;\n};\n\nconst tempQuaternion = new Quaternion();\n\nexport class RemoteController {\n public currentAnimation: AnimationState = AnimationState.idle;\n\n public networkState: CharacterState;\n\n constructor(private config: RemoteControllerConfig) {\n this.networkState = {\n id: this.config.id,\n position: {\n x: this.config.character.position.x,\n y: this.config.character.position.y,\n z: this.config.character.position.z,\n },\n rotation: {\n quaternionY: tempQuaternion.setFromEuler(this.config.character.rotation).y,\n quaternionW: 1,\n },\n state: this.currentAnimation as AnimationState,\n };\n }\n\n public update(clientUpdate: CharacterState, time: number, deltaTime: number): void {\n if (!this.config.character) {\n return;\n }\n this.updateFromNetwork(clientUpdate);\n this.config.character.update(time, deltaTime);\n }\n\n private updateFromNetwork(clientUpdate: CharacterState): void {\n const { position, rotation, state } = clientUpdate;\n this.config.character.position.lerp(new Vector3(position.x, position.y, position.z), 0.15);\n const rotationQuaternion = new Quaternion(0, rotation.quaternionY, 0, rotation.quaternionW);\n this.config.character.quaternion.slerp(rotationQuaternion, 0.6);\n if (state !== this.currentAnimation) {\n this.currentAnimation = state;\n this.config.character.updateAnimation(state);\n }\n }\n}\n", "import { Object3D, Quaternion, Vector3 } from \"three\";\n\nimport { toArray } from \"../helpers/math-helpers\";\n\nexport function encodeCharacterAndCamera(character: Object3D, camera: Object3D): string {\n return [\n ...toArray(character.position),\n ...toArray(character.quaternion),\n ...toArray(camera.position),\n ...toArray(camera.quaternion),\n ].join(\",\");\n}\n\nexport function decodeCharacterAndCamera(hash: string): {\n character: { position: Vector3; quaternion: Quaternion };\n camera: { position: Vector3; quaternion: Quaternion };\n} {\n const values = hash.split(\",\").map(Number);\n return {\n character: {\n position: new Vector3(values[0], values[1], values[2]),\n quaternion: new Quaternion(values[3], values[4], values[5], values[6]),\n },\n camera: {\n position: new Vector3(values[7], values[8], values[9]),\n quaternion: new Quaternion(values[10], values[11], values[12], values[13]),\n },\n };\n}\n", "import { ModelLoader, ModelLoadResult } from \"@mml-io/model-loader\";\nimport { AnimationClip, Object3D } from \"three\";\nimport { GLTF } from \"three/examples/jsm/loaders/GLTFLoader.js\";\n\nclass LRUCache<K, V> {\n private maxSize: number;\n private cache: Map<K, V>;\n\n constructor(maxSize: number = 100) {\n this.maxSize = maxSize;\n this.cache = new Map();\n }\n\n get(key: K): V | undefined {\n const item = this.cache.get(key);\n if (item) {\n this.cache.delete(key);\n this.cache.set(key, item);\n }\n return item;\n }\n\n set(key: K, value: V): void {\n if (this.cache.size >= this.maxSize) {\n const oldestKey = this.cache.keys().next().value;\n this.cache.delete(oldestKey);\n }\n this.cache.set(key, value);\n }\n}\n\ninterface CachedModel {\n blob: Blob;\n originalExtension: string;\n}\n\nexport class CharacterModelLoader {\n private readonly modelLoader: ModelLoader = new ModelLoader();\n private modelCache: LRUCache<string, CachedModel>;\n private ongoingLoads: Map<string, Promise<CachedModel>> = new Map();\n\n constructor(\n maxCacheSize: number = 100,\n private debug: boolean = false,\n ) {\n this.modelCache = new LRUCache(maxCacheSize);\n }\n\n async load(fileUrl: string, fileType: \"model\"): Promise<Object3D | undefined>;\n async load(fileUrl: string, fileType: \"animation\"): Promise<AnimationClip | undefined>;\n async load(\n fileUrl: string,\n fileType: \"model\" | \"animation\",\n ): Promise<Object3D | AnimationClip | undefined> {\n const cachedModel = this.modelCache.get(fileUrl);\n\n if (cachedModel) {\n return this.loadFromUrl(fileUrl, fileType, cachedModel.originalExtension);\n } else {\n if (this.debug === true) {\n console.log(`Loading ${fileUrl} from server`);\n }\n const ongoingLoad = this.ongoingLoads.get(fileUrl);\n if (ongoingLoad)\n return ongoingLoad.then((loadedModel) => {\n const blobURL = URL.createObjectURL(loadedModel.blob);\n return this.loadFromUrl(blobURL, fileType, loadedModel.originalExtension);\n });\n\n const loadPromise: Promise<CachedModel> = fetch(fileUrl)\n .then((response) => response.blob())\n .then((blob) => {\n const originalExtension = fileUrl.split(\".\").pop() || \"\";\n const cached = { blob, originalExtension };\n this.modelCache.set(fileUrl, cached);\n this.ongoingLoads.delete(fileUrl);\n return cached;\n });\n\n this.ongoingLoads.set(fileUrl, loadPromise);\n return loadPromise.then((loadedModel) => {\n const blobURL = URL.createObjectURL(loadedModel.blob);\n return this.loadFromUrl(blobURL, fileType, loadedModel.originalExtension);\n });\n }\n }\n\n private async loadFromUrl(\n url: string,\n fileType: \"model\" | \"animation\",\n extension: string,\n ): Promise<Object3D | AnimationClip | undefined> {\n return new Promise(async (resolve, reject) => {\n const modelLoadResult: ModelLoadResult = await this.modelLoader.load(\n url,\n (loaded: number, total: number) => {\n // no-op\n },\n );\n if (fileType === \"model\") {\n resolve(modelLoadResult.group as Object3D);\n } else if (fileType === \"animation\") {\n resolve(modelLoadResult.animations[0] as AnimationClip);\n } else {\n const error = `Trying to load unknown ${fileType} type of element from file ${url}`;\n console.error(error);\n reject(error);\n }\n });\n }\n}\n", "import { EventHandlerCollection } from \"./EventHandlerCollection\";\nimport { VirtualJoystick } from \"./VirtualJoystick\";\n\nexport enum Key {\n W = \"w\",\n A = \"a\",\n S = \"s\",\n D = \"d\",\n SHIFT = \"shift\",\n SPACE = \" \",\n C = \"c\",\n}\n\ntype KeyCallback = () => void;\ntype BindingsType = Map<Key, KeyCallback>;\n\nexport class KeyInputManager {\n private keys = new Map<string, boolean>();\n private eventHandlerCollection = new EventHandlerCollection();\n private bindings: BindingsType = new Map();\n\n constructor(private shouldCaptureKeyPress: () => boolean = () => true) {\n this.eventHandlerCollection.add(document, \"keydown\", this.onKeyDown.bind(this));\n this.eventHandlerCollection.add(document, \"keyup\", this.onKeyUp.bind(this));\n this.eventHandlerCollection.add(window, \"blur\", this.handleUnfocus.bind(this));\n }\n\n private handleUnfocus(_event: FocusEvent): void {\n this.keys.clear();\n }\n\n private onKeyDown(event: KeyboardEvent): void {\n if (this.shouldCaptureKeyPress()) {\n if (event.key.length === 2 && event.key[0] === \"F\") {\n // Ignore all Function keys\n return;\n }\n if (event.metaKey) {\n // Ignore all meta keys (e.g. Alt, Cmd)\n return;\n }\n this.keys.set(event.key.toLowerCase(), true);\n event.preventDefault();\n }\n }\n\n private onKeyUp(event: KeyboardEvent): void {\n this.keys.set(event.key.toLowerCase(), false);\n if (this.bindings.has(event.key.toLowerCase() as Key)) {\n this.bindings.get(event.key.toLowerCase() as Key)!();\n }\n }\n\n public isKeyPressed(key: string): boolean {\n return this.keys.get(key) || false;\n }\n\n public createKeyBinding(key: Key, callback: () => void): void {\n this.bindings.set(key, callback);\n }\n\n public isMovementKeyPressed(): boolean {\n return [Key.W, Key.A, Key.S, Key.D].some((key) => this.isKeyPressed(key));\n }\n\n private getForward(): boolean {\n return this.isKeyPressed(Key.W);\n }\n\n private getBackward(): boolean {\n return this.isKeyPressed(Key.S);\n }\n\n private getLeft(): boolean {\n return this.isKeyPressed(Key.A);\n }\n\n private getRight(): boolean {\n return this.isKeyPressed(Key.D);\n }\n\n private getRun(): boolean {\n return this.isKeyPressed(Key.SHIFT);\n }\n\n private getJump(): boolean {\n return this.isKeyPressed(Key.SPACE);\n }\n\n public getOutput(): { direction: number | null; isSprinting: boolean; jump: boolean } | null {\n const dx = (this.getRight() ? 1 : 0) - (this.getLeft() ? 1 : 0);\n const dy = (this.getBackward() ? 1 : 0) - (this.getForward() ? 1 : 0);\n const jump = this.getJump();\n if (dx === 0 && dy === 0) {\n if (this.getJump()) {\n return { direction: null, isSprinting: false, jump };\n }\n return null;\n }\n const direction = Math.atan2(dx, dy);\n return { direction, isSprinting: this.getRun(), jump };\n }\n\n public dispose() {\n this.eventHandlerCollection.clear();\n this.bindings.clear();\n }\n}\n", "interface VirtualJoyStickConfig {\n radius?: number;\n innerRadius?: number;\n mouseSupport?: boolean;\n}\n\nconst sprintingThreshold = 0.6;\n\nexport class VirtualJoystick {\n private radius: number;\n private innerRadius: number;\n private mouseSupport: boolean;\n\n private element: HTMLDivElement;\n\n private joystickBaseElement: HTMLSpanElement;\n private joystickCenterElement: HTMLSpanElement;\n private joystickPointerId: number | null = null;\n private joystickOutput: { direction: number; isSprinting: boolean } | null = null;\n\n private jumpButton: HTMLButtonElement;\n private jumpPointerId: number | null = null;\n\n constructor(\n private holderElement: HTMLElement,\n private config: VirtualJoyStickConfig,\n ) {\n this.radius = config.radius || 50;\n this.innerRadius = config.innerRadius || this.radius / 2;\n this.mouseSupport = this.checkTouch() || config.mouseSupport === true;\n\n this.element = document.createElement(\"div\");\n const style = this.element.style;\n style.display = this.mouseSupport ? \"flex\" : \"none\";\n style.position = \"absolute\";\n style.width = `100%`;\n style.height = `200px`;\n style.bottom = \"50px\";\n style.zIndex = \"10000\";\n style.alignItems = \"center\";\n style.justifyContent = \"space-between\";\n style.pointerEvents = \"none\";\n style.padding = \"20px\";\n style.boxSizing = \"border-box\";\n style.userSelect = \"none\";\n this.holderElement.appendChild(this.element);\n\n this.joystickBaseElement = this.createBase();\n this.element.appendChild(this.joystickBaseElement);\n\n this.joystickCenterElement = this.createCenter();\n this.joystickBaseElement.appendChild(this.joystickCenterElement);\n\n this.jumpButton = this.createJumpButton();\n this.element.appendChild(this.jumpButton);\n\n this.bindEvents();\n\n this.clearJoystickState();\n }\n\n public static checkForTouch(): boolean {\n try {\n document.createEvent(\"TouchEvent\");\n return true;\n } catch (e) {\n return false;\n }\n }\n\n private checkTouch() {\n return VirtualJoystick.checkForTouch();\n }\n\n private createBase() {\n const base = document.createElement(\"span\");\n const style = base.style;\n style.touchAction = \"pinch-zoom\";\n style.width = `${this.radius * 2}px`;\n style.height = `${this.radius * 2}px`;\n style.position = \"relative\";\n style.display = \"block\";\n style.borderRadius = \"50%\";\n style.borderColor = \"rgba(200,200,200,0.5)\";\n style.borderWidth = \"2px\";\n style.borderStyle = \"solid\";\n style.pointerEvents = \"auto\";\n style.userSelect = \"none\";\n return base;\n }\n\n private createCenter() {\n const center = document.createElement(\"div\");\n const style = center.style;\n style.width = `${this.innerRadius * 2}px`;\n style.height = `${this.innerRadius * 2}px`;\n style.position = \"absolute\";\n style.borderRadius = \"50%\";\n style.backgroundColor = \"rgba(200,200,200,0.3)\";\n style.borderWidth = \"1px\";\n style.borderColor = \"rgba(200,200,200,0.8)\";\n style.borderStyle = \"solid\";\n style.userSelect = \"none\";\n return center;\n }\n\n private createJumpButton() {\n const button = document.createElement(\"button\");\n button.textContent = \"JUMP\";\n const style = button.style;\n style.touchAction = \"pinch-zoom\";\n style.width = `100px`;\n style.height = `100px`;\n style.borderRadius = \"20px\";\n style.color = \"white\";\n style.font = \"Helvetica, sans-serif\";\n style.fontSize = \"16px\";\n style.backgroundColor = \"rgba(200,200,200,0.3)\";\n style.color = \"rgba(220,220,220,1)\";\n style.borderWidth = \"1px\";\n style.borderColor = \"rgba(200,200,200,0.8)\";\n style.borderStyle = \"solid\";\n style.pointerEvents = \"auto\";\n style.userSelect = \"none\";\n return button;\n }\n\n private bindEvents(): void {\n this.joystickBaseElement.addEventListener(\"pointerdown\", this.onJoystickPointerDown.bind(this));\n this.joystickBaseElement.addEventListener(\n \"contextmenu\",\n this.preventDefaultAndStopPropagation.bind(this),\n );\n this.joystickBaseElement.addEventListener(\n \"touchstart\",\n this.preventDefaultAndStopPropagation.bind(this),\n );\n\n this.jumpButton.addEventListener(\"pointerdown\", this.onJumpPointerDown.bind(this));\n this.jumpButton.addEventListener(\n \"contextmenu\",\n this.preventDefaultAndStopPropagation.bind(this),\n );\n this.jumpButton.addEventListener(\n \"touchstart\",\n this.preventDefaultAndStopPropagation.bind(this),\n );\n document.addEventListener(\"pointermove\", this.onPointerMove.bind(this));\n document.addEventListener(\"pointerup\", this.onPointerUp.bind(this));\n document.addEventListener(\"pointercancel\", this.onPointerUp.bind(this));\n }\n\n private preventDefaultAndStopPropagation(evt: PointerEvent): void {\n evt.preventDefault();\n evt.stopPropagation();\n }\n\n private onJumpPointerDown(evt: PointerEvent): void {\n if (this.jumpPointerId === null) {\n this.jumpPointerId = evt.pointerId;\n }\n }\n\n private onJoystickPointerDown(evt: PointerEvent): void {\n evt.preventDefault();\n evt.stopPropagation();\n if (evt.buttons !== 1) {\n return;\n }\n if (this.joystickPointerId === null) {\n this.joystickPointerId = evt.pointerId;\n this.updateControlAndDirection(evt);\n }\n }\n\n private onPointerMove(evt: PointerEvent): void {\n evt.preventDefault();\n evt.stopPropagation();\n if (evt.pointerId !== this.joystickPointerId) {\n return;\n }\n this.updateControlAndDirection(evt);\n }\n\n private onPointerUp(evt: PointerEvent): void {\n evt.preventDefault();\n evt.stopPropagation();\n\n if (evt.pointerId === this.jumpPointerId) {\n this.jumpPointerId = null;\n }\n if (evt.pointerId === this.joystickPointerId) {\n this.joystickPointerId = null;\n this.clearJoystickState();\n }\n }\n\n private clearJoystickState = (): void => {\n this.joystickOutput = null;\n this.joystickCenterElement.style.left = `${this.radius - this.innerRadius}px`;\n this.joystickCenterElement.style.top = `${this.radius - this.innerRadius}px`;\n };\n\n private updateControlAndDirection(input: PointerEvent): void {\n const rect = this.joystickBaseElement.getBoundingClientRect();\n const dx = input.clientX - (rect.left + this.radius);\n const dy = input.clientY - (rect.top + this.radius);\n\n const distance = Math.min(Math.sqrt(dx * dx + dy * dy), this.radius);\n const angle = Math.atan2(dy, dx);\n const constrainedX = distance * Math.cos(angle);\n const constrainedY = distance * Math.sin(angle);\n\n this.joystickCenterElement.style.left = `${constrainedX + this.radius - this.innerRadius}px`;\n this.joystickCenterElement.style.top = `${constrainedY + this.radius - this.innerRadius}px`;\n\n const direction = Math.atan2(dx, dy);\n const speed = distance / this.radius;\n const isSprinting = speed > sprintingThreshold;\n this.joystickOutput = { direction, isSprinting };\n }\n\n public getOutput(): { direction: number | null; isSprinting: boolean; jump: boolean } | null {\n const jump = this.jumpPointerId !== null;\n if (!this.joystickOutput) {\n if (jump) {\n return { direction: null, isSprinting: false, jump: jump };\n }\n return null;\n }\n return {\n ...this.joystickOutput,\n jump: jump,\n };\n }\n}\n", "import {\n ChatProbe,\n IMMLScene,\n Interaction,\n InteractionListener,\n InteractionManager,\n LinkProps,\n LoadingProgressManager,\n MElement,\n MMLDocumentTimeManager,\n PositionAndRotation,\n PromptManager,\n PromptProps,\n} from \"@mml-io/mml-web\";\nimport {\n ThreeJSClickTrigger,\n ThreeJSGraphicsAdapter,\n ThreeJSGraphicsInterface,\n ThreeJSInteractionAdapter,\n} from \"@mml-io/mml-web-threejs\";\nimport { AudioListener, Group, Object3D, PerspectiveCamera, Scene, WebGLRenderer } from \"three\";\n\nimport { CollisionsManager } from \"../collisions/CollisionsManager\";\n\ntype MMLCompositionSceneConfig = {\n targetElement: HTMLElement;\n renderer: WebGLRenderer;\n scene: Scene;\n camera: PerspectiveCamera;\n audioListener: AudioListener;\n collisionsManager: CollisionsManager;\n getUserPositionAndRotation: () => PositionAndRotation;\n};\n\nexport class MMLCompositionScene {\n public group: Group;\n\n public readonly mmlScene: IMMLScene<ThreeJSGraphicsAdapter>;\n public readonly documentTimeManager: MMLDocumentTimeManager;\n private readonly promptManager: PromptManager;\n private readonly interactionManager: InteractionManager;\n private readonly interactionListener: InteractionListener<ThreeJSGraphicsAdapter>;\n private readonly chatProbes = new Set<ChatProbe<ThreeJSGraphicsAdapter>>();\n private readonly clickTrigger: ThreeJSClickTrigger;\n private readonly loadingProgressManager: LoadingProgressManager;\n\n constructor(private config: MMLCompositionSceneConfig) {\n this.group = new Group();\n this.promptManager = PromptManager.init(this.config.targetElement);\n\n const graphicsAdapter: ThreeJSGraphicsAdapter = {\n collisionType: null as unknown as Object3D,\n containerType: null as unknown as Object3D,\n getGraphicsAdapterFactory: () => {\n return ThreeJSGraphicsInterface;\n },\n getRootContainer: () => {\n return this.group;\n },\n interactionShouldShowDistance(\n interaction: Interaction<ThreeJSGraphicsAdapter>,\n ): number | null {\n return ThreeJSInteractionAdapter.interactionShouldShowDistance(\n interaction,\n this.config.camera,\n this.config.scene,\n );\n },\n dispose(): void {},\n getAudioListener: () => {\n return config.audioListener;\n },\n getCamera: () => {\n return config.camera;\n },\n getThreeScene: () => {\n return config.scene;\n },\n getUserPositionAndRotation: () => {\n return this.config.getUserPositionAndRotation();\n },\n };\n\n const { interactionListener, interactionManager } = InteractionManager.init(\n this.config.targetElement,\n (interaction: Interaction<ThreeJSGraphicsAdapter>) => {\n return graphicsAdapter.interactionShouldShowDistance(interaction);\n },\n );\n this.interactionManager = interactionManager;\n this.interactionListener = interactionListener;\n this.loadingProgressManager = new LoadingProgressManager();\n this.documentTimeManager = new MMLDocumentTimeManager();\n\n this.mmlScene = {\n getGraphicsAdapter(): ThreeJSGraphicsAdapter {\n return graphicsAdapter;\n },\n hasGraphicsAdapter(): boolean {\n return true;\n },\n addCollider: (object: Object3D, mElement: MElement<ThreeJSGraphicsAdapter>) => {\n this.config.collisionsManager.addMeshesGroup(object as Group, mElement);\n },\n updateCollider: (object: Object3D) => {\n this.config.collisionsManager.updateMeshesGroup(object as Group);\n },\n removeCollider: (object: Object3D) => {\n this.config.collisionsManager.removeMeshesGroup(object as Group);\n },\n getUserPositionAndRotation: this.config.getUserPositionAndRotation,\n addInteraction: (interaction: Interaction<ThreeJSGraphicsAdapter>) => {\n this.interactionListener.addInteraction(interaction);\n },\n updateInteraction: (interaction: Interaction<ThreeJSGraphicsAdapter>) => {\n this.interactionListener.updateInteraction(interaction);\n },\n removeInteraction: (interaction: Interaction<ThreeJSGraphicsAdapter>) => {\n this.interactionListener.removeInteraction(interaction);\n },\n addChatProbe: (chatProbe: ChatProbe<ThreeJSGraphicsAdapter>) => {\n this.chatProbes.add(chatProbe);\n },\n updateChatProbe: () => {\n // no-op\n },\n removeChatProbe: (chatProbe: ChatProbe<ThreeJSGraphicsAdapter>) => {\n this.chatProbes.delete(chatProbe);\n },\n prompt: (\n promptProps: PromptProps,\n abortSignal: AbortSignal,\n callback: (message: string | null) => void,\n ) => {\n this.promptManager.prompt(promptProps, abortSignal, callback);\n },\n link: (\n linkProps: LinkProps,\n abortSignal: AbortSignal,\n windowCallback: (openedWindow: Window | null) => void,\n ) => {\n this.promptManager.link(linkProps, abortSignal, windowCallback);\n },\n getLoadingProgressManager: () => {\n return this.loadingProgressManager;\n },\n };\n\n this.clickTrigger = ThreeJSClickTrigger.init(\n this.config.targetElement,\n this.group,\n this.config.camera,\n );\n }\n\n onChatMessage(message: string) {\n for (const chatProbe of this.chatProbes) {\n chatProbe.trigger(message);\n }\n }\n\n dispose() {\n this.promptManager.dispose();\n this.clickTrigger.dispose();\n this.interactionManager.dispose();\n }\n}\n", "import * as EssentialsPlugin from \"@tweakpane/plugin-essentials\";\nimport {\n BloomEffect,\n EffectComposer,\n EffectPass,\n NormalPass,\n SSAOEffect,\n ToneMappingEffect,\n} from \"postprocessing\";\nimport { Scene, WebGLRenderer } from \"three\";\nimport { FolderApi, Pane } from \"tweakpane\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\nimport { LocalController } from \"../character/LocalController\";\nimport { EventHandlerCollection } from \"../input/EventHandlerCollection\";\nimport { BrightnessContrastSaturation } from \"../rendering/post-effects/bright-contrast-sat\";\nimport { GaussGrainEffect } from \"../rendering/post-effects/gauss-grain\";\nimport { Sun } from \"../sun/Sun\";\nimport { TimeManager } from \"../time/TimeManager\";\n\nimport { BrightnessContrastSaturationFolder } from \"./blades/bcsFolder\";\nimport { CameraFolder } from \"./blades/cameraFolder\";\nimport { CharacterControlsFolder } from \"./blades/characterControlsFolder\";\nimport { CharacterFolder } from \"./blades/characterFolder\";\nimport { EnvironmentFolder } from \"./blades/environmentFolder\";\nimport { PostExtrasFolder } from \"./blades/postExtrasFolder\";\nimport { RendererFolder, rendererValues } from \"./blades/rendererFolder\";\nimport { RendererStatsFolder } from \"./blades/rendererStatsFolder\";\nimport { SSAOFolder } from \"./blades/ssaoFolder\";\nimport { ToneMappingFolder } from \"./blades/toneMappingFolder\";\nimport { setTweakpaneActive } from \"./tweakPaneActivity\";\nimport { tweakPaneStyle } from \"./tweakPaneStyle\";\n\nexport class TweakPane {\n private gui: Pane;\n\n private renderStatsFolder: RendererStatsFolder;\n private rendererFolder: RendererFolder;\n private toneMappingFolder: ToneMappingFolder;\n private ssaoFolder: SSAOFolder;\n private bcsFolder: BrightnessContrastSaturationFolder;\n private postExtrasFolder: PostExtrasFolder;\n // @ts-ignore\n private character: CharacterFolder;\n private environment: EnvironmentFolder;\n private camera: CameraFolder;\n private characterControls: CharacterControlsFolder;\n\n private export: FolderApi;\n\n private saveVisibilityInLocalStorage: boolean = true;\n public guiVisible: boolean = false;\n private tweakPaneWrapper: HTMLDivElement;\n private eventHandlerCollection: EventHandlerCollection;\n\n constructor(\n private holderElement: HTMLElement,\n private renderer: WebGLRenderer,\n private scene: Scene,\n private composer: EffectComposer,\n ) {\n this.tweakPaneWrapper = document.createElement(\"div\");\n this.tweakPaneWrapper.style.position = \"fixed\";\n this.tweakPaneWrapper.style.width = \"400px\";\n this.tweakPaneWrapper.style.height = \"100%\";\n this.tweakPaneWrapper.style.top = \"0px\";\n this.tweakPaneWrapper.style.right = \"calc(-50vw)\";\n this.tweakPaneWrapper.style.zIndex = \"99\";\n this.tweakPaneWrapper.style.overflow = \"auto\";\n this.tweakPaneWrapper.style.backgroundColor = \"rgba(0, 0, 0, 0.66)\";\n this.tweakPaneWrapper.style.paddingLeft = \"5px\";\n this.tweakPaneWrapper.style.boxShadow = \"-7px 0px 12px rgba(0, 0, 0, 0.5)\";\n this.tweakPaneWrapper.style.transition = \"right cubic-bezier(0.83, 0, 0.17, 1) 0.7s\";\n holderElement.appendChild(this.tweakPaneWrapper);\n\n this.gui = new Pane({ container: this.tweakPaneWrapper! });\n this.gui.registerPlugin(EssentialsPlugin);\n\n if (this.saveVisibilityInLocalStorage) {\n const localStorageGuiVisible = localStorage.getItem(\"guiVisible\");\n if (localStorageGuiVisible !== null) {\n if (localStorageGuiVisible === \"true\") {\n this.guiVisible = true;\n } else if (localStorageGuiVisible === \"false\") {\n this.guiVisible = false;\n }\n }\n }\n\n const styleElement = document.createElement(\"style\");\n styleElement.type = \"text/css\";\n styleElement.appendChild(document.createTextNode(tweakPaneStyle));\n document.head.appendChild(styleElement);\n\n this.renderStatsFolder = new RendererStatsFolder(this.gui, true);\n this.rendererFolder = new RendererFolder(this.gui, false);\n this.toneMappingFolder = new ToneMappingFolder(this.gui, false);\n this.ssaoFolder = new SSAOFolder(this.gui, false);\n this.bcsFolder = new BrightnessContrastSaturationFolder(this.gui, false);\n this.postExtrasFolder = new PostExtrasFolder(this.gui, false);\n this.character = new CharacterFolder(this.gui, false);\n this.environment = new EnvironmentFolder(this.gui, false);\n this.camera = new CameraFolder(this.gui, false);\n this.characterControls = new CharacterControlsFolder(this.gui, false);\n\n this.toneMappingFolder.folder.hidden = rendererValues.toneMapping === 5 ? false : true;\n\n this.export = this.gui.addFolder({ title: \"import / export\", expanded: false });\n\n this.eventHandlerCollection = new EventHandlerCollection();\n\n const gui = this.gui as any;\n const paneElement: HTMLElement = gui.containerElem_;\n paneElement.style.right = this.guiVisible ? \"0px\" : \"-450px\";\n this.eventHandlerCollection.add(this.gui.element, \"mouseenter\", () => setTweakpaneActive(true));\n this.eventHandlerCollection.add(this.gui.element, \"mousemove\", () => setTweakpaneActive(true));\n this.eventHandlerCollection.add(this.gui.element, \"mousedown\", () => setTweakpaneActive(true));\n this.eventHandlerCollection.add(this.gui.element, \"mouseleave\", () =>\n setTweakpaneActive(false),\n );\n this.eventHandlerCollection.add(this.gui.element, \"mouseup\", () => setTweakpaneActive(false));\n this.eventHandlerCollection.add(window, \"keydown\", (e) => {\n this.processKey(e);\n });\n }\n\n private processKey(e: KeyboardEvent): void {\n if (e.key === \"p\") {\n this.toggleGUI();\n }\n }\n\n public setupRenderPane(\n composer: EffectComposer,\n normalPass: NormalPass,\n ppssaoEffect: SSAOEffect,\n ppssaoPass: EffectPass,\n n8aopass: any,\n toneMappingEffect: ToneMappingEffect,\n toneMappingPass: EffectPass,\n brightnessContrastSaturation: typeof BrightnessContrastSaturation,\n bloomEffect: BloomEffect,\n gaussGrainEffect: typeof GaussGrainEffect,\n hasLighting: boolean,\n sun: Sun | null,\n setHDR: () => void,\n setSkyboxAzimuthalAngle: (azimuthalAngle: number) => void,\n setSkyboxPolarAngle: (azimuthalAngle: number) => void,\n setAmbientLight: () => void,\n setFog: () => void,\n ): void {\n // RenderOptions\n this.rendererFolder.setupChangeEvent(\n this.renderer,\n this.toneMappingFolder.folder,\n toneMappingPass,\n );\n\n this.toneMappingFolder.setupChangeEvent(toneMappingEffect);\n this.ssaoFolder.setupChangeEvent(composer, normalPass, ppssaoEffect, ppssaoPass, n8aopass);\n this.bcsFolder.setupChangeEvent(brightnessContrastSaturation);\n this.postExtrasFolder.setupChangeEvent(bloomEffect, gaussGrainEffect);\n this.environment.setupChangeEvent(\n this.scene,\n setHDR,\n setSkyboxAzimuthalAngle,\n setSkyboxPolarAngle,\n setAmbientLight,\n setFog,\n sun,\n );\n this.environment.folder.hidden = hasLighting === false || sun === null;\n\n const exportButton = this.export.addButton({ title: \"export\" });\n exportButton.on(\"click\", () => {\n this.downloadSettingsAsJSON(this.gui.exportState());\n });\n const importButton = this.export.addButton({ title: \"import\" });\n importButton.on(\"click\", () => {\n this.importSettingsFromJSON((settings) => {\n this.gui.importState(settings);\n });\n });\n }\n\n public dispose() {\n this.eventHandlerCollection.clear();\n this.gui.dispose();\n this.tweakPaneWrapper.remove();\n }\n\n public setupCamPane(cameraManager: CameraManager) {\n this.camera.setupChangeEvent(cameraManager);\n }\n\n public setupCharacterController(localController: LocalController) {\n this.characterControls.setupChangeEvent(localController);\n }\n\n public updateStats(timeManager: TimeManager): void {\n this.renderStatsFolder.update(this.renderer, this.composer, timeManager);\n }\n\n public updateCameraData(cameraManager: CameraManager) {\n this.camera.update(cameraManager);\n }\n\n public updateCharacterData(localController: LocalController) {\n this.characterControls.update(localController);\n }\n\n private formatDateForFilename(): string {\n const date = new Date();\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, \"0\"); // Months are 0-11\n const day = String(date.getDate()).padStart(2, \"0\");\n const hours = String(date.getHours()).padStart(2, \"0\");\n const minutes = String(date.getMinutes()).padStart(2, \"0\");\n const seconds = String(date.getSeconds()).padStart(2, \"0\");\n return `${year}-${month}-${day} ${hours}-${minutes}-${seconds}`;\n }\n\n private downloadSettingsAsJSON(settings: any): void {\n const jsonString = JSON.stringify(settings, null, 2);\n const blob = new Blob([jsonString], { type: \"application/json\" });\n const url = URL.createObjectURL(blob);\n const a = document.createElement(\"a\");\n a.download = `settings ${this.formatDateForFilename()}.json`;\n a.href = url;\n a.click();\n URL.revokeObjectURL(url);\n }\n\n private importSettingsFromJSON(callback: (settings: any) => void): void {\n const input = document.createElement(\"input\");\n input.type = \"file\";\n input.accept = \".json\";\n input.addEventListener(\"change\", (event) => {\n const file = (event.target as HTMLInputElement).files?.[0];\n if (file) {\n const reader = new FileReader();\n reader.onload = (loadEvent) => {\n try {\n const settings = JSON.parse(loadEvent.target?.result as string);\n callback(settings);\n } catch (err) {\n console.error(\"Error parsing JSON:\", err);\n }\n };\n reader.readAsText(file);\n }\n });\n input.click();\n }\n\n private toggleGUI(): void {\n this.guiVisible = !this.guiVisible;\n const gui = this.gui as any;\n const paneElement: HTMLElement = gui.containerElem_;\n paneElement.style.right = this.guiVisible ? \"0px\" : \"-450px\";\n if (this.saveVisibilityInLocalStorage) {\n localStorage.setItem(\"guiVisible\", this.guiVisible === true ? \"true\" : \"false\");\n }\n }\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { BladeApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nimport { BrightnessContrastSaturation } from \"../../rendering/post-effects/bright-contrast-sat\";\n\nexport const bcsValues = {\n brightness: 0.06,\n contrast: 1.2,\n saturation: 1,\n};\n\nconst bcsOptions = {\n brightness: {\n amount: { min: -1.0, max: 1.0, step: 0.01 },\n },\n contrast: {\n amount: { min: 0.0, max: 2.0, step: 0.01 },\n },\n saturation: {\n amount: { min: 0.0, max: 2.0, step: 0.01 },\n },\n};\n\nexport class BrightnessContrastSaturationFolder {\n private folder: FolderApi;\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({\n title: \"brightness / contrast / sat\",\n expanded: expand,\n });\n this.folder.addBinding(bcsValues, \"brightness\", bcsOptions.brightness.amount);\n this.folder.addBinding(bcsValues, \"contrast\", bcsOptions.contrast.amount);\n this.folder.addBinding(bcsValues, \"saturation\", bcsOptions.saturation.amount);\n }\n\n public setupChangeEvent(brightnessContrastSaturation: typeof BrightnessContrastSaturation): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"brightness\":\n brightnessContrastSaturation.uniforms.brightness.value = e.value;\n break;\n case \"contrast\":\n brightnessContrastSaturation.uniforms.contrast.value = e.value;\n break;\n case \"saturation\":\n brightnessContrastSaturation.uniforms.saturation.value = e.value;\n break;\n }\n });\n }\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { Scene } from \"three\";\nimport { BladeApi, ButtonApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nimport { Sun } from \"../../sun/Sun\";\n\nexport const sunValues = {\n sunPosition: {\n sunAzimuthalAngle: 219,\n sunPolarAngle: -37,\n },\n sunIntensity: 3.7,\n sunColor: { r: 1.0, g: 1.0, b: 1.0 },\n};\n\nconst sunOptions = {\n sunPosition: {\n sunAzimuthalAngle: { min: 0, max: 360, step: 1 },\n sunPolarAngle: { min: -90, max: 90, step: 1 },\n },\n sunIntensity: { min: 0, max: 10, step: 0.1 },\n};\n\nexport const envValues = {\n skyboxAzimuthalAngle: 0,\n skyboxPolarAngle: 0,\n envMapIntensity: 0.07,\n skyboxIntensity: 0.8,\n skyboxBlurriness: 0.0,\n ambientLight: {\n ambientLightIntensity: 0.27,\n ambientLightColor: { r: 1, g: 1, b: 1 },\n },\n fog: {\n fogNear: 21,\n fogFar: 180,\n fogColor: { r: 0.7, g: 0.7, b: 0.7 },\n },\n};\n\nconst envOptions = {\n skyboxAzimuthalAngle: { min: 0, max: 360, step: 1 },\n skyboxPolarAngle: { min: 0, max: 360, step: 1 },\n skyboxIntensity: { min: 0, max: 1.3, step: 0.01 },\n skyboxBlurriness: { min: 0, max: 0.1, step: 0.001 },\n ambientLight: {\n ambientLightIntensity: { min: 0, max: 1, step: 0.01 },\n },\n fog: {\n fogNear: { min: 0, max: 80, step: 1 },\n fogFar: { min: 0, max: 300, step: 1 },\n },\n};\n\nexport class EnvironmentFolder {\n public folder: FolderApi;\n private sun: FolderApi;\n private envMap: FolderApi;\n private hdrButton: ButtonApi;\n private skybox: FolderApi;\n private ambient: FolderApi;\n private fog: FolderApi;\n\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({ title: \"environment\", expanded: expand });\n this.sun = this.folder.addFolder({ title: \"sun\", expanded: true });\n this.envMap = this.folder.addFolder({ title: \"envMap\", expanded: true });\n this.fog = this.folder.addFolder({ title: \"fog\", expanded: true });\n this.skybox = this.folder.addFolder({ title: \"skybox\", expanded: true });\n this.ambient = this.folder.addFolder({ title: \"ambient\", expanded: true });\n\n this.sun.addBinding(\n sunValues.sunPosition,\n \"sunAzimuthalAngle\",\n sunOptions.sunPosition.sunAzimuthalAngle,\n );\n this.sun.addBinding(\n sunValues.sunPosition,\n \"sunPolarAngle\",\n sunOptions.sunPosition.sunPolarAngle,\n );\n this.sun.addBinding(sunValues, \"sunIntensity\", sunOptions.sunIntensity);\n this.sun.addBinding(sunValues, \"sunColor\", {\n color: { type: \"float\" },\n });\n\n this.hdrButton = this.skybox.addButton({ title: \"Set HDRI\" });\n this.skybox.addBinding(envValues, \"skyboxIntensity\", envOptions.skyboxIntensity);\n this.skybox.addBinding(envValues, \"skyboxBlurriness\", envOptions.skyboxBlurriness);\n this.skybox.addBinding(envValues, \"skyboxAzimuthalAngle\", envOptions.skyboxAzimuthalAngle);\n this.skybox.addBinding(envValues, \"skyboxPolarAngle\", envOptions.skyboxPolarAngle);\n\n this.envMap.addBinding(envValues, \"envMapIntensity\", envOptions.skyboxIntensity);\n\n this.ambient.addBinding(\n envValues.ambientLight,\n \"ambientLightIntensity\",\n envOptions.ambientLight.ambientLightIntensity,\n );\n this.ambient.addBinding(envValues.ambientLight, \"ambientLightColor\", {\n color: { type: \"float\" },\n });\n\n this.fog.addBinding(envValues.fog, \"fogNear\", envOptions.fog.fogNear);\n this.fog.addBinding(envValues.fog, \"fogFar\", envOptions.fog.fogFar);\n this.fog.addBinding(envValues.fog, \"fogColor\", {\n color: { type: \"float\" },\n });\n }\n\n public setupChangeEvent(\n scene: Scene,\n setHDR: () => void,\n setSkyboxAzimuthalAngle: (azimuthalAngle: number) => void,\n setSkyboxPolarAngle: (polarAngle: number) => void,\n setAmbientLight: () => void,\n setFog: () => void,\n sun: Sun | null,\n ): void {\n this.sun.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"sunAzimuthalAngle\": {\n const value = e.value as number;\n sun?.setAzimuthalAngle(value * (Math.PI / 180));\n break;\n }\n case \"sunPolarAngle\": {\n const value = e.value as number;\n sun?.setPolarAngle(value * (Math.PI / 180));\n break;\n }\n case \"sunIntensity\": {\n const value = e.value as number;\n sun?.setIntensity(value);\n break;\n }\n case \"sunColor\": {\n const value = e.value as { r: number; g: number; b: number };\n sunValues.sunColor = {\n r: value.r,\n g: value.g,\n b: value.b,\n };\n sun?.setColor();\n break;\n }\n default:\n break;\n }\n });\n\n this.hdrButton.on(\"click\", () => {\n setHDR();\n });\n\n this.envMap.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"envMapIntensity\":\n scene.environmentIntensity = e.value as number;\n break;\n }\n });\n\n this.skybox.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"skyboxAzimuthalAngle\": {\n const value = e.value as number;\n setSkyboxAzimuthalAngle(value);\n break;\n }\n case \"skyboxPolarAngle\": {\n const value = e.value as number;\n envValues.skyboxPolarAngle = value;\n setSkyboxPolarAngle(value);\n break;\n }\n case \"skyboxIntensity\":\n scene.backgroundIntensity = e.value as number;\n break;\n case \"skyboxBlurriness\":\n scene.backgroundBlurriness = e.value as number;\n break;\n }\n });\n\n this.ambient.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"ambientLightIntensity\": {\n envValues.ambientLight.ambientLightIntensity = e.value as number;\n setAmbientLight();\n break;\n }\n case \"ambientLightColor\": {\n const value = e.value as { r: number; g: number; b: number };\n envValues.ambientLight.ambientLightColor = {\n r: value.r,\n g: value.g,\n b: value.b,\n };\n setAmbientLight();\n break;\n }\n }\n });\n\n this.fog.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"fogNear\": {\n envValues.fog.fogNear = e.value as number;\n setFog();\n break;\n }\n case \"fogFar\": {\n envValues.fog.fogFar = e.value as number;\n setFog();\n break;\n }\n case \"fogColor\": {\n const value = e.value as { r: number; g: number; b: number };\n envValues.fog.fogColor = {\n r: value.r,\n g: value.g,\n b: value.b,\n };\n setFog();\n break;\n }\n }\n });\n }\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { BloomEffect } from \"postprocessing\";\nimport { BladeApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nimport { GaussGrainEffect } from \"../../rendering/post-effects/gauss-grain\";\n\nexport const extrasValues = {\n grain: 0.045,\n bloom: 0.15,\n};\n\nconst extrasOptions = {\n grain: {\n amount: { min: 0, max: 0.2, step: 0.002 },\n },\n bloom: {\n amount: { min: 0, max: 50, step: 0.05 },\n },\n};\n\nexport class PostExtrasFolder {\n private folder: FolderApi;\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({ title: \"bloom / grain\", expanded: expand });\n this.folder.addBinding(extrasValues, \"bloom\", extrasOptions.bloom.amount);\n this.folder.addBinding(extrasValues, \"grain\", extrasOptions.grain.amount);\n }\n\n public setupChangeEvent(\n bloomEffect: BloomEffect,\n gaussGrainEffect: typeof GaussGrainEffect,\n ): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"bloom\":\n bloomEffect.intensity = e.value as number;\n break;\n case \"grain\":\n gaussGrainEffect.uniforms.amount.value = e.value as number;\n break;\n default:\n break;\n }\n });\n }\n}\n", "import { BladeController, View } from \"@tweakpane/core\";\nimport { EffectPass } from \"postprocessing\";\nimport { Scene, ShadowMapType, ToneMapping, WebGLRenderer } from \"three\";\nimport { BladeApi, FolderApi, TpChangeEvent } from \"tweakpane\";\n\nexport const rendererValues = {\n shadowMap: 2,\n toneMapping: 5,\n exposure: 1.7,\n};\n\nconst rendererOptions = {\n shadowMap: { min: 0, max: 2, step: 1 },\n toneMapping: { min: 0, max: 5, step: 1 },\n exposure: { min: 0, max: 3, step: 0.01 },\n};\n\nconst shadowMapTypes: Record<number, string> = {\n 0: \"BasicShadowMap\",\n 1: \"PCFShadowMap\",\n 2: \"PCFSoftShadowMap\",\n};\n\nconst toneMappingTypes: Record<number, string> = {\n 0: \"NoToneMapping\",\n 1: \"LinearToneMapping\",\n 2: \"ReinhardToneMapping\",\n 3: \"CineonToneMapping\",\n 4: \"ACESFilmicToneMapping\",\n 5: \"CustomToneMapping\",\n};\n\nconst monitoredValues = {\n shadowMapType: shadowMapTypes[rendererValues.shadowMap],\n toneMappingType: toneMappingTypes[rendererValues.toneMapping],\n};\n\nconst setShadowMapType = (value: number): void => {\n monitoredValues.shadowMapType = shadowMapTypes[value];\n};\n\nconst setToneMappingType = (value: number): void => {\n monitoredValues.toneMappingType = toneMappingTypes[value];\n rendererValues.toneMapping = value;\n console.log(rendererValues.toneMapping);\n};\n\nexport class RendererFolder {\n private folder: FolderApi;\n\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({\n title: \"rendererOptions\",\n expanded: expand,\n });\n\n this.folder.addBinding(rendererValues, \"shadowMap\", rendererOptions.shadowMap);\n this.folder.addBinding(monitoredValues, \"shadowMapType\", { readonly: true });\n this.folder.addBinding(rendererValues, \"toneMapping\", rendererOptions.toneMapping);\n this.folder.addBinding(monitoredValues, \"toneMappingType\", { readonly: true });\n this.folder.addBinding(rendererValues, \"exposure\", rendererOptions.exposure);\n }\n\n public setupChangeEvent(\n renderer: WebGLRenderer,\n toneMappingFolder: FolderApi,\n toneMappingPass: EffectPass,\n ): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"shadowMap\": {\n const value = e.value as ShadowMapType;\n renderer.shadowMap.type = value;\n setShadowMapType(value);\n break;\n }\n case \"toneMapping\":\n const value = e.value as ToneMapping;\n toneMappingFolder.hidden = e.value !== 5;\n toneMappingPass.enabled = e.value === 5 ? true : false;\n setToneMappingType(e.value as ToneMapping);\n break;\n case \"exposure\":\n renderer.toneMappingExposure = e.value as number;\n break;\n default:\n break;\n }\n });\n }\n}\n", "import { EffectComposer } from \"postprocessing\";\nimport { WebGLRenderer } from \"three\";\nimport { FolderApi } from \"tweakpane\";\n\nimport { TimeManager } from \"../../time/TimeManager\";\n\ntype StatsData = {\n triangles: string;\n geometries: string;\n textures: string;\n shaders: string;\n postPasses: string;\n drawCalls: string;\n rawDeltaTime: string;\n deltaTime: string;\n FPS: string;\n};\n\nexport class RendererStatsFolder {\n private folder: FolderApi;\n private performance: FolderApi;\n private defails: FolderApi;\n\n private statsData: StatsData = {\n triangles: \"0\",\n geometries: \"0\",\n textures: \"0\",\n shaders: \"0\",\n postPasses: \"0\",\n drawCalls: \"0\",\n rawDeltaTime: \"0\",\n deltaTime: \"0\",\n FPS: \"0\",\n };\n\n constructor(parentFolder: FolderApi, expanded: boolean = true) {\n this.folder = parentFolder.addFolder({ title: \"renderStats\", expanded: expanded });\n this.folder.addBinding(this.statsData, \"FPS\", { readonly: true });\n this.folder.addBinding(this.statsData, \"deltaTime\", { readonly: true });\n this.folder.addBinding(this.statsData, \"rawDeltaTime\", { readonly: true });\n this.folder.addBinding(this.statsData, \"triangles\", { readonly: true });\n this.folder.addBinding(this.statsData, \"geometries\", { readonly: true });\n this.folder.addBinding(this.statsData, \"textures\", { readonly: true });\n this.folder.addBinding(this.statsData, \"shaders\", { readonly: true });\n this.folder.addBinding(this.statsData, \"postPasses\", { readonly: true });\n this.folder.addBinding(this.statsData, \"drawCalls\", { readonly: true });\n }\n\n public update(renderer: WebGLRenderer, composer: EffectComposer, timeManager: TimeManager): void {\n const { geometries, textures } = renderer.info.memory;\n const { triangles, calls } = renderer.info.render;\n this.statsData.triangles = triangles.toString();\n this.statsData.geometries = geometries.toString();\n this.statsData.textures = textures.toString();\n this.statsData.shaders = renderer.info.programs!.length.toString();\n this.statsData.postPasses = composer.passes.length.toString();\n this.statsData.drawCalls = calls.toString();\n this.statsData.rawDeltaTime = (\n Math.round(timeManager.rawDeltaTime * 100000) / 100000\n ).toString();\n this.statsData.deltaTime = (Math.round(timeManager.deltaTime * 100000) / 100000).toString();\n this.statsData.FPS = timeManager.fps.toString();\n }\n}\n", "import { BindingApi, BladeApi, BladeController, TpChangeEvent, View } from \"@tweakpane/core\";\nimport { BlendFunction, EffectComposer, EffectPass, NormalPass, SSAOEffect } from \"postprocessing\";\nimport { Color } from \"three\";\nimport { FolderApi } from \"tweakpane\";\n\nexport const ppssaoValues = {\n enabled: false,\n blendFunction: BlendFunction.MULTIPLY,\n distanceScaling: true,\n depthAwareUpsampling: true,\n samples: 30,\n rings: 11,\n luminanceInfluence: 0.7,\n radius: 0.045,\n intensity: 3.14,\n bias: 0.01,\n fade: 0.06,\n resolutionScale: 0.5,\n color: { r: 0, g: 0, b: 0 },\n worldDistanceThreshold: 30,\n worldDistanceFalloff: 7,\n worldProximityThreshold: 0.5,\n worldProximityFalloff: 0.3,\n};\n\nconst ppssaoOptions = {\n samples: { min: 1, max: 50, step: 1 },\n rings: { min: 1, max: 50, step: 1 },\n luminanceInfluence: { min: 0, max: 1, step: 0.01 },\n radius: { min: 0, max: 0.1, step: 0.001 },\n intensity: { min: 0, max: 5, step: 0.1 },\n bias: { min: 0, max: 0.1, step: 0.001 },\n fade: { min: 0, max: 0.1, step: 0.001 },\n resolutionScale: { min: 0.25, max: 2, step: 0.25 },\n worldDistanceThreshold: { min: 0, max: 200, step: 1 },\n worldDistanceFalloff: { min: 0, max: 200, step: 1 },\n worldProximityThreshold: { min: 0, max: 2, step: 0.01 },\n worldProximityFalloff: { min: 0, max: 2, step: 0.01 },\n};\n\nexport const n8ssaoValues = {\n enabled: true,\n halfRes: true,\n aoRadius: 5,\n distanceFalloff: 3.0,\n intensity: 1.5,\n color: { r: 0, g: 0, b: 0 },\n aoSamples: 16,\n denoiseSamples: 4,\n denoiseRadius: 12,\n viewMode: \"Combined\",\n};\n\nexport const n8ssaoOptions = {\n radius: { min: 0.1, max: 6, step: 0.1 },\n distanceFalloff: { min: 1, max: 6, step: 0.1 },\n intensity: { min: 0.1, max: 5, step: 0.1 },\n aoSamples: [2, 4, 8, 16, 32, 64],\n denoiseSamples: [2, 4, 8, 16, 32, 64],\n denoiseRadius: [3, 6, 12],\n viewMode: [\"Combined\", \"AO\", \"No AO\", \"Split\", \"Split AO\", \"No AO\"],\n};\n\nconst ssaoMaterialParams = [\n \"fade\",\n \"bias\",\n \"minRadiusScale\",\n \"worldDistanceThreshold\",\n \"worldDistanceFalloff\",\n \"worldProximityThreshold\",\n \"worldProximityFalloff\",\n];\n\nexport class SSAOFolder {\n private folder: FolderApi;\n\n private ppssao: FolderApi;\n private n8ssao: FolderApi;\n\n private aoSamples: BindingApi;\n private denoiseSamples: BindingApi;\n private denoiseRadius: BindingApi;\n private aoDisplay: BindingApi;\n\n private postProcessingSSAOIndex: number = 1;\n\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({ title: \"ambientOcclusion\", expanded: expand });\n this.n8ssao = this.folder.addFolder({\n title: \"N8 ambientOcclusion\",\n expanded: n8ssaoValues.enabled,\n });\n this.ppssao = this.folder.addFolder({\n title: \"PP ambientOcclusion\",\n expanded: ppssaoValues.enabled,\n });\n\n // Post-processing SSAO\n {\n this.ppssao.addBinding({ enabled: ppssaoValues.enabled }, \"enabled\");\n this.ppssao.addBinding({ showEffectOnly: false }, \"showEffectOnly\");\n this.ppssao.addBinding(ppssaoValues, \"samples\", ppssaoOptions.samples);\n this.ppssao.addBinding(ppssaoValues, \"rings\", ppssaoOptions.rings);\n this.ppssao.addBinding(ppssaoValues, \"luminanceInfluence\", ppssaoOptions.luminanceInfluence);\n this.ppssao.addBinding(ppssaoValues, \"radius\", ppssaoOptions.radius);\n this.ppssao.addBinding(ppssaoValues, \"intensity\", ppssaoOptions.intensity);\n this.ppssao.addBinding(ppssaoValues, \"bias\", ppssaoOptions.bias);\n this.ppssao.addBinding(ppssaoValues, \"fade\", ppssaoOptions.fade);\n this.ppssao.addBinding(ppssaoValues, \"resolutionScale\", ppssaoOptions.resolutionScale);\n this.ppssao.addBinding(\n ppssaoValues,\n \"worldDistanceThreshold\",\n ppssaoOptions.worldDistanceThreshold,\n );\n this.ppssao.addBinding(\n ppssaoValues,\n \"worldDistanceFalloff\",\n ppssaoOptions.worldDistanceFalloff,\n );\n this.ppssao.addBinding(\n ppssaoValues,\n \"worldProximityThreshold\",\n ppssaoOptions.worldProximityThreshold,\n );\n this.ppssao.addBinding(\n ppssaoValues,\n \"worldProximityFalloff\",\n ppssaoOptions.worldProximityFalloff,\n );\n this.ppssao.addBinding(ppssaoValues, \"color\", { color: { alpha: false, type: \"float\" } });\n }\n\n // N8 SSAO\n {\n this.n8ssao.addBinding({ enabled: n8ssaoValues.enabled }, \"enabled\");\n this.n8ssao.addBinding({ halfRes: n8ssaoValues.halfRes }, \"halfRes\");\n this.n8ssao.addBinding(n8ssaoValues, \"aoRadius\", n8ssaoOptions.radius);\n this.n8ssao.addBinding(n8ssaoValues, \"distanceFalloff\", n8ssaoOptions.distanceFalloff);\n this.n8ssao.addBinding(n8ssaoValues, \"intensity\", n8ssaoOptions.intensity);\n this.n8ssao.addBinding(n8ssaoValues, \"color\", { color: { alpha: false, type: \"float\" } });\n\n this.aoSamples = this.n8ssao.addBinding(n8ssaoValues, \"aoSamples\", {\n view: \"radiogrid\",\n groupName: \"aoSamples\",\n size: [3, 2],\n cells: (x: number, y: number) => ({\n title: `${n8ssaoOptions.aoSamples[y * 3 + x]}`,\n value: n8ssaoOptions.aoSamples[y * 3 + x],\n }),\n label: \"aoSamples\",\n });\n\n this.denoiseSamples = this.n8ssao.addBinding(n8ssaoValues, \"denoiseSamples\", {\n view: \"radiogrid\",\n groupName: \"denoiseSamples\",\n size: [3, 2],\n cells: (x: number, y: number) => ({\n title: `${n8ssaoOptions.denoiseSamples[y * 3 + x]}`,\n value: n8ssaoOptions.denoiseSamples[y * 3 + x],\n }),\n label: \"denoiseSamples\",\n });\n\n this.denoiseRadius = this.n8ssao.addBinding(n8ssaoValues, \"denoiseRadius\", {\n view: \"radiogrid\",\n groupName: \"denoiseRadius\",\n size: [3, 1],\n cells: (x: number, y: number) => ({\n title: `${n8ssaoOptions.denoiseRadius[y * 3 + x]}`,\n value: n8ssaoOptions.denoiseRadius[y * 3 + x],\n }),\n label: \"denoiseRadius\",\n });\n\n this.aoDisplay = this.n8ssao.addBinding(n8ssaoValues, \"viewMode\", {\n view: \"radiogrid\",\n groupName: \"viewMode\",\n size: [3, 2],\n cells: (x: number, y: number) => ({\n title: `${n8ssaoOptions.viewMode[y * 3 + x]}`,\n value: `${n8ssaoOptions.viewMode[y * 3 + x]}`,\n }),\n label: \"viewMode\",\n });\n }\n\n this.folder.addBlade({ view: \"separator\" });\n }\n\n public setupChangeEvent(\n composer: EffectComposer,\n normalPass: NormalPass,\n ppssaoEffect: SSAOEffect,\n ppssaoPass: EffectPass,\n n8aopass: any,\n ): void {\n this.ppssao.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"enabled\": {\n const value = e.value as boolean;\n if (e.value === true) {\n composer.addPass(normalPass, this.postProcessingSSAOIndex);\n composer.addPass(ppssaoPass, this.postProcessingSSAOIndex + 1);\n } else {\n composer.removePass(ppssaoPass);\n composer.removePass(normalPass);\n }\n ppssaoValues.enabled = value;\n normalPass.enabled = value;\n ppssaoPass.enabled = value;\n break;\n }\n case \"showEffectOnly\": {\n const value = e.value as boolean;\n const blend = value === true ? BlendFunction.NORMAL : BlendFunction.MULTIPLY;\n ppssaoEffect.blendMode.blendFunction = blend;\n break;\n }\n case \"resolutionScale\": {\n const value = e.value as number;\n ppssaoEffect.resolution.scale = value;\n break;\n }\n case \"color\": {\n const value = e.value as { r: number; g: number; b: number };\n ppssaoEffect.color = new Color().setRGB(value.r, value.g, value.b);\n break;\n }\n default: {\n break;\n }\n }\n\n if (ssaoMaterialParams.includes(target)) {\n (ppssaoEffect.ssaoMaterial as any)[target] = e.value;\n return;\n }\n (ppssaoEffect as any)[target] = e.value;\n });\n\n this.n8ssao.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n switch (target) {\n case \"enabled\":\n if (e.value === true) {\n composer.addPass(n8aopass, this.postProcessingSSAOIndex + 2);\n composer.passes[this.postProcessingSSAOIndex + 2].setSize(\n window.innerWidth,\n window.innerHeight,\n );\n } else {\n composer.removePass(n8aopass);\n }\n n8aopass.enabled = e.value;\n break;\n case \"halfRes\":\n n8aopass.configuration.halfRes = e.value;\n break;\n case \"aoRadius\":\n n8aopass.configuration.aoRadius = e.value;\n break;\n case \"distanceFalloff\":\n n8aopass.configuration.distanceFalloff = e.value;\n break;\n case \"intensity\":\n n8aopass.configuration.intensity = e.value;\n break;\n case \"color\":\n const value = (e as any).value;\n n8aopass.configuration.color = new Color().setRGB(value.r, value.g, value.b);\n break;\n default:\n break;\n }\n });\n\n this.aoSamples.on(\"change\", (e: any) => {\n n8aopass.configuration.aoSamples = e.value;\n });\n\n this.denoiseSamples.on(\"change\", (e: any) => {\n n8aopass.configuration.denoiseSamples = e.value;\n });\n\n this.denoiseRadius.on(\"change\", (e: any) => {\n n8aopass.configuration.denoiseRadius = e.value;\n });\n\n this.aoDisplay.on(\"change\", (e: any) => {\n n8aopass.setDisplayMode(e.value);\n });\n }\n}\n", "import { BindingApi, BladeApi, BladeController, TpChangeEvent, View } from \"@tweakpane/core\";\nimport { ToneMappingEffect, ToneMappingMode } from \"postprocessing\";\nimport { FolderApi } from \"tweakpane\";\n\nexport const toneMappingValues = {\n mode: 7 as ToneMappingMode,\n resolution: 512,\n whitePoint: 32.0,\n middleGrey: 21.0,\n minLuminance: 0.01,\n averageLuminance: 0.01,\n adaptationRate: 2.0,\n};\n\nconst toneMappingOptions = {\n mode: { min: 0, max: 8, step: 1 },\n resolution: { min: 64, max: 512, step: 64 },\n whitePoint: { min: 0, max: 32, step: 0.01 },\n middleGrey: { min: 0, max: 32, step: 0.01 },\n minLuminance: { min: 0, max: 32, step: 0.001 },\n averageLuminance: { min: 0.001, max: 2, step: 0.001 },\n adaptationRate: { min: 0.1, max: 2.0, step: 0.1 },\n};\n\nconst customToneMappingTypes: Record<number, string> = {\n 0: \"LINEAR\",\n 1: \"REINHARD\",\n 2: \"REINHARD2\",\n 3: \"REINHARD2_ADAPTIVE\",\n 4: \"UNCHARTED2\",\n 5: \"OPTIMIZED_CINEON\",\n 6: \"ACES_FILMIC\",\n 7: \"AGX\",\n 8: \"NEUTRAL\",\n};\n\nconst customToneMappingBlade = {\n customToneMappingType: customToneMappingTypes[toneMappingValues.mode],\n};\n\nconst setCustomToneMappingType = (value: number): void => {\n customToneMappingBlade.customToneMappingType = customToneMappingTypes[value];\n};\n\nexport class ToneMappingFolder {\n public folder: FolderApi;\n private minLuminance: BindingApi;\n private avgLuminance: BindingApi;\n\n constructor(parentFolder: FolderApi, expand: boolean = false) {\n this.folder = parentFolder.addFolder({\n title: \"customToneMapping\",\n expanded: expand,\n });\n this.folder.addBinding(toneMappingValues, \"mode\", toneMappingOptions.mode);\n this.folder.addBinding(customToneMappingBlade, \"customToneMappingType\", { readonly: true });\n this.folder.addBinding(toneMappingValues, \"whitePoint\", toneMappingOptions.whitePoint);\n this.folder.addBinding(toneMappingValues, \"middleGrey\", toneMappingOptions.middleGrey);\n this.minLuminance = this.folder.addBinding(\n toneMappingValues,\n \"minLuminance\",\n toneMappingOptions.minLuminance,\n );\n this.minLuminance.hidden = false;\n this.avgLuminance = this.folder.addBinding(\n toneMappingValues,\n \"averageLuminance\",\n toneMappingOptions.averageLuminance,\n );\n this.avgLuminance.hidden = false;\n this.folder.addBinding(toneMappingValues, \"adaptationRate\", toneMappingOptions.adaptationRate);\n }\n\n public setupChangeEvent(toneMappingEffect: ToneMappingEffect): void {\n this.folder.on(\"change\", (e: TpChangeEvent<unknown, BladeApi<BladeController<View>>>) => {\n const target = (e.target as any).key;\n if (!target) return;\n if (target === \"mode\") {\n setCustomToneMappingType(e.value as number);\n }\n (toneMappingEffect as any)[target] = e.value;\n return;\n });\n }\n}\n", "export const tweakPaneStyle = `\n:root {\n --tp-base-background-color: rgba(12, 12, 12, 0.6);\n --tp-base-shadow-color: hsla(0, 0%, 0%, 0.2);\n --tp-button-background-color: hsla(0, 0%, 80%, 1);\n --tp-button-background-color-active: hsla(0, 0%, 100%, 1);\n --tp-button-background-color-focus: hsla(0, 0%, 95%, 1);\n --tp-button-background-color-hover: hsla(0, 0%, 85%, 1);\n --tp-button-foreground-color: hsla(0, 0%, 0%, 0.7);\n --tp-container-background-color: hsla(0, 0%, 0%, 0.3);\n --tp-container-background-color-active: hsla(0, 0%, 0%, 0.6);\n --tp-container-background-color-focus: hsla(0, 0%, 0%, 0.5);\n --tp-container-background-color-hover: hsla(0, 0%, 0%, 0.4);\n --tp-container-foreground-color: hsla(0, 0%, 90%, 0.6);\n --tp-groove-foreground-color: hsla(0, 0%, 0%, 0.2);\n --tp-input-background-color: hsla(0, 0%, 30%, 0.3);\n --tp-input-background-color-active: hsla(0, 0%, 0%, 0.6);\n --tp-input-background-color-focus: hsla(0, 0%, 0%, 0.5);\n --tp-input-background-color-hover: hsla(0, 0%, 0%, 0.4);\n --tp-input-foreground-color: hsla(0, 0%, 100%, 0.6);\n --tp-label-foreground-color: hsla(0, 0%, 100%, 0.6);\n --tp-monitor-background-color: hsla(0, 0%, 0%, 0.3);\n --tp-monitor-foreground-color: hsla(0, 0%, 100%, 0.3);\n}\n\n.tp-brkv {\n -webkit-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.tp-dfwv {\n z-index: 100;\n color: white;\n width: 600px !important;\n display: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n user-select: none;\n}\n\n.tp-fldv {\n margin: 1px 0px 0px 0px !important;\n}\n\n.tp-fldv_b {\n overflow: visible !important;\n}\n\n.tp-fldv_t {\n font-size: 13px;\n font-weight: 900;\n color: #ffffff;\n background-color: rgba(70, 70, 70, 0.3);\n border-top: 1px solid rgba(210, 210, 210, 0.1);\n border-radius: 3px;\n}\n\n.tp-lblv_l {\n font-size: 12px;\n padding-left: 0px !important;\n padding-right: 0px !important;\n}\n\n.tp-lblv_v {\n width: 150px;\n}\n\n.tp-sldtxtv_t {\n max-width: 50px;\n}\n\n.tp-sglv_i {\n font-size: 12px;\n color: rgba(255, 255, 255, 0.7);\n}\n\n.tp-ckbv_w {\n border: 1px solid rgba(200, 200, 250, 0.2);\n}\n`;\n", "import { HDRJPGLoader } from \"@monogrid/gainmap-js\";\nimport {\n BlendFunction,\n BloomEffect,\n EdgeDetectionMode,\n EffectComposer,\n EffectPass,\n FXAAEffect,\n NormalPass,\n PredicationMode,\n RenderPass,\n ShaderPass,\n SMAAEffect,\n SMAAPreset,\n SSAOEffect,\n TextureEffect,\n ToneMappingEffect,\n} from \"postprocessing\";\nimport {\n AmbientLight,\n Color,\n EquirectangularReflectionMapping,\n Euler,\n Fog,\n HalfFloatType,\n LinearSRGBColorSpace,\n LoadingManager,\n MathUtils,\n PerspectiveCamera,\n PMREMGenerator,\n Scene,\n ShadowMapType,\n SRGBColorSpace,\n Texture,\n ToneMapping,\n Vector2,\n WebGLRenderer,\n} from \"three\";\nimport { RGBELoader } from \"three/examples/jsm/loaders/RGBELoader.js\";\n\nimport { CameraManager } from \"../camera/CameraManager\";\nimport { Sun } from \"../sun/Sun\";\nimport { TimeManager } from \"../time/TimeManager\";\nimport { bcsValues } from \"../tweakpane/blades/bcsFolder\";\nimport { envValues, sunValues } from \"../tweakpane/blades/environmentFolder\";\nimport { extrasValues } from \"../tweakpane/blades/postExtrasFolder\";\nimport { rendererValues } from \"../tweakpane/blades/rendererFolder\";\nimport { n8ssaoValues, ppssaoValues } from \"../tweakpane/blades/ssaoFolder\";\nimport { toneMappingValues } from \"../tweakpane/blades/toneMappingFolder\";\nimport { TweakPane } from \"../tweakpane/TweakPane\";\n\nimport { BrightnessContrastSaturation } from \"./post-effects/bright-contrast-sat\";\nimport { GaussGrainEffect } from \"./post-effects/gauss-grain\";\nimport { N8SSAOPass } from \"./post-effects/n8-ssao/N8SSAOPass\";\n\ntype ComposerContructorArgs = {\n scene: Scene;\n cameraManager: CameraManager;\n spawnSun: boolean;\n environmentConfiguration?: EnvironmentConfiguration;\n};\n\nexport type EnvironmentConfiguration = {\n groundPlane?: boolean;\n skybox?: {\n intensity?: number;\n blurriness?: number;\n azimuthalAngle?: number;\n polarAngle?: number;\n } & (\n | {\n hdrJpgUrl: string;\n }\n | {\n hdrUrl: string;\n }\n );\n envMap?: {\n intensity?: number;\n };\n sun?: {\n intensity?: number;\n polarAngle?: number;\n azimuthalAngle?: number;\n };\n fog?: {\n fogNear?: number;\n fogFar?: number;\n fogColor?: {\n r: number;\n g: number;\n b: number;\n };\n };\n postProcessing?: {\n bloomIntensity?: number;\n };\n ambientLight?: {\n intensity?: number;\n };\n};\n\nexport class Composer {\n private width: number = 1;\n private height: number = 1;\n private resizeListener: () => void;\n public resolution: Vector2 = new Vector2(this.width, this.height);\n\n private readonly scene: Scene;\n public postPostScene: Scene;\n private readonly cameraManager: CameraManager;\n public readonly renderer: WebGLRenderer;\n\n public readonly effectComposer: EffectComposer;\n private readonly renderPass: RenderPass;\n\n private readonly normalPass: NormalPass;\n private readonly normalTextureEffect: TextureEffect;\n private readonly ppssaoEffect: SSAOEffect;\n private readonly ppssaoPass: EffectPass;\n private readonly n8aopass: N8SSAOPass;\n\n private readonly fxaaEffect: FXAAEffect;\n private readonly fxaaPass: EffectPass;\n private readonly bloomEffect: BloomEffect;\n private readonly bloomPass: EffectPass;\n private readonly toneMappingEffect: ToneMappingEffect;\n private readonly smaaEffect: SMAAEffect;\n\n private readonly toneMappingPass: EffectPass;\n private readonly smaaPass: EffectPass;\n\n private readonly bcs = BrightnessContrastSaturation;\n private readonly bcsPass: ShaderPass;\n\n private readonly gaussGrainEffect = GaussGrainEffect;\n private readonly gaussGrainPass: ShaderPass;\n\n private ambientLight: AmbientLight | null = null;\n private environmentConfiguration?: EnvironmentConfiguration;\n\n private skyboxState: {\n src: {\n hdrJpgUrl?: string;\n hdrUrl?: string;\n };\n latestPromise: Promise<unknown> | null;\n } = { src: {}, latestPromise: null };\n\n public sun: Sun | null = null;\n public spawnSun: boolean;\n\n constructor({\n scene,\n cameraManager,\n spawnSun = false,\n environmentConfiguration,\n }: ComposerContructorArgs) {\n this.scene = scene;\n this.cameraManager = cameraManager;\n this.postPostScene = new Scene();\n this.spawnSun = spawnSun;\n this.renderer = new WebGLRenderer({\n powerPreference: \"high-performance\",\n antialias: false,\n });\n this.renderer.outputColorSpace = SRGBColorSpace;\n this.renderer.info.autoReset = false;\n this.renderer.setSize(this.width, this.height);\n this.renderer.shadowMap.enabled = true;\n this.renderer.shadowMap.type = rendererValues.shadowMap as ShadowMapType;\n this.renderer.toneMapping = rendererValues.toneMapping as ToneMapping;\n this.renderer.toneMappingExposure = rendererValues.exposure;\n\n this.environmentConfiguration = environmentConfiguration;\n\n this.effectComposer = new EffectComposer(this.renderer, {\n frameBufferType: HalfFloatType,\n });\n\n this.renderPass = new RenderPass(this.scene, this.cameraManager.activeCamera);\n\n this.normalPass = new NormalPass(this.scene, this.cameraManager.activeCamera);\n this.normalPass.enabled = ppssaoValues.enabled;\n this.normalTextureEffect = new TextureEffect({\n blendFunction: BlendFunction.SKIP,\n texture: this.normalPass.texture,\n });\n\n this.ppssaoEffect = new SSAOEffect(this.cameraManager.activeCamera, this.normalPass.texture, {\n blendFunction: ppssaoValues.blendFunction,\n distanceScaling: ppssaoValues.distanceScaling,\n depthAwareUpsampling: ppssaoValues.depthAwareUpsampling,\n samples: ppssaoValues.samples,\n rings: ppssaoValues.rings,\n luminanceInfluence: ppssaoValues.luminanceInfluence,\n radius: ppssaoValues.radius,\n intensity: ppssaoValues.intensity,\n bias: ppssaoValues.bias,\n fade: ppssaoValues.fade,\n resolutionScale: ppssaoValues.resolutionScale,\n color: new Color().setRGB(ppssaoValues.color.r, ppssaoValues.color.g, ppssaoValues.color.b),\n worldDistanceThreshold: ppssaoValues.worldDistanceThreshold,\n worldDistanceFalloff: ppssaoValues.worldDistanceFalloff,\n worldProximityThreshold: ppssaoValues.worldProximityThreshold,\n worldProximityFalloff: ppssaoValues.worldProximityFalloff,\n });\n this.ppssaoPass = new EffectPass(\n this.cameraManager.activeCamera,\n this.ppssaoEffect,\n this.normalTextureEffect,\n );\n this.ppssaoPass.enabled = ppssaoValues.enabled;\n\n this.fxaaEffect = new FXAAEffect();\n\n if (environmentConfiguration?.postProcessing?.bloomIntensity) {\n extrasValues.bloom = environmentConfiguration.postProcessing.bloomIntensity;\n }\n\n this.updateSkyboxAndEnvValues();\n this.updateAmbientLightValues();\n this.updateFogValues();\n\n this.bloomEffect = new BloomEffect({\n intensity: extrasValues.bloom,\n });\n\n this.n8aopass = new N8SSAOPass(\n this.scene,\n this.cameraManager.activeCamera,\n this.width,\n this.height,\n );\n this.n8aopass.configuration.aoRadius = n8ssaoValues.aoRadius;\n this.n8aopass.configuration.distanceFalloff = n8ssaoValues.distanceFalloff;\n this.n8aopass.configuration.intensity = n8ssaoValues.intensity;\n this.n8aopass.configuration.color = new Color().setRGB(\n n8ssaoValues.color.r,\n n8ssaoValues.color.g,\n n8ssaoValues.color.b,\n );\n this.n8aopass.configuration.aoSamples = n8ssaoValues.aoSamples;\n this.n8aopass.configuration.denoiseSamples = n8ssaoValues.denoiseSamples;\n this.n8aopass.configuration.denoiseRadius = n8ssaoValues.denoiseRadius;\n this.n8aopass.enabled = n8ssaoValues.enabled;\n\n this.fxaaPass = new EffectPass(this.cameraManager.activeCamera, this.fxaaEffect);\n this.bloomPass = new EffectPass(this.cameraManager.activeCamera, this.bloomEffect);\n\n this.toneMappingEffect = new ToneMappingEffect({\n mode: toneMappingValues.mode,\n resolution: toneMappingValues.resolution,\n whitePoint: toneMappingValues.whitePoint,\n middleGrey: toneMappingValues.middleGrey,\n minLuminance: toneMappingValues.minLuminance,\n averageLuminance: toneMappingValues.averageLuminance,\n adaptationRate: toneMappingValues.adaptationRate,\n });\n this.smaaEffect = new SMAAEffect({\n preset: SMAAPreset.ULTRA,\n edgeDetectionMode: EdgeDetectionMode.COLOR,\n predicationMode: PredicationMode.DEPTH,\n });\n\n this.toneMappingPass = new EffectPass(this.cameraManager.activeCamera, this.toneMappingEffect);\n this.toneMappingPass.enabled =\n rendererValues.toneMapping === 5 || rendererValues.toneMapping === 0 ? true : false;\n\n this.bcsPass = new ShaderPass(this.bcs, \"tDiffuse\");\n this.bcs.uniforms.brightness.value = bcsValues.brightness;\n this.bcs.uniforms.contrast.value = bcsValues.contrast;\n this.bcs.uniforms.saturation.value = bcsValues.saturation;\n\n this.gaussGrainPass = new ShaderPass(this.gaussGrainEffect, \"tDiffuse\");\n this.gaussGrainEffect.uniforms.amount.value = extrasValues.grain;\n this.gaussGrainEffect.uniforms.alpha.value = 1.0;\n\n this.smaaPass = new EffectPass(this.cameraManager.activeCamera, this.smaaEffect);\n\n this.effectComposer.addPass(this.renderPass);\n if (ppssaoValues.enabled) {\n this.effectComposer.addPass(this.normalPass);\n this.effectComposer.addPass(this.ppssaoPass);\n }\n if (n8ssaoValues.enabled) {\n this.effectComposer.addPass(this.n8aopass);\n }\n this.effectComposer.addPass(this.fxaaPass);\n this.effectComposer.addPass(this.bloomPass);\n this.effectComposer.addPass(this.toneMappingPass);\n this.effectComposer.addPass(this.bcsPass);\n this.effectComposer.addPass(this.gaussGrainPass);\n\n if (this.spawnSun === true) {\n this.sun = new Sun();\n this.scene.add(this.sun);\n }\n\n if (this.environmentConfiguration?.skybox) {\n if (\"hdrJpgUrl\" in this.environmentConfiguration.skybox) {\n this.useHDRJPG(this.environmentConfiguration.skybox.hdrJpgUrl);\n } else if (\"hdrUrl\" in this.environmentConfiguration.skybox) {\n this.useHDRI(this.environmentConfiguration.skybox.hdrUrl);\n }\n }\n\n this.updateSunValues();\n\n this.resizeListener = () => {\n this.fitContainer();\n };\n window.addEventListener(\"resize\", this.resizeListener, false);\n this.fitContainer();\n }\n\n public updateEnvironmentConfiguration(environmentConfiguration: EnvironmentConfiguration) {\n this.environmentConfiguration = environmentConfiguration;\n\n if (environmentConfiguration.skybox) {\n if (\"hdrJpgUrl\" in environmentConfiguration.skybox) {\n this.useHDRJPG(environmentConfiguration.skybox.hdrJpgUrl);\n } else if (\"hdrUrl\" in environmentConfiguration.skybox) {\n this.useHDRI(environmentConfiguration.skybox.hdrUrl);\n }\n }\n\n this.updateSkyboxAndEnvValues();\n this.updateAmbientLightValues();\n this.updateSunValues();\n this.updateFogValues();\n }\n\n public setupTweakPane(tweakPane: TweakPane) {\n tweakPane.setupRenderPane(\n this.effectComposer,\n this.normalPass,\n this.ppssaoEffect,\n this.ppssaoPass,\n this.n8aopass,\n this.toneMappingEffect,\n this.toneMappingPass,\n this.bcs,\n this.bloomEffect,\n this.gaussGrainEffect,\n this.spawnSun,\n this.sun,\n this.setHDRIFromFile.bind(this),\n (azimuthalAngle: number) => {\n envValues.skyboxAzimuthalAngle = azimuthalAngle;\n this.updateSkyboxRotation();\n },\n (polarAngle: number) => {\n envValues.skyboxPolarAngle = polarAngle;\n this.updateSkyboxRotation();\n },\n this.setAmbientLight.bind(this),\n this.setFog.bind(this),\n );\n }\n\n public dispose() {\n window.removeEventListener(\"resize\", this.resizeListener);\n this.renderer.dispose();\n }\n\n public fitContainer() {\n if (!this) {\n console.error(\"Composer not initialized\");\n return;\n }\n const parentElement = this.renderer.domElement.parentNode as HTMLElement;\n if (!parentElement) {\n return;\n }\n this.width = parentElement.clientWidth;\n this.height = parentElement.clientHeight;\n this.cameraManager.activeCamera.aspect = this.width / this.height;\n this.cameraManager.activeCamera.updateProjectionMatrix();\n this.renderer.setPixelRatio(window.devicePixelRatio);\n this.resolution.set(\n this.width * window.devicePixelRatio,\n this.height * window.devicePixelRatio,\n );\n this.effectComposer.setSize(\n this.width / window.devicePixelRatio,\n this.height / window.devicePixelRatio,\n );\n this.renderPass.setSize(this.width, this.height);\n if (ppssaoValues.enabled) {\n this.normalPass.setSize(this.width, this.height);\n this.normalTextureEffect.setSize(this.width, this.height);\n this.ppssaoPass.setSize(this.width, this.height);\n }\n if (n8ssaoValues.enabled) {\n this.n8aopass.setSize(this.width, this.height);\n }\n this.fxaaPass.setSize(this.width, this.height);\n this.smaaPass.setSize(this.width, this.height);\n this.bloomPass.setSize(this.width, this.height);\n this.toneMappingPass.setSize(this.width, this.height);\n this.gaussGrainPass.setSize(this.width, this.height);\n this.gaussGrainEffect.uniforms.resolution.value = new Vector2(this.width, this.height);\n this.renderer.setSize(this.width, this.height);\n }\n\n public render(timeManager: TimeManager): void {\n this.renderer.info.reset();\n this.renderPass.mainCamera = this.cameraManager.activeCamera;\n this.normalPass.texture.needsUpdate = true;\n this.gaussGrainEffect.uniforms.time.value = timeManager.time;\n this.effectComposer.render();\n this.renderer.clearDepth();\n this.renderer.render(this.postPostScene, this.cameraManager.activeCamera);\n }\n\n public updateSkyboxRotation() {\n this.scene.backgroundRotation = new Euler(\n MathUtils.degToRad(envValues.skyboxPolarAngle),\n MathUtils.degToRad(envValues.skyboxAzimuthalAngle),\n 0,\n );\n this.scene.environmentRotation = new Euler(\n MathUtils.degToRad(envValues.skyboxPolarAngle),\n MathUtils.degToRad(envValues.skyboxAzimuthalAngle),\n 0,\n );\n }\n\n private async loadHDRJPG(url: string): Promise<Texture> {\n return new Promise((resolve, reject) => {\n const pmremGenerator = new PMREMGenerator(this.renderer);\n const hdrJpg = new HDRJPGLoader(this.renderer).load(url, () => {\n const hdrJpgEquirectangularMap = hdrJpg.renderTarget.texture;\n hdrJpgEquirectangularMap.mapping = EquirectangularReflectionMapping;\n hdrJpgEquirectangularMap.needsUpdate = true;\n\n const envMap = pmremGenerator!.fromEquirectangular(hdrJpgEquirectangularMap).texture;\n hdrJpgEquirectangularMap.dispose();\n pmremGenerator!.dispose();\n hdrJpg.dispose();\n if (envMap) {\n envMap.colorSpace = LinearSRGBColorSpace;\n envMap.needsUpdate = true;\n resolve(envMap);\n } else {\n reject(\"Failed to generate environment map\");\n }\n });\n });\n }\n\n private async loadHDRi(url: string): Promise<Texture> {\n return new Promise((resolve, reject) => {\n const pmremGenerator = new PMREMGenerator(this.renderer);\n new RGBELoader(new LoadingManager()).load(url, (texture) => {\n const envMap = pmremGenerator!.fromEquirectangular(texture).texture;\n texture.dispose();\n pmremGenerator!.dispose();\n if (envMap) {\n envMap.colorSpace = LinearSRGBColorSpace;\n envMap.needsUpdate = true;\n resolve(envMap);\n } else {\n reject(\"Failed to generate environment map\");\n }\n });\n });\n }\n\n public useHDRJPG(url: string, fromFile: boolean = false): void {\n if (this.skyboxState.src.hdrJpgUrl === url) {\n return;\n }\n\n const hdrJPGPromise = this.loadHDRJPG(url);\n this.skyboxState.src = { hdrJpgUrl: url };\n this.skyboxState.latestPromise = hdrJPGPromise;\n hdrJPGPromise.then((envMap) => {\n if (this.skyboxState.latestPromise !== hdrJPGPromise) {\n return;\n }\n this.applyEnvMap(envMap);\n });\n }\n\n public useHDRI(url: string): void {\n if (this.skyboxState.src.hdrUrl === url) {\n return;\n }\n const hdrPromise = this.loadHDRi(url);\n this.skyboxState.src = { hdrUrl: url };\n this.skyboxState.latestPromise = hdrPromise;\n hdrPromise.then((envMap) => {\n if (this.skyboxState.latestPromise !== hdrPromise) {\n return;\n }\n this.applyEnvMap(envMap);\n });\n }\n\n public setHDRIFromFile(): void {\n if (!this.renderer) return;\n const fileInput = document.createElement(\"input\");\n fileInput.type = \"file\";\n fileInput.accept = \".hdr,.jpg\";\n fileInput.addEventListener(\"change\", () => {\n const file = fileInput.files?.[0];\n if (!file) {\n console.log(\"no file\");\n return;\n }\n const extension = file.name.split(\".\").pop();\n const fileURL = URL.createObjectURL(file);\n if (fileURL) {\n if (extension === \"hdr\") {\n this.useHDRI(fileURL);\n } else if (extension === \"jpg\") {\n this.useHDRJPG(fileURL);\n } else {\n console.error(`Unrecognized extension for HDR file ${file.name}`);\n }\n URL.revokeObjectURL(fileURL);\n document.body.removeChild(fileInput);\n }\n });\n document.body.appendChild(fileInput);\n fileInput.click();\n }\n\n public setFog(): void {\n if (envValues.fog.fogFar === 0) {\n this.scene.fog = null;\n return;\n }\n const fogColor = new Color().setRGB(\n envValues.fog.fogColor.r,\n envValues.fog.fogColor.g,\n envValues.fog.fogColor.b,\n );\n this.scene.fog = new Fog(fogColor, envValues.fog.fogNear, envValues.fog.fogFar);\n }\n\n public setAmbientLight(): void {\n if (this.ambientLight) {\n this.scene.remove(this.ambientLight);\n this.ambientLight.dispose();\n }\n const ambientLightColor = new Color().setRGB(\n envValues.ambientLight.ambientLightColor.r,\n envValues.ambientLight.ambientLightColor.g,\n envValues.ambientLight.ambientLightColor.b,\n );\n this.ambientLight = new AmbientLight(\n ambientLightColor,\n envValues.ambientLight.ambientLightIntensity,\n );\n this.scene.add(this.ambientLight);\n }\n\n private updateSunValues() {\n if (typeof this.environmentConfiguration?.sun?.intensity === \"number\") {\n sunValues.sunIntensity = this.environmentConfiguration.sun.intensity;\n this.sun?.setIntensity(this.environmentConfiguration.sun.intensity);\n }\n if (typeof this.environmentConfiguration?.sun?.azimuthalAngle === \"number\") {\n sunValues.sunPosition.sunAzimuthalAngle = this.environmentConfiguration.sun.azimuthalAngle;\n this.sun?.setAzimuthalAngle(\n this.environmentConfiguration.sun.azimuthalAngle * (Math.PI / 180),\n );\n }\n if (typeof this.environmentConfiguration?.sun?.polarAngle === \"number\") {\n sunValues.sunPosition.sunPolarAngle = this.environmentConfiguration.sun.polarAngle;\n this.sun?.setPolarAngle(this.environmentConfiguration.sun.polarAngle * (Math.PI / 180));\n }\n }\n\n private updateFogValues() {\n if (typeof this.environmentConfiguration?.fog?.fogNear === \"number\") {\n envValues.fog.fogNear = this.environmentConfiguration.fog.fogNear;\n }\n if (typeof this.environmentConfiguration?.fog?.fogFar === \"number\") {\n envValues.fog.fogFar = this.environmentConfiguration.fog.fogFar;\n }\n if (\n typeof this.environmentConfiguration?.fog?.fogColor?.r === \"number\" &&\n typeof this.environmentConfiguration?.fog?.fogColor?.g === \"number\" &&\n typeof this.environmentConfiguration?.fog?.fogColor?.b === \"number\"\n ) {\n envValues.fog.fogColor.r = this.environmentConfiguration.fog.fogColor.r;\n envValues.fog.fogColor.g = this.environmentConfiguration.fog.fogColor.g;\n envValues.fog.fogColor.b = this.environmentConfiguration.fog.fogColor.b;\n }\n this.setFog();\n }\n\n private updateSkyboxAndEnvValues() {\n if (typeof this.environmentConfiguration?.envMap?.intensity === \"number\") {\n envValues.envMapIntensity = this.environmentConfiguration?.envMap.intensity;\n }\n this.scene.environmentIntensity = envValues.envMapIntensity;\n\n if (typeof this.environmentConfiguration?.skybox?.intensity === \"number\") {\n envValues.skyboxIntensity = this.environmentConfiguration?.skybox.intensity;\n }\n this.scene.backgroundIntensity = envValues.skyboxIntensity;\n\n if (typeof this.environmentConfiguration?.skybox?.blurriness === \"number\") {\n envValues.skyboxBlurriness = this.environmentConfiguration?.skybox.blurriness;\n }\n this.scene.backgroundBlurriness = envValues.skyboxBlurriness;\n\n if (typeof this.environmentConfiguration?.skybox?.azimuthalAngle === \"number\") {\n envValues.skyboxAzimuthalAngle = this.environmentConfiguration?.skybox.azimuthalAngle;\n this.updateSkyboxRotation();\n }\n\n if (typeof this.environmentConfiguration?.skybox?.polarAngle === \"number\") {\n envValues.skyboxPolarAngle = this.environmentConfiguration?.skybox.polarAngle;\n this.updateSkyboxRotation();\n }\n }\n\n private updateAmbientLightValues() {\n if (typeof this.environmentConfiguration?.ambientLight?.intensity === \"number\") {\n envValues.ambientLight.ambientLightIntensity =\n this.environmentConfiguration.ambientLight.intensity;\n }\n this.setAmbientLight();\n }\n\n private applyEnvMap(envMap: Texture) {\n this.scene.environment = envMap;\n this.scene.environmentIntensity = envValues.envMapIntensity;\n this.scene.environmentRotation = new Euler(\n MathUtils.degToRad(envValues.skyboxPolarAngle),\n MathUtils.degToRad(envValues.skyboxAzimuthalAngle),\n 0,\n );\n this.scene.background = envMap;\n this.scene.backgroundIntensity = envValues.skyboxIntensity;\n this.scene.backgroundBlurriness = envValues.skyboxBlurriness;\n this.scene.backgroundRotation = new Euler(\n MathUtils.degToRad(envValues.skyboxPolarAngle),\n MathUtils.degToRad(envValues.skyboxAzimuthalAngle),\n 0,\n );\n }\n}\n", "import { CameraHelper, Color, DirectionalLight, Group, OrthographicCamera, Vector3 } from \"three\";\n\nimport { sunValues } from \"../tweakpane/blades/environmentFolder\";\n\nexport class Sun extends Group {\n private readonly debug: boolean = false;\n private readonly sunOffset: Vector3 = new Vector3(\n sunValues.sunPosition.sunAzimuthalAngle * (Math.PI / 180),\n sunValues.sunPosition.sunPolarAngle * (Math.PI / 180),\n 100,\n );\n private readonly shadowResolution: number = 8192;\n private readonly shadowCamFrustum: number = 50;\n private readonly camHelper: CameraHelper | null = null;\n\n private readonly shadowCamera: OrthographicCamera;\n private readonly directionalLight: DirectionalLight;\n\n public target: Vector3 | null = null;\n\n constructor() {\n super();\n this.shadowCamera = new OrthographicCamera(\n -this.shadowCamFrustum,\n this.shadowCamFrustum,\n this.shadowCamFrustum,\n -this.shadowCamFrustum,\n 0.1,\n 200,\n );\n if (this.debug === true) {\n this.camHelper = new CameraHelper(this.shadowCamera);\n }\n this.directionalLight = new DirectionalLight(0xffffff);\n this.directionalLight.intensity = sunValues.sunIntensity;\n this.directionalLight.shadow.normalBias = 0.1;\n this.directionalLight.shadow.radius = 0.02;\n this.directionalLight.shadow.camera = this.shadowCamera;\n this.directionalLight.shadow.mapSize.set(this.shadowResolution, this.shadowResolution);\n this.directionalLight.castShadow = true;\n this.setColor();\n\n this.updateCharacterPosition(new Vector3(0, 0, 0));\n\n this.add(this.directionalLight);\n if (this.debug === true && this.camHelper instanceof CameraHelper) {\n this.add(this.camHelper);\n }\n }\n\n public updateCharacterPosition(position: Vector3 | undefined) {\n if (!position) return;\n this.target = position;\n this.setSunPosition(this.sunOffset.x, this.sunOffset.y);\n }\n\n public setAzimuthalAngle(angle: number) {\n if (this.sunOffset) this.sunOffset.x = angle;\n if (this.target) this.updateCharacterPosition(this.target);\n }\n\n public setPolarAngle(angle: number) {\n if (this.sunOffset) this.sunOffset.y = angle;\n if (this.target) this.updateCharacterPosition(this.target);\n }\n\n public setIntensity(intensity: number) {\n this.directionalLight.intensity = intensity;\n }\n\n public setColor() {\n this.directionalLight.color = new Color().setRGB(\n sunValues.sunColor.r,\n sunValues.sunColor.g,\n sunValues.sunColor.b,\n );\n }\n\n private setSunPosition(azimuthalAngle: number, polarAngle: number) {\n if (!this.target) return;\n const distance = this.sunOffset.z;\n const sphericalPosition = new Vector3(\n distance * Math.sin(polarAngle) * Math.cos(azimuthalAngle),\n distance * Math.cos(polarAngle),\n distance * Math.sin(polarAngle) * Math.sin(azimuthalAngle),\n );\n const newSunPosition = this.target.clone().add(sphericalPosition);\n this.directionalLight.position.set(newSunPosition.x, newSunPosition.y, newSunPosition.z);\n this.directionalLight.target.position.copy(this.target.clone());\n this.directionalLight.target.updateMatrixWorld();\n }\n}\n", "import { ShaderMaterial, Uniform } from \"three\";\n\nimport { vertexShader } from \"../shaders/vertex-shader\";\n\nexport const BrightnessContrastSaturation = new ShaderMaterial({\n uniforms: {\n tDiffuse: new Uniform(null),\n brightness: new Uniform(0.0),\n contrast: new Uniform(1.0),\n saturation: new Uniform(1.0),\n },\n vertexShader: vertexShader,\n fragmentShader: /* glsl */ `\n precision highp float;\n in vec2 vUv;\n\n uniform sampler2D tDiffuse;\n uniform float brightness;\n uniform float contrast;\n uniform float saturation;\n\n mat4 brightnessMatrix(float brightness) {\n return mat4(\n 1, 0, 0, 0,\n 0, 1, 0, 0,\n 0, 0, 1, 0,\n brightness, brightness, brightness, 1\n );\n }\n\n mat4 contrastMatrix(float contrast) {\n float t = (1.0 - contrast) / 2.0;\n\n return mat4(\n contrast, 0, 0, 0,\n 0, contrast, 0, 0,\n 0, 0, contrast, 0,\n t, t, t, 1\n );\n }\n\n mat4 saturationMatrix(float saturation) {\n vec3 luminance = vec3(0.3086, 0.6094, 0.0820);\n float oneMinusSat = 1.0 - saturation;\n vec3 red = vec3(luminance.x * oneMinusSat);\n red += vec3(saturation, 0, 0);\n vec3 green = vec3(luminance.y * oneMinusSat);\n green += vec3(0, saturation, 0);\n vec3 blue = vec3(luminance.z * oneMinusSat);\n blue += vec3(0, 0, saturation);\n return mat4(\n red, 0,\n green, 0,\n blue, 0,\n 0, 0, 0, 1\n );\n }\n\n void main(void) {\n vec4 color = texture(tDiffuse, vUv);\n gl_FragColor = (\n brightnessMatrix(brightness) *\n contrastMatrix(contrast) *\n saturationMatrix(saturation) *\n color\n );\n }\n `,\n dithering: true,\n});\n", "export const vertexShader = /* glsl */ `\n precision highp float;\n\n out vec2 vUv;\n void main() {\n vUv = uv;\n gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);\n }\n `;\n", "import { ShaderMaterial, Uniform, Vector2 } from \"three\";\n\nimport { vertexShader } from \"../shaders/vertex-shader\";\n\nexport const GaussGrainEffect = new ShaderMaterial({\n uniforms: {\n tDiffuse: new Uniform(null),\n resolution: new Uniform(new Vector2()),\n time: new Uniform(0.0),\n amount: new Uniform(0.0),\n alpha: new Uniform(0.0),\n },\n vertexShader: vertexShader,\n fragmentShader: /* glsl */ `\n precision highp float;\n in vec2 vUv;\n\n uniform sampler2D tDiffuse;\n uniform vec2 resolution;\n uniform float time;\n uniform float amount;\n uniform float alpha;\n\n const float PI = acos(-1.0);\n const float TAU = PI * 2.0;\n const float SQRTAU = sqrt(TAU);\n\n float gaussian(float z, float u, float o) {\n return (\n (1.0 / (o * SQRTAU)) *\n (exp(-(((z - u) * (z - u)) / (2.0 * (o * o)))))\n );\n }\n\n vec3 gaussgrain() {\n vec2 ps = vec2(1.0) / resolution.xy;\n vec2 uv = gl_FragCoord.xy * ps;\n float t = time;\n float seed = dot(uv, vec2(12.9898, 78.233));\n float noise = fract(sin(seed) * 43758.5453123 + t);\n noise = gaussian(noise, 0.0, 0.5);\n return vec3(noise);\n }\n\n void main(void) {\n vec2 uv = vUv;\n vec4 originalColor = texture(tDiffuse, uv);\n vec3 grain = gaussgrain();\n vec3 col = originalColor.rgb + (grain * amount);\n gl_FragColor = vec4(clamp(col, 0.0, 1.0), alpha);\n }\n `,\n dithering: true,\n});\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport { Pass } from \"postprocessing\";\nimport {\n Color,\n DataTexture,\n FloatType,\n Fog,\n FogExp2,\n HalfFloatType,\n LinearFilter,\n NearestFilter,\n NoColorSpace,\n OrthographicCamera,\n PerspectiveCamera,\n RGBAFormat,\n RedFormat,\n RepeatWrapping,\n Scene,\n ShaderMaterial,\n Texture,\n Uniform,\n Vector2,\n Vector3,\n WebGLRenderTarget,\n WebGLRenderer,\n} from \"three\";\n\nimport { BlueNoise } from \"./BlueNoise\";\nimport { DepthDownSample } from \"./DepthDownSample\";\nimport { EffectCompositer } from \"./EffectCompositer\";\nimport { EffectShader } from \"./EffectShader\";\nimport { FullScreenTriangle } from \"./FullScreenTriangle\";\nimport { PoissionBlur } from \"./PoissionBlur\";\n\nconst bluenoiseBits: Uint8Array = Uint8Array.from(atob(BlueNoise), (c) => c.charCodeAt(0));\n\nexport type RenderModeType = \"Combined\" | \"AO\" | \"No AO\" | \"Split\" | \"Split AO\";\n\ntype PresetsType = \"Performance\" | \"Low\" | \"Medium\" | \"High\" | \"Ultra\";\n\ninterface IConfiguration {\n aoSamples: number;\n aoRadius: number;\n denoiseSamples: number;\n denoiseRadius: number;\n distanceFalloff: number;\n intensity: number;\n denoiseIterations: number;\n renderMode: number;\n color: Color;\n gammaCorrection: boolean;\n logarithmicDepthBuffer: boolean;\n screenSpaceRadius: boolean;\n halfRes: boolean;\n depthAwareUpsampling: boolean;\n colorMultiply: boolean;\n}\n\nfunction checkTimerQuery(\n timerQuery: WebGLQuery,\n gl: WebGL2RenderingContext,\n pass: N8SSAOPass,\n): void {\n const available = gl.getQueryParameter(timerQuery, gl.QUERY_RESULT_AVAILABLE);\n if (available) {\n const elapsedTimeInNs = gl.getQueryParameter(timerQuery, gl.QUERY_RESULT);\n const elapsedTimeInMs = elapsedTimeInNs / 1000000;\n pass.lastTime = elapsedTimeInMs;\n } else {\n setTimeout(() => checkTimerQuery(timerQuery, gl, pass), 1);\n }\n}\n\nclass N8SSAOPass extends Pass {\n private debugMode: boolean;\n\n public scene: Scene;\n public camera: PerspectiveCamera | OrthographicCamera;\n public lastTime: number = 0;\n\n private width: number;\n private height: number;\n\n public configuration: IConfiguration & ProxyHandler<IConfiguration>;\n\n private autosetGamma: boolean = true;\n private samples: Vector3[] = [];\n private samplesR: number[] = [];\n private samplesDenoise: Vector2[] = [];\n\n private copyQuadMaterial: ShaderMaterial = new ShaderMaterial({\n uniforms: { tDiffuse: new Uniform(null) },\n\n depthWrite: false,\n\n vertexShader: /* glsl */ `\n varying vec2 vUv;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(position, 1);\n }\n `,\n\n fragmentShader: /* glsl */ `\n uniform sampler2D tDiffuse;\n varying vec2 vUv;\n void main(void) {\n gl_FragColor = texture2D(tDiffuse, vUv);\n }\n `,\n });\n\n private copyQuad: FullScreenTriangle = new FullScreenTriangle(this.copyQuadMaterial);\n\n private writeTargetInternal: WebGLRenderTarget;\n private readTargetInternal: WebGLRenderTarget;\n private outputTargetInternal: WebGLRenderTarget;\n private depthDownsampleTarget: WebGLRenderTarget | null;\n\n private depthDownsampleQuad: FullScreenTriangle | null;\n private effectShaderQuad: FullScreenTriangle | null;\n private effectCompositerQuad: FullScreenTriangle | null;\n private poissonBlurQuad: FullScreenTriangle | null;\n\n private depthTexture: Texture;\n private bluenoise: DataTexture;\n\n private r: Vector2;\n private c: Color;\n\n constructor(\n scene: Scene,\n camera: PerspectiveCamera | OrthographicCamera,\n width = 512,\n height = 512,\n ) {\n super();\n this.width = width;\n this.height = height;\n\n this.camera = camera;\n this.scene = scene;\n\n this.configuration = new Proxy(\n {\n aoSamples: 16,\n aoRadius: 5.0,\n denoiseSamples: 8,\n denoiseRadius: 12,\n distanceFalloff: 1.0,\n intensity: 5,\n denoiseIterations: 2.0,\n renderMode: 0,\n color: new Color(0, 0, 0),\n gammaCorrection: true,\n logarithmicDepthBuffer: false,\n screenSpaceRadius: false,\n halfRes: false,\n depthAwareUpsampling: true,\n colorMultiply: true,\n },\n {\n set: (target: any, propName: string, value: any) => {\n const oldProp = target[propName];\n target[propName] = value;\n if (propName === \"aoSamples\" && oldProp !== value) {\n this.configureAOPass(this.configuration.logarithmicDepthBuffer);\n }\n if (propName === \"denoiseSamples\" && oldProp !== value) {\n this.configureDenoisePass(this.configuration.logarithmicDepthBuffer);\n }\n if (propName === \"halfRes\" && oldProp !== value) {\n this.configureAOPass(this.configuration.logarithmicDepthBuffer);\n this.configureHalfResTargets();\n this.configureEffectCompositer(this.configuration.logarithmicDepthBuffer);\n this.setSize(this.width, this.height);\n }\n if (propName === \"depthAwareUpsampling\" && oldProp !== value) {\n this.configureEffectCompositer(this.configuration.logarithmicDepthBuffer);\n }\n if (propName === \"gammaCorrection\") {\n this.autosetGamma = false;\n }\n return true;\n },\n },\n );\n\n this.configureEffectCompositer(this.configuration.logarithmicDepthBuffer);\n this.configureSampleDependentPasses();\n this.configureHalfResTargets();\n\n this.writeTargetInternal = new WebGLRenderTarget(this.width, this.height, {\n minFilter: LinearFilter,\n magFilter: LinearFilter,\n depthBuffer: false,\n });\n\n this.readTargetInternal = new WebGLRenderTarget(this.width, this.height, {\n minFilter: LinearFilter,\n magFilter: LinearFilter,\n depthBuffer: false,\n });\n\n this.outputTargetInternal = new WebGLRenderTarget(this.width, this.height, {\n minFilter: LinearFilter,\n magFilter: LinearFilter,\n depthBuffer: false,\n });\n\n this.bluenoise = new DataTexture(bluenoiseBits, 128, 128);\n this.bluenoise.colorSpace = NoColorSpace;\n this.bluenoise.wrapS = RepeatWrapping;\n this.bluenoise.wrapT = RepeatWrapping;\n this.bluenoise.minFilter = NearestFilter;\n this.bluenoise.magFilter = NearestFilter;\n this.bluenoise.needsUpdate = true;\n this.lastTime = 0;\n this.needsDepthTexture = true;\n this.needsSwap = true;\n this.r = new Vector2();\n this.c = new Color();\n }\n\n private configureHalfResTargets(): void {\n if (this.configuration.halfRes) {\n this.depthDownsampleTarget = new WebGLRenderTarget(this.width / 2, this.height / 2, {\n count: 2,\n depthBuffer: false,\n });\n this.depthDownsampleTarget.textures[0].format = RedFormat;\n this.depthDownsampleTarget.textures[0].type = FloatType;\n this.depthDownsampleTarget.textures[0].minFilter = NearestFilter;\n this.depthDownsampleTarget.textures[0].magFilter = NearestFilter;\n this.depthDownsampleTarget.textures[1].format = RGBAFormat;\n this.depthDownsampleTarget.textures[1].type = HalfFloatType;\n this.depthDownsampleTarget.textures[1].minFilter = NearestFilter;\n this.depthDownsampleTarget.textures[1].magFilter = NearestFilter;\n this.depthDownsampleQuad = new FullScreenTriangle(new ShaderMaterial(DepthDownSample));\n } else {\n if (this.depthDownsampleTarget) {\n this.depthDownsampleTarget.dispose();\n this.depthDownsampleTarget = null;\n }\n if (this.depthDownsampleQuad) {\n this.depthDownsampleQuad.dispose();\n this.depthDownsampleQuad = null;\n }\n }\n }\n\n private configureSampleDependentPasses(): void {\n this.configureAOPass(this.configuration.logarithmicDepthBuffer);\n this.configureDenoisePass(this.configuration.logarithmicDepthBuffer);\n }\n\n private configureAOPass(logarithmicDepthBuffer = false): void {\n this.samples = this.generateHemisphereSamples(this.configuration.aoSamples);\n this.samplesR = this.generateHemisphereSamplesR(this.configuration.aoSamples);\n const e = { ...EffectShader };\n e.fragmentShader = e.fragmentShader\n .replace(\"16\", this.configuration.aoSamples.toString())\n .replace(\"16.0\", this.configuration.aoSamples.toString() + \".0\");\n if (logarithmicDepthBuffer) {\n e.fragmentShader = \"#define LOGDEPTH\\n\" + e.fragmentShader;\n }\n if (this.configuration.halfRes) {\n e.fragmentShader = \"#define HALFRES\\n\" + e.fragmentShader;\n }\n if (this.effectShaderQuad) {\n this.effectShaderQuad.material.dispose();\n this.effectShaderQuad.material = new ShaderMaterial(e);\n } else {\n this.effectShaderQuad = new FullScreenTriangle(new ShaderMaterial(e));\n }\n }\n\n private configureDenoisePass(logarithmicDepthBuffer: boolean = false): void {\n this.samplesDenoise = this.generateDenoiseSamples(this.configuration.denoiseSamples, 11);\n const p = { ...PoissionBlur };\n p.fragmentShader = p.fragmentShader.replace(\"16\", this.configuration.denoiseSamples.toString());\n if (logarithmicDepthBuffer) {\n p.fragmentShader = \"#define LOGDEPTH\\n\" + p.fragmentShader;\n }\n if (this.poissonBlurQuad) {\n this.poissonBlurQuad.material.dispose();\n this.poissonBlurQuad.material = new ShaderMaterial(p);\n } else {\n this.poissonBlurQuad = new FullScreenTriangle(new ShaderMaterial(p));\n }\n }\n\n private configureEffectCompositer(logarithmicDepthBuffer: boolean = false): void {\n const e = { ...EffectCompositer };\n\n if (logarithmicDepthBuffer) {\n e.fragmentShader = \"#define LOGDEPTH\\n\" + e.fragmentShader;\n }\n\n if (this.configuration.halfRes && this.configuration.depthAwareUpsampling) {\n e.fragmentShader = \"#define HALFRES\\n\" + e.fragmentShader;\n }\n\n if (this.effectCompositerQuad) {\n this.effectCompositerQuad.material.dispose();\n this.effectCompositerQuad.material = new ShaderMaterial(e);\n } else {\n this.effectCompositerQuad = new FullScreenTriangle(new ShaderMaterial(e));\n }\n }\n\n private generateHemisphereSamples(n: number): Vector3[] {\n const points = [];\n for (let k = 0; k < n; k++) {\n const theta = 2.399963 * k;\n const r = Math.sqrt(k + 0.5) / Math.sqrt(n);\n const x = r * Math.cos(theta);\n const y = r * Math.sin(theta);\n\n const z = Math.sqrt(1 - (x * x + y * y));\n points.push(new Vector3(x, y, z));\n }\n return points;\n }\n\n private generateHemisphereSamplesR(n: number): number[] {\n const samplesR = [];\n for (let i = 0; i < n; i++) {\n samplesR.push((i + 1) / n);\n }\n return samplesR;\n }\n\n private generateDenoiseSamples(numSamples: number, numRings: number): Vector2[] {\n const angleStep = (2 * Math.PI * numRings) / numSamples;\n const invNumSamples = 1.0 / numSamples;\n const radiusStep = invNumSamples;\n const samples = [];\n let radius = invNumSamples;\n let angle = 0;\n for (let i = 0; i < numSamples; i++) {\n samples.push(\n new Vector2(Math.cos(angle), Math.sin(angle)).multiplyScalar(Math.pow(radius, 0.75)),\n );\n radius += radiusStep;\n angle += angleStep;\n }\n return samples;\n }\n\n public setSize(width: number, height: number): void {\n this.width = width;\n this.height = height;\n const c = this.configuration.halfRes ? 0.5 : 1;\n this.writeTargetInternal.setSize(width * c, height * c);\n this.readTargetInternal.setSize(width * c, height * c);\n if (this.configuration.halfRes && this.depthDownsampleTarget) {\n this.depthDownsampleTarget.setSize(width * c, height * c);\n }\n this.outputTargetInternal.setSize(width, height);\n }\n\n public setDepthTexture(depthTexture: DataTexture): void {\n this.depthTexture = depthTexture;\n }\n\n public render(\n renderer: WebGLRenderer,\n inputBuffer: WebGLRenderTarget,\n outputBuffer: WebGLRenderTarget,\n ): void {\n const xrEnabled = renderer.xr.enabled;\n renderer.xr.enabled = false;\n\n let ext: any;\n let timerQuery: WebGLQuery | null = null;\n let gl: WebGL2RenderingContext | WebGLRenderingContext | null = null;\n gl = renderer.getContext();\n\n if (this.debugMode) {\n ext = gl.getExtension(\"EXT_disjoint_timer_query_webgl2\");\n if (ext === null) {\n console.error(\"EXT_disjoint_timer_query_webgl2 not available, disabling debug mode.\");\n this.debugMode = false;\n gl = null;\n }\n }\n\n if (this.debugMode && gl) {\n timerQuery = (gl as WebGL2RenderingContext).createQuery()!;\n (gl as WebGL2RenderingContext).beginQuery(ext.TIME_ELAPSED_EXT, timerQuery);\n }\n\n if (\n renderer.capabilities.logarithmicDepthBuffer !== this.configuration.logarithmicDepthBuffer\n ) {\n this.configuration.logarithmicDepthBuffer = renderer.capabilities.logarithmicDepthBuffer;\n this.configureAOPass(this.configuration.logarithmicDepthBuffer);\n this.configureDenoisePass(this.configuration.logarithmicDepthBuffer);\n this.configureEffectCompositer(this.configuration.logarithmicDepthBuffer);\n }\n\n if (inputBuffer.texture.type !== this.outputTargetInternal.texture.type) {\n this.outputTargetInternal.texture.type = inputBuffer.texture.type;\n this.outputTargetInternal.texture.needsUpdate = true;\n }\n\n this.camera.updateMatrixWorld();\n this.r.set(this.width, this.height);\n let trueRadius = this.configuration.aoRadius;\n\n if (this.configuration.halfRes && this.configuration.screenSpaceRadius) {\n trueRadius *= 0.5;\n }\n\n if (this.configuration.halfRes && this.depthDownsampleQuad) {\n const depthDownsampleUniforms = this.depthDownsampleQuad.material.uniforms;\n renderer.setRenderTarget(this.depthDownsampleTarget);\n depthDownsampleUniforms.sceneDepth.value = this.depthTexture;\n depthDownsampleUniforms.resolution.value = this.r;\n depthDownsampleUniforms.near.value = this.camera.near;\n depthDownsampleUniforms.far.value = this.camera.far;\n depthDownsampleUniforms.projectionMatrixInv.value = this.camera.projectionMatrixInverse;\n depthDownsampleUniforms.viewMatrixInv.value = this.camera.matrixWorld;\n depthDownsampleUniforms.logDepth.value = this.configuration.logarithmicDepthBuffer;\n this.depthDownsampleQuad.render(renderer);\n }\n\n if (!this.effectShaderQuad) return;\n\n const effectShaderUniforms = this.effectShaderQuad.material.uniforms;\n\n effectShaderUniforms.sceneDiffuse.value = inputBuffer.texture;\n effectShaderUniforms.sceneDepth.value = this.configuration.halfRes\n ? this.depthDownsampleTarget!.textures[0]\n : this.depthTexture;\n effectShaderUniforms.sceneNormal.value = this.configuration.halfRes\n ? this.depthDownsampleTarget!.textures[1]\n : null;\n effectShaderUniforms.projMat.value = this.camera.projectionMatrix;\n effectShaderUniforms.viewMat.value = this.camera.matrixWorldInverse;\n effectShaderUniforms.projViewMat.value = this.camera.projectionMatrix\n .clone()\n .multiply(this.camera.matrixWorldInverse.clone());\n effectShaderUniforms.projectionMatrixInv.value = this.camera.projectionMatrixInverse;\n effectShaderUniforms.viewMatrixInv.value = this.camera.matrixWorld;\n effectShaderUniforms.cameraPos.value = this.camera.getWorldPosition(new Vector3());\n effectShaderUniforms.resolution.value = this.configuration.halfRes\n ? this.r\n .clone()\n .multiplyScalar(1 / 2)\n .floor()\n : this.r;\n effectShaderUniforms.time.value = performance.now() / 1000;\n effectShaderUniforms.samples.value = this.samples;\n effectShaderUniforms.samplesR.value = this.samplesR;\n effectShaderUniforms.bluenoise.value = this.bluenoise;\n effectShaderUniforms.radius.value = trueRadius;\n effectShaderUniforms.distanceFalloff.value = this.configuration.distanceFalloff;\n effectShaderUniforms.near.value = this.camera.near;\n effectShaderUniforms.far.value = this.camera.far;\n effectShaderUniforms.logDepth.value = renderer.capabilities.logarithmicDepthBuffer;\n effectShaderUniforms.ortho.value = this.camera instanceof OrthographicCamera;\n effectShaderUniforms.screenSpaceRadius.value = this.configuration.screenSpaceRadius;\n\n // Start the AO\n renderer.setRenderTarget(this.writeTargetInternal);\n this.effectShaderQuad.render(renderer);\n // End the AO\n\n const poissonBlurUniforms = this.poissonBlurQuad!.material.uniforms;\n\n // Start the blur\n for (let i = 0; i < this.configuration.denoiseIterations; i++) {\n if (!poissonBlurUniforms || !this.poissonBlurQuad) return;\n [this.writeTargetInternal, this.readTargetInternal] = [\n this.readTargetInternal,\n this.writeTargetInternal,\n ];\n poissonBlurUniforms.tDiffuse.value = this.readTargetInternal.texture;\n poissonBlurUniforms.sceneDepth.value = this.configuration.halfRes\n ? this.depthDownsampleTarget!.textures[0]\n : this.depthTexture;\n poissonBlurUniforms.projMat.value = this.camera.projectionMatrix;\n poissonBlurUniforms.viewMat.value = this.camera.matrixWorldInverse;\n poissonBlurUniforms.projectionMatrixInv.value = this.camera.projectionMatrixInverse;\n poissonBlurUniforms.viewMatrixInv.value = this.camera.matrixWorld;\n poissonBlurUniforms.cameraPos.value = this.camera.getWorldPosition(new Vector3());\n poissonBlurUniforms.resolution.value = this.configuration.halfRes\n ? this.r\n .clone()\n .multiplyScalar(1 / 2)\n .floor()\n : this.r;\n poissonBlurUniforms.time.value = performance.now() / 1000;\n poissonBlurUniforms.blueNoise.value = this.bluenoise;\n poissonBlurUniforms.radius.value =\n this.configuration.denoiseRadius * (this.configuration.halfRes ? 1 / 2 : 1);\n poissonBlurUniforms.worldRadius.value = trueRadius;\n poissonBlurUniforms.distanceFalloff.value = this.configuration.distanceFalloff;\n poissonBlurUniforms.index.value = i;\n poissonBlurUniforms.poissonDisk.value = this.samplesDenoise;\n poissonBlurUniforms.near.value = this.camera.near;\n poissonBlurUniforms.far.value = this.camera.far;\n poissonBlurUniforms.logDepth.value = renderer.capabilities.logarithmicDepthBuffer;\n poissonBlurUniforms.screenSpaceRadius.value = this.configuration.screenSpaceRadius;\n renderer.setRenderTarget(this.writeTargetInternal);\n this.poissonBlurQuad.render(renderer);\n }\n // End the blur\n\n const effectCompositerUniforms = this.effectCompositerQuad!.material.uniforms;\n\n // Start the composition\n if (!effectCompositerUniforms || !this.effectCompositerQuad) return;\n effectCompositerUniforms.sceneDiffuse.value = inputBuffer.texture;\n effectCompositerUniforms.sceneDepth.value = this.depthTexture;\n effectCompositerUniforms.near.value = this.camera.near;\n effectCompositerUniforms.far.value = this.camera.far;\n effectCompositerUniforms.projectionMatrixInv.value = this.camera.projectionMatrixInverse;\n effectCompositerUniforms.viewMatrixInv.value = this.camera.matrixWorld;\n effectCompositerUniforms.logDepth.value = renderer.capabilities.logarithmicDepthBuffer;\n effectCompositerUniforms.ortho.value = this.camera instanceof OrthographicCamera;\n effectCompositerUniforms.downsampledDepth.value = this.configuration.halfRes\n ? this.depthDownsampleTarget!.textures[0]\n : this.depthTexture;\n effectCompositerUniforms.resolution.value = this.r;\n effectCompositerUniforms.blueNoise.value = this.bluenoise;\n effectCompositerUniforms.intensity.value = this.configuration.intensity;\n effectCompositerUniforms.renderMode.value = this.configuration.renderMode;\n effectCompositerUniforms.screenSpaceRadius.value = this.configuration.screenSpaceRadius;\n effectCompositerUniforms.radius.value = trueRadius;\n effectCompositerUniforms.distanceFalloff.value = this.configuration.distanceFalloff;\n effectCompositerUniforms.gammaCorrection.value = this.autosetGamma\n ? this.renderToScreen\n : this.configuration.gammaCorrection;\n effectCompositerUniforms.tDiffuse.value = this.writeTargetInternal.texture;\n effectCompositerUniforms.color.value = this.c\n .copy(this.configuration.color)\n .convertSRGBToLinear();\n effectCompositerUniforms.colorMultiply.value = this.configuration.colorMultiply;\n effectCompositerUniforms.cameraPos.value = this.camera.getWorldPosition(new Vector3());\n effectCompositerUniforms.fog.value = !!this.scene.fog;\n\n if (this.scene.fog) {\n if (this.scene.fog instanceof Fog && this.scene.fog.isFog === true) {\n effectCompositerUniforms.fogExp.value = false;\n effectCompositerUniforms.fogNear.value = this.scene.fog.near;\n effectCompositerUniforms.fogFar.value = this.scene.fog.far;\n } else if (this.scene.fog instanceof FogExp2) {\n effectCompositerUniforms.fogExp.value = true;\n effectCompositerUniforms.fogDensity.value = this.scene.fog.density;\n } else {\n console.error(`Unsupported fog type ${this.scene.fog.constructor.name} in SSAOPass.`);\n }\n }\n\n renderer.setRenderTarget(this.outputTargetInternal);\n this.effectCompositerQuad.render(renderer);\n renderer.setRenderTarget(this.renderToScreen ? null : outputBuffer);\n this.copyQuad.material.uniforms.tDiffuse.value = this.outputTargetInternal.texture;\n this.copyQuad.render(renderer);\n\n if (this.debugMode && gl && timerQuery) {\n (gl as WebGL2RenderingContext).endQuery(ext.TIME_ELAPSED_EXT);\n checkTimerQuery(timerQuery as WebGLQuery, gl as WebGL2RenderingContext, this);\n }\n\n renderer.xr.enabled = xrEnabled;\n }\n\n public enableDebugMode(): void {\n this.debugMode = true;\n }\n\n public disableDebugMode(): void {\n this.debugMode = false;\n }\n\n public setDisplayMode(mode: \"Combined\" | \"AO\" | \"No AO\" | \"Split\" | \"Split AO\"): void {\n this.configuration.renderMode = [\"Combined\", \"AO\", \"No AO\", \"Split\", \"Split AO\"].indexOf(\n mode,\n ) as number;\n }\n\n public setQualityMode(mode: PresetsType): void {\n if (mode === \"Performance\") {\n this.configuration.aoSamples = 8;\n this.configuration.denoiseSamples = 4;\n this.configuration.denoiseRadius = 12;\n } else if (mode === \"Low\") {\n this.configuration.aoSamples = 16;\n this.configuration.denoiseSamples = 4;\n this.configuration.denoiseRadius = 12;\n } else if (mode === \"Medium\") {\n this.configuration.aoSamples = 16;\n this.configuration.denoiseSamples = 8;\n this.configuration.denoiseRadius = 12;\n } else if (mode === \"High\") {\n this.configuration.aoSamples = 64;\n this.configuration.denoiseSamples = 8;\n this.configuration.denoiseRadius = 6;\n } else if (mode === \"Ultra\") {\n this.configuration.aoSamples = 64;\n this.configuration.denoiseSamples = 16;\n this.configuration.denoiseRadius = 6;\n }\n }\n}\n\nexport { N8SSAOPass };\n", "// Original code from: https://github.com/N8python/n8ao\n\n/* eslint-disable max-len */\nexport const BlueNoise: string =\n \"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\";\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport { Matrix4, Uniform, Vector2 } from \"three\";\n\nconst DepthDownSample = {\n uniforms: {\n sceneDepth: new Uniform(null),\n resolution: new Uniform(new Vector2()),\n near: new Uniform(0.1),\n far: new Uniform(1000.0),\n viewMatrixInv: new Uniform(new Matrix4()),\n projectionMatrixInv: new Uniform(new Matrix4()),\n logDepth: new Uniform(false),\n },\n\n depthWrite: false,\n\n depthTest: false,\n\n vertexShader: /* glsl */ `\n varying vec2 vUv;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(position, 1);\n }`,\n\n fragmentShader: /* glsl */ `\n uniform highp sampler2D sceneDepth;\n uniform vec2 resolution;\n uniform float near;\n uniform float far;\n uniform bool logDepth;\n uniform mat4 viewMatrixInv;\n uniform mat4 projectionMatrixInv;\n varying vec2 vUv;\n\n layout(location = 1) out vec4 gNormal;\n\n vec3 getWorldPosLog(vec3 posS) {\n vec2 uv = posS.xy;\n float z = posS.z;\n float nearZ = near;\n float farZ = far;\n float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;\n vec4 wpos = projectionMatrixInv * clipVec;\n return wpos.xyz / wpos.w;\n }\n\n vec3 getWorldPos(float depth, vec2 coord) {\n if (logDepth) {\n return getWorldPosLog(vec3(coord, depth));\n }\n float z = depth * 2.0 - 1.0;\n vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);\n vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;\n\n vec4 worldSpacePosition = viewSpacePosition;\n worldSpacePosition.xyz /= worldSpacePosition.w;\n\n return worldSpacePosition.xyz;\n }\n\n vec3 computeNormal(vec3 worldPos, vec2 vUv) {\n ivec2 p = ivec2(vUv * resolution);\n float c0 = texelFetch(sceneDepth, p, 0).x;\n float l2 = texelFetch(sceneDepth, p - ivec2(2, 0), 0).x;\n float l1 = texelFetch(sceneDepth, p - ivec2(1, 0), 0).x;\n float r1 = texelFetch(sceneDepth, p + ivec2(1, 0), 0).x;\n float r2 = texelFetch(sceneDepth, p + ivec2(2, 0), 0).x;\n float b2 = texelFetch(sceneDepth, p - ivec2(0, 2), 0).x;\n float b1 = texelFetch(sceneDepth, p - ivec2(0, 1), 0).x;\n float t1 = texelFetch(sceneDepth, p + ivec2(0, 1), 0).x;\n float t2 = texelFetch(sceneDepth, p + ivec2(0, 2), 0).x;\n float dl = abs((2.0 * l1 - l2) - c0);\n float dr = abs((2.0 * r1 - r2) - c0);\n float db = abs((2.0 * b1 - b2) - c0);\n float dt = abs((2.0 * t1 - t2) - c0);\n vec3 ce = getWorldPos(c0, vUv).xyz;\n vec3 dpdx = (\n (dl < dr)\n ? ce - getWorldPos(l1, (vUv - vec2(1.0 / resolution.x, 0.0))).xyz\n : -ce + getWorldPos(r1, (vUv + vec2(1.0 / resolution.x, 0.0))).xyz\n );\n vec3 dpdy = (\n (db < dt)\n ? ce - getWorldPos(b1, (vUv - vec2(0.0, 1.0 / resolution.y))).xyz\n : -ce + getWorldPos(t1, (vUv + vec2(0.0, 1.0 / resolution.y))).xyz\n );\n return normalize(cross(dpdx, dpdy));\n }\n\n void main(void) {\n vec2 uv = vUv - vec2(0.5) / resolution;\n vec2 pixelSize = vec2(1.0) / resolution;\n vec2[] uvSamples = vec2[4](\n uv,\n uv + vec2(pixelSize.x, 0.0),\n uv + vec2(0.0, pixelSize.y),\n uv + pixelSize\n );\n float depth00 = texture2D(sceneDepth, uvSamples[0]).r;\n float depth10 = texture2D(sceneDepth, uvSamples[1]).r;\n float depth01 = texture2D(sceneDepth, uvSamples[2]).r;\n float depth11 = texture2D(sceneDepth, uvSamples[3]).r;\n float minDepth = min(min(depth00, depth10), min(depth01, depth11));\n float maxDepth = max(max(depth00, depth10), max(depth01, depth11));\n float targetDepth = minDepth;\n\n if (mod(gl_FragCoord.x + gl_FragCoord.y, 2.0) > 0.5) { \n targetDepth = maxDepth;\n }\n\n int chosenIndex = 0;\n float[] samples = float[4](depth00, depth10, depth01, depth11);\n\n for(int i = 0; i < 4; ++i) {\n if (samples[i] == targetDepth) {\n chosenIndex = i;\n break;\n }\n }\n\n gl_FragColor = vec4(samples[chosenIndex], 0.0, 0.0, 1.0);\n gNormal = vec4(\n computeNormal(\n getWorldPos(samples[chosenIndex], uvSamples[chosenIndex]), uvSamples[chosenIndex]\n ),\n 0.0\n );\n }`,\n};\n\nexport { DepthDownSample };\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport { Matrix4, Uniform, Vector2, Vector3 } from \"three\";\n\nconst EffectCompositer = {\n uniforms: {\n sceneDiffuse: new Uniform(null),\n sceneDepth: new Uniform(null),\n tDiffuse: new Uniform(null),\n projMat: new Uniform(new Matrix4()),\n viewMat: new Uniform(new Matrix4()),\n projectionMatrixInv: new Uniform(new Matrix4()),\n viewMatrixInv: new Uniform(new Matrix4()),\n cameraPos: new Uniform(new Vector3()),\n resolution: new Uniform(new Vector2()),\n color: new Uniform(new Vector3()),\n blueNoise: new Uniform(null),\n downsampledDepth: new Uniform(null),\n time: new Uniform(0.0),\n intensity: new Uniform(10.0),\n renderMode: new Uniform(0.0),\n gammaCorrection: new Uniform(false),\n logDepth: new Uniform(false),\n ortho: new Uniform(false),\n near: new Uniform(0.1),\n far: new Uniform(1000.0),\n screenSpaceRadius: new Uniform(false),\n radius: new Uniform(0.0),\n distanceFalloff: new Uniform(1.0),\n fog: new Uniform(false),\n fogExp: new Uniform(false),\n fogDensity: new Uniform(0.0),\n fogNear: new Uniform(Infinity),\n fogFar: new Uniform(Infinity),\n colorMultiply: new Uniform(true),\n },\n\n depthWrite: false,\n\n depthTest: false,\n\n vertexShader: /* glsl */ `\n varying vec2 vUv;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(position, 1);\n }`,\n\n fragmentShader: /* glsl */ `\n uniform sampler2D sceneDiffuse;\n uniform highp sampler2D sceneDepth;\n uniform highp sampler2D downsampledDepth;\n uniform sampler2D tDiffuse;\n uniform sampler2D blueNoise;\n uniform vec2 resolution;\n uniform vec3 color;\n uniform mat4 projectionMatrixInv;\n uniform mat4 viewMatrixInv;\n uniform float intensity;\n uniform float renderMode;\n uniform float near;\n uniform float far;\n uniform bool gammaCorrection;\n uniform bool logDepth;\n uniform bool ortho;\n uniform bool screenSpaceRadius;\n uniform bool fog;\n uniform bool fogExp;\n uniform bool colorMultiply;\n uniform float fogDensity;\n uniform float fogNear;\n uniform float fogFar;\n uniform float radius;\n uniform float distanceFalloff;\n uniform vec3 cameraPos;\n varying vec2 vUv;\n\n highp float linearize_depth(highp float d, highp float zNear,highp float zFar) {\n return (zFar * zNear) / (zFar - d * (zFar - zNear));\n }\n \n highp float linearize_depth_ortho(highp float d, highp float nearZ, highp float farZ) {\n return nearZ + (farZ - nearZ) * d;\n }\n\n highp float linearize_depth_log(highp float d, highp float nearZ,highp float farZ) {\n float depth = pow(2.0, d * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n return (\n ortho\n ? linearize_depth_ortho(linDepth, nearZ, farZ)\n : linearize_depth(linDepth, nearZ, farZ)\n );\n }\n\n vec3 getWorldPosLog(vec3 posS) {\n vec2 uv = posS.xy;\n float z = posS.z;\n float nearZ =near;\n float farZ = far;\n float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;\n vec4 wpos = projectionMatrixInv * clipVec;\n return wpos.xyz / wpos.w;\n }\n\n vec3 getWorldPos(float depth, vec2 coord) {\n #ifdef LOGDEPTH\n return getWorldPosLog(vec3(coord, depth));\n #endif\n\n float z = depth * 2.0 - 1.0;\n vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);\n vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;\n\n if (abs(viewSpacePosition.w) < 1e-6) {\n discard;\n }\n\n viewSpacePosition /= viewSpacePosition.w;\n return (viewMatrixInv * viewSpacePosition).xyz;\n }\n\n\n vec3 computeNormal(vec3 worldPos, vec2 vUv) {\n ivec2 p = ivec2(vUv * resolution);\n float c0 = texelFetch(sceneDepth, p, 0).x;\n float l2 = texelFetch(sceneDepth, p - ivec2(2, 0), 0).x;\n float l1 = texelFetch(sceneDepth, p - ivec2(1, 0), 0).x;\n float r1 = texelFetch(sceneDepth, p + ivec2(1, 0), 0).x;\n float r2 = texelFetch(sceneDepth, p + ivec2(2, 0), 0).x;\n float b2 = texelFetch(sceneDepth, p - ivec2(0, 2), 0).x;\n float b1 = texelFetch(sceneDepth, p - ivec2(0, 1), 0).x;\n float t1 = texelFetch(sceneDepth, p + ivec2(0, 1), 0).x;\n float t2 = texelFetch(sceneDepth, p + ivec2(0, 2), 0).x;\n float dl = abs((2.0 * l1 - l2) - c0);\n float dr = abs((2.0 * r1 - r2) - c0);\n float db = abs((2.0 * b1 - b2) - c0);\n float dt = abs((2.0 * t1 - t2) - c0);\n vec3 ce = getWorldPos(c0, vUv).xyz;\n vec3 dpdx = (\n (dl < dr)\n ? ce - getWorldPos(l1, (vUv - vec2(1.0 / resolution.x, 0.0))).xyz\n : -ce + getWorldPos(r1, (vUv + vec2(1.0 / resolution.x, 0.0))).xyz\n );\n vec3 dpdy = (\n (db < dt)\n ? ce - getWorldPos(b1, (vUv - vec2(0.0, 1.0 / resolution.y))).xyz\n : -ce + getWorldPos(t1, (vUv + vec2(0.0, 1.0 / resolution.y))).xyz\n );\n return normalize(cross(dpdx, dpdy));\n }\n\n #include <common>\n #include <dithering_pars_fragment>\n\n void main(void) {\n vec4 sceneTexel = texture2D(sceneDiffuse, vUv);\n float depth = texture2D(sceneDepth, vUv).x;\n \n #ifdef HALFRES \n vec4 texel;\n if (depth == 1.0) {\n texel = vec4(0.0, 0.0, 0.0, 1.0);\n } else {\n vec3 worldPos = getWorldPos(depth, vUv);\n vec3 normal = computeNormal(getWorldPos(depth, vUv), vUv);\n\n float totalWeight = 0.0;\n float radiusToUse = (\n screenSpaceRadius\n ? distance(worldPos, getWorldPos(depth, vUv + vec2(radius, 0.0) / resolution))\n : radius\n );\n float distanceFalloffToUse = (\n screenSpaceRadius\n ? radiusToUse * distanceFalloff\n : distanceFalloff\n );\n for(float x = -1.0; x <= 1.0; x++) {\n for(float y = -1.0; y <= 1.0; y++) {\n vec2 offset = vec2(x, y);\n ivec2 p = ivec2((vUv * resolution * 0.5) + offset);\n vec2 pUv = vec2(p) / (resolution * 0.5);\n float sampleDepth = texelFetch(downsampledDepth,p, 0).x;\n vec4 sampleInfo = texelFetch(tDiffuse, p, 0);\n vec3 normalSample = sampleInfo.xyz * 2.0 - 1.0;\n vec3 worldPosSample = getWorldPos(sampleDepth, pUv);\n float tangentPlaneDist = abs(dot(worldPos - worldPosSample, normal));\n float rangeCheck = exp(\n -1.0 * tangentPlaneDist * (1.0 / distanceFalloffToUse)) * max(dot(normal, normalSample),\n 0.0\n );\n float weight = rangeCheck;\n totalWeight += weight;\n texel += sampleInfo * weight;\n }\n }\n if (totalWeight == 0.0) {\n texel = texture2D(tDiffuse, vUv);\n } else {\n texel /= totalWeight;\n }\n }\n #else\n vec4 texel = texture2D(tDiffuse, vUv);\n #endif\n\n #ifdef LOGDEPTH\n texel.a = clamp(texel.a, 0.0, 1.0);\n if (texel.a == 0.0) {\n texel.a = 1.0;\n }\n #endif\n\n float finalAo = pow(texel.a, intensity);\n float fogFactor;\n float fogDepth = distance(cameraPos, getWorldPos(depth, vUv));\n\n if (fog) {\n if (fogExp) {\n fogFactor = 1.0 - exp(-fogDensity * fogDensity * fogDepth * fogDepth);\n } else {\n fogFactor = smoothstep(fogNear, fogFar, fogDepth);\n }\n }\n\n finalAo = mix(finalAo, 1.0, fogFactor);\n vec3 aoApplied = color * mix(vec3(1.0), sceneTexel.rgb, float(colorMultiply));\n if (renderMode == 0.0) {\n gl_FragColor = vec4( mix(sceneTexel.rgb, aoApplied, 1.0 - finalAo), sceneTexel.a);\n } else if (renderMode == 1.0) {\n gl_FragColor = vec4( mix(vec3(1.0), aoApplied, 1.0 - finalAo), sceneTexel.a);\n } else if (renderMode == 2.0) {\n gl_FragColor = vec4( sceneTexel.rgb, sceneTexel.a);\n } else if (renderMode == 3.0) {\n if (vUv.x < 0.5) {\n gl_FragColor = vec4( sceneTexel.rgb, sceneTexel.a);\n } else if (abs(vUv.x - 0.5) < 1.0 / resolution.x) {\n gl_FragColor = vec4(1.0);\n } else {\n gl_FragColor = vec4(mix(sceneTexel.rgb, aoApplied, 1.0 - finalAo), sceneTexel.a);\n }\n } else if (renderMode == 4.0) {\n if (vUv.x < 0.5) {\n gl_FragColor = vec4( sceneTexel.rgb, sceneTexel.a);\n } else if (abs(vUv.x - 0.5) < 1.0 / resolution.x) {\n gl_FragColor = vec4(1.0);\n } else {\n gl_FragColor = vec4(mix(vec3(1.0), aoApplied, 1.0 - finalAo), sceneTexel.a);\n }\n }\n\n #include <dithering_fragment>\n\n if (gammaCorrection) {\n gl_FragColor = LinearTosRGB(gl_FragColor);\n }\n }\n `,\n};\nexport { EffectCompositer };\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport { Matrix4, Uniform, Vector2, Vector3 } from \"three\";\n\nconst EffectShader = {\n uniforms: {\n sceneDiffuse: new Uniform(null),\n sceneDepth: new Uniform(null),\n sceneNormal: new Uniform(null),\n projMat: new Uniform(new Matrix4()),\n viewMat: new Uniform(new Matrix4()),\n projViewMat: new Uniform(new Matrix4()),\n projectionMatrixInv: new Uniform(new Matrix4()),\n viewMatrixInv: new Uniform(new Matrix4()),\n cameraPos: new Uniform(new Vector3()),\n resolution: new Uniform(new Vector2()),\n time: new Uniform(0.0),\n samples: new Uniform([]),\n samplesR: new Uniform([]),\n bluenoise: new Uniform(null),\n distanceFalloff: new Uniform(1.0),\n radius: new Uniform(5.0),\n near: new Uniform(0.1),\n far: new Uniform(1000.0),\n logDepth: new Uniform(false),\n ortho: new Uniform(false),\n screenSpaceRadius: new Uniform(false),\n },\n\n depthWrite: false,\n\n depthTest: false,\n\n vertexShader: /* glsl */ `\n varying vec2 vUv;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(position, 1);\n }\n `,\n\n fragmentShader: /* glsl */ `\n #define SAMPLES 16\n #define FSAMPLES 16.0\n uniform sampler2D sceneDiffuse;\n uniform highp sampler2D sceneNormal;\n uniform highp sampler2D sceneDepth;\n uniform mat4 projectionMatrixInv;\n uniform mat4 viewMatrixInv;\n uniform mat4 projMat;\n uniform mat4 viewMat;\n uniform mat4 projViewMat;\n uniform vec3 cameraPos;\n uniform vec2 resolution;\n uniform float time;\n uniform vec3[SAMPLES] samples;\n uniform float[SAMPLES] samplesR;\n uniform float radius;\n uniform float distanceFalloff;\n uniform float near;\n uniform float far;\n uniform bool logDepth;\n uniform bool ortho;\n uniform bool screenSpaceRadius;\n uniform sampler2D bluenoise;\n varying vec2 vUv;\n\n highp float linearize_depth(highp float d, highp float zNear,highp float zFar) {\n return (zFar * zNear) / (zFar - d * (zFar - zNear));\n }\n\n highp float linearize_depth_ortho(highp float d, highp float nearZ, highp float farZ) {\n return nearZ + (farZ - nearZ) * d;\n }\n\n highp float linearize_depth_log(highp float d, highp float nearZ,highp float farZ) {\n float depth = pow(2.0, d * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n return (\n ortho\n ? linearize_depth_ortho(linDepth, nearZ, farZ)\n : linearize_depth(linDepth, nearZ, farZ)\n );\n }\n\n vec3 getWorldPosLog(vec3 posS) {\n vec2 uv = posS.xy;\n float z = posS.z;\n float nearZ =near;\n float farZ = far;\n float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;\n vec4 wpos = projectionMatrixInv * clipVec;\n return wpos.xyz / wpos.w;\n }\n\n vec3 getWorldPos(float depth, vec2 coord) {\n #ifdef LOGDEPTH\n return getWorldPosLog(vec3(coord, depth));\n #endif\n float z = depth * 2.0 - 1.0;\n vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);\n vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;\n\n vec4 worldSpacePosition = viewSpacePosition;\n worldSpacePosition.xyz /= worldSpacePosition.w;\n return worldSpacePosition.xyz;\n }\n\n vec3 computeNormal(vec3 worldPos, vec2 vUv) {\n ivec2 p = ivec2(vUv * resolution);\n float c0 = texelFetch(sceneDepth, p, 0).x;\n float l2 = texelFetch(sceneDepth, p - ivec2(2, 0), 0).x;\n float l1 = texelFetch(sceneDepth, p - ivec2(1, 0), 0).x;\n float r1 = texelFetch(sceneDepth, p + ivec2(1, 0), 0).x;\n float r2 = texelFetch(sceneDepth, p + ivec2(2, 0), 0).x;\n float b2 = texelFetch(sceneDepth, p - ivec2(0, 2), 0).x;\n float b1 = texelFetch(sceneDepth, p - ivec2(0, 1), 0).x;\n float t1 = texelFetch(sceneDepth, p + ivec2(0, 1), 0).x;\n float t2 = texelFetch(sceneDepth, p + ivec2(0, 2), 0).x;\n float dl = abs((2.0 * l1 - l2) - c0);\n float dr = abs((2.0 * r1 - r2) - c0);\n float db = abs((2.0 * b1 - b2) - c0);\n float dt = abs((2.0 * t1 - t2) - c0);\n vec3 ce = getWorldPos(c0, vUv).xyz;\n vec3 dpdx = (\n (dl < dr)\n ? ce - getWorldPos(l1, (vUv - vec2(1.0 / resolution.x, 0.0))).xyz\n : -ce + getWorldPos(r1, (vUv + vec2(1.0 / resolution.x, 0.0))).xyz\n );\n vec3 dpdy = (\n (db < dt)\n ? ce - getWorldPos(b1, (vUv - vec2(0.0, 1.0 / resolution.y))).xyz\n : -ce + getWorldPos(t1, (vUv + vec2(0.0, 1.0 / resolution.y))).xyz\n );\n return normalize(cross(dpdx, dpdy));\n }\n\n void main(void) {\n vec4 diffuse = texture2D(sceneDiffuse, vUv);\n float depth = texture2D(sceneDepth, vUv).x;\n\n if (depth == 1.0) {\n gl_FragColor = vec4(vec3(1.0), 1.0);\n return;\n }\n\n vec3 worldPos = getWorldPos(depth, vUv);\n\n #ifdef HALFRES\n vec3 normal = texture2D(sceneNormal, vUv).rgb;\n #else\n vec3 normal = computeNormal(worldPos, vUv);\n #endif\n\n vec4 noise = texture2D(bluenoise, gl_FragCoord.xy / 128.0);\n vec3 randomVec = normalize(noise.rgb * 2.0 - 1.0);\n vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));\n vec3 bitangent = cross(normal, tangent);\n mat3 tbn = mat3(tangent, bitangent, normal);\n float occluded = 0.0;\n float totalWeight = 0.0;\n\n float radiusToUse = (\n screenSpaceRadius\n ? distance(worldPos, getWorldPos(depth, vUv + vec2(radius, 0.0) / resolution))\n : radius\n );\n float distanceFalloffToUse = (\n screenSpaceRadius\n ? radiusToUse * distanceFalloff\n : distanceFalloff\n );\n float bias = (0.1 / near) * fwidth(distance(worldPos, cameraPos)) / radiusToUse;\n for(float i = 0.0; i < FSAMPLES; i++) {\n vec3 sampleDirection = tbn * samples[int(i)];\n float moveAmt = samplesR[int(mod(i + noise.a * FSAMPLES, FSAMPLES))];\n vec3 samplePos = worldPos + radiusToUse * moveAmt * sampleDirection;\n vec4 offset = projMat * vec4(samplePos, 1.0);\n offset.xyz /= offset.w;\n offset.xyz = offset.xyz * 0.5 + 0.5;\n float sampleDepth = textureLod(sceneDepth, offset.xy, 0.0).x;\n #ifdef LOGDEPTH\n float distSample = linearize_depth_log(sampleDepth, near, far);\n #else\n float distSample = (\n ortho\n ? linearize_depth_ortho(sampleDepth, near, far)\n : linearize_depth(sampleDepth, near, far)\n );\n #endif\n float distWorld = (\n ortho\n ? linearize_depth_ortho(offset.z, near, far)\n : linearize_depth(offset.z, near, far)\n );\n float rangeCheck = smoothstep(0.0, 1.0, distanceFalloffToUse / (abs(distSample - distWorld)));\n vec2 diff = gl_FragCoord.xy - ( offset.xy * resolution);\n float weight = dot(sampleDirection, normal);\n occluded += rangeCheck * weight *\n (distSample + bias < distWorld ? 1.0 : 0.0) *\n (\n (\n dot(diff, diff) < 1.0 ||\n (sampleDepth == depth) ||\n (offset.x < 0.0 || offset.x > 1.0 || offset.y < 0.0 || offset.y > 1.0) ? 0.0 : 1.0\n )\n );\n totalWeight += weight;\n }\n float occ = clamp(1.0 - occluded / totalWeight, 0.0, 1.0);\n gl_FragColor = vec4(0.5 + 0.5 * normal, occ);\n }`,\n};\n\nexport { EffectShader };\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport {\n BufferAttribute,\n BufferGeometry,\n Mesh,\n OrthographicCamera,\n ShaderMaterial,\n Sphere,\n WebGLRenderer,\n} from \"three\";\n\nexport class FullScreenTriangle {\n private camera: OrthographicCamera = new OrthographicCamera();\n private geometry: BufferGeometry = new BufferGeometry();\n private mesh: Mesh<BufferGeometry, ShaderMaterial>;\n\n constructor(material: ShaderMaterial) {\n this.geometry.setAttribute(\n \"position\",\n new BufferAttribute(new Float32Array([-1, -1, 3, -1, -1, 3]), 2),\n );\n this.geometry.setAttribute(\"uv\", new BufferAttribute(new Float32Array([0, 0, 2, 0, 0, 2]), 2));\n\n this.geometry.boundingSphere = new Sphere();\n this.geometry.computeBoundingSphere = function () {};\n\n this.mesh = new Mesh(this.geometry, material);\n this.mesh.frustumCulled = false;\n }\n\n get material(): ShaderMaterial {\n return this.mesh.material as ShaderMaterial;\n }\n\n set material(value: ShaderMaterial) {\n this.mesh.material = value;\n }\n\n public render(renderer: WebGLRenderer): void {\n renderer.render(this.mesh, this.camera);\n }\n\n public dispose(): void {\n this.mesh.material.dispose();\n this.mesh.geometry.dispose();\n }\n}\n", "// Original code from: https://github.com/N8python/n8ao\n// ported to TypeScript\n\nimport { Matrix4, Uniform, Vector2, Vector3 } from \"three\";\n\nexport const PoissionBlur = {\n uniforms: {\n sceneDiffuse: new Uniform(null),\n sceneDepth: new Uniform(null),\n tDiffuse: new Uniform(null),\n projMat: new Uniform(new Matrix4()),\n viewMat: new Uniform(new Matrix4()),\n projectionMatrixInv: new Uniform(new Matrix4()),\n viewMatrixInv: new Uniform(new Matrix4()),\n cameraPos: new Uniform(new Vector3()),\n resolution: new Uniform(new Vector2()),\n time: new Uniform(0.0),\n r: new Uniform(5.0),\n blueNoise: new Uniform(null),\n radius: new Uniform(12.0),\n worldRadius: new Uniform(5.0),\n index: new Uniform(0.0),\n poissonDisk: new Uniform([]),\n distanceFalloff: new Uniform(1.0),\n near: new Uniform(0.1),\n far: new Uniform(1000.0),\n logDepth: new Uniform(false),\n screenSpaceRadius: new Uniform(false),\n },\n\n depthWrite: false,\n\n depthTest: false,\n\n vertexShader: /* glsl */ `\n varying vec2 vUv;\n void main(void) {\n vUv = uv;\n gl_Position = vec4(position, 1.0);\n }`,\n\n fragmentShader: /* glsl */ `\n uniform sampler2D sceneDiffuse;\n uniform highp sampler2D sceneDepth;\n uniform sampler2D tDiffuse;\n uniform sampler2D blueNoise;\n uniform mat4 projectionMatrixInv;\n uniform mat4 viewMatrixInv;\n uniform vec2 resolution;\n uniform float r;\n uniform float radius;\n uniform float worldRadius;\n uniform float index;\n uniform float near;\n uniform float far;\n uniform float distanceFalloff;\n uniform bool logDepth;\n uniform bool screenSpaceRadius;\n varying vec2 vUv;\n\n highp float linearize_depth(highp float d, highp float zNear,highp float zFar) {\n highp float z_n = 2.0 * d - 1.0;\n return 2.0 * zNear * zFar / (zFar + zNear - z_n * (zFar - zNear));\n }\n\n highp float linearize_depth_log(highp float d, highp float nearZ,highp float farZ) {\n float depth = pow(2.0, d * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n return linearize_depth(linDepth, nearZ, farZ);\n }\n\n highp float linearize_depth_ortho(highp float d, highp float nearZ, highp float farZ) {\n return nearZ + (farZ - nearZ) * d;\n }\n\n vec3 getWorldPosLog(vec3 posS) {\n vec2 uv = posS.xy;\n float z = posS.z;\n float nearZ =near;\n float farZ = far;\n float depth = pow(2.0, z * log2(farZ + 1.0)) - 1.0;\n float a = farZ / (farZ - nearZ);\n float b = farZ * nearZ / (nearZ - farZ);\n float linDepth = a + b / depth;\n vec4 clipVec = vec4(uv, linDepth, 1.0) * 2.0 - 1.0;\n vec4 wpos = projectionMatrixInv * clipVec;\n return wpos.xyz / wpos.w;\n }\n\n vec3 getWorldPos(float depth, vec2 coord) {\n #ifdef LOGDEPTH\n return getWorldPosLog(vec3(coord, depth));\n #endif\n\n float z = depth * 2.0 - 1.0;\n vec4 clipSpacePosition = vec4(coord * 2.0 - 1.0, z, 1.0);\n vec4 viewSpacePosition = projectionMatrixInv * clipSpacePosition;\n\n vec4 worldSpacePosition = viewSpacePosition;\n worldSpacePosition.xyz /= worldSpacePosition.w;\n return worldSpacePosition.xyz;\n }\n\n #include <common>\n\n #define NUM_SAMPLES 16\n\n uniform vec2 poissonDisk[NUM_SAMPLES];\n\n void main(void) {\n const float pi = acos(-1.0);\n vec2 texelSize = vec2(1.0 / resolution.x, 1.0 / resolution.y);\n vec2 uv = vUv;\n vec4 data = texture2D(tDiffuse, vUv);\n float occlusion = data.a;\n float baseOcc = data.a;\n vec3 normal = data.rgb * 2.0 - 1.0;\n float count = 1.0;\n float d = texture2D(sceneDepth, vUv).x;\n if (d == 1.0) {\n gl_FragColor = data;\n return;\n }\n vec3 worldPos = getWorldPos(d, vUv);\n float size = radius;\n float angle;\n\n if (index == 0.0) {\n angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).x * PI2;\n } else if (index == 1.0) {\n angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).y * PI2;\n } else if (index == 2.0) {\n angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).z * PI2;\n } else {\n angle = texture2D(blueNoise, gl_FragCoord.xy / 128.0).w * PI2;\n }\n\n mat2 rotationMatrix = mat2(cos(angle), -sin(angle), sin(angle), cos(angle));\n float radiusToUse = (\n screenSpaceRadius\n ? distance(worldPos, getWorldPos(d, vUv + vec2(worldRadius, 0.0) / resolution))\n : worldRadius\n );\n float distanceFalloffToUse = (\n screenSpaceRadius\n ? radiusToUse * distanceFalloff\n : distanceFalloff\n );\n\n for(int i = 0; i < NUM_SAMPLES; i++) {\n vec2 offset = (rotationMatrix * poissonDisk[i]) * texelSize * size;\n vec4 dataSample = texture2D(tDiffuse, uv + offset);\n float occSample = dataSample.a;\n vec3 normalSample = dataSample.rgb * 2.0 - 1.0;\n float dSample = texture2D(sceneDepth, uv + offset).x;\n vec3 worldPosSample = getWorldPos(dSample, uv + offset);\n float tangentPlaneDist = abs(dot(worldPos - worldPosSample, normal));\n float rangeCheck = (\n (dSample == 1.0)\n ? 0.0\n : exp(\n -1.0 * tangentPlaneDist * (1.0 / distanceFalloffToUse)\n ) * max(dot(normal, normalSample), 0.0) * (1.0 - abs(occSample - baseOcc))\n );\n occlusion += occSample * rangeCheck;\n count += rangeCheck;\n }\n\n if (count > 0.0) {\n occlusion /= count;\n }\n\n #ifdef LOGDEPTH\n occlusion = clamp(occlusion, 0.0, 1.0);\n if (occlusion == 0.0) {\n occlusion = 1.0;\n }\n #endif\n gl_FragColor = vec4(0.5 + 0.5 * normal, occlusion);\n }\n `,\n};\n", "import { Clock } from \"three\";\n\nimport { ease } from \"../helpers/math-helpers\";\n\nexport class TimeManager {\n private clock: Clock = new Clock();\n private roundMagnitude: number = 200000;\n private maxAverageFrames: number = 150;\n private deltaTimes: number[] = [];\n\n private targetAverageDeltaTime: number = 0;\n private lerpedAverageMagDelta: number = 0;\n private fpsUpdateTime: number = 0;\n private framesSinceLastFPSUpdate: number = 0;\n\n public time: number = 0;\n public deltaTime: number = 0;\n public rawDeltaTime: number = 0;\n public smoothDeltaTime: number = 0;\n public frame: number = 0;\n public fps: number = 0;\n public averageFPS: number = 0;\n\n public static maxDeltaTime = 0.1; // 100ms\n\n update() {\n this.rawDeltaTime = this.clock.getDelta();\n if (this.rawDeltaTime > TimeManager.maxDeltaTime) {\n this.rawDeltaTime = TimeManager.maxDeltaTime;\n }\n this.frame++;\n this.time += this.rawDeltaTime;\n this.deltaTimes.push(this.rawDeltaTime);\n\n if (this.deltaTimes.length > this.maxAverageFrames) this.deltaTimes.shift();\n\n this.targetAverageDeltaTime =\n this.deltaTimes.reduce((prev, curr) => prev + curr, 0) / this.deltaTimes.length;\n\n this.lerpedAverageMagDelta += ease(\n this.targetAverageDeltaTime * this.roundMagnitude,\n this.lerpedAverageMagDelta,\n 0.12,\n );\n\n const revertMagnitude = this.lerpedAverageMagDelta / this.roundMagnitude;\n const smoothDT = Math.round(revertMagnitude * this.roundMagnitude) / this.roundMagnitude;\n\n this.smoothDeltaTime = smoothDT > this.rawDeltaTime * 1.75 ? this.rawDeltaTime : smoothDT;\n this.deltaTime = this.smoothDeltaTime;\n\n this.framesSinceLastFPSUpdate++;\n if (this.framesSinceLastFPSUpdate >= 60) {\n this.fps =\n Math.round((this.framesSinceLastFPSUpdate / (this.time - this.fpsUpdateTime)) * 100) / 100;\n\n this.fpsUpdateTime = this.time;\n this.framesSinceLastFPSUpdate = 0;\n }\n }\n}\n", "import { MElement, MMLCollisionTrigger } from \"@mml-io/mml-web\";\nimport {\n Box3,\n BufferGeometry,\n Color,\n DoubleSide,\n Euler,\n Group,\n InstancedMesh,\n Line3,\n LineBasicMaterial,\n Matrix4,\n Mesh,\n MeshBasicMaterial,\n Object3D,\n Quaternion,\n Ray,\n Scene,\n Vector3,\n} from \"three\";\nimport { VertexNormalsHelper } from \"three/examples/jsm/helpers/VertexNormalsHelper.js\";\nimport * as BufferGeometryUtils from \"three/examples/jsm/utils/BufferGeometryUtils.js\";\nimport { MeshBVH, MeshBVHHelper } from \"three-mesh-bvh\";\n\nimport { getRelativePositionAndRotationRelativeToObject } from \"./getRelativePositionAndRotationRelativeToObject\";\n\nexport type CollisionMeshState = {\n matrix: Matrix4;\n source: Group;\n meshBVH: MeshBVH;\n debugGroup?: Group;\n trackCollisions: boolean;\n};\n\nexport class CollisionsManager {\n private debug: boolean = false;\n private scene: Scene;\n private tempVector: Vector3 = new Vector3();\n private tempVector2: Vector3 = new Vector3();\n private tempVector3: Vector3 = new Vector3();\n private tempQuaternion: Quaternion = new Quaternion();\n private tempRay: Ray = new Ray();\n private tempMatrix = new Matrix4();\n private tempMatrix2 = new Matrix4();\n private tempBox = new Box3();\n private tempEuler = new Euler();\n private tempSegment = new Line3();\n private tempSegment2 = new Line3();\n\n public collisionMeshState: Map<Group, CollisionMeshState> = new Map();\n private collisionTrigger: MMLCollisionTrigger<Group>;\n private previouslyCollidingElements: null | Map<\n Group,\n { position: { x: number; y: number; z: number } }\n >;\n\n constructor(scene: Scene) {\n this.scene = scene;\n this.collisionTrigger = MMLCollisionTrigger.init();\n }\n\n public raycastFirst(\n ray: Ray,\n maximumDistance: number | null = null,\n ): [number, Vector3, CollisionMeshState, Vector3] | null {\n let minimumDistance: number | null = null;\n let minimumHit: CollisionMeshState | null = null;\n let minimumNormal: Vector3 | null = null;\n let minimumPoint: Vector3 | null = null;\n for (const [, collisionMeshState] of this.collisionMeshState) {\n this.tempRay.copy(ray).applyMatrix4(this.tempMatrix.copy(collisionMeshState.matrix).invert());\n const hit = collisionMeshState.meshBVH.raycastFirst(this.tempRay, DoubleSide);\n if (hit) {\n this.tempSegment.start.copy(this.tempRay.origin);\n this.tempSegment.end.copy(hit.point);\n this.tempSegment.applyMatrix4(collisionMeshState.matrix);\n const dist = this.tempSegment.distance();\n if (\n (maximumDistance === null || dist < maximumDistance) &&\n (minimumDistance === null || dist < minimumDistance)\n ) {\n minimumDistance = dist;\n minimumHit = collisionMeshState;\n if (minimumNormal === null) {\n minimumNormal = new Vector3();\n }\n if (minimumPoint === null) {\n minimumPoint = new Vector3();\n }\n minimumNormal = (hit.normal ? minimumNormal.copy(hit.normal) : minimumNormal)\n // Apply the rotation of the mesh to the normal\n .applyQuaternion(this.tempQuaternion.setFromRotationMatrix(collisionMeshState.matrix))\n .normalize();\n minimumPoint = minimumPoint.copy(hit.point).applyMatrix4(collisionMeshState.matrix);\n }\n }\n }\n if (\n minimumDistance === null ||\n minimumNormal === null ||\n minimumHit === null ||\n minimumPoint === null\n ) {\n return null;\n }\n return [minimumDistance, minimumNormal, minimumHit, minimumPoint];\n }\n\n private createCollisionMeshState(group: Group, trackCollisions: boolean): CollisionMeshState {\n const geometries: Array<BufferGeometry> = [];\n group.updateWorldMatrix(true, false);\n const invertedRootMatrix = this.tempMatrix.copy(group.matrixWorld).invert();\n group.traverse((child: Object3D) => {\n const asMesh = child as Mesh;\n if (asMesh.isMesh) {\n const asInstancedMesh = asMesh as InstancedMesh;\n if (asInstancedMesh.isInstancedMesh) {\n for (let i = 0; i < asInstancedMesh.count; i++) {\n const clonedGeometry = asInstancedMesh.geometry.clone();\n for (const key in clonedGeometry.attributes) {\n if (key !== \"position\") {\n clonedGeometry.deleteAttribute(key);\n }\n }\n clonedGeometry.applyMatrix4(\n this.tempMatrix2.fromArray(asInstancedMesh.instanceMatrix.array, i * 16),\n );\n if (clonedGeometry.index) {\n geometries.push(clonedGeometry.toNonIndexed());\n } else {\n geometries.push(clonedGeometry);\n }\n }\n } else {\n const clonedGeometry = asMesh.geometry.clone();\n asMesh.updateWorldMatrix(true, false);\n for (const key in clonedGeometry.attributes) {\n if (key !== \"position\") {\n clonedGeometry.deleteAttribute(key);\n }\n }\n clonedGeometry.applyMatrix4(\n this.tempMatrix2.multiplyMatrices(invertedRootMatrix, asMesh.matrixWorld),\n );\n if (clonedGeometry.index) {\n geometries.push(clonedGeometry.toNonIndexed());\n } else {\n geometries.push(clonedGeometry);\n }\n }\n }\n });\n\n const newBufferGeometry = BufferGeometryUtils.mergeGeometries(geometries, false);\n newBufferGeometry.computeVertexNormals();\n const meshBVH = new MeshBVH(newBufferGeometry);\n\n const meshState: CollisionMeshState = {\n source: group,\n meshBVH,\n matrix: group.matrixWorld.clone(),\n trackCollisions,\n };\n if (this.debug) {\n // Have to cast to add the boundsTree property to the geometry so that the MeshBVHHelper can find it\n (newBufferGeometry as any).boundsTree = meshBVH;\n\n const wireframeMesh = new Mesh(newBufferGeometry, new MeshBasicMaterial({ wireframe: true }));\n\n const normalsHelper = new VertexNormalsHelper(wireframeMesh, 0.25, 0x00ff00);\n\n const visualizer = new MeshBVHHelper(wireframeMesh, 4);\n (visualizer.edgeMaterial as LineBasicMaterial).color = new Color(\"blue\");\n\n const debugGroup = new Group();\n debugGroup.add(wireframeMesh, normalsHelper, visualizer as unknown as Object3D);\n\n group.matrixWorld.decompose(debugGroup.position, debugGroup.quaternion, debugGroup.scale);\n visualizer.update();\n\n meshState.debugGroup = debugGroup;\n }\n return meshState;\n }\n\n public addMeshesGroup(group: Group, mElement?: MElement): void {\n if (mElement) {\n this.collisionTrigger.addCollider(group, mElement);\n }\n const meshState = this.createCollisionMeshState(group, mElement !== undefined);\n if (meshState.debugGroup) {\n this.scene.add(meshState.debugGroup);\n }\n this.collisionMeshState.set(group, meshState);\n }\n\n public updateMeshesGroup(group: Group): void {\n const meshState = this.collisionMeshState.get(group);\n if (meshState) {\n group.updateWorldMatrix(true, false);\n meshState.matrix.copy(group.matrixWorld);\n if (meshState.debugGroup) {\n group.matrixWorld.decompose(\n meshState.debugGroup.position,\n meshState.debugGroup.quaternion,\n meshState.debugGroup.scale,\n );\n }\n }\n }\n\n public removeMeshesGroup(group: Group): void {\n this.collisionTrigger.removeCollider(group);\n const meshState = this.collisionMeshState.get(group);\n if (meshState) {\n if (meshState.debugGroup) {\n this.scene.remove(meshState.debugGroup);\n }\n this.collisionMeshState.delete(group);\n }\n }\n\n private applyCollider(\n worldBasedCapsuleSegment: Line3,\n capsuleRadius: number,\n meshState: CollisionMeshState,\n ): Vector3 | null {\n // Create a matrix to convert from world-space to mesh-space\n const meshMatrix = this.tempMatrix.copy(meshState.matrix).invert();\n\n // Create the bounding box for the capsule if it were in mesh-space\n const meshRelativeCapsuleBoundingBox = this.tempBox;\n meshRelativeCapsuleBoundingBox.makeEmpty();\n meshRelativeCapsuleBoundingBox.expandByPoint(worldBasedCapsuleSegment.start);\n meshRelativeCapsuleBoundingBox.expandByPoint(worldBasedCapsuleSegment.end);\n meshRelativeCapsuleBoundingBox.min.subScalar(capsuleRadius);\n meshRelativeCapsuleBoundingBox.max.addScalar(capsuleRadius);\n meshRelativeCapsuleBoundingBox.applyMatrix4(meshMatrix);\n // Create a segment/line for the capsule in mesh-space\n const meshRelativeCapsuleSegment = this.tempSegment;\n meshRelativeCapsuleSegment.start.copy(worldBasedCapsuleSegment.start);\n meshRelativeCapsuleSegment.end.copy(worldBasedCapsuleSegment.end);\n meshRelativeCapsuleSegment.applyMatrix4(meshMatrix);\n\n // Keep track of where the segment started in mesh-space so that we can calculate the delta later\n const initialMeshRelativeCapsuleSegmentStart = this.tempVector3.copy(\n meshRelativeCapsuleSegment.start,\n );\n\n let collisionPosition: Vector3 | null = null;\n let currentCollisionDistance: number = -1;\n meshState.meshBVH.shapecast({\n intersectsBounds: (meshBox) => {\n // Determine if this portion of the mesh overlaps with the capsule bounding box and is therefore worth checking\n // all of the triangles within\n return meshBox.intersectsBox(meshRelativeCapsuleBoundingBox);\n },\n intersectsTriangle: (meshTriangle) => {\n const closestPointOnTriangle = this.tempVector;\n const closestPointOnSegment = this.tempVector2;\n // Find the closest point between this triangle and the capsule segment in mesh-space\n meshTriangle.closestPointToSegment(\n meshRelativeCapsuleSegment,\n closestPointOnTriangle,\n closestPointOnSegment,\n );\n // Create a line segment between the closest points\n const intersectionSegment = this.tempSegment2;\n intersectionSegment.start.copy(closestPointOnTriangle);\n intersectionSegment.end.copy(closestPointOnSegment);\n // Calculate the distance between the closest points in mesh-space\n const modelReferenceDistance = intersectionSegment.distance();\n\n // Calculate the distance between the points in world-space\n intersectionSegment.applyMatrix4(meshState.matrix);\n const realDistance = intersectionSegment.distance();\n\n // If the real distance is less than the capsule radius then there is actually a collision between the capsule\n // and the triangle\n if (realDistance < capsuleRadius) {\n if (!collisionPosition) {\n collisionPosition = new Vector3()\n .copy(closestPointOnTriangle)\n .applyMatrix4(meshState.matrix);\n currentCollisionDistance = realDistance;\n } else if (realDistance < currentCollisionDistance) {\n collisionPosition.copy(closestPointOnTriangle).applyMatrix4(meshState.matrix);\n currentCollisionDistance = realDistance;\n }\n // Calculate the ratio between the real distance and the mesh-space distance\n const ratio = realDistance / modelReferenceDistance;\n // Calculate the depth of the collision in world-space\n const realDepth = capsuleRadius - realDistance;\n // Convert that depth back into mesh-space as all calculations during collision are to a mesh-space segment\n const modelDepth = realDepth / ratio;\n\n // Apply a corrective movement to the segment in mesh-space\n const direction = closestPointOnSegment.sub(closestPointOnTriangle).normalize();\n meshRelativeCapsuleSegment.start.addScaledVector(direction, modelDepth);\n meshRelativeCapsuleSegment.end.addScaledVector(direction, modelDepth);\n }\n },\n });\n\n if (collisionPosition) {\n // If there was a collision, calculate the delta between the original mesh-space segment and the now-moved one\n const delta = this.tempVector\n .copy(meshRelativeCapsuleSegment.start)\n .sub(initialMeshRelativeCapsuleSegmentStart);\n\n // Use the matrix for the mesh to convert the delta vector back to world-space (remove the position component of the matrix first to avoid translation)\n this.tempMatrix.copy(meshState.matrix).setPosition(0, 0, 0);\n delta.applyMatrix4(this.tempMatrix);\n\n // There's a possibility that the matrix is invalid (or scale zero) and the delta is NaN - if so, don't apply the delta\n if (!(isNaN(delta.x) && isNaN(delta.y) && isNaN(delta.z))) {\n // Convert the potentially-modified mesh-space segment back to world-space\n worldBasedCapsuleSegment.start.add(delta);\n worldBasedCapsuleSegment.end.add(delta);\n }\n }\n\n return collisionPosition;\n }\n\n public applyColliders(tempSegment: Line3, radius: number) {\n const collidedElements = new Map<\n Group,\n {\n position: { x: number; y: number; z: number };\n }\n >();\n for (const meshState of this.collisionMeshState.values()) {\n const collisionPosition = this.applyCollider(tempSegment, radius, meshState);\n if (collisionPosition && meshState.trackCollisions) {\n const relativePosition = getRelativePositionAndRotationRelativeToObject(\n {\n position: collisionPosition,\n rotation: this.tempEuler.set(0, 0, 0),\n },\n meshState.source,\n );\n collidedElements.set(meshState.source, {\n position: relativePosition.position,\n });\n }\n }\n\n /*\n The reported collisions include elements that were reported in the previous tick to ensure that the case of an\n avatar rising to a negligible distance above the surface and immediately back down onto it does not result in a\n discontinuity in the collision lifecycle. If the element is not colliding in the next frame then it will be\n dropped.\n\n This results in a single tick delay of reporting leave events, but this is a reasonable trade-off to avoid\n flickering collisions.\n */\n const reportedCollidingElements = new Map(collidedElements);\n if (this.previouslyCollidingElements) {\n for (const [element, position] of this.previouslyCollidingElements) {\n if (!reportedCollidingElements.has(element)) {\n reportedCollidingElements.set(element, position);\n }\n }\n }\n\n // Store the elements that were genuinely collided with this tick for the next tick to preserve if they are missed\n this.previouslyCollidingElements = collidedElements;\n this.collisionTrigger.setCurrentCollisions(reportedCollidingElements);\n }\n}\n", "import { PositionAndRotation } from \"@mml-io/mml-web\";\nimport { Euler, Matrix4, Object3D, Quaternion, Vector3 } from \"three\";\n\nconst tempContainerMatrix = new Matrix4();\nconst tempTargetMatrix = new Matrix4();\nconst tempPositionVector = new Vector3();\nconst tempRotationEuler = new Euler();\nconst tempRotationQuaternion = new Quaternion();\nconst tempScaleVector = new Vector3();\n\nexport function getRelativePositionAndRotationRelativeToObject(\n positionAndRotation: PositionAndRotation,\n container: Object3D,\n): PositionAndRotation {\n const { x, y, z } = positionAndRotation.position;\n const { x: rx, y: ry, z: rz } = positionAndRotation.rotation;\n\n container.updateWorldMatrix(true, false);\n tempContainerMatrix.copy(container.matrixWorld).invert();\n\n tempPositionVector.set(x, y, z);\n tempRotationEuler.set(rx, ry, rz);\n tempRotationQuaternion.setFromEuler(tempRotationEuler);\n tempScaleVector.set(1, 1, 1);\n\n tempTargetMatrix.compose(tempPositionVector, tempRotationQuaternion, tempScaleVector);\n tempTargetMatrix.premultiply(tempContainerMatrix);\n tempTargetMatrix.decompose(tempPositionVector, tempRotationQuaternion, tempScaleVector);\n\n tempRotationEuler.setFromQuaternion(tempRotationQuaternion);\n\n // Correct for the container's local scale\n tempPositionVector.multiply(container.scale);\n\n return {\n position: {\n x: tempPositionVector.x,\n y: tempPositionVector.y,\n z: tempPositionVector.z,\n },\n rotation: {\n x: tempRotationEuler.x,\n y: tempRotationEuler.y,\n z: tempRotationEuler.z,\n },\n };\n}\n", "import {\n CanvasTexture,\n FrontSide,\n Group,\n LinearMipMapLinearFilter,\n Mesh,\n MeshStandardMaterial,\n NearestFilter,\n PlaneGeometry,\n RepeatWrapping,\n Texture,\n} from \"three\";\n\n// Create a simple 2x2 checkerboard image\nconst canvas = document.createElement(\"canvas\");\ncanvas.width = 2;\ncanvas.height = 2;\nconst ctx = canvas.getContext(\"2d\")!;\nctx.fillStyle = \"#e0e0e0\";\nctx.fillRect(0, 0, 2, 2);\nctx.fillStyle = \"#606060\";\nctx.fillRect(0, 0, 1, 1);\nctx.fillRect(1, 1, 1, 1);\n\nexport class GroundPlane extends Group {\n private readonly floorSize = 210;\n private readonly floorTexture: Texture | null = null;\n private readonly floorGeometry = new PlaneGeometry(this.floorSize, this.floorSize, 1, 1);\n private readonly floorMaterial: MeshStandardMaterial;\n private readonly floorMesh: Mesh | null = null;\n\n constructor() {\n super();\n\n this.floorMaterial = new MeshStandardMaterial({\n color: 0xffffff,\n side: FrontSide,\n metalness: 0.05,\n roughness: 0.95,\n });\n this.floorMesh = new Mesh(this.floorGeometry, this.floorMaterial);\n this.floorMesh.receiveShadow = true;\n this.floorMesh.rotation.x = Math.PI * -0.5;\n this.add(this.floorMesh);\n\n this.floorTexture = new CanvasTexture(canvas);\n this.floorTexture!.wrapS = RepeatWrapping;\n this.floorTexture!.wrapT = RepeatWrapping;\n this.floorTexture!.magFilter = NearestFilter;\n this.floorTexture!.minFilter = LinearMipMapLinearFilter;\n this.floorTexture!.repeat.set(this.floorSize / 1.5, this.floorSize / 1.5);\n this.floorMaterial.map = this.floorTexture;\n this.floorMaterial.needsUpdate = true;\n }\n}\n", "import { LoadingProgressManager } from \"@mml-io/mml-web\";\n\nexport type LoadingScreenConfig = {\n background?: string;\n backgroundImageUrl?: string;\n backgroundBlurAmount?: number;\n overlayLayers?: Array<{\n overlayImageUrl: string;\n overlayAnchor: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\";\n overlayOffset?: { x: number; y: number };\n }>;\n title?: string;\n subtitle?: string;\n color?: string;\n};\n\nexport class LoadingScreen {\n public readonly element: HTMLDivElement;\n\n private readonly backgroundBlur: HTMLDivElement;\n\n private overlayLayers: HTMLDivElement[] = [];\n\n private loadingBanner: HTMLDivElement;\n private loadingBannerTitle: HTMLDivElement;\n private loadingBannerSubtitle: HTMLDivElement;\n\n private progressBarBackground: HTMLDivElement;\n private progressBarHolder: HTMLDivElement;\n private progressBar: HTMLDivElement;\n private loadingStatusText: HTMLDivElement;\n\n private progressDebugViewHolder: HTMLDivElement;\n private progressDebugView: HTMLDivElement;\n private progressDebugElement: HTMLPreElement;\n\n private debugLabel: HTMLLabelElement;\n private debugCheckbox: HTMLInputElement;\n\n private hasCompleted = false;\n private loadingCallback: () => void;\n private disposed: boolean = false;\n\n constructor(\n private loadingProgressManager: LoadingProgressManager,\n private config?: LoadingScreenConfig,\n ) {\n const defaultBackground = \"linear-gradient(45deg, #28284B 0%, #303056 100%)\";\n this.element = document.createElement(\"div\");\n this.element.id = \"loading-screen\";\n\n this.element.style.position = \"absolute\";\n this.element.style.top = \"0\";\n this.element.style.left = \"0\";\n this.element.style.width = \"100%\";\n this.element.style.height = \"100%\";\n this.element.style.backgroundColor = this.config?.background || defaultBackground;\n this.element.style.background = this.config?.background || defaultBackground;\n this.element.style.zIndex = \"10001\";\n\n this.backgroundBlur = document.createElement(\"div\");\n this.backgroundBlur.id = \"loading-screen-blur\";\n this.backgroundBlur.style.position = \"absolute\";\n this.backgroundBlur.style.top = \"0\";\n this.backgroundBlur.style.left = \"0\";\n this.backgroundBlur.style.width = \"100%\";\n this.backgroundBlur.style.height = \"100%\";\n this.backgroundBlur.style.display = \"flex\";\n if (this.config?.backgroundBlurAmount) {\n this.backgroundBlur.style.backdropFilter = `blur(${this.config.backgroundBlurAmount}px)`;\n }\n this.element.append(this.backgroundBlur);\n\n if (this.config?.backgroundImageUrl) {\n this.element.style.backgroundImage = `url(${this.config.backgroundImageUrl})`;\n this.element.style.backgroundPosition = \"center\";\n this.element.style.backgroundSize = \"cover\";\n }\n\n if (this.config?.overlayLayers) {\n const logLoadError = (imageUrl: string) => {\n console.error(`Failed to load overlay image: ${imageUrl}`);\n };\n\n for (const layer of this.config.overlayLayers) {\n const overlayLayer = document.createElement(\"div\");\n overlayLayer.style.position = \"absolute\";\n overlayLayer.style.background = `url(${layer.overlayImageUrl}) no-repeat`;\n overlayLayer.style.backgroundSize = \"contain\";\n\n const anchor = layer.overlayAnchor;\n const offsetX = layer.overlayOffset?.x || 0;\n const offsetY = layer.overlayOffset?.y || 0;\n\n if (anchor.includes(\"top\")) {\n overlayLayer.style.top = `${offsetY}px`;\n } else if (anchor.includes(\"bottom\")) {\n overlayLayer.style.bottom = `${offsetY}px`;\n }\n\n if (anchor.includes(\"left\")) {\n overlayLayer.style.left = `${offsetX}px`;\n } else if (anchor.includes(\"right\")) {\n overlayLayer.style.right = `${offsetX}px`;\n }\n\n const image = new Image();\n image.src = layer.overlayImageUrl;\n image.onload = () => {\n const naturalWidth = image.naturalWidth;\n const naturalHeight = image.naturalHeight;\n\n overlayLayer.style.width = `${naturalWidth}px`;\n overlayLayer.style.height = `${naturalHeight}px`;\n };\n\n image.onerror = () => logLoadError(layer.overlayImageUrl);\n\n this.overlayLayers.push(overlayLayer);\n this.backgroundBlur.append(overlayLayer);\n }\n }\n\n this.element.style.color = this.config?.color || \"white\";\n\n this.loadingBanner = document.createElement(\"div\");\n this.loadingBanner.style.position = \"absolute\";\n this.loadingBanner.style.display = \"flex\";\n this.loadingBanner.style.flexDirection = \"column\";\n this.loadingBanner.style.left = \"0\";\n this.loadingBanner.style.bottom = \"0\";\n this.loadingBanner.style.padding = \"0\";\n this.loadingBanner.style.width = \"100%\";\n this.loadingBanner.style.justifyContent = \"flex-end\";\n this.backgroundBlur.append(this.loadingBanner);\n\n if (this.config?.title) {\n this.loadingBannerTitle = document.createElement(\"div\");\n this.loadingBannerTitle.textContent = this.config.title;\n this.loadingBannerTitle.style.color = this.config?.color || \"white\";\n this.loadingBannerTitle.style.paddingLeft = \"40px\";\n this.loadingBannerTitle.style.paddingRight = \"40px\";\n this.loadingBannerTitle.style.fontSize = \"42px\";\n this.loadingBannerTitle.style.fontWeight = \"bold\";\n this.loadingBannerTitle.style.fontFamily = \"sans-serif\";\n if (this.config?.background) {\n this.loadingBannerTitle.style.textShadow = `0px 0px 80px ${this.config.background}`;\n }\n this.loadingBanner.append(this.loadingBannerTitle);\n }\n\n if (this.config?.subtitle) {\n this.loadingBannerSubtitle = document.createElement(\"div\");\n this.loadingBannerSubtitle.style.color = this.config?.color || \"white\";\n this.loadingBannerSubtitle.style.paddingLeft = \"40px\";\n this.loadingBannerSubtitle.style.paddingRight = \"40px\";\n this.loadingBannerSubtitle.style.fontSize = \"16px\";\n this.loadingBannerSubtitle.style.fontWeight = \"400\";\n this.loadingBannerSubtitle.style.fontFamily = \"sans-serif\";\n this.loadingBannerSubtitle.style.marginTop = \"12px\";\n if (this.config?.background) {\n this.loadingBannerSubtitle.style.textShadow = `0px 0px 40px ${this.config.background}`;\n }\n\n this.loadingBannerSubtitle.textContent = this.config.subtitle;\n this.loadingBanner.append(this.loadingBannerSubtitle);\n }\n\n this.progressDebugViewHolder = document.createElement(\"div\");\n this.progressDebugViewHolder.style.display = \"none\";\n this.progressDebugViewHolder.style.position = \"absolute\";\n this.progressDebugViewHolder.style.width = \"calc(100% - 80px)\";\n this.progressDebugViewHolder.style.maxHeight = \"calc(100% - 120px)\";\n this.progressDebugViewHolder.style.left = \"40px\";\n this.progressDebugViewHolder.style.bottom = \"60px\";\n this.progressDebugViewHolder.style.alignItems = \"center\";\n this.progressDebugViewHolder.style.justifyContent = \"center\";\n this.progressDebugViewHolder.style.zIndex = \"10003\";\n this.element.append(this.progressDebugViewHolder);\n\n this.progressDebugView = document.createElement(\"div\");\n this.progressDebugView.style.backgroundColor = \"rgba(128, 128, 128, 0.5)\";\n this.progressDebugView.style.border = \"1px solid black\";\n this.progressDebugView.style.borderRadius = \"7px\";\n this.progressDebugView.style.width = \"100%\";\n this.progressDebugView.style.maxWidth = \"100%\";\n this.progressDebugView.style.overflow = \"auto\";\n this.progressDebugViewHolder.append(this.progressDebugView);\n\n this.debugCheckbox = document.createElement(\"input\");\n this.debugCheckbox.type = \"checkbox\";\n this.debugCheckbox.checked = false;\n this.debugCheckbox.addEventListener(\"change\", () => {\n this.progressDebugElement.style.display = this.debugCheckbox.checked ? \"block\" : \"none\";\n this.loadingBannerTitle.style.display = this.debugCheckbox.checked ? \"none\" : \"flex\";\n this.loadingBannerSubtitle.style.display = this.debugCheckbox.checked ? \"none\" : \"flex\";\n if (this.hasCompleted) {\n this.dispose();\n }\n });\n\n this.debugLabel = document.createElement(\"label\");\n this.debugLabel.textContent = \"Debug loading\";\n this.debugLabel.style.fontFamily = \"sans-serif\";\n this.debugLabel.style.padding = \"5px\";\n this.debugLabel.style.display = \"inline-block\";\n this.debugLabel.style.userSelect = \"none\";\n this.debugLabel.append(this.debugCheckbox);\n this.progressDebugView.append(this.debugLabel);\n\n this.progressDebugElement = document.createElement(\"pre\");\n this.progressDebugElement.style.margin = \"0\";\n this.progressDebugElement.style.display = this.debugCheckbox.checked ? \"block\" : \"none\";\n this.progressDebugView.append(this.progressDebugElement);\n\n this.progressBarHolder = document.createElement(\"div\");\n this.progressBarHolder.style.display = \"flex\";\n this.progressBarHolder.style.alignItems = \"start\";\n this.progressBarHolder.style.justifyContent = \"flex-start\";\n this.progressBarHolder.style.width = \"100%\";\n this.progressBarHolder.style.marginLeft = \"40px\";\n this.progressBarHolder.style.marginBottom = \"40px\";\n this.progressBarHolder.style.cursor = \"pointer\";\n this.progressBarHolder.style.marginTop = \"24px\";\n this.loadingBanner.append(this.progressBarHolder);\n\n this.progressBarBackground = document.createElement(\"div\");\n this.progressBarBackground.style.position = \"relative\";\n this.progressBarBackground.style.width = \"80%\";\n this.progressBarBackground.style.maxWidth = \"400px\";\n this.progressBarBackground.style.minWidth = \"240px\";\n this.progressBarBackground.style.backgroundColor = \"rgba(32,32,32, 0.25)\";\n this.progressBarBackground.style.backdropFilter = \"blur(4px)\";\n this.progressBarBackground.style.height = \"16px\";\n this.progressBarBackground.style.lineHeight = \"16px\";\n this.progressBarBackground.style.borderRadius = \"16px\";\n this.progressBarBackground.style.overflow = \"hidden\";\n this.progressBarBackground.addEventListener(\"click\", () => {\n const display = this.progressDebugViewHolder.style.display;\n if (display === \"none\") {\n this.progressDebugViewHolder.style.display = \"flex\";\n } else {\n this.progressDebugViewHolder.style.display = \"none\";\n this.debugCheckbox.checked = false;\n this.progressDebugElement.style.display = this.debugCheckbox.checked ? \"block\" : \"none\";\n this.loadingBannerTitle.style.display = this.debugCheckbox.checked ? \"none\" : \"flex\";\n }\n });\n this.progressBarHolder.append(this.progressBarBackground);\n\n this.progressBar = document.createElement(\"div\");\n this.progressBar.style.position = \"absolute\";\n this.progressBar.style.top = \"0\";\n this.progressBar.style.left = \"0\";\n this.progressBar.style.width = \"0\";\n this.progressBar.style.height = \"100%\";\n this.progressBar.style.pointerEvents = \"none\";\n this.progressBar.style.backgroundColor = this.config?.color || \"#0050a4\";\n this.progressBarBackground.append(this.progressBar);\n\n this.loadingStatusText = document.createElement(\"div\");\n this.loadingStatusText.style.position = \"absolute\";\n this.loadingStatusText.style.top = \"0\";\n this.loadingStatusText.style.left = \"0\";\n this.loadingStatusText.style.width = \"100%\";\n this.loadingStatusText.style.height = \"100%\";\n this.loadingStatusText.style.color = \"rgba(200,200,200,0.9)\";\n this.loadingStatusText.style.fontSize = \"10px\";\n this.loadingStatusText.style.textAlign = \"center\";\n this.loadingStatusText.style.verticalAlign = \"middle\";\n this.loadingStatusText.style.mixBlendMode = \"difference\";\n this.loadingStatusText.style.fontFamily = \"sans-serif\";\n this.loadingStatusText.style.fontWeight = \"bold\";\n this.loadingStatusText.style.userSelect = \"none\";\n this.loadingStatusText.textContent = \"Loading...\";\n this.progressBarBackground.append(this.loadingStatusText);\n\n this.loadingCallback = () => {\n const [loadingRatio, completedLoading] = this.loadingProgressManager.toRatio();\n if (completedLoading) {\n if (!this.hasCompleted) {\n this.hasCompleted = true;\n if (!this.debugCheckbox.checked) {\n this.dispose();\n }\n }\n this.loadingStatusText.textContent = \"Completed\";\n this.progressBar.style.width = \"100%\";\n } else {\n this.loadingStatusText.textContent = `${(loadingRatio * 100).toFixed(2)}%`;\n this.progressBar.style.width = `${loadingRatio * 100}%`;\n }\n this.progressDebugElement.textContent = LoadingProgressManager.LoadingProgressSummaryToString(\n this.loadingProgressManager.toSummary(),\n );\n };\n\n this.loadingProgressManager.addProgressCallback(this.loadingCallback);\n }\n\n public dispose() {\n if (this.disposed) {\n return;\n }\n this.disposed = true;\n this.loadingProgressManager.removeProgressCallback(this.loadingCallback);\n this.element.remove();\n }\n}\n", "export class ErrorScreen {\n public readonly element: HTMLDivElement;\n\n private titleBannerText: HTMLDivElement;\n private messageText: HTMLDivElement;\n\n constructor(title: string, message: string) {\n this.element = document.createElement(\"div\");\n this.element.style.position = \"absolute\";\n this.element.style.top = \"0\";\n this.element.style.left = \"0\";\n this.element.style.display = \"flex\";\n this.element.style.alignItems = \"center\";\n this.element.style.justifyContent = \"center\";\n this.element.style.flexDirection = \"column\";\n this.element.style.width = \"100%\";\n this.element.style.height = \"100%\";\n this.element.style.background = \"linear-gradient(45deg, #111111 0%, #444444 100%)\";\n this.element.style.color = \"white\";\n\n this.titleBannerText = document.createElement(\"div\");\n this.titleBannerText.textContent = title;\n this.titleBannerText.style.fontSize = \"40px\";\n this.titleBannerText.style.fontWeight = \"bold\";\n this.titleBannerText.style.fontFamily = \"sans-serif\";\n this.element.append(this.titleBannerText);\n\n this.messageText = document.createElement(\"div\");\n this.messageText.style.textAlign = \"center\";\n this.messageText.style.fontFamily = \"sans-serif\";\n this.messageText.style.fontWeight = \"bold\";\n this.messageText.textContent = message;\n this.element.append(this.messageText);\n }\n\n public dispose() {\n this.element.remove();\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["Vector3", "Vector3", "Color", "Vector3", "Vector3", "AnimationState", "Vector3", "Mesh", "Mesh", "Color", "LinearFilter", "canvas", "Color", "LinearFilter", "Color", "Vector3", "Euler", "Group", "Quaternion", "Vector3", "Quaternion", "Raycaster", "Vector3", "Vector3", "Quaternion", "Raycaster", "Quaternion", "Vector3", "Quaternion", "Vector3", "Quaternion", "Vector3", "Vector3", "Quaternion", "Vector3", "Group", "Euler", "Quaternion", "ModelLoader", "Key", "Group", "value", "Color", "_a", "BlendFunction", "EffectComposer", "EffectPass", "NormalPass", "SSAOEffect", "Color", "Euler", "Fog", "HalfFloatType", "Scene", "Vector2", "WebGLRenderer", "Color", "Group", "Vector3", "Group", "Vector3", "Color", "ShaderMaterial", "Uniform", "ShaderMaterial", "Uniform", "Color", "LinearFilter", "OrthographicCamera", "RGBAFormat", "ShaderMaterial", "Uniform", "Vector2", "Vector3", "Matrix4", "Uniform", "Vector2", "Matrix4", "Uniform", "Vector2", "Vector3", "Matrix4", "Uniform", "Vector2", "Vector3", "Mesh", "OrthographicCamera", "Matrix4", "Uniform", "Vector2", "Vector3", "ShaderMaterial", "Uniform", "Color", "LinearFilter", "Vector2", "RGBAFormat", "Vector3", "OrthographicCamera", "Vector2", "Scene", "WebGLRenderer", "EffectComposer", "HalfFloatType", "NormalPass", "BlendFunction", "SSAOEffect", "Color", "EffectPass", "Euler", "Fog", "Box3", "Color", "Euler", "Group", "Line3", "Matrix4", "Mesh", "Quaternion", "Ray", "Vector3", "Euler", "Matrix4", "Quaternion", "Vector3", "Vector3", "Quaternion", "Ray", "Matrix4", "Box3", "Euler", "Line3", "Mesh", "Color", "Group", "FrontSide", "Group", "Mesh", "MeshStandardMaterial", "NearestFilter", "RepeatWrapping", "LoadingProgressManager"]
7
7
  }