{"version":3,"sources":["../src/ParticleUtils.ts","../src/PropertyNode.ts","../src/PropertyList.ts","../src/Emitter.ts","../src/Particle.ts","../src/PolygonalChain.ts","../src/PathParticle.ts","../src/AnimatedParticle.ts","../src/LinkedListContainer.ts"],"names":["TextureFromString","PropertyNode","value","time","ease","this","next","isStepped","ParticleUtils","generateEase","createList","data","array","list","node","_a","first","hexToRGB","length","i","_b","value_1","time_1","start","end","pixiNS","pixi","GetTextureFromString","s","parseInt","exec","pixi.VERSION","Texture","fromImage","from","verbose","DEG_TO_RADS","Math","PI","rotatePoint","angle","p","sin","c","cos","xnew","x","y","ynew","combineRGBComponents","r","g","b","normalize","point","oneOverLen","scaleBy","sqrt","color","output","alpha","charAt","substr","indexOf","a","segments","qty","oneOverQty","t","cp","e","getBlendMode","name","BLEND_MODES","NORMAL","toUpperCase","replace","createSteppedGradient","numSteps","currentNode","current","nextIndex","lerp","curVal","nextVal","intValueSimple","intColorSimple","intValueComplex","intColorComplex","intValueStepped","intColorStepped","ticker","PropertyList","isColor","interpolate","prototype","reset","Particle","emitter","_this","_super","call","prevChild","nextChild","anchor","velocity","Point","rotationSpeed","rotationAcceleration","maxLife","age","extraData","alphaList","speedList","speedMultiplier","acceleration","maxSpeed","NaN","scaleList","scaleMultiplier","colorList","_doAlpha","_doScale","_doSpeed","_doAcceleration","_doColor","_doNormalMovement","_oneOverLife","prev","init","Particle_init","update","Particle_update","Sprite_destroy","destroy","Particle_destroy","applyArt","kill","__extends","rotation","noRotation","scale","tint","visible","art","texture","EMPTY","delta","deltaX","deltaY","speed","oldVX","oldVY","currentSpeed","position","newRotationSpeed","atan2","recycle","parent","removeChild","parseArt","baseTexture","window","console","warn","parseData","Sprite","PolygonalChain","countingLengths","totalLength","Array","isArray","chain","prevPoint","j","second","push","p1","p2","l","segLength","getRandomPoint","out","chosenSeg","rand","random","shared","Ticker","helperPoint","Emitter","particleParent","particleImages","config","_currentImageIndex","_particleConstructor","startAlpha","startSpeed","minimumSpeedMultiplier","startScale","minimumScaleMultiplier","startColor","minLifetime","maxLifetime","minStartRotation","maxStartRotation","minRotationSpeed","maxRotationSpeed","particleBlendMode","customEase","_frequency","spawnChance","maxParticles","emitterLifetime","spawnPos","spawnType","_spawnFunc","spawnRect","spawnCircle","spawnPolygonalChain","particlesPerWave","particleSpacing","angleStart","ownerPos","_prevEmitterPos","_prevPosIsValid","_posChanged","_parent","addAtBack","particleCount","_emit","_spawnTimer","_emitterLife","_activeParticlesFirst","_activeParticlesLast","_poolFirst","_origConfig","_origArt","_autoUpdate","_destroyWhenComplete","_completeCallback","rotate","updateSpawnPos","updateOwnerPos","Object","defineProperty","cleanup","particle","slice","partClass","startRotation","min","max","lifetime","blendMode","parseSpawnType","frequency","pos","initAdditional","clone","emit","undefined","autoUpdate","orderedArt","_spawnRect","Rectangle","w","h","_spawnCircle","Circle","_spawnRing","minRadius","minR","_spawnBurst","_spawnPoint","_spawnPolygonalChain","spawnPolygon","newRot","diff","resetPositionTracking","remove","add","playOnceAndDestroy","callback","playOnce","settings","TARGET_FPMS","prevX","prevY","curX","curY","emitPosX","emitPosY","len","particleConstructor","floor","applyAdditionalProperties","addChildAt","addChild","cb","width","height","radius","MATH_FUNCS","WHITELISTER","RegExp","concat","join","PathParticle","path","initialRotation","initialPosition","movement","pathString","matches","match","Function","parsePath","error","AnimatedParticle","textures","duration","framerate","elapsed","loop","frame","outArr","outTextures","tex","dupe","count","LinkedListContainer","apply","arguments","_firstChild","_lastChild","_childCount","children","_i","child","sortDirty","transform","_parentID","_boundsID","onChildrenChange","index","Error","target","addChildBelow","relative","addChildAbove","swapChildren","child2","getChildIndex","test","setChildIndex","getChildAt","removeChildAt","removeChildren","beginIndex","endIndex","begin","range","removed","RangeError","updateTransform","worldAlpha","calculateBounds","_bounds","clear","_calculateBounds","renderable","_mask","maskObject","addBoundsMask","filterArea","addBoundsArea","addBounds","updateID","getLocalBounds","rect","skipChildrenUpdate","result","DisplayObject","render","renderer","filters","renderAdvanced","_render","batch","flush","mask","_enabledFilters","enabled","filter","pop","renderWebGL","renderAdvancedWebGL","_renderWebGL","_filters","filterManager","pushFilter","maskManager","pushMask","popMask","popFilter","renderCanvas","_renderCanvas","Container"],"mappings":"uDAQIA,eCiCA,SAAAC,EAAYC,EAAUC,EAAcC,GAEhCC,KAAKH,MAAQA,EACbG,KAAKF,KAAOA,EACZE,KAAKC,KAAO,KACZD,KAAKE,WAAY,EAGbF,KAAKD,KAFLA,EAE4B,mBAATA,EAAsBA,EAAOI,EAAAA,cAAcC,aAAaL,GAI/D,KAqDxB,OAtCkBH,EAAAS,WAAd,SAAmDC,GAE/C,GAAI,SAAUA,EACd,CACI,IAAMC,EAAQD,EAAKE,KACfC,OAAI,EACFC,EAAAH,EAAA,GAAEV,EAAAa,EAAAb,MAAOC,EAAAY,EAAAZ,KAGTa,EAAQF,EAAO,IAAIb,EAA8B,iBAAVC,EAAqBM,EAAAA,cAAcS,SAASf,GAASA,EAAOC,EAAMQ,EAAKP,MAGpH,GAAIQ,EAAMM,OAAS,GAAuB,IAAjBN,EAAMM,QAAgBN,EAAM,GAAGV,QAAUA,EAE9D,IAAK,IAAIiB,EAAI,EAAGA,EAAIP,EAAMM,SAAUC,EACpC,CACU,IAAAC,EAAAR,EAAAO,GAAEE,EAAAD,EAAAlB,MAAOoB,EAAAF,EAAAjB,KAEfW,EAAKR,KAAO,IAAIL,EAA8B,iBAAVoB,EAAqBb,EAAAA,cAAcS,SAASI,GAASA,EAAOC,GAChGR,EAAOA,EAAKR,KAKpB,OAFAU,EAAMT,YAAcI,EAAKJ,UAElBS,EAIX,IAAMO,EAAQ,IAAItB,EAAmC,iBAAfU,EAAKY,MAAqBf,EAAAA,cAAcS,SAASN,EAAKY,OAASZ,EAAKY,MAAO,GAQjH,OALIZ,EAAKa,MAAQb,EAAKY,QAElBA,EAAMjB,KAAO,IAAIL,EAAiC,iBAAbU,EAAKa,IAAmBhB,EAAAA,cAAcS,SAASN,EAAKa,KAAOb,EAAKa,IAAK,IAGvGD,GAEftB,KDhGMwB,EAASC,WAWCC,EAAqBC,GAEjC,OAAO5B,EAAkB4B,GATzB5B,EAFA6B,SAAS,WAAaC,KAAKC,EAAAA,SAAc,GAAI,IAAM,EAE9BN,EAAOO,QAAgBC,UAIxBR,EAAOO,QAAQE,KA0BvC,SAAiB1B,GAIAA,EAAA2B,SAAU,EAEV3B,EAAA4B,YAAcC,KAAKC,GAAK,IAOrB9B,EAAA+B,YAAhB,SAA4BC,EAAeC,GAEvC,GAAKD,EAAL,CACAA,GAAShC,EAAc4B,YACvB,IAAMR,EAAIS,KAAKK,IAAIF,GACbG,EAAIN,KAAKO,IAAIJ,GACbK,EAAQJ,EAAEK,EAAIH,EAAMF,EAAEM,EAAInB,EAC1BoB,EAAQP,EAAEK,EAAIlB,EAAMa,EAAEM,EAAIJ,EAEhCF,EAAEK,EAAID,EACNJ,EAAEM,EAAIC,IAUMxC,EAAAyC,qBAAhB,SAAqCC,EAAWC,EAAWC,GAEvD,OAAuBF,GAAK,GAAOC,GAAK,EAAKC,GAOjC5C,EAAA6C,UAAhB,SAA0BC,GAEtB,IAAMC,EAAa,EAAI/C,EAAcU,OAAOoC,GAE5CA,EAAMR,GAAKS,EACXD,EAAMP,GAAKQ,GAQC/C,EAAAgD,QAAhB,SAAwBF,EAAcpD,GAElCoD,EAAMR,GAAK5C,EACXoD,EAAMP,GAAK7C,GAQCM,EAAAU,OAAhB,SAAuBoC,GAEnB,OAAOjB,KAAKoB,KAAMH,EAAMR,EAAIQ,EAAMR,EAAMQ,EAAMP,EAAIO,EAAMP,IAW5CvC,EAAAS,SAAhB,SAAyByC,EAAeC,GAcpC,IAAIC,EAeJ,OA3BKD,IAEDA,EAAS,IAEW,MAApBD,EAAMG,OAAO,GAEbH,EAAQA,EAAMI,OAAO,GAEQ,IAAxBJ,EAAMK,QAAQ,QAEnBL,EAAQA,EAAMI,OAAO,IAIJ,IAAjBJ,EAAMxC,SAEN0C,EAAQF,EAAMI,OAAO,EAAG,GACxBJ,EAAQA,EAAMI,OAAO,IAEzBH,EAAOT,EAAIrB,SAAS6B,EAAMI,OAAO,EAAG,GAAI,IACxCH,EAAOR,EAAItB,SAAS6B,EAAMI,OAAO,EAAG,GAAI,IACxCH,EAAOP,EAAIvB,SAAS6B,EAAMI,OAAO,EAAG,GAAI,IACpCF,IAEAD,EAAOK,EAAInC,SAAS+B,EAAO,KAGxBD,GAWKnD,EAAAC,aAAhB,SAA6BwD,GAEzB,IAAMC,EAAMD,EAAS/C,OACfiD,EAAa,EAAID,EASvB,OAAO,SAAU/D,GAEb,IAAMgB,EAAK+C,EAAM/D,EAAQ,EAEnBiE,GAAKjE,EAAQgB,EAAIgD,GAAeD,EAChCtC,EAAIqC,EAAS9C,IAAM8C,EAASC,EAAM,GAExC,OAAQtC,EAAEA,EAAKwC,GAAM,GAAK,EAAIA,IAAMxC,EAAEyC,GAAKzC,EAAEA,GAAOwC,GAAKxC,EAAE0C,EAAI1C,EAAEA,MASzDpB,EAAA+D,aAAhB,SAA6BC,GAEzB,IAAKA,EAAM,OAAOC,EAAAA,YAAYC,OAE9B,IADAF,EAAOA,EAAKG,cACLH,EAAKT,QAAQ,MAAQ,GAExBS,EAAOA,EAAKI,QAAQ,IAAK,KAG7B,OAAQH,EAAAA,YAAoBD,IAASC,EAAAA,YAAYC,QAWrClE,EAAAqE,sBAAhB,SAAsChE,EAA2BiE,QAAA,IAAAA,IAAAA,EAAA,KAErC,iBAAbA,GAAyBA,GAAY,KAE5CA,EAAW,IAEf,IAAM9D,EAAQ,IAAIf,EAAoBO,EAAcS,SAASJ,EAAK,GAAGX,OAAQW,EAAK,GAAGV,MAErFa,EAAMT,WAAY,EAMlB,IALA,IAAIwE,EAAc/D,EACdgE,EAAUnE,EAAK,GACfoE,EAAY,EACZ3E,EAAOO,EAAKoE,GAEP9D,EAAI,EAAGA,EAAI2D,IAAY3D,EAChC,CAII,IAHA,IAAI+D,EAAO/D,EAAI2D,EAGRI,EAAO5E,EAAKH,MAEf6E,EAAU1E,EACVA,EAAOO,IAAOoE,GAGlBC,GAAQA,EAAOF,EAAQ7E,OAASG,EAAKH,KAAO6E,EAAQ7E,MACpD,IAAMgF,EAAS3E,EAAcS,SAAS+D,EAAQ9E,OACxCkF,EAAU5E,EAAcS,SAASX,EAAKJ,OACtCyD,EAAgB,CAClBT,GAAKkC,EAAQlC,EAAIiC,EAAOjC,GAAKgC,EAAQC,EAAOjC,EAC5CC,GAAKiC,EAAQjC,EAAIgC,EAAOhC,GAAK+B,EAAQC,EAAOhC,EAC5CC,GAAKgC,EAAQhC,EAAI+B,EAAO/B,GAAK8B,EAAQC,EAAO/B,GAGhD2B,EAAYzE,KAAO,IAAIL,EAAa0D,EAAQxC,EAAI2D,GAChDC,EAAcA,EAAYzE,KAK9B,OAAOU,GA/Mf,CAAiBR,EAAAA,gBAAAA,EAAAA,cAAa,0TEzC9B,SAAS6E,EAA2CH,GAKhD,OAHI7E,KAAKD,OACP8E,EAAO7E,KAAKD,KAAK8E,KAEV7E,KAAKC,KAAKJ,MAAQG,KAAK2E,QAAQ9E,OAASgF,EAAQ7E,KAAK2E,QAAQ9E,MAG1E,SAASoF,EAA0CJ,GAE3C7E,KAAKD,OACP8E,EAAO7E,KAAKD,KAAK8E,IACnB,IAAMC,EAAS9E,KAAK2E,QAAQ9E,MACxBkF,EAAU/E,KAAKC,KAAKJ,MAClBgD,GAAMkC,EAAQlC,EAAIiC,EAAOjC,GAAKgC,EAAQC,EAAOjC,EAC7CC,GAAMiC,EAAQjC,EAAIgC,EAAOhC,GAAK+B,EAAQC,EAAOhC,EAC7CC,GAAMgC,EAAQhC,EAAI+B,EAAO/B,GAAK8B,EAAQC,EAAO/B,EAEnD,OAAO5C,EAAAA,cAAcyC,qBAAqBC,EAAGC,EAAGC,GAGpD,SAASmC,EAA4CL,GAKjD,IAHI7E,KAAKD,OACP8E,EAAO7E,KAAKD,KAAK8E,IAEZA,EAAO7E,KAAKC,KAAKH,MAEpBE,KAAK2E,QAAU3E,KAAKC,KACpBD,KAAKC,KAAOD,KAAKC,KAAKA,KAK1B,OAFA4E,GAAQA,EAAO7E,KAAK2E,QAAQ7E,OAASE,KAAKC,KAAKH,KAAOE,KAAK2E,QAAQ7E,OAE1DE,KAAKC,KAAKJ,MAAQG,KAAK2E,QAAQ9E,OAASgF,EAAQ7E,KAAK2E,QAAQ9E,MAG1E,SAASsF,EAA2CN,GAKhD,IAHI7E,KAAKD,OACP8E,EAAO7E,KAAKD,KAAK8E,IAEZA,EAAO7E,KAAKC,KAAKH,MAEpBE,KAAK2E,QAAU3E,KAAKC,KACpBD,KAAKC,KAAOD,KAAKC,KAAKA,KAG1B4E,GAAQA,EAAO7E,KAAK2E,QAAQ7E,OAASE,KAAKC,KAAKH,KAAOE,KAAK2E,QAAQ7E,MACnE,IAAMgF,EAAS9E,KAAK2E,QAAQ9E,MACxBkF,EAAU/E,KAAKC,KAAKJ,MAClBgD,GAAMkC,EAAQlC,EAAIiC,EAAOjC,GAAKgC,EAAQC,EAAOjC,EAC7CC,GAAMiC,EAAQjC,EAAIgC,EAAOhC,GAAK+B,EAAQC,EAAOhC,EAC7CC,GAAMgC,EAAQhC,EAAI+B,EAAO/B,GAAK8B,EAAQC,EAAO/B,EAEnD,OAAO5C,EAAAA,cAAcyC,qBAAqBC,EAAGC,EAAGC,GAGpD,SAASqC,EAA4CP,GAKjD,IAHI7E,KAAKD,OACP8E,EAAO7E,KAAKD,KAAK8E,IAEZ7E,KAAKC,MAAQ4E,EAAO7E,KAAKC,KAAKH,MAEjCE,KAAK2E,QAAU3E,KAAKC,KACpBD,KAAKC,KAAOD,KAAKC,KAAKA,KAG1B,OAAOD,KAAK2E,QAAQ9E,MAGxB,SAASwF,EAA2CR,GAKhD,IAHI7E,KAAKD,OACP8E,EAAO7E,KAAKD,KAAK8E,IAEZ7E,KAAKC,MAAQ4E,EAAO7E,KAAKC,KAAKH,MAEjCE,KAAK2E,QAAU3E,KAAKC,KACpBD,KAAKC,KAAOD,KAAKC,KAAKA,KAE1B,IAAM6E,EAAS9E,KAAK2E,QAAQ9E,MAE5B,OAAOM,EAAAA,cAAcyC,qBAAqBkC,EAAOjC,EAAGiC,EAAOhC,EAAGgC,EAAO/B,OC3ErEuC,eDkHA,SAAAC,EAAYC,QAAA,IAAAA,IAAAA,GAAA,GAERxF,KAAK2E,QAAU,KACf3E,KAAKC,KAAO,KACZD,KAAKwF,UAAYA,EACjBxF,KAAKyF,YAAc,KACnBzF,KAAKD,KAAO,KA4BpB,OApBWwF,EAAAG,UAAAC,MAAP,SAAahF,GAETX,KAAK2E,QAAUhE,EACfX,KAAKC,KAAOU,EAAMV,KACDD,KAAKC,MAAQD,KAAKC,KAAKH,MAAQ,EAI5CE,KAAKyF,YAAczF,KAAKwF,QAAUP,EAAiBD,EAE9CrE,EAAMT,UAEXF,KAAKyF,YAAczF,KAAKwF,QAAUH,EAAkBD,EAIpDpF,KAAKyF,YAAczF,KAAKwF,QAAUL,EAAkBD,EAExDlF,KAAKD,KAAOC,KAAK2E,QAAQ5E,MAEjCwF,mBEfI,SAAAK,EAAYC,GAAZ,IAAAC,EAIIC,EAAAC,KAAAhG,OAAOA,YAEP8F,EAAKG,UAAYH,EAAKI,UAAY,KAElCJ,EAAKD,QAAUA,EAEfC,EAAKK,OAAO1D,EAAIqD,EAAKK,OAAOzD,EAAI,GAChCoD,EAAKM,SAAW,IAAIC,EAAAA,MACpBP,EAAKQ,cAAgB,EACrBR,EAAKS,qBAAuB,EAC5BT,EAAKU,QAAU,EACfV,EAAKW,IAAM,EACXX,EAAK/F,KAAO,KACZ+F,EAAKY,UAAY,KACjBZ,EAAKa,UAAY,IAAIpB,EACrBO,EAAKc,UAAY,IAAIrB,EACrBO,EAAKe,gBAAkB,EACvBf,EAAKgB,aAAe,IAAIT,EAAAA,MACxBP,EAAKiB,SAAWC,IAChBlB,EAAKmB,UAAY,IAAI1B,EACrBO,EAAKoB,gBAAkB,EACvBpB,EAAKqB,UAAY,IAAI5B,GAAa,GAClCO,EAAKsB,UAAW,EAChBtB,EAAKuB,UAAW,EAChBvB,EAAKwB,UAAW,EAChBxB,EAAKyB,iBAAkB,EACvBzB,EAAK0B,UAAW,EAChB1B,EAAK2B,mBAAoB,EACzB3B,EAAK4B,aAAe,EACpB5B,EAAK7F,KAAO,KACZ6F,EAAK6B,KAAO,KAGZ7B,EAAK8B,KAAO9B,EAAK8B,KACjB9B,EAAK+B,cAAgBjC,EAASF,UAAUkC,KACxC9B,EAAKgC,OAAShC,EAAKgC,OACnBhC,EAAKiC,gBAAkBnC,EAASF,UAAUoC,OAC1ChC,EAAKkC,eAAiBjC,EAAAL,UAAMuC,QAC5BnC,EAAKoC,iBAAmBtC,EAASF,UAAUuC,QAC3CnC,EAAKqC,SAAWrC,EAAKqC,SACrBrC,EAAKsC,KAAOtC,EAAKsC,OAgQzB,OApb8BC,EAAAzC,EAAAG,GA2LnBH,EAAAF,UAAAkC,KAAP,WAGI5H,KAAKyG,IAAM,EAEXzG,KAAKoG,SAAS3D,EAAIzC,KAAK4G,UAAUjC,QAAQ9E,MAAQG,KAAK6G,gBACtD7G,KAAKoG,SAAS1D,EAAI,EAClBvC,EAAAA,cAAc+B,YAAYlC,KAAKsI,SAAUtI,KAAKoG,UAC1CpG,KAAKuI,WAELvI,KAAKsI,SAAW,EAKhBtI,KAAKsI,UAAYnI,EAAAA,cAAc4B,YAGnC/B,KAAKsG,eAAiBnG,EAAAA,cAAc4B,YACpC/B,KAAKuG,sBAAwBpG,EAAAA,cAAc4B,YAG3C/B,KAAKuD,MAAQvD,KAAK2G,UAAUhC,QAAQ9E,MAEpCG,KAAKwI,MAAM/F,EAAIzC,KAAKwI,MAAM9F,EAAI1C,KAAKiH,UAAUtC,QAAQ9E,MAErDG,KAAKoH,WAAapH,KAAK2G,UAAUhC,QAAQ1E,KACzCD,KAAKsH,WAAatH,KAAK4G,UAAUjC,QAAQ1E,KACzCD,KAAKqH,WAAarH,KAAKiH,UAAUtC,QAAQ1E,KACzCD,KAAKwH,WAAaxH,KAAKmH,UAAUxC,QAAQ1E,KACzCD,KAAKuH,gBAA0C,IAAxBvH,KAAK8G,aAAarE,GAAmC,IAAxBzC,KAAK8G,aAAapE,EAEtE1C,KAAKyH,kBAAoBzH,KAAKsH,UAA6C,IAAjCtH,KAAK4G,UAAUjC,QAAQ9E,OAAeG,KAAKuH,gBAErFvH,KAAK0H,aAAe,EAAI1H,KAAKwG,QAE7B,IAAMnD,EAAQrD,KAAKmH,UAAUxC,QAAQ9E,MAErCG,KAAKyI,KAAOtI,EAAAA,cAAcyC,qBAAqBS,EAAMR,EAAGQ,EAAMP,EAAGO,EAAMN,GAEvE/C,KAAK0I,SAAU,GAQZ9C,EAAAF,UAAAyC,SAAP,SAAgBQ,GAEZ3I,KAAK4I,QAAUD,GAAOhH,EAAAA,QAAQkH,OAU3BjD,EAAAF,UAAAoC,OAAP,SAAcgB,GAKV,GAFA9I,KAAKyG,KAAOqC,EAER9I,KAAKyG,KAAOzG,KAAKwG,SAAWxG,KAAKyG,IAAM,EAIvC,OAFAzG,KAAKoI,QAEG,EAIZ,IAAIvD,EAAO7E,KAAKyG,IAAMzG,KAAK0H,aAwB3B,GAtBI1H,KAAKD,OAMD8E,EAJqB,IAArB7E,KAAKD,KAAKc,OAIFb,KAAKD,KAAa8E,EAAM,EAAG,EAAG,GAM/B7E,KAAKD,KAAK8E,IAKrB7E,KAAKoH,WAELpH,KAAKuD,MAAQvD,KAAK2G,UAAUlB,YAAYZ,IAGxC7E,KAAKqH,SACT,CACI,IAAMmB,EAAQxI,KAAKiH,UAAUxB,YAAYZ,GAAQ7E,KAAKkH,gBAEtDlH,KAAKwI,MAAM/F,EAAIzC,KAAKwI,MAAM9F,EAAI8F,EAGlC,GAAIxI,KAAKyH,kBACT,CACI,IAAIsB,OAAM,EACNC,OAAM,EAGV,GAAIhJ,KAAKsH,SACT,CACI,IAAM2B,EAAQjJ,KAAK4G,UAAUnB,YAAYZ,GAAQ7E,KAAK6G,gBAEtD1G,EAAAA,cAAc6C,UAAUhD,KAAKoG,UAC7BjG,EAAAA,cAAcgD,QAAQnD,KAAKoG,SAAU6C,GACrCF,EAAS/I,KAAKoG,SAAS3D,EAAIqG,EAC3BE,EAAShJ,KAAKoG,SAAS1D,EAAIoG,OAE1B,GAAI9I,KAAKuH,gBACd,CACI,IAAM2B,EAAQlJ,KAAKoG,SAAS3D,EACtB0G,EAAQnJ,KAAKoG,SAAS1D,EAI5B,GAFA1C,KAAKoG,SAAS3D,GAAKzC,KAAK8G,aAAarE,EAAIqG,EACzC9I,KAAKoG,SAAS1D,GAAK1C,KAAK8G,aAAapE,EAAIoG,EACrC9I,KAAK+G,SACT,CACI,IAAMqC,EAAejJ,EAAAA,cAAcU,OAAOb,KAAKoG,UAI3CgD,EAAepJ,KAAK+G,UAEpB5G,EAAAA,cAAcgD,QAAQnD,KAAKoG,SAAUpG,KAAK+G,SAAWqC,GAI7DL,GAAUG,EAAQlJ,KAAKoG,SAAS3D,GAAK,EAAIqG,EACzCE,GAAUG,EAAQnJ,KAAKoG,SAAS1D,GAAK,EAAIoG,OAIzCC,EAAS/I,KAAKoG,SAAS3D,EAAIqG,EAC3BE,EAAShJ,KAAKoG,SAAS1D,EAAIoG,EAG/B9I,KAAKqJ,SAAS5G,GAAKsG,EACnB/I,KAAKqJ,SAAS3G,GAAKsG,EAQvB,GALIhJ,KAAKwH,WAELxH,KAAKyI,KAAOzI,KAAKmH,UAAU1B,YAAYZ,IAGT,IAA9B7E,KAAKuG,qBACT,CACI,IAAM+C,EAAmBtJ,KAAKsG,cAAiBtG,KAAKuG,qBAAuBuC,EAE3E9I,KAAKsI,WAAatI,KAAKsG,cAAgBgD,GAAoB,EAAIR,EAC/D9I,KAAKsG,cAAgBgD,OAEO,IAAvBtJ,KAAKsG,cAEVtG,KAAKsI,UAAYtI,KAAKsG,cAAgBwC,EAEjC9I,KAAK8G,eAAiB9G,KAAKuI,aAEhCvI,KAAKsI,SAAWtG,KAAKuH,MAAMvJ,KAAKoG,SAAS1D,EAAG1C,KAAKoG,SAAS3D,IAG9D,OAAOoC,GAOJe,EAAAF,UAAA0C,KAAP,WAEIpI,KAAK6F,QAAQ2D,QAAQxJ,OAMlB4F,EAAAF,UAAAuC,QAAP,WAEQjI,KAAKyJ,QAELzJ,KAAKyJ,OAAOC,YAAY1J,MAE5BA,KAAKgI,iBACLhI,KAAK6F,QAAU7F,KAAKoG,SAAWpG,KAAKmH,UAAYnH,KAAKiH,UAAYjH,KAAK2G,UACxE3G,KAAK4G,UAAY5G,KAAKD,KAAOC,KAAKC,KAAOD,KAAK2H,KAAO,MAWzC/B,EAAA+D,SAAd,SAAuBhB,GAGnB,IAAI7H,EAEJ,IAAKA,EAAI6H,EAAI9H,OAAQC,GAAK,IAAKA,EAEL,iBAAX6H,EAAI7H,KAEX6H,EAAI7H,GAAKQ,EAAqBqH,EAAI7H,KAK1C,GAAIX,EAAAA,cAAc2B,QAEd,IAAKhB,EAAI6H,EAAI9H,OAAS,EAAGC,EAAI,IAAKA,EAE9B,GAAI6H,EAAI7H,GAAG8I,cAAgBjB,EAAI7H,EAAI,GAAG8I,YACtC,CACQC,OAAOC,SAGPA,QAAQC,KAAK,gGAEjB,MAKZ,OAAOpB,GASG/C,EAAAoE,UAAd,SAAwBtD,GAEpB,OAAOA,GAEfd,GApb8BqE,EAAAA,qBC4B1B,SAAAC,EAAY5J,GAERN,KAAK4D,SAAW,GAChB5D,KAAKmK,gBAAkB,GACvBnK,KAAKoK,YAAc,EACnBpK,KAAK4H,KAAKtH,GAoGlB,OA9FY4J,EAAAxE,UAAAkC,KAAR,SAAatH,GAGT,GAAKA,GAASA,EAAKO,OAId,GAAIwJ,MAAMC,QAAQhK,EAAK,IAGxB,IAAK,IAAIQ,EAAI,EAAGA,EAAIR,EAAKO,SAAUC,EAM/B,IAHA,IAAMyJ,EAAQjK,EAAKQ,GACf0J,EAAYD,EAAM,GAEbE,EAAI,EAAGA,EAAIF,EAAM1J,SAAU4J,EACpC,CACI,IAAMC,EAASH,EAAME,GAErBzK,KAAK4D,SAAS+G,KAAK,CAAEC,GAAIJ,EAAWK,GAAIH,EAAQI,EAAG,IACnDN,EAAYE,OASpB,IAHIF,EAAYlK,EAAK,GAGZQ,EAAI,EAAGA,EAAIR,EAAKO,SAAUC,EACnC,CACU4J,EAASpK,EAAKQ,GAEpBd,KAAK4D,SAAS+G,KAAK,CAAEC,GAAIJ,EAAWK,GAAIH,EAAQI,EAAG,IACnDN,EAAYE,OA9BhB1K,KAAK4D,SAAS+G,KAAK,CAAEC,GAAI,CAAEnI,EAAG,EAAGC,EAAG,GAAKmI,GAAI,CAAEpI,EAAG,EAAGC,EAAG,GAAKoI,EAAG,IAmCpE,IAAShK,EAAI,EAAGA,EAAId,KAAK4D,SAAS/C,SAAUC,EAC5C,CACU,IAAAJ,EAAAV,KAAA4D,SAAA9C,GAAE8J,EAAAlK,EAAAkK,GAAIC,EAAAnK,EAAAmK,GACNE,EAAY/I,KAAKoB,MAAOyH,EAAGpI,EAAImI,EAAGnI,IAAMoI,EAAGpI,EAAImI,EAAGnI,IAAQoI,EAAGnI,EAAIkI,EAAGlI,IAAMmI,EAAGnI,EAAIkI,EAAGlI,IAG1F1C,KAAK4D,SAAS9C,GAAGgK,EAAIC,EACrB/K,KAAKoK,aAAeW,EAEpB/K,KAAKmK,gBAAgBQ,KAAK3K,KAAKoK,eAQhCF,EAAAxE,UAAAsF,eAAP,SAAsBC,GAGlB,IACIC,EACArG,EAFEsG,EAAOnJ,KAAKoJ,SAAWpL,KAAKoK,YAKlC,GAA6B,IAAzBpK,KAAK4D,SAAS/C,OAEdqK,EAAYlL,KAAK4D,SAAS,GAC1BiB,EAAOsG,OAMP,IAAK,IAAIrK,EAAI,EAAGA,EAAId,KAAKmK,gBAAgBtJ,SAAUC,EAE/C,GAAIqK,EAAOnL,KAAKmK,gBAAgBrJ,GAChC,CACIoK,EAAYlL,KAAK4D,SAAS9C,GAG1B+D,EAAa,IAAN/D,EAAUqK,EAAOA,EAAOnL,KAAKmK,gBAAgBrJ,EAAI,GACxD,MAKZ+D,GAAQqG,EAAUJ,GAAK,EACf,IAAAF,EAAAM,EAAAN,GAAIC,EAAAK,EAAAL,GAGZI,EAAIxI,EAAImI,EAAGnI,EAAKoC,GAAQgG,EAAGpI,EAAImI,EAAGnI,GAClCwI,EAAIvI,EAAIkI,EAAGlI,EAAKmC,GAAQgG,EAAGnI,EAAIkI,EAAGlI,IAE1CwH,KFhIM9I,EAASC,EAIXiE,EAFA9D,SAAS,WAAaC,KAAKC,EAAAA,SAAc,GAAI,IAAM,EAEzCN,EAAekE,OAAO+F,OAIvBjK,EAAOkK,OAAOD,OAW3B,IAAME,EAAc,IAAIlF,EAAAA,mBAqRpB,SAAAmF,EAAYC,EAA2BC,EAAqBC,GAxBlD3L,KAAA4L,oBAAsB,EA0B5B5L,KAAK6L,qBAAuBjG,EAE5B5F,KAAK0L,eAAiB,KACtB1L,KAAK8L,WAAa,KAClB9L,KAAK+L,WAAa,KAClB/L,KAAKgM,uBAAyB,EAC9BhM,KAAK8G,aAAe,KACpB9G,KAAK+G,SAAWC,IAChBhH,KAAKiM,WAAa,KAClBjM,KAAKkM,uBAAyB,EAC9BlM,KAAKmM,WAAa,KAClBnM,KAAKoM,YAAc,EACnBpM,KAAKqM,YAAc,EACnBrM,KAAKsM,iBAAmB,EACxBtM,KAAKuM,iBAAmB,EACxBvM,KAAKuI,YAAa,EAClBvI,KAAKwM,iBAAmB,EACxBxM,KAAKyM,iBAAmB,EACxBzM,KAAK0M,kBAAoB,EACzB1M,KAAK2M,WAAa,KAClB3M,KAAK0G,UAAY,KAEjB1G,KAAK4M,WAAa,EAClB5M,KAAK6M,YAAc,EACnB7M,KAAK8M,aAAe,IACpB9M,KAAK+M,iBAAmB,EACxB/M,KAAKgN,SAAW,KAChBhN,KAAKiN,UAAY,KACjBjN,KAAKkN,WAAa,KAClBlN,KAAKmN,UAAY,KACjBnN,KAAKoN,YAAc,KACnBpN,KAAKqN,oBAAsB,KAC3BrN,KAAKsN,iBAAmB,EACxBtN,KAAKuN,gBAAkB,EACvBvN,KAAKwN,WAAa,EAElBxN,KAAKsI,SAAW,EAChBtI,KAAKyN,SAAW,KAChBzN,KAAK0N,gBAAkB,KACvB1N,KAAK2N,iBAAkB,EACvB3N,KAAK4N,aAAc,EACnB5N,KAAK6N,QAAU,KACf7N,KAAK8N,WAAY,EACjB9N,KAAK+N,cAAgB,EACrB/N,KAAKgO,OAAQ,EACbhO,KAAKiO,YAAc,EACnBjO,KAAKkO,cAAgB,EACrBlO,KAAKmO,sBAAwB,KAC7BnO,KAAKoO,qBAAuB,KAC5BpO,KAAKqO,WAAa,KAClBrO,KAAKsO,YAAc,KACnBtO,KAAKuO,SAAW,KAChBvO,KAAKwO,aAAc,EACnBxO,KAAK4L,oBAAsB,EAC3B5L,KAAKyO,sBAAuB,EAC5BzO,KAAK0O,kBAAoB,KAGzB1O,KAAKyJ,OAASgC,EAEVC,GAAkBC,GAElB3L,KAAK4H,KAAK8D,EAAgBC,GAI9B3L,KAAKwJ,QAAUxJ,KAAKwJ,QACpBxJ,KAAK8H,OAAS9H,KAAK8H,OACnB9H,KAAK2O,OAAS3O,KAAK2O,OACnB3O,KAAK4O,eAAiB5O,KAAK4O,eAC3B5O,KAAK6O,eAAiB7O,KAAK6O,eAu7BnC,OA96BIC,OAAAC,eAAWvD,EAAA9F,UAAA,aAAU,KAArB,WAAmC,OAAoC,IAA7B1F,KAAK4L,wBAC/C,SAAsB/L,GAElBG,KAAK4L,mBAAqB/L,EAAQ,GAAK,mCAO3CiP,OAAAC,eAAWvD,EAAA9F,UAAA,YAAS,KAApB,WAAiC,OAAO1F,KAAK4M,gBAC7C,SAAqB/M,GAKbG,KAAK4M,WAFY,iBAAV/M,GAAsBA,EAAQ,EAEnBA,EAIA,mCAQ1BiP,OAAAC,eAAWvD,EAAA9F,UAAA,sBAAmB,KAA9B,WAAoD,OAAO1F,KAAK6L,0BAChE,SAA+BhM,GAE3B,GAAIA,IAAUG,KAAK6L,qBACnB,CACI7L,KAAK6L,qBAAuBhM,EAE5BG,KAAKgP,UAEL,IAAK,IAAIC,EAAWjP,KAAKqO,WAAYY,EAAUA,EAAWA,EAAShP,KAE/DgP,EAAShH,UAEbjI,KAAKqO,WAAa,KAEdrO,KAAKsO,aAAetO,KAAKuO,UAEzBvO,KAAK4H,KAAK5H,KAAKuO,SAAUvO,KAAKsO,+CAQ1CQ,OAAAC,eAAWvD,EAAA9F,UAAA,SAAM,KAAjB,WAAiC,OAAO1F,KAAK6N,aAC7C,SAAkBhO,GAEdG,KAAKgP,UACLhP,KAAK6N,QAAUhO,mCAQZ2L,EAAA9F,UAAAkC,KAAP,SAAYe,EAAUgD,GAElB,GAAKhD,GAAQgD,EAAb,CAKA3L,KAAKgP,UAILhP,KAAKsO,YAAc3C,EACnB3L,KAAKuO,SAAW5F,EAGhBA,EAAM0B,MAAMC,QAAQ3B,GAAOA,EAAIuG,QAAU,CAACvG,GAE1C,IAAMwG,EAAYnP,KAAK6L,qBAEvB7L,KAAK0L,eAAiByD,EAAUxF,SAAWwF,EAAUxF,SAAShB,GAAOA,EAKjEgD,EAAOpI,MAEPvD,KAAK8L,WAAalM,EAAaS,WAAWsL,EAAOpI,OAIjDvD,KAAK8L,WAAa,IAAIlM,EAAa,EAAG,GAGtC+L,EAAO1C,OAEPjJ,KAAK+L,WAAanM,EAAaS,WAAWsL,EAAO1C,OAEjDjJ,KAAKgM,wBAA0B,2BAA4BL,EAASA,EAAOK,uBAA0BL,EAAO1C,MAAc+C,yBAA2B,IAIrJhM,KAAKgM,uBAAyB,EAC9BhM,KAAK+L,WAAa,IAAInM,EAAa,EAAG,IAG1C,IAAMkH,EAAe6E,EAAO7E,aAExBA,IAAiBA,EAAarE,GAAKqE,EAAapE,IAGhD1C,KAAK+L,WAAW9L,KAAO,KACvBD,KAAK8G,aAAe,IAAIT,EAAAA,MAAMS,EAAarE,EAAGqE,EAAapE,GAC3D1C,KAAK+G,SAAW4E,EAAO5E,UAAYC,KAInChH,KAAK8G,aAAe,IAAIT,EAAAA,MAGxBsF,EAAOnD,OAEPxI,KAAKiM,WAAarM,EAAaS,WAAWsL,EAAOnD,OAEjDxI,KAAKkM,wBAA0B,2BAA4BP,EAASA,EAAOO,uBAA0BP,EAAOnD,MAAc0D,yBAA2B,IAIrJlM,KAAKiM,WAAa,IAAIrM,EAAa,EAAG,GACtCI,KAAKkM,uBAAyB,GAG9BP,EAAOtI,MAEPrD,KAAKmM,WAAavM,EAAaS,WAAWsL,EAAOtI,OAIjDrD,KAAKmM,WAAa,IAAIvM,EAAa,CAAEiD,EAAG,IAAMC,EAAG,IAAMC,EAAG,KAAQ,GAGlE4I,EAAOyD,eAEPpP,KAAKsM,iBAAmBX,EAAOyD,cAAcC,IAC7CrP,KAAKuM,iBAAmBZ,EAAOyD,cAAcE,KAI7CtP,KAAKsM,iBAAmBtM,KAAKuM,iBAAmB,EAEhDZ,EAAOpD,aACXvI,KAAKsM,kBAAoBtM,KAAKuM,kBAE1BvM,KAAKuI,aAAeoD,EAAOpD,WAI3BvI,KAAKuI,YAAa,EAGlBoD,EAAOrF,eAEPtG,KAAKwM,iBAAmBb,EAAOrF,cAAc+I,IAC7CrP,KAAKyM,iBAAmBd,EAAOrF,cAAcgJ,KAI7CtP,KAAKwM,iBAAmBxM,KAAKyM,iBAAmB,EAGpDzM,KAAKuG,qBAAuBoF,EAAOpF,sBAAwB,EAE3DvG,KAAKoM,YAAcT,EAAO4D,SAASF,IACnCrP,KAAKqM,YAAcV,EAAO4D,SAASD,IAEnCtP,KAAK0M,kBAAoBvM,EAAAA,cAAc+D,aAAayH,EAAO6D,WAEvD7D,EAAO5L,KAEPC,KAAK2M,WAAoC,mBAAhBhB,EAAO5L,KAC1B4L,EAAO5L,KAAOI,EAAAA,cAAcC,aAAauL,EAAO5L,MAItDC,KAAK2M,WAAa,KAGlBwC,EAAUnF,UAEVhK,KAAK0G,UAAYyI,EAAUnF,UAAU2B,EAAOjF,WAI5C1G,KAAK0G,UAAYiF,EAAOjF,WAAa,KAMzC1G,KAAKmN,UAAYnN,KAAKoN,YAAc,KACpCpN,KAAKsN,iBAAmB,EACpB3B,EAAO2B,kBAAoB3B,EAAO2B,iBAAmB,IAErDtN,KAAKsN,iBAAmB3B,EAAO2B,kBAEnCtN,KAAKuN,gBAAkB,EACvBvN,KAAKwN,WAAa,EAElBxN,KAAKyP,eAAe9D,GAEpB3L,KAAK0P,UAAY/D,EAAO+D,UACxB1P,KAAK6M,YAA6C,iBAAvBlB,EAAOkB,aAA4BlB,EAAOkB,YAAc,EAAKlB,EAAOkB,YAAc,EAE7G7M,KAAK+M,gBAAkBpB,EAAOoB,kBAAoB,EAElD/M,KAAK8M,aAAenB,EAAOmB,aAAe,EAAInB,EAAOmB,aAAe,IAEpE9M,KAAK8N,YAAcnC,EAAOmC,UAE1B9N,KAAKsI,SAAW,EAChBtI,KAAKyN,SAAW,IAAIpH,EAAAA,MACpBrG,KAAKgN,SAAW,IAAI3G,EAAAA,MAAMsF,EAAOgE,IAAIlN,EAAGkJ,EAAOgE,IAAIjN,GAEnD1C,KAAK4P,eAAejH,EAAKgD,GAEzB3L,KAAK0N,gBAAkB1N,KAAKgN,SAAS6C,QAErC7P,KAAK2N,iBAAkB,EAEvB3N,KAAKiO,YAAc,EACnBjO,KAAK8P,UAAuBC,IAAhBpE,EAAOmE,QAA8BnE,EAAOmE,KACxD9P,KAAKgQ,aAAerE,EAAOqE,WAC3BhQ,KAAKiQ,aAAetE,EAAOsE,aAUrBzE,EAAA9F,UAAAkK,eAAV,SAAyBjH,EAAUgD,KAUzBH,EAAA9F,UAAA+J,eAAV,SAAyB9D,GAErB,IAAIyB,EAEJ,OAAQzB,EAAOsB,WAEX,IAAK,OACDjN,KAAKiN,UAAY,OACjBjN,KAAKkN,WAAalN,KAAKkQ,WACvB,IAAM/C,EAAYxB,EAAOwB,UAEzBnN,KAAKmN,UAAY,IAAIgD,EAAAA,UAAUhD,EAAU1K,EAAG0K,EAAUzK,EAAGyK,EAAUiD,EAAGjD,EAAUkD,GAChF,MACJ,IAAK,SACDrQ,KAAKiN,UAAY,SACjBjN,KAAKkN,WAAalN,KAAKsQ,aACvBlD,EAAczB,EAAOyB,YACrBpN,KAAKoN,YAAc,IAAImD,EAAAA,OAAOnD,EAAY3K,EAAG2K,EAAY1K,EAAG0K,EAAYvK,GACxE,MACJ,IAAK,OACD7C,KAAKiN,UAAY,OACjBjN,KAAKkN,WAAalN,KAAKwQ,WACvBpD,EAAczB,EAAOyB,YACrBpN,KAAKoN,YAAc,IAAImD,EAAAA,OAAOnD,EAAY3K,EAAG2K,EAAY1K,EAAG0K,EAAYvK,GACxE7C,KAAKoN,YAAYqD,UAAYrD,EAAYsD,KACzC,MACJ,IAAK,QACD1Q,KAAKiN,UAAY,QACjBjN,KAAKkN,WAAalN,KAAK2Q,YACvB3Q,KAAKuN,gBAAkB5B,EAAO4B,gBAC9BvN,KAAKwN,WAAa7B,EAAO6B,WAAa7B,EAAO6B,WAAa,EAC1D,MACJ,IAAK,QACDxN,KAAKiN,UAAY,QACjBjN,KAAKkN,WAAalN,KAAK4Q,YACvB,MACJ,IAAK,iBACD5Q,KAAKiN,UAAY,iBACjBjN,KAAKkN,WAAalN,KAAK6Q,qBACvB7Q,KAAKqN,oBAAsB,IAAInD,EAAeyB,EAAOmF,cACrD,MACJ,QACI9Q,KAAKiN,UAAY,QACjBjN,KAAKkN,WAAalN,KAAK4Q,cAU5BpF,EAAA9F,UAAA8D,QAAP,SAAeyF,GAEPA,EAAShP,OAETgP,EAAShP,KAAK0H,KAAOsH,EAAStH,MAE9BsH,EAAStH,OAETsH,EAAStH,KAAK1H,KAAOgP,EAAShP,MAE9BgP,IAAajP,KAAKoO,uBAElBpO,KAAKoO,qBAAuBa,EAAStH,MAErCsH,IAAajP,KAAKmO,wBAElBnO,KAAKmO,sBAAwBc,EAAShP,MAG1CgP,EAAStH,KAAO,KAChBsH,EAAShP,KAAOD,KAAKqO,WACrBrO,KAAKqO,WAAaY,EAEdA,EAASxF,QAETwF,EAASxF,OAAOC,YAAYuF,KAG9BjP,KAAK+N,eAOJvC,EAAA9F,UAAAiJ,OAAP,SAAcoC,GAEV,GAAI/Q,KAAKsI,WAAayI,EAAtB,CAEA,IAAMC,EAAOD,EAAS/Q,KAAKsI,SAE3BtI,KAAKsI,SAAWyI,EAEhB5Q,EAAAA,cAAc+B,YAAY8O,EAAMhR,KAAKgN,UAErChN,KAAK4N,aAAc,IAQhBpC,EAAA9F,UAAAkJ,eAAP,SAAsBnM,EAAWC,GAE7B1C,KAAK4N,aAAc,EACnB5N,KAAKgN,SAASvK,EAAIA,EAClBzC,KAAKgN,SAAStK,EAAIA,GASf8I,EAAA9F,UAAAmJ,eAAP,SAAsBpM,EAAWC,GAE7B1C,KAAK4N,aAAc,EACnB5N,KAAKyN,SAAShL,EAAIA,EAClBzC,KAAKyN,SAAS/K,EAAIA,GAQf8I,EAAA9F,UAAAuL,sBAAP,WAEIjR,KAAK2N,iBAAkB,GAO3BmB,OAAAC,eAAWvD,EAAA9F,UAAA,OAAI,KAAf,WAA6B,OAAO1F,KAAKgO,WACzC,SAAgBnO,GAEZG,KAAKgO,QAAUnO,EACfG,KAAKkO,aAAelO,KAAK+M,iDAO7B+B,OAAAC,eAAWvD,EAAA9F,UAAA,aAAU,KAArB,WAAmC,OAAO1F,KAAKwO,iBAC/C,SAAsB3O,GAEdG,KAAKwO,cAAgB3O,EAErByF,EAAO4L,OAAOlR,KAAK8H,OAAQ9H,OAErBA,KAAKwO,aAAe3O,GAE1ByF,EAAO6L,IAAInR,KAAK8H,OAAQ9H,MAE5BA,KAAKwO,cAAgB3O,mCAQlB2L,EAAA9F,UAAA0L,mBAAP,SAA0BC,GAEtBrR,KAAKgQ,YAAa,EAClBhQ,KAAK8P,MAAO,EACZ9P,KAAKyO,sBAAuB,EAC5BzO,KAAK0O,kBAAoB2C,GAOtB7F,EAAA9F,UAAA4L,SAAP,SAAgBD,GAEZrR,KAAK8P,MAAO,EACZ9P,KAAK0O,kBAAoB2C,GAOtB7F,EAAA9F,UAAAoC,OAAP,SAAcgB,GASV,GAPI9I,KAAKwO,cAEL1F,EAAQA,EAAQyI,EAAAA,SAASC,YAAc,KAKtCxR,KAAK6N,QAAV,CAEA,IAAI/M,EACAmO,EACAhP,EAOAwR,EACAC,EANJ,IAAKzC,EAAWjP,KAAKmO,sBAAuBc,EAAUA,EAAWhP,EAE7DA,EAAOgP,EAAShP,KAChBgP,EAASnH,OAAOgB,GAMhB9I,KAAK2N,kBAEL8D,EAAQzR,KAAK0N,gBAAgBjL,EAC7BiP,EAAQ1R,KAAK0N,gBAAgBhL,GAGjC,IAAMiP,EAAO3R,KAAKyN,SAAShL,EAAIzC,KAAKgN,SAASvK,EACvCmP,EAAO5R,KAAKyN,SAAS/K,EAAI1C,KAAKgN,SAAStK,EAG7C,GAAI1C,KAAKgO,MAKL,IAFAhO,KAAKiO,aAAenF,EAAQ,EAAI,EAAIA,EAE7B9I,KAAKiO,aAAe,GAC3B,CAEI,GAAIjO,KAAKkO,cAAgB,IAErBlO,KAAKkO,cAAgBlO,KAAK4M,WACtB5M,KAAKkO,cAAgB,GACzB,CACIlO,KAAKiO,YAAc,EACnBjO,KAAKkO,aAAe,EACpBlO,KAAK8P,MAAO,EACZ,MAIR,GAAI9P,KAAK+N,eAAiB/N,KAAK8M,aAE3B9M,KAAKiO,aAAejO,KAAK4M,eAF7B,CAMA,IAAI2C,OAAQ,EAWZ,GAPIA,EAFAvP,KAAKoM,cAAgBpM,KAAKqM,YAEfrM,KAAKoM,YAIJpK,KAAKoJ,UAAYpL,KAAKqM,YAAcrM,KAAKoM,aAAgBpM,KAAKoM,aAGzEpM,KAAKiO,YAAcsB,EACxB,CAGI,IAAIsC,OAAQ,EACRC,OAAQ,EAEZ,GAAI9R,KAAK2N,iBAAmB3N,KAAK4N,YACjC,CAEI,IAAM/I,EAAO,EAAK7E,KAAKiO,YAAcnF,EAErC+I,GAAaF,EAAOF,GAAS5M,EAAQ4M,EACrCK,GAAaF,EAAOF,GAAS7M,EAAQ6M,OAIrCG,EAAWF,EACXG,EAAWF,EAGf9Q,EAAI,EACJ,IAAK,IAAIiR,EAAM/P,KAAKqN,IAAIrP,KAAKsN,iBAAkBtN,KAAK8M,aAAe9M,KAAK+N,eAAgBjN,EAAIiR,IAAOjR,EAG/F,KAAId,KAAK6M,YAAc,GAAK7K,KAAKoJ,UAAYpL,KAAK6M,aAAlD,CAKA,IAAIzK,OAAC,EAEDpC,KAAKqO,YAELjM,EAAIpC,KAAKqO,WACTrO,KAAKqO,WAAarO,KAAKqO,WAAWpO,KAClCmC,EAAEnC,KAAO,MAITmC,EAAI,IAAIpC,KAAKgS,oBAAoBhS,MAIjCA,KAAK0L,eAAe7K,OAAS,GAGI,IAA7Bb,KAAK4L,oBAGLxJ,EAAE+F,SAASnI,KAAK0L,eAAe1L,KAAK4L,wBAEhC5L,KAAK4L,mBAAqB,GAAK5L,KAAK4L,oBAAsB5L,KAAK0L,eAAe7K,UAE9Eb,KAAK4L,mBAAqB,IAM9BxJ,EAAE+F,SAASnI,KAAK0L,eAAe1J,KAAKiQ,MAAMjQ,KAAKoJ,SAAWpL,KAAK0L,eAAe7K,UAOlFuB,EAAE+F,SAASnI,KAAK0L,eAAe,IAGnCtJ,EAAEuE,UAAUhB,MAAM3F,KAAK8L,YACa,IAAhC9L,KAAKgM,yBAGL5J,EAAEyE,gBAAmB7E,KAAKoJ,UAAY,EAAIpL,KAAKgM,wBAA2BhM,KAAKgM,wBAEnF5J,EAAEwE,UAAUjB,MAAM3F,KAAK+L,YACvB3J,EAAE0E,aAAarE,EAAIzC,KAAK8G,aAAarE,EACrCL,EAAE0E,aAAapE,EAAI1C,KAAK8G,aAAapE,EACrCN,EAAE2E,SAAW/G,KAAK+G,SACkB,IAAhC/G,KAAKkM,yBAGL9J,EAAE8E,gBAAmBlF,KAAKoJ,UAAY,EAAIpL,KAAKkM,wBAA2BlM,KAAKkM,wBAEnF9J,EAAE6E,UAAUtB,MAAM3F,KAAKiM,YACvB7J,EAAE+E,UAAUxB,MAAM3F,KAAKmM,YAEnBnM,KAAKwM,mBAAqBxM,KAAKyM,iBAE/BrK,EAAEkE,cAAgBtG,KAAKwM,iBAKvBpK,EAAEkE,cAAiBtE,KAAKoJ,UAAYpL,KAAKyM,iBAAmBzM,KAAKwM,kBAAqBxM,KAAKwM,iBAE/FpK,EAAEmE,qBAAuBvG,KAAKuG,qBAC9BnE,EAAEmG,WAAavI,KAAKuI,WAEpBnG,EAAEoE,QAAU+I,EAEZnN,EAAEoN,UAAYxP,KAAK0M,kBAEnBtK,EAAErC,KAAOC,KAAK2M,WAEdvK,EAAEsE,UAAY1G,KAAK0G,UAEnB1G,KAAKkS,0BAA0B9P,GAE/BpC,KAAKkN,WAAW9K,EAAGyP,EAAUC,EAAUhR,GAEvCsB,EAAEwF,OAEE5H,KAAK8N,UAEL9N,KAAK6N,QAAQsE,WAAW/P,EAAG,GAI3BpC,KAAK6N,QAAQuE,SAAShQ,GAGtBpC,KAAKoO,sBAELpO,KAAKoO,qBAAqBnO,KAAOmC,EACjCA,EAAEuF,KAAO3H,KAAKoO,qBACdpO,KAAKoO,qBAAuBhM,GAI5BpC,KAAKoO,qBAAuBpO,KAAKmO,sBAAwB/L,IAE3DpC,KAAK+N,cAEP3L,EAAE0F,QAAQ9H,KAAKiO,cAIvBjO,KAAKiO,aAAejO,KAAK4M,YAajC,GATI5M,KAAK4N,cAEL5N,KAAK0N,gBAAgBjL,EAAIkP,EACzB3R,KAAK0N,gBAAgBhL,EAAIkP,EACzB5R,KAAK2N,iBAAkB,EACvB3N,KAAK4N,aAAc,IAIlB5N,KAAKgO,QAAUhO,KAAKmO,sBACzB,CACI,GAAInO,KAAK0O,kBACT,CACI,IAAM2D,EAAKrS,KAAK0O,kBAEhB1O,KAAK0O,kBAAoB,KACzB2D,IAEArS,KAAKyO,sBAELzO,KAAKiI,aAWPuD,EAAA9F,UAAAwM,0BAAV,SAAoC9P,KAY1BoJ,EAAA9F,UAAAkL,YAAV,SAAsBxO,EAAayP,EAAkBC,GAI7C9R,KAAKsM,mBAAqBtM,KAAKuM,iBAE/BnK,EAAEkG,SAAWtI,KAAKsM,iBAAmBtM,KAAKsI,SAK1ClG,EAAEkG,SAAYtG,KAAKoJ,UAAYpL,KAAKuM,iBAAmBvM,KAAKsM,kBAAqBtM,KAAKsM,iBAAmBtM,KAAKsI,SAGlHlG,EAAEiH,SAAS5G,EAAIoP,EACfzP,EAAEiH,SAAS3G,EAAIoP,GAUTtG,EAAA9F,UAAAwK,WAAV,SAAqB9N,EAAayP,EAAkBC,GAI5C9R,KAAKsM,mBAAqBtM,KAAKuM,iBAE/BnK,EAAEkG,SAAWtI,KAAKsM,iBAAmBtM,KAAKsI,SAK1ClG,EAAEkG,SAAYtG,KAAKoJ,UAAYpL,KAAKuM,iBAAmBvM,KAAKsM,kBAAqBtM,KAAKsM,iBAAmBtM,KAAKsI,SAGlHiD,EAAY9I,EAAKT,KAAKoJ,SAAWpL,KAAKmN,UAAUmF,MAAStS,KAAKmN,UAAU1K,EACxE8I,EAAY7I,EAAKV,KAAKoJ,SAAWpL,KAAKmN,UAAUoF,OAAUvS,KAAKmN,UAAUzK,EACnD,IAAlB1C,KAAKsI,UAELnI,EAAAA,cAAc+B,YAAYlC,KAAKsI,SAAUiD,GAE7CnJ,EAAEiH,SAAS5G,EAAIoP,EAAWtG,EAAY9I,EACtCL,EAAEiH,SAAS3G,EAAIoP,EAAWvG,EAAY7I,GAUhC8I,EAAA9F,UAAA4K,aAAV,SAAuBlO,EAAayP,EAAkBC,GAI9C9R,KAAKsM,mBAAqBtM,KAAKuM,iBAE/BnK,EAAEkG,SAAWtI,KAAKsM,iBAAmBtM,KAAKsI,SAK1ClG,EAAEkG,SAAYtG,KAAKoJ,UAAYpL,KAAKuM,iBAAmBvM,KAAKsM,kBAAqBtM,KAAKsM,iBAAmBtM,KAAKsI,SAGlHiD,EAAY9I,EAAIT,KAAKoJ,SAAWpL,KAAKoN,YAAYoF,OACjDjH,EAAY7I,EAAI,EAEhBvC,EAAAA,cAAc+B,YAA4B,IAAhBF,KAAKoJ,SAAgBG,GAE/CA,EAAY9I,GAAKzC,KAAKoN,YAAY3K,EAClC8I,EAAY7I,GAAK1C,KAAKoN,YAAY1K,EAEZ,IAAlB1C,KAAKsI,UAELnI,EAAAA,cAAc+B,YAAYlC,KAAKsI,SAAUiD,GAG7CnJ,EAAEiH,SAAS5G,EAAIoP,EAAWtG,EAAY9I,EACtCL,EAAEiH,SAAS3G,EAAIoP,EAAWvG,EAAY7I,GAUhC8I,EAAA9F,UAAA8K,WAAV,SAAqBpO,EAAayP,EAAkBC,GAEhD,IAAM1E,EAAcpN,KAAKoN,YAIrBpN,KAAKsM,mBAAqBtM,KAAKuM,iBAE/BnK,EAAEkG,SAAWtI,KAAKsM,iBAAmBtM,KAAKsI,SAI1ClG,EAAEkG,SAAYtG,KAAKoJ,UAAYpL,KAAKuM,iBAAmBvM,KAAKsM,kBAClEtM,KAAKsM,iBAAmBtM,KAAKsI,SAGvB8E,EAAYqD,YAAcrD,EAAYoF,OAEtCjH,EAAY9I,EAAKT,KAAKoJ,UAAYgC,EAAYoF,OAASpF,EAAYqD,WACzErD,EAAYqD,UAINlF,EAAY9I,EAAI2K,EAAYoF,OAEhCjH,EAAY7I,EAAI,EAEhB,IAAMP,EAAwB,IAAhBH,KAAKoJ,SAEnBhJ,EAAEkG,UAAYnG,EACdhC,EAAAA,cAAc+B,YAAYC,EAAOoJ,GAEjCA,EAAY9I,GAAKzC,KAAKoN,YAAY3K,EAClC8I,EAAY7I,GAAK1C,KAAKoN,YAAY1K,EAEZ,IAAlB1C,KAAKsI,UAELnI,EAAAA,cAAc+B,YAAYlC,KAAKsI,SAAUiD,GAG7CnJ,EAAEiH,SAAS5G,EAAIoP,EAAWtG,EAAY9I,EACtCL,EAAEiH,SAAS3G,EAAIoP,EAAWvG,EAAY7I,GAUhC8I,EAAA9F,UAAAmL,qBAAV,SAA+BzO,EAAayP,EAAkBC,GAItD9R,KAAKsM,mBAAqBtM,KAAKuM,iBAE/BnK,EAAEkG,SAAWtI,KAAKsM,iBAAmBtM,KAAKsI,SAI1ClG,EAAEkG,SAAYtG,KAAKoJ,UAAYpL,KAAKuM,iBAAmBvM,KAAKsM,kBAClEtM,KAAKsM,iBAAmBtM,KAAKsI,SAG3BtI,KAAKqN,oBAAoBrC,eAAeO,GAElB,IAAlBvL,KAAKsI,UAELnI,EAAAA,cAAc+B,YAAYlC,KAAKsI,SAAUiD,GAG7CnJ,EAAEiH,SAAS5G,EAAIoP,EAAWtG,EAAY9I,EACtCL,EAAEiH,SAAS3G,EAAIoP,EAAWvG,EAAY7I,GAUhC8I,EAAA9F,UAAAiL,YAAV,SAAsBvO,EAAayP,EAAkBC,EAAkBhR,GAItC,IAAzBd,KAAKuN,gBAELnL,EAAEkG,SAA2B,IAAhBtG,KAAKoJ,SAIlBhJ,EAAEkG,SAAWtI,KAAKwN,WAAcxN,KAAKuN,gBAAkBzM,EAAKd,KAAKsI,SAGrElG,EAAEiH,SAAS5G,EAAIoP,EACfzP,EAAEiH,SAAS3G,EAAIoP,GAMZtG,EAAA9F,UAAAsJ,QAAP,WAEI,IAAIC,EACAhP,EAEJ,IAAKgP,EAAWjP,KAAKmO,sBAAuBc,EAAUA,EAAWhP,EAE7DA,EAAOgP,EAAShP,KAChBD,KAAKwJ,QAAQyF,GACTA,EAASxF,QAETwF,EAASxF,OAAOC,YAAYuF,GAGpCjP,KAAKmO,sBAAwBnO,KAAKoO,qBAAuB,KACzDpO,KAAK+N,cAAgB,GAMlBvC,EAAA9F,UAAAuC,QAAP,WAOI,IAAIhI,EAJJD,KAAKgQ,YAAa,EAElBhQ,KAAKgP,UAIL,IAAK,IAAIC,EAAWjP,KAAKqO,WAAYY,EAAUA,EAAWhP,EAGtDA,EAAOgP,EAAShP,KAChBgP,EAAShH,UAEbjI,KAAKqO,WAAarO,KAAK6N,QAAU7N,KAAK0L,eAAiB1L,KAAKgN,SAAWhN,KAAKyN,SACtEzN,KAAKmM,WAAanM,KAAKiM,WAAajM,KAAK8L,WAAa9L,KAAK+L,WAC3D/L,KAAK2M,WAAa3M,KAAK0O,kBAAoB,MAEzDlD,KG5yCMD,EAAc,IAAIlF,EAAAA,MAOlBoM,EAAa,CACf,MACA,OACA,MACA,QACA,QACA,OACA,IACA,KACA,MACA,MACA,MACA,OACA,OACA,OACA,QACA,OAMEC,EAAc,IAAIC,OACpB,CAGI,yCACFC,OAAOH,GAAYI,KAAK,KAC1B,uBAoEA,SAAAC,EAAYjN,GAAZ,IAAAC,EAEIC,EAAAC,KAAAhG,KAAM6F,IAAQ7F,YACd8F,EAAKiN,KAAO,KACZjN,EAAKkN,gBAAkB,EACvBlN,EAAKmN,gBAAkB,IAAI5M,EAAAA,MAC3BP,EAAKoN,SAAW,IAuHxB,OApJkC7K,EAAAyK,EAAA/M,GAoCvB+M,EAAApN,UAAAkC,KAAP,WAGI5H,KAAKgT,gBAAkBhT,KAAKsI,SAE5BtI,KAAK6H,gBAGL7H,KAAK+S,KAAO/S,KAAK0G,UAAUqM,KAE3B/S,KAAKyH,mBAAqBzH,KAAK+S,KAE/B/S,KAAKkT,SAAW,EAEhBlT,KAAKiT,gBAAgBxQ,EAAIzC,KAAKqJ,SAAS5G,EACvCzC,KAAKiT,gBAAgBvQ,EAAI1C,KAAKqJ,SAAS3G,GAOpCoQ,EAAApN,UAAAoC,OAAP,SAAcgB,GAEV,IAAMjE,EAAO7E,KAAK+H,gBAAgBe,GAGlC,GAAIjE,GAAQ,GAAK7E,KAAK+S,KACtB,CAEI,GAAI/S,KAAKsH,SACT,CACI,IAAM2B,EAAQjJ,KAAK4G,UAAUnB,YAAYZ,GAAQ7E,KAAK6G,gBAEtD7G,KAAKkT,UAAYjK,EAAQH,MAG7B,CACUG,EAAQjJ,KAAK4G,UAAUjC,QAAQ9E,MAAQG,KAAK6G,gBAElD7G,KAAKkT,UAAYjK,EAAQH,EAG7ByC,EAAY9I,EAAIzC,KAAKkT,SACrB3H,EAAY7I,EAAI1C,KAAK+S,KAAK/S,KAAKkT,UAC/B/S,EAAAA,cAAc+B,YAAYlC,KAAKgT,gBAAiBzH,GAChDvL,KAAKqJ,SAAS5G,EAAIzC,KAAKiT,gBAAgBxQ,EAAI8I,EAAY9I,EACvDzC,KAAKqJ,SAAS3G,EAAI1C,KAAKiT,gBAAgBvQ,EAAI6I,EAAY7I,EAG3D,OAAOmC,GAMJiO,EAAApN,UAAAuC,QAAP,WAEIjI,KAAKkI,mBACLlI,KAAK+S,KAAO/S,KAAKiT,gBAAkB,MAWzBH,EAAAnJ,SAAd,SAAuBhB,GAEnB,OAAO/C,EAAS+D,SAAShB,IAUfmK,EAAA9I,UAAd,SAAwBtD,GAEpB,IAAMpD,EAAc,GAEpB,GAAIoD,GAAaA,EAAUqM,KAEvB,IAEIzP,EAAOyP,KAhKvB,SAAmBI,GAIf,IAFA,IAAMC,EAAUD,EAAWE,MAAMX,GAExB5R,EAAIsS,EAAQvS,OAAS,EAAGC,GAAK,IAAKA,EAEnC2R,EAAW/O,QAAQ0P,EAAQtS,KAAO,IACpCsS,EAAQtS,GAAK,QAAQsS,EAAQtS,IAKnC,OAHAqS,EAAaC,EAAQP,KAAK,IAGnB,IAAIS,SAAS,IAAK,UAAUH,EAAU,KAoJnBI,CAAU7M,EAAUqM,MAEtC,MAAO9O,GAEC9D,EAAAA,cAAc2B,SAEdgI,QAAQ0J,MAAM,kDAElBlQ,EAAOyP,KAAO,UAKd5S,EAAAA,cAAc2B,SAEdgI,QAAQ0J,MAAM,qDAElBlQ,EAAOyP,KAAO,KAGlB,OAAOzP,GAEfwP,GApJkClN,iBCR9B,SAAA6N,EAAY5N,GAAZ,IAAAC,EAEIC,EAAAC,KAAAhG,KAAM6F,IAAQ7F,YAEd8F,EAAK4N,SAAW,KAChB5N,EAAK6N,SAAW,EAChB7N,EAAK8N,UAAY,EACjB9N,EAAK+N,QAAU,EACf/N,EAAKgO,MAAO,IAmJpB,OAzLsCzL,EAAAoL,EAAA1N,GA6C3B0N,EAAA/N,UAAAkC,KAAP,WAEI5H,KAAK6H,gBAEL7H,KAAK6T,QAAU,EAGX7T,KAAK4T,UAAY,IAEjB5T,KAAK2T,SAAW3T,KAAKwG,QACrBxG,KAAK4T,UAAY5T,KAAK0T,SAAS7S,OAASb,KAAK2T,WAQ9CF,EAAA/N,UAAAyC,SAAP,SAAgBQ,GAEZ3I,KAAK0T,SAAW/K,EAAI+K,SACpB1T,KAAK4T,UAAYjL,EAAIiL,UACrB5T,KAAK2T,SAAWhL,EAAIgL,SACpB3T,KAAK8T,KAAOnL,EAAImL,MAObL,EAAA/N,UAAAoC,OAAP,SAAcgB,GAEV,IAAMjE,EAAO7E,KAAK+H,gBAAgBe,GAGlC,GAAIjE,GAAQ,EACZ,CACI7E,KAAK6T,SAAW/K,EACZ9I,KAAK6T,QAAU7T,KAAK2T,WAGhB3T,KAAK8T,KAEL9T,KAAK6T,QAAU7T,KAAK6T,QAAU7T,KAAK2T,SAKnC3T,KAAK6T,QAAU7T,KAAK2T,SAAW,MAKvC,IAAMI,EAAU/T,KAAK6T,QAAU7T,KAAK4T,UAAa,KAAa,EAE9D5T,KAAK4I,QAAU5I,KAAK0T,SAASK,IAAUpS,EAAAA,QAAQkH,MAGnD,OAAOhE,GAMJ4O,EAAA/N,UAAAuC,QAAP,WAEIjI,KAAKkI,mBACLlI,KAAK0T,SAAW,MASND,EAAA9J,SAAd,SAAuBhB,GAInB,IAFA,IAAMqL,EAAsC,GAEnClT,EAAI,EAAGA,EAAI6H,EAAI9H,SAAUC,EAClC,CAMI,IALA,IAAMR,EAAOqI,EAAI7H,GACXwC,EAAS0Q,EAAOlT,GAAK,GACrBmT,EAAc3Q,EAAOoQ,SAAW,GAChCA,EAAWpT,EAAKoT,SAEbjJ,EAAI,EAAGA,EAAIiJ,EAAS7S,SAAU4J,EACvC,CACI,IAAIyJ,EAAMR,EAASjJ,GAEnB,GAAmB,iBAARyJ,EAEPD,EAAYtJ,KAAKrJ,EAAqB4S,SAErC,GAAIA,aAAevS,EAAAA,QAEpBsS,EAAYtJ,KAAKuJ,OAIrB,CACI,IAAIC,EAAOD,EAAIE,OAAS,EAUxB,IANIF,EAFuB,iBAAhBA,EAAItL,QAELtH,EAAqB4S,EAAItL,SAIzBsL,EAAItL,QAEPuL,EAAO,IAAKA,EAEfF,EAAYtJ,KAAKuJ,IAMN,cAAnB5T,EAAKsT,WAGLtQ,EAAOsQ,WAAa,EACpBtQ,EAAOqQ,SAAW,EAClBrQ,EAAOwQ,MAAO,IAKdxQ,EAAOwQ,OAASxT,EAAKwT,KAErBxQ,EAAOsQ,UAAYtT,EAAKsT,UAAY,EAAItT,EAAKsT,UAAY,GAEzDtQ,EAAOqQ,SAAWM,EAAYpT,OAASyC,EAAOsQ,WAItD,OAAOI,GAEfP,GAzLsC7N,iBCnCtC,SAAAyO,IAAA,IAAAvO,EAAA,OAAAC,GAAAA,EAAAuO,MAAAtU,KAAAuU,YAAAvU,YAEY8F,EAAA0O,YAAoC,KACpC1O,EAAA2O,WAAmC,KACnC3O,EAAA4O,YAAc,IAw4B1B,OA54ByCrM,EAAAgM,EAAAtO,GAMrC+I,OAAAC,eAAWsF,EAAA3O,UAAA,aAAU,KAArB,WAEI,OAAO1F,KAAKwU,6CAGhB1F,OAAAC,eAAWsF,EAAA3O,UAAA,YAAS,KAApB,WAEI,OAAO1F,KAAKyU,4CAGhB3F,OAAAC,eAAWsF,EAAA3O,UAAA,aAAU,KAArB,WAEI,OAAO1F,KAAK0U,6CAGTL,EAAA3O,UAAA0M,SAAP,eAA2C,IAAAuC,EAAA,GAAAC,EAAA,EAAAA,EAAAL,UAAA1T,OAAA+T,IAAAD,EAAAC,GAAAL,UAAAK,GAGvC,GAAID,EAAS9T,OAAS,EAGlB,IAAK,IAAIC,EAAI,EAAGA,EAAI6T,EAAS9T,OAAQC,IAGjCd,KAAKoS,SAASuC,EAAS7T,QAI/B,CACI,IAAM+T,EAAQF,EAAS,GAGnBE,EAAMpL,QAENoL,EAAMpL,OAAOC,YAAYmL,GAG5BA,EAAcpL,OAASzJ,KACxBA,KAAK8U,WAAY,EAGhBD,EAAME,UAAkBC,WAAa,EAGlChV,KAAKyU,YAELzU,KAAKyU,WAAWvO,UAAY2O,EAC5BA,EAAM5O,UAAYjG,KAAKyU,WACvBzU,KAAKyU,WAAaI,GAKlB7U,KAAKwU,YAAcxU,KAAKyU,WAAaI,IAIvC7U,KAAK0U,YAGN1U,KAAaiV,YAGdjV,KAAKkV,mBACLlV,KAAK8P,KAAK,aAAc+E,EAAO7U,KAAMA,KAAK0U,aAC1CG,EAAM/E,KAAK,QAAS9P,MAGxB,OAAO2U,EAAS,IAGbN,EAAA3O,UAAAyM,WAAP,SAA2C0C,EAAUM,GAEjD,GAAIA,EAAQ,GAAKA,EAAQnV,KAAK0U,YAE1B,MAAM,IAAIU,MAAM,yBAAyBD,EAAK,8BAA8BnV,KAAK0U,aAGjFG,EAAMpL,QAENoL,EAAMpL,OAAOC,YAAYmL,GAG5BA,EAAcpL,OAASzJ,KACxBA,KAAK8U,WAAY,EAGhBD,EAAME,UAAkBC,WAAa,EAEtC,IAAM1S,EAAKuS,EAGX,GAAK7U,KAAKwU,YAKL,GAAc,IAAVW,EAELnV,KAAKwU,YAAYvO,UAAY3D,EAC7BA,EAAE4D,UAAYlG,KAAKwU,YACnBxU,KAAKwU,YAAclS,OAGlB,GAAI6S,IAAUnV,KAAK0U,YAEpB1U,KAAKyU,WAAWvO,UAAY5D,EAC5BA,EAAE2D,UAAYjG,KAAKyU,WACnBzU,KAAKyU,WAAanS,MAKtB,CAII,IAHA,IAAIxB,EAAI,EACJuU,EAASrV,KAAKwU,YAEX1T,EAAIqU,GAEPE,EAASA,EAAOnP,YACdpF,EAGNuU,EAAOpP,UAAUC,UAAY5D,EAC7BA,EAAE2D,UAAYoP,EAAOpP,UACrB3D,EAAE4D,UAAYmP,EACdA,EAAOpP,UAAY3D,OAhCnBtC,KAAKwU,YAAcxU,KAAKyU,WAAanS,EA8CzC,QAVEtC,KAAK0U,YAGN1U,KAAaiV,YAGbjV,KAAakV,iBAAiBC,GAC/BN,EAAM/E,KAAK,QAAS9P,MACpBA,KAAK8P,KAAK,aAAc+E,EAAO7U,KAAMmV,GAE9BN,GAUJR,EAAA3O,UAAA4P,cAAP,SAA8CT,EAAUU,GAEpD,GAAIA,EAAS9L,SAAWzJ,KAEpB,MAAM,IAAIoV,MAAM,qEAmCpB,OAhCIP,EAAMpL,QAENoL,EAAMpL,OAAOC,YAAYmL,GAG5BA,EAAcpL,OAASzJ,KACxBA,KAAK8U,WAAY,EAGhBD,EAAME,UAAkBC,WAAa,EAGrCO,EAA6BtP,UAAUC,UAAa2O,EACpDA,EAAiC5O,UAAasP,EAA6BtP,UAC3E4O,EAAiC3O,UAAaqP,EAC9CA,EAA6BtP,UAAa4O,EACvC7U,KAAKwU,cAAgBe,IAErBvV,KAAKwU,YAAeK,KAItB7U,KAAK0U,YAGN1U,KAAaiV,YAGdjV,KAAKkV,mBACLlV,KAAK8P,KAAK,aAAc+E,EAAO7U,KAAMA,KAAK0U,aAC1CG,EAAM/E,KAAK,QAAS9P,MAEb6U,GAUJR,EAAA3O,UAAA8P,cAAP,SAA8CX,EAAUU,GAEpD,GAAIA,EAAS9L,SAAWzJ,KAEpB,MAAM,IAAIoV,MAAM,qEAmCpB,OAhCIP,EAAMpL,QAENoL,EAAMpL,OAAOC,YAAYmL,GAG5BA,EAAcpL,OAASzJ,KACxBA,KAAK8U,WAAY,EAGhBD,EAAME,UAAkBC,WAAa,EAGrCO,EAA6BrP,UAAUD,UAAa4O,EACpDA,EAAiC3O,UAAaqP,EAA6BrP,UAC3E2O,EAAiC5O,UAAasP,EAC9CA,EAA6BrP,UAAa2O,EACvC7U,KAAKyU,aAAec,IAEpBvV,KAAKyU,WAAcI,KAIrB7U,KAAK0U,YAGN1U,KAAaiV,YAGdjV,KAAKkV,mBACLlV,KAAK8P,KAAK,aAAc+E,EAAO7U,KAAMA,KAAK0U,aAC1CG,EAAM/E,KAAK,QAAS9P,MAEb6U,GAGJR,EAAA3O,UAAA+P,aAAP,SAAoBZ,EAAsBa,GAEtC,GAAIb,IAAUa,GAAUb,EAAMpL,SAAWzJ,MAAQ0V,EAAOjM,SAAWzJ,KAAnE,CAKM,IAAAU,EAAAmU,EAAE5O,EAAAvF,EAAAuF,UAAWC,EAAAxF,EAAAwF,UAElB2O,EAA0B5O,UAAayP,EAA2BzP,UAClE4O,EAA0B3O,UAAawP,EAA2BxP,UAClEwP,EAA2BzP,UAAYA,EACvCyP,EAA2BxP,UAAYA,EAEpClG,KAAKwU,cAAgBK,EAErB7U,KAAKwU,YAAckB,EAEd1V,KAAKwU,cAAgBkB,IAE1B1V,KAAKwU,YAAcK,GAEnB7U,KAAKyU,aAAeI,EAEpB7U,KAAKyU,WAAaiB,EAEb1V,KAAKyU,aAAeiB,IAEzB1V,KAAKyU,WAAaI,GAGtB7U,KAAKkV,qBAGFb,EAAA3O,UAAAiQ,cAAP,SAAqBd,GAKjB,IAHA,IAAIM,EAAQ,EACRS,EAAO5V,KAAKwU,YAEToB,GAECA,IAASf,GAIbe,EAAOA,EAAK1P,YACViP,EAEN,IAAKS,EAED,MAAM,IAAIR,MAAM,4DAGpB,OAAOD,GAGXd,EAAA3O,UAAAmQ,cAAA,SAAchB,EAAsBM,GAEhC,GAAIA,EAAQ,GAAKA,GAASnV,KAAK0U,YAE3B,MAAM,IAAIU,MAAM,aAAaD,EAAK,8BAA8BnV,KAAK0U,aAEzE,GAAIG,EAAMpL,SAAWzJ,KAEjB,MAAM,IAAIoV,MAAM,4DAwBpB,GApBKP,EAA0B3O,YAE1B2O,EAA0B3O,UAAUD,UAAa4O,EAA0B5O,WAE3E4O,EAA0B5O,YAE1B4O,EAA0B5O,UAAUC,UAAa2O,EAA0B3O,WAE5ElG,KAAKwU,cAAiBK,IAEtB7U,KAAKwU,YAAeK,EAA0B3O,WAE9ClG,KAAKyU,aAAgBI,IAErB7U,KAAKyU,WAAcI,EAA0B5O,WAEhD4O,EAA0B3O,UAAY,KACtC2O,EAA0B5O,UAAY,KAGlCjG,KAAKwU,YAIL,GAAc,IAAVW,EAELnV,KAAKwU,YAAYvO,UAAa4O,EAC7BA,EAA0B3O,UAAYlG,KAAKwU,YAC5CxU,KAAKwU,YAAeK,OAEnB,GAAIM,IAAUnV,KAAK0U,YAEpB1U,KAAKyU,WAAWvO,UAAa2O,EAC5BA,EAA0B5O,UAAYjG,KAAKyU,WAC5CzU,KAAKyU,WAAcI,MAGvB,CAII,IAHA,IAAI/T,EAAI,EACJuU,EAASrV,KAAKwU,YAEX1T,EAAIqU,GAEPE,EAASA,EAAOnP,YACdpF,EAENuU,EAAOpP,UAAUC,UAAa2O,EAC7BA,EAA0B5O,UAAYoP,EAAOpP,UAC7C4O,EAA0B3O,UAAYmP,EACvCA,EAAOpP,UAAa4O,OA3BpB7U,KAAKwU,YAAcxU,KAAKyU,WAAcI,EA8BzC7U,KAAakV,iBAAiBC,IAG5Bd,EAAA3O,UAAAgE,YAAP,eAA8C,IAAAiL,EAAA,GAAAC,EAAA,EAAAA,EAAAL,UAAA1T,OAAA+T,IAAAD,EAAAC,GAAAL,UAAAK,GAG1C,GAAID,EAAS9T,OAAS,EAGlB,IAAK,IAAIC,EAAI,EAAGA,EAAI6T,EAAS9T,OAAQC,IAEjCd,KAAK0J,YAAYiL,EAAS7T,QAIlC,CACI,IAAM+T,EAAQF,EAAS,GAGvB,GAAKE,EAAcpL,SAAWzJ,KAAM,OAAO,KAE1C6U,EAAcpL,OAAS,KAEvBoL,EAAME,UAAkBC,WAAa,EAGlCH,EAAM3O,YAEN2O,EAAM3O,UAAUD,UAAY4O,EAAM5O,WAElC4O,EAAM5O,YAEN4O,EAAM5O,UAAUC,UAAY2O,EAAM3O,WAElClG,KAAKwU,cAAgBK,IAErB7U,KAAKwU,YAAcK,EAAM3O,WAEzBlG,KAAKyU,aAAeI,IAEpB7U,KAAKyU,WAAaI,EAAM5O,WAG5B4O,EAAM3O,UAAY,KAClB2O,EAAM5O,UAAY,OAGhBjG,KAAK0U,YAGN1U,KAAaiV,YAGdjV,KAAKkV,mBACLL,EAAM/E,KAAK,UAAW9P,MACtBA,KAAK8P,KAAK,eAAgB+E,EAAO7U,MAGrC,OAAO2U,EAAS,IAGbN,EAAA3O,UAAAoQ,WAAP,SAAkBX,GAEd,GAAIA,EAAQ,GAAKA,GAASnV,KAAK0U,YAE3B,MAAM,IAAIU,MAAM,sBAAsBD,EAAK,qBAG/C,GAAc,IAAVA,EAEA,OAAOnV,KAAKwU,YAGX,GAAIW,IAAUnV,KAAK0U,YAEpB,OAAO1U,KAAKyU,WAOhB,IAHA,IAAI3T,EAAI,EACJuU,EAASrV,KAAKwU,YAEX1T,EAAIqU,GAEPE,EAASA,EAAOnP,YACdpF,EAGN,OAAOuU,GAGJhB,EAAA3O,UAAAqQ,cAAP,SAAqBZ,GAEjB,IAAMN,EAAQ7U,KAAK8V,WAAWX,GAqC9B,OAlCCN,EAAcpL,OAAS,KACvBoL,EAAME,UAAkBC,WAAa,EAElCH,EAAM3O,YAEN2O,EAAM3O,UAAUD,UAAY4O,EAAM5O,WAElC4O,EAAM5O,YAEN4O,EAAM5O,UAAUC,UAAY2O,EAAM3O,WAElClG,KAAKwU,cAAgBK,IAErB7U,KAAKwU,YAAcK,EAAM3O,WAEzBlG,KAAKyU,aAAeI,IAEpB7U,KAAKyU,WAAaI,EAAM5O,WAG5B4O,EAAM3O,UAAY,KAClB2O,EAAM5O,UAAY,OAGhBjG,KAAK0U,YAGN1U,KAAaiV,YAGbjV,KAAakV,iBAAiBC,GAC/BN,EAAM/E,KAAK,UAAW9P,MACtBA,KAAK8P,KAAK,eAAgB+E,EAAO7U,KAAMmV,GAEhCN,GAGJR,EAAA3O,UAAAsQ,eAAP,SAAsBC,EAAgBC,QAAhB,IAAAD,IAAAA,EAAA,QAAgB,IAAAC,IAAAA,EAAWlW,KAAK0U,aAElD,IAAMyB,EAAQF,EACR9U,EAAM+U,EACNE,EAAQjV,EAAMgV,EAEpB,GAAIC,EAAQ,GAAKA,GAASjV,EAC1B,CAII,IAHA,IAAMkV,EAA6B,GAC/BxB,EAAQ7U,KAAKwU,YAER1T,EAAI,EAAGA,GAAKK,GAAO0T,IAAS/T,EAAG+T,EAAQA,EAAM3O,UAE9CpF,GAAKqV,GAELE,EAAQ1L,KAAKkK,GAKrB,IAAM5O,EAAYoQ,EAAQ,GAAGpQ,UAEvBC,EAAYmQ,EAAQA,EAAQxV,OAAS,GAAGqF,UAEzCA,EASDA,EAAUD,UAAYA,EALtBjG,KAAKyU,WAAaxO,EAOjBA,EASDA,EAAUC,UAAYA,EALtBlG,KAAKwU,YAActO,EAQvB,IAASpF,EAAI,EAAGA,EAAIuV,EAAQxV,SAAUC,EAGjCuV,EAAQvV,GAAW2I,OAAS,KACzB4M,EAAQvV,GAAGiU,YAEVsB,EAAQvV,GAAGiU,UAAkBC,WAAa,GAE/CqB,EAAQvV,GAAGoF,UAAY,KACvBmQ,EAAQvV,GAAGmF,UAAY,KAG1BjG,KAAaiV,YAEbjV,KAAakV,iBAAiBe,GAE/B,IAASnV,EAAI,EAAGA,EAAIuV,EAAQxV,SAAUC,EAElCuV,EAAQvV,GAAGgP,KAAK,UAAW9P,MAC3BA,KAAK8P,KAAK,eAAgBuG,EAAQvV,GAAId,KAAMc,GAGhD,OAAOuV,EAEN,GAAc,IAAVD,GAAoC,IAArBpW,KAAK0U,YAEzB,MAAO,GAGX,MAAM,IAAI4B,WAAW,qEAOzBjC,EAAA3O,UAAA6Q,gBAAA,WASI,IAAI1B,EACA5U,EAEJ,IAVCD,KAAaiV,YAEdjV,KAAK+U,UAAUwB,gBAAgBvW,KAAKyJ,OAAOsL,WAG1C/U,KAAawW,WAAaxW,KAAKuD,MAAQvD,KAAKyJ,OAAO+M,WAK/C3B,EAAQ7U,KAAKwU,YAAaK,EAAOA,EAAQ5U,EAE1CA,EAAO4U,EAAM3O,UAET2O,EAAMnM,SAENmM,EAAM0B,mBASlBlC,EAAA3O,UAAA+Q,gBAAA,WAMI,IAAI5B,EACA5U,EAEJ,IAPAD,KAAK0W,QAAQC,QAEb3W,KAAK4W,mBAKA/B,EAAQ7U,KAAKwU,YAAaK,EAAOA,EAAQ5U,EAI1C,GAFAA,EAAO4U,EAAM3O,UAER2O,EAAMnM,SAAYmM,EAAMgC,WAQ7B,GAHAhC,EAAM4B,kBAGD5B,EAAciC,MACnB,CACI,IAAMC,EAAgBlC,EAAciC,MAAmBC,YAAelC,EAAciC,MAEpFC,EAAWN,kBACXzW,KAAK0W,QAAQM,cAAenC,EAAc6B,QAAUK,EAAmBL,cAElE7B,EAAMoC,WAEXjX,KAAK0W,QAAQQ,cAAerC,EAAc6B,QAAS7B,EAAMoC,YAIzDjX,KAAK0W,QAAQS,UAAWtC,EAAc6B,SAI7C1W,KAAK0W,QAAgBU,SAAYpX,KAAaiV,WAM5CZ,EAAA3O,UAAA2R,eAAP,SAAsBC,EAAkBC,QAAA,IAAAA,IAAAA,GAAA,GAGpC,IAAMC,EAASC,EAAAA,cAAc/R,UAAU2R,eAAerR,KAAKhG,KAAMsX,GAEjE,IAAKC,EACL,CACI,IAAI1C,OAAK,EACL5U,OAAI,EAER,IAAK4U,EAAQ7U,KAAKwU,YAAaK,EAAOA,EAAQ5U,EAE1CA,EAAO4U,EAAM3O,UAET2O,EAAMnM,SAENmM,EAAM0B,kBAKlB,OAAOiB,GAMXnD,EAAA3O,UAAAgS,OAAA,SAAOC,GAGH,GAAK3X,KAAK0I,WAAW1I,KAAKwW,YAAc,IAAMxW,KAAK6W,WAMnD,GAAI7W,KAAK8W,OAAU9W,KAAK4X,SAAW5X,KAAK4X,QAAQ/W,OAE5Cb,KAAK6X,eAAeF,OAGxB,CACI3X,KAAK8X,QAAQH,GAEb,IAAI9C,OAAK,EACL5U,OAAI,EAGR,IAAK4U,EAAQ7U,KAAKwU,YAAaK,EAAOA,EAAQ5U,EAE1CA,EAAO4U,EAAM3O,UACb2O,EAAM6C,OAAOC,KAQftD,EAAA3O,UAAAmS,eAAV,SAAyBF,GAErBA,EAASI,MAAMC,QAEf,IAsCInD,EACA5U,EAvCE2X,EAAU5X,KAAK4X,QACfK,EAAOjY,KAAK8W,MAMlB,GAAIc,EACJ,CACU5X,KAAakY,kBAEdlY,KAAakY,gBAAkB,IAGnClY,KAAakY,gBAAgBrX,OAAS,EAEvC,IAAK,IAAIC,EAAI,EAAGA,EAAI8W,EAAQ/W,OAAQC,IAE5B8W,EAAQ9W,GAAGqX,SAEVnY,KAAakY,gBAAgBvN,KAAKiN,EAAQ9W,IAI9Cd,KAAakY,gBAAgBrX,QAE9B8W,EAASS,OAAOzN,KAAK3K,KAAOA,KAAakY,iBAgBjD,IAZID,GAEAN,EAASM,KAAKtN,KAAK3K,KAAMA,KAAK8W,OAIlC9W,KAAK8X,QAAQH,GAMR9C,EAAQ7U,KAAKwU,YAAaK,EAAOA,EAAQ5U,EAE1CA,EAAO4U,EAAM3O,UACb2O,EAAM6C,OAAOC,GAGjBA,EAASI,MAAMC,QAEXC,GAEAN,EAASM,KAAKI,IAAIrY,MAGlB4X,GAAY5X,KAAakY,iBAAoBlY,KAAakY,gBAAgBrX,QAE1E8W,EAASS,OAAOC,OAOxBhE,EAAA3O,UAAA4S,YAAA,SAAYX,GAGR,GAAK3X,KAAK0I,WAAW1I,KAAKwW,YAAc,IAAMxW,KAAK6W,WAMnD,GAAI7W,KAAK8W,OAAU9W,KAAK4X,SAAW5X,KAAK4X,QAAQ/W,OAE5Cb,KAAKuY,oBAAoBZ,OAG7B,CACK3X,KAAawY,aAAab,GAE3B,IAAI9C,OAAK,EACL5U,OAAI,EAGR,IAAK4U,EAAQ7U,KAAKwU,YAAaK,EAAOA,EAAQ5U,EAE1CA,EAAO4U,EAAM3O,UACZ2O,EAAcyD,YAAYX,KAQ/BtD,EAAA3O,UAAA6S,oBAAR,SAA4BZ,GAExBA,EAASK,QAGT,IAmCInD,EACA5U,EApCE2X,EAAW5X,KAAayY,SACxBR,EAAOjY,KAAK8W,MAGlB,GAAIc,EACJ,CACU5X,KAAakY,kBAEdlY,KAAakY,gBAAkB,IAGnClY,KAAakY,gBAAgBrX,OAAS,EAEvC,IAAK,IAAIC,EAAI,EAAGA,EAAI8W,EAAQ/W,OAAQC,IAE5B8W,EAAQ9W,GAAGqX,SAEVnY,KAAakY,gBAAgBvN,KAAKiN,EAAQ9W,IAI9Cd,KAAakY,gBAAgBrX,QAE9B8W,EAASe,cAAcC,WAAW3Y,KAAOA,KAAakY,iBAgB9D,IAZID,GAEAN,EAASiB,YAAYC,SAAS7Y,KAAMA,KAAK8W,OAI5C9W,KAAawY,aAAab,GAMtB9C,EAAQ7U,KAAKwU,YAAaK,EAAOA,EAAQ5U,EAE1CA,EAAO4U,EAAM3O,UACZ2O,EAAcyD,YAAYX,GAG/BA,EAASK,QAELC,GAEAN,EAASiB,YAAYE,QAAQ9Y,KAAMA,KAAK8W,OAGxCc,GAAY5X,KAAakY,iBAAoBlY,KAAakY,gBAAgBrX,QAE1E8W,EAASe,cAAcK,aAO/B1E,EAAA3O,UAAAsT,aAAA,SAAarB,GAGT,GAAK3X,KAAK0I,WAAW1I,KAAKwW,YAAc,IAAMxW,KAAK6W,WAAnD,CAYA,IAAIhC,EACA5U,EAEJ,IAVID,KAAK8W,OAELa,EAASiB,YAAYC,SAAS7Y,KAAK8W,OAGtC9W,KAAaiZ,cAActB,GAKvB9C,EAAQ7U,KAAKwU,YAAaK,EAAOA,EAAQ5U,EAE1CA,EAAO4U,EAAM3O,UACZ2O,EAAcmE,aAAarB,GAG5B3X,KAAK8W,OAELa,EAASiB,YAAYE,QAAQnB,KAGzCtD,GA54ByC6E,EAAAA","file":"dist/pixi-particles.min.js.map","sourcesContent":["import { BLEND_MODES, Point, Texture } from 'pixi.js';\nimport { PropertyNode, ValueStep } from './PropertyNode';\n// eslint-disable-next-line no-duplicate-imports\nimport * as pixi from 'pixi.js';\n// get Texture.from()/Texture.fromImage(), in V4 and V5 friendly methods\n/**\n * @hidden\n */\nlet TextureFromString: (s: string) => pixi.Texture;\n// to avoid Rollup transforming our import, save pixi namespace in a variable\nconst pixiNS = pixi;\n\nif (parseInt((/^(\\d+)\\./).exec(pixi.VERSION)[1], 10) < 5)\n{\n TextureFromString = (pixiNS.Texture as any).fromImage;\n}\nelse\n{\n TextureFromString = pixiNS.Texture.from;\n}\n\nexport function GetTextureFromString(s: string): Texture\n{\n return TextureFromString(s);\n}\n\nexport interface Color {\n r: number;\n g: number;\n b: number;\n a?: number;\n}\n\nexport interface EaseSegment {\n cp: number;\n s: number;\n e: number;\n}\n\nexport type SimpleEase = (time: number) => number;\n\n/**\n * Contains helper functions for particles and emitters to use.\n */\nexport namespace ParticleUtils {\n /**\n * If errors and warnings should be logged within the library.\n */\n export const verbose = false;\n\n export const DEG_TO_RADS = Math.PI / 180;\n\n /**\n * Rotates a point by a given angle.\n * @param angle The angle to rotate by in degrees\n * @param p The point to rotate around 0,0.\n */\n export function rotatePoint(angle: number, p: Point): void\n {\n if (!angle) return;\n angle *= ParticleUtils.DEG_TO_RADS;\n const s = Math.sin(angle);\n const c = Math.cos(angle);\n const xnew = (p.x * c) - (p.y * s);\n const ynew = (p.x * s) + (p.y * c);\n\n p.x = xnew;\n p.y = ynew;\n }\n\n /**\n * Combines separate color components (0-255) into a single uint color.\n * @param r The red value of the color\n * @param g The green value of the color\n * @param b The blue value of the color\n * @return The color in the form of 0xRRGGBB\n */\n export function combineRGBComponents(r: number, g: number, b: number/* , a*/): number\n {\n return /* a << 24 |*/ (r << 16) | (g << 8) | b;\n }\n\n /**\n * Reduces the point to a length of 1.\n * @param point The point to normalize\n */\n export function normalize(point: Point): void\n {\n const oneOverLen = 1 / ParticleUtils.length(point);\n\n point.x *= oneOverLen;\n point.y *= oneOverLen;\n }\n\n /**\n * Multiplies the x and y values of this point by a value.\n * @param point The point to scaleBy\n * @param value The value to scale by.\n */\n export function scaleBy(point: Point, value: number): void\n {\n point.x *= value;\n point.y *= value;\n }\n\n /**\n * Returns the length (or magnitude) of this point.\n * @param point The point to measure length\n * @return The length of this point.\n */\n export function length(point: Point): number\n {\n return Math.sqrt((point.x * point.x) + (point.y * point.y));\n }\n\n /**\n * Converts a hex string from \"#AARRGGBB\", \"#RRGGBB\", \"0xAARRGGBB\", \"0xRRGGBB\",\n * \"AARRGGBB\", or \"RRGGBB\" to an object of ints of 0-255, as\n * {r, g, b, (a)}.\n * @param color The input color string.\n * @param output An object to put the output in. If omitted, a new object is created.\n * @return The object with r, g, and b properties, possibly with an a property.\n */\n export function hexToRGB(color: string, output?: Color): Color\n {\n if (!output)\n {\n output = {} as Color;\n }\n if (color.charAt(0) === '#')\n {\n color = color.substr(1);\n }\n else if (color.indexOf('0x') === 0)\n {\n color = color.substr(2);\n }\n let alpha;\n\n if (color.length === 8)\n {\n alpha = color.substr(0, 2);\n color = color.substr(2);\n }\n output.r = parseInt(color.substr(0, 2), 16);// Red\n output.g = parseInt(color.substr(2, 2), 16);// Green\n output.b = parseInt(color.substr(4, 2), 16);// Blue\n if (alpha)\n {\n output.a = parseInt(alpha, 16);\n }\n\n return output;\n }\n\n /**\n * Generates a custom ease function, based on the GreenSock custom ease, as demonstrated\n * by the related tool at http://www.greensock.com/customease/.\n * @param segments An array of segments, as created by\n * http://www.greensock.com/customease/.\n * @return A function that calculates the percentage of change at\n * a given point in time (0-1 inclusive).\n */\n export function generateEase(segments: EaseSegment[]): SimpleEase\n {\n const qty = segments.length;\n const oneOverQty = 1 / qty;\n /*\n * Calculates the percentage of change at a given point in time (0-1 inclusive).\n * @param {Number} time The time of the ease, 0-1 inclusive.\n * @return {Number} The percentage of the change, 0-1 inclusive (unless your\n * ease goes outside those bounds).\n */\n\n // eslint-disable-next-line func-names\n return function (time: number): number\n {\n const i = (qty * time) | 0;// do a quick floor operation\n\n const t = (time - (i * oneOverQty)) * qty;\n const s = segments[i] || segments[qty - 1];\n\n return (s.s + (t * ((2 * (1 - t) * (s.cp - s.s)) + (t * (s.e - s.s)))));\n };\n }\n\n /**\n * Gets a blend mode, ensuring that it is valid.\n * @param name The name of the blend mode to get.\n * @return The blend mode as specified in the PIXI.BLEND_MODES enumeration.\n */\n export function getBlendMode(name: string): number\n {\n if (!name) return BLEND_MODES.NORMAL;\n name = name.toUpperCase();\n while (name.indexOf(' ') >= 0)\n {\n name = name.replace(' ', '_');\n }\n\n return (BLEND_MODES as any)[name] || BLEND_MODES.NORMAL;\n }\n\n /**\n * Converts a list of {value, time} objects starting at time 0 and ending at time 1 into an evenly\n * spaced stepped list of PropertyNodes for color values. This is primarily to handle conversion of\n * linear gradients to fewer colors, allowing for some optimization for Canvas2d fallbacks.\n * @param list The list of data to convert.\n * @param [numSteps=10] The number of steps to use.\n * @return The blend mode as specified in the PIXI.blendModes enumeration.\n */\n export function createSteppedGradient(list: ValueStep[], numSteps = 10): PropertyNode\n {\n if (typeof numSteps !== 'number' || numSteps <= 0)\n {\n numSteps = 10;\n }\n const first = new PropertyNode(ParticleUtils.hexToRGB(list[0].value), list[0].time);\n\n first.isStepped = true;\n let currentNode = first;\n let current = list[0];\n let nextIndex = 1;\n let next = list[nextIndex];\n\n for (let i = 1; i < numSteps; ++i)\n {\n let lerp = i / numSteps;\n // ensure we are on the right segment, if multiple\n\n while (lerp > next.time)\n {\n current = next;\n next = list[++nextIndex];\n }\n // convert the lerp value to the segment range\n lerp = (lerp - current.time) / (next.time - current.time);\n const curVal = ParticleUtils.hexToRGB(current.value);\n const nextVal = ParticleUtils.hexToRGB(next.value);\n const output: Color = {\n r: ((nextVal.r - curVal.r) * lerp) + curVal.r,\n g: ((nextVal.g - curVal.g) * lerp) + curVal.g,\n b: ((nextVal.b - curVal.b) * lerp) + curVal.b,\n };\n\n currentNode.next = new PropertyNode(output, i / numSteps);\n currentNode = currentNode.next;\n }\n\n // we don't need to have a PropertyNode for time of 1, because in a stepped version at that point\n // the particle has died of old age\n return first;\n }\n}\n","import { ParticleUtils, EaseSegment, SimpleEase, Color } from './ParticleUtils';\nimport { BasicTweenable } from './EmitterConfig';\n\nexport interface ValueStep {\n value: T;\n time: number;\n}\n\nexport interface ValueList {\n list: ValueStep[];\n isStepped?: boolean;\n ease?: SimpleEase|EaseSegment[];\n}\n/**\n * A single node in a PropertyList.\n */\nexport class PropertyNode\n{\n /**\n * Value for the node.\n */\n public value: V;\n /**\n * Time value for the node. Between 0-1.\n */\n public time: number;\n /**\n * The next node in line.\n */\n public next: PropertyNode;\n /**\n * If this is the first node in the list, controls if the entire list is stepped or not.\n */\n public isStepped: boolean;\n public ease: SimpleEase;\n\n /**\n * @param value The value for this node\n * @param time The time for this node, between 0-1\n * @param [ease] Custom ease for this list. Only relevant for the first node.\n */\n constructor(value: V, time: number, ease?: SimpleEase|EaseSegment[])\n {\n this.value = value;\n this.time = time;\n this.next = null;\n this.isStepped = false;\n if (ease)\n {\n this.ease = typeof ease === 'function' ? ease : ParticleUtils.generateEase(ease);\n }\n else\n {\n this.ease = null;\n }\n }\n\n /**\n * Creates a list of property values from a data object {list, isStepped} with a list of objects in\n * the form {value, time}. Alternatively, the data object can be in the deprecated form of\n * {start, end}.\n * @param data The data for the list.\n * @param data.list The array of value and time objects.\n * @param data.isStepped If the list is stepped rather than interpolated.\n * @param data.ease Custom ease for this list.\n * @return The first node in the list\n */\n // eslint-disable-next-line max-len\n public static createList(data: ValueList|BasicTweenable): PropertyNode\n {\n if ('list' in data)\n {\n const array = data.list;\n let node;\n const { value, time } = array[0];\n\n // eslint-disable-next-line max-len\n const first = node = new PropertyNode(typeof value === 'string' ? ParticleUtils.hexToRGB(value) : value, time, data.ease);\n\n // only set up subsequent nodes if there are a bunch or the 2nd one is different from the first\n if (array.length > 2 || (array.length === 2 && array[1].value !== value))\n {\n for (let i = 1; i < array.length; ++i)\n {\n const { value, time } = array[i];\n\n node.next = new PropertyNode(typeof value === 'string' ? ParticleUtils.hexToRGB(value) : value, time);\n node = node.next;\n }\n }\n first.isStepped = !!data.isStepped;\n\n return first as PropertyNode;\n }\n\n // Handle deprecated version here\n const start = new PropertyNode(typeof data.start === 'string' ? ParticleUtils.hexToRGB(data.start) : data.start, 0);\n // only set up a next value if it is different from the starting value\n\n if (data.end !== data.start)\n {\n start.next = new PropertyNode(typeof data.end === 'string' ? ParticleUtils.hexToRGB(data.end) : data.end, 1);\n }\n\n return start as PropertyNode;\n }\n}\n","import { ParticleUtils, SimpleEase, Color } from './ParticleUtils';\nimport { PropertyNode } from './PropertyNode';\n\nfunction intValueSimple(this: PropertyList, lerp: number): number\n{\n if (this.ease)\n { lerp = this.ease(lerp); }\n\n return ((this.next.value - this.current.value) * lerp) + this.current.value;\n}\n\nfunction intColorSimple(this: PropertyList, lerp: number): number\n{\n if (this.ease)\n { lerp = this.ease(lerp); }\n const curVal = this.current.value; const\n nextVal = this.next.value;\n const r = ((nextVal.r - curVal.r) * lerp) + curVal.r;\n const g = ((nextVal.g - curVal.g) * lerp) + curVal.g;\n const b = ((nextVal.b - curVal.b) * lerp) + curVal.b;\n\n return ParticleUtils.combineRGBComponents(r, g, b);\n}\n\nfunction intValueComplex(this: PropertyList, lerp: number): number\n{\n if (this.ease)\n { lerp = this.ease(lerp); }\n // make sure we are on the right segment\n while (lerp > this.next.time)\n {\n this.current = this.next;\n this.next = this.next.next;\n }\n // convert the lerp value to the segment range\n lerp = (lerp - this.current.time) / (this.next.time - this.current.time);\n\n return ((this.next.value - this.current.value) * lerp) + this.current.value;\n}\n\nfunction intColorComplex(this: PropertyList, lerp: number): number\n{\n if (this.ease)\n { lerp = this.ease(lerp); }\n // make sure we are on the right segment\n while (lerp > this.next.time)\n {\n this.current = this.next;\n this.next = this.next.next;\n }\n // convert the lerp value to the segment range\n lerp = (lerp - this.current.time) / (this.next.time - this.current.time);\n const curVal = this.current.value; const\n nextVal = this.next.value;\n const r = ((nextVal.r - curVal.r) * lerp) + curVal.r;\n const g = ((nextVal.g - curVal.g) * lerp) + curVal.g;\n const b = ((nextVal.b - curVal.b) * lerp) + curVal.b;\n\n return ParticleUtils.combineRGBComponents(r, g, b);\n}\n\nfunction intValueStepped(this: PropertyList, lerp: number): number\n{\n if (this.ease)\n { lerp = this.ease(lerp); }\n // make sure we are on the right segment\n while (this.next && lerp > this.next.time)\n {\n this.current = this.next;\n this.next = this.next.next;\n }\n\n return this.current.value;\n}\n\nfunction intColorStepped(this: PropertyList, lerp: number): number\n{\n if (this.ease)\n { lerp = this.ease(lerp); }\n // make sure we are on the right segment\n while (this.next && lerp > this.next.time)\n {\n this.current = this.next;\n this.next = this.next.next;\n }\n const curVal = this.current.value;\n\n return ParticleUtils.combineRGBComponents(curVal.r, curVal.g, curVal.b);\n}\n\n/**\n * Singly linked list container for keeping track of interpolated properties for particles.\n * Each Particle will have one of these for each interpolated property.\n */\nexport class PropertyList\n{\n /**\n * The current property node in the linked list.\n */\n public current: PropertyNode;\n /**\n * The next property node in the linked list. Stored separately for slightly less variable\n * access.\n */\n public next: PropertyNode;\n /**\n * Calculates the correct value for the current interpolation value. This method is set in\n * the reset() method.\n * @param lerp The interpolation value from 0-1.\n * @return The interpolated value. Colors are converted to the hex value.\n */\n public interpolate: (lerp: number) => number;\n /**\n * A custom easing method for this list.\n * @param lerp The interpolation value from 0-1.\n * @return The eased value, also from 0-1.\n */\n public ease: SimpleEase;\n /**\n * If this list manages colors, which requires a different method for interpolation.\n */\n private isColor: boolean;\n\n /**\n * @param isColor If this list handles color values\n */\n constructor(isColor = false)\n {\n this.current = null;\n this.next = null;\n this.isColor = !!isColor;\n this.interpolate = null;\n this.ease = null;\n }\n\n /**\n * Resets the list for use.\n * @param first The first node in the list.\n * @param first.isStepped If the values should be stepped instead of interpolated linearly.\n */\n public reset(first: PropertyNode): void\n {\n this.current = first;\n this.next = first.next;\n const isSimple = this.next && this.next.time >= 1;\n\n if (isSimple)\n {\n this.interpolate = this.isColor ? intColorSimple : intValueSimple;\n }\n else if (first.isStepped)\n {\n this.interpolate = this.isColor ? intColorStepped : intValueStepped;\n }\n else\n {\n this.interpolate = this.isColor ? intColorComplex : intValueComplex;\n }\n this.ease = this.current.ease;\n }\n}\n","import { ParticleUtils, Color, SimpleEase } from './ParticleUtils';\nimport { Particle } from './Particle';\nimport { PropertyNode } from './PropertyNode';\nimport { PolygonalChain } from './PolygonalChain';\nimport { EmitterConfig, OldEmitterConfig } from './EmitterConfig';\nimport { Point, Circle, Rectangle, Container, settings } from 'pixi.js';\n// eslint-disable-next-line no-duplicate-imports\nimport * as pixi from 'pixi.js';\n// get the shared ticker, in V4 and V5 friendly methods\n/**\n * @hidden\n */\nlet ticker: pixi.Ticker;\n// to avoid Rollup transforming our import, save pixi namespace in a variable\nconst pixiNS = pixi;\n\nif (parseInt((/^(\\d+)\\./).exec(pixi.VERSION)[1], 10) < 5)\n{\n ticker = (pixiNS as any).ticker.shared;\n}\nelse\n{\n ticker = pixiNS.Ticker.shared;\n}\n\nexport interface ParticleConstructor\n{\n new (emitter: Emitter): Particle;\n}\n\n/**\n * @hidden\n */\nconst helperPoint = new Point();\n\n/**\n * A particle emitter.\n */\nexport class Emitter\n{\n /**\n * The constructor used to create new particles. The default is\n * the built in particle class.\n */\n protected _particleConstructor: typeof Particle;\n // properties for individual particles\n /**\n * An array of PIXI Texture objects.\n */\n public particleImages: any[];\n /**\n * The first node in the list of alpha values for all particles.\n */\n public startAlpha: PropertyNode;\n /**\n * The first node in the list of speed values of all particles.\n */\n public startSpeed: PropertyNode;\n /**\n * A minimum multiplier for the speed of a particle at all stages of its life. A value between\n * minimumSpeedMultiplier and 1 is randomly generated for each particle.\n */\n public minimumSpeedMultiplier: number;\n /**\n * Acceleration to apply to particles. Using this disables\n * any interpolation of particle speed. If the particles do\n * not have a rotation speed, then they will be rotated to\n * match the direction of travel.\n */\n public acceleration: Point;\n /**\n * The maximum speed allowed for accelerating particles. Negative values, values of 0 or NaN\n * will disable the maximum speed.\n */\n public maxSpeed: number;\n /**\n * The first node in the list of scale values of all particles.\n */\n public startScale: PropertyNode;\n /**\n * A minimum multiplier for the scale of a particle at all stages of its life. A value between\n * minimumScaleMultiplier and 1 is randomly generated for each particle.\n */\n public minimumScaleMultiplier: number;\n /**\n * The first node in the list of color values of all particles, as red, green, and blue\n * uints from 0-255.\n */\n public startColor: PropertyNode;\n /**\n * The minimum lifetime for a particle, in seconds.\n */\n public minLifetime: number;\n /**\n * The maximum lifetime for a particle, in seconds.\n */\n public maxLifetime: number;\n /**\n * The minimum start rotation for a particle, in degrees. This value\n * is ignored if the spawn type is \"burst\" or \"arc\".\n */\n public minStartRotation: number;\n /**\n * The maximum start rotation for a particle, in degrees. This value\n * is ignored if the spawn type is \"burst\" or \"arc\".\n */\n public maxStartRotation: number;\n /**\n * If no particle rotation should occur. Starting rotation will still\n * affect the direction in which particles move. If the rotation speed\n * is set, then this will be ignored.\n */\n public noRotation: boolean;\n /**\n * The minimum rotation speed for a particle, in degrees per second.\n * This only visually spins the particle, it does not change direction\n * of movement.\n */\n public minRotationSpeed: number;\n /**\n * The maximum rotation speed for a particle, in degrees per second.\n * This only visually spins the particle, it does not change direction\n * of movement.\n */\n public maxRotationSpeed: number;\n /**\n * The Acceleration of rotation (angular acceleration) for a particle, in degrees per second.\n */\n public rotationAcceleration: number;\n /**\n * The blend mode for all particles, as named by PIXI.blendModes.\n */\n public particleBlendMode: number;\n /**\n * An easing function for nonlinear interpolation of values. Accepts a single\n * parameter of time as a value from 0-1, inclusive. Expected outputs are values\n * from 0-1, inclusive.\n */\n public customEase: SimpleEase;\n /**\n *\tExtra data for use in custom particles. The emitter doesn't look inside, but\n *\tpasses it on to the particle to use in init().\n */\n public extraData: any;\n // properties for spawning particles\n /**\n * Time between particle spawns in seconds.\n */\n protected _frequency: number;\n /**\n * Chance that a particle will be spawned on each opportunity to spawn one.\n * 0 is 0%, 1 is 100%.\n */\n public spawnChance: number;\n /**\n * Maximum number of particles to keep alive at a time. If this limit\n * is reached, no more particles will spawn until some have died.\n */\n public maxParticles: number;\n /**\n * The amount of time in seconds to emit for before setting emit to false.\n * A value of -1 is an unlimited amount of time.\n */\n public emitterLifetime: number;\n /**\n * Position at which to spawn particles, relative to the emitter's owner's origin.\n * For example, the flames of a rocket travelling right might have a spawnPos\n * of {x:-50, y:0}.\n * to spawn at the rear of the rocket.\n * To change this, use updateSpawnPos().\n */\n public spawnPos: Point;\n /**\n * How the particles will be spawned. Valid types are \"point\", \"rectangle\",\n * \"circle\", \"burst\", \"ring\".\n */\n public spawnType: string;\n /**\n * A reference to the emitter function specific to the spawn type.\n */\n protected _spawnFunc: (p: Particle, emitPosX: number, emitPosY: number, i?: number) => void;\n /**\n * A rectangle relative to spawnPos to spawn particles inside if the spawn type is \"rect\".\n */\n public spawnRect: Rectangle;\n /**\n * A polygon relative to spawnPos to spawn particles on the chain if the spawn type is \"polygonalChain\".\n */\n public spawnPolygonalChain: PolygonalChain;\n /**\n * A circle relative to spawnPos to spawn particles inside if the spawn type is \"circle\".\n */\n public spawnCircle: Circle & {minRadius: number};\n /**\n * Number of particles to spawn time that the frequency allows for particles to spawn.\n */\n public particlesPerWave: number;\n /**\n * Spacing between particles in a burst. 0 gives a random angle for each particle.\n */\n public particleSpacing: number;\n /**\n * Angle at which to start spawning particles in a burst.\n */\n public angleStart: number;\n /**\n * Rotation of the emitter or emitter's owner in degrees. This is added to\n * the calculated spawn angle.\n * To change this, use rotate().\n */\n protected rotation: number;\n /**\n * The world position of the emitter's owner, to add spawnPos to when\n * spawning particles. To change this, use updateOwnerPos().\n */\n protected ownerPos: Point;\n /**\n * The origin + spawnPos in the previous update, so that the spawn position\n * can be interpolated to space out particles better.\n */\n protected _prevEmitterPos: Point;\n /**\n * If _prevEmitterPos is valid, to prevent interpolation on the first update\n */\n protected _prevPosIsValid: boolean;\n /**\n * If either ownerPos or spawnPos has changed since the previous update.\n */\n protected _posChanged: boolean;\n /**\n * The container to add particles to.\n */\n protected _parent: Container;\n /**\n * If particles should be added at the back of the display list instead of the front.\n */\n public addAtBack: boolean;\n /**\n * The current number of active particles.\n */\n public particleCount: number;\n /**\n * If particles should be emitted during update() calls. Setting this to false\n * stops new particles from being created, but allows existing ones to die out.\n */\n protected _emit: boolean;\n /**\n * The timer for when to spawn particles in seconds, where numbers less\n * than 0 mean that particles should be spawned.\n */\n protected _spawnTimer: number;\n /**\n * The life of the emitter in seconds.\n */\n protected _emitterLife: number;\n /**\n * The particles that are active and on the display list. This is the first particle in a\n * linked list.\n */\n protected _activeParticlesFirst: Particle;\n /**\n * The particles that are active and on the display list. This is the last particle in a\n * linked list.\n */\n protected _activeParticlesLast: Particle;\n /**\n * The particles that are not currently being used. This is the first particle in a\n * linked list.\n */\n protected _poolFirst: Particle;\n /**\n * The original config object that this emitter was initialized with.\n */\n protected _origConfig: any;\n /**\n * The original particle image data that this emitter was initialized with.\n */\n protected _origArt: any;\n /**\n * If the update function is called automatically from the shared ticker.\n * Setting this to false requires calling the update function manually.\n */\n protected _autoUpdate: boolean;\n /**\n * A number keeping index of currently applied image. Used to emit arts in order.\n */\n protected _currentImageIndex = -1;\n /**\n * If the emitter should destroy itself when all particles have died out. This is set by\n * playOnceAndDestroy();\n */\n protected _destroyWhenComplete: boolean;\n /**\n * A callback for when all particles have died out. This is set by\n * playOnceAndDestroy() or playOnce();\n */\n protected _completeCallback: () => void;\n\n /**\n * @param particleParent The container to add the particles to.\n * @param particleImages A texture or array of textures to use\n * for the particles. Strings will be turned\n * into textures via Texture.fromImage().\n * @param config A configuration object containing settings for the emitter.\n * @param config.emit If config.emit is explicitly passed as false, the\n * Emitter will start disabled.\n * @param config.autoUpdate If config.autoUpdate is explicitly passed as\n * true, the Emitter will automatically call\n * update via the PIXI shared ticker.\n */\n constructor(particleParent: Container, particleImages: any, config: EmitterConfig|OldEmitterConfig)\n {\n this._particleConstructor = Particle;\n // properties for individual particles\n this.particleImages = null;\n this.startAlpha = null;\n this.startSpeed = null;\n this.minimumSpeedMultiplier = 1;\n this.acceleration = null;\n this.maxSpeed = NaN;\n this.startScale = null;\n this.minimumScaleMultiplier = 1;\n this.startColor = null;\n this.minLifetime = 0;\n this.maxLifetime = 0;\n this.minStartRotation = 0;\n this.maxStartRotation = 0;\n this.noRotation = false;\n this.minRotationSpeed = 0;\n this.maxRotationSpeed = 0;\n this.particleBlendMode = 0;\n this.customEase = null;\n this.extraData = null;\n // properties for spawning particles\n this._frequency = 1;\n this.spawnChance = 1;\n this.maxParticles = 1000;\n this.emitterLifetime = -1;\n this.spawnPos = null;\n this.spawnType = null;\n this._spawnFunc = null;\n this.spawnRect = null;\n this.spawnCircle = null;\n this.spawnPolygonalChain = null;\n this.particlesPerWave = 1;\n this.particleSpacing = 0;\n this.angleStart = 0;\n // emitter properties\n this.rotation = 0;\n this.ownerPos = null;\n this._prevEmitterPos = null;\n this._prevPosIsValid = false;\n this._posChanged = false;\n this._parent = null;\n this.addAtBack = false;\n this.particleCount = 0;\n this._emit = false;\n this._spawnTimer = 0;\n this._emitterLife = -1;\n this._activeParticlesFirst = null;\n this._activeParticlesLast = null;\n this._poolFirst = null;\n this._origConfig = null;\n this._origArt = null;\n this._autoUpdate = false;\n this._currentImageIndex = -1;\n this._destroyWhenComplete = false;\n this._completeCallback = null;\n\n // set the initial parent\n this.parent = particleParent;\n\n if (particleImages && config)\n {\n this.init(particleImages, config);\n }\n\n // save often used functions on the instance instead of the prototype for better speed\n this.recycle = this.recycle;\n this.update = this.update;\n this.rotate = this.rotate;\n this.updateSpawnPos = this.updateSpawnPos;\n this.updateOwnerPos = this.updateOwnerPos;\n }\n\n /**\n * If the emitter is using particle art in order as provided in `particleImages`.\n * Effective only when `particleImages` has multiple art options.\n * This is particularly useful ensuring that each art shows up once, in case you need to emit a body in an order.\n * For example: dragon - [Head, body1, body2, ..., tail]\n */\n public get orderedArt(): boolean { return this._currentImageIndex !== -1; }\n public set orderedArt(value)\n {\n this._currentImageIndex = value ? 0 : -1;\n }\n\n /**\n * Time between particle spawns in seconds. If this value is not a number greater than 0,\n * it will be set to 1 (particle per second) to prevent infinite loops.\n */\n public get frequency(): number { return this._frequency; }\n public set frequency(value)\n {\n // do some error checking to prevent infinite loops\n if (typeof value === 'number' && value > 0)\n {\n this._frequency = value;\n }\n else\n {\n this._frequency = 1;\n }\n }\n /**\n * The constructor used to create new particles. The default is\n * the built in Particle class. Setting this will dump any active or\n * pooled particles, if the emitter has already been used.\n */\n public get particleConstructor(): typeof Particle { return this._particleConstructor; }\n public set particleConstructor(value)\n {\n if (value !== this._particleConstructor)\n {\n this._particleConstructor = value;\n // clean up existing particles\n this.cleanup();\n // scrap all the particles\n for (let particle = this._poolFirst; particle; particle = particle.next)\n {\n particle.destroy();\n }\n this._poolFirst = null;\n // re-initialize the emitter so that the new constructor can do anything it needs to\n if (this._origConfig && this._origArt)\n {\n this.init(this._origArt, this._origConfig);\n }\n }\n }\n\n /**\n * The container to add particles to. Settings this will dump any active particles.\n */\n public get parent(): Container { return this._parent; }\n public set parent(value)\n {\n this.cleanup();\n this._parent = value;\n }\n\n /**\n * Sets up the emitter based on the config settings.\n * @param art A texture or array of textures to use for the particles.\n * @param config A configuration object containing settings for the emitter.\n */\n public init(art: any, config: EmitterConfig|OldEmitterConfig): void\n {\n if (!art || !config)\n {\n return;\n }\n // clean up any existing particles\n this.cleanup();\n\n // store the original config and particle images, in case we need to re-initialize\n // when the particle constructor is changed\n this._origConfig = config;\n this._origArt = art;\n\n // set up the array of data, also ensuring that it is an array\n art = Array.isArray(art) ? art.slice() : [art];\n // run the art through the particle class's parsing function\n const partClass = this._particleConstructor;\n\n this.particleImages = partClass.parseArt ? partClass.parseArt(art) : art;\n // /////////////////////////\n // Particle Properties //\n // /////////////////////////\n // set up the alpha\n if (config.alpha)\n {\n this.startAlpha = PropertyNode.createList(config.alpha);\n }\n else\n {\n this.startAlpha = new PropertyNode(1, 0);\n }\n // set up the speed\n if (config.speed)\n {\n this.startSpeed = PropertyNode.createList(config.speed);\n // eslint-disable-next-line max-len\n this.minimumSpeedMultiplier = ('minimumSpeedMultiplier' in config ? config.minimumSpeedMultiplier : (config.speed as any).minimumSpeedMultiplier) || 1;\n }\n else\n {\n this.minimumSpeedMultiplier = 1;\n this.startSpeed = new PropertyNode(0, 0);\n }\n // set up acceleration\n const acceleration = config.acceleration;\n\n if (acceleration && (acceleration.x || acceleration.y))\n {\n // make sure we disable speed interpolation\n this.startSpeed.next = null;\n this.acceleration = new Point(acceleration.x, acceleration.y);\n this.maxSpeed = config.maxSpeed || NaN;\n }\n else\n {\n this.acceleration = new Point();\n }\n // set up the scale\n if (config.scale)\n {\n this.startScale = PropertyNode.createList(config.scale);\n // eslint-disable-next-line max-len\n this.minimumScaleMultiplier = ('minimumScaleMultiplier' in config ? config.minimumScaleMultiplier : (config.scale as any).minimumScaleMultiplier) || 1;\n }\n else\n {\n this.startScale = new PropertyNode(1, 0);\n this.minimumScaleMultiplier = 1;\n }\n // set up the color\n if (config.color)\n {\n this.startColor = PropertyNode.createList(config.color);\n }\n else\n {\n this.startColor = new PropertyNode({ r: 0xFF, g: 0xFF, b: 0xFF }, 0);\n }\n // set up the start rotation\n if (config.startRotation)\n {\n this.minStartRotation = config.startRotation.min;\n this.maxStartRotation = config.startRotation.max;\n }\n else\n {\n this.minStartRotation = this.maxStartRotation = 0;\n }\n if (config.noRotation\n && (this.minStartRotation || this.maxStartRotation))\n {\n this.noRotation = !!config.noRotation;\n }\n else\n {\n this.noRotation = false;\n }\n // set up the rotation speed\n if (config.rotationSpeed)\n {\n this.minRotationSpeed = config.rotationSpeed.min;\n this.maxRotationSpeed = config.rotationSpeed.max;\n }\n else\n {\n this.minRotationSpeed = this.maxRotationSpeed = 0;\n }\n\n this.rotationAcceleration = config.rotationAcceleration || 0;\n // set up the lifetime\n this.minLifetime = config.lifetime.min;\n this.maxLifetime = config.lifetime.max;\n // get the blend mode\n this.particleBlendMode = ParticleUtils.getBlendMode(config.blendMode);\n // use the custom ease if provided\n if (config.ease)\n {\n this.customEase = typeof config.ease === 'function'\n ? config.ease : ParticleUtils.generateEase(config.ease);\n }\n else\n {\n this.customEase = null;\n }\n // set up the extra data, running it through the particle class's parseData function.\n if (partClass.parseData)\n {\n this.extraData = partClass.parseData(config.extraData);\n }\n else\n {\n this.extraData = config.extraData || null;\n }\n // ////////////////////////\n // Emitter Properties //\n // ////////////////////////\n // reset spawn type specific settings\n this.spawnRect = this.spawnCircle = null;\n this.particlesPerWave = 1;\n if (config.particlesPerWave && config.particlesPerWave > 1)\n {\n this.particlesPerWave = config.particlesPerWave;\n }\n this.particleSpacing = 0;\n this.angleStart = 0;\n // determine the spawn function to use\n this.parseSpawnType(config);\n // set the spawning frequency\n this.frequency = config.frequency;\n this.spawnChance = (typeof config.spawnChance === 'number' && config.spawnChance > 0) ? config.spawnChance : 1;\n // set the emitter lifetime\n this.emitterLifetime = config.emitterLifetime || -1;\n // set the max particles\n this.maxParticles = config.maxParticles > 0 ? config.maxParticles : 1000;\n // determine if we should add the particle at the back of the list or not\n this.addAtBack = !!config.addAtBack;\n // reset the emitter position and rotation variables\n this.rotation = 0;\n this.ownerPos = new Point();\n this.spawnPos = new Point(config.pos.x, config.pos.y);\n\n this.initAdditional(art, config);\n\n this._prevEmitterPos = this.spawnPos.clone();\n // previous emitter position is invalid and should not be used for interpolation\n this._prevPosIsValid = false;\n // start emitting\n this._spawnTimer = 0;\n this.emit = config.emit === undefined ? true : !!config.emit;\n this.autoUpdate = !!config.autoUpdate;\n this.orderedArt = !!config.orderedArt;\n }\n\n /**\n * Sets up additional parameters to the emitter from config settings.\n * Using for parsing additional parameters on classes that extend from Emitter\n * @param art A texture or array of textures to use for the particles.\n * @param config A configuration object containing settings for the emitter.\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected initAdditional(art: any, config: EmitterConfig|OldEmitterConfig): void\n {\n // override in subclasses\n }\n\n /**\n * Parsing emitter spawn type from config settings.\n * Place for override and add new kind of spawn type\n * @param config A configuration object containing settings for the emitter.\n */\n protected parseSpawnType(config: EmitterConfig|OldEmitterConfig): void\n {\n let spawnCircle;\n\n switch (config.spawnType)\n {\n case 'rect':\n this.spawnType = 'rect';\n this._spawnFunc = this._spawnRect;\n const spawnRect = config.spawnRect;\n\n this.spawnRect = new Rectangle(spawnRect.x, spawnRect.y, spawnRect.w, spawnRect.h);\n break;\n case 'circle':\n this.spawnType = 'circle';\n this._spawnFunc = this._spawnCircle;\n spawnCircle = config.spawnCircle;\n this.spawnCircle = new Circle(spawnCircle.x, spawnCircle.y, spawnCircle.r) as any;\n break;\n case 'ring':\n this.spawnType = 'ring';\n this._spawnFunc = this._spawnRing;\n spawnCircle = config.spawnCircle;\n this.spawnCircle = new Circle(spawnCircle.x, spawnCircle.y, spawnCircle.r) as any;\n this.spawnCircle.minRadius = spawnCircle.minR;\n break;\n case 'burst':\n this.spawnType = 'burst';\n this._spawnFunc = this._spawnBurst;\n this.particleSpacing = config.particleSpacing;\n this.angleStart = config.angleStart ? config.angleStart : 0;\n break;\n case 'point':\n this.spawnType = 'point';\n this._spawnFunc = this._spawnPoint;\n break;\n case 'polygonalChain':\n this.spawnType = 'polygonalChain';\n this._spawnFunc = this._spawnPolygonalChain;\n this.spawnPolygonalChain = new PolygonalChain(config.spawnPolygon);\n break;\n default:\n this.spawnType = 'point';\n this._spawnFunc = this._spawnPoint;\n break;\n }\n }\n\n /**\n * Recycles an individual particle. For internal use only.\n * @param particle The particle to recycle.\n * @internal\n */\n public recycle(particle: Particle): void\n {\n if (particle.next)\n {\n particle.next.prev = particle.prev;\n }\n if (particle.prev)\n {\n particle.prev.next = particle.next;\n }\n if (particle === this._activeParticlesLast)\n {\n this._activeParticlesLast = particle.prev;\n }\n if (particle === this._activeParticlesFirst)\n {\n this._activeParticlesFirst = particle.next;\n }\n // add to pool\n particle.prev = null;\n particle.next = this._poolFirst;\n this._poolFirst = particle;\n // remove child from display, or make it invisible if it is in a ParticleContainer\n if (particle.parent)\n {\n particle.parent.removeChild(particle);\n }\n // decrease count\n --this.particleCount;\n }\n\n /**\n * Sets the rotation of the emitter to a new value.\n * @param newRot The new rotation, in degrees.\n */\n public rotate(newRot: number): void\n {\n if (this.rotation === newRot) return;\n // caclulate the difference in rotation for rotating spawnPos\n const diff = newRot - this.rotation;\n\n this.rotation = newRot;\n // rotate spawnPos\n ParticleUtils.rotatePoint(diff, this.spawnPos);\n // mark the position as having changed\n this._posChanged = true;\n }\n\n /**\n * Changes the spawn position of the emitter.\n * @param x The new x value of the spawn position for the emitter.\n * @param y The new y value of the spawn position for the emitter.\n */\n public updateSpawnPos(x: number, y: number): void\n {\n this._posChanged = true;\n this.spawnPos.x = x;\n this.spawnPos.y = y;\n }\n\n /**\n * Changes the position of the emitter's owner. You should call this if you are adding\n * particles to the world container that your emitter's owner is moving around in.\n * @param x The new x value of the emitter's owner.\n * @param y The new y value of the emitter's owner.\n */\n public updateOwnerPos(x: number, y: number): void\n {\n this._posChanged = true;\n this.ownerPos.x = x;\n this.ownerPos.y = y;\n }\n\n /**\n * Prevents emitter position interpolation in the next update.\n * This should be used if you made a major position change of your emitter's owner\n * that was not normal movement.\n */\n public resetPositionTracking(): void\n {\n this._prevPosIsValid = false;\n }\n\n /**\n * If particles should be emitted during update() calls. Setting this to false\n * stops new particles from being created, but allows existing ones to die out.\n */\n public get emit(): boolean { return this._emit; }\n public set emit(value)\n {\n this._emit = !!value;\n this._emitterLife = this.emitterLifetime;\n }\n\n /**\n * If the update function is called automatically from the shared ticker.\n * Setting this to false requires calling the update function manually.\n */\n public get autoUpdate(): boolean { return this._autoUpdate; }\n public set autoUpdate(value)\n {\n if (this._autoUpdate && !value)\n {\n ticker.remove(this.update, this);\n }\n else if (!this._autoUpdate && value)\n {\n ticker.add(this.update, this);\n }\n this._autoUpdate = !!value;\n }\n\n /**\n * Starts emitting particles, sets autoUpdate to true, and sets up the Emitter to destroy itself\n * when particle emission is complete.\n * @param callback Callback for when emission is complete (all particles have died off)\n */\n public playOnceAndDestroy(callback?: () => void): void\n {\n this.autoUpdate = true;\n this.emit = true;\n this._destroyWhenComplete = true;\n this._completeCallback = callback;\n }\n\n /**\n * Starts emitting particles and optionally calls a callback when particle emission is complete.\n * @param callback Callback for when emission is complete (all particles have died off)\n */\n public playOnce(callback?: () => void): void\n {\n this.emit = true;\n this._completeCallback = callback;\n }\n\n /**\n * Updates all particles spawned by this emitter and emits new ones.\n * @param delta Time elapsed since the previous frame, in __seconds__.\n */\n public update(delta: number): void\n {\n if (this._autoUpdate)\n {\n delta = delta / settings.TARGET_FPMS / 1000;\n }\n\n // if we don't have a parent to add particles to, then don't do anything.\n // this also works as a isDestroyed check\n if (!this._parent) return;\n // update existing particles\n let i;\n let particle;\n let next;\n\n for (particle = this._activeParticlesFirst; particle; particle = next)\n {\n next = particle.next;\n particle.update(delta);\n }\n let prevX;\n let prevY;\n // if the previous position is valid, store these for later interpolation\n\n if (this._prevPosIsValid)\n {\n prevX = this._prevEmitterPos.x;\n prevY = this._prevEmitterPos.y;\n }\n // store current position of the emitter as local variables\n const curX = this.ownerPos.x + this.spawnPos.x;\n const curY = this.ownerPos.y + this.spawnPos.y;\n // spawn new particles\n\n if (this._emit)\n {\n // decrease spawn timer\n this._spawnTimer -= delta < 0 ? 0 : delta;\n // while _spawnTimer < 0, we have particles to spawn\n while (this._spawnTimer <= 0)\n {\n // determine if the emitter should stop spawning\n if (this._emitterLife >= 0)\n {\n this._emitterLife -= this._frequency;\n if (this._emitterLife <= 0)\n {\n this._spawnTimer = 0;\n this._emitterLife = 0;\n this.emit = false;\n break;\n }\n }\n // determine if we have hit the particle limit\n if (this.particleCount >= this.maxParticles)\n {\n this._spawnTimer += this._frequency;\n continue;\n }\n // determine the particle lifetime\n let lifetime;\n\n if (this.minLifetime === this.maxLifetime)\n {\n lifetime = this.minLifetime;\n }\n else\n {\n lifetime = (Math.random() * (this.maxLifetime - this.minLifetime)) + this.minLifetime;\n }\n // only make the particle if it wouldn't immediately destroy itself\n if (-this._spawnTimer < lifetime)\n {\n // If the position has changed and this isn't the first spawn,\n // interpolate the spawn position\n let emitPosX; let\n emitPosY;\n\n if (this._prevPosIsValid && this._posChanged)\n {\n // 1 - _spawnTimer / delta, but _spawnTimer is negative\n const lerp = 1 + (this._spawnTimer / delta);\n\n emitPosX = ((curX - prevX) * lerp) + prevX;\n emitPosY = ((curY - prevY) * lerp) + prevY;\n }\n else// otherwise just set to the spawn position\n {\n emitPosX = curX;\n emitPosY = curY;\n }\n // create enough particles to fill the wave (non-burst types have a wave of 1)\n i = 0;\n for (let len = Math.min(this.particlesPerWave, this.maxParticles - this.particleCount); i < len; ++i)\n {\n // see if we actually spawn one\n if (this.spawnChance < 1 && Math.random() >= this.spawnChance)\n {\n continue;\n }\n // create particle\n let p;\n\n if (this._poolFirst)\n {\n p = this._poolFirst;\n this._poolFirst = this._poolFirst.next;\n p.next = null;\n }\n else\n {\n p = new this.particleConstructor(this);\n }\n\n // set a random texture if we have more than one\n if (this.particleImages.length > 1)\n {\n // if using ordered art\n if (this._currentImageIndex !== -1)\n {\n // get current art index, then increment for the next particle\n p.applyArt(this.particleImages[this._currentImageIndex++]);\n // loop around if needed\n if (this._currentImageIndex < 0 || this._currentImageIndex >= this.particleImages.length)\n {\n this._currentImageIndex = 0;\n }\n }\n // otherwise grab a random one\n else\n {\n p.applyArt(this.particleImages[Math.floor(Math.random() * this.particleImages.length)]);\n }\n }\n else\n {\n // if they are actually the same texture, a standard particle\n // will quit early from the texture setting in setTexture().\n p.applyArt(this.particleImages[0]);\n }\n // set up the start and end values\n p.alphaList.reset(this.startAlpha);\n if (this.minimumSpeedMultiplier !== 1)\n {\n // eslint-disable-next-line max-len\n p.speedMultiplier = (Math.random() * (1 - this.minimumSpeedMultiplier)) + this.minimumSpeedMultiplier;\n }\n p.speedList.reset(this.startSpeed);\n p.acceleration.x = this.acceleration.x;\n p.acceleration.y = this.acceleration.y;\n p.maxSpeed = this.maxSpeed;\n if (this.minimumScaleMultiplier !== 1)\n {\n // eslint-disable-next-line max-len\n p.scaleMultiplier = (Math.random() * (1 - this.minimumScaleMultiplier)) + this.minimumScaleMultiplier;\n }\n p.scaleList.reset(this.startScale);\n p.colorList.reset(this.startColor);\n // randomize the rotation speed\n if (this.minRotationSpeed === this.maxRotationSpeed)\n {\n p.rotationSpeed = this.minRotationSpeed;\n }\n else\n {\n // eslint-disable-next-line max-len\n p.rotationSpeed = (Math.random() * (this.maxRotationSpeed - this.minRotationSpeed)) + this.minRotationSpeed;\n }\n p.rotationAcceleration = this.rotationAcceleration;\n p.noRotation = this.noRotation;\n // set up the lifetime\n p.maxLife = lifetime;\n // set the blend mode\n p.blendMode = this.particleBlendMode;\n // set the custom ease, if any\n p.ease = this.customEase;\n // set the extra data, if any\n p.extraData = this.extraData;\n // set additional properties to particle\n this.applyAdditionalProperties(p);\n // call the proper function to handle rotation and position of particle\n this._spawnFunc(p, emitPosX, emitPosY, i);\n // initialize particle\n p.init();\n // add the particle to the display list\n if (this.addAtBack)\n {\n this._parent.addChildAt(p, 0);\n }\n else\n {\n this._parent.addChild(p);\n }\n // add particle to list of active particles\n if (this._activeParticlesLast)\n {\n this._activeParticlesLast.next = p;\n p.prev = this._activeParticlesLast;\n this._activeParticlesLast = p;\n }\n else\n {\n this._activeParticlesLast = this._activeParticlesFirst = p;\n }\n ++this.particleCount;\n // update the particle by the time passed, so the particles are spread out properly\n p.update(-this._spawnTimer);// we want a positive delta, because a negative delta messes things up\n }\n }\n // increase timer and continue on to any other particles that need to be created\n this._spawnTimer += this._frequency;\n }\n }\n // if the position changed before this update, then keep track of that\n if (this._posChanged)\n {\n this._prevEmitterPos.x = curX;\n this._prevEmitterPos.y = curY;\n this._prevPosIsValid = true;\n this._posChanged = false;\n }\n\n // if we are all done and should destroy ourselves, take care of that\n if (!this._emit && !this._activeParticlesFirst)\n {\n if (this._completeCallback)\n {\n const cb = this._completeCallback;\n\n this._completeCallback = null;\n cb();\n }\n if (this._destroyWhenComplete)\n {\n this.destroy();\n }\n }\n }\n\n /**\n * Set additional properties to new particle.\n * Using on classes that extend from Emitter\n * @param p The particle\n */\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n protected applyAdditionalProperties(p: Particle): void\n {\n // for override in subclass\n }\n\n /**\n * Positions a particle for a point type emitter.\n * @param p The particle to position and rotate.\n * @param emitPosX The emitter's x position\n * @param emitPosY The emitter's y position\n * @param i The particle number in the current wave. Not used for this function.\n */\n protected _spawnPoint(p: Particle, emitPosX: number, emitPosY: number): void\n {\n // set the initial rotation/direction of the particle based on\n // starting particle angle and rotation of emitter\n if (this.minStartRotation === this.maxStartRotation)\n {\n p.rotation = this.minStartRotation + this.rotation;\n }\n else\n {\n // eslint-disable-next-line max-len\n p.rotation = (Math.random() * (this.maxStartRotation - this.minStartRotation)) + this.minStartRotation + this.rotation;\n }\n // drop the particle at the emitter's position\n p.position.x = emitPosX;\n p.position.y = emitPosY;\n }\n\n /**\n * Positions a particle for a rectangle type emitter.\n * @param p The particle to position and rotate.\n * @param emitPosX The emitter's x position\n * @param emitPosY The emitter's y position\n * @param i The particle number in the current wave. Not used for this function.\n */\n protected _spawnRect(p: Particle, emitPosX: number, emitPosY: number): void\n {\n // set the initial rotation/direction of the particle based on starting\n // particle angle and rotation of emitter\n if (this.minStartRotation === this.maxStartRotation)\n {\n p.rotation = this.minStartRotation + this.rotation;\n }\n else\n {\n // eslint-disable-next-line max-len\n p.rotation = (Math.random() * (this.maxStartRotation - this.minStartRotation)) + this.minStartRotation + this.rotation;\n }\n // place the particle at a random point in the rectangle\n helperPoint.x = (Math.random() * this.spawnRect.width) + this.spawnRect.x;\n helperPoint.y = (Math.random() * this.spawnRect.height) + this.spawnRect.y;\n if (this.rotation !== 0)\n {\n ParticleUtils.rotatePoint(this.rotation, helperPoint);\n }\n p.position.x = emitPosX + helperPoint.x;\n p.position.y = emitPosY + helperPoint.y;\n }\n\n /**\n * Positions a particle for a circle type emitter.\n * @param p The particle to position and rotate.\n * @param emitPosX The emitter's x position\n * @param emitPosY The emitter's y position\n * @param i The particle number in the current wave. Not used for this function.\n */\n protected _spawnCircle(p: Particle, emitPosX: number, emitPosY: number): void\n {\n // set the initial rotation/direction of the particle based on starting\n // particle angle and rotation of emitter\n if (this.minStartRotation === this.maxStartRotation)\n {\n p.rotation = this.minStartRotation + this.rotation;\n }\n else\n {\n // eslint-disable-next-line max-len\n p.rotation = (Math.random() * (this.maxStartRotation - this.minStartRotation)) + this.minStartRotation + this.rotation;\n }\n // place the particle at a random radius in the circle\n helperPoint.x = Math.random() * this.spawnCircle.radius;\n helperPoint.y = 0;\n // rotate the point to a random angle in the circle\n ParticleUtils.rotatePoint(Math.random() * 360, helperPoint);\n // offset by the circle's center\n helperPoint.x += this.spawnCircle.x;\n helperPoint.y += this.spawnCircle.y;\n // rotate the point by the emitter's rotation\n if (this.rotation !== 0)\n {\n ParticleUtils.rotatePoint(this.rotation, helperPoint);\n }\n // set the position, offset by the emitter's position\n p.position.x = emitPosX + helperPoint.x;\n p.position.y = emitPosY + helperPoint.y;\n }\n\n /**\n * Positions a particle for a ring type emitter.\n * @param p The particle to position and rotate.\n * @param emitPosX The emitter's x position\n * @param emitPosY The emitter's y position\n * @param i The particle number in the current wave. Not used for this function.\n */\n protected _spawnRing(p: Particle, emitPosX: number, emitPosY: number): void\n {\n const spawnCircle = this.spawnCircle;\n // set the initial rotation/direction of the particle based on starting\n // particle angle and rotation of emitter\n\n if (this.minStartRotation === this.maxStartRotation)\n {\n p.rotation = this.minStartRotation + this.rotation;\n }\n else\n {\n p.rotation = (Math.random() * (this.maxStartRotation - this.minStartRotation))\n + this.minStartRotation + this.rotation;\n }\n // place the particle at a random radius in the ring\n if (spawnCircle.minRadius !== spawnCircle.radius)\n {\n helperPoint.x = (Math.random() * (spawnCircle.radius - spawnCircle.minRadius))\n + spawnCircle.minRadius;\n }\n else\n {\n helperPoint.x = spawnCircle.radius;\n }\n helperPoint.y = 0;\n // rotate the point to a random angle in the circle\n const angle = Math.random() * 360;\n\n p.rotation += angle;\n ParticleUtils.rotatePoint(angle, helperPoint);\n // offset by the circle's center\n helperPoint.x += this.spawnCircle.x;\n helperPoint.y += this.spawnCircle.y;\n // rotate the point by the emitter's rotation\n if (this.rotation !== 0)\n {\n ParticleUtils.rotatePoint(this.rotation, helperPoint);\n }\n // set the position, offset by the emitter's position\n p.position.x = emitPosX + helperPoint.x;\n p.position.y = emitPosY + helperPoint.y;\n }\n\n /**\n * Positions a particle for polygonal chain.\n * @param p The particle to position and rotate.\n * @param emitPosX The emitter's x position\n * @param emitPosY The emitter's y position\n * @param i The particle number in the current wave. Not used for this function.\n */\n protected _spawnPolygonalChain(p: Particle, emitPosX: number, emitPosY: number): void\n {\n // set the initial rotation/direction of the particle based on starting\n // particle angle and rotation of emitter\n if (this.minStartRotation === this.maxStartRotation)\n {\n p.rotation = this.minStartRotation + this.rotation;\n }\n else\n {\n p.rotation = (Math.random() * (this.maxStartRotation - this.minStartRotation))\n + this.minStartRotation + this.rotation;\n }\n // get random point on the polygon chain\n this.spawnPolygonalChain.getRandomPoint(helperPoint);\n // rotate the point by the emitter's rotation\n if (this.rotation !== 0)\n {\n ParticleUtils.rotatePoint(this.rotation, helperPoint);\n }\n // set the position, offset by the emitter's position\n p.position.x = emitPosX + helperPoint.x;\n p.position.y = emitPosY + helperPoint.y;\n }\n\n /**\n * Positions a particle for a burst type emitter.\n * @param p The particle to position and rotate.\n * @param emitPosX The emitter's x position\n * @param emitPosY The emitter's y position\n * @param i The particle number in the current wave.\n */\n protected _spawnBurst(p: Particle, emitPosX: number, emitPosY: number, i: number): void\n {\n // set the initial rotation/direction of the particle based on spawn\n // angle and rotation of emitter\n if (this.particleSpacing === 0)\n {\n p.rotation = Math.random() * 360;\n }\n else\n {\n p.rotation = this.angleStart + (this.particleSpacing * i) + this.rotation;\n }\n // drop the particle at the emitter's position\n p.position.x = emitPosX;\n p.position.y = emitPosY;\n }\n\n /**\n * Kills all active particles immediately.\n */\n public cleanup(): void\n {\n let particle;\n let next;\n\n for (particle = this._activeParticlesFirst; particle; particle = next)\n {\n next = particle.next;\n this.recycle(particle);\n if (particle.parent)\n {\n particle.parent.removeChild(particle);\n }\n }\n this._activeParticlesFirst = this._activeParticlesLast = null;\n this.particleCount = 0;\n }\n\n /**\n * Destroys the emitter and all of its particles.\n */\n public destroy(): void\n {\n // make sure we aren't still listening to any tickers\n this.autoUpdate = false;\n // puts all active particles in the pool, and removes them from the particle parent\n this.cleanup();\n // wipe the pool clean\n let next;\n\n for (let particle = this._poolFirst; particle; particle = next)\n {\n // store next value so we don't lose it in our destroy call\n next = particle.next;\n particle.destroy();\n }\n this._poolFirst = this._parent = this.particleImages = this.spawnPos = this.ownerPos\n = this.startColor = this.startScale = this.startAlpha = this.startSpeed\n = this.customEase = this._completeCallback = null;\n }\n}\n","import { Emitter } from './Emitter';\nimport { ParticleUtils, SimpleEase, Color, GetTextureFromString } from './ParticleUtils';\nimport { PropertyList } from './PropertyList';\nimport { LinkedListChild } from './LinkedListContainer';\nimport { Sprite, Point, Texture } from 'pixi.js';\n\n/**\n * An individual particle image. You shouldn't have to deal with these.\n */\nexport class Particle extends Sprite implements LinkedListChild\n{\n /**\n * The emitter that controls this particle.\n */\n public emitter: Emitter;\n /**\n * The velocity of the particle. Speed may change, but the angle also\n * contained in velocity is constant.\n */\n public velocity: Point;\n /**\n * The maximum lifetime of this particle, in seconds.\n */\n public maxLife: number;\n /**\n * The current age of the particle, in seconds.\n */\n public age: number;\n /**\n * A simple easing function to be applied to all properties that\n * are being interpolated.\n */\n public ease: SimpleEase;\n /**\n * Extra data that the emitter passes along for custom particles.\n */\n public extraData: any;\n /**\n * The alpha of the particle throughout its life.\n */\n public alphaList: PropertyList;\n /**\n * The speed of the particle throughout its life.\n */\n public speedList: PropertyList;\n /**\n * A multiplier from 0-1 applied to the speed of the particle at all times.\n */\n public speedMultiplier: number;\n /**\n * Acceleration to apply to the particle.\n */\n public acceleration: Point;\n /**\n * The maximum speed allowed for accelerating particles. Negative values, values of 0 or NaN\n * will disable the maximum speed.\n */\n public maxSpeed: number;\n /**\n * Speed at which the particle rotates, in radians per second.\n */\n public rotationSpeed: number;\n\n /**\n * Acceleration of rotation (angular acceleration) to apply to the particle.\n */\n public rotationAcceleration: number;\n\n /**\n * If particle rotation is locked, preventing rotation from occurring due\n * to directional changes.\n */\n public noRotation: boolean;\n /**\n * The scale of the particle throughout its life.\n */\n public scaleList: PropertyList;\n /**\n * A multiplier from 0-1 applied to the scale of the particle at all times.\n */\n public scaleMultiplier: number;\n /**\n * The tint of the particle throughout its life.\n */\n public colorList: PropertyList;\n /**\n * A reference to init, so that subclasses can access it without the penalty of Function.call()\n */\n protected Particle_init: typeof Particle.prototype.init;\n /**\n * A reference to update so that subclasses can access the original without the overhead\n * of Function.call().\n * @param delta Time elapsed since the previous frame, in __seconds__.\n * @return The standard interpolation multiplier (0-1) used for all relevant particle\n * properties. A value of -1 means the particle died of old age instead.\n */\n protected Particle_update: typeof Particle.prototype.update;\n protected Particle_destroy: typeof Particle.prototype.destroy;\n protected Sprite_destroy: typeof Sprite.prototype.destroy;\n /**\n * If alpha should be interpolated at all.\n */\n protected _doAlpha: boolean;\n /**\n * If scale should be interpolated at all.\n */\n protected _doScale: boolean;\n /**\n * If speed should be interpolated at all.\n */\n protected _doSpeed: boolean;\n /**\n * If acceleration should be handled at all. _doSpeed is mutually exclusive with this,\n * and _doSpeed gets priority.\n */\n protected _doAcceleration: boolean;\n /**\n * If color should be interpolated at all.\n */\n protected _doColor: boolean;\n /**\n * If normal movement should be handled. Subclasses wishing to override movement\n * can set this to false in init().\n */\n protected _doNormalMovement: boolean;\n /**\n * One divided by the max life of the particle, saved for slightly faster math.\n */\n private _oneOverLife: number;\n /**\n * Reference to the next particle in the list.\n */\n public next: Particle;\n\n /**\n * Reference to the previous particle in the list.\n */\n public prev: Particle;\n\n public prevChild: LinkedListChild;\n public nextChild: LinkedListChild;\n\n /**\n * @param {PIXI.particles.Emitter} emitter The emitter that controls this particle.\n */\n constructor(emitter: Emitter)\n {\n // start off the sprite with a blank texture, since we are going to replace it\n // later when the particle is initialized.\n super();\n // initialize LinkedListChild props so they are included in underlying JS class definition\n this.prevChild = this.nextChild = null;\n\n this.emitter = emitter;\n // particles should be centered\n this.anchor.x = this.anchor.y = 0.5;\n this.velocity = new Point();\n this.rotationSpeed = 0;\n this.rotationAcceleration = 0;\n this.maxLife = 0;\n this.age = 0;\n this.ease = null;\n this.extraData = null;\n this.alphaList = new PropertyList();\n this.speedList = new PropertyList();\n this.speedMultiplier = 1;\n this.acceleration = new Point();\n this.maxSpeed = NaN;\n this.scaleList = new PropertyList();\n this.scaleMultiplier = 1;\n this.colorList = new PropertyList(true);\n this._doAlpha = false;\n this._doScale = false;\n this._doSpeed = false;\n this._doAcceleration = false;\n this._doColor = false;\n this._doNormalMovement = false;\n this._oneOverLife = 0;\n this.next = null;\n this.prev = null;\n\n // save often used functions on the instance instead of the prototype for better speed\n this.init = this.init;\n this.Particle_init = Particle.prototype.init;\n this.update = this.update;\n this.Particle_update = Particle.prototype.update;\n this.Sprite_destroy = super.destroy;\n this.Particle_destroy = Particle.prototype.destroy;\n this.applyArt = this.applyArt;\n this.kill = this.kill;\n }\n\n /**\n * Initializes the particle for use, based on the properties that have to\n * have been set already on the particle.\n */\n public init(): void\n {\n // reset the age\n this.age = 0;\n // set up the velocity based on the start speed and rotation\n this.velocity.x = this.speedList.current.value * this.speedMultiplier;\n this.velocity.y = 0;\n ParticleUtils.rotatePoint(this.rotation, this.velocity);\n if (this.noRotation)\n {\n this.rotation = 0;\n }\n else\n {\n // convert rotation to Radians from Degrees\n this.rotation *= ParticleUtils.DEG_TO_RADS;\n }\n // convert rotation speed to Radians from Degrees\n this.rotationSpeed *= ParticleUtils.DEG_TO_RADS;\n this.rotationAcceleration *= ParticleUtils.DEG_TO_RADS;\n\n // set alpha to inital alpha\n this.alpha = this.alphaList.current.value;\n // set scale to initial scale\n this.scale.x = this.scale.y = this.scaleList.current.value;\n // figure out what we need to interpolate\n this._doAlpha = !!this.alphaList.current.next;\n this._doSpeed = !!this.speedList.current.next;\n this._doScale = !!this.scaleList.current.next;\n this._doColor = !!this.colorList.current.next;\n this._doAcceleration = this.acceleration.x !== 0 || this.acceleration.y !== 0;\n // _doNormalMovement can be cancelled by subclasses\n this._doNormalMovement = this._doSpeed || this.speedList.current.value !== 0 || this._doAcceleration;\n // save our lerp helper\n this._oneOverLife = 1 / this.maxLife;\n // set the inital color\n const color = this.colorList.current.value;\n\n this.tint = ParticleUtils.combineRGBComponents(color.r, color.g, color.b);\n // ensure visibility\n this.visible = true;\n }\n\n /**\n * Sets the texture for the particle. This can be overridden to allow\n * for an animated particle.\n * @param art The texture to set.\n */\n public applyArt(art: any): void\n {\n this.texture = art || Texture.EMPTY;\n }\n\n /**\n * Updates the particle.\n * @param delta Time elapsed since the previous frame, in __seconds__.\n * @return The standard interpolation multiplier (0-1) used for all\n * relevant particle properties. A value of -1 means the particle\n * died of old age instead.\n */\n public update(delta: number): number\n {\n // increase age\n this.age += delta;\n // recycle particle if it is too old\n if (this.age >= this.maxLife || this.age < 0)\n {\n this.kill();\n\n return -1;\n }\n\n // determine our interpolation value\n let lerp = this.age * this._oneOverLife;// lifetime / maxLife;\n\n if (this.ease)\n {\n if (this.ease.length === 4)\n {\n // the t, b, c, d parameters that some tween libraries use\n // (time, initial value, end value, duration)\n lerp = (this.ease as any)(lerp, 0, 1, 1);\n }\n else\n {\n // the simplified version that we like that takes\n // one parameter, time from 0-1. TweenJS eases provide this usage.\n lerp = this.ease(lerp);\n }\n }\n\n // interpolate alpha\n if (this._doAlpha)\n {\n this.alpha = this.alphaList.interpolate(lerp);\n }\n // interpolate scale\n if (this._doScale)\n {\n const scale = this.scaleList.interpolate(lerp) * this.scaleMultiplier;\n\n this.scale.x = this.scale.y = scale;\n }\n // handle movement\n if (this._doNormalMovement)\n {\n let deltaX: number;\n let deltaY: number;\n // interpolate speed\n\n if (this._doSpeed)\n {\n const speed = this.speedList.interpolate(lerp) * this.speedMultiplier;\n\n ParticleUtils.normalize(this.velocity);\n ParticleUtils.scaleBy(this.velocity, speed);\n deltaX = this.velocity.x * delta;\n deltaY = this.velocity.y * delta;\n }\n else if (this._doAcceleration)\n {\n const oldVX = this.velocity.x;\n const oldVY = this.velocity.y;\n\n this.velocity.x += this.acceleration.x * delta;\n this.velocity.y += this.acceleration.y * delta;\n if (this.maxSpeed)\n {\n const currentSpeed = ParticleUtils.length(this.velocity);\n // if we are going faster than we should, clamp at the max speed\n // DO NOT recalculate vector length\n\n if (currentSpeed > this.maxSpeed)\n {\n ParticleUtils.scaleBy(this.velocity, this.maxSpeed / currentSpeed);\n }\n }\n // calculate position delta by the midpoint between our old velocity and our new velocity\n deltaX = (oldVX + this.velocity.x) / 2 * delta;\n deltaY = (oldVY + this.velocity.y) / 2 * delta;\n }\n else\n {\n deltaX = this.velocity.x * delta;\n deltaY = this.velocity.y * delta;\n }\n // adjust position based on velocity\n this.position.x += deltaX;\n this.position.y += deltaY;\n }\n // interpolate color\n if (this._doColor)\n {\n this.tint = this.colorList.interpolate(lerp);\n }\n // update rotation\n if (this.rotationAcceleration !== 0)\n {\n const newRotationSpeed = this.rotationSpeed + (this.rotationAcceleration * delta);\n\n this.rotation += (this.rotationSpeed + newRotationSpeed) / 2 * delta;\n this.rotationSpeed = newRotationSpeed;\n }\n else if (this.rotationSpeed !== 0)\n {\n this.rotation += this.rotationSpeed * delta;\n }\n else if (this.acceleration && !this.noRotation)\n {\n this.rotation = Math.atan2(this.velocity.y, this.velocity.x);// + Math.PI / 2;\n }\n\n return lerp;\n }\n\n /**\n * Kills the particle, removing it from the display list\n * and telling the emitter to recycle it.\n */\n public kill(): void\n {\n this.emitter.recycle(this);\n }\n\n /**\n * Destroys the particle, removing references and preventing future use.\n */\n public destroy(): void\n {\n if (this.parent)\n {\n this.parent.removeChild(this);\n }\n this.Sprite_destroy();\n this.emitter = this.velocity = this.colorList = this.scaleList = this.alphaList\n = this.speedList = this.ease = this.next = this.prev = null;\n }\n\n /**\n * Checks over the art that was passed to the Emitter's init() function, to do any special\n * modifications to prepare it ahead of time.\n * @param art The array of art data. For Particle, it should be an array of\n * Textures. Any strings in the array will be converted to\n * Textures via Texture.from().\n * @return The art, after any needed modifications.\n */\n public static parseArt(art: any[]): any[]\n {\n // convert any strings to Textures.\n let i;\n\n for (i = art.length; i >= 0; --i)\n {\n if (typeof art[i] === 'string')\n {\n art[i] = GetTextureFromString(art[i]);\n }\n }\n // particles from different base textures will be slower in WebGL than if they\n // were from one spritesheet\n if (ParticleUtils.verbose)\n {\n for (i = art.length - 1; i > 0; --i)\n {\n if (art[i].baseTexture !== art[i - 1].baseTexture)\n {\n if (window.console)\n {\n // eslint-disable-next-line max-len\n console.warn('PixiParticles: using particle textures from different images may hinder performance in WebGL');\n }\n break;\n }\n }\n }\n\n return art;\n }\n\n /**\n * Parses extra emitter data to ensure it is set up for this particle class.\n * Particle does nothing to the extra data.\n * @param extraData The extra data from the particle config.\n * @return The parsed extra data.\n */\n public static parseData(extraData: any): any\n {\n return extraData;\n }\n}\n","import { Point } from 'pixi.js';\n\nexport interface BasicPoint\n{\n x: number;\n y: number;\n}\n\nexport interface Segment\n{\n p1: BasicPoint;\n p2: BasicPoint;\n l: number;\n}\n\n/**\n * Chain of line segments for generating spawn positions.\n */\nexport class PolygonalChain\n{\n /**\n * List of segment objects in the chain.\n */\n private segments: Segment[];\n /**\n * Total length of all segments of the chain.\n */\n private totalLength: number;\n /**\n * Total length of segments up to and including the segment of the same index.\n * Used for weighted random selection of segment.\n */\n private countingLengths: number[];\n\n /**\n * @param data Point data for polygon chains. Either a list of points for a single chain, or a list of chains.\n */\n constructor(data: BasicPoint[]|BasicPoint[][])\n {\n this.segments = [];\n this.countingLengths = [];\n this.totalLength = 0;\n this.init(data);\n }\n\n /**\n * @param data Point data for polygon chains. Either a list of points for a single chain, or a list of chains.\n */\n private init(data: BasicPoint[]|BasicPoint[][]): void\n {\n // if data is not present, set up a segment of length 0\n if (!data || !data.length)\n {\n this.segments.push({ p1: { x: 0, y: 0 }, p2: { x: 0, y: 0 }, l: 0 });\n }\n else if (Array.isArray(data[0]))\n {\n // list of segment chains, each defined as a list of points\n for (let i = 0; i < data.length; ++i)\n {\n // loop through the chain, connecting points\n const chain = data[i] as BasicPoint[];\n let prevPoint = chain[0] as BasicPoint;\n\n for (let j = 1; j < chain.length; ++j)\n {\n const second = chain[j] as BasicPoint;\n\n this.segments.push({ p1: prevPoint, p2: second, l: 0 });\n prevPoint = second;\n }\n }\n }\n else\n {\n let prevPoint = data[0] as BasicPoint;\n // list of points\n\n for (let i = 1; i < data.length; ++i)\n {\n const second = data[i] as BasicPoint;\n\n this.segments.push({ p1: prevPoint, p2: second, l: 0 });\n prevPoint = second;\n }\n }\n // now go through our segments to calculate the lengths so that we\n // can set up a nice weighted random distribution\n for (let i = 0; i < this.segments.length; ++i)\n {\n const { p1, p2 } = this.segments[i];\n const segLength = Math.sqrt(((p2.x - p1.x) * (p2.x - p1.x)) + ((p2.y - p1.y) * (p2.y - p1.y)));\n // save length so we can turn a random number into a 0-1 interpolation value later\n\n this.segments[i].l = segLength;\n this.totalLength += segLength;\n // keep track of the length so far, counting up\n this.countingLengths.push(this.totalLength);\n }\n }\n\n /**\n * Gets a random point in the chain.\n * @param out The point to store the selected position in.\n */\n public getRandomPoint(out: Point): void\n {\n // select a random spot in the length of the chain\n const rand = Math.random() * this.totalLength;\n let chosenSeg: Segment;\n let lerp: number;\n\n // if only one segment, it wins\n if (this.segments.length === 1)\n {\n chosenSeg = this.segments[0];\n lerp = rand;\n }\n else\n {\n // otherwise, go through countingLengths until we have determined\n // which segment we chose\n for (let i = 0; i < this.countingLengths.length; ++i)\n {\n if (rand < this.countingLengths[i])\n {\n chosenSeg = this.segments[i];\n // set lerp equal to the length into that segment\n // (i.e. the remainder after subtracting all the segments before it)\n lerp = i === 0 ? rand : rand - this.countingLengths[i - 1];\n break;\n }\n }\n }\n // divide lerp by the segment length, to result in a 0-1 number.\n lerp /= chosenSeg.l || 1;\n const { p1, p2 } = chosenSeg;\n // now calculate the position in the segment that the lerp value represents\n\n out.x = p1.x + (lerp * (p2.x - p1.x));\n out.y = p1.y + (lerp * (p2.y - p1.y));\n }\n}\n","import { ParticleUtils } from './ParticleUtils';\nimport { Particle } from './Particle';\nimport { Emitter } from './Emitter';\nimport { Point, Texture } from 'pixi.js';\n\n/**\n * A helper point for math things.\n * @hidden\n */\nconst helperPoint = new Point();\n\n/**\n * A hand picked list of Math functions (and a couple properties) that are\n * allowable. They should be used without the preceding \"Math.\"\n * @hidden\n */\nconst MATH_FUNCS = [\n 'pow',\n 'sqrt',\n 'abs',\n 'floor',\n 'round',\n 'ceil',\n 'E',\n 'PI',\n 'sin',\n 'cos',\n 'tan',\n 'asin',\n 'acos',\n 'atan',\n 'atan2',\n 'log',\n];\n/**\n * create an actual regular expression object from the string\n * @hidden\n */\nconst WHITELISTER = new RegExp(\n [\n // Allow the 4 basic operations, parentheses and all numbers/decimals, as well\n // as 'x', for the variable usage.\n '[01234567890\\\\.\\\\*\\\\-\\\\+\\\\/\\\\(\\\\)x ,]',\n ].concat(MATH_FUNCS).join('|'),\n 'g',\n);\n\n/**\n * Parses a string into a function for path following.\n * This involves whitelisting the string for safety, inserting \"Math.\" to math function\n * names, and using `new Function()` to generate a function.\n * @hidden\n * @param pathString The string to parse.\n * @return The path function - takes x, outputs y.\n */\nfunction parsePath(pathString: string): (x: number) => number\n{\n const matches = pathString.match(WHITELISTER);\n\n for (let i = matches.length - 1; i >= 0; --i)\n {\n if (MATH_FUNCS.indexOf(matches[i]) >= 0)\n { matches[i] = `Math.${matches[i]}`; }\n }\n pathString = matches.join('');\n\n // eslint-disable-next-line no-new-func\n return new Function('x', `return ${pathString};`) as (x: number) => number;\n}\n\n/**\n * An particle that follows a path defined by an algebraic expression, e.g. \"sin(x)\" or\n * \"5x + 3\".\n * To use this class, the particle config must have a \"path\" string in the\n * \"extraData\" parameter. This string should have \"x\" in it to represent movement (from the\n * speed settings of the particle). It may have numbers, parentheses, the four basic\n * operations, and the following Math functions or properties (without the preceding \"Math.\"):\n * \"pow\", \"sqrt\", \"abs\", \"floor\", \"round\", \"ceil\", \"E\", \"PI\", \"sin\", \"cos\", \"tan\", \"asin\",\n * \"acos\", \"atan\", \"atan2\", \"log\".\n * The overall movement of the particle and the expression value become x and y positions for\n * the particle, respectively. The final position is rotated by the spawn rotation/angle of\n * the particle.\n *\n * Some example paths:\n *\n * \t\"sin(x/10) * 20\" // A sine wave path.\n * \t\"cos(x/100) * 30\" // Particles curve counterclockwise (for medium speed/low lifetime particles)\n * \t\"pow(x/10, 2) / 2\" // Particles curve clockwise (remember, +y is down).\n */\nexport class PathParticle extends Particle\n{\n /**\n * The function representing the path the particle should take.\n */\n public path: Function;\n /**\n * The initial rotation in degrees of the particle, because the direction of the path\n * is based on that.\n */\n public initialRotation: number;\n /**\n * The initial position of the particle, as all path movement is added to that.\n */\n public initialPosition: Point;\n /**\n * Total single directional movement, due to speed.\n */\n public movement: number;\n\n /**\n * @param {PIXI.particles.Emitter} emitter The emitter that controls this PathParticle.\n */\n constructor(emitter: Emitter)\n {\n super(emitter);\n this.path = null;\n this.initialRotation = 0;\n this.initialPosition = new Point();\n this.movement = 0;\n }\n\n /**\n * Initializes the particle for use, based on the properties that have to\n * have been set already on the particle.\n */\n public init(): void\n {\n // get initial rotation before it is converted to radians\n this.initialRotation = this.rotation;\n // standard init\n this.Particle_init();\n\n // set the path for the particle\n this.path = this.extraData.path;\n // cancel the normal movement behavior\n this._doNormalMovement = !this.path;\n // reset movement\n this.movement = 0;\n // grab position\n this.initialPosition.x = this.position.x;\n this.initialPosition.y = this.position.y;\n }\n\n /**\n * Updates the particle.\n * @param delta Time elapsed since the previous frame, in __seconds__.\n */\n public update(delta: number): number\n {\n const lerp = this.Particle_update(delta);\n // if the particle died during the update, then don't bother\n\n if (lerp >= 0 && this.path)\n {\n // increase linear movement based on speed\n if (this._doSpeed)\n {\n const speed = this.speedList.interpolate(lerp) * this.speedMultiplier;\n\n this.movement += speed * delta;\n }\n else\n {\n const speed = this.speedList.current.value * this.speedMultiplier;\n\n this.movement += speed * delta;\n }\n // set up the helper point for rotation\n helperPoint.x = this.movement;\n helperPoint.y = this.path(this.movement);\n ParticleUtils.rotatePoint(this.initialRotation, helperPoint);\n this.position.x = this.initialPosition.x + helperPoint.x;\n this.position.y = this.initialPosition.y + helperPoint.y;\n }\n\n return lerp;\n }\n\n /**\n * Destroys the particle, removing references and preventing future use.\n */\n public destroy(): void\n {\n this.Particle_destroy();\n this.path = this.initialPosition = null;\n }\n\n /**\n * Checks over the art that was passed to the Emitter's init() function, to do any special\n * modifications to prepare it ahead of time. This just runs Particle.parseArt().\n * @param art The array of art data. For Particle, it should be an array of\n * Textures. Any strings in the array will be converted to\n * Textures via Texture.fromImage().\n * @return The art, after any needed modifications.\n */\n public static parseArt(art: (Texture|string)[]): Texture[]\n {\n return Particle.parseArt(art);\n }\n\n /**\n * Parses extra emitter data to ensure it is set up for this particle class.\n * PathParticle checks for the existence of path data, and parses the path data for use\n * by particle instances.\n * @param extraData The extra data from the particle config.\n * @return The parsed extra data.\n */\n public static parseData(extraData: {path: string}): any\n {\n const output: any = {};\n\n if (extraData && extraData.path)\n {\n try\n {\n output.path = parsePath(extraData.path);\n }\n catch (e)\n {\n if (ParticleUtils.verbose)\n {\n console.error('PathParticle: error in parsing path expression');\n }\n output.path = null;\n }\n }\n else\n {\n if (ParticleUtils.verbose)\n {\n console.error('PathParticle requires a path string in extraData!');\n }\n output.path = null;\n }\n\n return output;\n }\n}\n","import { Particle } from './Particle';\nimport { Emitter } from './Emitter';\nimport { GetTextureFromString } from './ParticleUtils';\nimport { Texture } from 'pixi.js';\n\nexport interface ParsedAnimatedParticleArt\n{\n textures: Texture[];\n duration: number;\n framerate: number;\n loop: boolean;\n}\n\nexport interface AnimatedParticleArt\n{\n framerate: 'matchLife'|number;\n loop?: boolean;\n textures: (string|Texture|{texture: string|Texture;count: number})[];\n}\n\n/**\n * An individual particle image with an animation. Art data passed to the emitter must be\n * formatted in a particular way for AnimatedParticle to be able to handle it:\n *\n * ```typescript\n * {\n * //framerate is required. It is the animation speed of the particle in frames per\n * //second.\n * //A value of \"matchLife\" causes the animation to match the lifetime of an individual\n * //particle, instead of at a constant framerate. This causes the animation to play\n * //through one time, completing when the particle expires.\n * framerate: 6,\n * //loop is optional, and defaults to false.\n * loop: true,\n * //textures is required, and can be an array of any (non-zero) length.\n * textures: [\n * //each entry represents a single texture that should be used for one or more\n * //frames. Any strings will be converted to Textures with Texture.from().\n * //Instances of PIXI.Texture will be used directly.\n * \"animFrame1.png\",\n * //entries can be an object with a 'count' property, telling AnimatedParticle to\n * //use that texture for 'count' frames sequentially.\n * {\n * texture: \"animFrame2.png\",\n * count: 3\n * },\n * \"animFrame3.png\"\n * ]\n * }\n * ```\n */\nexport class AnimatedParticle extends Particle\n{\n /**\n * Texture array used as each frame of animation, similarly to how MovieClip works.\n */\n private textures: Texture[];\n\n /**\n * Duration of the animation, in seconds.\n */\n private duration: number;\n\n /**\n * Animation framerate, in frames per second.\n */\n private framerate: number;\n\n /**\n * Animation time elapsed, in seconds.\n */\n private elapsed: number;\n\n /**\n * If this particle animation should loop.\n */\n private loop: boolean;\n\n /**\n * @param emitter The emitter that controls this AnimatedParticle.\n */\n constructor(emitter: Emitter)\n {\n super(emitter);\n\n this.textures = null;\n this.duration = 0;\n this.framerate = 0;\n this.elapsed = 0;\n this.loop = false;\n }\n\n /**\n * Initializes the particle for use, based on the properties that have to\n * have been set already on the particle.\n */\n public init(): void\n {\n this.Particle_init();\n\n this.elapsed = 0;\n\n // if the animation needs to match the particle's life, then cacluate variables\n if (this.framerate < 0)\n {\n this.duration = this.maxLife;\n this.framerate = this.textures.length / this.duration;\n }\n }\n\n /**\n * Sets the textures for the particle.\n * @param art An array of PIXI.Texture objects for this animated particle.\n */\n public applyArt(art: ParsedAnimatedParticleArt): void\n {\n this.textures = art.textures;\n this.framerate = art.framerate;\n this.duration = art.duration;\n this.loop = art.loop;\n }\n\n /**\n * Updates the particle.\n * @param delta Time elapsed since the previous frame, in __seconds__.\n */\n public update(delta: number): number\n {\n const lerp = this.Particle_update(delta);\n // only animate the particle if it is still alive\n\n if (lerp >= 0)\n {\n this.elapsed += delta;\n if (this.elapsed > this.duration)\n {\n // loop elapsed back around\n if (this.loop)\n {\n this.elapsed = this.elapsed % this.duration;\n }\n // subtract a small amount to prevent attempting to go past the end of the animation\n else\n {\n this.elapsed = this.duration - 0.000001;\n }\n }\n // add a very small number to the frame and then floor it to avoid\n // the frame being one short due to floating point errors.\n const frame = ((this.elapsed * this.framerate) + 0.0000001) | 0;\n\n this.texture = this.textures[frame] || Texture.EMPTY;\n }\n\n return lerp;\n }\n\n /**\n * Destroys the particle, removing references and preventing future use.\n */\n public destroy(): void\n {\n this.Particle_destroy();\n this.textures = null;\n }\n\n /**\n * Checks over the art that was passed to the Emitter's init() function, to do any special\n * modifications to prepare it ahead of time.\n * @param art The array of art data, properly formatted for AnimatedParticle.\n * @return The art, after any needed modifications.\n */\n public static parseArt(art: AnimatedParticleArt[]): any\n {\n const outArr: ParsedAnimatedParticleArt[] = [];\n\n for (let i = 0; i < art.length; ++i)\n {\n const data = art[i];\n const output = outArr[i] = {} as ParsedAnimatedParticleArt;\n const outTextures = output.textures = [] as Texture[];\n const textures = data.textures;\n\n for (let j = 0; j < textures.length; ++j)\n {\n let tex = textures[j];\n\n if (typeof tex === 'string')\n {\n outTextures.push(GetTextureFromString(tex));\n }\n else if (tex instanceof Texture)\n {\n outTextures.push(tex);\n }\n // assume an object with extra data determining duplicate frame data\n else\n {\n let dupe = tex.count || 1;\n\n if (typeof tex.texture === 'string')\n {\n tex = GetTextureFromString(tex.texture);\n }\n else// if(tex.texture instanceof Texture)\n {\n tex = tex.texture;\n }\n for (; dupe > 0; --dupe)\n {\n outTextures.push(tex);\n }\n }\n }\n\n // use these values to signify that the animation should match the particle life time.\n if (data.framerate === 'matchLife')\n {\n // -1 means that it should be calculated\n output.framerate = -1;\n output.duration = 0;\n output.loop = false;\n }\n else\n {\n // determine if the animation should loop\n output.loop = !!data.loop;\n // get the framerate, default to 60\n output.framerate = data.framerate > 0 ? data.framerate : 60;\n // determine the duration\n output.duration = outTextures.length / output.framerate;\n }\n }\n\n return outArr;\n }\n}\n","import { Container, DisplayObject, Renderer, Rectangle, MaskData } from 'pixi.js';\n\n/** Interface for a child of a LinkedListContainer (has the prev/next properties added) */\nexport interface LinkedListChild extends DisplayObject\n{\n nextChild: LinkedListChild|null;\n prevChild: LinkedListChild|null;\n}\n\n/**\n * A semi-experimental Container that uses a doubly linked list to manage children instead of an\n * array. This means that adding/removing children often is not the same performance hit that\n * it would to be continually pushing/splicing.\n * However, this is primarily intended to be used for heavy particle usage, and may not handle\n * edge cases well if used as a complete Container replacement.\n */\nexport class LinkedListContainer extends Container\n{\n private _firstChild: LinkedListChild|null = null;\n private _lastChild: LinkedListChild|null = null;\n private _childCount = 0;\n\n public get firstChild(): LinkedListChild\n {\n return this._firstChild;\n }\n\n public get lastChild(): LinkedListChild\n {\n return this._lastChild;\n }\n\n public get childCount(): number\n {\n return this._childCount;\n }\n\n public addChild(...children: T): T[0]\n {\n // if there is only one argument we can bypass looping through the them\n if (children.length > 1)\n {\n // loop through the array and add all children\n for (let i = 0; i < children.length; i++)\n {\n // eslint-disable-next-line prefer-rest-params\n this.addChild(children[i]);\n }\n }\n else\n {\n const child = children[0] as LinkedListChild;\n // if the child has a parent then lets remove it as PixiJS objects can only exist in one place\n\n if (child.parent)\n {\n child.parent.removeChild(child);\n }\n\n (child as any).parent = this;\n this.sortDirty = true;\n\n // ensure child transform will be recalculated\n (child.transform as any)._parentID = -1;\n\n // add to list if we have a list\n if (this._lastChild)\n {\n this._lastChild.nextChild = child;\n child.prevChild = this._lastChild;\n this._lastChild = child;\n }\n // otherwise initialize the list\n else\n {\n this._firstChild = this._lastChild = child;\n }\n\n // update child count\n ++this._childCount;\n\n // ensure bounds will be recalculated\n (this as any)._boundsID++;\n\n // TODO - lets either do all callbacks or all events.. not both!\n this.onChildrenChange();\n this.emit('childAdded', child, this, this._childCount);\n child.emit('added', this);\n }\n\n return children[0];\n }\n\n public addChildAt(child: T, index: number): T\n {\n if (index < 0 || index > this._childCount)\n {\n throw new Error(`addChildAt: The index ${index} supplied is out of bounds ${this._childCount}`);\n }\n\n if (child.parent)\n {\n child.parent.removeChild(child);\n }\n\n (child as any).parent = this;\n this.sortDirty = true;\n\n // ensure child transform will be recalculated\n (child.transform as any)._parentID = -1;\n\n const c = (child as any) as LinkedListChild;\n\n // if no children, do basic initialization\n if (!this._firstChild)\n {\n this._firstChild = this._lastChild = c;\n }\n // add at beginning (back)\n else if (index === 0)\n {\n this._firstChild.prevChild = c;\n c.nextChild = this._firstChild;\n this._firstChild = c;\n }\n // add at end (front)\n else if (index === this._childCount)\n {\n this._lastChild.nextChild = c;\n c.prevChild = this._lastChild;\n this._lastChild = c;\n }\n // otherwise we have to start counting through the children to find the right one\n // - SLOW, only provided to fully support the possibility of use\n else\n {\n let i = 0;\n let target = this._firstChild;\n\n while (i < index)\n {\n target = target.nextChild;\n ++i;\n }\n // insert before the target that we found at the specified index\n target.prevChild.nextChild = c;\n c.prevChild = target.prevChild;\n c.nextChild = target;\n target.prevChild = c;\n }\n\n // update child count\n ++this._childCount;\n\n // ensure bounds will be recalculated\n (this as any)._boundsID++;\n\n // TODO - lets either do all callbacks or all events.. not both!\n (this as any).onChildrenChange(index);// the PixiJS types say this has no arguments\n child.emit('added', this);\n this.emit('childAdded', child, this, index);\n\n return child;\n }\n\n /**\n * Adds a child to the container to be rendered below another child.\n *\n * @param child The child to add\n * @param relative - The current child to add the new child relative to.\n * @return The child that was added.\n */\n public addChildBelow(child: T, relative: DisplayObject): T\n {\n if (relative.parent !== this)\n {\n throw new Error(`addChildBelow: The relative target must be a child of this parent`);\n }\n\n if (child.parent)\n {\n child.parent.removeChild(child);\n }\n\n (child as any).parent = this;\n this.sortDirty = true;\n\n // ensure child transform will be recalculated\n (child.transform as any)._parentID = -1;\n\n // insert before the target that we were given\n (relative as LinkedListChild).prevChild.nextChild = (child as any as LinkedListChild);\n (child as any as LinkedListChild).prevChild = (relative as LinkedListChild).prevChild;\n (child as any as LinkedListChild).nextChild = (relative as LinkedListChild);\n (relative as LinkedListChild).prevChild = (child as any as LinkedListChild);\n if (this._firstChild === relative)\n {\n this._firstChild = (child as any as LinkedListChild);\n }\n\n // update child count\n ++this._childCount;\n\n // ensure bounds will be recalculated\n (this as any)._boundsID++;\n\n // TODO - lets either do all callbacks or all events.. not both!\n this.onChildrenChange();\n this.emit('childAdded', child, this, this._childCount);\n child.emit('added', this);\n\n return child;\n }\n\n /**\n * Adds a child to the container to be rendered above another child.\n *\n * @param child The child to add\n * @param relative - The current child to add the new child relative to.\n * @return The child that was added.\n */\n public addChildAbove(child: T, relative: DisplayObject): T\n {\n if (relative.parent !== this)\n {\n throw new Error(`addChildBelow: The relative target must be a child of this parent`);\n }\n\n if (child.parent)\n {\n child.parent.removeChild(child);\n }\n\n (child as any).parent = this;\n this.sortDirty = true;\n\n // ensure child transform will be recalculated\n (child.transform as any)._parentID = -1;\n\n // insert after the target that we were given\n (relative as LinkedListChild).nextChild.prevChild = (child as any as LinkedListChild);\n (child as any as LinkedListChild).nextChild = (relative as LinkedListChild).nextChild;\n (child as any as LinkedListChild).prevChild = (relative as LinkedListChild);\n (relative as LinkedListChild).nextChild = (child as any as LinkedListChild);\n if (this._lastChild === relative)\n {\n this._lastChild = (child as any as LinkedListChild);\n }\n\n // update child count\n ++this._childCount;\n\n // ensure bounds will be recalculated\n (this as any)._boundsID++;\n\n // TODO - lets either do all callbacks or all events.. not both!\n this.onChildrenChange();\n this.emit('childAdded', child, this, this._childCount);\n child.emit('added', this);\n\n return child;\n }\n\n public swapChildren(child: DisplayObject, child2: DisplayObject): void\n {\n if (child === child2 || child.parent !== this || child2.parent !== this)\n {\n return;\n }\n\n const { prevChild, nextChild } = (child as LinkedListChild);\n\n (child as LinkedListChild).prevChild = (child2 as LinkedListChild).prevChild;\n (child as LinkedListChild).nextChild = (child2 as LinkedListChild).nextChild;\n (child2 as LinkedListChild).prevChild = prevChild;\n (child2 as LinkedListChild).nextChild = nextChild;\n\n if (this._firstChild === child)\n {\n this._firstChild = child2 as LinkedListChild;\n }\n else if (this._firstChild === child2)\n {\n this._firstChild = child as LinkedListChild;\n }\n if (this._lastChild === child)\n {\n this._lastChild = child2 as LinkedListChild;\n }\n else if (this._lastChild === child2)\n {\n this._lastChild = child as LinkedListChild;\n }\n\n this.onChildrenChange();\n }\n\n public getChildIndex(child: DisplayObject): number\n {\n let index = 0;\n let test = this._firstChild;\n\n while (test)\n {\n if (test === child)\n {\n break;\n }\n test = test.nextChild;\n ++index;\n }\n if (!test)\n {\n throw new Error('The supplied DisplayObject must be a child of the caller');\n }\n\n return index;\n }\n\n setChildIndex(child: DisplayObject, index: number): void\n {\n if (index < 0 || index >= this._childCount)\n {\n throw new Error(`The index ${index} supplied is out of bounds ${this._childCount}`);\n }\n if (child.parent !== this)\n {\n throw new Error('The supplied DisplayObject must be a child of the caller');\n }\n\n // remove child\n if ((child as LinkedListChild).nextChild)\n {\n (child as LinkedListChild).nextChild.prevChild = (child as LinkedListChild).prevChild;\n }\n if ((child as LinkedListChild).prevChild)\n {\n (child as LinkedListChild).prevChild.nextChild = (child as LinkedListChild).nextChild;\n }\n if (this._firstChild === (child as LinkedListChild))\n {\n this._firstChild = (child as LinkedListChild).nextChild;\n }\n if (this._lastChild === (child as LinkedListChild))\n {\n this._lastChild = (child as LinkedListChild).prevChild;\n }\n (child as LinkedListChild).nextChild = null;\n (child as LinkedListChild).prevChild = null;\n\n // do addChildAt\n if (!this._firstChild)\n {\n this._firstChild = this._lastChild = (child as LinkedListChild);\n }\n else if (index === 0)\n {\n this._firstChild.prevChild = (child as LinkedListChild);\n (child as LinkedListChild).nextChild = this._firstChild;\n this._firstChild = (child as LinkedListChild);\n }\n else if (index === this._childCount)\n {\n this._lastChild.nextChild = (child as LinkedListChild);\n (child as LinkedListChild).prevChild = this._lastChild;\n this._lastChild = (child as LinkedListChild);\n }\n else\n {\n let i = 0;\n let target = this._firstChild;\n\n while (i < index)\n {\n target = target.nextChild;\n ++i;\n }\n target.prevChild.nextChild = (child as LinkedListChild);\n (child as LinkedListChild).prevChild = target.prevChild;\n (child as LinkedListChild).nextChild = target;\n target.prevChild = (child as LinkedListChild);\n }\n\n (this as any).onChildrenChange(index);\n }\n\n public removeChild(...children: T): T[0]\n {\n // if there is only one argument we can bypass looping through the them\n if (children.length > 1)\n {\n // loop through the arguments property and remove all children\n for (let i = 0; i < children.length; i++)\n {\n this.removeChild(children[i]);\n }\n }\n else\n {\n const child = children[0] as LinkedListChild;\n\n // bail if not actually our child\n if ((child as any).parent !== this) return null;\n\n (child as any).parent = null;\n // ensure child transform will be recalculated\n (child.transform as any)._parentID = -1;\n\n // swap out child references\n if (child.nextChild)\n {\n child.nextChild.prevChild = child.prevChild;\n }\n if (child.prevChild)\n {\n child.prevChild.nextChild = child.nextChild;\n }\n if (this._firstChild === child)\n {\n this._firstChild = child.nextChild;\n }\n if (this._lastChild === child)\n {\n this._lastChild = child.prevChild;\n }\n // clear sibling references\n child.nextChild = null;\n child.prevChild = null;\n\n // update child count\n --this._childCount;\n\n // ensure bounds will be recalculated\n (this as any)._boundsID++;\n\n // TODO - lets either do all callbacks or all events.. not both!\n this.onChildrenChange();\n child.emit('removed', this);\n this.emit('childRemoved', child, this);\n }\n\n return children[0];\n }\n\n public getChildAt(index: number): DisplayObject\n {\n if (index < 0 || index >= this._childCount)\n {\n throw new Error(`getChildAt: Index (${index}) does not exist.`);\n }\n\n if (index === 0)\n {\n return this._firstChild;\n }\n // add at end (front)\n else if (index === this._childCount)\n {\n return this._lastChild;\n }\n // otherwise we have to start counting through the children to find the right one\n // - SLOW, only provided to fully support the possibility of use\n let i = 0;\n let target = this._firstChild;\n\n while (i < index)\n {\n target = target.nextChild;\n ++i;\n }\n\n return target;\n }\n\n public removeChildAt(index: number): DisplayObject\n {\n const child = this.getChildAt(index) as LinkedListChild;\n\n // ensure child transform will be recalculated..\n (child as any).parent = null;\n (child.transform as any)._parentID = -1;\n // swap out child references\n if (child.nextChild)\n {\n child.nextChild.prevChild = child.prevChild;\n }\n if (child.prevChild)\n {\n child.prevChild.nextChild = child.nextChild;\n }\n if (this._firstChild === child)\n {\n this._firstChild = child.nextChild;\n }\n if (this._lastChild === child)\n {\n this._lastChild = child.prevChild;\n }\n // clear sibling references\n child.nextChild = null;\n child.prevChild = null;\n\n // update child count\n --this._childCount;\n\n // ensure bounds will be recalculated\n (this as any)._boundsID++;\n\n // TODO - lets either do all callbacks or all events.. not both!\n (this as any).onChildrenChange(index);// the PixiJS types say this has no arguments\n child.emit('removed', this);\n this.emit('childRemoved', child, this, index);\n\n return child;\n }\n\n public removeChildren(beginIndex = 0, endIndex = this._childCount): DisplayObject[]\n {\n const begin = beginIndex;\n const end = endIndex;\n const range = end - begin;\n\n if (range > 0 && range <= end)\n {\n const removed: LinkedListChild[] = [];\n let child = this._firstChild;\n\n for (let i = 0; i <= end && child; ++i, child = child.nextChild)\n {\n if (i >= begin)\n {\n removed.push(child);\n }\n }\n\n // child before removed section\n const prevChild = removed[0].prevChild;\n // child after removed section\n const nextChild = removed[removed.length - 1].nextChild;\n\n if (!nextChild)\n {\n // if we removed the last child, then the new last child is the one before\n // the removed section\n this._lastChild = prevChild;\n }\n else\n {\n // otherwise, stitch the child before the section to the child after\n nextChild.prevChild = prevChild;\n }\n if (!prevChild)\n {\n // if we removed the first child, then the new first child is the one after\n // the removed section\n this._firstChild = nextChild;\n }\n else\n {\n // otherwise stich the child after the section to the one before\n prevChild.nextChild = nextChild;\n }\n\n for (let i = 0; i < removed.length; ++i)\n {\n // clear parenting and sibling references for all removed children\n (removed[i] as any).parent = null;\n if (removed[i].transform)\n {\n (removed[i].transform as any)._parentID = -1;\n }\n removed[i].nextChild = null;\n removed[i].prevChild = null;\n }\n\n (this as any)._boundsID++;\n\n (this as any).onChildrenChange(beginIndex);\n\n for (let i = 0; i < removed.length; ++i)\n {\n removed[i].emit('removed', this);\n this.emit('childRemoved', removed[i], this, i);\n }\n\n return removed;\n }\n else if (range === 0 && this._childCount === 0)\n {\n return [];\n }\n\n throw new RangeError('removeChildren: numeric values are outside the acceptable range.');\n }\n\n /**\n * Updates the transform on all children of this container for rendering.\n * Copied from and overrides PixiJS v5 method (v4 method is identical)\n */\n updateTransform(): void\n {\n (this as any)._boundsID++;\n\n this.transform.updateTransform(this.parent.transform);\n\n // TODO: check render flags, how to process stuff here\n (this as any).worldAlpha = this.alpha * this.parent.worldAlpha;\n\n let child;\n let next;\n\n for (child = this._firstChild; child; child = next)\n {\n next = child.nextChild;\n\n if (child.visible)\n {\n child.updateTransform();\n }\n }\n }\n\n /**\n * Recalculates the bounds of the container.\n * Copied from and overrides PixiJS v5 method (v4 method is identical)\n */\n calculateBounds(): void\n {\n this._bounds.clear();\n\n this._calculateBounds();\n\n let child;\n let next;\n\n for (child = this._firstChild; child; child = next)\n {\n next = child.nextChild;\n\n if (!child.visible || !child.renderable)\n {\n continue;\n }\n\n child.calculateBounds();\n\n // TODO: filter+mask, need to mask both somehow\n if ((child as any)._mask)\n {\n const maskObject = (((child as any)._mask as MaskData).maskObject || (child as any)._mask) as Container;\n\n maskObject.calculateBounds();\n this._bounds.addBoundsMask((child as any)._bounds, (maskObject as any)._bounds);\n }\n else if (child.filterArea)\n {\n this._bounds.addBoundsArea((child as any)._bounds, child.filterArea);\n }\n else\n {\n this._bounds.addBounds((child as any)._bounds);\n }\n }\n\n (this._bounds as any).updateID = (this as any)._boundsID;\n }\n\n /**\n * Retrieves the local bounds of the displayObject as a rectangle object. Copied from and overrides PixiJS v5 method\n */\n public getLocalBounds(rect?: Rectangle, skipChildrenUpdate = false): Rectangle\n {\n // skip Container's getLocalBounds, go directly to DisplayObject\n const result = DisplayObject.prototype.getLocalBounds.call(this, rect);\n\n if (!skipChildrenUpdate)\n {\n let child;\n let next;\n\n for (child = this._firstChild; child; child = next)\n {\n next = child.nextChild;\n\n if (child.visible)\n {\n child.updateTransform();\n }\n }\n }\n\n return result;\n }\n\n /**\n * Renders the object using the WebGL renderer. Copied from and overrides PixiJS v5 method\n */\n render(renderer: Renderer): void\n {\n // if the object is not visible or the alpha is 0 then no need to render this element\n if (!this.visible || this.worldAlpha <= 0 || !this.renderable)\n {\n return;\n }\n\n // do a quick check to see if this element has a mask or a filter.\n if (this._mask || (this.filters && this.filters.length))\n {\n this.renderAdvanced(renderer);\n }\n else\n {\n this._render(renderer);\n\n let child;\n let next;\n\n // simple render children!\n for (child = this._firstChild; child; child = next)\n {\n next = child.nextChild;\n child.render(renderer);\n }\n }\n }\n\n /**\n * Render the object using the WebGL renderer and advanced features. Copied from and overrides PixiJS v5 method\n */\n protected renderAdvanced(renderer: Renderer): void\n {\n renderer.batch.flush();\n\n const filters = this.filters;\n const mask = this._mask;\n\n // _enabledFilters note: As of development, _enabledFilters is not documented in pixi.js\n // types but is in code of current release (5.2.4).\n\n // push filter first as we need to ensure the stencil buffer is correct for any masking\n if (filters)\n {\n if (!(this as any)._enabledFilters)\n {\n (this as any)._enabledFilters = [];\n }\n\n (this as any)._enabledFilters.length = 0;\n\n for (let i = 0; i < filters.length; i++)\n {\n if (filters[i].enabled)\n {\n (this as any)._enabledFilters.push(filters[i]);\n }\n }\n\n if ((this as any)._enabledFilters.length)\n {\n renderer.filter.push(this, (this as any)._enabledFilters);\n }\n }\n\n if (mask)\n {\n renderer.mask.push(this, this._mask);\n }\n\n // add this object to the batch, only rendered if it has a texture.\n this._render(renderer);\n\n let child;\n let next;\n\n // now loop through the children and make sure they get rendered\n for (child = this._firstChild; child; child = next)\n {\n next = child.nextChild;\n child.render(renderer);\n }\n\n renderer.batch.flush();\n\n if (mask)\n {\n renderer.mask.pop(this);\n }\n\n if (filters && (this as any)._enabledFilters && (this as any)._enabledFilters.length)\n {\n renderer.filter.pop();\n }\n }\n\n /**\n * Renders the object using the WebGL renderer. Copied from and overrides PixiJS V4 method.\n */\n renderWebGL(renderer: any): void\n {\n // if the object is not visible or the alpha is 0 then no need to render this element\n if (!this.visible || this.worldAlpha <= 0 || !this.renderable)\n {\n return;\n }\n\n // do a quick check to see if this element has a mask or a filter.\n if (this._mask || (this.filters && this.filters.length))\n {\n this.renderAdvancedWebGL(renderer);\n }\n else\n {\n (this as any)._renderWebGL(renderer);\n\n let child;\n let next;\n\n // simple render children!\n for (child = this._firstChild; child; child = next)\n {\n next = child.nextChild;\n (child as any).renderWebGL(renderer);\n }\n }\n }\n\n /**\n * Render the object using the WebGL renderer and advanced features. Copied from and overrides PixiJS V4 method.\n */\n private renderAdvancedWebGL(renderer: any): void\n {\n renderer.flush();\n\n // _filters is a v4 specific property\n const filters = (this as any)._filters;\n const mask = this._mask;\n\n // push filter first as we need to ensure the stencil buffer is correct for any masking\n if (filters)\n {\n if (!(this as any)._enabledFilters)\n {\n (this as any)._enabledFilters = [];\n }\n\n (this as any)._enabledFilters.length = 0;\n\n for (let i = 0; i < filters.length; i++)\n {\n if (filters[i].enabled)\n {\n (this as any)._enabledFilters.push(filters[i]);\n }\n }\n\n if ((this as any)._enabledFilters.length)\n {\n renderer.filterManager.pushFilter(this, (this as any)._enabledFilters);\n }\n }\n\n if (mask)\n {\n renderer.maskManager.pushMask(this, this._mask);\n }\n\n // add this object to the batch, only rendered if it has a texture.\n (this as any)._renderWebGL(renderer);\n\n let child;\n let next;\n\n // now loop through the children and make sure they get rendered\n for (child = this._firstChild; child; child = next)\n {\n next = child.nextChild;\n (child as any).renderWebGL(renderer);\n }\n\n renderer.flush();\n\n if (mask)\n {\n renderer.maskManager.popMask(this, this._mask);\n }\n\n if (filters && (this as any)._enabledFilters && (this as any)._enabledFilters.length)\n {\n renderer.filterManager.popFilter();\n }\n }\n\n /**\n * Renders the object using the Canvas renderer. Copied from and overrides PixiJS V4 method or Canvas mixin in V5.\n */\n renderCanvas(renderer: any): void\n {\n // if not visible or the alpha is 0 then no need to render this\n if (!this.visible || this.worldAlpha <= 0 || !this.renderable)\n {\n return;\n }\n\n if (this._mask)\n {\n renderer.maskManager.pushMask(this._mask);\n }\n\n (this as any)._renderCanvas(renderer);\n\n let child;\n let next;\n\n for (child = this._firstChild; child; child = next)\n {\n next = child.nextChild;\n (child as any).renderCanvas(renderer);\n }\n\n if (this._mask)\n {\n renderer.maskManager.popMask(renderer);\n }\n }\n}\n"]}