From 9e1d5d1a17bf0956c154515a87c7e0c226c23e71 Mon Sep 17 00:00:00 2001 From: konekowo Date: Thu, 12 Sep 2024 19:37:12 +0000 Subject: [PATCH] deploy: 183955802a7033ce151d54bb52a113ca8319fc9c --- game.81b4f0c7209e5b6027b6.js | 2 -- game.81b4f0c7209e5b6027b6.js.map | 1 - game.a7af8ee9d41f20465ca4.js | 2 ++ game.a7af8ee9d41f20465ca4.js.map | 1 + index.html | 2 +- 5 files changed, 4 insertions(+), 4 deletions(-) delete mode 100644 game.81b4f0c7209e5b6027b6.js delete mode 100644 game.81b4f0c7209e5b6027b6.js.map create mode 100644 game.a7af8ee9d41f20465ca4.js create mode 100644 game.a7af8ee9d41f20465ca4.js.map diff --git a/game.81b4f0c7209e5b6027b6.js b/game.81b4f0c7209e5b6027b6.js deleted file mode 100644 index abe5ce5..0000000 --- a/game.81b4f0c7209e5b6027b6.js +++ /dev/null @@ -1,2 +0,0 @@ -!function(){"use strict";var e,t={65918:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.MapAudio=t.Audio=void 0;class i{audio;timeStarted=0;source;id;isPlaying=!1;isPaused=!1;pausedTime=0;nodes=[];tempArrayMain=new Float32Array(256);tempArrayL=new Float32Array(64);tempArrayR=new Float32Array(64);LeftChannel=0;RightChannel=0;FrequencyAmplitudes=new Float32Array(256);_connectedToContext=!1;GetMaximumAudioLevel(){return Math.max(this.LeftChannel,this.RightChannel)}GetAverageAudioLevel(){return(this.LeftChannel+this.RightChannel)/2}Create(e){this.source=e.createBufferSource(),this.source.buffer=this.audio}AddAudioNode(e){if(!this.source)throw new Error("Source not created yet!");this.nodes.push(e)}GetNode(e){let t=this.nodes.filter((t=>t instanceof e));return t.length>0?t:null}ConnectToContext(e,t){if(!this.source)throw new Error("Source not created yet!");this._connectedToContext||(this._connectedToContext=!0,this.nodes.length>0?t?t(this.nodes,this.source):this.nodes.forEach(((t,i)=>{this.source.connect(t),t instanceof AnalyserNode||t.connect(e.destination)})):this.source.connect(e.destination))}Play(){if(!this.source)throw new Error("Source not created yet!");if(!this._connectedToContext)throw new Error("Not connected to audio context yet!");this.source.start(0,this.pausedTime),this.isPlaying=!0,this.isPaused=!1,this.timeStarted=Date.now()-this.pausedTime,this.pausedTime=0}Pause(){if(!this.source)throw new Error("Source not created yet!");if(!this._connectedToContext)throw new Error("Not connected to audio context yet!");this.pausedTime=Date.now()-this.timeStarted,this.source.stop(0),this.isPaused=!0,this.isPlaying=!1}Stop(){if(!this.source)throw new Error("Source not created yet!");if(!this._connectedToContext)throw new Error("Not connected to audio context yet!");this.source.stop(0),this.isPlaying=!1}RegisterEndCallBack(e){if(!this.source)throw new Error("Source not created yet!");this.source.onended=()=>{this.isPaused||e()}}}t.Audio=i;t.MapAudio=class extends i{beatmap;fadingOut=!1;fadeOutTimeout;playingCallback}},85437:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.AudioEngine=void 0;const n=i(14981),s=i(65918),a=i(17898),o=i(20825),r=i(87816),l=i(22331);t.AudioEngine=class{audioContext;_playingAudios;_musicQueue=[];_audioIdTicker=0;_changeCallbacks=[];silentMusic=this.createSilentMusic();useSilentMusic=!0;constructor(){this.audioContext=new AudioContext,this._playingAudios=new n.PlayingAudios,o.Main.app.ticker.add((()=>{this.update()}))}UpdateMusicQueue(){this._musicQueue[0]&&(this._musicQueue[0].fadingOut||0!=this._musicQueue[0].timeStarted||(this._play(this._musicQueue[0]),this._changeCallbacks.forEach((e=>e()))),this._musicQueue[0].fadingOut&&this._musicQueue[1]&&this._musicQueue[1]&&(this._play(this._musicQueue[1]),this._changeCallbacks.forEach((e=>e())))),this._musicQueue.length>=1?this.useSilentMusic=!1:(this.silentMusic=this.createSilentMusic(),this.useSilentMusic=!0)}createSilentMusic(){let e=new s.MapAudio;e.timeStarted=Date.now(),e.beatmap=new a.BeatmapData;let t=new r.UnInheritedTimingPoint;return t.time=0,t.beatLength=1e3,t.effects=l.Effect.None,e.beatmap.TimingPoints.TimingPoints.push(t),e}addMusicChangeEventListener(e){this._changeCallbacks.push(e)}removeMusicChangeEventListener(e){this._changeCallbacks=this._changeCallbacks.filter((t=>t!=e))}GetCurrentPlayingMusic(){return this.useSilentMusic?this.silentMusic:this._musicQueue[0]}PlayEffect(e,t){let i=new s.Audio;i.audio=e,i.id=this._audioIdTicker,this._play(i,t),this._audioIdTicker++}AddToMusicQueue(e,t,i){let n=new s.MapAudio;return n.audio=e,n.beatmap=t,n.id=this._audioIdTicker,i&&(n.playingCallback=i),this._musicQueue.push(n),this._audioIdTicker++,this.UpdateMusicQueue(),n.id}PlayMusicImmediately(e,t,i){this._musicQueue=[],this.AddToMusicQueue(e,t,i)}update(){let e=this.GetCurrentPlayingMusic();if(!this.useSilentMusic){let t=e.GetNode(AnalyserNode)[0],i=e.GetNode(AnalyserNode)[1],n=e.GetNode(AnalyserNode)[2];t.getFloatFrequencyData(e.tempArrayMain);for(let t=0;t{s+=(e+1)/2})),e.tempArrayR.forEach((e=>{a+=(e+1)/2})),s/=e.tempArrayL.length,a/=e.tempArrayR.length,e.LeftChannel=s,e.RightChannel=a}}_play(e,t){if(e.Create(this.audioContext),"beatmap"in e&&e.beatmap){this._playingAudios.audios.forEach((e=>{if("beatmap"in e&&e.beatmap){clearTimeout(e.fadeOutTimeout),e.fadingOut=!0;let t=e.GetNode(GainNode);if(null==t)throw new Error("Gain Node doesn't exist on Audio Object!");t[0].gain.linearRampToValueAtTime(0,this.audioContext.currentTime+.4),setTimeout((()=>{e.Stop()}),400)}}));let t=this.audioContext.createGain();t.gain.value=0;let i=this.audioContext.createAnalyser();i.fftSize=512,i.smoothingTimeConstant=0;let n=this.audioContext.createChannelSplitter(2),s=this.audioContext.createAnalyser();s.smoothingTimeConstant=0,s.fftSize=128;let a=this.audioContext.createAnalyser();a.smoothingTimeConstant=0,a.fftSize=128,e.AddAudioNode(t),e.AddAudioNode(i),e.AddAudioNode(s),e.AddAudioNode(a),e.ConnectToContext(this.audioContext,((e,o)=>{o.connect(t),t.connect(this.audioContext.destination),o.connect(i),o.connect(n),n.connect(s,0),n.connect(a,1)})),e.Play(),this._playingAudios.audios.push(e),e.playingCallback&&e.playingCallback(),t.gain.linearRampToValueAtTime(1,this.audioContext.currentTime+.4),e.fadeOutTimeout=setTimeout((()=>{t.gain.linearRampToValueAtTime(0,this.audioContext.currentTime+.4)}),1e3*(e.audio.duration-.4))}else e.ConnectToContext(this.audioContext),t&&e.source&&(e.source.playbackRate.value=t),e.Play(),this._playingAudios.audios.push(e);e.RegisterEndCallBack((()=>{e.isPlaying=!1,"beatmap"in e&&e.beatmap&&(this._musicQueue[0]==e&&this._musicQueue.splice(0,1),this.UpdateMusicQueue()),this._playingAudios.audios.forEach(((t,i)=>{t!==e||this._playingAudios.audios.splice(i,1)}))}))}}},14981:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.PlayingAudios=void 0;t.PlayingAudios=class{audios=[]}},9611:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.LogoVisualizer=void 0;const o=i(20825),r=a(i(58687)),l=i(5825),u=i(22331);class c extends r.Container{static size=900;frequencyAmplitudes=new Float32Array(256);audio;temporalAmplitudes=new Float32Array(256);graphics=new r.Graphics;index_change=5;bar_length=600;bars_per_visualiser=200;visualiser_rounds=5;decay_per_millisecond=.0024;time_between_updates=50;amplitude_dead_zone=1/this.bar_length;indexOffset=0;firstDraw=!0;start(){this.graphics.blendMode="add",this.addChild(this.graphics),this.graphics.eventMode="none",this.eventMode="none",setInterval((()=>{this.updateAmplitudes()}),this.time_between_updates)}draw(e){if(this.firstDraw)for(let e=0;ethis.frequencyAmplitudes[t]&&(this.frequencyAmplitudes[t]=i)}this.indexOffset=(this.indexOffset+this.index_change)%this.bars_per_visualiser}}t.LogoVisualizer=c},8211:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.MenuLogoVisualizer=void 0;const n=i(9611);class s extends n.LogoVisualizer{draw(e){super.draw(e)}}t.MenuLogoVisualizer=s},49323:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.LoadAnim=void 0;const o=a(i(58687)),r=a(i(29172)),l=i(92915);class u extends o.Container{bg;arc;arcContainer;animInterval;container;bgContainer;bgRotation=0;constructor(e,t){super(),this.pivot.set(.5,.5),this.container=new o.Container,this.container.alpha=0,this.rotation=2.5*Math.PI,this.bgContainer=new o.Container,this.bg=new o.Graphics,this.bg.roundRect(-50,-50,100,100,25),this.bg.fill(e),this.arcContainer=new o.Container,this.arc=new o.Graphics,this.arc.arc(0,0,27,Math.PI+.26,2.92*Math.PI),this.arc.stroke({width:8,color:t,cap:"round"}),this.arc.scale.set(-1,1),this.container.scale.set(.5,.5),this.bgContainer.addChild(this.bg),this.arcContainer.addChild(this.arc),this.bgContainer.addChild(this.arcContainer),this.container.addChild(this.bgContainer),this.addChild(this.container),l.Ease.getEase(this.container).ScaleTo(1,400,r.Easing.Quadratic.InOut).FadeIn(400,r.Easing.Quadratic.InOut),this.doAnims(),this.animInterval=setInterval((()=>{this.doAnims()}),800)}doAnims(){this.bgRotation+=90,l.Ease.getEase(this.bgContainer).createTween({value:this.bgContainer.angle},{value:this.bgRotation},!0,"angle",600,r.Easing.Quadratic.InOut)}getWidth(){return 100*this.scale.x}getHeight(){return 100*this.scale.y}draw(e){this.arcContainer.angle+=3*e.deltaTime}destroy(e){l.Ease.getEase(this.container).FadeOut(400,r.Easing.Quadratic.InOut).ScaleTo(.5,400,r.Easing.Quadratic.InOut),setTimeout((()=>{clearInterval(this.animInterval),super.destroy(e)}),400)}}t.LoadAnim=u},16982:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.Menu=void 0;const o=a(i(58687)),r=a(i(29172)),l=i(92915);class u extends o.Container{menuBG=new o.Graphics;isOpened=!1;constructor(){super(),this.menuBG.rect(0,-62.5,1,125),this.menuBG.fill({color:"rgb(50,50,50)"}),this.menuBG.scale.set(1,0),this.menuBG.alpha=0,this.addChild(this.menuBG)}Open(){this.isOpened=!0,l.Ease.getEase(this.menuBG).ScaleTo(1,400,r.Easing.Quintic.Out).FadeIn(400,r.Easing.Quintic.Out)}Close(){this.isOpened=!1,l.Ease.getEase(this.menuBG).ClearEasings().ScaleTo({x:1,y:0},300,r.Easing.Sinusoidal.In).FadeOut(300,r.Easing.Sinusoidal.In)}isOpen(){return this.isOpened}onResize(){this.position.set(-window.innerWidth,0),this.menuBG.width=2*window.innerWidth}}t.Menu=u},54349:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.OsuCircle=void 0;const o=a(i(58687)),r=i(44961),l=a(i(29172)),u=i(92915),c=i(20825),d=i(12235),h=i(16982),g=i(8211),f=i(9611),p=i(22331),m=i(5825);class v extends o.Container{outline;visualizer=new g.MenuLogoVisualizer;triangles=new r.Triangles;flash;logoContainer=new o.Container;logoBounceContainer=new o.Container;logoBeatContainer=new o.Container;logoAmplitudeContainer=new o.Container;logoHoverContainer=new o.Container;rippleContainer=new o.Container;ripple;menu=new h.Menu;defaultVisualizerAlpha=.5;early_activation=60;timeElapsedSinceLastBeat=0;timeUntilNextBeat=0;lastTimeElapasedSinceLastBeat=0;selectSample=d.Loader.GetAudio("mainMenu.osuLogo.select");backToLogoSample=d.Loader.GetAudio("mainMenu.osuLogo.backToLogo");isMouseDown=!1;mouseDownPosition={x:0,y:0};constructor(){super(),this.visualizer.start(),this.outline=o.Sprite.from("mainMenu.logoOutline"),this.outline.anchor.set(.5,.5);let e=.6;this.visualizer.scale.set(e),this.visualizer.pivot.set(f.LogoVisualizer.size/2,f.LogoVisualizer.size/2),this.visualizer.alpha=this.defaultVisualizerAlpha;let t=new o.Graphics;t.circle(0,0,450),t.fill({color:"white"}),t.scale=e,this.flash=o.Sprite.from("mainMenu.logoMask"),this.flash.anchor.set(.5,.5),this.flash.scale=e,this.flash.blendMode="add",this.flash.alpha=0,this.triangles.flash.anchor.set(.5,.5),this.triangles.flash.scale=e,this.outline.scale.set(e),this.triangles.scale.set(e),this.triangles.position.set(-this.outline.width/2,-this.outline.height/2),this.triangles.mask=t,this.ripple=o.Sprite.from("mainMenu.logoMask"),this.ripple.anchor.set(.5,.5),this.ripple.scale=e,this.ripple.alpha=0,this.ripple.blendMode="add",this.rippleContainer.addChild(this.ripple),this.logoContainer.addChild(this.visualizer),this.logoContainer.addChild(this.triangles),this.logoContainer.addChild(this.triangles.flash),this.logoContainer.addChild(t),this.logoContainer.addChild(this.flash),this.logoContainer.addChild(this.outline),this.logoContainer.hitArea=new o.Circle(0,0,288),this.logoContainer.eventMode="static",this.logoContainer.onmouseenter=this._onmouseenter,this.logoContainer.onmouseleave=this._onmouseleave,this.logoContainer.onmousedown=this._onmousedown,this.logoContainer.onclick=this._onclick,this.logoBeatContainer.addChild(this.logoContainer),this.logoAmplitudeContainer.addChild(this.logoBeatContainer),this.logoBounceContainer.addChild(this.rippleContainer),this.logoBounceContainer.addChild(this.logoAmplitudeContainer),this.logoHoverContainer.addChild(this.logoBounceContainer),this.addChild(this.logoHoverContainer),c.Main.app.stage.addEventListener("mouseup",(e=>{this._onmouseup(e)}))}_onmouseenter=e=>{u.Ease.getEase(this.logoHoverContainer).ScaleTo(1.1,500,l.Easing.Elastic.Out)};_onmouseleave=e=>{u.Ease.getEase(this.logoHoverContainer).ScaleTo(1,500,l.Easing.Elastic.Out)};_onmousedown=e=>{this.isMouseDown=!0,u.Ease.getEase(this.logoBounceContainer).ClearEasings().ScaleTo(.9,1e3,l.Easing.Sinusoidal.Out),this.mouseDownPosition={x:c.Main.mousePos.x,y:c.Main.mousePos.y}};_onclick=e=>{this.flash.alpha=.4,u.Ease.getEase(this.flash).ClearEasings().FadeOut(1500,l.Easing.Exponential.Out)};_onmouseup=e=>{this.isMouseDown=!1,u.Ease.getEase(this.logoBounceContainer).ClearEasings().ScaleTo(1,500,l.Easing.Elastic.Out).TransformTo({x:0,y:0},800,l.Easing.Elastic.Out)};onResize(){this.menu.onResize()}draw(e){this.visualizer.draw(e),this.triangles.draw(e);let t=c.Main.AudioEngine.GetCurrentPlayingMusic(),i=t.beatmap.TimingPoints.GetCurrentUninheritedTimingPoint(Date.now()-t.timeStarted);if(this.timeUntilNextBeat=(i.time-(Date.now()-t.timeStarted))%i.beatLength,this.timeUntilNextBeat<=0&&(this.timeUntilNextBeat+=i.beatLength),this.timeElapsedSinceLastBeat=i.beatLength-this.timeUntilNextBeat,c.Main.AudioEngine.useSilentMusic)this.logoAmplitudeContainer.scale=1,this.triangles.Velocity=m.MathUtil.Damp(this.triangles.Velocity,.5,.9,e.deltaMS);else{let n=t.GetMaximumAudioLevel();this.logoAmplitudeContainer.scale.set(m.MathUtil.Damp(this.logoAmplitudeContainer.scale.x,1-.04*Math.max(0,n-.4),.9,e.deltaMS)),this.triangles.Velocity=m.MathUtil.Damp(this.triangles.Velocity,.5*(i.effects==p.Effect.KiaiTime?4:2),.995,e.deltaMS)}if(this.lastTimeElapasedSinceLastBeat>this.timeElapsedSinceLastBeat&&this.onNewBeat(),this.lastTimeElapasedSinceLastBeat=this.timeElapsedSinceLastBeat,this.isMouseDown){let e={x:c.Main.mousePos.x-this.mouseDownPosition.x,y:c.Main.mousePos.y-this.mouseDownPosition.y},t=Math.sqrt(e.x*e.x+e.y*e.y);e.x*=t<=0?0:Math.pow(t,.6)/t,e.y*=t<=0?0:Math.pow(t,.6)/t,this.logoBounceContainer.x=e.x,this.logoBounceContainer.y=e.y}}onNewBeat(){let e=c.Main.AudioEngine.GetCurrentPlayingMusic(),t=e.beatmap.TimingPoints.GetCurrentUninheritedTimingPoint(Date.now()-e.timeStarted).beatLength,i=e.beatmap.TimingPoints.GetCurrentTimingPoints(Date.now()-e.timeStarted)[0],n=c.Main.AudioEngine.useSilentMusic?0:e.GetMaximumAudioLevel(),s=Math.min(1,.4+n);u.Ease.getEase(this.logoBeatContainer).ScaleTo(1-.02*s,this.early_activation,l.Easing.Linear.None).Then().ScaleTo(1,2*t,l.Easing.Quintic.Out),this.rippleContainer.scale=1.02,u.Ease.getEase(this.rippleContainer).ClearEasings().ScaleTo(1.02*(1+.04*s),2*t,l.Easing.Quintic.Out),this.ripple.alpha=.15*s,u.Ease.getEase(this.ripple).ClearEasings().FadeOut(t,l.Easing.Quintic.Out),i.effects==p.Effect.KiaiTime&&(u.Ease.getEase(this.triangles.flash).ClearEasings().FadeTo(.2*s,this.early_activation,l.Easing.Linear.None).Then().FadeTo(0,t,l.Easing.Linear.None),u.Ease.getEase(this.visualizer).ClearEasings().FadeTo(1.8*this.defaultVisualizerAlpha*s,this.early_activation,l.Easing.Linear.None).Then().FadeTo(this.defaultVisualizerAlpha,t,l.Easing.Linear.None)),setTimeout((()=>{this.triangles.Velocity+=s*(i.effects==p.Effect.KiaiTime?6:3)}),60)}}t.OsuCircle=v},44961:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t},o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.Triangles=void 0;const r=a(i(58687)),l=i(20825),u=o(i(46404)),c=o(i(58689)),d=o(i(61630));class h extends r.Container{flash;Velocity=1;bgGradient;triangles=[];graphics=new r.Graphics;timeSinceLastSpawn=0;instancePositionBuffer;totalTriangles=15;constructor(){super();let e=[16737963,13390473];this.bgGradient=new r.FillGradient(0,0,0,1024),e.forEach(((t,i)=>{const n=i/e.length;this.bgGradient.addColorStop(n,t)}));for(let e=0;e{this.mouseButtonClicked=e.button,this.visible&&(this.posMouseDown={x:r.Main.mousePos.x,y:r.Main.mousePos.y},this.mouseIsDown=!0,this.dragRotationState=f.DragStarted,d.Ease.getEase(this.animContainer).ClearEasings().ScaleTo(.9,800,h.Easing.Quintic.Out),d.Ease.getEase(this.mouseCursorAdditive).ClearEasings().FadeIn(800,h.Easing.Quintic.Out),r.Main.AudioEngine.PlayEffect(this.cursorTapSample))})),r.Main.app.stage.addEventListener("mouseup",(e=>{this.visible&&e.button==this.mouseButtonClicked&&(this.mouseIsDown=!1,d.Ease.getEase(this.animContainer).ClearEasings().ScaleTo(1,500,h.Easing.Elastic.Out),d.Ease.getEase(this.mouseCursorAdditive).ClearEasings().FadeOut(500,h.Easing.Quintic.Out),this.dragRotationState!=f.NotDragging&&(this.dragRotationState==f.Rotating&&d.Ease.getEase(this.animRotationContainer).ClearEasings().createTween({value:this.animRotationContainer.angle},{value:0},!0,"angle",800*(.5+Math.abs(this.animRotationContainer.angle/960)),(e=>Math.pow(2,-10*e)*Math.sin((.25*e-this.elastic_const2)*this.elastic_const)+1-this.elastic_offset_quarter*e)),this.dragRotationState=f.NotDragging),r.Main.AudioEngine.PlayEffect(this.cursorTapSample,.8))}))}PopIn(){d.Ease.getEase(this.animRotationContainer).ClearEasings(),this.visible=!0,d.Ease.getEase(this.mouseHideContainer).ClearEasings().FadeIn(250,h.Easing.Quintic.Out).ScaleTo(1,400,h.Easing.Quintic.Out),this.dragRotationState=f.NotDragging}PopOut(){d.Ease.getEase(this.mouseHideContainer).ClearEasings().FadeOut(250,h.Easing.Quintic.Out).ScaleTo(.6,250,h.Easing.Quintic.Out),d.Ease.getEase(this.animRotationContainer).ClearEasings().createTween({value:this.animRotationContainer.angle},{value:0},!0,"angle",400,h.Easing.Quintic.Out),this.dragRotationState=f.NotDragging}updateMouse(){if(this.mouseContainer.scale.set(.07*c.Screen.getScaleBasedOffScreenSize()),this.position.set(r.Main.mousePos.x,r.Main.mousePos.y),this.dragRotationState!=f.NotDragging&&this.visible){let e=Math.sqrt((2^Math.abs(this.posMouseDown.x-r.Main.mousePos.x))+(2^Math.abs(this.posMouseDown.y-r.Main.mousePos.y)));if(this.dragRotationState==f.DragStarted&&e>15&&(this.dragRotationState=f.Rotating,this.lastDragRotationState!=this.dragRotationState&&(this.posMouseDown={x:r.Main.mousePos.x,y:r.Main.mousePos.y})),this.dragRotationState==f.Rotating&&e>0){let e=r.Main.mousePos.x-this.posMouseDown.x,t=r.Main.mousePos.y-this.posMouseDown.y,i=u.MathUtil.RadiansToDegrees(Math.atan2(-e,t))+24.3,n=(i-this.animRotationContainer.angle)%360;n<-180&&(n+=360),n>180&&(n-=360),i=this.animRotationContainer.angle+n,this.animRotationContainer.angle=i,d.Ease.getEase(this.animRotationContainer).createTween({value:this.animRotationContainer.angle},{value:i},!0,"angle",120,h.Easing.Quintic.Out)}}this.lastDragRotationState=this.dragRotationState}}var f;t.MenuCursor=g,function(e){e[e.NotDragging=0]="NotDragging",e[e.DragStarted=1]="DragStarted",e[e.Rotating=2]="Rotating"}(f||(f={}))},36721:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.RandomBackground=void 0;const o=a(i(58687)),r=i(12235),l=i(84283),u=i(92915),c=a(i(29172)),d=i(20825);class h extends l.Screen{bgContainer=new o.Container;parallaxMultiplier=60;start(){this.bgContainer.pivot.set(.5,.5),this.bgContainer.position.set((d.Main.mousePos.x-this.getScreenWidth()/2)/this.parallaxMultiplier,(d.Main.mousePos.y-this.getScreenHeight()/2)/this.parallaxMultiplier),this.addChild(this.bgContainer),this.newRandomBG(),d.Main.AudioEngine.addMusicChangeEventListener((()=>{this.newRandomBG()}))}setBG(e){if(0==this.bgContainer.children?.length)this.bgContainer.addChild(e);else{let t=this.bgContainer.children[0];e.zIndex=-1,this.bgContainer.addChild(e),u.Ease.getEase(t,!0).FadeOut(800,c.Easing.Linear.None).Then((()=>{e.zIndex=0,t.destroy()}))}e.anchor.set(.5,.5),this.onResize()}newRandomBG(){let e=r.Loader.seasonalBackgroundsNum>0,t=(i=1,n=e?r.Loader.seasonalBackgroundsNum:r.Loader.defaultBackgroundsNum,Math.round(Math.random()*(n-i)+i));var i,n;this.setBG(o.Sprite.from((e?"seasonal_bg":"default_bg")+t))}draw(e){this.bgContainer.position.set((d.Main.mousePos.x-this.getScreenWidth()/2)/this.parallaxMultiplier,(d.Main.mousePos.y-this.getScreenHeight()/2)/this.parallaxMultiplier)}onClose(){return Promise.resolve(this)}onResize(){this.bgContainer.children.forEach((e=>{if(e instanceof o.Sprite){let t,i=e.texture.width,n=e.texture.height;t=window.innerWidth>window.innerHeight?window.innerWidth/i:window.innerHeight/n,n*t{i.id==e&&(t=i.data)})),!t)throw new Error("Asset not found!");return t}static GetString(e){let t;if(this.loadedList.forEach((i=>{i.id==e&&(t=i.dataString)})),!t)throw new Error("Asset not found or is not a string!");return t}static GetAudio(e){let t;if(this.loadedList.forEach((i=>{i.id==e&&(t=i.dataAudio)})),!t)throw new Error("Asset not found or was not marked as audio during loading!");return t}static addBackgrounds(){return new Promise((e=>{for(let e=1;ee.json())).then((t=>{t.backgrounds.forEach(((e,t)=>{this.loadList.push({id:"seasonal_bg"+(t+1),url:"https://corsproxy.io/?"+encodeURIComponent(e.url),pixiBundleName:"textures",loadParser:"loadTextures"}),this.seasonalBackgroundsNum=t+1})),e()})).catch((t=>{console.warn("Could not fetch seasonal backgrounds.",t),e()}))}))}static Load(e){return this.addToLoadList(),new Promise((t=>{this.addBackgrounds().then((()=>{let i=[],n=[],s=[],a=0,r=0;this.loadList.forEach((e=>{e.pixiBundleName?n.push(e):i.push(e)})),n.forEach((e=>{let t=!1;s.forEach((i=>{i.length>0&&i[0].pixiBundleName==e.pixiBundleName&&(i.push(e),t=!0)})),t||s.push([e])}));const l=e=>{e?r++:a++,r+a>=this.loadList.length&&t()};i.forEach((t=>{fetch(t.url).then((e=>e.blob())).then((i=>{t.isText||t.isAudio?t.isText?i.text().then((e=>{l(),this.loadedList.push({id:t.id,data:i,dataString:e})})):t.isAudio&&i.arrayBuffer().then((t=>e.decodeAudioData(t))).then((e=>{l(),this.loadedList.push({id:t.id,data:i,dataAudio:e})})):(l(),this.loadedList.push({id:t.id,data:i}))})).catch((e=>{l(!0),console.warn("Asset '"+t.id+"' failed to load: "+e)}))})),s.forEach((e=>{if(e.length>0){if(!e[0].pixiBundleName)throw new Error("wtf????");let t=[];e.forEach((e=>{e.loadParser?t.push({alias:e.id,src:e.url,loadParser:e.loadParser}):t.push({alias:e.id,src:e.url})})),o.Assets.addBundle(e[0].pixiBundleName,t),o.Assets.loadBundle(e[0].pixiBundleName).then((()=>{e.forEach((()=>{l()}))}))}}))}))}))}}},25373:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.InteractScreen=void 0;const o=i(84283),r=a(i(58687)),l=i(20825),u=i(94433),c=a(i(29172)),d=i(92915);class h extends o.Screen{text;text2;textContainer=new r.Container;textContainerContainer=new r.Container;introTrack;clickSound;clickArea=new r.Graphics;constructor(e,t){super(),this.introTrack=e,this.clickSound=t,this.text=new r.Text({text:"Click anywhere to play!",style:{fontFamily:"TorusRegular",fontSize:36,fill:"white"}}),this.text2=new r.Text({text:"(this is for enabling audio because it's required by web-browsers\n to have interaction on this webpage before playing audio.)",style:{fontFamily:"TorusRegular",fontSize:26,fill:"gray",align:"center"}})}start(){this.text.anchor.set(.5,.5),this.text2.anchor.set(.5,.5),this.text2.position.set(0,this.text.height+15),this.textContainer.addChild(this.text),this.textContainer.addChild(this.text2),this.textContainer.scale.set(.5),this.textContainer.alpha=0,this.textContainerContainer.addChild(this.textContainer),this.textContainerContainer.scale=o.Screen.getScaleBasedOffScreenSize(),this.textContainerContainer.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),this.addChild(this.textContainerContainer),this.clickArea.rect(0,0,1,1),this.clickArea.fill("rgba(0,0,0,0)"),this.clickArea.width=this.getScreenWidth(),this.clickArea.height=this.getScreenHeight(),this.clickArea.position.set(0,0),this.addChild(this.clickArea),this.clickArea.eventMode="static",this.clickArea.cursor="pointer";const e=()=>{this.clickArea.eventMode="none",l.Main.AudioEngine.PlayEffect(this.clickSound),l.Main.switchScreen(new u.IntroScreen(this.introTrack)),document.body.style.cursor="none",l.Main.pointerLock(),l.Main.lockKeyboard()};this.clickArea.onclick=()=>{e()},this.clickArea.ontap=()=>{e()},d.Ease.getEase(this.textContainer).FadeIn(400,c.Easing.Quadratic.Out).ScaleTo(1,400,c.Easing.Quadratic.Out)}onClose(){return new Promise((e=>{d.Ease.getEase(this.textContainer).FadeOut(200,c.Easing.Quadratic.Out).ScaleTo(.5,200,c.Easing.Quadratic.InOut),setTimeout((()=>{e(this)}),200)}))}draw(e){}onResize(){this.textContainerContainer.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),this.clickArea.width=this.getScreenWidth(),this.clickArea.height=this.getScreenHeight(),this.clickArea.position.set(0,0),this.textContainerContainer.scale=o.Screen.getScaleBasedOffScreenSize()}}t.InteractScreen=h},88662:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.GlitchingTriangles=void 0;const o=a(i(58687)),r=i(92915),l=a(i(29172));class u extends o.Container{constructor(e){super();let t=new o.Graphics,i=n(.2,1.2);function n(e,t){return Math.random()*(t-e)+e}t.moveTo(0,0),t.lineTo(-50*i,100*i),t.lineTo(50*i,100*i),t.lineTo(0,0),Math.random()<.5?t.fill("white"):t.stroke({color:"white",width:1});let s=n(e.x1,e.x2),a=n(e.y1,e.y2);t.position.set(s,a),r.Ease.getEase(t,!0).FadeOut(200,l.Easing.Linear.None),setTimeout((()=>{this.destroy()}),200),this.addChild(t)}}t.GlitchingTriangles=u},94433:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.IntroScreen=void 0;const o=i(84283),r=a(i(58687)),l=i(53931),u=i(20825),c=i(88662),d=i(58940),h=i(55402),g=i(9752),f=a(i(29172)),p=i(92915);class m extends o.Screen{introTrackUrl;doTextSpacingAnim=!1;triangles=new r.Container;ruleSetContainer=new r.Container;flash=new r.Graphics;logoContainerContainer=new r.Container;logoContainer=new r.Container;lazerLogo=new h.LazerLogo;flashed=!1;standard=r.Sprite.from("icon_ruleset_std");taiko=r.Sprite.from("icon_ruleset_taiko");ctb=r.Sprite.from("icon_ruleset_ctb");mania=r.Sprite.from("icon_ruleset_mania");bg=new r.Graphics;completionPromise;welcomeText=new r.Text({text:"",style:{fontFamily:"TorusThin",fontSize:42,fill:"white",letterSpacing:5}});constructor(e){super(),this.introTrackUrl=URL.createObjectURL(e),this.bg.rect(0,0,1,1),this.bg.fill("black")}start(){this.bg.width=window.innerWidth,this.bg.height=window.innerHeight,this.bg.x=0,this.bg.y=0,this.addChild(this.bg),this.lazerLogo.scale.set(o.Screen.getScaleBasedOffScreenSize()),this.logoContainer.addChild(this.lazerLogo),this.logoContainer.scale.set(1.2),this.logoContainerContainer.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),this.logoContainerContainer.pivot.set(.5,.5),this.logoContainerContainer.addChild(this.logoContainer),this.logoContainerContainer.alpha=0,this.addChild(this.logoContainerContainer),this.flash.rect(0,0,1,1),this.flash.fill("white"),this.flash.position.set(0,0),this.flash.width=this.getScreenWidth(),this.flash.height=this.getScreenHeight(),this.flash.blendMode="add",this.welcomeText.anchor.set(.5,.5),this.welcomeText.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),setTimeout((async()=>{const{entries:e}=await(0,l.unzip)(this.introTrackUrl);for(const[t,i]of Object.entries(e))if(t.endsWith(".osu")){i.text().then((t=>{let i=g.BeatmapParser.Parse(t);console.log(i);for(const[t,n]of Object.entries(e))t==i.General.AudioFileName&&n.arrayBuffer().then((e=>u.Main.AudioEngine.audioContext.decodeAudioData(e))).then((e=>{u.Main.AudioEngine.PlayMusicImmediately(e,i,(()=>{this.afterAudioPlay()}))}))}));break}}),0)}afterAudioPlay(){this.completionPromise=new Promise((e=>{let t;this.welcomeText.scale.set(o.Screen.getScaleBasedOffScreenSize()),this.addChild(this.welcomeText),setTimeout((()=>{this.welcomeText.text="wel",this.onResize()}),200),setTimeout((()=>{this.welcomeText.text="welcome",this.onResize()}),400),setTimeout((()=>{this.welcomeText.text="welcome to",this.onResize()}),700),this.triangles.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),this.triangles.scale.set(o.Screen.getScaleBasedOffScreenSize()),this.addChild(this.triangles),setTimeout((()=>{this.welcomeText.text="welcome to kosu!",this.doTextSpacingAnim=!0,t=setInterval((()=>{let e=new c.GlitchingTriangles({x1:-this.welcomeText.width/2-100,x2:this.welcomeText.width/2+100,y1:-this.welcomeText.height/2-150,y2:this.welcomeText.height/2+100});this.triangles.addChild(e)}),30),this.onResize()}),900),this.standard.anchor.set(.5,.5),this.standard.scale.set(.4*o.Screen.getScaleBasedOffScreenSize()),this.ruleSetContainer.addChild(this.standard),this.taiko.anchor.set(.5,.5),this.taiko.scale.set(.4*o.Screen.getScaleBasedOffScreenSize()),this.ruleSetContainer.addChild(this.taiko),this.ctb.anchor.set(.5,.5),this.ctb.scale.set(.4*o.Screen.getScaleBasedOffScreenSize()),this.ruleSetContainer.addChild(this.ctb),this.mania.anchor.set(.5,.5),this.mania.scale.set(.4*o.Screen.getScaleBasedOffScreenSize()),this.ruleSetContainer.addChild(this.mania),setTimeout((()=>{this.doTextSpacingAnim=!1,this.onResize(),clearInterval(t),this.welcomeText.destroy(),this.triangles.destroy(),this.ruleSetContainer.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),this.addChild(this.ruleSetContainer);this.standard.position.set(-375*o.Screen.getScaleBasedOffScreenSize(),0),this.taiko.position.set(-125*o.Screen.getScaleBasedOffScreenSize(),0),this.ctb.position.set(125*o.Screen.getScaleBasedOffScreenSize(),0),this.mania.position.set(375*o.Screen.getScaleBasedOffScreenSize(),0),p.Ease.getEase(this.ruleSetContainer).ScaleTo(.8,1e3,f.Easing.Linear.None)}),1450),setTimeout((()=>{this.standard.position.set(-240*o.Screen.getScaleBasedOffScreenSize(),0),this.taiko.position.set(-75*o.Screen.getScaleBasedOffScreenSize(),0),this.ctb.position.set(75*o.Screen.getScaleBasedOffScreenSize(),0),this.mania.position.set(240*o.Screen.getScaleBasedOffScreenSize(),0),this.standard.scale.set(o.Screen.getScaleBasedOffScreenSize()),this.taiko.scale.set(o.Screen.getScaleBasedOffScreenSize()),this.ctb.scale.set(o.Screen.getScaleBasedOffScreenSize()),this.mania.scale.set(o.Screen.getScaleBasedOffScreenSize())}),1650),setTimeout((()=>{this.standard.position.set(-350*o.Screen.getScaleBasedOffScreenSize(),0),this.taiko.position.set(-120*o.Screen.getScaleBasedOffScreenSize(),0),this.ctb.position.set(120*o.Screen.getScaleBasedOffScreenSize(),0),this.mania.position.set(350*o.Screen.getScaleBasedOffScreenSize(),0),this.standard.scale.set(2*o.Screen.getScaleBasedOffScreenSize()),this.taiko.scale.set(2*o.Screen.getScaleBasedOffScreenSize()),this.ctb.scale.set(2*o.Screen.getScaleBasedOffScreenSize()),this.mania.scale.set(2*o.Screen.getScaleBasedOffScreenSize()),p.Ease.getEase(this.ruleSetContainer).ScaleTo(1.3,1e3,f.Easing.Linear.None)}),1850),setTimeout((()=>{this.ruleSetContainer.destroy(),this.lazerLogo.start(),this.logoContainerContainer.alpha=1,this.logoContainerContainer.scale.set(1.2),p.Ease.getEase(this.logoContainerContainer).ScaleTo(1,920,f.Easing.Quadratic.In),setTimeout((()=>{p.Ease.getEase(this.logoContainer).ScaleTo(1.2-.8,276,f.Easing.Quintic.In)}),644)}),2080),setTimeout((()=>{this.addChild(this.flash),this.bg.destroy(),this.flash.eventMode="none",this.flashed=!0,this.logoContainerContainer.visible=!1,p.Ease.getEase(this.flash).FadeOut(1e3,f.Easing.Quadratic.Out).Then((()=>{e()})),u.Main.cursor.PopIn()}),3e3)})),u.Main.switchScreen(new d.MainMenu)}draw(e){this.doTextSpacingAnim&&(this.welcomeText.style.letterSpacing+=.15*e.deltaTime,this.onResize())}onClose(){return new Promise((e=>{this.completionPromise.then((()=>{e(this)}))}))}onResize(){this.bg.destroyed||(this.bg.width=window.innerWidth,this.bg.height=window.innerHeight,this.bg.x=0,this.bg.y=0),this.welcomeText.destroyed||this.welcomeText.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),this.triangles.destroyed||(this.triangles.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),this.triangles.scale.set(o.Screen.getScaleBasedOffScreenSize())),this.ruleSetContainer.destroyed||this.ruleSetContainer.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),!this.flash.destroyed&&this.flashed&&(this.flash.position.set(0,0),this.flash.width=this.getScreenWidth(),this.flash.height=this.getScreenHeight()),this.logoContainerContainer.destroyed||this.logoContainerContainer.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),this.lazerLogo.destroyed||this.lazerLogo.scale.set(o.Screen.getScaleBasedOffScreenSize()),this.welcomeText.destroyed||this.welcomeText.scale.set(o.Screen.getScaleBasedOffScreenSize()),this.standard.destroyed||this.standard.scale.set(.4*o.Screen.getScaleBasedOffScreenSize()),this.mania.destroyed||this.mania.scale.set(.4*o.Screen.getScaleBasedOffScreenSize()),this.ctb.destroyed||this.ctb.scale.set(.4*o.Screen.getScaleBasedOffScreenSize()),this.taiko.destroyed||this.taiko.scale.set(.4*o.Screen.getScaleBasedOffScreenSize())}}t.IntroScreen=m},55402:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.LazerLogo=void 0;const o=a(i(58687)),r=i(87525),l=a(i(29172)),u=i(92915);class c extends o.Container{highlight;background;textureHighlight=o.Texture.from("intro_triangles_osuLogo_anim_highlight");textureBackground=o.Texture.from("intro_triangles_osuLogo_anim_background");constructor(){super(),this.highlight=new r.LogoAnimation(this.textureHighlight,new o.Color("white")),this.background=new r.LogoAnimation(this.textureBackground,new o.Color("rgb(128, 128, 128)")),this.addChild(this.highlight),this.addChild(this.background)}start(){let e=new o.Container;e.scale.set(0,0),u.Ease.getEase(e).ScaleTo(1,920,l.Easing.Linear.None).OnEach((()=>{this.highlight.setProgress(e.scale.x),this.background.setProgress(e.scale.x)}))}}t.LazerLogo=c},87525:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t},o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.LogoAnimation=void 0;const r=a(i(58687)),l=o(i(26045)),u=o(i(44160)),c=o(i(46110));class d extends r.Container{shader;texture;constructor(e,t){super(),this.texture=e,this.shader=r.Shader.from({gl:{vertex:l.default,fragment:u.default},gpu:{vertex:{entryPoint:"mainVert",source:c.default},fragment:{entryPoint:"mainFrag",source:c.default}},resources:{uTexture:this.texture.source,uSampler:this.texture.source.style,uProgress:{progress:{value:0,type:"f32"}}}});const i=new r.Geometry({attributes:{aPosition:[-this.texture.width/2,-this.texture.height/2,this.texture.width/2,-this.texture.height/2,this.texture.width/2,this.texture.width/2,-this.texture.width/2,this.texture.width/2],aUV:[0,0,1,0,1,1,0,1],aColor:[t.red,t.green,t.blue,t.alpha,t.red,t.green,t.blue,t.alpha,t.red,t.green,t.blue,t.alpha,t.red,t.green,t.blue,t.alpha]},indexBuffer:[0,1,2,0,2,3]}),n=new r.Mesh({geometry:i,shader:this.shader});this.addChild(n)}setProgress(e){this.shader.resources.uProgress.uniforms.progress=e}}t.LogoAnimation=d},76969:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.LoadScreen=void 0;const n=i(84283),s=i(49323);class a extends n.Screen{loadAnim=new s.LoadAnim("rgba(255,255,255,0.7)","black");start(){this.loadAnim.scale.set(.8*n.Screen.getScaleBasedOffScreenSize()),this.loadAnim.position.set(this.getScreenWidth()-this.loadAnim.getWidth()-15,this.getScreenHeight()-this.loadAnim.getHeight()-15),this.addChild(this.loadAnim)}draw(e){this.loadAnim?.draw(e)}onClose(){return new Promise((e=>{null!=this.loadAnim&&this.loadAnim.destroy(),setTimeout((()=>{e(this)}),400)}))}onResize(){this.loadAnim.position.set(this.getScreenWidth()-this.loadAnim.getWidth()-20,this.getScreenHeight()-this.loadAnim.getHeight()-20),this.loadAnim.scale.set(.8*n.Screen.getScaleBasedOffScreenSize())}}t.LoadScreen=a},58940:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.MainMenu=void 0;const n=i(84283),s=i(36721),a=i(54349);class o extends n.Screen{bg=new s.RandomBackground;osuCircle=new a.OsuCircle;start(){this.bg.start(),this.addChild(this.bg),this.osuCircle.scale=n.Screen.getScaleBasedOffScreenSize(),this.addChild(this.osuCircle)}draw(e){this.bg.draw(e),this.osuCircle.draw(e)}onClose(){return new Promise((e=>{this.bg.onClose().then((()=>{e(this)}))}))}onResize(){this.osuCircle.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),this.bg.onResize(),this.osuCircle.onResize(),this.osuCircle.scale=n.Screen.getScaleBasedOffScreenSize()}}t.MainMenu=o},84283:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.Screen=void 0;const o=a(i(58687)),r=i(58293),l=i(64681);class u extends o.Container{constructor(){super()}static getScaleBasedOffScreenSize(){const e=r.Settings.getSetting(l.UIScale).getValue();return(window.innerWidth/1920+window.innerHeight/1080)/2*e}getScreenWidth(){return window.innerWidth}getScreenHeight(){return window.innerHeight}}t.Screen=u},75341:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.SettingsCategory=t.Setting=void 0;const n=i(58293);var s;t.Setting=class{info;constructor(e){this.info=e,n.Settings.register({setting:this,info:e})}onValueChanged(){}},function(e){e.General="General",e.Skin="Skin",e.Input="Input",e.UserInterface="User Interface",e.Gameplay="Gameplay",e.Rulesets="Rulesets",e.Audio="Audio",e.Graphics="Graphics",e.Online="Online",e.Maintenance="Maintenance",e.Debug="Debug"}(s||(t.SettingsCategory=s={}))},74975:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.DropdownSetting=void 0;const n=i(75341),s=i(58293);class a extends n.Setting{value;getValue(){if(!this.value)throw new Error("Value is undefined!");return this.value}getDefaultValue(){return this.defaultValue}setValue(e){this.list.find((t=>t.value==e.value&&t.displayName==e.displayName))?(this.value=e,s.Settings.save(),this.onValueChanged()):console.warn("The value provided to this DropDownSetting does not exist in the option list! Ignoring value provided.")}loadFromSaveValue(e){this.list.find((t=>t.value==e.value&&t.displayName==e.displayName))?(this.value=e,this.onValueChanged()):console.warn("The value provided to this DropDownSetting does not exist in the option list! Ignoring value provided.")}}t.DropdownSetting=a},78642:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.RangeSetting=void 0;const n=i(75341),s=i(58293),a=i(5825);class o extends n.Setting{value=0;getValue(){return this.value}getDefaultValue(){return this.defaultValue}setValue(e){this.value=a.MathUtil.clamp(this.minValue,this.maxValue,e),s.Settings.save(),this.onValueChanged()}loadFromSaveValue(e){this.value=a.MathUtil.clamp(this.minValue,this.maxValue,e),this.onValueChanged()}}t.RangeSetting=o},58293:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.Settings=void 0;const n=i(64681),s=i(44256),a=i(59029);t.Settings=class{static settingsList=[];static registerAll(){new n.UIScale,new s.Renderer,new a.MouseSensitivity}static load(){let e=window.localStorage.getItem("settings");if(null==e)return;let t=this.getList();try{JSON.parse(e).forEach((e=>{let i=!1;try{e.value||(console.warn("Setting '"+JSON.stringify(e)+"' may be corrupted, skipping!"),i=!0),e.info?(e.info.name||(console.warn("Setting '"+JSON.stringify(e)+"' may be corrupted, skipping!"),i=!0),e.info.category||(console.warn("Setting '"+JSON.stringify(e)+"' may be corrupted, skipping!"),i=!0)):(console.warn("Setting '"+JSON.stringify(e)+"' may be corrupted, skipping!"),i=!0)}catch(e){console.warn("Something went wrong when validating saved settings!",e),console.warn("The setting may be REALLY corrupted, skipping!"),i=!0}if(!i){let i=t.filter((t=>t.info.name==e.info.name&&t.info.category==e.info.category))[0];i?i.setting.loadFromSaveValue(e.value):console.warn("Could not find setting object '"+e.info.name+"', maybe it has been removed in this version of kosu?, skipping setting")}}))}catch(e){console.warn("Failed to load settings! Resetting Settings due to corrupted save!",e),this.reset()}}static save(){let e=this.getList(),t=[];e.forEach((e=>{e.setting.getValue()!=e.setting.getDefaultValue()&&t.push({info:e.info,value:e.setting.getValue()})})),window.localStorage.setItem("settings",JSON.stringify(t))}static reset(){console.warn("Resetting Settings!"),window.localStorage.removeItem("settings")}static register(e){this.settingsList.push(e)}static getSetting(e){return this.settingsList.filter((t=>t.setting instanceof e))[0].setting}static getSettingData(e){return this.settingsList.filter((t=>t.setting instanceof e))[0]}static getList(){return this.settingsList}}},44256:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.Renderer=void 0;const n=i(75341),s=i(74975);class a extends s.DropdownSetting{list=[];webglOption={displayName:"WebGL",value:"webgl"};webGpuOption={displayName:"WebGPU",value:"webgpu"};defaultValue=this.webglOption;constructor(){super({name:"Renderer",category:n.SettingsCategory.Graphics}),this.list.push(this.webglOption,this.webGpuOption),this.value=this.defaultValue}}t.Renderer=a},64681:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.UIScale=void 0;const n=i(78642),s=i(75341);class a extends n.RangeSetting{maxValue=.8;minValue=1.6;increment=.1;defaultValue=1;constructor(){super({name:"UI scaling",category:s.SettingsCategory.Graphics}),this.value=this.defaultValue}}t.UIScale=a},59029:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.MouseSensitivity=void 0;const n=i(78642),s=i(75341),a=i(58687);class o extends n.RangeSetting{defaultValue=1;increment=.01;maxValue=10;minValue=.1;constructor(){super({name:"Sensitivity",category:s.SettingsCategory.Input}),this.value=this.defaultValue,this.onValueChanged()}onValueChanged(){a.EventSystem.cursorSensitivity=this.getValue()}}t.MouseSensitivity=o},17898:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.BeatmapData=void 0;const n=i(85932),s=i(20352),a=i(32007),o=i(78878),r=i(54611),l=i(6386),u=i(43354);t.BeatmapData=class{General=new n.GeneralData;Editor=new s.EditorData;Metadata=new a.Metadata;Difficulty=new o.DifficultyData;Events=new r.EventsData;TimingPoints=new l.TimingPointsData;Colors=new u.ColorsData}},43354:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.ColorsData=void 0;t.ColorsData=class{Colors=[]}},78878:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.DifficultyData=void 0;t.DifficultyData=class{HPDrainRate;CircleSize;OverallDifficulty;ApproachRate;SliderMultiplier;SliderTickRate}},20352:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.EditorData=void 0;t.EditorData=class{Bookmarks=[];DistanceSpacing;BeatDivisor;GridSize;TimelineZoom}},54611:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.EventsData=void 0;t.EventsData=class{Events=[]}},37940:function(e,t){var i;Object.defineProperty(t,"__esModule",{value:!0}),t.Countdown=void 0,function(e){e[e.NoCountdown=0]="NoCountdown",e[e.Normal=1]="Normal",e[e.Half=2]="Half",e[e.Double=3]="Double"}(i||(t.Countdown=i={}))},85932:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.GeneralData=void 0;const n=i(37940),s=i(41080),a=i(90857),o=i(45274);t.GeneralData=class{AudioFileName;AudioLeadIn=0;AudioHash;PreviewTime=-1;Countdown=n.Countdown.Normal;SampleSet=s.SampleSet.Normal;StackLeniency=.7;Mode=a.Mode.OSU;LetterboxInBreaks=!1;StoryFireInFront=!0;UseSkinSprites=!1;AlwaysShowPlayfield=!1;OverlayPosition=o.OverlayPosition.NoChange;SkinPreference;EpilepsyWarning=!1;CountdownOffset=0;SpecialStyle=!1;WidescreenStoryboard=!1;SamplesMatchPlaybackRate=!1}},90857:function(e,t){var i;Object.defineProperty(t,"__esModule",{value:!0}),t.Mode=void 0,function(e){e[e.OSU=0]="OSU",e[e.TAIKO=1]="TAIKO",e[e.CATCH=2]="CATCH",e[e.MANIA=3]="MANIA"}(i||(t.Mode=i={}))},45274:function(e,t){var i;Object.defineProperty(t,"__esModule",{value:!0}),t.OverlayPosition=void 0,function(e){e.NoChange="NoChange",e.Below="Below",e.Above="Above"}(i||(t.OverlayPosition=i={}))},41080:function(e,t){var i;Object.defineProperty(t,"__esModule",{value:!0}),t.SampleSet=void 0,function(e){e.Normal="Normal",e.Soft="Soft",e.Drum="Drum"}(i||(t.SampleSet=i={}))},32007:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.Metadata=void 0;t.Metadata=class{Title;TitleUnicode;Artist;ArtistUnicode;Creator;Version;Source;Tags;BeatmapID;BeatmapSetID}},22331:function(e,t){var i;Object.defineProperty(t,"__esModule",{value:!0}),t.Effect=void 0,function(e){e[e.KiaiTime=1]="KiaiTime",e[e.None=0]="None",e[e.FirstBarLineOmittedInOsuTaikoAndOsuMania=3]="FirstBarLineOmittedInOsuTaikoAndOsuMania"}(i||(t.Effect=i={}))},3143:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.InheritedTimingPoint=void 0;const n=i(52032);class s extends n.TimingPoint{sliderVelocityMultiplier}t.InheritedTimingPoint=s},52032:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.TimingPoint=void 0;t.TimingPoint=class{time;sampleSet;sampleIndex;volume;effects}},6386:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.TimingPointsData=void 0;const n=i(87816),s=i(3143);t.TimingPointsData=class{TimingPoints=[];GetCurrentTimingPoints(e){let t=[],i=this.TimingPoints.filter((t=>{if(t.time<=e)return t}));if(0==i.length&&i.push(this.TimingPoints[0]),t.push(i[i.length-1]),t[0]instanceof s.InheritedTimingPoint){let i=this.TimingPoints.filter((e=>e instanceof n.UnInheritedTimingPoint)).filter((t=>{if(t.time<=e)return t}));if(0==i.length)throw new Error("Could not find a parent timing point for the un-inherited timing point!");t.push(i[i.length-1])}if(0==t.length)throw new Error("Could not find any timing points!");return t}GetCurrentUninheritedTimingPoint(e){let t,i=this.GetCurrentTimingPoints(e);if(i[0]instanceof n.UnInheritedTimingPoint)t=i[0];else{if(!(i[1]instanceof n.UnInheritedTimingPoint))throw new Error("Could not find any UnInherited Timing Points!");t=i[1]}return t}}},87816:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.UnInheritedTimingPoint=void 0;const n=i(52032);class s extends n.TimingPoint{beatLength;meter}t.UnInheritedTimingPoint=s},9752:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.BeatmapParser=void 0;const n=i(17898),s=i(30444),a=i(81347);class o{static Parse(e,t){const i=new n.BeatmapData;let r=e.split(/\r?\n|\r|\n/g);return a.GeneralParser.ParseGeneral(i,o.GetSection("General",r)),s.TimingPointsParser.ParseTimingPoints(i,o.GetSection("TimingPoints",r)),i}static GetSection(e,t){let i=[];return t.forEach(((n,s)=>{if(n=="["+e+"]")for(let e=s+1;e{let i=t.split(":");"AudioFilename"==i[0]&&(i[1].startsWith(" ")?e.General.AudioFileName=i[1].substring(1,i[1].length):e.General.AudioFileName=i[1]),"AudioFilename"==i[0]&&(i[1].startsWith(" ")?e.General.AudioFileName=i[1].substring(1,i[1].length):e.General.AudioFileName=i[1])}))}}},30444:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.TimingPointsParser=void 0;const n=i(87816),s=i(3143),a=i(22331);t.TimingPointsParser=class{static ParseTimingPoints(e,t){t.forEach((t=>{let i,o=t.split(",");"1"==o[6]?(i=new n.UnInheritedTimingPoint,i.beatLength=Number.parseFloat(o[1]),i.meter=Number.parseInt(o[2])):(i=new s.InheritedTimingPoint,i.sliderVelocityMultiplier=Number.parseFloat(o[1])),i.time=Number.parseInt(o[0]),i.sampleSet=Number.parseInt(o[3]),i.sampleIndex=Number.parseInt(o[4]),i.volume=Number.parseInt(o[5]),"1"==o[7]||"3"==o[7]?i.effects=Number.parseInt(o[7]):i.effects=a.Effect.None,e.TimingPoints.TimingPoints.push(i)}))}}},5825:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.MathUtil=void 0;class i{static RadiansToDegrees(e){return 180*e/Math.PI}static DegreesToRadians(e){return e*Math.PI/180}static clamp(e,t,i){return Math.min(Math.max(i,e),t)}static clamp01(e){return i.clamp(0,1,e)}static Damp(e,t,n,s){return i.Lerp(e,t,1-Math.pow(n,s))}static Lerp(e,t,i){return e+(t-e)*i}}t.MathUtil=i},92915:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.Ease=void 0;const o=a(i(29172));class r{static previousEases=[];easings=[];obj;delay=null;constructor(e,t){this.obj=e,t||r.previousEases.push(this)}static getEase(e,t){null==t&&(t=!1);let i=r.previousEases.filter((t=>t.obj==e));return i.length>0?i[0]:new r(e,t)}createTween(e,t,i,n,s,a){const r={value:0},u=new o.Tween(i?r:e),c=new l(u);return u.to(i?{value:1}:t,s),u.easing(a),u.onUpdate((()=>{this.obj.destroyed||(this.obj[n]=i?r.value*(t.value-e.value)+e.value:e),c.onUpdate()})),u.onStart((()=>{i&&(e.value=this.obj[n])})),null==this.delay?u.start():(this.delay.chain(u),this.delay=null),this.easings.push(c),u.onStop((()=>{this.onDone(u)})),u.onComplete((()=>{this.onDone(u)})),this}TransformTo(e,t,i){return this.createTween(this.obj.position,e,!1,"position",t,i),this}onDone(e){this.easings=this.easings.filter((t=>t.tween!=e))}ScaleTo(e,t,i){let n={x:0,y:0};return"number"==typeof e&&(n.x=e,n.y=e),this.createTween(this.obj.scale,n,!1,"scale",t,i),this}FadeTo(e,t,i){return this.createTween({value:this.obj.alpha},{value:e},!0,"alpha",t,i),this}FadeOut(e,t){return this.FadeTo(0,e,t),this}FadeIn(e,t){return this.FadeTo(1,e,t),this}ClearEasings(){return this.easings.forEach((e=>{e.tween.stop()})),this.easings=[],this}Then(e){let t=this.easings.sort(((e,t)=>e.tween.getDuration()-t.tween.getDuration()));return t.length>0&&(this.delay=t[0].tween,null!=e&&(t[0].tween.onComplete((()=>{this.onDone(t[0].tween),e()})),t[0].tween.onStop((()=>{this.onDone(t[0].tween),e()})))),this}OnEach(e){let t=this.easings.sort(((e,t)=>e.tween.getDuration()-t.tween.getDuration()));t.length>0&&t[0].registerOnUpdate(e)}}t.Ease=r;class l{tween;updateEventListeners=[];constructor(e){this.tween=e}onUpdate(){this.updateEventListeners.forEach((e=>{e()}))}registerOnUpdate(e){this.updateEventListeners.push(e)}unRegisterOnUpdate(e){this.updateEventListeners=this.updateEventListeners.filter((t=>!(e===t)))}}},29820:function(e,t,i){i(11307);const n=i(58687),s=i(20825),a=i(58293),o=i(44256),r=i(59029);a.Settings.registerAll(),a.Settings.load();const l=window.innerWidth,u=window.innerHeight,c=new n.Application;globalThis.__PIXI_APP__=c,window.onload=async()=>{const e=a.Settings.getSetting(o.Renderer).getValue().value;c.init({backgroundColor:"black",width:l,height:u,antialias:!0,preference:e,resolution:window.devicePixelRatio,autoDensity:!0}).then((()=>{new s.Main(c)}))},Object.defineProperty(window,"setSensitivity",{value:e=>{a.Settings.getSetting(r.MouseSensitivity).setValue(e)}}),Object.defineProperty(window,"setRenderer",{value:e=>{let t=a.Settings.getSetting(o.Renderer);t.setValue("webgl"==e?t.webglOption:t.webGpuOption),window.location.reload()}})},20825:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.Main=void 0;const o=a(i(58687)),r=i(76969),l=i(25373),u=i(12235),c=i(55686),d=i(85437),h=a(i(29172)),g=i(29847);class f{static app;static mousePos={x:0,y:0};static pointerLockExitTime;static cursor;static AudioEngine;static currentScreen;static allScreens=[];static clickArea=new o.Graphics;static doPointerLock=!1;static settingsPane;constructor(e){f.app=e,document.body.appendChild(f.app.canvas),f.settingsPane=new g.SettingsPane,f.settingsPane.zIndex=999998,f.app.stage.addChild(f.settingsPane),document.addEventListener("keydown",(e=>{e.ctrlKey&&"KeyO"==e.code&&f.settingsPane.toggle()})),this.doResize(),window.addEventListener("resize",this.doResize),f.app.ticker.add((()=>{h.update()})),f.app.stage.eventMode="static",f.AudioEngine=new d.AudioEngine,f.app.stage.addEventListener("mousemove",(e=>{f.mousePos.x=e.clientX,f.mousePos.y=e.clientY,f.cursor&&f.cursor.updateMouse()})),document.addEventListener("pointerlockchange",this.pointerLockChanged,!1),f.switchScreen(new r.LoadScreen),u.Loader.Load(f.AudioEngine.audioContext).then((()=>{f.cursor=new c.MenuCursor(!1);let e=u.Loader.GetAudio("sample_dialog_ok"),t=u.Loader.Get("introTrianglesTrack");f.switchScreen(new l.InteractScreen(t,e))}))}static lockKeyboard(){navigator.keyboard&&navigator.keyboard.lock([]).then((()=>{console.log("Locked keyboard!"),document.fullscreenElement||console.warn("Keyboard lock won't work unless the user is in fullscreen (as requested by the game, not if the user just presses F11)!")}))}static pointerLock(){try{this.doPointerLock=!0,f.app.canvas.requestPointerLock({unadjustedMovement:!0})}catch(e){console.warn("Failed to lock cursor, error:",e),this.doPointerLock=!1}}static exitPointerLock(){this.doPointerLock=!1,f.app.canvas.exitPointerLock()}static switchScreen(e){null!=this.currentScreen&&(this.currentScreen.zIndex=1,this.currentScreen.onClose().then((e=>{for(let t=0;t{e.onResize()})),f.settingsPane.resize()}pointerLockChanged(){!document.pointerLockElement&&f.doPointerLock?(o.EventSystem.isPointerLocked=!1,f.pointerLockExitTime=Date.now(),f.clickArea=new o.Graphics,f.clickArea.rect(0,0,1,1),f.clickArea.fill("rgba(0,0,0,0.1)"),f.clickArea.width=window.innerWidth,f.clickArea.height=window.innerHeight,f.clickArea.position.set(0,0),f.app.stage.addChild(f.clickArea),f.clickArea.eventMode="static",f.clickArea.cursor="pointer",f.cursor.PopOut(),f.clickArea.zIndex=9999999,f.clickArea.onclick=()=>{Date.now()-f.pointerLockExitTime<1500||(f.clickArea.removeFromParent(),f.clickArea.destroy(),f.pointerLock(),f.cursor.PopIn())}):o.EventSystem.isPointerLocked=!0}}t.Main=f},11307:function(e,t,i){i.r(t)},58689:function(e,t,i){i.r(t),t.default="in vec2 vUV;\nin vec2 vPositionOffset;\nin vec2 vPosition;\nin vec4 vColorTint;\nuniform sampler2D uTexture;\nuniform float time;\n\nvoid main() {\n float a = ((vPositionOffset.y + vPosition.y)/1200.0) - 0.1;\n vec4 color = texture(uTexture, vUV);\n if (a > 1.0) {\n a = 1.0;\n }\n gl_FragColor = (color*vColorTint)*a;\n}"},46404:function(e,t,i){i.r(t),t.default="in vec2 aPosition;\nin vec2 aUV;\nin vec2 aPositionOffset;\nin vec4 aColorTint;\n\nout vec2 vUV;\nout vec2 vPositionOffset;\nout vec2 vPosition;\nout vec4 vColorTint;\n\nuniform mat3 uProjectionMatrix;\nuniform mat3 uWorldTransformMatrix;\nuniform mat3 uTransformMatrix;\n\n\nvoid main() {\n\n mat3 mvp = uProjectionMatrix * uWorldTransformMatrix * uTransformMatrix;\n gl_Position = vec4((mvp * vec3(aPosition + aPositionOffset, 1.0)).xy, 0.0, 1.0);\n vPositionOffset = aPositionOffset;\n vUV = aUV;\n vPosition = aPosition;\n vColorTint = aColorTint;\n}"},61630:function(e,t,i){i.r(t),t.default="struct GlobalUniforms {\n uProjectionMatrix:mat3x3,\n uWorldTransformMatrix:mat3x3,\n uWorldColorAlpha: vec4,\n uResolution: vec2,\n}\n\nstruct LocalUniforms {\n uTransformMatrix:mat3x3,\n uColor:vec4,\n uRound:f32,\n}\n\n\n@group(0) @binding(0) var globalUniforms : GlobalUniforms;\n@group(1) @binding(0) var localUniforms : LocalUniforms;\n\nstruct VertexOutput {\n @builtin(position) position: vec4,\n @location(0) vUV: vec2,\n @location(1) vPositionOffset: vec2,\n @location(2) vPosition: vec2,\n @location(3) vColorTint: vec4\n};\n\n\n@vertex\nfn mainVert(\n @location(0) aPosition : vec2,\n @location(1) aUV : vec2,\n @location(2) aColorTint : vec4,\n @location(3) aPositionOffset : vec2,\n) -> VertexOutput {\n var mvp = globalUniforms.uProjectionMatrix\n * globalUniforms.uWorldTransformMatrix\n * localUniforms.uTransformMatrix;\n\n var output: VertexOutput;\n\n output.position = vec4(mvp * vec3(aPosition+aPositionOffset, 1.0), 1.0);\n output.vUV = aUV;\n output.vPosition = aPosition;\n output.vPositionOffset = aPositionOffset;\n output.vColorTint = aColorTint;\n\n return output;\n};\n\nstruct WaveUniforms {\n time:f32,\n}\n\n@group(2) @binding(1) var uTexture : texture_2d;\n@group(2) @binding(2) var uSampler : sampler;\n@group(2) @binding(3) var waveUniforms : WaveUniforms;\n\n@fragment\nfn mainFrag(\n @location(0) vUV: vec2,\n @location(1) vPositionOffset: vec2,\n @location(2) vPosition: vec2,\n @location(3) vColorTint: vec4\n) -> @location(0) vec4 {\n var a: f32 = ((vPositionOffset.y + vPosition.y)/1200.0) - 0.1;\n let color: vec4 = textureSample(uTexture, uSampler, vUV);\n if (a > 1.0){\n a = 1.0;\n }\n return (color*vColorTint)*a;\n};"},44160:function(e,t,i){i.r(t),t.default="in vec4 vColor;\nin vec2 vUV;\n\nuniform sampler2D uTexture;\nuniform float progress;\n\nvoid main() {\n vec4 color = texture2D(uTexture, vUV);\n float a = vColor.a * color.a;\n vec4 _vColor = vec4(smoothstep(0.88, 1.0, color.a))*vColor;\n vec4 outColor = (color.r < progress) ? vec4(_vColor.rgb * a, a) : vec4(0.0);\n gl_FragColor = outColor;\n}\n"},26045:function(e,t,i){i.r(t),t.default="in vec2 aPosition;\nin vec4 aColor;\nin vec2 aUV;\n\nout vec4 vColor;\nout vec2 vUV;\n\nuniform mat3 uProjectionMatrix;\nuniform mat3 uWorldTransformMatrix;\n\nuniform mat3 uTransformMatrix;\n\n\nvoid main() {\n\n mat3 mvp = uProjectionMatrix * uWorldTransformMatrix * uTransformMatrix;\n gl_Position = vec4((mvp * vec3(aPosition, 1.0)).xy, 0.0, 1.0);\n\n vColor = aColor;\n vUV = aUV;\n}\n"},46110:function(e,t,i){i.r(t),t.default="struct GlobalUniforms {\n uProjectionMatrix:mat3x3,\n uWorldTransformMatrix:mat3x3,\n uWorldColorAlpha: vec4,\n uResolution: vec2,\n}\n\nstruct LocalUniforms {\n uTransformMatrix:mat3x3,\n uColor:vec4,\n uRound:f32,\n}\n\n\n@group(0) @binding(0) var globalUniforms : GlobalUniforms;\n@group(1) @binding(0) var localUniforms : LocalUniforms;\n\nstruct VertexOutput {\n @builtin(position) position: vec4,\n @location(0) vUV: vec2,\n @location(1) vColor: vec4,\n};\n\n\n@vertex\nfn mainVert(@location(0) aPosition : vec2, @location(1) aUV : vec2, @location(2) aColor: vec4\n) -> VertexOutput {\n var mvp = globalUniforms.uProjectionMatrix\n * globalUniforms.uWorldTransformMatrix\n * localUniforms.uTransformMatrix;\n\n var output: VertexOutput;\n\n output.position = vec4(mvp * vec3(aPosition, 1.0), 1.0);\n output.vUV = aUV;\n output.vColor = aColor;\n\n return output;\n};\n\nstruct ProgressUniform {\n progress:f32\n}\n\n@group(2) @binding(1) var uTexture : texture_2d;\n@group(2) @binding(2) var uSampler : sampler;\n@group(2) @binding(3) var uProgress : ProgressUniform;\n\n@fragment\nfn mainFrag(@location(0) vUV: vec2, @location(1) vColor: vec4) -> @location(0) vec4 {\n let color: vec4 = textureSample(uTexture, uSampler, vUV);\n let a: f32 = color.a;\n let _vColor: vec4 = smoothstep(0.88, 1.0, color.a) * vColor;\n var outColor: vec4 = vec4(0.0);\n if (color.r < uProgress.progress) {\n outColor = vec4(_vColor.rgb * a, a);\n }\n return outColor;\n};\n"}},i={};function n(e){var s=i[e];if(void 0!==s)return s.exports;var a=i[e]={id:e,loaded:!1,exports:{}};return t[e].call(a.exports,a,a.exports,n),a.loaded=!0,a.exports}n.m=t,e=[],n.O=function(t,i,s,a){if(!i){var o=1/0;for(c=0;c=a)&&Object.keys(n.O).every((function(e){return n.O[e](i[l])}))?i.splice(l--,1):(r=!1,a0&&e[c-1][2]>a;c--)e[c]=e[c-1];e[c]=[i,s,a]},n.d=function(e,t){for(var i in t)n.o(t,i)&&!n.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},n.hmd=function(e){return(e=Object.create(e)).children||(e.children=[]),Object.defineProperty(e,"exports",{enumerable:!0,set:function(){throw new Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+e.id)}}),e},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},function(){var e={179:0};n.O.j=function(t){return 0===e[t]};var t=function(t,i){var s,a,o=i[0],r=i[1],l=i[2],u=0;if(o.some((function(t){return 0!==e[t]}))){for(s in r)n.o(r,s)&&(n.m[s]=r[s]);if(l)var c=l(n)}for(t&&t(i);u 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar chunkIds = deferred[i][0];\n\t\tvar fn = deferred[i][1];\n\t\tvar priority = deferred[i][2];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","import {BeatmapData} from \"../Util/Beatmap/Data/BeatmapData\";\n\nexport class Audio {\n public audio!: AudioBuffer;\n public timeStarted: number = 0;\n public source?: AudioBufferSourceNode\n public id!: number;\n public isPlaying: boolean = false;\n public isPaused: boolean = false;\n public pausedTime: number = 0;\n public nodes: AudioNode[] = [];\n public tempArrayMain = new Float32Array(256);\n public tempArrayL = new Float32Array(64);\n public tempArrayR = new Float32Array(64);\n public LeftChannel: number = 0;\n public RightChannel: number = 0;\n public FrequencyAmplitudes = new Float32Array(256);\n private _connectedToContext = false;\n\n public GetMaximumAudioLevel() {\n return Math.max(this.LeftChannel, this.RightChannel);\n }\n\n public GetAverageAudioLevel() {\n return (this.LeftChannel + this.RightChannel) / 2;\n }\n\n public Create(audioContext: AudioContext) {\n this.source = audioContext.createBufferSource();\n this.source.buffer = this.audio;\n }\n\n public AddAudioNode(node: AudioNode) {\n if (!this.source) {\n throw new Error(\"Source not created yet!\");\n }\n this.nodes.push(node);\n }\n\n public GetNode(type: new (...args: any[]) => T): T[] | null {\n let nodes = this.nodes.filter(node => node instanceof type) as T[];\n if (nodes.length > 0) {\n return nodes;\n } else {\n return null;\n }\n }\n\n public ConnectToContext(audioContext: AudioContext, howToConnectFunction?: (nodes: AudioNode[], source: AudioBufferSourceNode) => void) {\n if (!this.source) {\n throw new Error(\"Source not created yet!\");\n }\n if (this._connectedToContext) {\n return;\n }\n this._connectedToContext = true;\n if (this.nodes.length > 0) {\n if (howToConnectFunction) {\n howToConnectFunction(this.nodes, this.source);\n } else {\n this.nodes.forEach((node, index) => {\n this.source!.connect(node);\n if (!(node instanceof AnalyserNode)) {\n node.connect(audioContext.destination);\n }\n });\n }\n } else {\n this.source.connect(audioContext.destination);\n }\n }\n\n public Play() {\n if (!this.source) {\n throw new Error(\"Source not created yet!\");\n }\n if (!this._connectedToContext) {\n throw new Error(\"Not connected to audio context yet!\");\n }\n this.source.start(0, this.pausedTime);\n this.isPlaying = true;\n this.isPaused = false;\n this.timeStarted = Date.now() - this.pausedTime;\n this.pausedTime = 0;\n }\n\n public Pause() {\n if (!this.source) {\n throw new Error(\"Source not created yet!\");\n }\n if (!this._connectedToContext) {\n throw new Error(\"Not connected to audio context yet!\");\n }\n this.pausedTime = Date.now() - this.timeStarted;\n this.source.stop(0);\n this.isPaused = true;\n this.isPlaying = false;\n }\n\n public Stop() {\n if (!this.source) {\n throw new Error(\"Source not created yet!\");\n }\n if (!this._connectedToContext) {\n throw new Error(\"Not connected to audio context yet!\");\n }\n this.source.stop(0);\n this.isPlaying = false;\n }\n\n public RegisterEndCallBack(callback: () => void) {\n if (!this.source) {\n throw new Error(\"Source not created yet!\");\n }\n this.source.onended = () => {\n if (!this.isPaused) {\n callback();\n }\n }\n }\n\n}\n\nexport class MapAudio extends Audio {\n public beatmap!: BeatmapData;\n public fadingOut: boolean = false;\n // @ts-ignore\n public fadeOutTimeout!: Timeout\n public playingCallback?: () => void;\n\n}\n","import {PlayingAudios} from \"./PlayingAudios\";\nimport {Audio, MapAudio} from \"./Audio\";\nimport {BeatmapData} from \"../Util/Beatmap/Data/BeatmapData\";\nimport {Main} from \"../main\";\nimport {UnInheritedTimingPoint} from \"../Util/Beatmap/Data/Sections/TimingPoints/UnInheritedTimingPoint\";\nimport {Effect} from \"../Util/Beatmap/Data/Sections/TimingPoints/Effect\";\n\nexport class AudioEngine {\n public readonly audioContext: AudioContext;\n private readonly _playingAudios: PlayingAudios;\n private _musicQueue: MapAudio[] = [];\n private _audioIdTicker: number = 0;\n private _changeCallbacks: (() => void)[] = [];\n private silentMusic = this.createSilentMusic();\n public useSilentMusic = true;\n\n public constructor() {\n this.audioContext = new AudioContext();\n this._playingAudios = new PlayingAudios();\n Main.app.ticker.add(() => {\n this.update();\n });\n }\n\n public UpdateMusicQueue() {\n if (this._musicQueue[0]) {\n if (!this._musicQueue[0].fadingOut && this._musicQueue[0].timeStarted == 0) {\n this._play(this._musicQueue[0]);\n this._changeCallbacks.forEach((cb) => cb());\n }\n if (this._musicQueue[0].fadingOut && this._musicQueue[1]) {\n if (this._musicQueue[1]) {\n this._play(this._musicQueue[1]);\n this._changeCallbacks.forEach((cb) => cb());\n }\n }\n }\n if (!(this._musicQueue.length >= 1)) {\n this.silentMusic = this.createSilentMusic();\n this.useSilentMusic = true;\n }\n else {\n this.useSilentMusic = false;\n\n }\n }\n\n public createSilentMusic() {\n let mapAudio = new MapAudio();\n mapAudio.timeStarted = Date.now();\n mapAudio.beatmap = new BeatmapData();\n let timingPoint = new UnInheritedTimingPoint();\n timingPoint.time = 0;\n timingPoint.beatLength = 1000;\n timingPoint.effects = Effect.None;\n mapAudio.beatmap.TimingPoints.TimingPoints.push(timingPoint);\n return mapAudio;\n }\n\n public addMusicChangeEventListener(cb: () => void) {\n this._changeCallbacks.push(cb);\n }\n\n public removeMusicChangeEventListener(cb: () => void) {\n this._changeCallbacks = this._changeCallbacks.filter(callback => callback != cb);\n }\n\n public GetCurrentPlayingMusic(): MapAudio {\n return this.useSilentMusic ? this.silentMusic : this._musicQueue[0];\n }\n\n public PlayEffect(audio: AudioBuffer, pitch?: number) {\n let audioObj = new Audio();\n audioObj.audio = audio;\n audioObj.id = this._audioIdTicker;\n this._play(audioObj, pitch);\n this._audioIdTicker++;\n }\n\n public AddToMusicQueue(mapAudio: AudioBuffer, beatMapData: BeatmapData, musicPlayingCallback?: () => void) {\n let mapAudioObj = new MapAudio();\n mapAudioObj.audio = mapAudio;\n mapAudioObj.beatmap = beatMapData;\n mapAudioObj.id = this._audioIdTicker;\n if (musicPlayingCallback) {\n mapAudioObj.playingCallback = musicPlayingCallback;\n }\n this._musicQueue.push(mapAudioObj);\n this._audioIdTicker++;\n this.UpdateMusicQueue();\n return mapAudioObj.id;\n }\n\n public PlayMusicImmediately(mapAudio: AudioBuffer, beatMapData: BeatmapData, musicPlayingCallback?: () => void) {\n // clear queue\n this._musicQueue = [];\n this.AddToMusicQueue(mapAudio, beatMapData, musicPlayingCallback);\n }\n\n public update() {\n let currentPlaying = this.GetCurrentPlayingMusic();\n if (!this.useSilentMusic) {\n let analyzerMain = currentPlaying.GetNode(AnalyserNode)![0];\n let analyzerL = currentPlaying.GetNode(AnalyserNode)![1];\n let analyzerR = currentPlaying.GetNode(AnalyserNode)![2];\n\n analyzerMain.getFloatFrequencyData(currentPlaying.tempArrayMain);\n for (let i = 0; i < currentPlaying.FrequencyAmplitudes.length; i++) {\n currentPlaying.tempArrayMain[i] += 140;\n currentPlaying.tempArrayMain[i] /= 340;\n if (i < 3) {\n currentPlaying.tempArrayMain[i] *= (12 * currentPlaying.tempArrayMain[i]);\n } else if (i < 6) {\n currentPlaying.tempArrayMain[i] *= (9 * currentPlaying.tempArrayMain[i]);\n } else if (i < 100) {\n currentPlaying.tempArrayMain[i] *= (6 * currentPlaying.tempArrayMain[i]);\n }\n currentPlaying.tempArrayMain[i] /= 2;\n if (currentPlaying.tempArrayMain[i] == Infinity || currentPlaying.tempArrayMain[i] == -Infinity) {\n currentPlaying.FrequencyAmplitudes[i] = 0;\n }\n else {\n currentPlaying.FrequencyAmplitudes[i] = currentPlaying.tempArrayMain[i];\n }\n }\n\n analyzerL.getFloatTimeDomainData(currentPlaying.tempArrayL);\n analyzerR.getFloatTimeDomainData(currentPlaying.tempArrayR);\n let avgL = 0;\n let avgR = 0;\n currentPlaying.tempArrayL.forEach((value) => {\n avgL += (value + 1)/2;\n });\n currentPlaying.tempArrayR.forEach((value) => {\n avgR += (value + 1)/2;\n });\n avgL /= currentPlaying.tempArrayL.length;\n avgR /= currentPlaying.tempArrayR.length;\n currentPlaying.LeftChannel = avgL;\n currentPlaying.RightChannel = avgR;\n }\n }\n\n private _play(audio: Audio | MapAudio, pitch?: number) {\n audio.Create(this.audioContext);\n // check if audio is type of MapAudio\n if (\"beatmap\" in audio && audio.beatmap) {\n this._playingAudios.audios.forEach((audio) => {\n if (\"beatmap\" in audio && audio.beatmap) {\n clearTimeout(audio.fadeOutTimeout);\n audio.fadingOut = true;\n let gainNodes = audio.GetNode(GainNode);\n if (gainNodes == null) {\n throw new Error(\"Gain Node doesn't exist on Audio Object!\");\n }\n let gain = gainNodes[0];\n gain.gain.linearRampToValueAtTime(0, this.audioContext.currentTime + 0.4)\n setTimeout(() => {\n audio.Stop();\n }, 400);\n }\n });\n let gain = this.audioContext.createGain();\n gain.gain.value = 0;\n let analyzer = this.audioContext.createAnalyser();\n analyzer.fftSize = 512;\n analyzer.smoothingTimeConstant = 0;\n let splitter = this.audioContext.createChannelSplitter(2);\n let analyzerL = this.audioContext.createAnalyser();\n analyzerL.smoothingTimeConstant = 0;\n analyzerL.fftSize = 128;\n let analyzerR = this.audioContext.createAnalyser();\n analyzerR.smoothingTimeConstant = 0;\n analyzerR.fftSize = 128;\n audio.AddAudioNode(gain);\n audio.AddAudioNode(analyzer);\n audio.AddAudioNode(analyzerL);\n audio.AddAudioNode(analyzerR);\n audio.ConnectToContext(this.audioContext, (nodes, source) => {\n source.connect(gain);\n gain.connect(this.audioContext.destination);\n source.connect(analyzer);\n source.connect(splitter);\n splitter.connect(analyzerL, 0);\n splitter.connect(analyzerR, 1);\n });\n audio.Play();\n this._playingAudios.audios.push(audio);\n if (audio.playingCallback) {\n audio.playingCallback();\n }\n gain.gain.linearRampToValueAtTime(1, this.audioContext.currentTime + 0.4);\n audio.fadeOutTimeout = setTimeout(() => {\n gain.gain.linearRampToValueAtTime(0, this.audioContext.currentTime + 0.4);\n }, (audio.audio.duration - 0.4) * 1000);\n } else {\n audio.ConnectToContext(this.audioContext);\n if (pitch) {\n if (audio.source) {\n audio.source.playbackRate.value = pitch;\n }\n }\n audio.Play();\n this._playingAudios.audios.push(audio);\n }\n\n\n audio.RegisterEndCallBack(() => {\n audio.isPlaying = false;\n if (\"beatmap\" in audio && audio.beatmap) {\n if (this._musicQueue[0] == audio) {\n this._musicQueue.splice(0, 1);\n }\n this.UpdateMusicQueue();\n }\n this._playingAudios.audios.forEach((audioInArr, index) => {\n if (audioInArr === audio) {\n this._playingAudios.audios.splice(index, 1);\n return;\n }\n });\n });\n }\n\n}\n","import {Audio, MapAudio} from \"./Audio\";\n\nexport class PlayingAudios {\n public audios: (Audio | MapAudio)[] = [];\n}\n","import {Main} from \"../../main\";\nimport {MapAudio} from \"../../Audio/Audio\";\nimport * as PIXI from \"pixi.js\";\nimport {MathUtil} from \"../../Util/MathUtil\";\nimport {Effect} from \"../../Util/Beatmap/Data/Sections/TimingPoints/Effect\";\nimport {UnInheritedTimingPoint} from \"../../Util/Beatmap/Data/Sections/TimingPoints/UnInheritedTimingPoint\";\n\nexport class LogoVisualizer extends PIXI.Container {\n\n public static readonly size = 900;\n public frequencyAmplitudes: Float32Array = new Float32Array(256);\n protected audio!: MapAudio;\n protected temporalAmplitudes: Float32Array = new Float32Array(256);\n protected graphics: PIXI.Graphics = new PIXI.Graphics();\n // The number of bars to jump each update iteration.\n private readonly index_change = 5;\n // The maximum length of each bar in the visualiser. Will be reduced when kiai is not activated.\n private readonly bar_length = 600;\n // The number of bars in one rotation of the visualiser.\n private bars_per_visualiser = 200;\n // How many times we should stretch around the circumference (overlapping overselves).\n private readonly visualiser_rounds = 5;\n // How much should each bar go down each millisecond (based on a full bar).\n private readonly decay_per_millisecond = 0.0024;\n // Number of milliseconds between each amplitude update.\n private readonly time_between_updates = 50;\n // The minimum amplitude to show a bar.\n private readonly amplitude_dead_zone = 1 / this.bar_length;\n private indexOffset = 0;\n private firstDraw = true;\n\n public start() {\n this.graphics.blendMode = \"add\";\n this.addChild(this.graphics);\n this.graphics.eventMode = \"none\";\n this.eventMode = \"none\";\n setInterval(() => {\n this.updateAmplitudes()\n }, this.time_between_updates);\n\n }\n\n public draw(ticker: PIXI.Ticker) {\n if (this.firstDraw) {\n for (let i = 0; i < this.frequencyAmplitudes.length; i++) {\n this.frequencyAmplitudes[i] = 0;\n }\n }\n this.graphics.clear();\n let decayFactor = ticker.deltaMS * this.decay_per_millisecond;\n for (let i = 0; i < this.bars_per_visualiser; i++) {\n //3% of extra bar length to make it a little faster when bar is almost at it's minimum\n this.frequencyAmplitudes[i] -= decayFactor * (this.frequencyAmplitudes[i] + 0.03);\n if (this.frequencyAmplitudes[i] < 0) {\n this.frequencyAmplitudes[i] = 0;\n }\n }\n\n for (let j = 0; j < this.visualiser_rounds; j++) {\n for (let i = 0; i < this.bars_per_visualiser; i++) {\n if (this.frequencyAmplitudes[i] < this.amplitude_dead_zone) {\n continue;\n }\n\n let rotation = MathUtil.DegreesToRadians(i / this.bars_per_visualiser * 360 + j * 360 / this.visualiser_rounds);\n let rotationCos = Math.cos(rotation);\n let rotationSin = Math.sin(rotation);\n // taking the cos and sin to the 0..1 range\n let barPosition = {\n x: (rotationCos / 2 + 0.5) * LogoVisualizer.size,\n y: (rotationSin / 2 + 0.5) * LogoVisualizer.size\n };\n\n let barSize = {\n x: LogoVisualizer.size * Math.sqrt(2 * (1 - Math.cos(MathUtil.DegreesToRadians(360 / this.bars_per_visualiser)))) / 2,\n y: this.bar_length * this.frequencyAmplitudes[i]\n };\n // The distance between the bottom side of the bar and the top side.\n let amplitudeOffset = {x: rotationCos * barSize.y, y: rotationSin * barSize.y};\n\n this.graphics.moveTo(barPosition.x, barPosition.y);\n this.graphics.lineTo(barPosition.x + amplitudeOffset.x, barPosition.y + amplitudeOffset.y);\n this.graphics.stroke({color: \"rgba(255, 255, 255, 0.2)\", width: 14});\n }\n }\n this.firstDraw = false;\n }\n\n private updateAmplitudes() {\n this.audio = Main.AudioEngine.GetCurrentPlayingMusic();\n for (let i = 0; i < this.audio.FrequencyAmplitudes.length; i++) {\n this.temporalAmplitudes[i] = this.audio.FrequencyAmplitudes[i];\n }\n let timingPoint = this.audio.beatmap.TimingPoints.GetCurrentTimingPoints(Date.now() - this.audio.timeStarted)[0];\n for (let i = 0; i < this.bars_per_visualiser; i++) {\n let targetAmplitude = (this.temporalAmplitudes[(i + this.indexOffset) % this.bars_per_visualiser]) *\n (timingPoint.effects == Effect.KiaiTime ? 1 : 0.5);\n if (targetAmplitude > this.frequencyAmplitudes[i]) {\n this.frequencyAmplitudes[i] = targetAmplitude;\n }\n }\n this.indexOffset = (this.indexOffset + this.index_change) % this.bars_per_visualiser;\n }\n}\n","import {LogoVisualizer} from \"../LogoVisualizer\";\nimport * as PIXI from \"pixi.js\";\n\nexport class MenuLogoVisualizer extends LogoVisualizer {\n\n\n public draw(ticker: PIXI.Ticker) {\n super.draw(ticker);\n\n }\n}\n","import * as PIXI from \"pixi.js\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\nimport {Ease} from \"../../Util/TweenWrapper/Ease\";\n\nexport class LoadAnim extends PIXI.Container {\n private readonly bg: PIXI.Graphics;\n private readonly arc: PIXI.Graphics;\n private readonly arcContainer: PIXI.Container;\n private readonly animInterval: NodeJS.Timeout;\n private readonly container: PIXI.Container;\n private readonly bgContainer: PIXI.Container;\n private bgRotation: number = 0;\n\n public constructor(bgColor: string, arcColor: string) {\n super();\n this.pivot.set(0.5, 0.5);\n this.container = new PIXI.Container();\n this.container.alpha = 0;\n this.rotation = Math.PI * 2.5;\n this.bgContainer = new PIXI.Container();\n this.bg = new PIXI.Graphics();\n this.bg.roundRect(-50, -50, 100, 100, 25);\n this.bg.fill(bgColor);\n this.arcContainer = new PIXI.Container();\n this.arc = new PIXI.Graphics();\n this.arc.arc(0, 0, 27, Math.PI + .26, 2.92 * Math.PI);\n this.arc.stroke({\n width: 8,\n color: arcColor,\n cap: \"round\"\n });\n this.arc.scale.set(-1, 1);\n this.container.scale.set(0.5, 0.5);\n this.bgContainer.addChild(this.bg);\n this.arcContainer.addChild(this.arc);\n this.bgContainer.addChild(this.arcContainer);\n this.container.addChild(this.bgContainer);\n this.addChild(this.container);\n Ease.getEase(this.container).ScaleTo(1, 400, TWEEN.Easing.Quadratic.InOut)\n .FadeIn(400, TWEEN.Easing.Quadratic.InOut)\n this.doAnims();\n\n this.animInterval = setInterval(() => {\n this.doAnims();\n }, 800);\n }\n\n public doAnims() {\n this.bgRotation += 90;\n Ease.getEase(this.bgContainer).createTween({value: this.bgContainer.angle},\n {value: this.bgRotation}, true, \"angle\", 600, TWEEN.Easing.Quadratic.InOut);\n }\n\n public getWidth() {\n return 100 * this.scale.x;\n }\n\n public getHeight() {\n return 100 * this.scale.y;\n }\n\n public draw(deltaTime: PIXI.Ticker) {\n this.arcContainer.angle += (3 * deltaTime.deltaTime);\n }\n\n public destroy(_options?: PIXI.DestroyOptions | boolean) {\n Ease.getEase(this.container).FadeOut(400, TWEEN.Easing.Quadratic.InOut)\n .ScaleTo(0.5, 400, TWEEN.Easing.Quadratic.InOut);\n setTimeout(() => {\n clearInterval(this.animInterval);\n super.destroy(_options);\n }, 400);\n }\n\n}\n","import * as PIXI from \"pixi.js\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\nimport {Ease} from \"../../../../Util/TweenWrapper/Ease\";\n\nexport class Menu extends PIXI.Container {\n\n private menuBG = new PIXI.Graphics();\n private isOpened = false;\n\n public constructor() {\n super();\n this.menuBG.rect(0, -62.5, 1, 125);\n this.menuBG.fill({color: \"rgb(50,50,50)\"});\n this.menuBG.scale.set(1, 0);\n this.menuBG.alpha = 0;\n this.addChild(this.menuBG);\n\n }\n\n public Open() {\n this.isOpened = true;\n Ease.getEase(this.menuBG).ScaleTo(1, 400, TWEEN.Easing.Quintic.Out)\n .FadeIn(400, TWEEN.Easing.Quintic.Out);\n }\n\n public Close() {\n this.isOpened = false;\n Ease.getEase(this.menuBG).ClearEasings().ScaleTo({x: 1, y: 0}, 300, TWEEN.Easing.Sinusoidal.In)\n .FadeOut(300, TWEEN.Easing.Sinusoidal.In);\n }\n\n public isOpen() {\n return this.isOpened;\n }\n\n public onResize() {\n this.position.set(-window.innerWidth, 0);\n this.menuBG.width = window.innerWidth * 2;\n }\n}\n","import * as PIXI from \"pixi.js\";\nimport {Triangles} from \"./Triangles\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\nimport {Ease} from \"../../../Util/TweenWrapper/Ease\";\nimport {Main} from \"../../../main\";\nimport {Loader} from \"../../../Loader\";\nimport {Menu} from \"./Menu/Menu\";\nimport {MenuLogoVisualizer} from \"../../AudioVisualizers/impl/MenuLogoVisualizer\";\nimport {LogoVisualizer} from \"../../AudioVisualizers/LogoVisualizer\";\nimport {Effect} from \"../../../Util/Beatmap/Data/Sections/TimingPoints/Effect\";\nimport {UnInheritedTimingPoint} from \"../../../Util/Beatmap/Data/Sections/TimingPoints/UnInheritedTimingPoint\";\nimport {MathUtil} from \"../../../Util/MathUtil\";\n\nexport class OsuCircle extends PIXI.Container {\n\n private readonly outline: PIXI.Sprite;\n private readonly visualizer: MenuLogoVisualizer = new MenuLogoVisualizer();\n private readonly triangles: Triangles = new Triangles();\n private readonly flash;\n private readonly logoContainer = new PIXI.Container;\n private readonly logoBounceContainer = new PIXI.Container();\n private readonly logoBeatContainer = new PIXI.Container();\n private readonly logoAmplitudeContainer = new PIXI.Container();\n private readonly logoHoverContainer = new PIXI.Container();\n private readonly rippleContainer = new PIXI.Container();\n private readonly ripple;\n private readonly menu: Menu = new Menu();\n private readonly defaultVisualizerAlpha = 0.5;\n private readonly early_activation = 60;\n private timeElapsedSinceLastBeat = 0;\n private timeUntilNextBeat = 0;\n private lastTimeElapasedSinceLastBeat = 0;\n\n private selectSample = Loader.GetAudio(\"mainMenu.osuLogo.select\");\n private backToLogoSample = Loader.GetAudio(\"mainMenu.osuLogo.backToLogo\");\n\n private isMouseDown = false;\n private mouseDownPosition = {x: 0, y: 0};\n\n\n public constructor() {\n super();\n this.visualizer.start();\n\n\n this.outline = PIXI.Sprite.from(\"mainMenu.logoOutline\");\n this.outline.anchor.set(0.5, 0.5);\n //approximation of size in actual osu!lazer\n let scale = 0.6;\n this.visualizer.scale.set(scale);\n this.visualizer.pivot.set(LogoVisualizer.size/2, LogoVisualizer.size/2);\n this.visualizer.alpha = this.defaultVisualizerAlpha;\n\n let mask = new PIXI.Graphics();\n mask.circle(0,0,450);\n mask.fill({color:\"white\"});\n mask.scale = scale;\n\n\n this.flash = PIXI.Sprite.from(\"mainMenu.logoMask\");\n this.flash.anchor.set(0.5, 0.5);\n this.flash.scale = scale;\n this.flash.blendMode = \"add\";\n this.flash.alpha = 0;\n\n this.triangles.flash.anchor.set(0.5, 0.5);\n this.triangles.flash.scale = scale;\n\n this.outline.scale.set(scale);\n this.triangles.scale.set(scale);\n this.triangles.position.set(-(this.outline.width / 2), -(this.outline.height / 2));\n this.triangles.mask = mask;\n\n this.ripple = PIXI.Sprite.from(\"mainMenu.logoMask\");\n this.ripple.anchor.set(0.5, 0.5);\n this.ripple.scale = scale;\n this.ripple.alpha = 0;\n this.ripple.blendMode = \"add\";\n\n this.rippleContainer.addChild(this.ripple);\n this.logoContainer.addChild(this.visualizer);\n this.logoContainer.addChild(this.triangles);\n this.logoContainer.addChild(this.triangles.flash);\n this.logoContainer.addChild(mask);\n this.logoContainer.addChild(this.flash);\n this.logoContainer.addChild(this.outline);\n this.logoContainer.hitArea = new PIXI.Circle(0, 0, 480 * scale);\n this.logoContainer.eventMode = \"static\";\n\n this.logoContainer.onmouseenter = this._onmouseenter;\n this.logoContainer.onmouseleave = this._onmouseleave;\n this.logoContainer.onmousedown = this._onmousedown;\n this.logoContainer.onclick = this._onclick;\n\n this.logoBeatContainer.addChild(this.logoContainer);\n this.logoAmplitudeContainer.addChild(this.logoBeatContainer);\n this.logoBounceContainer.addChild(this.rippleContainer);\n this.logoBounceContainer.addChild(this.logoAmplitudeContainer);\n this.logoHoverContainer.addChild(this.logoBounceContainer);\n this.addChild(this.logoHoverContainer)\n\n // register event listeners\n Main.app.stage.addEventListener(\"mouseup\", (e) => {\n this._onmouseup(e);\n });\n\n }\n\n\n public _onmouseenter = (e: PIXI.FederatedMouseEvent) => {\n Ease.getEase(this.logoHoverContainer).ScaleTo(1.1, 500, TWEEN.Easing.Elastic.Out);\n }\n\n public _onmouseleave = (e: PIXI.FederatedMouseEvent) => {\n Ease.getEase(this.logoHoverContainer).ScaleTo(1, 500, TWEEN.Easing.Elastic.Out);\n }\n\n public _onmousedown = (e: PIXI.FederatedMouseEvent) => {\n this.isMouseDown = true;\n Ease.getEase(this.logoBounceContainer).ClearEasings().ScaleTo(0.9, 1000, TWEEN.Easing.Sinusoidal.Out);\n this.mouseDownPosition = {x: Main.mousePos.x, y: Main.mousePos.y};\n }\n\n public _onclick = (e: PIXI.FederatedMouseEvent) => {\n this.flash.alpha = 0.4;\n Ease.getEase(this.flash).ClearEasings()\n .FadeOut(1500, TWEEN.Easing.Exponential.Out);\n }\n\n public _onmouseup = (e: PIXI.FederatedMouseEvent) => {\n this.isMouseDown = false;\n Ease.getEase(this.logoBounceContainer).ClearEasings().ScaleTo(1, 500, TWEEN.Easing.Elastic.Out)\n .TransformTo({x: 0, y: 0}, 800, TWEEN.Easing.Elastic.Out);\n }\n\n public onResize() {\n this.menu.onResize();\n }\n\n public draw(ticker: PIXI.Ticker) {\n this.visualizer.draw(ticker);\n this.triangles.draw(ticker);\n //this.timeElapsedSinceLastBeat += ticker.deltaMS;\n let audio = Main.AudioEngine.GetCurrentPlayingMusic();\n let timingPoint = audio.beatmap.TimingPoints.GetCurrentUninheritedTimingPoint(Date.now() - audio.timeStarted);\n this.timeUntilNextBeat = (timingPoint.time - (Date.now() - audio.timeStarted)) % timingPoint.beatLength;\n if (this.timeUntilNextBeat <= 0) {\n this.timeUntilNextBeat += timingPoint.beatLength;\n }\n this.timeElapsedSinceLastBeat = timingPoint.beatLength - this.timeUntilNextBeat;\n if (!Main.AudioEngine.useSilentMusic) {\n let maxAmplitude = audio.GetMaximumAudioLevel();\n this.logoAmplitudeContainer.scale.set(MathUtil.Damp(this.logoAmplitudeContainer.scale.x,\n 1 - Math.max(0, maxAmplitude - 0.4) * 0.04, 0.9, ticker.deltaMS))\n this.triangles.Velocity = MathUtil.Damp(this.triangles.Velocity,\n 0.5 * (timingPoint.effects == Effect.KiaiTime ? 4 : 2), 0.995, ticker.deltaMS);\n } else {\n this.logoAmplitudeContainer.scale = 1;\n this.triangles.Velocity = MathUtil.Damp(this.triangles.Velocity, 0.5, 0.9, ticker.deltaMS);\n }\n if (this.lastTimeElapasedSinceLastBeat > this.timeElapsedSinceLastBeat) {\n this.onNewBeat();\n }\n\n this.lastTimeElapasedSinceLastBeat = this.timeElapsedSinceLastBeat;\n\n if (this.isMouseDown) {\n let change = {x: Main.mousePos.x - this.mouseDownPosition.x, y: Main.mousePos.y - this.mouseDownPosition.y};\n let length = Math.sqrt(change.x * change.x + change.y * change.y);\n // Diminish the drag distance as we go further to simulate \"rubber band\" feeling.\n change.x *= length <= 0 ? 0 : Math.pow(length, 0.6) / length;\n change.y *= length <= 0 ? 0 : Math.pow(length, 0.6) / length;\n this.logoBounceContainer.x = change.x;\n this.logoBounceContainer.y = change.y;\n }\n\n\n }\n\n private onNewBeat() {\n let audio = Main.AudioEngine.GetCurrentPlayingMusic();\n let timingPointUninherited = audio.beatmap.TimingPoints.GetCurrentUninheritedTimingPoint(Date.now() - audio.timeStarted);\n let beatLength = timingPointUninherited.beatLength;\n let timingPoint = audio.beatmap.TimingPoints.GetCurrentTimingPoints(Date.now() - audio.timeStarted)[0];\n let maxAmplitude = !Main.AudioEngine.useSilentMusic ? audio.GetMaximumAudioLevel() : 0;\n let amplitudeAdjust = Math.min(1, 0.4 + maxAmplitude);\n Ease.getEase(this.logoBeatContainer).ScaleTo(1 - 0.02 * amplitudeAdjust, this.early_activation, TWEEN.Easing.Linear.None).Then()\n .ScaleTo(1, beatLength * 2, TWEEN.Easing.Quintic.Out);\n this.rippleContainer.scale = 1.02;\n Ease.getEase(this.rippleContainer).ClearEasings().ScaleTo(1.02 * (1 + 0.04 * amplitudeAdjust), beatLength * 2, TWEEN.Easing.Quintic.Out);\n this.ripple.alpha = 0.15 * amplitudeAdjust;\n Ease.getEase(this.ripple).ClearEasings().FadeOut(beatLength, TWEEN.Easing.Quintic.Out);\n\n\n if (timingPoint.effects == Effect.KiaiTime) {\n Ease.getEase(this.triangles.flash).ClearEasings()\n .FadeTo(0.2 * amplitudeAdjust, this.early_activation, TWEEN.Easing.Linear.None).Then()\n .FadeTo(0, beatLength, TWEEN.Easing.Linear.None);\n Ease.getEase(this.visualizer).ClearEasings()\n .FadeTo(this.defaultVisualizerAlpha * 1.8 * amplitudeAdjust, this.early_activation, TWEEN.Easing.Linear.None).Then()\n .FadeTo(this.defaultVisualizerAlpha, beatLength, TWEEN.Easing.Linear.None);\n }\n setTimeout(() => {\n this.triangles.Velocity += amplitudeAdjust * (timingPoint.effects == Effect.KiaiTime ? 6 : 3);\n }, 60)\n\n }\n\n}\n","import * as PIXI from \"pixi.js\";\nimport {Main} from \"../../../main\";\nimport glVertShader from \"./osuCircleTriangles.vert\";\nimport glFragShader from \"./osuCircleTriangles.frag\";\nimport gpuShader from \"./osuCircleTriangles.wgsl\";\n\nexport class Triangles extends PIXI.Container {\n\n public flash: PIXI.Sprite;\n public Velocity: number = 1;\n private readonly bgGradient: PIXI.FillGradient;\n private triangles: Triangle[] = [];\n private graphics: PIXI.Graphics = new PIXI.Graphics();\n private timeSinceLastSpawn = 0;\n private instancePositionBuffer;\n private readonly totalTriangles = 15;\n\n public constructor() {\n super();\n\n let colorStops = [0xff66ab, 0xcc5289];\n this.bgGradient = new PIXI.FillGradient(0, 0, 0, 1024);\n colorStops.forEach((number, index) => {\n const ratio = index / colorStops.length;\n this.bgGradient.addColorStop(ratio, number);\n });\n\n for (let i = 0; i < this.totalTriangles; i++) {\n this.triangles.push({x: this.random(0, 1024), y: this.random(0, 1024), velocity: this.randVelocity()});\n }\n this.timeSinceLastSpawn = Date.now();\n\n this.graphics.rect(0, 0, 1024, 1024);\n this.graphics.fill(this.bgGradient);\n this.addChild(this.graphics);\n\n this.flash = PIXI.Sprite.from(\"mainMenu.logoMask\");\n //this.flash.anchor.set(0.5, 0.5);\n this.flash.alpha = 0;\n this.flash.blendMode = \"add\";\n\n this.instancePositionBuffer = new PIXI.Buffer({\n data: new Float32Array(this.totalTriangles * 2),\n usage: PIXI.BufferUsage.VERTEX | PIXI.BufferUsage.COPY_DST\n });\n const color = new PIXI.Color(\"rgb(182, 52, 111)\");\n const size = 30;\n const geometry = new PIXI.Geometry({\n attributes: {\n aPosition: [\n -10*size,\n -10*size, // x, y\n 10*size,\n -10*size, // x, y\n 10*size,\n 7.5*size, // x, y,\n -10*size,\n 7.5*size, // x, y,\n ],\n aUV: [0, 0, 1, 0, 1, 1, 0, 1],\n aColorTint: [\n color.red, color.green, color.blue, 1,\n color.red, color.green, color.blue, 1,\n color.red, color.green, color.blue, 1,\n color.red, color.green, color.blue, 1\n ],\n aPositionOffset: {\n buffer: this.instancePositionBuffer,\n instance: true\n }\n },\n indexBuffer: [0, 1, 2, 0, 2, 3],\n instanceCount: this.totalTriangles\n });\n const gl = {\n vertex: glVertShader,\n fragment: glFragShader\n };\n\n const gpu = {\n vertex: {\n entryPoint: \"mainVert\",\n source: gpuShader\n },\n fragment: {\n entryPoint: \"mainFrag\",\n source: gpuShader\n }\n };\n\n const triangleGraphic = new PIXI.Graphics();\n triangleGraphic.moveTo(0, 0);\n triangleGraphic.lineTo(-256, 512);\n triangleGraphic.lineTo(256, 512);\n triangleGraphic.lineTo(0, 0);\n triangleGraphic.stroke({color: \"white\", width: 4});\n\n const triangleTexture = Main.app.renderer.generateTexture(triangleGraphic);\n\n const shader = PIXI.Shader.from({\n gl,\n gpu,\n resources: {\n uTexture: triangleTexture.source,\n uSampler: triangleTexture.source.style,\n waveUniforms: {\n time: { value: 1, type: \"f32\" }\n }\n }\n });\n\n const triangleMesh = new PIXI.Mesh({\n geometry,\n shader\n });\n\n this.addChild(triangleMesh);\n\n\n\n }\n\n public destroy(options?: PIXI.DestroyOptions) {\n super.destroy(options);\n }\n\n public draw(ticker: PIXI.Ticker) {\n const data = this.instancePositionBuffer.data;\n let count = 0;\n\n for (let i = 0; i < this.totalTriangles; i++) {\n const triangle = this.triangles[i];\n\n triangle.y -= (ticker.deltaTime * this.Velocity * triangle.velocity);\n\n if (triangle.y + 100 < 0) {\n triangle.y = 1024 + 250;\n }\n\n data[count++] = triangle.x;\n data[count++] = triangle.y;\n }\n\n this.instancePositionBuffer.update();\n }\n\n private random(min: number, max: number) {\n return Math.random() * (max - min) + min;\n }\n\n private randVelocity() {\n let u1 = 1 - this.random(0, 1);\n let u2 = 1 - this.random(0, 1);\n let randStdNormal = (Math.sqrt(-2.0 * Math.log(u1)) * Math.sin(2.0 * Math.PI * u2));\n return Math.max(0.5 + 0.16 * randStdNormal, 0.1);\n }\n}\n\nexport interface Triangle {\n x: number;\n y: number;\n velocity: number;\n}\n","import * as PIXI from \"pixi.js\";\nimport {Main} from \"../../main\";\nimport {Loader} from \"../../Loader\";\nimport {MathUtil} from \"../../Util/MathUtil\";\nimport {Screen} from \"../../Screens/Screen\";\nimport {Ease} from \"../../Util/TweenWrapper/Ease\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\n\nexport class MenuCursor extends PIXI.Container {\n private mouseCursor = PIXI.Sprite.from(\"menu.cursor\");\n private mouseCursorAdditive = PIXI.Sprite.from(\"menu.cursor.additive\");\n private mouseContainer = new PIXI.Container();\n private animContainer = new PIXI.Container();\n private animRotationContainer = new PIXI.Container();\n private dragRotationState: DragRotationState = DragRotationState.NotDragging;\n private lastDragRotationState: DragRotationState = DragRotationState.NotDragging;\n private mouseHideContainer = new PIXI.Container();\n private readonly elastic_const2 = 0.075;\n private readonly elastic_const = 20.943951023931955;\n private readonly elastic_offset_quarter = Math.pow(2, -10) * Math.sin((.25 - this.elastic_const2) * this.elastic_const);\n\n private posMouseDown: { x: number, y: number } = {x: 0, y: 0};\n\n private mouseIsDown = false;\n\n private cursorTapSample = Loader.GetAudio(\"menu.cursor.sample.tap\");\n\n private mouseButtonClicked: number = -9999;\n\n public constructor(visible: boolean) {\n super();\n this.updateMouse();\n this.mouseContainer.scale.set(0.07 * Screen.getScaleBasedOffScreenSize());\n this.mouseCursorAdditive.alpha = 0;\n this.mouseCursorAdditive.blendMode = \"add\";\n this.mouseCursorAdditive.tint = \"0xFF66AA\"\n this.mouseContainer.addChild(this.mouseCursor);\n this.mouseContainer.addChild(this.mouseCursorAdditive);\n this.animContainer.addChild(this.mouseContainer);\n this.animRotationContainer.addChild(this.animContainer);\n this.mouseHideContainer.addChild(this.animRotationContainer);\n this.addChild(this.mouseHideContainer);\n if (!visible) {\n this.mouseHideContainer.scale.set(0.6);\n this.mouseHideContainer.alpha = 0;\n this.animRotationContainer.angle = 0;\n }\n this.zIndex = 999999;\n this.eventMode = \"none\";\n Main.app.stage.addChild(this);\n this.addEventListeners();\n }\n\n public addEventListeners() {\n Main.app.stage.addEventListener(\"mousedown\", (e) => {\n this.mouseButtonClicked = e.button;\n if (this.visible) {\n this.posMouseDown = {x: Main.mousePos.x, y: Main.mousePos.y};\n this.mouseIsDown = true;\n this.dragRotationState = DragRotationState.DragStarted;\n Ease.getEase(this.animContainer).ClearEasings().ScaleTo(0.9, 800, TWEEN.Easing.Quintic.Out);\n Ease.getEase(this.mouseCursorAdditive).ClearEasings().FadeIn(800, TWEEN.Easing.Quintic.Out);\n Main.AudioEngine.PlayEffect(this.cursorTapSample);\n }\n });\n Main.app.stage.addEventListener(\"mouseup\", (e) => {\n if (this.visible && e.button == this.mouseButtonClicked) {\n this.mouseIsDown = false;\n Ease.getEase(this.animContainer).ClearEasings().ScaleTo(1, 500, TWEEN.Easing.Elastic.Out);\n Ease.getEase(this.mouseCursorAdditive).ClearEasings().FadeOut(500, TWEEN.Easing.Quintic.Out);\n if (this.dragRotationState != DragRotationState.NotDragging) {\n if (this.dragRotationState == DragRotationState.Rotating) {\n Ease.getEase(this.animRotationContainer).ClearEasings().createTween({value: this.animRotationContainer.angle},\n {value: 0}, true, \"angle\", 800 * (0.5 + Math.abs(this.animRotationContainer.angle / 960)), (time: number) => {\n return Math.pow(2, -10 * time) * \n Math.sin((.25 * time - this.elastic_const2) * this.elastic_const) + 1 - this.elastic_offset_quarter * time;\n });\n }\n this.dragRotationState = DragRotationState.NotDragging;\n }\n Main.AudioEngine.PlayEffect(this.cursorTapSample, 0.8);\n }\n });\n }\n\n public PopIn() {\n Ease.getEase(this.animRotationContainer).ClearEasings();\n this.visible = true;\n Ease.getEase(this.mouseHideContainer).ClearEasings().FadeIn(250, TWEEN.Easing.Quintic.Out)\n .ScaleTo(1, 400, TWEEN.Easing.Quintic.Out);\n this.dragRotationState = DragRotationState.NotDragging\n }\n\n public PopOut() {\n Ease.getEase(this.mouseHideContainer).ClearEasings().FadeOut(250, TWEEN.Easing.Quintic.Out)\n .ScaleTo(0.6, 250, TWEEN.Easing.Quintic.Out);\n Ease.getEase(this.animRotationContainer).ClearEasings().createTween({value: this.animRotationContainer.angle},\n {value: 0}, true, \"angle\", 400, TWEEN.Easing.Quintic.Out);\n this.dragRotationState = DragRotationState.NotDragging;\n }\n\n public updateMouse() {\n this.mouseContainer.scale.set(0.07 * Screen.getScaleBasedOffScreenSize());\n this.position.set(Main.mousePos.x, Main.mousePos.y);\n if (this.dragRotationState != DragRotationState.NotDragging && this.visible) {\n let distance = Math.sqrt((((Math.abs(this.posMouseDown.x - Main.mousePos.x)) ^ 2) +\n ((Math.abs(this.posMouseDown.y - Main.mousePos.y)) ^ 2)));\n if (this.dragRotationState == DragRotationState.DragStarted && distance > 15) {\n this.dragRotationState = DragRotationState.Rotating;\n if (this.lastDragRotationState != this.dragRotationState) {\n this.posMouseDown = {x: Main.mousePos.x, y: Main.mousePos.y};\n }\n }\n\n if (this.dragRotationState == DragRotationState.Rotating && distance > 0) {\n let offsetX = Main.mousePos.x - this.posMouseDown.x;\n let offsetY = Main.mousePos.y - this.posMouseDown.y;\n let degrees = MathUtil.RadiansToDegrees(Math.atan2(-offsetX, offsetY)) + 24.3;\n\n let diff = (degrees - this.animRotationContainer.angle) % 360;\n if (diff < -180) {\n diff += 360;\n }\n if (diff > 180) {\n diff -= 360;\n }\n degrees = this.animRotationContainer.angle + diff;\n this.animRotationContainer.angle = degrees\n Ease.getEase(this.animRotationContainer).createTween({value: this.animRotationContainer.angle},\n {value: degrees}, true, \"angle\", 120, TWEEN.Easing.Quintic.Out);\n }\n }\n this.lastDragRotationState = this.dragRotationState;\n\n }\n\n\n}\n\nenum DragRotationState {\n NotDragging,\n DragStarted,\n Rotating\n}\n","import * as PIXI from \"pixi.js\";\nimport {Loader} from \"../../Loader\";\nimport {Screen} from \"../../Screens/Screen\";\nimport {Ease} from \"../../Util/TweenWrapper/Ease\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\nimport {Main} from \"../../main\";\n\nexport class RandomBackground extends Screen {\n\n private bgContainer = new PIXI.Container;\n\n private readonly parallaxMultiplier = 60;\n\n public start() {\n this.bgContainer.pivot.set(0.5, 0.5);\n this.bgContainer.position.set((Main.mousePos.x - (this.getScreenWidth() / 2)) / this.parallaxMultiplier,\n (Main.mousePos.y - (this.getScreenHeight() / 2)) / this.parallaxMultiplier);\n this.addChild(this.bgContainer);\n this.newRandomBG();\n Main.AudioEngine.addMusicChangeEventListener(() => {\n this.newRandomBG();\n });\n }\n\n public setBG(sprite: PIXI.Sprite) {\n if (this.bgContainer.children?.length == 0) {\n this.bgContainer.addChild(sprite);\n } else {\n let previous = this.bgContainer.children[0];\n sprite.zIndex = -1;\n this.bgContainer.addChild(sprite);\n Ease.getEase(previous, true).FadeOut(800, TWEEN.Easing.Linear.None).Then(() => {\n sprite.zIndex = 0;\n previous.destroy();\n });\n }\n sprite.anchor.set(0.5, 0.5);\n this.onResize();\n\n }\n\n public newRandomBG() {\n function random(min: number, max: number) {\n return Math.round(Math.random() * (max - min) + min);\n }\n\n let useSeasonalBackgrounds = Loader.seasonalBackgroundsNum > 0;\n let randomNum = random(1, useSeasonalBackgrounds ? Loader.seasonalBackgroundsNum : Loader.defaultBackgroundsNum);\n this.setBG(PIXI.Sprite.from((useSeasonalBackgrounds ? \"seasonal_bg\" : \"default_bg\") + randomNum));\n }\n\n public draw(deltaTime: PIXI.Ticker) {\n this.bgContainer.position.set((Main.mousePos.x - (this.getScreenWidth() / 2)) / this.parallaxMultiplier,\n (Main.mousePos.y - (this.getScreenHeight() / 2)) / this.parallaxMultiplier);\n }\n\n public onClose(): Promise {\n return Promise.resolve(this);\n }\n\n public onResize() {\n this.bgContainer.children.forEach((sprite) => {\n if (sprite instanceof PIXI.Sprite) {\n let texWidth = sprite.texture.width;\n let texHeight = sprite.texture.height;\n\n let scaleFactor: number;\n if (window.innerWidth > window.innerHeight) {\n scaleFactor = window.innerWidth / texWidth;\n } else {\n scaleFactor = window.innerHeight / texHeight;\n }\n\n if (texHeight * scaleFactor < window.innerHeight) {\n scaleFactor = window.innerHeight / texHeight;\n } else if (texWidth * scaleFactor < window.innerWidth) {\n\n }\n\n sprite.scale.set(scaleFactor + 0.05);\n sprite.position.set((this.getScreenWidth() / 2) - (this.getScreenWidth() / (this.parallaxMultiplier * 2)),\n this.getScreenHeight() / 2 - (this.getScreenHeight() / (this.parallaxMultiplier * 2)));\n }\n });\n\n\n }\n\n}\n","import * as PIXI from \"pixi.js\";\nimport {Ease} from \"../../Util/TweenWrapper/Ease\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\nimport {Screen} from \"../../Screens/Screen\";\n\nexport class SettingsPane extends PIXI.Container {\n private bg: PIXI.Graphics = new PIXI.Graphics();\n private isOpen = false;\n\n public constructor() {\n super();\n this.bg.rect(0, 0, 1, 1);\n this.bg.fill({color: \"rgb(20,20,20)\"});\n this.addChild(this.bg);\n this.resize();\n }\n\n public open() {\n Ease.getEase(this).TransformTo({x: 0, y: 0}, 400, TWEEN.Easing.Cubic.Out);\n this.isOpen = true;\n }\n\n public toggle() {\n if (this.isOpen) {this.close()} else {this.open()}\n }\n\n public close() {\n Ease.getEase(this).TransformTo({x: -this.getWidth(), y: 0}, 400, TWEEN.Easing.Cubic.Out);\n this.isOpen = false;\n }\n\n private getWidth() {\n return 500 * Screen.getScaleBasedOffScreenSize();\n }\n\n public resize() {\n this.width = this.getWidth();\n this.height = window.innerHeight;\n this.x = this.isOpen ? 0 : -this.getWidth();\n this.y = 0;\n }\n}","import * as PIXI from \"pixi.js\";\n\nexport class Loader {\n private static loadList: LoaderObject[] = [];\n private static loadedList: LoadedObject[] = [];\n public static readonly defaultBackgroundsNum = 8;\n public static seasonalBackgroundsNum: number = 0;\n\n private static addToLoadList() {\n // intro and interaction screen\n this.loadList.push({id: \"introTrianglesTrack\", url: \"assets/osu-assets/osu.Game.Resources/Tracks/triangles.osz\"});\n this.loadList.push({id: \"sample_dialog_ok\", url: \"assets/osu-assets/osu.Game.Resources/Samples/UI/dialog-ok-select.wav\", isAudio: true});\n this.loadList.push({id: \"TorusRegular\", url: \"assets/fonts/TorusRegular.otf\", pixiBundleName: \"fonts\"});\n this.loadList.push({id: \"TorusLight\", url: \"assets/fonts/TorusLight.otf\", pixiBundleName: \"fonts\"});\n this.loadList.push({id: \"TorusThin\", url: \"assets/fonts/TorusThin.otf\", pixiBundleName: \"fonts\"});\n this.loadList.push({id: \"icon_ruleset_std\", url: \"assets/icons/ruleset-standard.png\", pixiBundleName: \"textures\"});\n this.loadList.push({id: \"icon_ruleset_mania\", url: \"assets/icons/ruleset-mania.png\", pixiBundleName: \"textures\"});\n this.loadList.push({id: \"icon_ruleset_taiko\", url: \"assets/icons/ruleset-taiko.png\", pixiBundleName: \"textures\"});\n this.loadList.push({id: \"icon_ruleset_ctb\", url: \"assets/icons/ruleset-ctb.png\", pixiBundleName: \"textures\"});\n this.loadList.push({id: \"intro_triangles_osuLogo_anim_highlight\",\n url: \"assets/osu-assets/osu.Game.Resources/Textures/Intro/Triangles/logo-highlight.png\", pixiBundleName: \"textures\"});\n this.loadList.push({id: \"intro_triangles_osuLogo_anim_background\",\n url: \"assets/osu-assets/osu.Game.Resources/Textures/Intro/Triangles/logo-background.png\", pixiBundleName: \"textures\"});\n this.loadList.push({id: \"mainMenu.logoOutline\", url: \"assets/osu-assets/osu.Game.Resources/Textures/Menu/logo.png\", pixiBundleName: \"textures\"});\n this.loadList.push({id: \"mainMenu.logoMask\", url: \"assets/menu/logo-mask.png\", pixiBundleName: \"textures\"});\n this.loadList.push({id: \"mainMenu.osuLogo.select\", url: \"assets/osu-assets/osu.Game.Resources/Samples/Menu/osu-logo-select.wav\", isAudio: true});\n this.loadList.push({id: \"mainMenu.osuLogo.backToLogo\", url: \"assets/osu-assets/osu.Game.Resources/Samples/Menu/back-to-logo.wav\", isAudio: true});\n this.loadList.push({id: \"menu.cursor\", url: \"assets/osu-assets/osu.Game.Resources/Textures/Cursor/menu-cursor.png\", pixiBundleName: \"textures\"});\n this.loadList.push({id: \"menu.cursor.additive\", url: \"assets/osu-assets/osu.Game.Resources/Textures/Cursor/menu-cursor-additive.png\",\n pixiBundleName: \"textures\"});\n this.loadList.push({id: \"menu.cursor.sample.tap\", url: \"assets/osu-assets/osu.Game.Resources/Samples/UI/cursor-tap.wav\", isAudio: true});\n this.loadList.push({id: \"menu.kiaiFountains.star\", url: \"assets/osu-assets/osu.Game.Resources/Textures/Menu/fountain-star.png\", pixiBundleName: \"textures\"});\n }\n\n public static Get(id: string): Blob {\n let result;\n this.loadedList.forEach((loadedObj) => {\n if (loadedObj.id == id){\n result = loadedObj.data;\n }\n });\n if (!result){\n throw new Error(\"Asset not found!\");\n }\n return result;\n }\n\n public static GetString(id: string): string {\n let result;\n this.loadedList.forEach((loadedObj) => {\n if (loadedObj.id == id){\n result = loadedObj.dataString;\n }\n });\n if (!result){\n throw new Error(\"Asset not found or is not a string!\");\n }\n return result;\n }\n\n public static GetAudio(id: string): AudioBuffer {\n let result;\n this.loadedList.forEach((loadedObj) => {\n if (loadedObj.id == id){\n result = loadedObj.dataAudio;\n }\n });\n if (!result){\n throw new Error(\"Asset not found or was not marked as audio during loading!\");\n }\n return result;\n }\n\n private static addBackgrounds() {\n return new Promise(resolve => {\n for (let i = 1; i < this.defaultBackgroundsNum + 1; i++) {\n this.loadList.push({id: \"default_bg\"+i, url: \"assets/osu-assets/osu.Game.Resources/Textures/Menu/menu-background-\"+i+\".jpg\", pixiBundleName: \"textures\"});\n }\n fetch(\"https://corsproxy.io/?\"+ encodeURIComponent(\"https://osu.ppy.sh/api/v2/seasonal-backgrounds\"))\n .then(res => res.json()).then(res => {\n res.backgrounds.forEach((background: any, index: number) => {\n this.loadList.push({id: \"seasonal_bg\"+(index+1), url: \"https://corsproxy.io/?\"+ encodeURIComponent(background.url),\n pixiBundleName: \"textures\", loadParser: \"loadTextures\"});\n this.seasonalBackgroundsNum = index+1;\n });\n resolve();\n }).catch(error => {\n console.warn(\"Could not fetch seasonal backgrounds.\", error);\n resolve();\n });\n });\n }\n\n public static Load(audioContext: AudioContext) {\n this.addToLoadList();\n return new Promise((resolve) => {\n this.addBackgrounds().then(() => {\n let nonPixi: LoaderObject[] = [];\n let pixi: LoaderObject[] = [];\n let pixiwithBundles: LoaderObject[][] = [];\n\n let loadedAssets: number = 0;\n let erroredAssets: number = 0;\n\n this.loadList.forEach((loadObj) => {\n if (loadObj.pixiBundleName){\n pixi.push(loadObj);\n }\n else {\n nonPixi.push(loadObj);\n }\n });\n\n pixi.forEach((loadObj) => {\n let added = false;\n pixiwithBundles.forEach((loadObjs) => {\n if (loadObjs.length > 0){\n if (loadObjs[0].pixiBundleName == loadObj.pixiBundleName){\n loadObjs.push(loadObj);\n added = true;\n }\n }\n });\n if (!added){\n pixiwithBundles.push([loadObj]);\n }\n });\n\n const incrementLoadAssetNumber = (errored?: boolean) => {\n if (errored){\n erroredAssets++;\n }\n else {\n loadedAssets++;\n }\n\n if (erroredAssets + loadedAssets >= this.loadList.length){\n resolve();\n }\n }\n\n nonPixi.forEach((loadObj) => {\n fetch(loadObj.url)\n .then(response => response.blob())\n .then((response) => {\n if (!loadObj.isText && !loadObj.isAudio){\n incrementLoadAssetNumber();\n this.loadedList.push({id: loadObj.id, data: response});\n }\n else if (loadObj.isText) {\n response.text().then((text) => {\n incrementLoadAssetNumber();\n this.loadedList.push({id: loadObj.id, data: response, dataString: text});\n });\n }\n else if (loadObj.isAudio){\n response.arrayBuffer().then(arrBuff => audioContext.decodeAudioData(arrBuff))\n .then((audioBuff) => {\n incrementLoadAssetNumber();\n this.loadedList.push({id: loadObj.id, data: response, dataAudio: audioBuff});\n });\n }\n\n })\n .catch((error) => {\n incrementLoadAssetNumber(true);\n console.warn(\"Asset '\"+loadObj.id+\"' failed to load: \"+error);\n });\n });\n\n pixiwithBundles.forEach((bundle) => {\n if (bundle.length > 0){\n if (!bundle[0].pixiBundleName){\n throw new Error(\"wtf????\");\n }\n let assets: PIXI.UnresolvedAsset[] = [];\n bundle.forEach((loadObj) => {\n if (loadObj.loadParser){\n assets.push({alias: loadObj.id, src: loadObj.url, loadParser: loadObj.loadParser});\n }\n else {\n assets.push({alias: loadObj.id, src: loadObj.url});\n }\n\n });\n PIXI.Assets.addBundle(bundle[0].pixiBundleName, assets);\n PIXI.Assets.loadBundle(bundle[0].pixiBundleName).then(() => {\n bundle.forEach(() => {\n incrementLoadAssetNumber();\n });\n });\n }\n\n })\n });\n });\n }\n}\n\ninterface LoaderObject {\n id: string;\n url: string;\n pixiBundleName?: string;\n isText?: boolean;\n isAudio?: boolean;\n loadParser?: PIXI.LoadParserName;\n}\n\ninterface LoadedObject {\n id: string;\n data: Blob;\n dataString?: string;\n dataAudio?: AudioBuffer;\n}\n","import {Screen} from \"../Screen\";\nimport * as PIXI from \"pixi.js\";\nimport {Ticker} from \"pixi.js\";\nimport {Main} from \"../../main\";\nimport {IntroScreen} from \"../IntroScreen/IntroScreen\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\nimport {Ease} from \"../../Util/TweenWrapper/Ease\";\n\nexport class InteractScreen extends Screen {\n\n private readonly text: PIXI.Text;\n private readonly text2: PIXI.Text;\n private readonly textContainer = new PIXI.Container();\n private readonly textContainerContainer = new PIXI.Container();\n\n private readonly introTrack: Blob;\n private clickSound: AudioBuffer;\n\n private readonly clickArea: PIXI.Graphics = new PIXI.Graphics();\n\n public constructor(introTrack: Blob, clickSound: AudioBuffer) {\n super();\n this.introTrack = introTrack;\n this.clickSound = clickSound;\n\n this.text = new PIXI.Text({\n text: \"Click anywhere to play!\",\n style: {\n fontFamily: 'TorusRegular',\n fontSize: 36,\n fill: \"white\"\n }\n });\n this.text2 = new PIXI.Text({\n text: \"(this is for enabling audio because it's required by web-browsers\\n to have interaction on this webpage before playing audio.)\",\n style: {\n fontFamily: 'TorusRegular',\n fontSize: 26,\n fill: \"gray\",\n align: \"center\"\n }\n });\n }\n\n public start() {\n this.text.anchor.set(0.5, 0.5);\n this.text2.anchor.set(0.5, 0.5);\n this.text2.position.set(0, this.text.height + 15);\n this.textContainer.addChild(this.text);\n this.textContainer.addChild(this.text2);\n this.textContainer.scale.set(0.5);\n this.textContainer.alpha = 0;\n this.textContainerContainer.addChild(this.textContainer);\n this.textContainerContainer.scale = Screen.getScaleBasedOffScreenSize();\n this.textContainerContainer.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n this.addChild(this.textContainerContainer);\n\n this.clickArea.rect(0, 0, 1, 1);\n this.clickArea.fill(\"rgba(0,0,0,0)\");\n this.clickArea.width = this.getScreenWidth();\n this.clickArea.height = this.getScreenHeight();\n this.clickArea.position.set(0, 0);\n this.addChild(this.clickArea);\n\n this.clickArea.eventMode = \"static\";\n this.clickArea.cursor = \"pointer\";\n\n const clicked = () => {\n this.clickArea.eventMode = \"none\";\n Main.AudioEngine.PlayEffect(this.clickSound);\n Main.switchScreen(new IntroScreen(this.introTrack));\n document.body.style.cursor = \"none\";\n Main.pointerLock();\n Main.lockKeyboard();\n }\n\n this.clickArea.onclick = () => {\n clicked();\n\n }\n this.clickArea.ontap = () => {\n clicked();\n }\n Ease.getEase(this.textContainer).FadeIn(400, TWEEN.Easing.Quadratic.Out)\n .ScaleTo(1, 400, TWEEN.Easing.Quadratic.Out);\n }\n\n public onClose(): Promise {\n return new Promise((resolve) => {\n Ease.getEase(this.textContainer).FadeOut(200, TWEEN.Easing.Quadratic.Out)\n .ScaleTo(0.5, 200, TWEEN.Easing.Quadratic.InOut);\n setTimeout(() => {\n resolve(this);\n }, 200);\n });\n }\n\n public draw(deltaTime: Ticker) {\n\n }\n\n public onResize() {\n this.textContainerContainer.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n this.clickArea.width = this.getScreenWidth();\n this.clickArea.height = this.getScreenHeight();\n this.clickArea.position.set(0, 0);\n this.textContainerContainer.scale = Screen.getScaleBasedOffScreenSize();\n }\n}\n","import * as PIXI from \"pixi.js\";\nimport {Ease} from \"../../Util/TweenWrapper/Ease\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\n\nexport class GlitchingTriangles extends PIXI.Container {\n public constructor(bounds: GlitchingTrianglesBounds) {\n super();\n let triangle = new PIXI.Graphics();\n let scale = random(0.2, 1.2);\n triangle.moveTo(0, 0);\n triangle.lineTo(-50 * scale, 100 * scale);\n triangle.lineTo(50 * scale, 100 * scale);\n triangle.lineTo(0, 0);\n if (Math.random() < 0.5) {\n triangle.fill(\"white\");\n } else {\n triangle.stroke({color: \"white\", width: 1});\n }\n\n //triangle.anchor.set(0.5, 0.5)\n function random(min: number, max: number) {\n return Math.random() * (max - min) + min;\n }\n\n let randX = random(bounds.x1, bounds.x2);\n let randY = random(bounds.y1, bounds.y2);\n\n triangle.position.set(randX, randY);\n\n Ease.getEase(triangle, true).FadeOut(200, TWEEN.Easing.Linear.None);\n setTimeout(() => {\n this.destroy();\n }, 200);\n\n this.addChild(triangle);\n }\n\n}\n\nexport interface GlitchingTrianglesBounds {\n x1: number;\n x2: number;\n y1: number;\n y2: number;\n}\n","import {Screen} from \"../Screen\";\nimport * as PIXI from \"pixi.js\";\nimport {Ticker} from \"pixi.js\";\nimport {unzip} from 'unzipit';\nimport {Main} from \"../../main\";\nimport {GlitchingTriangles} from \"./GlitchingTriangles\";\nimport {MainMenu} from \"../MainMenu/MainMenu\";\nimport {LazerLogo} from \"./LazerLogo\";\nimport {BeatmapParser} from \"../../Util/Beatmap/Parser/BeatmapParser\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\nimport {Ease} from \"../../Util/TweenWrapper/Ease\";\n\nexport class IntroScreen extends Screen {\n\n private readonly introTrackUrl: string;\n\n private doTextSpacingAnim = false;\n private triangles = new PIXI.Container();\n private ruleSetContainer = new PIXI.Container();\n private flash = new PIXI.Graphics();\n\n private logoContainerContainer = new PIXI.Container();\n\n private logoContainer = new PIXI.Container();\n\n private lazerLogo = new LazerLogo();\n\n private flashed = false;\n\n private standard = PIXI.Sprite.from('icon_ruleset_std');\n private taiko = PIXI.Sprite.from('icon_ruleset_taiko');\n private ctb = PIXI.Sprite.from('icon_ruleset_ctb');\n private mania = PIXI.Sprite.from('icon_ruleset_mania');\n\n private bg: PIXI.Graphics = new PIXI.Graphics();\n\n private completionPromise!: Promise;\n\n private welcomeText: PIXI.Text = new PIXI.Text({\n text: \"\",\n style: {\n fontFamily: \"TorusThin\",\n fontSize: 42,\n fill: \"white\",\n letterSpacing: 5\n }\n });\n\n public constructor(introTrack: Blob) {\n super();\n this.introTrackUrl = URL.createObjectURL(introTrack);\n this.bg.rect(0, 0, 1, 1,);\n this.bg.fill(\"black\");\n }\n\n public start() {\n this.bg.width = window.innerWidth;\n this.bg.height = window.innerHeight;\n this.bg.x = 0;\n this.bg.y = 0;\n this.addChild(this.bg);\n this.lazerLogo.scale.set(Screen.getScaleBasedOffScreenSize());\n this.logoContainer.addChild(this.lazerLogo);\n this.logoContainer.scale.set(1.2);\n\n this.logoContainerContainer.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n this.logoContainerContainer.pivot.set(0.5, 0.5);\n this.logoContainerContainer.addChild(this.logoContainer);\n this.logoContainerContainer.alpha = 0;\n this.addChild(this.logoContainerContainer);\n\n this.flash.rect(0, 0, 1, 1);\n this.flash.fill(\"white\");\n this.flash.position.set(0, 0);\n this.flash.width = this.getScreenWidth();\n this.flash.height = this.getScreenHeight();\n this.flash.blendMode = \"add\";\n this.welcomeText.anchor.set(0.5, 0.5);\n this.welcomeText.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n setTimeout(async () => {\n const {entries} = await unzip(this.introTrackUrl);\n for (const [name, entry] of Object.entries(entries)) {\n if (name.endsWith(\".osu\")) {\n entry.text().then((osuFile) => {\n let beatmapData = BeatmapParser.Parse(osuFile);\n console.log(beatmapData);\n for (const [name, entry] of Object.entries(entries)) {\n if (name == beatmapData.General.AudioFileName) {\n entry.arrayBuffer().then(arrBuff => Main.AudioEngine.audioContext.decodeAudioData(arrBuff))\n .then((audioBuff) => {\n Main.AudioEngine.PlayMusicImmediately(audioBuff, beatmapData, () => {\n this.afterAudioPlay();\n });\n });\n }\n }\n\n });\n\n\n break;\n }\n }\n }, 0);\n }\n\n public afterAudioPlay() {\n this.completionPromise = new Promise((resolve) => {\n this.welcomeText.scale.set(Screen.getScaleBasedOffScreenSize());\n this.addChild(this.welcomeText);\n setTimeout(() => {\n this.welcomeText.text = \"wel\";\n this.onResize();\n }, 200);\n setTimeout(() => {\n this.welcomeText.text = \"welcome\";\n this.onResize();\n }, 400);\n setTimeout(() => {\n this.welcomeText.text = \"welcome to\";\n this.onResize();\n }, 700);\n let glitchingInterval: NodeJS.Timeout;\n\n this.triangles.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n this.triangles.scale.set(Screen.getScaleBasedOffScreenSize());\n this.addChild(this.triangles);\n setTimeout(() => {\n this.welcomeText.text = \"welcome to kosu!\";\n this.doTextSpacingAnim = true;\n glitchingInterval = setInterval(() => {\n let triangle = new GlitchingTriangles({\n x1: -(this.welcomeText.width / 2) - 100,\n x2: (this.welcomeText.width / 2) + 100,\n y1: -(this.welcomeText.height / 2) - 150,\n y2: (this.welcomeText.height / 2) + 100\n });\n this.triangles.addChild(triangle);\n }, 30);\n this.onResize();\n }, 900);\n\n\n this.standard.anchor.set(0.5, 0.5);\n this.standard.scale.set(0.4 * Screen.getScaleBasedOffScreenSize());\n this.ruleSetContainer.addChild(this.standard);\n this.taiko.anchor.set(0.5, 0.5);\n this.taiko.scale.set(0.4 * Screen.getScaleBasedOffScreenSize());\n this.ruleSetContainer.addChild(this.taiko);\n this.ctb.anchor.set(0.5, 0.5);\n this.ctb.scale.set(0.4 * Screen.getScaleBasedOffScreenSize());\n this.ruleSetContainer.addChild(this.ctb);\n this.mania.anchor.set(0.5, 0.5);\n this.mania.scale.set(0.4 * Screen.getScaleBasedOffScreenSize());\n this.ruleSetContainer.addChild(this.mania);\n\n setTimeout(() => {\n this.doTextSpacingAnim = false;\n this.onResize();\n clearInterval(glitchingInterval);\n this.welcomeText.destroy();\n this.triangles.destroy();\n this.ruleSetContainer.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n\n this.addChild(this.ruleSetContainer);\n\n let spacing = 100;\n this.standard.position.set(-((spacing * 2) + 175) * Screen.getScaleBasedOffScreenSize(), 0);\n this.taiko.position.set(-((spacing) + 25) * Screen.getScaleBasedOffScreenSize(), 0);\n this.ctb.position.set(((spacing) + 25) * Screen.getScaleBasedOffScreenSize(), 0);\n this.mania.position.set(((spacing * 2) + 175) * Screen.getScaleBasedOffScreenSize(), 0);\n Ease.getEase(this.ruleSetContainer).ScaleTo(0.8, 1000, TWEEN.Easing.Linear.None);\n }, 1450);\n\n setTimeout(() => {\n let spacing = 15;\n this.standard.position.set(-((spacing * 2) + 210) * Screen.getScaleBasedOffScreenSize(), 0);\n this.taiko.position.set(-((spacing) + 60) * Screen.getScaleBasedOffScreenSize(), 0);\n this.ctb.position.set(((spacing) + 60) * Screen.getScaleBasedOffScreenSize(), 0);\n this.mania.position.set(((spacing * 2) + 210) * Screen.getScaleBasedOffScreenSize(), 0);\n\n this.standard.scale.set(Screen.getScaleBasedOffScreenSize());\n this.taiko.scale.set(Screen.getScaleBasedOffScreenSize());\n this.ctb.scale.set(Screen.getScaleBasedOffScreenSize());\n this.mania.scale.set(Screen.getScaleBasedOffScreenSize());\n }, 1650);\n\n setTimeout(() => {\n let spacing = 60;\n this.standard.position.set(-((spacing * 2) + 230) * Screen.getScaleBasedOffScreenSize(), 0);\n this.taiko.position.set(-((spacing) + 60) * Screen.getScaleBasedOffScreenSize(), 0);\n this.ctb.position.set(((spacing) + 60) * Screen.getScaleBasedOffScreenSize(), 0);\n this.mania.position.set(((spacing * 2) + 230) * Screen.getScaleBasedOffScreenSize(), 0);\n\n this.standard.scale.set(2 * Screen.getScaleBasedOffScreenSize());\n this.taiko.scale.set(2 * Screen.getScaleBasedOffScreenSize());\n this.ctb.scale.set(2 * Screen.getScaleBasedOffScreenSize());\n this.mania.scale.set(2 * Screen.getScaleBasedOffScreenSize());\n Ease.getEase(this.ruleSetContainer).ScaleTo(1.3, 1000, TWEEN.Easing.Linear.None);\n }, 1850);\n\n setTimeout(() => {\n this.ruleSetContainer.destroy();\n this.lazerLogo.start();\n\n this.logoContainerContainer.alpha = 1;\n\n this.logoContainerContainer.scale.set(1.2);\n Ease.getEase(this.logoContainerContainer).ScaleTo(1.2 - 0.8 * 0.25, 920, TWEEN.Easing.Quadratic.In);\n\n setTimeout(() => {\n Ease.getEase(this.logoContainer).ScaleTo(1.2 - 0.8, 920 * 0.3, TWEEN.Easing.Quintic.In);\n }, 920 * 0.7);\n }, 2080);\n\n setTimeout(() => {\n this.addChild(this.flash);\n this.bg.destroy();\n this.flash.eventMode = \"none\";\n this.flashed = true;\n this.logoContainerContainer.visible = false;\n Ease.getEase(this.flash).FadeOut(1000, TWEEN.Easing.Quadratic.Out).Then(() => {resolve();});\n Main.cursor.PopIn();\n }, 3000);\n });\n Main.switchScreen(new MainMenu());\n }\n\n public draw(deltaTime: Ticker) {\n if (this.doTextSpacingAnim) {\n this.welcomeText.style.letterSpacing += 0.15 * deltaTime.deltaTime;\n this.onResize();\n }\n }\n\n public onClose(): Promise {\n return new Promise((resolve) => {\n this.completionPromise.then(()=> {\n resolve(this);\n })\n });\n }\n\n public onResize() {\n if (!this.bg.destroyed){\n this.bg.width = window.innerWidth;\n this.bg.height = window.innerHeight;\n this.bg.x = 0;\n this.bg.y = 0;\n }\n if (!this.welcomeText.destroyed) {\n this.welcomeText.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n }\n if (!this.triangles.destroyed) {\n this.triangles.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n this.triangles.scale.set(Screen.getScaleBasedOffScreenSize());\n }\n if (!this.ruleSetContainer.destroyed) {\n this.ruleSetContainer.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n }\n if (!this.flash.destroyed && this.flashed) {\n this.flash.position.set(0, 0);\n this.flash.width = this.getScreenWidth();\n this.flash.height = this.getScreenHeight();\n }\n if (!this.logoContainerContainer.destroyed) {\n this.logoContainerContainer.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n }\n if (!this.lazerLogo.destroyed) {\n this.lazerLogo.scale.set(Screen.getScaleBasedOffScreenSize());\n }\n if (!this.welcomeText.destroyed) {\n this.welcomeText.scale.set(Screen.getScaleBasedOffScreenSize());\n }\n if (!this.standard.destroyed) {\n this.standard.scale.set(0.4 * Screen.getScaleBasedOffScreenSize());\n }\n if (!this.mania.destroyed) {\n this.mania.scale.set(0.4 * Screen.getScaleBasedOffScreenSize());\n }\n if (!this.ctb.destroyed) {\n this.ctb.scale.set(0.4 * Screen.getScaleBasedOffScreenSize());\n }\n if (!this.taiko.destroyed) {\n this.taiko.scale.set(0.4 * Screen.getScaleBasedOffScreenSize());\n }\n }\n}\n","import * as PIXI from \"pixi.js\";\nimport {LogoAnimation} from \"./LogoAnimation\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\nimport {Ease} from \"../../Util/TweenWrapper/Ease\";\n\nexport class LazerLogo extends PIXI.Container {\n private readonly highlight: LogoAnimation;\n private readonly background: LogoAnimation;\n private textureHighlight = PIXI.Texture.from(\"intro_triangles_osuLogo_anim_highlight\");\n private textureBackground = PIXI.Texture.from(\"intro_triangles_osuLogo_anim_background\");\n\n public constructor() {\n super();\n this.highlight = new LogoAnimation(this.textureHighlight, new PIXI.Color(\"white\"));\n this.background = new LogoAnimation(this.textureBackground, new PIXI.Color(\"rgb(128, 128, 128)\"));\n this.addChild(this.highlight);\n this.addChild(this.background);\n }\n\n public start() {\n let dummy = new PIXI.Container();\n dummy.scale.set(0.0, 0.0);\n Ease.getEase(dummy).ScaleTo(1, 920, TWEEN.Easing.Linear.None).OnEach(() => {\n this.highlight.setProgress(dummy.scale.x);\n this.background.setProgress(dummy.scale.x);\n });\n }\n}\n","import * as PIXI from \"pixi.js\"\nimport glVertShader from \"./logoAnimation.vert\";\nimport glFragShader from \"./logoAnimation.frag\";\nimport gpuShader from \"./logoAnimation.wgsl\";\n\nexport class LogoAnimation extends PIXI.Container {\n private shader: PIXI.Shader;\n private texture: PIXI.Texture;\n\n public constructor(texture: PIXI.Texture, color: PIXI.Color) {\n super();\n this.texture = texture\n this.shader = PIXI.Shader.from({\n gl: {\n vertex: glVertShader,\n fragment: glFragShader,\n },\n gpu: {\n vertex: {\n entryPoint: 'mainVert',\n source: gpuShader\n },\n fragment: {\n entryPoint: 'mainFrag',\n source: gpuShader\n }\n },\n resources: {\n uTexture: this.texture.source,\n uSampler: this.texture.source.style,\n uProgress: {\n progress: {value: 0.0, type: 'f32'},\n },\n },\n });\n const quadGeometry = new PIXI.Geometry({\n attributes: {\n aPosition: [\n -this.texture.width / 2,\n -this.texture.height / 2, // x, y\n this.texture.width / 2,\n -this.texture.height / 2, // x, y\n this.texture.width / 2,\n this.texture.width / 2, // x, y,\n -this.texture.width / 2,\n this.texture.width / 2, // x, y,\n ],\n aUV: [0, 0, 1, 0, 1, 1, 0, 1],\n aColor: [\n color.red, color.green, color.blue, color.alpha,\n color.red, color.green, color.blue, color.alpha,\n color.red, color.green, color.blue, color.alpha,\n color.red, color.green, color.blue, color.alpha\n ]\n },\n indexBuffer: [0, 1, 2, 0, 2, 3],\n });\n const quad = new PIXI.Mesh({\n geometry: quadGeometry,\n shader: this.shader,\n });\n this.addChild(quad);\n }\n\n public setProgress(progress: number) {\n this.shader.resources.uProgress.uniforms.progress = progress;\n }\n}\n","import {Screen} from \"../Screen\";\nimport {LoadAnim} from \"../../Elements/LoadAnim/LoadAnim\";\nimport * as PIXI from \"pixi.js\";\n\nexport class LoadScreen extends Screen {\n\n private loadAnim = new LoadAnim(\"rgba(255,255,255,0.7)\", \"black\");\n\n public start() {\n this.loadAnim.scale.set(0.8 * Screen.getScaleBasedOffScreenSize());\n this.loadAnim.position.set(this.getScreenWidth() - this.loadAnim.getWidth() - 15, this.getScreenHeight() - this.loadAnim.getHeight() - 15);\n this.addChild(this.loadAnim);\n }\n\n public draw(deltaTime: PIXI.Ticker) {\n this.loadAnim?.draw(deltaTime);\n }\n\n public onClose(): Promise {\n return new Promise((resolve) => {\n if (this.loadAnim != null) {\n this.loadAnim.destroy();\n }\n setTimeout(() => {\n resolve(this);\n }, 400);\n });\n }\n\n public onResize() {\n this.loadAnim.position.set(this.getScreenWidth() - this.loadAnim.getWidth() - 20, this.getScreenHeight() - this.loadAnim.getHeight() - 20);\n this.loadAnim.scale.set(0.8 * Screen.getScaleBasedOffScreenSize());\n }\n}\n","import {Screen} from \"../Screen\";\nimport * as PIXI from \"pixi.js\";\nimport {RandomBackground} from \"../../Elements/RandomBackground/RandomBackground\";\nimport {OsuCircle} from \"../../Elements/MainMenu/OsuCircle/OsuCircle\";\n\nexport class MainMenu extends Screen {\n private bg = new RandomBackground();\n private osuCircle = new OsuCircle();\n\n public start() {\n this.bg.start();\n this.addChild(this.bg);\n this.osuCircle.scale = Screen.getScaleBasedOffScreenSize();\n this.addChild(this.osuCircle);\n }\n\n public draw(deltaTime: PIXI.Ticker) {\n this.bg.draw(deltaTime);\n this.osuCircle.draw(deltaTime);\n }\n\n public onClose(): Promise {\n return new Promise((resolve) => {\n this.bg.onClose().then(() => {\n resolve(this);\n });\n })\n }\n\n public onResize() {\n this.osuCircle.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n this.bg.onResize();\n this.osuCircle.onResize();\n this.osuCircle.scale = Screen.getScaleBasedOffScreenSize();\n }\n}\n","import * as PIXI from \"pixi.js\";\nimport {Settings} from \"../Settings/Settings\";\nimport {UIScale} from \"../Settings/impl/Graphics/UIScale\";\n\nexport abstract class Screen extends PIXI.Container {\n\n public constructor() {\n super();\n }\n\n public static getScaleBasedOffScreenSize() {\n // this was made with 1080p screens in mind.\n const uiScale = Settings.getSetting(UIScale).getValue();\n return ((((window.innerWidth / 1920) + (window.innerHeight / 1080)) / 2)) * uiScale\n }\n\n /**\n * Called once before the first frame is drawn\n */\n public abstract start(): void;\n\n\n /**\n * Called every frame\n */\n public abstract draw(deltaTime: PIXI.Ticker): void;\n\n /**\n * Called when screen will be closed, but has to return a promise to clean up after, for example, the screen's close animations are done.\n * Make sure you also pass in `this` into the promise's resolve.\n */\n public abstract onClose(): Promise;\n\n public abstract onResize(): void;\n\n protected getScreenWidth(): number {\n return window.innerWidth;\n }\n\n protected getScreenHeight(): number {\n return window.innerHeight;\n }\n}\n","import {Settings} from \"./Settings\";\n\nexport abstract class Setting {\n public readonly info: Settings;\n\n public constructor(SettingData: SettingInfo) {\n this.info = SettingData;\n Settings.register({setting: this, info: SettingData});\n }\n\n public abstract getValue(): any;\n\n public abstract getDefaultValue(): any;\n\n public abstract setValue(value: any): void;\n\n protected onValueChanged(): void {}\n\n /** When implementing this method, do **NOT** save the settings. This is so that loading won't reset most settings. */\n public abstract loadFromSaveValue(value: any): void;\n}\n\nexport interface SettingInfo {\n name: string;\n category: SettingsCategory;\n}\n\nexport enum SettingsCategory {\n General = \"General\",\n Skin = \"Skin\",\n Input = \"Input\",\n UserInterface = \"User Interface\",\n Gameplay = \"Gameplay\",\n Rulesets = \"Rulesets\",\n Audio = \"Audio\",\n Graphics = \"Graphics\",\n Online = \"Online\",\n Maintenance = \"Maintenance\",\n Debug = \"Debug\"\n}\n","import {Setting} from \"../Setting\";\nimport {Settings} from \"../Settings\";\n\nexport abstract class DropdownSetting extends Setting {\n public abstract readonly list: DropDownOption[];\n public abstract readonly defaultValue: DropDownOption;\n protected value: DropDownOption | undefined;\n\n public getValue(): DropDownOption {\n if (!this.value)\n throw new Error(\"Value is undefined!\");\n return this.value;\n }\n\n public getDefaultValue(): DropDownOption {\n return this.defaultValue;\n }\n\n public setValue(value: DropDownOption) {\n if (this.list.find((option) => option.value == value.value && option.displayName == value.displayName )) {\n this.value = value;\n Settings.save();\n this.onValueChanged();\n } else {\n console.warn('The value provided to this DropDownSetting does not exist in the option list! Ignoring value provided.');\n }\n }\n\n public loadFromSaveValue(value: DropDownOption) {\n if (this.list.find((option) => option.value == value.value && option.displayName == value.displayName)) {\n this.value = value;\n this.onValueChanged();\n } else {\n console.warn('The value provided to this DropDownSetting does not exist in the option list! Ignoring value provided.');\n }\n }\n}\n\nexport interface DropDownOption {\n displayName: string;\n value: string;\n}\n","import {Setting} from \"../Setting\";\nimport {Settings} from \"../Settings\";\nimport {MathUtil} from \"../../Util/MathUtil\";\n\nexport abstract class RangeSetting extends Setting {\n public abstract readonly minValue: number;\n public abstract readonly maxValue: number;\n public abstract readonly increment: number;\n public abstract readonly defaultValue: number;\n protected value: number = 0;\n\n public getValue(): number {\n return this.value;\n }\n\n public getDefaultValue(): number {\n return this.defaultValue;\n }\n\n public setValue(value: number) {\n this.value = MathUtil.clamp(this.minValue, this.maxValue, value);\n Settings.save();\n this.onValueChanged();\n }\n\n public loadFromSaveValue(value: number) {\n this.value = MathUtil.clamp(this.minValue, this.maxValue, value);\n this.onValueChanged();\n }\n}\n","import {Setting, SettingInfo} from \"./Setting\";\nimport {UIScale} from \"./impl/Graphics/UIScale\";\nimport {Renderer} from \"./impl/Graphics/Renderer\";\nimport {MouseSensitivity} from \"./impl/Input/MouseSensitivity\";\n\nexport class Settings {\n private static settingsList: SettingData[] = [];\n\n public static registerAll() {\n new UIScale();\n new Renderer();\n new MouseSensitivity();\n }\n\n public static load() {\n let settingSaveDataString = window.localStorage.getItem(\"settings\");\n if (settingSaveDataString == null) {\n return;\n }\n let settings = this.getList();\n try {\n let settingSaveData: SettingSaveData[] = JSON.parse(settingSaveDataString) as SettingSaveData[];\n settingSaveData.forEach((setting) => {\n let corrupt = false;\n try {\n if (!setting.value) {\n console.warn(\"Setting '\" + JSON.stringify(setting) + \"' may be corrupted, skipping!\");\n corrupt = true;\n }\n if (setting.info) {\n if (!setting.info.name) {\n console.warn(\"Setting '\" + JSON.stringify(setting) + \"' may be corrupted, skipping!\");\n corrupt = true;\n }\n if (!setting.info.category) {\n console.warn(\"Setting '\" + JSON.stringify(setting) + \"' may be corrupted, skipping!\");\n corrupt = true;\n }\n }\n else {\n console.warn(\"Setting '\" + JSON.stringify(setting) + \"' may be corrupted, skipping!\");\n corrupt = true;\n }\n }\n catch (e) {\n console.warn(\"Something went wrong when validating saved settings!\", e);\n console.warn(\"The setting may be REALLY corrupted, skipping!\");\n corrupt = true;\n }\n if (!corrupt) {\n let settingObj = settings.filter((_settingObj) => (_settingObj.info.name == setting.info.name) &&\n _settingObj.info.category == setting.info.category)[0];\n if (settingObj) {\n settingObj.setting.loadFromSaveValue(setting.value);\n } else {\n console.warn(\"Could not find setting object '\" + setting.info.name + \"', maybe it has been removed in this version of kosu?, skipping setting\")\n }\n }\n });\n }\n catch (e) {\n console.warn(\"Failed to load settings! Resetting Settings due to corrupted save!\", e);\n this.reset();\n }\n }\n\n public static save() {\n let settings = this.getList();\n let settingSaveData: SettingSaveData[] = [];\n settings.forEach((setting: SettingData) => {\n // only save if setting is different from default value\n if (setting.setting.getValue() != setting.setting.getDefaultValue()) {\n settingSaveData.push({info: setting.info, value: setting.setting.getValue()});\n }\n });\n window.localStorage.setItem(\"settings\", JSON.stringify(settingSaveData));\n }\n\n public static reset() {\n console.warn(\"Resetting Settings!\");\n window.localStorage.removeItem(\"settings\");\n }\n\n public static register(setting: SettingData) {\n this.settingsList.push(setting);\n }\n\n public static getSetting(setting: new (...args: any[]) => T): T {\n return this.settingsList.filter((_setting) => {\n return _setting.setting instanceof setting\n })[0].setting as T;\n }\n\n public static getSettingData(setting: new (...args: any[]) => T): SettingData {\n return this.settingsList.filter((_setting) => {\n return _setting.setting instanceof setting\n })[0];\n }\n\n public static getList() {\n return this.settingsList;\n }\n}\n\nexport interface SettingData {\n readonly setting: Setting;\n readonly info: SettingInfo;\n}\n\nexport interface SettingSaveData {\n readonly info: SettingInfo;\n readonly value: any;\n}\n","import {SettingsCategory} from \"../../Setting\";\nimport {DropDownOption, DropdownSetting} from \"../../SettingType/DropdownSetting\";\n\nexport class Renderer extends DropdownSetting {\n public readonly list: DropDownOption[] = [];\n\n public readonly webglOption: DropDownOption = {displayName: \"WebGL\", value: \"webgl\"}\n public readonly webGpuOption: DropDownOption = {displayName: \"WebGPU\", value: \"webgpu\"}\n public readonly defaultValue = this.webglOption;\n\n public constructor() {\n super({name: \"Renderer\", category: SettingsCategory.Graphics});\n this.list.push(this.webglOption, this.webGpuOption);\n this.value = this.defaultValue;\n }\n}\n","import {RangeSetting} from \"../../SettingType/RangeSetting\";\nimport {SettingsCategory} from \"../../Setting\";\n\nexport class UIScale extends RangeSetting {\n public readonly maxValue = 0.8;\n public readonly minValue = 1.6;\n public readonly increment = 0.1;\n public readonly defaultValue = 1;\n\n public constructor() {\n super({name: \"UI scaling\", category: SettingsCategory.Graphics});\n this.value = this.defaultValue;\n }\n}","import {RangeSetting} from \"../../SettingType/RangeSetting\";\nimport {SettingsCategory} from \"../../Setting\";\nimport {EventSystem} from \"pixi.js\";\n\nexport class MouseSensitivity extends RangeSetting{\n public readonly defaultValue: number = 1.0;\n public readonly increment: number = 0.01;\n public readonly maxValue: number = 10.0;\n public readonly minValue: number = 0.10;\n\n public constructor() {\n super({name: \"Sensitivity\", category: SettingsCategory.Input});\n this.value = this.defaultValue;\n this.onValueChanged();\n }\n\n public onValueChanged() {\n EventSystem.cursorSensitivity = this.getValue();\n }\n}\n","import {GeneralData} from \"./Sections/General/GeneralData\";\nimport {EditorData} from \"./Sections/Editor/EditorData\";\nimport {Metadata} from \"./Sections/Metadata/Metadata\";\nimport {DifficultyData} from \"./Sections/Difficulty/DifficultyData\";\nimport {EventsData} from \"./Sections/Events/EventsData\";\nimport {TimingPoint} from \"./Sections/TimingPoints/TimingPoint\";\nimport {TimingPointsData} from \"./Sections/TimingPoints/TimingPointsData\";\nimport {ColorsData} from \"./Sections/Colors/ColorsData\";\n\n/**\n * .osu (file format)\n */\nexport class BeatmapData {\n /**\n * General information about the beatmap\n */\n public General: GeneralData = new GeneralData();\n /**\n * Saved settings for the beatmap editor\n */\n public Editor: EditorData = new EditorData();\n /**\n * Information used to identify the beatmap\n */\n public Metadata: Metadata = new Metadata();\n /**\n * Difficulty settings\n */\n public Difficulty: DifficultyData = new DifficultyData();\n /**\n * Beatmap and storyboard graphic events\n */\n public Events: EventsData = new EventsData();\n /**\n * Timing and control points\n */\n public TimingPoints: TimingPointsData = new TimingPointsData();\n /**\n * Combo and skin colours\n */\n public Colors: ColorsData = new ColorsData();\n\n //TODO: add hitobject data\n\n}\n","import {Color} from \"./Color\";\n\n/**\n * \tCombo and skin colours\n */\nexport class ColorsData {\n public Colors: Color[] = [];\n}\n","/**\n * Difficulty settings\n */\nexport class DifficultyData {\n /**\n * HP setting (0–10)\n */\n public HPDrainRate!: number;\n /**\n * CS setting (0–10)\n */\n public CircleSize!: number;\n /**\n * OD setting (0–10)\n */\n public OverallDifficulty!: number;\n /**\n * AR setting (0–10)\n */\n public ApproachRate!: number;\n /**\n * Base slider velocity in hundreds of osu! pixels per beat\n */\n public SliderMultiplier!: number;\n /**\n * Amount of slider ticks per beat\n */\n public SliderTickRate!: number;\n}\n","/**\n * Saved settings for the beatmap editor\n */\nexport class EditorData {\n /**\n * Time in milliseconds of bookmarks\n */\n public Bookmarks: number[] = [];\n /**\n * Distance snap multiplier\n */\n public DistanceSpacing: number | undefined;\n /**\n * Beat snap divisor\n */\n public BeatDivisor: number | undefined;\n /**\n * Grid size\n */\n public GridSize: number | undefined;\n /**\n * Scale factor for the object timeline\n */\n public TimelineZoom: number | undefined;\n}\n","import {Event} from \"./Event\";\n\n/**\n * Beatmap and storyboard graphic events\n */\nexport class EventsData {\n public Events: Event[] = [];\n}\n","export enum Countdown {\n NoCountdown = 0,\n Normal = 1,\n Half = 2,\n Double = 3\n}","import {Countdown} from \"./Countdown\";\nimport {SampleSet} from \"./SampleSet\";\nimport {Mode} from \"./Mode\";\nimport {OverlayPosition} from \"./OverlayPosition\";\n/**\n * General information about the beatmap\n */\nexport class GeneralData {\n /**\n * Location of the audio file relative to the current folder.\n */\n public AudioFileName: string | undefined;\n /**\n * Milliseconds of silence before the audio starts playing\n */\n public AudioLeadIn: number = 0;\n /**\n * @deprecated The `AudioHash` property is deprecated according to the osu! wiki.\n */\n public AudioHash: string | undefined;\n /**\n * Time in milliseconds when the audio preview should start\n */\n public PreviewTime: number = -1;\n /**\n * Speed of the countdown before the first hit object (0 = no countdown, 1 = normal, 2 = half, 3 = double)\n */\n public Countdown: Countdown = Countdown.Normal;\n /**\n * Sample set that will be used if timing points do not override it (Normal, Soft, Drum)\n */\n public SampleSet: SampleSet = SampleSet.Normal;\n /**\n * Multiplier for the\n * threshold in time where hit objects placed close together stack (0–1)\n */\n public StackLeniency: number = 0.7;\n /**\n * Game mode (0 = osu!, 1 = osu!taiko, 2 = osu!catch, 3 = osu!mania)\n */\n public Mode: Mode = Mode.OSU;\n /**\n * Whether or not breaks have a letterboxing effect\n */\n public LetterboxInBreaks: boolean = false;\n /**\n * @deprecated The `StoryFireInFront` property is deprecated according to the osu! wiki.\n */\n public StoryFireInFront: boolean = true;\n /**\n * Whether or not the storyboard can use the user's skin images\n */\n public UseSkinSprites: boolean = false;\n /**\n * @deprecated The `AlwaysShowPlayfield` property is deprecated according to the osu! wiki.\n */\n public AlwaysShowPlayfield: boolean = false;\n /**\n * Draw order of hit circle overlays compared to hit numbers (NoChange = use skin setting,\n * Below = draw overlays under numbers, Above = draw overlays on top of numbers)\n */\n public OverlayPosition: OverlayPosition = OverlayPosition.NoChange;\n /**\n * Preferred skin to use during gameplay\n */\n public SkinPreference: string | undefined;\n /**\n * Whether or not a warning about flashing colours should be shown at the beginning of the map\n */\n public EpilepsyWarning: boolean = false;\n /**\n * Time in beats that the countdown starts before the first hit object\n */\n public CountdownOffset: number = 0;\n /**\n * Whether or not the \"N+1\" style key layout is used for osu!mania\n */\n public SpecialStyle: boolean = false;\n /**\n * Whether or not the storyboard allows widescreen viewing\n */\n public WidescreenStoryboard: boolean = false;\n /**\n * Whether or not sound samples will change rate when playing with speed-changing mods\n */\n public SamplesMatchPlaybackRate: boolean = false;\n}\n","export enum Mode {\n OSU = 0,\n TAIKO = 1,\n CATCH = 2,\n MANIA = 3\n}","export enum OverlayPosition {\n NoChange = \"NoChange\",\n Below = \"Below\",\n Above = \"Above\"\n}\n","export enum SampleSet {\n Normal = \"Normal\",\n Soft = \"Soft\",\n Drum = \"Drum\"\n}","/**\n * Information used to identify the beatmap\n */\nexport class Metadata {\n /**\n * Romanised song title\n */\n public Title!: string;\n /**\n * Song title\n */\n public TitleUnicode!: string;\n /**\n * Romanised song artist\n */\n public Artist!: string;\n /**\n * Song artist\n */\n public ArtistUnicode!: string;\n /**\n * Beatmap creator\n */\n public Creator!: string;\n /**\n * Difficulty name\n */\n public Version!: string;\n /**\n * Original media the song was produced for\n */\n public Source: string | undefined;\n /**\n * Search terms\n */\n public Tags!: string[];\n /**\n * Difficulty ID\n */\n public BeatmapID!: number;\n /**\n * Beatmap ID\n */\n public BeatmapSetID!: number;\n}\n","export enum Effect {\n KiaiTime = 1,\n None = 0,\n FirstBarLineOmittedInOsuTaikoAndOsuMania = 3\n}\n","import {TimingPoint} from \"./TimingPoint\";\n\nexport class InheritedTimingPoint extends TimingPoint {\n /**\n * a negative inverse slider velocity multiplier, as a percentage.\n * For example, `-50` would make all sliders in this timing section twice as fast as `SliderMultiplier`.\n */\n public sliderVelocityMultiplier!: number;\n\n}","import {TimingPointSampleSet} from \"./TimingPointSampleSet\";\nimport {Effect} from \"./Effect\";\n\nexport abstract class TimingPoint {\n /**\n * Start time of the timing section, in milliseconds from the beginning of the beatmap's audio.\n * The end of the timing section is the next timing point's time (or never, if this is the last timing point).\n */\n public time!: number;\n /**\n * Default sample set for hit objects (0 = beatmap default, 1 = normal, 2 = soft, 3 = drum).\n */\n public sampleSet!: TimingPointSampleSet;\n /**\n * Custom sample index for hit objects. 0 indicates osu!'s default hitsounds.\n */\n public sampleIndex!: number;\n /**\n * Volume percentage for hit objects.\n */\n public volume!: number;\n /**\n * Bit flags that give the timing point extra effects.\n * See the effects section.\n */\n public effects!: Effect\n}","import {TimingPoint} from \"./TimingPoint\";\nimport {UnInheritedTimingPoint} from \"./UnInheritedTimingPoint\";\nimport {InheritedTimingPoint} from \"./InheritedTimingPoint\";\n\n/**\n * Timing and control points\n */\nexport class TimingPointsData {\n public TimingPoints: TimingPoint[] = [];\n\n /**\n * Returns the current timing point in an array using the time provided.\n * If the current timing point is inherited, it will also return the parent\n * timing point along with it in the array as the second index.\n */\n public GetCurrentTimingPoints(time: number) {\n let toReturn: TimingPoint[] = [];\n let filter = this.TimingPoints.filter((timingPoint) => {if (timingPoint.time <= time) {return timingPoint}});\n if (filter.length == 0) {\n filter.push(this.TimingPoints[0]);\n }\n toReturn.push(filter[filter.length-1]);\n\n if (toReturn[0] instanceof InheritedTimingPoint) {\n let filter = this.TimingPoints.filter((timingPoint) => {return timingPoint instanceof UnInheritedTimingPoint})\n .filter((timingPoint) => {if (timingPoint.time <= time) {return timingPoint}});\n if (filter.length == 0) {\n throw new Error(\"Could not find a parent timing point for the un-inherited timing point!\");\n }\n toReturn.push(filter[filter.length-1]);\n }\n if (toReturn.length == 0) {\n throw new Error(\"Could not find any timing points!\");\n }\n return toReturn;\n }\n\n public GetCurrentUninheritedTimingPoint(time: number) {\n let timingPoint = this.GetCurrentTimingPoints(time);\n let unInheritedTimingPoint: UnInheritedTimingPoint;\n if (timingPoint[0] instanceof UnInheritedTimingPoint) {\n unInheritedTimingPoint = timingPoint[0];\n }\n else if(timingPoint[1] instanceof UnInheritedTimingPoint){\n unInheritedTimingPoint = timingPoint[1];\n }\n else {\n throw new Error(\"Could not find any UnInherited Timing Points!\")\n }\n return unInheritedTimingPoint;\n }\n\n}\n","import {TimingPoint} from \"./TimingPoint\";\n\nexport class UnInheritedTimingPoint extends TimingPoint {\n /**\n * The duration of a beat, in milliseconds.\n */\n public beatLength!: number;\n /**\n * Amount of beats in a measure.\n */\n public meter!: number;\n}\n","import {BeatmapData} from \"../Data/BeatmapData\";\nimport {TimingPointsParser} from \"./TimingPointsParser\";\nimport {GeneralParser} from \"./GeneralParser\";\n\nexport class BeatmapParser {\n public static Parse(osuFileContent: string, storyBoardFileContent?: string): BeatmapData {\n const beatMapData = new BeatmapData();\n let osuFileContentLines = osuFileContent.split(/\\r?\\n|\\r|\\n/g);\n GeneralParser.ParseGeneral(beatMapData, BeatmapParser.GetSection(\"General\", osuFileContentLines))\n TimingPointsParser.ParseTimingPoints(beatMapData, BeatmapParser.GetSection(\"TimingPoints\", osuFileContentLines));\n return beatMapData\n }\n public static GetSection(sectionName: string, osuFileContentLines: string[]) {\n let section: string[] = [];\n osuFileContentLines.forEach((str, index) => {\n if (str == \"[\"+sectionName+\"]\") {\n for (let i = index + 1; i < osuFileContentLines.length; i++) {\n if (osuFileContentLines[i] == \"\"){\n continue;\n }\n if (osuFileContentLines[i].startsWith(\"[\")){\n break;\n }\n section.push(osuFileContentLines[i]);\n }\n }\n });\n return section;\n }\n}\n","import {BeatmapData} from \"../Data/BeatmapData\";\n\nexport class GeneralParser {\n public static ParseGeneral(beatmapData: BeatmapData, section: string[]) {\n section.forEach((str) => {\n let propValue = str.split(\":\");\n if (propValue[0] == \"AudioFilename\") {\n if (propValue[1].startsWith(\" \")){\n beatmapData.General.AudioFileName = propValue[1].substring(1, propValue[1].length);\n }\n else {\n beatmapData.General.AudioFileName = propValue[1];\n }\n }\n if (propValue[0] == \"AudioFilename\") {\n if (propValue[1].startsWith(\" \")){\n beatmapData.General.AudioFileName = propValue[1].substring(1, propValue[1].length);\n }\n else {\n beatmapData.General.AudioFileName = propValue[1];\n }\n }\n })\n }\n\n}\n","import {BeatmapData} from \"../Data/BeatmapData\";\nimport {UnInheritedTimingPoint} from \"../Data/Sections/TimingPoints/UnInheritedTimingPoint\";\nimport {InheritedTimingPoint} from \"../Data/Sections/TimingPoints/InheritedTimingPoint\";\nimport {Effect} from \"../Data/Sections/TimingPoints/Effect\";\n\nexport class TimingPointsParser {\n public static ParseTimingPoints(beatmapData: BeatmapData, section: string[]) {\n section.forEach((str) => {\n let prop = str.split(\",\");\n let timingPoint;\n if (prop[6] == \"1\") {\n timingPoint = new UnInheritedTimingPoint();\n timingPoint.beatLength = Number.parseFloat(prop[1]);\n timingPoint.meter = Number.parseInt(prop[2]);\n }\n else {\n timingPoint = new InheritedTimingPoint();\n timingPoint.sliderVelocityMultiplier = Number.parseFloat(prop[1]);\n }\n timingPoint.time = Number.parseInt(prop[0]);\n timingPoint.sampleSet = Number.parseInt(prop[3]);\n timingPoint.sampleIndex = Number.parseInt(prop[4]);\n timingPoint.volume = Number.parseInt(prop[5]);\n if (prop[7] == \"1\" || prop[7] == \"3\"){\n timingPoint.effects = Number.parseInt(prop[7]);\n } else {\n timingPoint.effects = Effect.None;\n }\n\n beatmapData.TimingPoints.TimingPoints.push(timingPoint);\n });\n }\n}\n","export class MathUtil {\n public static RadiansToDegrees(radians: number) {\n return radians * 180 / Math.PI;\n }\n\n public static DegreesToRadians(degrees: number) {\n return degrees * Math.PI / 180;\n }\n\n public static clamp(min: number, max: number, value: number) {\n return Math.min(Math.max(value, min), max);\n }\n\n public static clamp01(value: number) {\n return MathUtil.clamp(0, 1, value);\n }\n\n public static Damp(start: number, final: number, base: number, exponent: number) {\n return MathUtil.Lerp(start, final, 1 - Math.pow(base, exponent));\n }\n\n public static Lerp(start: number, final: number, ammount: number) {\n return start + (final - start) * ammount;\n }\n\n}\n","import * as TWEEN from \"@tweenjs/tween.js\";\nimport * as PIXI from \"pixi.js\";\n\nexport class Ease {\n private static previousEases: Ease[] = [];\n private easings: Easing[] = [];\n private readonly obj: PIXI.Container;\n private delay: TWEEN.Tween | null = null;\n\n private constructor(obj: PIXI.Container, dontStore: boolean) {\n this.obj = obj;\n if (!dontStore) {\n Ease.previousEases.push(this);\n }\n }\n\n public static getEase(obj: PIXI.Container, dontStore?: boolean) {\n if (dontStore == null) {\n dontStore = false;\n }\n let checkIfEaseExists = Ease.previousEases.filter((ease) => {\n return ease.obj == obj;\n });\n if (checkIfEaseExists.length > 0) {\n return checkIfEaseExists[0];\n }\n return new Ease(obj, dontStore);\n }\n\n public createTween>(value: T, newValue: T, isPrimitive: boolean, property: keyof PIXI.Container, duration: number, easingFunc: (ammount: number) => number) {\n const tweenValue = {value: 0}\n const tween = new TWEEN.Tween(isPrimitive ? tweenValue : value);\n const easing = new Easing(tween);\n tween.to(isPrimitive ? {value: 1} : newValue, duration);\n tween.easing(easingFunc);\n tween.onUpdate(() => {\n if (!this.obj.destroyed) {\n if (!isPrimitive) {\n // @ts-ignore\n this.obj[property] = value;\n } else {\n // @ts-ignore\n this.obj[property] = (tweenValue.value * (newValue.value - value.value)) + value.value;\n }\n }\n easing.onUpdate();\n });\n\n tween.onStart(() => {\n if (isPrimitive) {\n // @ts-ignore\n value.value = this.obj[property];\n }\n });\n\n\n if (this.delay == null) {\n\n tween.start();\n } else {\n this.delay.chain(tween);\n this.delay = null;\n }\n this.easings.push(easing);\n\n tween.onStop(() => {\n this.onDone(tween);\n });\n tween.onComplete(() => {\n this.onDone(tween);\n });\n return this;\n }\n\n public TransformTo(newPosition: PIXI.PointData, duration: number, easing: (ammount: number) => number) {\n this.createTween(this.obj.position, newPosition, false, \"position\", duration, easing);\n return this;\n }\n\n private onDone(tween: TWEEN.Tween) {\n this.easings = this.easings.filter((tweenInArray) => {\n return tweenInArray.tween != tween\n })\n }\n\n public ScaleTo(newScale: PIXI.PointData | number, duration: number, easing: (ammount: number) => number) {\n let _newScale: PIXI.PointData = {x: 0, y: 0};\n if (typeof newScale == \"number\") {\n _newScale.x = newScale;\n _newScale.y = newScale;\n }\n this.createTween(this.obj.scale, _newScale, false, \"scale\", duration, easing);\n return this;\n }\n\n public FadeTo(newAlpha: number, duration: number, easing: (ammount: number) => number) {\n this.createTween({value: this.obj.alpha}, {value: newAlpha}, true, \"alpha\", duration, easing);\n return this;\n }\n\n public FadeOut(duration: number, easing: (ammount: number) => number) {\n this.FadeTo(0, duration, easing);\n return this;\n }\n\n public FadeIn(duration: number, easing: (ammount: number) => number) {\n this.FadeTo(1, duration, easing);\n return this;\n }\n\n public ClearEasings() {\n this.easings.forEach((tween) => {\n tween.tween.stop();\n });\n this.easings = [];\n return this;\n }\n\n public Then(cb?: () => void) {\n let largestDuration = this.easings.sort((a, b) => {\n return a.tween.getDuration() - b.tween.getDuration()\n });\n if (largestDuration.length > 0) {\n this.delay = largestDuration[0].tween;\n if (cb != undefined) {\n largestDuration[0].tween.onComplete(() => {this.onDone(largestDuration[0].tween); cb();});\n largestDuration[0].tween.onStop(() => {this.onDone(largestDuration[0].tween); cb();});\n }\n }\n return this;\n }\n\n public OnEach(cb: () => void) {\n let largestDuration = this.easings.sort((a, b) => {\n return a.tween.getDuration() - b.tween.getDuration()\n });\n if (largestDuration.length > 0) {\n largestDuration[0].registerOnUpdate(cb);\n }\n }\n}\n\nclass Easing {\n public tween: TWEEN.Tween;\n private updateEventListeners: (() => void)[] = [];\n public constructor(tween: TWEEN.Tween) {\n this.tween = tween;\n }\n public onUpdate() {\n this.updateEventListeners.forEach((eventListener) => {\n eventListener();\n })\n }\n public registerOnUpdate(cb: () => void) {\n this.updateEventListeners.push(cb);\n }\n public unRegisterOnUpdate(cb: () => void) {\n this.updateEventListeners = this.updateEventListeners.filter((ev) => {return !(cb === ev);});\n }\n}\n","import \"./style.css\";\nimport {Application, EventSystem} from \"pixi.js\";\nimport {Main} from \"./main\";\nimport {Settings} from \"./Settings/Settings\";\nimport {Renderer} from \"./Settings/impl/Graphics/Renderer\";\nimport {MouseSensitivity} from \"./Settings/impl/Input/MouseSensitivity\";\nSettings.registerAll();\nSettings.load();\nconst gameWidth = window.innerWidth;\nconst gameHeight = window.innerHeight;\n\nconst app = new Application();\n// @ts-ignore\nglobalThis.__PIXI_APP__ = app;\nwindow.onload = async (): Promise => {\n // @ts-ignore\n const renderer = Settings.getSetting(Renderer).getValue().value as \"webgl\" | \"webgpu\";\n app.init({\n backgroundColor: \"black\",\n width: gameWidth,\n height: gameHeight,\n antialias: true,\n preference: renderer,\n resolution: window.devicePixelRatio,\n autoDensity: true\n }).then(() => {\n new Main(app);\n });\n};\n\nObject.defineProperty(window, \"setSensitivity\", {value: (sensitivity: number) => {\n Settings.getSetting(MouseSensitivity).setValue(sensitivity);\n}});\n\nObject.defineProperty(window, \"setRenderer\", {value: (renderer: string) => {\n let rendererSetting = Settings.getSetting(Renderer);\n rendererSetting.setValue(renderer == \"webgl\" ? rendererSetting.webglOption : rendererSetting.webGpuOption);\n window.location.reload();\n}});\n","import * as PIXI from \"pixi.js\";\nimport {Application} from \"pixi.js\";\nimport {Screen} from \"./Screens/Screen\";\nimport {LoadScreen} from \"./Screens/LoadScreen/LoadScreen\";\nimport {InteractScreen} from \"./Screens/InteractScreen/InteractScreen\";\nimport {Loader} from \"./Loader\";\nimport {MenuCursor} from \"./Elements/MenuCursor/MenuCursor\";\nimport {AudioEngine} from \"./Audio/AudioEngine\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\nimport {SettingsPane} from \"./Elements/Settings/SettingsPane\";\n\nexport class Main {\n public static app: Application;\n public static mousePos = {x: 0, y: 0};\n public static pointerLockExitTime: number;\n public static cursor: MenuCursor;\n public static AudioEngine: AudioEngine;\n private static currentScreen: Screen | null;\n private static allScreens: Screen[] = [];\n private static clickArea: PIXI.Graphics = new PIXI.Graphics();\n private static doPointerLock: boolean = false;\n private static settingsPane: SettingsPane;\n\n public constructor(app: Application) {\n Main.app = app;\n // @ts-ignore\n document.body.appendChild(Main.app.canvas);\n\n Main.settingsPane = new SettingsPane();\n Main.settingsPane.zIndex = 999998;\n Main.app.stage.addChild(Main.settingsPane);\n\n document.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n if (e.ctrlKey && e.code == \"KeyO\"){\n Main.settingsPane.toggle();\n }\n });\n\n this.doResize();\n window.addEventListener(\"resize\", this.doResize);\n Main.app.ticker.add(() => {\n TWEEN.update();\n })\n Main.app.stage.eventMode = \"static\";\n Main.AudioEngine = new AudioEngine();\n Main.app.stage.addEventListener(\"mousemove\", (e) => {\n Main.mousePos.x = e.clientX;\n Main.mousePos.y = e.clientY;\n if (Main.cursor) {\n Main.cursor.updateMouse();\n }\n });\n document.addEventListener(\"pointerlockchange\", this.pointerLockChanged, false);\n Main.switchScreen(new LoadScreen());\n Loader.Load(Main.AudioEngine.audioContext).then(() => {\n Main.cursor = new MenuCursor(false);\n let dialogOk = Loader.GetAudio(\"sample_dialog_ok\");\n let introTrack = Loader.Get(\"introTrianglesTrack\");\n Main.switchScreen(new InteractScreen(introTrack, dialogOk));\n });\n }\n\n public static lockKeyboard() {\n // @ts-ignore\n if (navigator.keyboard) {\n // @ts-ignore\n navigator.keyboard.lock([]).then(() => {\n console.log(\"Locked keyboard!\");\n if (!document.fullscreenElement) {\n console.warn(\"Keyboard lock won't work unless the user is in fullscreen (as requested by the game, not if the user just presses F11)!\");\n }\n });\n }\n }\n\n public static pointerLock() {\n try {\n this.doPointerLock = true;\n // @ts-ignore\n Main.app.canvas.requestPointerLock({\n unadjustedMovement: true,\n });\n } catch (e) {\n console.warn(\"Failed to lock cursor, error:\", e);\n this.doPointerLock = false;\n }\n\n }\n\n public static exitPointerLock() {\n this.doPointerLock = false;\n // @ts-ignore\n Main.app.canvas.exitPointerLock();\n }\n\n public static switchScreen(screen: Screen) {\n if (this.currentScreen != null) {\n this.currentScreen.zIndex = 1;\n this.currentScreen.onClose().then((lastScreen) => {\n for (let i = 0; i < this.allScreens.length; i++) {\n if (this.allScreens[i] == lastScreen) {\n this.allScreens.splice(i, 1);\n }\n }\n Main.app.ticker.remove(lastScreen.draw);\n Main.app.stage.removeChild(lastScreen);\n lastScreen.destroy();\n });\n }\n Main.app.stage.addChild(screen);\n this.allScreens.push(screen);\n this.currentScreen = screen;\n screen.start();\n screen.onResize();\n Main.app.ticker.add(screen.draw, screen);\n }\n\n public doResize(): void {\n Main.app.renderer.resize(window.innerWidth, window.innerHeight);\n Main.app.stage.scale.x = 1;\n Main.app.stage.scale.y = 1;\n if (!Main.clickArea.destroyed) {\n Main.clickArea.width = window.innerWidth;\n Main.clickArea.height = window.innerHeight;\n Main.clickArea.position.set(0, 0);\n }\n Main.allScreens.forEach((screen) => {\n screen.onResize();\n })\n Main.settingsPane.resize();\n }\n\n private pointerLockChanged(): void {\n if (!document.pointerLockElement && Main.doPointerLock) {\n PIXI.EventSystem.isPointerLocked = false;\n Main.pointerLockExitTime = Date.now();\n Main.clickArea = new PIXI.Graphics();\n Main.clickArea.rect(0, 0, 1, 1);\n Main.clickArea.fill(\"rgba(0,0,0,0.1)\");\n Main.clickArea.width = window.innerWidth;\n Main.clickArea.height = window.innerHeight;\n Main.clickArea.position.set(0, 0);\n Main.app.stage.addChild(Main.clickArea);\n Main.clickArea.eventMode = \"static\";\n Main.clickArea.cursor = \"pointer\";\n Main.cursor.PopOut();\n Main.clickArea.zIndex = 9999999;\n Main.clickArea.onclick = () => {\n if (Date.now() - Main.pointerLockExitTime < 1500) {\n return;\n }\n Main.clickArea.removeFromParent();\n Main.clickArea.destroy();\n Main.pointerLock();\n Main.cursor.PopIn();\n }\n } else {\n PIXI.EventSystem.isPointerLocked = true;\n }\n }\n\n}\n","export default \"in vec2 vUV;\\nin vec2 vPositionOffset;\\nin vec2 vPosition;\\nin vec4 vColorTint;\\nuniform sampler2D uTexture;\\nuniform float time;\\n\\nvoid main() {\\n float a = ((vPositionOffset.y + vPosition.y)/1200.0) - 0.1;\\n vec4 color = texture(uTexture, vUV);\\n if (a > 1.0) {\\n a = 1.0;\\n }\\n gl_FragColor = (color*vColorTint)*a;\\n}\";","export default \"in vec2 aPosition;\\nin vec2 aUV;\\nin vec2 aPositionOffset;\\nin vec4 aColorTint;\\n\\nout vec2 vUV;\\nout vec2 vPositionOffset;\\nout vec2 vPosition;\\nout vec4 vColorTint;\\n\\nuniform mat3 uProjectionMatrix;\\nuniform mat3 uWorldTransformMatrix;\\nuniform mat3 uTransformMatrix;\\n\\n\\nvoid main() {\\n\\n mat3 mvp = uProjectionMatrix * uWorldTransformMatrix * uTransformMatrix;\\n gl_Position = vec4((mvp * vec3(aPosition + aPositionOffset, 1.0)).xy, 0.0, 1.0);\\n vPositionOffset = aPositionOffset;\\n vUV = aUV;\\n vPosition = aPosition;\\n vColorTint = aColorTint;\\n}\";","export default \"struct GlobalUniforms {\\n uProjectionMatrix:mat3x3,\\n uWorldTransformMatrix:mat3x3,\\n uWorldColorAlpha: vec4,\\n uResolution: vec2,\\n}\\n\\nstruct LocalUniforms {\\n uTransformMatrix:mat3x3,\\n uColor:vec4,\\n uRound:f32,\\n}\\n\\n\\n@group(0) @binding(0) var globalUniforms : GlobalUniforms;\\n@group(1) @binding(0) var localUniforms : LocalUniforms;\\n\\nstruct VertexOutput {\\n @builtin(position) position: vec4,\\n @location(0) vUV: vec2,\\n @location(1) vPositionOffset: vec2,\\n @location(2) vPosition: vec2,\\n @location(3) vColorTint: vec4\\n};\\n\\n\\n@vertex\\nfn mainVert(\\n @location(0) aPosition : vec2,\\n @location(1) aUV : vec2,\\n @location(2) aColorTint : vec4,\\n @location(3) aPositionOffset : vec2,\\n) -> VertexOutput {\\n var mvp = globalUniforms.uProjectionMatrix\\n * globalUniforms.uWorldTransformMatrix\\n * localUniforms.uTransformMatrix;\\n\\n var output: VertexOutput;\\n\\n output.position = vec4(mvp * vec3(aPosition+aPositionOffset, 1.0), 1.0);\\n output.vUV = aUV;\\n output.vPosition = aPosition;\\n output.vPositionOffset = aPositionOffset;\\n output.vColorTint = aColorTint;\\n\\n return output;\\n};\\n\\nstruct WaveUniforms {\\n time:f32,\\n}\\n\\n@group(2) @binding(1) var uTexture : texture_2d;\\n@group(2) @binding(2) var uSampler : sampler;\\n@group(2) @binding(3) var waveUniforms : WaveUniforms;\\n\\n@fragment\\nfn mainFrag(\\n @location(0) vUV: vec2,\\n @location(1) vPositionOffset: vec2,\\n @location(2) vPosition: vec2,\\n @location(3) vColorTint: vec4\\n) -> @location(0) vec4 {\\n var a: f32 = ((vPositionOffset.y + vPosition.y)/1200.0) - 0.1;\\n let color: vec4 = textureSample(uTexture, uSampler, vUV);\\n if (a > 1.0){\\n a = 1.0;\\n }\\n return (color*vColorTint)*a;\\n};\";","export default \"in vec4 vColor;\\nin vec2 vUV;\\n\\nuniform sampler2D uTexture;\\nuniform float progress;\\n\\nvoid main() {\\n vec4 color = texture2D(uTexture, vUV);\\n float a = vColor.a * color.a;\\n vec4 _vColor = vec4(smoothstep(0.88, 1.0, color.a))*vColor;\\n vec4 outColor = (color.r < progress) ? vec4(_vColor.rgb * a, a) : vec4(0.0);\\n gl_FragColor = outColor;\\n}\\n\";","export default \"in vec2 aPosition;\\nin vec4 aColor;\\nin vec2 aUV;\\n\\nout vec4 vColor;\\nout vec2 vUV;\\n\\nuniform mat3 uProjectionMatrix;\\nuniform mat3 uWorldTransformMatrix;\\n\\nuniform mat3 uTransformMatrix;\\n\\n\\nvoid main() {\\n\\n mat3 mvp = uProjectionMatrix * uWorldTransformMatrix * uTransformMatrix;\\n gl_Position = vec4((mvp * vec3(aPosition, 1.0)).xy, 0.0, 1.0);\\n\\n vColor = aColor;\\n vUV = aUV;\\n}\\n\";","export default \"struct GlobalUniforms {\\n uProjectionMatrix:mat3x3,\\n uWorldTransformMatrix:mat3x3,\\n uWorldColorAlpha: vec4,\\n uResolution: vec2,\\n}\\n\\nstruct LocalUniforms {\\n uTransformMatrix:mat3x3,\\n uColor:vec4,\\n uRound:f32,\\n}\\n\\n\\n@group(0) @binding(0) var globalUniforms : GlobalUniforms;\\n@group(1) @binding(0) var localUniforms : LocalUniforms;\\n\\nstruct VertexOutput {\\n @builtin(position) position: vec4,\\n @location(0) vUV: vec2,\\n @location(1) vColor: vec4,\\n};\\n\\n\\n@vertex\\nfn mainVert(@location(0) aPosition : vec2, @location(1) aUV : vec2, @location(2) aColor: vec4\\n) -> VertexOutput {\\n var mvp = globalUniforms.uProjectionMatrix\\n * globalUniforms.uWorldTransformMatrix\\n * localUniforms.uTransformMatrix;\\n\\n var output: VertexOutput;\\n\\n output.position = vec4(mvp * vec3(aPosition, 1.0), 1.0);\\n output.vUV = aUV;\\n output.vColor = aColor;\\n\\n return output;\\n};\\n\\nstruct ProgressUniform {\\n progress:f32\\n}\\n\\n@group(2) @binding(1) var uTexture : texture_2d;\\n@group(2) @binding(2) var uSampler : sampler;\\n@group(2) @binding(3) var uProgress : ProgressUniform;\\n\\n@fragment\\nfn mainFrag(@location(0) vUV: vec2, @location(1) vColor: vec4) -> @location(0) vec4 {\\n let color: vec4 = textureSample(uTexture, uSampler, vUV);\\n let a: f32 = color.a;\\n let _vColor: vec4 = smoothstep(0.88, 1.0, color.a) * vColor;\\n var outColor: vec4 = vec4(0.0);\\n if (color.r < uProgress.progress) {\\n outColor = vec4(_vColor.rgb * a, a);\\n }\\n return outColor;\\n};\\n\";","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\tloaded: false,\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Flag the module as loaded\n\tmodule.loaded = true;\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.hmd = function(module) {\n\tmodule = Object.create(module);\n\tif (!module.children) module.children = [];\n\tObject.defineProperty(module, 'exports', {\n\t\tenumerable: true,\n\t\tset: function() {\n\t\t\tthrow new Error('ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: ' + module.id);\n\t\t}\n\t});\n\treturn module;\n};","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t179: 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = function(parentChunkLoadingFunction, data) {\n\tvar chunkIds = data[0];\n\tvar moreModules = data[1];\n\tvar runtime = data[2];\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkkosu\"] = self[\"webpackChunkkosu\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [811], function() { return __webpack_require__(29820); })\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["deferred","Audio","audio","timeStarted","source","id","isPlaying","isPaused","pausedTime","nodes","tempArrayMain","Float32Array","tempArrayL","tempArrayR","LeftChannel","RightChannel","FrequencyAmplitudes","_connectedToContext","GetMaximumAudioLevel","Math","max","this","GetAverageAudioLevel","Create","audioContext","createBufferSource","buffer","AddAudioNode","node","Error","push","GetNode","type","filter","length","ConnectToContext","howToConnectFunction","forEach","index","connect","AnalyserNode","destination","Play","start","Date","now","Pause","stop","Stop","RegisterEndCallBack","callback","onended","exports","beatmap","fadingOut","fadeOutTimeout","playingCallback","PlayingAudios_1","require","Audio_1","BeatmapData_1","main_1","UnInheritedTimingPoint_1","Effect_1","_playingAudios","_musicQueue","_audioIdTicker","_changeCallbacks","silentMusic","createSilentMusic","useSilentMusic","constructor","AudioContext","PlayingAudios","Main","app","ticker","add","update","UpdateMusicQueue","_play","cb","mapAudio","MapAudio","BeatmapData","timingPoint","UnInheritedTimingPoint","time","beatLength","effects","Effect","None","TimingPoints","addMusicChangeEventListener","removeMusicChangeEventListener","GetCurrentPlayingMusic","PlayEffect","pitch","audioObj","AddToMusicQueue","beatMapData","musicPlayingCallback","mapAudioObj","PlayMusicImmediately","currentPlaying","analyzerMain","analyzerL","analyzerR","getFloatFrequencyData","i","Infinity","getFloatTimeDomainData","avgL","avgR","value","audios","clearTimeout","gainNodes","GainNode","gain","linearRampToValueAtTime","currentTime","setTimeout","createGain","analyzer","createAnalyser","fftSize","smoothingTimeConstant","splitter","createChannelSplitter","duration","playbackRate","splice","audioInArr","PIXI","__importStar","MathUtil_1","LogoVisualizer","Container","static","frequencyAmplitudes","temporalAmplitudes","graphics","Graphics","index_change","bar_length","bars_per_visualiser","visualiser_rounds","decay_per_millisecond","time_between_updates","amplitude_dead_zone","indexOffset","firstDraw","blendMode","addChild","eventMode","setInterval","updateAmplitudes","draw","clear","decayFactor","deltaMS","j","rotation","MathUtil","DegreesToRadians","rotationCos","cos","rotationSin","sin","barPosition","x","size","y","barSize","sqrt","amplitudeOffset","moveTo","lineTo","stroke","color","width","AudioEngine","GetCurrentTimingPoints","targetAmplitude","KiaiTime","LogoVisualizer_1","MenuLogoVisualizer","super","TWEEN","Ease_1","LoadAnim","bg","arc","arcContainer","animInterval","container","bgContainer","bgRotation","bgColor","arcColor","pivot","set","alpha","PI","roundRect","fill","cap","scale","Ease","getEase","ScaleTo","Easing","Quadratic","InOut","FadeIn","doAnims","createTween","angle","getWidth","getHeight","deltaTime","destroy","_options","FadeOut","clearInterval","Menu","menuBG","isOpened","rect","Open","Quintic","Out","Close","ClearEasings","Sinusoidal","In","isOpen","onResize","position","window","innerWidth","Triangles_1","Loader_1","Menu_1","MenuLogoVisualizer_1","OsuCircle","outline","visualizer","triangles","Triangles","flash","logoContainer","logoBounceContainer","logoBeatContainer","logoAmplitudeContainer","logoHoverContainer","rippleContainer","ripple","menu","defaultVisualizerAlpha","early_activation","timeElapsedSinceLastBeat","timeUntilNextBeat","lastTimeElapasedSinceLastBeat","selectSample","Loader","GetAudio","backToLogoSample","isMouseDown","mouseDownPosition","Sprite","from","anchor","mask","circle","height","hitArea","Circle","onmouseenter","_onmouseenter","onmouseleave","_onmouseleave","onmousedown","_onmousedown","onclick","_onclick","stage","addEventListener","e","_onmouseup","Elastic","mousePos","Exponential","TransformTo","GetCurrentUninheritedTimingPoint","Velocity","Damp","maxAmplitude","onNewBeat","change","pow","amplitudeAdjust","min","Linear","Then","FadeTo","osuCircleTriangles_vert_1","__importDefault","osuCircleTriangles_frag_1","osuCircleTriangles_wgsl_1","bgGradient","timeSinceLastSpawn","instancePositionBuffer","totalTriangles","colorStops","FillGradient","number","ratio","addColorStop","random","velocity","randVelocity","Buffer","data","usage","BufferUsage","VERTEX","COPY_DST","Color","geometry","Geometry","attributes","aPosition","aUV","aColorTint","red","green","blue","aPositionOffset","instance","indexBuffer","instanceCount","gl","vertex","default","fragment","gpu","entryPoint","triangleGraphic","triangleTexture","renderer","generateTexture","shader","Shader","resources","uTexture","uSampler","style","waveUniforms","triangleMesh","Mesh","options","count","triangle","u1","u2","randStdNormal","log","Screen_1","MenuCursor","mouseCursor","mouseCursorAdditive","mouseContainer","animContainer","animRotationContainer","dragRotationState","DragRotationState","NotDragging","lastDragRotationState","mouseHideContainer","elastic_const2","elastic_const","elastic_offset_quarter","posMouseDown","mouseIsDown","cursorTapSample","mouseButtonClicked","visible","updateMouse","Screen","getScaleBasedOffScreenSize","tint","zIndex","addEventListeners","button","DragStarted","Rotating","abs","PopIn","PopOut","distance","offsetX","offsetY","degrees","RadiansToDegrees","atan2","diff","RandomBackground","parallaxMultiplier","getScreenWidth","getScreenHeight","newRandomBG","setBG","sprite","children","previous","useSeasonalBackgrounds","seasonalBackgroundsNum","randomNum","defaultBackgroundsNum","round","onClose","Promise","resolve","scaleFactor","texWidth","texture","texHeight","innerHeight","SettingsPane","resize","open","Cubic","toggle","close","addToLoadList","loadList","url","isAudio","pixiBundleName","Get","result","loadedList","loadedObj","GetString","dataString","dataAudio","addBackgrounds","fetch","encodeURIComponent","then","res","json","backgrounds","background","loadParser","catch","error","console","warn","Load","nonPixi","pixi","pixiwithBundles","loadedAssets","erroredAssets","loadObj","added","loadObjs","incrementLoadAssetNumber","errored","response","blob","isText","text","arrayBuffer","arrBuff","decodeAudioData","audioBuff","bundle","assets","alias","src","Assets","addBundle","loadBundle","IntroScreen_1","InteractScreen","text2","textContainer","textContainerContainer","introTrack","clickSound","clickArea","Text","fontFamily","fontSize","align","cursor","clicked","switchScreen","IntroScreen","document","body","pointerLock","lockKeyboard","ontap","GlitchingTriangles","bounds","randX","x1","x2","randY","y1","y2","unzipit_1","GlitchingTriangles_1","MainMenu_1","LazerLogo_1","BeatmapParser_1","introTrackUrl","doTextSpacingAnim","ruleSetContainer","logoContainerContainer","lazerLogo","LazerLogo","flashed","standard","taiko","ctb","mania","completionPromise","welcomeText","letterSpacing","URL","createObjectURL","async","entries","unzip","name","entry","Object","endsWith","osuFile","beatmapData","BeatmapParser","Parse","General","AudioFileName","afterAudioPlay","glitchingInterval","MainMenu","destroyed","LogoAnimation_1","highlight","textureHighlight","Texture","textureBackground","LogoAnimation","dummy","OnEach","setProgress","logoAnimation_vert_1","logoAnimation_frag_1","logoAnimation_wgsl_1","uProgress","progress","quadGeometry","aColor","quad","uniforms","LoadAnim_1","LoadScreen","loadAnim","RandomBackground_1","OsuCircle_1","osuCircle","Settings_1","UIScale_1","uiScale","Settings","getSetting","UIScale","getValue","SettingsCategory","info","SettingData","register","setting","onValueChanged","Setting_1","DropdownSetting","Setting","getDefaultValue","defaultValue","setValue","list","find","option","displayName","save","loadFromSaveValue","RangeSetting","clamp","minValue","maxValue","Renderer_1","MouseSensitivity_1","registerAll","Renderer","MouseSensitivity","load","settingSaveDataString","localStorage","getItem","settings","getList","JSON","parse","corrupt","stringify","category","settingObj","_settingObj","reset","settingSaveData","setItem","removeItem","settingsList","_setting","getSettingData","DropdownSetting_1","webglOption","webGpuOption","RangeSetting_1","increment","pixi_js_1","Input","EventSystem","cursorSensitivity","GeneralData_1","EditorData_1","Metadata_1","DifficultyData_1","EventsData_1","TimingPointsData_1","ColorsData_1","GeneralData","Editor","EditorData","Metadata","Difficulty","DifficultyData","Events","EventsData","TimingPointsData","Colors","ColorsData","HPDrainRate","CircleSize","OverallDifficulty","ApproachRate","SliderMultiplier","SliderTickRate","Bookmarks","DistanceSpacing","BeatDivisor","GridSize","TimelineZoom","Countdown","Countdown_1","SampleSet_1","Mode_1","OverlayPosition_1","AudioLeadIn","AudioHash","PreviewTime","Normal","SampleSet","StackLeniency","Mode","OSU","LetterboxInBreaks","StoryFireInFront","UseSkinSprites","AlwaysShowPlayfield","OverlayPosition","NoChange","SkinPreference","EpilepsyWarning","CountdownOffset","SpecialStyle","WidescreenStoryboard","SamplesMatchPlaybackRate","Title","TitleUnicode","Artist","ArtistUnicode","Creator","Version","Source","Tags","BeatmapID","BeatmapSetID","TimingPoint_1","InheritedTimingPoint","TimingPoint","sliderVelocityMultiplier","sampleSet","sampleIndex","volume","InheritedTimingPoint_1","toReturn","unInheritedTimingPoint","meter","TimingPointsParser_1","GeneralParser_1","osuFileContent","storyBoardFileContent","osuFileContentLines","split","GeneralParser","ParseGeneral","GetSection","TimingPointsParser","ParseTimingPoints","sectionName","section","str","startsWith","propValue","substring","prop","Number","parseFloat","parseInt","radians","clamp01","final","base","exponent","Lerp","ammount","easings","obj","delay","dontStore","previousEases","checkIfEaseExists","ease","newValue","isPrimitive","property","easingFunc","tweenValue","tween","Tween","easing","to","onUpdate","onStart","chain","onStop","onDone","onComplete","newPosition","tweenInArray","newScale","_newScale","newAlpha","largestDuration","sort","a","b","getDuration","undefined","registerOnUpdate","updateEventListeners","eventListener","unRegisterOnUpdate","ev","gameWidth","gameHeight","Application","globalThis","__PIXI_APP__","onload","init","backgroundColor","antialias","preference","resolution","devicePixelRatio","autoDensity","defineProperty","sensitivity","rendererSetting","location","reload","LoadScreen_1","InteractScreen_1","MenuCursor_1","AudioEngine_1","SettingsPane_1","appendChild","canvas","settingsPane","ctrlKey","code","doResize","clientX","clientY","pointerLockChanged","dialogOk","navigator","keyboard","lock","fullscreenElement","doPointerLock","requestPointerLock","unadjustedMovement","exitPointerLock","screen","currentScreen","lastScreen","allScreens","remove","removeChild","pointerLockElement","isPointerLocked","pointerLockExitTime","removeFromParent","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","module","loaded","__webpack_modules__","call","m","O","chunkIds","fn","priority","notFulfilled","fulfilled","keys","every","key","r","d","definition","o","enumerable","get","hmd","create","prototype","hasOwnProperty","Symbol","toStringTag","installedChunks","chunkId","webpackJsonpCallback","parentChunkLoadingFunction","moreModules","runtime","some","chunkLoadingGlobal","self","bind","__webpack_exports__"],"sourceRoot":""} \ No newline at end of file diff --git a/game.a7af8ee9d41f20465ca4.js b/game.a7af8ee9d41f20465ca4.js new file mode 100644 index 0000000..58e61d7 --- /dev/null +++ b/game.a7af8ee9d41f20465ca4.js @@ -0,0 +1,2 @@ +!function(){"use strict";var e,t={65918:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.MapAudio=t.Audio=void 0;class i{audio;timeStarted=0;source;id;isPlaying=!1;isPaused=!1;pausedTime=0;nodes=[];tempArrayMain=new Float32Array(256);tempArrayL=new Float32Array(64);tempArrayR=new Float32Array(64);LeftChannel=0;RightChannel=0;FrequencyAmplitudes=new Float32Array(256);_connectedToContext=!1;GetMaximumAudioLevel(){return Math.max(this.LeftChannel,this.RightChannel)}GetAverageAudioLevel(){return(this.LeftChannel+this.RightChannel)/2}Create(e){this.source=e.createBufferSource(),this.source.buffer=this.audio}AddAudioNode(e){if(!this.source)throw new Error("Source not created yet!");this.nodes.push(e)}GetNode(e){let t=this.nodes.filter((t=>t instanceof e));return t.length>0?t:null}ConnectToContext(e,t){if(!this.source)throw new Error("Source not created yet!");this._connectedToContext||(this._connectedToContext=!0,this.nodes.length>0?t?t(this.nodes,this.source):this.nodes.forEach(((t,i)=>{this.source.connect(t),t instanceof AnalyserNode||t.connect(e.destination)})):this.source.connect(e.destination))}Play(){if(!this.source)throw new Error("Source not created yet!");if(!this._connectedToContext)throw new Error("Not connected to audio context yet!");this.source.start(0,this.pausedTime),this.isPlaying=!0,this.isPaused=!1,this.timeStarted=Date.now()-this.pausedTime,this.pausedTime=0}Pause(){if(!this.source)throw new Error("Source not created yet!");if(!this._connectedToContext)throw new Error("Not connected to audio context yet!");this.pausedTime=Date.now()-this.timeStarted,this.source.stop(0),this.isPaused=!0,this.isPlaying=!1}Stop(){if(!this.source)throw new Error("Source not created yet!");if(!this._connectedToContext)throw new Error("Not connected to audio context yet!");this.source.stop(0),this.isPlaying=!1}RegisterEndCallBack(e){if(!this.source)throw new Error("Source not created yet!");this.source.onended=()=>{this.isPaused||e()}}}t.Audio=i;t.MapAudio=class extends i{beatmap;fadingOut=!1;fadeOutTimeout;playingCallback}},85437:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.AudioEngine=void 0;const n=i(14981),s=i(65918),a=i(17898),o=i(20825),r=i(87816),l=i(22331);t.AudioEngine=class{audioContext;_playingAudios;_musicQueue=[];_audioIdTicker=0;_changeCallbacks=[];silentMusic=this.createSilentMusic();useSilentMusic=!0;constructor(){this.audioContext=new AudioContext,this._playingAudios=new n.PlayingAudios,o.Main.app.ticker.add((()=>{this.update()}))}UpdateMusicQueue(){this._musicQueue[0]&&(this._musicQueue[0].fadingOut||0!=this._musicQueue[0].timeStarted||(this._play(this._musicQueue[0]),this._changeCallbacks.forEach((e=>e()))),this._musicQueue[0].fadingOut&&this._musicQueue[1]&&this._musicQueue[1]&&(this._play(this._musicQueue[1]),this._changeCallbacks.forEach((e=>e())))),this._musicQueue.length>=1?this.useSilentMusic=!1:(this.silentMusic=this.createSilentMusic(),this.useSilentMusic=!0)}createSilentMusic(){let e=new s.MapAudio;e.timeStarted=Date.now(),e.beatmap=new a.BeatmapData;let t=new r.UnInheritedTimingPoint;return t.time=0,t.beatLength=1e3,t.effects=l.Effect.None,e.beatmap.TimingPoints.TimingPoints.push(t),e}addMusicChangeEventListener(e){this._changeCallbacks.push(e)}removeMusicChangeEventListener(e){this._changeCallbacks=this._changeCallbacks.filter((t=>t!=e))}GetCurrentPlayingMusic(){return this.useSilentMusic?this.silentMusic:this._musicQueue[0]}PlayEffect(e,t){let i=new s.Audio;i.audio=e,i.id=this._audioIdTicker,this._play(i,t),this._audioIdTicker++}AddToMusicQueue(e,t,i){let n=new s.MapAudio;return n.audio=e,n.beatmap=t,n.id=this._audioIdTicker,i&&(n.playingCallback=i),this._musicQueue.push(n),this._audioIdTicker++,this.UpdateMusicQueue(),n.id}PlayMusicImmediately(e,t,i){this._musicQueue=[],this.AddToMusicQueue(e,t,i)}update(){let e=this.GetCurrentPlayingMusic();if(!this.useSilentMusic){let t=e.GetNode(AnalyserNode)[0],i=e.GetNode(AnalyserNode)[1],n=e.GetNode(AnalyserNode)[2];t.getFloatFrequencyData(e.tempArrayMain);for(let t=0;t{s+=(e+1)/2})),e.tempArrayR.forEach((e=>{a+=(e+1)/2})),s/=e.tempArrayL.length,a/=e.tempArrayR.length,e.LeftChannel=s,e.RightChannel=a}}_play(e,t){if(e.Create(this.audioContext),"beatmap"in e&&e.beatmap){this._playingAudios.audios.forEach((e=>{if("beatmap"in e&&e.beatmap){clearTimeout(e.fadeOutTimeout),e.fadingOut=!0;let t=e.GetNode(GainNode);if(null==t)throw new Error("Gain Node doesn't exist on Audio Object!");t[0].gain.linearRampToValueAtTime(0,this.audioContext.currentTime+.4),setTimeout((()=>{e.Stop()}),400)}}));let t=this.audioContext.createGain();t.gain.value=0;let i=this.audioContext.createAnalyser();i.fftSize=512,i.smoothingTimeConstant=0;let n=this.audioContext.createChannelSplitter(2),s=this.audioContext.createAnalyser();s.smoothingTimeConstant=0,s.fftSize=128;let a=this.audioContext.createAnalyser();a.smoothingTimeConstant=0,a.fftSize=128,e.AddAudioNode(t),e.AddAudioNode(i),e.AddAudioNode(s),e.AddAudioNode(a),e.ConnectToContext(this.audioContext,((e,o)=>{o.connect(t),t.connect(this.audioContext.destination),o.connect(i),o.connect(n),n.connect(s,0),n.connect(a,1)})),e.Play(),this._playingAudios.audios.push(e),e.playingCallback&&e.playingCallback(),t.gain.linearRampToValueAtTime(1,this.audioContext.currentTime+.4),e.fadeOutTimeout=setTimeout((()=>{t.gain.linearRampToValueAtTime(0,this.audioContext.currentTime+.4)}),1e3*(e.audio.duration-.4))}else e.ConnectToContext(this.audioContext),t&&e.source&&(e.source.playbackRate.value=t),e.Play(),this._playingAudios.audios.push(e);e.RegisterEndCallBack((()=>{e.isPlaying=!1,"beatmap"in e&&e.beatmap&&(this._musicQueue[0]==e&&this._musicQueue.splice(0,1),this.UpdateMusicQueue()),this._playingAudios.audios.forEach(((t,i)=>{t!==e||this._playingAudios.audios.splice(i,1)}))}))}}},14981:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.PlayingAudios=void 0;t.PlayingAudios=class{audios=[]}},9611:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.LogoVisualizer=void 0;const o=i(20825),r=a(i(58687)),l=i(5825),u=i(22331);class c extends r.Container{static size=900;frequencyAmplitudes=new Float32Array(256);audio;temporalAmplitudes=new Float32Array(256);graphics=new r.Graphics;index_change=5;bar_length=600;bars_per_visualiser=200;visualiser_rounds=5;decay_per_millisecond=.0024;time_between_updates=50;amplitude_dead_zone=1/this.bar_length;indexOffset=0;firstDraw=!0;start(){this.graphics.blendMode="add",this.addChild(this.graphics),this.graphics.eventMode="none",this.eventMode="none",setInterval((()=>{this.updateAmplitudes()}),this.time_between_updates)}draw(e){if(this.firstDraw)for(let e=0;ethis.frequencyAmplitudes[t]&&(this.frequencyAmplitudes[t]=i)}this.indexOffset=(this.indexOffset+this.index_change)%this.bars_per_visualiser}}t.LogoVisualizer=c},8211:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.MenuLogoVisualizer=void 0;const n=i(9611);class s extends n.LogoVisualizer{draw(e){super.draw(e)}}t.MenuLogoVisualizer=s},49323:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.LoadAnim=void 0;const o=a(i(58687)),r=a(i(29172)),l=i(92915);class u extends o.Container{bg;arc;arcContainer;animInterval;container;bgContainer;bgRotation=0;constructor(e,t){super(),this.pivot.set(.5,.5),this.container=new o.Container,this.container.alpha=0,this.rotation=2.5*Math.PI,this.bgContainer=new o.Container,this.bg=new o.Graphics,this.bg.roundRect(-50,-50,100,100,25),this.bg.fill(e),this.arcContainer=new o.Container,this.arc=new o.Graphics,this.arc.arc(0,0,27,Math.PI+.26,2.92*Math.PI),this.arc.stroke({width:8,color:t,cap:"round"}),this.arc.scale.set(-1,1),this.container.scale.set(.5,.5),this.bgContainer.addChild(this.bg),this.arcContainer.addChild(this.arc),this.bgContainer.addChild(this.arcContainer),this.container.addChild(this.bgContainer),this.addChild(this.container),l.Ease.getEase(this.container).ScaleTo(1,400,r.Easing.Quadratic.InOut).FadeIn(400,r.Easing.Quadratic.InOut),this.doAnims(),this.animInterval=setInterval((()=>{this.doAnims()}),800)}doAnims(){this.bgRotation+=90,l.Ease.getEase(this.bgContainer).createTween({value:this.bgContainer.angle},{value:this.bgRotation},!0,"angle",600,r.Easing.Quadratic.InOut)}getWidth(){return 100*this.scale.x}getHeight(){return 100*this.scale.y}draw(e){this.arcContainer.angle+=3*e.deltaTime}destroy(e){l.Ease.getEase(this.container).FadeOut(400,r.Easing.Quadratic.InOut).ScaleTo(.5,400,r.Easing.Quadratic.InOut),setTimeout((()=>{clearInterval(this.animInterval),super.destroy(e)}),400)}}t.LoadAnim=u},16982:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.Menu=void 0;const o=a(i(58687)),r=a(i(29172)),l=i(92915);class u extends o.Container{menuBG=new o.Graphics;isOpened=!1;constructor(){super(),this.menuBG.rect(0,-62.5,1,125),this.menuBG.fill({color:"rgb(50,50,50)"}),this.menuBG.scale.set(1,0),this.menuBG.alpha=0,this.addChild(this.menuBG)}Open(){this.isOpened=!0,l.Ease.getEase(this.menuBG).ScaleTo(1,400,r.Easing.Quintic.Out).FadeIn(400,r.Easing.Quintic.Out)}Close(){this.isOpened=!1,l.Ease.getEase(this.menuBG).ClearEasings().ScaleTo({x:1,y:0},300,r.Easing.Sinusoidal.In).FadeOut(300,r.Easing.Sinusoidal.In)}isOpen(){return this.isOpened}onResize(){this.position.set(-window.innerWidth,0),this.menuBG.width=2*window.innerWidth}}t.Menu=u},54349:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.OsuCircle=void 0;const o=a(i(58687)),r=i(44961),l=a(i(29172)),u=i(92915),c=i(20825),d=i(12235),h=i(16982),g=i(8211),f=i(9611),p=i(22331),m=i(5825);class v extends o.Container{outline;visualizer=new g.MenuLogoVisualizer;triangles=new r.Triangles;flash;logoContainer=new o.Container;logoBounceContainer=new o.Container;logoBeatContainer=new o.Container;logoAmplitudeContainer=new o.Container;logoHoverContainer=new o.Container;rippleContainer=new o.Container;ripple;menu=new h.Menu;defaultVisualizerAlpha=.5;early_activation=60;timeElapsedSinceLastBeat=0;timeUntilNextBeat=0;lastTimeElapasedSinceLastBeat=0;selectSample=d.Loader.GetAudio("mainMenu.osuLogo.select");backToLogoSample=d.Loader.GetAudio("mainMenu.osuLogo.backToLogo");isMouseDown=!1;mouseDownPosition={x:0,y:0};constructor(){super(),this.visualizer.start(),this.outline=o.Sprite.from("mainMenu.logoOutline"),this.outline.anchor.set(.5,.5);let e=.6;this.visualizer.scale.set(e),this.visualizer.pivot.set(f.LogoVisualizer.size/2,f.LogoVisualizer.size/2),this.visualizer.alpha=this.defaultVisualizerAlpha;let t=new o.Graphics;t.circle(0,0,450),t.fill({color:"white"}),t.scale=e,this.flash=o.Sprite.from("mainMenu.logoMask"),this.flash.anchor.set(.5,.5),this.flash.scale=e,this.flash.blendMode="add",this.flash.alpha=0,this.triangles.flash.anchor.set(.5,.5),this.triangles.flash.scale=e,this.outline.scale.set(e),this.triangles.scale.set(e),this.triangles.position.set(-this.outline.width/2,-this.outline.height/2),this.triangles.mask=t,this.ripple=o.Sprite.from("mainMenu.logoMask"),this.ripple.anchor.set(.5,.5),this.ripple.scale=e,this.ripple.alpha=0,this.ripple.blendMode="add",this.rippleContainer.addChild(this.ripple),this.logoContainer.addChild(this.visualizer),this.logoContainer.addChild(this.triangles),this.logoContainer.addChild(this.triangles.flash),this.logoContainer.addChild(t),this.logoContainer.addChild(this.flash),this.logoContainer.addChild(this.outline),this.logoContainer.hitArea=new o.Circle(0,0,288),this.logoContainer.eventMode="static",this.logoContainer.onmouseenter=this._onmouseenter,this.logoContainer.onmouseleave=this._onmouseleave,this.logoContainer.onmousedown=this._onmousedown,this.logoContainer.onclick=this._onclick,this.logoBeatContainer.addChild(this.logoContainer),this.logoAmplitudeContainer.addChild(this.logoBeatContainer),this.logoBounceContainer.addChild(this.rippleContainer),this.logoBounceContainer.addChild(this.logoAmplitudeContainer),this.logoHoverContainer.addChild(this.logoBounceContainer),this.addChild(this.logoHoverContainer),c.Main.app.stage.addEventListener("mouseup",(e=>{this._onmouseup(e)}))}_onmouseenter=e=>{u.Ease.getEase(this.logoHoverContainer).ScaleTo(1.1,500,l.Easing.Elastic.Out)};_onmouseleave=e=>{u.Ease.getEase(this.logoHoverContainer).ScaleTo(1,500,l.Easing.Elastic.Out)};_onmousedown=e=>{this.isMouseDown=!0,u.Ease.getEase(this.logoBounceContainer).ClearEasings().ScaleTo(.9,1e3,l.Easing.Sinusoidal.Out),this.mouseDownPosition={x:c.Main.mousePos.x,y:c.Main.mousePos.y}};_onclick=e=>{this.flash.alpha=.4,u.Ease.getEase(this.flash).ClearEasings().FadeOut(1500,l.Easing.Exponential.Out)};_onmouseup=e=>{this.isMouseDown=!1,u.Ease.getEase(this.logoBounceContainer).ClearEasings().ScaleTo(1,500,l.Easing.Elastic.Out).TransformTo({x:0,y:0},800,l.Easing.Elastic.Out)};onResize(){this.menu.onResize()}draw(e){this.visualizer.draw(e),this.triangles.draw(e);let t=c.Main.AudioEngine.GetCurrentPlayingMusic(),i=t.beatmap.TimingPoints.GetCurrentUninheritedTimingPoint(Date.now()-t.timeStarted);if(this.timeUntilNextBeat=(i.time-(Date.now()-t.timeStarted))%i.beatLength,this.timeUntilNextBeat<=0&&(this.timeUntilNextBeat+=i.beatLength),this.timeElapsedSinceLastBeat=i.beatLength-this.timeUntilNextBeat,c.Main.AudioEngine.useSilentMusic)this.logoAmplitudeContainer.scale=1,this.triangles.Velocity=m.MathUtil.Damp(this.triangles.Velocity,.5,.9,e.deltaMS);else{let n=t.GetMaximumAudioLevel();this.logoAmplitudeContainer.scale.set(m.MathUtil.Damp(this.logoAmplitudeContainer.scale.x,1-.04*Math.max(0,n-.4),.9,e.deltaMS)),this.triangles.Velocity=m.MathUtil.Damp(this.triangles.Velocity,.5*(i.effects==p.Effect.KiaiTime?4:2),.995,e.deltaMS)}if(this.lastTimeElapasedSinceLastBeat>this.timeElapsedSinceLastBeat&&this.onNewBeat(),this.lastTimeElapasedSinceLastBeat=this.timeElapsedSinceLastBeat,this.isMouseDown){let e={x:c.Main.mousePos.x-this.mouseDownPosition.x,y:c.Main.mousePos.y-this.mouseDownPosition.y},t=Math.sqrt(e.x*e.x+e.y*e.y);e.x*=t<=0?0:Math.pow(t,.6)/t,e.y*=t<=0?0:Math.pow(t,.6)/t,this.logoBounceContainer.x=e.x,this.logoBounceContainer.y=e.y}}onNewBeat(){let e=c.Main.AudioEngine.GetCurrentPlayingMusic(),t=e.beatmap.TimingPoints.GetCurrentUninheritedTimingPoint(Date.now()-e.timeStarted).beatLength,i=e.beatmap.TimingPoints.GetCurrentTimingPoints(Date.now()-e.timeStarted)[0],n=c.Main.AudioEngine.useSilentMusic?0:e.GetMaximumAudioLevel(),s=Math.min(1,.4+n);u.Ease.getEase(this.logoBeatContainer).ScaleTo(1-.02*s,this.early_activation,l.Easing.Linear.None).Then().ScaleTo(1,2*t,l.Easing.Quintic.Out),this.rippleContainer.scale=1.02,u.Ease.getEase(this.rippleContainer).ClearEasings().ScaleTo(1.02*(1+.04*s),2*t,l.Easing.Quintic.Out),this.ripple.alpha=.15*s,u.Ease.getEase(this.ripple).ClearEasings().FadeOut(t,l.Easing.Quintic.Out),i.effects==p.Effect.KiaiTime&&(u.Ease.getEase(this.triangles.flash).ClearEasings().FadeTo(.2*s,this.early_activation,l.Easing.Linear.None).Then().FadeTo(0,t,l.Easing.Linear.None),u.Ease.getEase(this.visualizer).ClearEasings().FadeTo(1.8*this.defaultVisualizerAlpha*s,this.early_activation,l.Easing.Linear.None).Then().FadeTo(this.defaultVisualizerAlpha,t,l.Easing.Linear.None)),setTimeout((()=>{this.triangles.Velocity+=s*(i.effects==p.Effect.KiaiTime?6:3)}),60)}}t.OsuCircle=v},44961:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t},o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.Triangles=void 0;const r=a(i(58687)),l=i(20825),u=o(i(46404)),c=o(i(58689)),d=o(i(61630));class h extends r.Container{flash;Velocity=1;bgGradient;triangles=[];graphics=new r.Graphics;timeSinceLastSpawn=0;instancePositionBuffer;totalTriangles=15;constructor(){super();let e=[16737963,13390473];this.bgGradient=new r.FillGradient(0,0,0,1024),e.forEach(((t,i)=>{const n=i/e.length;this.bgGradient.addColorStop(n,t)}));for(let e=0;e{this.mouseButtonClicked=e.button,this.visible&&(this.posMouseDown={x:r.Main.mousePos.x,y:r.Main.mousePos.y},this.mouseIsDown=!0,this.dragRotationState=f.DragStarted,d.Ease.getEase(this.animContainer).ClearEasings().ScaleTo(.9,800,h.Easing.Quintic.Out),d.Ease.getEase(this.mouseCursorAdditive).ClearEasings().FadeIn(800,h.Easing.Quintic.Out),r.Main.AudioEngine.PlayEffect(this.cursorTapSample))})),r.Main.app.stage.addEventListener("mouseup",(e=>{this.visible&&e.button==this.mouseButtonClicked&&(this.mouseIsDown=!1,d.Ease.getEase(this.animContainer).ClearEasings().ScaleTo(1,500,h.Easing.Elastic.Out),d.Ease.getEase(this.mouseCursorAdditive).ClearEasings().FadeOut(500,h.Easing.Quintic.Out),this.dragRotationState!=f.NotDragging&&(this.dragRotationState==f.Rotating&&d.Ease.getEase(this.animRotationContainer).ClearEasings().createTween({value:this.animRotationContainer.angle},{value:0},!0,"angle",800*(.5+Math.abs(this.animRotationContainer.angle/960)),(e=>Math.pow(2,-10*e)*Math.sin((.25*e-this.elastic_const2)*this.elastic_const)+1-this.elastic_offset_quarter*e)),this.dragRotationState=f.NotDragging),r.Main.AudioEngine.PlayEffect(this.cursorTapSample,.8))}))}PopIn(){d.Ease.getEase(this.animRotationContainer).ClearEasings(),this.visible=!0,d.Ease.getEase(this.mouseHideContainer).ClearEasings().FadeIn(250,h.Easing.Quintic.Out).ScaleTo(1,400,h.Easing.Quintic.Out),this.dragRotationState=f.NotDragging}PopOut(){d.Ease.getEase(this.mouseHideContainer).ClearEasings().FadeOut(250,h.Easing.Quintic.Out).ScaleTo(.6,250,h.Easing.Quintic.Out),d.Ease.getEase(this.animRotationContainer).ClearEasings().createTween({value:this.animRotationContainer.angle},{value:0},!0,"angle",400,h.Easing.Quintic.Out),this.dragRotationState=f.NotDragging}updateMouse(){if(this.mouseContainer.scale.set(.07*c.Screen.getScaleBasedOffScreenSize()),this.position.set(r.Main.mousePos.x,r.Main.mousePos.y),this.dragRotationState!=f.NotDragging&&this.visible){let e=Math.sqrt((2^Math.abs(this.posMouseDown.x-r.Main.mousePos.x))+(2^Math.abs(this.posMouseDown.y-r.Main.mousePos.y)));if(this.dragRotationState==f.DragStarted&&e>15&&(this.dragRotationState=f.Rotating,this.lastDragRotationState!=this.dragRotationState&&(this.posMouseDown={x:r.Main.mousePos.x,y:r.Main.mousePos.y})),this.dragRotationState==f.Rotating&&e>0){let e=r.Main.mousePos.x-this.posMouseDown.x,t=r.Main.mousePos.y-this.posMouseDown.y,i=u.MathUtil.RadiansToDegrees(Math.atan2(-e,t))+24.3,n=(i-this.animRotationContainer.angle)%360;n<-180&&(n+=360),n>180&&(n-=360),i=this.animRotationContainer.angle+n,this.animRotationContainer.angle=i,d.Ease.getEase(this.animRotationContainer).createTween({value:this.animRotationContainer.angle},{value:i},!0,"angle",120,h.Easing.Quintic.Out)}}this.lastDragRotationState=this.dragRotationState}}var f;t.MenuCursor=g,function(e){e[e.NotDragging=0]="NotDragging",e[e.DragStarted=1]="DragStarted",e[e.Rotating=2]="Rotating"}(f||(f={}))},67991:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.Background=void 0;const o=a(i(58687)),r=i(92915),l=a(i(29172));class u extends o.Sprite{constructor(e){super(),this.texture=e,this.visible=!1,this.anchor.set(.5,.5)}show(){this.visible=!0}destroy(e){r.Ease.getEase(this).FadeOut(800,l.Easing.Linear.None).Then((()=>{this.visible=!1,super.destroy(e)})),this.zIndex=1}}t.Background=u},36721:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.RandomBackground=void 0;const o=a(i(58687)),r=i(12235),l=i(84283),u=i(20825),c=i(67991);class d extends l.Screen{bgContainer=new o.Container;parallaxMultiplier=60;start(){this.bgContainer.pivot.set(.5,.5),this.bgContainer.position.set((u.Main.mousePos.x-this.getScreenWidth()/2)/this.parallaxMultiplier,(u.Main.mousePos.y-this.getScreenHeight()/2)/this.parallaxMultiplier),this.addChild(this.bgContainer),this.newRandomBG(),u.Main.AudioEngine.addMusicChangeEventListener((()=>{this.newRandomBG()})),this.zIndex=-100}setBG(e){let t=new c.Background(e);if(this.bgContainer.addChild(t),t.show(),0==this.bgContainer.children?.length);else{this.bgContainer.children[0].destroy()}this.onResize()}newRandomBG(){let e=r.Loader.seasonalBackgroundsNum>0,t=(i=1,n=e?r.Loader.seasonalBackgroundsNum:r.Loader.defaultBackgroundsNum,Math.round(Math.random()*(n-i)+i));var i,n;this.setBG(o.Texture.from((e?"seasonal_bg":"default_bg")+t))}draw(e){this.bgContainer.position.set((u.Main.mousePos.x-this.getScreenWidth()/2)/this.parallaxMultiplier,(u.Main.mousePos.y-this.getScreenHeight()/2)/this.parallaxMultiplier)}onClose(){return Promise.resolve(this)}onResize(){this.bgContainer.children.forEach((e=>{if(e instanceof c.Background){let t,i=e.texture.width,n=e.texture.height;t=window.innerWidth>window.innerHeight?window.innerWidth/i:window.innerHeight/n,n*t{i.id==e&&(t=i.data)})),!t)throw new Error("Asset not found!");return t}static GetString(e){let t;if(this.loadedList.forEach((i=>{i.id==e&&(t=i.dataString)})),!t)throw new Error("Asset not found or is not a string!");return t}static GetAudio(e){let t;if(this.loadedList.forEach((i=>{i.id==e&&(t=i.dataAudio)})),!t)throw new Error("Asset not found or was not marked as audio during loading!");return t}static addBackgrounds(){return new Promise((e=>{for(let e=1;ee.json())).then((t=>{t.backgrounds.forEach(((e,t)=>{this.loadList.push({id:"seasonal_bg"+(t+1),url:"https://corsproxy.io/?"+encodeURIComponent(e.url),pixiBundleName:"textures",loadParser:"loadTextures"}),this.seasonalBackgroundsNum=t+1})),e()})).catch((t=>{console.warn("Could not fetch seasonal backgrounds.",t),e()}))}))}static Load(e){return this.addToLoadList(),new Promise((t=>{this.addBackgrounds().then((()=>{let i=[],n=[],s=[],a=0,r=0;this.loadList.forEach((e=>{e.pixiBundleName?n.push(e):i.push(e)})),n.forEach((e=>{let t=!1;s.forEach((i=>{i.length>0&&i[0].pixiBundleName==e.pixiBundleName&&(i.push(e),t=!0)})),t||s.push([e])}));const l=e=>{e?r++:a++,r+a>=this.loadList.length&&t()};i.forEach((t=>{fetch(t.url).then((e=>e.blob())).then((i=>{t.isText||t.isAudio?t.isText?i.text().then((e=>{l(),this.loadedList.push({id:t.id,data:i,dataString:e})})):t.isAudio&&i.arrayBuffer().then((t=>e.decodeAudioData(t))).then((e=>{l(),this.loadedList.push({id:t.id,data:i,dataAudio:e})})):(l(),this.loadedList.push({id:t.id,data:i}))})).catch((e=>{l(!0),console.warn("Asset '"+t.id+"' failed to load: "+e)}))})),s.forEach((e=>{if(e.length>0){if(!e[0].pixiBundleName)throw new Error("wtf????");let t=[];e.forEach((e=>{e.loadParser?t.push({alias:e.id,src:e.url,loadParser:e.loadParser}):t.push({alias:e.id,src:e.url})})),o.Assets.addBundle(e[0].pixiBundleName,t),o.Assets.loadBundle(e[0].pixiBundleName).then((()=>{e.forEach((()=>{l()}))}))}}))}))}))}}},25373:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.InteractScreen=void 0;const o=i(84283),r=a(i(58687)),l=i(20825),u=i(94433),c=a(i(29172)),d=i(92915);class h extends o.Screen{text;text2;textContainer=new r.Container;textContainerContainer=new r.Container;introTrack;clickSound;clickArea=new r.Graphics;constructor(e,t){super(),this.introTrack=e,this.clickSound=t,this.text=new r.Text({text:"Click anywhere to play!",style:{fontFamily:"TorusRegular",fontSize:36,fill:"white"}}),this.text2=new r.Text({text:"(this is for enabling audio because it's required by web-browsers\n to have interaction on this webpage before playing audio.)",style:{fontFamily:"TorusRegular",fontSize:26,fill:"gray",align:"center"}})}start(){this.text.anchor.set(.5,.5),this.text2.anchor.set(.5,.5),this.text2.position.set(0,this.text.height+15),this.textContainer.addChild(this.text),this.textContainer.addChild(this.text2),this.textContainer.scale.set(.5),this.textContainer.alpha=0,this.textContainerContainer.addChild(this.textContainer),this.textContainerContainer.scale=o.Screen.getScaleBasedOffScreenSize(),this.textContainerContainer.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),this.addChild(this.textContainerContainer),this.clickArea.rect(0,0,1,1),this.clickArea.fill("rgba(0,0,0,0)"),this.clickArea.width=this.getScreenWidth(),this.clickArea.height=this.getScreenHeight(),this.clickArea.position.set(0,0),this.addChild(this.clickArea),this.clickArea.eventMode="static",this.clickArea.cursor="pointer";const e=()=>{this.clickArea.eventMode="none",l.Main.AudioEngine.PlayEffect(this.clickSound),l.Main.switchScreen(new u.IntroScreen(this.introTrack)),document.body.style.cursor="none",l.Main.pointerLock(),l.Main.lockKeyboard()};this.clickArea.onclick=()=>{e()},this.clickArea.ontap=()=>{e()},d.Ease.getEase(this.textContainer).FadeIn(400,c.Easing.Quadratic.Out).ScaleTo(1,400,c.Easing.Quadratic.Out)}onClose(){return new Promise((e=>{d.Ease.getEase(this.textContainer).FadeOut(200,c.Easing.Quadratic.Out).ScaleTo(.5,200,c.Easing.Quadratic.InOut),setTimeout((()=>{e(this)}),200)}))}draw(e){}onResize(){this.textContainerContainer.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),this.clickArea.width=this.getScreenWidth(),this.clickArea.height=this.getScreenHeight(),this.clickArea.position.set(0,0),this.textContainerContainer.scale=o.Screen.getScaleBasedOffScreenSize()}}t.InteractScreen=h},88662:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.GlitchingTriangles=void 0;const o=a(i(58687)),r=i(92915),l=a(i(29172));class u extends o.Container{constructor(e){super();let t=new o.Graphics,i=n(.2,1.2);function n(e,t){return Math.random()*(t-e)+e}t.moveTo(0,0),t.lineTo(-50*i,100*i),t.lineTo(50*i,100*i),t.lineTo(0,0),Math.random()<.5?t.fill("white"):t.stroke({color:"white",width:1});let s=n(e.x1,e.x2),a=n(e.y1,e.y2);t.position.set(s,a),r.Ease.getEase(t,!0).FadeOut(200,l.Easing.Linear.None),setTimeout((()=>{this.destroy()}),200),this.addChild(t)}}t.GlitchingTriangles=u},94433:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.IntroScreen=void 0;const o=i(84283),r=a(i(58687)),l=i(53931),u=i(20825),c=i(88662),d=i(58940),h=i(55402),g=i(9752),f=a(i(29172)),p=i(92915);class m extends o.Screen{introTrackUrl;doTextSpacingAnim=!1;triangles=new r.Container;ruleSetContainer=new r.Container;flash=new r.Graphics;logoContainerContainer=new r.Container;logoContainer=new r.Container;lazerLogo=new h.LazerLogo;flashed=!1;standard=r.Sprite.from("icon_ruleset_std");taiko=r.Sprite.from("icon_ruleset_taiko");ctb=r.Sprite.from("icon_ruleset_ctb");mania=r.Sprite.from("icon_ruleset_mania");bg=new r.Graphics;completionPromise;welcomeText=new r.Text({text:"",style:{fontFamily:"TorusThin",fontSize:42,fill:"white",letterSpacing:5}});constructor(e){super(),this.introTrackUrl=URL.createObjectURL(e),this.bg.rect(0,0,1,1),this.bg.fill("black")}start(){this.bg.width=window.innerWidth,this.bg.height=window.innerHeight,this.bg.x=0,this.bg.y=0,this.addChild(this.bg),this.lazerLogo.scale.set(o.Screen.getScaleBasedOffScreenSize()),this.logoContainer.addChild(this.lazerLogo),this.logoContainer.scale.set(1.2),this.logoContainerContainer.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),this.logoContainerContainer.pivot.set(.5,.5),this.logoContainerContainer.addChild(this.logoContainer),this.logoContainerContainer.alpha=0,this.addChild(this.logoContainerContainer),this.flash.rect(0,0,1,1),this.flash.fill("white"),this.flash.position.set(0,0),this.flash.width=this.getScreenWidth(),this.flash.height=this.getScreenHeight(),this.flash.blendMode="add",this.welcomeText.anchor.set(.5,.5),this.welcomeText.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),setTimeout((async()=>{const{entries:e}=await(0,l.unzip)(this.introTrackUrl);for(const[t,i]of Object.entries(e))if(t.endsWith(".osu")){i.text().then((t=>{let i=g.BeatmapParser.Parse(t);console.log(i);for(const[t,n]of Object.entries(e))t==i.General.AudioFileName&&n.arrayBuffer().then((e=>u.Main.AudioEngine.audioContext.decodeAudioData(e))).then((e=>{u.Main.AudioEngine.PlayMusicImmediately(e,i,(()=>{this.afterAudioPlay()}))}))}));break}}),0)}afterAudioPlay(){this.completionPromise=new Promise((e=>{let t;this.welcomeText.scale.set(o.Screen.getScaleBasedOffScreenSize()),this.addChild(this.welcomeText),setTimeout((()=>{this.welcomeText.text="wel",this.onResize()}),200),setTimeout((()=>{this.welcomeText.text="welcome",this.onResize()}),400),setTimeout((()=>{this.welcomeText.text="welcome to",this.onResize()}),700),this.triangles.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),this.triangles.scale.set(o.Screen.getScaleBasedOffScreenSize()),this.addChild(this.triangles),setTimeout((()=>{this.welcomeText.text="welcome to kosu!",this.doTextSpacingAnim=!0,t=setInterval((()=>{let e=new c.GlitchingTriangles({x1:-this.welcomeText.width/2-100,x2:this.welcomeText.width/2+100,y1:-this.welcomeText.height/2-150,y2:this.welcomeText.height/2+100});this.triangles.addChild(e)}),30),this.onResize()}),900),this.standard.anchor.set(.5,.5),this.standard.scale.set(.4*o.Screen.getScaleBasedOffScreenSize()),this.ruleSetContainer.addChild(this.standard),this.taiko.anchor.set(.5,.5),this.taiko.scale.set(.4*o.Screen.getScaleBasedOffScreenSize()),this.ruleSetContainer.addChild(this.taiko),this.ctb.anchor.set(.5,.5),this.ctb.scale.set(.4*o.Screen.getScaleBasedOffScreenSize()),this.ruleSetContainer.addChild(this.ctb),this.mania.anchor.set(.5,.5),this.mania.scale.set(.4*o.Screen.getScaleBasedOffScreenSize()),this.ruleSetContainer.addChild(this.mania),setTimeout((()=>{this.doTextSpacingAnim=!1,this.onResize(),clearInterval(t),this.welcomeText.destroy(),this.triangles.destroy(),this.ruleSetContainer.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),this.addChild(this.ruleSetContainer);this.standard.position.set(-375*o.Screen.getScaleBasedOffScreenSize(),0),this.taiko.position.set(-125*o.Screen.getScaleBasedOffScreenSize(),0),this.ctb.position.set(125*o.Screen.getScaleBasedOffScreenSize(),0),this.mania.position.set(375*o.Screen.getScaleBasedOffScreenSize(),0),p.Ease.getEase(this.ruleSetContainer).ScaleTo(.8,1e3,f.Easing.Linear.None)}),1450),setTimeout((()=>{this.standard.position.set(-240*o.Screen.getScaleBasedOffScreenSize(),0),this.taiko.position.set(-75*o.Screen.getScaleBasedOffScreenSize(),0),this.ctb.position.set(75*o.Screen.getScaleBasedOffScreenSize(),0),this.mania.position.set(240*o.Screen.getScaleBasedOffScreenSize(),0),this.standard.scale.set(o.Screen.getScaleBasedOffScreenSize()),this.taiko.scale.set(o.Screen.getScaleBasedOffScreenSize()),this.ctb.scale.set(o.Screen.getScaleBasedOffScreenSize()),this.mania.scale.set(o.Screen.getScaleBasedOffScreenSize())}),1650),setTimeout((()=>{this.standard.position.set(-350*o.Screen.getScaleBasedOffScreenSize(),0),this.taiko.position.set(-120*o.Screen.getScaleBasedOffScreenSize(),0),this.ctb.position.set(120*o.Screen.getScaleBasedOffScreenSize(),0),this.mania.position.set(350*o.Screen.getScaleBasedOffScreenSize(),0),this.standard.scale.set(2*o.Screen.getScaleBasedOffScreenSize()),this.taiko.scale.set(2*o.Screen.getScaleBasedOffScreenSize()),this.ctb.scale.set(2*o.Screen.getScaleBasedOffScreenSize()),this.mania.scale.set(2*o.Screen.getScaleBasedOffScreenSize()),p.Ease.getEase(this.ruleSetContainer).ScaleTo(1.3,1e3,f.Easing.Linear.None)}),1850),setTimeout((()=>{this.ruleSetContainer.destroy(),this.lazerLogo.start(),this.logoContainerContainer.alpha=1,this.logoContainerContainer.scale.set(1.2),p.Ease.getEase(this.logoContainerContainer).ScaleTo(1,920,f.Easing.Quadratic.In),setTimeout((()=>{p.Ease.getEase(this.logoContainer).ScaleTo(1.2-.8,276,f.Easing.Quintic.In)}),644)}),2080),setTimeout((()=>{this.addChild(this.flash),this.bg.destroy(),this.flash.eventMode="none",this.flashed=!0,this.logoContainerContainer.visible=!1,p.Ease.getEase(this.flash).FadeOut(1e3,f.Easing.Quadratic.Out).Then((()=>{e()})),u.Main.cursor.PopIn()}),3e3)})),u.Main.switchScreen(new d.MainMenu)}draw(e){this.doTextSpacingAnim&&(this.welcomeText.style.letterSpacing+=.15*e.deltaTime,this.onResize())}onClose(){return new Promise((e=>{this.completionPromise.then((()=>{e(this)}))}))}onResize(){this.bg.destroyed||(this.bg.width=window.innerWidth,this.bg.height=window.innerHeight,this.bg.x=0,this.bg.y=0),this.welcomeText.destroyed||this.welcomeText.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),this.triangles.destroyed||(this.triangles.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),this.triangles.scale.set(o.Screen.getScaleBasedOffScreenSize())),this.ruleSetContainer.destroyed||this.ruleSetContainer.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),!this.flash.destroyed&&this.flashed&&(this.flash.position.set(0,0),this.flash.width=this.getScreenWidth(),this.flash.height=this.getScreenHeight()),this.logoContainerContainer.destroyed||this.logoContainerContainer.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),this.lazerLogo.destroyed||this.lazerLogo.scale.set(o.Screen.getScaleBasedOffScreenSize()),this.welcomeText.destroyed||this.welcomeText.scale.set(o.Screen.getScaleBasedOffScreenSize()),this.standard.destroyed||this.standard.scale.set(.4*o.Screen.getScaleBasedOffScreenSize()),this.mania.destroyed||this.mania.scale.set(.4*o.Screen.getScaleBasedOffScreenSize()),this.ctb.destroyed||this.ctb.scale.set(.4*o.Screen.getScaleBasedOffScreenSize()),this.taiko.destroyed||this.taiko.scale.set(.4*o.Screen.getScaleBasedOffScreenSize())}}t.IntroScreen=m},55402:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.LazerLogo=void 0;const o=a(i(58687)),r=i(87525),l=a(i(29172)),u=i(92915);class c extends o.Container{highlight;background;textureHighlight=o.Texture.from("intro_triangles_osuLogo_anim_highlight");textureBackground=o.Texture.from("intro_triangles_osuLogo_anim_background");constructor(){super(),this.highlight=new r.LogoAnimation(this.textureHighlight,new o.Color("white")),this.background=new r.LogoAnimation(this.textureBackground,new o.Color("rgb(128, 128, 128)")),this.addChild(this.highlight),this.addChild(this.background)}start(){let e=new o.Container;e.scale.set(0,0),u.Ease.getEase(e).ScaleTo(1,920,l.Easing.Linear.None).OnEach((()=>{this.highlight.setProgress(e.scale.x),this.background.setProgress(e.scale.x)}))}}t.LazerLogo=c},87525:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t},o=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.LogoAnimation=void 0;const r=a(i(58687)),l=o(i(26045)),u=o(i(44160)),c=o(i(46110));class d extends r.Container{shader;texture;constructor(e,t){super(),this.texture=e,this.shader=r.Shader.from({gl:{vertex:l.default,fragment:u.default},gpu:{vertex:{entryPoint:"mainVert",source:c.default},fragment:{entryPoint:"mainFrag",source:c.default}},resources:{uTexture:this.texture.source,uSampler:this.texture.source.style,uProgress:{progress:{value:0,type:"f32"}}}});const i=new r.Geometry({attributes:{aPosition:[-this.texture.width/2,-this.texture.height/2,this.texture.width/2,-this.texture.height/2,this.texture.width/2,this.texture.width/2,-this.texture.width/2,this.texture.width/2],aUV:[0,0,1,0,1,1,0,1],aColor:[t.red,t.green,t.blue,t.alpha,t.red,t.green,t.blue,t.alpha,t.red,t.green,t.blue,t.alpha,t.red,t.green,t.blue,t.alpha]},indexBuffer:[0,1,2,0,2,3]}),n=new r.Mesh({geometry:i,shader:this.shader});this.addChild(n)}setProgress(e){this.shader.resources.uProgress.uniforms.progress=e}}t.LogoAnimation=d},76969:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.LoadScreen=void 0;const n=i(84283),s=i(49323);class a extends n.Screen{loadAnim=new s.LoadAnim("rgba(255,255,255,0.7)","black");start(){this.loadAnim.scale.set(.8*n.Screen.getScaleBasedOffScreenSize()),this.loadAnim.position.set(this.getScreenWidth()-this.loadAnim.getWidth()-15,this.getScreenHeight()-this.loadAnim.getHeight()-15),this.addChild(this.loadAnim)}draw(e){this.loadAnim?.draw(e)}onClose(){return new Promise((e=>{null!=this.loadAnim&&this.loadAnim.destroy(),setTimeout((()=>{e(this)}),400)}))}onResize(){this.loadAnim.position.set(this.getScreenWidth()-this.loadAnim.getWidth()-20,this.getScreenHeight()-this.loadAnim.getHeight()-20),this.loadAnim.scale.set(.8*n.Screen.getScaleBasedOffScreenSize())}}t.LoadScreen=a},58940:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.MainMenu=void 0;const n=i(84283),s=i(36721),a=i(54349);class o extends n.Screen{bg=new s.RandomBackground;osuCircle=new a.OsuCircle;start(){this.bg.start(),this.addChild(this.bg),this.osuCircle.scale=n.Screen.getScaleBasedOffScreenSize(),this.addChild(this.osuCircle)}draw(e){this.bg.draw(e),this.osuCircle.draw(e)}onClose(){return new Promise((e=>{this.bg.onClose().then((()=>{e(this)}))}))}onResize(){this.osuCircle.position.set(this.getScreenWidth()/2,this.getScreenHeight()/2),this.bg.onResize(),this.osuCircle.onResize(),this.osuCircle.scale=n.Screen.getScaleBasedOffScreenSize()}}t.MainMenu=o},84283:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.Screen=void 0;const o=a(i(58687)),r=i(58293),l=i(64681);class u extends o.Container{constructor(){super()}static getScaleBasedOffScreenSize(){const e=r.Settings.getSetting(l.UIScale).getValue();return(window.innerWidth/1920+window.innerHeight/1080)/2*e}getScreenWidth(){return window.innerWidth}getScreenHeight(){return window.innerHeight}}t.Screen=u},75341:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.SettingsCategory=t.Setting=void 0;const n=i(58293);var s;t.Setting=class{info;constructor(e){this.info=e,n.Settings.register({setting:this,info:e})}onValueChanged(){}},function(e){e.General="General",e.Skin="Skin",e.Input="Input",e.UserInterface="User Interface",e.Gameplay="Gameplay",e.Rulesets="Rulesets",e.Audio="Audio",e.Graphics="Graphics",e.Online="Online",e.Maintenance="Maintenance",e.Debug="Debug"}(s||(t.SettingsCategory=s={}))},74975:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.DropdownSetting=void 0;const n=i(75341),s=i(58293);class a extends n.Setting{value;getValue(){if(!this.value)throw new Error("Value is undefined!");return this.value}getDefaultValue(){return this.defaultValue}setValue(e){this.list.find((t=>t.value==e.value&&t.displayName==e.displayName))?(this.value=e,s.Settings.save(),this.onValueChanged()):console.warn("The value provided to this DropDownSetting does not exist in the option list! Ignoring value provided.")}loadFromSaveValue(e){this.list.find((t=>t.value==e.value&&t.displayName==e.displayName))?(this.value=e,this.onValueChanged()):console.warn("The value provided to this DropDownSetting does not exist in the option list! Ignoring value provided.")}}t.DropdownSetting=a},78642:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.RangeSetting=void 0;const n=i(75341),s=i(58293),a=i(5825);class o extends n.Setting{value=0;getValue(){return this.value}getDefaultValue(){return this.defaultValue}setValue(e){this.value=a.MathUtil.clamp(this.minValue,this.maxValue,e),s.Settings.save(),this.onValueChanged()}loadFromSaveValue(e){this.value=a.MathUtil.clamp(this.minValue,this.maxValue,e),this.onValueChanged()}}t.RangeSetting=o},58293:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.Settings=void 0;const n=i(64681),s=i(44256),a=i(59029);t.Settings=class{static settingsList=[];static registerAll(){new n.UIScale,new s.Renderer,new a.MouseSensitivity}static load(){let e=window.localStorage.getItem("settings");if(null==e)return;let t=this.getList();try{JSON.parse(e).forEach((e=>{let i=!1;try{e.value||(console.warn("Setting '"+JSON.stringify(e)+"' may be corrupted, skipping!"),i=!0),e.info?(e.info.name||(console.warn("Setting '"+JSON.stringify(e)+"' may be corrupted, skipping!"),i=!0),e.info.category||(console.warn("Setting '"+JSON.stringify(e)+"' may be corrupted, skipping!"),i=!0)):(console.warn("Setting '"+JSON.stringify(e)+"' may be corrupted, skipping!"),i=!0)}catch(e){console.warn("Something went wrong when validating saved settings!",e),console.warn("The setting may be REALLY corrupted, skipping!"),i=!0}if(!i){let i=t.filter((t=>t.info.name==e.info.name&&t.info.category==e.info.category))[0];i?i.setting.loadFromSaveValue(e.value):console.warn("Could not find setting object '"+e.info.name+"', maybe it has been removed in this version of kosu?, skipping setting")}}))}catch(e){console.warn("Failed to load settings! Resetting Settings due to corrupted save!",e),this.reset()}}static save(){let e=this.getList(),t=[];e.forEach((e=>{e.setting.getValue()!=e.setting.getDefaultValue()&&t.push({info:e.info,value:e.setting.getValue()})})),window.localStorage.setItem("settings",JSON.stringify(t))}static reset(){console.warn("Resetting Settings!"),window.localStorage.removeItem("settings")}static register(e){this.settingsList.push(e)}static getSetting(e){return this.settingsList.filter((t=>t.setting instanceof e))[0].setting}static getSettingData(e){return this.settingsList.filter((t=>t.setting instanceof e))[0]}static getList(){return this.settingsList}}},44256:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.Renderer=void 0;const n=i(75341),s=i(74975);class a extends s.DropdownSetting{list=[];webglOption={displayName:"WebGL",value:"webgl"};webGpuOption={displayName:"WebGPU",value:"webgpu"};defaultValue=this.webglOption;constructor(){super({name:"Renderer",category:n.SettingsCategory.Graphics}),this.list.push(this.webglOption,this.webGpuOption),this.value=this.defaultValue}}t.Renderer=a},64681:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.UIScale=void 0;const n=i(78642),s=i(75341);class a extends n.RangeSetting{maxValue=.8;minValue=1.6;increment=.1;defaultValue=1;constructor(){super({name:"UI scaling",category:s.SettingsCategory.Graphics}),this.value=this.defaultValue}}t.UIScale=a},59029:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.MouseSensitivity=void 0;const n=i(78642),s=i(75341),a=i(58687);class o extends n.RangeSetting{defaultValue=1;increment=.01;maxValue=10;minValue=.1;constructor(){super({name:"Sensitivity",category:s.SettingsCategory.Input}),this.value=this.defaultValue,this.onValueChanged()}onValueChanged(){a.EventSystem.cursorSensitivity=this.getValue()}}t.MouseSensitivity=o},17898:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.BeatmapData=void 0;const n=i(85932),s=i(20352),a=i(32007),o=i(78878),r=i(54611),l=i(6386),u=i(43354);t.BeatmapData=class{General=new n.GeneralData;Editor=new s.EditorData;Metadata=new a.Metadata;Difficulty=new o.DifficultyData;Events=new r.EventsData;TimingPoints=new l.TimingPointsData;Colors=new u.ColorsData}},43354:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.ColorsData=void 0;t.ColorsData=class{Colors=[]}},78878:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.DifficultyData=void 0;t.DifficultyData=class{HPDrainRate;CircleSize;OverallDifficulty;ApproachRate;SliderMultiplier;SliderTickRate}},20352:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.EditorData=void 0;t.EditorData=class{Bookmarks=[];DistanceSpacing;BeatDivisor;GridSize;TimelineZoom}},54611:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.EventsData=void 0;t.EventsData=class{Events=[]}},37940:function(e,t){var i;Object.defineProperty(t,"__esModule",{value:!0}),t.Countdown=void 0,function(e){e[e.NoCountdown=0]="NoCountdown",e[e.Normal=1]="Normal",e[e.Half=2]="Half",e[e.Double=3]="Double"}(i||(t.Countdown=i={}))},85932:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.GeneralData=void 0;const n=i(37940),s=i(41080),a=i(90857),o=i(45274);t.GeneralData=class{AudioFileName;AudioLeadIn=0;AudioHash;PreviewTime=-1;Countdown=n.Countdown.Normal;SampleSet=s.SampleSet.Normal;StackLeniency=.7;Mode=a.Mode.OSU;LetterboxInBreaks=!1;StoryFireInFront=!0;UseSkinSprites=!1;AlwaysShowPlayfield=!1;OverlayPosition=o.OverlayPosition.NoChange;SkinPreference;EpilepsyWarning=!1;CountdownOffset=0;SpecialStyle=!1;WidescreenStoryboard=!1;SamplesMatchPlaybackRate=!1}},90857:function(e,t){var i;Object.defineProperty(t,"__esModule",{value:!0}),t.Mode=void 0,function(e){e[e.OSU=0]="OSU",e[e.TAIKO=1]="TAIKO",e[e.CATCH=2]="CATCH",e[e.MANIA=3]="MANIA"}(i||(t.Mode=i={}))},45274:function(e,t){var i;Object.defineProperty(t,"__esModule",{value:!0}),t.OverlayPosition=void 0,function(e){e.NoChange="NoChange",e.Below="Below",e.Above="Above"}(i||(t.OverlayPosition=i={}))},41080:function(e,t){var i;Object.defineProperty(t,"__esModule",{value:!0}),t.SampleSet=void 0,function(e){e.Normal="Normal",e.Soft="Soft",e.Drum="Drum"}(i||(t.SampleSet=i={}))},32007:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.Metadata=void 0;t.Metadata=class{Title;TitleUnicode;Artist;ArtistUnicode;Creator;Version;Source;Tags;BeatmapID;BeatmapSetID}},22331:function(e,t){var i;Object.defineProperty(t,"__esModule",{value:!0}),t.Effect=void 0,function(e){e[e.KiaiTime=1]="KiaiTime",e[e.None=0]="None",e[e.FirstBarLineOmittedInOsuTaikoAndOsuMania=3]="FirstBarLineOmittedInOsuTaikoAndOsuMania"}(i||(t.Effect=i={}))},3143:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.InheritedTimingPoint=void 0;const n=i(52032);class s extends n.TimingPoint{sliderVelocityMultiplier}t.InheritedTimingPoint=s},52032:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.TimingPoint=void 0;t.TimingPoint=class{time;sampleSet;sampleIndex;volume;effects}},6386:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.TimingPointsData=void 0;const n=i(87816),s=i(3143);t.TimingPointsData=class{TimingPoints=[];GetCurrentTimingPoints(e){let t=[],i=this.TimingPoints.filter((t=>{if(t.time<=e)return t}));if(0==i.length&&i.push(this.TimingPoints[0]),t.push(i[i.length-1]),t[0]instanceof s.InheritedTimingPoint){let i=this.TimingPoints.filter((e=>e instanceof n.UnInheritedTimingPoint)).filter((t=>{if(t.time<=e)return t}));if(0==i.length)throw new Error("Could not find a parent timing point for the un-inherited timing point!");t.push(i[i.length-1])}if(0==t.length)throw new Error("Could not find any timing points!");return t}GetCurrentUninheritedTimingPoint(e){let t,i=this.GetCurrentTimingPoints(e);if(i[0]instanceof n.UnInheritedTimingPoint)t=i[0];else{if(!(i[1]instanceof n.UnInheritedTimingPoint))throw new Error("Could not find any UnInherited Timing Points!");t=i[1]}return t}}},87816:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.UnInheritedTimingPoint=void 0;const n=i(52032);class s extends n.TimingPoint{beatLength;meter}t.UnInheritedTimingPoint=s},9752:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.BeatmapParser=void 0;const n=i(17898),s=i(30444),a=i(81347);class o{static Parse(e,t){const i=new n.BeatmapData;let r=e.split(/\r?\n|\r|\n/g);return a.GeneralParser.ParseGeneral(i,o.GetSection("General",r)),s.TimingPointsParser.ParseTimingPoints(i,o.GetSection("TimingPoints",r)),i}static GetSection(e,t){let i=[];return t.forEach(((n,s)=>{if(n=="["+e+"]")for(let e=s+1;e{let i=t.split(":");"AudioFilename"==i[0]&&(i[1].startsWith(" ")?e.General.AudioFileName=i[1].substring(1,i[1].length):e.General.AudioFileName=i[1]),"AudioFilename"==i[0]&&(i[1].startsWith(" ")?e.General.AudioFileName=i[1].substring(1,i[1].length):e.General.AudioFileName=i[1])}))}}},30444:function(e,t,i){Object.defineProperty(t,"__esModule",{value:!0}),t.TimingPointsParser=void 0;const n=i(87816),s=i(3143),a=i(22331);t.TimingPointsParser=class{static ParseTimingPoints(e,t){t.forEach((t=>{let i,o=t.split(",");"1"==o[6]?(i=new n.UnInheritedTimingPoint,i.beatLength=Number.parseFloat(o[1]),i.meter=Number.parseInt(o[2])):(i=new s.InheritedTimingPoint,i.sliderVelocityMultiplier=Number.parseFloat(o[1])),i.time=Number.parseInt(o[0]),i.sampleSet=Number.parseInt(o[3]),i.sampleIndex=Number.parseInt(o[4]),i.volume=Number.parseInt(o[5]),"1"==o[7]||"3"==o[7]?i.effects=Number.parseInt(o[7]):i.effects=a.Effect.None,e.TimingPoints.TimingPoints.push(i)}))}}},5825:function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.MathUtil=void 0;class i{static RadiansToDegrees(e){return 180*e/Math.PI}static DegreesToRadians(e){return e*Math.PI/180}static clamp(e,t,i){return Math.min(Math.max(i,e),t)}static clamp01(e){return i.clamp(0,1,e)}static Damp(e,t,n,s){return i.Lerp(e,t,1-Math.pow(n,s))}static Lerp(e,t,i){return e+(t-e)*i}}t.MathUtil=i},92915:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.Ease=void 0;const o=a(i(29172));class r{static previousEases=[];easings=[];obj;delay=null;constructor(e,t){this.obj=e,t||r.previousEases.push(this)}static getEase(e,t){null==t&&(t=!1);let i=r.previousEases.filter((t=>t.obj==e));return i.length>0?i[0]:new r(e,t)}createTween(e,t,i,n,s,a){const r={value:0},u=new o.Tween(i?r:e),c=new l(u);return u.to(i?{value:1}:t,s),u.easing(a),u.onUpdate((()=>{this.obj.destroyed||(this.obj[n]=i?r.value*(t.value-e.value)+e.value:e),c.onUpdate()})),u.onStart((()=>{i&&(e.value=this.obj[n])})),null==this.delay?u.start():(this.delay.chain(u),this.delay=null),this.easings.push(c),u.onStop((()=>{this.onDone(u)})),u.onComplete((()=>{this.onDone(u)})),this}TransformTo(e,t,i){return this.createTween(this.obj.position,e,!1,"position",t,i),this}onDone(e){this.easings=this.easings.filter((t=>t.tween!=e))}ScaleTo(e,t,i){let n={x:0,y:0};return"number"==typeof e&&(n.x=e,n.y=e),this.createTween(this.obj.scale,n,!1,"scale",t,i),this}FadeTo(e,t,i){return this.createTween({value:this.obj.alpha},{value:e},!0,"alpha",t,i),this}FadeOut(e,t){return this.FadeTo(0,e,t),this}FadeIn(e,t){return this.FadeTo(1,e,t),this}ClearEasings(){return this.easings.forEach((e=>{e.tween.stop()})),this.easings=[],this}Then(e){let t=this.easings.sort(((e,t)=>e.tween.getDuration()-t.tween.getDuration()));return t.length>0&&(this.delay=t[0].tween,null!=e&&(t[0].tween.onComplete((()=>{this.onDone(t[0].tween),e()})),t[0].tween.onStop((()=>{this.onDone(t[0].tween),e()})))),this}OnEach(e){let t=this.easings.sort(((e,t)=>e.tween.getDuration()-t.tween.getDuration()));t.length>0&&t[0].registerOnUpdate(e)}}t.Ease=r;class l{tween;updateEventListeners=[];constructor(e){this.tween=e}onUpdate(){this.updateEventListeners.forEach((e=>{e()}))}registerOnUpdate(e){this.updateEventListeners.push(e)}unRegisterOnUpdate(e){this.updateEventListeners=this.updateEventListeners.filter((t=>!(e===t)))}}},29820:function(e,t,i){i(11307);const n=i(58687),s=i(20825),a=i(58293),o=i(44256),r=i(59029);a.Settings.registerAll(),a.Settings.load();const l=window.innerWidth,u=window.innerHeight,c=new n.Application;globalThis.__PIXI_APP__=c,window.onload=async()=>{const e=a.Settings.getSetting(o.Renderer).getValue().value;c.init({backgroundColor:"black",width:l,height:u,antialias:!0,preference:e,resolution:window.devicePixelRatio,autoDensity:!0}).then((()=>{new s.Main(c)}))},Object.defineProperty(window,"setSensitivity",{value:e=>{a.Settings.getSetting(r.MouseSensitivity).setValue(e)}}),Object.defineProperty(window,"setRenderer",{value:e=>{let t=a.Settings.getSetting(o.Renderer);t.setValue("webgl"==e?t.webglOption:t.webGpuOption),window.location.reload()}})},20825:function(e,t,i){var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.Main=void 0;const o=a(i(58687)),r=i(76969),l=i(25373),u=i(12235),c=i(55686),d=i(85437),h=a(i(29172)),g=i(29847);class f{static app;static mousePos={x:0,y:0};static pointerLockExitTime;static cursor;static AudioEngine;static currentScreen;static allScreens=[];static clickArea=new o.Graphics;static doPointerLock=!1;static settingsPane;constructor(e){f.app=e,document.body.appendChild(f.app.canvas),f.settingsPane=new g.SettingsPane,f.settingsPane.zIndex=999998,f.app.stage.addChild(f.settingsPane),document.addEventListener("keydown",(e=>{e.ctrlKey&&"KeyO"==e.code&&f.settingsPane.toggle()})),this.doResize(),window.addEventListener("resize",this.doResize),f.app.ticker.add((()=>{h.update()})),f.app.stage.eventMode="static",f.AudioEngine=new d.AudioEngine,f.app.stage.addEventListener("mousemove",(e=>{f.mousePos.x=e.clientX,f.mousePos.y=e.clientY,f.cursor&&f.cursor.updateMouse()})),document.addEventListener("pointerlockchange",this.pointerLockChanged,!1),f.switchScreen(new r.LoadScreen),u.Loader.Load(f.AudioEngine.audioContext).then((()=>{f.cursor=new c.MenuCursor(!1);let e=u.Loader.GetAudio("sample_dialog_ok"),t=u.Loader.Get("introTrianglesTrack");f.switchScreen(new l.InteractScreen(t,e))}))}static lockKeyboard(){navigator.keyboard&&navigator.keyboard.lock([]).then((()=>{console.log("Locked keyboard!"),document.fullscreenElement||console.warn("Keyboard lock won't work unless the user is in fullscreen (as requested by the game, not if the user just presses F11)!")}))}static pointerLock(){try{this.doPointerLock=!0,f.app.canvas.requestPointerLock({unadjustedMovement:!0})}catch(e){console.warn("Failed to lock cursor, error:",e),this.doPointerLock=!1}}static exitPointerLock(){this.doPointerLock=!1,f.app.canvas.exitPointerLock()}static switchScreen(e){null!=this.currentScreen&&(this.currentScreen.zIndex=1,this.currentScreen.onClose().then((e=>{for(let t=0;t{e.onResize()})),f.settingsPane.resize()}pointerLockChanged(){!document.pointerLockElement&&f.doPointerLock?(o.EventSystem.isPointerLocked=!1,f.pointerLockExitTime=Date.now(),f.clickArea=new o.Graphics,f.clickArea.rect(0,0,1,1),f.clickArea.fill("rgba(0,0,0,0.1)"),f.clickArea.width=window.innerWidth,f.clickArea.height=window.innerHeight,f.clickArea.position.set(0,0),f.app.stage.addChild(f.clickArea),f.clickArea.eventMode="static",f.clickArea.cursor="pointer",f.cursor.PopOut(),f.clickArea.zIndex=9999999,f.clickArea.onclick=()=>{Date.now()-f.pointerLockExitTime<1500||(f.clickArea.removeFromParent(),f.clickArea.destroy(),f.pointerLock(),f.cursor.PopIn())}):o.EventSystem.isPointerLocked=!0}}t.Main=f},11307:function(e,t,i){i.r(t)},58689:function(e,t,i){i.r(t),t.default="in vec2 vUV;\nin vec2 vPositionOffset;\nin vec2 vPosition;\nin vec4 vColorTint;\nuniform sampler2D uTexture;\nuniform float time;\n\nvoid main() {\n float a = ((vPositionOffset.y + vPosition.y)/1200.0) - 0.1;\n vec4 color = texture(uTexture, vUV);\n if (a > 1.0) {\n a = 1.0;\n }\n gl_FragColor = (color*vColorTint)*a;\n}"},46404:function(e,t,i){i.r(t),t.default="in vec2 aPosition;\nin vec2 aUV;\nin vec2 aPositionOffset;\nin vec4 aColorTint;\n\nout vec2 vUV;\nout vec2 vPositionOffset;\nout vec2 vPosition;\nout vec4 vColorTint;\n\nuniform mat3 uProjectionMatrix;\nuniform mat3 uWorldTransformMatrix;\nuniform mat3 uTransformMatrix;\n\n\nvoid main() {\n\n mat3 mvp = uProjectionMatrix * uWorldTransformMatrix * uTransformMatrix;\n gl_Position = vec4((mvp * vec3(aPosition + aPositionOffset, 1.0)).xy, 0.0, 1.0);\n vPositionOffset = aPositionOffset;\n vUV = aUV;\n vPosition = aPosition;\n vColorTint = aColorTint;\n}"},61630:function(e,t,i){i.r(t),t.default="struct GlobalUniforms {\n uProjectionMatrix:mat3x3,\n uWorldTransformMatrix:mat3x3,\n uWorldColorAlpha: vec4,\n uResolution: vec2,\n}\n\nstruct LocalUniforms {\n uTransformMatrix:mat3x3,\n uColor:vec4,\n uRound:f32,\n}\n\n\n@group(0) @binding(0) var globalUniforms : GlobalUniforms;\n@group(1) @binding(0) var localUniforms : LocalUniforms;\n\nstruct VertexOutput {\n @builtin(position) position: vec4,\n @location(0) vUV: vec2,\n @location(1) vPositionOffset: vec2,\n @location(2) vPosition: vec2,\n @location(3) vColorTint: vec4\n};\n\n\n@vertex\nfn mainVert(\n @location(0) aPosition : vec2,\n @location(1) aUV : vec2,\n @location(2) aColorTint : vec4,\n @location(3) aPositionOffset : vec2,\n) -> VertexOutput {\n var mvp = globalUniforms.uProjectionMatrix\n * globalUniforms.uWorldTransformMatrix\n * localUniforms.uTransformMatrix;\n\n var output: VertexOutput;\n\n output.position = vec4(mvp * vec3(aPosition+aPositionOffset, 1.0), 1.0);\n output.vUV = aUV;\n output.vPosition = aPosition;\n output.vPositionOffset = aPositionOffset;\n output.vColorTint = aColorTint;\n\n return output;\n};\n\nstruct WaveUniforms {\n time:f32,\n}\n\n@group(2) @binding(1) var uTexture : texture_2d;\n@group(2) @binding(2) var uSampler : sampler;\n@group(2) @binding(3) var waveUniforms : WaveUniforms;\n\n@fragment\nfn mainFrag(\n @location(0) vUV: vec2,\n @location(1) vPositionOffset: vec2,\n @location(2) vPosition: vec2,\n @location(3) vColorTint: vec4\n) -> @location(0) vec4 {\n var a: f32 = ((vPositionOffset.y + vPosition.y)/1200.0) - 0.1;\n let color: vec4 = textureSample(uTexture, uSampler, vUV);\n if (a > 1.0){\n a = 1.0;\n }\n return (color*vColorTint)*a;\n};"},44160:function(e,t,i){i.r(t),t.default="in vec4 vColor;\nin vec2 vUV;\n\nuniform sampler2D uTexture;\nuniform float progress;\n\nvoid main() {\n vec4 color = texture2D(uTexture, vUV);\n float a = vColor.a * color.a;\n vec4 _vColor = vec4(smoothstep(0.88, 1.0, color.a))*vColor;\n vec4 outColor = (color.r < progress) ? vec4(_vColor.rgb * a, a) : vec4(0.0);\n gl_FragColor = outColor;\n}\n"},26045:function(e,t,i){i.r(t),t.default="in vec2 aPosition;\nin vec4 aColor;\nin vec2 aUV;\n\nout vec4 vColor;\nout vec2 vUV;\n\nuniform mat3 uProjectionMatrix;\nuniform mat3 uWorldTransformMatrix;\n\nuniform mat3 uTransformMatrix;\n\n\nvoid main() {\n\n mat3 mvp = uProjectionMatrix * uWorldTransformMatrix * uTransformMatrix;\n gl_Position = vec4((mvp * vec3(aPosition, 1.0)).xy, 0.0, 1.0);\n\n vColor = aColor;\n vUV = aUV;\n}\n"},46110:function(e,t,i){i.r(t),t.default="struct GlobalUniforms {\n uProjectionMatrix:mat3x3,\n uWorldTransformMatrix:mat3x3,\n uWorldColorAlpha: vec4,\n uResolution: vec2,\n}\n\nstruct LocalUniforms {\n uTransformMatrix:mat3x3,\n uColor:vec4,\n uRound:f32,\n}\n\n\n@group(0) @binding(0) var globalUniforms : GlobalUniforms;\n@group(1) @binding(0) var localUniforms : LocalUniforms;\n\nstruct VertexOutput {\n @builtin(position) position: vec4,\n @location(0) vUV: vec2,\n @location(1) vColor: vec4,\n};\n\n\n@vertex\nfn mainVert(@location(0) aPosition : vec2, @location(1) aUV : vec2, @location(2) aColor: vec4\n) -> VertexOutput {\n var mvp = globalUniforms.uProjectionMatrix\n * globalUniforms.uWorldTransformMatrix\n * localUniforms.uTransformMatrix;\n\n var output: VertexOutput;\n\n output.position = vec4(mvp * vec3(aPosition, 1.0), 1.0);\n output.vUV = aUV;\n output.vColor = aColor;\n\n return output;\n};\n\nstruct ProgressUniform {\n progress:f32\n}\n\n@group(2) @binding(1) var uTexture : texture_2d;\n@group(2) @binding(2) var uSampler : sampler;\n@group(2) @binding(3) var uProgress : ProgressUniform;\n\n@fragment\nfn mainFrag(@location(0) vUV: vec2, @location(1) vColor: vec4) -> @location(0) vec4 {\n let color: vec4 = textureSample(uTexture, uSampler, vUV);\n let a: f32 = color.a;\n let _vColor: vec4 = smoothstep(0.88, 1.0, color.a) * vColor;\n var outColor: vec4 = vec4(0.0);\n if (color.r < uProgress.progress) {\n outColor = vec4(_vColor.rgb * a, a);\n }\n return outColor;\n};\n"}},i={};function n(e){var s=i[e];if(void 0!==s)return s.exports;var a=i[e]={id:e,loaded:!1,exports:{}};return t[e].call(a.exports,a,a.exports,n),a.loaded=!0,a.exports}n.m=t,e=[],n.O=function(t,i,s,a){if(!i){var o=1/0;for(c=0;c=a)&&Object.keys(n.O).every((function(e){return n.O[e](i[l])}))?i.splice(l--,1):(r=!1,a0&&e[c-1][2]>a;c--)e[c]=e[c-1];e[c]=[i,s,a]},n.d=function(e,t){for(var i in t)n.o(t,i)&&!n.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},n.hmd=function(e){return(e=Object.create(e)).children||(e.children=[]),Object.defineProperty(e,"exports",{enumerable:!0,set:function(){throw new Error("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+e.id)}}),e},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},function(){var e={179:0};n.O.j=function(t){return 0===e[t]};var t=function(t,i){var s,a,o=i[0],r=i[1],l=i[2],u=0;if(o.some((function(t){return 0!==e[t]}))){for(s in r)n.o(r,s)&&(n.m[s]=r[s]);if(l)var c=l(n)}for(t&&t(i);u 0 && deferred[i - 1][2] > priority; i--) deferred[i] = deferred[i - 1];\n\t\tdeferred[i] = [chunkIds, fn, priority];\n\t\treturn;\n\t}\n\tvar notFulfilled = Infinity;\n\tfor (var i = 0; i < deferred.length; i++) {\n\t\tvar chunkIds = deferred[i][0];\n\t\tvar fn = deferred[i][1];\n\t\tvar priority = deferred[i][2];\n\t\tvar fulfilled = true;\n\t\tfor (var j = 0; j < chunkIds.length; j++) {\n\t\t\tif ((priority & 1 === 0 || notFulfilled >= priority) && Object.keys(__webpack_require__.O).every(function(key) { return __webpack_require__.O[key](chunkIds[j]); })) {\n\t\t\t\tchunkIds.splice(j--, 1);\n\t\t\t} else {\n\t\t\t\tfulfilled = false;\n\t\t\t\tif(priority < notFulfilled) notFulfilled = priority;\n\t\t\t}\n\t\t}\n\t\tif(fulfilled) {\n\t\t\tdeferred.splice(i--, 1)\n\t\t\tvar r = fn();\n\t\t\tif (r !== undefined) result = r;\n\t\t}\n\t}\n\treturn result;\n};","import {BeatmapData} from \"../Util/Beatmap/Data/BeatmapData\";\n\nexport class Audio {\n public audio!: AudioBuffer;\n public timeStarted: number = 0;\n public source?: AudioBufferSourceNode\n public id!: number;\n public isPlaying: boolean = false;\n public isPaused: boolean = false;\n public pausedTime: number = 0;\n public nodes: AudioNode[] = [];\n public tempArrayMain = new Float32Array(256);\n public tempArrayL = new Float32Array(64);\n public tempArrayR = new Float32Array(64);\n public LeftChannel: number = 0;\n public RightChannel: number = 0;\n public FrequencyAmplitudes = new Float32Array(256);\n private _connectedToContext = false;\n\n public GetMaximumAudioLevel() {\n return Math.max(this.LeftChannel, this.RightChannel);\n }\n\n public GetAverageAudioLevel() {\n return (this.LeftChannel + this.RightChannel) / 2;\n }\n\n public Create(audioContext: AudioContext) {\n this.source = audioContext.createBufferSource();\n this.source.buffer = this.audio;\n }\n\n public AddAudioNode(node: AudioNode) {\n if (!this.source) {\n throw new Error(\"Source not created yet!\");\n }\n this.nodes.push(node);\n }\n\n public GetNode(type: new (...args: any[]) => T): T[] | null {\n let nodes = this.nodes.filter(node => node instanceof type) as T[];\n if (nodes.length > 0) {\n return nodes;\n } else {\n return null;\n }\n }\n\n public ConnectToContext(audioContext: AudioContext, howToConnectFunction?: (nodes: AudioNode[], source: AudioBufferSourceNode) => void) {\n if (!this.source) {\n throw new Error(\"Source not created yet!\");\n }\n if (this._connectedToContext) {\n return;\n }\n this._connectedToContext = true;\n if (this.nodes.length > 0) {\n if (howToConnectFunction) {\n howToConnectFunction(this.nodes, this.source);\n } else {\n this.nodes.forEach((node, index) => {\n this.source!.connect(node);\n if (!(node instanceof AnalyserNode)) {\n node.connect(audioContext.destination);\n }\n });\n }\n } else {\n this.source.connect(audioContext.destination);\n }\n }\n\n public Play() {\n if (!this.source) {\n throw new Error(\"Source not created yet!\");\n }\n if (!this._connectedToContext) {\n throw new Error(\"Not connected to audio context yet!\");\n }\n this.source.start(0, this.pausedTime);\n this.isPlaying = true;\n this.isPaused = false;\n this.timeStarted = Date.now() - this.pausedTime;\n this.pausedTime = 0;\n }\n\n public Pause() {\n if (!this.source) {\n throw new Error(\"Source not created yet!\");\n }\n if (!this._connectedToContext) {\n throw new Error(\"Not connected to audio context yet!\");\n }\n this.pausedTime = Date.now() - this.timeStarted;\n this.source.stop(0);\n this.isPaused = true;\n this.isPlaying = false;\n }\n\n public Stop() {\n if (!this.source) {\n throw new Error(\"Source not created yet!\");\n }\n if (!this._connectedToContext) {\n throw new Error(\"Not connected to audio context yet!\");\n }\n this.source.stop(0);\n this.isPlaying = false;\n }\n\n public RegisterEndCallBack(callback: () => void) {\n if (!this.source) {\n throw new Error(\"Source not created yet!\");\n }\n this.source.onended = () => {\n if (!this.isPaused) {\n callback();\n }\n }\n }\n\n}\n\nexport class MapAudio extends Audio {\n public beatmap!: BeatmapData;\n public fadingOut: boolean = false;\n // @ts-ignore\n public fadeOutTimeout!: Timeout\n public playingCallback?: () => void;\n\n}\n","import {PlayingAudios} from \"./PlayingAudios\";\nimport {Audio, MapAudio} from \"./Audio\";\nimport {BeatmapData} from \"../Util/Beatmap/Data/BeatmapData\";\nimport {Main} from \"../main\";\nimport {UnInheritedTimingPoint} from \"../Util/Beatmap/Data/Sections/TimingPoints/UnInheritedTimingPoint\";\nimport {Effect} from \"../Util/Beatmap/Data/Sections/TimingPoints/Effect\";\n\nexport class AudioEngine {\n public readonly audioContext: AudioContext;\n private readonly _playingAudios: PlayingAudios;\n private _musicQueue: MapAudio[] = [];\n private _audioIdTicker: number = 0;\n private _changeCallbacks: (() => void)[] = [];\n private silentMusic = this.createSilentMusic();\n public useSilentMusic = true;\n\n public constructor() {\n this.audioContext = new AudioContext();\n this._playingAudios = new PlayingAudios();\n Main.app.ticker.add(() => {\n this.update();\n });\n }\n\n public UpdateMusicQueue() {\n if (this._musicQueue[0]) {\n if (!this._musicQueue[0].fadingOut && this._musicQueue[0].timeStarted == 0) {\n this._play(this._musicQueue[0]);\n this._changeCallbacks.forEach((cb) => cb());\n }\n if (this._musicQueue[0].fadingOut && this._musicQueue[1]) {\n if (this._musicQueue[1]) {\n this._play(this._musicQueue[1]);\n this._changeCallbacks.forEach((cb) => cb());\n }\n }\n }\n if (!(this._musicQueue.length >= 1)) {\n this.silentMusic = this.createSilentMusic();\n this.useSilentMusic = true;\n }\n else {\n this.useSilentMusic = false;\n\n }\n }\n\n public createSilentMusic() {\n let mapAudio = new MapAudio();\n mapAudio.timeStarted = Date.now();\n mapAudio.beatmap = new BeatmapData();\n let timingPoint = new UnInheritedTimingPoint();\n timingPoint.time = 0;\n timingPoint.beatLength = 1000;\n timingPoint.effects = Effect.None;\n mapAudio.beatmap.TimingPoints.TimingPoints.push(timingPoint);\n return mapAudio;\n }\n\n public addMusicChangeEventListener(cb: () => void) {\n this._changeCallbacks.push(cb);\n }\n\n public removeMusicChangeEventListener(cb: () => void) {\n this._changeCallbacks = this._changeCallbacks.filter(callback => callback != cb);\n }\n\n public GetCurrentPlayingMusic(): MapAudio {\n return this.useSilentMusic ? this.silentMusic : this._musicQueue[0];\n }\n\n public PlayEffect(audio: AudioBuffer, pitch?: number) {\n let audioObj = new Audio();\n audioObj.audio = audio;\n audioObj.id = this._audioIdTicker;\n this._play(audioObj, pitch);\n this._audioIdTicker++;\n }\n\n public AddToMusicQueue(mapAudio: AudioBuffer, beatMapData: BeatmapData, musicPlayingCallback?: () => void) {\n let mapAudioObj = new MapAudio();\n mapAudioObj.audio = mapAudio;\n mapAudioObj.beatmap = beatMapData;\n mapAudioObj.id = this._audioIdTicker;\n if (musicPlayingCallback) {\n mapAudioObj.playingCallback = musicPlayingCallback;\n }\n this._musicQueue.push(mapAudioObj);\n this._audioIdTicker++;\n this.UpdateMusicQueue();\n return mapAudioObj.id;\n }\n\n public PlayMusicImmediately(mapAudio: AudioBuffer, beatMapData: BeatmapData, musicPlayingCallback?: () => void) {\n // clear queue\n this._musicQueue = [];\n this.AddToMusicQueue(mapAudio, beatMapData, musicPlayingCallback);\n }\n\n public update() {\n let currentPlaying = this.GetCurrentPlayingMusic();\n if (!this.useSilentMusic) {\n let analyzerMain = currentPlaying.GetNode(AnalyserNode)![0];\n let analyzerL = currentPlaying.GetNode(AnalyserNode)![1];\n let analyzerR = currentPlaying.GetNode(AnalyserNode)![2];\n\n analyzerMain.getFloatFrequencyData(currentPlaying.tempArrayMain);\n for (let i = 0; i < currentPlaying.FrequencyAmplitudes.length; i++) {\n currentPlaying.tempArrayMain[i] += 140;\n currentPlaying.tempArrayMain[i] /= 340;\n if (i < 3) {\n currentPlaying.tempArrayMain[i] *= (12 * currentPlaying.tempArrayMain[i]);\n } else if (i < 6) {\n currentPlaying.tempArrayMain[i] *= (9 * currentPlaying.tempArrayMain[i]);\n } else if (i < 100) {\n currentPlaying.tempArrayMain[i] *= (6 * currentPlaying.tempArrayMain[i]);\n }\n currentPlaying.tempArrayMain[i] /= 2;\n if (currentPlaying.tempArrayMain[i] == Infinity || currentPlaying.tempArrayMain[i] == -Infinity) {\n currentPlaying.FrequencyAmplitudes[i] = 0;\n }\n else {\n currentPlaying.FrequencyAmplitudes[i] = currentPlaying.tempArrayMain[i];\n }\n }\n\n analyzerL.getFloatTimeDomainData(currentPlaying.tempArrayL);\n analyzerR.getFloatTimeDomainData(currentPlaying.tempArrayR);\n let avgL = 0;\n let avgR = 0;\n currentPlaying.tempArrayL.forEach((value) => {\n avgL += (value + 1)/2;\n });\n currentPlaying.tempArrayR.forEach((value) => {\n avgR += (value + 1)/2;\n });\n avgL /= currentPlaying.tempArrayL.length;\n avgR /= currentPlaying.tempArrayR.length;\n currentPlaying.LeftChannel = avgL;\n currentPlaying.RightChannel = avgR;\n }\n }\n\n private _play(audio: Audio | MapAudio, pitch?: number) {\n audio.Create(this.audioContext);\n // check if audio is type of MapAudio\n if (\"beatmap\" in audio && audio.beatmap) {\n this._playingAudios.audios.forEach((audio) => {\n if (\"beatmap\" in audio && audio.beatmap) {\n clearTimeout(audio.fadeOutTimeout);\n audio.fadingOut = true;\n let gainNodes = audio.GetNode(GainNode);\n if (gainNodes == null) {\n throw new Error(\"Gain Node doesn't exist on Audio Object!\");\n }\n let gain = gainNodes[0];\n gain.gain.linearRampToValueAtTime(0, this.audioContext.currentTime + 0.4)\n setTimeout(() => {\n audio.Stop();\n }, 400);\n }\n });\n let gain = this.audioContext.createGain();\n gain.gain.value = 0;\n let analyzer = this.audioContext.createAnalyser();\n analyzer.fftSize = 512;\n analyzer.smoothingTimeConstant = 0;\n let splitter = this.audioContext.createChannelSplitter(2);\n let analyzerL = this.audioContext.createAnalyser();\n analyzerL.smoothingTimeConstant = 0;\n analyzerL.fftSize = 128;\n let analyzerR = this.audioContext.createAnalyser();\n analyzerR.smoothingTimeConstant = 0;\n analyzerR.fftSize = 128;\n audio.AddAudioNode(gain);\n audio.AddAudioNode(analyzer);\n audio.AddAudioNode(analyzerL);\n audio.AddAudioNode(analyzerR);\n audio.ConnectToContext(this.audioContext, (nodes, source) => {\n source.connect(gain);\n gain.connect(this.audioContext.destination);\n source.connect(analyzer);\n source.connect(splitter);\n splitter.connect(analyzerL, 0);\n splitter.connect(analyzerR, 1);\n });\n audio.Play();\n this._playingAudios.audios.push(audio);\n if (audio.playingCallback) {\n audio.playingCallback();\n }\n gain.gain.linearRampToValueAtTime(1, this.audioContext.currentTime + 0.4);\n audio.fadeOutTimeout = setTimeout(() => {\n gain.gain.linearRampToValueAtTime(0, this.audioContext.currentTime + 0.4);\n }, (audio.audio.duration - 0.4) * 1000);\n } else {\n audio.ConnectToContext(this.audioContext);\n if (pitch) {\n if (audio.source) {\n audio.source.playbackRate.value = pitch;\n }\n }\n audio.Play();\n this._playingAudios.audios.push(audio);\n }\n\n\n audio.RegisterEndCallBack(() => {\n audio.isPlaying = false;\n if (\"beatmap\" in audio && audio.beatmap) {\n if (this._musicQueue[0] == audio) {\n this._musicQueue.splice(0, 1);\n }\n this.UpdateMusicQueue();\n }\n this._playingAudios.audios.forEach((audioInArr, index) => {\n if (audioInArr === audio) {\n this._playingAudios.audios.splice(index, 1);\n return;\n }\n });\n });\n }\n\n}\n","import {Audio, MapAudio} from \"./Audio\";\n\nexport class PlayingAudios {\n public audios: (Audio | MapAudio)[] = [];\n}\n","import {Main} from \"../../main\";\nimport {MapAudio} from \"../../Audio/Audio\";\nimport * as PIXI from \"pixi.js\";\nimport {MathUtil} from \"../../Util/MathUtil\";\nimport {Effect} from \"../../Util/Beatmap/Data/Sections/TimingPoints/Effect\";\nimport {UnInheritedTimingPoint} from \"../../Util/Beatmap/Data/Sections/TimingPoints/UnInheritedTimingPoint\";\n\nexport class LogoVisualizer extends PIXI.Container {\n\n public static readonly size = 900;\n public frequencyAmplitudes: Float32Array = new Float32Array(256);\n protected audio!: MapAudio;\n protected temporalAmplitudes: Float32Array = new Float32Array(256);\n protected graphics: PIXI.Graphics = new PIXI.Graphics();\n // The number of bars to jump each update iteration.\n private readonly index_change = 5;\n // The maximum length of each bar in the visualiser. Will be reduced when kiai is not activated.\n private readonly bar_length = 600;\n // The number of bars in one rotation of the visualiser.\n private bars_per_visualiser = 200;\n // How many times we should stretch around the circumference (overlapping overselves).\n private readonly visualiser_rounds = 5;\n // How much should each bar go down each millisecond (based on a full bar).\n private readonly decay_per_millisecond = 0.0024;\n // Number of milliseconds between each amplitude update.\n private readonly time_between_updates = 50;\n // The minimum amplitude to show a bar.\n private readonly amplitude_dead_zone = 1 / this.bar_length;\n private indexOffset = 0;\n private firstDraw = true;\n\n public start() {\n this.graphics.blendMode = \"add\";\n this.addChild(this.graphics);\n this.graphics.eventMode = \"none\";\n this.eventMode = \"none\";\n setInterval(() => {\n this.updateAmplitudes()\n }, this.time_between_updates);\n\n }\n\n public draw(ticker: PIXI.Ticker) {\n if (this.firstDraw) {\n for (let i = 0; i < this.frequencyAmplitudes.length; i++) {\n this.frequencyAmplitudes[i] = 0;\n }\n }\n this.graphics.clear();\n let decayFactor = ticker.deltaMS * this.decay_per_millisecond;\n for (let i = 0; i < this.bars_per_visualiser; i++) {\n //3% of extra bar length to make it a little faster when bar is almost at it's minimum\n this.frequencyAmplitudes[i] -= decayFactor * (this.frequencyAmplitudes[i] + 0.03);\n if (this.frequencyAmplitudes[i] < 0) {\n this.frequencyAmplitudes[i] = 0;\n }\n }\n\n for (let j = 0; j < this.visualiser_rounds; j++) {\n for (let i = 0; i < this.bars_per_visualiser; i++) {\n if (this.frequencyAmplitudes[i] < this.amplitude_dead_zone) {\n continue;\n }\n\n let rotation = MathUtil.DegreesToRadians(i / this.bars_per_visualiser * 360 + j * 360 / this.visualiser_rounds);\n let rotationCos = Math.cos(rotation);\n let rotationSin = Math.sin(rotation);\n // taking the cos and sin to the 0..1 range\n let barPosition = {\n x: (rotationCos / 2 + 0.5) * LogoVisualizer.size,\n y: (rotationSin / 2 + 0.5) * LogoVisualizer.size\n };\n\n let barSize = {\n x: LogoVisualizer.size * Math.sqrt(2 * (1 - Math.cos(MathUtil.DegreesToRadians(360 / this.bars_per_visualiser)))) / 2,\n y: this.bar_length * this.frequencyAmplitudes[i]\n };\n // The distance between the bottom side of the bar and the top side.\n let amplitudeOffset = {x: rotationCos * barSize.y, y: rotationSin * barSize.y};\n\n this.graphics.moveTo(barPosition.x, barPosition.y);\n this.graphics.lineTo(barPosition.x + amplitudeOffset.x, barPosition.y + amplitudeOffset.y);\n this.graphics.stroke({color: \"rgba(255, 255, 255, 0.2)\", width: 14});\n }\n }\n this.firstDraw = false;\n }\n\n private updateAmplitudes() {\n this.audio = Main.AudioEngine.GetCurrentPlayingMusic();\n for (let i = 0; i < this.audio.FrequencyAmplitudes.length; i++) {\n this.temporalAmplitudes[i] = this.audio.FrequencyAmplitudes[i];\n }\n let timingPoint = this.audio.beatmap.TimingPoints.GetCurrentTimingPoints(Date.now() - this.audio.timeStarted)[0];\n for (let i = 0; i < this.bars_per_visualiser; i++) {\n let targetAmplitude = (this.temporalAmplitudes[(i + this.indexOffset) % this.bars_per_visualiser]) *\n (timingPoint.effects == Effect.KiaiTime ? 1 : 0.5);\n if (targetAmplitude > this.frequencyAmplitudes[i]) {\n this.frequencyAmplitudes[i] = targetAmplitude;\n }\n }\n this.indexOffset = (this.indexOffset + this.index_change) % this.bars_per_visualiser;\n }\n}\n","import {LogoVisualizer} from \"../LogoVisualizer\";\nimport * as PIXI from \"pixi.js\";\n\nexport class MenuLogoVisualizer extends LogoVisualizer {\n\n\n public draw(ticker: PIXI.Ticker) {\n super.draw(ticker);\n\n }\n}\n","import * as PIXI from \"pixi.js\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\nimport {Ease} from \"../../Util/TweenWrapper/Ease\";\n\nexport class LoadAnim extends PIXI.Container {\n private readonly bg: PIXI.Graphics;\n private readonly arc: PIXI.Graphics;\n private readonly arcContainer: PIXI.Container;\n private readonly animInterval: NodeJS.Timeout;\n private readonly container: PIXI.Container;\n private readonly bgContainer: PIXI.Container;\n private bgRotation: number = 0;\n\n public constructor(bgColor: string, arcColor: string) {\n super();\n this.pivot.set(0.5, 0.5);\n this.container = new PIXI.Container();\n this.container.alpha = 0;\n this.rotation = Math.PI * 2.5;\n this.bgContainer = new PIXI.Container();\n this.bg = new PIXI.Graphics();\n this.bg.roundRect(-50, -50, 100, 100, 25);\n this.bg.fill(bgColor);\n this.arcContainer = new PIXI.Container();\n this.arc = new PIXI.Graphics();\n this.arc.arc(0, 0, 27, Math.PI + .26, 2.92 * Math.PI);\n this.arc.stroke({\n width: 8,\n color: arcColor,\n cap: \"round\"\n });\n this.arc.scale.set(-1, 1);\n this.container.scale.set(0.5, 0.5);\n this.bgContainer.addChild(this.bg);\n this.arcContainer.addChild(this.arc);\n this.bgContainer.addChild(this.arcContainer);\n this.container.addChild(this.bgContainer);\n this.addChild(this.container);\n Ease.getEase(this.container).ScaleTo(1, 400, TWEEN.Easing.Quadratic.InOut)\n .FadeIn(400, TWEEN.Easing.Quadratic.InOut)\n this.doAnims();\n\n this.animInterval = setInterval(() => {\n this.doAnims();\n }, 800);\n }\n\n public doAnims() {\n this.bgRotation += 90;\n Ease.getEase(this.bgContainer).createTween({value: this.bgContainer.angle},\n {value: this.bgRotation}, true, \"angle\", 600, TWEEN.Easing.Quadratic.InOut);\n }\n\n public getWidth() {\n return 100 * this.scale.x;\n }\n\n public getHeight() {\n return 100 * this.scale.y;\n }\n\n public draw(deltaTime: PIXI.Ticker) {\n this.arcContainer.angle += (3 * deltaTime.deltaTime);\n }\n\n public destroy(_options?: PIXI.DestroyOptions | boolean) {\n Ease.getEase(this.container).FadeOut(400, TWEEN.Easing.Quadratic.InOut)\n .ScaleTo(0.5, 400, TWEEN.Easing.Quadratic.InOut);\n setTimeout(() => {\n clearInterval(this.animInterval);\n super.destroy(_options);\n }, 400);\n }\n\n}\n","import * as PIXI from \"pixi.js\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\nimport {Ease} from \"../../../../Util/TweenWrapper/Ease\";\n\nexport class Menu extends PIXI.Container {\n\n private menuBG = new PIXI.Graphics();\n private isOpened = false;\n\n public constructor() {\n super();\n this.menuBG.rect(0, -62.5, 1, 125);\n this.menuBG.fill({color: \"rgb(50,50,50)\"});\n this.menuBG.scale.set(1, 0);\n this.menuBG.alpha = 0;\n this.addChild(this.menuBG);\n\n }\n\n public Open() {\n this.isOpened = true;\n Ease.getEase(this.menuBG).ScaleTo(1, 400, TWEEN.Easing.Quintic.Out)\n .FadeIn(400, TWEEN.Easing.Quintic.Out);\n }\n\n public Close() {\n this.isOpened = false;\n Ease.getEase(this.menuBG).ClearEasings().ScaleTo({x: 1, y: 0}, 300, TWEEN.Easing.Sinusoidal.In)\n .FadeOut(300, TWEEN.Easing.Sinusoidal.In);\n }\n\n public isOpen() {\n return this.isOpened;\n }\n\n public onResize() {\n this.position.set(-window.innerWidth, 0);\n this.menuBG.width = window.innerWidth * 2;\n }\n}\n","import * as PIXI from \"pixi.js\";\nimport {Triangles} from \"./Triangles\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\nimport {Ease} from \"../../../Util/TweenWrapper/Ease\";\nimport {Main} from \"../../../main\";\nimport {Loader} from \"../../../Loader\";\nimport {Menu} from \"./Menu/Menu\";\nimport {MenuLogoVisualizer} from \"../../AudioVisualizers/impl/MenuLogoVisualizer\";\nimport {LogoVisualizer} from \"../../AudioVisualizers/LogoVisualizer\";\nimport {Effect} from \"../../../Util/Beatmap/Data/Sections/TimingPoints/Effect\";\nimport {UnInheritedTimingPoint} from \"../../../Util/Beatmap/Data/Sections/TimingPoints/UnInheritedTimingPoint\";\nimport {MathUtil} from \"../../../Util/MathUtil\";\n\nexport class OsuCircle extends PIXI.Container {\n\n private readonly outline: PIXI.Sprite;\n private readonly visualizer: MenuLogoVisualizer = new MenuLogoVisualizer();\n private readonly triangles: Triangles = new Triangles();\n private readonly flash;\n private readonly logoContainer = new PIXI.Container;\n private readonly logoBounceContainer = new PIXI.Container();\n private readonly logoBeatContainer = new PIXI.Container();\n private readonly logoAmplitudeContainer = new PIXI.Container();\n private readonly logoHoverContainer = new PIXI.Container();\n private readonly rippleContainer = new PIXI.Container();\n private readonly ripple;\n private readonly menu: Menu = new Menu();\n private readonly defaultVisualizerAlpha = 0.5;\n private readonly early_activation = 60;\n private timeElapsedSinceLastBeat = 0;\n private timeUntilNextBeat = 0;\n private lastTimeElapasedSinceLastBeat = 0;\n\n private selectSample = Loader.GetAudio(\"mainMenu.osuLogo.select\");\n private backToLogoSample = Loader.GetAudio(\"mainMenu.osuLogo.backToLogo\");\n\n private isMouseDown = false;\n private mouseDownPosition = {x: 0, y: 0};\n\n\n public constructor() {\n super();\n this.visualizer.start();\n\n\n this.outline = PIXI.Sprite.from(\"mainMenu.logoOutline\");\n this.outline.anchor.set(0.5, 0.5);\n //approximation of size in actual osu!lazer\n let scale = 0.6;\n this.visualizer.scale.set(scale);\n this.visualizer.pivot.set(LogoVisualizer.size/2, LogoVisualizer.size/2);\n this.visualizer.alpha = this.defaultVisualizerAlpha;\n\n let mask = new PIXI.Graphics();\n mask.circle(0,0,450);\n mask.fill({color:\"white\"});\n mask.scale = scale;\n\n\n this.flash = PIXI.Sprite.from(\"mainMenu.logoMask\");\n this.flash.anchor.set(0.5, 0.5);\n this.flash.scale = scale;\n this.flash.blendMode = \"add\";\n this.flash.alpha = 0;\n\n this.triangles.flash.anchor.set(0.5, 0.5);\n this.triangles.flash.scale = scale;\n\n this.outline.scale.set(scale);\n this.triangles.scale.set(scale);\n this.triangles.position.set(-(this.outline.width / 2), -(this.outline.height / 2));\n this.triangles.mask = mask;\n\n this.ripple = PIXI.Sprite.from(\"mainMenu.logoMask\");\n this.ripple.anchor.set(0.5, 0.5);\n this.ripple.scale = scale;\n this.ripple.alpha = 0;\n this.ripple.blendMode = \"add\";\n\n this.rippleContainer.addChild(this.ripple);\n this.logoContainer.addChild(this.visualizer);\n this.logoContainer.addChild(this.triangles);\n this.logoContainer.addChild(this.triangles.flash);\n this.logoContainer.addChild(mask);\n this.logoContainer.addChild(this.flash);\n this.logoContainer.addChild(this.outline);\n this.logoContainer.hitArea = new PIXI.Circle(0, 0, 480 * scale);\n this.logoContainer.eventMode = \"static\";\n\n this.logoContainer.onmouseenter = this._onmouseenter;\n this.logoContainer.onmouseleave = this._onmouseleave;\n this.logoContainer.onmousedown = this._onmousedown;\n this.logoContainer.onclick = this._onclick;\n\n this.logoBeatContainer.addChild(this.logoContainer);\n this.logoAmplitudeContainer.addChild(this.logoBeatContainer);\n this.logoBounceContainer.addChild(this.rippleContainer);\n this.logoBounceContainer.addChild(this.logoAmplitudeContainer);\n this.logoHoverContainer.addChild(this.logoBounceContainer);\n this.addChild(this.logoHoverContainer)\n\n // register event listeners\n Main.app.stage.addEventListener(\"mouseup\", (e) => {\n this._onmouseup(e);\n });\n\n }\n\n\n public _onmouseenter = (e: PIXI.FederatedMouseEvent) => {\n Ease.getEase(this.logoHoverContainer).ScaleTo(1.1, 500, TWEEN.Easing.Elastic.Out);\n }\n\n public _onmouseleave = (e: PIXI.FederatedMouseEvent) => {\n Ease.getEase(this.logoHoverContainer).ScaleTo(1, 500, TWEEN.Easing.Elastic.Out);\n }\n\n public _onmousedown = (e: PIXI.FederatedMouseEvent) => {\n this.isMouseDown = true;\n Ease.getEase(this.logoBounceContainer).ClearEasings().ScaleTo(0.9, 1000, TWEEN.Easing.Sinusoidal.Out);\n this.mouseDownPosition = {x: Main.mousePos.x, y: Main.mousePos.y};\n }\n\n public _onclick = (e: PIXI.FederatedMouseEvent) => {\n this.flash.alpha = 0.4;\n Ease.getEase(this.flash).ClearEasings()\n .FadeOut(1500, TWEEN.Easing.Exponential.Out);\n }\n\n public _onmouseup = (e: PIXI.FederatedMouseEvent) => {\n this.isMouseDown = false;\n Ease.getEase(this.logoBounceContainer).ClearEasings().ScaleTo(1, 500, TWEEN.Easing.Elastic.Out)\n .TransformTo({x: 0, y: 0}, 800, TWEEN.Easing.Elastic.Out);\n }\n\n public onResize() {\n this.menu.onResize();\n }\n\n public draw(ticker: PIXI.Ticker) {\n this.visualizer.draw(ticker);\n this.triangles.draw(ticker);\n //this.timeElapsedSinceLastBeat += ticker.deltaMS;\n let audio = Main.AudioEngine.GetCurrentPlayingMusic();\n let timingPoint = audio.beatmap.TimingPoints.GetCurrentUninheritedTimingPoint(Date.now() - audio.timeStarted);\n this.timeUntilNextBeat = (timingPoint.time - (Date.now() - audio.timeStarted)) % timingPoint.beatLength;\n if (this.timeUntilNextBeat <= 0) {\n this.timeUntilNextBeat += timingPoint.beatLength;\n }\n this.timeElapsedSinceLastBeat = timingPoint.beatLength - this.timeUntilNextBeat;\n if (!Main.AudioEngine.useSilentMusic) {\n let maxAmplitude = audio.GetMaximumAudioLevel();\n this.logoAmplitudeContainer.scale.set(MathUtil.Damp(this.logoAmplitudeContainer.scale.x,\n 1 - Math.max(0, maxAmplitude - 0.4) * 0.04, 0.9, ticker.deltaMS))\n this.triangles.Velocity = MathUtil.Damp(this.triangles.Velocity,\n 0.5 * (timingPoint.effects == Effect.KiaiTime ? 4 : 2), 0.995, ticker.deltaMS);\n } else {\n this.logoAmplitudeContainer.scale = 1;\n this.triangles.Velocity = MathUtil.Damp(this.triangles.Velocity, 0.5, 0.9, ticker.deltaMS);\n }\n if (this.lastTimeElapasedSinceLastBeat > this.timeElapsedSinceLastBeat) {\n this.onNewBeat();\n }\n\n this.lastTimeElapasedSinceLastBeat = this.timeElapsedSinceLastBeat;\n\n if (this.isMouseDown) {\n let change = {x: Main.mousePos.x - this.mouseDownPosition.x, y: Main.mousePos.y - this.mouseDownPosition.y};\n let length = Math.sqrt(change.x * change.x + change.y * change.y);\n // Diminish the drag distance as we go further to simulate \"rubber band\" feeling.\n change.x *= length <= 0 ? 0 : Math.pow(length, 0.6) / length;\n change.y *= length <= 0 ? 0 : Math.pow(length, 0.6) / length;\n this.logoBounceContainer.x = change.x;\n this.logoBounceContainer.y = change.y;\n }\n\n\n }\n\n private onNewBeat() {\n let audio = Main.AudioEngine.GetCurrentPlayingMusic();\n let timingPointUninherited = audio.beatmap.TimingPoints.GetCurrentUninheritedTimingPoint(Date.now() - audio.timeStarted);\n let beatLength = timingPointUninherited.beatLength;\n let timingPoint = audio.beatmap.TimingPoints.GetCurrentTimingPoints(Date.now() - audio.timeStarted)[0];\n let maxAmplitude = !Main.AudioEngine.useSilentMusic ? audio.GetMaximumAudioLevel() : 0;\n let amplitudeAdjust = Math.min(1, 0.4 + maxAmplitude);\n Ease.getEase(this.logoBeatContainer).ScaleTo(1 - 0.02 * amplitudeAdjust, this.early_activation, TWEEN.Easing.Linear.None).Then()\n .ScaleTo(1, beatLength * 2, TWEEN.Easing.Quintic.Out);\n this.rippleContainer.scale = 1.02;\n Ease.getEase(this.rippleContainer).ClearEasings().ScaleTo(1.02 * (1 + 0.04 * amplitudeAdjust), beatLength * 2, TWEEN.Easing.Quintic.Out);\n this.ripple.alpha = 0.15 * amplitudeAdjust;\n Ease.getEase(this.ripple).ClearEasings().FadeOut(beatLength, TWEEN.Easing.Quintic.Out);\n\n\n if (timingPoint.effects == Effect.KiaiTime) {\n Ease.getEase(this.triangles.flash).ClearEasings()\n .FadeTo(0.2 * amplitudeAdjust, this.early_activation, TWEEN.Easing.Linear.None).Then()\n .FadeTo(0, beatLength, TWEEN.Easing.Linear.None);\n Ease.getEase(this.visualizer).ClearEasings()\n .FadeTo(this.defaultVisualizerAlpha * 1.8 * amplitudeAdjust, this.early_activation, TWEEN.Easing.Linear.None).Then()\n .FadeTo(this.defaultVisualizerAlpha, beatLength, TWEEN.Easing.Linear.None);\n }\n setTimeout(() => {\n this.triangles.Velocity += amplitudeAdjust * (timingPoint.effects == Effect.KiaiTime ? 6 : 3);\n }, 60)\n\n }\n\n}\n","import * as PIXI from \"pixi.js\";\nimport {Main} from \"../../../main\";\nimport glVertShader from \"./osuCircleTriangles.vert\";\nimport glFragShader from \"./osuCircleTriangles.frag\";\nimport gpuShader from \"./osuCircleTriangles.wgsl\";\n\nexport class Triangles extends PIXI.Container {\n\n public flash: PIXI.Sprite;\n public Velocity: number = 1;\n private readonly bgGradient: PIXI.FillGradient;\n private triangles: Triangle[] = [];\n private graphics: PIXI.Graphics = new PIXI.Graphics();\n private timeSinceLastSpawn = 0;\n private instancePositionBuffer;\n private readonly totalTriangles = 15;\n\n public constructor() {\n super();\n\n let colorStops = [0xff66ab, 0xcc5289];\n this.bgGradient = new PIXI.FillGradient(0, 0, 0, 1024);\n colorStops.forEach((number, index) => {\n const ratio = index / colorStops.length;\n this.bgGradient.addColorStop(ratio, number);\n });\n\n for (let i = 0; i < this.totalTriangles; i++) {\n this.triangles.push({x: this.random(0, 1024), y: this.random(0, 1024), velocity: this.randVelocity()});\n }\n this.timeSinceLastSpawn = Date.now();\n\n this.graphics.rect(0, 0, 1024, 1024);\n this.graphics.fill(this.bgGradient);\n this.addChild(this.graphics);\n\n this.flash = PIXI.Sprite.from(\"mainMenu.logoMask\");\n //this.flash.anchor.set(0.5, 0.5);\n this.flash.alpha = 0;\n this.flash.blendMode = \"add\";\n\n this.instancePositionBuffer = new PIXI.Buffer({\n data: new Float32Array(this.totalTriangles * 2),\n usage: PIXI.BufferUsage.VERTEX | PIXI.BufferUsage.COPY_DST\n });\n const color = new PIXI.Color(\"rgb(182, 52, 111)\");\n const size = 30;\n const geometry = new PIXI.Geometry({\n attributes: {\n aPosition: [\n -10*size,\n -10*size, // x, y\n 10*size,\n -10*size, // x, y\n 10*size,\n 7.5*size, // x, y,\n -10*size,\n 7.5*size, // x, y,\n ],\n aUV: [0, 0, 1, 0, 1, 1, 0, 1],\n aColorTint: [\n color.red, color.green, color.blue, 1,\n color.red, color.green, color.blue, 1,\n color.red, color.green, color.blue, 1,\n color.red, color.green, color.blue, 1\n ],\n aPositionOffset: {\n buffer: this.instancePositionBuffer,\n instance: true\n }\n },\n indexBuffer: [0, 1, 2, 0, 2, 3],\n instanceCount: this.totalTriangles\n });\n const gl = {\n vertex: glVertShader,\n fragment: glFragShader\n };\n\n const gpu = {\n vertex: {\n entryPoint: \"mainVert\",\n source: gpuShader\n },\n fragment: {\n entryPoint: \"mainFrag\",\n source: gpuShader\n }\n };\n\n const triangleGraphic = new PIXI.Graphics();\n triangleGraphic.moveTo(0, 0);\n triangleGraphic.lineTo(-256, 512);\n triangleGraphic.lineTo(256, 512);\n triangleGraphic.lineTo(0, 0);\n triangleGraphic.stroke({color: \"white\", width: 4});\n\n const triangleTexture = Main.app.renderer.generateTexture(triangleGraphic);\n\n const shader = PIXI.Shader.from({\n gl,\n gpu,\n resources: {\n uTexture: triangleTexture.source,\n uSampler: triangleTexture.source.style,\n waveUniforms: {\n time: { value: 1, type: \"f32\" }\n }\n }\n });\n\n const triangleMesh = new PIXI.Mesh({\n geometry,\n shader\n });\n\n this.addChild(triangleMesh);\n\n\n\n }\n\n public destroy(options?: PIXI.DestroyOptions) {\n super.destroy(options);\n }\n\n public draw(ticker: PIXI.Ticker) {\n const data = this.instancePositionBuffer.data;\n let count = 0;\n\n for (let i = 0; i < this.totalTriangles; i++) {\n const triangle = this.triangles[i];\n\n triangle.y -= ((ticker.deltaTime * this.Velocity * triangle.velocity)*1.2);\n\n if (triangle.y + 100 < 0) {\n triangle.y = 1024 + 250;\n }\n\n data[count++] = triangle.x;\n data[count++] = triangle.y;\n }\n\n this.instancePositionBuffer.update();\n }\n\n private random(min: number, max: number) {\n return Math.random() * (max - min) + min;\n }\n\n private randVelocity() {\n let u1 = 1 - this.random(0, 1);\n let u2 = 1 - this.random(0, 1);\n let randStdNormal = (Math.sqrt(-2.0 * Math.log(u1)) * Math.sin(2.0 * Math.PI * u2));\n return Math.max(0.5 + 0.16 * randStdNormal, 0.1);\n }\n}\n\nexport interface Triangle {\n x: number;\n y: number;\n velocity: number;\n}\n","import * as PIXI from \"pixi.js\";\nimport {Main} from \"../../main\";\nimport {Loader} from \"../../Loader\";\nimport {MathUtil} from \"../../Util/MathUtil\";\nimport {Screen} from \"../../Screens/Screen\";\nimport {Ease} from \"../../Util/TweenWrapper/Ease\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\n\nexport class MenuCursor extends PIXI.Container {\n private mouseCursor = PIXI.Sprite.from(\"menu.cursor\");\n private mouseCursorAdditive = PIXI.Sprite.from(\"menu.cursor.additive\");\n private mouseContainer = new PIXI.Container();\n private animContainer = new PIXI.Container();\n private animRotationContainer = new PIXI.Container();\n private dragRotationState: DragRotationState = DragRotationState.NotDragging;\n private lastDragRotationState: DragRotationState = DragRotationState.NotDragging;\n private mouseHideContainer = new PIXI.Container();\n private readonly elastic_const2 = 0.075;\n private readonly elastic_const = 20.943951023931955;\n private readonly elastic_offset_quarter = Math.pow(2, -10) * Math.sin((.25 - this.elastic_const2) * this.elastic_const);\n\n private posMouseDown: { x: number, y: number } = {x: 0, y: 0};\n\n private mouseIsDown = false;\n\n private cursorTapSample = Loader.GetAudio(\"menu.cursor.sample.tap\");\n\n private mouseButtonClicked: number = -9999;\n\n public constructor(visible: boolean) {\n super();\n this.updateMouse();\n this.mouseContainer.scale.set(0.07 * Screen.getScaleBasedOffScreenSize());\n this.mouseCursorAdditive.alpha = 0;\n this.mouseCursorAdditive.blendMode = \"add\";\n this.mouseCursorAdditive.tint = \"0xFF66AA\"\n this.mouseContainer.addChild(this.mouseCursor);\n this.mouseContainer.addChild(this.mouseCursorAdditive);\n this.animContainer.addChild(this.mouseContainer);\n this.animRotationContainer.addChild(this.animContainer);\n this.mouseHideContainer.addChild(this.animRotationContainer);\n this.addChild(this.mouseHideContainer);\n if (!visible) {\n this.mouseHideContainer.scale.set(0.6);\n this.mouseHideContainer.alpha = 0;\n this.animRotationContainer.angle = 0;\n }\n this.zIndex = 999999;\n this.eventMode = \"none\";\n Main.app.stage.addChild(this);\n this.addEventListeners();\n }\n\n public addEventListeners() {\n Main.app.stage.addEventListener(\"mousedown\", (e) => {\n this.mouseButtonClicked = e.button;\n if (this.visible) {\n this.posMouseDown = {x: Main.mousePos.x, y: Main.mousePos.y};\n this.mouseIsDown = true;\n this.dragRotationState = DragRotationState.DragStarted;\n Ease.getEase(this.animContainer).ClearEasings().ScaleTo(0.9, 800, TWEEN.Easing.Quintic.Out);\n Ease.getEase(this.mouseCursorAdditive).ClearEasings().FadeIn(800, TWEEN.Easing.Quintic.Out);\n Main.AudioEngine.PlayEffect(this.cursorTapSample);\n }\n });\n Main.app.stage.addEventListener(\"mouseup\", (e) => {\n if (this.visible && e.button == this.mouseButtonClicked) {\n this.mouseIsDown = false;\n Ease.getEase(this.animContainer).ClearEasings().ScaleTo(1, 500, TWEEN.Easing.Elastic.Out);\n Ease.getEase(this.mouseCursorAdditive).ClearEasings().FadeOut(500, TWEEN.Easing.Quintic.Out);\n if (this.dragRotationState != DragRotationState.NotDragging) {\n if (this.dragRotationState == DragRotationState.Rotating) {\n Ease.getEase(this.animRotationContainer).ClearEasings().createTween({value: this.animRotationContainer.angle},\n {value: 0}, true, \"angle\", 800 * (0.5 + Math.abs(this.animRotationContainer.angle / 960)), (time: number) => {\n return Math.pow(2, -10 * time) * \n Math.sin((.25 * time - this.elastic_const2) * this.elastic_const) + 1 - this.elastic_offset_quarter * time;\n });\n }\n this.dragRotationState = DragRotationState.NotDragging;\n }\n Main.AudioEngine.PlayEffect(this.cursorTapSample, 0.8);\n }\n });\n }\n\n public PopIn() {\n Ease.getEase(this.animRotationContainer).ClearEasings();\n this.visible = true;\n Ease.getEase(this.mouseHideContainer).ClearEasings().FadeIn(250, TWEEN.Easing.Quintic.Out)\n .ScaleTo(1, 400, TWEEN.Easing.Quintic.Out);\n this.dragRotationState = DragRotationState.NotDragging\n }\n\n public PopOut() {\n Ease.getEase(this.mouseHideContainer).ClearEasings().FadeOut(250, TWEEN.Easing.Quintic.Out)\n .ScaleTo(0.6, 250, TWEEN.Easing.Quintic.Out);\n Ease.getEase(this.animRotationContainer).ClearEasings().createTween({value: this.animRotationContainer.angle},\n {value: 0}, true, \"angle\", 400, TWEEN.Easing.Quintic.Out);\n this.dragRotationState = DragRotationState.NotDragging;\n }\n\n public updateMouse() {\n this.mouseContainer.scale.set(0.07 * Screen.getScaleBasedOffScreenSize());\n this.position.set(Main.mousePos.x, Main.mousePos.y);\n if (this.dragRotationState != DragRotationState.NotDragging && this.visible) {\n let distance = Math.sqrt((((Math.abs(this.posMouseDown.x - Main.mousePos.x)) ^ 2) +\n ((Math.abs(this.posMouseDown.y - Main.mousePos.y)) ^ 2)));\n if (this.dragRotationState == DragRotationState.DragStarted && distance > 15) {\n this.dragRotationState = DragRotationState.Rotating;\n if (this.lastDragRotationState != this.dragRotationState) {\n this.posMouseDown = {x: Main.mousePos.x, y: Main.mousePos.y};\n }\n }\n\n if (this.dragRotationState == DragRotationState.Rotating && distance > 0) {\n let offsetX = Main.mousePos.x - this.posMouseDown.x;\n let offsetY = Main.mousePos.y - this.posMouseDown.y;\n let degrees = MathUtil.RadiansToDegrees(Math.atan2(-offsetX, offsetY)) + 24.3;\n\n let diff = (degrees - this.animRotationContainer.angle) % 360;\n if (diff < -180) {\n diff += 360;\n }\n if (diff > 180) {\n diff -= 360;\n }\n degrees = this.animRotationContainer.angle + diff;\n this.animRotationContainer.angle = degrees\n Ease.getEase(this.animRotationContainer).createTween({value: this.animRotationContainer.angle},\n {value: degrees}, true, \"angle\", 120, TWEEN.Easing.Quintic.Out);\n }\n }\n this.lastDragRotationState = this.dragRotationState;\n\n }\n\n\n}\n\nenum DragRotationState {\n NotDragging,\n DragStarted,\n Rotating\n}\n","import * as PIXI from \"pixi.js\";\nimport {Ease} from \"../../Util/TweenWrapper/Ease\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\n\nexport class Background extends PIXI.Sprite {\n public constructor(texture: PIXI.Texture) {\n super();\n this.texture = texture;\n this.visible = false;\n this.anchor.set(0.5, 0.5);\n\n }\n\n public show() {\n this.visible = true;\n }\n\n public destroy(options?: PIXI.DestroyOptions) {\n Ease.getEase(this).FadeOut(800, TWEEN.Easing.Linear.None).Then(() => {\n this.visible = false;\n super.destroy(options);\n });\n this.zIndex = 1;\n }\n}","import * as PIXI from \"pixi.js\";\nimport {Loader} from \"../../Loader\";\nimport {Screen} from \"../../Screens/Screen\";\nimport {Main} from \"../../main\";\nimport {Background} from \"./Background\";\n\nexport class RandomBackground extends Screen {\n\n private bgContainer = new PIXI.Container;\n\n private readonly parallaxMultiplier = 60;\n\n public start() {\n this.bgContainer.pivot.set(0.5, 0.5);\n this.bgContainer.position.set((Main.mousePos.x - (this.getScreenWidth() / 2)) / this.parallaxMultiplier,\n (Main.mousePos.y - (this.getScreenHeight() / 2)) / this.parallaxMultiplier);\n this.addChild(this.bgContainer);\n this.newRandomBG();\n Main.AudioEngine.addMusicChangeEventListener(() => {\n this.newRandomBG();\n });\n this.zIndex = -100;\n }\n\n public setBG(texture: PIXI.Texture) {\n let bgSprite = new Background(texture);\n this.bgContainer.addChild(bgSprite);\n bgSprite.show();\n if (this.bgContainer.children?.length == 0) {\n } else {\n let previous = this.bgContainer.children[0] as Background;\n previous.destroy();\n }\n this.onResize();\n }\n\n public newRandomBG() {\n function random(min: number, max: number) {\n return Math.round(Math.random() * (max - min) + min);\n }\n\n let useSeasonalBackgrounds = Loader.seasonalBackgroundsNum > 0;\n let randomNum = random(1, useSeasonalBackgrounds ? Loader.seasonalBackgroundsNum : Loader.defaultBackgroundsNum);\n this.setBG(PIXI.Texture.from((useSeasonalBackgrounds ? \"seasonal_bg\" : \"default_bg\") + randomNum));\n }\n\n public draw(deltaTime: PIXI.Ticker) {\n this.bgContainer.position.set((Main.mousePos.x - (this.getScreenWidth() / 2)) / this.parallaxMultiplier,\n (Main.mousePos.y - (this.getScreenHeight() / 2)) / this.parallaxMultiplier);\n }\n\n public onClose(): Promise {\n return Promise.resolve(this);\n }\n\n public onResize() {\n this.bgContainer.children.forEach((sprite) => {\n if (sprite instanceof Background) {\n let texWidth = sprite.texture.width;\n let texHeight = sprite.texture.height;\n\n let scaleFactor: number;\n if (window.innerWidth > window.innerHeight) {\n scaleFactor = window.innerWidth / texWidth;\n } else {\n scaleFactor = window.innerHeight / texHeight;\n }\n\n if (texHeight * scaleFactor < window.innerHeight) {\n scaleFactor = window.innerHeight / texHeight;\n } else if (texWidth * scaleFactor < window.innerWidth) {\n\n }\n\n sprite.scale.set(scaleFactor + 0.05);\n sprite.position.set((this.getScreenWidth() / 2) - (this.getScreenWidth() / (this.parallaxMultiplier * 2)),\n this.getScreenHeight() / 2 - (this.getScreenHeight() / (this.parallaxMultiplier * 2)));\n }\n });\n\n\n }\n\n}\n","import * as PIXI from \"pixi.js\";\nimport {Ease} from \"../../Util/TweenWrapper/Ease\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\nimport {Screen} from \"../../Screens/Screen\";\n\nexport class SettingsPane extends PIXI.Container {\n private bg: PIXI.Graphics = new PIXI.Graphics();\n private isOpen = false;\n\n public constructor() {\n super();\n this.bg.rect(0, 0, 1, 1);\n this.bg.fill({color: \"rgb(20,20,20)\"});\n this.addChild(this.bg);\n this.resize();\n }\n\n public open() {\n Ease.getEase(this).TransformTo({x: 0, y: 0}, 400, TWEEN.Easing.Cubic.Out);\n this.isOpen = true;\n }\n\n public toggle() {\n if (this.isOpen) {this.close()} else {this.open()}\n }\n\n public close() {\n Ease.getEase(this).TransformTo({x: -this.getWidth(), y: 0}, 400, TWEEN.Easing.Cubic.Out);\n this.isOpen = false;\n }\n\n private getWidth() {\n return 500 * Screen.getScaleBasedOffScreenSize();\n }\n\n public resize() {\n this.width = this.getWidth();\n this.height = window.innerHeight;\n this.x = this.isOpen ? 0 : -this.getWidth();\n this.y = 0;\n }\n}","import * as PIXI from \"pixi.js\";\n\nexport class Loader {\n private static loadList: LoaderObject[] = [];\n private static loadedList: LoadedObject[] = [];\n public static readonly defaultBackgroundsNum = 8;\n public static seasonalBackgroundsNum: number = 0;\n\n private static addToLoadList() {\n // intro and interaction screen\n this.loadList.push({id: \"introTrianglesTrack\", url: \"assets/osu-assets/osu.Game.Resources/Tracks/triangles.osz\"});\n this.loadList.push({id: \"sample_dialog_ok\", url: \"assets/osu-assets/osu.Game.Resources/Samples/UI/dialog-ok-select.wav\", isAudio: true});\n this.loadList.push({id: \"TorusRegular\", url: \"assets/fonts/TorusRegular.otf\", pixiBundleName: \"fonts\"});\n this.loadList.push({id: \"TorusLight\", url: \"assets/fonts/TorusLight.otf\", pixiBundleName: \"fonts\"});\n this.loadList.push({id: \"TorusThin\", url: \"assets/fonts/TorusThin.otf\", pixiBundleName: \"fonts\"});\n this.loadList.push({id: \"icon_ruleset_std\", url: \"assets/icons/ruleset-standard.png\", pixiBundleName: \"textures\"});\n this.loadList.push({id: \"icon_ruleset_mania\", url: \"assets/icons/ruleset-mania.png\", pixiBundleName: \"textures\"});\n this.loadList.push({id: \"icon_ruleset_taiko\", url: \"assets/icons/ruleset-taiko.png\", pixiBundleName: \"textures\"});\n this.loadList.push({id: \"icon_ruleset_ctb\", url: \"assets/icons/ruleset-ctb.png\", pixiBundleName: \"textures\"});\n this.loadList.push({id: \"intro_triangles_osuLogo_anim_highlight\",\n url: \"assets/osu-assets/osu.Game.Resources/Textures/Intro/Triangles/logo-highlight.png\", pixiBundleName: \"textures\"});\n this.loadList.push({id: \"intro_triangles_osuLogo_anim_background\",\n url: \"assets/osu-assets/osu.Game.Resources/Textures/Intro/Triangles/logo-background.png\", pixiBundleName: \"textures\"});\n this.loadList.push({id: \"mainMenu.logoOutline\", url: \"assets/osu-assets/osu.Game.Resources/Textures/Menu/logo.png\", pixiBundleName: \"textures\"});\n this.loadList.push({id: \"mainMenu.logoMask\", url: \"assets/menu/logo-mask.png\", pixiBundleName: \"textures\"});\n this.loadList.push({id: \"mainMenu.osuLogo.select\", url: \"assets/osu-assets/osu.Game.Resources/Samples/Menu/osu-logo-select.wav\", isAudio: true});\n this.loadList.push({id: \"mainMenu.osuLogo.backToLogo\", url: \"assets/osu-assets/osu.Game.Resources/Samples/Menu/back-to-logo.wav\", isAudio: true});\n this.loadList.push({id: \"menu.cursor\", url: \"assets/osu-assets/osu.Game.Resources/Textures/Cursor/menu-cursor.png\", pixiBundleName: \"textures\"});\n this.loadList.push({id: \"menu.cursor.additive\", url: \"assets/osu-assets/osu.Game.Resources/Textures/Cursor/menu-cursor-additive.png\",\n pixiBundleName: \"textures\"});\n this.loadList.push({id: \"menu.cursor.sample.tap\", url: \"assets/osu-assets/osu.Game.Resources/Samples/UI/cursor-tap.wav\", isAudio: true});\n this.loadList.push({id: \"menu.kiaiFountains.star\", url: \"assets/osu-assets/osu.Game.Resources/Textures/Menu/fountain-star.png\", pixiBundleName: \"textures\"});\n }\n\n public static Get(id: string): Blob {\n let result;\n this.loadedList.forEach((loadedObj) => {\n if (loadedObj.id == id){\n result = loadedObj.data;\n }\n });\n if (!result){\n throw new Error(\"Asset not found!\");\n }\n return result;\n }\n\n public static GetString(id: string): string {\n let result;\n this.loadedList.forEach((loadedObj) => {\n if (loadedObj.id == id){\n result = loadedObj.dataString;\n }\n });\n if (!result){\n throw new Error(\"Asset not found or is not a string!\");\n }\n return result;\n }\n\n public static GetAudio(id: string): AudioBuffer {\n let result;\n this.loadedList.forEach((loadedObj) => {\n if (loadedObj.id == id){\n result = loadedObj.dataAudio;\n }\n });\n if (!result){\n throw new Error(\"Asset not found or was not marked as audio during loading!\");\n }\n return result;\n }\n\n private static addBackgrounds() {\n return new Promise(resolve => {\n for (let i = 1; i < this.defaultBackgroundsNum + 1; i++) {\n this.loadList.push({id: \"default_bg\"+i, url: \"assets/osu-assets/osu.Game.Resources/Textures/Menu/menu-background-\"+i+\".jpg\", pixiBundleName: \"textures\"});\n }\n fetch(\"https://corsproxy.io/?\"+ encodeURIComponent(\"https://osu.ppy.sh/api/v2/seasonal-backgrounds\"))\n .then(res => res.json()).then(res => {\n res.backgrounds.forEach((background: any, index: number) => {\n this.loadList.push({id: \"seasonal_bg\"+(index+1), url: \"https://corsproxy.io/?\"+ encodeURIComponent(background.url),\n pixiBundleName: \"textures\", loadParser: \"loadTextures\"});\n this.seasonalBackgroundsNum = index+1;\n });\n resolve();\n }).catch(error => {\n console.warn(\"Could not fetch seasonal backgrounds.\", error);\n resolve();\n });\n });\n }\n\n public static Load(audioContext: AudioContext) {\n this.addToLoadList();\n return new Promise((resolve) => {\n this.addBackgrounds().then(() => {\n let nonPixi: LoaderObject[] = [];\n let pixi: LoaderObject[] = [];\n let pixiwithBundles: LoaderObject[][] = [];\n\n let loadedAssets: number = 0;\n let erroredAssets: number = 0;\n\n this.loadList.forEach((loadObj) => {\n if (loadObj.pixiBundleName){\n pixi.push(loadObj);\n }\n else {\n nonPixi.push(loadObj);\n }\n });\n\n pixi.forEach((loadObj) => {\n let added = false;\n pixiwithBundles.forEach((loadObjs) => {\n if (loadObjs.length > 0){\n if (loadObjs[0].pixiBundleName == loadObj.pixiBundleName){\n loadObjs.push(loadObj);\n added = true;\n }\n }\n });\n if (!added){\n pixiwithBundles.push([loadObj]);\n }\n });\n\n const incrementLoadAssetNumber = (errored?: boolean) => {\n if (errored){\n erroredAssets++;\n }\n else {\n loadedAssets++;\n }\n\n if (erroredAssets + loadedAssets >= this.loadList.length){\n resolve();\n }\n }\n\n nonPixi.forEach((loadObj) => {\n fetch(loadObj.url)\n .then(response => response.blob())\n .then((response) => {\n if (!loadObj.isText && !loadObj.isAudio){\n incrementLoadAssetNumber();\n this.loadedList.push({id: loadObj.id, data: response});\n }\n else if (loadObj.isText) {\n response.text().then((text) => {\n incrementLoadAssetNumber();\n this.loadedList.push({id: loadObj.id, data: response, dataString: text});\n });\n }\n else if (loadObj.isAudio){\n response.arrayBuffer().then(arrBuff => audioContext.decodeAudioData(arrBuff))\n .then((audioBuff) => {\n incrementLoadAssetNumber();\n this.loadedList.push({id: loadObj.id, data: response, dataAudio: audioBuff});\n });\n }\n\n })\n .catch((error) => {\n incrementLoadAssetNumber(true);\n console.warn(\"Asset '\"+loadObj.id+\"' failed to load: \"+error);\n });\n });\n\n pixiwithBundles.forEach((bundle) => {\n if (bundle.length > 0){\n if (!bundle[0].pixiBundleName){\n throw new Error(\"wtf????\");\n }\n let assets: PIXI.UnresolvedAsset[] = [];\n bundle.forEach((loadObj) => {\n if (loadObj.loadParser){\n assets.push({alias: loadObj.id, src: loadObj.url, loadParser: loadObj.loadParser});\n }\n else {\n assets.push({alias: loadObj.id, src: loadObj.url});\n }\n\n });\n PIXI.Assets.addBundle(bundle[0].pixiBundleName, assets);\n PIXI.Assets.loadBundle(bundle[0].pixiBundleName).then(() => {\n bundle.forEach(() => {\n incrementLoadAssetNumber();\n });\n });\n }\n\n })\n });\n });\n }\n}\n\ninterface LoaderObject {\n id: string;\n url: string;\n pixiBundleName?: string;\n isText?: boolean;\n isAudio?: boolean;\n loadParser?: PIXI.LoadParserName;\n}\n\ninterface LoadedObject {\n id: string;\n data: Blob;\n dataString?: string;\n dataAudio?: AudioBuffer;\n}\n","import {Screen} from \"../Screen\";\nimport * as PIXI from \"pixi.js\";\nimport {Ticker} from \"pixi.js\";\nimport {Main} from \"../../main\";\nimport {IntroScreen} from \"../IntroScreen/IntroScreen\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\nimport {Ease} from \"../../Util/TweenWrapper/Ease\";\n\nexport class InteractScreen extends Screen {\n\n private readonly text: PIXI.Text;\n private readonly text2: PIXI.Text;\n private readonly textContainer = new PIXI.Container();\n private readonly textContainerContainer = new PIXI.Container();\n\n private readonly introTrack: Blob;\n private clickSound: AudioBuffer;\n\n private readonly clickArea: PIXI.Graphics = new PIXI.Graphics();\n\n public constructor(introTrack: Blob, clickSound: AudioBuffer) {\n super();\n this.introTrack = introTrack;\n this.clickSound = clickSound;\n\n this.text = new PIXI.Text({\n text: \"Click anywhere to play!\",\n style: {\n fontFamily: 'TorusRegular',\n fontSize: 36,\n fill: \"white\"\n }\n });\n this.text2 = new PIXI.Text({\n text: \"(this is for enabling audio because it's required by web-browsers\\n to have interaction on this webpage before playing audio.)\",\n style: {\n fontFamily: 'TorusRegular',\n fontSize: 26,\n fill: \"gray\",\n align: \"center\"\n }\n });\n }\n\n public start() {\n this.text.anchor.set(0.5, 0.5);\n this.text2.anchor.set(0.5, 0.5);\n this.text2.position.set(0, this.text.height + 15);\n this.textContainer.addChild(this.text);\n this.textContainer.addChild(this.text2);\n this.textContainer.scale.set(0.5);\n this.textContainer.alpha = 0;\n this.textContainerContainer.addChild(this.textContainer);\n this.textContainerContainer.scale = Screen.getScaleBasedOffScreenSize();\n this.textContainerContainer.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n this.addChild(this.textContainerContainer);\n\n this.clickArea.rect(0, 0, 1, 1);\n this.clickArea.fill(\"rgba(0,0,0,0)\");\n this.clickArea.width = this.getScreenWidth();\n this.clickArea.height = this.getScreenHeight();\n this.clickArea.position.set(0, 0);\n this.addChild(this.clickArea);\n\n this.clickArea.eventMode = \"static\";\n this.clickArea.cursor = \"pointer\";\n\n const clicked = () => {\n this.clickArea.eventMode = \"none\";\n Main.AudioEngine.PlayEffect(this.clickSound);\n Main.switchScreen(new IntroScreen(this.introTrack));\n document.body.style.cursor = \"none\";\n Main.pointerLock();\n Main.lockKeyboard();\n }\n\n this.clickArea.onclick = () => {\n clicked();\n\n }\n this.clickArea.ontap = () => {\n clicked();\n }\n Ease.getEase(this.textContainer).FadeIn(400, TWEEN.Easing.Quadratic.Out)\n .ScaleTo(1, 400, TWEEN.Easing.Quadratic.Out);\n }\n\n public onClose(): Promise {\n return new Promise((resolve) => {\n Ease.getEase(this.textContainer).FadeOut(200, TWEEN.Easing.Quadratic.Out)\n .ScaleTo(0.5, 200, TWEEN.Easing.Quadratic.InOut);\n setTimeout(() => {\n resolve(this);\n }, 200);\n });\n }\n\n public draw(deltaTime: Ticker) {\n\n }\n\n public onResize() {\n this.textContainerContainer.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n this.clickArea.width = this.getScreenWidth();\n this.clickArea.height = this.getScreenHeight();\n this.clickArea.position.set(0, 0);\n this.textContainerContainer.scale = Screen.getScaleBasedOffScreenSize();\n }\n}\n","import * as PIXI from \"pixi.js\";\nimport {Ease} from \"../../Util/TweenWrapper/Ease\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\n\nexport class GlitchingTriangles extends PIXI.Container {\n public constructor(bounds: GlitchingTrianglesBounds) {\n super();\n let triangle = new PIXI.Graphics();\n let scale = random(0.2, 1.2);\n triangle.moveTo(0, 0);\n triangle.lineTo(-50 * scale, 100 * scale);\n triangle.lineTo(50 * scale, 100 * scale);\n triangle.lineTo(0, 0);\n if (Math.random() < 0.5) {\n triangle.fill(\"white\");\n } else {\n triangle.stroke({color: \"white\", width: 1});\n }\n\n //triangle.anchor.set(0.5, 0.5)\n function random(min: number, max: number) {\n return Math.random() * (max - min) + min;\n }\n\n let randX = random(bounds.x1, bounds.x2);\n let randY = random(bounds.y1, bounds.y2);\n\n triangle.position.set(randX, randY);\n\n Ease.getEase(triangle, true).FadeOut(200, TWEEN.Easing.Linear.None);\n setTimeout(() => {\n this.destroy();\n }, 200);\n\n this.addChild(triangle);\n }\n\n}\n\nexport interface GlitchingTrianglesBounds {\n x1: number;\n x2: number;\n y1: number;\n y2: number;\n}\n","import {Screen} from \"../Screen\";\nimport * as PIXI from \"pixi.js\";\nimport {Ticker} from \"pixi.js\";\nimport {unzip} from 'unzipit';\nimport {Main} from \"../../main\";\nimport {GlitchingTriangles} from \"./GlitchingTriangles\";\nimport {MainMenu} from \"../MainMenu/MainMenu\";\nimport {LazerLogo} from \"./LazerLogo\";\nimport {BeatmapParser} from \"../../Util/Beatmap/Parser/BeatmapParser\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\nimport {Ease} from \"../../Util/TweenWrapper/Ease\";\n\nexport class IntroScreen extends Screen {\n\n private readonly introTrackUrl: string;\n\n private doTextSpacingAnim = false;\n private triangles = new PIXI.Container();\n private ruleSetContainer = new PIXI.Container();\n private flash = new PIXI.Graphics();\n\n private logoContainerContainer = new PIXI.Container();\n\n private logoContainer = new PIXI.Container();\n\n private lazerLogo = new LazerLogo();\n\n private flashed = false;\n\n private standard = PIXI.Sprite.from('icon_ruleset_std');\n private taiko = PIXI.Sprite.from('icon_ruleset_taiko');\n private ctb = PIXI.Sprite.from('icon_ruleset_ctb');\n private mania = PIXI.Sprite.from('icon_ruleset_mania');\n\n private bg: PIXI.Graphics = new PIXI.Graphics();\n\n private completionPromise!: Promise;\n\n private welcomeText: PIXI.Text = new PIXI.Text({\n text: \"\",\n style: {\n fontFamily: \"TorusThin\",\n fontSize: 42,\n fill: \"white\",\n letterSpacing: 5\n }\n });\n\n public constructor(introTrack: Blob) {\n super();\n this.introTrackUrl = URL.createObjectURL(introTrack);\n this.bg.rect(0, 0, 1, 1,);\n this.bg.fill(\"black\");\n }\n\n public start() {\n this.bg.width = window.innerWidth;\n this.bg.height = window.innerHeight;\n this.bg.x = 0;\n this.bg.y = 0;\n this.addChild(this.bg);\n this.lazerLogo.scale.set(Screen.getScaleBasedOffScreenSize());\n this.logoContainer.addChild(this.lazerLogo);\n this.logoContainer.scale.set(1.2);\n\n this.logoContainerContainer.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n this.logoContainerContainer.pivot.set(0.5, 0.5);\n this.logoContainerContainer.addChild(this.logoContainer);\n this.logoContainerContainer.alpha = 0;\n this.addChild(this.logoContainerContainer);\n\n this.flash.rect(0, 0, 1, 1);\n this.flash.fill(\"white\");\n this.flash.position.set(0, 0);\n this.flash.width = this.getScreenWidth();\n this.flash.height = this.getScreenHeight();\n this.flash.blendMode = \"add\";\n this.welcomeText.anchor.set(0.5, 0.5);\n this.welcomeText.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n setTimeout(async () => {\n const {entries} = await unzip(this.introTrackUrl);\n for (const [name, entry] of Object.entries(entries)) {\n if (name.endsWith(\".osu\")) {\n entry.text().then((osuFile) => {\n let beatmapData = BeatmapParser.Parse(osuFile);\n console.log(beatmapData);\n for (const [name, entry] of Object.entries(entries)) {\n if (name == beatmapData.General.AudioFileName) {\n entry.arrayBuffer().then(arrBuff => Main.AudioEngine.audioContext.decodeAudioData(arrBuff))\n .then((audioBuff) => {\n Main.AudioEngine.PlayMusicImmediately(audioBuff, beatmapData, () => {\n this.afterAudioPlay();\n });\n });\n }\n }\n\n });\n\n\n break;\n }\n }\n }, 0);\n }\n\n public afterAudioPlay() {\n this.completionPromise = new Promise((resolve) => {\n this.welcomeText.scale.set(Screen.getScaleBasedOffScreenSize());\n this.addChild(this.welcomeText);\n setTimeout(() => {\n this.welcomeText.text = \"wel\";\n this.onResize();\n }, 200);\n setTimeout(() => {\n this.welcomeText.text = \"welcome\";\n this.onResize();\n }, 400);\n setTimeout(() => {\n this.welcomeText.text = \"welcome to\";\n this.onResize();\n }, 700);\n let glitchingInterval: NodeJS.Timeout;\n\n this.triangles.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n this.triangles.scale.set(Screen.getScaleBasedOffScreenSize());\n this.addChild(this.triangles);\n setTimeout(() => {\n this.welcomeText.text = \"welcome to kosu!\";\n this.doTextSpacingAnim = true;\n glitchingInterval = setInterval(() => {\n let triangle = new GlitchingTriangles({\n x1: -(this.welcomeText.width / 2) - 100,\n x2: (this.welcomeText.width / 2) + 100,\n y1: -(this.welcomeText.height / 2) - 150,\n y2: (this.welcomeText.height / 2) + 100\n });\n this.triangles.addChild(triangle);\n }, 30);\n this.onResize();\n }, 900);\n\n\n this.standard.anchor.set(0.5, 0.5);\n this.standard.scale.set(0.4 * Screen.getScaleBasedOffScreenSize());\n this.ruleSetContainer.addChild(this.standard);\n this.taiko.anchor.set(0.5, 0.5);\n this.taiko.scale.set(0.4 * Screen.getScaleBasedOffScreenSize());\n this.ruleSetContainer.addChild(this.taiko);\n this.ctb.anchor.set(0.5, 0.5);\n this.ctb.scale.set(0.4 * Screen.getScaleBasedOffScreenSize());\n this.ruleSetContainer.addChild(this.ctb);\n this.mania.anchor.set(0.5, 0.5);\n this.mania.scale.set(0.4 * Screen.getScaleBasedOffScreenSize());\n this.ruleSetContainer.addChild(this.mania);\n\n setTimeout(() => {\n this.doTextSpacingAnim = false;\n this.onResize();\n clearInterval(glitchingInterval);\n this.welcomeText.destroy();\n this.triangles.destroy();\n this.ruleSetContainer.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n\n this.addChild(this.ruleSetContainer);\n\n let spacing = 100;\n this.standard.position.set(-((spacing * 2) + 175) * Screen.getScaleBasedOffScreenSize(), 0);\n this.taiko.position.set(-((spacing) + 25) * Screen.getScaleBasedOffScreenSize(), 0);\n this.ctb.position.set(((spacing) + 25) * Screen.getScaleBasedOffScreenSize(), 0);\n this.mania.position.set(((spacing * 2) + 175) * Screen.getScaleBasedOffScreenSize(), 0);\n Ease.getEase(this.ruleSetContainer).ScaleTo(0.8, 1000, TWEEN.Easing.Linear.None);\n }, 1450);\n\n setTimeout(() => {\n let spacing = 15;\n this.standard.position.set(-((spacing * 2) + 210) * Screen.getScaleBasedOffScreenSize(), 0);\n this.taiko.position.set(-((spacing) + 60) * Screen.getScaleBasedOffScreenSize(), 0);\n this.ctb.position.set(((spacing) + 60) * Screen.getScaleBasedOffScreenSize(), 0);\n this.mania.position.set(((spacing * 2) + 210) * Screen.getScaleBasedOffScreenSize(), 0);\n\n this.standard.scale.set(Screen.getScaleBasedOffScreenSize());\n this.taiko.scale.set(Screen.getScaleBasedOffScreenSize());\n this.ctb.scale.set(Screen.getScaleBasedOffScreenSize());\n this.mania.scale.set(Screen.getScaleBasedOffScreenSize());\n }, 1650);\n\n setTimeout(() => {\n let spacing = 60;\n this.standard.position.set(-((spacing * 2) + 230) * Screen.getScaleBasedOffScreenSize(), 0);\n this.taiko.position.set(-((spacing) + 60) * Screen.getScaleBasedOffScreenSize(), 0);\n this.ctb.position.set(((spacing) + 60) * Screen.getScaleBasedOffScreenSize(), 0);\n this.mania.position.set(((spacing * 2) + 230) * Screen.getScaleBasedOffScreenSize(), 0);\n\n this.standard.scale.set(2 * Screen.getScaleBasedOffScreenSize());\n this.taiko.scale.set(2 * Screen.getScaleBasedOffScreenSize());\n this.ctb.scale.set(2 * Screen.getScaleBasedOffScreenSize());\n this.mania.scale.set(2 * Screen.getScaleBasedOffScreenSize());\n Ease.getEase(this.ruleSetContainer).ScaleTo(1.3, 1000, TWEEN.Easing.Linear.None);\n }, 1850);\n\n setTimeout(() => {\n this.ruleSetContainer.destroy();\n this.lazerLogo.start();\n\n this.logoContainerContainer.alpha = 1;\n\n this.logoContainerContainer.scale.set(1.2);\n Ease.getEase(this.logoContainerContainer).ScaleTo(1.2 - 0.8 * 0.25, 920, TWEEN.Easing.Quadratic.In);\n\n setTimeout(() => {\n Ease.getEase(this.logoContainer).ScaleTo(1.2 - 0.8, 920 * 0.3, TWEEN.Easing.Quintic.In);\n }, 920 * 0.7);\n }, 2080);\n\n setTimeout(() => {\n this.addChild(this.flash);\n this.bg.destroy();\n this.flash.eventMode = \"none\";\n this.flashed = true;\n this.logoContainerContainer.visible = false;\n Ease.getEase(this.flash).FadeOut(1000, TWEEN.Easing.Quadratic.Out).Then(() => {resolve();});\n Main.cursor.PopIn();\n }, 3000);\n });\n Main.switchScreen(new MainMenu());\n }\n\n public draw(deltaTime: Ticker) {\n if (this.doTextSpacingAnim) {\n this.welcomeText.style.letterSpacing += 0.15 * deltaTime.deltaTime;\n this.onResize();\n }\n }\n\n public onClose(): Promise {\n return new Promise((resolve) => {\n this.completionPromise.then(()=> {\n resolve(this);\n })\n });\n }\n\n public onResize() {\n if (!this.bg.destroyed){\n this.bg.width = window.innerWidth;\n this.bg.height = window.innerHeight;\n this.bg.x = 0;\n this.bg.y = 0;\n }\n if (!this.welcomeText.destroyed) {\n this.welcomeText.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n }\n if (!this.triangles.destroyed) {\n this.triangles.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n this.triangles.scale.set(Screen.getScaleBasedOffScreenSize());\n }\n if (!this.ruleSetContainer.destroyed) {\n this.ruleSetContainer.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n }\n if (!this.flash.destroyed && this.flashed) {\n this.flash.position.set(0, 0);\n this.flash.width = this.getScreenWidth();\n this.flash.height = this.getScreenHeight();\n }\n if (!this.logoContainerContainer.destroyed) {\n this.logoContainerContainer.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n }\n if (!this.lazerLogo.destroyed) {\n this.lazerLogo.scale.set(Screen.getScaleBasedOffScreenSize());\n }\n if (!this.welcomeText.destroyed) {\n this.welcomeText.scale.set(Screen.getScaleBasedOffScreenSize());\n }\n if (!this.standard.destroyed) {\n this.standard.scale.set(0.4 * Screen.getScaleBasedOffScreenSize());\n }\n if (!this.mania.destroyed) {\n this.mania.scale.set(0.4 * Screen.getScaleBasedOffScreenSize());\n }\n if (!this.ctb.destroyed) {\n this.ctb.scale.set(0.4 * Screen.getScaleBasedOffScreenSize());\n }\n if (!this.taiko.destroyed) {\n this.taiko.scale.set(0.4 * Screen.getScaleBasedOffScreenSize());\n }\n }\n}\n","import * as PIXI from \"pixi.js\";\nimport {LogoAnimation} from \"./LogoAnimation\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\nimport {Ease} from \"../../Util/TweenWrapper/Ease\";\n\nexport class LazerLogo extends PIXI.Container {\n private readonly highlight: LogoAnimation;\n private readonly background: LogoAnimation;\n private textureHighlight = PIXI.Texture.from(\"intro_triangles_osuLogo_anim_highlight\");\n private textureBackground = PIXI.Texture.from(\"intro_triangles_osuLogo_anim_background\");\n\n public constructor() {\n super();\n this.highlight = new LogoAnimation(this.textureHighlight, new PIXI.Color(\"white\"));\n this.background = new LogoAnimation(this.textureBackground, new PIXI.Color(\"rgb(128, 128, 128)\"));\n this.addChild(this.highlight);\n this.addChild(this.background);\n }\n\n public start() {\n let dummy = new PIXI.Container();\n dummy.scale.set(0.0, 0.0);\n Ease.getEase(dummy).ScaleTo(1, 920, TWEEN.Easing.Linear.None).OnEach(() => {\n this.highlight.setProgress(dummy.scale.x);\n this.background.setProgress(dummy.scale.x);\n });\n }\n}\n","import * as PIXI from \"pixi.js\"\nimport glVertShader from \"./logoAnimation.vert\";\nimport glFragShader from \"./logoAnimation.frag\";\nimport gpuShader from \"./logoAnimation.wgsl\";\n\nexport class LogoAnimation extends PIXI.Container {\n private shader: PIXI.Shader;\n private texture: PIXI.Texture;\n\n public constructor(texture: PIXI.Texture, color: PIXI.Color) {\n super();\n this.texture = texture\n this.shader = PIXI.Shader.from({\n gl: {\n vertex: glVertShader,\n fragment: glFragShader,\n },\n gpu: {\n vertex: {\n entryPoint: 'mainVert',\n source: gpuShader\n },\n fragment: {\n entryPoint: 'mainFrag',\n source: gpuShader\n }\n },\n resources: {\n uTexture: this.texture.source,\n uSampler: this.texture.source.style,\n uProgress: {\n progress: {value: 0.0, type: 'f32'},\n },\n },\n });\n const quadGeometry = new PIXI.Geometry({\n attributes: {\n aPosition: [\n -this.texture.width / 2,\n -this.texture.height / 2, // x, y\n this.texture.width / 2,\n -this.texture.height / 2, // x, y\n this.texture.width / 2,\n this.texture.width / 2, // x, y,\n -this.texture.width / 2,\n this.texture.width / 2, // x, y,\n ],\n aUV: [0, 0, 1, 0, 1, 1, 0, 1],\n aColor: [\n color.red, color.green, color.blue, color.alpha,\n color.red, color.green, color.blue, color.alpha,\n color.red, color.green, color.blue, color.alpha,\n color.red, color.green, color.blue, color.alpha\n ]\n },\n indexBuffer: [0, 1, 2, 0, 2, 3],\n });\n const quad = new PIXI.Mesh({\n geometry: quadGeometry,\n shader: this.shader,\n });\n this.addChild(quad);\n }\n\n public setProgress(progress: number) {\n this.shader.resources.uProgress.uniforms.progress = progress;\n }\n}\n","import {Screen} from \"../Screen\";\nimport {LoadAnim} from \"../../Elements/LoadAnim/LoadAnim\";\nimport * as PIXI from \"pixi.js\";\n\nexport class LoadScreen extends Screen {\n\n private loadAnim = new LoadAnim(\"rgba(255,255,255,0.7)\", \"black\");\n\n public start() {\n this.loadAnim.scale.set(0.8 * Screen.getScaleBasedOffScreenSize());\n this.loadAnim.position.set(this.getScreenWidth() - this.loadAnim.getWidth() - 15, this.getScreenHeight() - this.loadAnim.getHeight() - 15);\n this.addChild(this.loadAnim);\n }\n\n public draw(deltaTime: PIXI.Ticker) {\n this.loadAnim?.draw(deltaTime);\n }\n\n public onClose(): Promise {\n return new Promise((resolve) => {\n if (this.loadAnim != null) {\n this.loadAnim.destroy();\n }\n setTimeout(() => {\n resolve(this);\n }, 400);\n });\n }\n\n public onResize() {\n this.loadAnim.position.set(this.getScreenWidth() - this.loadAnim.getWidth() - 20, this.getScreenHeight() - this.loadAnim.getHeight() - 20);\n this.loadAnim.scale.set(0.8 * Screen.getScaleBasedOffScreenSize());\n }\n}\n","import {Screen} from \"../Screen\";\nimport * as PIXI from \"pixi.js\";\nimport {RandomBackground} from \"../../Elements/RandomBackground/RandomBackground\";\nimport {OsuCircle} from \"../../Elements/MainMenu/OsuCircle/OsuCircle\";\n\nexport class MainMenu extends Screen {\n private bg = new RandomBackground();\n private osuCircle = new OsuCircle();\n\n public start() {\n this.bg.start();\n this.addChild(this.bg);\n this.osuCircle.scale = Screen.getScaleBasedOffScreenSize();\n this.addChild(this.osuCircle);\n }\n\n public draw(deltaTime: PIXI.Ticker) {\n this.bg.draw(deltaTime);\n this.osuCircle.draw(deltaTime);\n }\n\n public onClose(): Promise {\n return new Promise((resolve) => {\n this.bg.onClose().then(() => {\n resolve(this);\n });\n })\n }\n\n public onResize() {\n this.osuCircle.position.set(this.getScreenWidth() / 2, this.getScreenHeight() / 2);\n this.bg.onResize();\n this.osuCircle.onResize();\n this.osuCircle.scale = Screen.getScaleBasedOffScreenSize();\n }\n}\n","import * as PIXI from \"pixi.js\";\nimport {Settings} from \"../Settings/Settings\";\nimport {UIScale} from \"../Settings/impl/Graphics/UIScale\";\n\nexport abstract class Screen extends PIXI.Container {\n\n public constructor() {\n super();\n }\n\n public static getScaleBasedOffScreenSize() {\n // this was made with 1080p screens in mind.\n const uiScale = Settings.getSetting(UIScale).getValue();\n return ((((window.innerWidth / 1920) + (window.innerHeight / 1080)) / 2)) * uiScale\n }\n\n /**\n * Called once before the first frame is drawn\n */\n public abstract start(): void;\n\n\n /**\n * Called every frame\n */\n public abstract draw(deltaTime: PIXI.Ticker): void;\n\n /**\n * Called when screen will be closed, but has to return a promise to clean up after, for example, the screen's close animations are done.\n * Make sure you also pass in `this` into the promise's resolve.\n */\n public abstract onClose(): Promise;\n\n public abstract onResize(): void;\n\n protected getScreenWidth(): number {\n return window.innerWidth;\n }\n\n protected getScreenHeight(): number {\n return window.innerHeight;\n }\n}\n","import {Settings} from \"./Settings\";\n\nexport abstract class Setting {\n public readonly info: Settings;\n\n public constructor(SettingData: SettingInfo) {\n this.info = SettingData;\n Settings.register({setting: this, info: SettingData});\n }\n\n public abstract getValue(): any;\n\n public abstract getDefaultValue(): any;\n\n public abstract setValue(value: any): void;\n\n protected onValueChanged(): void {}\n\n /** When implementing this method, do **NOT** save the settings. This is so that loading won't reset most settings. */\n public abstract loadFromSaveValue(value: any): void;\n}\n\nexport interface SettingInfo {\n name: string;\n category: SettingsCategory;\n}\n\nexport enum SettingsCategory {\n General = \"General\",\n Skin = \"Skin\",\n Input = \"Input\",\n UserInterface = \"User Interface\",\n Gameplay = \"Gameplay\",\n Rulesets = \"Rulesets\",\n Audio = \"Audio\",\n Graphics = \"Graphics\",\n Online = \"Online\",\n Maintenance = \"Maintenance\",\n Debug = \"Debug\"\n}\n","import {Setting} from \"../Setting\";\nimport {Settings} from \"../Settings\";\n\nexport abstract class DropdownSetting extends Setting {\n public abstract readonly list: DropDownOption[];\n public abstract readonly defaultValue: DropDownOption;\n protected value: DropDownOption | undefined;\n\n public getValue(): DropDownOption {\n if (!this.value)\n throw new Error(\"Value is undefined!\");\n return this.value;\n }\n\n public getDefaultValue(): DropDownOption {\n return this.defaultValue;\n }\n\n public setValue(value: DropDownOption) {\n if (this.list.find((option) => option.value == value.value && option.displayName == value.displayName )) {\n this.value = value;\n Settings.save();\n this.onValueChanged();\n } else {\n console.warn('The value provided to this DropDownSetting does not exist in the option list! Ignoring value provided.');\n }\n }\n\n public loadFromSaveValue(value: DropDownOption) {\n if (this.list.find((option) => option.value == value.value && option.displayName == value.displayName)) {\n this.value = value;\n this.onValueChanged();\n } else {\n console.warn('The value provided to this DropDownSetting does not exist in the option list! Ignoring value provided.');\n }\n }\n}\n\nexport interface DropDownOption {\n displayName: string;\n value: string;\n}\n","import {Setting} from \"../Setting\";\nimport {Settings} from \"../Settings\";\nimport {MathUtil} from \"../../Util/MathUtil\";\n\nexport abstract class RangeSetting extends Setting {\n public abstract readonly minValue: number;\n public abstract readonly maxValue: number;\n public abstract readonly increment: number;\n public abstract readonly defaultValue: number;\n protected value: number = 0;\n\n public getValue(): number {\n return this.value;\n }\n\n public getDefaultValue(): number {\n return this.defaultValue;\n }\n\n public setValue(value: number) {\n this.value = MathUtil.clamp(this.minValue, this.maxValue, value);\n Settings.save();\n this.onValueChanged();\n }\n\n public loadFromSaveValue(value: number) {\n this.value = MathUtil.clamp(this.minValue, this.maxValue, value);\n this.onValueChanged();\n }\n}\n","import {Setting, SettingInfo} from \"./Setting\";\nimport {UIScale} from \"./impl/Graphics/UIScale\";\nimport {Renderer} from \"./impl/Graphics/Renderer\";\nimport {MouseSensitivity} from \"./impl/Input/MouseSensitivity\";\n\nexport class Settings {\n private static settingsList: SettingData[] = [];\n\n public static registerAll() {\n new UIScale();\n new Renderer();\n new MouseSensitivity();\n }\n\n public static load() {\n let settingSaveDataString = window.localStorage.getItem(\"settings\");\n if (settingSaveDataString == null) {\n return;\n }\n let settings = this.getList();\n try {\n let settingSaveData: SettingSaveData[] = JSON.parse(settingSaveDataString) as SettingSaveData[];\n settingSaveData.forEach((setting) => {\n let corrupt = false;\n try {\n if (!setting.value) {\n console.warn(\"Setting '\" + JSON.stringify(setting) + \"' may be corrupted, skipping!\");\n corrupt = true;\n }\n if (setting.info) {\n if (!setting.info.name) {\n console.warn(\"Setting '\" + JSON.stringify(setting) + \"' may be corrupted, skipping!\");\n corrupt = true;\n }\n if (!setting.info.category) {\n console.warn(\"Setting '\" + JSON.stringify(setting) + \"' may be corrupted, skipping!\");\n corrupt = true;\n }\n }\n else {\n console.warn(\"Setting '\" + JSON.stringify(setting) + \"' may be corrupted, skipping!\");\n corrupt = true;\n }\n }\n catch (e) {\n console.warn(\"Something went wrong when validating saved settings!\", e);\n console.warn(\"The setting may be REALLY corrupted, skipping!\");\n corrupt = true;\n }\n if (!corrupt) {\n let settingObj = settings.filter((_settingObj) => (_settingObj.info.name == setting.info.name) &&\n _settingObj.info.category == setting.info.category)[0];\n if (settingObj) {\n settingObj.setting.loadFromSaveValue(setting.value);\n } else {\n console.warn(\"Could not find setting object '\" + setting.info.name + \"', maybe it has been removed in this version of kosu?, skipping setting\")\n }\n }\n });\n }\n catch (e) {\n console.warn(\"Failed to load settings! Resetting Settings due to corrupted save!\", e);\n this.reset();\n }\n }\n\n public static save() {\n let settings = this.getList();\n let settingSaveData: SettingSaveData[] = [];\n settings.forEach((setting: SettingData) => {\n // only save if setting is different from default value\n if (setting.setting.getValue() != setting.setting.getDefaultValue()) {\n settingSaveData.push({info: setting.info, value: setting.setting.getValue()});\n }\n });\n window.localStorage.setItem(\"settings\", JSON.stringify(settingSaveData));\n }\n\n public static reset() {\n console.warn(\"Resetting Settings!\");\n window.localStorage.removeItem(\"settings\");\n }\n\n public static register(setting: SettingData) {\n this.settingsList.push(setting);\n }\n\n public static getSetting(setting: new (...args: any[]) => T): T {\n return this.settingsList.filter((_setting) => {\n return _setting.setting instanceof setting\n })[0].setting as T;\n }\n\n public static getSettingData(setting: new (...args: any[]) => T): SettingData {\n return this.settingsList.filter((_setting) => {\n return _setting.setting instanceof setting\n })[0];\n }\n\n public static getList() {\n return this.settingsList;\n }\n}\n\nexport interface SettingData {\n readonly setting: Setting;\n readonly info: SettingInfo;\n}\n\nexport interface SettingSaveData {\n readonly info: SettingInfo;\n readonly value: any;\n}\n","import {SettingsCategory} from \"../../Setting\";\nimport {DropDownOption, DropdownSetting} from \"../../SettingType/DropdownSetting\";\n\nexport class Renderer extends DropdownSetting {\n public readonly list: DropDownOption[] = [];\n\n public readonly webglOption: DropDownOption = {displayName: \"WebGL\", value: \"webgl\"}\n public readonly webGpuOption: DropDownOption = {displayName: \"WebGPU\", value: \"webgpu\"}\n public readonly defaultValue = this.webglOption;\n\n public constructor() {\n super({name: \"Renderer\", category: SettingsCategory.Graphics});\n this.list.push(this.webglOption, this.webGpuOption);\n this.value = this.defaultValue;\n }\n}\n","import {RangeSetting} from \"../../SettingType/RangeSetting\";\nimport {SettingsCategory} from \"../../Setting\";\n\nexport class UIScale extends RangeSetting {\n public readonly maxValue = 0.8;\n public readonly minValue = 1.6;\n public readonly increment = 0.1;\n public readonly defaultValue = 1;\n\n public constructor() {\n super({name: \"UI scaling\", category: SettingsCategory.Graphics});\n this.value = this.defaultValue;\n }\n}","import {RangeSetting} from \"../../SettingType/RangeSetting\";\nimport {SettingsCategory} from \"../../Setting\";\nimport {EventSystem} from \"pixi.js\";\n\nexport class MouseSensitivity extends RangeSetting{\n public readonly defaultValue: number = 1.0;\n public readonly increment: number = 0.01;\n public readonly maxValue: number = 10.0;\n public readonly minValue: number = 0.10;\n\n public constructor() {\n super({name: \"Sensitivity\", category: SettingsCategory.Input});\n this.value = this.defaultValue;\n this.onValueChanged();\n }\n\n public onValueChanged() {\n EventSystem.cursorSensitivity = this.getValue();\n }\n}\n","import {GeneralData} from \"./Sections/General/GeneralData\";\nimport {EditorData} from \"./Sections/Editor/EditorData\";\nimport {Metadata} from \"./Sections/Metadata/Metadata\";\nimport {DifficultyData} from \"./Sections/Difficulty/DifficultyData\";\nimport {EventsData} from \"./Sections/Events/EventsData\";\nimport {TimingPoint} from \"./Sections/TimingPoints/TimingPoint\";\nimport {TimingPointsData} from \"./Sections/TimingPoints/TimingPointsData\";\nimport {ColorsData} from \"./Sections/Colors/ColorsData\";\n\n/**\n * .osu (file format)\n */\nexport class BeatmapData {\n /**\n * General information about the beatmap\n */\n public General: GeneralData = new GeneralData();\n /**\n * Saved settings for the beatmap editor\n */\n public Editor: EditorData = new EditorData();\n /**\n * Information used to identify the beatmap\n */\n public Metadata: Metadata = new Metadata();\n /**\n * Difficulty settings\n */\n public Difficulty: DifficultyData = new DifficultyData();\n /**\n * Beatmap and storyboard graphic events\n */\n public Events: EventsData = new EventsData();\n /**\n * Timing and control points\n */\n public TimingPoints: TimingPointsData = new TimingPointsData();\n /**\n * Combo and skin colours\n */\n public Colors: ColorsData = new ColorsData();\n\n //TODO: add hitobject data\n\n}\n","import {Color} from \"./Color\";\n\n/**\n * \tCombo and skin colours\n */\nexport class ColorsData {\n public Colors: Color[] = [];\n}\n","/**\n * Difficulty settings\n */\nexport class DifficultyData {\n /**\n * HP setting (0–10)\n */\n public HPDrainRate!: number;\n /**\n * CS setting (0–10)\n */\n public CircleSize!: number;\n /**\n * OD setting (0–10)\n */\n public OverallDifficulty!: number;\n /**\n * AR setting (0–10)\n */\n public ApproachRate!: number;\n /**\n * Base slider velocity in hundreds of osu! pixels per beat\n */\n public SliderMultiplier!: number;\n /**\n * Amount of slider ticks per beat\n */\n public SliderTickRate!: number;\n}\n","/**\n * Saved settings for the beatmap editor\n */\nexport class EditorData {\n /**\n * Time in milliseconds of bookmarks\n */\n public Bookmarks: number[] = [];\n /**\n * Distance snap multiplier\n */\n public DistanceSpacing: number | undefined;\n /**\n * Beat snap divisor\n */\n public BeatDivisor: number | undefined;\n /**\n * Grid size\n */\n public GridSize: number | undefined;\n /**\n * Scale factor for the object timeline\n */\n public TimelineZoom: number | undefined;\n}\n","import {Event} from \"./Event\";\n\n/**\n * Beatmap and storyboard graphic events\n */\nexport class EventsData {\n public Events: Event[] = [];\n}\n","export enum Countdown {\n NoCountdown = 0,\n Normal = 1,\n Half = 2,\n Double = 3\n}","import {Countdown} from \"./Countdown\";\nimport {SampleSet} from \"./SampleSet\";\nimport {Mode} from \"./Mode\";\nimport {OverlayPosition} from \"./OverlayPosition\";\n/**\n * General information about the beatmap\n */\nexport class GeneralData {\n /**\n * Location of the audio file relative to the current folder.\n */\n public AudioFileName: string | undefined;\n /**\n * Milliseconds of silence before the audio starts playing\n */\n public AudioLeadIn: number = 0;\n /**\n * @deprecated The `AudioHash` property is deprecated according to the osu! wiki.\n */\n public AudioHash: string | undefined;\n /**\n * Time in milliseconds when the audio preview should start\n */\n public PreviewTime: number = -1;\n /**\n * Speed of the countdown before the first hit object (0 = no countdown, 1 = normal, 2 = half, 3 = double)\n */\n public Countdown: Countdown = Countdown.Normal;\n /**\n * Sample set that will be used if timing points do not override it (Normal, Soft, Drum)\n */\n public SampleSet: SampleSet = SampleSet.Normal;\n /**\n * Multiplier for the\n * threshold in time where hit objects placed close together stack (0–1)\n */\n public StackLeniency: number = 0.7;\n /**\n * Game mode (0 = osu!, 1 = osu!taiko, 2 = osu!catch, 3 = osu!mania)\n */\n public Mode: Mode = Mode.OSU;\n /**\n * Whether or not breaks have a letterboxing effect\n */\n public LetterboxInBreaks: boolean = false;\n /**\n * @deprecated The `StoryFireInFront` property is deprecated according to the osu! wiki.\n */\n public StoryFireInFront: boolean = true;\n /**\n * Whether or not the storyboard can use the user's skin images\n */\n public UseSkinSprites: boolean = false;\n /**\n * @deprecated The `AlwaysShowPlayfield` property is deprecated according to the osu! wiki.\n */\n public AlwaysShowPlayfield: boolean = false;\n /**\n * Draw order of hit circle overlays compared to hit numbers (NoChange = use skin setting,\n * Below = draw overlays under numbers, Above = draw overlays on top of numbers)\n */\n public OverlayPosition: OverlayPosition = OverlayPosition.NoChange;\n /**\n * Preferred skin to use during gameplay\n */\n public SkinPreference: string | undefined;\n /**\n * Whether or not a warning about flashing colours should be shown at the beginning of the map\n */\n public EpilepsyWarning: boolean = false;\n /**\n * Time in beats that the countdown starts before the first hit object\n */\n public CountdownOffset: number = 0;\n /**\n * Whether or not the \"N+1\" style key layout is used for osu!mania\n */\n public SpecialStyle: boolean = false;\n /**\n * Whether or not the storyboard allows widescreen viewing\n */\n public WidescreenStoryboard: boolean = false;\n /**\n * Whether or not sound samples will change rate when playing with speed-changing mods\n */\n public SamplesMatchPlaybackRate: boolean = false;\n}\n","export enum Mode {\n OSU = 0,\n TAIKO = 1,\n CATCH = 2,\n MANIA = 3\n}","export enum OverlayPosition {\n NoChange = \"NoChange\",\n Below = \"Below\",\n Above = \"Above\"\n}\n","export enum SampleSet {\n Normal = \"Normal\",\n Soft = \"Soft\",\n Drum = \"Drum\"\n}","/**\n * Information used to identify the beatmap\n */\nexport class Metadata {\n /**\n * Romanised song title\n */\n public Title!: string;\n /**\n * Song title\n */\n public TitleUnicode!: string;\n /**\n * Romanised song artist\n */\n public Artist!: string;\n /**\n * Song artist\n */\n public ArtistUnicode!: string;\n /**\n * Beatmap creator\n */\n public Creator!: string;\n /**\n * Difficulty name\n */\n public Version!: string;\n /**\n * Original media the song was produced for\n */\n public Source: string | undefined;\n /**\n * Search terms\n */\n public Tags!: string[];\n /**\n * Difficulty ID\n */\n public BeatmapID!: number;\n /**\n * Beatmap ID\n */\n public BeatmapSetID!: number;\n}\n","export enum Effect {\n KiaiTime = 1,\n None = 0,\n FirstBarLineOmittedInOsuTaikoAndOsuMania = 3\n}\n","import {TimingPoint} from \"./TimingPoint\";\n\nexport class InheritedTimingPoint extends TimingPoint {\n /**\n * a negative inverse slider velocity multiplier, as a percentage.\n * For example, `-50` would make all sliders in this timing section twice as fast as `SliderMultiplier`.\n */\n public sliderVelocityMultiplier!: number;\n\n}","import {TimingPointSampleSet} from \"./TimingPointSampleSet\";\nimport {Effect} from \"./Effect\";\n\nexport abstract class TimingPoint {\n /**\n * Start time of the timing section, in milliseconds from the beginning of the beatmap's audio.\n * The end of the timing section is the next timing point's time (or never, if this is the last timing point).\n */\n public time!: number;\n /**\n * Default sample set for hit objects (0 = beatmap default, 1 = normal, 2 = soft, 3 = drum).\n */\n public sampleSet!: TimingPointSampleSet;\n /**\n * Custom sample index for hit objects. 0 indicates osu!'s default hitsounds.\n */\n public sampleIndex!: number;\n /**\n * Volume percentage for hit objects.\n */\n public volume!: number;\n /**\n * Bit flags that give the timing point extra effects.\n * See the effects section.\n */\n public effects!: Effect\n}","import {TimingPoint} from \"./TimingPoint\";\nimport {UnInheritedTimingPoint} from \"./UnInheritedTimingPoint\";\nimport {InheritedTimingPoint} from \"./InheritedTimingPoint\";\n\n/**\n * Timing and control points\n */\nexport class TimingPointsData {\n public TimingPoints: TimingPoint[] = [];\n\n /**\n * Returns the current timing point in an array using the time provided.\n * If the current timing point is inherited, it will also return the parent\n * timing point along with it in the array as the second index.\n */\n public GetCurrentTimingPoints(time: number) {\n let toReturn: TimingPoint[] = [];\n let filter = this.TimingPoints.filter((timingPoint) => {if (timingPoint.time <= time) {return timingPoint}});\n if (filter.length == 0) {\n filter.push(this.TimingPoints[0]);\n }\n toReturn.push(filter[filter.length-1]);\n\n if (toReturn[0] instanceof InheritedTimingPoint) {\n let filter = this.TimingPoints.filter((timingPoint) => {return timingPoint instanceof UnInheritedTimingPoint})\n .filter((timingPoint) => {if (timingPoint.time <= time) {return timingPoint}});\n if (filter.length == 0) {\n throw new Error(\"Could not find a parent timing point for the un-inherited timing point!\");\n }\n toReturn.push(filter[filter.length-1]);\n }\n if (toReturn.length == 0) {\n throw new Error(\"Could not find any timing points!\");\n }\n return toReturn;\n }\n\n public GetCurrentUninheritedTimingPoint(time: number) {\n let timingPoint = this.GetCurrentTimingPoints(time);\n let unInheritedTimingPoint: UnInheritedTimingPoint;\n if (timingPoint[0] instanceof UnInheritedTimingPoint) {\n unInheritedTimingPoint = timingPoint[0];\n }\n else if(timingPoint[1] instanceof UnInheritedTimingPoint){\n unInheritedTimingPoint = timingPoint[1];\n }\n else {\n throw new Error(\"Could not find any UnInherited Timing Points!\")\n }\n return unInheritedTimingPoint;\n }\n\n}\n","import {TimingPoint} from \"./TimingPoint\";\n\nexport class UnInheritedTimingPoint extends TimingPoint {\n /**\n * The duration of a beat, in milliseconds.\n */\n public beatLength!: number;\n /**\n * Amount of beats in a measure.\n */\n public meter!: number;\n}\n","import {BeatmapData} from \"../Data/BeatmapData\";\nimport {TimingPointsParser} from \"./TimingPointsParser\";\nimport {GeneralParser} from \"./GeneralParser\";\n\nexport class BeatmapParser {\n public static Parse(osuFileContent: string, storyBoardFileContent?: string): BeatmapData {\n const beatMapData = new BeatmapData();\n let osuFileContentLines = osuFileContent.split(/\\r?\\n|\\r|\\n/g);\n GeneralParser.ParseGeneral(beatMapData, BeatmapParser.GetSection(\"General\", osuFileContentLines))\n TimingPointsParser.ParseTimingPoints(beatMapData, BeatmapParser.GetSection(\"TimingPoints\", osuFileContentLines));\n return beatMapData\n }\n public static GetSection(sectionName: string, osuFileContentLines: string[]) {\n let section: string[] = [];\n osuFileContentLines.forEach((str, index) => {\n if (str == \"[\"+sectionName+\"]\") {\n for (let i = index + 1; i < osuFileContentLines.length; i++) {\n if (osuFileContentLines[i] == \"\"){\n continue;\n }\n if (osuFileContentLines[i].startsWith(\"[\")){\n break;\n }\n section.push(osuFileContentLines[i]);\n }\n }\n });\n return section;\n }\n}\n","import {BeatmapData} from \"../Data/BeatmapData\";\n\nexport class GeneralParser {\n public static ParseGeneral(beatmapData: BeatmapData, section: string[]) {\n section.forEach((str) => {\n let propValue = str.split(\":\");\n if (propValue[0] == \"AudioFilename\") {\n if (propValue[1].startsWith(\" \")){\n beatmapData.General.AudioFileName = propValue[1].substring(1, propValue[1].length);\n }\n else {\n beatmapData.General.AudioFileName = propValue[1];\n }\n }\n if (propValue[0] == \"AudioFilename\") {\n if (propValue[1].startsWith(\" \")){\n beatmapData.General.AudioFileName = propValue[1].substring(1, propValue[1].length);\n }\n else {\n beatmapData.General.AudioFileName = propValue[1];\n }\n }\n })\n }\n\n}\n","import {BeatmapData} from \"../Data/BeatmapData\";\nimport {UnInheritedTimingPoint} from \"../Data/Sections/TimingPoints/UnInheritedTimingPoint\";\nimport {InheritedTimingPoint} from \"../Data/Sections/TimingPoints/InheritedTimingPoint\";\nimport {Effect} from \"../Data/Sections/TimingPoints/Effect\";\n\nexport class TimingPointsParser {\n public static ParseTimingPoints(beatmapData: BeatmapData, section: string[]) {\n section.forEach((str) => {\n let prop = str.split(\",\");\n let timingPoint;\n if (prop[6] == \"1\") {\n timingPoint = new UnInheritedTimingPoint();\n timingPoint.beatLength = Number.parseFloat(prop[1]);\n timingPoint.meter = Number.parseInt(prop[2]);\n }\n else {\n timingPoint = new InheritedTimingPoint();\n timingPoint.sliderVelocityMultiplier = Number.parseFloat(prop[1]);\n }\n timingPoint.time = Number.parseInt(prop[0]);\n timingPoint.sampleSet = Number.parseInt(prop[3]);\n timingPoint.sampleIndex = Number.parseInt(prop[4]);\n timingPoint.volume = Number.parseInt(prop[5]);\n if (prop[7] == \"1\" || prop[7] == \"3\"){\n timingPoint.effects = Number.parseInt(prop[7]);\n } else {\n timingPoint.effects = Effect.None;\n }\n\n beatmapData.TimingPoints.TimingPoints.push(timingPoint);\n });\n }\n}\n","export class MathUtil {\n public static RadiansToDegrees(radians: number) {\n return radians * 180 / Math.PI;\n }\n\n public static DegreesToRadians(degrees: number) {\n return degrees * Math.PI / 180;\n }\n\n public static clamp(min: number, max: number, value: number) {\n return Math.min(Math.max(value, min), max);\n }\n\n public static clamp01(value: number) {\n return MathUtil.clamp(0, 1, value);\n }\n\n public static Damp(start: number, final: number, base: number, exponent: number) {\n return MathUtil.Lerp(start, final, 1 - Math.pow(base, exponent));\n }\n\n public static Lerp(start: number, final: number, ammount: number) {\n return start + (final - start) * ammount;\n }\n\n}\n","import * as TWEEN from \"@tweenjs/tween.js\";\nimport * as PIXI from \"pixi.js\";\n\nexport class Ease {\n private static previousEases: Ease[] = [];\n private easings: Easing[] = [];\n private readonly obj: PIXI.Container;\n private delay: TWEEN.Tween | null = null;\n\n private constructor(obj: PIXI.Container, dontStore: boolean) {\n this.obj = obj;\n if (!dontStore) {\n Ease.previousEases.push(this);\n }\n }\n\n public static getEase(obj: PIXI.Container, dontStore?: boolean) {\n if (dontStore == null) {\n dontStore = false;\n }\n let checkIfEaseExists = Ease.previousEases.filter((ease) => {\n return ease.obj == obj;\n });\n if (checkIfEaseExists.length > 0) {\n return checkIfEaseExists[0];\n }\n return new Ease(obj, dontStore);\n }\n\n public createTween>(value: T, newValue: T, isPrimitive: boolean, property: keyof PIXI.Container, duration: number, easingFunc: (ammount: number) => number) {\n const tweenValue = {value: 0}\n const tween = new TWEEN.Tween(isPrimitive ? tweenValue : value);\n const easing = new Easing(tween);\n tween.to(isPrimitive ? {value: 1} : newValue, duration);\n tween.easing(easingFunc);\n tween.onUpdate(() => {\n if (!this.obj.destroyed) {\n if (!isPrimitive) {\n // @ts-ignore\n this.obj[property] = value;\n } else {\n // @ts-ignore\n this.obj[property] = (tweenValue.value * (newValue.value - value.value)) + value.value;\n }\n }\n easing.onUpdate();\n });\n\n tween.onStart(() => {\n if (isPrimitive) {\n // @ts-ignore\n value.value = this.obj[property];\n }\n });\n\n\n if (this.delay == null) {\n\n tween.start();\n } else {\n this.delay.chain(tween);\n this.delay = null;\n }\n this.easings.push(easing);\n\n tween.onStop(() => {\n this.onDone(tween);\n });\n tween.onComplete(() => {\n this.onDone(tween);\n });\n return this;\n }\n\n public TransformTo(newPosition: PIXI.PointData, duration: number, easing: (ammount: number) => number) {\n this.createTween(this.obj.position, newPosition, false, \"position\", duration, easing);\n return this;\n }\n\n private onDone(tween: TWEEN.Tween) {\n this.easings = this.easings.filter((tweenInArray) => {\n return tweenInArray.tween != tween\n })\n }\n\n public ScaleTo(newScale: PIXI.PointData | number, duration: number, easing: (ammount: number) => number) {\n let _newScale: PIXI.PointData = {x: 0, y: 0};\n if (typeof newScale == \"number\") {\n _newScale.x = newScale;\n _newScale.y = newScale;\n }\n this.createTween(this.obj.scale, _newScale, false, \"scale\", duration, easing);\n return this;\n }\n\n public FadeTo(newAlpha: number, duration: number, easing: (ammount: number) => number) {\n this.createTween({value: this.obj.alpha}, {value: newAlpha}, true, \"alpha\", duration, easing);\n return this;\n }\n\n public FadeOut(duration: number, easing: (ammount: number) => number) {\n this.FadeTo(0, duration, easing);\n return this;\n }\n\n public FadeIn(duration: number, easing: (ammount: number) => number) {\n this.FadeTo(1, duration, easing);\n return this;\n }\n\n public ClearEasings() {\n this.easings.forEach((tween) => {\n tween.tween.stop();\n });\n this.easings = [];\n return this;\n }\n\n public Then(cb?: () => void) {\n let largestDuration = this.easings.sort((a, b) => {\n return a.tween.getDuration() - b.tween.getDuration()\n });\n if (largestDuration.length > 0) {\n this.delay = largestDuration[0].tween;\n if (cb != undefined) {\n largestDuration[0].tween.onComplete(() => {this.onDone(largestDuration[0].tween); cb();});\n largestDuration[0].tween.onStop(() => {this.onDone(largestDuration[0].tween); cb();});\n }\n }\n return this;\n }\n\n public OnEach(cb: () => void) {\n let largestDuration = this.easings.sort((a, b) => {\n return a.tween.getDuration() - b.tween.getDuration()\n });\n if (largestDuration.length > 0) {\n largestDuration[0].registerOnUpdate(cb);\n }\n }\n}\n\nclass Easing {\n public tween: TWEEN.Tween;\n private updateEventListeners: (() => void)[] = [];\n public constructor(tween: TWEEN.Tween) {\n this.tween = tween;\n }\n public onUpdate() {\n this.updateEventListeners.forEach((eventListener) => {\n eventListener();\n })\n }\n public registerOnUpdate(cb: () => void) {\n this.updateEventListeners.push(cb);\n }\n public unRegisterOnUpdate(cb: () => void) {\n this.updateEventListeners = this.updateEventListeners.filter((ev) => {return !(cb === ev);});\n }\n}\n","import \"./style.css\";\nimport {Application, EventSystem} from \"pixi.js\";\nimport {Main} from \"./main\";\nimport {Settings} from \"./Settings/Settings\";\nimport {Renderer} from \"./Settings/impl/Graphics/Renderer\";\nimport {MouseSensitivity} from \"./Settings/impl/Input/MouseSensitivity\";\nSettings.registerAll();\nSettings.load();\nconst gameWidth = window.innerWidth;\nconst gameHeight = window.innerHeight;\n\nconst app = new Application();\n// @ts-ignore\nglobalThis.__PIXI_APP__ = app;\nwindow.onload = async (): Promise => {\n // @ts-ignore\n const renderer = Settings.getSetting(Renderer).getValue().value as \"webgl\" | \"webgpu\";\n app.init({\n backgroundColor: \"black\",\n width: gameWidth,\n height: gameHeight,\n antialias: true,\n preference: renderer,\n resolution: window.devicePixelRatio,\n autoDensity: true\n }).then(() => {\n new Main(app);\n });\n};\n\nObject.defineProperty(window, \"setSensitivity\", {value: (sensitivity: number) => {\n Settings.getSetting(MouseSensitivity).setValue(sensitivity);\n}});\n\nObject.defineProperty(window, \"setRenderer\", {value: (renderer: string) => {\n let rendererSetting = Settings.getSetting(Renderer);\n rendererSetting.setValue(renderer == \"webgl\" ? rendererSetting.webglOption : rendererSetting.webGpuOption);\n window.location.reload();\n}});\n","import * as PIXI from \"pixi.js\";\nimport {Application} from \"pixi.js\";\nimport {Screen} from \"./Screens/Screen\";\nimport {LoadScreen} from \"./Screens/LoadScreen/LoadScreen\";\nimport {InteractScreen} from \"./Screens/InteractScreen/InteractScreen\";\nimport {Loader} from \"./Loader\";\nimport {MenuCursor} from \"./Elements/MenuCursor/MenuCursor\";\nimport {AudioEngine} from \"./Audio/AudioEngine\";\nimport * as TWEEN from \"@tweenjs/tween.js\";\nimport {SettingsPane} from \"./Elements/Settings/SettingsPane\";\n\nexport class Main {\n public static app: Application;\n public static mousePos = {x: 0, y: 0};\n public static pointerLockExitTime: number;\n public static cursor: MenuCursor;\n public static AudioEngine: AudioEngine;\n private static currentScreen: Screen | null;\n private static allScreens: Screen[] = [];\n private static clickArea: PIXI.Graphics = new PIXI.Graphics();\n private static doPointerLock: boolean = false;\n private static settingsPane: SettingsPane;\n\n public constructor(app: Application) {\n Main.app = app;\n // @ts-ignore\n document.body.appendChild(Main.app.canvas);\n\n Main.settingsPane = new SettingsPane();\n Main.settingsPane.zIndex = 999998;\n Main.app.stage.addChild(Main.settingsPane);\n\n document.addEventListener(\"keydown\", (e: KeyboardEvent) => {\n if (e.ctrlKey && e.code == \"KeyO\"){\n Main.settingsPane.toggle();\n }\n });\n\n this.doResize();\n window.addEventListener(\"resize\", this.doResize);\n Main.app.ticker.add(() => {\n TWEEN.update();\n })\n Main.app.stage.eventMode = \"static\";\n Main.AudioEngine = new AudioEngine();\n Main.app.stage.addEventListener(\"mousemove\", (e) => {\n Main.mousePos.x = e.clientX;\n Main.mousePos.y = e.clientY;\n if (Main.cursor) {\n Main.cursor.updateMouse();\n }\n });\n document.addEventListener(\"pointerlockchange\", this.pointerLockChanged, false);\n Main.switchScreen(new LoadScreen());\n Loader.Load(Main.AudioEngine.audioContext).then(() => {\n Main.cursor = new MenuCursor(false);\n let dialogOk = Loader.GetAudio(\"sample_dialog_ok\");\n let introTrack = Loader.Get(\"introTrianglesTrack\");\n Main.switchScreen(new InteractScreen(introTrack, dialogOk));\n });\n }\n\n public static lockKeyboard() {\n // @ts-ignore\n if (navigator.keyboard) {\n // @ts-ignore\n navigator.keyboard.lock([]).then(() => {\n console.log(\"Locked keyboard!\");\n if (!document.fullscreenElement) {\n console.warn(\"Keyboard lock won't work unless the user is in fullscreen (as requested by the game, not if the user just presses F11)!\");\n }\n });\n }\n }\n\n public static pointerLock() {\n try {\n this.doPointerLock = true;\n // @ts-ignore\n Main.app.canvas.requestPointerLock({\n unadjustedMovement: true,\n });\n } catch (e) {\n console.warn(\"Failed to lock cursor, error:\", e);\n this.doPointerLock = false;\n }\n\n }\n\n public static exitPointerLock() {\n this.doPointerLock = false;\n // @ts-ignore\n Main.app.canvas.exitPointerLock();\n }\n\n public static switchScreen(screen: Screen) {\n if (this.currentScreen != null) {\n this.currentScreen.zIndex = 1;\n this.currentScreen.onClose().then((lastScreen) => {\n for (let i = 0; i < this.allScreens.length; i++) {\n if (this.allScreens[i] == lastScreen) {\n this.allScreens.splice(i, 1);\n }\n }\n Main.app.ticker.remove(lastScreen.draw);\n Main.app.stage.removeChild(lastScreen);\n lastScreen.destroy();\n });\n }\n Main.app.stage.addChild(screen);\n this.allScreens.push(screen);\n this.currentScreen = screen;\n screen.start();\n screen.onResize();\n Main.app.ticker.add(screen.draw, screen);\n }\n\n public doResize(): void {\n Main.app.renderer.resize(window.innerWidth, window.innerHeight);\n Main.app.stage.scale.x = 1;\n Main.app.stage.scale.y = 1;\n if (!Main.clickArea.destroyed) {\n Main.clickArea.width = window.innerWidth;\n Main.clickArea.height = window.innerHeight;\n Main.clickArea.position.set(0, 0);\n }\n Main.allScreens.forEach((screen) => {\n screen.onResize();\n })\n Main.settingsPane.resize();\n }\n\n private pointerLockChanged(): void {\n if (!document.pointerLockElement && Main.doPointerLock) {\n PIXI.EventSystem.isPointerLocked = false;\n Main.pointerLockExitTime = Date.now();\n Main.clickArea = new PIXI.Graphics();\n Main.clickArea.rect(0, 0, 1, 1);\n Main.clickArea.fill(\"rgba(0,0,0,0.1)\");\n Main.clickArea.width = window.innerWidth;\n Main.clickArea.height = window.innerHeight;\n Main.clickArea.position.set(0, 0);\n Main.app.stage.addChild(Main.clickArea);\n Main.clickArea.eventMode = \"static\";\n Main.clickArea.cursor = \"pointer\";\n Main.cursor.PopOut();\n Main.clickArea.zIndex = 9999999;\n Main.clickArea.onclick = () => {\n if (Date.now() - Main.pointerLockExitTime < 1500) {\n return;\n }\n Main.clickArea.removeFromParent();\n Main.clickArea.destroy();\n Main.pointerLock();\n Main.cursor.PopIn();\n }\n } else {\n PIXI.EventSystem.isPointerLocked = true;\n }\n }\n\n}\n","export default \"in vec2 vUV;\\nin vec2 vPositionOffset;\\nin vec2 vPosition;\\nin vec4 vColorTint;\\nuniform sampler2D uTexture;\\nuniform float time;\\n\\nvoid main() {\\n float a = ((vPositionOffset.y + vPosition.y)/1200.0) - 0.1;\\n vec4 color = texture(uTexture, vUV);\\n if (a > 1.0) {\\n a = 1.0;\\n }\\n gl_FragColor = (color*vColorTint)*a;\\n}\";","export default \"in vec2 aPosition;\\nin vec2 aUV;\\nin vec2 aPositionOffset;\\nin vec4 aColorTint;\\n\\nout vec2 vUV;\\nout vec2 vPositionOffset;\\nout vec2 vPosition;\\nout vec4 vColorTint;\\n\\nuniform mat3 uProjectionMatrix;\\nuniform mat3 uWorldTransformMatrix;\\nuniform mat3 uTransformMatrix;\\n\\n\\nvoid main() {\\n\\n mat3 mvp = uProjectionMatrix * uWorldTransformMatrix * uTransformMatrix;\\n gl_Position = vec4((mvp * vec3(aPosition + aPositionOffset, 1.0)).xy, 0.0, 1.0);\\n vPositionOffset = aPositionOffset;\\n vUV = aUV;\\n vPosition = aPosition;\\n vColorTint = aColorTint;\\n}\";","export default \"struct GlobalUniforms {\\n uProjectionMatrix:mat3x3,\\n uWorldTransformMatrix:mat3x3,\\n uWorldColorAlpha: vec4,\\n uResolution: vec2,\\n}\\n\\nstruct LocalUniforms {\\n uTransformMatrix:mat3x3,\\n uColor:vec4,\\n uRound:f32,\\n}\\n\\n\\n@group(0) @binding(0) var globalUniforms : GlobalUniforms;\\n@group(1) @binding(0) var localUniforms : LocalUniforms;\\n\\nstruct VertexOutput {\\n @builtin(position) position: vec4,\\n @location(0) vUV: vec2,\\n @location(1) vPositionOffset: vec2,\\n @location(2) vPosition: vec2,\\n @location(3) vColorTint: vec4\\n};\\n\\n\\n@vertex\\nfn mainVert(\\n @location(0) aPosition : vec2,\\n @location(1) aUV : vec2,\\n @location(2) aColorTint : vec4,\\n @location(3) aPositionOffset : vec2,\\n) -> VertexOutput {\\n var mvp = globalUniforms.uProjectionMatrix\\n * globalUniforms.uWorldTransformMatrix\\n * localUniforms.uTransformMatrix;\\n\\n var output: VertexOutput;\\n\\n output.position = vec4(mvp * vec3(aPosition+aPositionOffset, 1.0), 1.0);\\n output.vUV = aUV;\\n output.vPosition = aPosition;\\n output.vPositionOffset = aPositionOffset;\\n output.vColorTint = aColorTint;\\n\\n return output;\\n};\\n\\nstruct WaveUniforms {\\n time:f32,\\n}\\n\\n@group(2) @binding(1) var uTexture : texture_2d;\\n@group(2) @binding(2) var uSampler : sampler;\\n@group(2) @binding(3) var waveUniforms : WaveUniforms;\\n\\n@fragment\\nfn mainFrag(\\n @location(0) vUV: vec2,\\n @location(1) vPositionOffset: vec2,\\n @location(2) vPosition: vec2,\\n @location(3) vColorTint: vec4\\n) -> @location(0) vec4 {\\n var a: f32 = ((vPositionOffset.y + vPosition.y)/1200.0) - 0.1;\\n let color: vec4 = textureSample(uTexture, uSampler, vUV);\\n if (a > 1.0){\\n a = 1.0;\\n }\\n return (color*vColorTint)*a;\\n};\";","export default \"in vec4 vColor;\\nin vec2 vUV;\\n\\nuniform sampler2D uTexture;\\nuniform float progress;\\n\\nvoid main() {\\n vec4 color = texture2D(uTexture, vUV);\\n float a = vColor.a * color.a;\\n vec4 _vColor = vec4(smoothstep(0.88, 1.0, color.a))*vColor;\\n vec4 outColor = (color.r < progress) ? vec4(_vColor.rgb * a, a) : vec4(0.0);\\n gl_FragColor = outColor;\\n}\\n\";","export default \"in vec2 aPosition;\\nin vec4 aColor;\\nin vec2 aUV;\\n\\nout vec4 vColor;\\nout vec2 vUV;\\n\\nuniform mat3 uProjectionMatrix;\\nuniform mat3 uWorldTransformMatrix;\\n\\nuniform mat3 uTransformMatrix;\\n\\n\\nvoid main() {\\n\\n mat3 mvp = uProjectionMatrix * uWorldTransformMatrix * uTransformMatrix;\\n gl_Position = vec4((mvp * vec3(aPosition, 1.0)).xy, 0.0, 1.0);\\n\\n vColor = aColor;\\n vUV = aUV;\\n}\\n\";","export default \"struct GlobalUniforms {\\n uProjectionMatrix:mat3x3,\\n uWorldTransformMatrix:mat3x3,\\n uWorldColorAlpha: vec4,\\n uResolution: vec2,\\n}\\n\\nstruct LocalUniforms {\\n uTransformMatrix:mat3x3,\\n uColor:vec4,\\n uRound:f32,\\n}\\n\\n\\n@group(0) @binding(0) var globalUniforms : GlobalUniforms;\\n@group(1) @binding(0) var localUniforms : LocalUniforms;\\n\\nstruct VertexOutput {\\n @builtin(position) position: vec4,\\n @location(0) vUV: vec2,\\n @location(1) vColor: vec4,\\n};\\n\\n\\n@vertex\\nfn mainVert(@location(0) aPosition : vec2, @location(1) aUV : vec2, @location(2) aColor: vec4\\n) -> VertexOutput {\\n var mvp = globalUniforms.uProjectionMatrix\\n * globalUniforms.uWorldTransformMatrix\\n * localUniforms.uTransformMatrix;\\n\\n var output: VertexOutput;\\n\\n output.position = vec4(mvp * vec3(aPosition, 1.0), 1.0);\\n output.vUV = aUV;\\n output.vColor = aColor;\\n\\n return output;\\n};\\n\\nstruct ProgressUniform {\\n progress:f32\\n}\\n\\n@group(2) @binding(1) var uTexture : texture_2d;\\n@group(2) @binding(2) var uSampler : sampler;\\n@group(2) @binding(3) var uProgress : ProgressUniform;\\n\\n@fragment\\nfn mainFrag(@location(0) vUV: vec2, @location(1) vColor: vec4) -> @location(0) vec4 {\\n let color: vec4 = textureSample(uTexture, uSampler, vUV);\\n let a: f32 = color.a;\\n let _vColor: vec4 = smoothstep(0.88, 1.0, color.a) * vColor;\\n var outColor: vec4 = vec4(0.0);\\n if (color.r < uProgress.progress) {\\n outColor = vec4(_vColor.rgb * a, a);\\n }\\n return outColor;\\n};\\n\";","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\tid: moduleId,\n\t\tloaded: false,\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Flag the module as loaded\n\tmodule.loaded = true;\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n// expose the modules object (__webpack_modules__)\n__webpack_require__.m = __webpack_modules__;\n\n","// define getter functions for harmony exports\n__webpack_require__.d = function(exports, definition) {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.hmd = function(module) {\n\tmodule = Object.create(module);\n\tif (!module.children) module.children = [];\n\tObject.defineProperty(module, 'exports', {\n\t\tenumerable: true,\n\t\tset: function() {\n\t\t\tthrow new Error('ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: ' + module.id);\n\t\t}\n\t});\n\treturn module;\n};","__webpack_require__.o = function(obj, prop) { return Object.prototype.hasOwnProperty.call(obj, prop); }","// define __esModule on exports\n__webpack_require__.r = function(exports) {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","// no baseURI\n\n// object to store loaded and loading chunks\n// undefined = chunk not loaded, null = chunk preloaded/prefetched\n// [resolve, reject, Promise] = chunk loading, 0 = chunk loaded\nvar installedChunks = {\n\t179: 0\n};\n\n// no chunk on demand loading\n\n// no prefetching\n\n// no preloaded\n\n// no HMR\n\n// no HMR manifest\n\n__webpack_require__.O.j = function(chunkId) { return installedChunks[chunkId] === 0; };\n\n// install a JSONP callback for chunk loading\nvar webpackJsonpCallback = function(parentChunkLoadingFunction, data) {\n\tvar chunkIds = data[0];\n\tvar moreModules = data[1];\n\tvar runtime = data[2];\n\t// add \"moreModules\" to the modules object,\n\t// then flag all \"chunkIds\" as loaded and fire callback\n\tvar moduleId, chunkId, i = 0;\n\tif(chunkIds.some(function(id) { return installedChunks[id] !== 0; })) {\n\t\tfor(moduleId in moreModules) {\n\t\t\tif(__webpack_require__.o(moreModules, moduleId)) {\n\t\t\t\t__webpack_require__.m[moduleId] = moreModules[moduleId];\n\t\t\t}\n\t\t}\n\t\tif(runtime) var result = runtime(__webpack_require__);\n\t}\n\tif(parentChunkLoadingFunction) parentChunkLoadingFunction(data);\n\tfor(;i < chunkIds.length; i++) {\n\t\tchunkId = chunkIds[i];\n\t\tif(__webpack_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) {\n\t\t\tinstalledChunks[chunkId][0]();\n\t\t}\n\t\tinstalledChunks[chunkId] = 0;\n\t}\n\treturn __webpack_require__.O(result);\n}\n\nvar chunkLoadingGlobal = self[\"webpackChunkkosu\"] = self[\"webpackChunkkosu\"] || [];\nchunkLoadingGlobal.forEach(webpackJsonpCallback.bind(null, 0));\nchunkLoadingGlobal.push = webpackJsonpCallback.bind(null, chunkLoadingGlobal.push.bind(chunkLoadingGlobal));","// startup\n// Load entry module and return exports\n// This entry module depends on other loaded chunks and execution need to be delayed\nvar __webpack_exports__ = __webpack_require__.O(undefined, [811], function() { return __webpack_require__(29820); })\n__webpack_exports__ = __webpack_require__.O(__webpack_exports__);\n"],"names":["deferred","Audio","audio","timeStarted","source","id","isPlaying","isPaused","pausedTime","nodes","tempArrayMain","Float32Array","tempArrayL","tempArrayR","LeftChannel","RightChannel","FrequencyAmplitudes","_connectedToContext","GetMaximumAudioLevel","Math","max","this","GetAverageAudioLevel","Create","audioContext","createBufferSource","buffer","AddAudioNode","node","Error","push","GetNode","type","filter","length","ConnectToContext","howToConnectFunction","forEach","index","connect","AnalyserNode","destination","Play","start","Date","now","Pause","stop","Stop","RegisterEndCallBack","callback","onended","exports","beatmap","fadingOut","fadeOutTimeout","playingCallback","PlayingAudios_1","require","Audio_1","BeatmapData_1","main_1","UnInheritedTimingPoint_1","Effect_1","_playingAudios","_musicQueue","_audioIdTicker","_changeCallbacks","silentMusic","createSilentMusic","useSilentMusic","constructor","AudioContext","PlayingAudios","Main","app","ticker","add","update","UpdateMusicQueue","_play","cb","mapAudio","MapAudio","BeatmapData","timingPoint","UnInheritedTimingPoint","time","beatLength","effects","Effect","None","TimingPoints","addMusicChangeEventListener","removeMusicChangeEventListener","GetCurrentPlayingMusic","PlayEffect","pitch","audioObj","AddToMusicQueue","beatMapData","musicPlayingCallback","mapAudioObj","PlayMusicImmediately","currentPlaying","analyzerMain","analyzerL","analyzerR","getFloatFrequencyData","i","Infinity","getFloatTimeDomainData","avgL","avgR","value","audios","clearTimeout","gainNodes","GainNode","gain","linearRampToValueAtTime","currentTime","setTimeout","createGain","analyzer","createAnalyser","fftSize","smoothingTimeConstant","splitter","createChannelSplitter","duration","playbackRate","splice","audioInArr","PIXI","__importStar","MathUtil_1","LogoVisualizer","Container","static","frequencyAmplitudes","temporalAmplitudes","graphics","Graphics","index_change","bar_length","bars_per_visualiser","visualiser_rounds","decay_per_millisecond","time_between_updates","amplitude_dead_zone","indexOffset","firstDraw","blendMode","addChild","eventMode","setInterval","updateAmplitudes","draw","clear","decayFactor","deltaMS","j","rotation","MathUtil","DegreesToRadians","rotationCos","cos","rotationSin","sin","barPosition","x","size","y","barSize","sqrt","amplitudeOffset","moveTo","lineTo","stroke","color","width","AudioEngine","GetCurrentTimingPoints","targetAmplitude","KiaiTime","LogoVisualizer_1","MenuLogoVisualizer","super","TWEEN","Ease_1","LoadAnim","bg","arc","arcContainer","animInterval","container","bgContainer","bgRotation","bgColor","arcColor","pivot","set","alpha","PI","roundRect","fill","cap","scale","Ease","getEase","ScaleTo","Easing","Quadratic","InOut","FadeIn","doAnims","createTween","angle","getWidth","getHeight","deltaTime","destroy","_options","FadeOut","clearInterval","Menu","menuBG","isOpened","rect","Open","Quintic","Out","Close","ClearEasings","Sinusoidal","In","isOpen","onResize","position","window","innerWidth","Triangles_1","Loader_1","Menu_1","MenuLogoVisualizer_1","OsuCircle","outline","visualizer","triangles","Triangles","flash","logoContainer","logoBounceContainer","logoBeatContainer","logoAmplitudeContainer","logoHoverContainer","rippleContainer","ripple","menu","defaultVisualizerAlpha","early_activation","timeElapsedSinceLastBeat","timeUntilNextBeat","lastTimeElapasedSinceLastBeat","selectSample","Loader","GetAudio","backToLogoSample","isMouseDown","mouseDownPosition","Sprite","from","anchor","mask","circle","height","hitArea","Circle","onmouseenter","_onmouseenter","onmouseleave","_onmouseleave","onmousedown","_onmousedown","onclick","_onclick","stage","addEventListener","e","_onmouseup","Elastic","mousePos","Exponential","TransformTo","GetCurrentUninheritedTimingPoint","Velocity","Damp","maxAmplitude","onNewBeat","change","pow","amplitudeAdjust","min","Linear","Then","FadeTo","osuCircleTriangles_vert_1","__importDefault","osuCircleTriangles_frag_1","osuCircleTriangles_wgsl_1","bgGradient","timeSinceLastSpawn","instancePositionBuffer","totalTriangles","colorStops","FillGradient","number","ratio","addColorStop","random","velocity","randVelocity","Buffer","data","usage","BufferUsage","VERTEX","COPY_DST","Color","geometry","Geometry","attributes","aPosition","aUV","aColorTint","red","green","blue","aPositionOffset","instance","indexBuffer","instanceCount","gl","vertex","default","fragment","gpu","entryPoint","triangleGraphic","triangleTexture","renderer","generateTexture","shader","Shader","resources","uTexture","uSampler","style","waveUniforms","triangleMesh","Mesh","options","count","triangle","u1","u2","randStdNormal","log","Screen_1","MenuCursor","mouseCursor","mouseCursorAdditive","mouseContainer","animContainer","animRotationContainer","dragRotationState","DragRotationState","NotDragging","lastDragRotationState","mouseHideContainer","elastic_const2","elastic_const","elastic_offset_quarter","posMouseDown","mouseIsDown","cursorTapSample","mouseButtonClicked","visible","updateMouse","Screen","getScaleBasedOffScreenSize","tint","zIndex","addEventListeners","button","DragStarted","Rotating","abs","PopIn","PopOut","distance","offsetX","offsetY","degrees","RadiansToDegrees","atan2","diff","Background","texture","show","Background_1","RandomBackground","parallaxMultiplier","getScreenWidth","getScreenHeight","newRandomBG","setBG","bgSprite","children","useSeasonalBackgrounds","seasonalBackgroundsNum","randomNum","defaultBackgroundsNum","round","Texture","onClose","Promise","resolve","sprite","scaleFactor","texWidth","texHeight","innerHeight","SettingsPane","resize","open","Cubic","toggle","close","addToLoadList","loadList","url","isAudio","pixiBundleName","Get","result","loadedList","loadedObj","GetString","dataString","dataAudio","addBackgrounds","fetch","encodeURIComponent","then","res","json","backgrounds","background","loadParser","catch","error","console","warn","Load","nonPixi","pixi","pixiwithBundles","loadedAssets","erroredAssets","loadObj","added","loadObjs","incrementLoadAssetNumber","errored","response","blob","isText","text","arrayBuffer","arrBuff","decodeAudioData","audioBuff","bundle","assets","alias","src","Assets","addBundle","loadBundle","IntroScreen_1","InteractScreen","text2","textContainer","textContainerContainer","introTrack","clickSound","clickArea","Text","fontFamily","fontSize","align","cursor","clicked","switchScreen","IntroScreen","document","body","pointerLock","lockKeyboard","ontap","GlitchingTriangles","bounds","randX","x1","x2","randY","y1","y2","unzipit_1","GlitchingTriangles_1","MainMenu_1","LazerLogo_1","BeatmapParser_1","introTrackUrl","doTextSpacingAnim","ruleSetContainer","logoContainerContainer","lazerLogo","LazerLogo","flashed","standard","taiko","ctb","mania","completionPromise","welcomeText","letterSpacing","URL","createObjectURL","async","entries","unzip","name","entry","Object","endsWith","osuFile","beatmapData","BeatmapParser","Parse","General","AudioFileName","afterAudioPlay","glitchingInterval","MainMenu","destroyed","LogoAnimation_1","highlight","textureHighlight","textureBackground","LogoAnimation","dummy","OnEach","setProgress","logoAnimation_vert_1","logoAnimation_frag_1","logoAnimation_wgsl_1","uProgress","progress","quadGeometry","aColor","quad","uniforms","LoadAnim_1","LoadScreen","loadAnim","RandomBackground_1","OsuCircle_1","osuCircle","Settings_1","UIScale_1","uiScale","Settings","getSetting","UIScale","getValue","SettingsCategory","info","SettingData","register","setting","onValueChanged","Setting_1","DropdownSetting","Setting","getDefaultValue","defaultValue","setValue","list","find","option","displayName","save","loadFromSaveValue","RangeSetting","clamp","minValue","maxValue","Renderer_1","MouseSensitivity_1","registerAll","Renderer","MouseSensitivity","load","settingSaveDataString","localStorage","getItem","settings","getList","JSON","parse","corrupt","stringify","category","settingObj","_settingObj","reset","settingSaveData","setItem","removeItem","settingsList","_setting","getSettingData","DropdownSetting_1","webglOption","webGpuOption","RangeSetting_1","increment","pixi_js_1","Input","EventSystem","cursorSensitivity","GeneralData_1","EditorData_1","Metadata_1","DifficultyData_1","EventsData_1","TimingPointsData_1","ColorsData_1","GeneralData","Editor","EditorData","Metadata","Difficulty","DifficultyData","Events","EventsData","TimingPointsData","Colors","ColorsData","HPDrainRate","CircleSize","OverallDifficulty","ApproachRate","SliderMultiplier","SliderTickRate","Bookmarks","DistanceSpacing","BeatDivisor","GridSize","TimelineZoom","Countdown","Countdown_1","SampleSet_1","Mode_1","OverlayPosition_1","AudioLeadIn","AudioHash","PreviewTime","Normal","SampleSet","StackLeniency","Mode","OSU","LetterboxInBreaks","StoryFireInFront","UseSkinSprites","AlwaysShowPlayfield","OverlayPosition","NoChange","SkinPreference","EpilepsyWarning","CountdownOffset","SpecialStyle","WidescreenStoryboard","SamplesMatchPlaybackRate","Title","TitleUnicode","Artist","ArtistUnicode","Creator","Version","Source","Tags","BeatmapID","BeatmapSetID","TimingPoint_1","InheritedTimingPoint","TimingPoint","sliderVelocityMultiplier","sampleSet","sampleIndex","volume","InheritedTimingPoint_1","toReturn","unInheritedTimingPoint","meter","TimingPointsParser_1","GeneralParser_1","osuFileContent","storyBoardFileContent","osuFileContentLines","split","GeneralParser","ParseGeneral","GetSection","TimingPointsParser","ParseTimingPoints","sectionName","section","str","startsWith","propValue","substring","prop","Number","parseFloat","parseInt","radians","clamp01","final","base","exponent","Lerp","ammount","easings","obj","delay","dontStore","previousEases","checkIfEaseExists","ease","newValue","isPrimitive","property","easingFunc","tweenValue","tween","Tween","easing","to","onUpdate","onStart","chain","onStop","onDone","onComplete","newPosition","tweenInArray","newScale","_newScale","newAlpha","largestDuration","sort","a","b","getDuration","undefined","registerOnUpdate","updateEventListeners","eventListener","unRegisterOnUpdate","ev","gameWidth","gameHeight","Application","globalThis","__PIXI_APP__","onload","init","backgroundColor","antialias","preference","resolution","devicePixelRatio","autoDensity","defineProperty","sensitivity","rendererSetting","location","reload","LoadScreen_1","InteractScreen_1","MenuCursor_1","AudioEngine_1","SettingsPane_1","appendChild","canvas","settingsPane","ctrlKey","code","doResize","clientX","clientY","pointerLockChanged","dialogOk","navigator","keyboard","lock","fullscreenElement","doPointerLock","requestPointerLock","unadjustedMovement","exitPointerLock","screen","currentScreen","lastScreen","allScreens","remove","removeChild","pointerLockElement","isPointerLocked","pointerLockExitTime","removeFromParent","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","module","loaded","__webpack_modules__","call","m","O","chunkIds","fn","priority","notFulfilled","fulfilled","keys","every","key","r","d","definition","o","enumerable","get","hmd","create","prototype","hasOwnProperty","Symbol","toStringTag","installedChunks","chunkId","webpackJsonpCallback","parentChunkLoadingFunction","moreModules","runtime","some","chunkLoadingGlobal","self","bind","__webpack_exports__"],"sourceRoot":""} \ No newline at end of file diff --git a/index.html b/index.html index 5cd253e..6f5a7e4 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -kosu! \ No newline at end of file +kosu! \ No newline at end of file